Release 4chan X v1.7.34.
This commit is contained in:
parent
0e81e2dec2
commit
af11ce9f3f
@ -1,3 +1,6 @@
|
|||||||
|
### v1.7.34
|
||||||
|
*2014-05-11*
|
||||||
|
|
||||||
**Zixaphir**
|
**Zixaphir**
|
||||||
- JSON Navigation now works for backlinks (when Quote Inlining is disabled) and backlink hashlinks.
|
- JSON Navigation now works for backlinks (when Quote Inlining is disabled) and backlink hashlinks.
|
||||||
- Many spiffy performance, state awareness, and sanity improvements to JSON Navigation.
|
- Many spiffy performance, state awareness, and sanity improvements to JSON Navigation.
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* 4chan X - Version 1.7.33 - 2014-05-10
|
* 4chan X - Version 1.7.34 - 2014-05-11
|
||||||
*
|
*
|
||||||
* Licensed under the MIT license.
|
* Licensed under the MIT license.
|
||||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name 4chan X
|
// @name 4chan X
|
||||||
// @version 1.7.33
|
// @version 1.7.34
|
||||||
// @minGMVer 1.14
|
// @minGMVer 1.14
|
||||||
// @minFFVer 26
|
// @minFFVer 26
|
||||||
// @namespace 4chan-X
|
// @namespace 4chan-X
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Generated by CoffeeScript
|
// Generated by CoffeeScript
|
||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name 4chan X
|
// @name 4chan X
|
||||||
// @version 1.7.33
|
// @version 1.7.34
|
||||||
// @minGMVer 1.14
|
// @minGMVer 1.14
|
||||||
// @minFFVer 26
|
// @minFFVer 26
|
||||||
// @namespace 4chan-X
|
// @namespace 4chan-X
|
||||||
@ -24,7 +24,7 @@
|
|||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 4chan X - Version 1.7.33 - 2014-05-10
|
* 4chan X - Version 1.7.34 - 2014-05-11
|
||||||
*
|
*
|
||||||
* Licensed under the MIT license.
|
* Licensed under the MIT license.
|
||||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||||
@ -372,7 +372,7 @@
|
|||||||
doc = d.documentElement;
|
doc = d.documentElement;
|
||||||
|
|
||||||
g = {
|
g = {
|
||||||
VERSION: '1.7.33',
|
VERSION: '1.7.34',
|
||||||
NAMESPACE: '4chan X.',
|
NAMESPACE: '4chan X.',
|
||||||
boards: {}
|
boards: {}
|
||||||
};
|
};
|
||||||
@ -1707,14 +1707,12 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
SimpleDict.prototype.forEach = function(fn) {
|
SimpleDict.prototype.forEach = function(fn) {
|
||||||
var key, _i, _len, _ref, _results;
|
var key, _i, _len, _ref;
|
||||||
_ref = __slice.call(this.keys);
|
_ref = __slice.call(this.keys);
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
key = _ref[_i];
|
key = _ref[_i];
|
||||||
_results.push(fn(this[key]));
|
fn(this[key]);
|
||||||
}
|
}
|
||||||
return _results;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return SimpleDict;
|
return SimpleDict;
|
||||||
@ -2549,7 +2547,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
return Index.userPageNav(+a.pathname.split('/')[2]);
|
return Index.userPageNav(+a.pathname.split('/')[2] || 1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scrollToIndex: function() {
|
scrollToIndex: function() {
|
||||||
@ -2634,7 +2632,7 @@
|
|||||||
$.before(a, strong);
|
$.before(a, strong);
|
||||||
return $.add(strong, a);
|
return $.add(strong, a);
|
||||||
},
|
},
|
||||||
update: function(pageNum) {
|
update: function(pageNum, forceReparse) {
|
||||||
var now, onload, _ref, _ref1;
|
var now, onload, _ref, _ref1;
|
||||||
if (!navigator.onLine) {
|
if (!navigator.onLine) {
|
||||||
return;
|
return;
|
||||||
@ -2673,7 +2671,7 @@
|
|||||||
onabort: onload,
|
onabort: onload,
|
||||||
onloadend: onload
|
onloadend: onload
|
||||||
}, {
|
}, {
|
||||||
whenModified: Index.board === ("" + g.BOARD)
|
whenModified: !forceReparse
|
||||||
});
|
});
|
||||||
return $.addClass(Index.button, 'fa-spin');
|
return $.addClass(Index.button, 'fa-spin');
|
||||||
},
|
},
|
||||||
@ -2704,7 +2702,6 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Navigate.title();
|
Navigate.title();
|
||||||
Index.board = "" + g.BOARD;
|
|
||||||
try {
|
try {
|
||||||
if (req.status === 200) {
|
if (req.status === 200) {
|
||||||
Index.parse(req.response, pageNum);
|
Index.parse(req.response, pageNum);
|
||||||
@ -4915,7 +4912,7 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
firstNode: function() {
|
firstNode: function() {
|
||||||
var a, clone, container, containers, link, markYours, nodes, post, quote, _i, _j, _k, _len, _len1, _len2, _ref, _ref1;
|
var a, clone, container, containers, hash, link, markYours, nodes, post, quote, _i, _j, _k, _len, _len1, _len2, _ref, _ref1;
|
||||||
if (this.isClone || !this.quotes.length) {
|
if (this.isClone || !this.quotes.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -4949,7 +4946,15 @@
|
|||||||
if (Conf['Quote Inlining']) {
|
if (Conf['Quote Inlining']) {
|
||||||
$.on(link, 'click', QuoteInline.toggle);
|
$.on(link, 'click', QuoteInline.toggle);
|
||||||
if (Conf['Quote Hash Navigation']) {
|
if (Conf['Quote Hash Navigation']) {
|
||||||
nodes.push(QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
|
hash = QuoteInline.qiQuote(link, $.hasClass(link, 'filtered'));
|
||||||
|
nodes.push(hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Conf['JSON Navigation']) {
|
||||||
|
if (hash) {
|
||||||
|
Navigate.singleQuoteLink(hash);
|
||||||
|
} else if (!Conf['Quote Inlining']) {
|
||||||
|
Navigate.singleQuoteLink(link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$.add(container, nodes);
|
$.add(container, nodes);
|
||||||
@ -5664,7 +5669,6 @@
|
|||||||
});
|
});
|
||||||
$.on(sc, 'click', function() {
|
$.on(sc, 'click', function() {
|
||||||
if (Conf['Persistent QR'] || !QR.nodes || QR.nodes.el.hidden) {
|
if (Conf['Persistent QR'] || !QR.nodes || QR.nodes.el.hidden) {
|
||||||
$.event('CloseMenu');
|
|
||||||
QR.open();
|
QR.open();
|
||||||
QR.nodes.com.focus();
|
QR.nodes.com.focus();
|
||||||
return $.rmClass(this, 'disabled');
|
return $.rmClass(this, 'disabled');
|
||||||
@ -5729,22 +5733,15 @@
|
|||||||
$.on(d, 'dragover', QR.dragOver);
|
$.on(d, 'dragover', QR.dragOver);
|
||||||
$.on(d, 'drop', QR.dropFile);
|
$.on(d, 'drop', QR.dropFile);
|
||||||
$.on(d, 'dragstart dragend', QR.drag);
|
$.on(d, 'dragstart dragend', QR.drag);
|
||||||
return {
|
$.on(d, 'IndexRefresh', QR.generatePostableThreadsList);
|
||||||
catalog: function() {
|
$.on(d, 'ThreadUpdate', QR.statusCheck);
|
||||||
if (Conf["Persistent QR"]) {
|
if (!Conf['Persistent QR']) {
|
||||||
QR.open();
|
return;
|
||||||
}
|
}
|
||||||
if (Conf['Auto Hide QR']) {
|
QR.open();
|
||||||
return QR.hide();
|
if (Conf['Auto-Hide QR']) {
|
||||||
}
|
return QR.hide();
|
||||||
},
|
}
|
||||||
index: function() {
|
|
||||||
return $.on(d, 'IndexRefresh', QR.generatePostableThreadsList);
|
|
||||||
},
|
|
||||||
thread: function() {
|
|
||||||
return $.on(d, 'ThreadUpdate', QR.statusCheck);
|
|
||||||
}
|
|
||||||
}[g.VIEW]();
|
|
||||||
},
|
},
|
||||||
statusCheck: function() {
|
statusCheck: function() {
|
||||||
if (g.DEAD) {
|
if (g.DEAD) {
|
||||||
@ -10553,32 +10550,32 @@
|
|||||||
return Unread.update();
|
return Unread.update();
|
||||||
},
|
},
|
||||||
addPosts: function(posts) {
|
addPosts: function(posts) {
|
||||||
var ID, post, _i, _len, _ref, _ref1;
|
var ID, post, _i, _len, _ref, _ref1, _ref2;
|
||||||
for (_i = 0, _len = posts.length; _i < _len; _i++) {
|
for (_i = 0, _len = posts.length; _i < _len; _i++) {
|
||||||
post = posts[_i];
|
post = posts[_i];
|
||||||
ID = post.ID;
|
ID = post.ID;
|
||||||
if (ID <= Unread.lastReadPost || post.isHidden || QR.db.get({
|
if (ID <= Unread.lastReadPost || post.isHidden || ((_ref = QR.db) != null ? _ref.get({
|
||||||
boardID: post.board.ID,
|
boardID: post.board.ID,
|
||||||
threadID: post.thread.ID,
|
threadID: post.thread.ID,
|
||||||
postID: ID
|
postID: ID
|
||||||
})) {
|
}) : void 0)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Unread.posts.push(post);
|
Unread.posts.push(post);
|
||||||
Unread.addPostQuotingYou(post);
|
Unread.addPostQuotingYou(post);
|
||||||
}
|
}
|
||||||
if (Conf['Unread Line']) {
|
if (Conf['Unread Line']) {
|
||||||
Unread.setLine((_ref = (_ref1 = Unread.posts.first) != null ? _ref1.data : void 0, __indexOf.call(posts, _ref) >= 0));
|
Unread.setLine((_ref1 = (_ref2 = Unread.posts.first) != null ? _ref2.data : void 0, __indexOf.call(posts, _ref1) >= 0));
|
||||||
}
|
}
|
||||||
Unread.read();
|
Unread.read();
|
||||||
return Unread.update();
|
return Unread.update();
|
||||||
},
|
},
|
||||||
addPostQuotingYou: function(post) {
|
addPostQuotingYou: function(post) {
|
||||||
var quotelink, _i, _len, _ref;
|
var quotelink, _i, _len, _ref, _ref1;
|
||||||
_ref = post.nodes.quotelinks;
|
_ref = post.nodes.quotelinks;
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
quotelink = _ref[_i];
|
quotelink = _ref[_i];
|
||||||
if (!(QR.db.get(Get.postDataFromLink(quotelink)))) {
|
if (!((_ref1 = QR.db) != null ? _ref1.get(Get.postDataFromLink(quotelink)) : void 0)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Unread.postsQuotingYou.push(post);
|
Unread.postsQuotingYou.push(post);
|
||||||
@ -10644,7 +10641,7 @@
|
|||||||
return arr.splice(0, i);
|
return arr.splice(0, i);
|
||||||
},
|
},
|
||||||
read: $.debounce(100, function(e) {
|
read: $.debounce(100, function(e) {
|
||||||
var ID, data, height, post, posts;
|
var ID, data, height, post, posts, _ref;
|
||||||
if (d.hidden || !Unread.posts.length) {
|
if (d.hidden || !Unread.posts.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -10656,11 +10653,11 @@
|
|||||||
}
|
}
|
||||||
ID = post.ID, data = post.data;
|
ID = post.ID, data = post.data;
|
||||||
posts.rm(ID);
|
posts.rm(ID);
|
||||||
if (Conf['Mark Quotes of You'] && QR.db.get({
|
if (Conf['Mark Quotes of You'] && ((_ref = QR.db) != null ? _ref.get({
|
||||||
boardID: data.board.ID,
|
boardID: data.board.ID,
|
||||||
threadID: data.thread.ID,
|
threadID: data.thread.ID,
|
||||||
postID: ID
|
postID: ID
|
||||||
})) {
|
}) : void 0)) {
|
||||||
QuoteYou.lastRead = data.nodes.root;
|
QuoteYou.lastRead = data.nodes.root;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11773,7 +11770,9 @@
|
|||||||
case Conf['Update']:
|
case Conf['Update']:
|
||||||
switch (g.VIEW) {
|
switch (g.VIEW) {
|
||||||
case 'thread':
|
case 'thread':
|
||||||
ThreadUpdater.update();
|
if (Conf['Thread Updater']) {
|
||||||
|
ThreadUpdater.update();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'index':
|
case 'index':
|
||||||
if (Conf['JSON Navigation']) {
|
if (Conf['JSON Navigation']) {
|
||||||
@ -12422,9 +12421,7 @@
|
|||||||
if (g.VIEW === 'catalog' || g.BOARD.ID === 'f' || !Conf['JSON Navigation']) {
|
if (g.VIEW === 'catalog' || g.BOARD.ID === 'f' || !Conf['JSON Navigation']) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$.ready(function() {
|
$.on(window, 'popstate', Navigate.popstate);
|
||||||
return $.on(window, 'popstate', Navigate.popstate);
|
|
||||||
});
|
|
||||||
this.title = function() {};
|
this.title = function() {};
|
||||||
Thread.callbacks.push({
|
Thread.callbacks.push({
|
||||||
name: 'Navigate',
|
name: 'Navigate',
|
||||||
@ -12444,19 +12441,27 @@
|
|||||||
return $.on(replyLink, 'click', Navigate.navigate);
|
return $.on(replyLink, 'click', Navigate.navigate);
|
||||||
},
|
},
|
||||||
post: function() {
|
post: function() {
|
||||||
var hashlink, postlink, _i, _len, _ref;
|
var linktype;
|
||||||
if (g.VIEW === 'thread' && this.thread.ID === g.THREADID) {
|
if (!(g.VIEW === 'thread' && this.thread.ID === g.THREADID)) {
|
||||||
|
$.on($('a[title="Link to this post"]', this.nodes.info), 'click', Navigate.navigate);
|
||||||
|
}
|
||||||
|
if (!(linktype = Conf['Quote Inlining'] && Conf['Quote Hash Navigation'] ? '.hashlink' : !Conf['Quote Inlining'] ? '.quotelink' : null)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
postlink = $('a[title="Link to this post"]', this.nodes.info);
|
return Navigate.quoteLink($$(linktype, this.nodes.comment));
|
||||||
$.on(postlink, 'click', Navigate.navigate);
|
},
|
||||||
if (!Conf['Quote Hash Navigation']) {
|
quoteLink: function(links) {
|
||||||
return;
|
var link, _i, _len;
|
||||||
|
for (_i = 0, _len = links.length; _i < _len; _i++) {
|
||||||
|
link = links[_i];
|
||||||
|
Navigate.singleQuoteLink(link);
|
||||||
}
|
}
|
||||||
_ref = $$('.hashlink', this.nodes.comment);
|
},
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
singleQuoteLink: function(link) {
|
||||||
hashlink = _ref[_i];
|
var boardID, threadID, _ref;
|
||||||
$.on(hashlink, 'click', Navigate.navigate);
|
_ref = Get.postDataFromLink(link), boardID = _ref.boardID, threadID = _ref.threadID;
|
||||||
|
if (g.VIEW === 'index' || boardID !== g.BOARD.ID || threadID !== g.THREADID) {
|
||||||
|
return $.on(link, 'click', Navigate.navigate);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
clean: function() {
|
clean: function() {
|
||||||
@ -12511,80 +12516,67 @@
|
|||||||
Main.handleErrors(errors);
|
Main.handleErrors(errors);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ready: function(name, feature, condition) {
|
|
||||||
var err, error;
|
|
||||||
try {
|
|
||||||
if (condition) {
|
|
||||||
feature();
|
|
||||||
}
|
|
||||||
} catch (_error) {
|
|
||||||
err = _error;
|
|
||||||
error = [
|
|
||||||
{
|
|
||||||
message: "" + name + " Failed.",
|
|
||||||
error: err
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
Main.handleErrors(error);
|
|
||||||
}
|
|
||||||
return QR.generatePostableThreadsList();
|
|
||||||
},
|
|
||||||
updateContext: function(view) {
|
updateContext: function(view) {
|
||||||
var oldView;
|
var origFormThread, post, _i, _len, _ref;
|
||||||
g.DEAD = false;
|
g.DEAD = false;
|
||||||
|
if (view === 'thread') {
|
||||||
|
g.THREADID = +window.location.pathname.split('/')[3];
|
||||||
|
}
|
||||||
if (view !== g.VIEW) {
|
if (view !== g.VIEW) {
|
||||||
$.rmClass(doc, g.VIEW);
|
$.rmClass(doc, g.VIEW);
|
||||||
$.addClass(doc, view);
|
$.addClass(doc, view);
|
||||||
}
|
}
|
||||||
oldView = g.VIEW;
|
if (view === 'index') {
|
||||||
g.VIEW = view;
|
delete g.THREADID;
|
||||||
return {
|
}
|
||||||
index: function() {
|
origFormThread = $('form[name="post"] input[name="resto"]');
|
||||||
if (oldView === g.VIEW) {
|
if (view === 'thread') {
|
||||||
return;
|
if (!origFormThread) {
|
||||||
}
|
origFormThread = $.el('input', {
|
||||||
delete g.THREADID;
|
type: 'hidden',
|
||||||
QR.link.textContent = 'Start a Thread';
|
name: 'resto'
|
||||||
$.off(d, 'ThreadUpdate', QR.statusCheck);
|
});
|
||||||
return $.on(d, 'IndexRefresh', QR.generatePostableThreadsList);
|
$.after($.id('postPassword'), origFormThread);
|
||||||
},
|
|
||||||
thread: function() {
|
|
||||||
g.THREADID = +window.location.pathname.split('/')[3];
|
|
||||||
if (oldView === g.VIEW) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QR.link.textContent = 'Reply to Thread';
|
|
||||||
$.on(d, 'ThreadUpdate', QR.statusCheck);
|
|
||||||
return $.off(d, 'IndexRefresh', QR.generatePostableThreadsList);
|
|
||||||
}
|
}
|
||||||
}[g.VIEW]();
|
origFormThread.value = g.THREADID;
|
||||||
|
} else {
|
||||||
|
$.rm(origFormThread);
|
||||||
|
}
|
||||||
|
if (Conf['Quick Reply']) {
|
||||||
|
QR.link.textContent = g.VIEW === 'thread' ? 'Reply to Thread' : 'Start a Thread';
|
||||||
|
QR.status();
|
||||||
|
_ref = QR.posts;
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
post = _ref[_i];
|
||||||
|
post.thread = g.THREADID || 'new';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return g.VIEW = view;
|
||||||
},
|
},
|
||||||
updateBoard: function(boardID) {
|
updateBoard: function(boardID) {
|
||||||
var fullBoardList, onload, req, _ref, _ref1;
|
var current, fullBoardList;
|
||||||
fullBoardList = $('#full-board-list', Header.boardList);
|
fullBoardList = $('#full-board-list', Header.boardList);
|
||||||
if ((_ref = $('.current', fullBoardList)) != null) {
|
if (current = $('.current', fullBoardList)) {
|
||||||
_ref.classList.remove('current');
|
$.rmClass(current, 'current');
|
||||||
}
|
}
|
||||||
if ((_ref1 = $("a[href*='/" + boardID + "/']", fullBoardList)) != null) {
|
if (current = $("a[href*='/" + boardID + "/']", fullBoardList)) {
|
||||||
_ref1.classList.add('current');
|
$.addClass(current, 'current');
|
||||||
}
|
}
|
||||||
Header.generateBoardList(Conf['boardnav'].replace(/(\r\n|\n|\r)/g, ' '));
|
Header.generateBoardList(Conf['boardnav'].replace(/(\r\n|\n|\r)/g, ' '));
|
||||||
QR.flagsInput();
|
$('#returnlink a').href = "/" + g.BOARD + "/";
|
||||||
onload = function(e) {
|
$('form[name="post"]').action = "//sys.4chan.org/" + g.BOARD + "/post";
|
||||||
var aboard, board, err, _i, _len, _ref2;
|
if (Conf['Quick Reply']) {
|
||||||
if (e.type === 'abort') {
|
QR.flagsInput();
|
||||||
req.onloadend = null;
|
}
|
||||||
return;
|
return $.cache('//a.4cdn.org/boards.json', function() {
|
||||||
}
|
var aboard, board, err, _i, _len, _ref;
|
||||||
if (req.status !== 200) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
_ref2 = req.response.boards;
|
if (this.status !== 200) {
|
||||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
return;
|
||||||
aboard = _ref2[_i];
|
}
|
||||||
|
_ref = this.response.boards;
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
aboard = _ref[_i];
|
||||||
if (!(aboard.board === boardID)) {
|
if (!(aboard.board === boardID)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -12599,22 +12591,17 @@
|
|||||||
error: err
|
error: err
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
if (!board) {
|
if (!board) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Navigate.updateTitle(board);
|
Navigate.updateTitle(board);
|
||||||
return Navigate.updateSFW(!!board.ws_board);
|
return Navigate.updateSFW(!!board.ws_board);
|
||||||
};
|
|
||||||
return req = $.ajax('//a.4cdn.org/boards.json', {
|
|
||||||
onabort: onload,
|
|
||||||
onloadend: onload
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
updateSFW: function(sfw) {
|
updateSFW: function(sfw) {
|
||||||
var findStyle, style;
|
var findStyle, style;
|
||||||
Favicon.el.href = "//s.4cdn.org/image/favicon" + (sfw ? '-ws' : '') + ".ico";
|
Favicon.el.href = Favicon["default"] = "//s.4cdn.org/image/favicon" + (sfw ? '-ws' : '') + ".ico";
|
||||||
$.add(d.head, Favicon.el);
|
$.add(d.head, Favicon.el);
|
||||||
if (Favicon.SFW === sfw) {
|
if (Favicon.SFW === sfw) {
|
||||||
return;
|
return;
|
||||||
@ -12626,7 +12613,7 @@
|
|||||||
style = d.cookie.match(new RegExp("\b" + type + "\_style\=([^;]+);\b"));
|
style = d.cookie.match(new RegExp("\b" + type + "\_style\=([^;]+);\b"));
|
||||||
return ["" + type + "_style", (style ? style[1] : base)];
|
return ["" + type + "_style", (style ? style[1] : base)];
|
||||||
};
|
};
|
||||||
style = findStyle.apply(null, (sfw ? ['ws', 'Yotsuba B New'] : ['nws', 'Yotsuba New']));
|
style = sfw ? findStyle('ws', 'Yotsuba B New') : findStyle('nws', 'Yotsuba New');
|
||||||
$.globalEval("var style_group = '" + style[0] + "'");
|
$.globalEval("var style_group = '" + style[0] + "'");
|
||||||
$('link[title=switch]', d.head).href = $("link[title='" + style[1] + "']", d.head).href;
|
$('link[title=switch]', d.head).href = $("link[title='" + style[1] + "']", d.head).href;
|
||||||
return Main.setClass();
|
return Main.setClass();
|
||||||
@ -12640,24 +12627,51 @@
|
|||||||
return $('.boardTitle').textContent = d.title = "/" + board + "/ - " + title;
|
return $('.boardTitle').textContent = d.title = "/" + board + "/ - " + title;
|
||||||
},
|
},
|
||||||
navigate: function(e) {
|
navigate: function(e) {
|
||||||
var boardID, load, pageNum, path, threadID, view;
|
var boardID, load, pageNum, path, threadID, view, _, _ref;
|
||||||
if (this.hostname !== 'boards.4chan.org' || window.location.hostname === 'rs.4chan.org' || (e && (e.shiftKey || e.ctrlKey || (e.type === 'click' && e.button !== 0)))) {
|
if (this.hostname !== 'boards.4chan.org' || window.location.hostname === 'rs.4chan.org') {
|
||||||
return;
|
|
||||||
}
|
|
||||||
$.addClass(Index.button, 'fa-spin');
|
|
||||||
path = this.pathname.split('/');
|
|
||||||
if (path[0] === '') {
|
|
||||||
path.shift();
|
|
||||||
}
|
|
||||||
boardID = path[0], view = path[1], threadID = path[2];
|
|
||||||
if (view === 'catalog' || ('f' === boardID || 'f' === g.BOARD.ID)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e) {
|
if (e) {
|
||||||
|
if (e.shiftKey || e.ctrlKey || (e.type === 'click' && e.button !== 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.pathname === Navigate.path) {
|
||||||
|
if (this.id === 'popState') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (g.VIEW === 'thread') {
|
||||||
|
if (Conf['Thread Updater']) {
|
||||||
|
ThreadUpdater.update();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Index.update();
|
||||||
|
}
|
||||||
|
if (e != null) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$.addClass(Index.button, 'fa-spin');
|
||||||
|
if (Index.isSearching) {
|
||||||
|
Index.clearSearch();
|
||||||
|
}
|
||||||
|
_ref = this.pathname.split('/'), _ = _ref[0], boardID = _ref[1], view = _ref[2], threadID = _ref[3];
|
||||||
|
if (view === 'catalog' || ('f' === boardID || 'f' === g.BOARD.ID)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (e != null) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
Navigate.title = function() {};
|
Navigate.title = function() {};
|
||||||
delete Index.pageNum;
|
delete Index.pageNum;
|
||||||
|
$.rmAll(Header.hover);
|
||||||
|
if (threadID) {
|
||||||
|
view = 'thread';
|
||||||
|
} else {
|
||||||
|
pageNum = +view || 1;
|
||||||
|
view = 'index';
|
||||||
|
}
|
||||||
path = this.pathname;
|
path = this.pathname;
|
||||||
if (this.hash) {
|
if (this.hash) {
|
||||||
path += this.hash;
|
path += this.hash;
|
||||||
@ -12666,15 +12680,7 @@
|
|||||||
history.pushState(null, '', path);
|
history.pushState(null, '', path);
|
||||||
}
|
}
|
||||||
Navigate.path = this.pathname;
|
Navigate.path = this.pathname;
|
||||||
if (threadID) {
|
if (!(view === 'index' && 'index' === g.VIEW && boardID === g.BOARD.ID)) {
|
||||||
view = 'thread';
|
|
||||||
} else {
|
|
||||||
pageNum = +view || 1;
|
|
||||||
view = 'index';
|
|
||||||
}
|
|
||||||
if (view === g.VIEW && boardID === g.BOARD.ID) {
|
|
||||||
Navigate.updateContext(view);
|
|
||||||
} else {
|
|
||||||
Navigate.disconnect();
|
Navigate.disconnect();
|
||||||
Navigate.updateContext(view);
|
Navigate.updateContext(view);
|
||||||
Navigate.clean();
|
Navigate.clean();
|
||||||
@ -12692,21 +12698,20 @@
|
|||||||
return Navigate.updateBoard(boardID);
|
return Navigate.updateBoard(boardID);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Navigate.updateSFW(Favicon.SFW);
|
||||||
if (view === 'index') {
|
if (view === 'index') {
|
||||||
return Index.update(pageNum);
|
return Index.update(pageNum, true);
|
||||||
} else {
|
|
||||||
Navigate.updateSFW(Favicon.SFW);
|
|
||||||
load = Navigate.load;
|
|
||||||
Navigate.req = $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", {
|
|
||||||
onabort: load,
|
|
||||||
onloadend: load
|
|
||||||
});
|
|
||||||
return setTimeout((function() {
|
|
||||||
if (Navigate.req && !Navigate.notice) {
|
|
||||||
return Navigate.notice = new Notice('info', 'Loading thread...');
|
|
||||||
}
|
|
||||||
}), 3 * $.SECOND);
|
|
||||||
}
|
}
|
||||||
|
load = Navigate.load;
|
||||||
|
Navigate.req = $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", {
|
||||||
|
onabort: load,
|
||||||
|
onloadend: load
|
||||||
|
});
|
||||||
|
return setTimeout((function() {
|
||||||
|
if (Navigate.req && !Navigate.notice) {
|
||||||
|
return Navigate.notice = new Notice('info', 'Loading thread...');
|
||||||
|
}
|
||||||
|
}), 3 * $.SECOND);
|
||||||
},
|
},
|
||||||
load: function(e) {
|
load: function(e) {
|
||||||
var err, notice, req;
|
var err, notice, req;
|
||||||
@ -12739,12 +12744,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
parse: function(data) {
|
parse: function(data) {
|
||||||
var OP, board, errors, makePost, obj, post, posts, thread, threadRoot, _i, _len;
|
var OP, board, errors, i, makePost, obj, post, posts, thread, threadRoot;
|
||||||
board = g.BOARD;
|
|
||||||
Navigate.threadRoot = threadRoot = Build.thread(board, OP = data.shift(), true);
|
|
||||||
thread = new Thread(OP.no, board);
|
|
||||||
posts = [];
|
posts = [];
|
||||||
errors = null;
|
errors = null;
|
||||||
|
board = g.BOARD;
|
||||||
|
threadRoot = Build.thread(board, OP = data[0], true);
|
||||||
|
thread = new Thread(OP.no, board);
|
||||||
makePost = function(postNode) {
|
makePost = function(postNode) {
|
||||||
var err;
|
var err;
|
||||||
try {
|
try {
|
||||||
@ -12755,34 +12760,35 @@
|
|||||||
errors = [];
|
errors = [];
|
||||||
}
|
}
|
||||||
return errors.push({
|
return errors.push({
|
||||||
message: "Parsing of Post No." + thread.ID + " failed. Post will be skipped.",
|
message: "Parsing of Post No." + postNode.ID + " failed. Post will be skipped.",
|
||||||
error: err
|
error: err
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
makePost($('.opContainer', threadRoot));
|
makePost($('.opContainer', threadRoot));
|
||||||
for (_i = 0, _len = data.length; _i < _len; _i++) {
|
i = 0;
|
||||||
obj = data[_i];
|
while (obj = data[++i]) {
|
||||||
post = Build.postFromObject(obj, board);
|
post = Build.postFromObject(obj, board);
|
||||||
makePost(post);
|
makePost(post);
|
||||||
$.add(threadRoot, post);
|
$.add(threadRoot, post);
|
||||||
}
|
}
|
||||||
if (errors) {
|
|
||||||
Main.handleErrors(errors);
|
|
||||||
}
|
|
||||||
Main.callbackNodes(Thread, [thread]);
|
Main.callbackNodes(Thread, [thread]);
|
||||||
Main.callbackNodes(Post, posts);
|
Main.callbackNodes(Post, posts);
|
||||||
Navigate.ready('Quote Threading', QuoteThreading.force, Conf['Quote Threading'] && !Conf['Unread Count']);
|
if (Conf['Quote Threading'] && !Conf['Unread Count']) {
|
||||||
Navigate.buildThread();
|
QuoteThreading.force();
|
||||||
return Header.hashScroll.call(window);
|
}
|
||||||
},
|
|
||||||
buildThread: function() {
|
|
||||||
var board;
|
|
||||||
board = $('.board');
|
board = $('.board');
|
||||||
$.rmAll(board);
|
$.rmAll(board);
|
||||||
$.add(board, [Navigate.threadRoot, $.el('hr')]);
|
$.add(board, [threadRoot, $.el('hr')]);
|
||||||
if (Conf['Unread Count']) {
|
if (Conf['Unread Count']) {
|
||||||
return Navigate.ready('Unread Count', Unread.ready, Conf['Unread Count']);
|
Unread.ready();
|
||||||
|
}
|
||||||
|
if (Conf['Quick Reply']) {
|
||||||
|
QR.generatePostableThreadsList();
|
||||||
|
}
|
||||||
|
Header.hashScroll.call(window);
|
||||||
|
if (errors) {
|
||||||
|
return Main.handleErrors(errors);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pushState: function(path) {
|
pushState: function(path) {
|
||||||
@ -12791,9 +12797,6 @@
|
|||||||
},
|
},
|
||||||
popstate: function() {
|
popstate: function() {
|
||||||
var a;
|
var a;
|
||||||
if (window.location.pathname === Navigate.path) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
a = $.el('a', {
|
a = $.el('a', {
|
||||||
href: window.location,
|
href: window.location,
|
||||||
id: 'popState'
|
id: 'popState'
|
||||||
|
|||||||
BIN
builds/crx.crx
BIN
builds/crx.crx
Binary file not shown.
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "4chan X",
|
"name": "4chan X",
|
||||||
"version": "1.7.33",
|
"version": "1.7.34",
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
||||||
"icons": {
|
"icons": {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Generated by CoffeeScript
|
// Generated by CoffeeScript
|
||||||
/*
|
/*
|
||||||
* 4chan X - Version 1.7.33 - 2014-05-10
|
* 4chan X - Version 1.7.34 - 2014-05-11
|
||||||
*
|
*
|
||||||
* Licensed under the MIT license.
|
* Licensed under the MIT license.
|
||||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||||
@ -348,7 +348,7 @@
|
|||||||
doc = d.documentElement;
|
doc = d.documentElement;
|
||||||
|
|
||||||
g = {
|
g = {
|
||||||
VERSION: '1.7.33',
|
VERSION: '1.7.34',
|
||||||
NAMESPACE: '4chan X.',
|
NAMESPACE: '4chan X.',
|
||||||
boards: {}
|
boards: {}
|
||||||
};
|
};
|
||||||
@ -1744,14 +1744,12 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
SimpleDict.prototype.forEach = function(fn) {
|
SimpleDict.prototype.forEach = function(fn) {
|
||||||
var key, _i, _len, _ref, _results;
|
var key, _i, _len, _ref;
|
||||||
_ref = __slice.call(this.keys);
|
_ref = __slice.call(this.keys);
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
key = _ref[_i];
|
key = _ref[_i];
|
||||||
_results.push(fn(this[key]));
|
fn(this[key]);
|
||||||
}
|
}
|
||||||
return _results;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return SimpleDict;
|
return SimpleDict;
|
||||||
@ -2590,7 +2588,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
return Index.userPageNav(+a.pathname.split('/')[2]);
|
return Index.userPageNav(+a.pathname.split('/')[2] || 1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scrollToIndex: function() {
|
scrollToIndex: function() {
|
||||||
@ -2675,7 +2673,7 @@
|
|||||||
$.before(a, strong);
|
$.before(a, strong);
|
||||||
return $.add(strong, a);
|
return $.add(strong, a);
|
||||||
},
|
},
|
||||||
update: function(pageNum) {
|
update: function(pageNum, forceReparse) {
|
||||||
var now, onload, _ref, _ref1;
|
var now, onload, _ref, _ref1;
|
||||||
if (!navigator.onLine) {
|
if (!navigator.onLine) {
|
||||||
return;
|
return;
|
||||||
@ -2714,7 +2712,7 @@
|
|||||||
onabort: onload,
|
onabort: onload,
|
||||||
onloadend: onload
|
onloadend: onload
|
||||||
}, {
|
}, {
|
||||||
whenModified: Index.board === ("" + g.BOARD)
|
whenModified: !forceReparse
|
||||||
});
|
});
|
||||||
return $.addClass(Index.button, 'fa-spin');
|
return $.addClass(Index.button, 'fa-spin');
|
||||||
},
|
},
|
||||||
@ -2745,7 +2743,6 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Navigate.title();
|
Navigate.title();
|
||||||
Index.board = "" + g.BOARD;
|
|
||||||
try {
|
try {
|
||||||
if (req.status === 200) {
|
if (req.status === 200) {
|
||||||
Index.parse(req.response, pageNum);
|
Index.parse(req.response, pageNum);
|
||||||
@ -4949,7 +4946,7 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
firstNode: function() {
|
firstNode: function() {
|
||||||
var a, clone, container, containers, link, markYours, nodes, post, quote, _i, _j, _k, _len, _len1, _len2, _ref, _ref1;
|
var a, clone, container, containers, hash, link, markYours, nodes, post, quote, _i, _j, _k, _len, _len1, _len2, _ref, _ref1;
|
||||||
if (this.isClone || !this.quotes.length) {
|
if (this.isClone || !this.quotes.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -4983,7 +4980,15 @@
|
|||||||
if (Conf['Quote Inlining']) {
|
if (Conf['Quote Inlining']) {
|
||||||
$.on(link, 'click', QuoteInline.toggle);
|
$.on(link, 'click', QuoteInline.toggle);
|
||||||
if (Conf['Quote Hash Navigation']) {
|
if (Conf['Quote Hash Navigation']) {
|
||||||
nodes.push(QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
|
hash = QuoteInline.qiQuote(link, $.hasClass(link, 'filtered'));
|
||||||
|
nodes.push(hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Conf['JSON Navigation']) {
|
||||||
|
if (hash) {
|
||||||
|
Navigate.singleQuoteLink(hash);
|
||||||
|
} else if (!Conf['Quote Inlining']) {
|
||||||
|
Navigate.singleQuoteLink(link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$.add(container, nodes);
|
$.add(container, nodes);
|
||||||
@ -5698,7 +5703,6 @@
|
|||||||
});
|
});
|
||||||
$.on(sc, 'click', function() {
|
$.on(sc, 'click', function() {
|
||||||
if (Conf['Persistent QR'] || !QR.nodes || QR.nodes.el.hidden) {
|
if (Conf['Persistent QR'] || !QR.nodes || QR.nodes.el.hidden) {
|
||||||
$.event('CloseMenu');
|
|
||||||
QR.open();
|
QR.open();
|
||||||
QR.nodes.com.focus();
|
QR.nodes.com.focus();
|
||||||
return $.rmClass(this, 'disabled');
|
return $.rmClass(this, 'disabled');
|
||||||
@ -5764,22 +5768,15 @@
|
|||||||
$.on(d, 'dragover', QR.dragOver);
|
$.on(d, 'dragover', QR.dragOver);
|
||||||
$.on(d, 'drop', QR.dropFile);
|
$.on(d, 'drop', QR.dropFile);
|
||||||
$.on(d, 'dragstart dragend', QR.drag);
|
$.on(d, 'dragstart dragend', QR.drag);
|
||||||
return {
|
$.on(d, 'IndexRefresh', QR.generatePostableThreadsList);
|
||||||
catalog: function() {
|
$.on(d, 'ThreadUpdate', QR.statusCheck);
|
||||||
if (Conf["Persistent QR"]) {
|
if (!Conf['Persistent QR']) {
|
||||||
QR.open();
|
return;
|
||||||
}
|
}
|
||||||
if (Conf['Auto Hide QR']) {
|
QR.open();
|
||||||
return QR.hide();
|
if (Conf['Auto-Hide QR']) {
|
||||||
}
|
return QR.hide();
|
||||||
},
|
}
|
||||||
index: function() {
|
|
||||||
return $.on(d, 'IndexRefresh', QR.generatePostableThreadsList);
|
|
||||||
},
|
|
||||||
thread: function() {
|
|
||||||
return $.on(d, 'ThreadUpdate', QR.statusCheck);
|
|
||||||
}
|
|
||||||
}[g.VIEW]();
|
|
||||||
},
|
},
|
||||||
statusCheck: function() {
|
statusCheck: function() {
|
||||||
if (g.DEAD) {
|
if (g.DEAD) {
|
||||||
@ -10550,32 +10547,32 @@
|
|||||||
return Unread.update();
|
return Unread.update();
|
||||||
},
|
},
|
||||||
addPosts: function(posts) {
|
addPosts: function(posts) {
|
||||||
var ID, post, _i, _len, _ref, _ref1;
|
var ID, post, _i, _len, _ref, _ref1, _ref2;
|
||||||
for (_i = 0, _len = posts.length; _i < _len; _i++) {
|
for (_i = 0, _len = posts.length; _i < _len; _i++) {
|
||||||
post = posts[_i];
|
post = posts[_i];
|
||||||
ID = post.ID;
|
ID = post.ID;
|
||||||
if (ID <= Unread.lastReadPost || post.isHidden || QR.db.get({
|
if (ID <= Unread.lastReadPost || post.isHidden || ((_ref = QR.db) != null ? _ref.get({
|
||||||
boardID: post.board.ID,
|
boardID: post.board.ID,
|
||||||
threadID: post.thread.ID,
|
threadID: post.thread.ID,
|
||||||
postID: ID
|
postID: ID
|
||||||
})) {
|
}) : void 0)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Unread.posts.push(post);
|
Unread.posts.push(post);
|
||||||
Unread.addPostQuotingYou(post);
|
Unread.addPostQuotingYou(post);
|
||||||
}
|
}
|
||||||
if (Conf['Unread Line']) {
|
if (Conf['Unread Line']) {
|
||||||
Unread.setLine((_ref = (_ref1 = Unread.posts.first) != null ? _ref1.data : void 0, __indexOf.call(posts, _ref) >= 0));
|
Unread.setLine((_ref1 = (_ref2 = Unread.posts.first) != null ? _ref2.data : void 0, __indexOf.call(posts, _ref1) >= 0));
|
||||||
}
|
}
|
||||||
Unread.read();
|
Unread.read();
|
||||||
return Unread.update();
|
return Unread.update();
|
||||||
},
|
},
|
||||||
addPostQuotingYou: function(post) {
|
addPostQuotingYou: function(post) {
|
||||||
var quotelink, _i, _len, _ref;
|
var quotelink, _i, _len, _ref, _ref1;
|
||||||
_ref = post.nodes.quotelinks;
|
_ref = post.nodes.quotelinks;
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
quotelink = _ref[_i];
|
quotelink = _ref[_i];
|
||||||
if (!(QR.db.get(Get.postDataFromLink(quotelink)))) {
|
if (!((_ref1 = QR.db) != null ? _ref1.get(Get.postDataFromLink(quotelink)) : void 0)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Unread.postsQuotingYou.push(post);
|
Unread.postsQuotingYou.push(post);
|
||||||
@ -10641,7 +10638,7 @@
|
|||||||
return arr.splice(0, i);
|
return arr.splice(0, i);
|
||||||
},
|
},
|
||||||
read: $.debounce(100, function(e) {
|
read: $.debounce(100, function(e) {
|
||||||
var ID, data, height, post, posts;
|
var ID, data, height, post, posts, _ref;
|
||||||
if (d.hidden || !Unread.posts.length) {
|
if (d.hidden || !Unread.posts.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -10653,11 +10650,11 @@
|
|||||||
}
|
}
|
||||||
ID = post.ID, data = post.data;
|
ID = post.ID, data = post.data;
|
||||||
posts.rm(ID);
|
posts.rm(ID);
|
||||||
if (Conf['Mark Quotes of You'] && QR.db.get({
|
if (Conf['Mark Quotes of You'] && ((_ref = QR.db) != null ? _ref.get({
|
||||||
boardID: data.board.ID,
|
boardID: data.board.ID,
|
||||||
threadID: data.thread.ID,
|
threadID: data.thread.ID,
|
||||||
postID: ID
|
postID: ID
|
||||||
})) {
|
}) : void 0)) {
|
||||||
QuoteYou.lastRead = data.nodes.root;
|
QuoteYou.lastRead = data.nodes.root;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11776,7 +11773,9 @@
|
|||||||
case Conf['Update']:
|
case Conf['Update']:
|
||||||
switch (g.VIEW) {
|
switch (g.VIEW) {
|
||||||
case 'thread':
|
case 'thread':
|
||||||
ThreadUpdater.update();
|
if (Conf['Thread Updater']) {
|
||||||
|
ThreadUpdater.update();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'index':
|
case 'index':
|
||||||
if (Conf['JSON Navigation']) {
|
if (Conf['JSON Navigation']) {
|
||||||
@ -12422,12 +12421,15 @@
|
|||||||
Navigate = {
|
Navigate = {
|
||||||
path: window.location.pathname,
|
path: window.location.pathname,
|
||||||
init: function() {
|
init: function() {
|
||||||
|
var popstateHack;
|
||||||
if (g.VIEW === 'catalog' || g.BOARD.ID === 'f' || !Conf['JSON Navigation']) {
|
if (g.VIEW === 'catalog' || g.BOARD.ID === 'f' || !Conf['JSON Navigation']) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$.ready(function() {
|
popstateHack = function() {
|
||||||
|
$.off(window, 'popstate', popstateHack);
|
||||||
return $.on(window, 'popstate', Navigate.popstate);
|
return $.on(window, 'popstate', Navigate.popstate);
|
||||||
});
|
};
|
||||||
|
$.on(window, 'popstate', popstateHack);
|
||||||
this.title = function() {};
|
this.title = function() {};
|
||||||
Thread.callbacks.push({
|
Thread.callbacks.push({
|
||||||
name: 'Navigate',
|
name: 'Navigate',
|
||||||
@ -12447,19 +12449,27 @@
|
|||||||
return $.on(replyLink, 'click', Navigate.navigate);
|
return $.on(replyLink, 'click', Navigate.navigate);
|
||||||
},
|
},
|
||||||
post: function() {
|
post: function() {
|
||||||
var hashlink, postlink, _i, _len, _ref;
|
var linktype;
|
||||||
if (g.VIEW === 'thread' && this.thread.ID === g.THREADID) {
|
if (!(g.VIEW === 'thread' && this.thread.ID === g.THREADID)) {
|
||||||
|
$.on($('a[title="Link to this post"]', this.nodes.info), 'click', Navigate.navigate);
|
||||||
|
}
|
||||||
|
if (!(linktype = Conf['Quote Inlining'] && Conf['Quote Hash Navigation'] ? '.hashlink' : !Conf['Quote Inlining'] ? '.quotelink' : null)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
postlink = $('a[title="Link to this post"]', this.nodes.info);
|
return Navigate.quoteLink($$(linktype, this.nodes.comment));
|
||||||
$.on(postlink, 'click', Navigate.navigate);
|
},
|
||||||
if (!Conf['Quote Hash Navigation']) {
|
quoteLink: function(links) {
|
||||||
return;
|
var link, _i, _len;
|
||||||
|
for (_i = 0, _len = links.length; _i < _len; _i++) {
|
||||||
|
link = links[_i];
|
||||||
|
Navigate.singleQuoteLink(link);
|
||||||
}
|
}
|
||||||
_ref = $$('.hashlink', this.nodes.comment);
|
},
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
singleQuoteLink: function(link) {
|
||||||
hashlink = _ref[_i];
|
var boardID, threadID, _ref;
|
||||||
$.on(hashlink, 'click', Navigate.navigate);
|
_ref = Get.postDataFromLink(link), boardID = _ref.boardID, threadID = _ref.threadID;
|
||||||
|
if (g.VIEW === 'index' || boardID !== g.BOARD.ID || threadID !== g.THREADID) {
|
||||||
|
return $.on(link, 'click', Navigate.navigate);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
clean: function() {
|
clean: function() {
|
||||||
@ -12514,80 +12524,67 @@
|
|||||||
Main.handleErrors(errors);
|
Main.handleErrors(errors);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ready: function(name, feature, condition) {
|
|
||||||
var err, error;
|
|
||||||
try {
|
|
||||||
if (condition) {
|
|
||||||
feature();
|
|
||||||
}
|
|
||||||
} catch (_error) {
|
|
||||||
err = _error;
|
|
||||||
error = [
|
|
||||||
{
|
|
||||||
message: "" + name + " Failed.",
|
|
||||||
error: err
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
Main.handleErrors(error);
|
|
||||||
}
|
|
||||||
return QR.generatePostableThreadsList();
|
|
||||||
},
|
|
||||||
updateContext: function(view) {
|
updateContext: function(view) {
|
||||||
var oldView;
|
var origFormThread, post, _i, _len, _ref;
|
||||||
g.DEAD = false;
|
g.DEAD = false;
|
||||||
|
if (view === 'thread') {
|
||||||
|
g.THREADID = +window.location.pathname.split('/')[3];
|
||||||
|
}
|
||||||
if (view !== g.VIEW) {
|
if (view !== g.VIEW) {
|
||||||
$.rmClass(doc, g.VIEW);
|
$.rmClass(doc, g.VIEW);
|
||||||
$.addClass(doc, view);
|
$.addClass(doc, view);
|
||||||
}
|
}
|
||||||
oldView = g.VIEW;
|
if (view === 'index') {
|
||||||
g.VIEW = view;
|
delete g.THREADID;
|
||||||
return {
|
}
|
||||||
index: function() {
|
origFormThread = $('form[name="post"] input[name="resto"]');
|
||||||
if (oldView === g.VIEW) {
|
if (view === 'thread') {
|
||||||
return;
|
if (!origFormThread) {
|
||||||
}
|
origFormThread = $.el('input', {
|
||||||
delete g.THREADID;
|
type: 'hidden',
|
||||||
QR.link.textContent = 'Start a Thread';
|
name: 'resto'
|
||||||
$.off(d, 'ThreadUpdate', QR.statusCheck);
|
});
|
||||||
return $.on(d, 'IndexRefresh', QR.generatePostableThreadsList);
|
$.after($.id('postPassword'), origFormThread);
|
||||||
},
|
|
||||||
thread: function() {
|
|
||||||
g.THREADID = +window.location.pathname.split('/')[3];
|
|
||||||
if (oldView === g.VIEW) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QR.link.textContent = 'Reply to Thread';
|
|
||||||
$.on(d, 'ThreadUpdate', QR.statusCheck);
|
|
||||||
return $.off(d, 'IndexRefresh', QR.generatePostableThreadsList);
|
|
||||||
}
|
}
|
||||||
}[g.VIEW]();
|
origFormThread.value = g.THREADID;
|
||||||
|
} else {
|
||||||
|
$.rm(origFormThread);
|
||||||
|
}
|
||||||
|
if (Conf['Quick Reply']) {
|
||||||
|
QR.link.textContent = g.VIEW === 'thread' ? 'Reply to Thread' : 'Start a Thread';
|
||||||
|
QR.status();
|
||||||
|
_ref = QR.posts;
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
post = _ref[_i];
|
||||||
|
post.thread = g.THREADID || 'new';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return g.VIEW = view;
|
||||||
},
|
},
|
||||||
updateBoard: function(boardID) {
|
updateBoard: function(boardID) {
|
||||||
var fullBoardList, onload, req, _ref, _ref1;
|
var current, fullBoardList;
|
||||||
fullBoardList = $('#full-board-list', Header.boardList);
|
fullBoardList = $('#full-board-list', Header.boardList);
|
||||||
if ((_ref = $('.current', fullBoardList)) != null) {
|
if (current = $('.current', fullBoardList)) {
|
||||||
_ref.classList.remove('current');
|
$.rmClass(current, 'current');
|
||||||
}
|
}
|
||||||
if ((_ref1 = $("a[href*='/" + boardID + "/']", fullBoardList)) != null) {
|
if (current = $("a[href*='/" + boardID + "/']", fullBoardList)) {
|
||||||
_ref1.classList.add('current');
|
$.addClass(current, 'current');
|
||||||
}
|
}
|
||||||
Header.generateBoardList(Conf['boardnav'].replace(/(\r\n|\n|\r)/g, ' '));
|
Header.generateBoardList(Conf['boardnav'].replace(/(\r\n|\n|\r)/g, ' '));
|
||||||
QR.flagsInput();
|
$('#returnlink a').href = "/" + g.BOARD + "/";
|
||||||
onload = function(e) {
|
$('form[name="post"]').action = "//sys.4chan.org/" + g.BOARD + "/post";
|
||||||
var aboard, board, err, _i, _len, _ref2;
|
if (Conf['Quick Reply']) {
|
||||||
if (e.type === 'abort') {
|
QR.flagsInput();
|
||||||
req.onloadend = null;
|
}
|
||||||
return;
|
return $.cache('//a.4cdn.org/boards.json', function() {
|
||||||
}
|
var aboard, board, err, _i, _len, _ref;
|
||||||
if (req.status !== 200) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
_ref2 = req.response.boards;
|
if (this.status !== 200) {
|
||||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
return;
|
||||||
aboard = _ref2[_i];
|
}
|
||||||
|
_ref = this.response.boards;
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
aboard = _ref[_i];
|
||||||
if (!(aboard.board === boardID)) {
|
if (!(aboard.board === boardID)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -12602,22 +12599,17 @@
|
|||||||
error: err
|
error: err
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
if (!board) {
|
if (!board) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Navigate.updateTitle(board);
|
Navigate.updateTitle(board);
|
||||||
return Navigate.updateSFW(!!board.ws_board);
|
return Navigate.updateSFW(!!board.ws_board);
|
||||||
};
|
|
||||||
return req = $.ajax('//a.4cdn.org/boards.json', {
|
|
||||||
onabort: onload,
|
|
||||||
onloadend: onload
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
updateSFW: function(sfw) {
|
updateSFW: function(sfw) {
|
||||||
var findStyle, style;
|
var findStyle, style;
|
||||||
Favicon.el.href = "//s.4cdn.org/image/favicon" + (sfw ? '-ws' : '') + ".ico";
|
Favicon.el.href = Favicon["default"] = "//s.4cdn.org/image/favicon" + (sfw ? '-ws' : '') + ".ico";
|
||||||
$.add(d.head, Favicon.el);
|
$.add(d.head, Favicon.el);
|
||||||
if (Favicon.SFW === sfw) {
|
if (Favicon.SFW === sfw) {
|
||||||
return;
|
return;
|
||||||
@ -12629,7 +12621,7 @@
|
|||||||
style = d.cookie.match(new RegExp("\b" + type + "\_style\=([^;]+);\b"));
|
style = d.cookie.match(new RegExp("\b" + type + "\_style\=([^;]+);\b"));
|
||||||
return ["" + type + "_style", (style ? style[1] : base)];
|
return ["" + type + "_style", (style ? style[1] : base)];
|
||||||
};
|
};
|
||||||
style = findStyle.apply(null, (sfw ? ['ws', 'Yotsuba B New'] : ['nws', 'Yotsuba New']));
|
style = sfw ? findStyle('ws', 'Yotsuba B New') : findStyle('nws', 'Yotsuba New');
|
||||||
$.globalEval("var style_group = '" + style[0] + "'");
|
$.globalEval("var style_group = '" + style[0] + "'");
|
||||||
$('link[title=switch]', d.head).href = $("link[title='" + style[1] + "']", d.head).href;
|
$('link[title=switch]', d.head).href = $("link[title='" + style[1] + "']", d.head).href;
|
||||||
return Main.setClass();
|
return Main.setClass();
|
||||||
@ -12643,24 +12635,51 @@
|
|||||||
return $('.boardTitle').textContent = d.title = "/" + board + "/ - " + title;
|
return $('.boardTitle').textContent = d.title = "/" + board + "/ - " + title;
|
||||||
},
|
},
|
||||||
navigate: function(e) {
|
navigate: function(e) {
|
||||||
var boardID, load, pageNum, path, threadID, view;
|
var boardID, load, pageNum, path, threadID, view, _, _ref;
|
||||||
if (this.hostname !== 'boards.4chan.org' || window.location.hostname === 'rs.4chan.org' || (e && (e.shiftKey || e.ctrlKey || (e.type === 'click' && e.button !== 0)))) {
|
if (this.hostname !== 'boards.4chan.org' || window.location.hostname === 'rs.4chan.org') {
|
||||||
return;
|
|
||||||
}
|
|
||||||
$.addClass(Index.button, 'fa-spin');
|
|
||||||
path = this.pathname.split('/');
|
|
||||||
if (path[0] === '') {
|
|
||||||
path.shift();
|
|
||||||
}
|
|
||||||
boardID = path[0], view = path[1], threadID = path[2];
|
|
||||||
if (view === 'catalog' || ('f' === boardID || 'f' === g.BOARD.ID)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e) {
|
if (e) {
|
||||||
|
if (e.shiftKey || e.ctrlKey || (e.type === 'click' && e.button !== 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.pathname === Navigate.path) {
|
||||||
|
if (this.id === 'popState') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (g.VIEW === 'thread') {
|
||||||
|
if (Conf['Thread Updater']) {
|
||||||
|
ThreadUpdater.update();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Index.update();
|
||||||
|
}
|
||||||
|
if (e != null) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$.addClass(Index.button, 'fa-spin');
|
||||||
|
if (Index.isSearching) {
|
||||||
|
Index.clearSearch();
|
||||||
|
}
|
||||||
|
_ref = this.pathname.split('/'), _ = _ref[0], boardID = _ref[1], view = _ref[2], threadID = _ref[3];
|
||||||
|
if (view === 'catalog' || ('f' === boardID || 'f' === g.BOARD.ID)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (e != null) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
Navigate.title = function() {};
|
Navigate.title = function() {};
|
||||||
delete Index.pageNum;
|
delete Index.pageNum;
|
||||||
|
$.rmAll(Header.hover);
|
||||||
|
if (threadID) {
|
||||||
|
view = 'thread';
|
||||||
|
} else {
|
||||||
|
pageNum = +view || 1;
|
||||||
|
view = 'index';
|
||||||
|
}
|
||||||
path = this.pathname;
|
path = this.pathname;
|
||||||
if (this.hash) {
|
if (this.hash) {
|
||||||
path += this.hash;
|
path += this.hash;
|
||||||
@ -12669,15 +12688,7 @@
|
|||||||
history.pushState(null, '', path);
|
history.pushState(null, '', path);
|
||||||
}
|
}
|
||||||
Navigate.path = this.pathname;
|
Navigate.path = this.pathname;
|
||||||
if (threadID) {
|
if (!(view === 'index' && 'index' === g.VIEW && boardID === g.BOARD.ID)) {
|
||||||
view = 'thread';
|
|
||||||
} else {
|
|
||||||
pageNum = +view || 1;
|
|
||||||
view = 'index';
|
|
||||||
}
|
|
||||||
if (view === g.VIEW && boardID === g.BOARD.ID) {
|
|
||||||
Navigate.updateContext(view);
|
|
||||||
} else {
|
|
||||||
Navigate.disconnect();
|
Navigate.disconnect();
|
||||||
Navigate.updateContext(view);
|
Navigate.updateContext(view);
|
||||||
Navigate.clean();
|
Navigate.clean();
|
||||||
@ -12695,21 +12706,20 @@
|
|||||||
return Navigate.updateBoard(boardID);
|
return Navigate.updateBoard(boardID);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Navigate.updateSFW(Favicon.SFW);
|
||||||
if (view === 'index') {
|
if (view === 'index') {
|
||||||
return Index.update(pageNum);
|
return Index.update(pageNum, true);
|
||||||
} else {
|
|
||||||
Navigate.updateSFW(Favicon.SFW);
|
|
||||||
load = Navigate.load;
|
|
||||||
Navigate.req = $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", {
|
|
||||||
onabort: load,
|
|
||||||
onloadend: load
|
|
||||||
});
|
|
||||||
return setTimeout((function() {
|
|
||||||
if (Navigate.req && !Navigate.notice) {
|
|
||||||
return Navigate.notice = new Notice('info', 'Loading thread...');
|
|
||||||
}
|
|
||||||
}), 3 * $.SECOND);
|
|
||||||
}
|
}
|
||||||
|
load = Navigate.load;
|
||||||
|
Navigate.req = $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", {
|
||||||
|
onabort: load,
|
||||||
|
onloadend: load
|
||||||
|
});
|
||||||
|
return setTimeout((function() {
|
||||||
|
if (Navigate.req && !Navigate.notice) {
|
||||||
|
return Navigate.notice = new Notice('info', 'Loading thread...');
|
||||||
|
}
|
||||||
|
}), 3 * $.SECOND);
|
||||||
},
|
},
|
||||||
load: function(e) {
|
load: function(e) {
|
||||||
var err, notice, req;
|
var err, notice, req;
|
||||||
@ -12742,12 +12752,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
parse: function(data) {
|
parse: function(data) {
|
||||||
var OP, board, errors, makePost, obj, post, posts, thread, threadRoot, _i, _len;
|
var OP, board, errors, i, makePost, obj, post, posts, thread, threadRoot;
|
||||||
board = g.BOARD;
|
|
||||||
Navigate.threadRoot = threadRoot = Build.thread(board, OP = data.shift(), true);
|
|
||||||
thread = new Thread(OP.no, board);
|
|
||||||
posts = [];
|
posts = [];
|
||||||
errors = null;
|
errors = null;
|
||||||
|
board = g.BOARD;
|
||||||
|
threadRoot = Build.thread(board, OP = data[0], true);
|
||||||
|
thread = new Thread(OP.no, board);
|
||||||
makePost = function(postNode) {
|
makePost = function(postNode) {
|
||||||
var err;
|
var err;
|
||||||
try {
|
try {
|
||||||
@ -12758,34 +12768,35 @@
|
|||||||
errors = [];
|
errors = [];
|
||||||
}
|
}
|
||||||
return errors.push({
|
return errors.push({
|
||||||
message: "Parsing of Post No." + thread.ID + " failed. Post will be skipped.",
|
message: "Parsing of Post No." + postNode.ID + " failed. Post will be skipped.",
|
||||||
error: err
|
error: err
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
makePost($('.opContainer', threadRoot));
|
makePost($('.opContainer', threadRoot));
|
||||||
for (_i = 0, _len = data.length; _i < _len; _i++) {
|
i = 0;
|
||||||
obj = data[_i];
|
while (obj = data[++i]) {
|
||||||
post = Build.postFromObject(obj, board);
|
post = Build.postFromObject(obj, board);
|
||||||
makePost(post);
|
makePost(post);
|
||||||
$.add(threadRoot, post);
|
$.add(threadRoot, post);
|
||||||
}
|
}
|
||||||
if (errors) {
|
|
||||||
Main.handleErrors(errors);
|
|
||||||
}
|
|
||||||
Main.callbackNodes(Thread, [thread]);
|
Main.callbackNodes(Thread, [thread]);
|
||||||
Main.callbackNodes(Post, posts);
|
Main.callbackNodes(Post, posts);
|
||||||
Navigate.ready('Quote Threading', QuoteThreading.force, Conf['Quote Threading'] && !Conf['Unread Count']);
|
if (Conf['Quote Threading'] && !Conf['Unread Count']) {
|
||||||
Navigate.buildThread();
|
QuoteThreading.force();
|
||||||
return Header.hashScroll.call(window);
|
}
|
||||||
},
|
|
||||||
buildThread: function() {
|
|
||||||
var board;
|
|
||||||
board = $('.board');
|
board = $('.board');
|
||||||
$.rmAll(board);
|
$.rmAll(board);
|
||||||
$.add(board, [Navigate.threadRoot, $.el('hr')]);
|
$.add(board, [threadRoot, $.el('hr')]);
|
||||||
if (Conf['Unread Count']) {
|
if (Conf['Unread Count']) {
|
||||||
return Navigate.ready('Unread Count', Unread.ready, Conf['Unread Count']);
|
Unread.ready();
|
||||||
|
}
|
||||||
|
if (Conf['Quick Reply']) {
|
||||||
|
QR.generatePostableThreadsList();
|
||||||
|
}
|
||||||
|
Header.hashScroll.call(window);
|
||||||
|
if (errors) {
|
||||||
|
return Main.handleErrors(errors);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pushState: function(path) {
|
pushState: function(path) {
|
||||||
@ -12794,9 +12805,6 @@
|
|||||||
},
|
},
|
||||||
popstate: function() {
|
popstate: function() {
|
||||||
var a;
|
var a;
|
||||||
if (window.location.pathname === Navigate.path) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
a = $.el('a', {
|
a = $.el('a', {
|
||||||
href: window.location,
|
href: window.location,
|
||||||
id: 'popState'
|
id: 'popState'
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
||||||
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
|
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
|
||||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/crx.crx' version='1.7.33' />
|
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/crx.crx' version='1.7.34' />
|
||||||
</app>
|
</app>
|
||||||
</gupdate>
|
</gupdate>
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "4chan-X",
|
"name": "4chan-X",
|
||||||
"version": "1.7.33",
|
"version": "1.7.34",
|
||||||
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
||||||
"meta": {
|
"meta": {
|
||||||
"name": "4chan X",
|
"name": "4chan X",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user