main.js
362 lines
| 11.7 KiB
| application/javascript
|
JavascriptLexer
neko259
|
r332 | /* | ||
@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. | ||||
*/ | ||||
neko259
|
r1432 | var ITEM_VOLUME_LEVEL = 'volumeLevel'; | ||
neko259
|
r2080 | var ITEM_HIDDEN_POSTS = 'hiddenPosts'; | ||
neko259
|
r1868 | var IMAGE_TYPES = ['image/png', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/gif']; | ||
neko259
|
r1340 | |||
neko259
|
r653 | /** | ||
* An email is a hidden file to prevent spam bots from posting. It has to be | ||||
* hidden. | ||||
*/ | ||||
function hideEmailFromForm() { | ||||
$('.form-email').parent().parent().hide(); | ||||
} | ||||
neko259
|
r703 | /** | ||
* Highlight code blocks with code highlighter | ||||
*/ | ||||
neko259
|
r709 | function highlightCode(node) { | ||
node.find('pre code').each(function(i, e) { | ||||
neko259
|
r703 | hljs.highlightBlock(e); | ||
}); | ||||
} | ||||
neko259
|
r1463 | function updateFavPosts(data) { | ||
neko259
|
r1340 | var includePostBody = $('#fav-panel').is(":visible"); | ||
neko259
|
r1463 | |||
var allNewPostCount = 0; | ||||
neko259
|
r1340 | if (includePostBody) { | ||
neko259
|
r1463 | var favoriteThreadPanel = $('#fav-panel'); | ||
favoriteThreadPanel.empty(); | ||||
neko259
|
r1340 | } | ||
neko259
|
r1463 | |||
$.each($.parseJSON(data), function (_, dict) { | ||||
var newPostCount = dict.new_post_count; | ||||
allNewPostCount += newPostCount; | ||||
neko259
|
r1340 | |||
neko259
|
r1463 | 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>)"); | ||||
neko259
|
r1340 | } | ||
neko259
|
r1463 | favoriteThreadPanel.append(favThreadNode); | ||
neko259
|
r1340 | |||
neko259
|
r1463 | addRefLinkPreview(favThreadNode[0]); | ||
} | ||||
}); | ||||
neko259
|
r1340 | |||
neko259
|
r1463 | var newPostCountNode = $('#new-fav-post-count'); | ||
if (allNewPostCount > 0) { | ||||
newPostCountNode.text('(+' + allNewPostCount + ')'); | ||||
newPostCountNode.show(); | ||||
} else { | ||||
newPostCountNode.hide(); | ||||
} | ||||
neko259
|
r1340 | } | ||
function initFavPanel() { | ||||
neko259
|
r1463 | var favPanelButton = $('#fav-panel-btn'); | ||
neko259
|
r1465 | if (favPanelButton.length > 0 && typeof SharedWorker != 'undefined') { | ||
neko259
|
r1463 | var worker = new SharedWorker($('body').attr('data-update-script')); | ||
worker.port.onmessage = function(e) { | ||||
updateFavPosts(e.data); | ||||
}; | ||||
neko259
|
r1466 | worker.onerror = function(event){ | ||
throw new Error(event.message + " (" + event.filename + ":" + event.lineno + ")"); | ||||
neko259
|
r1464 | }; | ||
neko259
|
r1463 | worker.port.start(); | ||
$(favPanelButton).click(function() { | ||||
var favPanel = $('#fav-panel'); | ||||
favPanel.toggle(); | ||||
worker.port.postMessage({ includePostBody: favPanel.is(':visible')}); | ||||
neko259
|
r1340 | |||
neko259
|
r1341 | return false; | ||
}); | ||||
neko259
|
r1340 | |||
neko259
|
r1341 | $(document).on('keyup.removepic', function(e) { | ||
if(e.which === 27) { | ||||
$('#fav-panel').hide(); | ||||
} | ||||
}); | ||||
} | ||||
neko259
|
r1340 | } | ||
neko259
|
r1432 | 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) { | ||||
r1639 | if (!window.localStorage) return; | |||
neko259
|
r1432 | node.prop("volume", getVolumeLevel()); | ||
node.on('volumechange', function(event) { | ||||
setVolumeLevel(event.target.volume); | ||||
$("video,audio").prop("volume", getVolumeLevel()); | ||||
}); | ||||
} | ||||
neko259
|
r2080 | function getHiddenPosts() { | ||
var arr = Array(); | ||||
var hiddenPosts = localStorage.getItem(ITEM_HIDDEN_POSTS); | ||||
if (hiddenPosts) { | ||||
arr = JSON.parse(hiddenPosts); | ||||
} | ||||
return arr; | ||||
} | ||||
neko259
|
r2082 | function processPostHiding(posts) { | ||
neko259
|
r2080 | var hiddenPosts = getHiddenPosts(); | ||
neko259
|
r2082 | |||
$.each(posts, function(index) { | ||||
var post = $(this); | ||||
if (hiddenPosts.indexOf(post.attr("id")) > -1) { | ||||
post.toggleClass("hidden_post"); | ||||
} | ||||
}); | ||||
neko259
|
r2080 | } | ||
neko259
|
r1432 | /** | ||
* 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")); | ||||
neko259
|
r2082 | processPostHiding([post]); | ||
neko259
|
r1432 | } | ||
r1639 | /** | |||
* Fix compatibility issues with some rare browsers | ||||
*/ | ||||
function compatibilityCrutches() { | ||||
if (window.operamini) { | ||||
$('#form textarea').each(function() { this.placeholder = ''; }); | ||||
} | ||||
} | ||||
neko259
|
r2080 | 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"); | ||||
} | ||||
neko259
|
r1817 | 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; | ||||
neko259
|
r1940 | var id = $trigger.data('id'); | ||
neko259
|
r1817 | return { | ||
items: { | ||||
duplicates: { | ||||
name: gettext('Duplicates search'), | ||||
callback: function(key, opts) { | ||||
neko259
|
r1827 | window.location = '/feed/?image=' + $trigger.data('filename'); | ||
neko259
|
r1817 | } | ||
}, | ||||
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; | ||||
} | ||||
neko259
|
r1940 | }, | ||
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; | ||||
} | ||||
} | ||||
neko259
|
r1817 | } | ||
neko259
|
r1940 | } | ||
neko259
|
r1817 | }; | ||
} | ||||
}); | ||||
neko259
|
r2039 | |||
$.contextMenu({ | ||||
neko259
|
r2080 | selector: '.post .post-menu', | ||
neko259
|
r2039 | 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: { | ||||
neko259
|
r2080 | hide: { | ||
name: gettext('Hide/show'), | ||||
callback: function(key, opt) { | ||||
togglePostHidden(postId); | ||||
} | ||||
}, | ||||
neko259
|
r2039 | 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; | ||||
}, | ||||
neko259
|
r2080 | visible: canEditPost && hasIp | ||
neko259
|
r2039 | }, | ||
raw: { | ||||
name: 'RAW', | ||||
callback: function(key, opt) { | ||||
window.location = '/post_xml/' + postId; | ||||
}, | ||||
neko259
|
r2080 | visible: canEditPost && hasGlobalId | ||
neko259
|
r2039 | }, | ||
ban: { | ||||
name: gettext('Ban'), | ||||
callback: function(key, opt) { | ||||
if (confirm(gettext('Are you sure?'))) { | ||||
window.location = '/utils?method=ban&post_id=' + postId; | ||||
} | ||||
}, | ||||
neko259
|
r2080 | visible: canEditPost && hasIp | ||
neko259
|
r2039 | }, | ||
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 | ||||
} | ||||
} | ||||
}; | ||||
} | ||||
}); | ||||
neko259
|
r1817 | } | ||
neko259
|
r54 | $( document ).ready(function() { | ||
neko259
|
r653 | hideEmailFromForm(); | ||
neko259
|
r54 | $("a[href='#top']").click(function() { | ||
$("html, body").animate({ scrollTop: 0 }, "slow"); | ||||
return false; | ||||
}); | ||||
neko259
|
r63 | |||
neko259
|
r270 | addImgPreview(); | ||
neko259
|
r272 | |||
neko259
|
r352 | addRefLinkPreview(); | ||
neko259
|
r703 | |||
neko259
|
r709 | highlightCode($(document)); | ||
neko259
|
r1340 | |||
initFavPanel(); | ||||
neko259
|
r1432 | |||
var volumeUsers = $("video,audio"); | ||||
processVolumeUser(volumeUsers); | ||||
r1639 | ||||
neko259
|
r1817 | addContextMenu(); | ||
r1639 | compatibilityCrutches(); | |||
neko259
|
r2080 | |||
neko259
|
r2082 | processPostHiding($('.post')); | ||
rt@lightning
|
r228 | }); | ||