From c72d8fcdeb5d9a8d169675ea78855ef6d2739152 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 11 Sep 2012 05:46:02 +0200 Subject: [PATCH] Add accurate OP and Cross-thread indicators. --- 4chan_x.user.js | 95 ++++++++++++++++++++++++++++++++++++++++++++++--- script.coffee | 74 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 162 insertions(+), 7 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index a96781bfd..c30850281 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -74,7 +74,7 @@ */ (function() { - var $, $$, AutoGIF, Board, Build, Clone, Conf, Config, FileInfo, Get, ImageHover, Main, Post, QuoteBacklink, QuoteInline, QuotePreview, Quotify, Redirect, RevealSpoilers, Sauce, Thread, Time, UI, d, g, + var $, $$, AutoGIF, Board, Build, Clone, Conf, Config, FileInfo, Get, ImageHover, Main, Post, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, Quotify, Redirect, RevealSpoilers, Sauce, Thread, Time, UI, d, g, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; @@ -141,7 +141,7 @@ 'Quote Preview': [true, 'Show quoted post on hover.'], 'Quote Highlighting': [true, 'Highlight the previewed post.'], 'Resurrect Quotes': [true, 'Linkify dead quotes to archives.'], - 'Indicate OP quote': [true, 'Add \'(OP)\' to OP quotes.'], + 'Indicate OP Quotes': [true, 'Add \'(OP)\' to OP quotes.'], 'Indicate Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes.'] } }, @@ -965,6 +965,20 @@ $.log(err, 'Quote Backlinks'); } } + if (Conf['Indicate OP Quotes']) { + try { + QuoteOP.init(); + } catch (err) { + $.log(err, 'Indicate OP Quotes'); + } + } + if (Conf['Indicate Cross-thread Quotes']) { + try { + QuoteCT.init(); + } catch (err) { + $.log(err, 'Indicate Cross-thread Quotes'); + } + } if (Conf['Time Formatting']) { try { Time.init(); @@ -1450,7 +1464,7 @@ link.href = "/" + board + "/res/" + threadID + "#p" + postID; link.nextSibling.href = "/" + board + "/res/" + threadID + "#q" + postID; board = g.boards[board] || new Board(board); - thread = g.threads["" + board + "." + threadID] || new Thread(threadID, inBoard); + thread = g.threads["" + board + "." + threadID] || new Thread(threadID, board); post = new Post(pc, thread, board); Main.callbackNodes(Post, [post]); return Get.insert(post, root, context); @@ -1652,7 +1666,7 @@ className: 'inline' }); root = (isBacklink = $.hasClass(quotelink, 'backlink')) ? quotelink.parentNode.parentNode : $.x('ancestor-or-self::*[parent::blockquote][1]', quotelink); - context = Get.postFromRoot($.x('ancestor::div[contains(@class,"postContainer")][1]', this)); + context = Get.postFromRoot($.x('ancestor::div[contains(@class,"postContainer")][1]', quotelink)); $.after(root, inline); Get.postClone(board, threadID, postID, inline, context); if (!(board === g.BOARD.ID && $.x("ancestor::div[@id='t" + threadID + "']", quotelink))) { @@ -1862,6 +1876,79 @@ } }; + QuoteOP = { + init: function() { + this.text = '\u00A0(OP)'; + return Post.prototype.callbacks.push({ + name: 'Indicate OP Quotes', + cb: this.node + }); + }, + node: function() { + var board, op, quote, quotelinks, quotes, thread, _i, _j, _len, _len1, _ref; + if (this.isClone && this.thread === this.context.thread) { + return; + } + if (!(quotes = this.quotes).length) { + return; + } + quotelinks = this.nodes.quotelinks; + if (this.isClone && -1 < quotes.indexOf("" + this.board + "." + this.thread)) { + for (_i = 0, _len = quotelinks.length; _i < _len; _i++) { + quote = quotelinks[_i]; + quote.textContent = quote.textContent.replace(QuoteOP.text, ''); + } + } + _ref = this.isClone ? this.context : this, board = _ref.board, thread = _ref.thread; + op = "" + board + "." + thread; + if (!(-1 < quotes.indexOf(op))) { + return; + } + for (_j = 0, _len1 = quotelinks.length; _j < _len1; _j++) { + quote = quotelinks[_j]; + if (("" + (quote.pathname.split('/')[1]) + "." + quote.hash.slice(2)) === op) { + $.add(quote, $.tn(QuoteOP.text)); + } + } + } + }; + + QuoteCT = { + init: function() { + this.text = '\u00A0(Cross-thread)'; + return Post.prototype.callbacks.push({ + name: 'Indicate Cross-thread Quotes', + cb: this.node + }); + }, + node: function() { + var board, path, qBoard, qThread, quote, quotelinks, quotes, thread, _i, _len, _ref; + if (this.isClone && this.thread === this.context.thread) { + return; + } + if (!(quotes = this.quotes).length) { + return; + } + quotelinks = this.nodes.quotelinks; + _ref = this.isClone ? this.context : this, board = _ref.board, thread = _ref.thread; + for (_i = 0, _len = quotelinks.length; _i < _len; _i++) { + quote = quotelinks[_i]; + if ($.hasClass(quote, 'deadlink')) { + continue; + } + path = quote.pathname.split('/'); + qBoard = path[1]; + qThread = path[3]; + if (this.isClone && qBoard === this.board.ID && +qThread !== this.thread.ID) { + quote.textContent = quote.textContent.replace(QuoteCT.text, ''); + } + if (qBoard === board.ID && +qThread !== thread.ID) { + $.add(quote, $.tn(QuoteCT.text)); + } + } + } + }; + Time = { init: function() { this.funk = this.createFunc(Conf['time']); diff --git a/script.coffee b/script.coffee index 52860a68b..468c61e3b 100644 --- a/script.coffee +++ b/script.coffee @@ -55,7 +55,7 @@ Config = 'Quote Preview': [true, 'Show quoted post on hover.'] 'Quote Highlighting': [true, 'Highlight the previewed post.'] 'Resurrect Quotes': [true, 'Linkify dead quotes to archives.'] - 'Indicate OP quote': [true, 'Add \'(OP)\' to OP quotes.'] + 'Indicate OP Quotes': [true, 'Add \'(OP)\' to OP quotes.'] 'Indicate Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes.'] filter: name: [ @@ -769,6 +769,20 @@ Main = # XXX handle error $.log err, 'Quote Backlinks' + if Conf['Indicate OP Quotes'] + try + QuoteOP.init() + catch err + # XXX handle error + $.log err, 'Indicate OP Quotes' + + if Conf['Indicate Cross-thread Quotes'] + try + QuoteCT.init() + catch err + # XXX handle error + $.log err, 'Indicate Cross-thread Quotes' + if Conf['Time Formatting'] try Time.init() @@ -1263,7 +1277,7 @@ Get = board = g.boards[board] or new Board board thread = g.threads["#{board}.#{threadID}"] or - new Thread threadID, inBoard + new Thread threadID, board post = new Post pc, thread, board Main.callbackNodes Post, [post] Get.insert post, root, context @@ -1467,7 +1481,7 @@ QuoteInline = quotelink.parentNode.parentNode else $.x 'ancestor-or-self::*[parent::blockquote][1]', quotelink - context = Get.postFromRoot $.x 'ancestor::div[contains(@class,"postContainer")][1]', @ + context = Get.postFromRoot $.x 'ancestor::div[contains(@class,"postContainer")][1]', quotelink $.after root, inline Get.postClone board, threadID, postID, inline, context @@ -1658,6 +1672,60 @@ QuoteBacklink = @containers[id] or= $.el 'span', className: 'container' +QuoteOP = + init: -> + # \u00A0 is nbsp + @text = '\u00A0(OP)' + Post::callbacks.push + name: 'Indicate OP Quotes' + cb: @node + node: -> + # Stop there if it's a clone of a post in the same thread. + return if @isClone and @thread is @context.thread + # Stop there if there's no quotes in that post. + return unless (quotes = @quotes).length + quotelinks = @nodes.quotelinks + + # rm (OP) from cross-thread quotes. + if @isClone and -1 < quotes.indexOf "#{@board}.#{@thread}" + for quote in quotelinks + quote.textContent = quote.textContent.replace QuoteOP.text, '' + + {board, thread} = if @isClone then @context else @ + op = "#{board}.#{thread}" + # add (OP) to quotes quoting this context's OP. + return unless -1 < quotes.indexOf op + for quote in quotelinks + if "#{quote.pathname.split('/')[1]}.#{quote.hash[2..]}" is op + $.add quote, $.tn QuoteOP.text + return + +QuoteCT = + init: -> + # \u00A0 is nbsp + @text = '\u00A0(Cross-thread)' + Post::callbacks.push + name: 'Indicate Cross-thread Quotes' + cb: @node + node: -> + # Stop there if it's a clone of a post in the same thread. + return if @isClone and @thread is @context.thread + # Stop there if there's no quotes in that post. + return unless (quotes = @quotes).length + quotelinks = @nodes.quotelinks + + {board, thread} = if @isClone then @context else @ + for quote in quotelinks + continue if $.hasClass quote, 'deadlink' + path = quote.pathname.split '/' + qBoard = path[1] + qThread = path[3] + if @isClone and qBoard is @board.ID and +qThread isnt @thread.ID + quote.textContent = quote.textContent.replace QuoteCT.text, '' + if qBoard is board.ID and +qThread isnt thread.ID + $.add quote, $.tn QuoteCT.text + return + Time = init: -> @funk = @createFunc Conf['time']