From 6574746e907e769a5de69e3cb2228581f161db74 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sat, 4 Jan 2014 13:38:09 -0700 Subject: [PATCH 01/20] Start working on putting in aeosynth's RandomAccessList For performance, obviously. --- LICENSE | 8 +- builds/4chan-X.user.js | 140 ++++++++++++++++++++----- builds/crx/script.js | 140 ++++++++++++++++++++----- src/General/lib/classes.coffee | 3 +- src/General/lib/randomaccesslist.class | 58 ++++++++++ src/Monitoring/Unread.coffee | 35 ++++--- src/Quotelinks/QuoteThreading.coffee | 5 +- 7 files changed, 311 insertions(+), 78 deletions(-) create mode 100644 src/General/lib/randomaccesslist.class diff --git a/LICENSE b/LICENSE index 38ffc24ad..5ea10f543 100755 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ /* -* 4chan X - Version 1.2.44 - 2013-12-27 +* 4chan X - Version 1.2.44 - 2014-01-04 * * Licensed under the MIT license. * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE @@ -8,11 +8,11 @@ * http://zixaphir.github.io/appchan-x/ * 4chan x Copyright © 2009-2011 James Campos * https://github.com/aeosynth/4chan-x -* 4chan x Copyright © 2012-2013 Nicolas Stepien +* 4chan x Copyright © 2012-2014 Nicolas Stepien * https://4chan-x.just-believe.in/ -* 4chan x Copyright © 2013-2013 Jordan Bates +* 4chan x Copyright © 2013-2014 Jordan Bates * http://seaweedchan.github.io/4chan-x/ -* 4chan x Copyright © 2012-2013 ihavenoface +* 4chan x Copyright © 2012-2014 ihavenoface * http://ihavenoface.github.io/4chan-x/ * 4chan SS Copyright © 2011-2013 Ahodesuka * https://github.com/ahodesuka/4chan-Style-Script/ diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 01a734513..4a33a03db 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -22,7 +22,7 @@ // ==/UserScript== /* -* 4chan X - Version 1.2.44 - 2013-12-27 +* 4chan X - Version 1.2.44 - 2014-01-04 * * Licensed under the MIT license. * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE @@ -31,11 +31,11 @@ * http://zixaphir.github.io/appchan-x/ * 4chan x Copyright © 2009-2011 James Campos * https://github.com/aeosynth/4chan-x -* 4chan x Copyright © 2012-2013 Nicolas Stepien +* 4chan x Copyright © 2012-2014 Nicolas Stepien * https://4chan-x.just-believe.in/ -* 4chan x Copyright © 2013-2013 Jordan Bates +* 4chan x Copyright © 2013-2014 Jordan Bates * http://seaweedchan.github.io/4chan-x/ -* 4chan x Copyright © 2012-2013 ihavenoface +* 4chan x Copyright © 2012-2014 ihavenoface * http://ihavenoface.github.io/4chan-x/ * 4chan SS Copyright © 2011-2013 Ahodesuka * https://github.com/ahodesuka/4chan-Style-Script/ @@ -104,7 +104,7 @@ 'use strict'; (function() { - var $, $$, Anonymize, ArchiveLink, AutoGIF, Banner, Board, Build, 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, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, 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, 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, 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, __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, __hasProp = {}.hasOwnProperty, @@ -1458,6 +1458,87 @@ })(); + RandomAccessList = (function() { + function RandomAccessList() { + this.first = null; + this.last = null; + this.length = 0; + } + + RandomAccessList.prototype.push = function(item) { + var ID, last; + ID = item.ID; + last = this.last; + $.extend(item, { + prev: last, + next: null + }); + this[ID] = item; + this.last = last ? last.next = item : this.first = item; + return this.length++; + }; + + RandomAccessList.prototype.after = function(root, item) { + var next; + if (item.prev === root) { + return; + } + this.rmi(item); + next = root.next; + next.prev = root.next = item; + item.prev = root; + return item.next = next; + }; + + RandomAccessList.prototype.shift = function() { + return this.rm(this.first.ID); + }; + + RandomAccessList.prototype.splice = function(start, end) { + var cur, next; + if (!this[end]) { + return; + } + cur = start === 0 ? this.first : this[start]; + while (cur !== this[end]) { + if (!(next = cur.next, cur)) { + return; + } + this.rm(cur); + cur = next; + } + }; + + RandomAccessList.prototype.rm = function(ID) { + var item; + item = this[ID]; + if (!item) { + return; + } + delete this[ID]; + this.length--; + return this.rmi(item); + }; + + RandomAccessList.prototype.rmi = function(item) { + var next, prev; + prev = item.prev, next = item.next; + if (prev) { + prev.next = next; + } else { + this.first = next; + } + if (next) { + return next.prev = prev; + } else { + return this.last = prev; + } + }; + + return RandomAccessList; + + })(); + Polyfill = { init: function() {}, notificationPermission: function() { @@ -4868,10 +4949,11 @@ return QuoteThreading.hasRun = true; }, node: function() { - var ID, fullID, keys, len, post, posts, qid, quote, quotes, uniq, _i, _len; + var ID, fullID, keys, len, post, posts, qid, quote, quotes, replies, uniq, _i, _len; if (this.isClone || !QuoteThreading.enabled || this.thread.OP === this) { return; } + replies = Unread.replies; quotes = this.quotes, ID = this.ID, fullID = this.fullID; posts = g.posts; if (!(post = posts[fullID]) || post.isHidden) { @@ -4907,7 +4989,7 @@ if (QuoteThreading.hasRun) { height = doc.clientHeight; _ref = qpost.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; - if (!(__indexOf.call(Unread.posts, qpost) >= 0 || ((bottom < height) && (top > 0)))) { + if (!(Unread.posts[qpost.ID] || ((bottom < height) && (top > 0)))) { return false; } } @@ -4926,6 +5008,7 @@ }, toggle: function() { var container, containers, node, post, replies, reply, thread, _i, _j, _k, _len, _len1, _len2, _ref; + Unread.replies = new RandomAccessList; thread = $('.thread'); replies = $$('.thread > .replyContainer, .threadContainer > .replyContainer', thread); QuoteThreading.enabled = this.checked; @@ -9393,7 +9476,7 @@ this.hr = $.el('hr', { id: 'unread-line' }); - this.posts = []; + this.posts = new RandomAccessList; this.postsQuotingYou = []; return Thread.callbacks.push({ name: 'Unread', @@ -9437,7 +9520,7 @@ if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) { return; } - if (post = Unread.posts[0]) { + if (post = Unread.posts.first) { while (root = $.x('preceding-sibling::div[contains(@class,"replyContainer")][1]', post.nodes.root)) { if (!(post = Get.postFromRoot(root)).isHidden) { break; @@ -9458,7 +9541,7 @@ }); }, sync: function() { - var lastReadPost; + var lastReadPost, post; lastReadPost = Unread.db.get({ boardID: Unread.thread.board.ID, threadID: Unread.thread.ID, @@ -9469,6 +9552,14 @@ } Unread.lastReadPost = lastReadPost; Unread.readArray(Unread.posts); + post = Unread.posts.first; + while (post) { + if (post.ID > Unread.lastReadPost) { + break; + } + post = post.next; + } + Unread.posts.splice(0, i); Unread.readArray(Unread.postsQuotingYou); if (Conf['Unread Line']) { Unread.setLine(); @@ -9546,12 +9637,13 @@ } }, readSinglePost: function(post) { - var i; - if ((i = Unread.posts.indexOf(post)) === -1) { + var ID, i; + ID = post.ID; + if (!Unread.posts[ID]) { return; } - Unread.posts.splice(i, 1); - if (i === 0) { + Unread.posts.splice(ID(post.next.ID)); + if (post === Unread.posts.first) { Unread.lastReadPost = post.ID; Unread.saveLastReadPost(); } @@ -9571,14 +9663,14 @@ return arr.splice(0, i); }, read: $.debounce(50, function(e) { - var ID, height, i, post, posts; + var ID, height, post, posts; if (d.hidden || !Unread.posts.length) { return; } height = doc.clientHeight; posts = Unread.posts; - i = 0; - while (post = posts[i]) { + post = posts.first; + while (post) { if (Header.getBottomOf(post.nodes.root) > -1) { ID = post.ID; if (Conf['Mark Quotes of You']) { @@ -9586,23 +9678,15 @@ QuoteYou.lastRead = post.nodes.root; } } - if (Conf['Quote Threading']) { - posts.splice(i, 1); - continue; - } + post = post.next; } else { - if (!Conf['Quote Threading']) { - break; - } + break; } - i++; - } - if (i && !Conf['Quote Threading']) { - posts.splice(0, i); } if (!ID) { return; } + posts.splice(0, ID); if (Unread.lastReadPost < ID || !Unread.lastReadPost) { Unread.lastReadPost = ID; } diff --git a/builds/crx/script.js b/builds/crx/script.js index dac844bf7..28c04d8ab 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript /* -* 4chan X - Version 1.2.44 - 2013-12-27 +* 4chan X - Version 1.2.44 - 2014-01-04 * * Licensed under the MIT license. * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE @@ -9,11 +9,11 @@ * http://zixaphir.github.io/appchan-x/ * 4chan x Copyright © 2009-2011 James Campos * https://github.com/aeosynth/4chan-x -* 4chan x Copyright © 2012-2013 Nicolas Stepien +* 4chan x Copyright © 2012-2014 Nicolas Stepien * https://4chan-x.just-believe.in/ -* 4chan x Copyright © 2013-2013 Jordan Bates +* 4chan x Copyright © 2013-2014 Jordan Bates * http://seaweedchan.github.io/4chan-x/ -* 4chan x Copyright © 2012-2013 ihavenoface +* 4chan x Copyright © 2012-2014 ihavenoface * http://ihavenoface.github.io/4chan-x/ * 4chan SS Copyright © 2011-2013 Ahodesuka * https://github.com/ahodesuka/4chan-Style-Script/ @@ -82,7 +82,7 @@ 'use strict'; (function() { - var $, $$, Anonymize, ArchiveLink, AutoGIF, Banner, Board, Build, 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, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, 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, 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, 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, __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, __hasProp = {}.hasOwnProperty, @@ -1479,6 +1479,87 @@ })(); + RandomAccessList = (function() { + function RandomAccessList() { + this.first = null; + this.last = null; + this.length = 0; + } + + RandomAccessList.prototype.push = function(item) { + var ID, last; + ID = item.ID; + last = this.last; + $.extend(item, { + prev: last, + next: null + }); + this[ID] = item; + this.last = last ? last.next = item : this.first = item; + return this.length++; + }; + + RandomAccessList.prototype.after = function(root, item) { + var next; + if (item.prev === root) { + return; + } + this.rmi(item); + next = root.next; + next.prev = root.next = item; + item.prev = root; + return item.next = next; + }; + + RandomAccessList.prototype.shift = function() { + return this.rm(this.first.ID); + }; + + RandomAccessList.prototype.splice = function(start, end) { + var cur, next; + if (!this[end]) { + return; + } + cur = start === 0 ? this.first : this[start]; + while (cur !== this[end]) { + if (!(next = cur.next, cur)) { + return; + } + this.rm(cur); + cur = next; + } + }; + + RandomAccessList.prototype.rm = function(ID) { + var item; + item = this[ID]; + if (!item) { + return; + } + delete this[ID]; + this.length--; + return this.rmi(item); + }; + + RandomAccessList.prototype.rmi = function(item) { + var next, prev; + prev = item.prev, next = item.next; + if (prev) { + prev.next = next; + } else { + this.first = next; + } + if (next) { + return next.prev = prev; + } else { + return this.last = prev; + } + }; + + return RandomAccessList; + + })(); + Polyfill = { init: function() { this.notificationPermission(); @@ -4886,10 +4967,11 @@ return QuoteThreading.hasRun = true; }, node: function() { - var ID, fullID, keys, len, post, posts, qid, quote, quotes, uniq, _i, _len; + var ID, fullID, keys, len, post, posts, qid, quote, quotes, replies, uniq, _i, _len; if (this.isClone || !QuoteThreading.enabled || this.thread.OP === this) { return; } + replies = Unread.replies; quotes = this.quotes, ID = this.ID, fullID = this.fullID; posts = g.posts; if (!(post = posts[fullID]) || post.isHidden) { @@ -4925,7 +5007,7 @@ if (QuoteThreading.hasRun) { height = doc.clientHeight; _ref = qpost.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; - if (!(__indexOf.call(Unread.posts, qpost) >= 0 || ((bottom < height) && (top > 0)))) { + if (!(Unread.posts[qpost.ID] || ((bottom < height) && (top > 0)))) { return false; } } @@ -4944,6 +5026,7 @@ }, toggle: function() { var container, containers, node, post, replies, reply, thread, _i, _j, _k, _len, _len1, _len2, _ref; + Unread.replies = new RandomAccessList; thread = $('.thread'); replies = $$('.thread > .replyContainer, .threadContainer > .replyContainer', thread); QuoteThreading.enabled = this.checked; @@ -9391,7 +9474,7 @@ this.hr = $.el('hr', { id: 'unread-line' }); - this.posts = []; + this.posts = new RandomAccessList; this.postsQuotingYou = []; return Thread.callbacks.push({ name: 'Unread', @@ -9435,7 +9518,7 @@ if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) { return; } - if (post = Unread.posts[0]) { + if (post = Unread.posts.first) { while (root = $.x('preceding-sibling::div[contains(@class,"replyContainer")][1]', post.nodes.root)) { if (!(post = Get.postFromRoot(root)).isHidden) { break; @@ -9456,7 +9539,7 @@ }); }, sync: function() { - var lastReadPost; + var lastReadPost, post; lastReadPost = Unread.db.get({ boardID: Unread.thread.board.ID, threadID: Unread.thread.ID, @@ -9467,6 +9550,14 @@ } Unread.lastReadPost = lastReadPost; Unread.readArray(Unread.posts); + post = Unread.posts.first; + while (post) { + if (post.ID > Unread.lastReadPost) { + break; + } + post = post.next; + } + Unread.posts.splice(0, i); Unread.readArray(Unread.postsQuotingYou); if (Conf['Unread Line']) { Unread.setLine(); @@ -9544,12 +9635,13 @@ } }, readSinglePost: function(post) { - var i; - if ((i = Unread.posts.indexOf(post)) === -1) { + var ID, i; + ID = post.ID; + if (!Unread.posts[ID]) { return; } - Unread.posts.splice(i, 1); - if (i === 0) { + Unread.posts.splice(ID(post.next.ID)); + if (post === Unread.posts.first) { Unread.lastReadPost = post.ID; Unread.saveLastReadPost(); } @@ -9569,14 +9661,14 @@ return arr.splice(0, i); }, read: $.debounce(50, function(e) { - var ID, height, i, post, posts; + var ID, height, post, posts; if (d.hidden || !Unread.posts.length) { return; } height = doc.clientHeight; posts = Unread.posts; - i = 0; - while (post = posts[i]) { + post = posts.first; + while (post) { if (Header.getBottomOf(post.nodes.root) > -1) { ID = post.ID; if (Conf['Mark Quotes of You']) { @@ -9584,23 +9676,15 @@ QuoteYou.lastRead = post.nodes.root; } } - if (Conf['Quote Threading']) { - posts.splice(i, 1); - continue; - } + post = post.next; } else { - if (!Conf['Quote Threading']) { - break; - } + break; } - i++; - } - if (i && !Conf['Quote Threading']) { - posts.splice(0, i); } if (!ID) { return; } + posts.splice(0, ID); if (Unread.lastReadPost < ID || !Unread.lastReadPost) { Unread.lastReadPost = ID; } diff --git a/src/General/lib/classes.coffee b/src/General/lib/classes.coffee index 74697eec3..63c33645e 100755 --- a/src/General/lib/classes.coffee +++ b/src/General/lib/classes.coffee @@ -3,4 +3,5 @@ <%= grunt.file.read('src/General/lib/post.class') %> <%= grunt.file.read('src/General/lib/clone.class') %> <%= grunt.file.read('src/General/lib/databoard.class') %> -<%= grunt.file.read('src/General/lib/notice.class') %> \ No newline at end of file +<%= grunt.file.read('src/General/lib/notice.class') %> +<%= grunt.file.read('src/General/lib/randomaccesslist.class') %> \ No newline at end of file diff --git a/src/General/lib/randomaccesslist.class b/src/General/lib/randomaccesslist.class new file mode 100644 index 000000000..c53a0c932 --- /dev/null +++ b/src/General/lib/randomaccesslist.class @@ -0,0 +1,58 @@ +class RandomAccessList + constructor: -> + @first = null + @last = null + @length = 0 + + push: (item) -> + {ID} = item + {last} = @ + $.extend item, + prev: last + next: null + @[ID] = item + @last = if last + last.next = item + else + @first = item + @length++ + + after: (root, item) -> + return if item.prev is root + + @rmi item + + {next} = root + + next.prev = root.next = item + item.prev = root + item.next = next + + shift: -> + @rm @first.ID + + splice: (start, end) -> + return unless @[end] + cur = if start is 0 then @first else @[start] + while cur isnt @[end] + return unless {next} = cur + @rm cur + cur = next + + rm: (ID) -> + item = @[ID] + return unless item + delete @[ID] + @length-- + @rmi item + + rmi: (item) -> + {prev, next} = item + if prev + prev.next = next + else + @first = next + if next + next.prev = prev + else + @last = prev \ No newline at end of file diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee index 36d5f5213..e0d475ef1 100755 --- a/src/Monitoring/Unread.coffee +++ b/src/Monitoring/Unread.coffee @@ -5,7 +5,7 @@ Unread = @db = new DataBoard 'lastReadPosts', @sync @hr = $.el 'hr', id: 'unread-line' - @posts = [] + @posts = new RandomAccessList @postsQuotingYou = [] Thread.callbacks.push @@ -36,7 +36,7 @@ Unread = return unless Conf['Scroll to Last Read Post'] # Let the header's onload callback handle it. return if (hash = location.hash.match /\d+/) and hash[0] of Unread.thread.posts - if post = Unread.posts[0] + if post = Unread.posts.first # Scroll to a non-hidden, non-OP post that's before the first unread post. while root = $.x 'preceding-sibling::div[contains(@class,"replyContainer")][1]', post.nodes.root break unless (post = Get.postFromRoot root).isHidden @@ -60,6 +60,13 @@ Unread = return unless Unread.lastReadPost < lastReadPost Unread.lastReadPost = lastReadPost Unread.readArray Unread.posts + + post = Unread.posts.first + while post + break if post.ID > Unread.lastReadPost + post = post.next + Unread.posts.splice 0, i + Unread.readArray Unread.postsQuotingYou Unread.setLine() if Conf['Unread Line'] Unread.update() @@ -114,9 +121,10 @@ Unread = Unread.addPosts e.detail.newPosts readSinglePost: (post) -> - return if (i = Unread.posts.indexOf post) is -1 - Unread.posts.splice i, 1 - if i is 0 + {ID} = post + return unless Unread.posts[ID] + Unread.posts.splice ID post.next.ID + if post is Unread.posts.first Unread.lastReadPost = post.ID Unread.saveLastReadPost() if (i = Unread.postsQuotingYou.indexOf post) isnt -1 @@ -132,27 +140,22 @@ Unread = return if d.hidden or !Unread.posts.length height = doc.clientHeight {posts} = Unread - i = 0 - while post = posts[i] + post = posts.first + + while post if Header.getBottomOf(post.nodes.root) > -1 # post is not completely read {ID} = post if Conf['Mark Quotes of You'] if post.info.yours QuoteYou.lastRead = post.nodes.root - if Conf['Quote Threading'] - posts.splice i, 1 - continue + post = post.next else - unless Conf['Quote Threading'] - break - i++ - - if i and !Conf['Quote Threading'] - posts.splice 0, i + break return unless ID + posts.splice 0, ID Unread.lastReadPost = ID if Unread.lastReadPost < ID or !Unread.lastReadPost Unread.saveLastReadPost() Unread.readArray Unread.postsQuotingYou diff --git a/src/Quotelinks/QuoteThreading.coffee b/src/Quotelinks/QuoteThreading.coffee index 3287c9a4f..0bc8981f4 100755 --- a/src/Quotelinks/QuoteThreading.coffee +++ b/src/Quotelinks/QuoteThreading.coffee @@ -36,6 +36,8 @@ QuoteThreading = node: -> return if @isClone or not QuoteThreading.enabled or @thread.OP is @ + + {replies} = Unread {quotes, ID, fullID} = @ {posts} = g @@ -68,7 +70,7 @@ QuoteThreading = {bottom, top} = qpost.nodes.root.getBoundingClientRect() # Post is unread or is fully visible. - return false unless qpost in Unread.posts or ((bottom < height) and (top > 0)) + return false unless Unread.posts[qpost.ID] or ((bottom < height) and (top > 0)) qroot = qpost.nodes.root unless $.hasClass qroot, 'threadOP' @@ -83,6 +85,7 @@ QuoteThreading = return true toggle: -> + Unread.replies = new RandomAccessList thread = $ '.thread' replies = $$ '.thread > .replyContainer, .threadContainer > .replyContainer', thread QuoteThreading.enabled = @checked From 6b3443c12a79a0c706a82690b4ad19b5a5eaef50 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sun, 5 Jan 2014 10:02:05 -0700 Subject: [PATCH 02/20] Continue implementing the random access list and generally just optimizing Unread --- LICENSE | 2 +- builds/4chan-X.user.js | 53 +++++++++++++++++++++--------------- builds/crx/script.js | 53 +++++++++++++++++++++--------------- src/Monitoring/Unread.coffee | 38 ++++++++++++++------------ 4 files changed, 84 insertions(+), 62 deletions(-) diff --git a/LICENSE b/LICENSE index 5ea10f543..f67d12a1d 100755 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ /* -* 4chan X - Version 1.2.44 - 2014-01-04 +* 4chan X - Version 1.2.44 - 2014-01-05 * * Licensed under the MIT license. * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 8d75a4939..1b2782cb3 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -22,7 +22,7 @@ // ==/UserScript== /* -* 4chan X - Version 1.2.44 - 2014-01-04 +* 4chan X - Version 1.2.44 - 2014-01-05 * * Licensed under the MIT license. * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE @@ -9510,13 +9510,12 @@ } } Unread.addPosts(posts); - return Unread.scroll(); + if (Conf['Scroll to Last Read Post']) { + return Unread.scroll(); + } }, scroll: function() { var down, hash, post, posts, root; - if (!Conf['Scroll to Last Read Post']) { - return; - } if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) { return; } @@ -9539,7 +9538,7 @@ } }, sync: function() { - var lastReadPost, post; + var ID, lastReadPost, post; lastReadPost = Unread.db.get({ boardID: Unread.thread.board.ID, threadID: Unread.thread.ID, @@ -9555,9 +9554,13 @@ if (post.ID > Unread.lastReadPost) { break; } + ID = post.ID; + if (!post.next) { + break; + } post = post.next; } - Unread.posts.splice(0, i); + Unread.posts.splice(0, ID); Unread.readArray(Unread.postsQuotingYou); if (Conf['Unread Line']) { Unread.setLine(); @@ -9565,28 +9568,34 @@ return Unread.update(); }, addPosts: function(posts) { - var ID, data, post, _i, _len, _ref; + var ID, db, post, _i, _len, _ref; + db = QR.db ? function(_arg) { + var ID, board, data, thread; + board = _arg.board, thread = _arg.thread, ID = _arg.ID; + data = { + boardID: board.ID, + threadID: thread.ID, + postID: ID + }; + if (QR.db.get(data)) { + return true; + } else { + return false; + } + } : function() { + return false; + }; for (_i = 0, _len = posts.length; _i < _len; _i++) { post = posts[_i]; ID = post.ID; - if (ID <= Unread.lastReadPost || post.isHidden) { + if (ID <= Unread.lastReadPost || post.isHidden || db(post)) { continue; } - if (QR.db) { - data = { - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - }; - if (QR.db.get(data)) { - continue; - } - } Unread.posts.push(post); Unread.addPostQuotingYou(post); } if (Conf['Unread Line']) { - Unread.setLine((_ref = Unread.posts[0], __indexOf.call(posts, _ref) >= 0)); + Unread.setLine((_ref = Unread.posts.first, __indexOf.call(posts, _ref) >= 0)); } Unread.read(); return Unread.update(); @@ -9642,7 +9651,7 @@ } Unread.posts.splice(ID(post.next.ID)); if (post === Unread.posts.first) { - Unread.lastReadPost = post.ID; + Unread.lastReadPost = ID; Unread.saveLastReadPost(); } if ((i = Unread.postsQuotingYou.indexOf(post)) !== -1) { @@ -9709,7 +9718,7 @@ if (!(d.hidden || force === true)) { return; } - if (!(post = Unread.posts[0])) { + if (!(post = Unread.posts.first)) { return $.rm(Unread.hr); } if ($.x('preceding-sibling::div[contains(@class,"replyContainer")]', post.nodes.root)) { diff --git a/builds/crx/script.js b/builds/crx/script.js index 886266b36..65bb931e7 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript /* -* 4chan X - Version 1.2.44 - 2014-01-04 +* 4chan X - Version 1.2.44 - 2014-01-05 * * Licensed under the MIT license. * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE @@ -9493,13 +9493,12 @@ } } Unread.addPosts(posts); - return Unread.scroll(); + if (Conf['Scroll to Last Read Post']) { + return Unread.scroll(); + } }, scroll: function() { var down, hash, post, posts, root; - if (!Conf['Scroll to Last Read Post']) { - return; - } if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) { return; } @@ -9522,7 +9521,7 @@ } }, sync: function() { - var lastReadPost, post; + var ID, lastReadPost, post; lastReadPost = Unread.db.get({ boardID: Unread.thread.board.ID, threadID: Unread.thread.ID, @@ -9538,9 +9537,13 @@ if (post.ID > Unread.lastReadPost) { break; } + ID = post.ID; + if (!post.next) { + break; + } post = post.next; } - Unread.posts.splice(0, i); + Unread.posts.splice(0, ID); Unread.readArray(Unread.postsQuotingYou); if (Conf['Unread Line']) { Unread.setLine(); @@ -9548,28 +9551,34 @@ return Unread.update(); }, addPosts: function(posts) { - var ID, data, post, _i, _len, _ref; + var ID, db, post, _i, _len, _ref; + db = QR.db ? function(_arg) { + var ID, board, data, thread; + board = _arg.board, thread = _arg.thread, ID = _arg.ID; + data = { + boardID: board.ID, + threadID: thread.ID, + postID: ID + }; + if (QR.db.get(data)) { + return true; + } else { + return false; + } + } : function() { + return false; + }; for (_i = 0, _len = posts.length; _i < _len; _i++) { post = posts[_i]; ID = post.ID; - if (ID <= Unread.lastReadPost || post.isHidden) { + if (ID <= Unread.lastReadPost || post.isHidden || db(post)) { continue; } - if (QR.db) { - data = { - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - }; - if (QR.db.get(data)) { - continue; - } - } Unread.posts.push(post); Unread.addPostQuotingYou(post); } if (Conf['Unread Line']) { - Unread.setLine((_ref = Unread.posts[0], __indexOf.call(posts, _ref) >= 0)); + Unread.setLine((_ref = Unread.posts.first, __indexOf.call(posts, _ref) >= 0)); } Unread.read(); return Unread.update(); @@ -9625,7 +9634,7 @@ } Unread.posts.splice(ID(post.next.ID)); if (post === Unread.posts.first) { - Unread.lastReadPost = post.ID; + Unread.lastReadPost = ID; Unread.saveLastReadPost(); } if ((i = Unread.postsQuotingYou.indexOf(post)) !== -1) { @@ -9692,7 +9701,7 @@ if (!(d.hidden || force === true)) { return; } - if (!(post = Unread.posts[0])) { + if (!(post = Unread.posts.first)) { return $.rm(Unread.hr); } if ($.x('preceding-sibling::div[contains(@class,"replyContainer")]', post.nodes.root)) { diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee index 4a2c64236..c31bf41ba 100755 --- a/src/Monitoring/Unread.coffee +++ b/src/Monitoring/Unread.coffee @@ -30,10 +30,9 @@ Unread = for ID, post of Unread.thread.posts posts.push post if post.isReply Unread.addPosts posts - Unread.scroll() + Unread.scroll() if Conf['Scroll to Last Read Post'] scroll: -> - return unless Conf['Scroll to Last Read Post'] # Let the header's onload callback handle it. return if (hash = location.hash.match /\d+/) and hash[0] of Unread.thread.posts if post = Unread.posts.first @@ -46,7 +45,7 @@ Unread = # Scroll to the last read post. posts = Object.keys Unread.thread.posts {root} = Unread.thread.posts[posts[posts.length - 1]].nodes - + # Scroll to the target unless we scrolled past it. Header.scrollTo root, down if Header.getBottomOf(root) < 0 @@ -62,29 +61,34 @@ Unread = post = Unread.posts.first while post break if post.ID > Unread.lastReadPost + {ID} = post + break unless post.next post = post.next - Unread.posts.splice 0, i - + Unread.posts.splice 0, ID + Unread.readArray Unread.postsQuotingYou Unread.setLine() if Conf['Unread Line'] Unread.update() addPosts: (posts) -> + db = if QR.db + ({board, thread, ID}) -> + data = + boardID: board.ID + threadID: thread.ID + postID: ID + return if QR.db.get data then true else false + else -> + return false + for post in posts {ID} = post - if ID <= Unread.lastReadPost or post.isHidden - continue - if QR.db - data = - boardID: post.board.ID - threadID: post.thread.ID - postID: post.ID - continue if QR.db.get data + continue if ID <= Unread.lastReadPost or post.isHidden or db post Unread.posts.push post Unread.addPostQuotingYou post if Conf['Unread Line'] # Force line on visible threads if there were no unread posts previously. - Unread.setLine Unread.posts[0] in posts + Unread.setLine Unread.posts.first in posts Unread.read() Unread.update() @@ -123,7 +127,7 @@ Unread = return unless Unread.posts[ID] Unread.posts.splice ID post.next.ID if post is Unread.posts.first - Unread.lastReadPost = post.ID + Unread.lastReadPost = ID Unread.saveLastReadPost() if (i = Unread.postsQuotingYou.indexOf post) isnt -1 Unread.postsQuotingYou.splice i, 1 @@ -168,7 +172,7 @@ Unread = setLine: (force) -> return unless d.hidden or force is true - return $.rm Unread.hr unless post = Unread.posts[0] + return $.rm Unread.hr unless post = Unread.posts.first if $.x 'preceding-sibling::div[contains(@class,"replyContainer")]', post.nodes.root # not the first reply $.before post.nodes.root, Unread.hr @@ -176,7 +180,7 @@ Unread = count = Unread.posts.length if Conf['Unread Count'] - d.title = "#{if Conf['Quoted Title'] and Unread.postsQuotingYou.length then '(!) ' else ''}#{if count or !Conf['Hide Unread Count at (0)'] then "(#{count}) " else ''}#{if g.DEAD then "/#{g.BOARD}/ - 404" else "#{Unread.title}"}" + d.title = "#{if Conf['Quoted Title'] and Unread.postsQuotingYou.length then '(!) ' else ''}#{if count or !Conf['Hide Unread Count at (0)'] then "(#{count}) " else ''}#{if g.DEAD then "/#{g.BOARD}/ - 404" else "#{Unread.title}"}" <% if (type === 'crx') { %> # XXX Chrome bug where it doesn't always update the tab title. # crbug.com/124381 From 482f6444fe3fc3a412cad9a4f5a9031d5cca5de1 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sun, 5 Jan 2014 10:25:47 -0700 Subject: [PATCH 03/20] Logic fail. Also, why did cur work when it should have been cur.ID? --- builds/4chan-X.user.js | 11 +++++++---- builds/crx/script.js | 11 +++++++---- src/General/lib/randomaccesslist.class | 9 ++++++--- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 1b2782cb3..d2471009c 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1500,11 +1500,12 @@ return; } cur = start === 0 ? this.first : this[start]; - while (cur !== this[end]) { - if (!(next = cur.next, cur)) { + while (cur) { + next = cur.next; + this.rm(cur.ID); + if (!next || cur.ID === end) { return; } - this.rm(cur); cur = next; } }; @@ -1517,7 +1518,9 @@ } delete this[ID]; this.length--; - return this.rmi(item); + this.rmi(item); + delete item.next; + return delete item.previous; }; RandomAccessList.prototype.rmi = function(item) { diff --git a/builds/crx/script.js b/builds/crx/script.js index 65bb931e7..c42619d77 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1506,11 +1506,12 @@ return; } cur = start === 0 ? this.first : this[start]; - while (cur !== this[end]) { - if (!(next = cur.next, cur)) { + while (cur) { + next = cur.next; + this.rm(cur.ID); + if (!next || cur.ID === end) { return; } - this.rm(cur); cur = next; } }; @@ -1523,7 +1524,9 @@ } delete this[ID]; this.length--; - return this.rmi(item); + this.rmi(item); + delete item.next; + return delete item.previous; }; RandomAccessList.prototype.rmi = function(item) { diff --git a/src/General/lib/randomaccesslist.class b/src/General/lib/randomaccesslist.class index c53a0c932..0a3de2f0c 100644 --- a/src/General/lib/randomaccesslist.class +++ b/src/General/lib/randomaccesslist.class @@ -34,9 +34,10 @@ class RandomAccessList splice: (start, end) -> return unless @[end] cur = if start is 0 then @first else @[start] - while cur isnt @[end] - return unless {next} = cur - @rm cur + while cur + {next} = cur + @rm cur.ID + return if not next or cur.ID is end cur = next rm: (ID) -> @@ -45,6 +46,8 @@ class RandomAccessList delete @[ID] @length-- @rmi item + delete item.next + delete item.previous rmi: (item) -> {prev, next} = item From bb5dcaa4094d5ca958ec699fae441fe7aeceda59 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sun, 5 Jan 2014 10:34:23 -0700 Subject: [PATCH 04/20] Null properties? I don't see the point. --- builds/4chan-X.user.js | 7 +------ builds/crx/script.js | 7 +------ src/General/lib/randomaccesslist.class | 6 +----- 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index d2471009c..609dadbac 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1460,8 +1460,6 @@ RandomAccessList = (function() { function RandomAccessList() { - this.first = null; - this.last = null; this.length = 0; } @@ -1469,10 +1467,7 @@ var ID, last; ID = item.ID; last = this.last; - $.extend(item, { - prev: last, - next: null - }); + item.prev = last; this[ID] = item; this.last = last ? last.next = item : this.first = item; return this.length++; diff --git a/builds/crx/script.js b/builds/crx/script.js index c42619d77..ed950692f 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1466,8 +1466,6 @@ RandomAccessList = (function() { function RandomAccessList() { - this.first = null; - this.last = null; this.length = 0; } @@ -1475,10 +1473,7 @@ var ID, last; ID = item.ID; last = this.last; - $.extend(item, { - prev: last, - next: null - }); + item.prev = last; this[ID] = item; this.last = last ? last.next = item : this.first = item; return this.length++; diff --git a/src/General/lib/randomaccesslist.class b/src/General/lib/randomaccesslist.class index 0a3de2f0c..902f13fc3 100644 --- a/src/General/lib/randomaccesslist.class +++ b/src/General/lib/randomaccesslist.class @@ -1,15 +1,11 @@ class RandomAccessList constructor: -> - @first = null - @last = null @length = 0 push: (item) -> {ID} = item {last} = @ - $.extend item, - prev: last - next: null + item.prev = last @[ID] = item @last = if last last.next = item From af30942d60a2cac3655cb2a10ed5a01e370c7807 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sun, 5 Jan 2014 10:43:27 -0700 Subject: [PATCH 05/20] Reduce unnecessary usage of RAL.splice --- src/General/lib/randomaccesslist.class | 3 +-- src/Monitoring/Unread.coffee | 11 ++++------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/General/lib/randomaccesslist.class b/src/General/lib/randomaccesslist.class index 902f13fc3..aa736e33f 100644 --- a/src/General/lib/randomaccesslist.class +++ b/src/General/lib/randomaccesslist.class @@ -19,14 +19,13 @@ class RandomAccessList @rmi item {next} = root - next.prev = root.next = item item.prev = root item.next = next shift: -> @rm @first.ID - + splice: (start, end) -> return unless @[end] cur = if start is 0 then @first else @[start] diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee index c31bf41ba..c6fcf81f9 100755 --- a/src/Monitoring/Unread.coffee +++ b/src/Monitoring/Unread.coffee @@ -56,15 +56,12 @@ Unread = defaultValue: 0 return unless Unread.lastReadPost < lastReadPost Unread.lastReadPost = lastReadPost - Unread.readArray Unread.posts post = Unread.posts.first while post - break if post.ID > Unread.lastReadPost - {ID} = post - break unless post.next + break if ({ID} = post) > Unread.lastReadPost post = post.next - Unread.posts.splice 0, ID + Unread.posts.rm ID Unread.readArray Unread.postsQuotingYou Unread.setLine() if Conf['Unread Line'] @@ -125,7 +122,7 @@ Unread = readSinglePost: (post) -> {ID} = post return unless Unread.posts[ID] - Unread.posts.splice ID post.next.ID + Unread.posts.rm ID if post is Unread.posts.first Unread.lastReadPost = ID Unread.saveLastReadPost() @@ -152,12 +149,12 @@ Unread = if post.info.yours QuoteYou.lastRead = post.nodes.root post = post.next + posts.rm ID else break return unless ID - posts.splice 0, ID Unread.lastReadPost = ID if Unread.lastReadPost < ID or !Unread.lastReadPost Unread.saveLastReadPost() Unread.readArray Unread.postsQuotingYou From d31b18cc82ac227b2df370fbd894210c187abd23 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sun, 5 Jan 2014 10:45:14 -0700 Subject: [PATCH 06/20] Build? da fuq? --- builds/4chan-X.user.js | 13 ++++--------- builds/crx/script.js | 13 ++++--------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 609dadbac..69f9c020e 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -9546,19 +9546,14 @@ return; } Unread.lastReadPost = lastReadPost; - Unread.readArray(Unread.posts); post = Unread.posts.first; while (post) { - if (post.ID > Unread.lastReadPost) { - break; - } - ID = post.ID; - if (!post.next) { + if ((ID = post.ID, post) > Unread.lastReadPost) { break; } post = post.next; + Unread.posts.rm(ID); } - Unread.posts.splice(0, ID); Unread.readArray(Unread.postsQuotingYou); if (Conf['Unread Line']) { Unread.setLine(); @@ -9647,7 +9642,7 @@ if (!Unread.posts[ID]) { return; } - Unread.posts.splice(ID(post.next.ID)); + Unread.posts.rm(ID); if (post === Unread.posts.first) { Unread.lastReadPost = ID; Unread.saveLastReadPost(); @@ -9684,6 +9679,7 @@ } } post = post.next; + posts.rm(ID); } else { break; } @@ -9691,7 +9687,6 @@ if (!ID) { return; } - posts.splice(0, ID); if (Unread.lastReadPost < ID || !Unread.lastReadPost) { Unread.lastReadPost = ID; } diff --git a/builds/crx/script.js b/builds/crx/script.js index ed950692f..2891e2a7a 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -9529,19 +9529,14 @@ return; } Unread.lastReadPost = lastReadPost; - Unread.readArray(Unread.posts); post = Unread.posts.first; while (post) { - if (post.ID > Unread.lastReadPost) { - break; - } - ID = post.ID; - if (!post.next) { + if ((ID = post.ID, post) > Unread.lastReadPost) { break; } post = post.next; + Unread.posts.rm(ID); } - Unread.posts.splice(0, ID); Unread.readArray(Unread.postsQuotingYou); if (Conf['Unread Line']) { Unread.setLine(); @@ -9630,7 +9625,7 @@ if (!Unread.posts[ID]) { return; } - Unread.posts.splice(ID(post.next.ID)); + Unread.posts.rm(ID); if (post === Unread.posts.first) { Unread.lastReadPost = ID; Unread.saveLastReadPost(); @@ -9667,6 +9662,7 @@ } } post = post.next; + posts.rm(ID); } else { break; } @@ -9674,7 +9670,6 @@ if (!ID) { return; } - posts.splice(0, ID); if (Unread.lastReadPost < ID || !Unread.lastReadPost) { Unread.lastReadPost = ID; } From c1427e44943bb2b8626e023c5c227bc24013fc84 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sun, 5 Jan 2014 10:52:58 -0700 Subject: [PATCH 07/20] And... I think that's done. Well, that wasn't hard. --- builds/4chan-X.user.js | 21 +++++++++++---------- builds/crx/script.js | 21 +++++++++++---------- src/Quotelinks/QuoteThreading.coffee | 23 +++++++++++++---------- 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 69f9c020e..e688b10c3 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -4977,31 +4977,32 @@ return this.cb = QuoteThreading.nodeinsert; }, nodeinsert: function() { - var bottom, height, qpost, qroot, threadContainer, top, _ref; - qpost = g.posts[this.threaded]; + var bottom, height, post, root, threadContainer, top, _ref; + post = g.posts[this.threaded]; delete this.threaded; delete this.cb; - if (this.thread.OP === qpost) { + if (this.thread.OP === post) { return false; } if (QuoteThreading.hasRun) { height = doc.clientHeight; - _ref = qpost.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; - if (!(Unread.posts[qpost.ID] || ((bottom < height) && (top > 0)))) { + _ref = post.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; + if (!(Unread.posts[post.ID] || ((bottom < height) && (top > 0)))) { return false; } } - qroot = qpost.nodes.root; - if (!$.hasClass(qroot, 'threadOP')) { - $.addClass(qroot, 'threadOP'); + root = post.nodes.root; + if (!$.hasClass(root, 'threadOP')) { + $.addClass(root, 'threadOP'); threadContainer = $.el('div', { className: 'threadContainer' }); - $.after(qroot, threadContainer); + $.after(root, threadContainer); } else { - threadContainer = qroot.nextSibling; + threadContainer = root.nextSibling; } $.add(threadContainer, this.nodes.root); + Unread.posts.after(post.ID, this); return true; }, toggle: function() { diff --git a/builds/crx/script.js b/builds/crx/script.js index 2891e2a7a..f2f569043 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -4980,31 +4980,32 @@ return this.cb = QuoteThreading.nodeinsert; }, nodeinsert: function() { - var bottom, height, qpost, qroot, threadContainer, top, _ref; - qpost = g.posts[this.threaded]; + var bottom, height, post, root, threadContainer, top, _ref; + post = g.posts[this.threaded]; delete this.threaded; delete this.cb; - if (this.thread.OP === qpost) { + if (this.thread.OP === post) { return false; } if (QuoteThreading.hasRun) { height = doc.clientHeight; - _ref = qpost.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; - if (!(Unread.posts[qpost.ID] || ((bottom < height) && (top > 0)))) { + _ref = post.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; + if (!(Unread.posts[post.ID] || ((bottom < height) && (top > 0)))) { return false; } } - qroot = qpost.nodes.root; - if (!$.hasClass(qroot, 'threadOP')) { - $.addClass(qroot, 'threadOP'); + root = post.nodes.root; + if (!$.hasClass(root, 'threadOP')) { + $.addClass(root, 'threadOP'); threadContainer = $.el('div', { className: 'threadContainer' }); - $.after(qroot, threadContainer); + $.after(root, threadContainer); } else { - threadContainer = qroot.nextSibling; + threadContainer = root.nextSibling; } $.add(threadContainer, this.nodes.root); + Unread.posts.after(post.ID, this); return true; }, toggle: function() { diff --git a/src/Quotelinks/QuoteThreading.coffee b/src/Quotelinks/QuoteThreading.coffee index 0bc8981f4..5da0476e5 100755 --- a/src/Quotelinks/QuoteThreading.coffee +++ b/src/Quotelinks/QuoteThreading.coffee @@ -36,7 +36,7 @@ QuoteThreading = node: -> return if @isClone or not QuoteThreading.enabled or @thread.OP is @ - + {replies} = Unread {quotes, ID, fullID} = @ @@ -58,30 +58,33 @@ QuoteThreading = @cb = QuoteThreading.nodeinsert nodeinsert: -> - qpost = g.posts[@threaded] + post = g.posts[@threaded] delete @threaded delete @cb - return false if @thread.OP is qpost + return false if @thread.OP is post if QuoteThreading.hasRun height = doc.clientHeight - {bottom, top} = qpost.nodes.root.getBoundingClientRect() + {bottom, top} = post.nodes.root.getBoundingClientRect() # Post is unread or is fully visible. - return false unless Unread.posts[qpost.ID] or ((bottom < height) and (top > 0)) + return false unless Unread.posts[post.ID] or ((bottom < height) and (top > 0)) - qroot = qpost.nodes.root - unless $.hasClass qroot, 'threadOP' - $.addClass qroot, 'threadOP' + root = post.nodes.root + unless $.hasClass root, 'threadOP' + $.addClass root, 'threadOP' threadContainer = $.el 'div', className: 'threadContainer' - $.after qroot, threadContainer + $.after root, threadContainer else - threadContainer = qroot.nextSibling + threadContainer = root.nextSibling $.add threadContainer, @nodes.root + + Unread.posts.after post.ID, @ + return true toggle: -> From 3f60a05edc6017ea214b5bb0c4982c615eaecb4d Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sun, 5 Jan 2014 13:12:06 -0700 Subject: [PATCH 08/20] I was wrong. Still broken, but getting there --- builds/4chan-X.user.js | 148 +++++++++++++++++-------- builds/crx/script.js | 148 +++++++++++++++++-------- src/General/Main.coffee | 1 - src/General/lib/randomaccesslist.class | 25 ++++- src/Monitoring/Unread.coffee | 48 ++++---- src/Quotelinks/QuoteThreading.coffee | 40 ++++--- 6 files changed, 277 insertions(+), 133 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index e688b10c3..dfa6a4dc6 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1480,9 +1480,27 @@ } this.rmi(item); next = root.next; - next.prev = root.next = item; - item.prev = root; - return item.next = next; + next.prev = item; + item.next = next; + root.next = item; + return item.prev = root; + }; + + RandomAccessList.prototype.prepend = function(item) { + var ID, first; + ID = item.ID; + if (!this[ID]) { + this.push(item); + } + first = this.first; + if (this !== first) { + item.next = first; + } + if (first) { + first.prev = item; + } + this.first = item; + return delete item.prev; }; RandomAccessList.prototype.shift = function() { @@ -1533,6 +1551,19 @@ } }; + RandomAccessList.prototype.closest = function(ID) { + var item, prev; + item = this.first; + while (item) { + if (item.ID > ID) { + prev = item.prev.prev; + break; + } + item = item.next; + } + return (prev ? prev.ID : -1); + }; + return RandomAccessList; })(); @@ -4928,7 +4959,9 @@ el: this.controls, order: 98 }); - $.on(d, '4chanXInitFinished', this.setup); + if (!Conf['Unread Count']) { + $.on(d, '4chanXInitFinished', QuoteThreading.setup); + } return Post.callbacks.push({ name: 'Quote Threading', cb: this.node @@ -4977,17 +5010,18 @@ return this.cb = QuoteThreading.nodeinsert; }, nodeinsert: function() { - var bottom, height, post, root, threadContainer, top, _ref; + var ID, bottom, height, post, posts, root, threadContainer, top, _ref; post = g.posts[this.threaded]; - delete this.threaded; - delete this.cb; + posts = Unread.posts; + this.threaded; + this.cb; if (this.thread.OP === post) { return false; } if (QuoteThreading.hasRun) { height = doc.clientHeight; _ref = post.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; - if (!(Unread.posts[post.ID] || ((bottom < height) && (top > 0)))) { + if (!(posts[post.ID] || ((bottom < height) && (top > 0)))) { return false; } } @@ -5002,12 +5036,24 @@ threadContainer = root.nextSibling; } $.add(threadContainer, this.nodes.root); - Unread.posts.after(post.ID, this); + if (!posts[this.ID]) { + posts.push(this); + } + if (posts[post.ID]) { + posts.after(post, this); + } else { + if ((ID = posts.closest(ID)) !== -1) { + posts.after(posts[ID], this); + } else { + posts.prepend(this); + } + } return true; }, toggle: function() { var container, containers, node, post, replies, reply, thread, _i, _j, _k, _len, _len1, _len2, _ref; - Unread.replies = new RandomAccessList; + Unread.posts = new RandomAccessList; + Unread.ready(); thread = $('.thread'); replies = $$('.thread > .replyContainer, .threadContainer > .replyContainer', thread); QuoteThreading.enabled = this.checked; @@ -5015,9 +5061,14 @@ QuoteThreading.hasRun = false; for (_i = 0, _len = replies.length; _i < _len; _i++) { reply = replies[_i]; - QuoteThreading.node.call(node = Get.postFromRoot(reply)); + node = Get.postFromRoot(reply); if (node.cb) { - node.cb(); + node.cb.call(node); + } else { + QuoteThreading.node.call(node); + if (node.cb) { + node.cb.call(node); + } } } QuoteThreading.hasRun = true; @@ -5045,7 +5096,8 @@ kb: function() { var control; control = $.id('threadingControl'); - return control.click(); + control.checked = !control.checked; + return QuoteThreading.toggle.call(control); } }; @@ -9477,6 +9529,22 @@ }); this.posts = new RandomAccessList; this.postsQuotingYou = []; + this.qr = QR.db ? function(_arg) { + var ID, board, data, thread; + board = _arg.board, thread = _arg.thread, ID = _arg.ID; + data = { + boardID: board.ID, + threadID: thread.ID, + postID: ID + }; + if (QR.db.get(data)) { + return true; + } else { + return false; + } + } : function() { + return false; + }; return Thread.callbacks.push({ name: 'Unread', cb: this.node @@ -9509,6 +9577,9 @@ } } Unread.addPosts(posts); + if (Conf['Quote Threading']) { + QuoteThreading.setup(); + } if (Conf['Scroll to Last Read Post']) { return Unread.scroll(); } @@ -9562,30 +9633,16 @@ return Unread.update(); }, addPosts: function(posts) { - var ID, db, post, _i, _len, _ref; - db = QR.db ? function(_arg) { - var ID, board, data, thread; - board = _arg.board, thread = _arg.thread, ID = _arg.ID; - data = { - boardID: board.ID, - threadID: thread.ID, - postID: ID - }; - if (QR.db.get(data)) { - return true; - } else { - return false; - } - } : function() { - return false; - }; + var ID, post, _i, _len, _ref; for (_i = 0, _len = posts.length; _i < _len; _i++) { post = posts[_i]; ID = post.ID; - if (ID <= Unread.lastReadPost || post.isHidden || db(post)) { + if (ID <= Unread.lastReadPost || post.isHidden || Unread.qr(post)) { continue; } - Unread.posts.push(post); + if (!(post.prev || post.next)) { + Unread.posts.push(post); + } Unread.addPostQuotingYou(post); } if (Conf['Unread Line']) { @@ -9663,25 +9720,24 @@ } return arr.splice(0, i); }, - read: $.debounce(50, function(e) { + read: function(e) { var ID, height, post, posts; if (d.hidden || !Unread.posts.length) { return; } height = doc.clientHeight; posts = Unread.posts; - post = posts.first; - while (post) { - if (Header.getBottomOf(post.nodes.root) > -1) { - ID = post.ID; - if (Conf['Mark Quotes of You']) { - if (post.info.yours) { - QuoteYou.lastRead = post.nodes.root; - } - } - post = post.next; - posts.rm(ID); - } else { + while (post = posts.first) { + if (!(Header.getBottomOf(post.nodes.root) > -1)) { + break; + } + ID = post.ID; + if (Conf['Mark Quotes of You'] && post.info.yours) { + QuoteYou.lastRead = post.nodes.root; + } + posts.rm(ID); + if (post === posts.first) { + c.log(posts); break; } } @@ -9696,7 +9752,7 @@ if (e) { return Unread.update(); } - }), + }, saveLastReadPost: $.debounce(2 * $.SECOND, function() { if (Unread.thread.isDead) { return; diff --git a/builds/crx/script.js b/builds/crx/script.js index f2f569043..e314fce6a 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1486,9 +1486,27 @@ } this.rmi(item); next = root.next; - next.prev = root.next = item; - item.prev = root; - return item.next = next; + next.prev = item; + item.next = next; + root.next = item; + return item.prev = root; + }; + + RandomAccessList.prototype.prepend = function(item) { + var ID, first; + ID = item.ID; + if (!this[ID]) { + this.push(item); + } + first = this.first; + if (this !== first) { + item.next = first; + } + if (first) { + first.prev = item; + } + this.first = item; + return delete item.prev; }; RandomAccessList.prototype.shift = function() { @@ -1539,6 +1557,19 @@ } }; + RandomAccessList.prototype.closest = function(ID) { + var item, prev; + item = this.first; + while (item) { + if (item.ID > ID) { + prev = item.prev.prev; + break; + } + item = item.next; + } + return (prev ? prev.ID : -1); + }; + return RandomAccessList; })(); @@ -4931,7 +4962,9 @@ el: this.controls, order: 98 }); - $.on(d, '4chanXInitFinished', this.setup); + if (!Conf['Unread Count']) { + $.on(d, '4chanXInitFinished', QuoteThreading.setup); + } return Post.callbacks.push({ name: 'Quote Threading', cb: this.node @@ -4980,17 +5013,18 @@ return this.cb = QuoteThreading.nodeinsert; }, nodeinsert: function() { - var bottom, height, post, root, threadContainer, top, _ref; + var ID, bottom, height, post, posts, root, threadContainer, top, _ref; post = g.posts[this.threaded]; - delete this.threaded; - delete this.cb; + posts = Unread.posts; + this.threaded; + this.cb; if (this.thread.OP === post) { return false; } if (QuoteThreading.hasRun) { height = doc.clientHeight; _ref = post.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; - if (!(Unread.posts[post.ID] || ((bottom < height) && (top > 0)))) { + if (!(posts[post.ID] || ((bottom < height) && (top > 0)))) { return false; } } @@ -5005,12 +5039,24 @@ threadContainer = root.nextSibling; } $.add(threadContainer, this.nodes.root); - Unread.posts.after(post.ID, this); + if (!posts[this.ID]) { + posts.push(this); + } + if (posts[post.ID]) { + posts.after(post, this); + } else { + if ((ID = posts.closest(ID)) !== -1) { + posts.after(posts[ID], this); + } else { + posts.prepend(this); + } + } return true; }, toggle: function() { var container, containers, node, post, replies, reply, thread, _i, _j, _k, _len, _len1, _len2, _ref; - Unread.replies = new RandomAccessList; + Unread.posts = new RandomAccessList; + Unread.ready(); thread = $('.thread'); replies = $$('.thread > .replyContainer, .threadContainer > .replyContainer', thread); QuoteThreading.enabled = this.checked; @@ -5018,9 +5064,14 @@ QuoteThreading.hasRun = false; for (_i = 0, _len = replies.length; _i < _len; _i++) { reply = replies[_i]; - QuoteThreading.node.call(node = Get.postFromRoot(reply)); + node = Get.postFromRoot(reply); if (node.cb) { - node.cb(); + node.cb.call(node); + } else { + QuoteThreading.node.call(node); + if (node.cb) { + node.cb.call(node); + } } } QuoteThreading.hasRun = true; @@ -5048,7 +5099,8 @@ kb: function() { var control; control = $.id('threadingControl'); - return control.click(); + control.checked = !control.checked; + return QuoteThreading.toggle.call(control); } }; @@ -9460,6 +9512,22 @@ }); this.posts = new RandomAccessList; this.postsQuotingYou = []; + this.qr = QR.db ? function(_arg) { + var ID, board, data, thread; + board = _arg.board, thread = _arg.thread, ID = _arg.ID; + data = { + boardID: board.ID, + threadID: thread.ID, + postID: ID + }; + if (QR.db.get(data)) { + return true; + } else { + return false; + } + } : function() { + return false; + }; return Thread.callbacks.push({ name: 'Unread', cb: this.node @@ -9492,6 +9560,9 @@ } } Unread.addPosts(posts); + if (Conf['Quote Threading']) { + QuoteThreading.setup(); + } if (Conf['Scroll to Last Read Post']) { return Unread.scroll(); } @@ -9545,30 +9616,16 @@ return Unread.update(); }, addPosts: function(posts) { - var ID, db, post, _i, _len, _ref; - db = QR.db ? function(_arg) { - var ID, board, data, thread; - board = _arg.board, thread = _arg.thread, ID = _arg.ID; - data = { - boardID: board.ID, - threadID: thread.ID, - postID: ID - }; - if (QR.db.get(data)) { - return true; - } else { - return false; - } - } : function() { - return false; - }; + var ID, post, _i, _len, _ref; for (_i = 0, _len = posts.length; _i < _len; _i++) { post = posts[_i]; ID = post.ID; - if (ID <= Unread.lastReadPost || post.isHidden || db(post)) { + if (ID <= Unread.lastReadPost || post.isHidden || Unread.qr(post)) { continue; } - Unread.posts.push(post); + if (!(post.prev || post.next)) { + Unread.posts.push(post); + } Unread.addPostQuotingYou(post); } if (Conf['Unread Line']) { @@ -9646,25 +9703,24 @@ } return arr.splice(0, i); }, - read: $.debounce(50, function(e) { + read: function(e) { var ID, height, post, posts; if (d.hidden || !Unread.posts.length) { return; } height = doc.clientHeight; posts = Unread.posts; - post = posts.first; - while (post) { - if (Header.getBottomOf(post.nodes.root) > -1) { - ID = post.ID; - if (Conf['Mark Quotes of You']) { - if (post.info.yours) { - QuoteYou.lastRead = post.nodes.root; - } - } - post = post.next; - posts.rm(ID); - } else { + while (post = posts.first) { + if (!(Header.getBottomOf(post.nodes.root) > -1)) { + break; + } + ID = post.ID; + if (Conf['Mark Quotes of You'] && post.info.yours) { + QuoteYou.lastRead = post.nodes.root; + } + posts.rm(ID); + if (post === posts.first) { + c.log(posts); break; } } @@ -9679,7 +9735,7 @@ if (e) { return Unread.update(); } - }), + }, saveLastReadPost: $.debounce(2 * $.SECOND, function() { if (Unread.thread.isDead) { return; diff --git a/src/General/Main.coffee b/src/General/Main.coffee index 14b4c8dd9..61b083ecf 100755 --- a/src/General/Main.coffee +++ b/src/General/Main.coffee @@ -1,6 +1,5 @@ Main = init: -> - # flatten Config into Conf # and get saved or default values flatten = (parent, obj) -> diff --git a/src/General/lib/randomaccesslist.class b/src/General/lib/randomaccesslist.class index aa736e33f..40598be24 100644 --- a/src/General/lib/randomaccesslist.class +++ b/src/General/lib/randomaccesslist.class @@ -19,9 +19,19 @@ class RandomAccessList @rmi item {next} = root - next.prev = root.next = item - item.prev = root + next.prev = item item.next = next + root.next = item + item.prev = root + + prepend: (item) -> + {ID} = item + @push item unless @[ID] + {first} = @ + item.next = first unless @ is first + first.prev = item if first + @first = item + delete item.prev shift: -> @rm @first.ID @@ -53,4 +63,13 @@ class RandomAccessList if next next.prev = prev else - @last = prev \ No newline at end of file + @last = prev + + closest: (ID) -> + item = @first + while item + if item.ID > ID + {prev} = item.prev + break + item = item.next + return (if prev then prev.ID else -1) \ No newline at end of file diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee index c6fcf81f9..90e78b9d4 100755 --- a/src/Monitoring/Unread.coffee +++ b/src/Monitoring/Unread.coffee @@ -7,6 +7,16 @@ Unread = id: 'unread-line' @posts = new RandomAccessList @postsQuotingYou = [] + + @qr = if QR.db + ({board, thread, ID}) -> + data = + boardID: board.ID + threadID: thread.ID + postID: ID + return if QR.db.get data then true else false + else -> + return false Thread.callbacks.push name: 'Unread' @@ -30,6 +40,7 @@ Unread = for ID, post of Unread.thread.posts posts.push post if post.isReply Unread.addPosts posts + QuoteThreading.setup() if Conf['Quote Threading'] Unread.scroll() if Conf['Scroll to Last Read Post'] scroll: -> @@ -68,20 +79,10 @@ Unread = Unread.update() addPosts: (posts) -> - db = if QR.db - ({board, thread, ID}) -> - data = - boardID: board.ID - threadID: thread.ID - postID: ID - return if QR.db.get data then true else false - else -> - return false - for post in posts {ID} = post - continue if ID <= Unread.lastReadPost or post.isHidden or db post - Unread.posts.push post + continue if ID <= Unread.lastReadPost or post.isHidden or Unread.qr post + Unread.posts.push post unless post.prev or post.next Unread.addPostQuotingYou post if Conf['Unread Line'] # Force line on visible threads if there were no unread posts previously. @@ -135,22 +136,21 @@ Unread = break if post.ID > Unread.lastReadPost arr.splice 0, i - read: $.debounce 50, (e) -> + read: (e) -> return if d.hidden or !Unread.posts.length height = doc.clientHeight + {posts} = Unread + while post = posts.first + break unless Header.getBottomOf(post.nodes.root) > -1 # post is not completely read - post = posts.first - - while post - if Header.getBottomOf(post.nodes.root) > -1 # post is not completely read - {ID} = post - if Conf['Mark Quotes of You'] - if post.info.yours - QuoteYou.lastRead = post.nodes.root - post = post.next - posts.rm ID - else + {ID} = post + if Conf['Mark Quotes of You'] and post.info.yours + QuoteYou.lastRead = post.nodes.root + posts.rm ID + + if post is posts.first + c.log posts break return unless ID diff --git a/src/Quotelinks/QuoteThreading.coffee b/src/Quotelinks/QuoteThreading.coffee index 5da0476e5..f4930b6be 100755 --- a/src/Quotelinks/QuoteThreading.coffee +++ b/src/Quotelinks/QuoteThreading.coffee @@ -18,7 +18,7 @@ QuoteThreading = el: @controls order: 98 - $.on d, '4chanXInitFinished', @setup + $.on d, '4chanXInitFinished', QuoteThreading.setup unless Conf['Unread Count'] Post.callbacks.push name: 'Quote Threading' @@ -28,9 +28,7 @@ QuoteThreading = $.off d, '4chanXInitFinished', QuoteThreading.setup {posts} = g - for ID, post of posts - if post.cb - post.cb.call post + post.cb.call post for ID, post of posts when post.cb QuoteThreading.hasRun = true @@ -58,10 +56,11 @@ QuoteThreading = @cb = QuoteThreading.nodeinsert nodeinsert: -> - post = g.posts[@threaded] + post = g.posts[@threaded] + {posts} = Unread - delete @threaded - delete @cb + @threaded + @cb return false if @thread.OP is post @@ -70,7 +69,7 @@ QuoteThreading = {bottom, top} = post.nodes.root.getBoundingClientRect() # Post is unread or is fully visible. - return false unless Unread.posts[post.ID] or ((bottom < height) and (top > 0)) + return false unless posts[post.ID] or ((bottom < height) and (top > 0)) root = post.nodes.root unless $.hasClass root, 'threadOP' @@ -83,20 +82,34 @@ QuoteThreading = $.add threadContainer, @nodes.root - Unread.posts.after post.ID, @ + posts.push @ unless posts[@ID] + if posts[post.ID] + posts.after post, @ + else + if (ID = posts.closest ID) isnt -1 + posts.after posts[ID], @ + else + posts.prepend @ + return true toggle: -> - Unread.replies = new RandomAccessList + Unread.posts = new RandomAccessList + Unread.ready() + thread = $ '.thread' replies = $$ '.thread > .replyContainer, .threadContainer > .replyContainer', thread QuoteThreading.enabled = @checked if @checked QuoteThreading.hasRun = false for reply in replies - QuoteThreading.node.call node = Get.postFromRoot reply - node.cb() if node.cb + node = Get.postFromRoot reply + if node.cb + node.cb.call node + else + QuoteThreading.node.call node + node.cb.call node if node.cb QuoteThreading.hasRun = true else replies.sort (a, b) -> @@ -111,4 +124,5 @@ QuoteThreading = kb: -> control = $.id 'threadingControl' - control.click() \ No newline at end of file + control.checked = not control.checked + QuoteThreading.toggle.call control \ No newline at end of file From 4f8e304ee836be1547d8be883b9925ea51c7eb01 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sun, 5 Jan 2014 13:57:26 -0700 Subject: [PATCH 09/20] So terrible~ --- builds/4chan-X.user.js | 57 +++++++++++++------------- builds/crx/script.js | 57 +++++++++++++------------- src/General/lib/randomaccesslist.class | 10 ++--- src/Monitoring/Unread.coffee | 7 ++-- src/Quotelinks/QuoteThreading.coffee | 33 ++++++--------- 5 files changed, 77 insertions(+), 87 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index dfa6a4dc6..5d5a7ed69 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1480,9 +1480,8 @@ } this.rmi(item); next = root.next; - next.prev = item; + root.next = next.prev = item; item.next = next; - root.next = item; return item.prev = root; }; @@ -1493,12 +1492,11 @@ this.push(item); } first = this.first; - if (this !== first) { - item.next = first; - } - if (first) { - first.prev = item; + if (item === first) { + return; } + item.next = first; + first.prev = item; this.first = item; return delete item.prev; }; @@ -1533,7 +1531,7 @@ this.length--; this.rmi(item); delete item.next; - return delete item.previous; + return delete item.prev; }; RandomAccessList.prototype.rmi = function(item) { @@ -4968,11 +4966,11 @@ }); }, setup: function() { - var ID, post, posts; + var ID, post, _ref; $.off(d, '4chanXInitFinished', QuoteThreading.setup); - posts = g.posts; - for (ID in posts) { - post = posts[ID]; + _ref = g.posts; + for (ID in _ref) { + post = _ref[ID]; if (post.cb) { post.cb.call(post); } @@ -4980,48 +4978,42 @@ return QuoteThreading.hasRun = true; }, node: function() { - var ID, fullID, keys, len, post, posts, qid, quote, quotes, replies, uniq, _i, _len; + var ID, fullID, keys, len, post, posts, quote, quotes, _i, _len; if (this.isClone || !QuoteThreading.enabled || this.thread.OP === this) { return; } - replies = Unread.replies; quotes = this.quotes, ID = this.ID, fullID = this.fullID; posts = g.posts; if (!(post = posts[fullID]) || post.isHidden) { return; } - uniq = {}; + keys = []; len = ("" + g.BOARD).length + 1; for (_i = 0, _len = quotes.length; _i < _len; _i++) { quote = quotes[_i]; - qid = quote; - if (!(qid.slice(len) < ID)) { - continue; - } - if (qid in posts) { - uniq[qid.slice(len)] = true; + if (quote.slice(len) < ID) { + if (quote in posts) { + keys.push(quote); + } } } - keys = Object.keys(uniq); if (keys.length !== 1) { return; } - this.threaded = "" + g.BOARD + "." + keys[0]; + this.threaded = keys[0]; return this.cb = QuoteThreading.nodeinsert; }, nodeinsert: function() { var ID, bottom, height, post, posts, root, threadContainer, top, _ref; post = g.posts[this.threaded]; posts = Unread.posts; - this.threaded; - this.cb; if (this.thread.OP === post) { return false; } if (QuoteThreading.hasRun) { height = doc.clientHeight; _ref = post.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; - if (!(posts[post.ID] || ((bottom < height) && (top > 0)))) { + if (!((posts != null ? posts[post.ID] : void 0) || ((bottom < height) && (top > 0)))) { return false; } } @@ -5036,6 +5028,9 @@ threadContainer = root.nextSibling; } $.add(threadContainer, this.nodes.root); + if (!Conf['Unread Count'] || this.ID < Unread.lastReadPost) { + return true; + } if (!posts[this.ID]) { posts.push(this); } @@ -5052,8 +5047,10 @@ }, toggle: function() { var container, containers, node, post, replies, reply, thread, _i, _j, _k, _len, _len1, _len2, _ref; - Unread.posts = new RandomAccessList; - Unread.ready(); + if (Conf['Unread Count']) { + Unread.posts = new RandomAccessList; + Unread.ready(); + } thread = $('.thread'); replies = $$('.thread > .replyContainer, .threadContainer > .replyContainer', thread); QuoteThreading.enabled = this.checked; @@ -5091,7 +5088,9 @@ $.rmClass(post, 'threadOP'); } } - return Unread.update(true); + if (Conf['Unread Count']) { + return Unread.read(); + } }, kb: function() { var control; diff --git a/builds/crx/script.js b/builds/crx/script.js index e314fce6a..b18addccd 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1486,9 +1486,8 @@ } this.rmi(item); next = root.next; - next.prev = item; + root.next = next.prev = item; item.next = next; - root.next = item; return item.prev = root; }; @@ -1499,12 +1498,11 @@ this.push(item); } first = this.first; - if (this !== first) { - item.next = first; - } - if (first) { - first.prev = item; + if (item === first) { + return; } + item.next = first; + first.prev = item; this.first = item; return delete item.prev; }; @@ -1539,7 +1537,7 @@ this.length--; this.rmi(item); delete item.next; - return delete item.previous; + return delete item.prev; }; RandomAccessList.prototype.rmi = function(item) { @@ -4971,11 +4969,11 @@ }); }, setup: function() { - var ID, post, posts; + var ID, post, _ref; $.off(d, '4chanXInitFinished', QuoteThreading.setup); - posts = g.posts; - for (ID in posts) { - post = posts[ID]; + _ref = g.posts; + for (ID in _ref) { + post = _ref[ID]; if (post.cb) { post.cb.call(post); } @@ -4983,48 +4981,42 @@ return QuoteThreading.hasRun = true; }, node: function() { - var ID, fullID, keys, len, post, posts, qid, quote, quotes, replies, uniq, _i, _len; + var ID, fullID, keys, len, post, posts, quote, quotes, _i, _len; if (this.isClone || !QuoteThreading.enabled || this.thread.OP === this) { return; } - replies = Unread.replies; quotes = this.quotes, ID = this.ID, fullID = this.fullID; posts = g.posts; if (!(post = posts[fullID]) || post.isHidden) { return; } - uniq = {}; + keys = []; len = ("" + g.BOARD).length + 1; for (_i = 0, _len = quotes.length; _i < _len; _i++) { quote = quotes[_i]; - qid = quote; - if (!(qid.slice(len) < ID)) { - continue; - } - if (qid in posts) { - uniq[qid.slice(len)] = true; + if (quote.slice(len) < ID) { + if (quote in posts) { + keys.push(quote); + } } } - keys = Object.keys(uniq); if (keys.length !== 1) { return; } - this.threaded = "" + g.BOARD + "." + keys[0]; + this.threaded = keys[0]; return this.cb = QuoteThreading.nodeinsert; }, nodeinsert: function() { var ID, bottom, height, post, posts, root, threadContainer, top, _ref; post = g.posts[this.threaded]; posts = Unread.posts; - this.threaded; - this.cb; if (this.thread.OP === post) { return false; } if (QuoteThreading.hasRun) { height = doc.clientHeight; _ref = post.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; - if (!(posts[post.ID] || ((bottom < height) && (top > 0)))) { + if (!((posts != null ? posts[post.ID] : void 0) || ((bottom < height) && (top > 0)))) { return false; } } @@ -5039,6 +5031,9 @@ threadContainer = root.nextSibling; } $.add(threadContainer, this.nodes.root); + if (!Conf['Unread Count'] || this.ID < Unread.lastReadPost) { + return true; + } if (!posts[this.ID]) { posts.push(this); } @@ -5055,8 +5050,10 @@ }, toggle: function() { var container, containers, node, post, replies, reply, thread, _i, _j, _k, _len, _len1, _len2, _ref; - Unread.posts = new RandomAccessList; - Unread.ready(); + if (Conf['Unread Count']) { + Unread.posts = new RandomAccessList; + Unread.ready(); + } thread = $('.thread'); replies = $$('.thread > .replyContainer, .threadContainer > .replyContainer', thread); QuoteThreading.enabled = this.checked; @@ -5094,7 +5091,9 @@ $.rmClass(post, 'threadOP'); } } - return Unread.update(true); + if (Conf['Unread Count']) { + return Unread.read(); + } }, kb: function() { var control; diff --git a/src/General/lib/randomaccesslist.class b/src/General/lib/randomaccesslist.class index 40598be24..a2907aa01 100644 --- a/src/General/lib/randomaccesslist.class +++ b/src/General/lib/randomaccesslist.class @@ -19,17 +19,17 @@ class RandomAccessList @rmi item {next} = root - next.prev = item + root.next = next.prev = item item.next = next - root.next = item item.prev = root prepend: (item) -> {ID} = item @push item unless @[ID] {first} = @ - item.next = first unless @ is first - first.prev = item if first + return if item is first + item.next = first + first.prev = item @first = item delete item.prev @@ -52,7 +52,7 @@ class RandomAccessList @length-- @rmi item delete item.next - delete item.previous + delete item.prev rmi: (item) -> {prev, next} = item diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee index 90e78b9d4..52789e67d 100755 --- a/src/Monitoring/Unread.coffee +++ b/src/Monitoring/Unread.coffee @@ -7,7 +7,7 @@ Unread = id: 'unread-line' @posts = new RandomAccessList @postsQuotingYou = [] - + @qr = if QR.db ({board, thread, ID}) -> data = @@ -37,8 +37,7 @@ Unread = ready: -> $.off d, '4chanXInitFinished', Unread.ready posts = [] - for ID, post of Unread.thread.posts - posts.push post if post.isReply + posts.push post for ID, post of Unread.thread.posts when post.isReply Unread.addPosts posts QuoteThreading.setup() if Conf['Quote Threading'] Unread.scroll() if Conf['Scroll to Last Read Post'] @@ -148,7 +147,7 @@ Unread = if Conf['Mark Quotes of You'] and post.info.yours QuoteYou.lastRead = post.nodes.root posts.rm ID - + if post is posts.first c.log posts break diff --git a/src/Quotelinks/QuoteThreading.coffee b/src/Quotelinks/QuoteThreading.coffee index f4930b6be..eacb9b753 100755 --- a/src/Quotelinks/QuoteThreading.coffee +++ b/src/Quotelinks/QuoteThreading.coffee @@ -26,42 +26,32 @@ QuoteThreading = setup: -> $.off d, '4chanXInitFinished', QuoteThreading.setup - {posts} = g - post.cb.call post for ID, post of posts when post.cb + post.cb.call post for ID, post of g.posts when post.cb QuoteThreading.hasRun = true node: -> return if @isClone or not QuoteThreading.enabled or @thread.OP is @ - {replies} = Unread - {quotes, ID, fullID} = @ {posts} = g return if !(post = posts[fullID]) or post.isHidden # Filtered - uniq = {} + keys = [] len = "#{g.BOARD}".length + 1 - for quote in quotes - qid = quote - continue unless qid[len..] < ID - if qid of posts - uniq[qid[len..]] = true + for quote in quotes when quote[len..] < ID + keys.push quote if quote of posts - keys = Object.keys uniq return unless keys.length is 1 - @threaded = "#{g.BOARD}.#{keys[0]}" + @threaded = keys[0] @cb = QuoteThreading.nodeinsert nodeinsert: -> post = g.posts[@threaded] {posts} = Unread - @threaded - @cb - return false if @thread.OP is post if QuoteThreading.hasRun @@ -69,7 +59,7 @@ QuoteThreading = {bottom, top} = post.nodes.root.getBoundingClientRect() # Post is unread or is fully visible. - return false unless posts[post.ID] or ((bottom < height) and (top > 0)) + return false unless posts?[post.ID] or ((bottom < height) and (top > 0)) root = post.nodes.root unless $.hasClass root, 'threadOP' @@ -82,6 +72,8 @@ QuoteThreading = $.add threadContainer, @nodes.root + return true if not Conf['Unread Count'] or @ID < Unread.lastReadPost + posts.push @ unless posts[@ID] if posts[post.ID] @@ -91,12 +83,13 @@ QuoteThreading = posts.after posts[ID], @ else posts.prepend @ - + return true toggle: -> - Unread.posts = new RandomAccessList - Unread.ready() + if Conf['Unread Count'] + Unread.posts = new RandomAccessList + Unread.ready() thread = $ '.thread' replies = $$ '.thread > .replyContainer, .threadContainer > .replyContainer', thread @@ -120,7 +113,7 @@ QuoteThreading = containers = $$ '.threadContainer', thread $.rm container for container in containers $.rmClass post, 'threadOP' for post in $$ '.threadOP' - Unread.update true + Unread.read() if Conf['Unread Count'] kb: -> control = $.id 'threadingControl' From 5a080e7f6004db747c4e442a0201d5785d3abec6 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sun, 5 Jan 2014 17:47:40 -0700 Subject: [PATCH 10/20] D: --- builds/4chan-X.user.js | 58 +++++++++++++------------- builds/crx/script.js | 58 +++++++++++++------------- src/General/lib/randomaccesslist.class | 23 ++++------ src/Monitoring/Unread.coffee | 2 +- src/Quotelinks/QuoteThreading.coffee | 28 +++++++++---- 5 files changed, 89 insertions(+), 80 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 5d5a7ed69..2e3f25f91 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1480,21 +1480,19 @@ } this.rmi(item); next = root.next; - root.next = next.prev = item; + root.next = item; + item.prev = root; item.next = next; - return item.prev = root; + return next.prev = item; }; RandomAccessList.prototype.prepend = function(item) { - var ID, first; - ID = item.ID; - if (!this[ID]) { - this.push(item); - } + var first; first = this.first; - if (item === first) { + if (item === first || !this[item.ID]) { return; } + this.rmi(item); item.next = first; first.prev = item; this.first = item; @@ -1505,22 +1503,6 @@ return this.rm(this.first.ID); }; - RandomAccessList.prototype.splice = function(start, end) { - var cur, next; - if (!this[end]) { - return; - } - cur = start === 0 ? this.first : this[start]; - while (cur) { - next = cur.next; - this.rm(cur.ID); - if (!next || cur.ID === end) { - return; - } - cur = next; - } - }; - RandomAccessList.prototype.rm = function(ID) { var item; item = this[ID]; @@ -1554,7 +1536,7 @@ item = this.first; while (item) { if (item.ID > ID) { - prev = item.prev.prev; + prev = item.prev; break; } item = item.next; @@ -4979,12 +4961,21 @@ }, node: function() { var ID, fullID, keys, len, post, posts, quote, quotes, _i, _len; - if (this.isClone || !QuoteThreading.enabled || this.thread.OP === this) { + if (this.isClone || !QuoteThreading.enabled) { + return; + } + if (this.thread.OP === this) { + if (Conf['Unread Count']) { + Unread.posts.push(this); + } return; } quotes = this.quotes, ID = this.ID, fullID = this.fullID; posts = g.posts; if (!(post = posts[fullID]) || post.isHidden) { + if (Conf['Unread Count']) { + Unread.posts.push(this); + } return; } keys = []; @@ -4998,6 +4989,9 @@ } } if (keys.length !== 1) { + if (Conf['Unread Count']) { + Unread.posts.push(this); + } return; } this.threaded = keys[0]; @@ -5008,12 +5002,18 @@ post = g.posts[this.threaded]; posts = Unread.posts; if (this.thread.OP === post) { + if (Conf['Unread Count']) { + posts.push(this); + } return false; } if (QuoteThreading.hasRun) { height = doc.clientHeight; _ref = post.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; if (!((posts != null ? posts[post.ID] : void 0) || ((bottom < height) && (top > 0)))) { + if (Conf['Unread Count']) { + posts.push(this); + } return false; } } @@ -5026,9 +5026,11 @@ $.after(root, threadContainer); } else { threadContainer = root.nextSibling; + post = Get.postFromRoot($.x('child::div[contains(@class,"postContainer")][last()]', threadContainer)); } $.add(threadContainer, this.nodes.root); if (!Conf['Unread Count'] || this.ID < Unread.lastReadPost) { + this.prev = true; return true; } if (!posts[this.ID]) { @@ -5037,7 +5039,7 @@ if (posts[post.ID]) { posts.after(post, this); } else { - if ((ID = posts.closest(ID)) !== -1) { + if ((ID = posts.closest(post.ID)) !== -1) { posts.after(posts[ID], this); } else { posts.prepend(this); @@ -9699,11 +9701,11 @@ if (!Unread.posts[ID]) { return; } - Unread.posts.rm(ID); if (post === Unread.posts.first) { Unread.lastReadPost = ID; Unread.saveLastReadPost(); } + Unread.posts.rm(ID); if ((i = Unread.postsQuotingYou.indexOf(post)) !== -1) { Unread.postsQuotingYou.splice(i, 1); } diff --git a/builds/crx/script.js b/builds/crx/script.js index b18addccd..8279e6a60 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1486,21 +1486,19 @@ } this.rmi(item); next = root.next; - root.next = next.prev = item; + root.next = item; + item.prev = root; item.next = next; - return item.prev = root; + return next.prev = item; }; RandomAccessList.prototype.prepend = function(item) { - var ID, first; - ID = item.ID; - if (!this[ID]) { - this.push(item); - } + var first; first = this.first; - if (item === first) { + if (item === first || !this[item.ID]) { return; } + this.rmi(item); item.next = first; first.prev = item; this.first = item; @@ -1511,22 +1509,6 @@ return this.rm(this.first.ID); }; - RandomAccessList.prototype.splice = function(start, end) { - var cur, next; - if (!this[end]) { - return; - } - cur = start === 0 ? this.first : this[start]; - while (cur) { - next = cur.next; - this.rm(cur.ID); - if (!next || cur.ID === end) { - return; - } - cur = next; - } - }; - RandomAccessList.prototype.rm = function(ID) { var item; item = this[ID]; @@ -1560,7 +1542,7 @@ item = this.first; while (item) { if (item.ID > ID) { - prev = item.prev.prev; + prev = item.prev; break; } item = item.next; @@ -4982,12 +4964,21 @@ }, node: function() { var ID, fullID, keys, len, post, posts, quote, quotes, _i, _len; - if (this.isClone || !QuoteThreading.enabled || this.thread.OP === this) { + if (this.isClone || !QuoteThreading.enabled) { + return; + } + if (this.thread.OP === this) { + if (Conf['Unread Count']) { + Unread.posts.push(this); + } return; } quotes = this.quotes, ID = this.ID, fullID = this.fullID; posts = g.posts; if (!(post = posts[fullID]) || post.isHidden) { + if (Conf['Unread Count']) { + Unread.posts.push(this); + } return; } keys = []; @@ -5001,6 +4992,9 @@ } } if (keys.length !== 1) { + if (Conf['Unread Count']) { + Unread.posts.push(this); + } return; } this.threaded = keys[0]; @@ -5011,12 +5005,18 @@ post = g.posts[this.threaded]; posts = Unread.posts; if (this.thread.OP === post) { + if (Conf['Unread Count']) { + posts.push(this); + } return false; } if (QuoteThreading.hasRun) { height = doc.clientHeight; _ref = post.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; if (!((posts != null ? posts[post.ID] : void 0) || ((bottom < height) && (top > 0)))) { + if (Conf['Unread Count']) { + posts.push(this); + } return false; } } @@ -5029,9 +5029,11 @@ $.after(root, threadContainer); } else { threadContainer = root.nextSibling; + post = Get.postFromRoot($.x('child::div[contains(@class,"postContainer")][last()]', threadContainer)); } $.add(threadContainer, this.nodes.root); if (!Conf['Unread Count'] || this.ID < Unread.lastReadPost) { + this.prev = true; return true; } if (!posts[this.ID]) { @@ -5040,7 +5042,7 @@ if (posts[post.ID]) { posts.after(post, this); } else { - if ((ID = posts.closest(ID)) !== -1) { + if ((ID = posts.closest(post.ID)) !== -1) { posts.after(posts[ID], this); } else { posts.prepend(this); @@ -9682,11 +9684,11 @@ if (!Unread.posts[ID]) { return; } - Unread.posts.rm(ID); if (post === Unread.posts.first) { Unread.lastReadPost = ID; Unread.saveLastReadPost(); } + Unread.posts.rm(ID); if ((i = Unread.postsQuotingYou.indexOf(post)) !== -1) { Unread.postsQuotingYou.splice(i, 1); } diff --git a/src/General/lib/randomaccesslist.class b/src/General/lib/randomaccesslist.class index a2907aa01..a9955ff62 100644 --- a/src/General/lib/randomaccesslist.class +++ b/src/General/lib/randomaccesslist.class @@ -19,16 +19,16 @@ class RandomAccessList @rmi item {next} = root - root.next = next.prev = item - item.next = next + root.next = item item.prev = root + item.next = next + next.prev = item prepend: (item) -> - {ID} = item - @push item unless @[ID] {first} = @ - return if item is first - item.next = first + return if item is first or not @[item.ID] + @rmi item + item.next = first first.prev = item @first = item delete item.prev @@ -36,15 +36,6 @@ class RandomAccessList shift: -> @rm @first.ID - splice: (start, end) -> - return unless @[end] - cur = if start is 0 then @first else @[start] - while cur - {next} = cur - @rm cur.ID - return if not next or cur.ID is end - cur = next - rm: (ID) -> item = @[ID] return unless item @@ -69,7 +60,7 @@ class RandomAccessList item = @first while item if item.ID > ID - {prev} = item.prev + {prev} = item break item = item.next return (if prev then prev.ID else -1) \ No newline at end of file diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee index 52789e67d..146578b67 100755 --- a/src/Monitoring/Unread.coffee +++ b/src/Monitoring/Unread.coffee @@ -122,10 +122,10 @@ Unread = readSinglePost: (post) -> {ID} = post return unless Unread.posts[ID] - Unread.posts.rm ID if post is Unread.posts.first Unread.lastReadPost = ID Unread.saveLastReadPost() + Unread.posts.rm ID if (i = Unread.postsQuotingYou.indexOf post) isnt -1 Unread.postsQuotingYou.splice i, 1 Unread.update() diff --git a/src/Quotelinks/QuoteThreading.coffee b/src/Quotelinks/QuoteThreading.coffee index eacb9b753..6b2c5bbcd 100755 --- a/src/Quotelinks/QuoteThreading.coffee +++ b/src/Quotelinks/QuoteThreading.coffee @@ -32,18 +32,25 @@ QuoteThreading = QuoteThreading.hasRun = true node: -> - return if @isClone or not QuoteThreading.enabled or @thread.OP is @ + return if @isClone or not QuoteThreading.enabled + if @thread.OP is @ + Unread.posts.push @ if Conf['Unread Count'] + return {quotes, ID, fullID} = @ {posts} = g - return if !(post = posts[fullID]) or post.isHidden # Filtered + if !(post = posts[fullID]) or post.isHidden # Filtered + Unread.posts.push @ if Conf['Unread Count'] + return keys = [] len = "#{g.BOARD}".length + 1 for quote in quotes when quote[len..] < ID keys.push quote if quote of posts - return unless keys.length is 1 + unless keys.length is 1 + Unread.posts.push @ if Conf['Unread Count'] + return @threaded = keys[0] @cb = QuoteThreading.nodeinsert @@ -52,14 +59,18 @@ QuoteThreading = post = g.posts[@threaded] {posts} = Unread - return false if @thread.OP is post + if @thread.OP is post + posts.push @ if Conf['Unread Count'] + return false if QuoteThreading.hasRun height = doc.clientHeight {bottom, top} = post.nodes.root.getBoundingClientRect() # Post is unread or is fully visible. - return false unless posts?[post.ID] or ((bottom < height) and (top > 0)) + unless posts?[post.ID] or ((bottom < height) and (top > 0)) + posts.push @ if Conf['Unread Count'] + return false root = post.nodes.root unless $.hasClass root, 'threadOP' @@ -69,17 +80,20 @@ QuoteThreading = $.after root, threadContainer else threadContainer = root.nextSibling + post = Get.postFromRoot $.x 'child::div[contains(@class,"postContainer")][last()]', threadContainer $.add threadContainer, @nodes.root - return true if not Conf['Unread Count'] or @ID < Unread.lastReadPost + if not Conf['Unread Count'] or @ID < Unread.lastReadPost + @prev = true # Force Unread Count to ignore this post + return true posts.push @ unless posts[@ID] if posts[post.ID] posts.after post, @ else - if (ID = posts.closest ID) isnt -1 + if (ID = posts.closest post.ID) isnt -1 posts.after posts[ID], @ else posts.prepend @ From 1c5c542ca1fb9f9ea726fdb81615c06e2cca8a9a Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Mon, 6 Jan 2014 08:45:17 -0700 Subject: [PATCH 11/20] And that should fix everything. Woo. --- LICENSE | 2 +- builds/4chan-X.user.js | 17 ++++++++++------- builds/crx/script.js | 17 ++++++++++------- src/General/lib/randomaccesslist.class | 1 + src/Quotelinks/QuoteThreading.coffee | 13 +++++++------ 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/LICENSE b/LICENSE index f67d12a1d..f27731086 100755 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ /* -* 4chan X - Version 1.2.44 - 2014-01-05 +* 4chan X - Version 1.2.44 - 2014-01-06 * * Licensed under the MIT license. * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 2e3f25f91..bc7d7c9ff 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -22,7 +22,7 @@ // ==/UserScript== /* -* 4chan X - Version 1.2.44 - 2014-01-05 +* 4chan X - Version 1.2.44 - 2014-01-06 * * Licensed under the MIT license. * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE @@ -1466,6 +1466,9 @@ RandomAccessList.prototype.push = function(item) { var ID, last; ID = item.ID; + if (this[ID]) { + return; + } last = this.last; item.prev = last; this[ID] = item; @@ -5026,7 +5029,7 @@ $.after(root, threadContainer); } else { threadContainer = root.nextSibling; - post = Get.postFromRoot($.x('child::div[contains(@class,"postContainer")][last()]', threadContainer)); + post = Get.postFromRoot($.x('descendant::div[contains(@class,"postContainer")][last()]', threadContainer)); } $.add(threadContainer, this.nodes.root); if (!Conf['Unread Count'] || this.ID < Unread.lastReadPost) { @@ -5038,12 +5041,12 @@ } if (posts[post.ID]) { posts.after(post, this); + return true; + } + if ((ID = posts.closest(post.ID)) !== -1) { + posts.after(posts[ID], this); } else { - if ((ID = posts.closest(post.ID)) !== -1) { - posts.after(posts[ID], this); - } else { - posts.prepend(this); - } + posts.prepend(this); } return true; }, diff --git a/builds/crx/script.js b/builds/crx/script.js index 8279e6a60..ccd69b978 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript /* -* 4chan X - Version 1.2.44 - 2014-01-05 +* 4chan X - Version 1.2.44 - 2014-01-06 * * Licensed under the MIT license. * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE @@ -1472,6 +1472,9 @@ RandomAccessList.prototype.push = function(item) { var ID, last; ID = item.ID; + if (this[ID]) { + return; + } last = this.last; item.prev = last; this[ID] = item; @@ -5029,7 +5032,7 @@ $.after(root, threadContainer); } else { threadContainer = root.nextSibling; - post = Get.postFromRoot($.x('child::div[contains(@class,"postContainer")][last()]', threadContainer)); + post = Get.postFromRoot($.x('descendant::div[contains(@class,"postContainer")][last()]', threadContainer)); } $.add(threadContainer, this.nodes.root); if (!Conf['Unread Count'] || this.ID < Unread.lastReadPost) { @@ -5041,12 +5044,12 @@ } if (posts[post.ID]) { posts.after(post, this); + return true; + } + if ((ID = posts.closest(post.ID)) !== -1) { + posts.after(posts[ID], this); } else { - if ((ID = posts.closest(post.ID)) !== -1) { - posts.after(posts[ID], this); - } else { - posts.prepend(this); - } + posts.prepend(this); } return true; }, diff --git a/src/General/lib/randomaccesslist.class b/src/General/lib/randomaccesslist.class index a9955ff62..98c08a670 100644 --- a/src/General/lib/randomaccesslist.class +++ b/src/General/lib/randomaccesslist.class @@ -4,6 +4,7 @@ class RandomAccessList push: (item) -> {ID} = item + return if @[ID] {last} = @ item.prev = last @[ID] = item diff --git a/src/Quotelinks/QuoteThreading.coffee b/src/Quotelinks/QuoteThreading.coffee index 6b2c5bbcd..2cac9bbb0 100755 --- a/src/Quotelinks/QuoteThreading.coffee +++ b/src/Quotelinks/QuoteThreading.coffee @@ -72,7 +72,7 @@ QuoteThreading = posts.push @ if Conf['Unread Count'] return false - root = post.nodes.root + {root} = post.nodes unless $.hasClass root, 'threadOP' $.addClass root, 'threadOP' threadContainer = $.el 'div', @@ -80,7 +80,7 @@ QuoteThreading = $.after root, threadContainer else threadContainer = root.nextSibling - post = Get.postFromRoot $.x 'child::div[contains(@class,"postContainer")][last()]', threadContainer + post = Get.postFromRoot $.x 'descendant::div[contains(@class,"postContainer")][last()]', threadContainer $.add threadContainer, @nodes.root @@ -92,11 +92,12 @@ QuoteThreading = if posts[post.ID] posts.after post, @ + return true + + if (ID = posts.closest post.ID) isnt -1 + posts.after posts[ID], @ else - if (ID = posts.closest post.ID) isnt -1 - posts.after posts[ID], @ - else - posts.prepend @ + posts.prepend @ return true From b9f2702daf6eba26de94d9dd6c7fc7fd18dd9eaa Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Mon, 6 Jan 2014 08:55:26 -0700 Subject: [PATCH 12/20] Consolidate and cleanup --- builds/4chan-X.user.js | 21 ++++----------------- builds/crx/script.js | 21 ++++----------------- src/Quotelinks/QuoteThreading.coffee | 24 +++++++----------------- 3 files changed, 15 insertions(+), 51 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index bc7d7c9ff..130f342a8 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -4967,18 +4967,15 @@ if (this.isClone || !QuoteThreading.enabled) { return; } + if (Conf['Unread Count']) { + Unread.posts.push(this); + } if (this.thread.OP === this) { - if (Conf['Unread Count']) { - Unread.posts.push(this); - } return; } quotes = this.quotes, ID = this.ID, fullID = this.fullID; posts = g.posts; if (!(post = posts[fullID]) || post.isHidden) { - if (Conf['Unread Count']) { - Unread.posts.push(this); - } return; } keys = []; @@ -5005,18 +5002,12 @@ post = g.posts[this.threaded]; posts = Unread.posts; if (this.thread.OP === post) { - if (Conf['Unread Count']) { - posts.push(this); - } return false; } if (QuoteThreading.hasRun) { height = doc.clientHeight; _ref = post.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; if (!((posts != null ? posts[post.ID] : void 0) || ((bottom < height) && (top > 0)))) { - if (Conf['Unread Count']) { - posts.push(this); - } return false; } } @@ -5032,13 +5023,9 @@ post = Get.postFromRoot($.x('descendant::div[contains(@class,"postContainer")][last()]', threadContainer)); } $.add(threadContainer, this.nodes.root); - if (!Conf['Unread Count'] || this.ID < Unread.lastReadPost) { - this.prev = true; + if (!Conf['Unread Count']) { return true; } - if (!posts[this.ID]) { - posts.push(this); - } if (posts[post.ID]) { posts.after(post, this); return true; diff --git a/builds/crx/script.js b/builds/crx/script.js index ccd69b978..270b77c00 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -4970,18 +4970,15 @@ if (this.isClone || !QuoteThreading.enabled) { return; } + if (Conf['Unread Count']) { + Unread.posts.push(this); + } if (this.thread.OP === this) { - if (Conf['Unread Count']) { - Unread.posts.push(this); - } return; } quotes = this.quotes, ID = this.ID, fullID = this.fullID; posts = g.posts; if (!(post = posts[fullID]) || post.isHidden) { - if (Conf['Unread Count']) { - Unread.posts.push(this); - } return; } keys = []; @@ -5008,18 +5005,12 @@ post = g.posts[this.threaded]; posts = Unread.posts; if (this.thread.OP === post) { - if (Conf['Unread Count']) { - posts.push(this); - } return false; } if (QuoteThreading.hasRun) { height = doc.clientHeight; _ref = post.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; if (!((posts != null ? posts[post.ID] : void 0) || ((bottom < height) && (top > 0)))) { - if (Conf['Unread Count']) { - posts.push(this); - } return false; } } @@ -5035,13 +5026,9 @@ post = Get.postFromRoot($.x('descendant::div[contains(@class,"postContainer")][last()]', threadContainer)); } $.add(threadContainer, this.nodes.root); - if (!Conf['Unread Count'] || this.ID < Unread.lastReadPost) { - this.prev = true; + if (!Conf['Unread Count']) { return true; } - if (!posts[this.ID]) { - posts.push(this); - } if (posts[post.ID]) { posts.after(post, this); return true; diff --git a/src/Quotelinks/QuoteThreading.coffee b/src/Quotelinks/QuoteThreading.coffee index 2cac9bbb0..1d25944d5 100755 --- a/src/Quotelinks/QuoteThreading.coffee +++ b/src/Quotelinks/QuoteThreading.coffee @@ -33,15 +33,13 @@ QuoteThreading = node: -> return if @isClone or not QuoteThreading.enabled - if @thread.OP is @ - Unread.posts.push @ if Conf['Unread Count'] - return + Unread.posts.push @ if Conf['Unread Count'] + + return if @thread.OP is @ {quotes, ID, fullID} = @ {posts} = g - if !(post = posts[fullID]) or post.isHidden # Filtered - Unread.posts.push @ if Conf['Unread Count'] - return + return if !(post = posts[fullID]) or post.isHidden # Filtered keys = [] len = "#{g.BOARD}".length + 1 @@ -59,18 +57,14 @@ QuoteThreading = post = g.posts[@threaded] {posts} = Unread - if @thread.OP is post - posts.push @ if Conf['Unread Count'] - return false + return false if @thread.OP is post if QuoteThreading.hasRun height = doc.clientHeight {bottom, top} = post.nodes.root.getBoundingClientRect() # Post is unread or is fully visible. - unless posts?[post.ID] or ((bottom < height) and (top > 0)) - posts.push @ if Conf['Unread Count'] - return false + return false unless posts?[post.ID] or ((bottom < height) and (top > 0)) {root} = post.nodes unless $.hasClass root, 'threadOP' @@ -84,11 +78,7 @@ QuoteThreading = $.add threadContainer, @nodes.root - if not Conf['Unread Count'] or @ID < Unread.lastReadPost - @prev = true # Force Unread Count to ignore this post - return true - - posts.push @ unless posts[@ID] + return true unless Conf['Unread Count'] if posts[post.ID] posts.after post, @ From 77d97277c95bc5204457f0f2772237a4c8bce709 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Mon, 6 Jan 2014 09:04:45 -0700 Subject: [PATCH 13/20] Minor optimizations --- builds/4chan-X.user.js | 30 ++++++++++------------------ builds/crx/script.js | 30 ++++++++++------------------ src/Quotelinks/QuoteThreading.coffee | 20 +++++++------------ 3 files changed, 29 insertions(+), 51 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 130f342a8..d1af9a85a 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -4936,14 +4936,14 @@ innerHTML: '' }); input = $('input', this.controls); - $.on(input, 'change', QuoteThreading.toggle); + $.on(input, 'change', this.toggle); $.event('AddMenuEntry', { type: 'header', el: this.controls, order: 98 }); if (!Conf['Unread Count']) { - $.on(d, '4chanXInitFinished', QuoteThreading.setup); + $.on(d, '4chanXInitFinished', this.setup); } return Post.callbacks.push({ name: 'Quote Threading', @@ -4963,35 +4963,27 @@ return QuoteThreading.hasRun = true; }, node: function() { - var ID, fullID, keys, len, post, posts, quote, quotes, _i, _len; + var keys, len, post, posts, quote, _i, _len, _ref; + posts = g.posts; if (this.isClone || !QuoteThreading.enabled) { return; } if (Conf['Unread Count']) { Unread.posts.push(this); } - if (this.thread.OP === this) { - return; - } - quotes = this.quotes, ID = this.ID, fullID = this.fullID; - posts = g.posts; - if (!(post = posts[fullID]) || post.isHidden) { + if (this.thread.OP === this || !(post = posts[this.fullID]) || post.isHidden) { return; } keys = []; - len = ("" + g.BOARD).length + 1; - for (_i = 0, _len = quotes.length; _i < _len; _i++) { - quote = quotes[_i]; - if (quote.slice(len) < ID) { - if (quote in posts) { - keys.push(quote); - } + len = g.BOARD.ID.length + 1; + _ref = this.quotes; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + quote = _ref[_i]; + if ((quote.slice(len) < this.ID) && quote in posts) { + keys.push(quote); } } if (keys.length !== 1) { - if (Conf['Unread Count']) { - Unread.posts.push(this); - } return; } this.threaded = keys[0]; diff --git a/builds/crx/script.js b/builds/crx/script.js index 270b77c00..41ea48332 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -4939,14 +4939,14 @@ innerHTML: '' }); input = $('input', this.controls); - $.on(input, 'change', QuoteThreading.toggle); + $.on(input, 'change', this.toggle); $.event('AddMenuEntry', { type: 'header', el: this.controls, order: 98 }); if (!Conf['Unread Count']) { - $.on(d, '4chanXInitFinished', QuoteThreading.setup); + $.on(d, '4chanXInitFinished', this.setup); } return Post.callbacks.push({ name: 'Quote Threading', @@ -4966,35 +4966,27 @@ return QuoteThreading.hasRun = true; }, node: function() { - var ID, fullID, keys, len, post, posts, quote, quotes, _i, _len; + var keys, len, post, posts, quote, _i, _len, _ref; + posts = g.posts; if (this.isClone || !QuoteThreading.enabled) { return; } if (Conf['Unread Count']) { Unread.posts.push(this); } - if (this.thread.OP === this) { - return; - } - quotes = this.quotes, ID = this.ID, fullID = this.fullID; - posts = g.posts; - if (!(post = posts[fullID]) || post.isHidden) { + if (this.thread.OP === this || !(post = posts[this.fullID]) || post.isHidden) { return; } keys = []; - len = ("" + g.BOARD).length + 1; - for (_i = 0, _len = quotes.length; _i < _len; _i++) { - quote = quotes[_i]; - if (quote.slice(len) < ID) { - if (quote in posts) { - keys.push(quote); - } + len = g.BOARD.ID.length + 1; + _ref = this.quotes; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + quote = _ref[_i]; + if ((quote.slice(len) < this.ID) && quote in posts) { + keys.push(quote); } } if (keys.length !== 1) { - if (Conf['Unread Count']) { - Unread.posts.push(this); - } return; } this.threaded = keys[0]; diff --git a/src/Quotelinks/QuoteThreading.coffee b/src/Quotelinks/QuoteThreading.coffee index 1d25944d5..d5901b402 100755 --- a/src/Quotelinks/QuoteThreading.coffee +++ b/src/Quotelinks/QuoteThreading.coffee @@ -11,14 +11,14 @@ QuoteThreading = innerHTML: '' input = $ 'input', @controls - $.on input, 'change', QuoteThreading.toggle + $.on input, 'change', @toggle $.event 'AddMenuEntry', type: 'header' el: @controls order: 98 - $.on d, '4chanXInitFinished', QuoteThreading.setup unless Conf['Unread Count'] + $.on d, '4chanXInitFinished', @setup unless Conf['Unread Count'] Post.callbacks.push name: 'Quote Threading' @@ -32,23 +32,17 @@ QuoteThreading = QuoteThreading.hasRun = true node: -> + {posts} = g return if @isClone or not QuoteThreading.enabled Unread.posts.push @ if Conf['Unread Count'] - return if @thread.OP is @ - - {quotes, ID, fullID} = @ - {posts} = g - return if !(post = posts[fullID]) or post.isHidden # Filtered + return if @thread.OP is @ or !(post = posts[@fullID]) or post.isHidden # Filtered keys = [] - len = "#{g.BOARD}".length + 1 - for quote in quotes when quote[len..] < ID - keys.push quote if quote of posts + len = g.BOARD.ID.length + 1 + keys.push quote for quote in @quotes when (quote[len..] < @ID) and quote of posts - unless keys.length is 1 - Unread.posts.push @ if Conf['Unread Count'] - return + return unless keys.length is 1 @threaded = keys[0] @cb = QuoteThreading.nodeinsert From a569565cfff1225d62b6adb76ed0e4a07016a47f Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Mon, 6 Jan 2014 09:08:44 -0700 Subject: [PATCH 14/20] Remove debug code --- builds/4chan-X.user.js | 6 +----- builds/crx/script.js | 6 +----- src/Monitoring/Unread.coffee | 8 ++------ 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index d1af9a85a..dd6cac59e 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -9715,14 +9715,10 @@ break; } ID = post.ID; + posts.rm(ID); if (Conf['Mark Quotes of You'] && post.info.yours) { QuoteYou.lastRead = post.nodes.root; } - posts.rm(ID); - if (post === posts.first) { - c.log(posts); - break; - } } if (!ID) { return; diff --git a/builds/crx/script.js b/builds/crx/script.js index 41ea48332..f7758362c 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -9698,14 +9698,10 @@ break; } ID = post.ID; + posts.rm(ID); if (Conf['Mark Quotes of You'] && post.info.yours) { QuoteYou.lastRead = post.nodes.root; } - posts.rm(ID); - if (post === posts.first) { - c.log(posts); - break; - } } if (!ID) { return; diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee index 146578b67..1eeeebb0c 100755 --- a/src/Monitoring/Unread.coffee +++ b/src/Monitoring/Unread.coffee @@ -142,15 +142,11 @@ Unread = {posts} = Unread while post = posts.first break unless Header.getBottomOf(post.nodes.root) > -1 # post is not completely read - {ID} = post - if Conf['Mark Quotes of You'] and post.info.yours - QuoteYou.lastRead = post.nodes.root posts.rm ID - if post is posts.first - c.log posts - break + if Conf['Mark Quotes of You'] and post.info.yours + QuoteYou.lastRead = post.nodes.root return unless ID From 8b6ea725e4516294867572f1e9a6e7c0ad28cd0a Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Mon, 6 Jan 2014 09:15:20 -0700 Subject: [PATCH 15/20] post.cb.call(post) > post.cb() heh, comprehension fail. this was this anyways. --- builds/4chan-X.user.js | 6 +++--- builds/crx/script.js | 6 +++--- src/Monitoring/ThreadUpdater.coffee | 2 +- src/Quotelinks/QuoteThreading.coffee | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index dd6cac59e..5b818d23d 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -5044,11 +5044,11 @@ reply = replies[_i]; node = Get.postFromRoot(reply); if (node.cb) { - node.cb.call(node); + node.cb(); } else { QuoteThreading.node.call(node); if (node.cb) { - node.cb.call(node); + node.cb(); } } } @@ -8972,7 +8972,7 @@ } root = post.nodes.root; if (post.cb) { - if (!post.cb.call(post)) { + if (!post.cb()) { $.add(ThreadUpdater.root, root); } } else { diff --git a/builds/crx/script.js b/builds/crx/script.js index f7758362c..44692e17a 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -5047,11 +5047,11 @@ reply = replies[_i]; node = Get.postFromRoot(reply); if (node.cb) { - node.cb.call(node); + node.cb(); } else { QuoteThreading.node.call(node); if (node.cb) { - node.cb.call(node); + node.cb(); } } } @@ -8955,7 +8955,7 @@ } root = post.nodes.root; if (post.cb) { - if (!post.cb.call(post)) { + if (!post.cb()) { $.add(ThreadUpdater.root, root); } } else { diff --git a/src/Monitoring/ThreadUpdater.coffee b/src/Monitoring/ThreadUpdater.coffee index c0f801949..1a7be4a60 100755 --- a/src/Monitoring/ThreadUpdater.coffee +++ b/src/Monitoring/ThreadUpdater.coffee @@ -295,7 +295,7 @@ ThreadUpdater = continue unless posts.hasOwnProperty key root = post.nodes.root if post.cb - unless post.cb.call post + unless post.cb() $.add ThreadUpdater.root, root else $.add ThreadUpdater.root, root diff --git a/src/Quotelinks/QuoteThreading.coffee b/src/Quotelinks/QuoteThreading.coffee index d5901b402..94105c9b5 100755 --- a/src/Quotelinks/QuoteThreading.coffee +++ b/src/Quotelinks/QuoteThreading.coffee @@ -98,10 +98,10 @@ QuoteThreading = for reply in replies node = Get.postFromRoot reply if node.cb - node.cb.call node + node.cb() else QuoteThreading.node.call node - node.cb.call node if node.cb + node.cb() if node.cb QuoteThreading.hasRun = true else replies.sort (a, b) -> From 3a776fb5e1b717037ae08a58ad2f805803a10fb8 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Mon, 6 Jan 2014 09:17:54 -0700 Subject: [PATCH 16/20] Missed one. --- builds/4chan-X.user.js | 2 +- builds/crx/script.js | 2 +- src/Quotelinks/QuoteThreading.coffee | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 5b818d23d..31c09ba8c 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -4957,7 +4957,7 @@ for (ID in _ref) { post = _ref[ID]; if (post.cb) { - post.cb.call(post); + post.cb(); } } return QuoteThreading.hasRun = true; diff --git a/builds/crx/script.js b/builds/crx/script.js index 44692e17a..96890233e 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -4960,7 +4960,7 @@ for (ID in _ref) { post = _ref[ID]; if (post.cb) { - post.cb.call(post); + post.cb(); } } return QuoteThreading.hasRun = true; diff --git a/src/Quotelinks/QuoteThreading.coffee b/src/Quotelinks/QuoteThreading.coffee index 94105c9b5..575a7c5f8 100755 --- a/src/Quotelinks/QuoteThreading.coffee +++ b/src/Quotelinks/QuoteThreading.coffee @@ -27,7 +27,7 @@ QuoteThreading = setup: -> $.off d, '4chanXInitFinished', QuoteThreading.setup - post.cb.call post for ID, post of g.posts when post.cb + post.cb() for ID, post of g.posts when post.cb QuoteThreading.hasRun = true From a7ce01cb61a38580eb69e1622ae143386a12172e Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Mon, 6 Jan 2014 09:37:23 -0700 Subject: [PATCH 17/20] Fix toggle --- builds/4chan-X.user.js | 21 ++++++--------------- builds/crx/script.js | 21 ++++++--------------- src/Quotelinks/QuoteThreading.coffee | 22 +++++++++------------- 3 files changed, 21 insertions(+), 43 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 31c09ba8c..464001094 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -5030,35 +5030,26 @@ return true; }, toggle: function() { - var container, containers, node, post, replies, reply, thread, _i, _j, _k, _len, _len1, _len2, _ref; + var container, containers, post, replies, reply, thread, _i, _j, _k, _len, _len1, _len2, _ref; if (Conf['Unread Count']) { Unread.posts = new RandomAccessList; Unread.ready(); } thread = $('.thread'); replies = $$('.thread > .replyContainer, .threadContainer > .replyContainer', thread); - QuoteThreading.enabled = this.checked; - if (this.checked) { + if (QuoteThreading.enabled = this.checked) { QuoteThreading.hasRun = false; for (_i = 0, _len = replies.length; _i < _len; _i++) { reply = replies[_i]; - node = Get.postFromRoot(reply); - if (node.cb) { - node.cb(); - } else { - QuoteThreading.node.call(node); - if (node.cb) { - node.cb(); - } + post = Get.postFromRoot(reply); + if (post.cb) { + post.cb(); } } QuoteThreading.hasRun = true; } else { replies.sort(function(a, b) { - var aID, bID; - aID = Number(a.id.slice(2)); - bID = Number(b.id.slice(2)); - return aID - bID; + return Number(a.id.slice(2)) - Number(b.id.slice(2)); }); $.add(thread, replies); containers = $$('.threadContainer', thread); diff --git a/builds/crx/script.js b/builds/crx/script.js index 96890233e..c5ab8c091 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -5033,35 +5033,26 @@ return true; }, toggle: function() { - var container, containers, node, post, replies, reply, thread, _i, _j, _k, _len, _len1, _len2, _ref; + var container, containers, post, replies, reply, thread, _i, _j, _k, _len, _len1, _len2, _ref; if (Conf['Unread Count']) { Unread.posts = new RandomAccessList; Unread.ready(); } thread = $('.thread'); replies = $$('.thread > .replyContainer, .threadContainer > .replyContainer', thread); - QuoteThreading.enabled = this.checked; - if (this.checked) { + if (QuoteThreading.enabled = this.checked) { QuoteThreading.hasRun = false; for (_i = 0, _len = replies.length; _i < _len; _i++) { reply = replies[_i]; - node = Get.postFromRoot(reply); - if (node.cb) { - node.cb(); - } else { - QuoteThreading.node.call(node); - if (node.cb) { - node.cb(); - } + post = Get.postFromRoot(reply); + if (post.cb) { + post.cb(); } } QuoteThreading.hasRun = true; } else { replies.sort(function(a, b) { - var aID, bID; - aID = Number(a.id.slice(2)); - bID = Number(b.id.slice(2)); - return aID - bID; + return Number(a.id.slice(2)) - Number(b.id.slice(2)); }); $.add(thread, replies); containers = $$('.threadContainer', thread); diff --git a/src/Quotelinks/QuoteThreading.coffee b/src/Quotelinks/QuoteThreading.coffee index 575a7c5f8..ddc975dd0 100755 --- a/src/Quotelinks/QuoteThreading.coffee +++ b/src/Quotelinks/QuoteThreading.coffee @@ -28,7 +28,6 @@ QuoteThreading = $.off d, '4chanXInitFinished', QuoteThreading.setup post.cb() for ID, post of g.posts when post.cb - QuoteThreading.hasRun = true node: -> @@ -92,22 +91,19 @@ QuoteThreading = thread = $ '.thread' replies = $$ '.thread > .replyContainer, .threadContainer > .replyContainer', thread - QuoteThreading.enabled = @checked - if @checked + + if QuoteThreading.enabled = @checked QuoteThreading.hasRun = false for reply in replies - node = Get.postFromRoot reply - if node.cb - node.cb() - else - QuoteThreading.node.call node - node.cb() if node.cb + post = Get.postFromRoot reply + # QuoteThreading calculates whether or not posts should be threaded based on content + # and then threads them based on thread context, so regardless of whether or not it + # actually threads them all eligible posts WILL have a cb. Magic. + post.cb() if post.cb QuoteThreading.hasRun = true + else - replies.sort (a, b) -> - aID = Number a.id[2..] - bID = Number b.id[2..] - aID - bID + replies.sort (a, b) -> Number(a.id[2..]) - Number(b.id[2..]) $.add thread, replies containers = $$ '.threadContainer', thread $.rm container for container in containers From f782b0d3c019c5078d9185ab13bd2d89d962e494 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Mon, 6 Jan 2014 09:42:15 -0700 Subject: [PATCH 18/20] Throw a debounce back in for performance A scroll-event-based function every tenth of a second is better than whatever arbitrary timer scroll events can have. --- builds/4chan-X.user.js | 4 ++-- builds/crx/script.js | 4 ++-- src/Monitoring/Unread.coffee | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 464001094..f7a529dfe 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -9694,7 +9694,7 @@ } return arr.splice(0, i); }, - read: function(e) { + read: $.debounce(100, function(e) { var ID, height, post, posts; if (d.hidden || !Unread.posts.length) { return; @@ -9722,7 +9722,7 @@ if (e) { return Unread.update(); } - }, + }), saveLastReadPost: $.debounce(2 * $.SECOND, function() { if (Unread.thread.isDead) { return; diff --git a/builds/crx/script.js b/builds/crx/script.js index c5ab8c091..a8870f676 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -9677,7 +9677,7 @@ } return arr.splice(0, i); }, - read: function(e) { + read: $.debounce(100, function(e) { var ID, height, post, posts; if (d.hidden || !Unread.posts.length) { return; @@ -9705,7 +9705,7 @@ if (e) { return Unread.update(); } - }, + }), saveLastReadPost: $.debounce(2 * $.SECOND, function() { if (Unread.thread.isDead) { return; diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee index 1eeeebb0c..1632c3347 100755 --- a/src/Monitoring/Unread.coffee +++ b/src/Monitoring/Unread.coffee @@ -135,7 +135,7 @@ Unread = break if post.ID > Unread.lastReadPost arr.splice 0, i - read: (e) -> + read: $.debounce 100, (e) -> return if d.hidden or !Unread.posts.length height = doc.clientHeight From b1ca5739351daffea3a2819ef2c9157b0a75f0b2 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Mon, 6 Jan 2014 09:50:04 -0700 Subject: [PATCH 19/20] Just a couple silly things --- builds/4chan-X.user.js | 6 +----- builds/crx/script.js | 6 +----- src/Monitoring/Unread.coffee | 4 ++-- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index f7a529dfe..e656d3dc9 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -9511,11 +9511,7 @@ threadID: thread.ID, postID: ID }; - if (QR.db.get(data)) { - return true; - } else { - return false; - } + return (QR.db.get(data) ? true : false); } : function() { return false; }; diff --git a/builds/crx/script.js b/builds/crx/script.js index a8870f676..2c30a7514 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -9494,11 +9494,7 @@ threadID: thread.ID, postID: ID }; - if (QR.db.get(data)) { - return true; - } else { - return false; - } + return (QR.db.get(data) ? true : false); } : function() { return false; }; diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee index 1632c3347..85bdf3903 100755 --- a/src/Monitoring/Unread.coffee +++ b/src/Monitoring/Unread.coffee @@ -14,7 +14,7 @@ Unread = boardID: board.ID threadID: thread.ID postID: ID - return if QR.db.get data then true else false + return (if QR.db.get data then true else false) else -> return false @@ -158,7 +158,7 @@ Unread = saveLastReadPost: $.debounce 2 * $.SECOND, -> return if Unread.thread.isDead Unread.db.set - boardID: Unread.thread.board.ID + boardID: Unread.thread.board.ID threadID: Unread.thread.ID val: Unread.lastReadPost From 6d858de604d126cd4f0b9edc4ad54652384b563d Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Mon, 6 Jan 2014 09:55:16 -0700 Subject: [PATCH 20/20] Why not? --- builds/4chan-X.user.js | 11 +++++------ builds/crx/script.js | 11 +++++------ src/Monitoring/Unread.coffee | 8 ++++---- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index e656d3dc9..48ea00c3a 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -9503,13 +9503,12 @@ }); this.posts = new RandomAccessList; this.postsQuotingYou = []; - this.qr = QR.db ? function(_arg) { - var ID, board, data, thread; - board = _arg.board, thread = _arg.thread, ID = _arg.ID; + this.qr = QR.db ? function(post) { + var data; data = { - boardID: board.ID, - threadID: thread.ID, - postID: ID + boardID: post.board.ID, + threadID: post.thread.ID, + postID: post.ID }; return (QR.db.get(data) ? true : false); } : function() { diff --git a/builds/crx/script.js b/builds/crx/script.js index 2c30a7514..fb2328d4a 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -9486,13 +9486,12 @@ }); this.posts = new RandomAccessList; this.postsQuotingYou = []; - this.qr = QR.db ? function(_arg) { - var ID, board, data, thread; - board = _arg.board, thread = _arg.thread, ID = _arg.ID; + this.qr = QR.db ? function(post) { + var data; data = { - boardID: board.ID, - threadID: thread.ID, - postID: ID + boardID: post.board.ID, + threadID: post.thread.ID, + postID: post.ID }; return (QR.db.get(data) ? true : false); } : function() { diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee index 85bdf3903..02c50faf5 100755 --- a/src/Monitoring/Unread.coffee +++ b/src/Monitoring/Unread.coffee @@ -9,11 +9,11 @@ Unread = @postsQuotingYou = [] @qr = if QR.db - ({board, thread, ID}) -> + (post) -> data = - boardID: board.ID - threadID: thread.ID - postID: ID + boardID: post.board.ID + threadID: post.thread.ID + postID: post.ID return (if QR.db.get data then true else false) else -> return false