Preparse posts; global performance improvements. This is mostly efficient when parsing multiple posts at once (when opening a thread, or expanding a thread if mutation observers are working).
This commit is contained in:
parent
0f6d607902
commit
63f48aeba6
276
4chan_x.user.js
276
4chan_x.user.js
@ -72,7 +72,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var $, $$, DAY, Favicon, FileInfo, HOUR, MINUTE, Main, NAMESPACE, SECOND, Time, VERSION, anonymize, conf, config, d, engine, expandComment, expandThread, filter, flatten, g, getTitle, imgExpand, imgGif, imgHover, key, keybinds, log, nav, options, qr, quoteBacklink, quoteIndicators, quoteInline, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher, _base;
|
var $, $$, DAY, Favicon, FileInfo, HOUR, MINUTE, Main, NAMESPACE, SECOND, Time, VERSION, anonymize, conf, config, d, engine, expandComment, expandThread, filter, flatten, g, getTitle, imgExpand, imgGif, imgHover, key, keybinds, log, nav, options, qr, quoteBacklink, quoteDR, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher, _base;
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
main: {
|
main: {
|
||||||
@ -575,8 +575,9 @@
|
|||||||
if (Object.keys(this.filters).length) return g.callbacks.push(this.node);
|
if (Object.keys(this.filters).length) return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
createFilter: function(regexp, op, hl, top) {
|
createFilter: function(regexp, op, hl, top) {
|
||||||
return function(root, value, isOP) {
|
return function(post, value) {
|
||||||
var firstThread, thisThread;
|
var el, firstThread, isOP, thisThread;
|
||||||
|
el = post.el, isOP = post.isOP;
|
||||||
if (isOP && op === 'no' || !isOP && op === 'only') return false;
|
if (isOP && op === 'no' || !isOP && op === 'only') return false;
|
||||||
if (typeof regexp === 'string') {
|
if (typeof regexp === 'string') {
|
||||||
if (regexp !== value) return false;
|
if (regexp !== value) return false;
|
||||||
@ -585,12 +586,12 @@
|
|||||||
}
|
}
|
||||||
if (hl) {
|
if (hl) {
|
||||||
if (isOP) {
|
if (isOP) {
|
||||||
$.addClass(root, hl);
|
$.addClass(el, hl);
|
||||||
} else {
|
} else {
|
||||||
$.addClass(root.parentNode, hl);
|
$.addClass(el.parentNode, hl);
|
||||||
}
|
}
|
||||||
if (isOP && top && !g.REPLY) {
|
if (isOP && top && !g.REPLY) {
|
||||||
thisThread = root.parentNode;
|
thisThread = el.parentNode;
|
||||||
if (firstThread = $('div[class=op]')) {
|
if (firstThread = $('div[class=op]')) {
|
||||||
$.before(firstThread.parentNode, [thisThread, thisThread.nextElementSibling]);
|
$.before(firstThread.parentNode, [thisThread, thisThread.nextElementSibling]);
|
||||||
}
|
}
|
||||||
@ -598,86 +599,85 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isOP) {
|
if (isOP) {
|
||||||
if (!g.REPLY) threadHiding.hideHide(root.parentNode);
|
if (!g.REPLY) threadHiding.hideHide(el.parentNode);
|
||||||
} else {
|
} else {
|
||||||
replyHiding.hideHide(root);
|
replyHiding.hideHide(el);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
var Filter, isOP, key, klass, value, _i, _len, _ref;
|
var Filter, key, value, _i, _len, _ref;
|
||||||
klass = root.className;
|
if (post.isInlined) return;
|
||||||
if (/\binlined\b/.test(klass)) return;
|
|
||||||
if (!(isOP = klass === 'op')) root = $('td[id]', root);
|
|
||||||
for (key in filter.filters) {
|
for (key in filter.filters) {
|
||||||
value = filter[key](root, isOP);
|
value = filter[key](post);
|
||||||
if (value === false) continue;
|
if (value === false) continue;
|
||||||
_ref = filter.filters[key];
|
_ref = filter.filters[key];
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
Filter = _ref[_i];
|
Filter = _ref[_i];
|
||||||
if (Filter(root, value, isOP)) return;
|
if (Filter(post, value)) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
name: function(root, isOP) {
|
name: function(post) {
|
||||||
var name;
|
var name;
|
||||||
name = isOP ? $('.postername', root) : $('.commentpostername', root);
|
name = post.isOP ? $('.postername', post.el) : $('.commentpostername', post.el);
|
||||||
return name.textContent;
|
return name.textContent;
|
||||||
},
|
},
|
||||||
tripcode: function(root) {
|
tripcode: function(post) {
|
||||||
var trip;
|
var trip;
|
||||||
if (trip = $('.postertrip', root)) return trip.textContent;
|
if (trip = $('.postertrip', post.el)) return trip.textContent;
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
mod: function(root, isOP) {
|
mod: function(post) {
|
||||||
var mod;
|
var mod;
|
||||||
if (mod = (isOP ? $('.commentpostername', root) : $('.commentpostername ~ .commentpostername', root))) {
|
if (mod = (post.isOP ? $('.commentpostername', post.el) : $('.commentpostername ~ .commentpostername', post.el))) {
|
||||||
return mod.textContent;
|
return mod.textContent;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
email: function(root) {
|
email: function(post) {
|
||||||
var mail;
|
var mail;
|
||||||
if (mail = $('.linkmail', root)) return mail.href;
|
if (mail = $('.linkmail', post.el)) return mail.href;
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
subject: function(root, isOP) {
|
subject: function(post) {
|
||||||
var sub;
|
var sub;
|
||||||
sub = isOP ? $('.filetitle', root) : $('.replytitle', root);
|
sub = post.isOP ? $('.filetitle', post.el) : $('.replytitle', post.el);
|
||||||
return sub.textContent;
|
return sub.textContent;
|
||||||
},
|
},
|
||||||
comment: function(root) {
|
comment: function(post) {
|
||||||
var data, i, len, nodes, text;
|
var data, i, nodes, text, _ref;
|
||||||
text = [];
|
text = [];
|
||||||
nodes = d.evaluate('.//br|.//text()', root.lastChild, null, 7, null);
|
nodes = d.evaluate('.//br|.//text()', post.bq, null, 7, null);
|
||||||
i = 0;
|
for (i = 0, _ref = nodes.snapshotLength; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
|
||||||
len = nodes.snapshotLength;
|
text.push((data = nodes.snapshotItem(i).data) ? data : '\n');
|
||||||
while (i < len) {
|
|
||||||
text.push((data = nodes.snapshotItem(i++).data) ? data : '\n');
|
|
||||||
}
|
}
|
||||||
return text.join('');
|
return text.join('');
|
||||||
},
|
},
|
||||||
filename: function(root) {
|
filename: function(post) {
|
||||||
var file;
|
var file;
|
||||||
if (file = $('.filesize > span', root)) return file.title;
|
if (file = $('span', post.filesize)) return file.title;
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
dimensions: function(root) {
|
dimensions: function(post) {
|
||||||
var match, span;
|
var filesize, match;
|
||||||
if ((span = $('.filesize', root)) && (match = span.textContent.match(/\d+x\d+/))) {
|
filesize = post.filesize;
|
||||||
|
if (filesize && (match = filesize.textContent.match(/\d+x\d+/))) {
|
||||||
return match[0];
|
return match[0];
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
filesize: function(root) {
|
filesize: function(post) {
|
||||||
var img;
|
var img;
|
||||||
if (img = $('img[md5]', root)) return img.alt;
|
img = post.img;
|
||||||
|
if (img) return img.alt;
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
md5: function(root) {
|
md5: function(post) {
|
||||||
var img;
|
var img;
|
||||||
if (img = $('img[md5]', root)) return img.getAttribute('md5');
|
img = post.img;
|
||||||
|
if (img) return img.getAttribute('md5');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -686,15 +686,15 @@
|
|||||||
init: function() {
|
init: function() {
|
||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
var el, quote, _i, _len, _ref;
|
var el, quote, _i, _len, _ref;
|
||||||
if (root.className === 'inline') return;
|
if (post.isInlined) return;
|
||||||
_ref = $$('.quotelink', root);
|
_ref = post.quotes;
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
quote = _ref[_i];
|
quote = _ref[_i];
|
||||||
if ((el = $.id(quote.hash.slice(1))) && el.parentNode.parentNode.parentNode.hidden) {
|
if ((el = $.id(quote.hash.slice(1))) && el.parentNode.parentNode.parentNode.hidden) {
|
||||||
$.addClass(quote, 'filtered');
|
$.addClass(quote, 'filtered');
|
||||||
if (conf['Recursive Filtering']) root.hidden = true;
|
if (conf['Recursive Filtering']) post.root.hidden = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -866,9 +866,10 @@
|
|||||||
init: function() {
|
init: function() {
|
||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
var a, dd, id, reply;
|
var a, dd, id, reply;
|
||||||
if (!(dd = $('.doubledash', root))) return;
|
if (post["class"]) return;
|
||||||
|
dd = $('.doubledash', post.root);
|
||||||
dd.className = 'replyhider';
|
dd.className = 'replyhider';
|
||||||
a = $.el('a', {
|
a = $.el('a', {
|
||||||
textContent: '[ - ]',
|
textContent: '[ - ]',
|
||||||
@ -1312,8 +1313,8 @@
|
|||||||
$.on(d, 'dragstart', qr.drag);
|
$.on(d, 'dragstart', qr.drag);
|
||||||
return $.on(d, 'dragend', qr.drag);
|
return $.on(d, 'dragend', qr.drag);
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
return $.on($('.quotejs + .quotejs', root), 'click', qr.quote);
|
return $.on($('.quotejs + .quotejs', post.el), 'click', qr.quote);
|
||||||
},
|
},
|
||||||
open: function() {
|
open: function() {
|
||||||
if (qr.el) {
|
if (qr.el) {
|
||||||
@ -2745,11 +2746,11 @@
|
|||||||
init: function() {
|
init: function() {
|
||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
var name, trip;
|
var name, trip;
|
||||||
name = $('.commentpostername, .postername', root);
|
name = $('.commentpostername, .postername', post.el);
|
||||||
name.textContent = 'Anonymous';
|
name.textContent = 'Anonymous';
|
||||||
if (trip = $('.postertrip', root)) {
|
if (trip = $('.postertrip', post.el)) {
|
||||||
if (trip.parentNode.nodeName === 'A') {
|
if (trip.parentNode.nodeName === 'A') {
|
||||||
return $.rm(trip.parentNode);
|
return $.rm(trip.parentNode);
|
||||||
} else {
|
} else {
|
||||||
@ -2797,17 +2798,18 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
var img, link, nodes, span, _i, _len, _ref;
|
var img, link, nodes, _i, _len, _ref;
|
||||||
if (root.className === 'inline' || !(span = $('.filesize', root))) return;
|
img = post.img;
|
||||||
img = span.nextElementSibling.nextElementSibling;
|
if (post["class"] === 'inline' || !img) return;
|
||||||
|
img = img.parentNode;
|
||||||
nodes = [];
|
nodes = [];
|
||||||
_ref = sauce.links;
|
_ref = sauce.links;
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
link = _ref[_i];
|
link = _ref[_i];
|
||||||
nodes.push($.tn(' '), link(img));
|
nodes.push($.tn(' '), link(img));
|
||||||
}
|
}
|
||||||
return $.add(span, nodes);
|
return $.add(post.filesize, nodes);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2815,11 +2817,12 @@
|
|||||||
init: function() {
|
init: function() {
|
||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
var img;
|
var img;
|
||||||
if (!(img = $('img[alt^=Spoil]', root)) || root.className === 'inline') {
|
img = {
|
||||||
return;
|
post: post
|
||||||
}
|
};
|
||||||
|
if (!(img && /^Spoil/.test(img.alt)) || post["class"] === 'inline') return;
|
||||||
img.removeAttribute('height');
|
img.removeAttribute('height');
|
||||||
img.removeAttribute('width');
|
img.removeAttribute('width');
|
||||||
return img.src = "http://thumbs.4chan.org" + (img.parentNode.pathname.replace(/src(\/\d+).+$/, 'thumb$1s.jpg'));
|
return img.src = "http://thumbs.4chan.org" + (img.parentNode.pathname.replace(/src(\/\d+).+$/, 'thumb$1s.jpg'));
|
||||||
@ -2844,10 +2847,10 @@
|
|||||||
};
|
};
|
||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
var node, time;
|
var node, time;
|
||||||
if (root.className === 'inline') return;
|
if (post["class"] === 'inline') return;
|
||||||
node = $('.posttime', root) || $('span[id]', root).previousSibling;
|
node = $('.posttime', post.el) || $('span[id]', post.el).previousSibling;
|
||||||
Time.date = Time.parse(node);
|
Time.date = Time.parse(node);
|
||||||
time = $.el('time', {
|
time = $.el('time', {
|
||||||
textContent: ' ' + Time.funk(Time) + ' '
|
textContent: ' ' + Time.funk(Time) + ' '
|
||||||
@ -2937,9 +2940,9 @@
|
|||||||
this.setFormats();
|
this.setFormats();
|
||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
var fullname, link, node, regexp, resolution, shortname, size, type, unit, _, _ref;
|
var fullname, link, node, regexp, resolution, shortname, size, type, unit, _, _ref;
|
||||||
if (root.className === 'inline' || !(node = $('.filesize', root))) return;
|
if (post["class"] === 'inline' || !(node = post.filesize)) return;
|
||||||
type = node.childElementCount === 2 ? 0 : 1;
|
type = node.childElementCount === 2 ? 0 : 1;
|
||||||
regexp = type ? /^File: (<.+>)-\((?:Spoiler Image, )?([\d\.]+) (\w+), (\d+x\d+|PDF)/ : /^File: (<.+>)-\((?:Spoiler Image, )?([\d\.]+) (\w+), (\d+x\d+|PDF), <span title="(.+)">([^<]+)/;
|
regexp = type ? /^File: (<.+>)-\((?:Spoiler Image, )?([\d\.]+) (\w+), (\d+x\d+|PDF)/ : /^File: (<.+>)-\((?:Spoiler Image, )?([\d\.]+) (\w+), (\d+x\d+|PDF), <span title="(.+)">([^<]+)/;
|
||||||
_ref = node.innerHTML.match(regexp), _ = _ref[0], link = _ref[1], size = _ref[2], unit = _ref[3], resolution = _ref[4], fullname = _ref[5], shortname = _ref[6];
|
_ref = node.innerHTML.match(regexp), _ = _ref[0], link = _ref[1], size = _ref[2], unit = _ref[3], resolution = _ref[4], fullname = _ref[5], shortname = _ref[6];
|
||||||
@ -3059,20 +3062,19 @@
|
|||||||
quoteBacklink.funk = Function('id', "return '" + format + "'");
|
quoteBacklink.funk = Function('id', "return '" + format + "'");
|
||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
var a, container, el, id, link, qid, quote, quotes, _i, _len, _ref;
|
var a, container, el, link, qid, quote, quotes, root, _i, _len, _ref;
|
||||||
if (/\binline\b/.test(root.className)) return;
|
if (post.isInlined) return;
|
||||||
quotes = {};
|
quotes = {};
|
||||||
_ref = $$('.quotelink', root);
|
_ref = post.quotes;
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
quote = _ref[_i];
|
quote = _ref[_i];
|
||||||
if (qid = quote.hash.slice(1)) quotes[qid] = true;
|
if (qid = quote.hash.slice(1)) quotes[qid] = true;
|
||||||
}
|
}
|
||||||
id = $('input', root).name;
|
|
||||||
a = $.el('a', {
|
a = $.el('a', {
|
||||||
href: "#" + id,
|
href: "#" + post.id,
|
||||||
className: root.hidden ? 'filtered backlink' : 'backlink',
|
className: post.root.hidden ? 'filtered backlink' : 'backlink',
|
||||||
textContent: quoteBacklink.funk(id)
|
textContent: quoteBacklink.funk(post.id)
|
||||||
});
|
});
|
||||||
for (qid in quotes) {
|
for (qid in quotes) {
|
||||||
if (!(el = $.id(qid)) || el.className === 'op' && !conf['OP Backlinks']) {
|
if (!(el = $.id(qid)) || el.className === 'op' && !conf['OP Backlinks']) {
|
||||||
@ -3097,9 +3099,9 @@
|
|||||||
init: function() {
|
init: function() {
|
||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
var quote, _i, _len, _ref;
|
var quote, _i, _len, _ref;
|
||||||
_ref = $$('.quotelink, .backlink', root);
|
_ref = post.quotes.concat(post.backlinks);
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
quote = _ref[_i];
|
quote = _ref[_i];
|
||||||
if (!quote.hash) continue;
|
if (!quote.hash) continue;
|
||||||
@ -3223,9 +3225,9 @@
|
|||||||
init: function() {
|
init: function() {
|
||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
var quote, _i, _len, _ref;
|
var quote, _i, _len, _ref;
|
||||||
_ref = $$('.quotelink, .backlink', root);
|
_ref = post.quotes.concat(post.backlinks);
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
quote = _ref[_i];
|
quote = _ref[_i];
|
||||||
if (quote.hash) $.on(quote, 'mouseover', quotePreview.mouseover);
|
if (quote.hash) $.on(quote, 'mouseover', quotePreview.mouseover);
|
||||||
@ -3301,24 +3303,36 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
quoteIndicators = {
|
quoteOP = {
|
||||||
init: function() {
|
init: function() {
|
||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
var hash, path, quote, tid, _i, _len, _ref;
|
var quote, _i, _len, _ref;
|
||||||
if (root.className === 'inline') return;
|
if (post["class"] === 'inline') return;
|
||||||
tid = g.THREAD_ID || $.x('ancestor::div[contains(@class,"thread")]', root).firstChild.id;
|
_ref = post.quotes;
|
||||||
_ref = $$('.quotelink', root);
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
quote = _ref[_i];
|
quote = _ref[_i];
|
||||||
if (!(hash = quote.hash.slice(1))) continue;
|
if (quote.hash.slice(1) === post.threadId) {
|
||||||
if (conf['Indicate OP quote'] && hash === tid) {
|
|
||||||
$.add(quote, $.tn('\u00A0(OP)'));
|
$.add(quote, $.tn('\u00A0(OP)'));
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
path = quote.pathname;
|
}
|
||||||
if (conf['Indicate Cross-thread Quotes'] && path.lastIndexOf("/" + tid) === -1 && path.indexOf("/" + g.BOARD + "/") === 0) {
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
quoteDR = {
|
||||||
|
init: function() {
|
||||||
|
return g.callbacks.push(this.node);
|
||||||
|
},
|
||||||
|
node: function(post) {
|
||||||
|
var path, quote, _i, _len, _ref;
|
||||||
|
if (post["class"] === 'inline') return;
|
||||||
|
_ref = post.quotes;
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
quote = _ref[_i];
|
||||||
|
if (!quote.hash) continue;
|
||||||
|
path = quote.pathname.split('/');
|
||||||
|
if (path[1] === g.BOARD && path[3] !== post.threadId) {
|
||||||
$.add(quote, $.tn('\u00A0(Cross-thread)'));
|
$.add(quote, $.tn('\u00A0(Cross-thread)'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3329,16 +3343,15 @@
|
|||||||
init: function() {
|
init: function() {
|
||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
var a, span;
|
var a;
|
||||||
if (!(a = $('.reportbutton', root))) {
|
if (!(a = $('.reportbutton', post.el))) {
|
||||||
span = $('span[id]', root);
|
|
||||||
a = $.el('a', {
|
a = $.el('a', {
|
||||||
className: 'reportbutton',
|
className: 'reportbutton',
|
||||||
innerHTML: '[ ! ]',
|
innerHTML: '[ ! ]',
|
||||||
href: 'javascript:;'
|
href: 'javascript:;'
|
||||||
});
|
});
|
||||||
$.after(span, [$.tn(' '), a]);
|
$.after($('span[id]', post.el), [$.tn(' '), a]);
|
||||||
}
|
}
|
||||||
return $.on(a, 'click', reportButton.report);
|
return $.on(a, 'click', reportButton.report);
|
||||||
},
|
},
|
||||||
@ -3372,11 +3385,11 @@
|
|||||||
})();
|
})();
|
||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
var imgcount;
|
var imgcount;
|
||||||
if (/\binline\b/.test(root.className)) return;
|
if (post.isInlined) return;
|
||||||
$.id('postcount').textContent = ++threadStats.posts;
|
$.id('postcount').textContent = ++threadStats.posts;
|
||||||
if (!$('img[md5]', root)) return;
|
if (!post.img) return;
|
||||||
imgcount = $.id('imagecount');
|
imgcount = $.id('imagecount');
|
||||||
imgcount.textContent = ++threadStats.images;
|
imgcount.textContent = ++threadStats.images;
|
||||||
if (threadStats.images > threadStats.imgLimit) {
|
if (threadStats.images > threadStats.imgLimit) {
|
||||||
@ -3393,9 +3406,9 @@
|
|||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
replies: [],
|
replies: [],
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
if (root.hidden || root.className) return;
|
if (post.root.hidden || post["class"]) return;
|
||||||
unread.replies.push(root);
|
unread.replies.push(post.root);
|
||||||
return unread.update();
|
return unread.update();
|
||||||
},
|
},
|
||||||
scroll: function() {
|
scroll: function() {
|
||||||
@ -3530,10 +3543,9 @@
|
|||||||
init: function() {
|
init: function() {
|
||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
var thumb;
|
if (!post.img) return;
|
||||||
if (!(thumb = $('img[md5]', root))) return;
|
return $.on(post.img, 'mouseover', imgHover.mouseover);
|
||||||
return $.on(thumb, 'mouseover', imgHover.mouseover);
|
|
||||||
},
|
},
|
||||||
mouseover: function() {
|
mouseover: function() {
|
||||||
ui.el = $.el('img', {
|
ui.el = $.el('img', {
|
||||||
@ -3565,14 +3577,14 @@
|
|||||||
init: function() {
|
init: function() {
|
||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
var img, src, thumb;
|
var img, src;
|
||||||
if (root.hidden || !(thumb = $('img[md5]', root))) return;
|
if (post.root.hidden || post.img) return;
|
||||||
src = thumb.parentNode.href;
|
src = post.img.parentNode.href;
|
||||||
if (/gif$/.test(src) && !/spoiler/.test(src)) {
|
if (/gif$/.test(src) && !/spoiler/.test(src)) {
|
||||||
img = $.el('img');
|
img = $.el('img');
|
||||||
$.on(img, 'load', function() {
|
$.on(img, 'load', function() {
|
||||||
return thumb.src = src;
|
return post.img.src = src;
|
||||||
});
|
});
|
||||||
return img.src = src;
|
return img.src = src;
|
||||||
}
|
}
|
||||||
@ -3584,12 +3596,12 @@
|
|||||||
g.callbacks.push(this.node);
|
g.callbacks.push(this.node);
|
||||||
return imgExpand.dialog();
|
return imgExpand.dialog();
|
||||||
},
|
},
|
||||||
node: function(root) {
|
node: function(post) {
|
||||||
var a, thumb;
|
var a;
|
||||||
if (!(thumb = $('img[md5]', root))) return;
|
if (!post.img) return;
|
||||||
a = thumb.parentNode;
|
a = post.img.parentNode;
|
||||||
$.on(a, 'click', imgExpand.cb.toggle);
|
$.on(a, 'click', imgExpand.cb.toggle);
|
||||||
if (imgExpand.on && !root.hidden && root.className !== 'inline') {
|
if (imgExpand.on && !post.root.hidden && post["class"] !== 'inline') {
|
||||||
return imgExpand.expand(a.firstChild);
|
return imgExpand.expand(a.firstChild);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -3814,9 +3826,8 @@
|
|||||||
if (conf['Quote Inline']) quoteInline.init();
|
if (conf['Quote Inline']) quoteInline.init();
|
||||||
if (conf['Quote Preview']) quotePreview.init();
|
if (conf['Quote Preview']) quotePreview.init();
|
||||||
if (conf['Quote Backlinks']) quoteBacklink.init();
|
if (conf['Quote Backlinks']) quoteBacklink.init();
|
||||||
if (conf['Indicate OP quote'] || conf['Indicate Cross-thread Quotes']) {
|
if (conf['Indicate OP quote']) quoteOP.init();
|
||||||
quoteIndicators.init();
|
if (conf['Indicate Cross-thread Quotes']) quoteDR.init();
|
||||||
}
|
|
||||||
return $.ready(Main.ready);
|
return $.ready(Main.ready);
|
||||||
},
|
},
|
||||||
ready: function() {
|
ready: function() {
|
||||||
@ -3880,14 +3891,33 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
node: function(nodes, notify) {
|
node: function(nodes, notify) {
|
||||||
var callback, node, _i, _j, _len, _len2, _ref;
|
var callback, klass, node, post, posts, _i, _j, _k, _len, _len2, _len3, _ref;
|
||||||
|
posts = [];
|
||||||
|
for (_i = 0, _len = nodes.length; _i < _len; _i++) {
|
||||||
|
node = nodes[_i];
|
||||||
|
klass = node.className;
|
||||||
|
posts.push({
|
||||||
|
root: node,
|
||||||
|
el: klass === 'op' ? node : $('td[id]', node),
|
||||||
|
"class": klass,
|
||||||
|
id: $('input', node).name,
|
||||||
|
threadId: g.THREAD_ID || $.x('ancestor::div[contains(@class,"thread")]', node).firstChild.id,
|
||||||
|
isOP: klass === 'op',
|
||||||
|
isInlined: /\binlined\b/.test(klass),
|
||||||
|
filesize: $('.filesize', node),
|
||||||
|
img: $('img[md5]', node),
|
||||||
|
quotes: $$('.quotelink', node),
|
||||||
|
backlinks: $$('.backlink', node),
|
||||||
|
bq: node.lastChild
|
||||||
|
});
|
||||||
|
}
|
||||||
_ref = g.callbacks;
|
_ref = g.callbacks;
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) {
|
||||||
callback = _ref[_i];
|
callback = _ref[_j];
|
||||||
try {
|
try {
|
||||||
for (_j = 0, _len2 = nodes.length; _j < _len2; _j++) {
|
for (_k = 0, _len3 = posts.length; _k < _len3; _k++) {
|
||||||
node = nodes[_j];
|
post = posts[_k];
|
||||||
callback(node);
|
callback(post);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (notify) {
|
if (notify) {
|
||||||
|
|||||||
244
script.coffee
244
script.coffee
@ -499,7 +499,8 @@ filter =
|
|||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
|
|
||||||
createFilter: (regexp, op, hl, top) ->
|
createFilter: (regexp, op, hl, top) ->
|
||||||
(root, value, isOP) ->
|
(post, value) ->
|
||||||
|
{el, isOP} = post
|
||||||
if isOP and op is 'no' or !isOP and op is 'only'
|
if isOP and op is 'no' or !isOP and op is 'only'
|
||||||
return false
|
return false
|
||||||
if typeof regexp is 'string'
|
if typeof regexp is 'string'
|
||||||
@ -510,12 +511,12 @@ filter =
|
|||||||
return false
|
return false
|
||||||
if hl
|
if hl
|
||||||
if isOP
|
if isOP
|
||||||
$.addClass root, hl
|
$.addClass el, hl
|
||||||
else
|
else
|
||||||
$.addClass root.parentNode, hl
|
$.addClass el.parentNode, hl
|
||||||
if isOP and top and not g.REPLY
|
if isOP and top and not g.REPLY
|
||||||
# Put the highlighted OPs' threads on top of the board pages...
|
# Put the highlighted OPs' threads on top of the board pages...
|
||||||
thisThread = root.parentNode
|
thisThread = el.parentNode
|
||||||
# ...before the first non highlighted thread.
|
# ...before the first non highlighted thread.
|
||||||
if firstThread = $ 'div[class=op]'
|
if firstThread = $ 'div[class=op]'
|
||||||
$.before firstThread.parentNode, [thisThread, thisThread.nextElementSibling]
|
$.before firstThread.parentNode, [thisThread, thisThread.nextElementSibling]
|
||||||
@ -523,78 +524,76 @@ filter =
|
|||||||
return false
|
return false
|
||||||
if isOP
|
if isOP
|
||||||
unless g.REPLY
|
unless g.REPLY
|
||||||
threadHiding.hideHide root.parentNode
|
threadHiding.hideHide el.parentNode
|
||||||
else
|
else
|
||||||
replyHiding.hideHide root
|
replyHiding.hideHide el
|
||||||
true
|
true
|
||||||
|
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
klass = root.className
|
return if post.isInlined
|
||||||
return if /\binlined\b/.test klass
|
|
||||||
unless isOP = klass is 'op'
|
|
||||||
root = $ 'td[id]', root
|
|
||||||
for key of filter.filters
|
for key of filter.filters
|
||||||
value = filter[key] root, isOP
|
value = filter[key] post
|
||||||
if value is false
|
if value is false
|
||||||
# Continue if there's nothing to filter (no tripcode for example).
|
# Continue if there's nothing to filter (no tripcode for example).
|
||||||
continue
|
continue
|
||||||
for Filter in filter.filters[key]
|
for Filter in filter.filters[key]
|
||||||
if Filter root, value, isOP
|
if Filter post, value
|
||||||
return
|
return
|
||||||
|
|
||||||
name: (root, isOP) ->
|
name: (post) ->
|
||||||
name = if isOP then $ '.postername', root else $ '.commentpostername', root
|
name = if post.isOP then $ '.postername', post.el else $ '.commentpostername', post.el
|
||||||
name.textContent
|
name.textContent
|
||||||
tripcode: (root) ->
|
tripcode: (post) ->
|
||||||
if trip = $ '.postertrip', root
|
if trip = $ '.postertrip', post.el
|
||||||
return trip.textContent
|
return trip.textContent
|
||||||
false
|
false
|
||||||
mod: (root, isOP) ->
|
mod: (post) ->
|
||||||
if mod = (if isOP then $ '.commentpostername', root else $ '.commentpostername ~ .commentpostername', root)
|
if mod = (if post.isOP then $ '.commentpostername', post.el else $ '.commentpostername ~ .commentpostername', post.el)
|
||||||
return mod.textContent
|
return mod.textContent
|
||||||
false
|
false
|
||||||
email: (root) ->
|
email: (post) ->
|
||||||
if mail = $ '.linkmail', root
|
if mail = $ '.linkmail', post.el
|
||||||
return mail.href
|
return mail.href
|
||||||
false
|
false
|
||||||
subject: (root, isOP) ->
|
subject: (post) ->
|
||||||
sub = if isOP then $ '.filetitle', root else $ '.replytitle', root
|
sub = if post.isOP then $ '.filetitle', post.el else $ '.replytitle', post.el
|
||||||
sub.textContent
|
sub.textContent
|
||||||
comment: (root) ->
|
comment: (post) ->
|
||||||
text = []
|
text = []
|
||||||
# XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE is 7
|
# XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE is 7
|
||||||
nodes = d.evaluate './/br|.//text()', root.lastChild, null, 7, null
|
nodes = d.evaluate './/br|.//text()', post.bq, null, 7, null
|
||||||
i = 0
|
for i in [0...nodes.snapshotLength]
|
||||||
len = nodes.snapshotLength
|
text.push if data = nodes.snapshotItem(i).data then data else '\n'
|
||||||
while i < len
|
|
||||||
text.push if data = nodes.snapshotItem(i++).data then data else '\n'
|
|
||||||
text.join ''
|
text.join ''
|
||||||
filename: (root) ->
|
filename: (post) ->
|
||||||
if file = $ '.filesize > span', root
|
if file = $ 'span', post.filesize
|
||||||
return file.title
|
return file.title
|
||||||
false
|
false
|
||||||
dimensions: (root) ->
|
dimensions: (post) ->
|
||||||
if (span = $ '.filesize', root) and match = span.textContent.match /\d+x\d+/
|
{filesize} = post
|
||||||
|
if filesize and match = filesize.textContent.match /\d+x\d+/
|
||||||
return match[0]
|
return match[0]
|
||||||
return false
|
return false
|
||||||
filesize: (root) ->
|
filesize: (post) ->
|
||||||
if img = $ 'img[md5]', root
|
{img} = post
|
||||||
|
if img
|
||||||
return img.alt
|
return img.alt
|
||||||
false
|
false
|
||||||
md5: (root) ->
|
md5: (post) ->
|
||||||
if img = $ 'img[md5]', root
|
{img} = post
|
||||||
|
if img
|
||||||
return img.getAttribute 'md5'
|
return img.getAttribute 'md5'
|
||||||
false
|
false
|
||||||
|
|
||||||
strikethroughQuotes =
|
strikethroughQuotes =
|
||||||
init: ->
|
init: ->
|
||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
return if root.className is 'inline'
|
return if post.isInlined
|
||||||
for quote in $$ '.quotelink', root
|
for quote in post.quotes
|
||||||
if (el = $.id quote.hash[1..]) and el.parentNode.parentNode.parentNode.hidden
|
if (el = $.id quote.hash[1..]) and el.parentNode.parentNode.parentNode.hidden
|
||||||
$.addClass quote, 'filtered'
|
$.addClass quote, 'filtered'
|
||||||
root.hidden = true if conf['Recursive Filtering']
|
post.root.hidden = true if conf['Recursive Filtering']
|
||||||
return
|
return
|
||||||
|
|
||||||
expandComment =
|
expandComment =
|
||||||
@ -711,8 +710,9 @@ replyHiding =
|
|||||||
init: ->
|
init: ->
|
||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
|
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
return unless dd = $ '.doubledash', root
|
return if post.class
|
||||||
|
dd = $ '.doubledash', post.root
|
||||||
dd.className = 'replyhider'
|
dd.className = 'replyhider'
|
||||||
a = $.el 'a',
|
a = $.el 'a',
|
||||||
textContent: '[ - ]'
|
textContent: '[ - ]'
|
||||||
@ -755,8 +755,8 @@ replyHiding =
|
|||||||
|
|
||||||
if conf['Show Stubs']
|
if conf['Show Stubs']
|
||||||
name = $('.commentpostername', reply).textContent
|
name = $('.commentpostername', reply).textContent
|
||||||
uid = $('.posteruid', reply)?.textContent or ''
|
uid = $('.posteruid', reply)?.textContent or ''
|
||||||
trip = $('.postertrip', reply)?.textContent or ''
|
trip = $('.postertrip', reply)?.textContent or ''
|
||||||
|
|
||||||
div = $.el 'div',
|
div = $.el 'div',
|
||||||
className: 'stub'
|
className: 'stub'
|
||||||
@ -1037,8 +1037,8 @@ qr =
|
|||||||
$.on d, 'dragstart', qr.drag
|
$.on d, 'dragstart', qr.drag
|
||||||
$.on d, 'dragend', qr.drag
|
$.on d, 'dragend', qr.drag
|
||||||
|
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
$.on $('.quotejs + .quotejs', root), 'click', qr.quote
|
$.on $('.quotejs + .quotejs', post.el), 'click', qr.quote
|
||||||
|
|
||||||
open: ->
|
open: ->
|
||||||
if qr.el
|
if qr.el
|
||||||
@ -2264,10 +2264,10 @@ watcher =
|
|||||||
anonymize =
|
anonymize =
|
||||||
init: ->
|
init: ->
|
||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
name = $ '.commentpostername, .postername', root
|
name = $ '.commentpostername, .postername', post.el
|
||||||
name.textContent = 'Anonymous'
|
name.textContent = 'Anonymous'
|
||||||
if trip = $ '.postertrip', root
|
if trip = $ '.postertrip', post.el
|
||||||
if trip.parentNode.nodeName is 'A'
|
if trip.parentNode.nodeName is 'A'
|
||||||
$.rm trip.parentNode
|
$.rm trip.parentNode
|
||||||
else
|
else
|
||||||
@ -2302,19 +2302,22 @@ sauce =
|
|||||||
target: '_blank'
|
target: '_blank'
|
||||||
textContent: domain
|
textContent: domain
|
||||||
|
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
return if root.className is 'inline' or not span = $ '.filesize', root
|
{img} = post
|
||||||
img = span.nextElementSibling.nextElementSibling
|
return if post.class is 'inline' or not img
|
||||||
|
img = img.parentNode
|
||||||
nodes = []
|
nodes = []
|
||||||
for link in sauce.links
|
for link in sauce.links
|
||||||
nodes.push $.tn(' '), link img
|
nodes.push $.tn(' '), link img
|
||||||
$.add span, nodes
|
$.add post.filesize, nodes
|
||||||
|
|
||||||
revealSpoilers =
|
revealSpoilers =
|
||||||
init: ->
|
init: ->
|
||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
return if not (img = $ 'img[alt^=Spoil]', root) or root.className is 'inline'
|
img = {post}
|
||||||
|
if not (img and /^Spoil/.test img.alt) or post.class is 'inline'
|
||||||
|
return
|
||||||
img.removeAttribute 'height'
|
img.removeAttribute 'height'
|
||||||
img.removeAttribute 'width'
|
img.removeAttribute 'width'
|
||||||
img.src = "http://thumbs.4chan.org#{img.parentNode.pathname.replace(/src(\/\d+).+$/, 'thumb$1s.jpg')}"
|
img.src = "http://thumbs.4chan.org#{img.parentNode.pathname.replace(/src(\/\d+).+$/, 'thumb$1s.jpg')}"
|
||||||
@ -2341,10 +2344,10 @@ Time =
|
|||||||
new Date year, month, day, hour, min
|
new Date year, month, day, hour, min
|
||||||
|
|
||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
return if root.className is 'inline'
|
return if post.class is 'inline'
|
||||||
# .posttime exists on every board except /f/
|
# .posttime exists on every board except /f/
|
||||||
node = $('.posttime', root) or $('span[id]', root).previousSibling
|
node = $('.posttime', post.el) or $('span[id]', post.el).previousSibling
|
||||||
Time.date = Time.parse node
|
Time.date = Time.parse node
|
||||||
time = $.el 'time',
|
time = $.el 'time',
|
||||||
textContent: ' ' + Time.funk(Time) + ' '
|
textContent: ' ' + Time.funk(Time) + ' '
|
||||||
@ -2402,8 +2405,8 @@ FileInfo =
|
|||||||
return if g.BOARD is 'f'
|
return if g.BOARD is 'f'
|
||||||
@setFormats()
|
@setFormats()
|
||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
return if root.className is 'inline' or not node = $ '.filesize', root
|
return if post.class is 'inline' or not node = post.filesize
|
||||||
type = if node.childElementCount is 2 then 0 else 1
|
type = if node.childElementCount is 2 then 0 else 1
|
||||||
regexp =
|
regexp =
|
||||||
if type
|
if type
|
||||||
@ -2484,20 +2487,18 @@ quoteBacklink =
|
|||||||
format = conf['backlink'].replace /%id/g, "' + id + '"
|
format = conf['backlink'].replace /%id/g, "' + id + '"
|
||||||
quoteBacklink.funk = Function 'id', "return '#{format}'"
|
quoteBacklink.funk = Function 'id', "return '#{format}'"
|
||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
return if /\binline\b/.test root.className
|
return if post.isInlined
|
||||||
quotes = {}
|
quotes = {}
|
||||||
for quote in $$ '.quotelink', root
|
for quote in post.quotes
|
||||||
# Don't process >>>/b/.
|
# Don't process >>>/b/.
|
||||||
if qid = quote.hash[1..]
|
if qid = quote.hash[1..]
|
||||||
# Duplicate quotes get overwritten.
|
# Duplicate quotes get overwritten.
|
||||||
quotes[qid] = true
|
quotes[qid] = true
|
||||||
# OP or reply id.
|
|
||||||
id = $('input', root).name
|
|
||||||
a = $.el 'a',
|
a = $.el 'a',
|
||||||
href: "##{id}"
|
href: "##{post.id}"
|
||||||
className: if root.hidden then 'filtered backlink' else 'backlink'
|
className: if post.root.hidden then 'filtered backlink' else 'backlink'
|
||||||
textContent: quoteBacklink.funk id
|
textContent: quoteBacklink.funk post.id
|
||||||
for qid of quotes
|
for qid of quotes
|
||||||
# Don't backlink the OP.
|
# Don't backlink the OP.
|
||||||
continue if !(el = $.id qid) or el.className is 'op' and !conf['OP Backlinks']
|
continue if !(el = $.id qid) or el.className is 'op' and !conf['OP Backlinks']
|
||||||
@ -2516,8 +2517,8 @@ quoteBacklink =
|
|||||||
quoteInline =
|
quoteInline =
|
||||||
init: ->
|
init: ->
|
||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
for quote in $$ '.quotelink, .backlink', root
|
for quote in post.quotes.concat post.backlinks
|
||||||
continue unless quote.hash
|
continue unless quote.hash
|
||||||
quote.removeAttribute 'onclick'
|
quote.removeAttribute 'onclick'
|
||||||
$.on quote, 'click', quoteInline.toggle
|
$.on quote, 'click', quoteInline.toggle
|
||||||
@ -2608,8 +2609,8 @@ quoteInline =
|
|||||||
quotePreview =
|
quotePreview =
|
||||||
init: ->
|
init: ->
|
||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
for quote in $$ '.quotelink, .backlink', root
|
for quote in post.quotes.concat post.backlinks
|
||||||
$.on quote, 'mouseover', quotePreview.mouseover if quote.hash
|
$.on quote, 'mouseover', quotePreview.mouseover if quote.hash
|
||||||
return
|
return
|
||||||
mouseover: (e) ->
|
mouseover: (e) ->
|
||||||
@ -2668,23 +2669,29 @@ quotePreview =
|
|||||||
if conf['File Info Formatting']
|
if conf['File Info Formatting']
|
||||||
FileInfo.node qp
|
FileInfo.node qp
|
||||||
|
|
||||||
quoteIndicators =
|
quoteOP =
|
||||||
init: ->
|
init: ->
|
||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
return if root.className is 'inline'
|
return if post.class is 'inline'
|
||||||
# We use contains() so that it works with hidden threads
|
for quote in post.quotes
|
||||||
tid = g.THREAD_ID or $.x('ancestor::div[contains(@class,"thread")]', root).firstChild.id
|
if quote.hash[1..] is post.threadId
|
||||||
for quote in $$ '.quotelink', root
|
|
||||||
unless hash = quote.hash[1..]
|
|
||||||
continue
|
|
||||||
if conf['Indicate OP quote'] and hash is tid
|
|
||||||
# \u00A0 is nbsp
|
# \u00A0 is nbsp
|
||||||
$.add quote, $.tn '\u00A0(OP)'
|
$.add quote, $.tn '\u00A0(OP)'
|
||||||
|
return
|
||||||
|
|
||||||
|
quoteDR =
|
||||||
|
init: ->
|
||||||
|
g.callbacks.push @node
|
||||||
|
node: (post) ->
|
||||||
|
return if post.class is 'inline'
|
||||||
|
for quote in post.quotes
|
||||||
|
unless quote.hash
|
||||||
|
# Make sure this isn't a link to the board we're on.
|
||||||
continue
|
continue
|
||||||
path = quote.pathname
|
path = quote.pathname.split '/'
|
||||||
#if quote leads to a different thread id and is located on the same board (index 0)
|
# If quote leads to a different thread id and is located on the same board.
|
||||||
if conf['Indicate Cross-thread Quotes'] and path.lastIndexOf("/#{tid}") is -1 and path.indexOf("/#{g.BOARD}/") is 0
|
if path[1] is g.BOARD and path[3] isnt post.threadId
|
||||||
# \u00A0 is nbsp
|
# \u00A0 is nbsp
|
||||||
$.add quote, $.tn '\u00A0(Cross-thread)'
|
$.add quote, $.tn '\u00A0(Cross-thread)'
|
||||||
return
|
return
|
||||||
@ -2692,14 +2699,13 @@ quoteIndicators =
|
|||||||
reportButton =
|
reportButton =
|
||||||
init: ->
|
init: ->
|
||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
if not a = $ '.reportbutton', root
|
if not a = $ '.reportbutton', post.el
|
||||||
span = $ 'span[id]', root
|
|
||||||
a = $.el 'a',
|
a = $.el 'a',
|
||||||
className: 'reportbutton'
|
className: 'reportbutton'
|
||||||
innerHTML: '[ ! ]'
|
innerHTML: '[ ! ]'
|
||||||
href: 'javascript:;'
|
href: 'javascript:;'
|
||||||
$.after span, [$.tn(' '), a]
|
$.after $('span[id]', post.el), [$.tn(' '), a]
|
||||||
$.on a, 'click', reportButton.report
|
$.on a, 'click', reportButton.report
|
||||||
report: ->
|
report: ->
|
||||||
url = "http://sys.4chan.org/#{g.BOARD}/imgboard.php?mode=report&no=#{$.x('preceding-sibling::input', @).name}"
|
url = "http://sys.4chan.org/#{g.BOARD}/imgboard.php?mode=report&no=#{$.x('preceding-sibling::input', @).name}"
|
||||||
@ -2722,10 +2728,10 @@ threadStats =
|
|||||||
else
|
else
|
||||||
151
|
151
|
||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
return if /\binline\b/.test root.className
|
return if post.isInlined
|
||||||
$.id('postcount').textContent = ++threadStats.posts
|
$.id('postcount').textContent = ++threadStats.posts
|
||||||
return unless $ 'img[md5]', root
|
return unless post.img
|
||||||
imgcount = $.id 'imagecount'
|
imgcount = $.id 'imagecount'
|
||||||
imgcount.textContent = ++threadStats.images
|
imgcount.textContent = ++threadStats.images
|
||||||
if threadStats.images > threadStats.imgLimit
|
if threadStats.images > threadStats.imgLimit
|
||||||
@ -2740,9 +2746,9 @@ unread =
|
|||||||
|
|
||||||
replies: []
|
replies: []
|
||||||
|
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
return if root.hidden or root.className
|
return if post.root.hidden or post.class
|
||||||
unread.replies.push root
|
unread.replies.push post.root
|
||||||
unread.update()
|
unread.update()
|
||||||
|
|
||||||
scroll: ->
|
scroll: ->
|
||||||
@ -2848,9 +2854,9 @@ redirect =
|
|||||||
imgHover =
|
imgHover =
|
||||||
init: ->
|
init: ->
|
||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
return unless thumb = $ 'img[md5]', root
|
return unless post.img
|
||||||
$.on thumb, 'mouseover', imgHover.mouseover
|
$.on post.img, 'mouseover', imgHover.mouseover
|
||||||
mouseover: ->
|
mouseover: ->
|
||||||
ui.el = $.el 'img'
|
ui.el = $.el 'img'
|
||||||
id: 'ihover'
|
id: 'ihover'
|
||||||
@ -2874,14 +2880,14 @@ imgHover =
|
|||||||
imgGif =
|
imgGif =
|
||||||
init: ->
|
init: ->
|
||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
return if root.hidden or !thumb = $ 'img[md5]', root
|
return if post.root.hidden or post.img
|
||||||
src = thumb.parentNode.href
|
src = post.img.parentNode.href
|
||||||
if /gif$/.test(src) and !/spoiler/.test src
|
if /gif$/.test(src) and !/spoiler/.test src
|
||||||
img = $.el 'img'
|
img = $.el 'img'
|
||||||
$.on img, 'load', ->
|
$.on img, 'load', ->
|
||||||
# Replace the thumbnail once the GIF has finished loading.
|
# Replace the thumbnail once the GIF has finished loading.
|
||||||
thumb.src = src
|
post.img.src = src
|
||||||
img.src = src
|
img.src = src
|
||||||
|
|
||||||
imgExpand =
|
imgExpand =
|
||||||
@ -2889,11 +2895,11 @@ imgExpand =
|
|||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
imgExpand.dialog()
|
imgExpand.dialog()
|
||||||
|
|
||||||
node: (root) ->
|
node: (post) ->
|
||||||
return unless thumb = $ 'img[md5]', root
|
return unless post.img
|
||||||
a = thumb.parentNode
|
a = post.img.parentNode
|
||||||
$.on a, 'click', imgExpand.cb.toggle
|
$.on a, 'click', imgExpand.cb.toggle
|
||||||
if imgExpand.on and !root.hidden and root.className isnt 'inline'
|
if imgExpand.on and !post.root.hidden and post.class isnt 'inline'
|
||||||
imgExpand.expand a.firstChild
|
imgExpand.expand a.firstChild
|
||||||
cb:
|
cb:
|
||||||
toggle: (e) ->
|
toggle: (e) ->
|
||||||
@ -3103,8 +3109,11 @@ Main =
|
|||||||
if conf['Quote Backlinks']
|
if conf['Quote Backlinks']
|
||||||
quoteBacklink.init()
|
quoteBacklink.init()
|
||||||
|
|
||||||
if conf['Indicate OP quote'] or conf['Indicate Cross-thread Quotes']
|
if conf['Indicate OP quote']
|
||||||
quoteIndicators.init()
|
quoteOP.init()
|
||||||
|
|
||||||
|
if conf['Indicate Cross-thread Quotes']
|
||||||
|
quoteDR.init()
|
||||||
|
|
||||||
$.ready Main.ready
|
$.ready Main.ready
|
||||||
|
|
||||||
@ -3162,7 +3171,6 @@ Main =
|
|||||||
if conf['Index Navigation']
|
if conf['Index Navigation']
|
||||||
nav.init()
|
nav.init()
|
||||||
|
|
||||||
|
|
||||||
nodes = $$ '.op, a + table', form
|
nodes = $$ '.op, a + table', form
|
||||||
Main.node nodes, true
|
Main.node nodes, true
|
||||||
|
|
||||||
@ -3191,9 +3199,25 @@ Main =
|
|||||||
window.location = "https://raw.github.com/mayhemydg/4chan-x/#{version}/4chan_x.user.js"
|
window.location = "https://raw.github.com/mayhemydg/4chan-x/#{version}/4chan_x.user.js"
|
||||||
|
|
||||||
node: (nodes, notify) ->
|
node: (nodes, notify) ->
|
||||||
|
posts = []
|
||||||
|
for node in nodes
|
||||||
|
klass = node.className
|
||||||
|
posts.push
|
||||||
|
root: node
|
||||||
|
el: if klass is 'op' then node else $ 'td[id]', node
|
||||||
|
class: klass
|
||||||
|
id: $('input', node).name
|
||||||
|
threadId: g.THREAD_ID or $.x('ancestor::div[contains(@class,"thread")]', node).firstChild.id
|
||||||
|
isOP: klass is 'op'
|
||||||
|
isInlined: /\binlined\b/.test klass
|
||||||
|
filesize: $ '.filesize', node
|
||||||
|
img: $ 'img[md5]', node
|
||||||
|
quotes: $$ '.quotelink', node
|
||||||
|
backlinks: $$ '.backlink', node
|
||||||
|
bq: node.lastChild
|
||||||
for callback in g.callbacks
|
for callback in g.callbacks
|
||||||
try
|
try
|
||||||
callback node for node in nodes
|
callback post for post in posts
|
||||||
catch err
|
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 error: #{err.message}\nhttp://mayhemydg.github.com/4chan-x/#bug-report\n\n#{err.stack}" if notify
|
||||||
return
|
return
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user