From 1e39406094d7179c56b210e3a95469c7d344debf Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Fri, 31 Aug 2012 23:29:16 +0200 Subject: [PATCH] Add partial quotifying. --- 4chan_x.user.js | 54 ++++++++++++++++++++++++++++++++- script.coffee | 79 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 1 deletion(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index a98fda2c5..b05ad01b0 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -73,7 +73,7 @@ */ (function() { - var $, $$, Board, Conf, Config, Main, Post, Thread, Time, UI, d, g; + var $, $$, Board, Conf, Config, Main, Post, Quotify, Thread, Time, UI, d, g; Config = { main: { @@ -818,6 +818,13 @@ return (_ref2 = $.id('boardNavDesktopFoot')) != null ? _ref2.hidden = true : void 0; }, initFeatures: function() { + if (Conf['Resurrect Quotes']) { + try { + Quotify.init(); + } catch (err) { + $.log(err, 'Resurrect Quotes'); + } + } if (Conf['Time Formatting']) { try { Time.init(); @@ -887,6 +894,51 @@ css: "/* general */\n.move {\n cursor: move;\n}\nlabel {\n cursor: pointer;\n}\n\n/* 4chan style fixes */\n.opContainer, .op {\n display: block !important;\n}\n.post {\n overflow: visible !important;\n}\n\n/* header */\nbody.fourchan_x {\n margin-top: 2.5em;\n}\n#boardNavDesktop.reply {\n border-width: 0 0 1px;\n padding: 4px;\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n transition: opacity .1s ease-in-out;\n -o-transition: opacity .1s ease-in-out;\n -moz-transition: opacity .1s ease-in-out;\n -webkit-transition: opacity .1s ease-in-out;\n z-index: 1;\n}\n#boardNavDesktop.reply:not(:hover) {\n opacity: .4;\n transition: opacity 1.5s .5s ease-in-out;\n -o-transition: opacity 1.5s .5s ease-in-out;\n -moz-transition: opacity 1.5s .5s ease-in-out;\n -webkit-transition: opacity 1.5s .5s ease-in-out;\n}\n#boardNavDesktop.reply a {\n margin: -1px;\n}\n#settings {\n float: right;\n}" }; + Quotify = { + init: function() { + return Post.prototype.callbacks.push({ + name: 'Resurrect Quotes', + cb: this.node + }); + }, + node: function() { + var ID, a, board, data, i, index, m, node, nodes, quote, quoteID, quotes, snapshot, text, _i, _j, _len, _ref; + snapshot = d.evaluate('.//text()[not(parent::a)]', this.nodes.comment, null, 6, null); + for (i = _i = 0, _ref = snapshot.snapshotLength; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { + node = snapshot.snapshotItem(i); + data = node.data; + if (!(quotes = data.match(/>>(>\/[a-z\d]+\/)?\d+/g))) { + continue; + } + nodes = []; + for (_j = 0, _len = quotes.length; _j < _len; _j++) { + quote = quotes[_j]; + index = data.indexOf(quote); + if (text = data.slice(0, index)) { + nodes.push($.tn(text)); + } + ID = quote.match(/\d+$/)[0]; + board = (m = quote.match(/^>>>\/([a-z\d]+)/)) ? m[1] : this.board.ID; + quoteID = "" + board + "." + ID; + if (this.quotes.indexOf(quoteID) === -1) { + this.quotes.push(quoteID); + } + a = $.el('a', { + textContent: quote + }); + this.nodes.quotelinks.push(a); + $.log(this.nodes.quotelinks, this.quotes); + nodes.push(a); + data = data.slice(index + quote.length); + } + if (data) { + nodes.push($.tn(data)); + } + $.replace(node, nodes); + } + } + }; + Time = { init: function() { this.funk = this.createFunc(); diff --git a/script.coffee b/script.coffee index aac238aaf..bdcbf1a3e 100644 --- a/script.coffee +++ b/script.coffee @@ -654,6 +654,13 @@ Main = $.id('boardNavDesktopFoot')?.hidden = true initFeatures: -> + if Conf['Resurrect Quotes'] + try + Quotify.init() + catch err + # XXX handle error + $.log err, 'Resurrect Quotes' + if Conf['Time Formatting'] try Time.init() @@ -757,6 +764,78 @@ body.fourchan_x { +Quotify = + init: -> + Post::callbacks.push + name: 'Resurrect Quotes' + cb: @node + node: -> + # return if post.isInlined and not post.isCrosspost + + # XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE is 6 + # Get all the text nodes that are not inside an anchor. + snapshot = d.evaluate './/text()[not(parent::a)]', @nodes.comment, null, 6, null + + for i in [0...snapshot.snapshotLength] + node = snapshot.snapshotItem i + data = node.data + + # Only accept nodes with potentially valid links + continue unless quotes = data.match />>(>\/[a-z\d]+\/)?\d+/g + + nodes = [] + + for quote in quotes + index = data.indexOf quote + if text = data[...index] + # Potential text before this valid quote. + nodes.push $.tn text + + ID = quote.match(/\d+$/)[0] + board = + if m = quote.match /^>>>\/([a-z\d]+)/ + m[1] + else + @board.ID + + quoteID = "#{board}.#{ID}" + if @quotes.indexOf(quoteID) is -1 + @quotes.push quoteID + + a = $.el 'a', + # \u00A0 is nbsp + # textContent: "#{quote}\u00A0(Dead)" + textContent: quote + + # if board is g.BOARD and $.id "p#{ID}" + # a.href = "#p#{ID}" + # a.className = 'quotelink' + # a.setAttribute 'onclick', "replyhl('#{ID}');" + # else + # a.href = Redirect.thread board, 0, ID + # a.className = 'deadlink' + # a.target = '_blank' + # if Redirect.post board, ID + # $.addClass a, 'quotelink' + # # XXX https://github.com/greasemonkey/greasemonkey/issues/1571 + # # GM can't into dataset + # # a.dataset.board = board + # # a.dataset.id = ID + # a.setAttribute 'data-board', board + # a.setAttribute 'data-id', ID + + @nodes.quotelinks.push a + $.log @nodes.quotelinks, @quotes + nodes.push a + data = data[index + quote.length..] + + if data + # Potential text after the last valid quote. + nodes.push $.tn data + + $.replace node, nodes + return + Time = init: -> @funk = @createFunc()