/* @licstart The following is the entire license notice for the JavaScript code in this page. Copyright (C) 2013 neko259 The JavaScript code in this page is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License (GNU GPL) as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. The code is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. As additional permission under GNU GPL version 3 section 7, you may distribute non-source (e.g., minimized or compacted) forms of that code without the copy of the GNU GPL normally required by section 4, provided you include this license notice and a URL through which recipients can access the Corresponding Source. @licend The above is the entire license notice for the JavaScript code in this page. */ var ITEM_VOLUME_LEVEL = 'volumeLevel'; var ITEM_HIDDEN_POSTS = 'hiddenPosts'; var IMAGE_TYPES = ['image/png', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/gif']; /** * An email is a hidden file to prevent spam bots from posting. It has to be * hidden. */ function hideEmailFromForm() { $('.form-email').parent().parent().hide(); } /** * Highlight code blocks with code highlighter */ function highlightCode(node) { node.find('pre code').each(function(i, e) { hljs.highlightBlock(e); }); } function updateFavPosts(data) { var includePostBody = $('#fav-panel').is(":visible"); var allNewPostCount = 0; if (includePostBody) { var favoriteThreadPanel = $('#fav-panel'); favoriteThreadPanel.empty(); } $.each($.parseJSON(data), function (_, dict) { var newPostCount = dict.new_post_count; allNewPostCount += newPostCount; if (includePostBody) { var favThreadNode = $('
'); favThreadNode.append($(dict.post_url)); favThreadNode.append(' '); favThreadNode.append($('' + dict.title + '')); if (newPostCount > 0) { favThreadNode.append(' (+' + newPostCount + ")"); } favoriteThreadPanel.append(favThreadNode); addRefLinkPreview(favThreadNode[0]); } }); var newPostCountNode = $('#new-fav-post-count'); if (allNewPostCount > 0) { newPostCountNode.text('(+' + allNewPostCount + ')'); newPostCountNode.show(); } else { newPostCountNode.hide(); } } function initFavPanel() { var favPanelButton = $('#fav-panel-btn'); if (favPanelButton.length > 0 && typeof SharedWorker != 'undefined') { var worker = new SharedWorker($('body').attr('data-update-script')); worker.port.onmessage = function(e) { updateFavPosts(e.data); }; worker.onerror = function(event){ throw new Error(event.message + " (" + event.filename + ":" + event.lineno + ")"); }; worker.port.start(); $(favPanelButton).click(function() { var favPanel = $('#fav-panel'); favPanel.toggle(); worker.port.postMessage({ includePostBody: favPanel.is(':visible')}); return false; }); $(document).on('keyup.removepic', function(e) { if(e.which === 27) { $('#fav-panel').hide(); } }); } } function setVolumeLevel(level) { localStorage.setItem(ITEM_VOLUME_LEVEL, level); } function getVolumeLevel() { var level = localStorage.getItem(ITEM_VOLUME_LEVEL); if (level == null) { level = 1.0; } return level } function processVolumeUser(node) { if (!window.localStorage) return; node.prop("volume", getVolumeLevel()); node.on('volumechange', function(event) { setVolumeLevel(event.target.volume); $("video,audio").prop("volume", getVolumeLevel()); }); } function getHiddenPosts() { var arr = Array(); var hiddenPosts = localStorage.getItem(ITEM_HIDDEN_POSTS); if (hiddenPosts) { arr = JSON.parse(hiddenPosts); } return arr; } function processPostHiding(posts) { var hiddenPosts = getHiddenPosts(); $.each(posts, function(index) { var post = $(this); if (hiddenPosts.indexOf(post.attr("id")) > -1) { post.toggleClass("hidden_post"); } }); } /** * Add all scripts than need to work on post, when the post is added to the * document. */ function addScriptsToPost(post) { addRefLinkPreview(post[0]); highlightCode(post); processVolumeUser(post.find("video,audio")); processPostHiding([post]); } /** * Fix compatibility issues with some rare browsers */ function compatibilityCrutches() { if (window.operamini) { $('#form textarea').each(function() { this.placeholder = ''; }); } } function togglePostHidden(postId) { var hiddenPosts = getHiddenPosts(); var elIndex = hiddenPosts.indexOf(postId); if (elIndex > -1) { hiddenPosts.splice(elIndex, 1); } else { hiddenPosts.push(postId); } localStorage.setItem(ITEM_HIDDEN_POSTS, JSON.stringify(hiddenPosts)); $('#' + postId).toggleClass("hidden_post"); } function addContextMenu() { $.contextMenu({ selector: '.file-menu', trigger: 'left', build: function($trigger, e) { var fileSearchUrl = $trigger.data('search-url'); var isImage = IMAGE_TYPES.indexOf($trigger.data('type')) > -1; var hasUrl = fileSearchUrl.length > 0; var id = $trigger.data('id'); return { items: { duplicates: { name: gettext('Duplicates search'), callback: function(key, opts) { window.location = '/feed/?image=' + $trigger.data('filename'); } }, google: { name: 'Google', visible: isImage && hasUrl, callback: function(key, opts) { window.location = 'https://www.google.com/searchbyimage?image_url=' + fileSearchUrl; } }, iqdb: { name: 'IQDB', visible: isImage && hasUrl, callback: function(key, opts) { window.location = 'http://iqdb.org/?url=' + fileSearchUrl; } }, tineye: { name: 'TinEye', visible: isImage && hasUrl, callback: function(key, opts) { window.location = 'http://tineye.com/search?url=' + fileSearchUrl; } }, addAlias: { name: gettext('Add local sticker'), callback: function(key, opts) { var alias = prompt(gettext('Input sticker name')); if (alias) { window.location = '/stickers/?action=add&name=' + alias + '&id=' + id; } } } } }; } }); $.contextMenu({ selector: '.post .post-menu', trigger: 'left', build: function($trigger, e) { var canEditPost = PERMS['change_post']; var canDeletePost = PERMS['delete_post']; var canEditThread = PERMS['change_thread']; var canDeleteThread = PERMS['delete_thread']; var post = $trigger.parents('.post'); var isOpening = post.data('opening') === 'True'; var threadId = post.data('thread-id'); var hasGlobalId = post.data('has-global-id') === 'True'; var posterIp = $trigger.siblings('.pub_time').attr('title'); var hasIp = posterIp != null; var postId = post.attr('id'); return { items: { hide: { name: gettext('Hide/show'), callback: function(key, opt) { togglePostHidden(postId); } }, edit: { name: gettext('Edit'), callback: function(key, opt) { window.location = '/admin/boards/post/' + postId + '/change/'; }, visible: canEditPost }, deletePost: { name: gettext('Delete post'), callback: function(key, opt) { window.location = '/admin/boards/post/' + postId + '/delete/'; }, visible: !isOpening && canDeletePost }, editThread: { name: gettext('Edit thread'), callback: function(key, opt) { window.location = '/admin/boards/thread/' + threadId + '/change/'; }, visible: isOpening && canEditThread }, deleteThread: { name: gettext('Delete thread'), callback: function(key, opt) { window.location = '/admin/boards/thread/' + threadId + '/delete/'; }, visible: isOpening && canDeleteThread }, findByIp: { name: 'IP = ' + posterIp, callback: function(key, opt) { window.location = '/feed/?ip=' + posterIp; }, visible: canEditPost && hasIp }, raw: { name: 'RAW', callback: function(key, opt) { window.location = '/post_xml/' + postId; }, visible: canEditPost && hasGlobalId }, ban: { name: gettext('Ban'), callback: function(key, opt) { if (confirm(gettext('Are you sure?'))) { window.location = '/utils?method=ban&post_id=' + postId; } }, visible: canEditPost && hasIp }, banAndDelete: { name: gettext('Ban and delete'), callback: function(key, opt) { if (confirm(gettext('Are you sure?'))) { window.location = '/utils?method=ban_and_delete&post_id=' + postId; } }, visible: hasIp && canDeletePost }, rollover: { name: gettext('Rollover thread'), callback: function(key, opt) { if (confirm(gettext('Are you sure?'))) { window.location = '/all/?t_from_id=' + postId + '#form'; } }, visible: isOpening } } }; } }); } $( document ).ready(function() { hideEmailFromForm(); $("a[href='#top']").click(function() { $("html, body").animate({ scrollTop: 0 }, "slow"); return false; }); addImgPreview(); addRefLinkPreview(); highlightCode($(document)); initFavPanel(); var volumeUsers = $("video,audio"); processVolumeUser(volumeUsers); addContextMenu(); compatibilityCrutches(); processPostHiding($('.post')); });