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