diff --git a/CHANGELOG.md b/CHANGELOG.md
index cc652595a..809b5b557 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,18 @@ The attributions below are for work that has been incorporated into the script a
The links to individual versions below are to copies of the script with the update URL removed. If you want automatic updates, install the script from the links on the [main page](https://github.com/ccd0/4chan-x).
+### v1.9.3.5
+*2014-09-18* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.3.5/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.3.5/builds/4chan-X-noupdate.crx "Chromium version")]
+
+**ccd0**
+- Revert a bad "fix" from v1.9.3.2.
+
+### v1.9.3.4
+*2014-09-18* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.3.4/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.3.4/builds/4chan-X-noupdate.crx "Chromium version")]
+
+**ccd0**
+- Archived thread related bugfixes.
+
### v1.9.3.3
*2014-09-17* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.3.3/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.3.3/builds/4chan-X-noupdate.crx "Chromium version")]
diff --git a/LICENSE b/LICENSE
index 5885cd61f..ad7cc6501 100755
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,5 @@
/*
-* 4chan X - Version 1.9.3.3
+* 4chan X - Version 1.9.3.5
*
* Licensed under the MIT license.
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
diff --git a/builds/4chan-X-beta.crx b/builds/4chan-X-beta.crx
index 25985ee86..7bbc299e9 100644
Binary files a/builds/4chan-X-beta.crx and b/builds/4chan-X-beta.crx differ
diff --git a/builds/4chan-X-beta.meta.js b/builds/4chan-X-beta.meta.js
index 82b7e23ed..7c791d59f 100644
--- a/builds/4chan-X-beta.meta.js
+++ b/builds/4chan-X-beta.meta.js
@@ -1,6 +1,6 @@
// ==UserScript==
// @name 4chan X beta
-// @version 1.9.3.3
+// @version 1.9.3.5
// @minGMVer 1.14
// @minFFVer 26
// @namespace 4chan-X
diff --git a/builds/4chan-X-beta.user.js b/builds/4chan-X-beta.user.js
index 440b65d29..d924a4fdd 100644
--- a/builds/4chan-X-beta.user.js
+++ b/builds/4chan-X-beta.user.js
@@ -1,7 +1,7 @@
// Generated by CoffeeScript
// ==UserScript==
// @name 4chan X beta
-// @version 1.9.3.3
+// @version 1.9.3.5
// @minGMVer 1.14
// @minFFVer 26
// @namespace 4chan-X
@@ -24,7 +24,7 @@
// ==/UserScript==
/*
-* 4chan X - Version 1.9.3.3
+* 4chan X - Version 1.9.3.5
*
* Licensed under the MIT license.
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
@@ -267,7 +267,7 @@
'Current Board': [false, 'Only show watched threads from the current board.'],
'Auto Watch': [true, 'Automatically watch threads you start.'],
'Auto Watch Reply': [false, 'Automatically watch threads you reply to.'],
- 'Auto Prune': [false, 'Automatically prune 404\'d threads.'],
+ 'Auto Prune': [false, 'Automatically prune dead threads.'],
'Show Unread Count': [true, 'Show number of unread posts in watched threads.']
},
filter: {
@@ -376,7 +376,7 @@
doc = d.documentElement;
g = {
- VERSION: '1.9.3.3',
+ VERSION: '1.9.3.5',
NAMESPACE: '4chan X.',
NAME: '4chan X',
FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions',
@@ -1501,7 +1501,7 @@
};
DataBoard.prototype.clean = function() {
- var boardID, now, val, _ref;
+ var boardID, now, threadID, val, _ref;
_ref = this.data.boards;
for (boardID in _ref) {
val = _ref[boardID];
@@ -1513,44 +1513,29 @@
if ((this.data.lastChecked || 0) < now - 2 * $.HOUR) {
this.data.lastChecked = now;
for (boardID in this.data.boards) {
- this.ajaxClean(boardID);
+ for (threadID in this.data.boards[boardID]) {
+ this.ajaxClean(boardID, threadID);
+ }
}
}
return this.save();
};
- DataBoard.prototype.ajaxClean = function(boardID) {
- return $.cache("//a.4cdn.org/" + boardID + "/threads.json", (function(_this) {
- return function(e) {
- var board, page, thread, threads, _i, _j, _len, _len1, _ref, _ref1;
- if (e.target.status !== 200) {
+ DataBoard.prototype.ajaxClean = function(boardID, threadID) {
+ return $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", {
+ onloadend: (function(_this) {
+ return function(e) {
if (e.target.status === 404) {
- _this["delete"]({
- boardID: boardID
+ return _this["delete"]({
+ boardID: boardID,
+ threadID: threadID
});
}
- return;
- }
- board = _this.data.boards[boardID];
- threads = {};
- _ref = e.target.response;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- page = _ref[_i];
- _ref1 = page.threads;
- for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
- thread = _ref1[_j];
- if (thread.no in board) {
- threads[thread.no] = board[thread.no];
- }
- }
- }
- _this.data.boards[boardID] = threads;
- _this.deleteIfEmpty({
- boardID: boardID
- });
- return _this.save();
- };
- })(this));
+ };
+ })(this)
+ }, {
+ type: 'head'
+ });
};
DataBoard.prototype.onSync = function(data) {
@@ -4045,7 +4030,6 @@
isImage: (_ref = el.nodeName) === 'IMG' || _ref === 'VIDEO',
cb: cb,
endEvents: endEvents,
- ready: false,
latestEvent: latestEvent,
clientHeight: doc.clientHeight,
clientWidth: doc.clientWidth,
@@ -4056,7 +4040,6 @@
$.asap(function() {
return !el.parentNode || asapTest();
}, function() {
- o.ready = true;
if (el.parentNode) {
return o.hover(o.latestEvent);
}
@@ -4076,9 +4059,6 @@
hover = function(e) {
var clientX, clientY, height, left, right, style, threshold, top, _ref;
this.latestEvent = e;
- if (!this.ready) {
- return;
- }
height = this.el.offsetHeight;
clientX = e.clientX, clientY = e.clientY;
top = this.isImage ? Math.max(0, clientY * (this.clientHeight - height) / this.clientHeight) : Math.max(0, Math.min(this.clientHeight - height, clientY - 120));
@@ -5971,7 +5951,12 @@
}
},
statusCheck: function() {
- if (g.DEAD) {
+ var thread;
+ if (!QR.nodes) {
+ return;
+ }
+ thread = QR.posts[0].thread;
+ if (thread !== 'new' && g.threads["" + g.BOARD + "." + thread].isDead) {
return QR.abort();
} else {
return QR.status();
@@ -10129,7 +10114,7 @@
$.on(window, 'online offline', ThreadUpdater.cb.online);
$.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost);
$.on(d, 'visibilitychange', ThreadUpdater.cb.visibility);
- if (g.DEAD) {
+ if (ThreadUpdater.thread.isArchived) {
return ThreadUpdater.set('status', 'Archived', 'warning');
} else {
return ThreadUpdater.cb.online();
@@ -10143,7 +10128,7 @@
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',
cb: {
online: function() {
- if (g.DEAD) {
+ if (ThreadUpdater.thread.isDead) {
return;
}
if (ThreadUpdater.online = navigator.onLine) {
@@ -10173,7 +10158,7 @@
ThreadUpdater.outdateCount = 0;
ThreadUpdater.set('timer', '...');
}
- if (!(g.DEAD || ThreadUpdater.foundPost || ThreadUpdater.checkPostCount >= 5)) {
+ if (!(ThreadUpdater.thread.isDead || ThreadUpdater.foundPost || ThreadUpdater.checkPostCount >= 5)) {
return setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * $.SECOND);
}
ThreadUpdater.setInterval();
@@ -10211,9 +10196,9 @@
req = ThreadUpdater.req;
switch (req.status) {
case 200:
- g.DEAD = !!+req.response.posts[0].archived;
ThreadUpdater.parse(req.response.posts);
- if (g.DEAD) {
+ if (!!req.response.posts[0].archived) {
+ ThreadUpdater.thread.isArchived = true;
ThreadUpdater.set('status', 'Archived', 'warning');
ThreadUpdater.kill();
} else {
@@ -10242,7 +10227,6 @@
confirmed = false;
}
if (confirmed) {
- g.DEAD = true;
ThreadUpdater.set('status', '404', 'warning');
return ThreadUpdater.kill();
} else {
@@ -10601,7 +10585,6 @@
});
} else {
data.isDead = true;
- delete data.unread;
ThreadWatcher.db.set({
boardID: boardID,
threadID: threadID,
@@ -10641,7 +10624,7 @@
fetchStatus: function(_arg) {
var boardID, data, fetchCount, threadID;
boardID = _arg.boardID, threadID = _arg.threadID, data = _arg.data;
- if (data.isDead) {
+ if (data.isDead && !Conf['Show Unread Count']) {
return;
}
fetchCount = ThreadWatcher.fetchCount;
@@ -10652,7 +10635,7 @@
fetchCount.fetching++;
return $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", {
onloadend: function() {
- var lastReadPost, postObj, status, unread, _i, _len, _ref, _ref1;
+ var isDead, lastReadPost, postObj, status, unread, _i, _len, _ref, _ref1;
fetchCount.fetched++;
if (fetchCount.fetched === fetchCount.fetching) {
fetchCount.fetched = 0;
@@ -10664,6 +10647,15 @@
}
ThreadWatcher.status.textContent = status;
if (this.status === 200 && this.response) {
+ isDead = !!this.response.posts[0].archived;
+ if (isDead && Conf['Auto Prune']) {
+ ThreadWatcher.db["delete"]({
+ boardID: boardID,
+ threadID: threadID
+ });
+ ThreadWatcher.refresh();
+ return;
+ }
lastReadPost = ThreadWatcher.unreaddb.get({
boardID: boardID,
threadID: threadID,
@@ -10681,7 +10673,8 @@
unread++;
}
}
- if (unread !== data.unread) {
+ if (isDead !== data.isDead || unread !== data.unread) {
+ data.isDead = isDead;
data.unread = unread;
ThreadWatcher.db.set({
boardID: boardID,
@@ -10708,8 +10701,6 @@
return ThreadWatcher.refresh();
}
}
- }, {
- type: Conf['Show Unread Count'] ? 'get' : 'head'
});
},
getAll: function() {
@@ -10733,7 +10724,7 @@
return all;
},
makeLine: function(boardID, threadID, data) {
- var count, div, fullID, href, link, title, x;
+ var count, div, fullID, link, title, x;
x = $.el('a', {
className: 'fa fa-times',
href: 'javascript:;'
@@ -10747,14 +10738,8 @@
textContent: Conf['Show Unread Count'] && (data.unread != null) ? "\u00A0(" + data.unread + ")" : '',
className: 'watcher-unread'
});
- if (Conf['404 Redirect'] && data.isDead) {
- href = Redirect.to('thread', {
- boardID: boardID,
- threadID: threadID
- });
- }
link = $.el('a', {
- href: href || ("/" + boardID + "/thread/" + threadID),
+ href: "/" + boardID + "/thread/" + threadID,
title: data.excerpt,
className: 'watcher-link'
});
@@ -10837,7 +10822,7 @@
val: data
});
ThreadWatcher.refresh();
- if (Conf['Show Unread Count'] && !data.isDead) {
+ if (Conf['Show Unread Count']) {
return ThreadWatcher.fetchStatus({
boardID: boardID,
threadID: threadID,
@@ -10921,7 +10906,7 @@
cb: ThreadWatcher.cb.pruneDeads,
entry: {
el: $.el('a', {
- textContent: 'Prune 404\'d threads'
+ textContent: 'Prune dead threads'
})
},
refresh: function() {
@@ -11202,7 +11187,7 @@
}
}),
saveLastReadPost: $.debounce(2 * $.SECOND, function() {
- if (Unread.thread.isDead) {
+ if (Unread.thread.isDead && !Unread.thread.isArchived) {
return;
}
return Unread.db.set({
@@ -11224,16 +11209,19 @@
}
},
update: function() {
- var count, countQuotingYou;
+ var count, countQuotingYou, titleCount, titleDead, titleQuotingYou;
count = Unread.posts.length;
countQuotingYou = Object.keys(Unread.postsQuotingYou).length;
if (Conf['Unread Count']) {
- d.title = "" + (Conf['Quoted Title'] && countQuotingYou ? '(!) ' : '') + (count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : '') + (g.DEAD ? Unread.title.replace('-', '- 404 -') : Unread.title);
+ titleQuotingYou = Conf['Quoted Title'] && countQuotingYou ? '(!) ' : '';
+ titleCount = count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : '';
+ titleDead = Unread.thread.isDead ? Unread.title.replace('-', (Unread.thread.isArchived ? '- Archived -' : '- 404 -')) : Unread.title;
+ d.title = "" + titleQuotingYou + titleCount + titleDead;
}
if (!Conf['Unread Favicon']) {
return;
}
- Favicon.el.href = g.DEAD ? countQuotingYou ? Favicon.unreadDeadY : count ? Favicon.unreadDead : Favicon.dead : count ? countQuotingYou ? Favicon.unreadY : Favicon.unread : Favicon["default"];
+ Favicon.el.href = Unread.thread.isDead ? countQuotingYou ? Favicon.unreadDeadY : count ? Favicon.unreadDead : Favicon.dead : count ? countQuotingYou ? Favicon.unreadY : Favicon.unread : Favicon["default"];
return $.add(d.head, Favicon.el);
}
};
@@ -12884,7 +12872,7 @@
className: 'dialog'
});
$.extend(dialog, {
- innerHTML: "
"
+ innerHTML: ""
});
$.on($('.export', Settings.dialog), 'click', Settings["export"]);
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
@@ -13693,14 +13681,16 @@
},
initThread: function() {
var board, err, errors, postRoot, posts, thread, threadRoot, threads, _i, _j, _len, _len1, _ref, _ref1, _ref2;
- g.DEAD = !!((_ref = $('.closed')) != null ? _ref.textContent.match(/Thread archived/) : void 0);
if (board = $('.board')) {
threads = [];
posts = [];
- _ref1 = $$('.board > .thread', board);
- for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
- threadRoot = _ref1[_i];
+ _ref = $$('.board > .thread', board);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ threadRoot = _ref[_i];
thread = new Thread(+threadRoot.id.slice(1), g.BOARD);
+ if (g.VIEW === 'thread') {
+ thread.isDead = thread.isArchived = !!((_ref1 = $('.closed')) != null ? _ref1.textContent.match(/Thread archived/) : void 0);
+ }
threads.push(thread);
_ref2 = $$('.thread > .postContainer', threadRoot);
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
diff --git a/builds/4chan-X-noupdate.crx b/builds/4chan-X-noupdate.crx
index 5b5446aa5..4d61740c0 100644
Binary files a/builds/4chan-X-noupdate.crx and b/builds/4chan-X-noupdate.crx differ
diff --git a/builds/4chan-X-noupdate.user.js b/builds/4chan-X-noupdate.user.js
index 5a11cde89..3403f9c9f 100644
--- a/builds/4chan-X-noupdate.user.js
+++ b/builds/4chan-X-noupdate.user.js
@@ -1,7 +1,7 @@
// Generated by CoffeeScript
// ==UserScript==
// @name 4chan X
-// @version 1.9.3.3
+// @version 1.9.3.5
// @minGMVer 1.14
// @minFFVer 26
// @namespace 4chan-X
@@ -23,7 +23,7 @@
// ==/UserScript==
/*
-* 4chan X - Version 1.9.3.3
+* 4chan X - Version 1.9.3.5
*
* Licensed under the MIT license.
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
@@ -266,7 +266,7 @@
'Current Board': [false, 'Only show watched threads from the current board.'],
'Auto Watch': [true, 'Automatically watch threads you start.'],
'Auto Watch Reply': [false, 'Automatically watch threads you reply to.'],
- 'Auto Prune': [false, 'Automatically prune 404\'d threads.'],
+ 'Auto Prune': [false, 'Automatically prune dead threads.'],
'Show Unread Count': [true, 'Show number of unread posts in watched threads.']
},
filter: {
@@ -375,7 +375,7 @@
doc = d.documentElement;
g = {
- VERSION: '1.9.3.3',
+ VERSION: '1.9.3.5',
NAMESPACE: '4chan X.',
NAME: '4chan X',
FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions',
@@ -1500,7 +1500,7 @@
};
DataBoard.prototype.clean = function() {
- var boardID, now, val, _ref;
+ var boardID, now, threadID, val, _ref;
_ref = this.data.boards;
for (boardID in _ref) {
val = _ref[boardID];
@@ -1512,44 +1512,29 @@
if ((this.data.lastChecked || 0) < now - 2 * $.HOUR) {
this.data.lastChecked = now;
for (boardID in this.data.boards) {
- this.ajaxClean(boardID);
+ for (threadID in this.data.boards[boardID]) {
+ this.ajaxClean(boardID, threadID);
+ }
}
}
return this.save();
};
- DataBoard.prototype.ajaxClean = function(boardID) {
- return $.cache("//a.4cdn.org/" + boardID + "/threads.json", (function(_this) {
- return function(e) {
- var board, page, thread, threads, _i, _j, _len, _len1, _ref, _ref1;
- if (e.target.status !== 200) {
+ DataBoard.prototype.ajaxClean = function(boardID, threadID) {
+ return $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", {
+ onloadend: (function(_this) {
+ return function(e) {
if (e.target.status === 404) {
- _this["delete"]({
- boardID: boardID
+ return _this["delete"]({
+ boardID: boardID,
+ threadID: threadID
});
}
- return;
- }
- board = _this.data.boards[boardID];
- threads = {};
- _ref = e.target.response;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- page = _ref[_i];
- _ref1 = page.threads;
- for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
- thread = _ref1[_j];
- if (thread.no in board) {
- threads[thread.no] = board[thread.no];
- }
- }
- }
- _this.data.boards[boardID] = threads;
- _this.deleteIfEmpty({
- boardID: boardID
- });
- return _this.save();
- };
- })(this));
+ };
+ })(this)
+ }, {
+ type: 'head'
+ });
};
DataBoard.prototype.onSync = function(data) {
@@ -4044,7 +4029,6 @@
isImage: (_ref = el.nodeName) === 'IMG' || _ref === 'VIDEO',
cb: cb,
endEvents: endEvents,
- ready: false,
latestEvent: latestEvent,
clientHeight: doc.clientHeight,
clientWidth: doc.clientWidth,
@@ -4055,7 +4039,6 @@
$.asap(function() {
return !el.parentNode || asapTest();
}, function() {
- o.ready = true;
if (el.parentNode) {
return o.hover(o.latestEvent);
}
@@ -4075,9 +4058,6 @@
hover = function(e) {
var clientX, clientY, height, left, right, style, threshold, top, _ref;
this.latestEvent = e;
- if (!this.ready) {
- return;
- }
height = this.el.offsetHeight;
clientX = e.clientX, clientY = e.clientY;
top = this.isImage ? Math.max(0, clientY * (this.clientHeight - height) / this.clientHeight) : Math.max(0, Math.min(this.clientHeight - height, clientY - 120));
@@ -5970,7 +5950,12 @@
}
},
statusCheck: function() {
- if (g.DEAD) {
+ var thread;
+ if (!QR.nodes) {
+ return;
+ }
+ thread = QR.posts[0].thread;
+ if (thread !== 'new' && g.threads["" + g.BOARD + "." + thread].isDead) {
return QR.abort();
} else {
return QR.status();
@@ -10128,7 +10113,7 @@
$.on(window, 'online offline', ThreadUpdater.cb.online);
$.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost);
$.on(d, 'visibilitychange', ThreadUpdater.cb.visibility);
- if (g.DEAD) {
+ if (ThreadUpdater.thread.isArchived) {
return ThreadUpdater.set('status', 'Archived', 'warning');
} else {
return ThreadUpdater.cb.online();
@@ -10142,7 +10127,7 @@
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',
cb: {
online: function() {
- if (g.DEAD) {
+ if (ThreadUpdater.thread.isDead) {
return;
}
if (ThreadUpdater.online = navigator.onLine) {
@@ -10172,7 +10157,7 @@
ThreadUpdater.outdateCount = 0;
ThreadUpdater.set('timer', '...');
}
- if (!(g.DEAD || ThreadUpdater.foundPost || ThreadUpdater.checkPostCount >= 5)) {
+ if (!(ThreadUpdater.thread.isDead || ThreadUpdater.foundPost || ThreadUpdater.checkPostCount >= 5)) {
return setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * $.SECOND);
}
ThreadUpdater.setInterval();
@@ -10210,9 +10195,9 @@
req = ThreadUpdater.req;
switch (req.status) {
case 200:
- g.DEAD = !!+req.response.posts[0].archived;
ThreadUpdater.parse(req.response.posts);
- if (g.DEAD) {
+ if (!!req.response.posts[0].archived) {
+ ThreadUpdater.thread.isArchived = true;
ThreadUpdater.set('status', 'Archived', 'warning');
ThreadUpdater.kill();
} else {
@@ -10241,7 +10226,6 @@
confirmed = false;
}
if (confirmed) {
- g.DEAD = true;
ThreadUpdater.set('status', '404', 'warning');
return ThreadUpdater.kill();
} else {
@@ -10600,7 +10584,6 @@
});
} else {
data.isDead = true;
- delete data.unread;
ThreadWatcher.db.set({
boardID: boardID,
threadID: threadID,
@@ -10640,7 +10623,7 @@
fetchStatus: function(_arg) {
var boardID, data, fetchCount, threadID;
boardID = _arg.boardID, threadID = _arg.threadID, data = _arg.data;
- if (data.isDead) {
+ if (data.isDead && !Conf['Show Unread Count']) {
return;
}
fetchCount = ThreadWatcher.fetchCount;
@@ -10651,7 +10634,7 @@
fetchCount.fetching++;
return $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", {
onloadend: function() {
- var lastReadPost, postObj, status, unread, _i, _len, _ref, _ref1;
+ var isDead, lastReadPost, postObj, status, unread, _i, _len, _ref, _ref1;
fetchCount.fetched++;
if (fetchCount.fetched === fetchCount.fetching) {
fetchCount.fetched = 0;
@@ -10663,6 +10646,15 @@
}
ThreadWatcher.status.textContent = status;
if (this.status === 200 && this.response) {
+ isDead = !!this.response.posts[0].archived;
+ if (isDead && Conf['Auto Prune']) {
+ ThreadWatcher.db["delete"]({
+ boardID: boardID,
+ threadID: threadID
+ });
+ ThreadWatcher.refresh();
+ return;
+ }
lastReadPost = ThreadWatcher.unreaddb.get({
boardID: boardID,
threadID: threadID,
@@ -10680,7 +10672,8 @@
unread++;
}
}
- if (unread !== data.unread) {
+ if (isDead !== data.isDead || unread !== data.unread) {
+ data.isDead = isDead;
data.unread = unread;
ThreadWatcher.db.set({
boardID: boardID,
@@ -10707,8 +10700,6 @@
return ThreadWatcher.refresh();
}
}
- }, {
- type: Conf['Show Unread Count'] ? 'get' : 'head'
});
},
getAll: function() {
@@ -10732,7 +10723,7 @@
return all;
},
makeLine: function(boardID, threadID, data) {
- var count, div, fullID, href, link, title, x;
+ var count, div, fullID, link, title, x;
x = $.el('a', {
className: 'fa fa-times',
href: 'javascript:;'
@@ -10746,14 +10737,8 @@
textContent: Conf['Show Unread Count'] && (data.unread != null) ? "\u00A0(" + data.unread + ")" : '',
className: 'watcher-unread'
});
- if (Conf['404 Redirect'] && data.isDead) {
- href = Redirect.to('thread', {
- boardID: boardID,
- threadID: threadID
- });
- }
link = $.el('a', {
- href: href || ("/" + boardID + "/thread/" + threadID),
+ href: "/" + boardID + "/thread/" + threadID,
title: data.excerpt,
className: 'watcher-link'
});
@@ -10836,7 +10821,7 @@
val: data
});
ThreadWatcher.refresh();
- if (Conf['Show Unread Count'] && !data.isDead) {
+ if (Conf['Show Unread Count']) {
return ThreadWatcher.fetchStatus({
boardID: boardID,
threadID: threadID,
@@ -10920,7 +10905,7 @@
cb: ThreadWatcher.cb.pruneDeads,
entry: {
el: $.el('a', {
- textContent: 'Prune 404\'d threads'
+ textContent: 'Prune dead threads'
})
},
refresh: function() {
@@ -11201,7 +11186,7 @@
}
}),
saveLastReadPost: $.debounce(2 * $.SECOND, function() {
- if (Unread.thread.isDead) {
+ if (Unread.thread.isDead && !Unread.thread.isArchived) {
return;
}
return Unread.db.set({
@@ -11223,16 +11208,19 @@
}
},
update: function() {
- var count, countQuotingYou;
+ var count, countQuotingYou, titleCount, titleDead, titleQuotingYou;
count = Unread.posts.length;
countQuotingYou = Object.keys(Unread.postsQuotingYou).length;
if (Conf['Unread Count']) {
- d.title = "" + (Conf['Quoted Title'] && countQuotingYou ? '(!) ' : '') + (count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : '') + (g.DEAD ? Unread.title.replace('-', '- 404 -') : Unread.title);
+ titleQuotingYou = Conf['Quoted Title'] && countQuotingYou ? '(!) ' : '';
+ titleCount = count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : '';
+ titleDead = Unread.thread.isDead ? Unread.title.replace('-', (Unread.thread.isArchived ? '- Archived -' : '- 404 -')) : Unread.title;
+ d.title = "" + titleQuotingYou + titleCount + titleDead;
}
if (!Conf['Unread Favicon']) {
return;
}
- Favicon.el.href = g.DEAD ? countQuotingYou ? Favicon.unreadDeadY : count ? Favicon.unreadDead : Favicon.dead : count ? countQuotingYou ? Favicon.unreadY : Favicon.unread : Favicon["default"];
+ Favicon.el.href = Unread.thread.isDead ? countQuotingYou ? Favicon.unreadDeadY : count ? Favicon.unreadDead : Favicon.dead : count ? countQuotingYou ? Favicon.unreadY : Favicon.unread : Favicon["default"];
return $.add(d.head, Favicon.el);
}
};
@@ -12883,7 +12871,7 @@
className: 'dialog'
});
$.extend(dialog, {
- innerHTML: ""
+ innerHTML: ""
});
$.on($('.export', Settings.dialog), 'click', Settings["export"]);
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
@@ -13692,14 +13680,16 @@
},
initThread: function() {
var board, err, errors, postRoot, posts, thread, threadRoot, threads, _i, _j, _len, _len1, _ref, _ref1, _ref2;
- g.DEAD = !!((_ref = $('.closed')) != null ? _ref.textContent.match(/Thread archived/) : void 0);
if (board = $('.board')) {
threads = [];
posts = [];
- _ref1 = $$('.board > .thread', board);
- for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
- threadRoot = _ref1[_i];
+ _ref = $$('.board > .thread', board);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ threadRoot = _ref[_i];
thread = new Thread(+threadRoot.id.slice(1), g.BOARD);
+ if (g.VIEW === 'thread') {
+ thread.isDead = thread.isArchived = !!((_ref1 = $('.closed')) != null ? _ref1.textContent.match(/Thread archived/) : void 0);
+ }
threads.push(thread);
_ref2 = $$('.thread > .postContainer', threadRoot);
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
diff --git a/builds/4chan-X.crx b/builds/4chan-X.crx
index 943e00f12..4764f5007 100644
Binary files a/builds/4chan-X.crx and b/builds/4chan-X.crx differ
diff --git a/builds/4chan-X.meta.js b/builds/4chan-X.meta.js
index 157c89e8b..bc63fc090 100644
--- a/builds/4chan-X.meta.js
+++ b/builds/4chan-X.meta.js
@@ -1,6 +1,6 @@
// ==UserScript==
// @name 4chan X
-// @version 1.9.3.3
+// @version 1.9.3.5
// @minGMVer 1.14
// @minFFVer 26
// @namespace 4chan-X
diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js
index 9fb438979..85cb2769b 100644
--- a/builds/4chan-X.user.js
+++ b/builds/4chan-X.user.js
@@ -1,7 +1,7 @@
// Generated by CoffeeScript
// ==UserScript==
// @name 4chan X
-// @version 1.9.3.3
+// @version 1.9.3.5
// @minGMVer 1.14
// @minFFVer 26
// @namespace 4chan-X
@@ -24,7 +24,7 @@
// ==/UserScript==
/*
-* 4chan X - Version 1.9.3.3
+* 4chan X - Version 1.9.3.5
*
* Licensed under the MIT license.
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
@@ -267,7 +267,7 @@
'Current Board': [false, 'Only show watched threads from the current board.'],
'Auto Watch': [true, 'Automatically watch threads you start.'],
'Auto Watch Reply': [false, 'Automatically watch threads you reply to.'],
- 'Auto Prune': [false, 'Automatically prune 404\'d threads.'],
+ 'Auto Prune': [false, 'Automatically prune dead threads.'],
'Show Unread Count': [true, 'Show number of unread posts in watched threads.']
},
filter: {
@@ -376,7 +376,7 @@
doc = d.documentElement;
g = {
- VERSION: '1.9.3.3',
+ VERSION: '1.9.3.5',
NAMESPACE: '4chan X.',
NAME: '4chan X',
FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions',
@@ -1501,7 +1501,7 @@
};
DataBoard.prototype.clean = function() {
- var boardID, now, val, _ref;
+ var boardID, now, threadID, val, _ref;
_ref = this.data.boards;
for (boardID in _ref) {
val = _ref[boardID];
@@ -1513,44 +1513,29 @@
if ((this.data.lastChecked || 0) < now - 2 * $.HOUR) {
this.data.lastChecked = now;
for (boardID in this.data.boards) {
- this.ajaxClean(boardID);
+ for (threadID in this.data.boards[boardID]) {
+ this.ajaxClean(boardID, threadID);
+ }
}
}
return this.save();
};
- DataBoard.prototype.ajaxClean = function(boardID) {
- return $.cache("//a.4cdn.org/" + boardID + "/threads.json", (function(_this) {
- return function(e) {
- var board, page, thread, threads, _i, _j, _len, _len1, _ref, _ref1;
- if (e.target.status !== 200) {
+ DataBoard.prototype.ajaxClean = function(boardID, threadID) {
+ return $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", {
+ onloadend: (function(_this) {
+ return function(e) {
if (e.target.status === 404) {
- _this["delete"]({
- boardID: boardID
+ return _this["delete"]({
+ boardID: boardID,
+ threadID: threadID
});
}
- return;
- }
- board = _this.data.boards[boardID];
- threads = {};
- _ref = e.target.response;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- page = _ref[_i];
- _ref1 = page.threads;
- for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
- thread = _ref1[_j];
- if (thread.no in board) {
- threads[thread.no] = board[thread.no];
- }
- }
- }
- _this.data.boards[boardID] = threads;
- _this.deleteIfEmpty({
- boardID: boardID
- });
- return _this.save();
- };
- })(this));
+ };
+ })(this)
+ }, {
+ type: 'head'
+ });
};
DataBoard.prototype.onSync = function(data) {
@@ -4045,7 +4030,6 @@
isImage: (_ref = el.nodeName) === 'IMG' || _ref === 'VIDEO',
cb: cb,
endEvents: endEvents,
- ready: false,
latestEvent: latestEvent,
clientHeight: doc.clientHeight,
clientWidth: doc.clientWidth,
@@ -4056,7 +4040,6 @@
$.asap(function() {
return !el.parentNode || asapTest();
}, function() {
- o.ready = true;
if (el.parentNode) {
return o.hover(o.latestEvent);
}
@@ -4076,9 +4059,6 @@
hover = function(e) {
var clientX, clientY, height, left, right, style, threshold, top, _ref;
this.latestEvent = e;
- if (!this.ready) {
- return;
- }
height = this.el.offsetHeight;
clientX = e.clientX, clientY = e.clientY;
top = this.isImage ? Math.max(0, clientY * (this.clientHeight - height) / this.clientHeight) : Math.max(0, Math.min(this.clientHeight - height, clientY - 120));
@@ -5971,7 +5951,12 @@
}
},
statusCheck: function() {
- if (g.DEAD) {
+ var thread;
+ if (!QR.nodes) {
+ return;
+ }
+ thread = QR.posts[0].thread;
+ if (thread !== 'new' && g.threads["" + g.BOARD + "." + thread].isDead) {
return QR.abort();
} else {
return QR.status();
@@ -10129,7 +10114,7 @@
$.on(window, 'online offline', ThreadUpdater.cb.online);
$.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost);
$.on(d, 'visibilitychange', ThreadUpdater.cb.visibility);
- if (g.DEAD) {
+ if (ThreadUpdater.thread.isArchived) {
return ThreadUpdater.set('status', 'Archived', 'warning');
} else {
return ThreadUpdater.cb.online();
@@ -10143,7 +10128,7 @@
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',
cb: {
online: function() {
- if (g.DEAD) {
+ if (ThreadUpdater.thread.isDead) {
return;
}
if (ThreadUpdater.online = navigator.onLine) {
@@ -10173,7 +10158,7 @@
ThreadUpdater.outdateCount = 0;
ThreadUpdater.set('timer', '...');
}
- if (!(g.DEAD || ThreadUpdater.foundPost || ThreadUpdater.checkPostCount >= 5)) {
+ if (!(ThreadUpdater.thread.isDead || ThreadUpdater.foundPost || ThreadUpdater.checkPostCount >= 5)) {
return setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * $.SECOND);
}
ThreadUpdater.setInterval();
@@ -10211,9 +10196,9 @@
req = ThreadUpdater.req;
switch (req.status) {
case 200:
- g.DEAD = !!+req.response.posts[0].archived;
ThreadUpdater.parse(req.response.posts);
- if (g.DEAD) {
+ if (!!req.response.posts[0].archived) {
+ ThreadUpdater.thread.isArchived = true;
ThreadUpdater.set('status', 'Archived', 'warning');
ThreadUpdater.kill();
} else {
@@ -10242,7 +10227,6 @@
confirmed = false;
}
if (confirmed) {
- g.DEAD = true;
ThreadUpdater.set('status', '404', 'warning');
return ThreadUpdater.kill();
} else {
@@ -10601,7 +10585,6 @@
});
} else {
data.isDead = true;
- delete data.unread;
ThreadWatcher.db.set({
boardID: boardID,
threadID: threadID,
@@ -10641,7 +10624,7 @@
fetchStatus: function(_arg) {
var boardID, data, fetchCount, threadID;
boardID = _arg.boardID, threadID = _arg.threadID, data = _arg.data;
- if (data.isDead) {
+ if (data.isDead && !Conf['Show Unread Count']) {
return;
}
fetchCount = ThreadWatcher.fetchCount;
@@ -10652,7 +10635,7 @@
fetchCount.fetching++;
return $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", {
onloadend: function() {
- var lastReadPost, postObj, status, unread, _i, _len, _ref, _ref1;
+ var isDead, lastReadPost, postObj, status, unread, _i, _len, _ref, _ref1;
fetchCount.fetched++;
if (fetchCount.fetched === fetchCount.fetching) {
fetchCount.fetched = 0;
@@ -10664,6 +10647,15 @@
}
ThreadWatcher.status.textContent = status;
if (this.status === 200 && this.response) {
+ isDead = !!this.response.posts[0].archived;
+ if (isDead && Conf['Auto Prune']) {
+ ThreadWatcher.db["delete"]({
+ boardID: boardID,
+ threadID: threadID
+ });
+ ThreadWatcher.refresh();
+ return;
+ }
lastReadPost = ThreadWatcher.unreaddb.get({
boardID: boardID,
threadID: threadID,
@@ -10681,7 +10673,8 @@
unread++;
}
}
- if (unread !== data.unread) {
+ if (isDead !== data.isDead || unread !== data.unread) {
+ data.isDead = isDead;
data.unread = unread;
ThreadWatcher.db.set({
boardID: boardID,
@@ -10708,8 +10701,6 @@
return ThreadWatcher.refresh();
}
}
- }, {
- type: Conf['Show Unread Count'] ? 'get' : 'head'
});
},
getAll: function() {
@@ -10733,7 +10724,7 @@
return all;
},
makeLine: function(boardID, threadID, data) {
- var count, div, fullID, href, link, title, x;
+ var count, div, fullID, link, title, x;
x = $.el('a', {
className: 'fa fa-times',
href: 'javascript:;'
@@ -10747,14 +10738,8 @@
textContent: Conf['Show Unread Count'] && (data.unread != null) ? "\u00A0(" + data.unread + ")" : '',
className: 'watcher-unread'
});
- if (Conf['404 Redirect'] && data.isDead) {
- href = Redirect.to('thread', {
- boardID: boardID,
- threadID: threadID
- });
- }
link = $.el('a', {
- href: href || ("/" + boardID + "/thread/" + threadID),
+ href: "/" + boardID + "/thread/" + threadID,
title: data.excerpt,
className: 'watcher-link'
});
@@ -10837,7 +10822,7 @@
val: data
});
ThreadWatcher.refresh();
- if (Conf['Show Unread Count'] && !data.isDead) {
+ if (Conf['Show Unread Count']) {
return ThreadWatcher.fetchStatus({
boardID: boardID,
threadID: threadID,
@@ -10921,7 +10906,7 @@
cb: ThreadWatcher.cb.pruneDeads,
entry: {
el: $.el('a', {
- textContent: 'Prune 404\'d threads'
+ textContent: 'Prune dead threads'
})
},
refresh: function() {
@@ -11202,7 +11187,7 @@
}
}),
saveLastReadPost: $.debounce(2 * $.SECOND, function() {
- if (Unread.thread.isDead) {
+ if (Unread.thread.isDead && !Unread.thread.isArchived) {
return;
}
return Unread.db.set({
@@ -11224,16 +11209,19 @@
}
},
update: function() {
- var count, countQuotingYou;
+ var count, countQuotingYou, titleCount, titleDead, titleQuotingYou;
count = Unread.posts.length;
countQuotingYou = Object.keys(Unread.postsQuotingYou).length;
if (Conf['Unread Count']) {
- d.title = "" + (Conf['Quoted Title'] && countQuotingYou ? '(!) ' : '') + (count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : '') + (g.DEAD ? Unread.title.replace('-', '- 404 -') : Unread.title);
+ titleQuotingYou = Conf['Quoted Title'] && countQuotingYou ? '(!) ' : '';
+ titleCount = count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : '';
+ titleDead = Unread.thread.isDead ? Unread.title.replace('-', (Unread.thread.isArchived ? '- Archived -' : '- 404 -')) : Unread.title;
+ d.title = "" + titleQuotingYou + titleCount + titleDead;
}
if (!Conf['Unread Favicon']) {
return;
}
- Favicon.el.href = g.DEAD ? countQuotingYou ? Favicon.unreadDeadY : count ? Favicon.unreadDead : Favicon.dead : count ? countQuotingYou ? Favicon.unreadY : Favicon.unread : Favicon["default"];
+ Favicon.el.href = Unread.thread.isDead ? countQuotingYou ? Favicon.unreadDeadY : count ? Favicon.unreadDead : Favicon.dead : count ? countQuotingYou ? Favicon.unreadY : Favicon.unread : Favicon["default"];
return $.add(d.head, Favicon.el);
}
};
@@ -12884,7 +12872,7 @@
className: 'dialog'
});
$.extend(dialog, {
- innerHTML: ""
+ innerHTML: ""
});
$.on($('.export', Settings.dialog), 'click', Settings["export"]);
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
@@ -13693,14 +13681,16 @@
},
initThread: function() {
var board, err, errors, postRoot, posts, thread, threadRoot, threads, _i, _j, _len, _len1, _ref, _ref1, _ref2;
- g.DEAD = !!((_ref = $('.closed')) != null ? _ref.textContent.match(/Thread archived/) : void 0);
if (board = $('.board')) {
threads = [];
posts = [];
- _ref1 = $$('.board > .thread', board);
- for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
- threadRoot = _ref1[_i];
+ _ref = $$('.board > .thread', board);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ threadRoot = _ref[_i];
thread = new Thread(+threadRoot.id.slice(1), g.BOARD);
+ if (g.VIEW === 'thread') {
+ thread.isDead = thread.isArchived = !!((_ref1 = $('.closed')) != null ? _ref1.textContent.match(/Thread archived/) : void 0);
+ }
threads.push(thread);
_ref2 = $$('.thread > .postContainer', threadRoot);
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
diff --git a/builds/4chan-X.zip b/builds/4chan-X.zip
index e6d55f274..84b69f927 100644
Binary files a/builds/4chan-X.zip and b/builds/4chan-X.zip differ
diff --git a/builds/updates-beta.xml b/builds/updates-beta.xml
index 09b49afdf..a8ab6876c 100644
--- a/builds/updates-beta.xml
+++ b/builds/updates-beta.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/builds/updates.xml b/builds/updates.xml
index 2e5c015eb..2efd69bfe 100644
--- a/builds/updates.xml
+++ b/builds/updates.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/package.json b/package.json
index 71efc248d..a8c3e9e7e 100755
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"description": "Cross-browser userscript for maximum lurking on 4chan.",
"meta": {
"name": "4chan X",
- "version": "1.9.3.3",
+ "version": "1.9.3.5",
"repo": "https://github.com/ccd0/4chan-x/",
"page": "https://github.com/ccd0/4chan-x",
"downloads": "https://ccd0.github.io/4chan-x/builds/",
diff --git a/src/General/Config.coffee b/src/General/Config.coffee
index 3d68cfd1c..45408e983 100755
--- a/src/General/Config.coffee
+++ b/src/General/Config.coffee
@@ -476,7 +476,7 @@ Config =
]
'Auto Prune': [
false
- 'Automatically prune 404\'d threads.'
+ 'Automatically prune dead threads.'
]
'Show Unread Count': [
true
diff --git a/src/General/Main.coffee b/src/General/Main.coffee
index f789700c8..2b725b9e4 100755
--- a/src/General/Main.coffee
+++ b/src/General/Main.coffee
@@ -160,14 +160,13 @@ Main =
new Notice 'warning', 'Cookies need to be enabled on 4chan for <%= meta.name %> to operate properly.', 30
initThread: ->
- g.DEAD = !!$('.closed')?.textContent.match(/Thread archived/)
-
if board = $ '.board'
threads = []
posts = []
for threadRoot in $$ '.board > .thread', board
thread = new Thread +threadRoot.id[1..], g.BOARD
+ thread.isDead = thread.isArchived = !!$('.closed')?.textContent.match(/Thread archived/) if g.VIEW is 'thread'
threads.push thread
for postRoot in $$ '.thread > .postContainer', threadRoot
try
diff --git a/src/General/UI.coffee b/src/General/UI.coffee
index 44eec8030..fa30d32d6 100755
--- a/src/General/UI.coffee
+++ b/src/General/UI.coffee
@@ -310,7 +310,6 @@ UI = do ->
isImage: el.nodeName in ['IMG', 'VIDEO']
cb
endEvents
- ready: false
latestEvent
clientHeight: doc.clientHeight
clientWidth: doc.clientWidth
@@ -322,7 +321,6 @@ UI = do ->
$.asap ->
!el.parentNode or asapTest()
, ->
- o.ready = true
o.hover o.latestEvent if el.parentNode
$.on root, endEvents, o.hoverend
@@ -337,7 +335,6 @@ UI = do ->
hover = (e) ->
@latestEvent = e
- return unless @ready
height = @el.offsetHeight
{clientX, clientY} = e
diff --git a/src/General/lib/databoard.class b/src/General/lib/databoard.class
index 923e4b8b4..f0567d78d 100755
--- a/src/General/lib/databoard.class
+++ b/src/General/lib/databoard.class
@@ -70,23 +70,17 @@ class DataBoard
if (@data.lastChecked or 0) < now - 2 * $.HOUR
@data.lastChecked = now
for boardID of @data.boards
- @ajaxClean boardID
+ for threadID of @data.boards[boardID]
+ @ajaxClean boardID, threadID
@save()
- ajaxClean: (boardID) ->
- $.cache "//a.4cdn.org/#{boardID}/threads.json", (e) =>
- if e.target.status isnt 200
- @delete {boardID} if e.target.status is 404
- return
- board = @data.boards[boardID]
- threads = {}
- for page in e.target.response
- for thread in page.threads
- if thread.no of board
- threads[thread.no] = board[thread.no]
- @data.boards[boardID] = threads
- @deleteIfEmpty {boardID}
- @save()
+ ajaxClean: (boardID, threadID) ->
+ $.ajax "//a.4cdn.org/#{boardID}/thread/#{threadID}.json",
+ onloadend: (e) =>
+ if e.target.status is 404
+ @delete {boardID, threadID}
+ ,
+ type: 'head'
onSync: (data) =>
@data = data or boards: {}
diff --git a/src/Monitoring/ThreadUpdater.coffee b/src/Monitoring/ThreadUpdater.coffee
index eb5ca6764..5130262c4 100755
--- a/src/Monitoring/ThreadUpdater.coffee
+++ b/src/Monitoring/ThreadUpdater.coffee
@@ -74,7 +74,7 @@ ThreadUpdater =
$.on d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost
$.on d, 'visibilitychange', ThreadUpdater.cb.visibility
- if g.DEAD
+ if ThreadUpdater.thread.isArchived
ThreadUpdater.set 'status', 'Archived', 'warning'
else
ThreadUpdater.cb.online()
@@ -87,7 +87,7 @@ ThreadUpdater =
cb:
online: ->
- return if g.DEAD
+ return if ThreadUpdater.thread.isDead
if ThreadUpdater.online = navigator.onLine
ThreadUpdater.outdateCount = 0
ThreadUpdater.setInterval()
@@ -105,7 +105,7 @@ ThreadUpdater =
ThreadUpdater.seconds = 0
ThreadUpdater.outdateCount = 0
ThreadUpdater.set 'timer', '...'
- unless g.DEAD or ThreadUpdater.foundPost or ThreadUpdater.checkPostCount >= 5
+ unless ThreadUpdater.thread.isDead or ThreadUpdater.foundPost or ThreadUpdater.checkPostCount >= 5
return setTimeout ThreadUpdater.update, ++ThreadUpdater.checkPostCount * $.SECOND
ThreadUpdater.setInterval()
ThreadUpdater.checkPostCount = 0
@@ -131,9 +131,9 @@ ThreadUpdater =
{req} = ThreadUpdater
switch req.status
when 200
- g.DEAD = !!+req.response.posts[0].archived
ThreadUpdater.parse req.response.posts
- if g.DEAD
+ if !!req.response.posts[0].archived
+ ThreadUpdater.thread.isArchived = true
ThreadUpdater.set 'status', 'Archived', 'warning'
ThreadUpdater.kill()
else
@@ -151,7 +151,6 @@ ThreadUpdater =
else
confirmed = false
if confirmed
- g.DEAD = true
ThreadUpdater.set 'status', '404', 'warning'
ThreadUpdater.kill()
else
diff --git a/src/Monitoring/ThreadWatcher.coffee b/src/Monitoring/ThreadWatcher.coffee
index b9d8ccebb..596e118dc 100755
--- a/src/Monitoring/ThreadWatcher.coffee
+++ b/src/Monitoring/ThreadWatcher.coffee
@@ -102,13 +102,12 @@ ThreadWatcher =
ThreadWatcher.db.delete {boardID, threadID}
else
data.isDead = true
- delete data.unread
ThreadWatcher.db.set {boardID, threadID, val: data}
ThreadWatcher.refresh()
onThreadRefresh: (e) ->
thread = g.threads[e.detail.threadID]
return unless e.detail[404] and ThreadWatcher.db.get {boardID: thread.board.ID, threadID: thread.ID}
- # Update 404 status.
+ # Update dead status.
ThreadWatcher.add thread
fetchCount:
@@ -120,7 +119,7 @@ ThreadWatcher =
ThreadWatcher.fetchStatus thread
return
fetchStatus: ({boardID, threadID, data}) ->
- return if data.isDead
+ return if data.isDead and !Conf['Show Unread Count']
{fetchCount} = ThreadWatcher
if fetchCount.fetching is 0
ThreadWatcher.status.textContent = '...'
@@ -139,6 +138,12 @@ ThreadWatcher =
ThreadWatcher.status.textContent = status
if @status is 200 and @response
+ isDead = !!@response.posts[0].archived
+ if isDead and Conf['Auto Prune']
+ ThreadWatcher.db.delete {boardID, threadID}
+ ThreadWatcher.refresh()
+ return
+
lastReadPost = ThreadWatcher.unreaddb.get
boardID: boardID
threadID: threadID
@@ -150,7 +155,8 @@ ThreadWatcher =
if postObj.no > lastReadPost and !QR.db?.get {boardID, threadID, postID: postObj.no}
unread++
- if unread isnt data.unread
+ if isDead isnt data.isDead or unread isnt data.unread
+ data.isDead = isDead
data.unread = unread
ThreadWatcher.db.set {boardID, threadID, val: data}
ThreadWatcher.refresh()
@@ -163,8 +169,6 @@ ThreadWatcher =
delete data.unread
ThreadWatcher.db.set {boardID, threadID, val: data}
ThreadWatcher.refresh()
- ,
- type: if Conf['Show Unread Count'] then 'get' else 'head'
getAll: ->
all = []
@@ -189,10 +193,8 @@ ThreadWatcher =
textContent: if Conf['Show Unread Count'] and data.unread? then "\u00A0(#{data.unread})" else ''
className: 'watcher-unread'
- if Conf['404 Redirect'] and data.isDead
- href = Redirect.to 'thread', {boardID, threadID}
link = $.el 'a',
- href: href or "/#{boardID}/thread/#{threadID}"
+ href: "/#{boardID}/thread/#{threadID}"
title: data.excerpt
className: 'watcher-link'
$.add link, [title, count]
@@ -245,7 +247,7 @@ ThreadWatcher =
data.excerpt = Get.threadExcerpt thread
ThreadWatcher.db.set {boardID, threadID, val: data}
ThreadWatcher.refresh()
- if Conf['Show Unread Count'] and !data.isDead
+ if Conf['Show Unread Count']
ThreadWatcher.fetchStatus {boardID, threadID, data}
rm: (boardID, threadID) ->
ThreadWatcher.db.delete {boardID, threadID}
@@ -296,12 +298,12 @@ ThreadWatcher =
textContent: 'Open all threads'
refresh: -> (if ThreadWatcher.list.firstElementChild then $.rmClass else $.addClass) @el, 'disabled'
- # `Prune 404'd threads` entry
+ # `Prune dead threads` entry
entries.push
cb: ThreadWatcher.cb.pruneDeads
entry:
el: $.el 'a',
- textContent: 'Prune 404\'d threads'
+ textContent: 'Prune dead threads'
refresh: -> (if $('.dead-thread', ThreadWatcher.list) then $.rmClass else $.addClass) @el, 'disabled'
# `Settings` entries:
diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee
index 5dc497441..a8db0b9ec 100755
--- a/src/Monitoring/Unread.coffee
+++ b/src/Monitoring/Unread.coffee
@@ -163,7 +163,7 @@ Unread =
Unread.update() if e
saveLastReadPost: $.debounce 2 * $.SECOND, ->
- return if Unread.thread.isDead
+ return if Unread.thread.isDead and !Unread.thread.isArchived
Unread.db.set
boardID: Unread.thread.board.ID
threadID: Unread.thread.ID
@@ -180,12 +180,18 @@ Unread =
countQuotingYou = Object.keys(Unread.postsQuotingYou).length
if Conf['Unread Count']
- d.title = "#{if Conf['Quoted Title'] and countQuotingYou then '(!) ' else ''}#{if count or !Conf['Hide Unread Count at (0)'] then "(#{count}) " else ''}#{if g.DEAD then Unread.title.replace '-', '- 404 -' else Unread.title}"
+ titleQuotingYou = if Conf['Quoted Title'] and countQuotingYou then '(!) ' else ''
+ titleCount = if count or !Conf['Hide Unread Count at (0)'] then "(#{count}) " else ''
+ titleDead = if Unread.thread.isDead
+ Unread.title.replace '-', (if Unread.thread.isArchived then '- Archived -' else '- 404 -')
+ else
+ Unread.title
+ d.title = "#{titleQuotingYou}#{titleCount}#{titleDead}"
return unless Conf['Unread Favicon']
Favicon.el.href =
- if g.DEAD
+ if Unread.thread.isDead
if countQuotingYou
Favicon.unreadDeadY
else if count
diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee
index 453dfcda9..cd88b1503 100644
--- a/src/Posting/QR.coffee
+++ b/src/Posting/QR.coffee
@@ -80,7 +80,9 @@ QR =
QR.hide() if Conf['Auto-Hide QR']
statusCheck: ->
- if g.DEAD
+ return unless QR.nodes
+ {thread} = QR.posts[0]
+ if thread isnt 'new' and g.threads["#{g.BOARD}.#{thread}"].isDead
QR.abort()
else
QR.status()