Merge branch 'v3'

Conflicts:
	LICENSE
	builds/crx/script.js
This commit is contained in:
Zixaphir 2013-08-06 16:03:07 -07:00
commit 4410a8f118
9 changed files with 407 additions and 361 deletions

View File

@ -1,5 +1,5 @@
/* /*
* appchan x - Version 2.2.2 - 2013-08-05 * appchan x - Version 2.2.2 - 2013-08-06
* *
* Licensed under the MIT license. * Licensed under the MIT license.
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE * https://github.com/zixaphir/appchan-x/blob/master/LICENSE

View File

@ -19,7 +19,7 @@
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAgMAAAAqbBEUAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAHFJREFUKFOt0LENACEIBdBv4Qju4wgWanEj3D6OcIVMKaitYHEU/jwTCQj8W75kiVCSBvdQ5/AvfVHBin11BgdRq3ysBgfwBDRrj3MCIA+oAQaku/Q1cNctrAmyDl577tOThYt/Y1RBM4DgOHzM0HFTAyLukH/cmRnqAAAAAElFTkSuQmCC // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAgMAAAAqbBEUAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAHFJREFUKFOt0LENACEIBdBv4Qju4wgWanEj3D6OcIVMKaitYHEU/jwTCQj8W75kiVCSBvdQ5/AvfVHBin11BgdRq3ysBgfwBDRrj3MCIA+oAQaku/Q1cNctrAmyDl577tOThYt/Y1RBM4DgOHzM0HFTAyLukH/cmRnqAAAAAElFTkSuQmCC
// ==/UserScript== // ==/UserScript==
/* /*
* 4chan X - Version 1.2.25 - 2013-08-05 * 4chan X - Version 1.2.25 - 2013-08-06
* *
* Licensed under the MIT license. * Licensed under the MIT license.
* https://github.com/seaweedchan/4chan-x/blob/master/LICENSE * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE
@ -1787,9 +1787,9 @@
top = post.getBoundingClientRect().top; top = post.getBoundingClientRect().top;
if (Conf['Fixed Header'] && !Conf['Bottom Header']) { if (Conf['Fixed Header'] && !Conf['Bottom Header']) {
headRect = Header.bar.getBoundingClientRect(); headRect = Header.bar.getBoundingClientRect();
top += -headRect.top - headRect.height; top -= headRect.top + headRect.height;
} }
return doc.scrollTop += top; return window.scrollBy(0, top);
}, },
addShortcut: function(el) { addShortcut: function(el) {
var shortcut; var shortcut;
@ -2351,8 +2351,8 @@
$.add(Header.hover, menu); $.add(Header.hover, menu);
mRect = menu.getBoundingClientRect(); mRect = menu.getBoundingClientRect();
bRect = button.getBoundingClientRect(); bRect = button.getBoundingClientRect();
bTop = doc.scrollTop + d.body.scrollTop + bRect.top; bTop = window.scrollY + bRect.top;
bLeft = doc.scrollLeft + d.body.scrollLeft + bRect.left; bLeft = window.scrollX + bRect.left;
cHeight = doc.clientHeight; cHeight = doc.clientHeight;
cWidth = doc.clientWidth; cWidth = doc.clientWidth;
_ref1 = bRect.top + bRect.height + mRect.height < cHeight ? [bRect.bottom, null] : [null, cHeight - bRect.top], top = _ref1[0], bottom = _ref1[1]; _ref1 = bRect.top + bRect.height + mRect.height < cHeight ? [bRect.bottom, null] : [null, cHeight - bRect.top], top = _ref1[0], bottom = _ref1[1];
@ -6283,7 +6283,7 @@
} }
}, },
toggle: function(post) { toggle: function(post) {
var headRect, node, rect, root, thumb, top; var headRect, rect, root, thumb, x, y;
thumb = post.file.thumb; thumb = post.file.thumb;
if (!(post.file.isExpanded || $.hasClass(thumb, 'expanding'))) { if (!(post.file.isExpanded || $.hasClass(thumb, 'expanding'))) {
@ -6291,35 +6291,31 @@
return; return;
} }
ImageExpand.contract(post); ImageExpand.contract(post);
node = post.nodes.root; root = post.nodes.root;
rect = Conf['Advance on contract'] ? (function() { rect = (Conf['Advance on contract'] ? (function() {
while (node.nextElementSibling) { var next;
if (!(node = node.nextElementSibling)) {
return post.nodes.root; next = root;
} while (next = $.x("following::div[contains(@class,'postContainer')][1]", next)) {
if (!$.hasClass(node, 'postContainer')) { if ($('.stub', next) || next.offsetHeight === 0) {
continue; continue;
} }
if (node.offsetHeight > 0 && !$('.stub', node)) { return next;
break;
}
} }
return node.getBoundingClientRect(); return root;
})() : post.nodes.root.getBoundingClientRect(); })() : root).getBoundingClientRect();
if (!(rect.top <= 0 || rect.left <= 0)) {
return;
}
top = rect.top;
if (Conf['Fixed Header'] && !Conf['Bottom Header']) {
headRect = Header.bar.getBoundingClientRect();
top += -headRect.top - headRect.height;
}
root = doc;
if (rect.top < 0) { if (rect.top < 0) {
root.scrollTop += top; y = rect.top;
if (Conf['Fixed Header'] && !Conf['Bottom Header']) {
headRect = Header.bar.getBoundingClientRect();
y -= headRect.top + headRect.height;
}
} }
if (rect.left < 0) { if (rect.left < 0) {
return root.scrollLeft = 0; x = -window.scrollX;
}
if (x || y) {
return window.scrollBy(x, y);
} }
}, },
contract: function(post) { contract: function(post) {
@ -6370,16 +6366,15 @@
} }
prev = post.nodes.root.getBoundingClientRect(); prev = post.nodes.root.getBoundingClientRect();
return $.queueTask(function() { return $.queueTask(function() {
var curr, root; var curr;
$.addClass(post.nodes.root, 'expanded-image'); $.addClass(post.nodes.root, 'expanded-image');
$.rmClass(post.file.thumb, 'expanding'); $.rmClass(post.file.thumb, 'expanding');
if (!(prev.top + prev.height <= 0)) { if (!(prev.top + prev.height <= 0)) {
return; return;
} }
root = doc;
curr = post.nodes.root.getBoundingClientRect(); curr = post.nodes.root.getBoundingClientRect();
return root.scrollTop += curr.height - prev.height + curr.top - prev.top; return window.scrollBy(0, curr.height - prev.height + curr.top - prev.top);
}); });
}, },
error: function() { error: function() {
@ -7613,7 +7608,7 @@
} }
if (scroll) { if (scroll) {
if (Conf['Bottom Scroll']) { if (Conf['Bottom Scroll']) {
doc.scrollTop = d.body.clientHeight; window.scrollTo(0, d.body.clientHeight);
} else { } else {
if (root) { if (root) {
Header.scrollToPost(root); Header.scrollToPost(root);
@ -8612,34 +8607,34 @@
}); });
}, },
node: function() { node: function() {
var a, span; var a, files, posts, span, _ref;
if (!(span = $('.summary', this.OP.nodes.root.parentNode))) { if (!(span = $.x('following-sibling::span[contains(@class,"summary")][1]', this.OP.nodes.root))) {
return; return;
} }
_ref = span.textContent.match(/\d+/g), posts = _ref[0], files = _ref[1];
a = $.el('a', { a = $.el('a', {
textContent: "+ " + span.textContent, textContent: ExpandThread.text('+', posts, files),
className: 'summary', className: 'summary',
href: 'javascript:;' href: 'javascript:;'
}); });
$.on(a, 'click', ExpandThread.cbToggle); $.on(a, 'click', ExpandThread.cbToggle);
return $.replace(span, a); return $.replace(span, a);
}, },
text: function(status, posts, files) {
return ("" + status + " " + posts + " post" + (posts > 1 ? 's' : '')) + (+files ? " and " + files + " image repl" + (files > 1 ? 'ies' : 'y') : "") + (" " + (status === '-' ? 'shown' : 'omitted') + ".");
},
cbToggle: function() { cbToggle: function() {
var op; return ExpandThread.toggle(Get.threadFromRoot(this.parentNode));
op = Get.postFromRoot(this.previousElementSibling);
return ExpandThread.toggle(op.thread);
}, },
toggle: function(thread) { toggle: function(thread) {
var a, inlined, num, post, replies, reply, threadRoot, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; var a, files, filesCount, inlined, num, post, posts, postsCount, reply, threadRoot, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4;
threadRoot = thread.OP.nodes.root.parentNode; threadRoot = thread.OP.nodes.root.parentNode;
a = $('.summary', threadRoot); a = $('.summary', threadRoot);
switch (thread.isExpanded) { switch (thread.isExpanded) {
case false: case false:
case void 0: case void 0:
thread.isExpanded = 'loading';
_ref = $$('.thread > .postContainer', threadRoot); _ref = $$('.thread > .postContainer', threadRoot);
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
post = _ref[_i]; post = _ref[_i];
@ -8650,7 +8645,8 @@
return; return;
} }
thread.isExpanded = 'loading'; thread.isExpanded = 'loading';
a.textContent = a.textContent.replace('+', '...'); _ref1 = a.textContent.match(/\d+/g), posts = _ref1[0], files = _ref1[1];
a.textContent = ExpandThread.text('...', posts, files);
$.cache("//api.4chan.org/" + thread.board + "/res/" + thread + ".json", function() { $.cache("//api.4chan.org/" + thread.board + "/res/" + thread + ".json", function() {
return ExpandThread.parse(this, thread, a); return ExpandThread.parse(this, thread, a);
}); });
@ -8660,84 +8656,99 @@
if (!a) { if (!a) {
return; return;
} }
a.textContent = a.textContent.replace('...', '+'); _ref2 = a.textContent.match(/\d+/g), posts = _ref2[0], files = _ref2[1];
a.textContent = ExpandThread.text('+', posts, files);
break; break;
case true: case true:
thread.isExpanded = false; thread.isExpanded = false;
if (a) { num = (function() {
a.textContent = a.textContent.replace('-', '+').replace('hide', 'view').replace('expanded', 'omitted'); if (thread.isSticky) {
num = (function() { return 1;
if (thread.isSticky) { } else {
return 1; switch (g.BOARD.ID) {
} else { case 'b':
switch (g.BOARD.ID) { case 'vg':
case 'b': case 'q':
case 'vg': return 3;
case 'q': case 't':
return 3; return 1;
case 't': default:
return 1; return 5;
default:
return 5;
}
} }
})();
replies = $$('.thread > .replyContainer', threadRoot).slice(0, -num);
for (_j = 0, _len1 = replies.length; _j < _len1; _j++) {
reply = replies[_j];
if (Conf['Quote Inlining']) {
while (inlined = $('.inlined', reply)) {
inlined.click();
}
}
$.rm(reply);
} }
} })();
_ref1 = $$('.thread > .postContainer', threadRoot); posts = $$(".thread > .replyContainer", threadRoot);
for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { _ref3 = [thread.OP.nodes.root].concat(posts.slice(-num));
post = _ref1[_k]; for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
post = _ref3[_j];
ExpandComment.contract(Get.postFromRoot(post)); ExpandComment.contract(Get.postFromRoot(post));
} }
if (!a) {
return;
}
postsCount = 0;
filesCount = 0;
_ref4 = posts.slice(0, -num);
for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
reply = _ref4[_k];
if (Conf['Quote Inlining']) {
while (inlined = $('.inlined', reply)) {
inlined.click();
}
}
postsCount++;
if ('file' in Get.postFromRoot(reply)) {
filesCount++;
}
$.rm(reply);
}
a.textContent = ExpandThread.text('+', postsCount, filesCount);
} }
}, },
parse: function(req, thread, a) { parse: function(req, thread, a) {
var link, node, nodes, post, posts, replies, reply, spoilerRange, status, _i, _len; var filesCount, link, post, posts, postsCount, postsObj, postsRoot, reply, root, spoilerRange, _i, _len;
if (a.textContent[0] === '+') { if (a.textContent[0] === '+') {
return; return;
} }
status = req.status; if (![200, 304].contains(req.status)) {
if (![200, 304].contains(status)) { a.textContent = "Error " + req.statusText + " (" + req.status + ")";
a.textContent = "Error " + req.statusText + " (" + status + ")"; $.off(a, 'click', ExpandThread.cbToggle);
$.off(a, 'click', ExpandThread.cb.toggle);
return; return;
} }
thread.isExpanded = true; thread.isExpanded = true;
a.textContent = a.textContent.replace('...', '-').replace('view', 'hide').replace('omitted', 'expanded');
posts = JSON.parse(req.response).posts; posts = JSON.parse(req.response).posts;
if (spoilerRange = posts[0].custom_spoiler) { if (spoilerRange = posts.shift().custom_spoiler) {
Build.spoilerRange[g.BOARD] = spoilerRange; Build.spoilerRange[thread.board] = spoilerRange;
} }
replies = posts.slice(1); postsObj = [];
posts = []; postsRoot = [];
nodes = []; filesCount = 0;
for (_i = 0, _len = replies.length; _i < _len; _i++) { for (_i = 0, _len = posts.length; _i < _len; _i++) {
reply = replies[_i]; reply = posts[_i];
if (post = thread.posts[reply.no]) { if (post = thread.posts[reply.no]) {
nodes.push(post.nodes.root); if ('file' in post) {
filesCount++;
}
postsRoot.push(post.nodes.root);
continue; continue;
} }
node = Build.postFromObject(reply, thread.board.ID); root = Build.postFromObject(reply, thread.board.ID);
post = new Post(node, thread, thread.board); post = new Post(root, thread, thread.board);
link = $('a[title="Highlight this post"]', node); link = $('a[title="Highlight this post"]', root);
link.href = "res/" + thread + "#p" + post; link.href = "res/" + thread + "#p" + post;
link.nextSibling.href = "res/" + thread + "#q" + post; link.nextSibling.href = "res/" + thread + "#q" + post;
posts.push(post); if ('file' in post) {
nodes.push(node); filesCount++;
}
postsObj.push(post);
postsRoot.push(root);
} }
Main.callbackNodes(Post, posts); Main.callbackNodes(Post, postsObj);
$.after(a, nodes); $.after(a, postsRoot);
return Fourchan.parseThread(thread.ID, 1, nodes.length); postsCount = postsRoot.length;
a.textContent = ExpandThread.text('-', postsCount, filesCount);
return Fourchan.parseThread(thread.ID, 1, postsCount);
} }
}; };

View File

@ -18,7 +18,7 @@
// ==/UserScript== // ==/UserScript==
/* /*
* appchan x - Version 2.2.2 - 2013-08-05 * appchan x - Version 2.2.2 - 2013-08-06
* *
* Licensed under the MIT license. * Licensed under the MIT license.
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE * https://github.com/zixaphir/appchan-x/blob/master/LICENSE
@ -4082,9 +4082,9 @@
top = post.getBoundingClientRect().top; top = post.getBoundingClientRect().top;
if (Conf['Fixed Header'] && !Conf['Bottom Header']) { if (Conf['Fixed Header'] && !Conf['Bottom Header']) {
headRect = Header.bar.getBoundingClientRect(); headRect = Header.bar.getBoundingClientRect();
top += -headRect.top - headRect.height; top -= headRect.top + headRect.height;
} }
return doc.scrollTop += top; return window.scrollBy(0, top);
}, },
addShortcut: function(el) { addShortcut: function(el) {
var shortcut; var shortcut;
@ -4638,8 +4638,8 @@
$.add(Header.hover, menu); $.add(Header.hover, menu);
mRect = menu.getBoundingClientRect(); mRect = menu.getBoundingClientRect();
bRect = button.getBoundingClientRect(); bRect = button.getBoundingClientRect();
bTop = doc.scrollTop + d.body.scrollTop + bRect.top; bTop = window.scrollY + bRect.top;
bLeft = doc.scrollLeft + d.body.scrollLeft + bRect.left; bLeft = window.scrollX + bRect.left;
cHeight = doc.clientHeight; cHeight = doc.clientHeight;
cWidth = doc.clientWidth; cWidth = doc.clientWidth;
_ref1 = bRect.top + bRect.height + mRect.height < cHeight ? [bRect.bottom, null] : [null, cHeight - bRect.top], top = _ref1[0], bottom = _ref1[1]; _ref1 = bRect.top + bRect.height + mRect.height < cHeight ? [bRect.bottom, null] : [null, cHeight - bRect.top], top = _ref1[0], bottom = _ref1[1];
@ -8612,7 +8612,7 @@
} }
}, },
toggle: function(post) { toggle: function(post) {
var headRect, node, rect, root, thumb, top; var headRect, rect, root, thumb, x, y;
thumb = post.file.thumb; thumb = post.file.thumb;
if (!(post.file.isExpanded || $.hasClass(thumb, 'expanding'))) { if (!(post.file.isExpanded || $.hasClass(thumb, 'expanding'))) {
@ -8620,35 +8620,31 @@
return; return;
} }
ImageExpand.contract(post); ImageExpand.contract(post);
node = post.nodes.root; root = post.nodes.root;
rect = Conf['Advance on contract'] ? (function() { rect = (Conf['Advance on contract'] ? (function() {
while (node.nextElementSibling) { var next;
if (!(node = node.nextElementSibling)) {
return post.nodes.root; next = root;
} while (next = $.x("following::div[contains(@class,'postContainer')][1]", next)) {
if (!$.hasClass(node, 'postContainer')) { if ($('.stub', next) || next.offsetHeight === 0) {
continue; continue;
} }
if (node.offsetHeight > 0 && !$('.stub', node)) { return next;
break;
}
} }
return node.getBoundingClientRect(); return root;
})() : post.nodes.root.getBoundingClientRect(); })() : root).getBoundingClientRect();
if (!(rect.top <= 0 || rect.left <= 0)) {
return;
}
top = rect.top;
if (Conf['Fixed Header'] && !Conf['Bottom Header']) {
headRect = Header.bar.getBoundingClientRect();
top += -headRect.top - headRect.height;
}
root = doc;
if (rect.top < 0) { if (rect.top < 0) {
root.scrollTop += top; y = rect.top;
if (Conf['Fixed Header'] && !Conf['Bottom Header']) {
headRect = Header.bar.getBoundingClientRect();
y -= headRect.top + headRect.height;
}
} }
if (rect.left < 0) { if (rect.left < 0) {
return root.scrollLeft = 0; x = -window.scrollX;
}
if (x || y) {
return window.scrollBy(x, y);
} }
}, },
contract: function(post) { contract: function(post) {
@ -8699,16 +8695,15 @@
} }
prev = post.nodes.root.getBoundingClientRect(); prev = post.nodes.root.getBoundingClientRect();
return $.queueTask(function() { return $.queueTask(function() {
var curr, root; var curr;
$.addClass(post.nodes.root, 'expanded-image'); $.addClass(post.nodes.root, 'expanded-image');
$.rmClass(post.file.thumb, 'expanding'); $.rmClass(post.file.thumb, 'expanding');
if (!(prev.top + prev.height <= 0)) { if (!(prev.top + prev.height <= 0)) {
return; return;
} }
root = doc;
curr = post.nodes.root.getBoundingClientRect(); curr = post.nodes.root.getBoundingClientRect();
return root.scrollTop += curr.height - prev.height + curr.top - prev.top; return window.scrollBy(0, curr.height - prev.height + curr.top - prev.top);
}); });
}, },
error: function() { error: function() {
@ -9958,7 +9953,7 @@
} }
if (scroll) { if (scroll) {
if (Conf['Bottom Scroll']) { if (Conf['Bottom Scroll']) {
doc.scrollTop = d.body.clientHeight; window.scrollTo(0, d.body.clientHeight);
} else { } else {
if (root) { if (root) {
Header.scrollToPost(root); Header.scrollToPost(root);
@ -12452,34 +12447,34 @@
}); });
}, },
node: function() { node: function() {
var a, span; var a, files, posts, span, _ref;
if (!(span = $('.summary', this.OP.nodes.root.parentNode))) { if (!(span = $.x('following-sibling::span[contains(@class,"summary")][1]', this.OP.nodes.root))) {
return; return;
} }
_ref = span.textContent.match(/\d+/g), posts = _ref[0], files = _ref[1];
a = $.el('a', { a = $.el('a', {
textContent: "+ " + span.textContent, textContent: ExpandThread.text('+', posts, files),
className: 'summary', className: 'summary',
href: 'javascript:;' href: 'javascript:;'
}); });
$.on(a, 'click', ExpandThread.cbToggle); $.on(a, 'click', ExpandThread.cbToggle);
return $.replace(span, a); return $.replace(span, a);
}, },
text: function(status, posts, files) {
return ("" + status + " " + posts + " post" + (posts > 1 ? 's' : '')) + (+files ? " and " + files + " image repl" + (files > 1 ? 'ies' : 'y') : "") + (" " + (status === '-' ? 'shown' : 'omitted') + ".");
},
cbToggle: function() { cbToggle: function() {
var op; return ExpandThread.toggle(Get.threadFromRoot(this.parentNode));
op = Get.postFromRoot(this.previousElementSibling);
return ExpandThread.toggle(op.thread);
}, },
toggle: function(thread) { toggle: function(thread) {
var a, inlined, num, post, replies, reply, threadRoot, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; var a, files, filesCount, inlined, num, post, posts, postsCount, reply, threadRoot, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4;
threadRoot = thread.OP.nodes.root.parentNode; threadRoot = thread.OP.nodes.root.parentNode;
a = $('.summary', threadRoot); a = $('.summary', threadRoot);
switch (thread.isExpanded) { switch (thread.isExpanded) {
case false: case false:
case void 0: case void 0:
thread.isExpanded = 'loading';
_ref = $$('.thread > .postContainer', threadRoot); _ref = $$('.thread > .postContainer', threadRoot);
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
post = _ref[_i]; post = _ref[_i];
@ -12490,7 +12485,8 @@
return; return;
} }
thread.isExpanded = 'loading'; thread.isExpanded = 'loading';
a.textContent = a.textContent.replace('+', '...'); _ref1 = a.textContent.match(/\d+/g), posts = _ref1[0], files = _ref1[1];
a.textContent = ExpandThread.text('...', posts, files);
$.cache("//api.4chan.org/" + thread.board + "/res/" + thread + ".json", function() { $.cache("//api.4chan.org/" + thread.board + "/res/" + thread + ".json", function() {
return ExpandThread.parse(this, thread, a); return ExpandThread.parse(this, thread, a);
}); });
@ -12500,84 +12496,99 @@
if (!a) { if (!a) {
return; return;
} }
a.textContent = a.textContent.replace('...', '+'); _ref2 = a.textContent.match(/\d+/g), posts = _ref2[0], files = _ref2[1];
a.textContent = ExpandThread.text('+', posts, files);
break; break;
case true: case true:
thread.isExpanded = false; thread.isExpanded = false;
if (a) { num = (function() {
a.textContent = a.textContent.replace('-', '+').replace('hide', 'view').replace('expanded', 'omitted'); if (thread.isSticky) {
num = (function() { return 1;
if (thread.isSticky) { } else {
return 1; switch (g.BOARD.ID) {
} else { case 'b':
switch (g.BOARD.ID) { case 'vg':
case 'b': case 'q':
case 'vg': return 3;
case 'q': case 't':
return 3; return 1;
case 't': default:
return 1; return 5;
default:
return 5;
}
} }
})();
replies = $$('.thread > .replyContainer', threadRoot).slice(0, -num);
for (_j = 0, _len1 = replies.length; _j < _len1; _j++) {
reply = replies[_j];
if (Conf['Quote Inlining']) {
while (inlined = $('.inlined', reply)) {
inlined.click();
}
}
$.rm(reply);
} }
} })();
_ref1 = $$('.thread > .postContainer', threadRoot); posts = $$(".thread > .replyContainer", threadRoot);
for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { _ref3 = [thread.OP.nodes.root].concat(posts.slice(-num));
post = _ref1[_k]; for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
post = _ref3[_j];
ExpandComment.contract(Get.postFromRoot(post)); ExpandComment.contract(Get.postFromRoot(post));
} }
if (!a) {
return;
}
postsCount = 0;
filesCount = 0;
_ref4 = posts.slice(0, -num);
for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
reply = _ref4[_k];
if (Conf['Quote Inlining']) {
while (inlined = $('.inlined', reply)) {
inlined.click();
}
}
postsCount++;
if ('file' in Get.postFromRoot(reply)) {
filesCount++;
}
$.rm(reply);
}
a.textContent = ExpandThread.text('+', postsCount, filesCount);
} }
}, },
parse: function(req, thread, a) { parse: function(req, thread, a) {
var link, node, nodes, post, posts, replies, reply, spoilerRange, status, _i, _len; var filesCount, link, post, posts, postsCount, postsObj, postsRoot, reply, root, spoilerRange, _i, _len;
if (a.textContent[0] === '+') { if (a.textContent[0] === '+') {
return; return;
} }
status = req.status; if (![200, 304].contains(req.status)) {
if (![200, 304].contains(status)) { a.textContent = "Error " + req.statusText + " (" + req.status + ")";
a.textContent = "Error " + req.statusText + " (" + status + ")"; $.off(a, 'click', ExpandThread.cbToggle);
$.off(a, 'click', ExpandThread.cb.toggle);
return; return;
} }
thread.isExpanded = true; thread.isExpanded = true;
a.textContent = a.textContent.replace('...', '-').replace('view', 'hide').replace('omitted', 'expanded');
posts = JSON.parse(req.response).posts; posts = JSON.parse(req.response).posts;
if (spoilerRange = posts[0].custom_spoiler) { if (spoilerRange = posts.shift().custom_spoiler) {
Build.spoilerRange[g.BOARD] = spoilerRange; Build.spoilerRange[thread.board] = spoilerRange;
} }
replies = posts.slice(1); postsObj = [];
posts = []; postsRoot = [];
nodes = []; filesCount = 0;
for (_i = 0, _len = replies.length; _i < _len; _i++) { for (_i = 0, _len = posts.length; _i < _len; _i++) {
reply = replies[_i]; reply = posts[_i];
if (post = thread.posts[reply.no]) { if (post = thread.posts[reply.no]) {
nodes.push(post.nodes.root); if ('file' in post) {
filesCount++;
}
postsRoot.push(post.nodes.root);
continue; continue;
} }
node = Build.postFromObject(reply, thread.board.ID); root = Build.postFromObject(reply, thread.board.ID);
post = new Post(node, thread, thread.board); post = new Post(root, thread, thread.board);
link = $('a[title="Highlight this post"]', node); link = $('a[title="Highlight this post"]', root);
link.href = "res/" + thread + "#p" + post; link.href = "res/" + thread + "#p" + post;
link.nextSibling.href = "res/" + thread + "#q" + post; link.nextSibling.href = "res/" + thread + "#q" + post;
posts.push(post); if ('file' in post) {
nodes.push(node); filesCount++;
}
postsObj.push(post);
postsRoot.push(root);
} }
Main.callbackNodes(Post, posts); Main.callbackNodes(Post, postsObj);
$.after(a, nodes); $.after(a, postsRoot);
return Fourchan.parseThread(thread.ID, 1, nodes.length); postsCount = postsRoot.length;
a.textContent = ExpandThread.text('-', postsCount, filesCount);
return Fourchan.parseThread(thread.ID, 1, postsCount);
} }
}; };

View File

@ -1,6 +1,6 @@
// Generated by CoffeeScript // Generated by CoffeeScript
/* /*
* appchan x - Version 2.2.2 - 2013-08-05 * appchan x - Version 2.2.2 - 2013-08-06
* *
* Licensed under the MIT license. * Licensed under the MIT license.
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE * https://github.com/zixaphir/appchan-x/blob/master/LICENSE
@ -4095,9 +4095,9 @@
top = post.getBoundingClientRect().top; top = post.getBoundingClientRect().top;
if (Conf['Fixed Header'] && !Conf['Bottom Header']) { if (Conf['Fixed Header'] && !Conf['Bottom Header']) {
headRect = Header.bar.getBoundingClientRect(); headRect = Header.bar.getBoundingClientRect();
top += -headRect.top - headRect.height; top -= headRect.top + headRect.height;
} }
return d.body.scrollTop += top; return window.scrollBy(0, top);
}, },
addShortcut: function(el) { addShortcut: function(el) {
var shortcut; var shortcut;
@ -4651,8 +4651,8 @@
$.add(Header.hover, menu); $.add(Header.hover, menu);
mRect = menu.getBoundingClientRect(); mRect = menu.getBoundingClientRect();
bRect = button.getBoundingClientRect(); bRect = button.getBoundingClientRect();
bTop = doc.scrollTop + d.body.scrollTop + bRect.top; bTop = window.scrollY + bRect.top;
bLeft = doc.scrollLeft + d.body.scrollLeft + bRect.left; bLeft = window.scrollX + bRect.left;
cHeight = doc.clientHeight; cHeight = doc.clientHeight;
cWidth = doc.clientWidth; cWidth = doc.clientWidth;
_ref1 = bRect.top + bRect.height + mRect.height < cHeight ? [bRect.bottom, null] : [null, cHeight - bRect.top], top = _ref1[0], bottom = _ref1[1]; _ref1 = bRect.top + bRect.height + mRect.height < cHeight ? [bRect.bottom, null] : [null, cHeight - bRect.top], top = _ref1[0], bottom = _ref1[1];
@ -8594,7 +8594,7 @@
} }
}, },
toggle: function(post) { toggle: function(post) {
var headRect, node, rect, root, thumb, top; var headRect, rect, root, thumb, x, y;
thumb = post.file.thumb; thumb = post.file.thumb;
if (!(post.file.isExpanded || $.hasClass(thumb, 'expanding'))) { if (!(post.file.isExpanded || $.hasClass(thumb, 'expanding'))) {
@ -8602,35 +8602,31 @@
return; return;
} }
ImageExpand.contract(post); ImageExpand.contract(post);
node = post.nodes.root; root = post.nodes.root;
rect = Conf['Advance on contract'] ? (function() { rect = (Conf['Advance on contract'] ? (function() {
while (node.nextElementSibling) { var next;
if (!(node = node.nextElementSibling)) {
return post.nodes.root; next = root;
} while (next = $.x("following::div[contains(@class,'postContainer')][1]", next)) {
if (!$.hasClass(node, 'postContainer')) { if ($('.stub', next) || next.offsetHeight === 0) {
continue; continue;
} }
if (node.offsetHeight > 0 && !$('.stub', node)) { return next;
break;
}
} }
return node.getBoundingClientRect(); return root;
})() : post.nodes.root.getBoundingClientRect(); })() : root).getBoundingClientRect();
if (!(rect.top <= 0 || rect.left <= 0)) {
return;
}
top = rect.top;
if (Conf['Fixed Header'] && !Conf['Bottom Header']) {
headRect = Header.bar.getBoundingClientRect();
top += -headRect.top - headRect.height;
}
root = d.body;
if (rect.top < 0) { if (rect.top < 0) {
root.scrollTop += top; y = rect.top;
if (Conf['Fixed Header'] && !Conf['Bottom Header']) {
headRect = Header.bar.getBoundingClientRect();
y -= headRect.top + headRect.height;
}
} }
if (rect.left < 0) { if (rect.left < 0) {
return root.scrollLeft = 0; x = -window.scrollX;
}
if (x || y) {
return window.scrollBy(x, y);
} }
}, },
contract: function(post) { contract: function(post) {
@ -8681,16 +8677,15 @@
} }
prev = post.nodes.root.getBoundingClientRect(); prev = post.nodes.root.getBoundingClientRect();
return $.queueTask(function() { return $.queueTask(function() {
var curr, root; var curr;
$.addClass(post.nodes.root, 'expanded-image'); $.addClass(post.nodes.root, 'expanded-image');
$.rmClass(post.file.thumb, 'expanding'); $.rmClass(post.file.thumb, 'expanding');
if (!(prev.top + prev.height <= 0)) { if (!(prev.top + prev.height <= 0)) {
return; return;
} }
root = d.body;
curr = post.nodes.root.getBoundingClientRect(); curr = post.nodes.root.getBoundingClientRect();
return root.scrollTop += curr.height - prev.height + curr.top - prev.top; return window.scrollBy(0, curr.height - prev.height + curr.top - prev.top);
}); });
}, },
error: function() { error: function() {
@ -9940,7 +9935,7 @@
} }
if (scroll) { if (scroll) {
if (Conf['Bottom Scroll']) { if (Conf['Bottom Scroll']) {
d.body.scrollTop = d.body.clientHeight; window.scrollTo(0, d.body.clientHeight);
} else { } else {
if (root) { if (root) {
Header.scrollToPost(root); Header.scrollToPost(root);
@ -12439,34 +12434,34 @@
}); });
}, },
node: function() { node: function() {
var a, span; var a, files, posts, span, _ref;
if (!(span = $('.summary', this.OP.nodes.root.parentNode))) { if (!(span = $.x('following-sibling::span[contains(@class,"summary")][1]', this.OP.nodes.root))) {
return; return;
} }
_ref = span.textContent.match(/\d+/g), posts = _ref[0], files = _ref[1];
a = $.el('a', { a = $.el('a', {
textContent: "+ " + span.textContent, textContent: ExpandThread.text('+', posts, files),
className: 'summary', className: 'summary',
href: 'javascript:;' href: 'javascript:;'
}); });
$.on(a, 'click', ExpandThread.cbToggle); $.on(a, 'click', ExpandThread.cbToggle);
return $.replace(span, a); return $.replace(span, a);
}, },
text: function(status, posts, files) {
return ("" + status + " " + posts + " post" + (posts > 1 ? 's' : '')) + (+files ? " and " + files + " image repl" + (files > 1 ? 'ies' : 'y') : "") + (" " + (status === '-' ? 'shown' : 'omitted') + ".");
},
cbToggle: function() { cbToggle: function() {
var op; return ExpandThread.toggle(Get.threadFromRoot(this.parentNode));
op = Get.postFromRoot(this.previousElementSibling);
return ExpandThread.toggle(op.thread);
}, },
toggle: function(thread) { toggle: function(thread) {
var a, inlined, num, post, replies, reply, threadRoot, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; var a, files, filesCount, inlined, num, post, posts, postsCount, reply, threadRoot, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4;
threadRoot = thread.OP.nodes.root.parentNode; threadRoot = thread.OP.nodes.root.parentNode;
a = $('.summary', threadRoot); a = $('.summary', threadRoot);
switch (thread.isExpanded) { switch (thread.isExpanded) {
case false: case false:
case void 0: case void 0:
thread.isExpanded = 'loading';
_ref = $$('.thread > .postContainer', threadRoot); _ref = $$('.thread > .postContainer', threadRoot);
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
post = _ref[_i]; post = _ref[_i];
@ -12477,7 +12472,8 @@
return; return;
} }
thread.isExpanded = 'loading'; thread.isExpanded = 'loading';
a.textContent = a.textContent.replace('+', '...'); _ref1 = a.textContent.match(/\d+/g), posts = _ref1[0], files = _ref1[1];
a.textContent = ExpandThread.text('...', posts, files);
$.cache("//api.4chan.org/" + thread.board + "/res/" + thread + ".json", function() { $.cache("//api.4chan.org/" + thread.board + "/res/" + thread + ".json", function() {
return ExpandThread.parse(this, thread, a); return ExpandThread.parse(this, thread, a);
}); });
@ -12487,84 +12483,99 @@
if (!a) { if (!a) {
return; return;
} }
a.textContent = a.textContent.replace('...', '+'); _ref2 = a.textContent.match(/\d+/g), posts = _ref2[0], files = _ref2[1];
a.textContent = ExpandThread.text('+', posts, files);
break; break;
case true: case true:
thread.isExpanded = false; thread.isExpanded = false;
if (a) { num = (function() {
a.textContent = a.textContent.replace('-', '+').replace('hide', 'view').replace('expanded', 'omitted'); if (thread.isSticky) {
num = (function() { return 1;
if (thread.isSticky) { } else {
return 1; switch (g.BOARD.ID) {
} else { case 'b':
switch (g.BOARD.ID) { case 'vg':
case 'b': case 'q':
case 'vg': return 3;
case 'q': case 't':
return 3; return 1;
case 't': default:
return 1; return 5;
default:
return 5;
}
} }
})();
replies = $$('.thread > .replyContainer', threadRoot).slice(0, -num);
for (_j = 0, _len1 = replies.length; _j < _len1; _j++) {
reply = replies[_j];
if (Conf['Quote Inlining']) {
while (inlined = $('.inlined', reply)) {
inlined.click();
}
}
$.rm(reply);
} }
} })();
_ref1 = $$('.thread > .postContainer', threadRoot); posts = $$(".thread > .replyContainer", threadRoot);
for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { _ref3 = [thread.OP.nodes.root].concat(posts.slice(-num));
post = _ref1[_k]; for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
post = _ref3[_j];
ExpandComment.contract(Get.postFromRoot(post)); ExpandComment.contract(Get.postFromRoot(post));
} }
if (!a) {
return;
}
postsCount = 0;
filesCount = 0;
_ref4 = posts.slice(0, -num);
for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
reply = _ref4[_k];
if (Conf['Quote Inlining']) {
while (inlined = $('.inlined', reply)) {
inlined.click();
}
}
postsCount++;
if ('file' in Get.postFromRoot(reply)) {
filesCount++;
}
$.rm(reply);
}
a.textContent = ExpandThread.text('+', postsCount, filesCount);
} }
}, },
parse: function(req, thread, a) { parse: function(req, thread, a) {
var link, node, nodes, post, posts, replies, reply, spoilerRange, status, _i, _len; var filesCount, link, post, posts, postsCount, postsObj, postsRoot, reply, root, spoilerRange, _i, _len;
if (a.textContent[0] === '+') { if (a.textContent[0] === '+') {
return; return;
} }
status = req.status; if (![200, 304].contains(req.status)) {
if (![200, 304].contains(status)) { a.textContent = "Error " + req.statusText + " (" + req.status + ")";
a.textContent = "Error " + req.statusText + " (" + status + ")"; $.off(a, 'click', ExpandThread.cbToggle);
$.off(a, 'click', ExpandThread.cb.toggle);
return; return;
} }
thread.isExpanded = true; thread.isExpanded = true;
a.textContent = a.textContent.replace('...', '-').replace('view', 'hide').replace('omitted', 'expanded');
posts = JSON.parse(req.response).posts; posts = JSON.parse(req.response).posts;
if (spoilerRange = posts[0].custom_spoiler) { if (spoilerRange = posts.shift().custom_spoiler) {
Build.spoilerRange[g.BOARD] = spoilerRange; Build.spoilerRange[thread.board] = spoilerRange;
} }
replies = posts.slice(1); postsObj = [];
posts = []; postsRoot = [];
nodes = []; filesCount = 0;
for (_i = 0, _len = replies.length; _i < _len; _i++) { for (_i = 0, _len = posts.length; _i < _len; _i++) {
reply = replies[_i]; reply = posts[_i];
if (post = thread.posts[reply.no]) { if (post = thread.posts[reply.no]) {
nodes.push(post.nodes.root); if ('file' in post) {
filesCount++;
}
postsRoot.push(post.nodes.root);
continue; continue;
} }
node = Build.postFromObject(reply, thread.board.ID); root = Build.postFromObject(reply, thread.board.ID);
post = new Post(node, thread, thread.board); post = new Post(root, thread, thread.board);
link = $('a[title="Highlight this post"]', node); link = $('a[title="Highlight this post"]', root);
link.href = "res/" + thread + "#p" + post; link.href = "res/" + thread + "#p" + post;
link.nextSibling.href = "res/" + thread + "#q" + post; link.nextSibling.href = "res/" + thread + "#q" + post;
posts.push(post); if ('file' in post) {
nodes.push(node); filesCount++;
}
postsObj.push(post);
postsRoot.push(root);
} }
Main.callbackNodes(Post, posts); Main.callbackNodes(Post, postsObj);
$.after(a, nodes); $.after(a, postsRoot);
return Fourchan.parseThread(thread.ID, 1, nodes.length); postsCount = postsRoot.length;
a.textContent = ExpandThread.text('-', postsCount, filesCount);
return Fourchan.parseThread(thread.ID, 1, postsCount);
} }
}; };

View File

@ -246,8 +246,8 @@ Header =
{top} = post.getBoundingClientRect() {top} = post.getBoundingClientRect()
if Conf['Fixed Header'] and not Conf['Bottom Header'] if Conf['Fixed Header'] and not Conf['Bottom Header']
headRect = Header.bar.getBoundingClientRect() headRect = Header.bar.getBoundingClientRect()
top += - headRect.top - headRect.height top -= headRect.top + headRect.height
<% if (type === 'crx') { %>d.body<% } else { %>doc<% } %>.scrollTop += top window.scrollBy 0, top
addShortcut: (el) -> addShortcut: (el) ->
shortcut = $.el 'span', shortcut = $.el 'span',

View File

@ -67,8 +67,8 @@ UI = do ->
# Position # Position
mRect = menu.getBoundingClientRect() mRect = menu.getBoundingClientRect()
bRect = button.getBoundingClientRect() bRect = button.getBoundingClientRect()
bTop = doc.scrollTop + d.body.scrollTop + bRect.top bTop = window.scrollY + bRect.top
bLeft = doc.scrollLeft + d.body.scrollLeft + bRect.left bLeft = window.scrollX + bRect.left
cHeight = doc.clientHeight cHeight = doc.clientHeight
cWidth = doc.clientWidth cWidth = doc.clientWidth
[top, bottom] = if bRect.top + bRect.height + mRect.height < cHeight [top, bottom] = if bRect.top + bRect.height + mRect.height < cHeight

View File

@ -63,27 +63,28 @@ ImageExpand =
ImageExpand.expand post ImageExpand.expand post
return return
ImageExpand.contract post ImageExpand.contract post
node = post.nodes.root # Scroll back to the thumbnail when contracting the image
rect = if Conf['Advance on contract'] then do -> # to avoid being left miles away from the relevant post.
# FIXME does not work with Quote Threading {root} = post.nodes
while node.nextElementSibling rect = (if Conf['Advance on contract'] then do ->
return post.nodes.root unless node = node.nextElementSibling next = root
continue unless $.hasClass node, 'postContainer' while next = $.x "following::div[contains(@class,'postContainer')][1]", next
break if node.offsetHeight > 0 and not $ '.stub', node continue if $('.stub', next) or next.offsetHeight is 0
node.getBoundingClientRect() return next
else root
post.nodes.root.getBoundingClientRect() else
return unless rect.top <= 0 or rect.left <= 0 root
).getBoundingClientRect()
{top} = rect if rect.top < 0
if Conf['Fixed Header'] and not Conf['Bottom Header'] y = rect.top
headRect = Header.bar.getBoundingClientRect() if Conf['Fixed Header'] and not Conf['Bottom Header']
top += - headRect.top - headRect.height headRect = Header.bar.getBoundingClientRect()
y -= headRect.top + headRect.height
root = <% if (type === 'crx') { %>d.body<% } else { %>doc<% } %> if rect.left < 0
x = -window.scrollX
root.scrollTop += top if rect.top < 0 window.scrollBy x, y if x or y
root.scrollLeft = 0 if rect.left < 0
contract: (post) -> contract: (post) ->
$.rmClass post.nodes.root, 'expanded-image' $.rmClass post.nodes.root, 'expanded-image'
@ -123,9 +124,8 @@ ImageExpand =
$.addClass post.nodes.root, 'expanded-image' $.addClass post.nodes.root, 'expanded-image'
$.rmClass post.file.thumb, 'expanding' $.rmClass post.file.thumb, 'expanding'
return unless prev.top + prev.height <= 0 return unless prev.top + prev.height <= 0
root = <% if (type === 'crx') { %>d.body<% } else { %>doc<% } %>
curr = post.nodes.root.getBoundingClientRect() curr = post.nodes.root.getBoundingClientRect()
root.scrollTop += curr.height - prev.height + curr.top - prev.top window.scrollBy 0, curr.height - prev.height + curr.top - prev.top
error: -> error: ->
post = Get.postFromNode @ post = Get.postFromNode @

View File

@ -5,18 +5,24 @@ ExpandThread =
Thread::callbacks.push Thread::callbacks.push
name: 'Thread Expansion' name: 'Thread Expansion'
cb: @node cb: @node
node: -> node: ->
return unless span = $ '.summary', @OP.nodes.root.parentNode return unless span = $.x 'following-sibling::span[contains(@class,"summary")][1]', @OP.nodes.root
[posts, files] = span.textContent.match /\d+/g
a = $.el 'a', a = $.el 'a',
textContent: "+ #{span.textContent}" textContent: ExpandThread.text '+', posts, files
className: 'summary' className: 'summary'
href: 'javascript:;' href: 'javascript:;'
$.on a, 'click', ExpandThread.cbToggle $.on a, 'click', ExpandThread.cbToggle
$.replace span, a $.replace span, a
text: (status, posts, files) ->
"#{status} #{posts} post#{if posts > 1 then 's' else ''}" +
(if +files then " and #{files} image repl#{if files > 1 then 'ies' else 'y'}" else "") +
" #{if status is '-' then 'shown' else 'omitted'}."
cbToggle: -> cbToggle: ->
op = Get.postFromRoot @previousElementSibling ExpandThread.toggle Get.threadFromRoot @parentNode
ExpandThread.toggle op.thread
toggle: (thread) -> toggle: (thread) ->
threadRoot = thread.OP.nodes.root.parentNode threadRoot = thread.OP.nodes.root.parentNode
@ -24,74 +30,82 @@ ExpandThread =
switch thread.isExpanded switch thread.isExpanded
when false, undefined when false, undefined
thread.isExpanded = 'loading'
for post in $$ '.thread > .postContainer', threadRoot for post in $$ '.thread > .postContainer', threadRoot
ExpandComment.expand Get.postFromRoot post ExpandComment.expand Get.postFromRoot post
unless a unless a
thread.isExpanded = true thread.isExpanded = true
return return
thread.isExpanded = 'loading' thread.isExpanded = 'loading'
a.textContent = a.textContent.replace '+', '...' [posts, files] = a.textContent.match /\d+/g
a.textContent = ExpandThread.text '...', posts, files
$.cache "//api.4chan.org/#{thread.board}/res/#{thread}.json", -> $.cache "//api.4chan.org/#{thread.board}/res/#{thread}.json", ->
ExpandThread.parse @, thread, a ExpandThread.parse @, thread, a
when 'loading' when 'loading'
thread.isExpanded = false thread.isExpanded = false
return unless a return unless a
a.textContent = a.textContent.replace '...', '+' [posts, files] = a.textContent.match /\d+/g
a.textContent = ExpandThread.text '+', posts, files
when true when true
thread.isExpanded = false thread.isExpanded = false
if a #goddamit moot
a.textContent = a.textContent.replace('-', '+').replace('hide', 'view').replace('expanded', 'omitted') num = if thread.isSticky
#goddamit moot 1
num = if thread.isSticky else switch g.BOARD.ID
1 # XXX boards config
else switch g.BOARD.ID when 'b', 'vg', 'q' then 3
# XXX boards config when 't' then 1
when 'b', 'vg', 'q' then 3 else 5
when 't' then 1 posts = $$ ".thread > .replyContainer", threadRoot
else 5 for post in [thread.OP.nodes.root].concat posts[-num..]
replies = $$('.thread > .replyContainer', threadRoot)[...-num]
for reply in replies
if Conf['Quote Inlining']
# rm clones
inlined.click() while inlined = $ '.inlined', reply
$.rm reply
for post in $$ '.thread > .postContainer', threadRoot
ExpandComment.contract Get.postFromRoot post ExpandComment.contract Get.postFromRoot post
return unless a
postsCount = 0
filesCount = 0
for reply in posts[...-num]
if Conf['Quote Inlining']
# rm clones
inlined.click() while inlined = $ '.inlined', reply
postsCount++
filesCount++ if 'file' of Get.postFromRoot reply
$.rm reply
a.textContent = ExpandThread.text '+', postsCount, filesCount
return return
parse: (req, thread, a) -> parse: (req, thread, a) ->
return if a.textContent[0] is '+' return if a.textContent[0] is '+'
{status} = req unless [200, 304].contains req.status
unless [200, 304].contains status a.textContent = "Error #{req.statusText} (#{req.status})"
a.textContent = "Error #{req.statusText} (#{status})" $.off a, 'click', ExpandThread.cbToggle
$.off a, 'click', ExpandThread.cb.toggle
return return
thread.isExpanded = true thread.isExpanded = true
a.textContent = a.textContent.replace('...', '-').replace('view', 'hide').replace('omitted', 'expanded')
posts = JSON.parse(req.response).posts {posts} = JSON.parse req.response
if spoilerRange = posts[0].custom_spoiler if spoilerRange = posts.shift().custom_spoiler
Build.spoilerRange[g.BOARD] = spoilerRange Build.spoilerRange[thread.board] = spoilerRange
replies = posts[1..] postsObj = []
posts = [] postsRoot = []
nodes = [] filesCount = 0
for reply in replies for reply in posts
if post = thread.posts[reply.no] if post = thread.posts[reply.no]
nodes.push post.nodes.root filesCount++ if 'file' of post
postsRoot.push post.nodes.root
continue continue
node = Build.postFromObject reply, thread.board.ID root = Build.postFromObject reply, thread.board.ID
post = new Post node, thread, thread.board post = new Post root, thread, thread.board
link = $ 'a[title="Highlight this post"]', node link = $ 'a[title="Highlight this post"]', root
link.href = "res/#{thread}#p#{post}" link.href = "res/#{thread}#p#{post}"
link.nextSibling.href = "res/#{thread}#q#{post}" link.nextSibling.href = "res/#{thread}#q#{post}"
posts.push post filesCount++ if 'file' of post
nodes.push node postsObj.push post
Main.callbackNodes Post, posts postsRoot.push root
$.after a, nodes Main.callbackNodes Post, postsObj
$.after a, postsRoot
Fourchan.parseThread thread.ID, 1, nodes.length postsCount = postsRoot.length
a.textContent = ExpandThread.text '-', postsCount, filesCount
Fourchan.parseThread thread.ID, 1, postsCount

View File

@ -294,7 +294,6 @@ ThreadUpdater =
unless count unless count
ThreadUpdater.set 'status', null, null ThreadUpdater.set 'status', null, null
ThreadUpdater.outdateCount++ ThreadUpdater.outdateCount++
else else
ThreadUpdater.set 'status', "+#{count}", 'new' ThreadUpdater.set 'status', "+#{count}", 'new'
ThreadUpdater.outdateCount = 0 ThreadUpdater.outdateCount = 0
@ -320,7 +319,7 @@ ThreadUpdater =
if scroll if scroll
if Conf['Bottom Scroll'] if Conf['Bottom Scroll']
<% if (type === 'crx') { %>d.body<% } else { %>doc<% } %>.scrollTop = d.body.clientHeight window.scrollTo 0, d.body.clientHeight
else else
Header.scrollToPost root if root Header.scrollToPost root if root