I really don't like iterating through objects.
This commit is contained in:
parent
481ca6af72
commit
dc5daeba06
@ -104,7 +104,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var $, $$, Anonymize, ArchiveLink, AutoGIF, Banner, Board, Build, Callbacks, CatalogLinks, Clone, Conf, Config, CustomCSS, DataBoard, DeleteLink, Dice, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, ImageExpand, ImageHover, ImageLoader, Index, InfiniScroll, Keybinds, Linkify, Main, Menu, Nav, Navigate, 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, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, c, d, doc, g,
|
var $, $$, Anonymize, ArchiveLink, AutoGIF, Banner, Board, Build, Callbacks, CatalogLinks, Clone, Conf, Config, CustomCSS, DataBoard, DeleteLink, Dice, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, ImageExpand, ImageHover, ImageLoader, Index, InfiniScroll, Keybinds, Linkify, Main, Menu, Nav, Navigate, 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,
|
||||||
__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; },
|
__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; },
|
||||||
__slice = [].slice,
|
__slice = [].slice,
|
||||||
__hasProp = {}.hasOwnProperty,
|
__hasProp = {}.hasOwnProperty,
|
||||||
@ -363,9 +363,7 @@
|
|||||||
g = {
|
g = {
|
||||||
VERSION: '1.3.2',
|
VERSION: '1.3.2',
|
||||||
NAMESPACE: '4chan X.',
|
NAMESPACE: '4chan X.',
|
||||||
boards: {},
|
boards: {}
|
||||||
threads: {},
|
|
||||||
posts: {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$ = function(selector, root) {
|
$ = function(selector, root) {
|
||||||
@ -807,6 +805,16 @@
|
|||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
$.remove = function(arr, value) {
|
||||||
|
var i;
|
||||||
|
i = arr.indexOf(value);
|
||||||
|
if (i === -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
arr.splice(i, 1);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
$$ = function(selector, root) {
|
$$ = function(selector, root) {
|
||||||
if (root == null) {
|
if (root == null) {
|
||||||
root = d.body;
|
root = d.body;
|
||||||
@ -880,8 +888,8 @@
|
|||||||
|
|
||||||
function Board(ID) {
|
function Board(ID) {
|
||||||
this.ID = ID;
|
this.ID = ID;
|
||||||
this.threads = {};
|
this.threads = new SimpleDict;
|
||||||
this.posts = {};
|
this.posts = new SimpleDict;
|
||||||
g.boards[this] = this;
|
g.boards[this] = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -900,12 +908,12 @@
|
|||||||
this.ID = ID;
|
this.ID = ID;
|
||||||
this.board = board;
|
this.board = board;
|
||||||
this.fullID = "" + this.board + "." + this.ID;
|
this.fullID = "" + this.board + "." + this.ID;
|
||||||
this.posts = {};
|
this.posts = new SimpleDict;
|
||||||
this.isSticky = false;
|
this.isSticky = false;
|
||||||
this.isClosed = false;
|
this.isClosed = false;
|
||||||
this.postLimit = false;
|
this.postLimit = false;
|
||||||
this.fileLimit = false;
|
this.fileLimit = false;
|
||||||
g.threads[this.fullID] = board.threads[this] = this;
|
g.threads.push(this.fullID, board.threads.push(this, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread.prototype.setPage = function(pageNum) {
|
Thread.prototype.setPage = function(pageNum) {
|
||||||
@ -949,14 +957,11 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
Thread.prototype.collect = function() {
|
Thread.prototype.collect = function() {
|
||||||
var post, postID, _ref;
|
this.posts.forEach(function(post) {
|
||||||
_ref = this.posts;
|
return post.collect();
|
||||||
for (postID in _ref) {
|
});
|
||||||
post = _ref[postID];
|
g.threads.rm(this.fullID);
|
||||||
post.collect();
|
return this.board.threads.rm(this);
|
||||||
}
|
|
||||||
delete g.threads[this.fullID];
|
|
||||||
return delete this.board.threads[this];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return Thread;
|
return Thread;
|
||||||
@ -1035,7 +1040,7 @@
|
|||||||
this.parseQuotes();
|
this.parseQuotes();
|
||||||
this.parseFile(that);
|
this.parseFile(that);
|
||||||
this.clones = [];
|
this.clones = [];
|
||||||
g.posts[this.fullID] = thread.posts[this] = board.posts[this] = this;
|
g.posts.push(this.fullID, thread.posts.push(this, board.posts.push(this, this)));
|
||||||
if (that.isArchived) {
|
if (that.isArchived) {
|
||||||
this.kill();
|
this.kill();
|
||||||
}
|
}
|
||||||
@ -1205,9 +1210,9 @@
|
|||||||
|
|
||||||
Post.prototype.collect = function() {
|
Post.prototype.collect = function() {
|
||||||
this.kill();
|
this.kill();
|
||||||
delete g.posts[this.fullID];
|
g.posts.rm(this.fullID);
|
||||||
delete this.thread.posts[this];
|
this.thread.posts.rm(this);
|
||||||
return delete this.board.posts[this];
|
return this.board.posts.rm(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
Post.prototype.addClone = function(context) {
|
Post.prototype.addClone = function(context) {
|
||||||
@ -1605,6 +1610,41 @@
|
|||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
SimpleDict = (function() {
|
||||||
|
function SimpleDict() {
|
||||||
|
this.keys = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleDict.prototype.push = function(key, data) {
|
||||||
|
key = "" + key;
|
||||||
|
if (!this[key]) {
|
||||||
|
this.keys.push(key);
|
||||||
|
}
|
||||||
|
return this[key] = data;
|
||||||
|
};
|
||||||
|
|
||||||
|
SimpleDict.prototype.rm = function(key) {
|
||||||
|
key = "" + key;
|
||||||
|
if ($.remove(this.keys, key)) {
|
||||||
|
return delete this[key];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SimpleDict.prototype.forEach = function(fn) {
|
||||||
|
var key, _i, _len, _ref, _results;
|
||||||
|
_ref = __slice.call(this.keys);
|
||||||
|
_results = [];
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
key = _ref[_i];
|
||||||
|
_results.push(fn(this[key]));
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
};
|
||||||
|
|
||||||
|
return SimpleDict;
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
Polyfill = {
|
Polyfill = {
|
||||||
init: function() {},
|
init: function() {},
|
||||||
notificationPermission: function() {
|
notificationPermission: function() {
|
||||||
@ -2559,7 +2599,7 @@
|
|||||||
}
|
}
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
err = _error;
|
err = _error;
|
||||||
c.error('Index failure:', err);
|
c.error("Index failure: " + err.message, err.stack);
|
||||||
if (notice) {
|
if (notice) {
|
||||||
notice.setType('error');
|
notice.setType('error');
|
||||||
notice.el.lastElementChild.textContent = 'Index refresh failed.';
|
notice.el.lastElementChild.textContent = 'Index refresh failed.';
|
||||||
@ -2587,7 +2627,6 @@
|
|||||||
return Index.setPage();
|
return Index.setPage();
|
||||||
},
|
},
|
||||||
parseThreadList: function(pages) {
|
parseThreadList: function(pages) {
|
||||||
var thread, threadID, _ref, _ref1;
|
|
||||||
Index.pagesNum = pages.length;
|
Index.pagesNum = pages.length;
|
||||||
Index.threadsNumPerPage = pages[0].threads.length;
|
Index.threadsNumPerPage = pages[0].threads.length;
|
||||||
Index.liveThreadData = pages.reduce((function(arr, next) {
|
Index.liveThreadData = pages.reduce((function(arr, next) {
|
||||||
@ -2596,13 +2635,12 @@
|
|||||||
Index.liveThreadIDs = Index.liveThreadData.map(function(data) {
|
Index.liveThreadIDs = Index.liveThreadData.map(function(data) {
|
||||||
return data.no;
|
return data.no;
|
||||||
});
|
});
|
||||||
_ref = g.BOARD.threads;
|
g.BOARD.threads.forEach(function(thread) {
|
||||||
for (threadID in _ref) {
|
var _ref;
|
||||||
thread = _ref[threadID];
|
if (_ref = thread.ID, __indexOf.call(Index.liveThreadIDs, _ref) < 0) {
|
||||||
if (_ref1 = thread.ID, __indexOf.call(Index.liveThreadIDs, _ref1) < 0) {
|
return thread.collect();
|
||||||
thread.collect();
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
},
|
},
|
||||||
buildThreads: function() {
|
buildThreads: function() {
|
||||||
var err, errors, i, posts, thread, threadData, threadRoot, threads, _i, _len, _ref;
|
var err, errors, i, posts, thread, threadData, threadRoot, threads, _i, _len, _ref;
|
||||||
@ -2612,20 +2650,20 @@
|
|||||||
_ref = Index.liveThreadData;
|
_ref = Index.liveThreadData;
|
||||||
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
|
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
|
||||||
threadData = _ref[i];
|
threadData = _ref[i];
|
||||||
threadRoot = Build.thread(g.BOARD, threadData);
|
|
||||||
Index.nodes.push(threadRoot, $.el('hr'));
|
|
||||||
if (thread = g.BOARD.threads[threadData.no]) {
|
|
||||||
thread.setPage(Math.floor(i / Index.threadsNumPerPage));
|
|
||||||
thread.setStatus('Sticky', !!threadData.sticky);
|
|
||||||
thread.setStatus('Closed', !!threadData.closed);
|
|
||||||
} else {
|
|
||||||
thread = new Thread(threadData.no, g.BOARD);
|
|
||||||
threads.push(thread);
|
|
||||||
}
|
|
||||||
if (thread.ID in thread.posts) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
|
threadRoot = Build.thread(g.BOARD, threadData);
|
||||||
|
if (thread = g.BOARD.threads[threadData.no]) {
|
||||||
|
thread.setPage(Math.floor(i / Index.threadsNumPerPage));
|
||||||
|
thread.setStatus('Sticky', !!threadData.sticky);
|
||||||
|
thread.setStatus('Closed', !!threadData.closed);
|
||||||
|
} else {
|
||||||
|
thread = new Thread(threadData.no, g.BOARD);
|
||||||
|
threads.push(thread);
|
||||||
|
}
|
||||||
|
Index.nodes.push(threadRoot, $.el('hr'));
|
||||||
|
if (thread.ID in thread.posts) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
posts.push(new Post($('.opContainer', threadRoot), thread, g.BOARD));
|
posts.push(new Post($('.opContainer', threadRoot), thread, g.BOARD));
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
err = _error;
|
err = _error;
|
||||||
@ -2633,7 +2671,7 @@
|
|||||||
errors = [];
|
errors = [];
|
||||||
}
|
}
|
||||||
errors.push({
|
errors.push({
|
||||||
message: "Parsing of Post No." + thread + " failed. Post will be skipped.",
|
message: "Parsing of Thread No." + thread + " failed. Thread will be skipped.",
|
||||||
error: err
|
error: err
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -3105,36 +3143,38 @@
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
allQuotelinksLinkingTo: function(post) {
|
allQuotelinksLinkingTo: function(post) {
|
||||||
var ID, handleQuotes, quote, quotedPost, quotelinks, quoterPost, _i, _len, _ref, _ref1, _ref2;
|
var fullID, handleQuotes, posts, qPost, quote, quotelinks, _i, _len, _ref;
|
||||||
quotelinks = [];
|
quotelinks = [];
|
||||||
handleQuotes = function(post, type) {
|
posts = g.posts;
|
||||||
|
fullID = {
|
||||||
|
post: post
|
||||||
|
};
|
||||||
|
handleQuotes = function(qPost, type) {
|
||||||
var clone, _i, _len, _ref;
|
var clone, _i, _len, _ref;
|
||||||
quotelinks.push.apply(quotelinks, post.nodes[type]);
|
quotelinks.push.apply(quotelinks, qPost.nodes[type]);
|
||||||
_ref = post.clones;
|
_ref = qPost.clones;
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
clone = _ref[_i];
|
clone = _ref[_i];
|
||||||
quotelinks.push.apply(quotelinks, clone.nodes[type]);
|
quotelinks.push.apply(quotelinks, clone.nodes[type]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
_ref = g.posts;
|
posts.forEach(function(qPost) {
|
||||||
for (ID in _ref) {
|
if (__indexOf.call(qPost.quotes, fullID) >= 0) {
|
||||||
quoterPost = _ref[ID];
|
return handleQuotes(qPost, 'quotelinks');
|
||||||
if (_ref1 = post.fullID, __indexOf.call(quoterPost.quotes, _ref1) >= 0) {
|
|
||||||
handleQuotes(quoterPost, 'quotelinks');
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
if (Conf['Quote Backlinks']) {
|
if (Conf['Quote Backlinks']) {
|
||||||
_ref2 = post.quotes;
|
_ref = post.quotes;
|
||||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
quote = _ref2[_i];
|
quote = _ref[_i];
|
||||||
if (quotedPost = g.posts[quote]) {
|
if (qPost = posts[quote]) {
|
||||||
handleQuotes(quotedPost, 'backlinks');
|
handleQuotes(qPost, 'backlinks');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return quotelinks.filter(function(quotelink) {
|
return quotelinks.filter(function(quotelink) {
|
||||||
var boardID, postID, _ref3;
|
var boardID, postID, _ref1;
|
||||||
_ref3 = Get.postDataFromLink(quotelink), boardID = _ref3.boardID, postID = _ref3.postID;
|
_ref1 = Get.postDataFromLink(quotelink), boardID = _ref1.boardID, postID = _ref1.postID;
|
||||||
return boardID === post.board.ID && postID === post.ID;
|
return boardID === post.board.ID && postID === post.ID;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -4400,16 +4440,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
apply: function() {
|
apply: function() {
|
||||||
var ID, args, fullID, post, recursive, _ref;
|
var args, fullID, post, recursive;
|
||||||
recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
|
recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
|
||||||
fullID = post.fullID;
|
fullID = post.fullID;
|
||||||
_ref = g.posts;
|
return g.posts.forEach(function(post) {
|
||||||
for (ID in _ref) {
|
|
||||||
post = _ref[ID];
|
|
||||||
if (__indexOf.call(post.quotes, fullID) >= 0) {
|
if (__indexOf.call(post.quotes, fullID) >= 0) {
|
||||||
recursive.apply(null, [post].concat(__slice.call(args)));
|
return recursive.apply(null, [post].concat(__slice.call(args)));
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -5125,14 +5163,11 @@
|
|||||||
return QuoteThreading.force();
|
return QuoteThreading.force();
|
||||||
},
|
},
|
||||||
force: function() {
|
force: function() {
|
||||||
var ID, post, _ref;
|
return g.posts.forEach(function(post) {
|
||||||
_ref = g.posts;
|
|
||||||
for (ID in _ref) {
|
|
||||||
post = _ref[ID];
|
|
||||||
if (post.cb) {
|
if (post.cb) {
|
||||||
post.cb(true);
|
return post.cb(true);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
},
|
},
|
||||||
node: function() {
|
node: function() {
|
||||||
var keys, len, post, posts, quote, _i, _len, _ref;
|
var keys, len, post, posts, quote, _i, _len, _ref;
|
||||||
@ -5199,20 +5234,18 @@
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
toggle: function() {
|
toggle: function() {
|
||||||
var ID, container, containers, nodes, post, posts, thread, _i, _j, _k, _len, _len1, _len2, _ref, _ref1;
|
var container, containers, nodes, post, posts, thread, _i, _j, _k, _len, _len1, _len2, _ref;
|
||||||
if (QuoteThreading.enabled = this.checked) {
|
if (QuoteThreading.enabled = this.checked) {
|
||||||
QuoteThreading.force();
|
QuoteThreading.force();
|
||||||
} else {
|
} else {
|
||||||
thread = $('.thread');
|
thread = $('.thread');
|
||||||
posts = [];
|
posts = [];
|
||||||
nodes = [];
|
nodes = [];
|
||||||
_ref = g.posts;
|
g.posts.forEach(function(post) {
|
||||||
for (ID in _ref) {
|
|
||||||
post = _ref[ID];
|
|
||||||
if (!(post === post.thread.OP || post.isClone)) {
|
if (!(post === post.thread.OP || post.isClone)) {
|
||||||
posts.push(post);
|
return posts.push(post);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
posts.sort(function(a, b) {
|
posts.sort(function(a, b) {
|
||||||
return a.ID - b.ID;
|
return a.ID - b.ID;
|
||||||
});
|
});
|
||||||
@ -5226,9 +5259,9 @@
|
|||||||
container = containers[_j];
|
container = containers[_j];
|
||||||
$.rm(container);
|
$.rm(container);
|
||||||
}
|
}
|
||||||
_ref1 = $$('.threadOP');
|
_ref = $$('.threadOP');
|
||||||
for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
|
for (_k = 0, _len2 = _ref.length; _k < _len2; _k++) {
|
||||||
post = _ref1[_k];
|
post = _ref[_k];
|
||||||
$.rmClass(post, 'threadOP');
|
$.rmClass(post, 'threadOP');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5836,13 +5869,15 @@
|
|||||||
return QR.nodes.fileInput.click();
|
return QR.nodes.fileInput.click();
|
||||||
},
|
},
|
||||||
generatePostableThreadsList: function() {
|
generatePostableThreadsList: function() {
|
||||||
var list, options, thread, val;
|
var list, options, thread, val, _i, _len, _ref;
|
||||||
if (!QR.nodes) {
|
if (!QR.nodes) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
list = QR.nodes.thread;
|
list = QR.nodes.thread;
|
||||||
options = [list.firstChild];
|
options = [list.firstChild];
|
||||||
for (thread in g.BOARD.threads) {
|
_ref = g.BOARD.threads.keys;
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
thread = _ref[_i];
|
||||||
options.push($.el('option', {
|
options.push($.el('option', {
|
||||||
value: thread,
|
value: thread,
|
||||||
textContent: "Thread No." + thread
|
textContent: "Thread No." + thread
|
||||||
@ -7371,8 +7406,19 @@
|
|||||||
return ImageExpand.toggle(Get.postFromNode(this));
|
return ImageExpand.toggle(Get.postFromNode(this));
|
||||||
},
|
},
|
||||||
toggleAll: function() {
|
toggleAll: function() {
|
||||||
var ID, file, func, post, _i, _len, _ref, _ref1;
|
var func;
|
||||||
$.event('CloseMenu');
|
$.event('CloseMenu');
|
||||||
|
func = function(post) {
|
||||||
|
var file;
|
||||||
|
file = post.file;
|
||||||
|
if (!(file && file.isImage && doc.contains(post.nodes.root))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return $.queueTask(func, post);
|
||||||
|
};
|
||||||
if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) {
|
if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) {
|
||||||
ImageExpand.EAI.className = 'contract-all-shortcut fa fa-compress';
|
ImageExpand.EAI.className = 'contract-all-shortcut fa fa-compress';
|
||||||
ImageExpand.EAI.title = 'Contract All Images';
|
ImageExpand.EAI.title = 'Contract All Images';
|
||||||
@ -7382,22 +7428,15 @@
|
|||||||
ImageExpand.EAI.title = 'Expand All Images';
|
ImageExpand.EAI.title = 'Expand All Images';
|
||||||
func = ImageExpand.contract;
|
func = ImageExpand.contract;
|
||||||
}
|
}
|
||||||
_ref = g.posts;
|
return g.posts.forEach(function(post) {
|
||||||
for (ID in _ref) {
|
var _i, _len, _ref;
|
||||||
post = _ref[ID];
|
func(post);
|
||||||
_ref1 = [post].concat(post.clones);
|
_ref = post.clones;
|
||||||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
post = _ref1[_i];
|
post = _ref[_i];
|
||||||
file = post.file;
|
func(post);
|
||||||
if (!(file && file.isImage && doc.contains(post.nodes.root))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$.queueTask(func, post);
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
},
|
},
|
||||||
setFitness: function() {
|
setFitness: function() {
|
||||||
return (this.checked ? $.addClass : $.rmClass)(doc, this.name.toLowerCase().replace(/\s+/g, '-'));
|
return (this.checked ? $.addClass : $.rmClass)(doc, this.name.toLowerCase().replace(/\s+/g, '-'));
|
||||||
@ -7681,6 +7720,10 @@
|
|||||||
name: 'Image Replace',
|
name: 'Image Replace',
|
||||||
cb: this.node
|
cb: this.node
|
||||||
});
|
});
|
||||||
|
Thread.callbacks.push({
|
||||||
|
name: 'Image Replace',
|
||||||
|
cb: this.thread
|
||||||
|
});
|
||||||
if (!(Conf['Image Prefetching'] && g.VIEW === 'thread')) {
|
if (!(Conf['Image Prefetching'] && g.VIEW === 'thread')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -7695,6 +7738,9 @@
|
|||||||
order: 104
|
order: 104
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
thread: function() {
|
||||||
|
return ImageLoader.thread = this;
|
||||||
|
},
|
||||||
node: function() {
|
node: function() {
|
||||||
var URL, img, string, style, thumb, type, _ref, _ref1;
|
var URL, img, string, style, thumb, type, _ref, _ref1;
|
||||||
if (this.isClone || this.isHidden || this.thread.isHidden || !((_ref = this.file) != null ? _ref.isImage : void 0)) {
|
if (this.isClone || this.isHidden || this.thread.isHidden || !((_ref = this.file) != null ? _ref.isImage : void 0)) {
|
||||||
@ -7717,14 +7763,10 @@
|
|||||||
return img.src = URL;
|
return img.src = URL;
|
||||||
},
|
},
|
||||||
toggle: function() {
|
toggle: function() {
|
||||||
var enabled, id, post, _ref;
|
var enabled;
|
||||||
enabled = Conf['prefetch'] = this.checked;
|
enabled = Conf['prefetch'] = this.checked;
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
_ref = g.threads["" + g.BOARD.ID + "." + g.THREADID].posts;
|
ImageLoader.thread.posts.forEach(ImageLoader.node.call);
|
||||||
for (id in _ref) {
|
|
||||||
post = _ref[id];
|
|
||||||
ImageLoader.node.call(post);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -8721,17 +8763,15 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
node: function() {
|
node: function() {
|
||||||
var ID, fileCount, post, postCount, _ref;
|
var fileCount, postCount;
|
||||||
postCount = 0;
|
postCount = 0;
|
||||||
fileCount = 0;
|
fileCount = 0;
|
||||||
_ref = this.posts;
|
this.posts.forEach(function(post) {
|
||||||
for (ID in _ref) {
|
|
||||||
post = _ref[ID];
|
|
||||||
postCount++;
|
postCount++;
|
||||||
if (post.file) {
|
if (post.file) {
|
||||||
fileCount++;
|
return fileCount++;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
ThreadStats.thread = this;
|
ThreadStats.thread = this;
|
||||||
ThreadStats.fetchPage();
|
ThreadStats.fetchPage();
|
||||||
ThreadStats.update(postCount, fileCount);
|
ThreadStats.update(postCount, fileCount);
|
||||||
@ -9112,7 +9152,7 @@
|
|||||||
return new Notice('info', "The thread is " + change + ".", 30);
|
return new Notice('info', "The thread is " + change + ".", 30);
|
||||||
},
|
},
|
||||||
parse: function(postObjects) {
|
parse: function(postObjects) {
|
||||||
var ID, OP, count, deletedFiles, deletedPosts, files, index, key, node, num, post, postObject, posts, root, scroll, _i, _len, _ref;
|
var ID, OP, count, deletedFiles, deletedPosts, files, index, key, node, num, post, postObject, posts, root, scroll, _i, _j, _len, _len1, _ref;
|
||||||
OP = postObjects[0];
|
OP = postObjects[0];
|
||||||
Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler;
|
Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler;
|
||||||
ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky);
|
ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky);
|
||||||
@ -9139,9 +9179,11 @@
|
|||||||
}
|
}
|
||||||
deletedPosts = [];
|
deletedPosts = [];
|
||||||
deletedFiles = [];
|
deletedFiles = [];
|
||||||
_ref = ThreadUpdater.thread.posts;
|
posts = ThreadUpdater.thread.posts;
|
||||||
for (ID in _ref) {
|
_ref = posts.keys;
|
||||||
post = _ref[ID];
|
for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
|
||||||
|
ID = _ref[_j];
|
||||||
|
post = posts[ID];
|
||||||
ID = +ID;
|
ID = +ID;
|
||||||
if (__indexOf.call(index, ID) < 0) {
|
if (__indexOf.call(index, ID) < 0) {
|
||||||
post.kill();
|
post.kill();
|
||||||
@ -9360,7 +9402,7 @@
|
|||||||
_ref = db.data.boards[boardID];
|
_ref = db.data.boards[boardID];
|
||||||
for (threadID in _ref) {
|
for (threadID in _ref) {
|
||||||
data = _ref[threadID];
|
data = _ref[threadID];
|
||||||
if (!data.isDead && !(threadID in g.BOARD.threads)) {
|
if (!data.isDead && __indexOf.call(g.BOARD.threads.keys, threadID) < 0) {
|
||||||
if (Conf['Auto Prune']) {
|
if (Conf['Auto Prune']) {
|
||||||
ThreadWatcher.db["delete"]({
|
ThreadWatcher.db["delete"]({
|
||||||
boardID: boardID,
|
boardID: boardID,
|
||||||
@ -9498,7 +9540,7 @@
|
|||||||
return div;
|
return div;
|
||||||
},
|
},
|
||||||
refresh: function() {
|
refresh: function() {
|
||||||
var boardID, data, helper, list, nodes, refresher, thread, threadID, toggler, watched, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3;
|
var boardID, data, helper, list, nodes, refresher, thread, threadID, threads, toggler, watched, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3;
|
||||||
nodes = [];
|
nodes = [];
|
||||||
_ref = ThreadWatcher.getAll();
|
_ref = ThreadWatcher.getAll();
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
@ -9508,9 +9550,11 @@
|
|||||||
list = ThreadWatcher.list;
|
list = ThreadWatcher.list;
|
||||||
$.rmAll(list);
|
$.rmAll(list);
|
||||||
$.add(list, nodes);
|
$.add(list, nodes);
|
||||||
_ref2 = g.BOARD.threads;
|
threads = g.BOARD.threads;
|
||||||
for (threadID in _ref2) {
|
_ref2 = threads.keys;
|
||||||
thread = _ref2[threadID];
|
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
|
||||||
|
threadID = _ref2[_j];
|
||||||
|
thread = threads[threadID];
|
||||||
toggler = $('.watch-thread-link', thread.OP.nodes.post);
|
toggler = $('.watch-thread-link', thread.OP.nodes.post);
|
||||||
watched = ThreadWatcher.db.get({
|
watched = ThreadWatcher.db.get({
|
||||||
boardID: thread.board.ID,
|
boardID: thread.board.ID,
|
||||||
@ -9521,8 +9565,8 @@
|
|||||||
toggler.title = "" + helper[1] + " Thread";
|
toggler.title = "" + helper[1] + " Thread";
|
||||||
}
|
}
|
||||||
_ref3 = ThreadWatcher.menu.refreshers;
|
_ref3 = ThreadWatcher.menu.refreshers;
|
||||||
for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
|
for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) {
|
||||||
refresher = _ref3[_j];
|
refresher = _ref3[_k];
|
||||||
refresher();
|
refresher();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -9763,16 +9807,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
ready: function() {
|
ready: function() {
|
||||||
var ID, post, posts, _ref;
|
var posts;
|
||||||
$.off(d, '4chanXInitFinished', Unread.ready);
|
$.off(d, '4chanXInitFinished', Unread.ready);
|
||||||
posts = [];
|
posts = [];
|
||||||
_ref = Unread.thread.posts;
|
Unread.thread.posts.forEach(function(post) {
|
||||||
for (ID in _ref) {
|
|
||||||
post = _ref[ID];
|
|
||||||
if (post.isReply) {
|
if (post.isReply) {
|
||||||
posts.push(post);
|
return posts.push(post);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
if (!Conf['Quote Threading']) {
|
if (!Conf['Quote Threading']) {
|
||||||
Unread.addPosts(posts);
|
Unread.addPosts(posts);
|
||||||
}
|
}
|
||||||
@ -9784,7 +9826,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
scroll: function() {
|
scroll: function() {
|
||||||
var down, hash, post, posts, root;
|
var down, hash, keys, post, posts, root;
|
||||||
if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) {
|
if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -9799,8 +9841,9 @@
|
|||||||
}
|
}
|
||||||
down = true;
|
down = true;
|
||||||
} else {
|
} else {
|
||||||
posts = Object.keys(Unread.thread.posts);
|
posts = Unread.thread.posts;
|
||||||
root = Unread.thread.posts[posts[posts.length - 1]].nodes.root;
|
keys = posts.keys;
|
||||||
|
root = posts[keys[keys.length - 1]].nodes.root;
|
||||||
}
|
}
|
||||||
if (Header.getBottomOf(root) < 0) {
|
if (Header.getBottomOf(root) < 0) {
|
||||||
return Header.scrollTo(root, down);
|
return Header.scrollTo(root, down);
|
||||||
@ -10700,13 +10743,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onIndexRefresh: function() {
|
onIndexRefresh: function() {
|
||||||
var thread, threadID, _ref;
|
|
||||||
ExpandThread.disconnect(true);
|
ExpandThread.disconnect(true);
|
||||||
_ref = g.BOARD.threads;
|
return g.BOARD.threads.forEach(function(thread) {
|
||||||
for (threadID in _ref) {
|
return ExpandThread.setButton(thread);
|
||||||
thread = _ref[threadID];
|
});
|
||||||
ExpandThread.setButton(thread);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
text: function(status, posts, files) {
|
text: function(status, posts, files) {
|
||||||
return ("" + status + " " + posts + " post" + (posts > 1 ? 's' : '')) + (+files ? " and " + files + " image repl" + (files > 1 ? 'ies' : 'y') : "") + (" " + (status === '-' ? 'shown' : 'omitted') + ".");
|
return ("" + status + " " + posts + " post" + (posts > 1 ? 's' : '')) + (+files ? " and " + files + " image repl" + (files > 1 ? 'ies' : 'y') : "") + (" " + (status === '-' ? 'shown' : 'omitted') + ".");
|
||||||
@ -11924,13 +11964,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
clean: function() {
|
clean: function() {
|
||||||
var id, posts, thread, threads, _ref;
|
var posts, threads;
|
||||||
posts = g.posts, threads = g.threads;
|
posts = g.posts, threads = g.threads;
|
||||||
_ref = g.threads;
|
g.threads.forEach(function(thread) {
|
||||||
for (id in _ref) {
|
return thread.collect();
|
||||||
thread = _ref[id];
|
});
|
||||||
thread.collect();
|
|
||||||
}
|
|
||||||
QuoteBacklink.containers = {};
|
QuoteBacklink.containers = {};
|
||||||
return $.rmAll($('.board'));
|
return $.rmAll($('.board'));
|
||||||
},
|
},
|
||||||
@ -12876,6 +12914,8 @@
|
|||||||
Main = {
|
Main = {
|
||||||
init: function() {
|
init: function() {
|
||||||
var db, flatten, pathname, _i, _len, _ref, _ref1;
|
var db, flatten, pathname, _i, _len, _ref, _ref1;
|
||||||
|
g.threads = new SimpleDict;
|
||||||
|
g.posts = new SimpleDict;
|
||||||
pathname = location.pathname.split('/');
|
pathname = location.pathname.split('/');
|
||||||
g.BOARD = new Board(pathname[1]);
|
g.BOARD = new Board(pathname[1]);
|
||||||
if ((_ref = g.BOARD.ID) === 'z' || _ref === 'fk') {
|
if ((_ref = g.BOARD.ID) === 'z' || _ref === 'fk') {
|
||||||
|
|||||||
@ -82,7 +82,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var $, $$, Anonymize, ArchiveLink, AutoGIF, Banner, Board, Build, Callbacks, CatalogLinks, Clone, Conf, Config, CustomCSS, DataBoard, DeleteLink, Dice, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, ImageExpand, ImageHover, ImageLoader, Index, InfiniScroll, Keybinds, Linkify, Main, Menu, Nav, Navigate, 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, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, c, d, doc, g,
|
var $, $$, Anonymize, ArchiveLink, AutoGIF, Banner, Board, Build, Callbacks, CatalogLinks, Clone, Conf, Config, CustomCSS, DataBoard, DeleteLink, Dice, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, ImageExpand, ImageHover, ImageLoader, Index, InfiniScroll, Keybinds, Linkify, Main, Menu, Nav, Navigate, 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,
|
||||||
__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; },
|
__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; },
|
||||||
__slice = [].slice,
|
__slice = [].slice,
|
||||||
__hasProp = {}.hasOwnProperty,
|
__hasProp = {}.hasOwnProperty,
|
||||||
@ -341,9 +341,7 @@
|
|||||||
g = {
|
g = {
|
||||||
VERSION: '1.3.2',
|
VERSION: '1.3.2',
|
||||||
NAMESPACE: '4chan X.',
|
NAMESPACE: '4chan X.',
|
||||||
boards: {},
|
boards: {}
|
||||||
threads: {},
|
|
||||||
posts: {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$ = function(selector, root) {
|
$ = function(selector, root) {
|
||||||
@ -812,6 +810,16 @@
|
|||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
$.remove = function(arr, value) {
|
||||||
|
var i;
|
||||||
|
i = arr.indexOf(value);
|
||||||
|
if (i === -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
arr.splice(i, 1);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
$$ = function(selector, root) {
|
$$ = function(selector, root) {
|
||||||
if (root == null) {
|
if (root == null) {
|
||||||
root = d.body;
|
root = d.body;
|
||||||
@ -885,8 +893,8 @@
|
|||||||
|
|
||||||
function Board(ID) {
|
function Board(ID) {
|
||||||
this.ID = ID;
|
this.ID = ID;
|
||||||
this.threads = {};
|
this.threads = new SimpleDict;
|
||||||
this.posts = {};
|
this.posts = new SimpleDict;
|
||||||
g.boards[this] = this;
|
g.boards[this] = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -905,12 +913,12 @@
|
|||||||
this.ID = ID;
|
this.ID = ID;
|
||||||
this.board = board;
|
this.board = board;
|
||||||
this.fullID = "" + this.board + "." + this.ID;
|
this.fullID = "" + this.board + "." + this.ID;
|
||||||
this.posts = {};
|
this.posts = new SimpleDict;
|
||||||
this.isSticky = false;
|
this.isSticky = false;
|
||||||
this.isClosed = false;
|
this.isClosed = false;
|
||||||
this.postLimit = false;
|
this.postLimit = false;
|
||||||
this.fileLimit = false;
|
this.fileLimit = false;
|
||||||
g.threads[this.fullID] = board.threads[this] = this;
|
g.threads.push(this.fullID, board.threads.push(this, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread.prototype.setPage = function(pageNum) {
|
Thread.prototype.setPage = function(pageNum) {
|
||||||
@ -954,14 +962,11 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
Thread.prototype.collect = function() {
|
Thread.prototype.collect = function() {
|
||||||
var post, postID, _ref;
|
this.posts.forEach(function(post) {
|
||||||
_ref = this.posts;
|
return post.collect();
|
||||||
for (postID in _ref) {
|
});
|
||||||
post = _ref[postID];
|
g.threads.rm(this.fullID);
|
||||||
post.collect();
|
return this.board.threads.rm(this);
|
||||||
}
|
|
||||||
delete g.threads[this.fullID];
|
|
||||||
return delete this.board.threads[this];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return Thread;
|
return Thread;
|
||||||
@ -1040,7 +1045,7 @@
|
|||||||
this.parseQuotes();
|
this.parseQuotes();
|
||||||
this.parseFile(that);
|
this.parseFile(that);
|
||||||
this.clones = [];
|
this.clones = [];
|
||||||
g.posts[this.fullID] = thread.posts[this] = board.posts[this] = this;
|
g.posts.push(this.fullID, thread.posts.push(this, board.posts.push(this, this)));
|
||||||
if (that.isArchived) {
|
if (that.isArchived) {
|
||||||
this.kill();
|
this.kill();
|
||||||
}
|
}
|
||||||
@ -1211,9 +1216,9 @@
|
|||||||
|
|
||||||
Post.prototype.collect = function() {
|
Post.prototype.collect = function() {
|
||||||
this.kill();
|
this.kill();
|
||||||
delete g.posts[this.fullID];
|
g.posts.rm(this.fullID);
|
||||||
delete this.thread.posts[this];
|
this.thread.posts.rm(this);
|
||||||
return delete this.board.posts[this];
|
return this.board.posts.rm(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
Post.prototype.addClone = function(context) {
|
Post.prototype.addClone = function(context) {
|
||||||
@ -1611,6 +1616,41 @@
|
|||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
SimpleDict = (function() {
|
||||||
|
function SimpleDict() {
|
||||||
|
this.keys = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleDict.prototype.push = function(key, data) {
|
||||||
|
key = "" + key;
|
||||||
|
if (!this[key]) {
|
||||||
|
this.keys.push(key);
|
||||||
|
}
|
||||||
|
return this[key] = data;
|
||||||
|
};
|
||||||
|
|
||||||
|
SimpleDict.prototype.rm = function(key) {
|
||||||
|
key = "" + key;
|
||||||
|
if ($.remove(this.keys, key)) {
|
||||||
|
return delete this[key];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SimpleDict.prototype.forEach = function(fn) {
|
||||||
|
var key, _i, _len, _ref, _results;
|
||||||
|
_ref = __slice.call(this.keys);
|
||||||
|
_results = [];
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
key = _ref[_i];
|
||||||
|
_results.push(fn(this[key]));
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
};
|
||||||
|
|
||||||
|
return SimpleDict;
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
Polyfill = {
|
Polyfill = {
|
||||||
init: function() {
|
init: function() {
|
||||||
this.notificationPermission();
|
this.notificationPermission();
|
||||||
@ -2569,7 +2609,7 @@
|
|||||||
}
|
}
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
err = _error;
|
err = _error;
|
||||||
c.error('Index failure:', err);
|
c.error("Index failure: " + err.message, err.stack);
|
||||||
if (notice) {
|
if (notice) {
|
||||||
notice.setType('error');
|
notice.setType('error');
|
||||||
notice.el.lastElementChild.textContent = 'Index refresh failed.';
|
notice.el.lastElementChild.textContent = 'Index refresh failed.';
|
||||||
@ -2597,7 +2637,6 @@
|
|||||||
return Index.setPage();
|
return Index.setPage();
|
||||||
},
|
},
|
||||||
parseThreadList: function(pages) {
|
parseThreadList: function(pages) {
|
||||||
var thread, threadID, _ref, _ref1;
|
|
||||||
Index.pagesNum = pages.length;
|
Index.pagesNum = pages.length;
|
||||||
Index.threadsNumPerPage = pages[0].threads.length;
|
Index.threadsNumPerPage = pages[0].threads.length;
|
||||||
Index.liveThreadData = pages.reduce((function(arr, next) {
|
Index.liveThreadData = pages.reduce((function(arr, next) {
|
||||||
@ -2606,13 +2645,12 @@
|
|||||||
Index.liveThreadIDs = Index.liveThreadData.map(function(data) {
|
Index.liveThreadIDs = Index.liveThreadData.map(function(data) {
|
||||||
return data.no;
|
return data.no;
|
||||||
});
|
});
|
||||||
_ref = g.BOARD.threads;
|
g.BOARD.threads.forEach(function(thread) {
|
||||||
for (threadID in _ref) {
|
var _ref;
|
||||||
thread = _ref[threadID];
|
if (_ref = thread.ID, __indexOf.call(Index.liveThreadIDs, _ref) < 0) {
|
||||||
if (_ref1 = thread.ID, __indexOf.call(Index.liveThreadIDs, _ref1) < 0) {
|
return thread.collect();
|
||||||
thread.collect();
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
},
|
},
|
||||||
buildThreads: function() {
|
buildThreads: function() {
|
||||||
var err, errors, i, posts, thread, threadData, threadRoot, threads, _i, _len, _ref;
|
var err, errors, i, posts, thread, threadData, threadRoot, threads, _i, _len, _ref;
|
||||||
@ -2622,20 +2660,20 @@
|
|||||||
_ref = Index.liveThreadData;
|
_ref = Index.liveThreadData;
|
||||||
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
|
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
|
||||||
threadData = _ref[i];
|
threadData = _ref[i];
|
||||||
threadRoot = Build.thread(g.BOARD, threadData);
|
|
||||||
Index.nodes.push(threadRoot, $.el('hr'));
|
|
||||||
if (thread = g.BOARD.threads[threadData.no]) {
|
|
||||||
thread.setPage(Math.floor(i / Index.threadsNumPerPage));
|
|
||||||
thread.setStatus('Sticky', !!threadData.sticky);
|
|
||||||
thread.setStatus('Closed', !!threadData.closed);
|
|
||||||
} else {
|
|
||||||
thread = new Thread(threadData.no, g.BOARD);
|
|
||||||
threads.push(thread);
|
|
||||||
}
|
|
||||||
if (thread.ID in thread.posts) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
|
threadRoot = Build.thread(g.BOARD, threadData);
|
||||||
|
if (thread = g.BOARD.threads[threadData.no]) {
|
||||||
|
thread.setPage(Math.floor(i / Index.threadsNumPerPage));
|
||||||
|
thread.setStatus('Sticky', !!threadData.sticky);
|
||||||
|
thread.setStatus('Closed', !!threadData.closed);
|
||||||
|
} else {
|
||||||
|
thread = new Thread(threadData.no, g.BOARD);
|
||||||
|
threads.push(thread);
|
||||||
|
}
|
||||||
|
Index.nodes.push(threadRoot, $.el('hr'));
|
||||||
|
if (thread.ID in thread.posts) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
posts.push(new Post($('.opContainer', threadRoot), thread, g.BOARD));
|
posts.push(new Post($('.opContainer', threadRoot), thread, g.BOARD));
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
err = _error;
|
err = _error;
|
||||||
@ -2643,7 +2681,7 @@
|
|||||||
errors = [];
|
errors = [];
|
||||||
}
|
}
|
||||||
errors.push({
|
errors.push({
|
||||||
message: "Parsing of Post No." + thread + " failed. Post will be skipped.",
|
message: "Parsing of Thread No." + thread + " failed. Thread will be skipped.",
|
||||||
error: err
|
error: err
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -3115,36 +3153,38 @@
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
allQuotelinksLinkingTo: function(post) {
|
allQuotelinksLinkingTo: function(post) {
|
||||||
var ID, handleQuotes, quote, quotedPost, quotelinks, quoterPost, _i, _len, _ref, _ref1, _ref2;
|
var fullID, handleQuotes, posts, qPost, quote, quotelinks, _i, _len, _ref;
|
||||||
quotelinks = [];
|
quotelinks = [];
|
||||||
handleQuotes = function(post, type) {
|
posts = g.posts;
|
||||||
|
fullID = {
|
||||||
|
post: post
|
||||||
|
};
|
||||||
|
handleQuotes = function(qPost, type) {
|
||||||
var clone, _i, _len, _ref;
|
var clone, _i, _len, _ref;
|
||||||
quotelinks.push.apply(quotelinks, post.nodes[type]);
|
quotelinks.push.apply(quotelinks, qPost.nodes[type]);
|
||||||
_ref = post.clones;
|
_ref = qPost.clones;
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
clone = _ref[_i];
|
clone = _ref[_i];
|
||||||
quotelinks.push.apply(quotelinks, clone.nodes[type]);
|
quotelinks.push.apply(quotelinks, clone.nodes[type]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
_ref = g.posts;
|
posts.forEach(function(qPost) {
|
||||||
for (ID in _ref) {
|
if (__indexOf.call(qPost.quotes, fullID) >= 0) {
|
||||||
quoterPost = _ref[ID];
|
return handleQuotes(qPost, 'quotelinks');
|
||||||
if (_ref1 = post.fullID, __indexOf.call(quoterPost.quotes, _ref1) >= 0) {
|
|
||||||
handleQuotes(quoterPost, 'quotelinks');
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
if (Conf['Quote Backlinks']) {
|
if (Conf['Quote Backlinks']) {
|
||||||
_ref2 = post.quotes;
|
_ref = post.quotes;
|
||||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
quote = _ref2[_i];
|
quote = _ref[_i];
|
||||||
if (quotedPost = g.posts[quote]) {
|
if (qPost = posts[quote]) {
|
||||||
handleQuotes(quotedPost, 'backlinks');
|
handleQuotes(qPost, 'backlinks');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return quotelinks.filter(function(quotelink) {
|
return quotelinks.filter(function(quotelink) {
|
||||||
var boardID, postID, _ref3;
|
var boardID, postID, _ref1;
|
||||||
_ref3 = Get.postDataFromLink(quotelink), boardID = _ref3.boardID, postID = _ref3.postID;
|
_ref1 = Get.postDataFromLink(quotelink), boardID = _ref1.boardID, postID = _ref1.postID;
|
||||||
return boardID === post.board.ID && postID === post.ID;
|
return boardID === post.board.ID && postID === post.ID;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -4403,16 +4443,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
apply: function() {
|
apply: function() {
|
||||||
var ID, args, fullID, post, recursive, _ref;
|
var args, fullID, post, recursive;
|
||||||
recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
|
recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
|
||||||
fullID = post.fullID;
|
fullID = post.fullID;
|
||||||
_ref = g.posts;
|
return g.posts.forEach(function(post) {
|
||||||
for (ID in _ref) {
|
|
||||||
post = _ref[ID];
|
|
||||||
if (__indexOf.call(post.quotes, fullID) >= 0) {
|
if (__indexOf.call(post.quotes, fullID) >= 0) {
|
||||||
recursive.apply(null, [post].concat(__slice.call(args)));
|
return recursive.apply(null, [post].concat(__slice.call(args)));
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -5128,14 +5166,11 @@
|
|||||||
return QuoteThreading.force();
|
return QuoteThreading.force();
|
||||||
},
|
},
|
||||||
force: function() {
|
force: function() {
|
||||||
var ID, post, _ref;
|
return g.posts.forEach(function(post) {
|
||||||
_ref = g.posts;
|
|
||||||
for (ID in _ref) {
|
|
||||||
post = _ref[ID];
|
|
||||||
if (post.cb) {
|
if (post.cb) {
|
||||||
post.cb(true);
|
return post.cb(true);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
},
|
},
|
||||||
node: function() {
|
node: function() {
|
||||||
var keys, len, post, posts, quote, _i, _len, _ref;
|
var keys, len, post, posts, quote, _i, _len, _ref;
|
||||||
@ -5202,20 +5237,18 @@
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
toggle: function() {
|
toggle: function() {
|
||||||
var ID, container, containers, nodes, post, posts, thread, _i, _j, _k, _len, _len1, _len2, _ref, _ref1;
|
var container, containers, nodes, post, posts, thread, _i, _j, _k, _len, _len1, _len2, _ref;
|
||||||
if (QuoteThreading.enabled = this.checked) {
|
if (QuoteThreading.enabled = this.checked) {
|
||||||
QuoteThreading.force();
|
QuoteThreading.force();
|
||||||
} else {
|
} else {
|
||||||
thread = $('.thread');
|
thread = $('.thread');
|
||||||
posts = [];
|
posts = [];
|
||||||
nodes = [];
|
nodes = [];
|
||||||
_ref = g.posts;
|
g.posts.forEach(function(post) {
|
||||||
for (ID in _ref) {
|
|
||||||
post = _ref[ID];
|
|
||||||
if (!(post === post.thread.OP || post.isClone)) {
|
if (!(post === post.thread.OP || post.isClone)) {
|
||||||
posts.push(post);
|
return posts.push(post);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
posts.sort(function(a, b) {
|
posts.sort(function(a, b) {
|
||||||
return a.ID - b.ID;
|
return a.ID - b.ID;
|
||||||
});
|
});
|
||||||
@ -5229,9 +5262,9 @@
|
|||||||
container = containers[_j];
|
container = containers[_j];
|
||||||
$.rm(container);
|
$.rm(container);
|
||||||
}
|
}
|
||||||
_ref1 = $$('.threadOP');
|
_ref = $$('.threadOP');
|
||||||
for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
|
for (_k = 0, _len2 = _ref.length; _k < _len2; _k++) {
|
||||||
post = _ref1[_k];
|
post = _ref[_k];
|
||||||
$.rmClass(post, 'threadOP');
|
$.rmClass(post, 'threadOP');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5844,13 +5877,15 @@
|
|||||||
return QR.nodes.fileInput.click();
|
return QR.nodes.fileInput.click();
|
||||||
},
|
},
|
||||||
generatePostableThreadsList: function() {
|
generatePostableThreadsList: function() {
|
||||||
var list, options, thread, val;
|
var list, options, thread, val, _i, _len, _ref;
|
||||||
if (!QR.nodes) {
|
if (!QR.nodes) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
list = QR.nodes.thread;
|
list = QR.nodes.thread;
|
||||||
options = [list.firstChild];
|
options = [list.firstChild];
|
||||||
for (thread in g.BOARD.threads) {
|
_ref = g.BOARD.threads.keys;
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
thread = _ref[_i];
|
||||||
options.push($.el('option', {
|
options.push($.el('option', {
|
||||||
value: thread,
|
value: thread,
|
||||||
textContent: "Thread No." + thread
|
textContent: "Thread No." + thread
|
||||||
@ -7354,8 +7389,19 @@
|
|||||||
return ImageExpand.toggle(Get.postFromNode(this));
|
return ImageExpand.toggle(Get.postFromNode(this));
|
||||||
},
|
},
|
||||||
toggleAll: function() {
|
toggleAll: function() {
|
||||||
var ID, file, func, post, _i, _len, _ref, _ref1;
|
var func;
|
||||||
$.event('CloseMenu');
|
$.event('CloseMenu');
|
||||||
|
func = function(post) {
|
||||||
|
var file;
|
||||||
|
file = post.file;
|
||||||
|
if (!(file && file.isImage && doc.contains(post.nodes.root))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return $.queueTask(func, post);
|
||||||
|
};
|
||||||
if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) {
|
if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) {
|
||||||
ImageExpand.EAI.className = 'contract-all-shortcut fa fa-compress';
|
ImageExpand.EAI.className = 'contract-all-shortcut fa fa-compress';
|
||||||
ImageExpand.EAI.title = 'Contract All Images';
|
ImageExpand.EAI.title = 'Contract All Images';
|
||||||
@ -7365,22 +7411,15 @@
|
|||||||
ImageExpand.EAI.title = 'Expand All Images';
|
ImageExpand.EAI.title = 'Expand All Images';
|
||||||
func = ImageExpand.contract;
|
func = ImageExpand.contract;
|
||||||
}
|
}
|
||||||
_ref = g.posts;
|
return g.posts.forEach(function(post) {
|
||||||
for (ID in _ref) {
|
var _i, _len, _ref;
|
||||||
post = _ref[ID];
|
func(post);
|
||||||
_ref1 = [post].concat(post.clones);
|
_ref = post.clones;
|
||||||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
post = _ref1[_i];
|
post = _ref[_i];
|
||||||
file = post.file;
|
func(post);
|
||||||
if (!(file && file.isImage && doc.contains(post.nodes.root))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$.queueTask(func, post);
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
},
|
},
|
||||||
setFitness: function() {
|
setFitness: function() {
|
||||||
return (this.checked ? $.addClass : $.rmClass)(doc, this.name.toLowerCase().replace(/\s+/g, '-'));
|
return (this.checked ? $.addClass : $.rmClass)(doc, this.name.toLowerCase().replace(/\s+/g, '-'));
|
||||||
@ -7664,6 +7703,10 @@
|
|||||||
name: 'Image Replace',
|
name: 'Image Replace',
|
||||||
cb: this.node
|
cb: this.node
|
||||||
});
|
});
|
||||||
|
Thread.callbacks.push({
|
||||||
|
name: 'Image Replace',
|
||||||
|
cb: this.thread
|
||||||
|
});
|
||||||
if (!(Conf['Image Prefetching'] && g.VIEW === 'thread')) {
|
if (!(Conf['Image Prefetching'] && g.VIEW === 'thread')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -7678,6 +7721,9 @@
|
|||||||
order: 104
|
order: 104
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
thread: function() {
|
||||||
|
return ImageLoader.thread = this;
|
||||||
|
},
|
||||||
node: function() {
|
node: function() {
|
||||||
var URL, img, string, style, thumb, type, _ref, _ref1;
|
var URL, img, string, style, thumb, type, _ref, _ref1;
|
||||||
if (this.isClone || this.isHidden || this.thread.isHidden || !((_ref = this.file) != null ? _ref.isImage : void 0)) {
|
if (this.isClone || this.isHidden || this.thread.isHidden || !((_ref = this.file) != null ? _ref.isImage : void 0)) {
|
||||||
@ -7700,14 +7746,10 @@
|
|||||||
return img.src = URL;
|
return img.src = URL;
|
||||||
},
|
},
|
||||||
toggle: function() {
|
toggle: function() {
|
||||||
var enabled, id, post, _ref;
|
var enabled;
|
||||||
enabled = Conf['prefetch'] = this.checked;
|
enabled = Conf['prefetch'] = this.checked;
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
_ref = g.threads["" + g.BOARD.ID + "." + g.THREADID].posts;
|
ImageLoader.thread.posts.forEach(ImageLoader.node.call);
|
||||||
for (id in _ref) {
|
|
||||||
post = _ref[id];
|
|
||||||
ImageLoader.node.call(post);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -8704,17 +8746,15 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
node: function() {
|
node: function() {
|
||||||
var ID, fileCount, post, postCount, _ref;
|
var fileCount, postCount;
|
||||||
postCount = 0;
|
postCount = 0;
|
||||||
fileCount = 0;
|
fileCount = 0;
|
||||||
_ref = this.posts;
|
this.posts.forEach(function(post) {
|
||||||
for (ID in _ref) {
|
|
||||||
post = _ref[ID];
|
|
||||||
postCount++;
|
postCount++;
|
||||||
if (post.file) {
|
if (post.file) {
|
||||||
fileCount++;
|
return fileCount++;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
ThreadStats.thread = this;
|
ThreadStats.thread = this;
|
||||||
ThreadStats.fetchPage();
|
ThreadStats.fetchPage();
|
||||||
ThreadStats.update(postCount, fileCount);
|
ThreadStats.update(postCount, fileCount);
|
||||||
@ -9095,7 +9135,7 @@
|
|||||||
return new Notice('info', "The thread is " + change + ".", 30);
|
return new Notice('info', "The thread is " + change + ".", 30);
|
||||||
},
|
},
|
||||||
parse: function(postObjects) {
|
parse: function(postObjects) {
|
||||||
var ID, OP, count, deletedFiles, deletedPosts, files, index, key, node, num, post, postObject, posts, root, scroll, _i, _len, _ref;
|
var ID, OP, count, deletedFiles, deletedPosts, files, index, key, node, num, post, postObject, posts, root, scroll, _i, _j, _len, _len1, _ref;
|
||||||
OP = postObjects[0];
|
OP = postObjects[0];
|
||||||
Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler;
|
Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler;
|
||||||
ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky);
|
ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky);
|
||||||
@ -9122,9 +9162,11 @@
|
|||||||
}
|
}
|
||||||
deletedPosts = [];
|
deletedPosts = [];
|
||||||
deletedFiles = [];
|
deletedFiles = [];
|
||||||
_ref = ThreadUpdater.thread.posts;
|
posts = ThreadUpdater.thread.posts;
|
||||||
for (ID in _ref) {
|
_ref = posts.keys;
|
||||||
post = _ref[ID];
|
for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
|
||||||
|
ID = _ref[_j];
|
||||||
|
post = posts[ID];
|
||||||
ID = +ID;
|
ID = +ID;
|
||||||
if (__indexOf.call(index, ID) < 0) {
|
if (__indexOf.call(index, ID) < 0) {
|
||||||
post.kill();
|
post.kill();
|
||||||
@ -9343,7 +9385,7 @@
|
|||||||
_ref = db.data.boards[boardID];
|
_ref = db.data.boards[boardID];
|
||||||
for (threadID in _ref) {
|
for (threadID in _ref) {
|
||||||
data = _ref[threadID];
|
data = _ref[threadID];
|
||||||
if (!data.isDead && !(threadID in g.BOARD.threads)) {
|
if (!data.isDead && __indexOf.call(g.BOARD.threads.keys, threadID) < 0) {
|
||||||
if (Conf['Auto Prune']) {
|
if (Conf['Auto Prune']) {
|
||||||
ThreadWatcher.db["delete"]({
|
ThreadWatcher.db["delete"]({
|
||||||
boardID: boardID,
|
boardID: boardID,
|
||||||
@ -9481,7 +9523,7 @@
|
|||||||
return div;
|
return div;
|
||||||
},
|
},
|
||||||
refresh: function() {
|
refresh: function() {
|
||||||
var boardID, data, helper, list, nodes, refresher, thread, threadID, toggler, watched, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3;
|
var boardID, data, helper, list, nodes, refresher, thread, threadID, threads, toggler, watched, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3;
|
||||||
nodes = [];
|
nodes = [];
|
||||||
_ref = ThreadWatcher.getAll();
|
_ref = ThreadWatcher.getAll();
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
@ -9491,9 +9533,11 @@
|
|||||||
list = ThreadWatcher.list;
|
list = ThreadWatcher.list;
|
||||||
$.rmAll(list);
|
$.rmAll(list);
|
||||||
$.add(list, nodes);
|
$.add(list, nodes);
|
||||||
_ref2 = g.BOARD.threads;
|
threads = g.BOARD.threads;
|
||||||
for (threadID in _ref2) {
|
_ref2 = threads.keys;
|
||||||
thread = _ref2[threadID];
|
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
|
||||||
|
threadID = _ref2[_j];
|
||||||
|
thread = threads[threadID];
|
||||||
toggler = $('.watch-thread-link', thread.OP.nodes.post);
|
toggler = $('.watch-thread-link', thread.OP.nodes.post);
|
||||||
watched = ThreadWatcher.db.get({
|
watched = ThreadWatcher.db.get({
|
||||||
boardID: thread.board.ID,
|
boardID: thread.board.ID,
|
||||||
@ -9504,8 +9548,8 @@
|
|||||||
toggler.title = "" + helper[1] + " Thread";
|
toggler.title = "" + helper[1] + " Thread";
|
||||||
}
|
}
|
||||||
_ref3 = ThreadWatcher.menu.refreshers;
|
_ref3 = ThreadWatcher.menu.refreshers;
|
||||||
for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
|
for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) {
|
||||||
refresher = _ref3[_j];
|
refresher = _ref3[_k];
|
||||||
refresher();
|
refresher();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -9746,16 +9790,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
ready: function() {
|
ready: function() {
|
||||||
var ID, post, posts, _ref;
|
var posts;
|
||||||
$.off(d, '4chanXInitFinished', Unread.ready);
|
$.off(d, '4chanXInitFinished', Unread.ready);
|
||||||
posts = [];
|
posts = [];
|
||||||
_ref = Unread.thread.posts;
|
Unread.thread.posts.forEach(function(post) {
|
||||||
for (ID in _ref) {
|
|
||||||
post = _ref[ID];
|
|
||||||
if (post.isReply) {
|
if (post.isReply) {
|
||||||
posts.push(post);
|
return posts.push(post);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
if (!Conf['Quote Threading']) {
|
if (!Conf['Quote Threading']) {
|
||||||
Unread.addPosts(posts);
|
Unread.addPosts(posts);
|
||||||
}
|
}
|
||||||
@ -9767,7 +9809,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
scroll: function() {
|
scroll: function() {
|
||||||
var down, hash, post, posts, root;
|
var down, hash, keys, post, posts, root;
|
||||||
if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) {
|
if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -9782,8 +9824,9 @@
|
|||||||
}
|
}
|
||||||
down = true;
|
down = true;
|
||||||
} else {
|
} else {
|
||||||
posts = Object.keys(Unread.thread.posts);
|
posts = Unread.thread.posts;
|
||||||
root = Unread.thread.posts[posts[posts.length - 1]].nodes.root;
|
keys = posts.keys;
|
||||||
|
root = posts[keys[keys.length - 1]].nodes.root;
|
||||||
}
|
}
|
||||||
if (Header.getBottomOf(root) < 0) {
|
if (Header.getBottomOf(root) < 0) {
|
||||||
return Header.scrollTo(root, down);
|
return Header.scrollTo(root, down);
|
||||||
@ -10689,13 +10732,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onIndexRefresh: function() {
|
onIndexRefresh: function() {
|
||||||
var thread, threadID, _ref;
|
|
||||||
ExpandThread.disconnect(true);
|
ExpandThread.disconnect(true);
|
||||||
_ref = g.BOARD.threads;
|
return g.BOARD.threads.forEach(function(thread) {
|
||||||
for (threadID in _ref) {
|
return ExpandThread.setButton(thread);
|
||||||
thread = _ref[threadID];
|
});
|
||||||
ExpandThread.setButton(thread);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
text: function(status, posts, files) {
|
text: function(status, posts, files) {
|
||||||
return ("" + status + " " + posts + " post" + (posts > 1 ? 's' : '')) + (+files ? " and " + files + " image repl" + (files > 1 ? 'ies' : 'y') : "") + (" " + (status === '-' ? 'shown' : 'omitted') + ".");
|
return ("" + status + " " + posts + " post" + (posts > 1 ? 's' : '')) + (+files ? " and " + files + " image repl" + (files > 1 ? 'ies' : 'y') : "") + (" " + (status === '-' ? 'shown' : 'omitted') + ".");
|
||||||
@ -11913,13 +11953,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
clean: function() {
|
clean: function() {
|
||||||
var id, posts, thread, threads, _ref;
|
var posts, threads;
|
||||||
posts = g.posts, threads = g.threads;
|
posts = g.posts, threads = g.threads;
|
||||||
_ref = g.threads;
|
g.threads.forEach(function(thread) {
|
||||||
for (id in _ref) {
|
return thread.collect();
|
||||||
thread = _ref[id];
|
});
|
||||||
thread.collect();
|
|
||||||
}
|
|
||||||
QuoteBacklink.containers = {};
|
QuoteBacklink.containers = {};
|
||||||
return $.rmAll($('.board'));
|
return $.rmAll($('.board'));
|
||||||
},
|
},
|
||||||
@ -12863,6 +12901,8 @@
|
|||||||
Main = {
|
Main = {
|
||||||
init: function() {
|
init: function() {
|
||||||
var db, flatten, pathname, _i, _len, _ref, _ref1;
|
var db, flatten, pathname, _i, _len, _ref, _ref1;
|
||||||
|
g.threads = new SimpleDict;
|
||||||
|
g.posts = new SimpleDict;
|
||||||
pathname = location.pathname.split('/');
|
pathname = location.pathname.split('/');
|
||||||
g.BOARD = new Board(pathname[1]);
|
g.BOARD = new Board(pathname[1]);
|
||||||
if ((_ref = g.BOARD.ID) === 'z' || _ref === 'fk') {
|
if ((_ref = g.BOARD.ID) === 'z' || _ref === 'fk') {
|
||||||
|
|||||||
@ -32,7 +32,6 @@ Recursive =
|
|||||||
|
|
||||||
apply: (recursive, post, args...) ->
|
apply: (recursive, post, args...) ->
|
||||||
{fullID} = post
|
{fullID} = post
|
||||||
for ID, post of g.posts
|
g.posts.forEach (post) ->
|
||||||
if fullID in post.quotes
|
if fullID in post.quotes
|
||||||
recursive post, args...
|
recursive post, args...
|
||||||
return
|
|
||||||
|
|||||||
@ -40,22 +40,28 @@ Get =
|
|||||||
allQuotelinksLinkingTo: (post) ->
|
allQuotelinksLinkingTo: (post) ->
|
||||||
# Get quotelinks & backlinks linking to the given post.
|
# Get quotelinks & backlinks linking to the given post.
|
||||||
quotelinks = []
|
quotelinks = []
|
||||||
handleQuotes = (post, type) ->
|
{posts} = g
|
||||||
quotelinks.push post.nodes[type]...
|
fullID = {post}
|
||||||
quotelinks.push clone.nodes[type]... for clone in post.clones
|
handleQuotes = (qPost, type) ->
|
||||||
|
quotelinks.push qPost.nodes[type]...
|
||||||
|
quotelinks.push clone.nodes[type]... for clone in qPost.clones
|
||||||
return
|
return
|
||||||
# First:
|
# First:
|
||||||
# In every posts,
|
# In every posts,
|
||||||
# if it did quote this post,
|
# if it did quote this post,
|
||||||
# get all their backlinks.
|
# get all their backlinks.
|
||||||
handleQuotes quoterPost, 'quotelinks' for ID, quoterPost of g.posts when post.fullID in quoterPost.quotes
|
posts.forEach (qPost) ->
|
||||||
|
if fullID in qPost.quotes
|
||||||
|
handleQuotes qPost, 'quotelinks'
|
||||||
|
|
||||||
# Second:
|
# Second:
|
||||||
# If we have quote backlinks:
|
# If we have quote backlinks:
|
||||||
# in all posts this post quoted
|
# in all posts this post quoted
|
||||||
# and their clones,
|
# and their clones,
|
||||||
# get all of their backlinks.
|
# get all of their backlinks.
|
||||||
if Conf['Quote Backlinks']
|
if Conf['Quote Backlinks']
|
||||||
handleQuotes quotedPost, 'backlinks' for quote in post.quotes when quotedPost = g.posts[quote]
|
handleQuotes qPost, 'backlinks' for quote in post.quotes when qPost = posts[quote]
|
||||||
|
|
||||||
# Third:
|
# Third:
|
||||||
# Filter out irrelevant quotelinks.
|
# Filter out irrelevant quotelinks.
|
||||||
quotelinks.filter (quotelink) ->
|
quotelinks.filter (quotelink) ->
|
||||||
|
|||||||
@ -5,6 +5,4 @@ doc = d.documentElement
|
|||||||
g =
|
g =
|
||||||
VERSION: '<%= version %>'
|
VERSION: '<%= version %>'
|
||||||
NAMESPACE: '<%= meta.name %>.'
|
NAMESPACE: '<%= meta.name %>.'
|
||||||
boards: {}
|
boards: {}
|
||||||
threads: {}
|
|
||||||
posts: {}
|
|
||||||
@ -277,7 +277,7 @@ Index =
|
|||||||
else if req.status is 304 and pageNum?
|
else if req.status is 304 and pageNum?
|
||||||
Index.pageNav pageNum
|
Index.pageNav pageNum
|
||||||
catch err
|
catch err
|
||||||
c.error 'Index failure:', err
|
c.error "Index failure: #{err.message}", err.stack
|
||||||
# network error or non-JSON content for example.
|
# network error or non-JSON content for example.
|
||||||
if notice
|
if notice
|
||||||
notice.setType 'error'
|
notice.setType 'error'
|
||||||
@ -308,8 +308,8 @@ Index =
|
|||||||
Index.threadsNumPerPage = pages[0].threads.length
|
Index.threadsNumPerPage = pages[0].threads.length
|
||||||
Index.liveThreadData = pages.reduce ((arr, next) -> arr.concat next.threads), []
|
Index.liveThreadData = pages.reduce ((arr, next) -> arr.concat next.threads), []
|
||||||
Index.liveThreadIDs = Index.liveThreadData.map (data) -> data.no
|
Index.liveThreadIDs = Index.liveThreadData.map (data) -> data.no
|
||||||
for threadID, thread of g.BOARD.threads when thread.ID not in Index.liveThreadIDs
|
g.BOARD.threads.forEach (thread) ->
|
||||||
thread.collect()
|
thread.collect() unless thread.ID in Index.liveThreadIDs
|
||||||
return
|
return
|
||||||
|
|
||||||
buildThreads: ->
|
buildThreads: ->
|
||||||
@ -317,23 +317,23 @@ Index =
|
|||||||
threads = []
|
threads = []
|
||||||
posts = []
|
posts = []
|
||||||
for threadData, i in Index.liveThreadData
|
for threadData, i in Index.liveThreadData
|
||||||
threadRoot = Build.thread g.BOARD, threadData
|
|
||||||
Index.nodes.push threadRoot, $.el 'hr'
|
|
||||||
if thread = g.BOARD.threads[threadData.no]
|
|
||||||
thread.setPage Math.floor i / Index.threadsNumPerPage
|
|
||||||
thread.setStatus 'Sticky', !!threadData.sticky
|
|
||||||
thread.setStatus 'Closed', !!threadData.closed
|
|
||||||
else
|
|
||||||
thread = new Thread threadData.no, g.BOARD
|
|
||||||
threads.push thread
|
|
||||||
continue if thread.ID of thread.posts
|
|
||||||
try
|
try
|
||||||
|
threadRoot = Build.thread g.BOARD, threadData
|
||||||
|
if thread = g.BOARD.threads[threadData.no]
|
||||||
|
thread.setPage Math.floor i / Index.threadsNumPerPage
|
||||||
|
thread.setStatus 'Sticky', !!threadData.sticky
|
||||||
|
thread.setStatus 'Closed', !!threadData.closed
|
||||||
|
else
|
||||||
|
thread = new Thread threadData.no, g.BOARD
|
||||||
|
threads.push thread
|
||||||
|
Index.nodes.push threadRoot, $.el 'hr'
|
||||||
|
continue if thread.ID of thread.posts
|
||||||
posts.push new Post $('.opContainer', threadRoot), thread, g.BOARD
|
posts.push new Post $('.opContainer', threadRoot), thread, g.BOARD
|
||||||
catch err
|
catch err
|
||||||
# Skip posts that we failed to parse.
|
# Skip posts that we failed to parse.
|
||||||
errors = [] unless errors
|
errors = [] unless errors
|
||||||
errors.push
|
errors.push
|
||||||
message: "Parsing of Post No.#{thread} failed. Post will be skipped."
|
message: "Parsing of Thread No.#{thread} failed. Thread will be skipped."
|
||||||
error: err
|
error: err
|
||||||
Main.handleErrors errors if errors
|
Main.handleErrors errors if errors
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
Main =
|
Main =
|
||||||
init: ->
|
init: ->
|
||||||
|
g.threads = new SimpleDict
|
||||||
|
g.posts = new SimpleDict
|
||||||
|
|
||||||
pathname = location.pathname.split '/'
|
pathname = location.pathname.split '/'
|
||||||
g.BOARD = new Board pathname[1]
|
g.BOARD = new Board pathname[1]
|
||||||
return if g.BOARD.ID in ['z', 'fk']
|
return if g.BOARD.ID in ['z', 'fk']
|
||||||
|
|||||||
@ -34,7 +34,7 @@ Navigate =
|
|||||||
{posts, threads} = g
|
{posts, threads} = g
|
||||||
|
|
||||||
# Garbage collection
|
# Garbage collection
|
||||||
thread.collect() for id, thread of g.threads
|
g.threads.forEach (thread) -> thread.collect()
|
||||||
|
|
||||||
QuoteBacklink.containers = {}
|
QuoteBacklink.containers = {}
|
||||||
|
|
||||||
|
|||||||
@ -404,5 +404,11 @@ $.set = do ->
|
|||||||
return
|
return
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
|
$.remove = (arr, value) ->
|
||||||
|
i = arr.indexOf value
|
||||||
|
return false if i is -1
|
||||||
|
arr.splice i, 1
|
||||||
|
true
|
||||||
|
|
||||||
$$ = (selector, root=d.body) ->
|
$$ = (selector, root=d.body) ->
|
||||||
[root.querySelectorAll(selector)...]
|
[root.querySelectorAll(selector)...]
|
||||||
|
|||||||
@ -2,7 +2,7 @@ class Board
|
|||||||
toString: -> @ID
|
toString: -> @ID
|
||||||
|
|
||||||
constructor: (@ID) ->
|
constructor: (@ID) ->
|
||||||
@threads = {}
|
@threads = new SimpleDict
|
||||||
@posts = {}
|
@posts = new SimpleDict
|
||||||
|
|
||||||
g.boards[@] = @
|
g.boards[@] = @
|
||||||
@ -6,3 +6,4 @@
|
|||||||
<%= grunt.file.read('src/General/lib/databoard.class') %>
|
<%= grunt.file.read('src/General/lib/databoard.class') %>
|
||||||
<%= grunt.file.read('src/General/lib/notice.class') %>
|
<%= grunt.file.read('src/General/lib/notice.class') %>
|
||||||
<%= grunt.file.read('src/General/lib/randomaccesslist.class') %>
|
<%= grunt.file.read('src/General/lib/randomaccesslist.class') %>
|
||||||
|
<%= grunt.file.read('src/General/lib/simpledict.class') %>
|
||||||
@ -54,7 +54,7 @@ class Post
|
|||||||
@parseFile that
|
@parseFile that
|
||||||
|
|
||||||
@clones = []
|
@clones = []
|
||||||
g.posts[@fullID] = thread.posts[@] = board.posts[@] = @
|
g.posts.push @fullID, thread.posts.push @, board.posts.push @, @
|
||||||
@kill() if that.isArchived
|
@kill() if that.isArchived
|
||||||
|
|
||||||
parseComment: ->
|
parseComment: ->
|
||||||
@ -208,9 +208,9 @@ class Post
|
|||||||
|
|
||||||
collect: ->
|
collect: ->
|
||||||
@kill()
|
@kill()
|
||||||
delete g.posts[@fullID]
|
g.posts.rm @fullID
|
||||||
delete @thread.posts[@]
|
@thread.posts.rm @
|
||||||
delete @board.posts[@]
|
@board.posts.rm @
|
||||||
|
|
||||||
addClone: (context) ->
|
addClone: (context) ->
|
||||||
new Clone @, context
|
new Clone @, context
|
||||||
|
|||||||
14
src/General/lib/simpledict.class
Normal file
14
src/General/lib/simpledict.class
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
class SimpleDict
|
||||||
|
constructor: ->
|
||||||
|
@keys = []
|
||||||
|
|
||||||
|
push: (key, data) ->
|
||||||
|
key = "#{key}"
|
||||||
|
@keys.push key unless @[key]
|
||||||
|
@[key] = data
|
||||||
|
|
||||||
|
rm: (key) ->
|
||||||
|
key = "#{key}"
|
||||||
|
delete @[key] if $.remove @keys, key
|
||||||
|
|
||||||
|
forEach: (fn) -> fn @[key] for key in [@keys...]
|
||||||
@ -4,13 +4,13 @@ class Thread
|
|||||||
|
|
||||||
constructor: (@ID, @board) ->
|
constructor: (@ID, @board) ->
|
||||||
@fullID = "#{@board}.#{@ID}"
|
@fullID = "#{@board}.#{@ID}"
|
||||||
@posts = {}
|
@posts = new SimpleDict
|
||||||
@isSticky = false
|
@isSticky = false
|
||||||
@isClosed = false
|
@isClosed = false
|
||||||
@postLimit = false
|
@postLimit = false
|
||||||
@fileLimit = false
|
@fileLimit = false
|
||||||
|
|
||||||
g.threads[@fullID] = board.threads[@] = @
|
g.threads.push @fullID, board.threads.push @, @
|
||||||
|
|
||||||
setPage: (pageNum) ->
|
setPage: (pageNum) ->
|
||||||
icon = $ '.page-num', @OP.nodes.post
|
icon = $ '.page-num', @OP.nodes.post
|
||||||
@ -44,6 +44,6 @@ class Thread
|
|||||||
@timeOfDeath = Date.now()
|
@timeOfDeath = Date.now()
|
||||||
|
|
||||||
collect: ->
|
collect: ->
|
||||||
post.collect() for postID, post of @posts
|
@posts.forEach (post) -> post.collect()
|
||||||
delete g.threads[@fullID]
|
g.threads.rm @fullID
|
||||||
delete @board.threads[@]
|
@board.threads.rm @
|
||||||
|
|||||||
@ -32,6 +32,14 @@ ImageExpand =
|
|||||||
ImageExpand.toggle Get.postFromNode @
|
ImageExpand.toggle Get.postFromNode @
|
||||||
toggleAll: ->
|
toggleAll: ->
|
||||||
$.event 'CloseMenu'
|
$.event 'CloseMenu'
|
||||||
|
func = (post) ->
|
||||||
|
{file} = post
|
||||||
|
return unless file and file.isImage and doc.contains post.nodes.root
|
||||||
|
if ImageExpand.on and
|
||||||
|
(!Conf['Expand spoilers'] and file.isSpoiler or
|
||||||
|
Conf['Expand from here'] and Header.getTopOf(file.thumb) < 0)
|
||||||
|
return
|
||||||
|
$.queueTask func, post
|
||||||
if ImageExpand.on = $.hasClass ImageExpand.EAI, 'expand-all-shortcut'
|
if ImageExpand.on = $.hasClass ImageExpand.EAI, 'expand-all-shortcut'
|
||||||
ImageExpand.EAI.className = 'contract-all-shortcut fa fa-compress'
|
ImageExpand.EAI.className = 'contract-all-shortcut fa fa-compress'
|
||||||
ImageExpand.EAI.title = 'Contract All Images'
|
ImageExpand.EAI.title = 'Contract All Images'
|
||||||
@ -40,16 +48,10 @@ ImageExpand =
|
|||||||
ImageExpand.EAI.className = 'expand-all-shortcut fa fa-expand'
|
ImageExpand.EAI.className = 'expand-all-shortcut fa fa-expand'
|
||||||
ImageExpand.EAI.title = 'Expand All Images'
|
ImageExpand.EAI.title = 'Expand All Images'
|
||||||
func = ImageExpand.contract
|
func = ImageExpand.contract
|
||||||
for ID, post of g.posts
|
g.posts.forEach (post) ->
|
||||||
for post in [post].concat post.clones
|
func post
|
||||||
{file} = post
|
func post for post in post.clones
|
||||||
continue unless file and file.isImage and doc.contains post.nodes.root
|
return
|
||||||
if ImageExpand.on and
|
|
||||||
(!Conf['Expand spoilers'] and file.isSpoiler or
|
|
||||||
Conf['Expand from here'] and Header.getTopOf(file.thumb) < 0)
|
|
||||||
continue
|
|
||||||
$.queueTask func, post
|
|
||||||
return
|
|
||||||
setFitness: ->
|
setFitness: ->
|
||||||
(if @checked then $.addClass else $.rmClass) doc, @name.toLowerCase().replace /\s+/g, '-'
|
(if @checked then $.addClass else $.rmClass) doc, @name.toLowerCase().replace /\s+/g, '-'
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,10 @@ ImageLoader =
|
|||||||
name: 'Image Replace'
|
name: 'Image Replace'
|
||||||
cb: @node
|
cb: @node
|
||||||
|
|
||||||
|
Thread.callbacks.push
|
||||||
|
name: 'Image Replace'
|
||||||
|
cb: @thread
|
||||||
|
|
||||||
return unless Conf['Image Prefetching'] and g.VIEW is 'thread'
|
return unless Conf['Image Prefetching'] and g.VIEW is 'thread'
|
||||||
|
|
||||||
prefetch = $.el 'label',
|
prefetch = $.el 'label',
|
||||||
@ -20,6 +24,9 @@ ImageLoader =
|
|||||||
el: prefetch
|
el: prefetch
|
||||||
order: 104
|
order: 104
|
||||||
|
|
||||||
|
thread: ->
|
||||||
|
ImageLoader.thread = @
|
||||||
|
|
||||||
node: ->
|
node: ->
|
||||||
return if @isClone or @isHidden or @thread.isHidden or !@file?.isImage
|
return if @isClone or @isHidden or @thread.isHidden or !@file?.isImage
|
||||||
{thumb, URL} = @file
|
{thumb, URL} = @file
|
||||||
@ -38,5 +45,5 @@ ImageLoader =
|
|||||||
toggle: ->
|
toggle: ->
|
||||||
enabled = Conf['prefetch'] = @checked
|
enabled = Conf['prefetch'] = @checked
|
||||||
if enabled
|
if enabled
|
||||||
ImageLoader.node.call post for id, post of g.threads["#{g.BOARD.ID}.#{g.THREADID}"].posts
|
ImageLoader.thread.posts.forEach ImageLoader.node.call
|
||||||
return
|
return
|
||||||
@ -19,9 +19,8 @@ ExpandThread =
|
|||||||
|
|
||||||
onIndexRefresh: ->
|
onIndexRefresh: ->
|
||||||
ExpandThread.disconnect true
|
ExpandThread.disconnect true
|
||||||
for threadID, thread of g.BOARD.threads
|
g.BOARD.threads.forEach (thread) ->
|
||||||
ExpandThread.setButton thread
|
ExpandThread.setButton thread
|
||||||
return
|
|
||||||
|
|
||||||
text: (status, posts, files) ->
|
text: (status, posts, files) ->
|
||||||
"#{status} #{posts} post#{if posts > 1 then 's' else ''}" +
|
"#{status} #{posts} post#{if posts > 1 then 's' else ''}" +
|
||||||
|
|||||||
@ -26,7 +26,7 @@ ThreadStats =
|
|||||||
node: ->
|
node: ->
|
||||||
postCount = 0
|
postCount = 0
|
||||||
fileCount = 0
|
fileCount = 0
|
||||||
for ID, post of @posts
|
@posts.forEach (post) ->
|
||||||
postCount++
|
postCount++
|
||||||
fileCount++ if post.file
|
fileCount++ if post.file
|
||||||
ThreadStats.thread = @
|
ThreadStats.thread = @
|
||||||
|
|||||||
@ -290,7 +290,9 @@ ThreadUpdater =
|
|||||||
deletedFiles = []
|
deletedFiles = []
|
||||||
|
|
||||||
# Check for deleted posts/files.
|
# Check for deleted posts/files.
|
||||||
for ID, post of ThreadUpdater.thread.posts
|
{posts} = ThreadUpdater.thread
|
||||||
|
for ID in posts.keys
|
||||||
|
post = posts[ID]
|
||||||
# XXX tmp fix for 4chan's racing condition
|
# XXX tmp fix for 4chan's racing condition
|
||||||
# giving us false-positive dead posts.
|
# giving us false-positive dead posts.
|
||||||
# continue if post.isDead
|
# continue if post.isDead
|
||||||
|
|||||||
@ -96,7 +96,7 @@ ThreadWatcher =
|
|||||||
onIndexRefresh: ->
|
onIndexRefresh: ->
|
||||||
{db} = ThreadWatcher
|
{db} = ThreadWatcher
|
||||||
boardID = g.BOARD.ID
|
boardID = g.BOARD.ID
|
||||||
for threadID, data of db.data.boards[boardID] when not data.isDead and threadID not of g.BOARD.threads
|
for threadID, data of db.data.boards[boardID] when not data.isDead and threadID not in g.BOARD.threads.keys
|
||||||
if Conf['Auto Prune']
|
if Conf['Auto Prune']
|
||||||
ThreadWatcher.db.delete {boardID, threadID}
|
ThreadWatcher.db.delete {boardID, threadID}
|
||||||
else
|
else
|
||||||
@ -180,7 +180,9 @@ ThreadWatcher =
|
|||||||
$.rmAll list
|
$.rmAll list
|
||||||
$.add list, nodes
|
$.add list, nodes
|
||||||
|
|
||||||
for threadID, thread of g.BOARD.threads
|
{threads} = g.BOARD
|
||||||
|
for threadID in threads.keys
|
||||||
|
thread = threads[threadID]
|
||||||
toggler = $ '.watch-thread-link', thread.OP.nodes.post
|
toggler = $ '.watch-thread-link', thread.OP.nodes.post
|
||||||
watched = ThreadWatcher.db.get {boardID: thread.board.ID, threadID}
|
watched = ThreadWatcher.db.get {boardID: thread.board.ID, threadID}
|
||||||
helper = if watched then ['addClass', 'Unwatch'] else ['rmClass', 'Watch']
|
helper = if watched then ['addClass', 'Unwatch'] else ['rmClass', 'Watch']
|
||||||
|
|||||||
@ -42,7 +42,7 @@ Unread =
|
|||||||
ready: ->
|
ready: ->
|
||||||
$.off d, '4chanXInitFinished', Unread.ready
|
$.off d, '4chanXInitFinished', Unread.ready
|
||||||
posts = []
|
posts = []
|
||||||
posts.push post for ID, post of Unread.thread.posts when post.isReply
|
Unread.thread.posts.forEach (post) -> posts.push post if post.isReply
|
||||||
Unread.addPosts posts unless Conf['Quote Threading']
|
Unread.addPosts posts unless Conf['Quote Threading']
|
||||||
QuoteThreading.force() if Conf['Quote Threading']
|
QuoteThreading.force() if Conf['Quote Threading']
|
||||||
Unread.scroll() if Conf['Scroll to Last Read Post']
|
Unread.scroll() if Conf['Scroll to Last Read Post']
|
||||||
@ -58,8 +58,9 @@ Unread =
|
|||||||
down = true
|
down = true
|
||||||
else
|
else
|
||||||
# Scroll to the last read post.
|
# Scroll to the last read post.
|
||||||
posts = Object.keys Unread.thread.posts
|
{posts} = Unread.thread
|
||||||
{root} = Unread.thread.posts[posts[posts.length - 1]].nodes
|
{keys} = posts
|
||||||
|
{root} = posts[keys[keys.length - 1]].nodes
|
||||||
|
|
||||||
# Scroll to the target unless we scrolled past it.
|
# Scroll to the target unless we scrolled past it.
|
||||||
Header.scrollTo root, down if Header.getBottomOf(root) < 0
|
Header.scrollTo root, down if Header.getBottomOf(root) < 0
|
||||||
|
|||||||
@ -326,7 +326,7 @@ QR =
|
|||||||
return unless QR.nodes
|
return unless QR.nodes
|
||||||
list = QR.nodes.thread
|
list = QR.nodes.thread
|
||||||
options = [list.firstChild]
|
options = [list.firstChild]
|
||||||
for thread of g.BOARD.threads
|
for thread in g.BOARD.threads.keys
|
||||||
options.push $.el 'option',
|
options.push $.el 'option',
|
||||||
value: thread
|
value: thread
|
||||||
textContent: "Thread No.#{thread}"
|
textContent: "Thread No.#{thread}"
|
||||||
|
|||||||
@ -42,8 +42,8 @@ QuoteThreading =
|
|||||||
QuoteThreading.force()
|
QuoteThreading.force()
|
||||||
|
|
||||||
force: ->
|
force: ->
|
||||||
post.cb true for ID, post of g.posts when post.cb
|
g.posts.forEach (post) ->
|
||||||
return
|
post.cb true if post.cb
|
||||||
|
|
||||||
node: ->
|
node: ->
|
||||||
{posts} = g
|
{posts} = g
|
||||||
@ -107,7 +107,9 @@ QuoteThreading =
|
|||||||
posts = []
|
posts = []
|
||||||
nodes = []
|
nodes = []
|
||||||
|
|
||||||
posts.push post for ID, post of g.posts when not (post is post.thread.OP or post.isClone)
|
g.posts.forEach (post) ->
|
||||||
|
posts.push post unless post is post.thread.OP or post.isClone
|
||||||
|
|
||||||
posts.sort (a, b) -> a.ID - b.ID
|
posts.sort (a, b) -> a.ID - b.ID
|
||||||
|
|
||||||
nodes.push post.nodes.root for post in posts
|
nodes.push post.nodes.root for post in posts
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user