From bcbae6c84f7131e42bdcc6109621159254292d7a Mon Sep 17 00:00:00 2001 From: carboncopy Date: Fri, 19 Jul 2013 23:18:11 -0500 Subject: [PATCH 1/8] display rolled dice while on /tg/ --- src/General/Config.coffee | 1 + src/General/Main.coffee | 1 + src/Miscellaneous/Dice.coffee | 20 ++++++++++++++++++++ 3 files changed, 22 insertions(+) create mode 100644 src/Miscellaneous/Dice.coffee diff --git a/src/General/Config.coffee b/src/General/Config.coffee index f7a1e24e4..2badf110b 100644 --- a/src/General/Config.coffee +++ b/src/General/Config.coffee @@ -13,6 +13,7 @@ Config = 'Index Navigation': [false, 'Add buttons to navigate between threads.'] 'Reply Navigation': [false, 'Add buttons to navigate to top / bottom of thread.'] 'Check for Updates': [true, 'Notify when updated versions of <%= meta.name %> are available.'] + 'Show Dice Rolled': [true, 'Show dice that were entered into the email field.'] 'Filtering': 'Anonymize': [false, 'Make everyone Anonymous.'] 'Filter': [true, 'Self-moderation placebo.'] diff --git a/src/General/Main.coffee b/src/General/Main.coffee index a1dd45ae4..044796280 100644 --- a/src/General/Main.coffee +++ b/src/General/Main.coffee @@ -114,6 +114,7 @@ Main = initFeature 'Thread Watcher', ThreadWatcher initFeature 'Index Navigation', Nav initFeature 'Keybinds', Keybinds + initFeature 'Dice Checker', Dice # c.timeEnd 'All initializations' $.on d, 'AddCallback', Main.addCallback diff --git a/src/Miscellaneous/Dice.coffee b/src/Miscellaneous/Dice.coffee new file mode 100644 index 000000000..1614a6ca9 --- /dev/null +++ b/src/Miscellaneous/Dice.coffee @@ -0,0 +1,20 @@ +Dice = + init: -> + return if g.VIEW is 'catalog' or !Conf['Show Dice Rolled'] + # or !Conf['Show dice being rolled'] + return if g.BOARD.ID isnt 'tg' + Post::callbacks.push + name: 'Dice roller' + cb: @node + node: -> + return if @isClone + email = @info.email + dicestats = /dice\W(\d+)d(\d+)/.exec(email) + return if not dicestats + roll = ($$("b",@nodes.comment).filter (elem)->elem.innerHTML.lastIndexOf("Rolled", 0) == 0)[0] + return if not roll + rollResults = roll.innerHTML.slice 7 + dicestr = dicestats[1]+"d"+dicestats[2] + roll.innerHTML = "Rolled " + dicestr + " and got " + rollResults + + From 5eabd9ce0d5f44a3ff6bba4778931a921c0fe8f2 Mon Sep 17 00:00:00 2001 From: carboncopy Date: Wed, 7 Aug 2013 15:55:57 -0500 Subject: [PATCH 2/8] updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 793177903..04a47aa59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ +- Added dice monitoring on /tg/ - Fix impossibility to create new threads when in dead threads. ### 3.5.7 - *2013-07-13* From 8c95fe1995899b7dd6c63502113149b908143cc9 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Thu, 8 Aug 2013 11:25:03 +0200 Subject: [PATCH 3/8] Tweak Dice code. #1218 --- CHANGELOG.md | 3 ++- src/General/Config.coffee | 2 +- src/General/Main.coffee | 2 +- src/Miscellaneous/Dice.coffee | 28 ++++++++++++---------------- 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04a47aa59..353dce5e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ -- Added dice monitoring on /tg/ +- **New feature**: `Show Dice Roll` + - Shows dice that were entered into the email field on /tg/. - Fix impossibility to create new threads when in dead threads. ### 3.5.7 - *2013-07-13* diff --git a/src/General/Config.coffee b/src/General/Config.coffee index 2badf110b..7cbc64d18 100644 --- a/src/General/Config.coffee +++ b/src/General/Config.coffee @@ -12,8 +12,8 @@ Config = 'Thread Expansion': [true, 'Add buttons to expand threads.'] 'Index Navigation': [false, 'Add buttons to navigate between threads.'] 'Reply Navigation': [false, 'Add buttons to navigate to top / bottom of thread.'] + 'Show Dice Roll': [true, 'Show dice that were entered into the email field.'] 'Check for Updates': [true, 'Notify when updated versions of <%= meta.name %> are available.'] - 'Show Dice Rolled': [true, 'Show dice that were entered into the email field.'] 'Filtering': 'Anonymize': [false, 'Make everyone Anonymous.'] 'Filter': [true, 'Self-moderation placebo.'] diff --git a/src/General/Main.coffee b/src/General/Main.coffee index 044796280..92a543676 100644 --- a/src/General/Main.coffee +++ b/src/General/Main.coffee @@ -114,7 +114,7 @@ Main = initFeature 'Thread Watcher', ThreadWatcher initFeature 'Index Navigation', Nav initFeature 'Keybinds', Keybinds - initFeature 'Dice Checker', Dice + initFeature 'Show Dice Roll', Dice # c.timeEnd 'All initializations' $.on d, 'AddCallback', Main.addCallback diff --git a/src/Miscellaneous/Dice.coffee b/src/Miscellaneous/Dice.coffee index 1614a6ca9..67559eca4 100644 --- a/src/Miscellaneous/Dice.coffee +++ b/src/Miscellaneous/Dice.coffee @@ -1,20 +1,16 @@ Dice = init: -> - return if g.VIEW is 'catalog' or !Conf['Show Dice Rolled'] - # or !Conf['Show dice being rolled'] - return if g.BOARD.ID isnt 'tg' + return if g.BOARD.ID isnt 'tg' or g.VIEW is 'catalog' or !Conf['Show Dice Roll'] Post::callbacks.push - name: 'Dice roller' - cb: @node + name: 'Show Dice Roll' + cb: @node node: -> - return if @isClone - email = @info.email - dicestats = /dice\W(\d+)d(\d+)/.exec(email) - return if not dicestats - roll = ($$("b",@nodes.comment).filter (elem)->elem.innerHTML.lastIndexOf("Rolled", 0) == 0)[0] - return if not roll - rollResults = roll.innerHTML.slice 7 - dicestr = dicestats[1]+"d"+dicestats[2] - roll.innerHTML = "Rolled " + dicestr + " and got " + rollResults - - + return if @isClone or not dicestats = @info.email?.match /dice\+(\d+)d(\d+)/ + # Use the text node directly, as the has two
. + roll = $('b', @nodes.comment).firstChild + # Stop here if it looks like this: + # Rolled 44 + # and not this: + # Rolled 9, 8, 10, 3, 5 = 35 + return unless rollResults = roll.textContent.match /^Rolled (\d+)$/ + roll.textContent = "Rolled #{dicestats[1]}d#{dicestats[2]} and got #{rollResults[1]}" From 2cbf3d909d251755924f43dcea4a44a580fc9f26 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Thu, 8 Aug 2013 17:24:46 +0200 Subject: [PATCH 4/8] Tweak dice code further. #1218 Also use `data` instead of `textContent` as it performs faster. --- src/Miscellaneous/Dice.coffee | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Miscellaneous/Dice.coffee b/src/Miscellaneous/Dice.coffee index 67559eca4..93bdb06cd 100644 --- a/src/Miscellaneous/Dice.coffee +++ b/src/Miscellaneous/Dice.coffee @@ -5,12 +5,7 @@ Dice = name: 'Show Dice Roll' cb: @node node: -> - return if @isClone or not dicestats = @info.email?.match /dice\+(\d+)d(\d+)/ + return if @isClone or not dicestats = @info.email?.match /dice[+\s](\d+)d(\d+)/ # Use the text node directly, as the has two
. roll = $('b', @nodes.comment).firstChild - # Stop here if it looks like this: - # Rolled 44 - # and not this: - # Rolled 9, 8, 10, 3, 5 = 35 - return unless rollResults = roll.textContent.match /^Rolled (\d+)$/ - roll.textContent = "Rolled #{dicestats[1]}d#{dicestats[2]} and got #{rollResults[1]}" + roll.data = "Rolled #{dicestats[1]}d#{dicestats[2]} and got #{roll.data.slice 7}" From 0b55e34361c9126358c1b70ad0adbc945434deeb Mon Sep 17 00:00:00 2001 From: Mayhem Date: Fri, 9 Aug 2013 12:41:59 +0200 Subject: [PATCH 5/8] Allow fetching posts for archives that require credentials. --- json/archives.json | 1 + lib/$.coffee | 16 ++++++++-------- src/Archive/Redirect.coffee | 4 +++- src/General/Get.coffee | 18 ++++++++++++------ 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/json/archives.json b/json/archives.json index 15c52e369..95ac1a37a 100644 --- a/json/archives.json +++ b/json/archives.json @@ -103,6 +103,7 @@ "domain": "beta.foolz.us", "http": true, "https": true, + "withCredentials": true, "software": "foolfuuka", "boards": ["a", "co", "gd", "h", "jp", "m", "mlp", "q", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"], "files": ["a", "gd", "h", "jp", "m", "q", "tg", "u", "vg", "vp", "vr", "wsg"] diff --git a/lib/$.coffee b/lib/$.coffee index 306eba722..7e25bb5f2 100644 --- a/lib/$.coffee +++ b/lib/$.coffee @@ -49,7 +49,7 @@ $.ajax = (url, options, extra={}) -> r $.cache = do -> reqs = {} - (url, cb) -> + (url, cb, options) -> if req = reqs[url] if req.readyState is 4 cb.call req, req.evt @@ -57,13 +57,13 @@ $.cache = do -> req.callbacks.push cb return rm = -> delete reqs[url] - req = $.ajax url, - onload: (e) -> - cb.call @, e for cb in @callbacks - @evt = e - delete @callbacks - onabort: rm - onerror: rm + req = $.ajax url, options + $.on req, 'load', (e) -> + cb.call @, e for cb in @callbacks + @evt = e + delete @callbacks + $.on req, 'abort', rm + $.on req, 'error', rm req.callbacks = [cb] reqs[url] = req $.cb = diff --git a/src/Archive/Redirect.coffee b/src/Archive/Redirect.coffee index edc4e621c..1da3f9f8a 100644 --- a/src/Archive/Redirect.coffee +++ b/src/Archive/Redirect.coffee @@ -74,7 +74,9 @@ Redirect = # Remove necessary HTTPS procotol in September 2013. if archive.name in ['Foolz', 'NSFW Foolz'] protocol = 'https://' - "#{protocol}#{archive.domain}/_/api/chan/post/?board=#{boardID}&num=#{postID}" + URL = new String "#{protocol}#{archive.domain}/_/api/chan/post/?board=#{boardID}&num=#{postID}" + URL.archive = archive + URL file: (archive, {boardID, filename}) -> "#{Redirect.protocol archive}#{archive.domain}/#{boardID}/full_image/#{filename}" diff --git a/src/General/Get.coffee b/src/General/Get.coffee index 5e9cfbbcf..fe2a056b0 100644 --- a/src/General/Get.coffee +++ b/src/General/Get.coffee @@ -71,8 +71,10 @@ Get = $.cache "//api.4chan.org/#{boardID}/res/#{threadID}.json", -> Get.fetchedPost @, boardID, threadID, postID, root, context else if url = Redirect.to 'post', {boardID, postID} - $.cache url, -> - Get.archivedPost @, boardID, postID, root, context + $.cache url, + -> Get.archivedPost @, boardID, postID, root, context + , + withCredentials: url.archive.withCredentials insert: (post, root, context) -> # Stop here if the container has been removed while loading. return unless root.parentNode @@ -97,8 +99,10 @@ Get = if status not in [200, 304] # The thread can die by the time we check a quote. if url = Redirect.to 'post', {boardID, postID} - $.cache url, -> - Get.archivedPost @, boardID, postID, root, context + $.cache url, + -> Get.archivedPost @, boardID, postID, root, context + , + withCredentials: url.archive.withCredentials else $.addClass root, 'warning' root.textContent = @@ -115,8 +119,10 @@ Get = if post.no > postID # The post can be deleted by the time we check a quote. if url = Redirect.to 'post', {boardID, postID} - $.cache url, -> - Get.archivedPost @, boardID, postID, root, context + $.cache url, + -> Get.archivedPost @, boardID, postID, root, context + , + withCredentials: url.archive.withCredentials else $.addClass root, 'warning' root.textContent = "Post No.#{postID} was not found." From 6f6c1be3b168c167072bed0a3ce9af9270c45919 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Fri, 9 Aug 2013 18:44:22 +0200 Subject: [PATCH 6/8] Fix #1219. --- src/Miscellaneous/Time.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Miscellaneous/Time.coffee b/src/Miscellaneous/Time.coffee index 1f57d19d1..0f054283a 100644 --- a/src/Miscellaneous/Time.coffee +++ b/src/Miscellaneous/Time.coffee @@ -56,4 +56,4 @@ Time = p: -> if @getHours() < 12 then 'AM' else 'PM' P: -> if @getHours() < 12 then 'am' else 'pm' S: -> Time.zeroPad @getSeconds() - y: -> @getFullYear() - 2000 + y: -> @getFullYear().toString()[2..] From ee291bad0ce37f990416f596b75d40812c84e32f Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Fri, 9 Aug 2013 19:21:26 -0700 Subject: [PATCH 7/8] Force stub menu to work --- builds/4chan-X.user.js | 156 +++++++++++++++++------------- builds/crx/script.js | 156 +++++++++++++++++------------- src/Filtering/PostHiding.coffee | 25 +++-- src/Filtering/ThreadHiding.coffee | 55 ++++++++--- src/General/Get.coffee | 2 +- src/Menu/Menu.coffee | 21 ++-- src/Quotelinks/QuoteYou.coffee | 2 +- 7 files changed, 244 insertions(+), 173 deletions(-) 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 From 10a2a96a965855783e816141a0813f56d281b2e8 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Fri, 9 Aug 2013 19:40:21 -0700 Subject: [PATCH 8/8] Oops --- builds/4chan-X.user.js | 2 +- builds/crx/script.js | 2 +- src/General/Get.coffee | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index cf4d6addc..2f997141e 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1995,7 +1995,7 @@ } }, postFromNode: function(root) { - return Get.postFromRoot($.x('(ancestor::div[contains(@class,"postContainer")]|following::div[contains(@class,"postContainer")])', root)); + return Get.postFromRoot($.x('(ancestor::div[contains(@class,"postContainer")]|following::div[contains(@class,"postContainer")])[1]', root)); }, contextFromNode: function(quotelink) { return Get.postFromRoot($.x('ancestor::div[parent::div[@class="thread"]][1]', quotelink)); diff --git a/builds/crx/script.js b/builds/crx/script.js index 1e575d241..787755dde 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -2007,7 +2007,7 @@ } }, postFromNode: function(root) { - return Get.postFromRoot($.x('(ancestor::div[contains(@class,"postContainer")]|following::div[contains(@class,"postContainer")])', root)); + return Get.postFromRoot($.x('(ancestor::div[contains(@class,"postContainer")]|following::div[contains(@class,"postContainer")])[1]', root)); }, contextFromNode: function(quotelink) { return Get.postFromRoot($.x('ancestor::div[parent::div[@class="thread"]][1]', quotelink)); diff --git a/src/General/Get.coffee b/src/General/Get.coffee index 6b9d94e86..bedb80bd6 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")]|following::div[contains(@class,"postContainer")])', root + Get.postFromRoot $.x '(ancestor::div[contains(@class,"postContainer")]|following::div[contains(@class,"postContainer")])[1]', root contextFromNode: (quotelink) -> Get.postFromRoot $.x 'ancestor::div[parent::div[@class="thread"]][1]', quotelink postDataFromLink: (link) ->