diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 00e4422d2..0f8fb21f4 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1996,7 +1996,7 @@ } }, postFromNode: function(root) { - return Get.postFromRoot($.x('ancestor::div[contains(@class,"postContainer")][1]', root)); + return Get.postFromRoot($.x('(ancestor::div[contains(@class,"postContainer")]|following::div[contains(@class,"postContainer")])', root)); }, contextFromNode: function(quotelink) { return Get.postFromRoot($.x('ancestor::div[parent::div[@class="thread"]][1]', quotelink)); @@ -3225,15 +3225,11 @@ var post; post = Get.postFromNode(this); - if (post.isHidden) { - PostHiding.show(post); - } else { - PostHiding.hide(post); - } + PostHiding[(post.isHidden ? 'show' : 'hide')](post); return PostHiding.saveHiddenState(post, post.isHidden); }, hide: function(post, makeStub, hideRecursively) { - var a, postInfo, quotelink, _i, _len, _ref; + var a, button, postInfo, quotelink, _i, _len, _ref; if (makeStub == null) { makeStub = Conf['Stubs']; @@ -3259,15 +3255,12 @@ return; } a = PostHiding.makeButton(post, 'show'); - postInfo = Conf['Anonymize'] ? 'Anonymous' : $('.nameBlock', post.nodes.info).textContent; + postInfo = Conf['Anonymize'] ? 'Anonymous' : post.info.name; $.add(a, $.tn(" " + postInfo)); post.nodes.stub = $.el('div', { className: 'stub' }); - $.add(post.nodes.stub, a); - if (Conf['Menu']) { - $.add(post.nodes.stub, [$.tn(' '), Menu.makeButton(post)]); - } + $.add(post.nodes.stub, !Conf['Menu'] ? a : [a, $.tn(' '), button = Menu.makeButton(post)]); return $.prepend(post.nodes.root, post.nodes.stub); }, show: function(post, showRecursively) { @@ -3462,11 +3455,6 @@ makeStub = $.el('label', { innerHTML: " Make stub" }); - hideStubLink = $.el('a', { - textContent: 'Hide stub', - href: 'javascript:;' - }); - $.on(hideStubLink, 'click', ThreadHiding.menu.hideStub); $.event('AddMenuEntry', { type: 'post', el: div, @@ -3489,6 +3477,34 @@ } ] }); + div = $.el('a', { + className: 'show-thread-link', + textContent: 'Show thread', + href: 'javascript:;' + }); + $.on(show, 'click', ThreadHiding.menu.show); + $.event('AddMenuEntry', { + type: 'post' + }); + ({ + el: div, + order: 20, + open: function(_arg) { + var isReply, thread; + + thread = _arg.thread, isReply = _arg.isReply; + if (isReply || !thread.isHidden) { + return false; + } + ThreadHiding.menu.thread = thread; + return true; + } + }); + hideStubLink = $.el('a', { + textContent: 'Hide stub', + href: 'javascript:;' + }); + $.on(hideStubLink, 'click', ThreadHiding.menu.hideStub); return $.event('AddMenuEntry', { type: 'post', el: hideStubLink, @@ -3513,6 +3529,14 @@ ThreadHiding.saveHiddenState(thread, makeStub); return $.event('CloseMenu'); }, + show: function() { + var thread; + + thread = ThreadHiding.menu.thread; + ThreadHiding.show(thread); + ThreadHiding.saveHiddenState(thread); + return $.event('CloseMenu'); + }, hideStub: function() { var thread; @@ -3567,7 +3591,7 @@ return ThreadHiding.saveHiddenState(thread); }, hide: function(thread, makeStub) { - var OP, a, numReplies, opInfo, span, threadRoot; + var OP, a, button, numReplies, opInfo, span, threadRoot; if (makeStub == null) { makeStub = Conf['Stubs']; @@ -3579,22 +3603,15 @@ threadRoot.hidden = threadRoot.nextElementSibling.hidden = true; return; } - numReplies = 0; - if (span = $('.summary', threadRoot)) { - numReplies = +span.textContent.match(/\d+/); - } - numReplies += $$('.opContainer ~ .replyContainer', threadRoot).length; - numReplies = numReplies === 1 ? '1 reply' : "" + numReplies + " replies"; - opInfo = Conf['Anonymize'] ? 'Anonymous' : $('.nameBlock', OP.nodes.info).textContent; + numReplies = ((span = $('.summary', threadRoot)) ? +span.textContent.match(/\d+/) : 0) + $$('.opContainer ~ .replyContainer', threadRoot).length; + numReplies = numReplies === 1 ? '1 reply' : "" + (numReplies || 'No') + " replies"; + opInfo = Conf['Anonymize'] ? 'Anonymous' : OP.info.name; a = ThreadHiding.makeButton(thread, 'show'); $.add(a, $.tn(" " + opInfo + " (" + numReplies + ")")); thread.stub = $.el('div', { className: 'stub' }); - $.add(thread.stub, a); - if (Conf['Menu']) { - $.add(thread.stub, [$.tn(' '), Menu.makeButton(OP)]); - } + $.add(thread.stub, !Conf['Menu'] ? a : [a, $.tn(' '), button = Menu.makeButton(OP)]); return $.prepend(threadRoot, thread.stub); }, show: function(thread) { @@ -4203,7 +4220,9 @@ seek: function(type) { var post, posts, result, str; - return unlses(Conf['Mark Quotes of You'] && Conf['Quick Reply']); + if (!(Conf['Mark Quotes of You'] && Conf['Quick Reply'])) { + return; + } $.rmClass($('.highlight'), 'highlight'); if (!QuoteYou.lastRead) { if (!(post = QuoteYou.lastRead = $('.quotesYou'))) { @@ -6993,45 +7012,48 @@ } }; - Menu = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['Menu']) { - return; - } - this.menu = new UI.Menu('post'); - return Post.prototype.callbacks.push({ - name: 'Menu', - cb: this.node - }); - }, - node: function() { - var button; + Menu = (function() { + var a; - if (this.isClone) { - button = $('.menu-button', this.nodes.info); - } else { - button = Menu.makeButton(this); - $.add(this.nodes.info, [$.tn('\u00A0'), button]); - } - return $.on(button, 'click', Menu.toggle); - }, - makeButton: (function() { - var a; + a = $.el('a', { + className: 'menu-button brackets-wrap', + innerHTML: '', + href: 'javascript:;' + }); + return { + init: function() { + if (g.VIEW === 'catalog' || !Conf['Menu']) { + return; + } + this.menu = new UI.Menu('post'); + return Post.prototype.callbacks.push({ + name: 'Menu', + cb: this.node + }); + }, + node: function() { + var button; - a = null; - return function() { - a || (a = $.el('a', { - className: 'menu-button fourchanx-link', - innerHTML: '', - href: 'javascript:;' - })); - return a.cloneNode(true); - }; - })(), - toggle: function(e) { - return Menu.menu.toggle(e, this, Get.postFromNode(this)); - } - }; + if (this.isClone) { + button = $('.menu-button', this.nodes.info); + } else { + button = a.cloneNode(true); + $.add(this.nodes.info, [$.tn('\u00A0'), button]); + } + return $.on(button, 'click', Menu.toggle); + }, + makeButton: function() { + var el; + + el = a.cloneNode(true); + $.on(el, 'click', Menu.toggle); + return el; + }, + toggle: function(e) { + return Menu.menu.toggle(e, this, Get.postFromNode(this)); + } + }; + })(); ReportLink = { init: function() { diff --git a/builds/crx/script.js b/builds/crx/script.js index 111dc57fc..cd6c5b4cd 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -2008,7 +2008,7 @@ } }, postFromNode: function(root) { - return Get.postFromRoot($.x('ancestor::div[contains(@class,"postContainer")][1]', root)); + return Get.postFromRoot($.x('(ancestor::div[contains(@class,"postContainer")]|following::div[contains(@class,"postContainer")])', root)); }, contextFromNode: function(quotelink) { return Get.postFromRoot($.x('ancestor::div[parent::div[@class="thread"]][1]', quotelink)); @@ -3230,15 +3230,11 @@ var post; post = Get.postFromNode(this); - if (post.isHidden) { - PostHiding.show(post); - } else { - PostHiding.hide(post); - } + PostHiding[(post.isHidden ? 'show' : 'hide')](post); return PostHiding.saveHiddenState(post, post.isHidden); }, hide: function(post, makeStub, hideRecursively) { - var a, postInfo, quotelink, _i, _len, _ref; + var a, button, postInfo, quotelink, _i, _len, _ref; if (makeStub == null) { makeStub = Conf['Stubs']; @@ -3264,15 +3260,12 @@ return; } a = PostHiding.makeButton(post, 'show'); - postInfo = Conf['Anonymize'] ? 'Anonymous' : $('.nameBlock', post.nodes.info).textContent; + postInfo = Conf['Anonymize'] ? 'Anonymous' : post.info.name; $.add(a, $.tn(" " + postInfo)); post.nodes.stub = $.el('div', { className: 'stub' }); - $.add(post.nodes.stub, a); - if (Conf['Menu']) { - $.add(post.nodes.stub, [$.tn(' '), Menu.makeButton(post)]); - } + $.add(post.nodes.stub, !Conf['Menu'] ? a : [a, $.tn(' '), button = Menu.makeButton(post)]); return $.prepend(post.nodes.root, post.nodes.stub); }, show: function(post, showRecursively) { @@ -3467,11 +3460,6 @@ makeStub = $.el('label', { innerHTML: " Make stub" }); - hideStubLink = $.el('a', { - textContent: 'Hide stub', - href: 'javascript:;' - }); - $.on(hideStubLink, 'click', ThreadHiding.menu.hideStub); $.event('AddMenuEntry', { type: 'post', el: div, @@ -3494,6 +3482,34 @@ } ] }); + div = $.el('a', { + className: 'show-thread-link', + textContent: 'Show thread', + href: 'javascript:;' + }); + $.on(show, 'click', ThreadHiding.menu.show); + $.event('AddMenuEntry', { + type: 'post' + }); + ({ + el: div, + order: 20, + open: function(_arg) { + var isReply, thread; + + thread = _arg.thread, isReply = _arg.isReply; + if (isReply || !thread.isHidden) { + return false; + } + ThreadHiding.menu.thread = thread; + return true; + } + }); + hideStubLink = $.el('a', { + textContent: 'Hide stub', + href: 'javascript:;' + }); + $.on(hideStubLink, 'click', ThreadHiding.menu.hideStub); return $.event('AddMenuEntry', { type: 'post', el: hideStubLink, @@ -3518,6 +3534,14 @@ ThreadHiding.saveHiddenState(thread, makeStub); return $.event('CloseMenu'); }, + show: function() { + var thread; + + thread = ThreadHiding.menu.thread; + ThreadHiding.show(thread); + ThreadHiding.saveHiddenState(thread); + return $.event('CloseMenu'); + }, hideStub: function() { var thread; @@ -3572,7 +3596,7 @@ return ThreadHiding.saveHiddenState(thread); }, hide: function(thread, makeStub) { - var OP, a, numReplies, opInfo, span, threadRoot; + var OP, a, button, numReplies, opInfo, span, threadRoot; if (makeStub == null) { makeStub = Conf['Stubs']; @@ -3584,22 +3608,15 @@ threadRoot.hidden = threadRoot.nextElementSibling.hidden = true; return; } - numReplies = 0; - if (span = $('.summary', threadRoot)) { - numReplies = +span.textContent.match(/\d+/); - } - numReplies += $$('.opContainer ~ .replyContainer', threadRoot).length; - numReplies = numReplies === 1 ? '1 reply' : "" + numReplies + " replies"; - opInfo = Conf['Anonymize'] ? 'Anonymous' : $('.nameBlock', OP.nodes.info).textContent; + numReplies = ((span = $('.summary', threadRoot)) ? +span.textContent.match(/\d+/) : 0) + $$('.opContainer ~ .replyContainer', threadRoot).length; + numReplies = numReplies === 1 ? '1 reply' : "" + (numReplies || 'No') + " replies"; + opInfo = Conf['Anonymize'] ? 'Anonymous' : OP.info.name; a = ThreadHiding.makeButton(thread, 'show'); $.add(a, $.tn(" " + opInfo + " (" + numReplies + ")")); thread.stub = $.el('div', { className: 'stub' }); - $.add(thread.stub, a); - if (Conf['Menu']) { - $.add(thread.stub, [$.tn(' '), Menu.makeButton(OP)]); - } + $.add(thread.stub, !Conf['Menu'] ? a : [a, $.tn(' '), button = Menu.makeButton(OP)]); return $.prepend(threadRoot, thread.stub); }, show: function(thread) { @@ -4208,7 +4225,9 @@ seek: function(type) { var post, posts, result, str; - return unlses(Conf['Mark Quotes of You'] && Conf['Quick Reply']); + if (!(Conf['Mark Quotes of You'] && Conf['Quick Reply'])) { + return; + } $.rmClass($('.highlight'), 'highlight'); if (!QuoteYou.lastRead) { if (!(post = QuoteYou.lastRead = $('.quotesYou'))) { @@ -6974,45 +6993,48 @@ } }; - Menu = { - init: function() { - if (g.VIEW === 'catalog' || !Conf['Menu']) { - return; - } - this.menu = new UI.Menu('post'); - return Post.prototype.callbacks.push({ - name: 'Menu', - cb: this.node - }); - }, - node: function() { - var button; + Menu = (function() { + var a; - if (this.isClone) { - button = $('.menu-button', this.nodes.info); - } else { - button = Menu.makeButton(this); - $.add(this.nodes.info, [$.tn('\u00A0'), button]); - } - return $.on(button, 'click', Menu.toggle); - }, - makeButton: (function() { - var a; + a = $.el('a', { + className: 'menu-button brackets-wrap', + innerHTML: '', + href: 'javascript:;' + }); + return { + init: function() { + if (g.VIEW === 'catalog' || !Conf['Menu']) { + return; + } + this.menu = new UI.Menu('post'); + return Post.prototype.callbacks.push({ + name: 'Menu', + cb: this.node + }); + }, + node: function() { + var button; - a = null; - return function() { - a || (a = $.el('a', { - className: 'menu-button fourchanx-link', - innerHTML: '', - href: 'javascript:;' - })); - return a.cloneNode(true); - }; - })(), - toggle: function(e) { - return Menu.menu.toggle(e, this, Get.postFromNode(this)); - } - }; + if (this.isClone) { + button = $('.menu-button', this.nodes.info); + } else { + button = a.cloneNode(true); + $.add(this.nodes.info, [$.tn('\u00A0'), button]); + } + return $.on(button, 'click', Menu.toggle); + }, + makeButton: function() { + var el; + + el = a.cloneNode(true); + $.on(el, 'click', Menu.toggle); + return el; + }, + toggle: function(e) { + return Menu.menu.toggle(e, this, Get.postFromNode(this)); + } + }; + })(); ReportLink = { init: function() { diff --git a/src/Filtering/PostHiding.coffee b/src/Filtering/PostHiding.coffee index 9d19ac74b..8c7be2ae3 100644 --- a/src/Filtering/PostHiding.coffee +++ b/src/Filtering/PostHiding.coffee @@ -17,7 +17,7 @@ PostHiding = PostHiding.hide @, data.makeStub, data.hideRecursively else Recursive.apply PostHiding.hide, @, data.makeStub, true - Recursive.add PostHiding.hide, @, data.makeStub, true + Recursive.add PostHiding.hide, @, data.makeStub, true return unless Conf['Reply Hiding Buttons'] $.replace $('.sideArrows', @nodes.root), PostHiding.makeButton @, 'hide' @@ -108,11 +108,12 @@ PostHiding = PostHiding.hide post, makeStub, replies else if replies Recursive.apply PostHiding.hide, post, makeStub, true - Recursive.add PostHiding.hide, post, makeStub, true + Recursive.add PostHiding.hide, post, makeStub, true else return PostHiding.saveHiddenState post, true, thisPost, makeStub, replies $.event 'CloseMenu' + show: -> parent = @parentNode thisPost = $('input[name=thisPost]', parent).checked @@ -122,7 +123,7 @@ PostHiding = PostHiding.show post, replies else if replies Recursive.apply PostHiding.show, post, true - Recursive.rm PostHiding.hide, post, true + Recursive.rm PostHiding.hide, post, true else return if data = PostHiding.db.get {boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID} @@ -158,10 +159,7 @@ PostHiding = toggle: -> post = Get.postFromNode @ - if post.isHidden - PostHiding.show post - else - PostHiding.hide post + PostHiding[(if post.isHidden then 'show' else 'hide')] post PostHiding.saveHiddenState post, post.isHidden hide: (post, makeStub=Conf['Stubs'], hideRecursively=Conf['Recursive Hiding']) -> @@ -170,7 +168,7 @@ PostHiding = if hideRecursively Recursive.apply PostHiding.hide, post, makeStub, true - Recursive.add PostHiding.hide, post, makeStub, true + Recursive.add PostHiding.hide, post, makeStub, true for quotelink in Get.allQuotelinksLinkingTo post $.addClass quotelink, 'filtered' @@ -184,13 +182,14 @@ PostHiding = if Conf['Anonymize'] 'Anonymous' else - $('.nameBlock', post.nodes.info).textContent + post.info.name $.add a, $.tn " #{postInfo}" post.nodes.stub = $.el 'div', className: 'stub' - $.add post.nodes.stub, a - if Conf['Menu'] - $.add post.nodes.stub, [$.tn(' '), Menu.makeButton post] + $.add post.nodes.stub, unless Conf['Menu'] + a + else + [a, $.tn(' '), button = Menu.makeButton post] $.prepend post.nodes.root, post.nodes.stub show: (post, showRecursively=Conf['Recursive Hiding']) -> @@ -202,7 +201,7 @@ PostHiding = post.isHidden = false if showRecursively Recursive.apply PostHiding.show, post, true - Recursive.rm PostHiding.hide, post + Recursive.rm PostHiding.hide, post for quotelink in Get.allQuotelinksLinkingTo post $.rmClass quotelink, 'filtered' return \ No newline at end of file diff --git a/src/Filtering/ThreadHiding.coffee b/src/Filtering/ThreadHiding.coffee index a1d9a79f8..f193afbde 100644 --- a/src/Filtering/ThreadHiding.coffee +++ b/src/Filtering/ThreadHiding.coffee @@ -71,11 +71,6 @@ ThreadHiding = makeStub = $.el 'label', innerHTML: " Make stub" - hideStubLink = $.el 'a', - textContent: 'Hide stub' - href: 'javascript:;' - $.on hideStubLink, 'click', ThreadHiding.menu.hideStub - $.event 'AddMenuEntry', type: 'post' el: div @@ -87,6 +82,27 @@ ThreadHiding = true subEntries: [el: apply; el: makeStub] + div = $.el 'a', + className: 'show-thread-link' + textContent: 'Show thread' + href: 'javascript:;' + $.on show, 'click', ThreadHiding.menu.show + + $.event 'AddMenuEntry', + type: 'post' + el: div + order: 20 + open: ({thread, isReply}) -> + if isReply or !thread.isHidden + return false + ThreadHiding.menu.thread = thread + true + + hideStubLink = $.el 'a', + textContent: 'Hide stub' + href: 'javascript:;' + $.on hideStubLink, 'click', ThreadHiding.menu.hideStub + $.event 'AddMenuEntry', type: 'post' el: hideStubLink @@ -102,6 +118,13 @@ ThreadHiding = ThreadHiding.hide thread, makeStub ThreadHiding.saveHiddenState thread, makeStub $.event 'CloseMenu' + + show: -> + {thread} = ThreadHiding.menu + ThreadHiding.show thread + ThreadHiding.saveHiddenState thread + $.event 'CloseMenu' + hideStub: -> {thread} = ThreadHiding.menu ThreadHiding.hide thread, false @@ -150,24 +173,28 @@ ThreadHiding = threadRoot.hidden = threadRoot.nextElementSibling.hidden = true #
return - numReplies = 0 - if span = $ '.summary', threadRoot - numReplies = +span.textContent.match /\d+/ - numReplies += $$('.opContainer ~ .replyContainer', threadRoot).length - numReplies = if numReplies is 1 then '1 reply' else "#{numReplies} replies" + numReplies = ( + if span = $ '.summary', threadRoot + +span.textContent.match /\d+/ + else + 0 + ) + + $$('.opContainer ~ .replyContainer', threadRoot).length + numReplies = if numReplies is 1 then '1 reply' else "#{numReplies or 'No'} replies" opInfo = if Conf['Anonymize'] 'Anonymous' else - $('.nameBlock', OP.nodes.info).textContent + OP.info.name a = ThreadHiding.makeButton thread, 'show' $.add a, $.tn " #{opInfo} (#{numReplies})" thread.stub = $.el 'div', className: 'stub' - $.add thread.stub, a - if Conf['Menu'] - $.add thread.stub, [$.tn(' '), Menu.makeButton OP] + $.add thread.stub, unless Conf['Menu'] + a + else + [a, $.tn(' '), button = Menu.makeButton OP] $.prepend threadRoot, thread.stub show: (thread) -> diff --git a/src/General/Get.coffee b/src/General/Get.coffee index 50d32684b..43787f62d 100644 --- a/src/General/Get.coffee +++ b/src/General/Get.coffee @@ -18,7 +18,7 @@ Get = post = g.posts["#{boardID}.#{postID}"] if index then post.clones[index] else post postFromNode: (root) -> - Get.postFromRoot $.x 'ancestor::div[contains(@class,"postContainer")][1]', root + Get.postFromRoot $.x '(ancestor::div[contains(@class,"postContainer")]|following::div[contains(@class,"postContainer")])', root contextFromNode: (quotelink) -> Get.postFromRoot $.x 'ancestor::div[parent::div[@class="thread"]][1]', quotelink postDataFromLink: (link) -> diff --git a/src/Menu/Menu.coffee b/src/Menu/Menu.coffee index 98e8865ad..29fc8399e 100644 --- a/src/Menu/Menu.coffee +++ b/src/Menu/Menu.coffee @@ -1,4 +1,9 @@ -Menu = +Menu = do -> + a = $.el 'a', + className: 'menu-button brackets-wrap' + innerHTML: '' + href: 'javascript:;' + init: -> return if g.VIEW is 'catalog' or !Conf['Menu'] @@ -11,18 +16,14 @@ Menu = if @isClone button = $ '.menu-button', @nodes.info else - button = Menu.makeButton @ + button = a.cloneNode true $.add @nodes.info, [$.tn('\u00A0'), button] $.on button, 'click', Menu.toggle - makeButton: do -> - a = null - -> - a or= $.el 'a', - className: 'menu-button fourchanx-link' - innerHTML: '' - href: 'javascript:;' - a.cloneNode true + makeButton: -> + el = a.cloneNode true + $.on el, 'click', Menu.toggle + el toggle: (e) -> Menu.menu.toggle e, @, Get.postFromNode @ diff --git a/src/Quotelinks/QuoteYou.coffee b/src/Quotelinks/QuoteYou.coffee index b71d37a99..985940041 100644 --- a/src/Quotelinks/QuoteYou.coffee +++ b/src/Quotelinks/QuoteYou.coffee @@ -33,7 +33,7 @@ QuoteYou = cb: seek: (type) -> - return unlses Conf['Mark Quotes of You'] and Conf['Quick Reply'] + return unless Conf['Mark Quotes of You'] and Conf['Quick Reply'] $.rmClass $('.highlight'), 'highlight' unless QuoteYou.lastRead