Release 4chan X v1.10.4.0.
This commit is contained in:
parent
0c45d35da6
commit
2e9980fee4
@ -2,6 +2,14 @@ Sometimes the changelog has notes (not comprehensive) acknowledging people's wor
|
||||
|
||||
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.10.4
|
||||
|
||||
**v1.10.4.0** *(2015-03-09)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.4.0/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.4.0/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- Based on v1.10.3.9.
|
||||
- Add `Ignore Offline Status` option in the Updater header submenu to continue auto-updating even when your browser reports you are offline.
|
||||
- Fix `Auto Scroll` not scrolling to the first new post.
|
||||
- Restore `deletedPosts` and `deletedFiles` fields of the `ThreadUpdate` event, which will now each contain an array of the relevant posts' full IDs.
|
||||
|
||||
### v1.10.3
|
||||
|
||||
**v1.10.3.9** *(2015-03-07)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.3.9/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.3.9/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
|
||||
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
// ==UserScript==
|
||||
// @name 4chan X beta
|
||||
// @version 1.10.3.9
|
||||
// @version 1.10.4.0
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript
|
||||
// ==UserScript==
|
||||
// @name 4chan X beta
|
||||
// @version 1.10.3.9
|
||||
// @version 1.10.4.0
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -377,6 +377,7 @@
|
||||
'Bottom Scroll': [false, 'Always scroll to the bottom, not the first new post. Useful for event threads.'],
|
||||
'Scroll BG': [false, 'Auto-scroll background tabs.'],
|
||||
'Auto Update': [true, 'Automatically fetch new posts.'],
|
||||
'Ignore Offline Status': [false, 'Update even if your browser reports you are offline.'],
|
||||
'Optional Increase': [false, 'Increase the intervals between updates on threads without new posts.']
|
||||
},
|
||||
'Interval': 30
|
||||
@ -394,7 +395,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.10.3.9',
|
||||
VERSION: '1.10.4.0',
|
||||
NAMESPACE: '4chan X.',
|
||||
NAME: '4chan X',
|
||||
FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions',
|
||||
@ -1418,35 +1419,6 @@
|
||||
}
|
||||
};
|
||||
|
||||
Post.prototype.resurrect = function() {
|
||||
var clone, k, len1, len2, q, quotelink, ref, ref1, strong;
|
||||
delete this.isDead;
|
||||
$.rmClass(this.nodes.root, 'deleted-post');
|
||||
strong = $('strong.warning', this.nodes.info);
|
||||
if (this.file && this.file.isDead) {
|
||||
strong.textContent = '[File deleted]';
|
||||
} else {
|
||||
$.rm(strong);
|
||||
}
|
||||
if (this.isClone) {
|
||||
return;
|
||||
}
|
||||
ref = this.clones;
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
clone = ref[k];
|
||||
clone.resurrect();
|
||||
}
|
||||
ref1 = Get.allQuotelinksLinkingTo(this);
|
||||
for (q = 0, len2 = ref1.length; q < len2; q++) {
|
||||
quotelink = ref1[q];
|
||||
if (!($.hasClass(quotelink, 'deadlink'))) {
|
||||
continue;
|
||||
}
|
||||
quotelink.textContent = quotelink.textContent.replace('\u00A0(Dead)', '');
|
||||
$.rmClass(quotelink, 'deadlink');
|
||||
}
|
||||
};
|
||||
|
||||
Post.prototype.collect = function() {
|
||||
this.kill();
|
||||
g.posts.rm(this.fullID);
|
||||
@ -3565,9 +3537,6 @@
|
||||
},
|
||||
update: function(state) {
|
||||
var now, ref, ref1;
|
||||
if (!navigator.onLine) {
|
||||
return;
|
||||
}
|
||||
delete Index.pageNum;
|
||||
if ((ref = Index.req) != null) {
|
||||
ref.abort();
|
||||
@ -7591,7 +7560,6 @@
|
||||
postID: postID,
|
||||
val: true
|
||||
});
|
||||
ThreadUpdater.postID = postID;
|
||||
$.event('QRPostSuccessful', {
|
||||
boardID: g.BOARD.ID,
|
||||
threadID: threadID,
|
||||
@ -11808,59 +11776,30 @@
|
||||
});
|
||||
},
|
||||
node: function() {
|
||||
var x;
|
||||
MarkNewIPs.ipCount = this.ipCount;
|
||||
MarkNewIPs.postIDs = (function() {
|
||||
var k, len1, ref, results;
|
||||
ref = this.posts.keys;
|
||||
results = [];
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
x = ref[k];
|
||||
results.push(+x);
|
||||
}
|
||||
return results;
|
||||
}).call(this);
|
||||
return $.on(d, 'ThreadUpdate', MarkNewIPs.onUpdate);
|
||||
},
|
||||
onUpdate: function(e) {
|
||||
var added, fullID, i, ipCount, k, len1, len2, len3, len4, newPosts, obj, postIDs, q, ref, ref1, removed, u, w, x;
|
||||
ref = e.detail, ipCount = ref.ipCount, newPosts = ref.newPosts;
|
||||
postIDs = ThreadUpdater.postIDs;
|
||||
var deletedPosts, fullID, i, ipCount, k, len1, len2, newPosts, q, ref;
|
||||
ref = e.detail, ipCount = ref.ipCount, newPosts = ref.newPosts, deletedPosts = ref.deletedPosts;
|
||||
if (ipCount == null) {
|
||||
return;
|
||||
}
|
||||
if (newPosts.length) {
|
||||
obj = {};
|
||||
ref1 = MarkNewIPs.postIDs;
|
||||
for (k = 0, len1 = ref1.length; k < len1; k++) {
|
||||
x = ref1[k];
|
||||
obj[x] = true;
|
||||
}
|
||||
added = 0;
|
||||
for (q = 0, len2 = postIDs.length; q < len2; q++) {
|
||||
x = postIDs[q];
|
||||
if (!(x in obj)) {
|
||||
added++;
|
||||
switch (ipCount - MarkNewIPs.ipCount) {
|
||||
case newPosts.length:
|
||||
i = MarkNewIPs.ipCount;
|
||||
for (k = 0, len1 = newPosts.length; k < len1; k++) {
|
||||
fullID = newPosts[k];
|
||||
MarkNewIPs.markNew(g.posts[fullID], ++i);
|
||||
}
|
||||
break;
|
||||
case -deletedPosts.length:
|
||||
for (q = 0, len2 = newPosts.length; q < len2; q++) {
|
||||
fullID = newPosts[q];
|
||||
MarkNewIPs.markOld(g.posts[fullID]);
|
||||
}
|
||||
}
|
||||
removed = MarkNewIPs.postIDs.length + added - postIDs.length;
|
||||
switch (ipCount - MarkNewIPs.ipCount) {
|
||||
case added:
|
||||
i = MarkNewIPs.ipCount;
|
||||
for (u = 0, len3 = newPosts.length; u < len3; u++) {
|
||||
fullID = newPosts[u];
|
||||
MarkNewIPs.markNew(g.posts[fullID], ++i);
|
||||
}
|
||||
break;
|
||||
case -removed:
|
||||
for (w = 0, len4 = newPosts.length; w < len4; w++) {
|
||||
fullID = newPosts[w];
|
||||
MarkNewIPs.markOld(g.posts[fullID]);
|
||||
}
|
||||
}
|
||||
}
|
||||
MarkNewIPs.ipCount = ipCount;
|
||||
return MarkNewIPs.postIDs = postIDs;
|
||||
return MarkNewIPs.ipCount = ipCount;
|
||||
},
|
||||
markNew: function(post, ipCount) {
|
||||
var counter, suffix;
|
||||
@ -12040,7 +11979,7 @@
|
||||
id: 'updater'
|
||||
});
|
||||
$.extend(sc, {
|
||||
innerHTML: "<span id=\"update-status\"></span><span id=\"update-timer\" title=\"Update now\"></span>"
|
||||
innerHTML: "<span id=\"update-status\" class=\"empty\"></span><span id=\"update-timer\" class=\"empty\" title=\"Update now\"></span>"
|
||||
});
|
||||
$.ready(function() {
|
||||
return Header.addShortcut(sc);
|
||||
@ -12057,7 +11996,6 @@
|
||||
this.checkPostCount = 0;
|
||||
this.timer = $('#update-timer', sc);
|
||||
this.status = $('#update-status', sc);
|
||||
this.isUpdating = Conf['Auto Update'];
|
||||
$.on(this.timer, 'click', this.update);
|
||||
$.on(this.status, 'click', this.update);
|
||||
updateLink = $.el('span', {
|
||||
@ -12082,7 +12020,7 @@
|
||||
$.on(input, 'change', this.cb.scrollBG);
|
||||
this.cb.scrollBG();
|
||||
} else if (input.name === 'Auto Update') {
|
||||
$.on(input, 'change', this.cb.autoUpdate);
|
||||
$.on(input, 'change', this.setInterval);
|
||||
}
|
||||
subEntries.push({
|
||||
el: el
|
||||
@ -12112,17 +12050,21 @@
|
||||
ThreadUpdater.root = this.OP.nodes.root.parentNode;
|
||||
ThreadUpdater.lastPost = +this.posts.keys[this.posts.keys.length - 1];
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
ThreadUpdater.postIDs = [];
|
||||
ThreadUpdater.fileIDs = [];
|
||||
this.posts.forEach(function(post) {
|
||||
ThreadUpdater.postIDs.push(post.ID);
|
||||
if (post.file && !post.file.isDead) {
|
||||
return ThreadUpdater.fileIDs.push(post.ID);
|
||||
}
|
||||
});
|
||||
ThreadUpdater.cb.interval.call($.el('input', {
|
||||
value: Conf['Interval']
|
||||
}));
|
||||
$.on(window, 'online offline', ThreadUpdater.cb.online);
|
||||
$.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost);
|
||||
$.on(d, 'visibilitychange', ThreadUpdater.cb.visibility);
|
||||
if (ThreadUpdater.thread.isArchived) {
|
||||
return ThreadUpdater.set('status', 'Archived', 'warning');
|
||||
} else {
|
||||
return ThreadUpdater.cb.online();
|
||||
}
|
||||
return ThreadUpdater.setInterval();
|
||||
},
|
||||
|
||||
/*
|
||||
@ -12135,32 +12077,24 @@
|
||||
if (ThreadUpdater.thread.isDead) {
|
||||
return;
|
||||
}
|
||||
if (ThreadUpdater.online = navigator.onLine) {
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
ThreadUpdater.setInterval();
|
||||
return ThreadUpdater.set('status', '', '');
|
||||
if (navigator.onLine) {
|
||||
ThreadUpdater.set('status', '');
|
||||
} else {
|
||||
ThreadUpdater.set('timer', '');
|
||||
ThreadUpdater.set('status', 'Offline', 'warning');
|
||||
return clearTimeout(ThreadUpdater.timeoutID);
|
||||
}
|
||||
if (Conf['Auto Update'] && !Conf['Ignore Offline Status']) {
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
return ThreadUpdater.setInterval();
|
||||
}
|
||||
},
|
||||
checkpost: function(e) {
|
||||
if (!ThreadUpdater.checkPostCount) {
|
||||
if (e && e.detail.threadID !== ThreadUpdater.thread.ID) {
|
||||
return;
|
||||
}
|
||||
ThreadUpdater.seconds = 0;
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
ThreadUpdater.set('timer', '...');
|
||||
if (e.detail.threadID !== ThreadUpdater.thread.ID) {
|
||||
return;
|
||||
}
|
||||
if (!(ThreadUpdater.thread.isDead || ThreadUpdater.foundPost || ThreadUpdater.checkPostCount >= 5)) {
|
||||
return setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * $.SECOND);
|
||||
}
|
||||
ThreadUpdater.setInterval();
|
||||
ThreadUpdater.postID = e.detail.postID;
|
||||
ThreadUpdater.checkPostCount = 0;
|
||||
delete ThreadUpdater.foundPost;
|
||||
return delete ThreadUpdater.postID;
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
return ThreadUpdater.setInterval();
|
||||
},
|
||||
visibility: function() {
|
||||
if (d.hidden) {
|
||||
@ -12178,9 +12112,6 @@
|
||||
return !d.hidden;
|
||||
};
|
||||
},
|
||||
autoUpdate: function() {
|
||||
return ThreadUpdater.count(ThreadUpdater.isUpdating = this.checked);
|
||||
},
|
||||
interval: function(e) {
|
||||
var val;
|
||||
val = parseInt(this.value, 10);
|
||||
@ -12197,16 +12128,15 @@
|
||||
req = ThreadUpdater.req;
|
||||
switch (req.status) {
|
||||
case 200:
|
||||
ThreadUpdater.parse(req.response.posts);
|
||||
ThreadUpdater.parse(req);
|
||||
if (ThreadUpdater.thread.isArchived) {
|
||||
ThreadUpdater.set('status', 'Archived', 'warning');
|
||||
ThreadUpdater.kill();
|
||||
return ThreadUpdater.kill();
|
||||
} else {
|
||||
ThreadUpdater.setInterval();
|
||||
return ThreadUpdater.setInterval();
|
||||
}
|
||||
break;
|
||||
case 404:
|
||||
$.ajax("//a.4cdn.org/" + ThreadUpdater.thread.board + "/catalog.json", {
|
||||
return $.ajax("//a.4cdn.org/" + ThreadUpdater.thread.board + "/catalog.json", {
|
||||
onloadend: function() {
|
||||
var confirmed, k, len1, len2, page, q, ref, ref1, thread;
|
||||
if (this.status === 200) {
|
||||
@ -12227,51 +12157,70 @@
|
||||
confirmed = false;
|
||||
}
|
||||
if (confirmed) {
|
||||
ThreadUpdater.set('status', '404', 'warning');
|
||||
return ThreadUpdater.kill();
|
||||
} else {
|
||||
return ThreadUpdater.error(req);
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
ThreadUpdater.error(req);
|
||||
}
|
||||
if (ThreadUpdater.postID) {
|
||||
return ThreadUpdater.cb.checkpost();
|
||||
return ThreadUpdater.error(req);
|
||||
}
|
||||
}
|
||||
},
|
||||
kill: function() {
|
||||
ThreadUpdater.set('timer', '');
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
ThreadUpdater.thread.kill();
|
||||
ThreadUpdater.setInterval();
|
||||
return $.event('ThreadUpdate', {
|
||||
404: true,
|
||||
threadID: ThreadUpdater.thread.fullID
|
||||
});
|
||||
},
|
||||
error: function(req) {
|
||||
var klass, ref, text;
|
||||
if (req.status === 304) {
|
||||
ThreadUpdater.set('status', '');
|
||||
}
|
||||
ThreadUpdater.setInterval();
|
||||
ref = req.status === 304 ? ['', ''] : [req.statusText + " (" + req.status + ")", 'warning'], text = ref[0], klass = ref[1];
|
||||
return ThreadUpdater.set('status', text, klass);
|
||||
if (!req.status) {
|
||||
return ThreadUpdater.set('status', 'Connection Failed', 'warning');
|
||||
} else if (req.status !== 304) {
|
||||
return ThreadUpdater.set('status', req.statusText + " (" + req.status + ")", 'warning');
|
||||
}
|
||||
},
|
||||
setInterval: function() {
|
||||
var cur, i, j, limit;
|
||||
i = ThreadUpdater.interval + 1;
|
||||
if (Conf['Optional Increase']) {
|
||||
cur = ThreadUpdater.outdateCount || 1;
|
||||
limit = d.hidden ? 7 : 10;
|
||||
j = cur <= limit ? cur : limit;
|
||||
cur = (Math.floor(i * 0.1) || 1) * j * j;
|
||||
ThreadUpdater.seconds = cur > i ? cur <= 300 ? cur : 300 : i;
|
||||
} else {
|
||||
ThreadUpdater.seconds = i;
|
||||
var cur, interval, j, limit;
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
if (ThreadUpdater.thread.isDead) {
|
||||
ThreadUpdater.set('status', (ThreadUpdater.thread.isArchived ? 'Archived' : '404'), 'warning');
|
||||
ThreadUpdater.set('timer', '');
|
||||
return;
|
||||
}
|
||||
ThreadUpdater.set('timer', ThreadUpdater.seconds);
|
||||
return ThreadUpdater.count(true);
|
||||
if (ThreadUpdater.postID && ThreadUpdater.checkPostCount < 5) {
|
||||
ThreadUpdater.set('timer', '...', 'loading');
|
||||
ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * $.SECOND);
|
||||
return;
|
||||
}
|
||||
if (!Conf['Auto Update']) {
|
||||
ThreadUpdater.set('timer', 'Update');
|
||||
return;
|
||||
}
|
||||
if (!navigator.onLine) {
|
||||
ThreadUpdater.set('status', 'Offline', 'warning');
|
||||
if (!Conf['Ignore Offline Status']) {
|
||||
ThreadUpdater.set('timer', '');
|
||||
return;
|
||||
}
|
||||
}
|
||||
interval = ThreadUpdater.interval;
|
||||
if (Conf['Optional Increase']) {
|
||||
limit = d.hidden ? 7 : 10;
|
||||
j = Math.min(ThreadUpdater.outdateCount, limit);
|
||||
cur = (Math.floor(interval * 0.1) || 1) * j * j;
|
||||
ThreadUpdater.seconds = $.minmax(cur, interval, 300);
|
||||
} else {
|
||||
ThreadUpdater.seconds = interval;
|
||||
}
|
||||
return ThreadUpdater.timeout();
|
||||
},
|
||||
intervalShortcut: function() {
|
||||
var settings;
|
||||
@ -12287,40 +12236,22 @@
|
||||
} else {
|
||||
el.textContent = text;
|
||||
}
|
||||
if (klass !== void 0) {
|
||||
return el.className = klass;
|
||||
}
|
||||
},
|
||||
count: function(start) {
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
if (start && ThreadUpdater.isUpdating && navigator.onLine) {
|
||||
return ThreadUpdater.timeout();
|
||||
}
|
||||
return el.className = klass != null ? klass : (text === '' ? 'empty' : '');
|
||||
},
|
||||
timeout: function() {
|
||||
var n;
|
||||
ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000);
|
||||
if (!(n = --ThreadUpdater.seconds)) {
|
||||
if (ThreadUpdater.seconds) {
|
||||
ThreadUpdater.set('timer', ThreadUpdater.seconds);
|
||||
ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000);
|
||||
} else {
|
||||
ThreadUpdater.outdateCount++;
|
||||
return ThreadUpdater.update();
|
||||
} else if (n <= -60) {
|
||||
ThreadUpdater.set('status', 'Retrying', '');
|
||||
return ThreadUpdater.update();
|
||||
} else if (n > 0) {
|
||||
return ThreadUpdater.set('timer', n);
|
||||
ThreadUpdater.update();
|
||||
}
|
||||
return ThreadUpdater.seconds--;
|
||||
},
|
||||
update: function() {
|
||||
var ref;
|
||||
if (!navigator.onLine) {
|
||||
return;
|
||||
}
|
||||
ThreadUpdater.count();
|
||||
if (Conf['Auto Update']) {
|
||||
ThreadUpdater.set('timer', '...');
|
||||
} else {
|
||||
ThreadUpdater.set('timer', 'Update');
|
||||
}
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
ThreadUpdater.set('timer', '...', 'loading');
|
||||
if ((ref = ThreadUpdater.req) != null) {
|
||||
ref.abort();
|
||||
}
|
||||
@ -12343,17 +12274,25 @@
|
||||
change = type === 'Sticky' ? status ? 'now a sticky' : 'not a sticky anymore' : status ? 'now closed' : 'not closed anymore';
|
||||
return new Notice('info', "The thread is " + change + ".", 30);
|
||||
},
|
||||
parse: function(postObjects) {
|
||||
var OP, count, files, index, ipCountEl, k, len1, len2, node, num, post, postObject, posts, q, root, scroll;
|
||||
parse: function(req) {
|
||||
var ID, OP, board, count, deletedFiles, deletedPosts, files, firstPost, index, ipCountEl, k, lastModified, len1, len2, len3, len4, node, num, post, postObject, postObjects, posts, q, ref, ref1, ref2, scroll, thread, u, w;
|
||||
lastModified = new Date(req.getResponseHeader('Last-Modified'));
|
||||
if (ThreadUpdater.lastModified && lastModified < ThreadUpdater.lastModified) {
|
||||
return;
|
||||
}
|
||||
ThreadUpdater.lastModified = lastModified;
|
||||
postObjects = req.response.posts;
|
||||
OP = postObjects[0];
|
||||
Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler;
|
||||
ThreadUpdater.thread.setStatus('Archived', !!+OP.archived);
|
||||
thread = ThreadUpdater.thread;
|
||||
board = thread.board;
|
||||
Build.spoilerRange[board] = OP.custom_spoiler;
|
||||
thread.setStatus('Archived', !!+OP.archived);
|
||||
ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky);
|
||||
ThreadUpdater.updateThreadStatus('Closed', !!OP.closed);
|
||||
ThreadUpdater.thread.postLimit = !!OP.bumplimit;
|
||||
ThreadUpdater.thread.fileLimit = !!OP.imagelimit;
|
||||
thread.postLimit = !!OP.bumplimit;
|
||||
thread.fileLimit = !!OP.imagelimit;
|
||||
if (OP.unique_ips != null) {
|
||||
ThreadUpdater.thread.ipCount = OP.unique_ips;
|
||||
thread.ipCount = OP.unique_ips;
|
||||
}
|
||||
posts = [];
|
||||
index = [];
|
||||
@ -12370,27 +12309,36 @@
|
||||
continue;
|
||||
}
|
||||
count++;
|
||||
node = Build.postFromObject(postObject, ThreadUpdater.thread.board.ID);
|
||||
posts.push(new Post(node, ThreadUpdater.thread, ThreadUpdater.thread.board));
|
||||
node = Build.postFromObject(postObject, board.ID);
|
||||
posts.push(new Post(node, thread, board));
|
||||
if (ThreadUpdater.postID === num) {
|
||||
delete ThreadUpdater.postID;
|
||||
}
|
||||
}
|
||||
ThreadUpdater.thread.posts.forEach(function(post) {
|
||||
var ID;
|
||||
ID = +post.ID;
|
||||
if (!(post.info.date > Date.now() - 60 * $.SECOND)) {
|
||||
if (indexOf.call(index, ID) < 0) {
|
||||
post.kill();
|
||||
} else if (post.isDead) {
|
||||
post.resurrect();
|
||||
} else if (post.file && !(post.file.isDead || indexOf.call(files, ID) >= 0)) {
|
||||
post.kill(true);
|
||||
}
|
||||
deletedPosts = [];
|
||||
ref = ThreadUpdater.postIDs;
|
||||
for (q = 0, len2 = ref.length; q < len2; q++) {
|
||||
ID = ref[q];
|
||||
if (!(indexOf.call(index, ID) < 0)) {
|
||||
continue;
|
||||
}
|
||||
if (ThreadUpdater.postID && ThreadUpdater.postID === ID) {
|
||||
return ThreadUpdater.foundPost = true;
|
||||
thread.posts[ID].kill();
|
||||
deletedPosts.push(board + "." + ID);
|
||||
}
|
||||
ThreadUpdater.postIDs = index;
|
||||
deletedFiles = [];
|
||||
ref1 = ThreadUpdater.fileIDs;
|
||||
for (u = 0, len3 = ref1.length; u < len3; u++) {
|
||||
ID = ref1[u];
|
||||
if (!(!(indexOf.call(files, ID) >= 0 || (ref2 = board + "." + ID, indexOf.call(deletedPosts, ref2) >= 0)))) {
|
||||
continue;
|
||||
}
|
||||
});
|
||||
thread.posts[ID].kill(true);
|
||||
deletedFiles.push(board + "." + ID);
|
||||
}
|
||||
ThreadUpdater.fileIDs = files;
|
||||
if (!count) {
|
||||
ThreadUpdater.set('status', '', '');
|
||||
ThreadUpdater.set('status', '');
|
||||
} else {
|
||||
ThreadUpdater.set('status', "+" + count, 'new');
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
@ -12405,10 +12353,11 @@
|
||||
ThreadUpdater.lastPost = posts[count - 1].ID;
|
||||
Main.callbackNodes(Post, posts);
|
||||
scroll = Conf['Auto Scroll'] && ThreadUpdater.scrollBG() && ThreadUpdater.root.getBoundingClientRect().bottom - doc.clientHeight < 25;
|
||||
for (q = 0, len2 = posts.length; q < len2; q++) {
|
||||
post = posts[q];
|
||||
root = post.nodes.root;
|
||||
firstPost = null;
|
||||
for (w = 0, len4 = posts.length; w < len4; w++) {
|
||||
post = posts[w];
|
||||
if (!QuoteThreading.insert(post)) {
|
||||
firstPost || (firstPost = post.nodes.root);
|
||||
$.add(ThreadUpdater.root, post.nodes.root);
|
||||
}
|
||||
}
|
||||
@ -12417,8 +12366,8 @@
|
||||
if (Conf['Bottom Scroll']) {
|
||||
window.scrollTo(0, d.body.clientHeight);
|
||||
} else {
|
||||
if (root) {
|
||||
Header.scrollTo(root);
|
||||
if (firstPost) {
|
||||
Header.scrollTo(firstPost);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12428,21 +12377,22 @@
|
||||
ipCountEl.previousSibling.textContent = ipCountEl.previousSibling.textContent.replace(/\b(?:is|are)\b/, OP.unique_ips === 1 ? 'is' : 'are');
|
||||
ipCountEl.nextSibling.textContent = ipCountEl.nextSibling.textContent.replace(/\bposters?\b/, OP.unique_ips === 1 ? 'poster' : 'posters');
|
||||
}
|
||||
ThreadUpdater.postIDs = index;
|
||||
return $.event('ThreadUpdate', {
|
||||
404: false,
|
||||
threadID: ThreadUpdater.thread.fullID,
|
||||
threadID: thread.fullID,
|
||||
newPosts: (function() {
|
||||
var len3, results, u;
|
||||
var len5, results, y;
|
||||
results = [];
|
||||
for (u = 0, len3 = posts.length; u < len3; u++) {
|
||||
post = posts[u];
|
||||
for (y = 0, len5 = posts.length; y < len5; y++) {
|
||||
post = posts[y];
|
||||
results.push(post.fullID);
|
||||
}
|
||||
return results;
|
||||
})(),
|
||||
deletedPosts: deletedPosts,
|
||||
deletedFiles: deletedFiles,
|
||||
postCount: OP.replies + 1,
|
||||
fileCount: OP.images + (!!ThreadUpdater.thread.OP.file && !ThreadUpdater.thread.OP.file.isDead),
|
||||
fileCount: OP.images + (!!thread.OP.file && !thread.OP.file.isDead),
|
||||
ipCount: OP.unique_ips
|
||||
});
|
||||
}
|
||||
@ -17769,8 +17719,8 @@
|
||||
".new {\n" +
|
||||
" color: limegreen;\n" +
|
||||
"}\n" +
|
||||
"#update-status.new {\n" +
|
||||
" margin-right: 5px;\n" +
|
||||
"#update-status:not(.empty) + #update-timer:not(.empty):not(.loading) {\n" +
|
||||
" margin-left: 5px;\n" +
|
||||
"}\n" +
|
||||
"#update-timer {\n" +
|
||||
" cursor: pointer;\n" +
|
||||
|
||||
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.10.3.9
|
||||
// @version 1.10.4.0
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -376,6 +376,7 @@
|
||||
'Bottom Scroll': [false, 'Always scroll to the bottom, not the first new post. Useful for event threads.'],
|
||||
'Scroll BG': [false, 'Auto-scroll background tabs.'],
|
||||
'Auto Update': [true, 'Automatically fetch new posts.'],
|
||||
'Ignore Offline Status': [false, 'Update even if your browser reports you are offline.'],
|
||||
'Optional Increase': [false, 'Increase the intervals between updates on threads without new posts.']
|
||||
},
|
||||
'Interval': 30
|
||||
@ -393,7 +394,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.10.3.9',
|
||||
VERSION: '1.10.4.0',
|
||||
NAMESPACE: '4chan X.',
|
||||
NAME: '4chan X',
|
||||
FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions',
|
||||
@ -1417,35 +1418,6 @@
|
||||
}
|
||||
};
|
||||
|
||||
Post.prototype.resurrect = function() {
|
||||
var clone, k, len1, len2, q, quotelink, ref, ref1, strong;
|
||||
delete this.isDead;
|
||||
$.rmClass(this.nodes.root, 'deleted-post');
|
||||
strong = $('strong.warning', this.nodes.info);
|
||||
if (this.file && this.file.isDead) {
|
||||
strong.textContent = '[File deleted]';
|
||||
} else {
|
||||
$.rm(strong);
|
||||
}
|
||||
if (this.isClone) {
|
||||
return;
|
||||
}
|
||||
ref = this.clones;
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
clone = ref[k];
|
||||
clone.resurrect();
|
||||
}
|
||||
ref1 = Get.allQuotelinksLinkingTo(this);
|
||||
for (q = 0, len2 = ref1.length; q < len2; q++) {
|
||||
quotelink = ref1[q];
|
||||
if (!($.hasClass(quotelink, 'deadlink'))) {
|
||||
continue;
|
||||
}
|
||||
quotelink.textContent = quotelink.textContent.replace('\u00A0(Dead)', '');
|
||||
$.rmClass(quotelink, 'deadlink');
|
||||
}
|
||||
};
|
||||
|
||||
Post.prototype.collect = function() {
|
||||
this.kill();
|
||||
g.posts.rm(this.fullID);
|
||||
@ -3564,9 +3536,6 @@
|
||||
},
|
||||
update: function(state) {
|
||||
var now, ref, ref1;
|
||||
if (!navigator.onLine) {
|
||||
return;
|
||||
}
|
||||
delete Index.pageNum;
|
||||
if ((ref = Index.req) != null) {
|
||||
ref.abort();
|
||||
@ -7590,7 +7559,6 @@
|
||||
postID: postID,
|
||||
val: true
|
||||
});
|
||||
ThreadUpdater.postID = postID;
|
||||
$.event('QRPostSuccessful', {
|
||||
boardID: g.BOARD.ID,
|
||||
threadID: threadID,
|
||||
@ -11807,59 +11775,30 @@
|
||||
});
|
||||
},
|
||||
node: function() {
|
||||
var x;
|
||||
MarkNewIPs.ipCount = this.ipCount;
|
||||
MarkNewIPs.postIDs = (function() {
|
||||
var k, len1, ref, results;
|
||||
ref = this.posts.keys;
|
||||
results = [];
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
x = ref[k];
|
||||
results.push(+x);
|
||||
}
|
||||
return results;
|
||||
}).call(this);
|
||||
return $.on(d, 'ThreadUpdate', MarkNewIPs.onUpdate);
|
||||
},
|
||||
onUpdate: function(e) {
|
||||
var added, fullID, i, ipCount, k, len1, len2, len3, len4, newPosts, obj, postIDs, q, ref, ref1, removed, u, w, x;
|
||||
ref = e.detail, ipCount = ref.ipCount, newPosts = ref.newPosts;
|
||||
postIDs = ThreadUpdater.postIDs;
|
||||
var deletedPosts, fullID, i, ipCount, k, len1, len2, newPosts, q, ref;
|
||||
ref = e.detail, ipCount = ref.ipCount, newPosts = ref.newPosts, deletedPosts = ref.deletedPosts;
|
||||
if (ipCount == null) {
|
||||
return;
|
||||
}
|
||||
if (newPosts.length) {
|
||||
obj = {};
|
||||
ref1 = MarkNewIPs.postIDs;
|
||||
for (k = 0, len1 = ref1.length; k < len1; k++) {
|
||||
x = ref1[k];
|
||||
obj[x] = true;
|
||||
}
|
||||
added = 0;
|
||||
for (q = 0, len2 = postIDs.length; q < len2; q++) {
|
||||
x = postIDs[q];
|
||||
if (!(x in obj)) {
|
||||
added++;
|
||||
switch (ipCount - MarkNewIPs.ipCount) {
|
||||
case newPosts.length:
|
||||
i = MarkNewIPs.ipCount;
|
||||
for (k = 0, len1 = newPosts.length; k < len1; k++) {
|
||||
fullID = newPosts[k];
|
||||
MarkNewIPs.markNew(g.posts[fullID], ++i);
|
||||
}
|
||||
break;
|
||||
case -deletedPosts.length:
|
||||
for (q = 0, len2 = newPosts.length; q < len2; q++) {
|
||||
fullID = newPosts[q];
|
||||
MarkNewIPs.markOld(g.posts[fullID]);
|
||||
}
|
||||
}
|
||||
removed = MarkNewIPs.postIDs.length + added - postIDs.length;
|
||||
switch (ipCount - MarkNewIPs.ipCount) {
|
||||
case added:
|
||||
i = MarkNewIPs.ipCount;
|
||||
for (u = 0, len3 = newPosts.length; u < len3; u++) {
|
||||
fullID = newPosts[u];
|
||||
MarkNewIPs.markNew(g.posts[fullID], ++i);
|
||||
}
|
||||
break;
|
||||
case -removed:
|
||||
for (w = 0, len4 = newPosts.length; w < len4; w++) {
|
||||
fullID = newPosts[w];
|
||||
MarkNewIPs.markOld(g.posts[fullID]);
|
||||
}
|
||||
}
|
||||
}
|
||||
MarkNewIPs.ipCount = ipCount;
|
||||
return MarkNewIPs.postIDs = postIDs;
|
||||
return MarkNewIPs.ipCount = ipCount;
|
||||
},
|
||||
markNew: function(post, ipCount) {
|
||||
var counter, suffix;
|
||||
@ -12039,7 +11978,7 @@
|
||||
id: 'updater'
|
||||
});
|
||||
$.extend(sc, {
|
||||
innerHTML: "<span id=\"update-status\"></span><span id=\"update-timer\" title=\"Update now\"></span>"
|
||||
innerHTML: "<span id=\"update-status\" class=\"empty\"></span><span id=\"update-timer\" class=\"empty\" title=\"Update now\"></span>"
|
||||
});
|
||||
$.ready(function() {
|
||||
return Header.addShortcut(sc);
|
||||
@ -12056,7 +11995,6 @@
|
||||
this.checkPostCount = 0;
|
||||
this.timer = $('#update-timer', sc);
|
||||
this.status = $('#update-status', sc);
|
||||
this.isUpdating = Conf['Auto Update'];
|
||||
$.on(this.timer, 'click', this.update);
|
||||
$.on(this.status, 'click', this.update);
|
||||
updateLink = $.el('span', {
|
||||
@ -12081,7 +12019,7 @@
|
||||
$.on(input, 'change', this.cb.scrollBG);
|
||||
this.cb.scrollBG();
|
||||
} else if (input.name === 'Auto Update') {
|
||||
$.on(input, 'change', this.cb.autoUpdate);
|
||||
$.on(input, 'change', this.setInterval);
|
||||
}
|
||||
subEntries.push({
|
||||
el: el
|
||||
@ -12111,17 +12049,21 @@
|
||||
ThreadUpdater.root = this.OP.nodes.root.parentNode;
|
||||
ThreadUpdater.lastPost = +this.posts.keys[this.posts.keys.length - 1];
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
ThreadUpdater.postIDs = [];
|
||||
ThreadUpdater.fileIDs = [];
|
||||
this.posts.forEach(function(post) {
|
||||
ThreadUpdater.postIDs.push(post.ID);
|
||||
if (post.file && !post.file.isDead) {
|
||||
return ThreadUpdater.fileIDs.push(post.ID);
|
||||
}
|
||||
});
|
||||
ThreadUpdater.cb.interval.call($.el('input', {
|
||||
value: Conf['Interval']
|
||||
}));
|
||||
$.on(window, 'online offline', ThreadUpdater.cb.online);
|
||||
$.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost);
|
||||
$.on(d, 'visibilitychange', ThreadUpdater.cb.visibility);
|
||||
if (ThreadUpdater.thread.isArchived) {
|
||||
return ThreadUpdater.set('status', 'Archived', 'warning');
|
||||
} else {
|
||||
return ThreadUpdater.cb.online();
|
||||
}
|
||||
return ThreadUpdater.setInterval();
|
||||
},
|
||||
|
||||
/*
|
||||
@ -12134,32 +12076,24 @@
|
||||
if (ThreadUpdater.thread.isDead) {
|
||||
return;
|
||||
}
|
||||
if (ThreadUpdater.online = navigator.onLine) {
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
ThreadUpdater.setInterval();
|
||||
return ThreadUpdater.set('status', '', '');
|
||||
if (navigator.onLine) {
|
||||
ThreadUpdater.set('status', '');
|
||||
} else {
|
||||
ThreadUpdater.set('timer', '');
|
||||
ThreadUpdater.set('status', 'Offline', 'warning');
|
||||
return clearTimeout(ThreadUpdater.timeoutID);
|
||||
}
|
||||
if (Conf['Auto Update'] && !Conf['Ignore Offline Status']) {
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
return ThreadUpdater.setInterval();
|
||||
}
|
||||
},
|
||||
checkpost: function(e) {
|
||||
if (!ThreadUpdater.checkPostCount) {
|
||||
if (e && e.detail.threadID !== ThreadUpdater.thread.ID) {
|
||||
return;
|
||||
}
|
||||
ThreadUpdater.seconds = 0;
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
ThreadUpdater.set('timer', '...');
|
||||
if (e.detail.threadID !== ThreadUpdater.thread.ID) {
|
||||
return;
|
||||
}
|
||||
if (!(ThreadUpdater.thread.isDead || ThreadUpdater.foundPost || ThreadUpdater.checkPostCount >= 5)) {
|
||||
return setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * $.SECOND);
|
||||
}
|
||||
ThreadUpdater.setInterval();
|
||||
ThreadUpdater.postID = e.detail.postID;
|
||||
ThreadUpdater.checkPostCount = 0;
|
||||
delete ThreadUpdater.foundPost;
|
||||
return delete ThreadUpdater.postID;
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
return ThreadUpdater.setInterval();
|
||||
},
|
||||
visibility: function() {
|
||||
if (d.hidden) {
|
||||
@ -12177,9 +12111,6 @@
|
||||
return !d.hidden;
|
||||
};
|
||||
},
|
||||
autoUpdate: function() {
|
||||
return ThreadUpdater.count(ThreadUpdater.isUpdating = this.checked);
|
||||
},
|
||||
interval: function(e) {
|
||||
var val;
|
||||
val = parseInt(this.value, 10);
|
||||
@ -12196,16 +12127,15 @@
|
||||
req = ThreadUpdater.req;
|
||||
switch (req.status) {
|
||||
case 200:
|
||||
ThreadUpdater.parse(req.response.posts);
|
||||
ThreadUpdater.parse(req);
|
||||
if (ThreadUpdater.thread.isArchived) {
|
||||
ThreadUpdater.set('status', 'Archived', 'warning');
|
||||
ThreadUpdater.kill();
|
||||
return ThreadUpdater.kill();
|
||||
} else {
|
||||
ThreadUpdater.setInterval();
|
||||
return ThreadUpdater.setInterval();
|
||||
}
|
||||
break;
|
||||
case 404:
|
||||
$.ajax("//a.4cdn.org/" + ThreadUpdater.thread.board + "/catalog.json", {
|
||||
return $.ajax("//a.4cdn.org/" + ThreadUpdater.thread.board + "/catalog.json", {
|
||||
onloadend: function() {
|
||||
var confirmed, k, len1, len2, page, q, ref, ref1, thread;
|
||||
if (this.status === 200) {
|
||||
@ -12226,51 +12156,70 @@
|
||||
confirmed = false;
|
||||
}
|
||||
if (confirmed) {
|
||||
ThreadUpdater.set('status', '404', 'warning');
|
||||
return ThreadUpdater.kill();
|
||||
} else {
|
||||
return ThreadUpdater.error(req);
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
ThreadUpdater.error(req);
|
||||
}
|
||||
if (ThreadUpdater.postID) {
|
||||
return ThreadUpdater.cb.checkpost();
|
||||
return ThreadUpdater.error(req);
|
||||
}
|
||||
}
|
||||
},
|
||||
kill: function() {
|
||||
ThreadUpdater.set('timer', '');
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
ThreadUpdater.thread.kill();
|
||||
ThreadUpdater.setInterval();
|
||||
return $.event('ThreadUpdate', {
|
||||
404: true,
|
||||
threadID: ThreadUpdater.thread.fullID
|
||||
});
|
||||
},
|
||||
error: function(req) {
|
||||
var klass, ref, text;
|
||||
if (req.status === 304) {
|
||||
ThreadUpdater.set('status', '');
|
||||
}
|
||||
ThreadUpdater.setInterval();
|
||||
ref = req.status === 304 ? ['', ''] : [req.statusText + " (" + req.status + ")", 'warning'], text = ref[0], klass = ref[1];
|
||||
return ThreadUpdater.set('status', text, klass);
|
||||
if (!req.status) {
|
||||
return ThreadUpdater.set('status', 'Connection Failed', 'warning');
|
||||
} else if (req.status !== 304) {
|
||||
return ThreadUpdater.set('status', req.statusText + " (" + req.status + ")", 'warning');
|
||||
}
|
||||
},
|
||||
setInterval: function() {
|
||||
var cur, i, j, limit;
|
||||
i = ThreadUpdater.interval + 1;
|
||||
if (Conf['Optional Increase']) {
|
||||
cur = ThreadUpdater.outdateCount || 1;
|
||||
limit = d.hidden ? 7 : 10;
|
||||
j = cur <= limit ? cur : limit;
|
||||
cur = (Math.floor(i * 0.1) || 1) * j * j;
|
||||
ThreadUpdater.seconds = cur > i ? cur <= 300 ? cur : 300 : i;
|
||||
} else {
|
||||
ThreadUpdater.seconds = i;
|
||||
var cur, interval, j, limit;
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
if (ThreadUpdater.thread.isDead) {
|
||||
ThreadUpdater.set('status', (ThreadUpdater.thread.isArchived ? 'Archived' : '404'), 'warning');
|
||||
ThreadUpdater.set('timer', '');
|
||||
return;
|
||||
}
|
||||
ThreadUpdater.set('timer', ThreadUpdater.seconds);
|
||||
return ThreadUpdater.count(true);
|
||||
if (ThreadUpdater.postID && ThreadUpdater.checkPostCount < 5) {
|
||||
ThreadUpdater.set('timer', '...', 'loading');
|
||||
ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * $.SECOND);
|
||||
return;
|
||||
}
|
||||
if (!Conf['Auto Update']) {
|
||||
ThreadUpdater.set('timer', 'Update');
|
||||
return;
|
||||
}
|
||||
if (!navigator.onLine) {
|
||||
ThreadUpdater.set('status', 'Offline', 'warning');
|
||||
if (!Conf['Ignore Offline Status']) {
|
||||
ThreadUpdater.set('timer', '');
|
||||
return;
|
||||
}
|
||||
}
|
||||
interval = ThreadUpdater.interval;
|
||||
if (Conf['Optional Increase']) {
|
||||
limit = d.hidden ? 7 : 10;
|
||||
j = Math.min(ThreadUpdater.outdateCount, limit);
|
||||
cur = (Math.floor(interval * 0.1) || 1) * j * j;
|
||||
ThreadUpdater.seconds = $.minmax(cur, interval, 300);
|
||||
} else {
|
||||
ThreadUpdater.seconds = interval;
|
||||
}
|
||||
return ThreadUpdater.timeout();
|
||||
},
|
||||
intervalShortcut: function() {
|
||||
var settings;
|
||||
@ -12286,40 +12235,22 @@
|
||||
} else {
|
||||
el.textContent = text;
|
||||
}
|
||||
if (klass !== void 0) {
|
||||
return el.className = klass;
|
||||
}
|
||||
},
|
||||
count: function(start) {
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
if (start && ThreadUpdater.isUpdating && navigator.onLine) {
|
||||
return ThreadUpdater.timeout();
|
||||
}
|
||||
return el.className = klass != null ? klass : (text === '' ? 'empty' : '');
|
||||
},
|
||||
timeout: function() {
|
||||
var n;
|
||||
ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000);
|
||||
if (!(n = --ThreadUpdater.seconds)) {
|
||||
if (ThreadUpdater.seconds) {
|
||||
ThreadUpdater.set('timer', ThreadUpdater.seconds);
|
||||
ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000);
|
||||
} else {
|
||||
ThreadUpdater.outdateCount++;
|
||||
return ThreadUpdater.update();
|
||||
} else if (n <= -60) {
|
||||
ThreadUpdater.set('status', 'Retrying', '');
|
||||
return ThreadUpdater.update();
|
||||
} else if (n > 0) {
|
||||
return ThreadUpdater.set('timer', n);
|
||||
ThreadUpdater.update();
|
||||
}
|
||||
return ThreadUpdater.seconds--;
|
||||
},
|
||||
update: function() {
|
||||
var ref;
|
||||
if (!navigator.onLine) {
|
||||
return;
|
||||
}
|
||||
ThreadUpdater.count();
|
||||
if (Conf['Auto Update']) {
|
||||
ThreadUpdater.set('timer', '...');
|
||||
} else {
|
||||
ThreadUpdater.set('timer', 'Update');
|
||||
}
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
ThreadUpdater.set('timer', '...', 'loading');
|
||||
if ((ref = ThreadUpdater.req) != null) {
|
||||
ref.abort();
|
||||
}
|
||||
@ -12342,17 +12273,25 @@
|
||||
change = type === 'Sticky' ? status ? 'now a sticky' : 'not a sticky anymore' : status ? 'now closed' : 'not closed anymore';
|
||||
return new Notice('info', "The thread is " + change + ".", 30);
|
||||
},
|
||||
parse: function(postObjects) {
|
||||
var OP, count, files, index, ipCountEl, k, len1, len2, node, num, post, postObject, posts, q, root, scroll;
|
||||
parse: function(req) {
|
||||
var ID, OP, board, count, deletedFiles, deletedPosts, files, firstPost, index, ipCountEl, k, lastModified, len1, len2, len3, len4, node, num, post, postObject, postObjects, posts, q, ref, ref1, ref2, scroll, thread, u, w;
|
||||
lastModified = new Date(req.getResponseHeader('Last-Modified'));
|
||||
if (ThreadUpdater.lastModified && lastModified < ThreadUpdater.lastModified) {
|
||||
return;
|
||||
}
|
||||
ThreadUpdater.lastModified = lastModified;
|
||||
postObjects = req.response.posts;
|
||||
OP = postObjects[0];
|
||||
Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler;
|
||||
ThreadUpdater.thread.setStatus('Archived', !!+OP.archived);
|
||||
thread = ThreadUpdater.thread;
|
||||
board = thread.board;
|
||||
Build.spoilerRange[board] = OP.custom_spoiler;
|
||||
thread.setStatus('Archived', !!+OP.archived);
|
||||
ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky);
|
||||
ThreadUpdater.updateThreadStatus('Closed', !!OP.closed);
|
||||
ThreadUpdater.thread.postLimit = !!OP.bumplimit;
|
||||
ThreadUpdater.thread.fileLimit = !!OP.imagelimit;
|
||||
thread.postLimit = !!OP.bumplimit;
|
||||
thread.fileLimit = !!OP.imagelimit;
|
||||
if (OP.unique_ips != null) {
|
||||
ThreadUpdater.thread.ipCount = OP.unique_ips;
|
||||
thread.ipCount = OP.unique_ips;
|
||||
}
|
||||
posts = [];
|
||||
index = [];
|
||||
@ -12369,27 +12308,36 @@
|
||||
continue;
|
||||
}
|
||||
count++;
|
||||
node = Build.postFromObject(postObject, ThreadUpdater.thread.board.ID);
|
||||
posts.push(new Post(node, ThreadUpdater.thread, ThreadUpdater.thread.board));
|
||||
node = Build.postFromObject(postObject, board.ID);
|
||||
posts.push(new Post(node, thread, board));
|
||||
if (ThreadUpdater.postID === num) {
|
||||
delete ThreadUpdater.postID;
|
||||
}
|
||||
}
|
||||
ThreadUpdater.thread.posts.forEach(function(post) {
|
||||
var ID;
|
||||
ID = +post.ID;
|
||||
if (!(post.info.date > Date.now() - 60 * $.SECOND)) {
|
||||
if (indexOf.call(index, ID) < 0) {
|
||||
post.kill();
|
||||
} else if (post.isDead) {
|
||||
post.resurrect();
|
||||
} else if (post.file && !(post.file.isDead || indexOf.call(files, ID) >= 0)) {
|
||||
post.kill(true);
|
||||
}
|
||||
deletedPosts = [];
|
||||
ref = ThreadUpdater.postIDs;
|
||||
for (q = 0, len2 = ref.length; q < len2; q++) {
|
||||
ID = ref[q];
|
||||
if (!(indexOf.call(index, ID) < 0)) {
|
||||
continue;
|
||||
}
|
||||
if (ThreadUpdater.postID && ThreadUpdater.postID === ID) {
|
||||
return ThreadUpdater.foundPost = true;
|
||||
thread.posts[ID].kill();
|
||||
deletedPosts.push(board + "." + ID);
|
||||
}
|
||||
ThreadUpdater.postIDs = index;
|
||||
deletedFiles = [];
|
||||
ref1 = ThreadUpdater.fileIDs;
|
||||
for (u = 0, len3 = ref1.length; u < len3; u++) {
|
||||
ID = ref1[u];
|
||||
if (!(!(indexOf.call(files, ID) >= 0 || (ref2 = board + "." + ID, indexOf.call(deletedPosts, ref2) >= 0)))) {
|
||||
continue;
|
||||
}
|
||||
});
|
||||
thread.posts[ID].kill(true);
|
||||
deletedFiles.push(board + "." + ID);
|
||||
}
|
||||
ThreadUpdater.fileIDs = files;
|
||||
if (!count) {
|
||||
ThreadUpdater.set('status', '', '');
|
||||
ThreadUpdater.set('status', '');
|
||||
} else {
|
||||
ThreadUpdater.set('status', "+" + count, 'new');
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
@ -12404,10 +12352,11 @@
|
||||
ThreadUpdater.lastPost = posts[count - 1].ID;
|
||||
Main.callbackNodes(Post, posts);
|
||||
scroll = Conf['Auto Scroll'] && ThreadUpdater.scrollBG() && ThreadUpdater.root.getBoundingClientRect().bottom - doc.clientHeight < 25;
|
||||
for (q = 0, len2 = posts.length; q < len2; q++) {
|
||||
post = posts[q];
|
||||
root = post.nodes.root;
|
||||
firstPost = null;
|
||||
for (w = 0, len4 = posts.length; w < len4; w++) {
|
||||
post = posts[w];
|
||||
if (!QuoteThreading.insert(post)) {
|
||||
firstPost || (firstPost = post.nodes.root);
|
||||
$.add(ThreadUpdater.root, post.nodes.root);
|
||||
}
|
||||
}
|
||||
@ -12416,8 +12365,8 @@
|
||||
if (Conf['Bottom Scroll']) {
|
||||
window.scrollTo(0, d.body.clientHeight);
|
||||
} else {
|
||||
if (root) {
|
||||
Header.scrollTo(root);
|
||||
if (firstPost) {
|
||||
Header.scrollTo(firstPost);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12427,21 +12376,22 @@
|
||||
ipCountEl.previousSibling.textContent = ipCountEl.previousSibling.textContent.replace(/\b(?:is|are)\b/, OP.unique_ips === 1 ? 'is' : 'are');
|
||||
ipCountEl.nextSibling.textContent = ipCountEl.nextSibling.textContent.replace(/\bposters?\b/, OP.unique_ips === 1 ? 'poster' : 'posters');
|
||||
}
|
||||
ThreadUpdater.postIDs = index;
|
||||
return $.event('ThreadUpdate', {
|
||||
404: false,
|
||||
threadID: ThreadUpdater.thread.fullID,
|
||||
threadID: thread.fullID,
|
||||
newPosts: (function() {
|
||||
var len3, results, u;
|
||||
var len5, results, y;
|
||||
results = [];
|
||||
for (u = 0, len3 = posts.length; u < len3; u++) {
|
||||
post = posts[u];
|
||||
for (y = 0, len5 = posts.length; y < len5; y++) {
|
||||
post = posts[y];
|
||||
results.push(post.fullID);
|
||||
}
|
||||
return results;
|
||||
})(),
|
||||
deletedPosts: deletedPosts,
|
||||
deletedFiles: deletedFiles,
|
||||
postCount: OP.replies + 1,
|
||||
fileCount: OP.images + (!!ThreadUpdater.thread.OP.file && !ThreadUpdater.thread.OP.file.isDead),
|
||||
fileCount: OP.images + (!!thread.OP.file && !thread.OP.file.isDead),
|
||||
ipCount: OP.unique_ips
|
||||
});
|
||||
}
|
||||
@ -17768,8 +17718,8 @@
|
||||
".new {\n" +
|
||||
" color: limegreen;\n" +
|
||||
"}\n" +
|
||||
"#update-status.new {\n" +
|
||||
" margin-right: 5px;\n" +
|
||||
"#update-status:not(.empty) + #update-timer:not(.empty):not(.loading) {\n" +
|
||||
" margin-left: 5px;\n" +
|
||||
"}\n" +
|
||||
"#update-timer {\n" +
|
||||
" cursor: pointer;\n" +
|
||||
|
||||
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.10.3.9
|
||||
// @version 1.10.4.0
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.10.3.9
|
||||
// @version 1.10.4.0
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -377,6 +377,7 @@
|
||||
'Bottom Scroll': [false, 'Always scroll to the bottom, not the first new post. Useful for event threads.'],
|
||||
'Scroll BG': [false, 'Auto-scroll background tabs.'],
|
||||
'Auto Update': [true, 'Automatically fetch new posts.'],
|
||||
'Ignore Offline Status': [false, 'Update even if your browser reports you are offline.'],
|
||||
'Optional Increase': [false, 'Increase the intervals between updates on threads without new posts.']
|
||||
},
|
||||
'Interval': 30
|
||||
@ -394,7 +395,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.10.3.9',
|
||||
VERSION: '1.10.4.0',
|
||||
NAMESPACE: '4chan X.',
|
||||
NAME: '4chan X',
|
||||
FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions',
|
||||
@ -1418,35 +1419,6 @@
|
||||
}
|
||||
};
|
||||
|
||||
Post.prototype.resurrect = function() {
|
||||
var clone, k, len1, len2, q, quotelink, ref, ref1, strong;
|
||||
delete this.isDead;
|
||||
$.rmClass(this.nodes.root, 'deleted-post');
|
||||
strong = $('strong.warning', this.nodes.info);
|
||||
if (this.file && this.file.isDead) {
|
||||
strong.textContent = '[File deleted]';
|
||||
} else {
|
||||
$.rm(strong);
|
||||
}
|
||||
if (this.isClone) {
|
||||
return;
|
||||
}
|
||||
ref = this.clones;
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
clone = ref[k];
|
||||
clone.resurrect();
|
||||
}
|
||||
ref1 = Get.allQuotelinksLinkingTo(this);
|
||||
for (q = 0, len2 = ref1.length; q < len2; q++) {
|
||||
quotelink = ref1[q];
|
||||
if (!($.hasClass(quotelink, 'deadlink'))) {
|
||||
continue;
|
||||
}
|
||||
quotelink.textContent = quotelink.textContent.replace('\u00A0(Dead)', '');
|
||||
$.rmClass(quotelink, 'deadlink');
|
||||
}
|
||||
};
|
||||
|
||||
Post.prototype.collect = function() {
|
||||
this.kill();
|
||||
g.posts.rm(this.fullID);
|
||||
@ -3565,9 +3537,6 @@
|
||||
},
|
||||
update: function(state) {
|
||||
var now, ref, ref1;
|
||||
if (!navigator.onLine) {
|
||||
return;
|
||||
}
|
||||
delete Index.pageNum;
|
||||
if ((ref = Index.req) != null) {
|
||||
ref.abort();
|
||||
@ -7591,7 +7560,6 @@
|
||||
postID: postID,
|
||||
val: true
|
||||
});
|
||||
ThreadUpdater.postID = postID;
|
||||
$.event('QRPostSuccessful', {
|
||||
boardID: g.BOARD.ID,
|
||||
threadID: threadID,
|
||||
@ -11808,59 +11776,30 @@
|
||||
});
|
||||
},
|
||||
node: function() {
|
||||
var x;
|
||||
MarkNewIPs.ipCount = this.ipCount;
|
||||
MarkNewIPs.postIDs = (function() {
|
||||
var k, len1, ref, results;
|
||||
ref = this.posts.keys;
|
||||
results = [];
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
x = ref[k];
|
||||
results.push(+x);
|
||||
}
|
||||
return results;
|
||||
}).call(this);
|
||||
return $.on(d, 'ThreadUpdate', MarkNewIPs.onUpdate);
|
||||
},
|
||||
onUpdate: function(e) {
|
||||
var added, fullID, i, ipCount, k, len1, len2, len3, len4, newPosts, obj, postIDs, q, ref, ref1, removed, u, w, x;
|
||||
ref = e.detail, ipCount = ref.ipCount, newPosts = ref.newPosts;
|
||||
postIDs = ThreadUpdater.postIDs;
|
||||
var deletedPosts, fullID, i, ipCount, k, len1, len2, newPosts, q, ref;
|
||||
ref = e.detail, ipCount = ref.ipCount, newPosts = ref.newPosts, deletedPosts = ref.deletedPosts;
|
||||
if (ipCount == null) {
|
||||
return;
|
||||
}
|
||||
if (newPosts.length) {
|
||||
obj = {};
|
||||
ref1 = MarkNewIPs.postIDs;
|
||||
for (k = 0, len1 = ref1.length; k < len1; k++) {
|
||||
x = ref1[k];
|
||||
obj[x] = true;
|
||||
}
|
||||
added = 0;
|
||||
for (q = 0, len2 = postIDs.length; q < len2; q++) {
|
||||
x = postIDs[q];
|
||||
if (!(x in obj)) {
|
||||
added++;
|
||||
switch (ipCount - MarkNewIPs.ipCount) {
|
||||
case newPosts.length:
|
||||
i = MarkNewIPs.ipCount;
|
||||
for (k = 0, len1 = newPosts.length; k < len1; k++) {
|
||||
fullID = newPosts[k];
|
||||
MarkNewIPs.markNew(g.posts[fullID], ++i);
|
||||
}
|
||||
break;
|
||||
case -deletedPosts.length:
|
||||
for (q = 0, len2 = newPosts.length; q < len2; q++) {
|
||||
fullID = newPosts[q];
|
||||
MarkNewIPs.markOld(g.posts[fullID]);
|
||||
}
|
||||
}
|
||||
removed = MarkNewIPs.postIDs.length + added - postIDs.length;
|
||||
switch (ipCount - MarkNewIPs.ipCount) {
|
||||
case added:
|
||||
i = MarkNewIPs.ipCount;
|
||||
for (u = 0, len3 = newPosts.length; u < len3; u++) {
|
||||
fullID = newPosts[u];
|
||||
MarkNewIPs.markNew(g.posts[fullID], ++i);
|
||||
}
|
||||
break;
|
||||
case -removed:
|
||||
for (w = 0, len4 = newPosts.length; w < len4; w++) {
|
||||
fullID = newPosts[w];
|
||||
MarkNewIPs.markOld(g.posts[fullID]);
|
||||
}
|
||||
}
|
||||
}
|
||||
MarkNewIPs.ipCount = ipCount;
|
||||
return MarkNewIPs.postIDs = postIDs;
|
||||
return MarkNewIPs.ipCount = ipCount;
|
||||
},
|
||||
markNew: function(post, ipCount) {
|
||||
var counter, suffix;
|
||||
@ -12040,7 +11979,7 @@
|
||||
id: 'updater'
|
||||
});
|
||||
$.extend(sc, {
|
||||
innerHTML: "<span id=\"update-status\"></span><span id=\"update-timer\" title=\"Update now\"></span>"
|
||||
innerHTML: "<span id=\"update-status\" class=\"empty\"></span><span id=\"update-timer\" class=\"empty\" title=\"Update now\"></span>"
|
||||
});
|
||||
$.ready(function() {
|
||||
return Header.addShortcut(sc);
|
||||
@ -12057,7 +11996,6 @@
|
||||
this.checkPostCount = 0;
|
||||
this.timer = $('#update-timer', sc);
|
||||
this.status = $('#update-status', sc);
|
||||
this.isUpdating = Conf['Auto Update'];
|
||||
$.on(this.timer, 'click', this.update);
|
||||
$.on(this.status, 'click', this.update);
|
||||
updateLink = $.el('span', {
|
||||
@ -12082,7 +12020,7 @@
|
||||
$.on(input, 'change', this.cb.scrollBG);
|
||||
this.cb.scrollBG();
|
||||
} else if (input.name === 'Auto Update') {
|
||||
$.on(input, 'change', this.cb.autoUpdate);
|
||||
$.on(input, 'change', this.setInterval);
|
||||
}
|
||||
subEntries.push({
|
||||
el: el
|
||||
@ -12112,17 +12050,21 @@
|
||||
ThreadUpdater.root = this.OP.nodes.root.parentNode;
|
||||
ThreadUpdater.lastPost = +this.posts.keys[this.posts.keys.length - 1];
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
ThreadUpdater.postIDs = [];
|
||||
ThreadUpdater.fileIDs = [];
|
||||
this.posts.forEach(function(post) {
|
||||
ThreadUpdater.postIDs.push(post.ID);
|
||||
if (post.file && !post.file.isDead) {
|
||||
return ThreadUpdater.fileIDs.push(post.ID);
|
||||
}
|
||||
});
|
||||
ThreadUpdater.cb.interval.call($.el('input', {
|
||||
value: Conf['Interval']
|
||||
}));
|
||||
$.on(window, 'online offline', ThreadUpdater.cb.online);
|
||||
$.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost);
|
||||
$.on(d, 'visibilitychange', ThreadUpdater.cb.visibility);
|
||||
if (ThreadUpdater.thread.isArchived) {
|
||||
return ThreadUpdater.set('status', 'Archived', 'warning');
|
||||
} else {
|
||||
return ThreadUpdater.cb.online();
|
||||
}
|
||||
return ThreadUpdater.setInterval();
|
||||
},
|
||||
|
||||
/*
|
||||
@ -12135,32 +12077,24 @@
|
||||
if (ThreadUpdater.thread.isDead) {
|
||||
return;
|
||||
}
|
||||
if (ThreadUpdater.online = navigator.onLine) {
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
ThreadUpdater.setInterval();
|
||||
return ThreadUpdater.set('status', '', '');
|
||||
if (navigator.onLine) {
|
||||
ThreadUpdater.set('status', '');
|
||||
} else {
|
||||
ThreadUpdater.set('timer', '');
|
||||
ThreadUpdater.set('status', 'Offline', 'warning');
|
||||
return clearTimeout(ThreadUpdater.timeoutID);
|
||||
}
|
||||
if (Conf['Auto Update'] && !Conf['Ignore Offline Status']) {
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
return ThreadUpdater.setInterval();
|
||||
}
|
||||
},
|
||||
checkpost: function(e) {
|
||||
if (!ThreadUpdater.checkPostCount) {
|
||||
if (e && e.detail.threadID !== ThreadUpdater.thread.ID) {
|
||||
return;
|
||||
}
|
||||
ThreadUpdater.seconds = 0;
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
ThreadUpdater.set('timer', '...');
|
||||
if (e.detail.threadID !== ThreadUpdater.thread.ID) {
|
||||
return;
|
||||
}
|
||||
if (!(ThreadUpdater.thread.isDead || ThreadUpdater.foundPost || ThreadUpdater.checkPostCount >= 5)) {
|
||||
return setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * $.SECOND);
|
||||
}
|
||||
ThreadUpdater.setInterval();
|
||||
ThreadUpdater.postID = e.detail.postID;
|
||||
ThreadUpdater.checkPostCount = 0;
|
||||
delete ThreadUpdater.foundPost;
|
||||
return delete ThreadUpdater.postID;
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
return ThreadUpdater.setInterval();
|
||||
},
|
||||
visibility: function() {
|
||||
if (d.hidden) {
|
||||
@ -12178,9 +12112,6 @@
|
||||
return !d.hidden;
|
||||
};
|
||||
},
|
||||
autoUpdate: function() {
|
||||
return ThreadUpdater.count(ThreadUpdater.isUpdating = this.checked);
|
||||
},
|
||||
interval: function(e) {
|
||||
var val;
|
||||
val = parseInt(this.value, 10);
|
||||
@ -12197,16 +12128,15 @@
|
||||
req = ThreadUpdater.req;
|
||||
switch (req.status) {
|
||||
case 200:
|
||||
ThreadUpdater.parse(req.response.posts);
|
||||
ThreadUpdater.parse(req);
|
||||
if (ThreadUpdater.thread.isArchived) {
|
||||
ThreadUpdater.set('status', 'Archived', 'warning');
|
||||
ThreadUpdater.kill();
|
||||
return ThreadUpdater.kill();
|
||||
} else {
|
||||
ThreadUpdater.setInterval();
|
||||
return ThreadUpdater.setInterval();
|
||||
}
|
||||
break;
|
||||
case 404:
|
||||
$.ajax("//a.4cdn.org/" + ThreadUpdater.thread.board + "/catalog.json", {
|
||||
return $.ajax("//a.4cdn.org/" + ThreadUpdater.thread.board + "/catalog.json", {
|
||||
onloadend: function() {
|
||||
var confirmed, k, len1, len2, page, q, ref, ref1, thread;
|
||||
if (this.status === 200) {
|
||||
@ -12227,51 +12157,70 @@
|
||||
confirmed = false;
|
||||
}
|
||||
if (confirmed) {
|
||||
ThreadUpdater.set('status', '404', 'warning');
|
||||
return ThreadUpdater.kill();
|
||||
} else {
|
||||
return ThreadUpdater.error(req);
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
ThreadUpdater.error(req);
|
||||
}
|
||||
if (ThreadUpdater.postID) {
|
||||
return ThreadUpdater.cb.checkpost();
|
||||
return ThreadUpdater.error(req);
|
||||
}
|
||||
}
|
||||
},
|
||||
kill: function() {
|
||||
ThreadUpdater.set('timer', '');
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
ThreadUpdater.thread.kill();
|
||||
ThreadUpdater.setInterval();
|
||||
return $.event('ThreadUpdate', {
|
||||
404: true,
|
||||
threadID: ThreadUpdater.thread.fullID
|
||||
});
|
||||
},
|
||||
error: function(req) {
|
||||
var klass, ref, text;
|
||||
if (req.status === 304) {
|
||||
ThreadUpdater.set('status', '');
|
||||
}
|
||||
ThreadUpdater.setInterval();
|
||||
ref = req.status === 304 ? ['', ''] : [req.statusText + " (" + req.status + ")", 'warning'], text = ref[0], klass = ref[1];
|
||||
return ThreadUpdater.set('status', text, klass);
|
||||
if (!req.status) {
|
||||
return ThreadUpdater.set('status', 'Connection Failed', 'warning');
|
||||
} else if (req.status !== 304) {
|
||||
return ThreadUpdater.set('status', req.statusText + " (" + req.status + ")", 'warning');
|
||||
}
|
||||
},
|
||||
setInterval: function() {
|
||||
var cur, i, j, limit;
|
||||
i = ThreadUpdater.interval + 1;
|
||||
if (Conf['Optional Increase']) {
|
||||
cur = ThreadUpdater.outdateCount || 1;
|
||||
limit = d.hidden ? 7 : 10;
|
||||
j = cur <= limit ? cur : limit;
|
||||
cur = (Math.floor(i * 0.1) || 1) * j * j;
|
||||
ThreadUpdater.seconds = cur > i ? cur <= 300 ? cur : 300 : i;
|
||||
} else {
|
||||
ThreadUpdater.seconds = i;
|
||||
var cur, interval, j, limit;
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
if (ThreadUpdater.thread.isDead) {
|
||||
ThreadUpdater.set('status', (ThreadUpdater.thread.isArchived ? 'Archived' : '404'), 'warning');
|
||||
ThreadUpdater.set('timer', '');
|
||||
return;
|
||||
}
|
||||
ThreadUpdater.set('timer', ThreadUpdater.seconds);
|
||||
return ThreadUpdater.count(true);
|
||||
if (ThreadUpdater.postID && ThreadUpdater.checkPostCount < 5) {
|
||||
ThreadUpdater.set('timer', '...', 'loading');
|
||||
ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * $.SECOND);
|
||||
return;
|
||||
}
|
||||
if (!Conf['Auto Update']) {
|
||||
ThreadUpdater.set('timer', 'Update');
|
||||
return;
|
||||
}
|
||||
if (!navigator.onLine) {
|
||||
ThreadUpdater.set('status', 'Offline', 'warning');
|
||||
if (!Conf['Ignore Offline Status']) {
|
||||
ThreadUpdater.set('timer', '');
|
||||
return;
|
||||
}
|
||||
}
|
||||
interval = ThreadUpdater.interval;
|
||||
if (Conf['Optional Increase']) {
|
||||
limit = d.hidden ? 7 : 10;
|
||||
j = Math.min(ThreadUpdater.outdateCount, limit);
|
||||
cur = (Math.floor(interval * 0.1) || 1) * j * j;
|
||||
ThreadUpdater.seconds = $.minmax(cur, interval, 300);
|
||||
} else {
|
||||
ThreadUpdater.seconds = interval;
|
||||
}
|
||||
return ThreadUpdater.timeout();
|
||||
},
|
||||
intervalShortcut: function() {
|
||||
var settings;
|
||||
@ -12287,40 +12236,22 @@
|
||||
} else {
|
||||
el.textContent = text;
|
||||
}
|
||||
if (klass !== void 0) {
|
||||
return el.className = klass;
|
||||
}
|
||||
},
|
||||
count: function(start) {
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
if (start && ThreadUpdater.isUpdating && navigator.onLine) {
|
||||
return ThreadUpdater.timeout();
|
||||
}
|
||||
return el.className = klass != null ? klass : (text === '' ? 'empty' : '');
|
||||
},
|
||||
timeout: function() {
|
||||
var n;
|
||||
ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000);
|
||||
if (!(n = --ThreadUpdater.seconds)) {
|
||||
if (ThreadUpdater.seconds) {
|
||||
ThreadUpdater.set('timer', ThreadUpdater.seconds);
|
||||
ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000);
|
||||
} else {
|
||||
ThreadUpdater.outdateCount++;
|
||||
return ThreadUpdater.update();
|
||||
} else if (n <= -60) {
|
||||
ThreadUpdater.set('status', 'Retrying', '');
|
||||
return ThreadUpdater.update();
|
||||
} else if (n > 0) {
|
||||
return ThreadUpdater.set('timer', n);
|
||||
ThreadUpdater.update();
|
||||
}
|
||||
return ThreadUpdater.seconds--;
|
||||
},
|
||||
update: function() {
|
||||
var ref;
|
||||
if (!navigator.onLine) {
|
||||
return;
|
||||
}
|
||||
ThreadUpdater.count();
|
||||
if (Conf['Auto Update']) {
|
||||
ThreadUpdater.set('timer', '...');
|
||||
} else {
|
||||
ThreadUpdater.set('timer', 'Update');
|
||||
}
|
||||
clearTimeout(ThreadUpdater.timeoutID);
|
||||
ThreadUpdater.set('timer', '...', 'loading');
|
||||
if ((ref = ThreadUpdater.req) != null) {
|
||||
ref.abort();
|
||||
}
|
||||
@ -12343,17 +12274,25 @@
|
||||
change = type === 'Sticky' ? status ? 'now a sticky' : 'not a sticky anymore' : status ? 'now closed' : 'not closed anymore';
|
||||
return new Notice('info', "The thread is " + change + ".", 30);
|
||||
},
|
||||
parse: function(postObjects) {
|
||||
var OP, count, files, index, ipCountEl, k, len1, len2, node, num, post, postObject, posts, q, root, scroll;
|
||||
parse: function(req) {
|
||||
var ID, OP, board, count, deletedFiles, deletedPosts, files, firstPost, index, ipCountEl, k, lastModified, len1, len2, len3, len4, node, num, post, postObject, postObjects, posts, q, ref, ref1, ref2, scroll, thread, u, w;
|
||||
lastModified = new Date(req.getResponseHeader('Last-Modified'));
|
||||
if (ThreadUpdater.lastModified && lastModified < ThreadUpdater.lastModified) {
|
||||
return;
|
||||
}
|
||||
ThreadUpdater.lastModified = lastModified;
|
||||
postObjects = req.response.posts;
|
||||
OP = postObjects[0];
|
||||
Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler;
|
||||
ThreadUpdater.thread.setStatus('Archived', !!+OP.archived);
|
||||
thread = ThreadUpdater.thread;
|
||||
board = thread.board;
|
||||
Build.spoilerRange[board] = OP.custom_spoiler;
|
||||
thread.setStatus('Archived', !!+OP.archived);
|
||||
ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky);
|
||||
ThreadUpdater.updateThreadStatus('Closed', !!OP.closed);
|
||||
ThreadUpdater.thread.postLimit = !!OP.bumplimit;
|
||||
ThreadUpdater.thread.fileLimit = !!OP.imagelimit;
|
||||
thread.postLimit = !!OP.bumplimit;
|
||||
thread.fileLimit = !!OP.imagelimit;
|
||||
if (OP.unique_ips != null) {
|
||||
ThreadUpdater.thread.ipCount = OP.unique_ips;
|
||||
thread.ipCount = OP.unique_ips;
|
||||
}
|
||||
posts = [];
|
||||
index = [];
|
||||
@ -12370,27 +12309,36 @@
|
||||
continue;
|
||||
}
|
||||
count++;
|
||||
node = Build.postFromObject(postObject, ThreadUpdater.thread.board.ID);
|
||||
posts.push(new Post(node, ThreadUpdater.thread, ThreadUpdater.thread.board));
|
||||
node = Build.postFromObject(postObject, board.ID);
|
||||
posts.push(new Post(node, thread, board));
|
||||
if (ThreadUpdater.postID === num) {
|
||||
delete ThreadUpdater.postID;
|
||||
}
|
||||
}
|
||||
ThreadUpdater.thread.posts.forEach(function(post) {
|
||||
var ID;
|
||||
ID = +post.ID;
|
||||
if (!(post.info.date > Date.now() - 60 * $.SECOND)) {
|
||||
if (indexOf.call(index, ID) < 0) {
|
||||
post.kill();
|
||||
} else if (post.isDead) {
|
||||
post.resurrect();
|
||||
} else if (post.file && !(post.file.isDead || indexOf.call(files, ID) >= 0)) {
|
||||
post.kill(true);
|
||||
}
|
||||
deletedPosts = [];
|
||||
ref = ThreadUpdater.postIDs;
|
||||
for (q = 0, len2 = ref.length; q < len2; q++) {
|
||||
ID = ref[q];
|
||||
if (!(indexOf.call(index, ID) < 0)) {
|
||||
continue;
|
||||
}
|
||||
if (ThreadUpdater.postID && ThreadUpdater.postID === ID) {
|
||||
return ThreadUpdater.foundPost = true;
|
||||
thread.posts[ID].kill();
|
||||
deletedPosts.push(board + "." + ID);
|
||||
}
|
||||
ThreadUpdater.postIDs = index;
|
||||
deletedFiles = [];
|
||||
ref1 = ThreadUpdater.fileIDs;
|
||||
for (u = 0, len3 = ref1.length; u < len3; u++) {
|
||||
ID = ref1[u];
|
||||
if (!(!(indexOf.call(files, ID) >= 0 || (ref2 = board + "." + ID, indexOf.call(deletedPosts, ref2) >= 0)))) {
|
||||
continue;
|
||||
}
|
||||
});
|
||||
thread.posts[ID].kill(true);
|
||||
deletedFiles.push(board + "." + ID);
|
||||
}
|
||||
ThreadUpdater.fileIDs = files;
|
||||
if (!count) {
|
||||
ThreadUpdater.set('status', '', '');
|
||||
ThreadUpdater.set('status', '');
|
||||
} else {
|
||||
ThreadUpdater.set('status', "+" + count, 'new');
|
||||
ThreadUpdater.outdateCount = 0;
|
||||
@ -12405,10 +12353,11 @@
|
||||
ThreadUpdater.lastPost = posts[count - 1].ID;
|
||||
Main.callbackNodes(Post, posts);
|
||||
scroll = Conf['Auto Scroll'] && ThreadUpdater.scrollBG() && ThreadUpdater.root.getBoundingClientRect().bottom - doc.clientHeight < 25;
|
||||
for (q = 0, len2 = posts.length; q < len2; q++) {
|
||||
post = posts[q];
|
||||
root = post.nodes.root;
|
||||
firstPost = null;
|
||||
for (w = 0, len4 = posts.length; w < len4; w++) {
|
||||
post = posts[w];
|
||||
if (!QuoteThreading.insert(post)) {
|
||||
firstPost || (firstPost = post.nodes.root);
|
||||
$.add(ThreadUpdater.root, post.nodes.root);
|
||||
}
|
||||
}
|
||||
@ -12417,8 +12366,8 @@
|
||||
if (Conf['Bottom Scroll']) {
|
||||
window.scrollTo(0, d.body.clientHeight);
|
||||
} else {
|
||||
if (root) {
|
||||
Header.scrollTo(root);
|
||||
if (firstPost) {
|
||||
Header.scrollTo(firstPost);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12428,21 +12377,22 @@
|
||||
ipCountEl.previousSibling.textContent = ipCountEl.previousSibling.textContent.replace(/\b(?:is|are)\b/, OP.unique_ips === 1 ? 'is' : 'are');
|
||||
ipCountEl.nextSibling.textContent = ipCountEl.nextSibling.textContent.replace(/\bposters?\b/, OP.unique_ips === 1 ? 'poster' : 'posters');
|
||||
}
|
||||
ThreadUpdater.postIDs = index;
|
||||
return $.event('ThreadUpdate', {
|
||||
404: false,
|
||||
threadID: ThreadUpdater.thread.fullID,
|
||||
threadID: thread.fullID,
|
||||
newPosts: (function() {
|
||||
var len3, results, u;
|
||||
var len5, results, y;
|
||||
results = [];
|
||||
for (u = 0, len3 = posts.length; u < len3; u++) {
|
||||
post = posts[u];
|
||||
for (y = 0, len5 = posts.length; y < len5; y++) {
|
||||
post = posts[y];
|
||||
results.push(post.fullID);
|
||||
}
|
||||
return results;
|
||||
})(),
|
||||
deletedPosts: deletedPosts,
|
||||
deletedFiles: deletedFiles,
|
||||
postCount: OP.replies + 1,
|
||||
fileCount: OP.images + (!!ThreadUpdater.thread.OP.file && !ThreadUpdater.thread.OP.file.isDead),
|
||||
fileCount: OP.images + (!!thread.OP.file && !thread.OP.file.isDead),
|
||||
ipCount: OP.unique_ips
|
||||
});
|
||||
}
|
||||
@ -17769,8 +17719,8 @@
|
||||
".new {\n" +
|
||||
" color: limegreen;\n" +
|
||||
"}\n" +
|
||||
"#update-status.new {\n" +
|
||||
" margin-right: 5px;\n" +
|
||||
"#update-status:not(.empty) + #update-timer:not(.empty):not(.loading) {\n" +
|
||||
" margin-left: 5px;\n" +
|
||||
"}\n" +
|
||||
"#update-timer {\n" +
|
||||
" cursor: pointer;\n" +
|
||||
|
||||
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
||||
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X-beta.crx' version='1.10.3.9' />
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X-beta.crx' version='1.10.4.0' />
|
||||
</app>
|
||||
</gupdate>
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
||||
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X.crx' version='1.10.3.9' />
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X.crx' version='1.10.4.0' />
|
||||
</app>
|
||||
</gupdate>
|
||||
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
||||
"meta": {
|
||||
"name": "4chan X",
|
||||
"version": "1.10.3.9",
|
||||
"date": "2015-03-07T13:50:13.050Z",
|
||||
"version": "1.10.4.0",
|
||||
"date": "2015-03-09T09:49:25.081Z",
|
||||
"repo": "https://github.com/ccd0/4chan-x/",
|
||||
"page": "https://github.com/ccd0/4chan-x",
|
||||
"downloads": "https://ccd0.github.io/4chan-x/builds/",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user