From 6bc5f5d9be4efd9abf27ee2da05893435d856978 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 8 Mar 2012 01:14:14 +0100 Subject: [PATCH 01/14] Load conf[]s in Main.init. --- 4chan_x.user.js | 18 +++++++++--------- script.coffee | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 2e474b937..d8068d999 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -73,7 +73,7 @@ */ (function() { - var $, $$, Anonymize, AutoGif, DAY, ExpandComment, ExpandThread, Favicon, FileInfo, Filter, GetTitle, HOUR, ImageExpand, ImageHover, Keybinds, MINUTE, Main, NAMESPACE, Nav, Options, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, Redirect, ReplyHiding, ReportButton, RevealSpoilers, SECOND, Sauce, StrikethroughQuotes, ThreadHiding, ThreadStats, Threading, Time, TitlePost, Unread, Updater, VERSION, Watcher, conf, config, d, engine, flatten, g, key, log, qr, ui, val, _base; + var $, $$, Anonymize, AutoGif, DAY, ExpandComment, ExpandThread, Favicon, FileInfo, Filter, GetTitle, HOUR, ImageExpand, ImageHover, Keybinds, MINUTE, Main, NAMESPACE, Nav, Options, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, Redirect, ReplyHiding, ReportButton, RevealSpoilers, SECOND, Sauce, StrikethroughQuotes, ThreadHiding, ThreadStats, Threading, Time, TitlePost, Unread, Updater, VERSION, Watcher, conf, config, d, engine, flatten, g, log, qr, ui, _base; config = { main: { @@ -534,11 +534,6 @@ } }); - for (key in conf) { - val = conf[key]; - conf[key] = $.get(key, val); - } - $$ = function(selector, root) { if (root == null) root = d.body; return Array.prototype.slice.call(root.querySelectorAll(selector)); @@ -972,7 +967,7 @@ return $.on(d, 'keydown', Keybinds.keydown); }, keydown: function(e) { - var o, range, selEnd, selStart, ta, thread, value, _ref, _ref2; + var key, o, range, selEnd, selStart, ta, thread, value, _ref, _ref2; if (!(key = Keybinds.keyCode(e)) || /TEXTAREA|INPUT/.test(e.target.nodeName) && !(e.altKey || e.ctrlKey || e.keyCode === 27)) { return; } @@ -1064,7 +1059,7 @@ return e.preventDefault(); }, keyCode: function(e) { - var c, kc; + var c, kc, key; key = (function() { switch (kc = e.keyCode) { case 8: @@ -2372,6 +2367,7 @@ return g.hiddenReplies = {}; }, keybind: function(e) { + var key; if (e.keyCode === 9) return; e.preventDefault(); e.stopPropagation(); @@ -3837,7 +3833,7 @@ Main = { init: function() { - var cutoff, hiddenThreads, id, now, path, pathname, temp, timestamp, _ref; + var cutoff, hiddenThreads, id, key, now, path, pathname, temp, timestamp, val, _ref; path = location.pathname; pathname = path.slice(1).split('/'); g.BOARD = pathname[0], temp = pathname[1]; @@ -3847,6 +3843,10 @@ } else { g.PAGENUM = parseInt(temp) || 0; } + for (key in conf) { + val = conf[key]; + conf[key] = $.get(key, val); + } $.on(window, 'message', Main.message); switch (location.hostname) { case 'sys.4chan.org': diff --git a/script.coffee b/script.coffee index b6331d37b..b5e9667dc 100644 --- a/script.coffee +++ b/script.coffee @@ -449,10 +449,6 @@ $.extend $, name = NAMESPACE + name localStorage[name] = JSON.stringify value -#load values from localStorage -for key, val of conf - conf[key] = $.get key, val - $$ = (selector, root=d.body) -> Array::slice.call root.querySelectorAll selector @@ -3143,6 +3139,10 @@ Main = else g.PAGENUM = parseInt(temp) or 0 + #load values from localStorage + for key, val of conf + conf[key] = $.get key, val + $.on window, 'message', Main.message switch location.hostname From 29617d64efbd0d7dcc5dde38fb9622bc803121fc Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 8 Mar 2012 01:47:30 +0100 Subject: [PATCH 02/14] Init more features asynchronously. --- 4chan_x.user.js | 72 ++++++++++++++++++++++++++++++++++--------------- script.coffee | 38 +++++++++++++------------- 2 files changed, 70 insertions(+), 40 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index d8068d999..dc2a79c5b 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1258,8 +1258,12 @@ qr = { init: function() { - var form, iframe, link, loadChecking; if (!$.id('recaptcha_challenge_field_holder')) return; + g.callbacks.push(this.node); + return setTimeout(this.asyncInit); + }, + asyncInit: function() { + var form, iframe, link, loadChecking, script; if (conf['Hide Original Post Form']) { link = $.el('h1', { innerHTML: "" + (g.REPLY ? 'Quick Reply' : 'New Thread') + "" @@ -1271,7 +1275,6 @@ form = d.forms[0]; $.before(form, link); } - g.callbacks.push(this.node); if (/chrome/i.test(navigator.userAgent)) { qr.status({ ready: true @@ -1299,19 +1302,14 @@ }); $.add(d.head, iframe); } - setTimeout(function() { - var script; - script = $.el('script', { - textContent: 'Recaptcha.focus_response_field=function(){}' - }); - $.add(d.head, script); - return $.rm(script); + script = $.el('script', { + textContent: 'Recaptcha.focus_response_field=function(){}' }); + $.add(d.head, script); + $.rm(script); if (conf['Persistent QR']) { - setTimeout(function() { - qr.dialog(); - if (conf['Auto Hide QR']) return qr.hide(); - }); + qr.dialog(); + if (conf['Auto Hide QR']) qr.hide(); } $.on(d, 'dragover', qr.dragOver); $.on(d, 'drop', qr.dropFile); @@ -3948,19 +3946,51 @@ Favicon.init(); if (conf['Quick Reply']) qr.init(); if (conf['Image Expansion']) ImageExpand.init(); - if (conf['Thread Watcher']) Watcher.init(); - if (conf['Keybinds']) Keybinds.init(); + if (conf['Thread Watcher']) { + setTimeout(function() { + return Watcher.init(); + }); + } + if (conf['Keybinds']) { + setTimeout(function() { + return Keybinds.init(); + }); + } if (g.REPLY) { - if (conf['Thread Updater']) Updater.init(); + if (conf['Thread Updater']) { + setTimeout(function() { + return Updater.init(); + }); + } if (conf['Thread Stats']) ThreadStats.init(); - if (conf['Reply Navigation']) Nav.init(); + if (conf['Reply Navigation']) { + setTimeout(function() { + return Nav.init(); + }); + } if (conf['Post in Title']) TitlePost.init(); if (conf['Unread Count'] || conf['Unread Favicon']) Unread.init(); } else { - if (conf['Thread Hiding']) ThreadHiding.init(); - if (conf['Thread Expansion']) ExpandThread.init(); - if (conf['Comment Expansion']) ExpandComment.init(); - if (conf['Index Navigation']) Nav.init(); + if (conf['Thread Hiding']) { + setTimeout(function() { + return ThreadHiding.init(); + }); + } + if (conf['Thread Expansion']) { + setTimeout(function() { + return ExpandThread.init(); + }); + } + if (conf['Comment Expansion']) { + setTimeout(function() { + return ExpandComment.init(); + }); + } + if (conf['Index Navigation']) { + setTimeout(function() { + return Nav.init(); + }); + } } nodes = []; _ref2 = $$('.op, a + table', form); diff --git a/script.coffee b/script.coffee index b5e9667dc..c86936f61 100644 --- a/script.coffee +++ b/script.coffee @@ -1031,6 +1031,10 @@ Nav = qr = init: -> return unless $.id 'recaptcha_challenge_field_holder' + g.callbacks.push @node + setTimeout @asyncInit + + asyncInit: -> if conf['Hide Original Post Form'] link = $.el 'h1', innerHTML: "#{if g.REPLY then 'Quick Reply' else 'New Thread'}" $.on $('a', link), 'click', -> @@ -1038,7 +1042,6 @@ qr = $('textarea', qr.el).focus() form = d.forms[0] $.before form, link - g.callbacks.push @node # CORS is ignored for content script on Chrome, but not Safari/Oprah/Firefox. if /chrome/i.test navigator.userAgent @@ -1056,17 +1059,14 @@ qr = $.on iframe, 'load', -> if @src isnt 'about:blank' then setTimeout loadChecking, 500, @ $.add d.head, iframe - # This is extemely slow, execute is asynchronously. - setTimeout -> - # Prevent original captcha input from being focused on reload. - script = $.el 'script', textContent: 'Recaptcha.focus_response_field=function(){}' - $.add d.head, script - $.rm script + # Prevent original captcha input from being focused on reload. + script = $.el 'script', textContent: 'Recaptcha.focus_response_field=function(){}' + $.add d.head, script + $.rm script if conf['Persistent QR'] - setTimeout -> - qr.dialog() - qr.hide() if conf['Auto Hide QR'] + qr.dialog() + qr.hide() if conf['Auto Hide QR'] $.on d, 'dragover', qr.dragOver $.on d, 'drop', qr.dropFile $.on d, 'dragstart', qr.drag @@ -2054,7 +2054,7 @@ ThreadHiding = hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {} for thread in $$ '.thread' op = thread.firstChild - a = $.el 'a', + a = $.el 'a', textContent: '[ - ]' href: 'javascript:;' $.on a, 'click', ThreadHiding.cb.hide @@ -3266,20 +3266,20 @@ Main = ImageExpand.init() if conf['Thread Watcher'] - Watcher.init() + setTimeout -> Watcher.init() if conf['Keybinds'] - Keybinds.init() + setTimeout -> Keybinds.init() if g.REPLY if conf['Thread Updater'] - Updater.init() + setTimeout -> Updater.init() if conf['Thread Stats'] ThreadStats.init() if conf['Reply Navigation'] - Nav.init() + setTimeout -> Nav.init() if conf['Post in Title'] TitlePost.init() @@ -3289,16 +3289,16 @@ Main = else #not reply if conf['Thread Hiding'] - ThreadHiding.init() + setTimeout -> ThreadHiding.init() if conf['Thread Expansion'] - ExpandThread.init() + setTimeout -> ExpandThread.init() if conf['Comment Expansion'] - ExpandComment.init() + setTimeout -> ExpandComment.init() if conf['Index Navigation'] - Nav.init() + setTimeout -> Nav.init() nodes = [] for node in $$ '.op, a + table', form From d7b6b0823a459c83bfb625dbf26f1b5e67037d9d Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 8 Mar 2012 06:29:39 +0100 Subject: [PATCH 03/14] if nodes instanceof Node --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index dc2a79c5b..895678e3d 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -419,7 +419,7 @@ }, nodes: function(nodes) { var frag, node, _i, _len; - if (!(nodes instanceof Array)) return nodes; + if (nodes instanceof Node) return nodes; frag = d.createDocumentFragment(); for (_i = 0, _len = nodes.length; _i < _len; _i++) { node = nodes[_i]; diff --git a/script.coffee b/script.coffee index c86936f61..561bffa68 100644 --- a/script.coffee +++ b/script.coffee @@ -335,7 +335,7 @@ $.extend $, tn: (s) -> d.createTextNode s nodes: (nodes) -> - unless nodes instanceof Array + if nodes instanceof Node return nodes frag = d.createDocumentFragment() for node in nodes From 543caa37d45d6a26aa3ae5e5d07e952f1771eeb9 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 8 Mar 2012 20:14:16 +0100 Subject: [PATCH 04/14] Trim input values before localStoring them. --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 895678e3d..bb3d6d0d3 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -386,7 +386,7 @@ return conf[this.name] = this.checked; }, value: function() { - $.set(this.name, this.value); + $.set(this.name, this.value.trim()); return conf[this.name] = this.value; } }, diff --git a/script.coffee b/script.coffee index 561bffa68..690f4f8af 100644 --- a/script.coffee +++ b/script.coffee @@ -313,7 +313,7 @@ $.extend $, $.set @name, @checked conf[@name] = @checked value: -> - $.set @name, @value + $.set @name, @value.trim() conf[@name] = @value addStyle: (css) -> style = $.el 'style', From e9c7e71e230771bb32e03915d82a2b0d87a4e83c Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Thu, 8 Mar 2012 20:19:48 +0100 Subject: [PATCH 05/14] Display the current version in error alerts. --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index bb3d6d0d3..9f584960a 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -4059,7 +4059,7 @@ } } catch (err) { if (notify) { - alert("4chan X error: " + err.message + "\nhttp://mayhemydg.github.com/4chan-x/#bug-report\n\n" + err.stack); + alert("4chan X (" + VERSION + ") error: " + err.message + "\nhttp://mayhemydg.github.com/4chan-x/#bug-report\n\n" + err.stack); } } } diff --git a/script.coffee b/script.coffee index 690f4f8af..1fab03024 100644 --- a/script.coffee +++ b/script.coffee @@ -3349,7 +3349,7 @@ Main = try callback node for node in nodes catch err - alert "4chan X error: #{err.message}\nhttp://mayhemydg.github.com/4chan-x/#bug-report\n\n#{err.stack}" if notify + alert "4chan X (#{VERSION}) error: #{err.message}\nhttp://mayhemydg.github.com/4chan-x/#bug-report\n\n#{err.stack}" if notify return observer: (mutations) -> nodes = [] From 628ae5d9dbe25b3b09ab918a60943a0b2d10f770 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 10 Mar 2012 18:37:17 +0100 Subject: [PATCH 06/14] ThreadHiding refactor. --- 4chan_x.user.js | 116 ++++++++++++++++++++---------------------------- script.coffee | 98 ++++++++++++++++++---------------------- 2 files changed, 92 insertions(+), 122 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 9f584960a..eefe26c87 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -605,7 +605,7 @@ if (result === true) { if (isOP) { if (!g.REPLY) { - ThreadHiding.hideHide(post.el.parentNode); + ThreadHiding.hide(post.el.parentNode); } else { continue; } @@ -1051,7 +1051,7 @@ Keybinds.hl(-1, thread); break; case conf.hide: - ThreadHiding.toggle(thread); + if (/\bthread\b/.test(thread.className)) ThreadHiding.toggle(thread); break; default: return; @@ -2443,10 +2443,9 @@ ThreadHiding = { init: function() { - var a, hiddenThreads, op, thread, _i, _len, _ref, _results; + var a, hiddenThreads, op, thread, _i, _len, _ref; hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {}); _ref = $$('.thread'); - _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { thread = _ref[_i]; op = thread.firstChild; @@ -2454,83 +2453,62 @@ textContent: '[ - ]', href: 'javascript:;' }); - $.on(a, 'click', ThreadHiding.cb.hide); + $.on(a, 'click', ThreadHiding.cb); $.prepend(op, a); - if (op.id in hiddenThreads) { - _results.push(ThreadHiding.hideHide(thread)); - } else { - _results.push(void 0); - } + if (op.id in hiddenThreads) ThreadHiding.hide(thread); } - return _results; }, - cb: { - hide: function() { - var thread; - thread = this.parentNode.parentNode; - return ThreadHiding.hide(thread); - }, - show: function() { - var thread; - thread = this.parentNode.parentNode; - return ThreadHiding.show(thread); - } + cb: function() { + return ThreadHiding.toggle(this.parentNode.parentNode); }, toggle: function(thread) { - if (/\bstub\b/.test(thread.className) || thread.hidden) { - return ThreadHiding.show(thread); + var hiddenThreads, id; + hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {}); + id = $('.op', thread).id; + if (thread.hidden || /\bstub\b/.test(thread.className)) { + ThreadHiding.show(thread); + delete hiddenThreads[id]; } else { - return ThreadHiding.hide(thread); + ThreadHiding.hide(thread); + hiddenThreads[id] = Date.now(); } + return $.set("hiddenThreads/" + g.BOARD + "/", hiddenThreads); }, hide: function(thread) { - var hiddenThreads, id; - ThreadHiding.hideHide(thread); - id = thread.firstChild.id; - hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {}); - hiddenThreads[id] = Date.now(); - return $.set("hiddenThreads/" + g.BOARD + "/", hiddenThreads); - }, - hideHide: function(thread) { - var a, div, name, num, span, text, trip, uid, _ref, _ref2; - if (conf['Show Stubs']) { - if (/stub/.test(thread.className)) return; - if (span = $('.omittedposts', thread)) { - num = Number(span.textContent.match(/\d+/)[0]); - } else { - num = 0; - } - num += $$('table', thread).length; - text = num === 1 ? "1 reply" : "" + num + " replies"; - name = $('.postername', thread).textContent; - uid = ((_ref = $('.posteruid', thread)) != null ? _ref.textContent : void 0) || ''; - trip = ((_ref2 = $('.postername + .postertrip', thread)) != null ? _ref2.textContent : void 0) || ''; - a = $.el('a', { - innerHTML: "[ + ] " + name + uid + trip + " (" + text + ")", - href: 'javascript:;' - }); - $.on(a, 'click', ThreadHiding.cb.show); - div = $.el('div', { - className: 'block' - }); - $.add(div, a); - $.add(thread, div); - return $.addClass(thread, 'stub'); - } else { + var a, div, name, num, op, span, text, trip, uid, _ref, _ref2; + if (!conf['Show Stubs']) { thread.hidden = true; - return thread.nextSibling.hidden = true; + thread.nextSibling.hidden = true; + return; } + if (/\bstub\b/.test(thread.className)) return; + num = 0; + if (span = $('.omittedposts', thread)) { + num = Number(span.textContent.match(/\d+/)[0]); + } + num += $$('.op ~ table', thread).length; + text = num === 1 ? '1 reply' : "" + num + " replies"; + op = $('.op', thread); + name = $('.postername', op).textContent; + uid = ((_ref = $('.posteruid', op)) != null ? _ref.textContent : void 0) || ''; + trip = ((_ref2 = $('.postertrip', op)) != null ? _ref2.textContent : void 0) || ''; + a = $.el('a', { + innerHTML: "[ + ] " + name + " " + uid + " " + trip + " (" + text + ")", + href: 'javascript:;' + }); + $.on(a, 'click', ThreadHiding.cb); + div = $.el('div', { + className: 'block' + }); + $.add(div, a); + $.prepend(thread, div); + return $.addClass(thread, 'stub'); }, - show: function(thread) { - var hiddenThreads, id; - $.rm($('div.block', thread)); + show: function(thread, id) { + $.rm($('.block', thread)); $.removeClass(thread, 'stub'); thread.hidden = false; - thread.nextSibling.hidden = false; - id = thread.firstChild.id; - hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {}); - delete hiddenThreads[id]; - return $.set("hiddenThreads/" + g.BOARD + "/", hiddenThreads); + return thread.nextSibling.hidden = false; } }; @@ -4097,7 +4075,9 @@ a[href="javascript:;"] {\ text-decoration: none;\ }\ \ -.thread.stub > :not(.block),\ +.block ~ .op,\ +.block ~ .omittedposts,\ +.block ~ table,\ #content > [name=tab]:not(:checked) + div,\ #updater:not(:hover) > :not(.move),\ #qp > input, #qp .inline, .forwarded {\ diff --git a/script.coffee b/script.coffee index 1fab03024..bed6b2131 100644 --- a/script.coffee +++ b/script.coffee @@ -540,7 +540,7 @@ Filter = if result is true if isOP unless g.REPLY - ThreadHiding.hideHide post.el.parentNode + ThreadHiding.hide post.el.parentNode else continue else @@ -888,7 +888,7 @@ Keybinds = when conf.previousReply Keybinds.hl -1, thread when conf.hide - ThreadHiding.toggle thread + ThreadHiding.toggle thread if /\bthread\b/.test thread.className else return e.preventDefault() @@ -2057,75 +2057,63 @@ ThreadHiding = a = $.el 'a', textContent: '[ - ]' href: 'javascript:;' - $.on a, 'click', ThreadHiding.cb.hide + $.on a, 'click', ThreadHiding.cb $.prepend op, a if op.id of hiddenThreads - ThreadHiding.hideHide thread + ThreadHiding.hide thread + return - cb: - hide: -> - thread = @parentNode.parentNode - ThreadHiding.hide thread - show: -> - thread = @parentNode.parentNode - ThreadHiding.show thread + cb: -> + ThreadHiding.toggle @parentNode.parentNode toggle: (thread) -> - if /\bstub\b/.test(thread.className) or thread.hidden + hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {} + id = $('.op', thread).id + if thread.hidden or /\bstub\b/.test thread.className ThreadHiding.show thread + delete hiddenThreads[id] else ThreadHiding.hide thread - - hide: (thread) -> - ThreadHiding.hideHide thread - - id = thread.firstChild.id - - hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {} - hiddenThreads[id] = Date.now() + hiddenThreads[id] = Date.now() $.set "hiddenThreads/#{g.BOARD}/", hiddenThreads - hideHide: (thread) -> - if conf['Show Stubs'] - return if /stub/.test thread.className #already hidden by filter - if span = $ '.omittedposts', thread - num = Number span.textContent.match(/\d+/)[0] - else - num = 0 - num += $$('table', thread).length - text = if num is 1 then "1 reply" else "#{num} replies" - name = $('.postername', thread).textContent - uid = $('.posteruid', thread)?.textContent or '' - trip = $('.postername + .postertrip', thread)?.textContent or '' - - a = $.el 'a', - innerHTML: "[ + ] #{name}#{uid}#{trip} (#{text})" - href: 'javascript:;' - $.on a, 'click', ThreadHiding.cb.show - - div = $.el 'div', - className: 'block' - - $.add div, a - $.add thread, div - $.addClass thread, 'stub' - else + hide: (thread) -> + unless conf['Show Stubs'] thread.hidden = true thread.nextSibling.hidden = true + return - show: (thread) -> - $.rm $ 'div.block', thread + return if /\bstub\b/.test thread.className # already hidden by filter + + num = 0 + if span = $ '.omittedposts', thread + num = Number span.textContent.match(/\d+/)[0] + num += $$('.op ~ table', thread).length + text = if num is 1 then '1 reply' else "#{num} replies" + op = $ '.op', thread + name = $('.postername', op).textContent + uid = $('.posteruid', op)?.textContent or '' + trip = $('.postertrip', op)?.textContent or '' + + a = $.el 'a', + innerHTML: "[ + ] #{name} #{uid} #{trip} (#{text})" + href: 'javascript:;' + $.on a, 'click', ThreadHiding.cb + + div = $.el 'div', + className: 'block' + + $.add div, a + $.prepend thread, div + $.addClass thread, 'stub' + + show: (thread, id) -> + $.rm $ '.block', thread $.removeClass thread, 'stub' thread.hidden = false thread.nextSibling.hidden = false - id = thread.firstChild.id - - hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {} - delete hiddenThreads[id] - $.set "hiddenThreads/#{g.BOARD}/", hiddenThreads - Updater = init: -> html = "
-#{conf['Interval']}
" @@ -3376,7 +3364,9 @@ a[href="javascript:;"] { text-decoration: none; } -.thread.stub > :not(.block), +.block ~ .op, +.block ~ .omittedposts, +.block ~ table, #content > [name=tab]:not(:checked) + div, #updater:not(:hover) > :not(.move), #qp > input, #qp .inline, .forwarded { From dd77d0d89d6075786df6c6562a7582d70e947073 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 10 Mar 2012 20:50:45 +0100 Subject: [PATCH 07/14] ReplyHiding refactor. --- 4chan_x.user.js | 105 +++++++++++++++++++++--------------------------- script.coffee | 87 +++++++++++++++++---------------------- 2 files changed, 81 insertions(+), 111 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index eefe26c87..0da2630bd 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -610,7 +610,7 @@ continue; } } else { - ReplyHiding.hideHide(post.el); + ReplyHiding.hide(post.root); } return; } @@ -883,76 +883,61 @@ ReplyHiding = { init: function() { - this.a = $.el('a', { - textContent: '[ - ]', - href: 'javascript:;' + this.td = $.el('td', { + noWrap: true, + className: 'replyhider', + innerHTML: '[ - ]' }); return g.callbacks.push(this.node); }, node: function(post) { - var a, dd; + var td; if (post["class"]) return; - dd = post.el.previousSibling; - dd.className = 'replyhider'; - a = ReplyHiding.a.cloneNode(true); - $.on(a, 'click', ReplyHiding.cb.hide); - $.replace(dd.firstChild, a); - if (post.id in g.hiddenReplies) return ReplyHiding.hide(post.el); + td = ReplyHiding.td.cloneNode(true); + $.on(td.firstChild, 'click', ReplyHiding.toggle); + $.replace(post.el.previousSibling, td); + if (post.id in g.hiddenReplies) return ReplyHiding.hide(post.root); }, - cb: { - hide: function() { - var reply; - reply = this.parentNode.nextSibling; - return ReplyHiding.hide(reply); - }, - show: function() { - var div, table; - div = this.parentNode; - table = div.nextSibling; - ReplyHiding.show(table); - return $.rm(div); + toggle: function() { + var id, parent, quote, table, _i, _j, _len, _len2, _ref, _ref2; + parent = this.parentNode; + if (parent.className === 'replyhider') { + ReplyHiding.hide(parent.parentNode.parentNode.parentNode); + id = parent.nextSibling.id; + _ref = $$(".quotelink[href='#" + id + "'], .backlink[href='#" + id + "']"); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + quote = _ref[_i]; + $.addClass(quote, 'filtered'); + } + g.hiddenReplies[id] = Date.now(); + } else { + table = parent.nextSibling; + table.hidden = false; + $.rm(parent); + id = table.firstChild.firstChild.lastChild.id; + _ref2 = $$(".quotelink[href='#" + id + "'], .backlink[href='#" + id + "']"); + for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { + quote = _ref2[_j]; + $.removeClass(quote, 'filtered'); + } + delete g.hiddenReplies[id]; } - }, - hide: function(reply) { - var id, quote, _i, _len, _ref; - ReplyHiding.hideHide(reply); - id = reply.id; - _ref = $$(".quotelink[href='#" + id + "'], .backlink[href='#" + id + "']"); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - quote = _ref[_i]; - $.addClass(quote, 'filtered'); - } - g.hiddenReplies[id] = Date.now(); return $.set("hiddenReplies/" + g.BOARD + "/", g.hiddenReplies); }, - hideHide: function(reply) { - var div, name, table, trip, uid, _ref, _ref2; - table = reply.parentNode.parentNode.parentNode; + hide: function(table) { + var div, name, trip, uid, _ref, _ref2; if (table.hidden) return; table.hidden = true; - if (conf['Show Stubs']) { - name = $('.commentpostername', reply).textContent; - uid = ((_ref = $('.posteruid', reply)) != null ? _ref.textContent : void 0) || ''; - trip = ((_ref2 = $('.postertrip', reply)) != null ? _ref2.textContent : void 0) || ''; - div = $.el('div', { - className: 'stub', - innerHTML: "[ + ] " + name + " " + uid + " " + trip + "" - }); - $.on($('a', div), 'click', ReplyHiding.cb.show); - return $.before(table, div); - } - }, - show: function(table) { - var id, quote, _i, _len, _ref; - table.hidden = false; - id = $('td[id]', table).id; - _ref = $$(".quotelink[href='#" + id + "'], .backlink[href='#" + id + "']"); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - quote = _ref[_i]; - $.removeClass(quote, 'filtered'); - } - delete g.hiddenReplies[id]; - return $.set("hiddenReplies/" + g.BOARD + "/", g.hiddenReplies); + if (!conf['Show Stubs']) return; + name = $('td[id] > .commentpostername', table).textContent; + uid = ((_ref = $('td[id] > .posteruid', table)) != null ? _ref.textContent : void 0) || ''; + trip = ((_ref2 = $('td[id] > .postertrip', table)) != null ? _ref2.textContent : void 0) || ''; + div = $.el('div', { + className: 'stub', + innerHTML: "[ + ] " + name + " " + uid + " " + trip + "" + }); + $.on(div.firstChild, 'click', ReplyHiding.toggle); + return $.before(table, div); } }; diff --git a/script.coffee b/script.coffee index bed6b2131..1eb783ebd 100644 --- a/script.coffee +++ b/script.coffee @@ -544,7 +544,7 @@ Filter = else continue else - ReplyHiding.hideHide post.el + ReplyHiding.hide post.root return # Highlight @@ -742,70 +742,55 @@ ExpandThread = ReplyHiding = init: -> - @a = $.el 'a', - textContent: '[ - ]' - href: 'javascript:;' + @td = $.el 'td', + noWrap: true + className: 'replyhider' + innerHTML: '[ - ]' g.callbacks.push @node node: (post) -> return if post.class - dd = post.el.previousSibling - dd.className = 'replyhider' - a = ReplyHiding.a.cloneNode true - $.on a, 'click', ReplyHiding.cb.hide - $.replace dd.firstChild, a + td = ReplyHiding.td.cloneNode true + $.on td.firstChild, 'click', ReplyHiding.toggle + $.replace post.el.previousSibling, td if post.id of g.hiddenReplies - ReplyHiding.hide post.el + ReplyHiding.hide post.root - cb: - hide: -> - reply = @parentNode.nextSibling - ReplyHiding.hide reply - - show: -> - div = @parentNode - table = div.nextSibling - ReplyHiding.show table - - $.rm div - - hide: (reply) -> - ReplyHiding.hideHide reply - - id = reply.id - for quote in $$ ".quotelink[href='##{id}'], .backlink[href='##{id}']" - $.addClass quote, 'filtered' - - g.hiddenReplies[id] = Date.now() + toggle: -> + parent = @parentNode + if parent.className is 'replyhider' + ReplyHiding.hide parent.parentNode.parentNode.parentNode + id = parent.nextSibling.id + for quote in $$ ".quotelink[href='##{id}'], .backlink[href='##{id}']" + $.addClass quote, 'filtered' + g.hiddenReplies[id] = Date.now() + else + table = parent.nextSibling + table.hidden = false + $.rm parent + id = table.firstChild.firstChild.lastChild.id + for quote in $$ ".quotelink[href='##{id}'], .backlink[href='##{id}']" + $.removeClass quote, 'filtered' + delete g.hiddenReplies[id] $.set "hiddenReplies/#{g.BOARD}/", g.hiddenReplies - hideHide: (reply) -> - table = reply.parentNode.parentNode.parentNode - return if table.hidden #already hidden by filter + hide: (table) -> + return if table.hidden # already hidden by filter table.hidden = true - if conf['Show Stubs'] - name = $('.commentpostername', reply).textContent - uid = $('.posteruid', reply)?.textContent or '' - trip = $('.postertrip', reply)?.textContent or '' + return unless conf['Show Stubs'] - div = $.el 'div', - className: 'stub' - innerHTML: "[ + ] #{name} #{uid} #{trip}" - $.on $('a', div), 'click', ReplyHiding.cb.show - $.before table, div + name = $('td[id] > .commentpostername', table).textContent + uid = $('td[id] > .posteruid', table)?.textContent or '' + trip = $('td[id] > .postertrip', table)?.textContent or '' - show: (table) -> - table.hidden = false - - id = $('td[id]', table).id - for quote in $$ ".quotelink[href='##{id}'], .backlink[href='##{id}']" - $.removeClass quote, 'filtered' - - delete g.hiddenReplies[id] - $.set "hiddenReplies/#{g.BOARD}/", g.hiddenReplies + div = $.el 'div', + className: 'stub' + innerHTML: "[ + ] #{name} #{uid} #{trip}" + $.on div.firstChild, 'click', ReplyHiding.toggle + $.before table, div Keybinds = init: -> From 8ed8309b3129e3c8a8cfc62118647d0f38b947e5 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Mar 2012 04:10:42 +0100 Subject: [PATCH 08/14] Slight Comment Expansion optimization. Sup @aeosynth. --- 4chan_x.user.js | 24 ++++++------------------ script.coffee | 18 +++++++----------- 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 0da2630bd..b09bcb83a 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -736,29 +736,17 @@ })); }, parse: function(req, a, threadID, replyID) { - var body, bq, post, quote, quotes, reply, _i, _j, _len, _len2, _ref; + var bq, doc, post, quote, quotes, _i, _len; if (req.status !== 200) { a.textContent = "" + req.status + " " + req.statusText; return; } - body = $.el('body', { - innerHTML: req.responseText - }); - if (threadID === replyID) { - bq = $('blockquote', body); - } else { - _ref = $$('td[id]', body); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - reply = _ref[_i]; - if (reply.id === replyID) { - bq = $('blockquote', reply); - break; - } - } - } + doc = d.implementation.createHTMLDocument(); + doc.documentElement.innerHTML = req.responseText; + bq = threadID === replyID ? $('blockquote', doc) : $('blockquote', doc.getElementById(replyID)); quotes = $$('.quotelink', bq); - for (_j = 0, _len2 = quotes.length; _j < _len2; _j++) { - quote = quotes[_j]; + for (_i = 0, _len = quotes.length; _i < _len; _i++) { + quote = quotes[_i]; if (quote.getAttribute('href') === quote.hash) { quote.pathname = "/" + g.BOARD + "/res/" + threadID; } diff --git a/script.coffee b/script.coffee index 1eb783ebd..dbf281d2c 100644 --- a/script.coffee +++ b/script.coffee @@ -637,18 +637,14 @@ ExpandComment = a.textContent = "#{req.status} #{req.statusText}" return - body = $.el 'body', - innerHTML: req.responseText + doc = d.implementation.createHTMLDocument() + doc.documentElement.innerHTML = req.responseText - if threadID is replyID #OP - bq = $ 'blockquote', body - else - #css selectors don't like ids starting with numbers, - # getElementById only works for root document. - for reply in $$ 'td[id]', body - if reply.id == replyID - bq = $ 'blockquote', reply - break + bq = + if threadID is replyID # OP + $ 'blockquote', doc + else + $ 'blockquote', doc.getElementById replyID quotes = $$ '.quotelink', bq for quote in quotes if quote.getAttribute('href') is quote.hash From 8514eae04661e7d3ef1b6c7393e64e95380898d4 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Mar 2012 05:13:04 +0100 Subject: [PATCH 09/14] Links in a locationless document have their hash, and probably more, values empty. Also shave some lines. --- 4chan_x.user.js | 20 ++++++++------------ script.coffee | 14 +++++--------- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index b09bcb83a..4d3d908b8 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -744,6 +744,7 @@ doc = d.implementation.createHTMLDocument(); doc.documentElement.innerHTML = req.responseText; bq = threadID === replyID ? $('blockquote', doc) : $('blockquote', doc.getElementById(replyID)); + $.replace(a.parentNode.parentNode, bq); quotes = $$('.quotelink', bq); for (_i = 0, _len = quotes.length; _i < _len; _i++) { quote = quotes[_i]; @@ -751,7 +752,6 @@ quote.pathname = "/" + g.BOARD + "/res/" + threadID; } } - $.replace(a.parentNode.parentNode, bq); post = { threadId: threadID, quotes: quotes, @@ -2559,7 +2559,7 @@ }; }, update: function() { - var body, id, newPosts, nodes, reply, scroll, _i, _len, _ref, _ref2; + var body, id, newPosts, nodes, reply, scroll, _i, _len, _ref; if (this.status === 404) { Updater.timer.textContent = ''; Updater.count.textContent = 404; @@ -2598,23 +2598,19 @@ body = $.el('body', { innerHTML: this.responseText }); - id = ((_ref = $('td[id]', Updater.br.previousElementSibling)) != null ? _ref.id : void 0) || 0; + id = $('input', Updater.br.previousElementSibling).name; nodes = []; - _ref2 = $$('.reply', body).reverse(); - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - reply = _ref2[_i]; + _ref = $$('.reply', body).reverse(); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + reply = _ref[_i]; if (reply.id <= id) break; nodes.push(reply.parentNode.parentNode.parentNode); } newPosts = nodes.length; scroll = conf['Scrolling'] && Updater.scrollBG() && newPosts && Updater.br.previousElementSibling.getBoundingClientRect().bottom - d.body.clientHeight < 25; if (conf['Verbose']) { - Updater.count.textContent = '+' + newPosts; - if (newPosts === 0) { - Updater.count.className = null; - } else { - Updater.count.className = 'new'; - } + Updater.count.textContent = "+" + newPosts; + Updater.count.className = newPosts ? 'new' : null; } $.before(Updater.br, nodes.reverse()); if (scroll) return Updater.br.previousSibling.scrollIntoView(); diff --git a/script.coffee b/script.coffee index dbf281d2c..bfedb48e7 100644 --- a/script.coffee +++ b/script.coffee @@ -645,11 +645,11 @@ ExpandComment = $ 'blockquote', doc else $ 'blockquote', doc.getElementById replyID + $.replace a.parentNode.parentNode, bq quotes = $$ '.quotelink', bq for quote in quotes if quote.getAttribute('href') is quote.hash quote.pathname = "/#{g.BOARD}/res/#{threadID}" - $.replace a.parentNode.parentNode, bq post = threadId: threadID quotes: quotes @@ -2198,22 +2198,18 @@ Updater = body = $.el 'body', innerHTML: @responseText - id = $('td[id]', Updater.br.previousElementSibling)?.id or 0 + id = $('input', Updater.br.previousElementSibling).name nodes = [] for reply in $$('.reply', body).reverse() - if reply.id <= id #make sure to not insert older posts - break + break if reply.id <= id #make sure to not insert older posts nodes.push reply.parentNode.parentNode.parentNode #table newPosts = nodes.length scroll = conf['Scrolling'] && Updater.scrollBG() && newPosts && Updater.br.previousElementSibling.getBoundingClientRect().bottom - d.body.clientHeight < 25 if conf['Verbose'] - Updater.count.textContent = '+' + newPosts - if newPosts is 0 - Updater.count.className = null - else - Updater.count.className = 'new' + Updater.count.textContent = "+#{newPosts}" + Updater.count.className = if newPosts then 'new' else null $.before Updater.br, nodes.reverse() if scroll From 4db82feca59adb72104376049b465c641a349add Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Mar 2012 05:51:30 +0100 Subject: [PATCH 10/14] Use document.implementation.createHTMLDocument() for Quote Inlining and Quote Previewing too. --- 4chan_x.user.js | 54 +++++++++++++------------------------------------ script.coffee | 44 ++++++++++++++++++---------------------- 2 files changed, 34 insertions(+), 64 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 4d3d908b8..35c8c83f4 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -3186,32 +3186,19 @@ } }, parse: function(req, pathname, id, threadID, inline) { - var body, href, html, link, newInline, op, quote, reply, _i, _j, _len, _len2, _ref, _ref2; + var doc, href, link, newInline, node, quote, _i, _len, _ref; if (!inline.parentNode) return; if (req.status !== 200) { inline.textContent = "" + req.status + " " + req.statusText; return; } - body = $.el('body', { - innerHTML: req.responseText - }); - if (id === threadID) { - op = Threading.op($('body > form', body).firstChild); - html = op.innerHTML; - } else { - _ref = $$('.reply', body); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - reply = _ref[_i]; - if (reply.id === id) { - html = reply.innerHTML; - break; - } - } - } - newInline = QuoteInline.table(id, html); - _ref2 = $$('.quotelink', newInline); - for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { - quote = _ref2[_j]; + doc = d.implementation.createHTMLDocument(); + doc.documentElement.innerHTML = req.responseText; + node = id === threadID ? Threading.op($('body > form', doc).firstChild) : doc.getElementById(id); + newInline = QuoteInline.table(id, node.innerHTML); + _ref = $$('.quotelink', newInline); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + quote = _ref[_i]; if ((href = quote.getAttribute('href')) === quote.hash) { quote.pathname = pathname; } else if (!g.REPLY && href !== quote.href) { @@ -3291,29 +3278,16 @@ return $.off(this, 'click', QuotePreview.mouseout); }, parse: function(req, id, threadID) { - var body, html, op, post, qp, reply, _i, _len, _ref; - if (!((qp = ui.el) && (qp.innerHTML === ("Loading " + id + "...")))) return; + var doc, node, post, qp; + if (!((qp = ui.el) && qp.innerHTML === ("Loading " + id + "..."))) return; if (req.status !== 200) { qp.textContent = "" + req.status + " " + req.statusText; return; } - body = $.el('body', { - innerHTML: req.responseText - }); - if (id === threadID) { - op = Threading.op($('body > form', body).firstChild); - html = op.innerHTML; - } else { - _ref = $$('.reply', body); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - reply = _ref[_i]; - if (reply.id === id) { - html = reply.innerHTML; - break; - } - } - } - qp.innerHTML = html; + doc = d.implementation.createHTMLDocument(); + doc.documentElement.innerHTML = req.responseText; + node = id === threadID ? Threading.op($('body > form', doc).firstChild) : doc.getElementById(id); + qp.innerHTML = node.innerHTML; post = { root: qp, filesize: $('.filesize', qp), diff --git a/script.coffee b/script.coffee index bfedb48e7..1208092db 100644 --- a/script.coffee +++ b/script.coffee @@ -2646,19 +2646,17 @@ QuoteInline = inline.textContent = "#{req.status} #{req.statusText}" return - body = $.el 'body', - innerHTML: req.responseText - if id is threadID #OP - op = Threading.op $('body > form', body).firstChild - html = op.innerHTML - else - for reply in $$ '.reply', body - if reply.id == id - html = reply.innerHTML - break - newInline = QuoteInline.table id, html + doc = d.implementation.createHTMLDocument() + doc.documentElement.innerHTML = req.responseText + + node = + if id is threadID #OP + Threading.op $('body > form', doc).firstChild + else + doc.getElementById id + newInline = QuoteInline.table id, node.innerHTML for quote in $$ '.quotelink', newInline - if (href = quote.getAttribute('href')) is quote.hash #add pathname to normal quotes + if (href = quote.getAttribute 'href') is quote.hash #add pathname to normal quotes quote.pathname = pathname else if !g.REPLY and href isnt quote.href #fix x-thread links, not x-board ones quote.href = "res/#{href}" @@ -2714,23 +2712,21 @@ QuotePreview = $.off @, 'mouseout', QuotePreview.mouseout $.off @, 'click', QuotePreview.mouseout parse: (req, id, threadID) -> - return unless (qp = ui.el) and (qp.innerHTML is "Loading #{id}...") + return unless (qp = ui.el) and qp.innerHTML is "Loading #{id}..." if req.status isnt 200 qp.textContent = "#{req.status} #{req.statusText}" return - body = $.el 'body', - innerHTML: req.responseText - if id is threadID #OP - op = Threading.op $('body > form', body).firstChild - html = op.innerHTML - else - for reply in $$ '.reply', body - if reply.id == id - html = reply.innerHTML - break - qp.innerHTML = html + doc = d.implementation.createHTMLDocument() + doc.documentElement.innerHTML = req.responseText + + node = + if id is threadID #OP + Threading.op $('body > form', doc).firstChild + else + doc.getElementById id + qp.innerHTML = node.innerHTML post = root: qp filesize: $ '.filesize', qp From 42377c69cdb48e30d9c1863a6b237fdf046ec2f6 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Mar 2012 06:03:59 +0100 Subject: [PATCH 11/14] Don't add a class to hidden threads with stubs. This will slightly improve performance for thread id perparsing on board pages. --- 4chan_x.user.js | 12 +++++------- script.coffee | 10 ++++------ 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 35c8c83f4..24061e539 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -2438,7 +2438,7 @@ var hiddenThreads, id; hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {}); id = $('.op', thread).id; - if (thread.hidden || /\bstub\b/.test(thread.className)) { + if (thread.hidden || thread.firstChild.className === 'block') { ThreadHiding.show(thread); delete hiddenThreads[id]; } else { @@ -2454,7 +2454,7 @@ thread.nextSibling.hidden = true; return; } - if (/\bstub\b/.test(thread.className)) return; + if (thread.firstChild.className === 'block') return; num = 0; if (span = $('.omittedposts', thread)) { num = Number(span.textContent.match(/\d+/)[0]); @@ -2474,12 +2474,10 @@ className: 'block' }); $.add(div, a); - $.prepend(thread, div); - return $.addClass(thread, 'stub'); + return $.prepend(thread, div); }, show: function(thread, id) { $.rm($('.block', thread)); - $.removeClass(thread, 'stub'); thread.hidden = false; return thread.nextSibling.hidden = false; } @@ -3279,7 +3277,7 @@ }, parse: function(req, id, threadID) { var doc, node, post, qp; - if (!((qp = ui.el) && qp.innerHTML === ("Loading " + id + "..."))) return; + if (!((qp = ui.el) && qp.textContent === ("Loading " + id + "..."))) return; if (req.status !== 200) { qp.textContent = "" + req.status + " " + req.statusText; return; @@ -3958,7 +3956,7 @@ el: klass === 'op' ? node : node.firstChild.firstChild.lastChild, "class": klass, id: node.getElementsByTagName('input')[0].name, - threadId: g.THREAD_ID || $.x('ancestor::div[contains(@class,"thread")]', node).firstChild.id, + threadId: g.THREAD_ID || $.x('ancestor::div[@class="thread"]', node).firstChild.id, isOP: klass === 'op', isInlined: /\binline\b/.test(klass), filesize: node.getElementsByClassName('filesize')[0] || false, diff --git a/script.coffee b/script.coffee index 1208092db..208ff1263 100644 --- a/script.coffee +++ b/script.coffee @@ -2051,7 +2051,7 @@ ThreadHiding = toggle: (thread) -> hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {} id = $('.op', thread).id - if thread.hidden or /\bstub\b/.test thread.className + if thread.hidden or thread.firstChild.className is 'block' ThreadHiding.show thread delete hiddenThreads[id] else @@ -2065,7 +2065,7 @@ ThreadHiding = thread.nextSibling.hidden = true return - return if /\bstub\b/.test thread.className # already hidden by filter + return if thread.firstChild.className is 'block' # already hidden by filter num = 0 if span = $ '.omittedposts', thread @@ -2087,11 +2087,9 @@ ThreadHiding = $.add div, a $.prepend thread, div - $.addClass thread, 'stub' show: (thread, id) -> $.rm $ '.block', thread - $.removeClass thread, 'stub' thread.hidden = false thread.nextSibling.hidden = false @@ -2712,7 +2710,7 @@ QuotePreview = $.off @, 'mouseout', QuotePreview.mouseout $.off @, 'click', QuotePreview.mouseout parse: (req, id, threadID) -> - return unless (qp = ui.el) and qp.innerHTML is "Loading #{id}..." + return unless (qp = ui.el) and qp.textContent is "Loading #{id}..." if req.status isnt 200 qp.textContent = "#{req.status} #{req.statusText}" @@ -3297,7 +3295,7 @@ Main = el: if klass is 'op' then node else node.firstChild.firstChild.lastChild class: klass id: node.getElementsByTagName('input')[0].name - threadId: g.THREAD_ID or $.x('ancestor::div[contains(@class,"thread")]', node).firstChild.id + threadId: g.THREAD_ID or $.x('ancestor::div[@class="thread"]', node).firstChild.id isOP: klass is 'op' isInlined: /\binline\b/.test klass filesize: node.getElementsByClassName('filesize')[0] or false From 9ce3679a2e21d9a321fd867a90a5b973af519b45 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Mar 2012 13:56:57 +0100 Subject: [PATCH 12/14] Firefox needlessly requires an argument for document.implementation.createHTMLDocument. --- 4chan_x.user.js | 6 +++--- script.coffee | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 24061e539..0898eab0c 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -741,7 +741,7 @@ a.textContent = "" + req.status + " " + req.statusText; return; } - doc = d.implementation.createHTMLDocument(); + doc = d.implementation.createHTMLDocument(null); doc.documentElement.innerHTML = req.responseText; bq = threadID === replyID ? $('blockquote', doc) : $('blockquote', doc.getElementById(replyID)); $.replace(a.parentNode.parentNode, bq); @@ -3190,7 +3190,7 @@ inline.textContent = "" + req.status + " " + req.statusText; return; } - doc = d.implementation.createHTMLDocument(); + doc = d.implementation.createHTMLDocument(null); doc.documentElement.innerHTML = req.responseText; node = id === threadID ? Threading.op($('body > form', doc).firstChild) : doc.getElementById(id); newInline = QuoteInline.table(id, node.innerHTML); @@ -3282,7 +3282,7 @@ qp.textContent = "" + req.status + " " + req.statusText; return; } - doc = d.implementation.createHTMLDocument(); + doc = d.implementation.createHTMLDocument(null); doc.documentElement.innerHTML = req.responseText; node = id === threadID ? Threading.op($('body > form', doc).firstChild) : doc.getElementById(id); qp.innerHTML = node.innerHTML; diff --git a/script.coffee b/script.coffee index 208ff1263..84eb0dffa 100644 --- a/script.coffee +++ b/script.coffee @@ -637,7 +637,7 @@ ExpandComment = a.textContent = "#{req.status} #{req.statusText}" return - doc = d.implementation.createHTMLDocument() + doc = d.implementation.createHTMLDocument null doc.documentElement.innerHTML = req.responseText bq = @@ -2644,7 +2644,7 @@ QuoteInline = inline.textContent = "#{req.status} #{req.statusText}" return - doc = d.implementation.createHTMLDocument() + doc = d.implementation.createHTMLDocument null doc.documentElement.innerHTML = req.responseText node = @@ -2716,7 +2716,7 @@ QuotePreview = qp.textContent = "#{req.status} #{req.statusText}" return - doc = d.implementation.createHTMLDocument() + doc = d.implementation.createHTMLDocument null doc.documentElement.innerHTML = req.responseText node = From b40a79a9f4e2ea30fea17cfa18edf721d5d1c224 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Mar 2012 14:52:59 +0100 Subject: [PATCH 13/14] Use ReplyHiding when Recursively Filtering. This will add stubs when the option is enabled. --- 4chan_x.user.js | 2 +- script.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 0898eab0c..1282af981 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -709,7 +709,7 @@ quote = _ref[_i]; if ((el = $.id(quote.hash.slice(1))) && el.parentNode.parentNode.parentNode.hidden) { $.addClass(quote, 'filtered'); - if (conf['Recursive Filtering']) post.root.hidden = true; + if (conf['Recursive Filtering']) ReplyHiding.hide(post.root); } } } diff --git a/script.coffee b/script.coffee index 84eb0dffa..068fee957 100644 --- a/script.coffee +++ b/script.coffee @@ -617,7 +617,7 @@ StrikethroughQuotes = for quote in post.quotes if (el = $.id quote.hash[1..]) and el.parentNode.parentNode.parentNode.hidden $.addClass quote, 'filtered' - post.root.hidden = true if conf['Recursive Filtering'] + ReplyHiding.hide post.root if conf['Recursive Filtering'] return ExpandComment = From 97bc32eefabe21b3f74e87d78ea2978ca7904675 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sun, 11 Mar 2012 17:28:08 +0100 Subject: [PATCH 14/14] Clicking on 'New Thread' should select 'New thread' in the QR's thread list. --- 4chan_x.user.js | 1 + script.coffee | 1 + 2 files changed, 2 insertions(+) diff --git a/4chan_x.user.js b/4chan_x.user.js index 1282af981..04347bb19 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1243,6 +1243,7 @@ }); $.on($('a', link), 'click', function() { qr.open(); + if (!g.REPLY) $('select', qr.el).value = 'new'; return $('textarea', qr.el).focus(); }); form = d.forms[0]; diff --git a/script.coffee b/script.coffee index 068fee957..f86540347 100644 --- a/script.coffee +++ b/script.coffee @@ -1020,6 +1020,7 @@ qr = link = $.el 'h1', innerHTML: "#{if g.REPLY then 'Quick Reply' else 'New Thread'}" $.on $('a', link), 'click', -> qr.open() + $('select', qr.el).value = 'new' unless g.REPLY $('textarea', qr.el).focus() form = d.forms[0] $.before form, link