diff options
Diffstat (limited to 'js')
| -rw-r--r-- | js/ajax.js | 16 | ||||
| -rw-r--r-- | js/catalog-search.js | 82 | ||||
| -rw-r--r-- | js/expand-video.js | 4 | ||||
| -rw-r--r-- | js/favorites.js | 1 | ||||
| -rw-r--r-- | js/file-selector.js | 191 | ||||
| -rw-r--r-- | js/forced-anon.js | 2 | ||||
| -rw-r--r-- | js/gallery-view.js | 165 | ||||
| -rw-r--r-- | js/hide-images.js | 4 | ||||
| -rw-r--r-- | js/image-hover.js | 182 | ||||
| -rw-r--r-- | js/live-index.js | 2 | ||||
| -rw-r--r-- | js/no-animated-gif.js | 2 | ||||
| -rw-r--r-- | js/own-board.js | 116 | ||||
| -rw-r--r-- | js/quick-reply.js | 11 | ||||
| -rw-r--r-- | js/thread-stats.js | 116 | ||||
| -rw-r--r-- | js/toggle-images.js | 2 | ||||
| -rw-r--r-- | js/treeview.js | 48 | ||||
| -rw-r--r-- | js/upload-selection.js | 2 | ||||
| m--------- | js/wPaint | 0 | ||||
| -rw-r--r-- | js/watch.js | 9 | ||||
| -rw-r--r-- | js/wpaint.js | 9 |
20 files changed, 920 insertions, 44 deletions
@@ -115,17 +115,10 @@ $(window).ready(function() { } }, error: function(xhr, status, er) { - // An error occured - do_not_ajax = true; - $(form).find('input[type="submit"]').each(function() { - var $replacement = $('<input type="hidden">'); - $replacement.attr('name', $(this).attr('name')); - $replacement.val(submit_txt); - $(this) - .after($replacement) - .replaceWith($('<input type="button">').val(submit_txt)); - }); - $(form).submit(); + console.log(xhr); + alert(_('The server took too long to submit your post. Your post was probably still submitted. If it wasn\'t, we might be experiencing issues right now -- please try your post again later. Error information: ') + "<div><textarea>" + JSON.stringify(xhr) + "</textarea></div>"); + $(form).find('input[type="submit"]').val(submit_txt); + $(form).find('input[type="submit"]').removeAttr('disabled'); }, data: formData, cache: false, @@ -141,6 +134,7 @@ $(window).ready(function() { }; setup_form($('form[name="post"]')); $(window).on('quick-reply', function() { + $('form#quick-reply').off('submit'); setup_form($('form#quick-reply')); }); }); diff --git a/js/catalog-search.js b/js/catalog-search.js new file mode 100644 index 00000000..17a8edac --- /dev/null +++ b/js/catalog-search.js @@ -0,0 +1,82 @@ +/* + * catalog-search.js + * - Search and filters threads when on catalog view + * - Optional shortcuts 's' and 'esc' to open and close the search. + * + * Usage: + * $config['additional_javascript'][] = 'js/jquery.min.js'; + * $config['additional_javascript'][] = 'js/comment-toolbar.js'; + */ +if (active_page == 'catalog') { + onready(function () { + 'use strict'; + + // 'true' = enable shortcuts + var useKeybinds = true; + + // trigger the search 400ms after last keystroke + var delay = 400; + var timeoutHandle; + + //search and hide none matching threads + function filter(search_term) { + $('.replies').each(function () { + var subject = $(this).children('.intro').text().toLowerCase(); + var comment = $(this).clone().children().remove(':lt(2)').end().text().trim().toLowerCase(); + search_term = search_term.toLowerCase(); + + if (subject.indexOf(search_term) == -1 && comment.indexOf(search_term) == -1) { + $(this).parents('div[id="Grid"]>.mix').css('display', 'none'); + } else { + $(this).parents('div[id="Grid"]>.mix').css('display', 'inline-block'); + } + }); + } + + function searchToggle() { + var button = $('#catalog_search_button')[0]; + + if (!button.dataset.expanded) { + button.dataset.expanded = '1'; + button.innerText = 'Close'; + $('.catalog_search').append(' <input id="search_field" style="border: inset 1px;">'); + $('#search_field').focus(); + } else { + delete button.dataset.expanded; + button.innerText = 'Search'; + $('.catalog_search').children().last().remove(); + $('div[id="Grid"]>.mix').each(function () { $(this).css('display', 'inline-block'); }); + } + } + + $('.threads').before('<span class="catalog_search">[<a id="catalog_search_button" style="text-decoration:none; cursor:pointer;"></a>]</span>'); + $('#catalog_search_button').text('Search'); + + $('#catalog_search_button').on('click', searchToggle); + $('.catalog_search').on('keyup', 'input#search_field', function (e) { + window.clearTimeout(timeoutHandle); + timeoutHandle = window.setTimeout(filter, 400, e.target.value); + }); + + if (useKeybinds) { + // 's' + $('body').on('keydown', function (e) { + if (e.which === 83 && e.target.tagName === 'BODY' && !(e.ctrlKey || e.altKey || e.shiftKey)) { + e.preventDefault(); + if ($('#search_field').length !== 0) { + $('#search_field').focus(); + } else { + searchToggle(); + } + } + }); + // 'esc' + $('.catalog_search').on('keydown', 'input#search_field', function (e) { + if (e.which === 27 && !(e.ctrlKey || e.altKey || e.shiftKey)) { + window.clearTimeout(timeoutHandle); + searchToggle(); + } + }); + } + }); +} diff --git a/js/expand-video.js b/js/expand-video.js index 79872510..08b474c1 100644 --- a/js/expand-video.js +++ b/js/expand-video.js @@ -204,13 +204,13 @@ function setupVideo(thumb, url) { function setupVideosIn(element) { var thumbs = element.querySelectorAll("a.file"); for (var i = 0; i < thumbs.length; i++) { - if (/\.webm$/.test(thumbs[i].pathname)) { + if (/\.webm$|\.mp4$/.test(thumbs[i].pathname)) { setupVideo(thumbs[i], thumbs[i].href); } else { var m = thumbs[i].search.match(/\bv=([^&]*)/); if (m != null) { var url = decodeURIComponent(m[1]); - if (/\.webm$/.test(url)) setupVideo(thumbs[i], url); + if (/\.webm$|\.mp4$/.test(url)) setupVideo(thumbs[i], url); } } } diff --git a/js/favorites.js b/js/favorites.js index e325e110..daf7b732 100644 --- a/js/favorites.js +++ b/js/favorites.js @@ -54,7 +54,6 @@ if (active_page == 'thread' || active_page == 'index') { $(document).ready(function(){ var favorites = JSON.parse(localStorage.favorites); var is_board_favorite = ~$.inArray(board_name, favorites); - console.log(is_board_favorite); $('header>h1').append('<a id="favorite-star" href="#" data-active="'+(is_board_favorite ? 'true' : 'false')+'" style="color: '+(is_board_favorite ? 'yellow' : 'grey')+'; text-decoration:none">\u2605</span>'); add_favorites(); diff --git a/js/file-selector.js b/js/file-selector.js new file mode 100644 index 00000000..207a5ae9 --- /dev/null +++ b/js/file-selector.js @@ -0,0 +1,191 @@ +/* + * file-selector.js - Add support for drag and drop file selection, and paste from clipbboard on supported browsers. + * + * Usage: + * $config['additional_javascript'][] = 'js/jquery.min.js'; + * $config['additional_javascript'][] = 'js/file-selector.js'; + */ +function init_file_selector(max_images) { + +$(document).ready(function () { + // add options panel item + if (window.Options && Options.get_tab('general')) { + Options.extend_tab('general', '<label id="file-drag-drop"><input type="checkbox">' + _('Drag and drop file selection') + '</label>'); + + $('#file-drag-drop>input').on('click', function() { + if ($('#file-drag-drop>input').is(':checked')) { + localStorage.file_dragdrop = 'true'; + } else { + localStorage.file_dragdrop = 'false'; + } + }); + + if (typeof localStorage.file_dragdrop === 'undefined') localStorage.file_dragdrop = 'true'; + if (localStorage.file_dragdrop === 'true') $('#file-drag-drop>input').prop('checked', true); + } +}); + +// disabled by user, or incompatible browser. +if (localStorage.file_dragdrop == 'false' || !(window.URL.createObjectURL && window.File)) + return; + +// multipost not enabled +if (typeof max_images == 'undefined') { + var max_images = 1; +} + +$('<div class="dropzone-wrap" style="display: none;">'+ + '<div class="dropzone" tabindex="0">'+ + '<div class="file-hint">'+_('Select/drop/paste files here')+'</div>'+ + '<div class="file-thumbs"></div>'+ + '</div>'+ + '</div>'+ +'</div>').prependTo('#upload td'); + +var files = []; +$('#upload_file').remove(); // remove the original file selector +$('.dropzone-wrap').css('user-select', 'none').show(); // let jquery add browser specific prefix + +function addFile(file) { + if (files.length == max_images) + return; + + files.push(file); + addThumb(file); +} + +function removeFile(file) { + files.splice(files.indexOf(file), 1); +} + +function getThumbElement(file) { + return $('.tmb-container').filter(function(){return($(this).data('file-ref')==file);}); +} + +function addThumb(file) { + + var fileName = (file.name.length < 24) ? file.name : file.name.substr(0, 22) + '…'; + var fileType = file.type.split('/')[0]; + var fileExt = file.type.split('/')[1]; + var $container = $('<div>') + .addClass('tmb-container') + .data('file-ref', file) + .append( + $('<div>').addClass('remove-btn').html('✖'), + $('<div>').addClass('file-tmb'), + $('<div>').addClass('tmb-filename').html(fileName) + ) + .appendTo('.file-thumbs'); + + var $fileThumb = $container.find('.file-tmb'); + if (fileType == 'image') { + // if image file, generate thumbnail + var objURL = window.URL.createObjectURL(file); + $fileThumb.css('background-image', 'url('+ objURL +')'); + } else { + $fileThumb.html('<span>' + fileExt.toUpperCase() + '</span>'); + } +} + +$(document).on('ajax_before_post', function (e, formData) { + for (var i=0; i<max_images; i++) { + var key = 'file'; + if (i > 0) key += i + 1; + if (typeof files[i] === 'undefined') break; + formData.append(key, files[i]); + } +}); + +// clear file queue and UI on success +$(document).on('ajax_after_post', function () { + files = []; + $('.file-thumbs').empty(); +}); + +var dragCounter = 0; +var dropHandlers = { + dragenter: function (e) { + e.stopPropagation(); + e.preventDefault(); + + if (dragCounter === 0) $('.dropzone').addClass('dragover'); + dragCounter++; + }, + dragover: function (e) { + // needed for webkit to work + e.stopPropagation(); + e.preventDefault(); + }, + dragleave: function (e) { + e.stopPropagation(); + e.preventDefault(); + + dragCounter--; + if (dragCounter === 0) $('.dropzone').removeClass('dragover'); + }, + drop: function (e) { + e.stopPropagation(); + e.preventDefault(); + + $('.dropzone').removeClass('dragover'); + dragCounter = 0; + + var fileList = e.originalEvent.dataTransfer.files; + for (var i=0; i<fileList.length; i++) { + addFile(fileList[i]); + } + } +}; + + +// attach handlers +$(document).on(dropHandlers); + +$(document).on('click', '.dropzone .remove-btn', function (e) { + e.stopPropagation(); + + var file = $(e.target).parent().data('file-ref'); + + getThumbElement(file).remove(); + removeFile(file); +}); + +$(document).on('keypress click', '.dropzone', function (e) { + e.stopPropagation(); + + // accept mouse click or Enter + if ((e.which != 1 || e.target.className != 'file-hint') && + e.which != 13) + return; + + var $fileSelector = $('<input type="file" multiple>'); + + $fileSelector.on('change', function (e) { + if (this.files.length > 0) { + for (var i=0; i<this.files.length; i++) { + addFile(this.files[i]); + } + } + $(this).remove(); + }); + + $fileSelector.click(); +}); + +$(document).on('paste', function (e) { + var clipboard = e.originalEvent.clipboardData; + if (typeof clipboard.items != 'undefined' && clipboard.items.length != 0) { + + //Webkit + for (var i=0; i<clipboard.items.length; i++) { + if (clipboard.items[i].kind != 'file') + continue; + + //convert blob to file + var file = new File([clipboard.items[i].getAsFile()], 'ClipboardImage.png', {type: 'image/png'}); + addFile(file); + } + } +}); + +} diff --git a/js/forced-anon.js b/js/forced-anon.js index 5ea68199..11327ec9 100644 --- a/js/forced-anon.js +++ b/js/forced-anon.js @@ -64,7 +64,7 @@ $(document).ready(function() { if (window.Options && Options.get_tab('general')) { selector = '#forced-anon'; event = 'change'; - Options.extend_tab("general", "<label id='forced-anon'><input type='checkbox' /> "+_('Forced anonymity')+"</label>"); + Options.extend_tab("general", "<label id='forced-anon'><input type='checkbox' />"+_('Forced anonymity')+"</label>"); } else { selector = '#forced-anon'; diff --git a/js/gallery-view.js b/js/gallery-view.js new file mode 100644 index 00000000..2d7d85b4 --- /dev/null +++ b/js/gallery-view.js @@ -0,0 +1,165 @@ +if (active_page == 'index' || active_page == 'thread') +$(function(){ + + var gallery_view = false; + + $('hr:first').before('<div id="gallery-view" style="text-align:right"><a class="unimportant" href="javascript:void(0)">-</a></div>'); + $('#gallery-view a').html(gallery_view ? _("Disable gallery mode") : _("Enable gallery mode")).click(function() { + gallery_view = !gallery_view; + $(this).html(gallery_view ? _("Disable gallery mode") : _("Enable gallery mode")); + toggle_gview(document); + }); + + var toggle_gview = function(elem) { + if (gallery_view) { + $(elem).find('img.post-image').parent().each(function() { + this.oldonclick = this.onclick; + this.onclick = handle_click; + $(this).attr('data-galid', Math.random()); + }); + } + else { + $(elem).find('img.post-image').parent().each(function() { + if (this.onclick == handle_click) this.onclick = this.oldonclick; + }); + } + }; + + $(document).on('new_post', toggle_gview); + + var gallery_opened = false; + + var handle_click = function(e) { + e.stopPropagation(); + e.preventDefault(); + + if (!gallery_opened) open_gallery(); + + gallery_setimage($(this).attr('data-galid')); + }; + + var handler, images, active, toolbar; + + var open_gallery = function() { + $('body').css('overflow', 'hidden'); + + gallery_opened = true; + + handler = $("<div id='alert_handler'></div>").hide().appendTo('body').css('text-align', 'left'); + + $("<div id='alert_background'></div>").click(close_gallery).appendTo(handler); + + images = $("<div id='gallery_images'></div>").appendTo(handler); + toolbar = $("<div id='gallery_toolbar'></div>").appendTo(handler); + active = $("<div id='gallery_main'></div>").appendTo(handler); + + active.on('click', function() { + close_gallery(); + }); + + $('img.post-image').parent().each(function() { + var thumb = $(this).find('img').attr('src'); + + var i = $('<img>').appendTo(images); + i.attr('src', thumb); + i.attr('data-galid-th', $(this).attr('data-galid')); + + i.on('click', function(e) { + gallery_setimage($(this).attr('data-galid-th')); + }); + }); + + $("<a href='javascript:void(0)'><i class='fa fa-times'></i></div>") + .click(close_gallery).appendTo(toolbar); + + $('body').on('keydown.gview', function(e) { + if (e.which == 39 || e.which == 40) { // right or down arrow + gallery_setimage(+1); + e.preventDefault(); + } + else if (e.which == 37 || e.which == 38) { // left or up arrow + gallery_setimage(-1); + e.preventDefault(); + } + }); + + handler.fadeIn(400); + }; + + var gallery_setimage = function(a) { + if (a == +1 || a == -1) { + var meth = (a == -1) ? 'prev' : 'next'; + a = $('#gallery_images img.active')[meth]().attr('data-galid-th'); + if (!a) return; + } + + $('#gallery_images img.active').removeClass('active'); + + var thumb = $('#gallery_images [data-galid-th="'+a+'"]'); + var elem = $('a[data-galid="'+a+'"]'); + + thumb.addClass('active'); + + var topscroll = thumb.position().top + images.scrollTop(); + topscroll -= images.height() / 2; + topscroll += thumb.height() / 2; + images.animate({'scrollTop': topscroll}, 300); + + var img = elem.attr('href'); + + active.find('img, video').fadeOut(200, function() { $(this).remove(); }); + + var i; + if (img.match(/player\.php/)) { + img = img.replace(/.*player\.php\?v=|&t=.*/g, ''); + } + if (img.match(/\.webm$|\.mp4$|\.ogv$/i)) { // We are handling video nao + i = $('<video>'); + i.attr('src', img); + i.attr('autoplay', true); + i.attr('controls', true); + i.appendTo(active); + i.hide(); + } + else { // Just a plain image + i = $('<img>'); + i.attr('src', img); + i.appendTo(active); + i.hide(); + } + + // Let's actually preload the next few images + var nextimg = $('#gallery_images active'); + for (var j = 0; j < 3; j++) { + nextimg = nextimg.next(); + var attr; + if (attr = nextimg.attr('data-gaild-th')) { + var href = $('a[data-galid="'+attr+'"]').attr('href'); + if (href.match(/\.webm|\.mp4|\.ogv/i)) { j--; continue; } + if ($('[data-galid-preload="'+attr+'"]').length) continue; + var img = $('<img>').attr('src', href).attr('data-galid-preload', attr).hide().appendTo('body').on('load', function() { $(this).remove(); }); + } + else break; + } + + i.one('load canplay', function() { + i.css('left', 'calc(50% - '+i.width()+'px / 2)'); + i.css('top', 'calc(50% - '+i.height()+'px / 2)'); + i.fadeIn(200); + }).on('click', function(e) { + e.stopPropagation(); + gallery_setimage(+1); + }); + }; + + var close_gallery = function() { + $('body').css('overflow', 'auto'); + + gallery_opened = false; + + $('body').off('keydown.gview'); + + handler.fadeOut(400, function() { handler.remove(); }); + }; + +}); diff --git a/js/hide-images.js b/js/hide-images.js index 023c166c..323a1a1f 100644 --- a/js/hide-images.js +++ b/js/hide-images.js @@ -93,9 +93,9 @@ $(document).ready(function(){ $(this).parent().prev().find('.hide-image-link').click(); }; - $('div.post > a > img.post-image, div > a > img.post-image').each(handle_images); + $('div.post > a > img.post-image, div.post > a > video.post-image, div > a > img.post-image, div > a > video.post-image').each(handle_images); $(document).on('new_post', function(e, post) { - $(post).find('a > img.post-image').each(handle_images); + $(post).find('a > img.post-image, a > video.post-image').each(handle_images); }); }); diff --git a/js/image-hover.js b/js/image-hover.js new file mode 100644 index 00000000..93d61702 --- /dev/null +++ b/js/image-hover.js @@ -0,0 +1,182 @@ +/* image-hover.js + * This script is copied almost verbatim from https://github.com/Pashe/8chanX/blob/2-0/8chan-x.user.js + * All I did was remove the sprintf dependency and integrate it into 8chan's Options as opposed to Pashe's. + * I also changed initHover() to also bind on new_post. + * Thanks Pashe for using WTFPL. + */ + +if (active_page === "catalog" || active_page === "thread" || active_page === "index") { +$(document).on('ready', function(){ + +if (window.Options && Options.get_tab('general')) { + Options.extend_tab("general", + "<fieldset><legend>Image hover</legend>" + + ("<label class='image-hover' id='imageHover'><input type='checkbox' /> "+_('Image hover')+"</label>") + + ("<label class='image-hover' id='catalogImageHover'><input type='checkbox' /> "+_('Image hover on catalog')+"</label>") + + ("<label class='image-hover' id='imageHoverFollowCursor'><input type='checkbox' /> "+_('Image hover should follow cursor')+"</label>") + + "</fieldset>"); +} + +$('.image-hover').on('change', function(){ + var setting = $(this).attr('id'); + + localStorage[setting] = $(this).children('input').is(':checked'); +}); + +if (!localStorage.imageHover || !localStorage.catalogImageHover || !localStorage.imageHoverFollowCursor) { + localStorage.imageHover = 'false'; + localStorage.catalogImageHover = 'false'; + localStorage.imageHoverFollowCursor = 'false'; +} + +if (getSetting('imageHover')) $('#imageHover>input').prop('checked', 'checked'); +if (getSetting('catalogImageHover')) $('#catalogImageHover>input').prop('checked', 'checked'); +if (getSetting('imageHoverFollowCursor')) $('#imageHoverFollowCursor>input').prop('checked', 'checked'); + +function getFileExtension(filename) { //Pashe, WTFPL + if (filename.match(/\.([a-z0-9]+)(&loop.*)?$/i) !== null) { + return filename.match(/\.([a-z0-9]+)(&loop.*)?$/i)[1]; + } else if (filename.match(/https?:\/\/(www\.)?youtube.com/)) { + return 'Youtube'; + } else { + return "unknown: " + filename; + } +} + +function isImage(fileExtension) { //Pashe, WTFPL + return ($.inArray(fileExtension, ["jpg", "jpeg", "gif", "png"]) !== -1); +} + +function isVideo(fileExtension) { //Pashe, WTFPL + return ($.inArray(fileExtension, ["webm", "mp4"]) !== -1); +} + +function isOnCatalog() { + return window.active_page === "catalog"; +} + +function isOnThread() { + return window.active_page === "thread"; +} + +function getSetting(key) { + return (localStorage[key] == 'true'); +} + +function initImageHover() { //Pashe, influenced by tux, et al, WTFPL + if (!getSetting("imageHover") && !getSetting("catalogImageHover")) {return;} + + var selectors = []; + + if (getSetting("imageHover")) {selectors.push("img.post-image", "canvas.post-image");} + if (getSetting("catalogImageHover") && isOnCatalog()) { + selectors.push(".thread-image"); + $(".theme-catalog div.thread").css("position", "inherit"); + } + + function bindEvents(el) { + $(el).find(selectors.join(", ")).each(function () { + if ($(this).parent().data("expanded")) {return;} + + var $this = $(this); + + $this.on("mousemove", imageHoverStart); + $this.on("mouseout", imageHoverEnd); + $this.on("click", imageHoverEnd); + }); + } + + bindEvents(document.body); + $(document).on('new_post', function(e, post) { + bindEvents(post); + }); +} + +function imageHoverStart(e) { //Pashe, anonish, WTFPL + var hoverImage = $("#chx_hoverImage"); + + if (hoverImage.length) { + if (getSetting("imageHoverFollowCursor")) { + var scrollTop = $(window).scrollTop(); + var imgY = e.pageY; + var imgTop = imgY; + var windowWidth = $(window).width(); + var imgWidth = hoverImage.width() + e.pageX; + + if (imgY < scrollTop + 15) { + imgTop = scrollTop; + } else if (imgY > scrollTop + $(window).height() - hoverImage.height() - 15) { + imgTop = scrollTop + $(window).height() - hoverImage.height() - 15; + } + + if (imgWidth > windowWidth) { + hoverImage.css({ + 'left': (e.pageX + (windowWidth - imgWidth)), + 'top' : imgTop, + }); + } else { + hoverImage.css({ + 'left': e.pageX, + 'top' : imgTop, + }); + } + + hoverImage.appendTo($("body")); + } + + return; + } + + var $this = $(this); + + var fullUrl; + if ($this.parent().attr("href").match("src")) { + fullUrl = $this.parent().attr("href"); + } else if (isOnCatalog()) { + fullUrl = $this.attr("data-fullimage"); + if (!isImage(getFileExtension(fullUrl))) {fullUrl = $this.attr("src");} + } + + if (isVideo(getFileExtension(fullUrl))) {return;} + + hoverImage = $('<img id="chx_hoverImage" src="'+fullUrl+'" />'); + + if (getSetting("imageHoverFollowCursor")) { + var size = $this.parents('.file').find('.unimportant').text().match(/\b(\d+)x(\d+)\b/), + maxWidth = $(window).width(), + maxHeight = $(window).height(); + + var scale = Math.min(1, maxWidth / size[1], maxHeight / size[2]); + hoverImage.css({ + "position" : "absolute", + "z-index" : 101, + "pointer-events": "none", + "width" : size[1] + "px", + "height" : size[2] + "px", + "max-width" : (size[1] * scale) + "px", + "max-height" : (size[2] * scale) + "px", + 'left' : e.pageX, + 'top' : imgTop, + }); + } else { + hoverImage.css({ + "position" : "fixed", + "top" : 0, + "right" : 0, + "z-index" : 101, + "pointer-events": "none", + "max-width" : "100%", + "max-height" : "100%", + }); + } + hoverImage.appendTo($("body")); + if (isOnThread()) {$this.css("cursor", "none");} +} + +function imageHoverEnd() { //Pashe, WTFPL + $("#chx_hoverImage").remove(); +} + +initImageHover(); +}); +} diff --git a/js/live-index.js b/js/live-index.js index 463f7596..017d0c1f 100644 --- a/js/live-index.js +++ b/js/live-index.js @@ -58,7 +58,7 @@ if (active_page == 'index' && (""+document.location).match(/\/(index\.html)?(\?| update_new_threads(new_threads); }); - }, 1000); + }, 20000); }); $(document).on("new_post", function(e, post) { diff --git a/js/no-animated-gif.js b/js/no-animated-gif.js index 45a55f97..a10a6497 100644 --- a/js/no-animated-gif.js +++ b/js/no-animated-gif.js @@ -57,7 +57,7 @@ if (active_page == 'thread' || active_page == 'index' || active_page == 'ukko' | if (window.Options && Options.get_tab('general')) { selector = '#no-animated-gif>input'; event = 'change'; - Options.extend_tab("general", "<label id='no-animated-gif'><input type='checkbox' /> "+_('Unanimate GIFs')+"</label>"); + Options.extend_tab("general", "<label id='no-animated-gif'><input type='checkbox' />"+_('Unanimate GIFs')+"</label>"); } else { selector = '#no-animated-gif'; diff --git a/js/own-board.js b/js/own-board.js new file mode 100644 index 00000000..497c568c --- /dev/null +++ b/js/own-board.js @@ -0,0 +1,116 @@ +/***************************************************************** + * ------- WARNING! --------- * + ***************************************************************** + * This script is at the current time undocumented and * + * unsupported. It is still a work in progress and will likely * + * change. You are on your own. * + *****************************************************************/ + ++function() { + +var uniq = function(a) { + var b = {}; + var c = []; + a.forEach(function(i) { + if (!b[i]) { + c.push(i); + b[i] = true; + } + }); + return c; +}; + + +if (active_page == 'thread' || active_page == 'index') { + var board = null; + + $(function() { + board = $('input[name="board"]').first().val(); + }); + + $(document).on('ajax_after_post', function(e, r) { + var threads = JSON.parse(localStorage.obthreads || '[]'); + + var thread = null; + if (active_page == 'index') { + thread = r.id|0; + } + else { + thread = $('[id^="thread_"]').first().attr('id').replace("thread_", "")|0; + } + + threads.push([board, thread]); + threads = uniq(threads); + localStorage.obthreads = JSON.stringify(threads); + }); +} + +var loaded = false; +$(function() { + loaded = true; +}); + +var activate = function() { + if (document.location.hash != '#own') return false; + + if (loaded) late_activate(); + else $(function() { late_activate(); }); + + return true; +}; + +var late_activate = function() { + $('[id^="thread_"]').remove(); + + var threads = JSON.parse(localStorage.obthreads || '[]'); + + threads.forEach(function(v) { + var board = v[0]; + var thread = v[1]; + var url = "/"+board+"/res/"+thread+".html"; + + $.get(url, function(html) { + var s = $(html).find('[id^="thread_"]'); + + s[0].bumptime = (new Date(s.find("time").last().attr("datetime"))).getTime(); + + var added = false; + $('[id^="thread_"]').each(function() { + if (added) return; + if (s[0].bumptime > this.bumptime) { + added = true; + s.insertBefore(this); + } + }); + if (!added) { + s.appendTo('[name="postcontrols"]'); + } + + s.find('.post.reply').addClass('hidden').hide().slice(-3).removeClass('hidden').show(); + + s.find('.post.reply.hidden').next().addClass('hidden').hide(); // Hide <br> elements + + var posts_omitted = s.find('.post.reply.hidden').length; + var images_omitted = s.find('.post.reply.hidden img').length; + + if (posts_omitted > 0) { + var omitted = $(fmt('<span class="omitted">'+_('{0} posts and {1} images omitted.')+' '+_('Click reply to view.')+'</span>', + [posts_omitted, images_omitted])); + + omitted.appendTo(s.find('.post.op')); + } + + var reply = $('<a href="'+url+'">['+_('Reply')+']</a>').appendTo(s.find('.intro').first()); + + $(document).trigger('new_post', s[0]); + }); + }); +}; + +$(window).on("hashchange", function() { + return !activate(); +}); +activate(); + + +}(); diff --git a/js/quick-reply.js b/js/quick-reply.js index 07fe4aef..12cca366 100644 --- a/js/quick-reply.js +++ b/js/quick-reply.js @@ -83,11 +83,12 @@ }\ #quick-reply textarea {\ width: 100%;\ + min-width: 100%;\ box-sizing: border-box;\ -webkit-box-sizing:border-box;\ -moz-box-sizing: border-box;\ font-size: 10pt;\ - resize: vertical;\ + resize: vertical horizontal;\ }\ #quick-reply input, #quick-reply select, #quick-reply textarea {\ margin: 0 0 1px 0;\ @@ -115,7 +116,7 @@ #quick-reply td.recaptcha-response {\ padding: 0 0 1px 0;\ }\ - @media screen and (max-width: 800px) {\ + @media screen and (max-width: 400px) {\ #quick-reply {\ display: none !important;\ }\ @@ -363,7 +364,7 @@ $(window).ready(function() { if (settings.get('hide_at_top', true)) { $(window).scroll(function() { - if ($(this).width() <= 800) + if ($(this).width() <= 400) return; if ($(this).scrollTop() < $origPostForm.offset().top + $origPostForm.height() - 100) $postForm.fadeOut(100); @@ -384,7 +385,7 @@ }; $(window).on('cite', function(e, id, with_link) { - if ($(this).width() <= 800) + if ($(this).width() <= 400) return; show_quick_reply(); if (with_link) { @@ -439,7 +440,7 @@ $('.quick-reply-btn').hide(); $(window).scroll(function() { - if ($(this).width() <= 800) + if ($(this).width() <= 400) return; if ($(this).scrollTop() < $('form[name="post"]:first').offset().top + $('form[name="post"]:first').height() - 100) $('.quick-reply-btn').fadeOut(100); diff --git a/js/thread-stats.js b/js/thread-stats.js new file mode 100644 index 00000000..8873dbdb --- /dev/null +++ b/js/thread-stats.js @@ -0,0 +1,116 @@ +/* + * thread-stats.js + * - Adds statistics of the thread below the posts area + * - Shows ID post count beside each postID on hover + * + * Usage: + * $config['additional_javascript'][] = 'js/jquery.min.js'; + * $config['additional_javascript'][] = 'js/thread-stats.js'; + */ +if (active_page == 'thread') { +$(document).ready(function(){ + //check if page uses unique ID + var IDsupport = ($('.poster_id').length > 0); + var thread_id = (document.location.pathname + document.location.search).split('/'); + thread_id = thread_id[thread_id.length -1].split('+')[0].split('-')[0].split('.')[0]; + + $('.boardlist.bottom, footer') + .first() + .before('<div id="thread_stats"></div>'); + var el = $('#thread_stats'); + el.prepend(_('Page')+' <span id="thread_stats_page">?</span>'); + if (IDsupport){ + el.prepend('<span id="thread_stats_uids">0</span> UIDs | '); + } + el.prepend('<span id="thread_stats_images">0</span> '+_('images')+' | '); + el.prepend('<span id="thread_stats_posts">0</span> '+_('replies')+' | '); + delete el; + function update_thread_stats(){ + var op = $('#thread_'+ thread_id +' > div.post.op:not(.post-hover):not(.inline)').first(); + var replies = $('#thread_'+ thread_id +' > div.post.reply:not(.post-hover):not(.inline)'); + // post count + $('#thread_stats_posts').text(replies.length); + // image count + $('#thread_stats_images').text(replies.filter(function(){ + return $(this).find('> .files').text().trim() != false; + }).length); + // unique ID count + if (IDsupport) { + var opID = op.find('> .intro > .poster_id').text(); + var ids = {}; + replies.each(function(){ + var cur = $(this).find('> .intro > .poster_id'); + var curID = cur.text(); + if (ids[curID] === undefined) { + ids[curID] = 0; + } + ids[curID]++; + }); + if (ids[opID] === undefined) { + ids[opID] = 0; + } + ids[opID]++; + var cur = op.find('>.intro >.poster_id'); + cur.find('+.posts_by_id').remove(); + cur.after('<span class="posts_by_id"> ('+ ids[cur.text()] +')</span>'); + replies.each(function(){ + cur = $(this).find('>.intro >.poster_id'); + cur.find('+.posts_by_id').remove(); + cur.after('<span class="posts_by_id"> ('+ ids[cur.text()] +')</span>'); + }); + var size = function(obj) { + var size = 0, key; + for (key in obj) { + if (obj.hasOwnProperty(key)) size++; + } + return size; + }; + $('#thread_stats_uids').text(size(ids)); + } + var board_name = $('input[name="board"]').val(); + $.getJSON('//'+ document.location.host +'/'+ board_name +'/threads.json').success(function(data){ + var found, page = '???'; + for (var i=0;data[i];i++){ + var threads = data[i].threads; + for (var j=0; threads[j]; j++){ + if (parseInt(threads[j].no) == parseInt(thread_id)) { + page = data[i].page +1; + found = true; + break; + } + } + if (found) break; + } + $('#thread_stats_page').text(page); + if (!found) $('#thread_stats_page').css('color','red'); + else $('#thread_stats_page').css('color',''); + }); + } + // load the current page the thread is on. + // uses ajax call so it gets loaded on a delay (depending on network resources available) + var thread_stats_page_timer = setInterval(function(){ + var board_name = $('input[name="board"]').val(); + $.getJSON('//'+ document.location.host +'/'+ board_name +'/threads.json').success(function(data){ + var found, page = '???'; + for (var i=0;data[i];i++){ + var threads = data[i].threads; + for (var j=0; threads[j]; j++){ + if (parseInt(threads[j].no) == parseInt(thread_id)) { + page = data[i].page +1; + found = true; + break; + } + } + if (found) break; + } + $('#thread_stats_page').text(page); + if (!found) $('#thread_stats_page').css('color','red'); + else $('#thread_stats_page').css('color',''); + }); + },30000); + $('body').append('<style>.posts_by_id{display:none;}.poster_id:hover+.posts_by_id{display:initial}</style>'); + update_thread_stats(); + $('#update_thread').click(update_thread_stats); + $(document).on('new_post',update_thread_stats); +}); +} diff --git a/js/toggle-images.js b/js/toggle-images.js index 20940ccf..b8940252 100644 --- a/js/toggle-images.js +++ b/js/toggle-images.js @@ -60,7 +60,7 @@ $(document).ready(function(){ if (window.Options && Options.get_tab('general')) { selector = '#toggle-images>input'; event = 'change'; - Options.extend_tab("general", "<label id='toggle-images'><input type='checkbox' /> "+_('Hide images')+"</label>"); + Options.extend_tab("general", "<label id='toggle-images'><input type='checkbox' />"+_('Hide images')+"</label>"); } else { selector = '#toggle-images a'; diff --git a/js/treeview.js b/js/treeview.js index 78ad620b..1709debb 100644 --- a/js/treeview.js +++ b/js/treeview.js @@ -11,14 +11,28 @@ * */ -if (active_page == 'thread') +if (active_page == 'thread' || active_page == 'ukko' || active_page == 'index') $(function() { - $('hr:first').before('<div id="treeview" style="text-align:right"><a class="unimportant" href="javascript:void(0)"></a></div>'); - $('div#treeview a') - .text(_('Tree view')) - .click(function(e) { - e.preventDefault(); + if (window.Options && Options.get_tab('general')) { + var selector = '#treeview-global>input'; + Options.extend_tab("general", "<label id='treeview-global'><input type='checkbox' /> "+_('Use tree view by default')+"</label>"); + $(selector).on('change', function() { + if (localStorage.treeview === 'true') { + localStorage.treeview = 'false'; + } else { + localStorage.treeview = 'true'; + } + }); + if (localStorage.treeview === 'true') { + $(selector).attr('checked', 'checked'); + } + } +}); +if (active_page == 'thread') +$(function() { + var treeview = function(enable) { + if (enable === true) { $('.post.reply').each(function(){ var references = []; $(this).find('.body a').each(function(){ @@ -26,7 +40,6 @@ $(function() { references.push(parseInt($(this).html().replace('>>', ''))); } }); - var maxref = references.reduce(function(a,b) { return a > b ? a : b; }, 0); var parent_post = $("#reply_"+maxref); @@ -39,7 +52,24 @@ $(function() { post.detach().css("margin-left", margin).insertAfter(parent_post.next()); br.detach().insertAfter(post); - }); - }); + } else { + $('.post.reply').sort(function(a,b) { + return parseInt(a.id.replace('reply_', '')) - parseInt(b.id.replace('reply_', '')); + }).each(function () { + var post = $(this); + var br = post.next(); + post.detach().css('margin-left', '').appendTo('.thread'); + br.detach().insertAfter(post); + }); + } + } + + $('hr:first').before('<div class="unimportant" style="text-align:right"><label for="treeview"><input type="checkbox" id="treeview"> '+_('Tree view')+'</label></div>'); + $('input#treeview').on('change', function(e) { treeview($(this).is(':checked')); }); + + if (localStorage.treeview === 'true') { + treeview(true); + $('input#treeview').attr('checked', true); + } }); diff --git a/js/upload-selection.js b/js/upload-selection.js index e2032748..b342a134 100644 --- a/js/upload-selection.js +++ b/js/upload-selection.js @@ -25,6 +25,7 @@ $(function(){ $("#upload_url").hide(); $("#upload_embed").hide(); $(".add_image").hide(); + $(".dropzone-wrap").hide(); $('[id^=upload_file]').each(function(i, v) { $(v).val(''); @@ -40,6 +41,7 @@ $(function(){ enable_file = function() { disable_all(); $("#upload").show(); + $(".dropzone-wrap").show(); $(".file_separator").show(); $("[id^=upload_file]").show(); $(".add_image").show(); diff --git a/js/wPaint b/js/wPaint -Subproject 2c272dffca0f3d7b7163bd82ba15629f5440927 +Subproject f11220032e7edb8349516d3751d3aaee0fd0de6 diff --git a/js/watch.js b/js/watch.js index a202130f..07c6942a 100644 --- a/js/watch.js +++ b/js/watch.js @@ -98,6 +98,9 @@ $(function(){ else { bc.threads = bc.threads || {}; bc.threads[thread] = Date.now(); + + bc.slugs = bc.slugs || {}; + bc.slugs[thread] = document.location.pathname + document.location.search; } st[board] = bc; storage_save(st); @@ -121,7 +124,7 @@ $(function(){ var tag; if (variant == 'desktop') { - tag = $("<a href='"+modRoot+board+"/res/"+tid+".html'><span>#"+tid+"</span><span class='cb-uri watch-remove'>"+newposts+"</span>"); + tag = $("<a href='"+((storage()[board].slugs && storage()[board].slugs[tid]) || (modRoot+board+"/res/"+tid+".html"))+"'><span>#"+tid+"</span><span class='cb-uri watch-remove'>"+newposts+"</span>"); tag.find(".watch-remove").mouseenter(function() { this.oldval = $(this).html(); $(this).css("min-width", $(this).width()); @@ -132,7 +135,7 @@ $(function(){ }) } else if (variant == 'mobile') { - tag = $("<a href='"+modRoot+board+"/res/"+tid+".html'><span>#"+tid+"</span><span class='cb-uri'>"+newposts+"</span>" + tag = $("<a href='"+((storage()[board].slugs && storage()[board].slugs[tid]) || (modRoot+board+"/res/"+tid+".html"))+"'><span>#"+tid+"</span><span class='cb-uri'>"+newposts+"</span>" +"<span class='cb-uri watch-remove'><i class='fa fa-minus'></i></span>"); } @@ -245,7 +248,7 @@ $(function(){ var st = storage(); var sched = 0; - var sched_diff = 300; + var sched_diff = 2000; for (var i in st) { if (st[i].watched) { diff --git a/js/wpaint.js b/js/wpaint.js index 9c619070..a245a22b 100644 --- a/js/wpaint.js +++ b/js/wpaint.js @@ -13,12 +13,7 @@ * $config['additional_javascript'][] = 'js/jquery.min.js'; * $config['additional_javascript'][] = 'js/jquery-ui.custom.min.js'; * $config['additional_javascript'][] = 'js/ajax.js'; - * $config['additional_javascript'][] = 'js/wPaint/lib/wColorPicker.min.js'; - * $config['additional_javascript'][] = 'js/wPaint/wPaint.min.js'; - * $config['additional_javascript'][] = 'js/wPaint/plugins/main/wPaint.menu.main.min.js'; - * $config['additional_javascript'][] = 'js/wPaint/plugins/text/wPaint.menu.text.min.js'; - * $config['additional_javascript'][] = 'js/wPaint/plugins/shapes/wPaint.menu.main.shapes.min.js'; - * $config['additional_javascript'][] = 'js/wPaint/plugins/file/wPaint.menu.main.file.min.js'; + * $config['additional_javascript'][] = 'js/wPaint/8ch.js'; * $config['additional_javascript'][] = 'js/wpaint.js'; * $config['additional_javascript'][] = 'js/upload-selection.js'; * @@ -49,7 +44,7 @@ oekaki.init = function() { var oekaki_form = '<tr id="oekaki"><th>Oekaki</th><td><div id="wpaintctr"><div id="wpaintdiv"></div></div></td></tr>'; // Add oekaki after the file input - $('form[name="post"]:not(#quick-reply) input[type="file"]').parent().parent().after(oekaki_form); + $('form[name="post"]:not(#quick-reply) [id="upload"]').after(oekaki_form); $('<link class="wpaintcss" rel="stylesheet" href="'+configRoot+'js/wPaint/wPaint.min.css" />').appendTo($("head")); $('<link class="wpaintcss" rel="stylesheet" href="'+configRoot+'js/wPaint/lib/wColorPicker.min.css" />').appendTo($("head")); |
