Merge branch 'master' into v3
I really need to get back to this.
This commit is contained in:
commit
cf55f670c0
@ -3,7 +3,7 @@
|
|||||||
// @version 3.0.0
|
// @version 3.0.0
|
||||||
// @description Cross-browser userscript for maximum lurking on 4chan.
|
// @description Cross-browser userscript for maximum lurking on 4chan.
|
||||||
// @copyright 2009-2011 James Campos <james.r.campos@gmail.com>
|
// @copyright 2009-2011 James Campos <james.r.campos@gmail.com>
|
||||||
// @copyright 2012 Nicolas Stepien <stepien.nicolas@gmail.com>
|
// @copyright 2012-2013 Nicolas Stepien <stepien.nicolas@gmail.com>
|
||||||
// @license MIT; http://en.wikipedia.org/wiki/Mit_license
|
// @license MIT; http://en.wikipedia.org/wiki/Mit_license
|
||||||
// @match *://boards.4chan.org/*
|
// @match *://boards.4chan.org/*
|
||||||
// @match *://images.4chan.org/*
|
// @match *://images.4chan.org/*
|
||||||
|
|||||||
192
4chan_x.user.js
192
4chan_x.user.js
@ -3,7 +3,7 @@
|
|||||||
// @version 3.0.0
|
// @version 3.0.0
|
||||||
// @description Cross-browser userscript for maximum lurking on 4chan.
|
// @description Cross-browser userscript for maximum lurking on 4chan.
|
||||||
// @copyright 2009-2011 James Campos <james.r.campos@gmail.com>
|
// @copyright 2009-2011 James Campos <james.r.campos@gmail.com>
|
||||||
// @copyright 2012 Nicolas Stepien <stepien.nicolas@gmail.com>
|
// @copyright 2012-2013 Nicolas Stepien <stepien.nicolas@gmail.com>
|
||||||
// @license MIT; http://en.wikipedia.org/wiki/Mit_license
|
// @license MIT; http://en.wikipedia.org/wiki/Mit_license
|
||||||
// @match *://boards.4chan.org/*
|
// @match *://boards.4chan.org/*
|
||||||
// @match *://images.4chan.org/*
|
// @match *://images.4chan.org/*
|
||||||
@ -20,11 +20,11 @@
|
|||||||
// @icon https://github.com/MayhemYDG/4chan-x/raw/stable/img/icon.gif
|
// @icon https://github.com/MayhemYDG/4chan-x/raw/stable/img/icon.gif
|
||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
|
|
||||||
/* 4chan X Alpha - Version 3.0.0 - 2012-10-25
|
/* 4chan X Alpha - Version 3.0.0 - 2013-01-13
|
||||||
* http://mayhemydg.github.com/4chan-x/
|
* http://mayhemydg.github.com/4chan-x/
|
||||||
*
|
*
|
||||||
* Copyright (c) 2009-2011 James Campos <james.r.campos@gmail.com>
|
* Copyright (c) 2009-2011 James Campos <james.r.campos@gmail.com>
|
||||||
* Copyright (c) 2012 Nicolas Stepien <stepien.nicolas@gmail.com>
|
* Copyright (c) 2012-2013 Nicolas Stepien <stepien.nicolas@gmail.com>
|
||||||
* Licensed under the MIT license.
|
* Licensed under the MIT license.
|
||||||
* https://github.com/MayhemYDG/4chan-x/blob/master/LICENSE
|
* https://github.com/MayhemYDG/4chan-x/blob/master/LICENSE
|
||||||
*
|
*
|
||||||
@ -161,6 +161,7 @@
|
|||||||
},
|
},
|
||||||
updater: {
|
updater: {
|
||||||
checkbox: {
|
checkbox: {
|
||||||
|
'Beep': [false, 'Beep on new post to completely read thread.'],
|
||||||
'Auto Scroll': [false, 'Scroll updated posts into view. Only enabled at bottom of page.'],
|
'Auto Scroll': [false, 'Scroll updated posts into view. Only enabled at bottom of page.'],
|
||||||
'Scroll BG': [false, 'Auto-scroll background tabs.'],
|
'Scroll BG': [false, 'Auto-scroll background tabs.'],
|
||||||
'Auto Update': [true, 'Automatically fetch new posts.']
|
'Auto Update': [true, 'Automatically fetch new posts.']
|
||||||
@ -571,6 +572,9 @@
|
|||||||
open: function(url) {
|
open: function(url) {
|
||||||
return (GM_openInTab || window.open)(url, '_blank');
|
return (GM_openInTab || window.open)(url, '_blank');
|
||||||
},
|
},
|
||||||
|
hidden: function() {
|
||||||
|
return d.hidden || d.oHidden || d.mozHidden || d.webkitHidden;
|
||||||
|
},
|
||||||
queueTask: (function() {
|
queueTask: (function() {
|
||||||
var execTask, taskChannel, taskQueue;
|
var execTask, taskChannel, taskQueue;
|
||||||
taskQueue = [];
|
taskQueue = [];
|
||||||
@ -691,6 +695,8 @@
|
|||||||
return "//archive.foolz.us/" + board + "/full_image/" + filename;
|
return "//archive.foolz.us/" + board + "/full_image/" + filename;
|
||||||
case 'u':
|
case 'u':
|
||||||
return "//nsfw.foolz.us/" + board + "/full_image/" + filename;
|
return "//nsfw.foolz.us/" + board + "/full_image/" + filename;
|
||||||
|
case 'po':
|
||||||
|
return "http://archive.thedarkcave.org/" + board + "/full_image/" + filename;
|
||||||
case 'ck':
|
case 'ck':
|
||||||
case 'lit':
|
case 'lit':
|
||||||
return "//fuuka.warosu.org/" + board + "/full_image/" + filename;
|
return "//fuuka.warosu.org/" + board + "/full_image/" + filename;
|
||||||
@ -700,7 +706,6 @@
|
|||||||
case 'cgl':
|
case 'cgl':
|
||||||
case 'g':
|
case 'g':
|
||||||
case 'mu':
|
case 'mu':
|
||||||
case 'soc':
|
|
||||||
case 'w':
|
case 'w':
|
||||||
return "//rbt.asia/" + board + "/full_image/" + filename;
|
return "//rbt.asia/" + board + "/full_image/" + filename;
|
||||||
case 'an':
|
case 'an':
|
||||||
@ -711,6 +716,8 @@
|
|||||||
case 'toy':
|
case 'toy':
|
||||||
case 'x':
|
case 'x':
|
||||||
return "http://archive.heinessen.com/" + board + "/full_image/" + filename;
|
return "http://archive.heinessen.com/" + board + "/full_image/" + filename;
|
||||||
|
case 'c':
|
||||||
|
return "//archive.nyafuu.org/" + board + "/full_image/" + filename;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
post: function(board, postID) {
|
post: function(board, postID) {
|
||||||
@ -732,6 +739,8 @@
|
|||||||
case 'u':
|
case 'u':
|
||||||
case 'kuku':
|
case 'kuku':
|
||||||
return "//nsfw.foolz.us/_/api/chan/post/?board=" + board + "&num=" + postID;
|
return "//nsfw.foolz.us/_/api/chan/post/?board=" + board + "&num=" + postID;
|
||||||
|
case 'po':
|
||||||
|
return "http://archive.thedarkcave.org/_/api/chan/post/?board=" + board + "&num=" + postID;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
to: function(data) {
|
to: function(data) {
|
||||||
@ -757,6 +766,9 @@
|
|||||||
case 'kuku':
|
case 'kuku':
|
||||||
url = Redirect.path('//nsfw.foolz.us', 'foolfuuka', data);
|
url = Redirect.path('//nsfw.foolz.us', 'foolfuuka', data);
|
||||||
break;
|
break;
|
||||||
|
case 'po':
|
||||||
|
url = Redirect.path('http://archive.thedarkcave.org', 'foolfuuka', data);
|
||||||
|
break;
|
||||||
case 'ck':
|
case 'ck':
|
||||||
case 'lit':
|
case 'lit':
|
||||||
url = Redirect.path('//fuuka.warosu.org', 'fuuka', data);
|
url = Redirect.path('//fuuka.warosu.org', 'fuuka', data);
|
||||||
@ -768,7 +780,6 @@
|
|||||||
case 'cgl':
|
case 'cgl':
|
||||||
case 'g':
|
case 'g':
|
||||||
case 'mu':
|
case 'mu':
|
||||||
case 'soc':
|
|
||||||
case 'w':
|
case 'w':
|
||||||
url = Redirect.path('//rbt.asia', 'fuuka', data);
|
url = Redirect.path('//rbt.asia', 'fuuka', data);
|
||||||
break;
|
break;
|
||||||
@ -781,6 +792,9 @@
|
|||||||
case 'x':
|
case 'x':
|
||||||
url = Redirect.path('http://archive.heinessen.com', 'fuuka', data);
|
url = Redirect.path('http://archive.heinessen.com', 'fuuka', data);
|
||||||
break;
|
break;
|
||||||
|
case 'c':
|
||||||
|
url = Redirect.path('//archive.nyafuu.org', 'fuuka', data);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (data.threadID) {
|
if (data.threadID) {
|
||||||
url = "//boards.4chan.org/" + board + "/";
|
url = "//boards.4chan.org/" + board + "/";
|
||||||
@ -807,6 +821,9 @@
|
|||||||
postID = postID.match(/\d+/)[0];
|
postID = postID.match(/\d+/)[0];
|
||||||
}
|
}
|
||||||
path = threadID ? "" + board + "/thread/" + threadID : "" + board + "/post/" + postID;
|
path = threadID ? "" + board + "/thread/" + threadID : "" + board + "/post/" + postID;
|
||||||
|
if (archiver === 'foolfuuka') {
|
||||||
|
path += '/';
|
||||||
|
}
|
||||||
if (threadID && postID) {
|
if (threadID && postID) {
|
||||||
path += archiver === 'foolfuuka' ? "#" + postID : "#p" + postID;
|
path += archiver === 'foolfuuka' ? "#" + postID : "#p" + postID;
|
||||||
}
|
}
|
||||||
@ -835,7 +852,7 @@
|
|||||||
capcode: data.capcode,
|
capcode: data.capcode,
|
||||||
tripcode: data.trip,
|
tripcode: data.trip,
|
||||||
uniqueID: data.id,
|
uniqueID: data.id,
|
||||||
email: data.email ? encodeURIComponent(data.email.replace(/"/g, '"')) : '',
|
email: data.email ? encodeURI(data.email.replace(/"/g, '"')) : '',
|
||||||
subject: data.sub,
|
subject: data.sub,
|
||||||
flagCode: data.country,
|
flagCode: data.country,
|
||||||
flagName: data.country_name,
|
flagName: data.country_name,
|
||||||
@ -1111,7 +1128,7 @@
|
|||||||
return '</b>';
|
return '</b>';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
comment = bq.innerHTML.replace(/(^|>)(>[^<$]+)(<|$)/g, '$1<span class=quote>$2</span>$3');
|
comment = bq.innerHTML.replace(/(^|>)(>[^<$]*)(<|$)/g, '$1<span class=quote>$2</span>$3').replace(/((>){2}(>\/[a-z\d]+\/)?\d+)/g, '<span class=deadlink>$1</span>');
|
||||||
threadID = data.thread_num;
|
threadID = data.thread_num;
|
||||||
o = {
|
o = {
|
||||||
postID: "" + postID,
|
postID: "" + postID,
|
||||||
@ -1130,7 +1147,7 @@
|
|||||||
})(),
|
})(),
|
||||||
tripcode: data.trip,
|
tripcode: data.trip,
|
||||||
uniqueID: data.poster_hash,
|
uniqueID: data.poster_hash,
|
||||||
email: data.email ? encodeURIComponent(data.email) : '',
|
email: data.email ? encodeURI(data.email) : '',
|
||||||
subject: data.title_processed,
|
subject: data.title_processed,
|
||||||
flagCode: data.poster_country,
|
flagCode: data.poster_country,
|
||||||
flagName: data.poster_country_name_processed,
|
flagName: data.poster_country_name_processed,
|
||||||
@ -1171,79 +1188,73 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
node: function() {
|
node: function() {
|
||||||
var ID, a, board, data, i, index, m, node, nodes, post, quote, quoteID, quotes, snapshot, text, _i, _j, _len, _ref;
|
var ID, a, board, deadlink, m, post, quote, quoteID, redirect, _i, _len, _ref, _ref1;
|
||||||
if (this.isClone) {
|
if (this.isClone) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
snapshot = d.evaluate('.//text()[not(parent::a)]', this.nodes.comment, null, 6, null);
|
_ref = $$('.deadlink', post.blockquote);
|
||||||
for (i = _i = 0, _ref = snapshot.snapshotLength; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
node = snapshot.snapshotItem(i);
|
deadlink = _ref[_i];
|
||||||
data = node.data;
|
if (deadlink.parentNode.className === 'prettyprint') {
|
||||||
if (!(quotes = data.match(/>>(>\/[a-z\d]+\/)?\d+/g))) {
|
$.replace(deadlink, Array.prototype.slice.call(deadlink.childNodes));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
nodes = [];
|
quote = deadlink.textContent;
|
||||||
for (_j = 0, _len = quotes.length; _j < _len; _j++) {
|
if (!(ID = (_ref1 = quote.match(/\d+$/)) != null ? _ref1[0] : void 0)) {
|
||||||
quote = quotes[_j];
|
continue;
|
||||||
index = data.indexOf(quote);
|
}
|
||||||
if (text = data.slice(0, index)) {
|
board = (m = quote.match(/^>>>\/([a-z\d]+)/)) ? m[1] : this.board.ID;
|
||||||
nodes.push($.tn(text));
|
quoteID = "" + board + "." + ID;
|
||||||
}
|
if (post = g.posts[quoteID]) {
|
||||||
ID = quote.match(/\d+$/)[0];
|
if (!post.isDead) {
|
||||||
board = (m = quote.match(/^>>>\/([a-z\d]+)/)) ? m[1] : this.board.ID;
|
|
||||||
quoteID = "" + board + "." + ID;
|
|
||||||
if (post = g.posts[quoteID]) {
|
|
||||||
if (post.isDead) {
|
|
||||||
a = $.el('a', {
|
|
||||||
href: Redirect.to({
|
|
||||||
board: board,
|
|
||||||
threadID: 0,
|
|
||||||
postID: ID
|
|
||||||
}),
|
|
||||||
className: 'quotelink deadlink',
|
|
||||||
textContent: "" + quote + "\u00A0(Dead)",
|
|
||||||
target: '_blank'
|
|
||||||
});
|
|
||||||
a.setAttribute('data-board', board);
|
|
||||||
a.setAttribute('data-threadid', post.thread.ID);
|
|
||||||
a.setAttribute('data-postid', ID);
|
|
||||||
} else {
|
|
||||||
a = $.el('a', {
|
|
||||||
href: "/" + board + "/" + post.thread + "/res/#p" + ID,
|
|
||||||
className: 'quotelink',
|
|
||||||
textContent: quote
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
a = $.el('a', {
|
a = $.el('a', {
|
||||||
href: Redirect.to({
|
href: "/" + board + "/" + post.thread + "/res/#p" + ID,
|
||||||
board: board,
|
className: 'quotelink',
|
||||||
threadID: 0,
|
textContent: quote
|
||||||
postID: ID
|
});
|
||||||
}),
|
} else if (redirect = Redirect.to({
|
||||||
className: 'deadlink',
|
board: board,
|
||||||
|
threadID: post.thread.ID,
|
||||||
|
postID: ID
|
||||||
|
})) {
|
||||||
|
a = $.el('a', {
|
||||||
|
href: redirect,
|
||||||
|
className: 'quotelink deadlink',
|
||||||
target: '_blank',
|
target: '_blank',
|
||||||
textContent: "" + quote + "\u00A0(Dead)"
|
textContent: "" + quote + "\u00A0(Dead)"
|
||||||
});
|
});
|
||||||
if (Redirect.post(board, ID)) {
|
a.setAttribute('data-board', board);
|
||||||
$.addClass(a, 'quotelink');
|
a.setAttribute('data-threadid', post.thread.ID);
|
||||||
a.setAttribute('data-board', board);
|
a.setAttribute('data-postid', ID);
|
||||||
a.setAttribute('data-postid', ID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (this.quotes.indexOf(quoteID) === -1) {
|
} else if (redirect = Redirect.to({
|
||||||
this.quotes.push(quoteID);
|
board: board,
|
||||||
|
threadID: 0,
|
||||||
|
postID: ID
|
||||||
|
})) {
|
||||||
|
a = $.el('a', {
|
||||||
|
href: redirect,
|
||||||
|
className: 'deadlink',
|
||||||
|
target: '_blank',
|
||||||
|
textContent: "" + quote + "\u00A0(Dead)"
|
||||||
|
});
|
||||||
|
if (Redirect.post(board, ID)) {
|
||||||
|
$.addClass(a, 'quotelink');
|
||||||
|
a.setAttribute('data-board', board);
|
||||||
|
a.setAttribute('data-postid', ID);
|
||||||
}
|
}
|
||||||
if ($.hasClass(a, 'quotelink')) {
|
|
||||||
this.nodes.quotelinks.push(a);
|
|
||||||
}
|
|
||||||
nodes.push(a);
|
|
||||||
data = data.slice(index + quote.length);
|
|
||||||
}
|
}
|
||||||
if (data) {
|
if (a) {
|
||||||
nodes.push($.tn(data));
|
$.replace(deadlink, a);
|
||||||
|
} else {
|
||||||
|
deadlink.textContent += "\u00A0(Dead)";
|
||||||
|
}
|
||||||
|
if (this.quotes.indexOf(quoteID) === -1) {
|
||||||
|
this.quotes.push(quoteID);
|
||||||
|
}
|
||||||
|
if ($.hasClass(a, 'quotelink')) {
|
||||||
|
this.nodes.quotelinks.push(a);
|
||||||
}
|
}
|
||||||
$.replace(node, nodes);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1988,6 +1999,12 @@
|
|||||||
node: function() {
|
node: function() {
|
||||||
return new ThreadUpdater.Updater(this);
|
return new ThreadUpdater.Updater(this);
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
|
http://freesound.org/people/pierrecartoons1979/sounds/90112/
|
||||||
|
cc-by-nc-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
beep: 'data:audio/wav;base64,UklGRjQDAABXQVZFZm10IBAAAAABAAEAgD4AAIA+AAABAAgAc21wbDwAAABBAAADAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkYXRhzAIAAGMms8em0tleMV4zIpLVo8nhfSlcPR102Ki+5JspVEkdVtKzs+K1NEhUIT7DwKrcy0g6WygsrM2k1NpiLl0zIY/WpMrjgCdbPhxw2Kq+5Z4qUkkdU9K1s+K5NkVTITzBwqnczko3WikrqM+l1NxlLF0zIIvXpsnjgydZPhxs2ay95aIrUEkdUdC3suK8N0NUIjq+xKrcz002WioppdGm091pK1w0IIjYp8jkhydXPxxq2K295aUrTkoeTs65suK+OUFUIzi7xqrb0VA0WSoootKm0t5tKlo1H4TYqMfkiydWQBxm16+85actTEseS8y7seHAPD9TIza5yKra01QyWSson9On0d5wKVk2H4DYqcfkjidUQB1j1rG75KsvSkseScu8seDCPz1TJDW2yara1FYxWSwnm9Sn0N9zKVg2H33ZqsXkkihSQR1g1bK65K0wSEsfR8i+seDEQTxUJTOzy6rY1VowWC0mmNWoz993KVc3H3rYq8TklSlRQh1d1LS647AyR0wgRMbAsN/GRDpTJTKwzKrX1l4vVy4lldWpzt97KVY4IXbUr8LZljVPRCxhw7W3z6ZISkw1VK+4sMWvXEhSPk6buay9sm5JVkZNiLWqtrJ+TldNTnquqbCwilZXU1BwpKirrpNgWFhTaZmnpquZbFlbVmWOpaOonHZcXlljhaGhpZ1+YWBdYn2cn6GdhmdhYGN3lp2enIttY2Jjco+bnJuOdGZlZXCImJqakHpoZ2Zug5WYmZJ/bGlobX6RlpeSg3BqaW16jZSVkoZ0bGtteImSk5KIeG5tbnaFkJKRinxxbm91gY2QkIt/c3BwdH6Kj4+LgnZxcXR8iI2OjIR5c3J0e4WLjYuFe3VzdHmCioyLhn52dHR5gIiKioeAeHV1eH+GiYqHgXp2dnh9hIiJh4J8eHd4fIKHiIeDfXl4eHyBhoeHhH96eHmA',
|
||||||
Updater: (function() {
|
Updater: (function() {
|
||||||
|
|
||||||
function _Class(thread) {
|
function _Class(thread) {
|
||||||
@ -2064,9 +2081,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
visibility: function() {
|
visibility: function() {
|
||||||
var state;
|
if ($.hidden()) {
|
||||||
state = d.visibilityState || d.oVisibilityState || d.mozVisibilityState || d.webkitVisibilityState;
|
|
||||||
if (state !== 'visible') {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.unsuccessfulFetchCount = 0;
|
this.unsuccessfulFetchCount = 0;
|
||||||
@ -2085,7 +2100,7 @@
|
|||||||
return this.scrollBG = this['Scroll BG'] ? function() {
|
return this.scrollBG = this['Scroll BG'] ? function() {
|
||||||
return true;
|
return true;
|
||||||
} : function() {
|
} : function() {
|
||||||
return !(d.hidden || d.oHidden || d.mozHidden || d.webkitHidden);
|
return !$.hidden();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
autoUpdate: function() {
|
autoUpdate: function() {
|
||||||
@ -2143,7 +2158,7 @@
|
|||||||
var i, j;
|
var i, j;
|
||||||
i = this.interval;
|
i = this.interval;
|
||||||
j = Math.min(this.unsuccessfulFetchCount, 10);
|
j = Math.min(this.unsuccessfulFetchCount, 10);
|
||||||
if (!(d.hidden || d.oHidden || d.mozHidden || d.webkitHidden)) {
|
if (!$.hidden()) {
|
||||||
j = Math.min(j, 7);
|
j = Math.min(j, 7);
|
||||||
}
|
}
|
||||||
return this.seconds = Math.max(i, [0, 5, 10, 15, 20, 30, 60, 90, 120, 240, 300][j]);
|
return this.seconds = Math.max(i, [0, 5, 10, 15, 20, 30, 60, 90, 120, 240, 300][j]);
|
||||||
@ -2231,6 +2246,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count) {
|
if (count) {
|
||||||
|
if (Conf['Beep'] && $.hidden() && (Unread.replies.length === 0)) {
|
||||||
|
if (!this.audio) {
|
||||||
|
this.audio = $.el('audio', {
|
||||||
|
src: ThreadUpdater.beep
|
||||||
|
});
|
||||||
|
}
|
||||||
|
audio.play();
|
||||||
|
}
|
||||||
this.set('status', "+" + count);
|
this.set('status', "+" + count);
|
||||||
this.status.className = 'new';
|
this.status.className = 'new';
|
||||||
this.unsuccessfulFetchCount = 0;
|
this.unsuccessfulFetchCount = 0;
|
||||||
@ -2299,7 +2322,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
function Post(root, thread, board, that) {
|
function Post(root, thread, board, that) {
|
||||||
var alt, anchor, bq, capcode, data, date, email, file, fileInfo, flag, i, info, name, node, nodes, post, quotelink, quotes, size, subject, text, thumb, tripcode, uniqueID, unit, _i, _j, _k, _len, _len1, _ref, _ref1, _ref2;
|
var alt, anchor, bq, capcode, data, date, email, file, fileInfo, flag, hash, i, info, name, node, nodes, pathname, post, quotelink, quotes, size, subject, text, thumb, tripcode, uniqueID, unit, _i, _j, _k, _len, _len1, _ref, _ref1, _ref2;
|
||||||
this.thread = thread;
|
this.thread = thread;
|
||||||
this.board = board;
|
this.board = board;
|
||||||
if (that == null) {
|
if (that == null) {
|
||||||
@ -2365,13 +2388,22 @@
|
|||||||
_ref2 = $$('.quotelink', this.nodes.comment);
|
_ref2 = $$('.quotelink', this.nodes.comment);
|
||||||
for (_k = 0, _len1 = _ref2.length; _k < _len1; _k++) {
|
for (_k = 0, _len1 = _ref2.length; _k < _len1; _k++) {
|
||||||
quotelink = _ref2[_k];
|
quotelink = _ref2[_k];
|
||||||
if (quotelink.hash) {
|
hash = quotelink.hash;
|
||||||
this.nodes.quotelinks.push(quotelink);
|
if (!hash) {
|
||||||
if (quotelink.parentNode.parentNode.className === 'capcodeReplies') {
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
quotes["" + (quotelink.pathname.split('/')[1]) + "." + quotelink.hash.slice(2)] = true;
|
|
||||||
}
|
}
|
||||||
|
pathname = quotelink.pathname;
|
||||||
|
if (/catalog$/.test(pathname)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (quotelink.hostname !== 'boards.4chan.org') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this.nodes.quotelinks.push(quotelink);
|
||||||
|
if (quotelink.parentNode.parentNode.className === 'capcodeReplies') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
quotes["" + (pathname.split('/')[1]) + "." + hash.slice(2)] = true;
|
||||||
}
|
}
|
||||||
this.quotes = Object.keys(quotes);
|
this.quotes = Object.keys(quotes);
|
||||||
if ((file = $('.file', post)) && (thumb = $('img[data-md5]', file))) {
|
if ((file = $('.file', post)) && (thumb = $('img[data-md5]', file))) {
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@ -1,5 +1,5 @@
|
|||||||
Copyright (c) 2009-2011 James Campos <james.r.campos@gmail.com>
|
Copyright (c) 2009-2011 James Campos <james.r.campos@gmail.com>
|
||||||
Copyright (c) 2012 Nicolas Stepien <stepien.nicolas@gmail.com>
|
Copyright (c) 2012-2013 Nicolas Stepien <stepien.nicolas@gmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation
|
obtaining a copy of this software and associated documentation
|
||||||
|
|||||||
41
changelog
41
changelog
@ -7,6 +7,47 @@ alpha
|
|||||||
Fix Quote Highlighting not affecting inlined quotes.
|
Fix Quote Highlighting not affecting inlined quotes.
|
||||||
|
|
||||||
master
|
master
|
||||||
|
- Mayhem
|
||||||
|
Add /po/ archive redirection for threads, images and post resurrection.
|
||||||
|
|
||||||
|
2.37.3
|
||||||
|
- Mayhem
|
||||||
|
Fix successful posting causing errors.
|
||||||
|
Fix 4chan X trying to interact with >>>/board/rules links.
|
||||||
|
|
||||||
|
2.37.2
|
||||||
|
- aeosynth
|
||||||
|
Beep on new post to completely read thread
|
||||||
|
- Mayhem
|
||||||
|
Fix dead quotes.
|
||||||
|
|
||||||
|
2.37.1
|
||||||
|
- noface
|
||||||
|
Fix Anonymize not working on stubs.
|
||||||
|
- Mayhem
|
||||||
|
Fix selection quoting on Opera.
|
||||||
|
Fix history bug with Persistent QR enabled on Chrome.
|
||||||
|
Fix posting warning not displaying the reason.
|
||||||
|
Fix deadquotes showing up in code-tags.
|
||||||
|
|
||||||
|
2.37.0
|
||||||
|
- noface
|
||||||
|
Add Catalog Links toggle.
|
||||||
|
Fix Anonymize not working on hovered posts.
|
||||||
|
- Mayhem
|
||||||
|
Added catalog support.
|
||||||
|
Sync thread hiding between index and catalog.
|
||||||
|
Add /c/ archived thread and image redirection.
|
||||||
|
|
||||||
|
2.36.3
|
||||||
|
- Mayhem
|
||||||
|
Fix next/previous page keybinds.
|
||||||
|
|
||||||
|
2.36.2
|
||||||
|
- noface
|
||||||
|
Add tags support on /f/.
|
||||||
|
- Mayhem
|
||||||
|
Add /mu/ archived image redirection.
|
||||||
|
|
||||||
2.36.1
|
2.36.1
|
||||||
- noface
|
- noface
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
postMessage({version:'2.36.1'},'*')
|
postMessage({version:'2.37.3'},'*')
|
||||||
@ -138,6 +138,8 @@ $.extend $,
|
|||||||
return
|
return
|
||||||
open: (url) ->
|
open: (url) ->
|
||||||
(GM_openInTab or window.open) url, '_blank'
|
(GM_openInTab or window.open) url, '_blank'
|
||||||
|
hidden: ->
|
||||||
|
d.hidden or d.oHidden or d.mozHidden or d.webkitHidden
|
||||||
queueTask: (->
|
queueTask: (->
|
||||||
# inspired by https://www.w3.org/Bugs/Public/show_bug.cgi?id=15007
|
# inspired by https://www.w3.org/Bugs/Public/show_bug.cgi?id=15007
|
||||||
taskQueue = []
|
taskQueue = []
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
* http://mayhemydg.github.com/4chan-x/
|
* http://mayhemydg.github.com/4chan-x/
|
||||||
*
|
*
|
||||||
* Copyright (c) 2009-2011 James Campos <james.r.campos@gmail.com>
|
* Copyright (c) 2009-2011 James Campos <james.r.campos@gmail.com>
|
||||||
* Copyright (c) <%= grunt.template.today('yyyy') %> Nicolas Stepien <stepien.nicolas@gmail.com>
|
* Copyright (c) 2012-<%= grunt.template.today('yyyy') %> Nicolas Stepien <stepien.nicolas@gmail.com>
|
||||||
* Licensed under the MIT license.
|
* Licensed under the MIT license.
|
||||||
* <%= meta.repo %>blob/master/LICENSE
|
* <%= meta.repo %>blob/master/LICENSE
|
||||||
*
|
*
|
||||||
|
|||||||
@ -156,6 +156,7 @@ Config =
|
|||||||
'hide': ['x', 'Hide thread.']
|
'hide': ['x', 'Hide thread.']
|
||||||
updater:
|
updater:
|
||||||
checkbox:
|
checkbox:
|
||||||
|
'Beep': [false, 'Beep on new post to completely read thread.']
|
||||||
'Auto Scroll': [false, 'Scroll updated posts into view. Only enabled at bottom of page.']
|
'Auto Scroll': [false, 'Scroll updated posts into view. Only enabled at bottom of page.']
|
||||||
'Scroll BG': [false, 'Auto-scroll background tabs.']
|
'Scroll BG': [false, 'Auto-scroll background tabs.']
|
||||||
'Auto Update': [true, 'Automatically fetch new posts.']
|
'Auto Update': [true, 'Automatically fetch new posts.']
|
||||||
|
|||||||
@ -7,20 +7,26 @@ Redirect =
|
|||||||
"//archive.foolz.us/#{board}/full_image/#{filename}"
|
"//archive.foolz.us/#{board}/full_image/#{filename}"
|
||||||
when 'u'
|
when 'u'
|
||||||
"//nsfw.foolz.us/#{board}/full_image/#{filename}"
|
"//nsfw.foolz.us/#{board}/full_image/#{filename}"
|
||||||
|
when 'po'
|
||||||
|
"http://archive.thedarkcave.org/#{board}/full_image/#{filename}"
|
||||||
when 'ck', 'lit'
|
when 'ck', 'lit'
|
||||||
"//fuuka.warosu.org/#{board}/full_image/#{filename}"
|
"//fuuka.warosu.org/#{board}/full_image/#{filename}"
|
||||||
when 'diy', 'sci'
|
when 'diy', 'sci'
|
||||||
"//archive.installgentoo.net/#{board}/full_image/#{filename}"
|
"//archive.installgentoo.net/#{board}/full_image/#{filename}"
|
||||||
when 'cgl', 'g', 'mu', 'soc', 'w'
|
when 'cgl', 'g', 'mu', 'w'
|
||||||
"//rbt.asia/#{board}/full_image/#{filename}"
|
"//rbt.asia/#{board}/full_image/#{filename}"
|
||||||
when 'an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'
|
when 'an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'
|
||||||
"http://archive.heinessen.com/#{board}/full_image/#{filename}"
|
"http://archive.heinessen.com/#{board}/full_image/#{filename}"
|
||||||
|
when 'c'
|
||||||
|
"//archive.nyafuu.org/#{board}/full_image/#{filename}"
|
||||||
post: (board, postID) ->
|
post: (board, postID) ->
|
||||||
switch board
|
switch board
|
||||||
when 'a', 'co', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'v', 'vg', 'wsg', 'dev', 'foolz'
|
when 'a', 'co', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'v', 'vg', 'wsg', 'dev', 'foolz'
|
||||||
"//archive.foolz.us/_/api/chan/post/?board=#{board}&num=#{postID}"
|
"//archive.foolz.us/_/api/chan/post/?board=#{board}&num=#{postID}"
|
||||||
when 'u', 'kuku'
|
when 'u', 'kuku'
|
||||||
"//nsfw.foolz.us/_/api/chan/post/?board=#{board}&num=#{postID}"
|
"//nsfw.foolz.us/_/api/chan/post/?board=#{board}&num=#{postID}"
|
||||||
|
when 'po'
|
||||||
|
"http://archive.thedarkcave.org/_/api/chan/post/?board=#{board}&num=#{postID}"
|
||||||
# for fuuka-based archives:
|
# for fuuka-based archives:
|
||||||
# https://github.com/eksopl/fuuka/issues/27
|
# https://github.com/eksopl/fuuka/issues/27
|
||||||
to: (data) ->
|
to: (data) ->
|
||||||
@ -30,14 +36,18 @@ Redirect =
|
|||||||
url = Redirect.path '//archive.foolz.us', 'foolfuuka', data
|
url = Redirect.path '//archive.foolz.us', 'foolfuuka', data
|
||||||
when 'u', 'kuku'
|
when 'u', 'kuku'
|
||||||
url = Redirect.path '//nsfw.foolz.us', 'foolfuuka', data
|
url = Redirect.path '//nsfw.foolz.us', 'foolfuuka', data
|
||||||
|
when 'po'
|
||||||
|
url = Redirect.path 'http://archive.thedarkcave.org', 'foolfuuka', data
|
||||||
when 'ck', 'lit'
|
when 'ck', 'lit'
|
||||||
url = Redirect.path '//fuuka.warosu.org', 'fuuka', data
|
url = Redirect.path '//fuuka.warosu.org', 'fuuka', data
|
||||||
when 'diy', 'sci'
|
when 'diy', 'sci'
|
||||||
url = Redirect.path '//archive.installgentoo.net', 'fuuka', data
|
url = Redirect.path '//archive.installgentoo.net', 'fuuka', data
|
||||||
when 'cgl', 'g', 'mu', 'soc', 'w'
|
when 'cgl', 'g', 'mu', 'w'
|
||||||
url = Redirect.path '//rbt.asia', 'fuuka', data
|
url = Redirect.path '//rbt.asia', 'fuuka', data
|
||||||
when 'an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'
|
when 'an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'
|
||||||
url = Redirect.path 'http://archive.heinessen.com', 'fuuka', data
|
url = Redirect.path 'http://archive.heinessen.com', 'fuuka', data
|
||||||
|
when 'c'
|
||||||
|
url = Redirect.path '//archive.nyafuu.org', 'fuuka', data
|
||||||
else
|
else
|
||||||
if data.threadID
|
if data.threadID
|
||||||
url = "//boards.4chan.org/#{board}/"
|
url = "//boards.4chan.org/#{board}/"
|
||||||
@ -68,6 +78,8 @@ Redirect =
|
|||||||
"#{board}/thread/#{threadID}"
|
"#{board}/thread/#{threadID}"
|
||||||
else
|
else
|
||||||
"#{board}/post/#{postID}"
|
"#{board}/post/#{postID}"
|
||||||
|
if archiver is 'foolfuuka'
|
||||||
|
path += '/'
|
||||||
if threadID and postID
|
if threadID and postID
|
||||||
path +=
|
path +=
|
||||||
if archiver is 'foolfuuka'
|
if archiver is 'foolfuuka'
|
||||||
@ -98,7 +110,7 @@ Build =
|
|||||||
capcode: data.capcode
|
capcode: data.capcode
|
||||||
tripcode: data.trip
|
tripcode: data.trip
|
||||||
uniqueID: data.id
|
uniqueID: data.id
|
||||||
email: if data.email then encodeURIComponent data.email.replace /"/g, '"' else ''
|
email: if data.email then encodeURI data.email.replace /"/g, '"' else ''
|
||||||
subject: data.sub
|
subject: data.sub
|
||||||
flagCode: data.country
|
flagCode: data.country
|
||||||
flagName: data.country_name
|
flagName: data.country_name
|
||||||
@ -474,8 +486,12 @@ Get =
|
|||||||
'<b style="color: red;">'
|
'<b style="color: red;">'
|
||||||
when '[/banned]'
|
when '[/banned]'
|
||||||
'</b>'
|
'</b>'
|
||||||
# greentext
|
|
||||||
comment = bq.innerHTML.replace /(^|>)(>[^<$]+)(<|$)/g, '$1<span class=quote>$2</span>$3'
|
comment = bq.innerHTML
|
||||||
|
# greentext
|
||||||
|
.replace(/(^|>)(>[^<$]*)(<|$)/g, '$1<span class=quote>$2</span>$3')
|
||||||
|
# quotes
|
||||||
|
.replace /((>){2}(>\/[a-z\d]+\/)?\d+)/g, '<span class=deadlink>$1</span>'
|
||||||
|
|
||||||
threadID = data.thread_num
|
threadID = data.thread_num
|
||||||
o =
|
o =
|
||||||
@ -491,7 +507,7 @@ Get =
|
|||||||
when 'D' then 'developer'
|
when 'D' then 'developer'
|
||||||
tripcode: data.trip
|
tripcode: data.trip
|
||||||
uniqueID: data.poster_hash
|
uniqueID: data.poster_hash
|
||||||
email: if data.email then encodeURIComponent data.email else ''
|
email: if data.email then encodeURI data.email else ''
|
||||||
subject: data.title_processed
|
subject: data.title_processed
|
||||||
flagCode: data.poster_country
|
flagCode: data.poster_country
|
||||||
flagName: data.poster_country_name_processed
|
flagName: data.poster_country_name_processed
|
||||||
@ -529,82 +545,63 @@ Quotify =
|
|||||||
cb: @node
|
cb: @node
|
||||||
node: ->
|
node: ->
|
||||||
return if @isClone
|
return if @isClone
|
||||||
|
for deadlink in $$ '.deadlink', post.blockquote
|
||||||
|
if deadlink.parentNode.className is 'prettyprint'
|
||||||
|
# Don't quotify deadlinks inside code tags,
|
||||||
|
# un-`span` them.
|
||||||
|
$.replace deadlink, Array::slice.call deadlink.childNodes
|
||||||
|
continue
|
||||||
|
|
||||||
# XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE === 6
|
quote = deadlink.textContent
|
||||||
# Get all the text nodes that are not inside an anchor.
|
continue unless ID = quote.match(/\d+$/)?[0]
|
||||||
snapshot = d.evaluate './/text()[not(parent::a)]', @nodes.comment, null, 6, null
|
board =
|
||||||
|
if m = quote.match /^>>>\/([a-z\d]+)/
|
||||||
for i in [0...snapshot.snapshotLength]
|
m[1]
|
||||||
node = snapshot.snapshotItem i
|
|
||||||
data = node.data
|
|
||||||
|
|
||||||
# Only accept nodes with potentially valid links
|
|
||||||
continue unless quotes = data.match />>(>\/[a-z\d]+\/)?\d+/g
|
|
||||||
|
|
||||||
nodes = []
|
|
||||||
|
|
||||||
for quote in quotes
|
|
||||||
index = data.indexOf quote
|
|
||||||
if text = data[...index]
|
|
||||||
# Potential text before this valid quote.
|
|
||||||
nodes.push $.tn text
|
|
||||||
|
|
||||||
ID = quote.match(/\d+$/)[0]
|
|
||||||
board =
|
|
||||||
if m = quote.match /^>>>\/([a-z\d]+)/
|
|
||||||
m[1]
|
|
||||||
else
|
|
||||||
@board.ID
|
|
||||||
|
|
||||||
quoteID = "#{board}.#{ID}"
|
|
||||||
|
|
||||||
# \u00A0 is nbsp
|
|
||||||
if post = g.posts[quoteID]
|
|
||||||
if post.isDead
|
|
||||||
a = $.el 'a',
|
|
||||||
href: Redirect.to
|
|
||||||
board: board
|
|
||||||
threadID: 0
|
|
||||||
postID: ID
|
|
||||||
className: 'quotelink deadlink'
|
|
||||||
textContent: "#{quote}\u00A0(Dead)"
|
|
||||||
target: '_blank'
|
|
||||||
a.setAttribute 'data-board', board
|
|
||||||
a.setAttribute 'data-threadid', post.thread.ID
|
|
||||||
a.setAttribute 'data-postid', ID
|
|
||||||
else
|
|
||||||
# Don't (Dead) when quotifying in an archived post,
|
|
||||||
# and we know the post still exists.
|
|
||||||
a = $.el 'a',
|
|
||||||
href: "/#{board}/#{post.thread}/res/#p#{ID}"
|
|
||||||
className: 'quotelink'
|
|
||||||
textContent: quote
|
|
||||||
else
|
else
|
||||||
|
@board.ID
|
||||||
|
quoteID = "#{board}.#{ID}"
|
||||||
|
|
||||||
|
# \u00A0 is nbsp
|
||||||
|
if post = g.posts[quoteID]
|
||||||
|
unless post.isDead
|
||||||
|
# Don't (Dead) when quotifying in an archived post,
|
||||||
|
# and we know the post still exists.
|
||||||
a = $.el 'a',
|
a = $.el 'a',
|
||||||
href: Redirect.to
|
href: "/#{board}/#{post.thread}/res/#p#{ID}"
|
||||||
board: board
|
className: 'quotelink'
|
||||||
threadID: 0
|
textContent: quote
|
||||||
postID: ID
|
else if redirect = Redirect.to {board: board, threadID: post.thread.ID, postID: ID}
|
||||||
className: 'deadlink'
|
# Replace the .deadlink span if we can redirect.
|
||||||
|
a = $.el 'a',
|
||||||
|
href: redirect
|
||||||
|
className: 'quotelink deadlink'
|
||||||
target: '_blank'
|
target: '_blank'
|
||||||
textContent: "#{quote}\u00A0(Dead)"
|
textContent: "#{quote}\u00A0(Dead)"
|
||||||
if Redirect.post board, ID
|
a.setAttribute 'data-board', board
|
||||||
$.addClass a, 'quotelink'
|
a.setAttribute 'data-threadid', post.thread.ID
|
||||||
a.setAttribute 'data-board', board
|
a.setAttribute 'data-postid', ID
|
||||||
a.setAttribute 'data-postid', ID
|
else if redirect = Redirect.to {board: board, threadID: 0, postID: ID}
|
||||||
|
# Replace the .deadlink span if we can redirect.
|
||||||
|
a = $.el 'a',
|
||||||
|
href: redirect
|
||||||
|
className: 'deadlink'
|
||||||
|
target: '_blank'
|
||||||
|
textContent: "#{quote}\u00A0(Dead)"
|
||||||
|
if Redirect.post board, ID
|
||||||
|
# Make it function as a normal quote if we can fetch the post.
|
||||||
|
$.addClass a, 'quotelink'
|
||||||
|
a.setAttribute 'data-board', board
|
||||||
|
a.setAttribute 'data-postid', ID
|
||||||
|
|
||||||
if @quotes.indexOf(quoteID) is -1
|
if a
|
||||||
@quotes.push quoteID
|
$.replace deadlink, a
|
||||||
if $.hasClass a, 'quotelink'
|
else
|
||||||
@nodes.quotelinks.push a
|
deadlink.textContent += "\u00A0(Dead)"
|
||||||
nodes.push a
|
|
||||||
data = data[index + quote.length..]
|
|
||||||
|
|
||||||
if data
|
if @quotes.indexOf(quoteID) is -1
|
||||||
# Potential text after the last valid quote.
|
@quotes.push quoteID
|
||||||
nodes.push $.tn data
|
if $.hasClass a, 'quotelink'
|
||||||
|
@nodes.quotelinks.push a
|
||||||
$.replace node, nodes
|
|
||||||
return
|
return
|
||||||
|
|
||||||
QuoteInline =
|
QuoteInline =
|
||||||
@ -1109,6 +1106,12 @@ ThreadUpdater =
|
|||||||
cb: @node
|
cb: @node
|
||||||
node: ->
|
node: ->
|
||||||
new ThreadUpdater.Updater @
|
new ThreadUpdater.Updater @
|
||||||
|
###
|
||||||
|
http://freesound.org/people/pierrecartoons1979/sounds/90112/
|
||||||
|
cc-by-nc-3.0
|
||||||
|
###
|
||||||
|
beep: 'data:audio/wav;base64,UklGRjQDAABXQVZFZm10IBAAAAABAAEAgD4AAIA+AAABAAgAc21wbDwAAABBAAADAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkYXRhzAIAAGMms8em0tleMV4zIpLVo8nhfSlcPR102Ki+5JspVEkdVtKzs+K1NEhUIT7DwKrcy0g6WygsrM2k1NpiLl0zIY/WpMrjgCdbPhxw2Kq+5Z4qUkkdU9K1s+K5NkVTITzBwqnczko3WikrqM+l1NxlLF0zIIvXpsnjgydZPhxs2ay95aIrUEkdUdC3suK8N0NUIjq+xKrcz002WioppdGm091pK1w0IIjYp8jkhydXPxxq2K295aUrTkoeTs65suK+OUFUIzi7xqrb0VA0WSoootKm0t5tKlo1H4TYqMfkiydWQBxm16+85actTEseS8y7seHAPD9TIza5yKra01QyWSson9On0d5wKVk2H4DYqcfkjidUQB1j1rG75KsvSkseScu8seDCPz1TJDW2yara1FYxWSwnm9Sn0N9zKVg2H33ZqsXkkihSQR1g1bK65K0wSEsfR8i+seDEQTxUJTOzy6rY1VowWC0mmNWoz993KVc3H3rYq8TklSlRQh1d1LS647AyR0wgRMbAsN/GRDpTJTKwzKrX1l4vVy4lldWpzt97KVY4IXbUr8LZljVPRCxhw7W3z6ZISkw1VK+4sMWvXEhSPk6buay9sm5JVkZNiLWqtrJ+TldNTnquqbCwilZXU1BwpKirrpNgWFhTaZmnpquZbFlbVmWOpaOonHZcXlljhaGhpZ1+YWBdYn2cn6GdhmdhYGN3lp2enIttY2Jjco+bnJuOdGZlZXCImJqakHpoZ2Zug5WYmZJ/bGlobX6RlpeSg3BqaW16jZSVkoZ0bGtteImSk5KIeG5tbnaFkJKRinxxbm91gY2QkIt/c3BwdH6Kj4+LgnZxcXR8iI2OjIR5c3J0e4WLjYuFe3VzdHmCioyLhn52dHR5gIiKioeAeHV1eH+GiYqHgXp2dnh9hIiJh4J8eHd4fIKHiIeDfXl4eHyBhoeHhH96eHmA'
|
||||||
|
|
||||||
|
|
||||||
Updater: class
|
Updater: class
|
||||||
constructor: (@thread) ->
|
constructor: (@thread) ->
|
||||||
@ -1175,8 +1178,7 @@ ThreadUpdater =
|
|||||||
@unsuccessfulFetchCount = 0
|
@unsuccessfulFetchCount = 0
|
||||||
setTimeout @update.bind(@), 1000 if @seconds > 2
|
setTimeout @update.bind(@), 1000 if @seconds > 2
|
||||||
visibility: ->
|
visibility: ->
|
||||||
state = d.visibilityState or d.oVisibilityState or d.mozVisibilityState or d.webkitVisibilityState
|
return if $.hidden()
|
||||||
return if state isnt 'visible'
|
|
||||||
# Reset the counter when we focus this tab.
|
# Reset the counter when we focus this tab.
|
||||||
@unsuccessfulFetchCount = 0
|
@unsuccessfulFetchCount = 0
|
||||||
if @seconds > @interval
|
if @seconds > @interval
|
||||||
@ -1191,7 +1193,7 @@ ThreadUpdater =
|
|||||||
if @['Scroll BG']
|
if @['Scroll BG']
|
||||||
-> true
|
-> true
|
||||||
else
|
else
|
||||||
-> !(d.hidden or d.oHidden or d.mozHidden or d.webkitHidden)
|
-> not $.hidden()
|
||||||
autoUpdate: ->
|
autoUpdate: ->
|
||||||
if @['Auto Update This'] and @online
|
if @['Auto Update This'] and @online
|
||||||
@timeoutID = setTimeout @timeout.bind(@), 1000
|
@timeoutID = setTimeout @timeout.bind(@), 1000
|
||||||
@ -1241,7 +1243,7 @@ ThreadUpdater =
|
|||||||
getInterval: ->
|
getInterval: ->
|
||||||
i = @interval
|
i = @interval
|
||||||
j = Math.min @unsuccessfulFetchCount, 10
|
j = Math.min @unsuccessfulFetchCount, 10
|
||||||
unless d.hidden or d.oHidden or d.mozHidden or d.webkitHidden
|
unless $.hidden()
|
||||||
# Lower the max refresh rate limit on visible tabs.
|
# Lower the max refresh rate limit on visible tabs.
|
||||||
j = Math.min j, 7
|
j = Math.min j, 7
|
||||||
@seconds = Math.max i, [0, 5, 10, 15, 20, 30, 60, 90, 120, 240, 300][j]
|
@seconds = Math.max i, [0, 5, 10, 15, 20, 30, 60, 90, 120, 240, 300][j]
|
||||||
@ -1308,6 +1310,10 @@ ThreadUpdater =
|
|||||||
post.kill true
|
post.kill true
|
||||||
|
|
||||||
if count
|
if count
|
||||||
|
if Conf['Beep'] and $.hidden() and (Unread.replies.length is 0)
|
||||||
|
unless @audio
|
||||||
|
@audio = $.el 'audio', src: ThreadUpdater.beep
|
||||||
|
audio.play()
|
||||||
@set 'status', "+#{count}"
|
@set 'status', "+#{count}"
|
||||||
@status.className = 'new'
|
@status.className = 'new'
|
||||||
@unsuccessfulFetchCount = 0
|
@unsuccessfulFetchCount = 0
|
||||||
|
|||||||
@ -88,13 +88,24 @@ class Post
|
|||||||
quotes = {}
|
quotes = {}
|
||||||
for quotelink in $$ '.quotelink', @nodes.comment
|
for quotelink in $$ '.quotelink', @nodes.comment
|
||||||
# Don't add board links. (>>>/b/)
|
# Don't add board links. (>>>/b/)
|
||||||
|
hash = quotelink.hash
|
||||||
|
continue unless hash
|
||||||
|
|
||||||
|
# Don't add catalog links. (>>>/b/catalog or >>>/b/search)
|
||||||
|
pathname = quotelink.pathname
|
||||||
|
continue if /catalog$/.test pathname
|
||||||
|
|
||||||
|
# Don't add rules links. (>>>/a/rules)
|
||||||
# Don't add text-board quotelinks. (>>>/img/1234)
|
# Don't add text-board quotelinks. (>>>/img/1234)
|
||||||
|
continue if quotelink.hostname isnt 'boards.4chan.org'
|
||||||
|
|
||||||
|
@nodes.quotelinks.push quotelink
|
||||||
|
|
||||||
# Don't count capcode replies as quotes. (Admin/Mod/Dev Replies: ...)
|
# Don't count capcode replies as quotes. (Admin/Mod/Dev Replies: ...)
|
||||||
# Only add quotes that link to posts on an imageboard.
|
continue if quotelink.parentNode.parentNode.className is 'capcodeReplies'
|
||||||
if quotelink.hash
|
|
||||||
@nodes.quotelinks.push quotelink
|
# Basically, only add quotes that link to posts on an imageboard.
|
||||||
continue if quotelink.parentNode.parentNode.className is 'capcodeReplies'
|
quotes["#{pathname.split('/')[1]}.#{hash[2..]}"] = true
|
||||||
quotes["#{quotelink.pathname.split('/')[1]}.#{quotelink.hash[2..]}"] = true
|
|
||||||
@quotes = Object.keys quotes
|
@quotes = Object.keys quotes
|
||||||
|
|
||||||
if (file = $ '.file', post) and thumb = $ 'img[data-md5]', file
|
if (file = $ '.file', post) and thumb = $ 'img[data-md5]', file
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
// @version <%= pkg.version %>
|
// @version <%= pkg.version %>
|
||||||
// @description Cross-browser userscript for maximum lurking on 4chan.
|
// @description Cross-browser userscript for maximum lurking on 4chan.
|
||||||
// @copyright 2009-2011 James Campos <james.r.campos@gmail.com>
|
// @copyright 2009-2011 James Campos <james.r.campos@gmail.com>
|
||||||
// @copyright <%= grunt.template.today('yyyy') %> Nicolas Stepien <stepien.nicolas@gmail.com>
|
// @copyright 2012-<%= grunt.template.today('yyyy') %> Nicolas Stepien <stepien.nicolas@gmail.com>
|
||||||
// @license MIT; http://en.wikipedia.org/wiki/Mit_license
|
// @license MIT; http://en.wikipedia.org/wiki/Mit_license
|
||||||
// @match *://boards.4chan.org/*
|
// @match *://boards.4chan.org/*
|
||||||
// @match *://images.4chan.org/*
|
// @match *://images.4chan.org/*
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user