Finishing up merge, onto testing...
This commit is contained in:
parent
e4dde07c11
commit
409f1f9ecf
@ -8161,7 +8161,8 @@
|
|||||||
|
|
||||||
QuotePreview = {
|
QuotePreview = {
|
||||||
init: function() {
|
init: function() {
|
||||||
if (!Conf['Quote Previewing']) {
|
var _ref;
|
||||||
|
if (!(((_ref = g.VIEW) === 'index' || _ref === 'thread') && Conf['Quote Previewing'])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Conf['Comment Expansion']) {
|
if (Conf['Comment Expansion']) {
|
||||||
@ -8244,7 +8245,8 @@
|
|||||||
|
|
||||||
QuoteStrikeThrough = {
|
QuoteStrikeThrough = {
|
||||||
init: function() {
|
init: function() {
|
||||||
if (!Conf['Post Hiding'] && !Conf['Post Hiding Link'] && !Conf['Filter']) {
|
var _ref;
|
||||||
|
if (!(((_ref = g.VIEW) === 'index' || _ref === 'thread') && (Conf['Post Hiding'] || Conf['Post Hiding Link'] || Conf['Filter']))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return Post.callbacks.push({
|
return Post.callbacks.push({
|
||||||
@ -8275,164 +8277,181 @@
|
|||||||
|
|
||||||
QuoteThreading = {
|
QuoteThreading = {
|
||||||
init: function() {
|
init: function() {
|
||||||
var input;
|
|
||||||
if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) {
|
if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.enabled = true;
|
this.enabled = true;
|
||||||
this.controls = $.el('span', {
|
this.controls = $.el('span', {
|
||||||
innerHTML: '<label><input id=threadingControl type=checkbox checked> Threading</label>'
|
innerHTML: "<label><input id=\"threadingControl\" type=\"checkbox\" checked> Threading</label>"
|
||||||
|
});
|
||||||
|
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);
|
||||||
});
|
});
|
||||||
input = $('input', this.controls);
|
|
||||||
$.on(input, 'change', this.toggle);
|
|
||||||
Header.menu.addEntry(this.entry = {
|
Header.menu.addEntry(this.entry = {
|
||||||
el: this.controls,
|
el: this.controls,
|
||||||
order: 98
|
order: 98
|
||||||
});
|
});
|
||||||
if (!Conf['Unread Count']) {
|
Thread.callbacks.push({
|
||||||
$.on(d, '4chanXInitFinished', this.ready);
|
name: 'Quote Threading',
|
||||||
}
|
cb: this.setThread
|
||||||
|
});
|
||||||
return Post.callbacks.push({
|
return Post.callbacks.push({
|
||||||
name: 'Quote Threading',
|
name: 'Quote Threading',
|
||||||
cb: this.node
|
cb: this.node
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
disconnect: function() {
|
parent: {},
|
||||||
var input;
|
children: {},
|
||||||
if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) {
|
inserted: {},
|
||||||
return;
|
setThread: function() {
|
||||||
}
|
QuoteThreading.thread = this;
|
||||||
input = $('input', this.controls);
|
return $.asap((function() {
|
||||||
$.off(input, 'change', this.toggle);
|
return !Conf['Thread Updater'] || $('.navLinksBot > .updatelink');
|
||||||
Header.menu.rmEntry(this.entry);
|
}), function() {
|
||||||
delete this.enabled;
|
return $.add($('.navLinksBot'), [$.tn(' '), QuoteThreading.threadNewLink]);
|
||||||
delete this.controls;
|
|
||||||
delete this.entry;
|
|
||||||
return Post.callbacks.disconnect('Quote Threading');
|
|
||||||
},
|
|
||||||
ready: function() {
|
|
||||||
$.off(d, '4chanXInitFinished', QuoteThreading.ready);
|
|
||||||
return QuoteThreading.force();
|
|
||||||
},
|
|
||||||
force: function() {
|
|
||||||
g.posts.forEach(function(post) {
|
|
||||||
if (post.cb) {
|
|
||||||
return post.cb(true);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
if (Conf['Unread Count'] && Unread.thread.OP.nodes.root.parentElement.parentElement) {
|
|
||||||
Unread.read();
|
|
||||||
return Unread.update();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
node: function() {
|
node: function() {
|
||||||
var keys, len, posts, quote, _i, _len, _ref;
|
var parent, parents, quote, thread;
|
||||||
posts = g.posts;
|
if (this.isFetchedQuote || this.isClone || !this.isReply) {
|
||||||
if (this.isClone || !QuoteThreading.enabled) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Conf['Unread Count']) {
|
thread = QuoteThreading.thread;
|
||||||
Unread.posts.push(this);
|
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];
|
||||||
}
|
}
|
||||||
if (this.thread.OP === this || this.isHidden) {
|
},
|
||||||
return;
|
descendants: function(post) {
|
||||||
}
|
var child, children, posts, _i, _len;
|
||||||
keys = [];
|
posts = [post];
|
||||||
len = g.BOARD.ID.length + 1;
|
if (children = QuoteThreading.children[post.fullID]) {
|
||||||
_ref = this.quotes;
|
for (_i = 0, _len = children.length; _i < _len; _i++) {
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
child = children[_i];
|
||||||
quote = _ref[_i];
|
posts = posts.concat(QuoteThreading.descendants(child));
|
||||||
if ((quote.slice(len) < this.ID) && quote in posts) {
|
|
||||||
keys.push(quote);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (keys.length !== 1) {
|
return posts;
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.threaded = keys[0];
|
|
||||||
return this.cb = QuoteThreading.nodeinsert;
|
|
||||||
},
|
},
|
||||||
nodeinsert: function(force) {
|
insert: function(post) {
|
||||||
var bottom, height, post, posts, root, threadContainer, top, _ref;
|
var child, children, descendants, i, next, nodes, order, parent, prev, prev2, threadContainer, x, _base, _i, _j, _k, _len, _name;
|
||||||
post = g.posts[this.threaded];
|
if (!(QuoteThreading.enabled && (parent = QuoteThreading.parent[post.fullID]) && !QuoteThreading.inserted[post.fullID])) {
|
||||||
if (this.thread.OP === post) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
posts = Unread.posts;
|
descendants = QuoteThreading.descendants(post);
|
||||||
root = post.nodes.root;
|
if (!Unread.posts.has(parent.ID) && descendants.some(function(x) {
|
||||||
if (!force) {
|
return Unread.posts.has(x.ID);
|
||||||
height = doc.clientHeight;
|
})) {
|
||||||
_ref = root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top;
|
QuoteThreading.threadNewLink.hidden = false;
|
||||||
if (!((Conf['Unread Count'] && posts[post.ID]) || ((bottom < height) && (top > 0)))) {
|
return 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')) {
|
if (i !== children.length) {
|
||||||
threadContainer = root.nextElementSibling;
|
next = children[i];
|
||||||
post = Get.postFromRoot($.x('descendant::div[contains(@class,"postContainer")][last()]', threadContainer));
|
for (_j = 0, _len = descendants.length; _j < _len; _j++) {
|
||||||
$.add(threadContainer, this.nodes.root);
|
x = descendants[_j];
|
||||||
|
order.before(order[next.ID], order[x.ID]);
|
||||||
|
}
|
||||||
|
children.splice(i, 0, post);
|
||||||
|
$.before(next.nodes.root, nodes);
|
||||||
} else {
|
} else {
|
||||||
threadContainer = $.el('div', {
|
prev = parent;
|
||||||
className: 'threadContainer'
|
while ((prev2 = QuoteThreading.children[prev.fullID]) && prev2.length) {
|
||||||
});
|
prev = prev2[prev2.length - 1];
|
||||||
$.add(threadContainer, this.nodes.root);
|
}
|
||||||
$.after(root, threadContainer);
|
for (_k = descendants.length - 1; _k >= 0; _k += -1) {
|
||||||
$.addClass(root, 'threadOP');
|
x = descendants[_k];
|
||||||
|
order.after(order[prev.ID], order[x.ID]);
|
||||||
|
}
|
||||||
|
children.push(post);
|
||||||
|
$.add(threadContainer, nodes);
|
||||||
}
|
}
|
||||||
if (!Conf['Unread Count']) {
|
QuoteThreading.inserted[post.fullID] = true;
|
||||||
return true;
|
if (!parent.nodes.threadContainer) {
|
||||||
}
|
parent.nodes.threadContainer = threadContainer;
|
||||||
if (post = posts[post.ID]) {
|
$.addClass(parent.nodes.root, 'threadOP');
|
||||||
posts.after(post, posts[this.ID]);
|
$.after(parent.nodes.root, threadContainer);
|
||||||
} else if (posts[this.ID]) {
|
|
||||||
posts.prepend(posts[this.ID]);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
toggle: function() {
|
rethread: function(enabled) {
|
||||||
var container, containers, nodes, post, posts, thread, _i, _j, _k, _len, _len1, _len2, _ref;
|
var nodes, posts, thread;
|
||||||
if (QuoteThreading.enabled = this.checked) {
|
thread = QuoteThreading.thread;
|
||||||
QuoteThreading.force();
|
posts = thread.posts;
|
||||||
|
if (QuoteThreading.enabled = enabled) {
|
||||||
|
posts.forEach(QuoteThreading.insert);
|
||||||
} else {
|
} else {
|
||||||
thread = $('.thread');
|
|
||||||
posts = [];
|
|
||||||
nodes = [];
|
nodes = [];
|
||||||
g.posts.forEach(function(post) {
|
Unread.order = new RandomAccessList;
|
||||||
if (!(post === post.thread.OP || post.isClone)) {
|
QuoteThreading.inserted = {};
|
||||||
return posts.push(post);
|
posts.forEach(function(post) {
|
||||||
|
if (post.isFetchedQuote) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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) {
|
$.add(thread.OP.nodes.root.parentNode, nodes);
|
||||||
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');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
Unread.position = Unread.order.first;
|
||||||
kb: function() {
|
Unread.updatePosition();
|
||||||
var control;
|
Unread.setLine(true);
|
||||||
control = $.id('threadingControl');
|
Unread.read();
|
||||||
control.checked = !control.checked;
|
return Unread.update();
|
||||||
return QuoteThreading.toggle.call(control);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Quotify = {
|
Quotify = {
|
||||||
init: function() {
|
init: function() {
|
||||||
if (!Conf['Resurrect Quotes']) {
|
var _ref;
|
||||||
|
if (((_ref = g.VIEW) !== 'index' && _ref !== 'thread') || !Conf['Resurrect Quotes'] && g.BOARD.ID !== 'pol') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Conf['Comment Expansion']) {
|
if (Conf['Comment Expansion']) {
|
||||||
@ -8458,7 +8477,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
parseDeadlink: function(deadlink) {
|
parseDeadlink: function(deadlink) {
|
||||||
var a, boardID, m, post, postID, quote, quoteID, redirect, _ref;
|
var a, boardID, fetchable, m, post, postID, quote, quoteID, redirect, _ref;
|
||||||
if ($.hasClass(deadlink.parentNode, 'prettyprint')) {
|
if ($.hasClass(deadlink.parentNode, 'prettyprint')) {
|
||||||
Quotify.fixDeadlink(deadlink);
|
Quotify.fixDeadlink(deadlink);
|
||||||
return;
|
return;
|
||||||
@ -8474,36 +8493,58 @@
|
|||||||
boardID = (m = quote.match(/^>>>\/([a-z\d]+)/)) ? m[1] : this.board.ID;
|
boardID = (m = quote.match(/^>>>\/([a-z\d]+)/)) ? m[1] : this.board.ID;
|
||||||
quoteID = "" + boardID + "." + postID;
|
quoteID = "" + boardID + "." + postID;
|
||||||
if (post = g.posts[quoteID]) {
|
if (post = g.posts[quoteID]) {
|
||||||
a = $.el('a', {
|
if (!post.isDead) {
|
||||||
href: Build.path(boardID, post.thread.ID, postID),
|
a = $.el('a', {
|
||||||
className: post.isDead ? 'quotelink deadlink' : 'quotelink',
|
href: Build.postURL(boardID, post.thread.ID, postID),
|
||||||
textContent: quote
|
className: 'quotelink',
|
||||||
});
|
textContent: quote
|
||||||
$.extend(a.dataset, {
|
});
|
||||||
boardID: boardID,
|
} else {
|
||||||
threadID: post.thread.ID,
|
a = $.el('a', {
|
||||||
postID: postID
|
href: Build.postURL(boardID, post.thread.ID, postID),
|
||||||
});
|
className: 'quotelink deadlink',
|
||||||
} else if (redirect = Redirect.to('thread', {
|
target: '_blank',
|
||||||
boardID: boardID,
|
textContent: "" + quote + "\u00A0(Dead)"
|
||||||
postID: postID
|
});
|
||||||
})) {
|
|
||||||
a = $.el('a', {
|
|
||||||
href: redirect,
|
|
||||||
className: 'deadlink',
|
|
||||||
textContent: quote,
|
|
||||||
target: '_blank'
|
|
||||||
});
|
|
||||||
if (Redirect.to('post', {
|
|
||||||
boardID: boardID,
|
|
||||||
postID: postID
|
|
||||||
})) {
|
|
||||||
$.addClass(a, 'quotelink');
|
|
||||||
$.extend(a.dataset, {
|
$.extend(a.dataset, {
|
||||||
boardID: boardID,
|
boardID: boardID,
|
||||||
|
threadID: post.thread.ID,
|
||||||
postID: postID
|
postID: postID
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} else if ((this.board.ID === boardID && boardID === 'pol') && postID.length === 9 && postID[-2] === postID[-1]) {
|
||||||
|
postID = postID.slice(0, -1);
|
||||||
|
quoteID = "" + boardID + "." + postID;
|
||||||
|
a = $.el('a', {
|
||||||
|
href: Build.postURL(boardID, this.thread.ID, postID),
|
||||||
|
className: 'quotelink',
|
||||||
|
textContent: quote
|
||||||
|
});
|
||||||
|
} else if (Conf['Resurrect Quotes']) {
|
||||||
|
redirect = Redirect.to('thread', {
|
||||||
|
boardID: boardID,
|
||||||
|
threadID: 0,
|
||||||
|
postID: postID
|
||||||
|
});
|
||||||
|
fetchable = Redirect.to('post', {
|
||||||
|
boardID: boardID,
|
||||||
|
postID: postID
|
||||||
|
});
|
||||||
|
if (redirect || fetchable) {
|
||||||
|
a = $.el('a', {
|
||||||
|
href: redirect || 'javascript:;',
|
||||||
|
className: 'deadlink',
|
||||||
|
target: '_blank',
|
||||||
|
textContent: "" + quote + "\u00A0(Dead)"
|
||||||
|
});
|
||||||
|
if (fetchable) {
|
||||||
|
$.addClass(a, 'quotelink');
|
||||||
|
$.extend(a.dataset, {
|
||||||
|
boardID: boardID,
|
||||||
|
postID: postID
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (__indexOf.call(this.quotes, quoteID) < 0) {
|
if (__indexOf.call(this.quotes, quoteID) < 0) {
|
||||||
this.quotes.push(quoteID);
|
this.quotes.push(quoteID);
|
||||||
@ -10388,7 +10429,7 @@
|
|||||||
return function(persona) {
|
return function(persona) {
|
||||||
_this.name = 'name' in QR.persona.always ? QR.persona.always.name : prev ? prev.name : persona.name;
|
_this.name = 'name' in QR.persona.always ? QR.persona.always.name : prev ? prev.name : persona.name;
|
||||||
_this.email = 'email' in QR.persona.always ? QR.persona.always.email : prev && !/^sage$/.test(prev.email) ? prev.email : persona.email;
|
_this.email = 'email' in QR.persona.always ? QR.persona.always.email : prev && !/^sage$/.test(prev.email) ? prev.email : persona.email;
|
||||||
_this.sub = 'sub' in QR.persona.always ? QR.persona.always.sub : Conf['Remember Subject'] ? prev ? prev.sub : persona.sub : '';
|
_this.sub = 'sub' in QR.persona.always ? QR.persona.always.sub : '';
|
||||||
if (QR.nodes.flag) {
|
if (QR.nodes.flag) {
|
||||||
_this.flag = prev ? prev.flag : persona.flag;
|
_this.flag = prev ? prev.flag : persona.flag;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8206,7 +8206,8 @@
|
|||||||
|
|
||||||
QuotePreview = {
|
QuotePreview = {
|
||||||
init: function() {
|
init: function() {
|
||||||
if (!Conf['Quote Previewing']) {
|
var _ref;
|
||||||
|
if (!(((_ref = g.VIEW) === 'index' || _ref === 'thread') && Conf['Quote Previewing'])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Conf['Comment Expansion']) {
|
if (Conf['Comment Expansion']) {
|
||||||
@ -8289,7 +8290,8 @@
|
|||||||
|
|
||||||
QuoteStrikeThrough = {
|
QuoteStrikeThrough = {
|
||||||
init: function() {
|
init: function() {
|
||||||
if (!Conf['Post Hiding'] && !Conf['Post Hiding Link'] && !Conf['Filter']) {
|
var _ref;
|
||||||
|
if (!(((_ref = g.VIEW) === 'index' || _ref === 'thread') && (Conf['Post Hiding'] || Conf['Post Hiding Link'] || Conf['Filter']))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return Post.callbacks.push({
|
return Post.callbacks.push({
|
||||||
@ -8320,164 +8322,181 @@
|
|||||||
|
|
||||||
QuoteThreading = {
|
QuoteThreading = {
|
||||||
init: function() {
|
init: function() {
|
||||||
var input;
|
|
||||||
if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) {
|
if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.enabled = true;
|
this.enabled = true;
|
||||||
this.controls = $.el('span', {
|
this.controls = $.el('span', {
|
||||||
innerHTML: '<label><input id=threadingControl type=checkbox checked> Threading</label>'
|
innerHTML: "<label><input id=\"threadingControl\" type=\"checkbox\" checked> Threading</label>"
|
||||||
|
});
|
||||||
|
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);
|
||||||
});
|
});
|
||||||
input = $('input', this.controls);
|
|
||||||
$.on(input, 'change', this.toggle);
|
|
||||||
Header.menu.addEntry(this.entry = {
|
Header.menu.addEntry(this.entry = {
|
||||||
el: this.controls,
|
el: this.controls,
|
||||||
order: 98
|
order: 98
|
||||||
});
|
});
|
||||||
if (!Conf['Unread Count']) {
|
Thread.callbacks.push({
|
||||||
$.on(d, '4chanXInitFinished', this.ready);
|
name: 'Quote Threading',
|
||||||
}
|
cb: this.setThread
|
||||||
|
});
|
||||||
return Post.callbacks.push({
|
return Post.callbacks.push({
|
||||||
name: 'Quote Threading',
|
name: 'Quote Threading',
|
||||||
cb: this.node
|
cb: this.node
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
disconnect: function() {
|
parent: {},
|
||||||
var input;
|
children: {},
|
||||||
if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) {
|
inserted: {},
|
||||||
return;
|
setThread: function() {
|
||||||
}
|
QuoteThreading.thread = this;
|
||||||
input = $('input', this.controls);
|
return $.asap((function() {
|
||||||
$.off(input, 'change', this.toggle);
|
return !Conf['Thread Updater'] || $('.navLinksBot > .updatelink');
|
||||||
Header.menu.rmEntry(this.entry);
|
}), function() {
|
||||||
delete this.enabled;
|
return $.add($('.navLinksBot'), [$.tn(' '), QuoteThreading.threadNewLink]);
|
||||||
delete this.controls;
|
|
||||||
delete this.entry;
|
|
||||||
return Post.callbacks.disconnect('Quote Threading');
|
|
||||||
},
|
|
||||||
ready: function() {
|
|
||||||
$.off(d, '4chanXInitFinished', QuoteThreading.ready);
|
|
||||||
return QuoteThreading.force();
|
|
||||||
},
|
|
||||||
force: function() {
|
|
||||||
g.posts.forEach(function(post) {
|
|
||||||
if (post.cb) {
|
|
||||||
return post.cb(true);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
if (Conf['Unread Count'] && Unread.thread.OP.nodes.root.parentElement.parentElement) {
|
|
||||||
Unread.read();
|
|
||||||
return Unread.update();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
node: function() {
|
node: function() {
|
||||||
var keys, len, posts, quote, _i, _len, _ref;
|
var parent, parents, quote, thread;
|
||||||
posts = g.posts;
|
if (this.isFetchedQuote || this.isClone || !this.isReply) {
|
||||||
if (this.isClone || !QuoteThreading.enabled) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Conf['Unread Count']) {
|
thread = QuoteThreading.thread;
|
||||||
Unread.posts.push(this);
|
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];
|
||||||
}
|
}
|
||||||
if (this.thread.OP === this || this.isHidden) {
|
},
|
||||||
return;
|
descendants: function(post) {
|
||||||
}
|
var child, children, posts, _i, _len;
|
||||||
keys = [];
|
posts = [post];
|
||||||
len = g.BOARD.ID.length + 1;
|
if (children = QuoteThreading.children[post.fullID]) {
|
||||||
_ref = this.quotes;
|
for (_i = 0, _len = children.length; _i < _len; _i++) {
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
child = children[_i];
|
||||||
quote = _ref[_i];
|
posts = posts.concat(QuoteThreading.descendants(child));
|
||||||
if ((quote.slice(len) < this.ID) && quote in posts) {
|
|
||||||
keys.push(quote);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (keys.length !== 1) {
|
return posts;
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.threaded = keys[0];
|
|
||||||
return this.cb = QuoteThreading.nodeinsert;
|
|
||||||
},
|
},
|
||||||
nodeinsert: function(force) {
|
insert: function(post) {
|
||||||
var bottom, height, post, posts, root, threadContainer, top, _ref;
|
var child, children, descendants, i, next, nodes, order, parent, prev, prev2, threadContainer, x, _base, _i, _j, _k, _len, _name;
|
||||||
post = g.posts[this.threaded];
|
if (!(QuoteThreading.enabled && (parent = QuoteThreading.parent[post.fullID]) && !QuoteThreading.inserted[post.fullID])) {
|
||||||
if (this.thread.OP === post) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
posts = Unread.posts;
|
descendants = QuoteThreading.descendants(post);
|
||||||
root = post.nodes.root;
|
if (!Unread.posts.has(parent.ID) && descendants.some(function(x) {
|
||||||
if (!force) {
|
return Unread.posts.has(x.ID);
|
||||||
height = doc.clientHeight;
|
})) {
|
||||||
_ref = root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top;
|
QuoteThreading.threadNewLink.hidden = false;
|
||||||
if (!((Conf['Unread Count'] && posts[post.ID]) || ((bottom < height) && (top > 0)))) {
|
return 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')) {
|
if (i !== children.length) {
|
||||||
threadContainer = root.nextElementSibling;
|
next = children[i];
|
||||||
post = Get.postFromRoot($.x('descendant::div[contains(@class,"postContainer")][last()]', threadContainer));
|
for (_j = 0, _len = descendants.length; _j < _len; _j++) {
|
||||||
$.add(threadContainer, this.nodes.root);
|
x = descendants[_j];
|
||||||
|
order.before(order[next.ID], order[x.ID]);
|
||||||
|
}
|
||||||
|
children.splice(i, 0, post);
|
||||||
|
$.before(next.nodes.root, nodes);
|
||||||
} else {
|
} else {
|
||||||
threadContainer = $.el('div', {
|
prev = parent;
|
||||||
className: 'threadContainer'
|
while ((prev2 = QuoteThreading.children[prev.fullID]) && prev2.length) {
|
||||||
});
|
prev = prev2[prev2.length - 1];
|
||||||
$.add(threadContainer, this.nodes.root);
|
}
|
||||||
$.after(root, threadContainer);
|
for (_k = descendants.length - 1; _k >= 0; _k += -1) {
|
||||||
$.addClass(root, 'threadOP');
|
x = descendants[_k];
|
||||||
|
order.after(order[prev.ID], order[x.ID]);
|
||||||
|
}
|
||||||
|
children.push(post);
|
||||||
|
$.add(threadContainer, nodes);
|
||||||
}
|
}
|
||||||
if (!Conf['Unread Count']) {
|
QuoteThreading.inserted[post.fullID] = true;
|
||||||
return true;
|
if (!parent.nodes.threadContainer) {
|
||||||
}
|
parent.nodes.threadContainer = threadContainer;
|
||||||
if (post = posts[post.ID]) {
|
$.addClass(parent.nodes.root, 'threadOP');
|
||||||
posts.after(post, posts[this.ID]);
|
$.after(parent.nodes.root, threadContainer);
|
||||||
} else if (posts[this.ID]) {
|
|
||||||
posts.prepend(posts[this.ID]);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
toggle: function() {
|
rethread: function(enabled) {
|
||||||
var container, containers, nodes, post, posts, thread, _i, _j, _k, _len, _len1, _len2, _ref;
|
var nodes, posts, thread;
|
||||||
if (QuoteThreading.enabled = this.checked) {
|
thread = QuoteThreading.thread;
|
||||||
QuoteThreading.force();
|
posts = thread.posts;
|
||||||
|
if (QuoteThreading.enabled = enabled) {
|
||||||
|
posts.forEach(QuoteThreading.insert);
|
||||||
} else {
|
} else {
|
||||||
thread = $('.thread');
|
|
||||||
posts = [];
|
|
||||||
nodes = [];
|
nodes = [];
|
||||||
g.posts.forEach(function(post) {
|
Unread.order = new RandomAccessList;
|
||||||
if (!(post === post.thread.OP || post.isClone)) {
|
QuoteThreading.inserted = {};
|
||||||
return posts.push(post);
|
posts.forEach(function(post) {
|
||||||
|
if (post.isFetchedQuote) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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) {
|
$.add(thread.OP.nodes.root.parentNode, nodes);
|
||||||
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');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
Unread.position = Unread.order.first;
|
||||||
kb: function() {
|
Unread.updatePosition();
|
||||||
var control;
|
Unread.setLine(true);
|
||||||
control = $.id('threadingControl');
|
Unread.read();
|
||||||
control.checked = !control.checked;
|
return Unread.update();
|
||||||
return QuoteThreading.toggle.call(control);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Quotify = {
|
Quotify = {
|
||||||
init: function() {
|
init: function() {
|
||||||
if (!Conf['Resurrect Quotes']) {
|
var _ref;
|
||||||
|
if (((_ref = g.VIEW) !== 'index' && _ref !== 'thread') || !Conf['Resurrect Quotes'] && g.BOARD.ID !== 'pol') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Conf['Comment Expansion']) {
|
if (Conf['Comment Expansion']) {
|
||||||
@ -8503,7 +8522,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
parseDeadlink: function(deadlink) {
|
parseDeadlink: function(deadlink) {
|
||||||
var a, boardID, m, post, postID, quote, quoteID, redirect, _ref;
|
var a, boardID, fetchable, m, post, postID, quote, quoteID, redirect, _ref;
|
||||||
if ($.hasClass(deadlink.parentNode, 'prettyprint')) {
|
if ($.hasClass(deadlink.parentNode, 'prettyprint')) {
|
||||||
Quotify.fixDeadlink(deadlink);
|
Quotify.fixDeadlink(deadlink);
|
||||||
return;
|
return;
|
||||||
@ -8519,36 +8538,58 @@
|
|||||||
boardID = (m = quote.match(/^>>>\/([a-z\d]+)/)) ? m[1] : this.board.ID;
|
boardID = (m = quote.match(/^>>>\/([a-z\d]+)/)) ? m[1] : this.board.ID;
|
||||||
quoteID = "" + boardID + "." + postID;
|
quoteID = "" + boardID + "." + postID;
|
||||||
if (post = g.posts[quoteID]) {
|
if (post = g.posts[quoteID]) {
|
||||||
a = $.el('a', {
|
if (!post.isDead) {
|
||||||
href: Build.path(boardID, post.thread.ID, postID),
|
a = $.el('a', {
|
||||||
className: post.isDead ? 'quotelink deadlink' : 'quotelink',
|
href: Build.postURL(boardID, post.thread.ID, postID),
|
||||||
textContent: quote
|
className: 'quotelink',
|
||||||
});
|
textContent: quote
|
||||||
$.extend(a.dataset, {
|
});
|
||||||
boardID: boardID,
|
} else {
|
||||||
threadID: post.thread.ID,
|
a = $.el('a', {
|
||||||
postID: postID
|
href: Build.postURL(boardID, post.thread.ID, postID),
|
||||||
});
|
className: 'quotelink deadlink',
|
||||||
} else if (redirect = Redirect.to('thread', {
|
target: '_blank',
|
||||||
boardID: boardID,
|
textContent: "" + quote + "\u00A0(Dead)"
|
||||||
postID: postID
|
});
|
||||||
})) {
|
|
||||||
a = $.el('a', {
|
|
||||||
href: redirect,
|
|
||||||
className: 'deadlink',
|
|
||||||
textContent: quote,
|
|
||||||
target: '_blank'
|
|
||||||
});
|
|
||||||
if (Redirect.to('post', {
|
|
||||||
boardID: boardID,
|
|
||||||
postID: postID
|
|
||||||
})) {
|
|
||||||
$.addClass(a, 'quotelink');
|
|
||||||
$.extend(a.dataset, {
|
$.extend(a.dataset, {
|
||||||
boardID: boardID,
|
boardID: boardID,
|
||||||
|
threadID: post.thread.ID,
|
||||||
postID: postID
|
postID: postID
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} else if ((this.board.ID === boardID && boardID === 'pol') && postID.length === 9 && postID[-2] === postID[-1]) {
|
||||||
|
postID = postID.slice(0, -1);
|
||||||
|
quoteID = "" + boardID + "." + postID;
|
||||||
|
a = $.el('a', {
|
||||||
|
href: Build.postURL(boardID, this.thread.ID, postID),
|
||||||
|
className: 'quotelink',
|
||||||
|
textContent: quote
|
||||||
|
});
|
||||||
|
} else if (Conf['Resurrect Quotes']) {
|
||||||
|
redirect = Redirect.to('thread', {
|
||||||
|
boardID: boardID,
|
||||||
|
threadID: 0,
|
||||||
|
postID: postID
|
||||||
|
});
|
||||||
|
fetchable = Redirect.to('post', {
|
||||||
|
boardID: boardID,
|
||||||
|
postID: postID
|
||||||
|
});
|
||||||
|
if (redirect || fetchable) {
|
||||||
|
a = $.el('a', {
|
||||||
|
href: redirect || 'javascript:;',
|
||||||
|
className: 'deadlink',
|
||||||
|
target: '_blank',
|
||||||
|
textContent: "" + quote + "\u00A0(Dead)"
|
||||||
|
});
|
||||||
|
if (fetchable) {
|
||||||
|
$.addClass(a, 'quotelink');
|
||||||
|
$.extend(a.dataset, {
|
||||||
|
boardID: boardID,
|
||||||
|
postID: postID
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (__indexOf.call(this.quotes, quoteID) < 0) {
|
if (__indexOf.call(this.quotes, quoteID) < 0) {
|
||||||
this.quotes.push(quoteID);
|
this.quotes.push(quoteID);
|
||||||
@ -10431,7 +10472,7 @@
|
|||||||
return function(persona) {
|
return function(persona) {
|
||||||
_this.name = 'name' in QR.persona.always ? QR.persona.always.name : prev ? prev.name : persona.name;
|
_this.name = 'name' in QR.persona.always ? QR.persona.always.name : prev ? prev.name : persona.name;
|
||||||
_this.email = 'email' in QR.persona.always ? QR.persona.always.email : prev && !/^sage$/.test(prev.email) ? prev.email : persona.email;
|
_this.email = 'email' in QR.persona.always ? QR.persona.always.email : prev && !/^sage$/.test(prev.email) ? prev.email : persona.email;
|
||||||
_this.sub = 'sub' in QR.persona.always ? QR.persona.always.sub : Conf['Remember Subject'] ? prev ? prev.sub : persona.sub : '';
|
_this.sub = 'sub' in QR.persona.always ? QR.persona.always.sub : '';
|
||||||
if (QR.nodes.flag) {
|
if (QR.nodes.flag) {
|
||||||
_this.flag = prev ? prev.flag : persona.flag;
|
_this.flag = prev ? prev.flag : persona.flag;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,8 +52,6 @@ QR.post = class
|
|||||||
|
|
||||||
@sub = if 'sub' of QR.persona.always
|
@sub = if 'sub' of QR.persona.always
|
||||||
QR.persona.always.sub
|
QR.persona.always.sub
|
||||||
else if Conf['Remember Subject']
|
|
||||||
if prev then prev.sub else persona.sub
|
|
||||||
else
|
else
|
||||||
''
|
''
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
QuotePreview =
|
QuotePreview =
|
||||||
init: ->
|
init: ->
|
||||||
return if !Conf['Quote Previewing']
|
return unless g.VIEW in ['index', 'thread'] and Conf['Quote Previewing']
|
||||||
|
|
||||||
if Conf['Comment Expansion']
|
if Conf['Comment Expansion']
|
||||||
ExpandComment.callbacks.push @node
|
ExpandComment.callbacks.push @node
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
QuoteStrikeThrough =
|
QuoteStrikeThrough =
|
||||||
init: ->
|
init: ->
|
||||||
return if !Conf['Post Hiding'] and !Conf['Post Hiding Link'] and !Conf['Filter']
|
return unless g.VIEW in ['index', 'thread'] and
|
||||||
|
(Conf['Post Hiding'] or Conf['Post Hiding Link'] or Conf['Filter'])
|
||||||
|
|
||||||
Post.callbacks.push
|
Post.callbacks.push
|
||||||
name: 'Strike-through Quotes'
|
name: 'Strike-through Quotes'
|
||||||
|
|||||||
@ -8,123 +8,118 @@ QuoteThreading =
|
|||||||
|
|
||||||
@enabled = true
|
@enabled = true
|
||||||
@controls = $.el 'span',
|
@controls = $.el 'span',
|
||||||
innerHTML: '<label><input id=threadingControl type=checkbox checked> Threading</label>'
|
<%= html('<label><input id="threadingControl" type="checkbox" checked> Threading</label>') %>
|
||||||
|
@threadNewLink = $.el 'span',
|
||||||
|
className: 'brackets-wrap threadnewlink'
|
||||||
|
hidden: true
|
||||||
|
$.extend @threadNewLink, <%= html('<a href="javascript:;">Thread New Posts</a>') %>
|
||||||
|
|
||||||
input = $ 'input', @controls
|
$.on $('input', @controls), 'change', ->
|
||||||
$.on input, 'change', @toggle
|
QuoteThreading.rethread @checked
|
||||||
|
$.on @threadNewLink.firstElementChild, 'click', ->
|
||||||
|
QuoteThreading.threadNewLink.hidden = true
|
||||||
|
QuoteThreading.rethread true
|
||||||
|
|
||||||
Header.menu.addEntry @entry =
|
Header.menu.addEntry @entry =
|
||||||
el: @controls
|
el: @controls
|
||||||
order: 98
|
order: 98
|
||||||
|
|
||||||
$.on d, '4chanXInitFinished', @ready unless Conf['Unread Count']
|
Thread.callbacks.push
|
||||||
|
name: 'Quote Threading'
|
||||||
|
cb: @setThread
|
||||||
Post.callbacks.push
|
Post.callbacks.push
|
||||||
name: 'Quote Threading'
|
name: 'Quote Threading'
|
||||||
cb: @node
|
cb: @node
|
||||||
|
|
||||||
disconnect: ->
|
parent: {}
|
||||||
return unless Conf['Quote Threading'] and g.VIEW is 'thread'
|
children: {}
|
||||||
input = $ 'input', @controls
|
inserted: {}
|
||||||
$.off input, 'change', @toggle
|
|
||||||
|
|
||||||
Header.menu.rmEntry @entry
|
setThread: ->
|
||||||
|
QuoteThreading.thread = @
|
||||||
delete @enabled
|
$.asap (-> !Conf['Thread Updater'] or $ '.navLinksBot > .updatelink'), ->
|
||||||
delete @controls
|
$.add $('.navLinksBot'), [$.tn(' '), QuoteThreading.threadNewLink]
|
||||||
delete @entry
|
|
||||||
|
|
||||||
Post.callbacks.disconnect 'Quote Threading'
|
|
||||||
|
|
||||||
ready: ->
|
|
||||||
$.off d, '4chanXInitFinished', QuoteThreading.ready
|
|
||||||
QuoteThreading.force()
|
|
||||||
|
|
||||||
force: ->
|
|
||||||
g.posts.forEach (post) ->
|
|
||||||
post.cb true if post.cb
|
|
||||||
|
|
||||||
if Conf['Unread Count'] and Unread.thread.OP.nodes.root.parentElement.parentElement
|
|
||||||
Unread.read()
|
|
||||||
Unread.update()
|
|
||||||
|
|
||||||
node: ->
|
node: ->
|
||||||
{posts} = g
|
return if @isFetchedQuote or @isClone or !@isReply
|
||||||
return if @isClone or not QuoteThreading.enabled
|
{thread} = QuoteThreading
|
||||||
|
parents = for quote in @quotes
|
||||||
|
parent = g.posts[quote]
|
||||||
|
continue if !parent or parent.isFetchedQuote or !parent.isReply or parent.ID >= @ID
|
||||||
|
parent
|
||||||
|
if parents.length is 1
|
||||||
|
QuoteThreading.parent[@fullID] = parents[0]
|
||||||
|
|
||||||
Unread.posts.push @ if Conf['Unread Count']
|
descendants: (post) ->
|
||||||
return if @thread.OP is @ or @isHidden # Filtered
|
posts = [post]
|
||||||
|
if children = QuoteThreading.children[post.fullID]
|
||||||
|
for child in children
|
||||||
|
posts = posts.concat QuoteThreading.descendants child
|
||||||
|
posts
|
||||||
|
|
||||||
keys = []
|
insert: (post) ->
|
||||||
len = g.BOARD.ID.length + 1
|
return false unless QuoteThreading.enabled and
|
||||||
keys.push quote for quote in @quotes when (quote[len..] < @ID) and quote of posts
|
(parent = QuoteThreading.parent[post.fullID]) and
|
||||||
|
!QuoteThreading.inserted[post.fullID]
|
||||||
|
|
||||||
return unless keys.length is 1
|
descendants = QuoteThreading.descendants post
|
||||||
|
if !Unread.posts.has(parent.ID) and descendants.some((x) -> Unread.posts.has(x.ID))
|
||||||
|
QuoteThreading.threadNewLink.hidden = false
|
||||||
|
return false
|
||||||
|
|
||||||
@threaded = keys[0]
|
{order} = Unread
|
||||||
@cb = QuoteThreading.nodeinsert
|
children = (QuoteThreading.children[parent.fullID] or= [])
|
||||||
|
threadContainer = parent.nodes.threadContainer or $.el 'div', className: 'threadContainer'
|
||||||
nodeinsert: (force) ->
|
nodes = [post.nodes.root]
|
||||||
post = g.posts[@threaded]
|
nodes.push post.nodes.threadContainer if post.nodes.threadContainer
|
||||||
|
|
||||||
return false if @thread.OP is post
|
|
||||||
|
|
||||||
{posts} = Unread
|
|
||||||
{root} = post.nodes
|
|
||||||
|
|
||||||
unless force
|
|
||||||
height = doc.clientHeight
|
|
||||||
{bottom, top} = root.getBoundingClientRect()
|
|
||||||
|
|
||||||
# Post is unread or is fully visible.
|
|
||||||
return false unless (Conf['Unread Count'] and posts[post.ID]) or ((bottom < height) and (top > 0))
|
|
||||||
|
|
||||||
if $.hasClass root, 'threadOP'
|
|
||||||
threadContainer = root.nextElementSibling
|
|
||||||
post = Get.postFromRoot $.x 'descendant::div[contains(@class,"postContainer")][last()]', threadContainer
|
|
||||||
$.add threadContainer, @nodes.root
|
|
||||||
|
|
||||||
|
i = children.length
|
||||||
|
i-- for child in children by -1 when child.ID >= post.ID
|
||||||
|
if i isnt children.length
|
||||||
|
next = children[i]
|
||||||
|
order.before order[next.ID], order[x.ID] for x in descendants
|
||||||
|
children.splice i, 0, post
|
||||||
|
$.before next.nodes.root, nodes
|
||||||
else
|
else
|
||||||
threadContainer = $.el 'div',
|
prev = parent
|
||||||
className: 'threadContainer'
|
while (prev2 = QuoteThreading.children[prev.fullID]) and prev2.length
|
||||||
$.add threadContainer, @nodes.root
|
prev = prev2[prev2.length-1]
|
||||||
$.after root, threadContainer
|
order.after order[prev.ID], order[x.ID] for x in descendants by -1
|
||||||
$.addClass root, 'threadOP'
|
children.push post
|
||||||
|
$.add threadContainer, nodes
|
||||||
|
|
||||||
return true unless Conf['Unread Count']
|
QuoteThreading.inserted[post.fullID] = true
|
||||||
|
|
||||||
if post = posts[post.ID]
|
unless parent.nodes.threadContainer
|
||||||
posts.after post, posts[@ID]
|
parent.nodes.threadContainer = threadContainer
|
||||||
|
$.addClass parent.nodes.root, 'threadOP'
|
||||||
else if posts[@ID]
|
$.after parent.nodes.root, threadContainer
|
||||||
posts.prepend posts[@ID]
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
toggle: ->
|
rethread: (enabled) ->
|
||||||
if QuoteThreading.enabled = @checked
|
{thread} = QuoteThreading
|
||||||
QuoteThreading.force()
|
{posts} = thread
|
||||||
|
|
||||||
|
if QuoteThreading.enabled = enabled
|
||||||
|
posts.forEach QuoteThreading.insert
|
||||||
else
|
else
|
||||||
thread = $('.thread')
|
|
||||||
posts = []
|
|
||||||
nodes = []
|
nodes = []
|
||||||
|
Unread.order = new RandomAccessList
|
||||||
g.posts.forEach (post) ->
|
QuoteThreading.inserted = {}
|
||||||
posts.push post unless post is post.thread.OP or post.isClone
|
posts.forEach (post) ->
|
||||||
|
return if post.isFetchedQuote
|
||||||
|
Unread.order.push post
|
||||||
|
nodes.push post.nodes.root if post.isReply
|
||||||
|
if QuoteThreading.children[post.fullID]
|
||||||
|
delete QuoteThreading.children[post.fullID]
|
||||||
|
$.rmClass post.nodes.root, 'threadOP'
|
||||||
|
$.rm post.nodes.threadContainer
|
||||||
|
delete post.nodes.threadContainer
|
||||||
|
$.add thread.OP.nodes.root.parentNode, nodes
|
||||||
|
|
||||||
posts.sort (a, b) -> a.ID - b.ID
|
Unread.position = Unread.order.first
|
||||||
|
Unread.updatePosition()
|
||||||
nodes.push post.nodes.root for post in posts
|
Unread.setLine true
|
||||||
$.add thread, nodes
|
Unread.read()
|
||||||
|
Unread.update()
|
||||||
containers = $$ '.threadContainer', thread
|
|
||||||
$.rm container for container in containers
|
|
||||||
$.rmClass post, 'threadOP' for post in $$ '.threadOP'
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
kb: ->
|
|
||||||
control = $.id 'threadingControl'
|
|
||||||
control.checked = not control.checked
|
|
||||||
QuoteThreading.toggle.call control
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
Quotify =
|
Quotify =
|
||||||
init: ->
|
init: ->
|
||||||
return if !Conf['Resurrect Quotes']
|
return if g.VIEW not in ['index', 'thread'] or !Conf['Resurrect Quotes'] and g.BOARD.ID isnt 'pol'
|
||||||
|
|
||||||
if Conf['Comment Expansion']
|
if Conf['Comment Expansion']
|
||||||
ExpandComment.callbacks.push @node
|
ExpandComment.callbacks.push @node
|
||||||
@ -41,25 +41,45 @@ Quotify =
|
|||||||
quoteID = "#{boardID}.#{postID}"
|
quoteID = "#{boardID}.#{postID}"
|
||||||
|
|
||||||
if post = g.posts[quoteID]
|
if post = g.posts[quoteID]
|
||||||
# Don't add 'deadlink' when quotifying in an archived post,
|
unless post.isDead
|
||||||
# and we don't know if the post died yet.
|
# Don't (Dead) when quotifying in an archived post,
|
||||||
a = $.el 'a',
|
# and we know the post still exists.
|
||||||
href: Build.path boardID, post.thread.ID, postID
|
a = $.el 'a',
|
||||||
className: if post.isDead then 'quotelink deadlink' else 'quotelink'
|
href: Build.postURL boardID, post.thread.ID, postID
|
||||||
textContent: quote
|
className: 'quotelink'
|
||||||
$.extend a.dataset, {boardID, threadID: post.thread.ID, postID}
|
textContent: quote
|
||||||
|
else
|
||||||
|
# Replace the .deadlink span if we can redirect.
|
||||||
|
a = $.el 'a',
|
||||||
|
href: Build.postURL boardID, post.thread.ID, postID
|
||||||
|
className: 'quotelink deadlink'
|
||||||
|
target: '_blank'
|
||||||
|
textContent: "#{quote}\u00A0(Dead)"
|
||||||
|
$.extend a.dataset, {boardID, threadID: post.thread.ID, postID}
|
||||||
|
|
||||||
else if redirect = Redirect.to 'thread', {boardID, postID}
|
else if @board.ID is boardID is 'pol' and postID.length is 9 and postID[-2] is postID[-1]
|
||||||
# Replace the .deadlink span if we can redirect.
|
# XXX Misquotes due to fake doubles on /pol/. Assume they are all intra-thread.
|
||||||
|
postID = postID[...-1]
|
||||||
|
quoteID = "#{boardID}.#{postID}"
|
||||||
a = $.el 'a',
|
a = $.el 'a',
|
||||||
href: redirect
|
href: Build.postURL boardID, @thread.ID, postID
|
||||||
className: 'deadlink'
|
className: 'quotelink'
|
||||||
textContent: quote
|
textContent: quote
|
||||||
target: '_blank'
|
|
||||||
if Redirect.to 'post', {boardID, postID}
|
else if Conf['Resurrect Quotes']
|
||||||
# Make it function as a normal quote if we can fetch the post.
|
redirect = Redirect.to 'thread', {boardID, threadID: 0, postID}
|
||||||
$.addClass a, 'quotelink'
|
fetchable = Redirect.to 'post', {boardID, postID}
|
||||||
$.extend a.dataset, {boardID, postID}
|
if redirect or fetchable
|
||||||
|
# Replace the .deadlink span if we can redirect or fetch the post.
|
||||||
|
a = $.el 'a',
|
||||||
|
href: redirect or 'javascript:;'
|
||||||
|
className: 'deadlink'
|
||||||
|
target: '_blank'
|
||||||
|
textContent: "#{quote}\u00A0(Dead)"
|
||||||
|
if fetchable
|
||||||
|
# Make it function as a normal quote if we can fetch the post.
|
||||||
|
$.addClass a, 'quotelink'
|
||||||
|
$.extend a.dataset, {boardID, postID}
|
||||||
|
|
||||||
@quotes.push quoteID unless quoteID in @quotes
|
@quotes.push quoteID unless quoteID in @quotes
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user