Merge branch 'master' into quotify
This commit is contained in:
commit
e3fe3f6606
420
4chan_x.user.js
420
4chan_x.user.js
@ -73,7 +73,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var $, $$, Anonymize, AutoGif, DAY, DeadQuotes, ExpandComment, ExpandThread, Favicon, FileInfo, Filter, GetTitle, HOUR, ImageExpand, ImageHover, Keybinds, MINUTE, Main, NAMESPACE, Nav, Options, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, Redirect, ReplyHiding, ReportButton, RevealSpoilers, SECOND, Sauce, StrikethroughQuotes, ThreadHiding, ThreadStats, Threading, Time, TitlePost, Unread, Updater, VERSION, Watcher, conf, config, d, engine, flatten, g, key, log, qr, ui, val, _base;
|
var $, $$, Anonymize, AutoGif, DAY, DeadQuotes, ExpandComment, ExpandThread, Favicon, FileInfo, Filter, GetTitle, HOUR, ImageExpand, ImageHover, Keybinds, MINUTE, Main, NAMESPACE, Nav, Options, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, Redirect, ReplyHiding, ReportButton, RevealSpoilers, SECOND, Sauce, StrikethroughQuotes, ThreadHiding, ThreadStats, Threading, Time, TitlePost, Unread, Updater, VERSION, Watcher, conf, config, d, engine, flatten, g, log, qr, ui, _base;
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
main: {
|
main: {
|
||||||
@ -387,7 +387,7 @@
|
|||||||
return conf[this.name] = this.checked;
|
return conf[this.name] = this.checked;
|
||||||
},
|
},
|
||||||
value: function() {
|
value: function() {
|
||||||
$.set(this.name, this.value);
|
$.set(this.name, this.value.trim());
|
||||||
return conf[this.name] = this.value;
|
return conf[this.name] = this.value;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -417,7 +417,7 @@
|
|||||||
},
|
},
|
||||||
nodes: function(nodes) {
|
nodes: function(nodes) {
|
||||||
var frag, node, _i, _len;
|
var frag, node, _i, _len;
|
||||||
if (!(nodes instanceof Array)) return nodes;
|
if (nodes instanceof Node) return nodes;
|
||||||
frag = d.createDocumentFragment();
|
frag = d.createDocumentFragment();
|
||||||
for (_i = 0, _len = nodes.length; _i < _len; _i++) {
|
for (_i = 0, _len = nodes.length; _i < _len; _i++) {
|
||||||
node = nodes[_i];
|
node = nodes[_i];
|
||||||
@ -535,11 +535,6 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for (key in conf) {
|
|
||||||
val = conf[key];
|
|
||||||
conf[key] = $.get(key, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
$$ = function(selector, root) {
|
$$ = function(selector, root) {
|
||||||
if (root == null) root = d.body;
|
if (root == null) root = d.body;
|
||||||
return Array.prototype.slice.call(root.querySelectorAll(selector));
|
return Array.prototype.slice.call(root.querySelectorAll(selector));
|
||||||
@ -611,12 +606,12 @@
|
|||||||
if (result === true) {
|
if (result === true) {
|
||||||
if (isOP) {
|
if (isOP) {
|
||||||
if (!g.REPLY) {
|
if (!g.REPLY) {
|
||||||
ThreadHiding.hideHide(post.el.parentNode);
|
ThreadHiding.hide(post.el.parentNode);
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ReplyHiding.hideHide(post.el);
|
ReplyHiding.hide(post.root);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -715,7 +710,7 @@
|
|||||||
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']) post.root.hidden = true;
|
if (conf['Recursive Filtering']) ReplyHiding.hide(post.root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -742,34 +737,22 @@
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
parse: function(req, a, threadID, replyID) {
|
parse: function(req, a, threadID, replyID) {
|
||||||
var body, bq, post, quote, quotes, reply, _i, _j, _len, _len2, _ref;
|
var bq, doc, post, quote, quotes, _i, _len;
|
||||||
if (req.status !== 200) {
|
if (req.status !== 200) {
|
||||||
a.textContent = "" + req.status + " " + req.statusText;
|
a.textContent = "" + req.status + " " + req.statusText;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
body = $.el('body', {
|
doc = d.implementation.createHTMLDocument(null);
|
||||||
innerHTML: req.responseText
|
doc.documentElement.innerHTML = req.responseText;
|
||||||
});
|
bq = threadID === replyID ? $('blockquote', doc) : $('blockquote', doc.getElementById(replyID));
|
||||||
if (threadID === replyID) {
|
$.replace(a.parentNode.parentNode, bq);
|
||||||
bq = $('blockquote', body);
|
|
||||||
} else {
|
|
||||||
_ref = $$('td[id]', body);
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
reply = _ref[_i];
|
|
||||||
if (reply.id === replyID) {
|
|
||||||
bq = $('blockquote', reply);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
quotes = $$('.quotelink', bq);
|
quotes = $$('.quotelink', bq);
|
||||||
for (_j = 0, _len2 = quotes.length; _j < _len2; _j++) {
|
for (_i = 0, _len = quotes.length; _i < _len; _i++) {
|
||||||
quote = quotes[_j];
|
quote = quotes[_i];
|
||||||
if (quote.getAttribute('href') === quote.hash) {
|
if (quote.getAttribute('href') === quote.hash) {
|
||||||
quote.pathname = "/" + g.BOARD + "/res/" + threadID;
|
quote.pathname = "/" + g.BOARD + "/res/" + threadID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$.replace(a.parentNode.parentNode, bq);
|
|
||||||
post = {
|
post = {
|
||||||
threadId: threadID,
|
threadId: threadID,
|
||||||
quotes: quotes,
|
quotes: quotes,
|
||||||
@ -890,76 +873,61 @@
|
|||||||
|
|
||||||
ReplyHiding = {
|
ReplyHiding = {
|
||||||
init: function() {
|
init: function() {
|
||||||
this.a = $.el('a', {
|
this.td = $.el('td', {
|
||||||
textContent: '[ - ]',
|
noWrap: true,
|
||||||
href: 'javascript:;'
|
className: 'replyhider',
|
||||||
|
innerHTML: '<a href="javascript:;">[ - ]</a>'
|
||||||
});
|
});
|
||||||
return g.callbacks.push(this.node);
|
return g.callbacks.push(this.node);
|
||||||
},
|
},
|
||||||
node: function(post) {
|
node: function(post) {
|
||||||
var a, dd;
|
var td;
|
||||||
if (post["class"]) return;
|
if (post["class"]) return;
|
||||||
dd = post.el.previousSibling;
|
td = ReplyHiding.td.cloneNode(true);
|
||||||
dd.className = 'replyhider';
|
$.on(td.firstChild, 'click', ReplyHiding.toggle);
|
||||||
a = ReplyHiding.a.cloneNode(true);
|
$.replace(post.el.previousSibling, td);
|
||||||
$.on(a, 'click', ReplyHiding.cb.hide);
|
if (post.id in g.hiddenReplies) return ReplyHiding.hide(post.root);
|
||||||
$.replace(dd.firstChild, a);
|
|
||||||
if (post.id in g.hiddenReplies) return ReplyHiding.hide(post.el);
|
|
||||||
},
|
},
|
||||||
cb: {
|
toggle: function() {
|
||||||
hide: function() {
|
var id, parent, quote, table, _i, _j, _len, _len2, _ref, _ref2;
|
||||||
var reply;
|
parent = this.parentNode;
|
||||||
reply = this.parentNode.nextSibling;
|
if (parent.className === 'replyhider') {
|
||||||
return ReplyHiding.hide(reply);
|
ReplyHiding.hide(parent.parentNode.parentNode.parentNode);
|
||||||
},
|
id = parent.nextSibling.id;
|
||||||
show: function() {
|
_ref = $$(".quotelink[href='#" + id + "'], .backlink[href='#" + id + "']");
|
||||||
var div, table;
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
div = this.parentNode;
|
quote = _ref[_i];
|
||||||
table = div.nextSibling;
|
$.addClass(quote, 'filtered');
|
||||||
ReplyHiding.show(table);
|
}
|
||||||
return $.rm(div);
|
g.hiddenReplies[id] = Date.now();
|
||||||
|
} else {
|
||||||
|
table = parent.nextSibling;
|
||||||
|
table.hidden = false;
|
||||||
|
$.rm(parent);
|
||||||
|
id = table.firstChild.firstChild.lastChild.id;
|
||||||
|
_ref2 = $$(".quotelink[href='#" + id + "'], .backlink[href='#" + id + "']");
|
||||||
|
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
|
||||||
|
quote = _ref2[_j];
|
||||||
|
$.removeClass(quote, 'filtered');
|
||||||
|
}
|
||||||
|
delete g.hiddenReplies[id];
|
||||||
}
|
}
|
||||||
},
|
|
||||||
hide: function(reply) {
|
|
||||||
var id, quote, _i, _len, _ref;
|
|
||||||
ReplyHiding.hideHide(reply);
|
|
||||||
id = reply.id;
|
|
||||||
_ref = $$(".quotelink[href='#" + id + "'], .backlink[href='#" + id + "']");
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
quote = _ref[_i];
|
|
||||||
$.addClass(quote, 'filtered');
|
|
||||||
}
|
|
||||||
g.hiddenReplies[id] = Date.now();
|
|
||||||
return $.set("hiddenReplies/" + g.BOARD + "/", g.hiddenReplies);
|
return $.set("hiddenReplies/" + g.BOARD + "/", g.hiddenReplies);
|
||||||
},
|
},
|
||||||
hideHide: function(reply) {
|
hide: function(table) {
|
||||||
var div, name, table, trip, uid, _ref, _ref2;
|
var div, name, trip, uid, _ref, _ref2;
|
||||||
table = reply.parentNode.parentNode.parentNode;
|
|
||||||
if (table.hidden) return;
|
if (table.hidden) return;
|
||||||
table.hidden = true;
|
table.hidden = true;
|
||||||
if (conf['Show Stubs']) {
|
if (!conf['Show Stubs']) return;
|
||||||
name = $('.commentpostername', reply).textContent;
|
name = $('td[id] > .commentpostername', table).textContent;
|
||||||
uid = ((_ref = $('.posteruid', reply)) != null ? _ref.textContent : void 0) || '';
|
uid = ((_ref = $('td[id] > .posteruid', table)) != null ? _ref.textContent : void 0) || '';
|
||||||
trip = ((_ref2 = $('.postertrip', reply)) != null ? _ref2.textContent : void 0) || '';
|
trip = ((_ref2 = $('td[id] > .postertrip', table)) != null ? _ref2.textContent : void 0) || '';
|
||||||
div = $.el('div', {
|
div = $.el('div', {
|
||||||
className: 'stub',
|
className: 'stub',
|
||||||
innerHTML: "<a href=javascript:;><span>[ + ]</span> " + name + " " + uid + " " + trip + "</a>"
|
innerHTML: "<a href=javascript:;><span>[ + ]</span> " + name + " " + uid + " " + trip + "</a>"
|
||||||
});
|
});
|
||||||
$.on($('a', div), 'click', ReplyHiding.cb.show);
|
$.on(div.firstChild, 'click', ReplyHiding.toggle);
|
||||||
return $.before(table, div);
|
return $.before(table, div);
|
||||||
}
|
|
||||||
},
|
|
||||||
show: function(table) {
|
|
||||||
var id, quote, _i, _len, _ref;
|
|
||||||
table.hidden = false;
|
|
||||||
id = $('td[id]', table).id;
|
|
||||||
_ref = $$(".quotelink[href='#" + id + "'], .backlink[href='#" + id + "']");
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
quote = _ref[_i];
|
|
||||||
$.removeClass(quote, 'filtered');
|
|
||||||
}
|
|
||||||
delete g.hiddenReplies[id];
|
|
||||||
return $.set("hiddenReplies/" + g.BOARD + "/", g.hiddenReplies);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -974,7 +942,7 @@
|
|||||||
return $.on(d, 'keydown', Keybinds.keydown);
|
return $.on(d, 'keydown', Keybinds.keydown);
|
||||||
},
|
},
|
||||||
keydown: function(e) {
|
keydown: function(e) {
|
||||||
var o, range, selEnd, selStart, ta, thread, value, _ref, _ref2;
|
var key, o, range, selEnd, selStart, ta, thread, value, _ref, _ref2;
|
||||||
if (!(key = Keybinds.keyCode(e)) || /TEXTAREA|INPUT/.test(e.target.nodeName) && !(e.altKey || e.ctrlKey || e.keyCode === 27)) {
|
if (!(key = Keybinds.keyCode(e)) || /TEXTAREA|INPUT/.test(e.target.nodeName) && !(e.altKey || e.ctrlKey || e.keyCode === 27)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1058,7 +1026,7 @@
|
|||||||
Keybinds.hl(-1, thread);
|
Keybinds.hl(-1, thread);
|
||||||
break;
|
break;
|
||||||
case conf.hide:
|
case conf.hide:
|
||||||
ThreadHiding.toggle(thread);
|
if (/\bthread\b/.test(thread.className)) ThreadHiding.toggle(thread);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
@ -1066,7 +1034,7 @@
|
|||||||
return e.preventDefault();
|
return e.preventDefault();
|
||||||
},
|
},
|
||||||
keyCode: function(e) {
|
keyCode: function(e) {
|
||||||
var c, kc;
|
var c, kc, key;
|
||||||
key = (function() {
|
key = (function() {
|
||||||
switch (kc = e.keyCode) {
|
switch (kc = e.keyCode) {
|
||||||
case 8:
|
case 8:
|
||||||
@ -1265,20 +1233,24 @@
|
|||||||
|
|
||||||
qr = {
|
qr = {
|
||||||
init: function() {
|
init: function() {
|
||||||
var form, iframe, link, loadChecking;
|
|
||||||
if (!$.id('recaptcha_challenge_field_holder')) return;
|
if (!$.id('recaptcha_challenge_field_holder')) return;
|
||||||
|
g.callbacks.push(this.node);
|
||||||
|
return setTimeout(this.asyncInit);
|
||||||
|
},
|
||||||
|
asyncInit: function() {
|
||||||
|
var form, iframe, link, loadChecking, script;
|
||||||
if (conf['Hide Original Post Form']) {
|
if (conf['Hide Original Post Form']) {
|
||||||
link = $.el('h1', {
|
link = $.el('h1', {
|
||||||
innerHTML: "<a href=javascript:;>" + (g.REPLY ? 'Quick Reply' : 'New Thread') + "</a>"
|
innerHTML: "<a href=javascript:;>" + (g.REPLY ? 'Quick Reply' : 'New Thread') + "</a>"
|
||||||
});
|
});
|
||||||
$.on($('a', link), 'click', function() {
|
$.on($('a', link), 'click', function() {
|
||||||
qr.open();
|
qr.open();
|
||||||
|
if (!g.REPLY) $('select', qr.el).value = 'new';
|
||||||
return $('textarea', qr.el).focus();
|
return $('textarea', qr.el).focus();
|
||||||
});
|
});
|
||||||
form = d.forms[0];
|
form = d.forms[0];
|
||||||
$.before(form, link);
|
$.before(form, link);
|
||||||
}
|
}
|
||||||
g.callbacks.push(this.node);
|
|
||||||
if (/chrome/i.test(navigator.userAgent)) {
|
if (/chrome/i.test(navigator.userAgent)) {
|
||||||
qr.status({
|
qr.status({
|
||||||
ready: true
|
ready: true
|
||||||
@ -1306,19 +1278,14 @@
|
|||||||
});
|
});
|
||||||
$.add(d.head, iframe);
|
$.add(d.head, iframe);
|
||||||
}
|
}
|
||||||
setTimeout(function() {
|
script = $.el('script', {
|
||||||
var script;
|
textContent: 'Recaptcha.focus_response_field=function(){}'
|
||||||
script = $.el('script', {
|
|
||||||
textContent: 'Recaptcha.focus_response_field=function(){}'
|
|
||||||
});
|
|
||||||
$.add(d.head, script);
|
|
||||||
return $.rm(script);
|
|
||||||
});
|
});
|
||||||
|
$.add(d.head, script);
|
||||||
|
$.rm(script);
|
||||||
if (conf['Persistent QR']) {
|
if (conf['Persistent QR']) {
|
||||||
setTimeout(function() {
|
qr.dialog();
|
||||||
qr.dialog();
|
if (conf['Auto Hide QR']) qr.hide();
|
||||||
if (conf['Auto Hide QR']) return qr.hide();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
$.on(d, 'dragover', qr.dragOver);
|
$.on(d, 'dragover', qr.dragOver);
|
||||||
$.on(d, 'drop', qr.dropFile);
|
$.on(d, 'drop', qr.dropFile);
|
||||||
@ -2374,6 +2341,7 @@
|
|||||||
return g.hiddenReplies = {};
|
return g.hiddenReplies = {};
|
||||||
},
|
},
|
||||||
keybind: function(e) {
|
keybind: function(e) {
|
||||||
|
var key;
|
||||||
if (e.keyCode === 9) return;
|
if (e.keyCode === 9) return;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@ -2451,10 +2419,9 @@
|
|||||||
|
|
||||||
ThreadHiding = {
|
ThreadHiding = {
|
||||||
init: function() {
|
init: function() {
|
||||||
var a, hiddenThreads, op, thread, _i, _len, _ref, _results;
|
var a, hiddenThreads, op, thread, _i, _len, _ref;
|
||||||
hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {});
|
hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {});
|
||||||
_ref = $$('.thread');
|
_ref = $$('.thread');
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
thread = _ref[_i];
|
thread = _ref[_i];
|
||||||
op = thread.firstChild;
|
op = thread.firstChild;
|
||||||
@ -2462,83 +2429,60 @@
|
|||||||
textContent: '[ - ]',
|
textContent: '[ - ]',
|
||||||
href: 'javascript:;'
|
href: 'javascript:;'
|
||||||
});
|
});
|
||||||
$.on(a, 'click', ThreadHiding.cb.hide);
|
$.on(a, 'click', ThreadHiding.cb);
|
||||||
$.prepend(op, a);
|
$.prepend(op, a);
|
||||||
if (op.id in hiddenThreads) {
|
if (op.id in hiddenThreads) ThreadHiding.hide(thread);
|
||||||
_results.push(ThreadHiding.hideHide(thread));
|
|
||||||
} else {
|
|
||||||
_results.push(void 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return _results;
|
|
||||||
},
|
},
|
||||||
cb: {
|
cb: function() {
|
||||||
hide: function() {
|
return ThreadHiding.toggle(this.parentNode.parentNode);
|
||||||
var thread;
|
|
||||||
thread = this.parentNode.parentNode;
|
|
||||||
return ThreadHiding.hide(thread);
|
|
||||||
},
|
|
||||||
show: function() {
|
|
||||||
var thread;
|
|
||||||
thread = this.parentNode.parentNode;
|
|
||||||
return ThreadHiding.show(thread);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
toggle: function(thread) {
|
toggle: function(thread) {
|
||||||
if (/\bstub\b/.test(thread.className) || thread.hidden) {
|
var hiddenThreads, id;
|
||||||
return ThreadHiding.show(thread);
|
hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {});
|
||||||
|
id = $('.op', thread).id;
|
||||||
|
if (thread.hidden || thread.firstChild.className === 'block') {
|
||||||
|
ThreadHiding.show(thread);
|
||||||
|
delete hiddenThreads[id];
|
||||||
} else {
|
} else {
|
||||||
return ThreadHiding.hide(thread);
|
ThreadHiding.hide(thread);
|
||||||
|
hiddenThreads[id] = Date.now();
|
||||||
}
|
}
|
||||||
|
return $.set("hiddenThreads/" + g.BOARD + "/", hiddenThreads);
|
||||||
},
|
},
|
||||||
hide: function(thread) {
|
hide: function(thread) {
|
||||||
var hiddenThreads, id;
|
var a, div, name, num, op, span, text, trip, uid, _ref, _ref2;
|
||||||
ThreadHiding.hideHide(thread);
|
if (!conf['Show Stubs']) {
|
||||||
id = thread.firstChild.id;
|
|
||||||
hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {});
|
|
||||||
hiddenThreads[id] = Date.now();
|
|
||||||
return $.set("hiddenThreads/" + g.BOARD + "/", hiddenThreads);
|
|
||||||
},
|
|
||||||
hideHide: function(thread) {
|
|
||||||
var a, div, name, num, span, text, trip, uid, _ref, _ref2;
|
|
||||||
if (conf['Show Stubs']) {
|
|
||||||
if (/stub/.test(thread.className)) return;
|
|
||||||
if (span = $('.omittedposts', thread)) {
|
|
||||||
num = Number(span.textContent.match(/\d+/)[0]);
|
|
||||||
} else {
|
|
||||||
num = 0;
|
|
||||||
}
|
|
||||||
num += $$('table', thread).length;
|
|
||||||
text = num === 1 ? "1 reply" : "" + num + " replies";
|
|
||||||
name = $('.postername', thread).textContent;
|
|
||||||
uid = ((_ref = $('.posteruid', thread)) != null ? _ref.textContent : void 0) || '';
|
|
||||||
trip = ((_ref2 = $('.postername + .postertrip', thread)) != null ? _ref2.textContent : void 0) || '';
|
|
||||||
a = $.el('a', {
|
|
||||||
innerHTML: "<span>[ + ]</span> " + name + uid + trip + " (" + text + ")",
|
|
||||||
href: 'javascript:;'
|
|
||||||
});
|
|
||||||
$.on(a, 'click', ThreadHiding.cb.show);
|
|
||||||
div = $.el('div', {
|
|
||||||
className: 'block'
|
|
||||||
});
|
|
||||||
$.add(div, a);
|
|
||||||
$.add(thread, div);
|
|
||||||
return $.addClass(thread, 'stub');
|
|
||||||
} else {
|
|
||||||
thread.hidden = true;
|
thread.hidden = true;
|
||||||
return thread.nextSibling.hidden = true;
|
thread.nextSibling.hidden = true;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
if (thread.firstChild.className === 'block') return;
|
||||||
|
num = 0;
|
||||||
|
if (span = $('.omittedposts', thread)) {
|
||||||
|
num = Number(span.textContent.match(/\d+/)[0]);
|
||||||
|
}
|
||||||
|
num += $$('.op ~ table', thread).length;
|
||||||
|
text = num === 1 ? '1 reply' : "" + num + " replies";
|
||||||
|
op = $('.op', thread);
|
||||||
|
name = $('.postername', op).textContent;
|
||||||
|
uid = ((_ref = $('.posteruid', op)) != null ? _ref.textContent : void 0) || '';
|
||||||
|
trip = ((_ref2 = $('.postertrip', op)) != null ? _ref2.textContent : void 0) || '';
|
||||||
|
a = $.el('a', {
|
||||||
|
innerHTML: "<span>[ + ]</span> " + name + " " + uid + " " + trip + " (" + text + ")",
|
||||||
|
href: 'javascript:;'
|
||||||
|
});
|
||||||
|
$.on(a, 'click', ThreadHiding.cb);
|
||||||
|
div = $.el('div', {
|
||||||
|
className: 'block'
|
||||||
|
});
|
||||||
|
$.add(div, a);
|
||||||
|
return $.prepend(thread, div);
|
||||||
},
|
},
|
||||||
show: function(thread) {
|
show: function(thread, id) {
|
||||||
var hiddenThreads, id;
|
$.rm($('.block', thread));
|
||||||
$.rm($('div.block', thread));
|
|
||||||
$.removeClass(thread, 'stub');
|
|
||||||
thread.hidden = false;
|
thread.hidden = false;
|
||||||
thread.nextSibling.hidden = false;
|
return thread.nextSibling.hidden = false;
|
||||||
id = thread.firstChild.id;
|
|
||||||
hiddenThreads = $.get("hiddenThreads/" + g.BOARD + "/", {});
|
|
||||||
delete hiddenThreads[id];
|
|
||||||
return $.set("hiddenThreads/" + g.BOARD + "/", hiddenThreads);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2616,7 +2560,7 @@
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
update: function() {
|
update: function() {
|
||||||
var body, id, newPosts, nodes, reply, scroll, _i, _len, _ref, _ref2;
|
var body, id, newPosts, nodes, reply, scroll, _i, _len, _ref;
|
||||||
if (this.status === 404) {
|
if (this.status === 404) {
|
||||||
Updater.timer.textContent = '';
|
Updater.timer.textContent = '';
|
||||||
Updater.count.textContent = 404;
|
Updater.count.textContent = 404;
|
||||||
@ -2655,23 +2599,19 @@
|
|||||||
body = $.el('body', {
|
body = $.el('body', {
|
||||||
innerHTML: this.responseText
|
innerHTML: this.responseText
|
||||||
});
|
});
|
||||||
id = ((_ref = $('td[id]', Updater.br.previousElementSibling)) != null ? _ref.id : void 0) || 0;
|
id = $('input', Updater.br.previousElementSibling).name;
|
||||||
nodes = [];
|
nodes = [];
|
||||||
_ref2 = $$('.reply', body).reverse();
|
_ref = $$('.reply', body).reverse();
|
||||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
reply = _ref2[_i];
|
reply = _ref[_i];
|
||||||
if (reply.id <= id) break;
|
if (reply.id <= id) break;
|
||||||
nodes.push(reply.parentNode.parentNode.parentNode);
|
nodes.push(reply.parentNode.parentNode.parentNode);
|
||||||
}
|
}
|
||||||
newPosts = nodes.length;
|
newPosts = nodes.length;
|
||||||
scroll = conf['Scrolling'] && Updater.scrollBG() && newPosts && Updater.br.previousElementSibling.getBoundingClientRect().bottom - d.body.clientHeight < 25;
|
scroll = conf['Scrolling'] && Updater.scrollBG() && newPosts && Updater.br.previousElementSibling.getBoundingClientRect().bottom - d.body.clientHeight < 25;
|
||||||
if (conf['Verbose']) {
|
if (conf['Verbose']) {
|
||||||
Updater.count.textContent = '+' + newPosts;
|
Updater.count.textContent = "+" + newPosts;
|
||||||
if (newPosts === 0) {
|
Updater.count.className = newPosts ? 'new' : null;
|
||||||
Updater.count.className = null;
|
|
||||||
} else {
|
|
||||||
Updater.count.className = 'new';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$.before(Updater.br, nodes.reverse());
|
$.before(Updater.br, nodes.reverse());
|
||||||
if (scroll) return Updater.br.previousSibling.scrollIntoView();
|
if (scroll) return Updater.br.previousSibling.scrollIntoView();
|
||||||
@ -3247,32 +3187,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
parse: function(req, pathname, id, threadID, inline) {
|
parse: function(req, pathname, id, threadID, inline) {
|
||||||
var body, href, html, link, newInline, op, quote, reply, _i, _j, _len, _len2, _ref, _ref2;
|
var doc, href, link, newInline, node, quote, _i, _len, _ref;
|
||||||
if (!inline.parentNode) return;
|
if (!inline.parentNode) return;
|
||||||
if (req.status !== 200) {
|
if (req.status !== 200) {
|
||||||
inline.textContent = "" + req.status + " " + req.statusText;
|
inline.textContent = "" + req.status + " " + req.statusText;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
body = $.el('body', {
|
doc = d.implementation.createHTMLDocument(null);
|
||||||
innerHTML: req.responseText
|
doc.documentElement.innerHTML = req.responseText;
|
||||||
});
|
node = id === threadID ? Threading.op($('body > form', doc).firstChild) : doc.getElementById(id);
|
||||||
if (id === threadID) {
|
newInline = QuoteInline.table(id, node.innerHTML);
|
||||||
op = Threading.op($('body > form', body).firstChild);
|
_ref = $$('.quotelink', newInline);
|
||||||
html = op.innerHTML;
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
} else {
|
quote = _ref[_i];
|
||||||
_ref = $$('.reply', body);
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
reply = _ref[_i];
|
|
||||||
if (reply.id === id) {
|
|
||||||
html = reply.innerHTML;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newInline = QuoteInline.table(id, html);
|
|
||||||
_ref2 = $$('.quotelink', newInline);
|
|
||||||
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
|
|
||||||
quote = _ref2[_j];
|
|
||||||
if ((href = quote.getAttribute('href')) === quote.hash) {
|
if ((href = quote.getAttribute('href')) === quote.hash) {
|
||||||
quote.pathname = pathname;
|
quote.pathname = pathname;
|
||||||
} else if (!g.REPLY && href !== quote.href) {
|
} else if (!g.REPLY && href !== quote.href) {
|
||||||
@ -3352,29 +3279,16 @@
|
|||||||
return $.off(this, 'click', QuotePreview.mouseout);
|
return $.off(this, 'click', QuotePreview.mouseout);
|
||||||
},
|
},
|
||||||
parse: function(req, id, threadID) {
|
parse: function(req, id, threadID) {
|
||||||
var body, html, op, post, qp, reply, _i, _len, _ref;
|
var doc, node, post, qp;
|
||||||
if (!((qp = ui.el) && (qp.innerHTML === ("Loading " + id + "...")))) return;
|
if (!((qp = ui.el) && qp.textContent === ("Loading " + id + "..."))) return;
|
||||||
if (req.status !== 200) {
|
if (req.status !== 200) {
|
||||||
qp.textContent = "" + req.status + " " + req.statusText;
|
qp.textContent = "" + req.status + " " + req.statusText;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
body = $.el('body', {
|
doc = d.implementation.createHTMLDocument(null);
|
||||||
innerHTML: req.responseText
|
doc.documentElement.innerHTML = req.responseText;
|
||||||
});
|
node = id === threadID ? Threading.op($('body > form', doc).firstChild) : doc.getElementById(id);
|
||||||
if (id === threadID) {
|
qp.innerHTML = node.innerHTML;
|
||||||
op = Threading.op($('body > form', body).firstChild);
|
|
||||||
html = op.innerHTML;
|
|
||||||
} else {
|
|
||||||
_ref = $$('.reply', body);
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
reply = _ref[_i];
|
|
||||||
if (reply.id === id) {
|
|
||||||
html = reply.innerHTML;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
qp.innerHTML = html;
|
|
||||||
post = {
|
post = {
|
||||||
root: qp,
|
root: qp,
|
||||||
filesize: $('.filesize', qp),
|
filesize: $('.filesize', qp),
|
||||||
@ -3865,7 +3779,7 @@
|
|||||||
|
|
||||||
Main = {
|
Main = {
|
||||||
init: function() {
|
init: function() {
|
||||||
var cutoff, hiddenThreads, id, now, path, pathname, temp, timestamp, _ref;
|
var cutoff, hiddenThreads, id, key, now, path, pathname, temp, timestamp, val, _ref;
|
||||||
path = location.pathname;
|
path = location.pathname;
|
||||||
pathname = path.slice(1).split('/');
|
pathname = path.slice(1).split('/');
|
||||||
g.BOARD = pathname[0], temp = pathname[1];
|
g.BOARD = pathname[0], temp = pathname[1];
|
||||||
@ -3875,6 +3789,10 @@
|
|||||||
} else {
|
} else {
|
||||||
g.PAGENUM = parseInt(temp) || 0;
|
g.PAGENUM = parseInt(temp) || 0;
|
||||||
}
|
}
|
||||||
|
for (key in conf) {
|
||||||
|
val = conf[key];
|
||||||
|
conf[key] = $.get(key, val);
|
||||||
|
}
|
||||||
$.on(window, 'message', Main.message);
|
$.on(window, 'message', Main.message);
|
||||||
switch (location.hostname) {
|
switch (location.hostname) {
|
||||||
case 'sys.4chan.org':
|
case 'sys.4chan.org':
|
||||||
@ -3977,19 +3895,51 @@
|
|||||||
Favicon.init();
|
Favicon.init();
|
||||||
if (conf['Quick Reply']) qr.init();
|
if (conf['Quick Reply']) qr.init();
|
||||||
if (conf['Image Expansion']) ImageExpand.init();
|
if (conf['Image Expansion']) ImageExpand.init();
|
||||||
if (conf['Thread Watcher']) Watcher.init();
|
if (conf['Thread Watcher']) {
|
||||||
if (conf['Keybinds']) Keybinds.init();
|
setTimeout(function() {
|
||||||
|
return Watcher.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (conf['Keybinds']) {
|
||||||
|
setTimeout(function() {
|
||||||
|
return Keybinds.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
if (g.REPLY) {
|
if (g.REPLY) {
|
||||||
if (conf['Thread Updater']) Updater.init();
|
if (conf['Thread Updater']) {
|
||||||
|
setTimeout(function() {
|
||||||
|
return Updater.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
if (conf['Thread Stats']) ThreadStats.init();
|
if (conf['Thread Stats']) ThreadStats.init();
|
||||||
if (conf['Reply Navigation']) Nav.init();
|
if (conf['Reply Navigation']) {
|
||||||
|
setTimeout(function() {
|
||||||
|
return Nav.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
if (conf['Post in Title']) TitlePost.init();
|
if (conf['Post in Title']) TitlePost.init();
|
||||||
if (conf['Unread Count'] || conf['Unread Favicon']) Unread.init();
|
if (conf['Unread Count'] || conf['Unread Favicon']) Unread.init();
|
||||||
} else {
|
} else {
|
||||||
if (conf['Thread Hiding']) ThreadHiding.init();
|
if (conf['Thread Hiding']) {
|
||||||
if (conf['Thread Expansion']) ExpandThread.init();
|
setTimeout(function() {
|
||||||
if (conf['Comment Expansion']) ExpandComment.init();
|
return ThreadHiding.init();
|
||||||
if (conf['Index Navigation']) Nav.init();
|
});
|
||||||
|
}
|
||||||
|
if (conf['Thread Expansion']) {
|
||||||
|
setTimeout(function() {
|
||||||
|
return ExpandThread.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (conf['Comment Expansion']) {
|
||||||
|
setTimeout(function() {
|
||||||
|
return ExpandComment.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (conf['Index Navigation']) {
|
||||||
|
setTimeout(function() {
|
||||||
|
return Nav.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
nodes = [];
|
nodes = [];
|
||||||
_ref2 = $$('.op, a + table', form);
|
_ref2 = $$('.op, a + table', form);
|
||||||
@ -4036,7 +3986,7 @@
|
|||||||
el: klass === 'op' ? node : node.firstChild.firstChild.lastChild,
|
el: klass === 'op' ? node : node.firstChild.firstChild.lastChild,
|
||||||
"class": klass,
|
"class": klass,
|
||||||
id: node.getElementsByTagName('input')[0].name,
|
id: node.getElementsByTagName('input')[0].name,
|
||||||
threadId: g.THREAD_ID || $.x('ancestor::div[contains(@class,"thread")]', node).firstChild.id,
|
threadId: g.THREAD_ID || $.x('ancestor::div[@class="thread"]', node).firstChild.id,
|
||||||
isOP: klass === 'op',
|
isOP: klass === 'op',
|
||||||
isInlined: /\binline\b/.test(klass),
|
isInlined: /\binline\b/.test(klass),
|
||||||
filesize: node.getElementsByClassName('filesize')[0] || false,
|
filesize: node.getElementsByClassName('filesize')[0] || false,
|
||||||
@ -4058,7 +4008,7 @@
|
|||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (notify) {
|
if (notify) {
|
||||||
alert("4chan X error: " + err.message + "\nhttp://mayhemydg.github.com/4chan-x/#bug-report\n\n" + err.stack);
|
alert("4chan X (" + VERSION + ") error: " + err.message + "\nhttp://mayhemydg.github.com/4chan-x/#bug-report\n\n" + err.stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4096,7 +4046,9 @@ a[href="javascript:;"] {\
|
|||||||
text-decoration: none;\
|
text-decoration: none;\
|
||||||
}\
|
}\
|
||||||
\
|
\
|
||||||
.thread.stub > :not(.block),\
|
.block ~ .op,\
|
||||||
|
.block ~ .omittedposts,\
|
||||||
|
.block ~ table,\
|
||||||
#content > [name=tab]:not(:checked) + div,\
|
#content > [name=tab]:not(:checked) + div,\
|
||||||
#updater:not(:hover) > :not(.move),\
|
#updater:not(:hover) > :not(.move),\
|
||||||
#qp > input, #qp .inline, .forwarded {\
|
#qp > input, #qp .inline, .forwarded {\
|
||||||
|
|||||||
318
script.coffee
318
script.coffee
@ -314,7 +314,7 @@ $.extend $,
|
|||||||
$.set @name, @checked
|
$.set @name, @checked
|
||||||
conf[@name] = @checked
|
conf[@name] = @checked
|
||||||
value: ->
|
value: ->
|
||||||
$.set @name, @value
|
$.set @name, @value.trim()
|
||||||
conf[@name] = @value
|
conf[@name] = @value
|
||||||
addStyle: (css) ->
|
addStyle: (css) ->
|
||||||
style = $.el 'style',
|
style = $.el 'style',
|
||||||
@ -334,7 +334,7 @@ $.extend $,
|
|||||||
tn: (s) ->
|
tn: (s) ->
|
||||||
d.createTextNode s
|
d.createTextNode s
|
||||||
nodes: (nodes) ->
|
nodes: (nodes) ->
|
||||||
unless nodes instanceof Array
|
if nodes instanceof Node
|
||||||
return nodes
|
return nodes
|
||||||
frag = d.createDocumentFragment()
|
frag = d.createDocumentFragment()
|
||||||
for node in nodes
|
for node in nodes
|
||||||
@ -450,10 +450,6 @@ $.extend $,
|
|||||||
name = NAMESPACE + name
|
name = NAMESPACE + name
|
||||||
localStorage[name] = JSON.stringify value
|
localStorage[name] = JSON.stringify value
|
||||||
|
|
||||||
#load values from localStorage
|
|
||||||
for key, val of conf
|
|
||||||
conf[key] = $.get key, val
|
|
||||||
|
|
||||||
$$ = (selector, root=d.body) ->
|
$$ = (selector, root=d.body) ->
|
||||||
Array::slice.call root.querySelectorAll selector
|
Array::slice.call root.querySelectorAll selector
|
||||||
|
|
||||||
@ -545,11 +541,11 @@ Filter =
|
|||||||
if result is true
|
if result is true
|
||||||
if isOP
|
if isOP
|
||||||
unless g.REPLY
|
unless g.REPLY
|
||||||
ThreadHiding.hideHide post.el.parentNode
|
ThreadHiding.hide post.el.parentNode
|
||||||
else
|
else
|
||||||
continue
|
continue
|
||||||
else
|
else
|
||||||
ReplyHiding.hideHide post.el
|
ReplyHiding.hide post.root
|
||||||
return
|
return
|
||||||
|
|
||||||
# Highlight
|
# Highlight
|
||||||
@ -622,7 +618,7 @@ StrikethroughQuotes =
|
|||||||
for quote in post.quotes
|
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'
|
||||||
post.root.hidden = true if conf['Recursive Filtering']
|
ReplyHiding.hide post.root if conf['Recursive Filtering']
|
||||||
return
|
return
|
||||||
|
|
||||||
ExpandComment =
|
ExpandComment =
|
||||||
@ -642,23 +638,19 @@ ExpandComment =
|
|||||||
a.textContent = "#{req.status} #{req.statusText}"
|
a.textContent = "#{req.status} #{req.statusText}"
|
||||||
return
|
return
|
||||||
|
|
||||||
body = $.el 'body',
|
doc = d.implementation.createHTMLDocument null
|
||||||
innerHTML: req.responseText
|
doc.documentElement.innerHTML = req.responseText
|
||||||
|
|
||||||
if threadID is replyID #OP
|
bq =
|
||||||
bq = $ 'blockquote', body
|
if threadID is replyID # OP
|
||||||
else
|
$ 'blockquote', doc
|
||||||
#css selectors don't like ids starting with numbers,
|
else
|
||||||
# getElementById only works for root document.
|
$ 'blockquote', doc.getElementById replyID
|
||||||
for reply in $$ 'td[id]', body
|
$.replace a.parentNode.parentNode, bq
|
||||||
if reply.id == replyID
|
|
||||||
bq = $ 'blockquote', reply
|
|
||||||
break
|
|
||||||
quotes = $$ '.quotelink', bq
|
quotes = $$ '.quotelink', bq
|
||||||
for quote in quotes
|
for quote in quotes
|
||||||
if quote.getAttribute('href') is quote.hash
|
if quote.getAttribute('href') is quote.hash
|
||||||
quote.pathname = "/#{g.BOARD}/res/#{threadID}"
|
quote.pathname = "/#{g.BOARD}/res/#{threadID}"
|
||||||
$.replace a.parentNode.parentNode, bq
|
|
||||||
post =
|
post =
|
||||||
threadId: threadID
|
threadId: threadID
|
||||||
quotes: quotes
|
quotes: quotes
|
||||||
@ -749,70 +741,55 @@ ExpandThread =
|
|||||||
|
|
||||||
ReplyHiding =
|
ReplyHiding =
|
||||||
init: ->
|
init: ->
|
||||||
@a = $.el 'a',
|
@td = $.el 'td',
|
||||||
textContent: '[ - ]'
|
noWrap: true
|
||||||
href: 'javascript:;'
|
className: 'replyhider'
|
||||||
|
innerHTML: '<a href="javascript:;">[ - ]</a>'
|
||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
|
|
||||||
node: (post) ->
|
node: (post) ->
|
||||||
return if post.class
|
return if post.class
|
||||||
dd = post.el.previousSibling
|
td = ReplyHiding.td.cloneNode true
|
||||||
dd.className = 'replyhider'
|
$.on td.firstChild, 'click', ReplyHiding.toggle
|
||||||
a = ReplyHiding.a.cloneNode true
|
$.replace post.el.previousSibling, td
|
||||||
$.on a, 'click', ReplyHiding.cb.hide
|
|
||||||
$.replace dd.firstChild, a
|
|
||||||
|
|
||||||
if post.id of g.hiddenReplies
|
if post.id of g.hiddenReplies
|
||||||
ReplyHiding.hide post.el
|
ReplyHiding.hide post.root
|
||||||
|
|
||||||
cb:
|
toggle: ->
|
||||||
hide: ->
|
parent = @parentNode
|
||||||
reply = @parentNode.nextSibling
|
if parent.className is 'replyhider'
|
||||||
ReplyHiding.hide reply
|
ReplyHiding.hide parent.parentNode.parentNode.parentNode
|
||||||
|
id = parent.nextSibling.id
|
||||||
show: ->
|
for quote in $$ ".quotelink[href='##{id}'], .backlink[href='##{id}']"
|
||||||
div = @parentNode
|
$.addClass quote, 'filtered'
|
||||||
table = div.nextSibling
|
g.hiddenReplies[id] = Date.now()
|
||||||
ReplyHiding.show table
|
else
|
||||||
|
table = parent.nextSibling
|
||||||
$.rm div
|
table.hidden = false
|
||||||
|
$.rm parent
|
||||||
hide: (reply) ->
|
id = table.firstChild.firstChild.lastChild.id
|
||||||
ReplyHiding.hideHide reply
|
for quote in $$ ".quotelink[href='##{id}'], .backlink[href='##{id}']"
|
||||||
|
$.removeClass quote, 'filtered'
|
||||||
id = reply.id
|
delete g.hiddenReplies[id]
|
||||||
for quote in $$ ".quotelink[href='##{id}'], .backlink[href='##{id}']"
|
|
||||||
$.addClass quote, 'filtered'
|
|
||||||
|
|
||||||
g.hiddenReplies[id] = Date.now()
|
|
||||||
$.set "hiddenReplies/#{g.BOARD}/", g.hiddenReplies
|
$.set "hiddenReplies/#{g.BOARD}/", g.hiddenReplies
|
||||||
|
|
||||||
hideHide: (reply) ->
|
hide: (table) ->
|
||||||
table = reply.parentNode.parentNode.parentNode
|
return if table.hidden # already hidden by filter
|
||||||
return if table.hidden #already hidden by filter
|
|
||||||
|
|
||||||
table.hidden = true
|
table.hidden = true
|
||||||
|
|
||||||
if conf['Show Stubs']
|
return unless conf['Show Stubs']
|
||||||
name = $('.commentpostername', reply).textContent
|
|
||||||
uid = $('.posteruid', reply)?.textContent or ''
|
|
||||||
trip = $('.postertrip', reply)?.textContent or ''
|
|
||||||
|
|
||||||
div = $.el 'div',
|
name = $('td[id] > .commentpostername', table).textContent
|
||||||
className: 'stub'
|
uid = $('td[id] > .posteruid', table)?.textContent or ''
|
||||||
innerHTML: "<a href=javascript:;><span>[ + ]</span> #{name} #{uid} #{trip}</a>"
|
trip = $('td[id] > .postertrip', table)?.textContent or ''
|
||||||
$.on $('a', div), 'click', ReplyHiding.cb.show
|
|
||||||
$.before table, div
|
|
||||||
|
|
||||||
show: (table) ->
|
div = $.el 'div',
|
||||||
table.hidden = false
|
className: 'stub'
|
||||||
|
innerHTML: "<a href=javascript:;><span>[ + ]</span> #{name} #{uid} #{trip}</a>"
|
||||||
id = $('td[id]', table).id
|
$.on div.firstChild, 'click', ReplyHiding.toggle
|
||||||
for quote in $$ ".quotelink[href='##{id}'], .backlink[href='##{id}']"
|
$.before table, div
|
||||||
$.removeClass quote, 'filtered'
|
|
||||||
|
|
||||||
delete g.hiddenReplies[id]
|
|
||||||
$.set "hiddenReplies/#{g.BOARD}/", g.hiddenReplies
|
|
||||||
|
|
||||||
Keybinds =
|
Keybinds =
|
||||||
init: ->
|
init: ->
|
||||||
@ -895,7 +872,7 @@ Keybinds =
|
|||||||
when conf.previousReply
|
when conf.previousReply
|
||||||
Keybinds.hl -1, thread
|
Keybinds.hl -1, thread
|
||||||
when conf.hide
|
when conf.hide
|
||||||
ThreadHiding.toggle thread
|
ThreadHiding.toggle thread if /\bthread\b/.test thread.className
|
||||||
else
|
else
|
||||||
return
|
return
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@ -1038,14 +1015,18 @@ Nav =
|
|||||||
qr =
|
qr =
|
||||||
init: ->
|
init: ->
|
||||||
return unless $.id 'recaptcha_challenge_field_holder'
|
return unless $.id 'recaptcha_challenge_field_holder'
|
||||||
|
g.callbacks.push @node
|
||||||
|
setTimeout @asyncInit
|
||||||
|
|
||||||
|
asyncInit: ->
|
||||||
if conf['Hide Original Post Form']
|
if conf['Hide Original Post Form']
|
||||||
link = $.el 'h1', innerHTML: "<a href=javascript:;>#{if g.REPLY then 'Quick Reply' else 'New Thread'}</a>"
|
link = $.el 'h1', innerHTML: "<a href=javascript:;>#{if g.REPLY then 'Quick Reply' else 'New Thread'}</a>"
|
||||||
$.on $('a', link), 'click', ->
|
$.on $('a', link), 'click', ->
|
||||||
qr.open()
|
qr.open()
|
||||||
|
$('select', qr.el).value = 'new' unless g.REPLY
|
||||||
$('textarea', qr.el).focus()
|
$('textarea', qr.el).focus()
|
||||||
form = d.forms[0]
|
form = d.forms[0]
|
||||||
$.before form, link
|
$.before form, link
|
||||||
g.callbacks.push @node
|
|
||||||
|
|
||||||
# CORS is ignored for content script on Chrome, but not Safari/Oprah/Firefox.
|
# CORS is ignored for content script on Chrome, but not Safari/Oprah/Firefox.
|
||||||
if /chrome/i.test navigator.userAgent
|
if /chrome/i.test navigator.userAgent
|
||||||
@ -1063,17 +1044,14 @@ qr =
|
|||||||
$.on iframe, 'load', -> if @src isnt 'about:blank' then setTimeout loadChecking, 500, @
|
$.on iframe, 'load', -> if @src isnt 'about:blank' then setTimeout loadChecking, 500, @
|
||||||
$.add d.head, iframe
|
$.add d.head, iframe
|
||||||
|
|
||||||
# This is extemely slow, execute is asynchronously.
|
# Prevent original captcha input from being focused on reload.
|
||||||
setTimeout ->
|
script = $.el 'script', textContent: 'Recaptcha.focus_response_field=function(){}'
|
||||||
# Prevent original captcha input from being focused on reload.
|
$.add d.head, script
|
||||||
script = $.el 'script', textContent: 'Recaptcha.focus_response_field=function(){}'
|
$.rm script
|
||||||
$.add d.head, script
|
|
||||||
$.rm script
|
|
||||||
|
|
||||||
if conf['Persistent QR']
|
if conf['Persistent QR']
|
||||||
setTimeout ->
|
qr.dialog()
|
||||||
qr.dialog()
|
qr.hide() if conf['Auto Hide QR']
|
||||||
qr.hide() if conf['Auto Hide QR']
|
|
||||||
$.on d, 'dragover', qr.dragOver
|
$.on d, 'dragover', qr.dragOver
|
||||||
$.on d, 'drop', qr.dropFile
|
$.on d, 'drop', qr.dropFile
|
||||||
$.on d, 'dragstart', qr.drag
|
$.on d, 'dragstart', qr.drag
|
||||||
@ -2061,78 +2039,64 @@ ThreadHiding =
|
|||||||
hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {}
|
hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {}
|
||||||
for thread in $$ '.thread'
|
for thread in $$ '.thread'
|
||||||
op = thread.firstChild
|
op = thread.firstChild
|
||||||
a = $.el 'a',
|
a = $.el 'a',
|
||||||
textContent: '[ - ]'
|
textContent: '[ - ]'
|
||||||
href: 'javascript:;'
|
href: 'javascript:;'
|
||||||
$.on a, 'click', ThreadHiding.cb.hide
|
$.on a, 'click', ThreadHiding.cb
|
||||||
$.prepend op, a
|
$.prepend op, a
|
||||||
|
|
||||||
if op.id of hiddenThreads
|
if op.id of hiddenThreads
|
||||||
ThreadHiding.hideHide thread
|
ThreadHiding.hide thread
|
||||||
|
return
|
||||||
|
|
||||||
cb:
|
cb: ->
|
||||||
hide: ->
|
ThreadHiding.toggle @parentNode.parentNode
|
||||||
thread = @parentNode.parentNode
|
|
||||||
ThreadHiding.hide thread
|
|
||||||
show: ->
|
|
||||||
thread = @parentNode.parentNode
|
|
||||||
ThreadHiding.show thread
|
|
||||||
|
|
||||||
toggle: (thread) ->
|
toggle: (thread) ->
|
||||||
if /\bstub\b/.test(thread.className) or thread.hidden
|
hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {}
|
||||||
|
id = $('.op', thread).id
|
||||||
|
if thread.hidden or thread.firstChild.className is 'block'
|
||||||
ThreadHiding.show thread
|
ThreadHiding.show thread
|
||||||
|
delete hiddenThreads[id]
|
||||||
else
|
else
|
||||||
ThreadHiding.hide thread
|
ThreadHiding.hide thread
|
||||||
|
hiddenThreads[id] = Date.now()
|
||||||
|
$.set "hiddenThreads/#{g.BOARD}/", hiddenThreads
|
||||||
|
|
||||||
hide: (thread) ->
|
hide: (thread) ->
|
||||||
ThreadHiding.hideHide thread
|
unless conf['Show Stubs']
|
||||||
|
|
||||||
id = thread.firstChild.id
|
|
||||||
|
|
||||||
hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {}
|
|
||||||
hiddenThreads[id] = Date.now()
|
|
||||||
$.set "hiddenThreads/#{g.BOARD}/", hiddenThreads
|
|
||||||
|
|
||||||
hideHide: (thread) ->
|
|
||||||
if conf['Show Stubs']
|
|
||||||
return if /stub/.test thread.className #already hidden by filter
|
|
||||||
if span = $ '.omittedposts', thread
|
|
||||||
num = Number span.textContent.match(/\d+/)[0]
|
|
||||||
else
|
|
||||||
num = 0
|
|
||||||
num += $$('table', thread).length
|
|
||||||
text = if num is 1 then "1 reply" else "#{num} replies"
|
|
||||||
name = $('.postername', thread).textContent
|
|
||||||
uid = $('.posteruid', thread)?.textContent or ''
|
|
||||||
trip = $('.postername + .postertrip', thread)?.textContent or ''
|
|
||||||
|
|
||||||
a = $.el 'a',
|
|
||||||
innerHTML: "<span>[ + ]</span> #{name}#{uid}#{trip} (#{text})"
|
|
||||||
href: 'javascript:;'
|
|
||||||
$.on a, 'click', ThreadHiding.cb.show
|
|
||||||
|
|
||||||
div = $.el 'div',
|
|
||||||
className: 'block'
|
|
||||||
|
|
||||||
$.add div, a
|
|
||||||
$.add thread, div
|
|
||||||
$.addClass thread, 'stub'
|
|
||||||
else
|
|
||||||
thread.hidden = true
|
thread.hidden = true
|
||||||
thread.nextSibling.hidden = true
|
thread.nextSibling.hidden = true
|
||||||
|
return
|
||||||
|
|
||||||
show: (thread) ->
|
return if thread.firstChild.className is 'block' # already hidden by filter
|
||||||
$.rm $ 'div.block', thread
|
|
||||||
$.removeClass thread, 'stub'
|
num = 0
|
||||||
|
if span = $ '.omittedposts', thread
|
||||||
|
num = Number span.textContent.match(/\d+/)[0]
|
||||||
|
num += $$('.op ~ table', thread).length
|
||||||
|
text = if num is 1 then '1 reply' else "#{num} replies"
|
||||||
|
op = $ '.op', thread
|
||||||
|
name = $('.postername', op).textContent
|
||||||
|
uid = $('.posteruid', op)?.textContent or ''
|
||||||
|
trip = $('.postertrip', op)?.textContent or ''
|
||||||
|
|
||||||
|
a = $.el 'a',
|
||||||
|
innerHTML: "<span>[ + ]</span> #{name} #{uid} #{trip} (#{text})"
|
||||||
|
href: 'javascript:;'
|
||||||
|
$.on a, 'click', ThreadHiding.cb
|
||||||
|
|
||||||
|
div = $.el 'div',
|
||||||
|
className: 'block'
|
||||||
|
|
||||||
|
$.add div, a
|
||||||
|
$.prepend thread, div
|
||||||
|
|
||||||
|
show: (thread, id) ->
|
||||||
|
$.rm $ '.block', thread
|
||||||
thread.hidden = false
|
thread.hidden = false
|
||||||
thread.nextSibling.hidden = false
|
thread.nextSibling.hidden = false
|
||||||
|
|
||||||
id = thread.firstChild.id
|
|
||||||
|
|
||||||
hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {}
|
|
||||||
delete hiddenThreads[id]
|
|
||||||
$.set "hiddenThreads/#{g.BOARD}/", hiddenThreads
|
|
||||||
|
|
||||||
Updater =
|
Updater =
|
||||||
init: ->
|
init: ->
|
||||||
html = "<div class=move><span id=count></span> <span id=timer>-#{conf['Interval']}</span></div>"
|
html = "<div class=move><span id=count></span> <span id=timer>-#{conf['Interval']}</span></div>"
|
||||||
@ -2236,22 +2200,18 @@ Updater =
|
|||||||
body = $.el 'body',
|
body = $.el 'body',
|
||||||
innerHTML: @responseText
|
innerHTML: @responseText
|
||||||
|
|
||||||
id = $('td[id]', Updater.br.previousElementSibling)?.id or 0
|
id = $('input', Updater.br.previousElementSibling).name
|
||||||
nodes = []
|
nodes = []
|
||||||
for reply in $$('.reply', body).reverse()
|
for reply in $$('.reply', body).reverse()
|
||||||
if reply.id <= id #make sure to not insert older posts
|
break if reply.id <= id #make sure to not insert older posts
|
||||||
break
|
|
||||||
nodes.push reply.parentNode.parentNode.parentNode #table
|
nodes.push reply.parentNode.parentNode.parentNode #table
|
||||||
|
|
||||||
newPosts = nodes.length
|
newPosts = nodes.length
|
||||||
scroll = conf['Scrolling'] && Updater.scrollBG() && newPosts &&
|
scroll = conf['Scrolling'] && Updater.scrollBG() && newPosts &&
|
||||||
Updater.br.previousElementSibling.getBoundingClientRect().bottom - d.body.clientHeight < 25
|
Updater.br.previousElementSibling.getBoundingClientRect().bottom - d.body.clientHeight < 25
|
||||||
if conf['Verbose']
|
if conf['Verbose']
|
||||||
Updater.count.textContent = '+' + newPosts
|
Updater.count.textContent = "+#{newPosts}"
|
||||||
if newPosts is 0
|
Updater.count.className = if newPosts then 'new' else null
|
||||||
Updater.count.className = null
|
|
||||||
else
|
|
||||||
Updater.count.className = 'new'
|
|
||||||
|
|
||||||
$.before Updater.br, nodes.reverse()
|
$.before Updater.br, nodes.reverse()
|
||||||
if scroll
|
if scroll
|
||||||
@ -2688,19 +2648,17 @@ QuoteInline =
|
|||||||
inline.textContent = "#{req.status} #{req.statusText}"
|
inline.textContent = "#{req.status} #{req.statusText}"
|
||||||
return
|
return
|
||||||
|
|
||||||
body = $.el 'body',
|
doc = d.implementation.createHTMLDocument null
|
||||||
innerHTML: req.responseText
|
doc.documentElement.innerHTML = req.responseText
|
||||||
if id is threadID #OP
|
|
||||||
op = Threading.op $('body > form', body).firstChild
|
node =
|
||||||
html = op.innerHTML
|
if id is threadID #OP
|
||||||
else
|
Threading.op $('body > form', doc).firstChild
|
||||||
for reply in $$ '.reply', body
|
else
|
||||||
if reply.id == id
|
doc.getElementById id
|
||||||
html = reply.innerHTML
|
newInline = QuoteInline.table id, node.innerHTML
|
||||||
break
|
|
||||||
newInline = QuoteInline.table id, html
|
|
||||||
for quote in $$ '.quotelink', newInline
|
for quote in $$ '.quotelink', newInline
|
||||||
if (href = quote.getAttribute('href')) is quote.hash #add pathname to normal quotes
|
if (href = quote.getAttribute 'href') is quote.hash #add pathname to normal quotes
|
||||||
quote.pathname = pathname
|
quote.pathname = pathname
|
||||||
else if !g.REPLY and href isnt quote.href #fix x-thread links, not x-board ones
|
else if !g.REPLY and href isnt quote.href #fix x-thread links, not x-board ones
|
||||||
quote.href = "res/#{href}"
|
quote.href = "res/#{href}"
|
||||||
@ -2756,23 +2714,21 @@ QuotePreview =
|
|||||||
$.off @, 'mouseout', QuotePreview.mouseout
|
$.off @, 'mouseout', QuotePreview.mouseout
|
||||||
$.off @, 'click', QuotePreview.mouseout
|
$.off @, 'click', QuotePreview.mouseout
|
||||||
parse: (req, id, threadID) ->
|
parse: (req, id, threadID) ->
|
||||||
return unless (qp = ui.el) and (qp.innerHTML is "Loading #{id}...")
|
return unless (qp = ui.el) and qp.textContent is "Loading #{id}..."
|
||||||
|
|
||||||
if req.status isnt 200
|
if req.status isnt 200
|
||||||
qp.textContent = "#{req.status} #{req.statusText}"
|
qp.textContent = "#{req.status} #{req.statusText}"
|
||||||
return
|
return
|
||||||
|
|
||||||
body = $.el 'body',
|
doc = d.implementation.createHTMLDocument null
|
||||||
innerHTML: req.responseText
|
doc.documentElement.innerHTML = req.responseText
|
||||||
if id is threadID #OP
|
|
||||||
op = Threading.op $('body > form', body).firstChild
|
node =
|
||||||
html = op.innerHTML
|
if id is threadID #OP
|
||||||
else
|
Threading.op $('body > form', doc).firstChild
|
||||||
for reply in $$ '.reply', body
|
else
|
||||||
if reply.id == id
|
doc.getElementById id
|
||||||
html = reply.innerHTML
|
qp.innerHTML = node.innerHTML
|
||||||
break
|
|
||||||
qp.innerHTML = html
|
|
||||||
post =
|
post =
|
||||||
root: qp
|
root: qp
|
||||||
filesize: $ '.filesize', qp
|
filesize: $ '.filesize', qp
|
||||||
@ -3176,6 +3132,10 @@ Main =
|
|||||||
else
|
else
|
||||||
g.PAGENUM = parseInt(temp) or 0
|
g.PAGENUM = parseInt(temp) or 0
|
||||||
|
|
||||||
|
#load values from localStorage
|
||||||
|
for key, val of conf
|
||||||
|
conf[key] = $.get key, val
|
||||||
|
|
||||||
$.on window, 'message', Main.message
|
$.on window, 'message', Main.message
|
||||||
|
|
||||||
switch location.hostname
|
switch location.hostname
|
||||||
@ -3302,20 +3262,20 @@ Main =
|
|||||||
ImageExpand.init()
|
ImageExpand.init()
|
||||||
|
|
||||||
if conf['Thread Watcher']
|
if conf['Thread Watcher']
|
||||||
Watcher.init()
|
setTimeout -> Watcher.init()
|
||||||
|
|
||||||
if conf['Keybinds']
|
if conf['Keybinds']
|
||||||
Keybinds.init()
|
setTimeout -> Keybinds.init()
|
||||||
|
|
||||||
if g.REPLY
|
if g.REPLY
|
||||||
if conf['Thread Updater']
|
if conf['Thread Updater']
|
||||||
Updater.init()
|
setTimeout -> Updater.init()
|
||||||
|
|
||||||
if conf['Thread Stats']
|
if conf['Thread Stats']
|
||||||
ThreadStats.init()
|
ThreadStats.init()
|
||||||
|
|
||||||
if conf['Reply Navigation']
|
if conf['Reply Navigation']
|
||||||
Nav.init()
|
setTimeout -> Nav.init()
|
||||||
|
|
||||||
if conf['Post in Title']
|
if conf['Post in Title']
|
||||||
TitlePost.init()
|
TitlePost.init()
|
||||||
@ -3325,16 +3285,16 @@ Main =
|
|||||||
|
|
||||||
else #not reply
|
else #not reply
|
||||||
if conf['Thread Hiding']
|
if conf['Thread Hiding']
|
||||||
ThreadHiding.init()
|
setTimeout -> ThreadHiding.init()
|
||||||
|
|
||||||
if conf['Thread Expansion']
|
if conf['Thread Expansion']
|
||||||
ExpandThread.init()
|
setTimeout -> ExpandThread.init()
|
||||||
|
|
||||||
if conf['Comment Expansion']
|
if conf['Comment Expansion']
|
||||||
ExpandComment.init()
|
setTimeout -> ExpandComment.init()
|
||||||
|
|
||||||
if conf['Index Navigation']
|
if conf['Index Navigation']
|
||||||
Nav.init()
|
setTimeout -> Nav.init()
|
||||||
|
|
||||||
nodes = []
|
nodes = []
|
||||||
for node in $$ '.op, a + table', form
|
for node in $$ '.op, a + table', form
|
||||||
@ -3372,7 +3332,7 @@ Main =
|
|||||||
el: if klass is 'op' then node else node.firstChild.firstChild.lastChild
|
el: if klass is 'op' then node else node.firstChild.firstChild.lastChild
|
||||||
class: klass
|
class: klass
|
||||||
id: node.getElementsByTagName('input')[0].name
|
id: node.getElementsByTagName('input')[0].name
|
||||||
threadId: g.THREAD_ID or $.x('ancestor::div[contains(@class,"thread")]', node).firstChild.id
|
threadId: g.THREAD_ID or $.x('ancestor::div[@class="thread"]', node).firstChild.id
|
||||||
isOP: klass is 'op'
|
isOP: klass is 'op'
|
||||||
isInlined: /\binline\b/.test klass
|
isInlined: /\binline\b/.test klass
|
||||||
filesize: node.getElementsByClassName('filesize')[0] or false
|
filesize: node.getElementsByClassName('filesize')[0] or false
|
||||||
@ -3385,7 +3345,7 @@ Main =
|
|||||||
try
|
try
|
||||||
callback node for node in nodes
|
callback node for node in nodes
|
||||||
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 (#{VERSION}) error: #{err.message}\nhttp://mayhemydg.github.com/4chan-x/#bug-report\n\n#{err.stack}" if notify
|
||||||
return
|
return
|
||||||
observer: (mutations) ->
|
observer: (mutations) ->
|
||||||
nodes = []
|
nodes = []
|
||||||
@ -3412,7 +3372,9 @@ a[href="javascript:;"] {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.thread.stub > :not(.block),
|
.block ~ .op,
|
||||||
|
.block ~ .omittedposts,
|
||||||
|
.block ~ table,
|
||||||
#content > [name=tab]:not(:checked) + div,
|
#content > [name=tab]:not(:checked) + div,
|
||||||
#updater:not(:hover) > :not(.move),
|
#updater:not(:hover) > :not(.move),
|
||||||
#qp > input, #qp .inline, .forwarded {
|
#qp > input, #qp .inline, .forwarded {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user