|
|
/*
|
|
|
@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 = $('<div class="post"></div>');
|
|
|
favThreadNode.append($(dict.post_url));
|
|
|
favThreadNode.append(' ');
|
|
|
favThreadNode.append($('<span class="title">' + dict.title + '</span>'));
|
|
|
|
|
|
if (newPostCount > 0) {
|
|
|
favThreadNode.append(' (<a href="' + dict.newest_post_link + '">+' + newPostCount + "</a>)");
|
|
|
}
|
|
|
|
|
|
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
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
$( 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'));
|
|
|
});
|
|
|
|