Release 4chan X v1.9.14.0.
This commit is contained in:
parent
c38c37c720
commit
fcf4e2144a
@ -2,6 +2,15 @@ The attributions below are for work that has been incorporated into the script a
|
||||
|
||||
The links to individual versions below are to copies of the script with the update URL removed. If you want automatic updates, install the script from the links on the [main page](https://github.com/ccd0/4chan-x).
|
||||
|
||||
<!-- v1.9.14.x -->
|
||||
### v1.9.14.0
|
||||
*2014-11-30* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.14.0/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.14.0/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
|
||||
**ccd0**
|
||||
- `Quote Threading` is now compatible with the `Unread Line` and `Scroll to Last Read Post` features.
|
||||
- When there are unread replies to a read post, which are not threaded so you don't miss them, a `[Thread New Posts]` link appears at the bottom of the page, which will thread them when clicked.
|
||||
- Fix some scrolling bugs when images are contracted.
|
||||
|
||||
<!-- v1.9.13.x -->
|
||||
### v1.9.13.4
|
||||
*2014-11-26* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.13.4/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.9.13.4/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
|
||||
2
LICENSE
2
LICENSE
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 4chan X - Version 1.9.13.4
|
||||
* 4chan X - Version 1.9.14.0
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||
|
||||
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
// ==UserScript==
|
||||
// @name 4chan X beta
|
||||
// @version 1.9.13.4
|
||||
// @version 1.9.14.0
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript
|
||||
// ==UserScript==
|
||||
// @name 4chan X beta
|
||||
// @version 1.9.13.4
|
||||
// @version 1.9.14.0
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -24,7 +24,7 @@
|
||||
// ==/UserScript==
|
||||
|
||||
/*
|
||||
* 4chan X - Version 1.9.13.4
|
||||
* 4chan X - Version 1.9.14.0
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||
@ -107,7 +107,7 @@
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var $, $$, Anonymize, ArchiveLink, Banner, Board, Build, Callbacks, CatalogLinks, CatalogThread, Clone, Conf, Config, CrossOrigin, CustomCSS, DataBoard, DeleteLink, DownloadLink, E, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, IDHighlight, ImageCommon, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, MarkNewIPs, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, c, d, doc, g,
|
||||
var $, $$, Anonymize, ArchiveLink, Banner, Board, Build, Callbacks, CatalogLinks, CatalogThread, Clone, Conf, Config, CrossOrigin, CustomCSS, DataBoard, DeleteLink, DownloadLink, E, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, IDHighlight, ImageCommon, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, MarkNewIPs, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, ShimSet, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, c, d, doc, g,
|
||||
__slice = [].slice,
|
||||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
|
||||
__hasProp = {}.hasOwnProperty,
|
||||
@ -388,7 +388,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.9.13.4',
|
||||
VERSION: '1.9.14.0',
|
||||
NAMESPACE: '4chan X.',
|
||||
NAME: '4chan X',
|
||||
FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions',
|
||||
@ -1887,6 +1887,40 @@
|
||||
|
||||
})();
|
||||
|
||||
ShimSet = (function() {
|
||||
function ShimSet() {
|
||||
this.elements = {};
|
||||
this.size = 0;
|
||||
}
|
||||
|
||||
ShimSet.prototype.has = function(value) {
|
||||
return value in this.elements;
|
||||
};
|
||||
|
||||
ShimSet.prototype.add = function(value) {
|
||||
if (this.elements[value]) {
|
||||
return;
|
||||
}
|
||||
this.elements[value] = true;
|
||||
return this.size++;
|
||||
};
|
||||
|
||||
ShimSet.prototype["delete"] = function(value) {
|
||||
if (!this.elements[value]) {
|
||||
return;
|
||||
}
|
||||
delete this.elements[value];
|
||||
return this.size--;
|
||||
};
|
||||
|
||||
return ShimSet;
|
||||
|
||||
})();
|
||||
|
||||
if (!('Set' in window)) {
|
||||
window.Set = ShimSet;
|
||||
}
|
||||
|
||||
Polyfill = {
|
||||
init: function() {
|
||||
this.notificationPermission();
|
||||
@ -6024,7 +6058,6 @@
|
||||
|
||||
QuoteThreading = {
|
||||
init: function() {
|
||||
var input;
|
||||
if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) {
|
||||
return;
|
||||
}
|
||||
@ -6032,123 +6065,164 @@
|
||||
this.controls = $.el('span', {
|
||||
innerHTML: "<label><input id=\"threadingControl\" type=\"checkbox\" checked> Threading</label>"
|
||||
});
|
||||
input = $('input', this.controls);
|
||||
$.on(input, 'change', this.toggle);
|
||||
this.threadNewLink = $.el('span', {
|
||||
className: 'brackets-wrap threadnewlink',
|
||||
hidden: true
|
||||
});
|
||||
$.extend(this.threadNewLink, {
|
||||
innerHTML: "<a href=\"javascript:;\">Thread New Posts</a>"
|
||||
});
|
||||
$.on($('input', this.controls), 'change', function() {
|
||||
return QuoteThreading.rethread(this.checked);
|
||||
});
|
||||
$.on(this.threadNewLink.firstElementChild, 'click', function() {
|
||||
QuoteThreading.threadNewLink.hidden = true;
|
||||
return QuoteThreading.rethread(true);
|
||||
});
|
||||
Header.menu.addEntry(this.entry = {
|
||||
el: this.controls,
|
||||
order: 98
|
||||
});
|
||||
Thread.callbacks.push({
|
||||
name: 'Quote Threading',
|
||||
cb: this.setThread
|
||||
});
|
||||
return Post.callbacks.push({
|
||||
name: 'Quote Threading',
|
||||
cb: this.node
|
||||
});
|
||||
},
|
||||
force: function() {
|
||||
g.posts.forEach(function(post) {
|
||||
if (post.cb) {
|
||||
return post.cb(true);
|
||||
}
|
||||
parent: {},
|
||||
children: {},
|
||||
inserted: {},
|
||||
setThread: function() {
|
||||
QuoteThreading.thread = this;
|
||||
return $.asap((function() {
|
||||
return !Conf['Thread Updater'] || $('.navLinksBot > .updatelink');
|
||||
}), function() {
|
||||
return $.add($('.navLinksBot'), [$.tn(' '), QuoteThreading.threadNewLink]);
|
||||
});
|
||||
Unread.read();
|
||||
return Unread.update();
|
||||
},
|
||||
node: function() {
|
||||
var keys, len, posts, quote, _i, _len, _ref;
|
||||
posts = g.posts;
|
||||
if (this.isClone || !QuoteThreading.enabled) {
|
||||
var parent, parents, quote, thread;
|
||||
if (this.isFetchedQuote || this.isClone || !this.isReply) {
|
||||
return;
|
||||
}
|
||||
Unread.addPost(this);
|
||||
if (this.thread.OP === this || this.isHidden) {
|
||||
return;
|
||||
thread = QuoteThreading.thread;
|
||||
parents = (function() {
|
||||
var _i, _len, _ref, _results;
|
||||
_ref = this.quotes;
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
quote = _ref[_i];
|
||||
parent = g.posts[quote];
|
||||
if (!parent || parent.isFetchedQuote || !parent.isReply || parent.ID >= this.ID) {
|
||||
continue;
|
||||
}
|
||||
_results.push(parent);
|
||||
}
|
||||
return _results;
|
||||
}).call(this);
|
||||
if (parents.length === 1) {
|
||||
return QuoteThreading.parent[this.fullID] = parents[0];
|
||||
}
|
||||
keys = [];
|
||||
len = g.BOARD.ID.length + 1;
|
||||
_ref = this.quotes;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
quote = _ref[_i];
|
||||
if ((quote.slice(len) < this.ID) && quote in posts) {
|
||||
keys.push(quote);
|
||||
},
|
||||
descendants: function(post) {
|
||||
var child, children, posts, _i, _len;
|
||||
posts = [post];
|
||||
if (children = QuoteThreading.children[post.fullID]) {
|
||||
for (_i = 0, _len = children.length; _i < _len; _i++) {
|
||||
child = children[_i];
|
||||
posts = posts.concat(QuoteThreading.descendants(child));
|
||||
}
|
||||
}
|
||||
if (keys.length !== 1) {
|
||||
return;
|
||||
}
|
||||
this.threaded = keys[0];
|
||||
return this.cb = QuoteThreading.nodeinsert;
|
||||
return posts;
|
||||
},
|
||||
nodeinsert: function(force) {
|
||||
var bottom, height, post, posts, root, threadContainer, top, _ref;
|
||||
post = g.posts[this.threaded];
|
||||
if (this.thread.OP === post) {
|
||||
insert: function(post) {
|
||||
var child, children, descendants, i, next, nodes, order, parent, prev, prev2, threadContainer, x, _base, _i, _j, _k, _len, _name;
|
||||
if (!(QuoteThreading.enabled && (parent = QuoteThreading.parent[post.fullID]) && !QuoteThreading.inserted[post.fullID])) {
|
||||
return false;
|
||||
}
|
||||
posts = Unread.posts;
|
||||
root = post.nodes.root;
|
||||
if (!force) {
|
||||
height = doc.clientHeight;
|
||||
_ref = root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top;
|
||||
if (!(posts[post.ID] || ((bottom < height) && (top > 0)))) {
|
||||
return false;
|
||||
descendants = QuoteThreading.descendants(post);
|
||||
if (!Unread.posts.has(parent.ID) && descendants.some(function(x) {
|
||||
return Unread.posts.has(x.ID);
|
||||
})) {
|
||||
QuoteThreading.threadNewLink.hidden = false;
|
||||
return false;
|
||||
}
|
||||
order = Unread.order;
|
||||
children = ((_base = QuoteThreading.children)[_name = parent.fullID] || (_base[_name] = []));
|
||||
threadContainer = parent.nodes.threadContainer || $.el('div', {
|
||||
className: 'threadContainer'
|
||||
});
|
||||
nodes = [post.nodes.root];
|
||||
if (post.nodes.threadContainer) {
|
||||
nodes.push(post.nodes.threadContainer);
|
||||
}
|
||||
i = children.length;
|
||||
for (_i = children.length - 1; _i >= 0; _i += -1) {
|
||||
child = children[_i];
|
||||
if (child.ID >= post.ID) {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if ($.hasClass(root, 'threadOP')) {
|
||||
threadContainer = root.nextElementSibling;
|
||||
post = Get.postFromRoot($.x('descendant::div[contains(@class,"postContainer")][last()]', threadContainer));
|
||||
$.add(threadContainer, this.nodes.root);
|
||||
if (i !== children.length) {
|
||||
next = children[i];
|
||||
for (_j = 0, _len = descendants.length; _j < _len; _j++) {
|
||||
x = descendants[_j];
|
||||
order.before(order[next.ID], order[x.ID]);
|
||||
}
|
||||
children.splice(i, 0, post);
|
||||
$.before(next.nodes.root, nodes);
|
||||
} else {
|
||||
threadContainer = $.el('div', {
|
||||
className: 'threadContainer'
|
||||
});
|
||||
$.add(threadContainer, this.nodes.root);
|
||||
$.after(root, threadContainer);
|
||||
$.addClass(root, 'threadOP');
|
||||
prev = parent;
|
||||
while ((prev2 = QuoteThreading.children[prev.fullID]) && prev2.length) {
|
||||
prev = prev2[prev2.length - 1];
|
||||
}
|
||||
for (_k = descendants.length - 1; _k >= 0; _k += -1) {
|
||||
x = descendants[_k];
|
||||
order.after(order[prev.ID], order[x.ID]);
|
||||
}
|
||||
children.push(post);
|
||||
$.add(threadContainer, nodes);
|
||||
}
|
||||
if (post = posts[post.ID]) {
|
||||
posts.after(post, posts[this.ID]);
|
||||
} else if (posts[this.ID]) {
|
||||
posts.prepend(posts[this.ID]);
|
||||
QuoteThreading.inserted[post.fullID] = true;
|
||||
if (!parent.nodes.threadContainer) {
|
||||
parent.nodes.threadContainer = threadContainer;
|
||||
$.addClass(parent.nodes.root, 'threadOP');
|
||||
$.after(parent.nodes.root, threadContainer);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
toggle: function() {
|
||||
var container, containers, nodes, post, posts, thread, _i, _j, _k, _len, _len1, _len2, _ref;
|
||||
if (QuoteThreading.enabled = this.checked) {
|
||||
QuoteThreading.force();
|
||||
rethread: function(enabled) {
|
||||
var nodes, posts, thread;
|
||||
thread = QuoteThreading.thread;
|
||||
posts = thread.posts;
|
||||
if (QuoteThreading.enabled = enabled) {
|
||||
posts.forEach(QuoteThreading.insert);
|
||||
} else {
|
||||
thread = $('.thread');
|
||||
posts = [];
|
||||
nodes = [];
|
||||
g.posts.forEach(function(post) {
|
||||
if (!(post === post.thread.OP || post.isClone)) {
|
||||
return posts.push(post);
|
||||
Unread.order = new RandomAccessList;
|
||||
QuoteThreading.inserted = {};
|
||||
posts.forEach(function(post) {
|
||||
Unread.order.push(post);
|
||||
if (post.isReply) {
|
||||
nodes.push(post.nodes.root);
|
||||
}
|
||||
if (QuoteThreading.children[post.fullID]) {
|
||||
delete QuoteThreading.children[post.fullID];
|
||||
$.rmClass(post.nodes.root, 'threadOP');
|
||||
$.rm(post.nodes.threadContainer);
|
||||
return delete post.nodes.threadContainer;
|
||||
}
|
||||
});
|
||||
posts.sort(function(a, b) {
|
||||
return a.ID - b.ID;
|
||||
});
|
||||
for (_i = 0, _len = posts.length; _i < _len; _i++) {
|
||||
post = posts[_i];
|
||||
nodes.push(post.nodes.root);
|
||||
}
|
||||
$.add(thread, nodes);
|
||||
containers = $$('.threadContainer', thread);
|
||||
for (_j = 0, _len1 = containers.length; _j < _len1; _j++) {
|
||||
container = containers[_j];
|
||||
$.rm(container);
|
||||
}
|
||||
_ref = $$('.threadOP');
|
||||
for (_k = 0, _len2 = _ref.length; _k < _len2; _k++) {
|
||||
post = _ref[_k];
|
||||
$.rmClass(post, 'threadOP');
|
||||
}
|
||||
$.add(thread.OP.nodes.root.parentNode, nodes);
|
||||
}
|
||||
},
|
||||
kb: function() {
|
||||
var control;
|
||||
control = $.id('threadingControl');
|
||||
control.checked = !control.checked;
|
||||
return QuoteThreading.toggle.call(control);
|
||||
Unread.position = Unread.order.first;
|
||||
Unread.updatePosition();
|
||||
Unread.setLine(true);
|
||||
Unread.read();
|
||||
return Unread.update();
|
||||
}
|
||||
};
|
||||
|
||||
@ -8862,44 +8936,34 @@
|
||||
}
|
||||
},
|
||||
toggle: function(post) {
|
||||
var headRect, left, root, top, x, y, _ref;
|
||||
var next;
|
||||
if (!(post.file.isExpanding || post.file.isExpanded)) {
|
||||
post.file.scrollIntoView = Conf['Scroll into view'];
|
||||
ImageExpand.expand(post);
|
||||
return;
|
||||
}
|
||||
ImageExpand.contract(post);
|
||||
root = post.nodes.root;
|
||||
_ref = (Conf['Advance on contract'] ? (function() {
|
||||
var next;
|
||||
next = root;
|
||||
if (Conf['Advance on contract']) {
|
||||
next = post.nodes.root;
|
||||
while (next = $.x("following::div[contains(@class,'postContainer')][1]", next)) {
|
||||
if ($('.stub', next) || next.offsetHeight === 0) {
|
||||
continue;
|
||||
if (!($('.stub', next) || next.offsetHeight === 0)) {
|
||||
break;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
return root;
|
||||
})() : root).getBoundingClientRect(), top = _ref.top, left = _ref.left;
|
||||
if (top < 0) {
|
||||
y = top;
|
||||
if (Conf['Fixed Header'] && !Conf['Bottom Header']) {
|
||||
headRect = Header.bar.getBoundingClientRect();
|
||||
y -= headRect.top + headRect.height;
|
||||
if (next) {
|
||||
return Header.scrollTo(next);
|
||||
}
|
||||
}
|
||||
if (left < 0) {
|
||||
x = -window.scrollX;
|
||||
}
|
||||
if (x || y) {
|
||||
return window.scrollBy(x, y);
|
||||
}
|
||||
},
|
||||
contract: function(post) {
|
||||
var bottom, cb, el, eventName, file, oldHeight, x, _i, _len, _ref, _ref1;
|
||||
var bottom, cb, el, eventName, file, oldHeight, scrollY, top, x, _i, _len, _ref, _ref1;
|
||||
file = post.file;
|
||||
bottom = post.nodes.root.getBoundingClientRect().bottom;
|
||||
oldHeight = d.body.clientHeight;
|
||||
if (el = file.fullImage) {
|
||||
top = Header.getTopOf(el);
|
||||
bottom = top + el.getBoundingClientRect().height;
|
||||
oldHeight = d.body.clientHeight;
|
||||
scrollY = window.scrollY;
|
||||
}
|
||||
$.rmClass(post.nodes.root, 'expanded-image');
|
||||
$.rmClass(file.thumb, 'expanding');
|
||||
if (file.videoControls) {
|
||||
@ -8912,35 +8976,43 @@
|
||||
x = _ref[_i];
|
||||
delete file[x];
|
||||
}
|
||||
if (doc.contains(post.nodes.root) && bottom <= 0) {
|
||||
window.scrollBy(0, d.body.clientHeight - oldHeight);
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
if (el = file.fullImage) {
|
||||
$.off(el, 'error', ImageExpand.error);
|
||||
ImageCommon.pushCache(el);
|
||||
if (file.isVideo) {
|
||||
el.pause();
|
||||
_ref1 = ImageExpand.videoCB;
|
||||
for (eventName in _ref1) {
|
||||
cb = _ref1[eventName];
|
||||
$.off(el, eventName, cb);
|
||||
}
|
||||
if (doc.contains(el)) {
|
||||
if (bottom <= 0) {
|
||||
window.scroll(0, scrollY + d.body.clientHeight - oldHeight);
|
||||
} else {
|
||||
Header.scrollToIfNeeded(post.nodes.root);
|
||||
}
|
||||
if (Conf['Restart when Opened']) {
|
||||
ImageCommon.rewind(file.thumb);
|
||||
if (window.scrollX > 0) {
|
||||
window.scroll(0, window.scrollY);
|
||||
}
|
||||
delete file.fullImage;
|
||||
return $.queueTask(function() {
|
||||
if (file.isExpanding || file.isExpanded) {
|
||||
return;
|
||||
}
|
||||
$.rmClass(el, 'full-image');
|
||||
if (el.id) {
|
||||
return;
|
||||
}
|
||||
return $.rm(el);
|
||||
});
|
||||
}
|
||||
$.off(el, 'error', ImageExpand.error);
|
||||
ImageCommon.pushCache(el);
|
||||
if (file.isVideo) {
|
||||
el.pause();
|
||||
_ref1 = ImageExpand.videoCB;
|
||||
for (eventName in _ref1) {
|
||||
cb = _ref1[eventName];
|
||||
$.off(el, eventName, cb);
|
||||
}
|
||||
}
|
||||
if (Conf['Restart when Opened']) {
|
||||
ImageCommon.rewind(file.thumb);
|
||||
}
|
||||
delete file.fullImage;
|
||||
return $.queueTask(function() {
|
||||
if (file.isExpanding || file.isExpanded) {
|
||||
return;
|
||||
}
|
||||
$.rmClass(el, 'full-image');
|
||||
if (el.id) {
|
||||
return;
|
||||
}
|
||||
return $.rm(el);
|
||||
});
|
||||
},
|
||||
expand: function(post, src) {
|
||||
var el, file, isVideo, thumb, _ref;
|
||||
@ -8993,19 +9065,20 @@
|
||||
}
|
||||
},
|
||||
completeExpand: function(post) {
|
||||
var bottom, file, imageBottom, oldHeight;
|
||||
var bottom, file, imageBottom, oldHeight, scrollY;
|
||||
file = post.file;
|
||||
if (!file.isExpanding) {
|
||||
return;
|
||||
}
|
||||
bottom = post.nodes.root.getBoundingClientRect().bottom;
|
||||
bottom = Header.getTopOf(file.thumb) + file.thumb.getBoundingClientRect().height;
|
||||
oldHeight = d.body.clientHeight;
|
||||
scrollY = window.scrollY;
|
||||
$.addClass(post.nodes.root, 'expanded-image');
|
||||
$.rmClass(file.thumb, 'expanding');
|
||||
file.isExpanded = true;
|
||||
delete file.isExpanding;
|
||||
if (doc.contains(post.nodes.root) && bottom <= 0) {
|
||||
window.scrollBy(0, d.body.clientHeight - oldHeight);
|
||||
window.scroll(window.scrollX, scrollY + d.body.clientHeight - oldHeight);
|
||||
}
|
||||
if (file.scrollIntoView) {
|
||||
delete file.scrollIntoView;
|
||||
@ -9207,7 +9280,7 @@
|
||||
ImageCommon.rewind(this);
|
||||
}
|
||||
el.id = 'ihover';
|
||||
$.after(Header.hover, el);
|
||||
$.add(Header.hover, el);
|
||||
if (isVideo) {
|
||||
el.loop = true;
|
||||
el.controls = false;
|
||||
@ -11143,7 +11216,7 @@
|
||||
return new Notice('info', "The thread is " + change + ".", 30);
|
||||
},
|
||||
parse: function(postObjects) {
|
||||
var OP, count, files, index, ipCountEl, node, num, post, postObject, posts, root, scroll, _i, _j, _len, _len1;
|
||||
var OP, count, files, index, ipCountEl, node, num, post, postObject, posts, scroll, _i, _j, _len, _len1;
|
||||
OP = postObjects[0];
|
||||
Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler;
|
||||
ThreadUpdater.thread.setStatus('Archived', !!+OP.archived);
|
||||
@ -11206,13 +11279,8 @@
|
||||
scroll = Conf['Auto Scroll'] && ThreadUpdater.scrollBG() && ThreadUpdater.root.getBoundingClientRect().bottom - doc.clientHeight < 25;
|
||||
for (_j = 0, _len1 = posts.length; _j < _len1; _j++) {
|
||||
post = posts[_j];
|
||||
root = post.nodes.root;
|
||||
if (post.cb) {
|
||||
if (!post.cb()) {
|
||||
$.add(ThreadUpdater.root, root);
|
||||
}
|
||||
} else {
|
||||
$.add(ThreadUpdater.root, root);
|
||||
if (!QuoteThreading.insert(post)) {
|
||||
$.add(ThreadUpdater.root, post.nodes.root);
|
||||
}
|
||||
}
|
||||
$.event('PostsInserted');
|
||||
@ -11475,7 +11543,7 @@
|
||||
defaultValue: 0
|
||||
});
|
||||
unread = quotingYou = 0;
|
||||
_ref = this.response.posts.slice(1);
|
||||
_ref = this.response.posts;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
postObj = _ref[_i];
|
||||
if (!(postObj.no > lastReadPost)) {
|
||||
@ -11811,68 +11879,76 @@
|
||||
this.hr = $.el('hr', {
|
||||
id: 'unread-line'
|
||||
});
|
||||
this.posts = new RandomAccessList;
|
||||
this.postsQuotingYou = {};
|
||||
return Thread.callbacks.push({
|
||||
this.posts = new Set;
|
||||
this.postsQuotingYou = new Set;
|
||||
this.order = new RandomAccessList;
|
||||
this.position = null;
|
||||
Thread.callbacks.push({
|
||||
name: 'Unread',
|
||||
cb: this.node
|
||||
});
|
||||
return Post.callbacks.push({
|
||||
name: 'Unread',
|
||||
cb: this.addPost
|
||||
});
|
||||
},
|
||||
node: function() {
|
||||
var ID, _i, _len, _ref;
|
||||
Unread.thread = this;
|
||||
Unread.title = d.title;
|
||||
Unread.db.forceSync();
|
||||
Unread.lastReadPost = Unread.db.get({
|
||||
boardID: this.board.ID,
|
||||
threadID: this.ID,
|
||||
defaultValue: 0
|
||||
});
|
||||
Unread.readCount = 0;
|
||||
_ref = this.posts.keys;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
ID = _ref[_i];
|
||||
if (+ID <= Unread.lastReadPost) {
|
||||
Unread.readCount++;
|
||||
}
|
||||
}
|
||||
$.one(d, '4chanXInitFinished', Unread.ready);
|
||||
$.on(d, 'ThreadUpdate', Unread.onUpdate);
|
||||
$.on(d, 'scroll visibilitychange', Unread.read);
|
||||
if (Conf['Unread Line'] && !Conf['Quote Threading']) {
|
||||
if (Conf['Unread Line']) {
|
||||
return $.on(d, 'visibilitychange', Unread.setLine);
|
||||
}
|
||||
},
|
||||
ready: function() {
|
||||
var posts;
|
||||
if (!Conf['Quote Threading']) {
|
||||
posts = [];
|
||||
Unread.thread.posts.forEach(function(post) {
|
||||
if (post.isReply) {
|
||||
return posts.push(post);
|
||||
}
|
||||
});
|
||||
Unread.addPosts(posts);
|
||||
}
|
||||
if (Conf['Quote Threading']) {
|
||||
QuoteThreading.force();
|
||||
}
|
||||
if (Conf['Scroll to Last Read Post'] && !Conf['Quote Threading']) {
|
||||
Unread.setLine(true);
|
||||
Unread.read();
|
||||
Unread.update();
|
||||
if (Conf['Scroll to Last Read Post']) {
|
||||
return Unread.scroll();
|
||||
}
|
||||
},
|
||||
positionPrev: function() {
|
||||
if (Unread.position) {
|
||||
return Unread.position.prev;
|
||||
} else {
|
||||
return Unread.order.last;
|
||||
}
|
||||
},
|
||||
scroll: function() {
|
||||
var ID, hash, posts, root, _i, _ref;
|
||||
var hash, position, root;
|
||||
if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) {
|
||||
return;
|
||||
}
|
||||
posts = Unread.thread.posts;
|
||||
_ref = posts.keys;
|
||||
for (_i = _ref.length - 1; _i >= 0; _i += -1) {
|
||||
ID = _ref[_i];
|
||||
if (!(+ID <= Unread.lastReadPost)) {
|
||||
continue;
|
||||
}
|
||||
root = posts[ID].nodes.root;
|
||||
if (root.getBoundingClientRect().height) {
|
||||
position = Unread.positionPrev();
|
||||
while (position) {
|
||||
root = position.data.nodes.root;
|
||||
if (!root.getBoundingClientRect().height) {
|
||||
position = position.prev;
|
||||
} else {
|
||||
Header.scrollToIfNeeded(root, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
sync: function() {
|
||||
var ID, lastReadPost, _i, _len, _ref;
|
||||
var ID, i, lastReadPost, postIDs, _i, _ref, _ref1;
|
||||
if (Unread.lastReadPost == null) {
|
||||
return;
|
||||
}
|
||||
@ -11885,44 +11961,36 @@
|
||||
return;
|
||||
}
|
||||
Unread.lastReadPost = lastReadPost;
|
||||
_ref = Unread.thread.posts.keys;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
ID = _ref[_i];
|
||||
if (+ID > Unread.lastReadPost) {
|
||||
postIDs = Unread.thread.posts.keys;
|
||||
for (i = _i = _ref = Unread.readCount, _ref1 = postIDs.length; _i < _ref1; i = _i += 1) {
|
||||
ID = +postIDs[i];
|
||||
if (ID > Unread.lastReadPost) {
|
||||
break;
|
||||
}
|
||||
Unread.posts.rm(ID);
|
||||
delete Unread.postsQuotingYou[ID];
|
||||
}
|
||||
if (Conf['Unread Line'] && !Conf['Quote Threading']) {
|
||||
Unread.setLine();
|
||||
Unread.posts["delete"](ID);
|
||||
Unread.postsQuotingYou["delete"](ID);
|
||||
Unread.readCount++;
|
||||
}
|
||||
Unread.updatePosition();
|
||||
Unread.setLine();
|
||||
return Unread.update();
|
||||
},
|
||||
addPost: function(post) {
|
||||
addPost: function() {
|
||||
var _ref;
|
||||
if (post.ID <= Unread.lastReadPost || post.isHidden || ((_ref = QR.db) != null ? _ref.get({
|
||||
boardID: post.board.ID,
|
||||
threadID: post.thread.ID,
|
||||
postID: post.ID
|
||||
if (this.isFetchedQuote || this.isClone) {
|
||||
return;
|
||||
}
|
||||
Unread.order.push(this);
|
||||
if (this.ID <= Unread.lastReadPost || this.isHidden || ((_ref = QR.db) != null ? _ref.get({
|
||||
boardID: this.board.ID,
|
||||
threadID: this.thread.ID,
|
||||
postID: this.ID
|
||||
}) : void 0)) {
|
||||
return;
|
||||
}
|
||||
Unread.posts.push(post);
|
||||
return Unread.addPostQuotingYou(post);
|
||||
},
|
||||
addPosts: function(posts) {
|
||||
var oldCount, post, _i, _len;
|
||||
oldCount = Unread.posts.length;
|
||||
for (_i = 0, _len = posts.length; _i < _len; _i++) {
|
||||
post = posts[_i];
|
||||
Unread.addPost(post);
|
||||
}
|
||||
if (Conf['Unread Line'] && !Conf['Quote Threading']) {
|
||||
Unread.setLine(oldCount === 0 && Unread.posts.length !== 0);
|
||||
}
|
||||
Unread.read();
|
||||
return Unread.update();
|
||||
Unread.posts.add(this.ID);
|
||||
Unread.addPostQuotingYou(this);
|
||||
return Unread.position != null ? Unread.position : Unread.position = Unread.order[this.ID];
|
||||
},
|
||||
addPostQuotingYou: function(post) {
|
||||
var quotelink, _i, _len, _ref, _ref1;
|
||||
@ -11932,7 +12000,7 @@
|
||||
if (!((_ref1 = QR.db) != null ? _ref1.get(Get.postDataFromLink(quotelink)) : void 0)) {
|
||||
continue;
|
||||
}
|
||||
Unread.postsQuotingYou[post.ID] = post;
|
||||
Unread.postsQuotingYou.add(post.ID);
|
||||
Unread.openNotification(post);
|
||||
return;
|
||||
}
|
||||
@ -11957,80 +12025,76 @@
|
||||
};
|
||||
},
|
||||
onUpdate: function(e) {
|
||||
var fullID;
|
||||
if (e.detail[404]) {
|
||||
return Unread.update();
|
||||
} else if (!QuoteThreading.enabled) {
|
||||
return Unread.addPosts((function() {
|
||||
var _i, _len, _ref, _results;
|
||||
_ref = e.detail.newPosts;
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
fullID = _ref[_i];
|
||||
_results.push(g.posts[fullID]);
|
||||
}
|
||||
return _results;
|
||||
})());
|
||||
} else {
|
||||
if (!e.detail[404]) {
|
||||
Unread.setLine();
|
||||
Unread.read();
|
||||
return Unread.update();
|
||||
}
|
||||
return Unread.update();
|
||||
},
|
||||
readSinglePost: function(post) {
|
||||
var ID, posts;
|
||||
var ID;
|
||||
ID = post.ID;
|
||||
posts = Unread.posts;
|
||||
if (!posts[ID]) {
|
||||
if (!Unread.posts.has(ID)) {
|
||||
return;
|
||||
}
|
||||
posts.rm(ID);
|
||||
delete Unread.postsQuotingYou[ID];
|
||||
Unread.posts["delete"](ID);
|
||||
Unread.postsQuotingYou["delete"](ID);
|
||||
Unread.updatePosition();
|
||||
Unread.saveLastReadPost();
|
||||
return Unread.update();
|
||||
},
|
||||
read: $.debounce(100, function(e) {
|
||||
var ID, count, data, height, post, posts, _ref;
|
||||
if (d.hidden || !Unread.posts.length) {
|
||||
var ID, count, data, height, root, _ref, _ref1;
|
||||
if (d.hidden || !Unread.posts.size) {
|
||||
return;
|
||||
}
|
||||
height = doc.clientHeight;
|
||||
posts = Unread.posts;
|
||||
count = 0;
|
||||
while (post = posts.first) {
|
||||
if (!(Header.getBottomOf(post.data.nodes.root) > -1)) {
|
||||
while (Unread.position) {
|
||||
_ref = Unread.position, ID = _ref.ID, data = _ref.data;
|
||||
root = data.nodes.root;
|
||||
if (!(!root.getBoundingClientRect().height || Header.getBottomOf(root) > -1)) {
|
||||
break;
|
||||
}
|
||||
ID = post.ID, data = post.data;
|
||||
count++;
|
||||
posts.rm(ID);
|
||||
delete Unread.postsQuotingYou[ID];
|
||||
if (Conf['Mark Quotes of You'] && ((_ref = QR.db) != null ? _ref.get({
|
||||
Unread.posts["delete"](ID);
|
||||
Unread.postsQuotingYou["delete"](ID);
|
||||
if (Conf['Mark Quotes of You'] && ((_ref1 = QR.db) != null ? _ref1.get({
|
||||
boardID: data.board.ID,
|
||||
threadID: data.thread.ID,
|
||||
postID: ID
|
||||
}) : void 0)) {
|
||||
QuoteYou.lastRead = data.nodes.root;
|
||||
QuoteYou.lastRead = root;
|
||||
}
|
||||
Unread.position = Unread.position.next;
|
||||
}
|
||||
if (!count) {
|
||||
return;
|
||||
}
|
||||
Unread.updatePosition();
|
||||
Unread.saveLastReadPost();
|
||||
if (e) {
|
||||
return Unread.update();
|
||||
}
|
||||
}),
|
||||
updatePosition: function() {
|
||||
var _results;
|
||||
_results = [];
|
||||
while (Unread.position && !Unread.posts.has(Unread.position.ID)) {
|
||||
_results.push(Unread.position = Unread.position.next);
|
||||
}
|
||||
return _results;
|
||||
},
|
||||
saveLastReadPost: $.debounce(2 * $.SECOND, function() {
|
||||
var ID, _i, _len, _ref;
|
||||
_ref = Unread.thread.posts.keys;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
ID = _ref[_i];
|
||||
if (Unread.posts[ID]) {
|
||||
var ID, i, postIDs, _i, _ref, _ref1;
|
||||
postIDs = Unread.thread.posts.keys;
|
||||
for (i = _i = _ref = Unread.readCount, _ref1 = postIDs.length; _i < _ref1; i = _i += 1) {
|
||||
ID = +postIDs[i];
|
||||
if (Unread.posts.has(ID)) {
|
||||
break;
|
||||
}
|
||||
if (+ID > Unread.lastReadPost) {
|
||||
Unread.lastReadPost = +ID;
|
||||
}
|
||||
Unread.lastReadPost = ID;
|
||||
Unread.readCount++;
|
||||
}
|
||||
if (Unread.thread.isDead && !Unread.thread.isArchived) {
|
||||
return;
|
||||
@ -12043,26 +12107,22 @@
|
||||
});
|
||||
}),
|
||||
setLine: function(force) {
|
||||
var ID, posts, _i, _ref;
|
||||
if (!(d.hidden || force === true)) {
|
||||
if (!Conf['Unread Line']) {
|
||||
return;
|
||||
}
|
||||
if (!Unread.posts.length) {
|
||||
return $.rm(Unread.hr);
|
||||
}
|
||||
posts = Unread.thread.posts;
|
||||
_ref = posts.keys;
|
||||
for (_i = _ref.length - 1; _i >= 0; _i += -1) {
|
||||
ID = _ref[_i];
|
||||
if (+ID <= Unread.lastReadPost) {
|
||||
return $.after(posts[ID].nodes.root, Unread.hr);
|
||||
if (d.hidden || (force === true)) {
|
||||
if (Unread.linePosition = Unread.positionPrev()) {
|
||||
$.after(Unread.linePosition.data.nodes.root, Unread.hr);
|
||||
} else {
|
||||
$.rm(Unread.hr);
|
||||
}
|
||||
}
|
||||
return Unread.hr.hidden = Unread.linePosition === Unread.order.last;
|
||||
},
|
||||
update: function() {
|
||||
var count, countQuotingYou, titleCount, titleDead, titleQuotingYou;
|
||||
count = Unread.posts.length;
|
||||
countQuotingYou = Object.keys(Unread.postsQuotingYou).length;
|
||||
count = Unread.posts.size;
|
||||
countQuotingYou = Unread.postsQuotingYou.size;
|
||||
if (Conf['Unread Count']) {
|
||||
titleQuotingYou = Conf['Quoted Title'] && countQuotingYou ? '(!) ' : '';
|
||||
titleCount = count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : '';
|
||||
@ -13854,7 +13914,7 @@
|
||||
className: 'dialog'
|
||||
});
|
||||
$.extend(dialog, {
|
||||
innerHTML: "<nav><div class=sections-list></div><p class='imp-exp-result warning'></p><div class=credits><a class=export>Export</a> | <a class=import>Import</a> | <a class=reset>Reset Settings</a> | <input type=file hidden><a href='https://github.com/ccd0/4chan-x' target=_blank>4chan X</a> | <a href='https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md' target=_blank>1.9.13.4</a> | <a href='https://github.com/ccd0/4chan-x/issues' target=_blank>Issues</a> | <a href=javascript:; class='close fa fa-times' title=Close></a></div></nav><div class=section-container><section></section></div>"
|
||||
innerHTML: "<nav><div class=sections-list></div><p class='imp-exp-result warning'></p><div class=credits><a class=export>Export</a> | <a class=import>Import</a> | <a class=reset>Reset Settings</a> | <input type=file hidden><a href='https://github.com/ccd0/4chan-x' target=_blank>4chan X</a> | <a href='https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md' target=_blank>1.9.14.0</a> | <a href='https://github.com/ccd0/4chan-x/issues' target=_blank>Issues</a> | <a href=javascript:; class='close fa fa-times' title=Close></a></div></nav><div class=section-container><section></section></div>"
|
||||
});
|
||||
$.on($('.export', Settings.dialog), 'click', Settings["export"]);
|
||||
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
|
||||
@ -14715,6 +14775,11 @@
|
||||
}
|
||||
Main.callbackNodes(Thread, threads);
|
||||
return Main.callbackNodesDB(Post, posts, function() {
|
||||
var post, _k, _len2;
|
||||
for (_k = 0, _len2 = posts.length; _k < _len2; _k++) {
|
||||
post = posts[_k];
|
||||
QuoteThreading.insert(post);
|
||||
}
|
||||
return $.event('4chanXInitFinished');
|
||||
});
|
||||
} else {
|
||||
|
||||
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.9.13.4
|
||||
// @version 1.9.14.0
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -23,7 +23,7 @@
|
||||
// ==/UserScript==
|
||||
|
||||
/*
|
||||
* 4chan X - Version 1.9.13.4
|
||||
* 4chan X - Version 1.9.14.0
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||
@ -106,7 +106,7 @@
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var $, $$, Anonymize, ArchiveLink, Banner, Board, Build, Callbacks, CatalogLinks, CatalogThread, Clone, Conf, Config, CrossOrigin, CustomCSS, DataBoard, DeleteLink, DownloadLink, E, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, IDHighlight, ImageCommon, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, MarkNewIPs, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, c, d, doc, g,
|
||||
var $, $$, Anonymize, ArchiveLink, Banner, Board, Build, Callbacks, CatalogLinks, CatalogThread, Clone, Conf, Config, CrossOrigin, CustomCSS, DataBoard, DeleteLink, DownloadLink, E, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, IDHighlight, ImageCommon, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, MarkNewIPs, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, ShimSet, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, c, d, doc, g,
|
||||
__slice = [].slice,
|
||||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
|
||||
__hasProp = {}.hasOwnProperty,
|
||||
@ -387,7 +387,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.9.13.4',
|
||||
VERSION: '1.9.14.0',
|
||||
NAMESPACE: '4chan X.',
|
||||
NAME: '4chan X',
|
||||
FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions',
|
||||
@ -1886,6 +1886,40 @@
|
||||
|
||||
})();
|
||||
|
||||
ShimSet = (function() {
|
||||
function ShimSet() {
|
||||
this.elements = {};
|
||||
this.size = 0;
|
||||
}
|
||||
|
||||
ShimSet.prototype.has = function(value) {
|
||||
return value in this.elements;
|
||||
};
|
||||
|
||||
ShimSet.prototype.add = function(value) {
|
||||
if (this.elements[value]) {
|
||||
return;
|
||||
}
|
||||
this.elements[value] = true;
|
||||
return this.size++;
|
||||
};
|
||||
|
||||
ShimSet.prototype["delete"] = function(value) {
|
||||
if (!this.elements[value]) {
|
||||
return;
|
||||
}
|
||||
delete this.elements[value];
|
||||
return this.size--;
|
||||
};
|
||||
|
||||
return ShimSet;
|
||||
|
||||
})();
|
||||
|
||||
if (!('Set' in window)) {
|
||||
window.Set = ShimSet;
|
||||
}
|
||||
|
||||
Polyfill = {
|
||||
init: function() {
|
||||
this.notificationPermission();
|
||||
@ -6023,7 +6057,6 @@
|
||||
|
||||
QuoteThreading = {
|
||||
init: function() {
|
||||
var input;
|
||||
if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) {
|
||||
return;
|
||||
}
|
||||
@ -6031,123 +6064,164 @@
|
||||
this.controls = $.el('span', {
|
||||
innerHTML: "<label><input id=\"threadingControl\" type=\"checkbox\" checked> Threading</label>"
|
||||
});
|
||||
input = $('input', this.controls);
|
||||
$.on(input, 'change', this.toggle);
|
||||
this.threadNewLink = $.el('span', {
|
||||
className: 'brackets-wrap threadnewlink',
|
||||
hidden: true
|
||||
});
|
||||
$.extend(this.threadNewLink, {
|
||||
innerHTML: "<a href=\"javascript:;\">Thread New Posts</a>"
|
||||
});
|
||||
$.on($('input', this.controls), 'change', function() {
|
||||
return QuoteThreading.rethread(this.checked);
|
||||
});
|
||||
$.on(this.threadNewLink.firstElementChild, 'click', function() {
|
||||
QuoteThreading.threadNewLink.hidden = true;
|
||||
return QuoteThreading.rethread(true);
|
||||
});
|
||||
Header.menu.addEntry(this.entry = {
|
||||
el: this.controls,
|
||||
order: 98
|
||||
});
|
||||
Thread.callbacks.push({
|
||||
name: 'Quote Threading',
|
||||
cb: this.setThread
|
||||
});
|
||||
return Post.callbacks.push({
|
||||
name: 'Quote Threading',
|
||||
cb: this.node
|
||||
});
|
||||
},
|
||||
force: function() {
|
||||
g.posts.forEach(function(post) {
|
||||
if (post.cb) {
|
||||
return post.cb(true);
|
||||
}
|
||||
parent: {},
|
||||
children: {},
|
||||
inserted: {},
|
||||
setThread: function() {
|
||||
QuoteThreading.thread = this;
|
||||
return $.asap((function() {
|
||||
return !Conf['Thread Updater'] || $('.navLinksBot > .updatelink');
|
||||
}), function() {
|
||||
return $.add($('.navLinksBot'), [$.tn(' '), QuoteThreading.threadNewLink]);
|
||||
});
|
||||
Unread.read();
|
||||
return Unread.update();
|
||||
},
|
||||
node: function() {
|
||||
var keys, len, posts, quote, _i, _len, _ref;
|
||||
posts = g.posts;
|
||||
if (this.isClone || !QuoteThreading.enabled) {
|
||||
var parent, parents, quote, thread;
|
||||
if (this.isFetchedQuote || this.isClone || !this.isReply) {
|
||||
return;
|
||||
}
|
||||
Unread.addPost(this);
|
||||
if (this.thread.OP === this || this.isHidden) {
|
||||
return;
|
||||
thread = QuoteThreading.thread;
|
||||
parents = (function() {
|
||||
var _i, _len, _ref, _results;
|
||||
_ref = this.quotes;
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
quote = _ref[_i];
|
||||
parent = g.posts[quote];
|
||||
if (!parent || parent.isFetchedQuote || !parent.isReply || parent.ID >= this.ID) {
|
||||
continue;
|
||||
}
|
||||
_results.push(parent);
|
||||
}
|
||||
return _results;
|
||||
}).call(this);
|
||||
if (parents.length === 1) {
|
||||
return QuoteThreading.parent[this.fullID] = parents[0];
|
||||
}
|
||||
keys = [];
|
||||
len = g.BOARD.ID.length + 1;
|
||||
_ref = this.quotes;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
quote = _ref[_i];
|
||||
if ((quote.slice(len) < this.ID) && quote in posts) {
|
||||
keys.push(quote);
|
||||
},
|
||||
descendants: function(post) {
|
||||
var child, children, posts, _i, _len;
|
||||
posts = [post];
|
||||
if (children = QuoteThreading.children[post.fullID]) {
|
||||
for (_i = 0, _len = children.length; _i < _len; _i++) {
|
||||
child = children[_i];
|
||||
posts = posts.concat(QuoteThreading.descendants(child));
|
||||
}
|
||||
}
|
||||
if (keys.length !== 1) {
|
||||
return;
|
||||
}
|
||||
this.threaded = keys[0];
|
||||
return this.cb = QuoteThreading.nodeinsert;
|
||||
return posts;
|
||||
},
|
||||
nodeinsert: function(force) {
|
||||
var bottom, height, post, posts, root, threadContainer, top, _ref;
|
||||
post = g.posts[this.threaded];
|
||||
if (this.thread.OP === post) {
|
||||
insert: function(post) {
|
||||
var child, children, descendants, i, next, nodes, order, parent, prev, prev2, threadContainer, x, _base, _i, _j, _k, _len, _name;
|
||||
if (!(QuoteThreading.enabled && (parent = QuoteThreading.parent[post.fullID]) && !QuoteThreading.inserted[post.fullID])) {
|
||||
return false;
|
||||
}
|
||||
posts = Unread.posts;
|
||||
root = post.nodes.root;
|
||||
if (!force) {
|
||||
height = doc.clientHeight;
|
||||
_ref = root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top;
|
||||
if (!(posts[post.ID] || ((bottom < height) && (top > 0)))) {
|
||||
return false;
|
||||
descendants = QuoteThreading.descendants(post);
|
||||
if (!Unread.posts.has(parent.ID) && descendants.some(function(x) {
|
||||
return Unread.posts.has(x.ID);
|
||||
})) {
|
||||
QuoteThreading.threadNewLink.hidden = false;
|
||||
return false;
|
||||
}
|
||||
order = Unread.order;
|
||||
children = ((_base = QuoteThreading.children)[_name = parent.fullID] || (_base[_name] = []));
|
||||
threadContainer = parent.nodes.threadContainer || $.el('div', {
|
||||
className: 'threadContainer'
|
||||
});
|
||||
nodes = [post.nodes.root];
|
||||
if (post.nodes.threadContainer) {
|
||||
nodes.push(post.nodes.threadContainer);
|
||||
}
|
||||
i = children.length;
|
||||
for (_i = children.length - 1; _i >= 0; _i += -1) {
|
||||
child = children[_i];
|
||||
if (child.ID >= post.ID) {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if ($.hasClass(root, 'threadOP')) {
|
||||
threadContainer = root.nextElementSibling;
|
||||
post = Get.postFromRoot($.x('descendant::div[contains(@class,"postContainer")][last()]', threadContainer));
|
||||
$.add(threadContainer, this.nodes.root);
|
||||
if (i !== children.length) {
|
||||
next = children[i];
|
||||
for (_j = 0, _len = descendants.length; _j < _len; _j++) {
|
||||
x = descendants[_j];
|
||||
order.before(order[next.ID], order[x.ID]);
|
||||
}
|
||||
children.splice(i, 0, post);
|
||||
$.before(next.nodes.root, nodes);
|
||||
} else {
|
||||
threadContainer = $.el('div', {
|
||||
className: 'threadContainer'
|
||||
});
|
||||
$.add(threadContainer, this.nodes.root);
|
||||
$.after(root, threadContainer);
|
||||
$.addClass(root, 'threadOP');
|
||||
prev = parent;
|
||||
while ((prev2 = QuoteThreading.children[prev.fullID]) && prev2.length) {
|
||||
prev = prev2[prev2.length - 1];
|
||||
}
|
||||
for (_k = descendants.length - 1; _k >= 0; _k += -1) {
|
||||
x = descendants[_k];
|
||||
order.after(order[prev.ID], order[x.ID]);
|
||||
}
|
||||
children.push(post);
|
||||
$.add(threadContainer, nodes);
|
||||
}
|
||||
if (post = posts[post.ID]) {
|
||||
posts.after(post, posts[this.ID]);
|
||||
} else if (posts[this.ID]) {
|
||||
posts.prepend(posts[this.ID]);
|
||||
QuoteThreading.inserted[post.fullID] = true;
|
||||
if (!parent.nodes.threadContainer) {
|
||||
parent.nodes.threadContainer = threadContainer;
|
||||
$.addClass(parent.nodes.root, 'threadOP');
|
||||
$.after(parent.nodes.root, threadContainer);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
toggle: function() {
|
||||
var container, containers, nodes, post, posts, thread, _i, _j, _k, _len, _len1, _len2, _ref;
|
||||
if (QuoteThreading.enabled = this.checked) {
|
||||
QuoteThreading.force();
|
||||
rethread: function(enabled) {
|
||||
var nodes, posts, thread;
|
||||
thread = QuoteThreading.thread;
|
||||
posts = thread.posts;
|
||||
if (QuoteThreading.enabled = enabled) {
|
||||
posts.forEach(QuoteThreading.insert);
|
||||
} else {
|
||||
thread = $('.thread');
|
||||
posts = [];
|
||||
nodes = [];
|
||||
g.posts.forEach(function(post) {
|
||||
if (!(post === post.thread.OP || post.isClone)) {
|
||||
return posts.push(post);
|
||||
Unread.order = new RandomAccessList;
|
||||
QuoteThreading.inserted = {};
|
||||
posts.forEach(function(post) {
|
||||
Unread.order.push(post);
|
||||
if (post.isReply) {
|
||||
nodes.push(post.nodes.root);
|
||||
}
|
||||
if (QuoteThreading.children[post.fullID]) {
|
||||
delete QuoteThreading.children[post.fullID];
|
||||
$.rmClass(post.nodes.root, 'threadOP');
|
||||
$.rm(post.nodes.threadContainer);
|
||||
return delete post.nodes.threadContainer;
|
||||
}
|
||||
});
|
||||
posts.sort(function(a, b) {
|
||||
return a.ID - b.ID;
|
||||
});
|
||||
for (_i = 0, _len = posts.length; _i < _len; _i++) {
|
||||
post = posts[_i];
|
||||
nodes.push(post.nodes.root);
|
||||
}
|
||||
$.add(thread, nodes);
|
||||
containers = $$('.threadContainer', thread);
|
||||
for (_j = 0, _len1 = containers.length; _j < _len1; _j++) {
|
||||
container = containers[_j];
|
||||
$.rm(container);
|
||||
}
|
||||
_ref = $$('.threadOP');
|
||||
for (_k = 0, _len2 = _ref.length; _k < _len2; _k++) {
|
||||
post = _ref[_k];
|
||||
$.rmClass(post, 'threadOP');
|
||||
}
|
||||
$.add(thread.OP.nodes.root.parentNode, nodes);
|
||||
}
|
||||
},
|
||||
kb: function() {
|
||||
var control;
|
||||
control = $.id('threadingControl');
|
||||
control.checked = !control.checked;
|
||||
return QuoteThreading.toggle.call(control);
|
||||
Unread.position = Unread.order.first;
|
||||
Unread.updatePosition();
|
||||
Unread.setLine(true);
|
||||
Unread.read();
|
||||
return Unread.update();
|
||||
}
|
||||
};
|
||||
|
||||
@ -8861,44 +8935,34 @@
|
||||
}
|
||||
},
|
||||
toggle: function(post) {
|
||||
var headRect, left, root, top, x, y, _ref;
|
||||
var next;
|
||||
if (!(post.file.isExpanding || post.file.isExpanded)) {
|
||||
post.file.scrollIntoView = Conf['Scroll into view'];
|
||||
ImageExpand.expand(post);
|
||||
return;
|
||||
}
|
||||
ImageExpand.contract(post);
|
||||
root = post.nodes.root;
|
||||
_ref = (Conf['Advance on contract'] ? (function() {
|
||||
var next;
|
||||
next = root;
|
||||
if (Conf['Advance on contract']) {
|
||||
next = post.nodes.root;
|
||||
while (next = $.x("following::div[contains(@class,'postContainer')][1]", next)) {
|
||||
if ($('.stub', next) || next.offsetHeight === 0) {
|
||||
continue;
|
||||
if (!($('.stub', next) || next.offsetHeight === 0)) {
|
||||
break;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
return root;
|
||||
})() : root).getBoundingClientRect(), top = _ref.top, left = _ref.left;
|
||||
if (top < 0) {
|
||||
y = top;
|
||||
if (Conf['Fixed Header'] && !Conf['Bottom Header']) {
|
||||
headRect = Header.bar.getBoundingClientRect();
|
||||
y -= headRect.top + headRect.height;
|
||||
if (next) {
|
||||
return Header.scrollTo(next);
|
||||
}
|
||||
}
|
||||
if (left < 0) {
|
||||
x = -window.scrollX;
|
||||
}
|
||||
if (x || y) {
|
||||
return window.scrollBy(x, y);
|
||||
}
|
||||
},
|
||||
contract: function(post) {
|
||||
var bottom, cb, el, eventName, file, oldHeight, x, _i, _len, _ref, _ref1;
|
||||
var bottom, cb, el, eventName, file, oldHeight, scrollY, top, x, _i, _len, _ref, _ref1;
|
||||
file = post.file;
|
||||
bottom = post.nodes.root.getBoundingClientRect().bottom;
|
||||
oldHeight = d.body.clientHeight;
|
||||
if (el = file.fullImage) {
|
||||
top = Header.getTopOf(el);
|
||||
bottom = top + el.getBoundingClientRect().height;
|
||||
oldHeight = d.body.clientHeight;
|
||||
scrollY = window.scrollY;
|
||||
}
|
||||
$.rmClass(post.nodes.root, 'expanded-image');
|
||||
$.rmClass(file.thumb, 'expanding');
|
||||
if (file.videoControls) {
|
||||
@ -8911,35 +8975,43 @@
|
||||
x = _ref[_i];
|
||||
delete file[x];
|
||||
}
|
||||
if (doc.contains(post.nodes.root) && bottom <= 0) {
|
||||
window.scrollBy(0, d.body.clientHeight - oldHeight);
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
if (el = file.fullImage) {
|
||||
$.off(el, 'error', ImageExpand.error);
|
||||
ImageCommon.pushCache(el);
|
||||
if (file.isVideo) {
|
||||
el.pause();
|
||||
_ref1 = ImageExpand.videoCB;
|
||||
for (eventName in _ref1) {
|
||||
cb = _ref1[eventName];
|
||||
$.off(el, eventName, cb);
|
||||
}
|
||||
if (doc.contains(el)) {
|
||||
if (bottom <= 0) {
|
||||
window.scroll(0, scrollY + d.body.clientHeight - oldHeight);
|
||||
} else {
|
||||
Header.scrollToIfNeeded(post.nodes.root);
|
||||
}
|
||||
if (Conf['Restart when Opened']) {
|
||||
ImageCommon.rewind(file.thumb);
|
||||
if (window.scrollX > 0) {
|
||||
window.scroll(0, window.scrollY);
|
||||
}
|
||||
delete file.fullImage;
|
||||
return $.queueTask(function() {
|
||||
if (file.isExpanding || file.isExpanded) {
|
||||
return;
|
||||
}
|
||||
$.rmClass(el, 'full-image');
|
||||
if (el.id) {
|
||||
return;
|
||||
}
|
||||
return $.rm(el);
|
||||
});
|
||||
}
|
||||
$.off(el, 'error', ImageExpand.error);
|
||||
ImageCommon.pushCache(el);
|
||||
if (file.isVideo) {
|
||||
el.pause();
|
||||
_ref1 = ImageExpand.videoCB;
|
||||
for (eventName in _ref1) {
|
||||
cb = _ref1[eventName];
|
||||
$.off(el, eventName, cb);
|
||||
}
|
||||
}
|
||||
if (Conf['Restart when Opened']) {
|
||||
ImageCommon.rewind(file.thumb);
|
||||
}
|
||||
delete file.fullImage;
|
||||
return $.queueTask(function() {
|
||||
if (file.isExpanding || file.isExpanded) {
|
||||
return;
|
||||
}
|
||||
$.rmClass(el, 'full-image');
|
||||
if (el.id) {
|
||||
return;
|
||||
}
|
||||
return $.rm(el);
|
||||
});
|
||||
},
|
||||
expand: function(post, src) {
|
||||
var el, file, isVideo, thumb, _ref;
|
||||
@ -8992,19 +9064,20 @@
|
||||
}
|
||||
},
|
||||
completeExpand: function(post) {
|
||||
var bottom, file, imageBottom, oldHeight;
|
||||
var bottom, file, imageBottom, oldHeight, scrollY;
|
||||
file = post.file;
|
||||
if (!file.isExpanding) {
|
||||
return;
|
||||
}
|
||||
bottom = post.nodes.root.getBoundingClientRect().bottom;
|
||||
bottom = Header.getTopOf(file.thumb) + file.thumb.getBoundingClientRect().height;
|
||||
oldHeight = d.body.clientHeight;
|
||||
scrollY = window.scrollY;
|
||||
$.addClass(post.nodes.root, 'expanded-image');
|
||||
$.rmClass(file.thumb, 'expanding');
|
||||
file.isExpanded = true;
|
||||
delete file.isExpanding;
|
||||
if (doc.contains(post.nodes.root) && bottom <= 0) {
|
||||
window.scrollBy(0, d.body.clientHeight - oldHeight);
|
||||
window.scroll(window.scrollX, scrollY + d.body.clientHeight - oldHeight);
|
||||
}
|
||||
if (file.scrollIntoView) {
|
||||
delete file.scrollIntoView;
|
||||
@ -9206,7 +9279,7 @@
|
||||
ImageCommon.rewind(this);
|
||||
}
|
||||
el.id = 'ihover';
|
||||
$.after(Header.hover, el);
|
||||
$.add(Header.hover, el);
|
||||
if (isVideo) {
|
||||
el.loop = true;
|
||||
el.controls = false;
|
||||
@ -11142,7 +11215,7 @@
|
||||
return new Notice('info', "The thread is " + change + ".", 30);
|
||||
},
|
||||
parse: function(postObjects) {
|
||||
var OP, count, files, index, ipCountEl, node, num, post, postObject, posts, root, scroll, _i, _j, _len, _len1;
|
||||
var OP, count, files, index, ipCountEl, node, num, post, postObject, posts, scroll, _i, _j, _len, _len1;
|
||||
OP = postObjects[0];
|
||||
Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler;
|
||||
ThreadUpdater.thread.setStatus('Archived', !!+OP.archived);
|
||||
@ -11205,13 +11278,8 @@
|
||||
scroll = Conf['Auto Scroll'] && ThreadUpdater.scrollBG() && ThreadUpdater.root.getBoundingClientRect().bottom - doc.clientHeight < 25;
|
||||
for (_j = 0, _len1 = posts.length; _j < _len1; _j++) {
|
||||
post = posts[_j];
|
||||
root = post.nodes.root;
|
||||
if (post.cb) {
|
||||
if (!post.cb()) {
|
||||
$.add(ThreadUpdater.root, root);
|
||||
}
|
||||
} else {
|
||||
$.add(ThreadUpdater.root, root);
|
||||
if (!QuoteThreading.insert(post)) {
|
||||
$.add(ThreadUpdater.root, post.nodes.root);
|
||||
}
|
||||
}
|
||||
$.event('PostsInserted');
|
||||
@ -11474,7 +11542,7 @@
|
||||
defaultValue: 0
|
||||
});
|
||||
unread = quotingYou = 0;
|
||||
_ref = this.response.posts.slice(1);
|
||||
_ref = this.response.posts;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
postObj = _ref[_i];
|
||||
if (!(postObj.no > lastReadPost)) {
|
||||
@ -11810,68 +11878,76 @@
|
||||
this.hr = $.el('hr', {
|
||||
id: 'unread-line'
|
||||
});
|
||||
this.posts = new RandomAccessList;
|
||||
this.postsQuotingYou = {};
|
||||
return Thread.callbacks.push({
|
||||
this.posts = new Set;
|
||||
this.postsQuotingYou = new Set;
|
||||
this.order = new RandomAccessList;
|
||||
this.position = null;
|
||||
Thread.callbacks.push({
|
||||
name: 'Unread',
|
||||
cb: this.node
|
||||
});
|
||||
return Post.callbacks.push({
|
||||
name: 'Unread',
|
||||
cb: this.addPost
|
||||
});
|
||||
},
|
||||
node: function() {
|
||||
var ID, _i, _len, _ref;
|
||||
Unread.thread = this;
|
||||
Unread.title = d.title;
|
||||
Unread.db.forceSync();
|
||||
Unread.lastReadPost = Unread.db.get({
|
||||
boardID: this.board.ID,
|
||||
threadID: this.ID,
|
||||
defaultValue: 0
|
||||
});
|
||||
Unread.readCount = 0;
|
||||
_ref = this.posts.keys;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
ID = _ref[_i];
|
||||
if (+ID <= Unread.lastReadPost) {
|
||||
Unread.readCount++;
|
||||
}
|
||||
}
|
||||
$.one(d, '4chanXInitFinished', Unread.ready);
|
||||
$.on(d, 'ThreadUpdate', Unread.onUpdate);
|
||||
$.on(d, 'scroll visibilitychange', Unread.read);
|
||||
if (Conf['Unread Line'] && !Conf['Quote Threading']) {
|
||||
if (Conf['Unread Line']) {
|
||||
return $.on(d, 'visibilitychange', Unread.setLine);
|
||||
}
|
||||
},
|
||||
ready: function() {
|
||||
var posts;
|
||||
if (!Conf['Quote Threading']) {
|
||||
posts = [];
|
||||
Unread.thread.posts.forEach(function(post) {
|
||||
if (post.isReply) {
|
||||
return posts.push(post);
|
||||
}
|
||||
});
|
||||
Unread.addPosts(posts);
|
||||
}
|
||||
if (Conf['Quote Threading']) {
|
||||
QuoteThreading.force();
|
||||
}
|
||||
if (Conf['Scroll to Last Read Post'] && !Conf['Quote Threading']) {
|
||||
Unread.setLine(true);
|
||||
Unread.read();
|
||||
Unread.update();
|
||||
if (Conf['Scroll to Last Read Post']) {
|
||||
return Unread.scroll();
|
||||
}
|
||||
},
|
||||
positionPrev: function() {
|
||||
if (Unread.position) {
|
||||
return Unread.position.prev;
|
||||
} else {
|
||||
return Unread.order.last;
|
||||
}
|
||||
},
|
||||
scroll: function() {
|
||||
var ID, hash, posts, root, _i, _ref;
|
||||
var hash, position, root;
|
||||
if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) {
|
||||
return;
|
||||
}
|
||||
posts = Unread.thread.posts;
|
||||
_ref = posts.keys;
|
||||
for (_i = _ref.length - 1; _i >= 0; _i += -1) {
|
||||
ID = _ref[_i];
|
||||
if (!(+ID <= Unread.lastReadPost)) {
|
||||
continue;
|
||||
}
|
||||
root = posts[ID].nodes.root;
|
||||
if (root.getBoundingClientRect().height) {
|
||||
position = Unread.positionPrev();
|
||||
while (position) {
|
||||
root = position.data.nodes.root;
|
||||
if (!root.getBoundingClientRect().height) {
|
||||
position = position.prev;
|
||||
} else {
|
||||
Header.scrollToIfNeeded(root, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
sync: function() {
|
||||
var ID, lastReadPost, _i, _len, _ref;
|
||||
var ID, i, lastReadPost, postIDs, _i, _ref, _ref1;
|
||||
if (Unread.lastReadPost == null) {
|
||||
return;
|
||||
}
|
||||
@ -11884,44 +11960,36 @@
|
||||
return;
|
||||
}
|
||||
Unread.lastReadPost = lastReadPost;
|
||||
_ref = Unread.thread.posts.keys;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
ID = _ref[_i];
|
||||
if (+ID > Unread.lastReadPost) {
|
||||
postIDs = Unread.thread.posts.keys;
|
||||
for (i = _i = _ref = Unread.readCount, _ref1 = postIDs.length; _i < _ref1; i = _i += 1) {
|
||||
ID = +postIDs[i];
|
||||
if (ID > Unread.lastReadPost) {
|
||||
break;
|
||||
}
|
||||
Unread.posts.rm(ID);
|
||||
delete Unread.postsQuotingYou[ID];
|
||||
}
|
||||
if (Conf['Unread Line'] && !Conf['Quote Threading']) {
|
||||
Unread.setLine();
|
||||
Unread.posts["delete"](ID);
|
||||
Unread.postsQuotingYou["delete"](ID);
|
||||
Unread.readCount++;
|
||||
}
|
||||
Unread.updatePosition();
|
||||
Unread.setLine();
|
||||
return Unread.update();
|
||||
},
|
||||
addPost: function(post) {
|
||||
addPost: function() {
|
||||
var _ref;
|
||||
if (post.ID <= Unread.lastReadPost || post.isHidden || ((_ref = QR.db) != null ? _ref.get({
|
||||
boardID: post.board.ID,
|
||||
threadID: post.thread.ID,
|
||||
postID: post.ID
|
||||
if (this.isFetchedQuote || this.isClone) {
|
||||
return;
|
||||
}
|
||||
Unread.order.push(this);
|
||||
if (this.ID <= Unread.lastReadPost || this.isHidden || ((_ref = QR.db) != null ? _ref.get({
|
||||
boardID: this.board.ID,
|
||||
threadID: this.thread.ID,
|
||||
postID: this.ID
|
||||
}) : void 0)) {
|
||||
return;
|
||||
}
|
||||
Unread.posts.push(post);
|
||||
return Unread.addPostQuotingYou(post);
|
||||
},
|
||||
addPosts: function(posts) {
|
||||
var oldCount, post, _i, _len;
|
||||
oldCount = Unread.posts.length;
|
||||
for (_i = 0, _len = posts.length; _i < _len; _i++) {
|
||||
post = posts[_i];
|
||||
Unread.addPost(post);
|
||||
}
|
||||
if (Conf['Unread Line'] && !Conf['Quote Threading']) {
|
||||
Unread.setLine(oldCount === 0 && Unread.posts.length !== 0);
|
||||
}
|
||||
Unread.read();
|
||||
return Unread.update();
|
||||
Unread.posts.add(this.ID);
|
||||
Unread.addPostQuotingYou(this);
|
||||
return Unread.position != null ? Unread.position : Unread.position = Unread.order[this.ID];
|
||||
},
|
||||
addPostQuotingYou: function(post) {
|
||||
var quotelink, _i, _len, _ref, _ref1;
|
||||
@ -11931,7 +11999,7 @@
|
||||
if (!((_ref1 = QR.db) != null ? _ref1.get(Get.postDataFromLink(quotelink)) : void 0)) {
|
||||
continue;
|
||||
}
|
||||
Unread.postsQuotingYou[post.ID] = post;
|
||||
Unread.postsQuotingYou.add(post.ID);
|
||||
Unread.openNotification(post);
|
||||
return;
|
||||
}
|
||||
@ -11956,80 +12024,76 @@
|
||||
};
|
||||
},
|
||||
onUpdate: function(e) {
|
||||
var fullID;
|
||||
if (e.detail[404]) {
|
||||
return Unread.update();
|
||||
} else if (!QuoteThreading.enabled) {
|
||||
return Unread.addPosts((function() {
|
||||
var _i, _len, _ref, _results;
|
||||
_ref = e.detail.newPosts;
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
fullID = _ref[_i];
|
||||
_results.push(g.posts[fullID]);
|
||||
}
|
||||
return _results;
|
||||
})());
|
||||
} else {
|
||||
if (!e.detail[404]) {
|
||||
Unread.setLine();
|
||||
Unread.read();
|
||||
return Unread.update();
|
||||
}
|
||||
return Unread.update();
|
||||
},
|
||||
readSinglePost: function(post) {
|
||||
var ID, posts;
|
||||
var ID;
|
||||
ID = post.ID;
|
||||
posts = Unread.posts;
|
||||
if (!posts[ID]) {
|
||||
if (!Unread.posts.has(ID)) {
|
||||
return;
|
||||
}
|
||||
posts.rm(ID);
|
||||
delete Unread.postsQuotingYou[ID];
|
||||
Unread.posts["delete"](ID);
|
||||
Unread.postsQuotingYou["delete"](ID);
|
||||
Unread.updatePosition();
|
||||
Unread.saveLastReadPost();
|
||||
return Unread.update();
|
||||
},
|
||||
read: $.debounce(100, function(e) {
|
||||
var ID, count, data, height, post, posts, _ref;
|
||||
if (d.hidden || !Unread.posts.length) {
|
||||
var ID, count, data, height, root, _ref, _ref1;
|
||||
if (d.hidden || !Unread.posts.size) {
|
||||
return;
|
||||
}
|
||||
height = doc.clientHeight;
|
||||
posts = Unread.posts;
|
||||
count = 0;
|
||||
while (post = posts.first) {
|
||||
if (!(Header.getBottomOf(post.data.nodes.root) > -1)) {
|
||||
while (Unread.position) {
|
||||
_ref = Unread.position, ID = _ref.ID, data = _ref.data;
|
||||
root = data.nodes.root;
|
||||
if (!(!root.getBoundingClientRect().height || Header.getBottomOf(root) > -1)) {
|
||||
break;
|
||||
}
|
||||
ID = post.ID, data = post.data;
|
||||
count++;
|
||||
posts.rm(ID);
|
||||
delete Unread.postsQuotingYou[ID];
|
||||
if (Conf['Mark Quotes of You'] && ((_ref = QR.db) != null ? _ref.get({
|
||||
Unread.posts["delete"](ID);
|
||||
Unread.postsQuotingYou["delete"](ID);
|
||||
if (Conf['Mark Quotes of You'] && ((_ref1 = QR.db) != null ? _ref1.get({
|
||||
boardID: data.board.ID,
|
||||
threadID: data.thread.ID,
|
||||
postID: ID
|
||||
}) : void 0)) {
|
||||
QuoteYou.lastRead = data.nodes.root;
|
||||
QuoteYou.lastRead = root;
|
||||
}
|
||||
Unread.position = Unread.position.next;
|
||||
}
|
||||
if (!count) {
|
||||
return;
|
||||
}
|
||||
Unread.updatePosition();
|
||||
Unread.saveLastReadPost();
|
||||
if (e) {
|
||||
return Unread.update();
|
||||
}
|
||||
}),
|
||||
updatePosition: function() {
|
||||
var _results;
|
||||
_results = [];
|
||||
while (Unread.position && !Unread.posts.has(Unread.position.ID)) {
|
||||
_results.push(Unread.position = Unread.position.next);
|
||||
}
|
||||
return _results;
|
||||
},
|
||||
saveLastReadPost: $.debounce(2 * $.SECOND, function() {
|
||||
var ID, _i, _len, _ref;
|
||||
_ref = Unread.thread.posts.keys;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
ID = _ref[_i];
|
||||
if (Unread.posts[ID]) {
|
||||
var ID, i, postIDs, _i, _ref, _ref1;
|
||||
postIDs = Unread.thread.posts.keys;
|
||||
for (i = _i = _ref = Unread.readCount, _ref1 = postIDs.length; _i < _ref1; i = _i += 1) {
|
||||
ID = +postIDs[i];
|
||||
if (Unread.posts.has(ID)) {
|
||||
break;
|
||||
}
|
||||
if (+ID > Unread.lastReadPost) {
|
||||
Unread.lastReadPost = +ID;
|
||||
}
|
||||
Unread.lastReadPost = ID;
|
||||
Unread.readCount++;
|
||||
}
|
||||
if (Unread.thread.isDead && !Unread.thread.isArchived) {
|
||||
return;
|
||||
@ -12042,26 +12106,22 @@
|
||||
});
|
||||
}),
|
||||
setLine: function(force) {
|
||||
var ID, posts, _i, _ref;
|
||||
if (!(d.hidden || force === true)) {
|
||||
if (!Conf['Unread Line']) {
|
||||
return;
|
||||
}
|
||||
if (!Unread.posts.length) {
|
||||
return $.rm(Unread.hr);
|
||||
}
|
||||
posts = Unread.thread.posts;
|
||||
_ref = posts.keys;
|
||||
for (_i = _ref.length - 1; _i >= 0; _i += -1) {
|
||||
ID = _ref[_i];
|
||||
if (+ID <= Unread.lastReadPost) {
|
||||
return $.after(posts[ID].nodes.root, Unread.hr);
|
||||
if (d.hidden || (force === true)) {
|
||||
if (Unread.linePosition = Unread.positionPrev()) {
|
||||
$.after(Unread.linePosition.data.nodes.root, Unread.hr);
|
||||
} else {
|
||||
$.rm(Unread.hr);
|
||||
}
|
||||
}
|
||||
return Unread.hr.hidden = Unread.linePosition === Unread.order.last;
|
||||
},
|
||||
update: function() {
|
||||
var count, countQuotingYou, titleCount, titleDead, titleQuotingYou;
|
||||
count = Unread.posts.length;
|
||||
countQuotingYou = Object.keys(Unread.postsQuotingYou).length;
|
||||
count = Unread.posts.size;
|
||||
countQuotingYou = Unread.postsQuotingYou.size;
|
||||
if (Conf['Unread Count']) {
|
||||
titleQuotingYou = Conf['Quoted Title'] && countQuotingYou ? '(!) ' : '';
|
||||
titleCount = count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : '';
|
||||
@ -13853,7 +13913,7 @@
|
||||
className: 'dialog'
|
||||
});
|
||||
$.extend(dialog, {
|
||||
innerHTML: "<nav><div class=sections-list></div><p class='imp-exp-result warning'></p><div class=credits><a class=export>Export</a> | <a class=import>Import</a> | <a class=reset>Reset Settings</a> | <input type=file hidden><a href='https://github.com/ccd0/4chan-x' target=_blank>4chan X</a> | <a href='https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md' target=_blank>1.9.13.4</a> | <a href='https://github.com/ccd0/4chan-x/issues' target=_blank>Issues</a> | <a href=javascript:; class='close fa fa-times' title=Close></a></div></nav><div class=section-container><section></section></div>"
|
||||
innerHTML: "<nav><div class=sections-list></div><p class='imp-exp-result warning'></p><div class=credits><a class=export>Export</a> | <a class=import>Import</a> | <a class=reset>Reset Settings</a> | <input type=file hidden><a href='https://github.com/ccd0/4chan-x' target=_blank>4chan X</a> | <a href='https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md' target=_blank>1.9.14.0</a> | <a href='https://github.com/ccd0/4chan-x/issues' target=_blank>Issues</a> | <a href=javascript:; class='close fa fa-times' title=Close></a></div></nav><div class=section-container><section></section></div>"
|
||||
});
|
||||
$.on($('.export', Settings.dialog), 'click', Settings["export"]);
|
||||
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
|
||||
@ -14714,6 +14774,11 @@
|
||||
}
|
||||
Main.callbackNodes(Thread, threads);
|
||||
return Main.callbackNodesDB(Post, posts, function() {
|
||||
var post, _k, _len2;
|
||||
for (_k = 0, _len2 = posts.length; _k < _len2; _k++) {
|
||||
post = posts[_k];
|
||||
QuoteThreading.insert(post);
|
||||
}
|
||||
return $.event('4chanXInitFinished');
|
||||
});
|
||||
} else {
|
||||
|
||||
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.9.13.4
|
||||
// @version 1.9.14.0
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.9.13.4
|
||||
// @version 1.9.14.0
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -24,7 +24,7 @@
|
||||
// ==/UserScript==
|
||||
|
||||
/*
|
||||
* 4chan X - Version 1.9.13.4
|
||||
* 4chan X - Version 1.9.14.0
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||
@ -107,7 +107,7 @@
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var $, $$, Anonymize, ArchiveLink, Banner, Board, Build, Callbacks, CatalogLinks, CatalogThread, Clone, Conf, Config, CrossOrigin, CustomCSS, DataBoard, DeleteLink, DownloadLink, E, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, IDHighlight, ImageCommon, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, MarkNewIPs, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, c, d, doc, g,
|
||||
var $, $$, Anonymize, ArchiveLink, Banner, Board, Build, Callbacks, CatalogLinks, CatalogThread, Clone, Conf, Config, CrossOrigin, CustomCSS, DataBoard, DeleteLink, DownloadLink, E, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, IDHighlight, ImageCommon, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, MarkNewIPs, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, ShimSet, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, c, d, doc, g,
|
||||
__slice = [].slice,
|
||||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
|
||||
__hasProp = {}.hasOwnProperty,
|
||||
@ -388,7 +388,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.9.13.4',
|
||||
VERSION: '1.9.14.0',
|
||||
NAMESPACE: '4chan X.',
|
||||
NAME: '4chan X',
|
||||
FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions',
|
||||
@ -1887,6 +1887,40 @@
|
||||
|
||||
})();
|
||||
|
||||
ShimSet = (function() {
|
||||
function ShimSet() {
|
||||
this.elements = {};
|
||||
this.size = 0;
|
||||
}
|
||||
|
||||
ShimSet.prototype.has = function(value) {
|
||||
return value in this.elements;
|
||||
};
|
||||
|
||||
ShimSet.prototype.add = function(value) {
|
||||
if (this.elements[value]) {
|
||||
return;
|
||||
}
|
||||
this.elements[value] = true;
|
||||
return this.size++;
|
||||
};
|
||||
|
||||
ShimSet.prototype["delete"] = function(value) {
|
||||
if (!this.elements[value]) {
|
||||
return;
|
||||
}
|
||||
delete this.elements[value];
|
||||
return this.size--;
|
||||
};
|
||||
|
||||
return ShimSet;
|
||||
|
||||
})();
|
||||
|
||||
if (!('Set' in window)) {
|
||||
window.Set = ShimSet;
|
||||
}
|
||||
|
||||
Polyfill = {
|
||||
init: function() {
|
||||
this.notificationPermission();
|
||||
@ -6024,7 +6058,6 @@
|
||||
|
||||
QuoteThreading = {
|
||||
init: function() {
|
||||
var input;
|
||||
if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) {
|
||||
return;
|
||||
}
|
||||
@ -6032,123 +6065,164 @@
|
||||
this.controls = $.el('span', {
|
||||
innerHTML: "<label><input id=\"threadingControl\" type=\"checkbox\" checked> Threading</label>"
|
||||
});
|
||||
input = $('input', this.controls);
|
||||
$.on(input, 'change', this.toggle);
|
||||
this.threadNewLink = $.el('span', {
|
||||
className: 'brackets-wrap threadnewlink',
|
||||
hidden: true
|
||||
});
|
||||
$.extend(this.threadNewLink, {
|
||||
innerHTML: "<a href=\"javascript:;\">Thread New Posts</a>"
|
||||
});
|
||||
$.on($('input', this.controls), 'change', function() {
|
||||
return QuoteThreading.rethread(this.checked);
|
||||
});
|
||||
$.on(this.threadNewLink.firstElementChild, 'click', function() {
|
||||
QuoteThreading.threadNewLink.hidden = true;
|
||||
return QuoteThreading.rethread(true);
|
||||
});
|
||||
Header.menu.addEntry(this.entry = {
|
||||
el: this.controls,
|
||||
order: 98
|
||||
});
|
||||
Thread.callbacks.push({
|
||||
name: 'Quote Threading',
|
||||
cb: this.setThread
|
||||
});
|
||||
return Post.callbacks.push({
|
||||
name: 'Quote Threading',
|
||||
cb: this.node
|
||||
});
|
||||
},
|
||||
force: function() {
|
||||
g.posts.forEach(function(post) {
|
||||
if (post.cb) {
|
||||
return post.cb(true);
|
||||
}
|
||||
parent: {},
|
||||
children: {},
|
||||
inserted: {},
|
||||
setThread: function() {
|
||||
QuoteThreading.thread = this;
|
||||
return $.asap((function() {
|
||||
return !Conf['Thread Updater'] || $('.navLinksBot > .updatelink');
|
||||
}), function() {
|
||||
return $.add($('.navLinksBot'), [$.tn(' '), QuoteThreading.threadNewLink]);
|
||||
});
|
||||
Unread.read();
|
||||
return Unread.update();
|
||||
},
|
||||
node: function() {
|
||||
var keys, len, posts, quote, _i, _len, _ref;
|
||||
posts = g.posts;
|
||||
if (this.isClone || !QuoteThreading.enabled) {
|
||||
var parent, parents, quote, thread;
|
||||
if (this.isFetchedQuote || this.isClone || !this.isReply) {
|
||||
return;
|
||||
}
|
||||
Unread.addPost(this);
|
||||
if (this.thread.OP === this || this.isHidden) {
|
||||
return;
|
||||
thread = QuoteThreading.thread;
|
||||
parents = (function() {
|
||||
var _i, _len, _ref, _results;
|
||||
_ref = this.quotes;
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
quote = _ref[_i];
|
||||
parent = g.posts[quote];
|
||||
if (!parent || parent.isFetchedQuote || !parent.isReply || parent.ID >= this.ID) {
|
||||
continue;
|
||||
}
|
||||
_results.push(parent);
|
||||
}
|
||||
return _results;
|
||||
}).call(this);
|
||||
if (parents.length === 1) {
|
||||
return QuoteThreading.parent[this.fullID] = parents[0];
|
||||
}
|
||||
keys = [];
|
||||
len = g.BOARD.ID.length + 1;
|
||||
_ref = this.quotes;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
quote = _ref[_i];
|
||||
if ((quote.slice(len) < this.ID) && quote in posts) {
|
||||
keys.push(quote);
|
||||
},
|
||||
descendants: function(post) {
|
||||
var child, children, posts, _i, _len;
|
||||
posts = [post];
|
||||
if (children = QuoteThreading.children[post.fullID]) {
|
||||
for (_i = 0, _len = children.length; _i < _len; _i++) {
|
||||
child = children[_i];
|
||||
posts = posts.concat(QuoteThreading.descendants(child));
|
||||
}
|
||||
}
|
||||
if (keys.length !== 1) {
|
||||
return;
|
||||
}
|
||||
this.threaded = keys[0];
|
||||
return this.cb = QuoteThreading.nodeinsert;
|
||||
return posts;
|
||||
},
|
||||
nodeinsert: function(force) {
|
||||
var bottom, height, post, posts, root, threadContainer, top, _ref;
|
||||
post = g.posts[this.threaded];
|
||||
if (this.thread.OP === post) {
|
||||
insert: function(post) {
|
||||
var child, children, descendants, i, next, nodes, order, parent, prev, prev2, threadContainer, x, _base, _i, _j, _k, _len, _name;
|
||||
if (!(QuoteThreading.enabled && (parent = QuoteThreading.parent[post.fullID]) && !QuoteThreading.inserted[post.fullID])) {
|
||||
return false;
|
||||
}
|
||||
posts = Unread.posts;
|
||||
root = post.nodes.root;
|
||||
if (!force) {
|
||||
height = doc.clientHeight;
|
||||
_ref = root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top;
|
||||
if (!(posts[post.ID] || ((bottom < height) && (top > 0)))) {
|
||||
return false;
|
||||
descendants = QuoteThreading.descendants(post);
|
||||
if (!Unread.posts.has(parent.ID) && descendants.some(function(x) {
|
||||
return Unread.posts.has(x.ID);
|
||||
})) {
|
||||
QuoteThreading.threadNewLink.hidden = false;
|
||||
return false;
|
||||
}
|
||||
order = Unread.order;
|
||||
children = ((_base = QuoteThreading.children)[_name = parent.fullID] || (_base[_name] = []));
|
||||
threadContainer = parent.nodes.threadContainer || $.el('div', {
|
||||
className: 'threadContainer'
|
||||
});
|
||||
nodes = [post.nodes.root];
|
||||
if (post.nodes.threadContainer) {
|
||||
nodes.push(post.nodes.threadContainer);
|
||||
}
|
||||
i = children.length;
|
||||
for (_i = children.length - 1; _i >= 0; _i += -1) {
|
||||
child = children[_i];
|
||||
if (child.ID >= post.ID) {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if ($.hasClass(root, 'threadOP')) {
|
||||
threadContainer = root.nextElementSibling;
|
||||
post = Get.postFromRoot($.x('descendant::div[contains(@class,"postContainer")][last()]', threadContainer));
|
||||
$.add(threadContainer, this.nodes.root);
|
||||
if (i !== children.length) {
|
||||
next = children[i];
|
||||
for (_j = 0, _len = descendants.length; _j < _len; _j++) {
|
||||
x = descendants[_j];
|
||||
order.before(order[next.ID], order[x.ID]);
|
||||
}
|
||||
children.splice(i, 0, post);
|
||||
$.before(next.nodes.root, nodes);
|
||||
} else {
|
||||
threadContainer = $.el('div', {
|
||||
className: 'threadContainer'
|
||||
});
|
||||
$.add(threadContainer, this.nodes.root);
|
||||
$.after(root, threadContainer);
|
||||
$.addClass(root, 'threadOP');
|
||||
prev = parent;
|
||||
while ((prev2 = QuoteThreading.children[prev.fullID]) && prev2.length) {
|
||||
prev = prev2[prev2.length - 1];
|
||||
}
|
||||
for (_k = descendants.length - 1; _k >= 0; _k += -1) {
|
||||
x = descendants[_k];
|
||||
order.after(order[prev.ID], order[x.ID]);
|
||||
}
|
||||
children.push(post);
|
||||
$.add(threadContainer, nodes);
|
||||
}
|
||||
if (post = posts[post.ID]) {
|
||||
posts.after(post, posts[this.ID]);
|
||||
} else if (posts[this.ID]) {
|
||||
posts.prepend(posts[this.ID]);
|
||||
QuoteThreading.inserted[post.fullID] = true;
|
||||
if (!parent.nodes.threadContainer) {
|
||||
parent.nodes.threadContainer = threadContainer;
|
||||
$.addClass(parent.nodes.root, 'threadOP');
|
||||
$.after(parent.nodes.root, threadContainer);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
toggle: function() {
|
||||
var container, containers, nodes, post, posts, thread, _i, _j, _k, _len, _len1, _len2, _ref;
|
||||
if (QuoteThreading.enabled = this.checked) {
|
||||
QuoteThreading.force();
|
||||
rethread: function(enabled) {
|
||||
var nodes, posts, thread;
|
||||
thread = QuoteThreading.thread;
|
||||
posts = thread.posts;
|
||||
if (QuoteThreading.enabled = enabled) {
|
||||
posts.forEach(QuoteThreading.insert);
|
||||
} else {
|
||||
thread = $('.thread');
|
||||
posts = [];
|
||||
nodes = [];
|
||||
g.posts.forEach(function(post) {
|
||||
if (!(post === post.thread.OP || post.isClone)) {
|
||||
return posts.push(post);
|
||||
Unread.order = new RandomAccessList;
|
||||
QuoteThreading.inserted = {};
|
||||
posts.forEach(function(post) {
|
||||
Unread.order.push(post);
|
||||
if (post.isReply) {
|
||||
nodes.push(post.nodes.root);
|
||||
}
|
||||
if (QuoteThreading.children[post.fullID]) {
|
||||
delete QuoteThreading.children[post.fullID];
|
||||
$.rmClass(post.nodes.root, 'threadOP');
|
||||
$.rm(post.nodes.threadContainer);
|
||||
return delete post.nodes.threadContainer;
|
||||
}
|
||||
});
|
||||
posts.sort(function(a, b) {
|
||||
return a.ID - b.ID;
|
||||
});
|
||||
for (_i = 0, _len = posts.length; _i < _len; _i++) {
|
||||
post = posts[_i];
|
||||
nodes.push(post.nodes.root);
|
||||
}
|
||||
$.add(thread, nodes);
|
||||
containers = $$('.threadContainer', thread);
|
||||
for (_j = 0, _len1 = containers.length; _j < _len1; _j++) {
|
||||
container = containers[_j];
|
||||
$.rm(container);
|
||||
}
|
||||
_ref = $$('.threadOP');
|
||||
for (_k = 0, _len2 = _ref.length; _k < _len2; _k++) {
|
||||
post = _ref[_k];
|
||||
$.rmClass(post, 'threadOP');
|
||||
}
|
||||
$.add(thread.OP.nodes.root.parentNode, nodes);
|
||||
}
|
||||
},
|
||||
kb: function() {
|
||||
var control;
|
||||
control = $.id('threadingControl');
|
||||
control.checked = !control.checked;
|
||||
return QuoteThreading.toggle.call(control);
|
||||
Unread.position = Unread.order.first;
|
||||
Unread.updatePosition();
|
||||
Unread.setLine(true);
|
||||
Unread.read();
|
||||
return Unread.update();
|
||||
}
|
||||
};
|
||||
|
||||
@ -8862,44 +8936,34 @@
|
||||
}
|
||||
},
|
||||
toggle: function(post) {
|
||||
var headRect, left, root, top, x, y, _ref;
|
||||
var next;
|
||||
if (!(post.file.isExpanding || post.file.isExpanded)) {
|
||||
post.file.scrollIntoView = Conf['Scroll into view'];
|
||||
ImageExpand.expand(post);
|
||||
return;
|
||||
}
|
||||
ImageExpand.contract(post);
|
||||
root = post.nodes.root;
|
||||
_ref = (Conf['Advance on contract'] ? (function() {
|
||||
var next;
|
||||
next = root;
|
||||
if (Conf['Advance on contract']) {
|
||||
next = post.nodes.root;
|
||||
while (next = $.x("following::div[contains(@class,'postContainer')][1]", next)) {
|
||||
if ($('.stub', next) || next.offsetHeight === 0) {
|
||||
continue;
|
||||
if (!($('.stub', next) || next.offsetHeight === 0)) {
|
||||
break;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
return root;
|
||||
})() : root).getBoundingClientRect(), top = _ref.top, left = _ref.left;
|
||||
if (top < 0) {
|
||||
y = top;
|
||||
if (Conf['Fixed Header'] && !Conf['Bottom Header']) {
|
||||
headRect = Header.bar.getBoundingClientRect();
|
||||
y -= headRect.top + headRect.height;
|
||||
if (next) {
|
||||
return Header.scrollTo(next);
|
||||
}
|
||||
}
|
||||
if (left < 0) {
|
||||
x = -window.scrollX;
|
||||
}
|
||||
if (x || y) {
|
||||
return window.scrollBy(x, y);
|
||||
}
|
||||
},
|
||||
contract: function(post) {
|
||||
var bottom, cb, el, eventName, file, oldHeight, x, _i, _len, _ref, _ref1;
|
||||
var bottom, cb, el, eventName, file, oldHeight, scrollY, top, x, _i, _len, _ref, _ref1;
|
||||
file = post.file;
|
||||
bottom = post.nodes.root.getBoundingClientRect().bottom;
|
||||
oldHeight = d.body.clientHeight;
|
||||
if (el = file.fullImage) {
|
||||
top = Header.getTopOf(el);
|
||||
bottom = top + el.getBoundingClientRect().height;
|
||||
oldHeight = d.body.clientHeight;
|
||||
scrollY = window.scrollY;
|
||||
}
|
||||
$.rmClass(post.nodes.root, 'expanded-image');
|
||||
$.rmClass(file.thumb, 'expanding');
|
||||
if (file.videoControls) {
|
||||
@ -8912,35 +8976,43 @@
|
||||
x = _ref[_i];
|
||||
delete file[x];
|
||||
}
|
||||
if (doc.contains(post.nodes.root) && bottom <= 0) {
|
||||
window.scrollBy(0, d.body.clientHeight - oldHeight);
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
if (el = file.fullImage) {
|
||||
$.off(el, 'error', ImageExpand.error);
|
||||
ImageCommon.pushCache(el);
|
||||
if (file.isVideo) {
|
||||
el.pause();
|
||||
_ref1 = ImageExpand.videoCB;
|
||||
for (eventName in _ref1) {
|
||||
cb = _ref1[eventName];
|
||||
$.off(el, eventName, cb);
|
||||
}
|
||||
if (doc.contains(el)) {
|
||||
if (bottom <= 0) {
|
||||
window.scroll(0, scrollY + d.body.clientHeight - oldHeight);
|
||||
} else {
|
||||
Header.scrollToIfNeeded(post.nodes.root);
|
||||
}
|
||||
if (Conf['Restart when Opened']) {
|
||||
ImageCommon.rewind(file.thumb);
|
||||
if (window.scrollX > 0) {
|
||||
window.scroll(0, window.scrollY);
|
||||
}
|
||||
delete file.fullImage;
|
||||
return $.queueTask(function() {
|
||||
if (file.isExpanding || file.isExpanded) {
|
||||
return;
|
||||
}
|
||||
$.rmClass(el, 'full-image');
|
||||
if (el.id) {
|
||||
return;
|
||||
}
|
||||
return $.rm(el);
|
||||
});
|
||||
}
|
||||
$.off(el, 'error', ImageExpand.error);
|
||||
ImageCommon.pushCache(el);
|
||||
if (file.isVideo) {
|
||||
el.pause();
|
||||
_ref1 = ImageExpand.videoCB;
|
||||
for (eventName in _ref1) {
|
||||
cb = _ref1[eventName];
|
||||
$.off(el, eventName, cb);
|
||||
}
|
||||
}
|
||||
if (Conf['Restart when Opened']) {
|
||||
ImageCommon.rewind(file.thumb);
|
||||
}
|
||||
delete file.fullImage;
|
||||
return $.queueTask(function() {
|
||||
if (file.isExpanding || file.isExpanded) {
|
||||
return;
|
||||
}
|
||||
$.rmClass(el, 'full-image');
|
||||
if (el.id) {
|
||||
return;
|
||||
}
|
||||
return $.rm(el);
|
||||
});
|
||||
},
|
||||
expand: function(post, src) {
|
||||
var el, file, isVideo, thumb, _ref;
|
||||
@ -8993,19 +9065,20 @@
|
||||
}
|
||||
},
|
||||
completeExpand: function(post) {
|
||||
var bottom, file, imageBottom, oldHeight;
|
||||
var bottom, file, imageBottom, oldHeight, scrollY;
|
||||
file = post.file;
|
||||
if (!file.isExpanding) {
|
||||
return;
|
||||
}
|
||||
bottom = post.nodes.root.getBoundingClientRect().bottom;
|
||||
bottom = Header.getTopOf(file.thumb) + file.thumb.getBoundingClientRect().height;
|
||||
oldHeight = d.body.clientHeight;
|
||||
scrollY = window.scrollY;
|
||||
$.addClass(post.nodes.root, 'expanded-image');
|
||||
$.rmClass(file.thumb, 'expanding');
|
||||
file.isExpanded = true;
|
||||
delete file.isExpanding;
|
||||
if (doc.contains(post.nodes.root) && bottom <= 0) {
|
||||
window.scrollBy(0, d.body.clientHeight - oldHeight);
|
||||
window.scroll(window.scrollX, scrollY + d.body.clientHeight - oldHeight);
|
||||
}
|
||||
if (file.scrollIntoView) {
|
||||
delete file.scrollIntoView;
|
||||
@ -9207,7 +9280,7 @@
|
||||
ImageCommon.rewind(this);
|
||||
}
|
||||
el.id = 'ihover';
|
||||
$.after(Header.hover, el);
|
||||
$.add(Header.hover, el);
|
||||
if (isVideo) {
|
||||
el.loop = true;
|
||||
el.controls = false;
|
||||
@ -11143,7 +11216,7 @@
|
||||
return new Notice('info', "The thread is " + change + ".", 30);
|
||||
},
|
||||
parse: function(postObjects) {
|
||||
var OP, count, files, index, ipCountEl, node, num, post, postObject, posts, root, scroll, _i, _j, _len, _len1;
|
||||
var OP, count, files, index, ipCountEl, node, num, post, postObject, posts, scroll, _i, _j, _len, _len1;
|
||||
OP = postObjects[0];
|
||||
Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler;
|
||||
ThreadUpdater.thread.setStatus('Archived', !!+OP.archived);
|
||||
@ -11206,13 +11279,8 @@
|
||||
scroll = Conf['Auto Scroll'] && ThreadUpdater.scrollBG() && ThreadUpdater.root.getBoundingClientRect().bottom - doc.clientHeight < 25;
|
||||
for (_j = 0, _len1 = posts.length; _j < _len1; _j++) {
|
||||
post = posts[_j];
|
||||
root = post.nodes.root;
|
||||
if (post.cb) {
|
||||
if (!post.cb()) {
|
||||
$.add(ThreadUpdater.root, root);
|
||||
}
|
||||
} else {
|
||||
$.add(ThreadUpdater.root, root);
|
||||
if (!QuoteThreading.insert(post)) {
|
||||
$.add(ThreadUpdater.root, post.nodes.root);
|
||||
}
|
||||
}
|
||||
$.event('PostsInserted');
|
||||
@ -11475,7 +11543,7 @@
|
||||
defaultValue: 0
|
||||
});
|
||||
unread = quotingYou = 0;
|
||||
_ref = this.response.posts.slice(1);
|
||||
_ref = this.response.posts;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
postObj = _ref[_i];
|
||||
if (!(postObj.no > lastReadPost)) {
|
||||
@ -11811,68 +11879,76 @@
|
||||
this.hr = $.el('hr', {
|
||||
id: 'unread-line'
|
||||
});
|
||||
this.posts = new RandomAccessList;
|
||||
this.postsQuotingYou = {};
|
||||
return Thread.callbacks.push({
|
||||
this.posts = new Set;
|
||||
this.postsQuotingYou = new Set;
|
||||
this.order = new RandomAccessList;
|
||||
this.position = null;
|
||||
Thread.callbacks.push({
|
||||
name: 'Unread',
|
||||
cb: this.node
|
||||
});
|
||||
return Post.callbacks.push({
|
||||
name: 'Unread',
|
||||
cb: this.addPost
|
||||
});
|
||||
},
|
||||
node: function() {
|
||||
var ID, _i, _len, _ref;
|
||||
Unread.thread = this;
|
||||
Unread.title = d.title;
|
||||
Unread.db.forceSync();
|
||||
Unread.lastReadPost = Unread.db.get({
|
||||
boardID: this.board.ID,
|
||||
threadID: this.ID,
|
||||
defaultValue: 0
|
||||
});
|
||||
Unread.readCount = 0;
|
||||
_ref = this.posts.keys;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
ID = _ref[_i];
|
||||
if (+ID <= Unread.lastReadPost) {
|
||||
Unread.readCount++;
|
||||
}
|
||||
}
|
||||
$.one(d, '4chanXInitFinished', Unread.ready);
|
||||
$.on(d, 'ThreadUpdate', Unread.onUpdate);
|
||||
$.on(d, 'scroll visibilitychange', Unread.read);
|
||||
if (Conf['Unread Line'] && !Conf['Quote Threading']) {
|
||||
if (Conf['Unread Line']) {
|
||||
return $.on(d, 'visibilitychange', Unread.setLine);
|
||||
}
|
||||
},
|
||||
ready: function() {
|
||||
var posts;
|
||||
if (!Conf['Quote Threading']) {
|
||||
posts = [];
|
||||
Unread.thread.posts.forEach(function(post) {
|
||||
if (post.isReply) {
|
||||
return posts.push(post);
|
||||
}
|
||||
});
|
||||
Unread.addPosts(posts);
|
||||
}
|
||||
if (Conf['Quote Threading']) {
|
||||
QuoteThreading.force();
|
||||
}
|
||||
if (Conf['Scroll to Last Read Post'] && !Conf['Quote Threading']) {
|
||||
Unread.setLine(true);
|
||||
Unread.read();
|
||||
Unread.update();
|
||||
if (Conf['Scroll to Last Read Post']) {
|
||||
return Unread.scroll();
|
||||
}
|
||||
},
|
||||
positionPrev: function() {
|
||||
if (Unread.position) {
|
||||
return Unread.position.prev;
|
||||
} else {
|
||||
return Unread.order.last;
|
||||
}
|
||||
},
|
||||
scroll: function() {
|
||||
var ID, hash, posts, root, _i, _ref;
|
||||
var hash, position, root;
|
||||
if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) {
|
||||
return;
|
||||
}
|
||||
posts = Unread.thread.posts;
|
||||
_ref = posts.keys;
|
||||
for (_i = _ref.length - 1; _i >= 0; _i += -1) {
|
||||
ID = _ref[_i];
|
||||
if (!(+ID <= Unread.lastReadPost)) {
|
||||
continue;
|
||||
}
|
||||
root = posts[ID].nodes.root;
|
||||
if (root.getBoundingClientRect().height) {
|
||||
position = Unread.positionPrev();
|
||||
while (position) {
|
||||
root = position.data.nodes.root;
|
||||
if (!root.getBoundingClientRect().height) {
|
||||
position = position.prev;
|
||||
} else {
|
||||
Header.scrollToIfNeeded(root, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
sync: function() {
|
||||
var ID, lastReadPost, _i, _len, _ref;
|
||||
var ID, i, lastReadPost, postIDs, _i, _ref, _ref1;
|
||||
if (Unread.lastReadPost == null) {
|
||||
return;
|
||||
}
|
||||
@ -11885,44 +11961,36 @@
|
||||
return;
|
||||
}
|
||||
Unread.lastReadPost = lastReadPost;
|
||||
_ref = Unread.thread.posts.keys;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
ID = _ref[_i];
|
||||
if (+ID > Unread.lastReadPost) {
|
||||
postIDs = Unread.thread.posts.keys;
|
||||
for (i = _i = _ref = Unread.readCount, _ref1 = postIDs.length; _i < _ref1; i = _i += 1) {
|
||||
ID = +postIDs[i];
|
||||
if (ID > Unread.lastReadPost) {
|
||||
break;
|
||||
}
|
||||
Unread.posts.rm(ID);
|
||||
delete Unread.postsQuotingYou[ID];
|
||||
}
|
||||
if (Conf['Unread Line'] && !Conf['Quote Threading']) {
|
||||
Unread.setLine();
|
||||
Unread.posts["delete"](ID);
|
||||
Unread.postsQuotingYou["delete"](ID);
|
||||
Unread.readCount++;
|
||||
}
|
||||
Unread.updatePosition();
|
||||
Unread.setLine();
|
||||
return Unread.update();
|
||||
},
|
||||
addPost: function(post) {
|
||||
addPost: function() {
|
||||
var _ref;
|
||||
if (post.ID <= Unread.lastReadPost || post.isHidden || ((_ref = QR.db) != null ? _ref.get({
|
||||
boardID: post.board.ID,
|
||||
threadID: post.thread.ID,
|
||||
postID: post.ID
|
||||
if (this.isFetchedQuote || this.isClone) {
|
||||
return;
|
||||
}
|
||||
Unread.order.push(this);
|
||||
if (this.ID <= Unread.lastReadPost || this.isHidden || ((_ref = QR.db) != null ? _ref.get({
|
||||
boardID: this.board.ID,
|
||||
threadID: this.thread.ID,
|
||||
postID: this.ID
|
||||
}) : void 0)) {
|
||||
return;
|
||||
}
|
||||
Unread.posts.push(post);
|
||||
return Unread.addPostQuotingYou(post);
|
||||
},
|
||||
addPosts: function(posts) {
|
||||
var oldCount, post, _i, _len;
|
||||
oldCount = Unread.posts.length;
|
||||
for (_i = 0, _len = posts.length; _i < _len; _i++) {
|
||||
post = posts[_i];
|
||||
Unread.addPost(post);
|
||||
}
|
||||
if (Conf['Unread Line'] && !Conf['Quote Threading']) {
|
||||
Unread.setLine(oldCount === 0 && Unread.posts.length !== 0);
|
||||
}
|
||||
Unread.read();
|
||||
return Unread.update();
|
||||
Unread.posts.add(this.ID);
|
||||
Unread.addPostQuotingYou(this);
|
||||
return Unread.position != null ? Unread.position : Unread.position = Unread.order[this.ID];
|
||||
},
|
||||
addPostQuotingYou: function(post) {
|
||||
var quotelink, _i, _len, _ref, _ref1;
|
||||
@ -11932,7 +12000,7 @@
|
||||
if (!((_ref1 = QR.db) != null ? _ref1.get(Get.postDataFromLink(quotelink)) : void 0)) {
|
||||
continue;
|
||||
}
|
||||
Unread.postsQuotingYou[post.ID] = post;
|
||||
Unread.postsQuotingYou.add(post.ID);
|
||||
Unread.openNotification(post);
|
||||
return;
|
||||
}
|
||||
@ -11957,80 +12025,76 @@
|
||||
};
|
||||
},
|
||||
onUpdate: function(e) {
|
||||
var fullID;
|
||||
if (e.detail[404]) {
|
||||
return Unread.update();
|
||||
} else if (!QuoteThreading.enabled) {
|
||||
return Unread.addPosts((function() {
|
||||
var _i, _len, _ref, _results;
|
||||
_ref = e.detail.newPosts;
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
fullID = _ref[_i];
|
||||
_results.push(g.posts[fullID]);
|
||||
}
|
||||
return _results;
|
||||
})());
|
||||
} else {
|
||||
if (!e.detail[404]) {
|
||||
Unread.setLine();
|
||||
Unread.read();
|
||||
return Unread.update();
|
||||
}
|
||||
return Unread.update();
|
||||
},
|
||||
readSinglePost: function(post) {
|
||||
var ID, posts;
|
||||
var ID;
|
||||
ID = post.ID;
|
||||
posts = Unread.posts;
|
||||
if (!posts[ID]) {
|
||||
if (!Unread.posts.has(ID)) {
|
||||
return;
|
||||
}
|
||||
posts.rm(ID);
|
||||
delete Unread.postsQuotingYou[ID];
|
||||
Unread.posts["delete"](ID);
|
||||
Unread.postsQuotingYou["delete"](ID);
|
||||
Unread.updatePosition();
|
||||
Unread.saveLastReadPost();
|
||||
return Unread.update();
|
||||
},
|
||||
read: $.debounce(100, function(e) {
|
||||
var ID, count, data, height, post, posts, _ref;
|
||||
if (d.hidden || !Unread.posts.length) {
|
||||
var ID, count, data, height, root, _ref, _ref1;
|
||||
if (d.hidden || !Unread.posts.size) {
|
||||
return;
|
||||
}
|
||||
height = doc.clientHeight;
|
||||
posts = Unread.posts;
|
||||
count = 0;
|
||||
while (post = posts.first) {
|
||||
if (!(Header.getBottomOf(post.data.nodes.root) > -1)) {
|
||||
while (Unread.position) {
|
||||
_ref = Unread.position, ID = _ref.ID, data = _ref.data;
|
||||
root = data.nodes.root;
|
||||
if (!(!root.getBoundingClientRect().height || Header.getBottomOf(root) > -1)) {
|
||||
break;
|
||||
}
|
||||
ID = post.ID, data = post.data;
|
||||
count++;
|
||||
posts.rm(ID);
|
||||
delete Unread.postsQuotingYou[ID];
|
||||
if (Conf['Mark Quotes of You'] && ((_ref = QR.db) != null ? _ref.get({
|
||||
Unread.posts["delete"](ID);
|
||||
Unread.postsQuotingYou["delete"](ID);
|
||||
if (Conf['Mark Quotes of You'] && ((_ref1 = QR.db) != null ? _ref1.get({
|
||||
boardID: data.board.ID,
|
||||
threadID: data.thread.ID,
|
||||
postID: ID
|
||||
}) : void 0)) {
|
||||
QuoteYou.lastRead = data.nodes.root;
|
||||
QuoteYou.lastRead = root;
|
||||
}
|
||||
Unread.position = Unread.position.next;
|
||||
}
|
||||
if (!count) {
|
||||
return;
|
||||
}
|
||||
Unread.updatePosition();
|
||||
Unread.saveLastReadPost();
|
||||
if (e) {
|
||||
return Unread.update();
|
||||
}
|
||||
}),
|
||||
updatePosition: function() {
|
||||
var _results;
|
||||
_results = [];
|
||||
while (Unread.position && !Unread.posts.has(Unread.position.ID)) {
|
||||
_results.push(Unread.position = Unread.position.next);
|
||||
}
|
||||
return _results;
|
||||
},
|
||||
saveLastReadPost: $.debounce(2 * $.SECOND, function() {
|
||||
var ID, _i, _len, _ref;
|
||||
_ref = Unread.thread.posts.keys;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
ID = _ref[_i];
|
||||
if (Unread.posts[ID]) {
|
||||
var ID, i, postIDs, _i, _ref, _ref1;
|
||||
postIDs = Unread.thread.posts.keys;
|
||||
for (i = _i = _ref = Unread.readCount, _ref1 = postIDs.length; _i < _ref1; i = _i += 1) {
|
||||
ID = +postIDs[i];
|
||||
if (Unread.posts.has(ID)) {
|
||||
break;
|
||||
}
|
||||
if (+ID > Unread.lastReadPost) {
|
||||
Unread.lastReadPost = +ID;
|
||||
}
|
||||
Unread.lastReadPost = ID;
|
||||
Unread.readCount++;
|
||||
}
|
||||
if (Unread.thread.isDead && !Unread.thread.isArchived) {
|
||||
return;
|
||||
@ -12043,26 +12107,22 @@
|
||||
});
|
||||
}),
|
||||
setLine: function(force) {
|
||||
var ID, posts, _i, _ref;
|
||||
if (!(d.hidden || force === true)) {
|
||||
if (!Conf['Unread Line']) {
|
||||
return;
|
||||
}
|
||||
if (!Unread.posts.length) {
|
||||
return $.rm(Unread.hr);
|
||||
}
|
||||
posts = Unread.thread.posts;
|
||||
_ref = posts.keys;
|
||||
for (_i = _ref.length - 1; _i >= 0; _i += -1) {
|
||||
ID = _ref[_i];
|
||||
if (+ID <= Unread.lastReadPost) {
|
||||
return $.after(posts[ID].nodes.root, Unread.hr);
|
||||
if (d.hidden || (force === true)) {
|
||||
if (Unread.linePosition = Unread.positionPrev()) {
|
||||
$.after(Unread.linePosition.data.nodes.root, Unread.hr);
|
||||
} else {
|
||||
$.rm(Unread.hr);
|
||||
}
|
||||
}
|
||||
return Unread.hr.hidden = Unread.linePosition === Unread.order.last;
|
||||
},
|
||||
update: function() {
|
||||
var count, countQuotingYou, titleCount, titleDead, titleQuotingYou;
|
||||
count = Unread.posts.length;
|
||||
countQuotingYou = Object.keys(Unread.postsQuotingYou).length;
|
||||
count = Unread.posts.size;
|
||||
countQuotingYou = Unread.postsQuotingYou.size;
|
||||
if (Conf['Unread Count']) {
|
||||
titleQuotingYou = Conf['Quoted Title'] && countQuotingYou ? '(!) ' : '';
|
||||
titleCount = count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : '';
|
||||
@ -13854,7 +13914,7 @@
|
||||
className: 'dialog'
|
||||
});
|
||||
$.extend(dialog, {
|
||||
innerHTML: "<nav><div class=sections-list></div><p class='imp-exp-result warning'></p><div class=credits><a class=export>Export</a> | <a class=import>Import</a> | <a class=reset>Reset Settings</a> | <input type=file hidden><a href='https://github.com/ccd0/4chan-x' target=_blank>4chan X</a> | <a href='https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md' target=_blank>1.9.13.4</a> | <a href='https://github.com/ccd0/4chan-x/issues' target=_blank>Issues</a> | <a href=javascript:; class='close fa fa-times' title=Close></a></div></nav><div class=section-container><section></section></div>"
|
||||
innerHTML: "<nav><div class=sections-list></div><p class='imp-exp-result warning'></p><div class=credits><a class=export>Export</a> | <a class=import>Import</a> | <a class=reset>Reset Settings</a> | <input type=file hidden><a href='https://github.com/ccd0/4chan-x' target=_blank>4chan X</a> | <a href='https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md' target=_blank>1.9.14.0</a> | <a href='https://github.com/ccd0/4chan-x/issues' target=_blank>Issues</a> | <a href=javascript:; class='close fa fa-times' title=Close></a></div></nav><div class=section-container><section></section></div>"
|
||||
});
|
||||
$.on($('.export', Settings.dialog), 'click', Settings["export"]);
|
||||
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
|
||||
@ -14715,6 +14775,11 @@
|
||||
}
|
||||
Main.callbackNodes(Thread, threads);
|
||||
return Main.callbackNodesDB(Post, posts, function() {
|
||||
var post, _k, _len2;
|
||||
for (_k = 0, _len2 = posts.length; _k < _len2; _k++) {
|
||||
post = posts[_k];
|
||||
QuoteThreading.insert(post);
|
||||
}
|
||||
return $.event('4chanXInitFinished');
|
||||
});
|
||||
} else {
|
||||
|
||||
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.9.13.4' />
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X-beta.crx' version='1.9.14.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.9.13.4' />
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X.crx' version='1.9.14.0' />
|
||||
</app>
|
||||
</gupdate>
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
||||
"meta": {
|
||||
"name": "4chan X",
|
||||
"version": "1.9.13.4",
|
||||
"version": "1.9.14.0",
|
||||
"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