diff --git a/builds/appchan-x.user.js b/builds/appchan-x.user.js index b01f9ea5d..ed20b4e16 100644 --- a/builds/appchan-x.user.js +++ b/builds/appchan-x.user.js @@ -3274,6 +3274,7 @@ this.thread.OP = this; this.thread.isSticky = !!$('.stickyIcon', info); this.thread.isClosed = !!$('.closedIcon', info); + root.parentElement.dataset.fullID = this.fullID; } this.info = {}; if (subject = $('.subject', info)) { @@ -4951,10 +4952,14 @@ return $.event('change', null, Index.selectMode); }, cycleSortType: function() { - var i, type, types, _i, _len; - types = __slice.call(Index.selectSort.options).filter(function(option) { - return !option.disabled; - }); + var i, option, type, types, _i, _len; + types = []; + i = 0; + while (option = Index.selectSort.options[i++]) { + if (!option.disabled) { + types.push(option); + } + } for (i = _i = 0, _len = types.length; _i < _len; i = ++_i) { type = types[i]; if (type.selected) { @@ -4965,13 +4970,15 @@ return $.event('change', null, Index.selectSort); }, catalogSwitch: function() { - var hash; - if (!Conf['JSON Navigation']) { - return; - } - $.set('Index Mode', 'catalog'); - hash = window.location.hash; - return window.location = './' + hash; + return $.get('JSON Navigation', true, function(items) { + var hash; + if (!items['JSON Navigation']) { + return; + } + $.set('Index Mode', 'catalog'); + hash = window.location.hash; + return window.location = './' + hash; + }); }, searchTest: function() { var hash, match; @@ -5061,20 +5068,18 @@ return Index.buildIndex(); }, target: function() { - var thread, threadID, thumb, _ref; - _ref = g.BOARD.threads; - for (threadID in _ref) { - thread = _ref[threadID]; + return g.BOARD.threads.forEach(function(thread) { + var thumb; if (!thread.catalogView) { - continue; + return; } thumb = thread.catalogView.nodes.thumb; if (Conf['Open threads in a new tab']) { - thumb.target = '_blank'; + return thumb.target = '_blank'; } else { - thumb.removeAttribute('target'); + return thumb.removeAttribute('target'); } - } + }); }, replies: function() { Index.buildThreads(); @@ -5429,12 +5434,11 @@ return $.event('IndexRefresh'); }, buildHRs: function(threadRoots) { - var node, nodes, _i, _len; + var i, node, nodes; nodes = []; - for (_i = 0, _len = threadRoots.length; _i < _len; _i++) { - node = threadRoots[_i]; - nodes.push(node); - nodes.push($.el('hr')); + i = 0; + while (node = threadRoots[i++]) { + nodes.push(node, $.el('hr')); } return nodes; }, @@ -5479,7 +5483,7 @@ return Main.callbackNodes(Post, posts); }, buildCatalogViews: function() { - var catalogThreads, thread, _i, _len, _ref; + var catalogThreads, i, nodes, thread, _i, _len, _ref; catalogThreads = []; _ref = Index.sortedThreads; for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -5489,9 +5493,12 @@ } } Main.callbackNodes(CatalogThread, catalogThreads); - return Index.sortedThreads.map(function(thread) { - return thread.catalogView.nodes.root; - }); + nodes = []; + i = 0; + while (thread = Index.sortedThreads[i++]) { + nodes.push(thread.catalogView.nodes.root); + } + return nodes; }, sizeCatalogViews: function(nodes) { var height, node, ratio, size, thumb, width, _i, _len, _ref; @@ -5509,13 +5516,16 @@ } }, sort: function() { - var sortedThreadIDs; - switch (Conf['Index Sort']) { - case 'bump': - sortedThreadIDs = Index.liveThreadIDs; - break; - case 'lastreply': - sortedThreadIDs = __slice.call(Index.liveThreadData).sort(function(a, b) { + var i, sortedThreadIDs, sortedThreads, thread, threadID; + sortedThreads = []; + sortedThreadIDs = []; + ({ + 'bump': function() { + return sortedThreadIDs = Index.liveThreadIDs; + }, + 'lastreply': function() { + var data, i, liveData; + liveData = __slice.call(Index.liveThreadData).sort(function(a, b) { var _ref, _ref1; if ('last_replies' in a) { _ref = a.last_replies, a = _ref[_ref.length - 1]; @@ -5524,34 +5534,49 @@ _ref1 = b.last_replies, b = _ref1[_ref1.length - 1]; } return b.no - a.no; - }).map(function(data) { - return data.no; }); - break; - case 'birth': - sortedThreadIDs = __slice.call(Index.liveThreadIDs).sort(function(a, b) { + i = 0; + while (data = liveData[i++]) { + sortedThreadIDs.push(data.no); + } + }, + 'birth': function() { + return sortedThreadIDs = __slice.call(Index.liveThreadIDs).sort(function(a, b) { return b - a; }); - break; - case 'replycount': - sortedThreadIDs = __slice.call(Index.liveThreadData).sort(function(a, b) { + }, + 'replycount': function() { + var data, i, liveData; + liveData = __slice.call(Index.liveThreadData).sort(function(a, b) { return b.replies - a.replies; - }).map(function(data) { - return data.no; }); - break; - case 'filecount': - sortedThreadIDs = __slice.call(Index.liveThreadData).sort(function(a, b) { + i = 0; + while (data = liveData[i++]) { + sortedThreadIDs.push(data.no); + } + }, + 'filecount': function() { + var data, i, liveData; + liveData = __slice.call(Index.liveThreadData).sort(function(a, b) { return b.images - a.images; - }).map(function(data) { - return data.no; }); + i = 0; + while (data = liveData[i++]) { + sortedThreadIDs.push(data.no); + } + } + })[Conf['Index Sort']](); + i = 0; + while (threadID = sortedThreadIDs[i++]) { + sortedThreads.push(g.BOARD.threads[threadID]); + } + Index.sortedThreads = []; + i = 0; + while (thread = sortedThreads[i++]) { + if (thread.isHidden === Index.showHiddenThreads) { + Index.sortedThreads.push(thread); + } } - Index.sortedThreads = sortedThreadIDs.map(function(threadID) { - return g.BOARD.threads[threadID]; - }).filter(function(thread) { - return thread.isHidden === Index.showHiddenThreads; - }); if (Index.isSearching) { Index.sortedThreads = Index.querySearch(Index.searchInput.value) || Index.sortedThreads; } @@ -5574,7 +5599,7 @@ } }, buildIndex: function(infinite) { - var nodes, pageNum, threads, threadsPerPage; + var nodes, pageNum, thread, threads, threadsPerPage, _i, _j, _len, _len1, _ref; switch (Conf['Index Mode']) { case 'paged': case 'infinite': @@ -5585,9 +5610,11 @@ } threadsPerPage = Index.getThreadsNumPerPage(); threads = Index.sortedThreads.slice(threadsPerPage * pageNum, threadsPerPage * (pageNum + 1)); - nodes = threads.map(function(thread) { - return thread.OP.nodes.root.parentNode; - }); + nodes = []; + for (_i = 0, _len = threads.length; _i < _len; _i++) { + thread = threads[_i]; + nodes.push(thread.OP.nodes.root.parentNode); + } Index.buildReplies(threads); nodes = Index.buildHRs(nodes); Index.buildPagelist(); @@ -5598,9 +5625,12 @@ Index.sizeCatalogViews(nodes); break; default: - nodes = Index.sortedThreads.map(function(thread) { - return thread.OP.nodes.root.parentNode; - }); + nodes = []; + _ref = Index.sortedThreads; + for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { + thread = _ref[_j]; + nodes.push(thread.OP.nodes.root.parentNode); + } Index.buildReplies(Index.sortedThreads); nodes = Index.buildHRs(nodes); } @@ -5650,9 +5680,16 @@ return Index.search(keywords); }, search: function(keywords) { - return Index.sortedThreads.filter(function(thread) { - return Index.searchMatch(thread, keywords); - }); + var filtered, i, sortedThreads, thread; + filtered = []; + i = 0; + sortedThreads = Index.sortedThreads; + while (thread = sortedThreads[i++]) { + if (Index.searchMatch(thread, keywords)) { + filtered.push(thread); + } + } + return Index.sortedThreads = filtered; }, searchMatch: function(thread, keywords) { var file, info, key, keyword, text, _i, _j, _len, _len1, _ref, _ref1; @@ -5964,7 +6001,7 @@ return "/" + thread.board + "/ - " + excerpt; }, threadFromRoot: function(root) { - return g.threads["" + g.BOARD + "." + root.id.slice(1)]; + return g.threads[root.dataset.fullID]; }, threadFromNode: function(node) { return Get.threadFromRoot($.x('ancestor::div[@class="thread"]', node)); @@ -5982,9 +6019,7 @@ return Get.postFromRoot($.x('ancestor::div[contains(@class,"postContainer")][1]', node)); }, contextFromNode: function(node) { - var snapshot; - snapshot = $.X('ancestor::div[contains(@class,"postContainer")]', node); - return Get.postFromRoot(snapshot.snapshotItem(snapshot.length - 1)); + return Get.postFromRoot($.x('ancestor::div[@class="thread"]', node).firstElementChild); }, postDataFromLink: function(link) { var boardID, path, postID, threadID, _ref; @@ -7366,7 +7401,7 @@ return $.add(this.nodes.info, container); }, buildBacklink: function(quoted, quoter) { - var a, frag, text; + var a, frag, hash, text; frag = QuoteBacklink.frag.cloneNode(true); a = frag.lastElementChild; a.href = "/" + quoter.board + "/res/" + quoter.thread + "#p" + quoter; @@ -7384,7 +7419,14 @@ if (Conf['Quote Inlining']) { $.on(a, 'click', QuoteInline.toggle); if (Conf['Quote Hash Navigation']) { - QuoteInline.qiQuote(a, quoter.isHidden); + hash = QuoteInline.qiQuote(a, quoter.isHidden); + } + } + if (Conf['JSON Navigation']) { + if (hash) { + Navigate.singleQuoteLink(hash); + } else if (!Conf['Quote Inlining']) { + Navigate.singleQuoteLink(a); } } return frag; @@ -16223,22 +16265,28 @@ return $.on(replyLink, 'click', Navigate.navigate); }, post: function() { - var boardID, hashlink, postID, postlink, threadID, _i, _len, _ref, _ref1; - if (Conf['Quote Hash Navigation']) { - _ref = $$('.hashlink', this.nodes.comment); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - hashlink = _ref[_i]; - _ref1 = Get.postDataFromLink(hashlink), boardID = _ref1.boardID, threadID = _ref1.threadID, postID = _ref1.postID; - if (boardID !== g.BOARD.ID || (threadID !== g.THREADID)) { - $.on(hashlink, 'click', Navigate.navigate); - } - } + var linktype; + if (!(g.VIEW === 'thread' && this.thread.ID === g.THREADID)) { + $.on($('a[title="Highlight this post"]', this.nodes.info), 'click', Navigate.navigate); } - if (g.VIEW === 'thread' && this.thread.ID === g.THREADID) { + if (!(linktype = Conf['Quote Inlining'] && Conf['Quote Hash Navigation'] ? '.hashlink' : !Conf['Quote Inlining'] ? '.quotelink' : null)) { return; } - postlink = $('a[title="Highlight this post"]', this.nodes.info); - return $.on(postlink, 'click', Navigate.navigate); + return Navigate.quoteLink($$(linktype, this.nodes.comment)); + }, + quoteLink: function(links) { + var link, _i, _len; + for (_i = 0, _len = links.length; _i < _len; _i++) { + link = links[_i]; + Navigate.singleQuoteLink(link); + } + }, + singleQuoteLink: function(link) { + var boardID, threadID, _ref; + _ref = Get.postDataFromLink(link), boardID = _ref.boardID, threadID = _ref.threadID; + if (g.VIEW === 'index' || boardID !== g.BOARD.ID || threadID !== g.THREADID) { + return $.on(link, 'click', Navigate.navigate); + } }, clean: function() { g.threads.forEach(function(thread) { diff --git a/builds/crx/script.js b/builds/crx/script.js index cb639f9c6..38f0f5f3b 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -3327,6 +3327,7 @@ this.thread.OP = this; this.thread.isSticky = !!$('.stickyIcon', info); this.thread.isClosed = !!$('.closedIcon', info); + root.parentElement.dataset.fullID = this.fullID; } this.info = {}; if (subject = $('.subject', info)) { @@ -5009,10 +5010,14 @@ return $.event('change', null, Index.selectMode); }, cycleSortType: function() { - var i, type, types, _i, _len; - types = __slice.call(Index.selectSort.options).filter(function(option) { - return !option.disabled; - }); + var i, option, type, types, _i, _len; + types = []; + i = 0; + while (option = Index.selectSort.options[i++]) { + if (!option.disabled) { + types.push(option); + } + } for (i = _i = 0, _len = types.length; _i < _len; i = ++_i) { type = types[i]; if (type.selected) { @@ -5023,13 +5028,15 @@ return $.event('change', null, Index.selectSort); }, catalogSwitch: function() { - var hash; - if (!Conf['JSON Navigation']) { - return; - } - $.set('Index Mode', 'catalog'); - hash = window.location.hash; - return window.location = './' + hash; + return $.get('JSON Navigation', true, function(items) { + var hash; + if (!items['JSON Navigation']) { + return; + } + $.set('Index Mode', 'catalog'); + hash = window.location.hash; + return window.location = './' + hash; + }); }, searchTest: function() { var hash, match; @@ -5119,20 +5126,18 @@ return Index.buildIndex(); }, target: function() { - var thread, threadID, thumb, _ref; - _ref = g.BOARD.threads; - for (threadID in _ref) { - thread = _ref[threadID]; + return g.BOARD.threads.forEach(function(thread) { + var thumb; if (!thread.catalogView) { - continue; + return; } thumb = thread.catalogView.nodes.thumb; if (Conf['Open threads in a new tab']) { - thumb.target = '_blank'; + return thumb.target = '_blank'; } else { - thumb.removeAttribute('target'); + return thumb.removeAttribute('target'); } - } + }); }, replies: function() { Index.buildThreads(); @@ -5487,12 +5492,11 @@ return $.event('IndexRefresh'); }, buildHRs: function(threadRoots) { - var node, nodes, _i, _len; + var i, node, nodes; nodes = []; - for (_i = 0, _len = threadRoots.length; _i < _len; _i++) { - node = threadRoots[_i]; - nodes.push(node); - nodes.push($.el('hr')); + i = 0; + while (node = threadRoots[i++]) { + nodes.push(node, $.el('hr')); } return nodes; }, @@ -5537,7 +5541,7 @@ return Main.callbackNodes(Post, posts); }, buildCatalogViews: function() { - var catalogThreads, thread, _i, _len, _ref; + var catalogThreads, i, nodes, thread, _i, _len, _ref; catalogThreads = []; _ref = Index.sortedThreads; for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -5547,9 +5551,12 @@ } } Main.callbackNodes(CatalogThread, catalogThreads); - return Index.sortedThreads.map(function(thread) { - return thread.catalogView.nodes.root; - }); + nodes = []; + i = 0; + while (thread = Index.sortedThreads[i++]) { + nodes.push(thread.catalogView.nodes.root); + } + return nodes; }, sizeCatalogViews: function(nodes) { var height, node, ratio, size, thumb, width, _i, _len, _ref; @@ -5567,13 +5574,16 @@ } }, sort: function() { - var sortedThreadIDs; - switch (Conf['Index Sort']) { - case 'bump': - sortedThreadIDs = Index.liveThreadIDs; - break; - case 'lastreply': - sortedThreadIDs = __slice.call(Index.liveThreadData).sort(function(a, b) { + var i, sortedThreadIDs, sortedThreads, thread, threadID; + sortedThreads = []; + sortedThreadIDs = []; + ({ + 'bump': function() { + return sortedThreadIDs = Index.liveThreadIDs; + }, + 'lastreply': function() { + var data, i, liveData; + liveData = __slice.call(Index.liveThreadData).sort(function(a, b) { var _ref, _ref1; if ('last_replies' in a) { _ref = a.last_replies, a = _ref[_ref.length - 1]; @@ -5582,34 +5592,49 @@ _ref1 = b.last_replies, b = _ref1[_ref1.length - 1]; } return b.no - a.no; - }).map(function(data) { - return data.no; }); - break; - case 'birth': - sortedThreadIDs = __slice.call(Index.liveThreadIDs).sort(function(a, b) { + i = 0; + while (data = liveData[i++]) { + sortedThreadIDs.push(data.no); + } + }, + 'birth': function() { + return sortedThreadIDs = __slice.call(Index.liveThreadIDs).sort(function(a, b) { return b - a; }); - break; - case 'replycount': - sortedThreadIDs = __slice.call(Index.liveThreadData).sort(function(a, b) { + }, + 'replycount': function() { + var data, i, liveData; + liveData = __slice.call(Index.liveThreadData).sort(function(a, b) { return b.replies - a.replies; - }).map(function(data) { - return data.no; }); - break; - case 'filecount': - sortedThreadIDs = __slice.call(Index.liveThreadData).sort(function(a, b) { + i = 0; + while (data = liveData[i++]) { + sortedThreadIDs.push(data.no); + } + }, + 'filecount': function() { + var data, i, liveData; + liveData = __slice.call(Index.liveThreadData).sort(function(a, b) { return b.images - a.images; - }).map(function(data) { - return data.no; }); + i = 0; + while (data = liveData[i++]) { + sortedThreadIDs.push(data.no); + } + } + })[Conf['Index Sort']](); + i = 0; + while (threadID = sortedThreadIDs[i++]) { + sortedThreads.push(g.BOARD.threads[threadID]); + } + Index.sortedThreads = []; + i = 0; + while (thread = sortedThreads[i++]) { + if (thread.isHidden === Index.showHiddenThreads) { + Index.sortedThreads.push(thread); + } } - Index.sortedThreads = sortedThreadIDs.map(function(threadID) { - return g.BOARD.threads[threadID]; - }).filter(function(thread) { - return thread.isHidden === Index.showHiddenThreads; - }); if (Index.isSearching) { Index.sortedThreads = Index.querySearch(Index.searchInput.value) || Index.sortedThreads; } @@ -5632,7 +5657,7 @@ } }, buildIndex: function(infinite) { - var nodes, pageNum, threads, threadsPerPage; + var nodes, pageNum, thread, threads, threadsPerPage, _i, _j, _len, _len1, _ref; switch (Conf['Index Mode']) { case 'paged': case 'infinite': @@ -5643,9 +5668,11 @@ } threadsPerPage = Index.getThreadsNumPerPage(); threads = Index.sortedThreads.slice(threadsPerPage * pageNum, threadsPerPage * (pageNum + 1)); - nodes = threads.map(function(thread) { - return thread.OP.nodes.root.parentNode; - }); + nodes = []; + for (_i = 0, _len = threads.length; _i < _len; _i++) { + thread = threads[_i]; + nodes.push(thread.OP.nodes.root.parentNode); + } Index.buildReplies(threads); nodes = Index.buildHRs(nodes); Index.buildPagelist(); @@ -5656,9 +5683,12 @@ Index.sizeCatalogViews(nodes); break; default: - nodes = Index.sortedThreads.map(function(thread) { - return thread.OP.nodes.root.parentNode; - }); + nodes = []; + _ref = Index.sortedThreads; + for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { + thread = _ref[_j]; + nodes.push(thread.OP.nodes.root.parentNode); + } Index.buildReplies(Index.sortedThreads); nodes = Index.buildHRs(nodes); } @@ -5708,9 +5738,16 @@ return Index.search(keywords); }, search: function(keywords) { - return Index.sortedThreads.filter(function(thread) { - return Index.searchMatch(thread, keywords); - }); + var filtered, i, sortedThreads, thread; + filtered = []; + i = 0; + sortedThreads = Index.sortedThreads; + while (thread = sortedThreads[i++]) { + if (Index.searchMatch(thread, keywords)) { + filtered.push(thread); + } + } + return Index.sortedThreads = filtered; }, searchMatch: function(thread, keywords) { var file, info, key, keyword, text, _i, _j, _len, _len1, _ref, _ref1; @@ -6022,7 +6059,7 @@ return "/" + thread.board + "/ - " + excerpt; }, threadFromRoot: function(root) { - return g.threads["" + g.BOARD + "." + root.id.slice(1)]; + return g.threads[root.dataset.fullID]; }, threadFromNode: function(node) { return Get.threadFromRoot($.x('ancestor::div[@class="thread"]', node)); @@ -6040,9 +6077,7 @@ return Get.postFromRoot($.x('ancestor::div[contains(@class,"postContainer")][1]', node)); }, contextFromNode: function(node) { - var snapshot; - snapshot = $.X('ancestor::div[contains(@class,"postContainer")]', node); - return Get.postFromRoot(snapshot.snapshotItem(snapshot.length - 1)); + return Get.postFromRoot($.x('ancestor::div[@class="thread"]', node).firstElementChild); }, postDataFromLink: function(link) { var boardID, path, postID, threadID, _ref; @@ -7417,7 +7452,7 @@ return $.add(this.nodes.info, container); }, buildBacklink: function(quoted, quoter) { - var a, frag, text; + var a, frag, hash, text; frag = QuoteBacklink.frag.cloneNode(true); a = frag.lastElementChild; a.href = "/" + quoter.board + "/res/" + quoter.thread + "#p" + quoter; @@ -7435,7 +7470,14 @@ if (Conf['Quote Inlining']) { $.on(a, 'click', QuoteInline.toggle); if (Conf['Quote Hash Navigation']) { - QuoteInline.qiQuote(a, quoter.isHidden); + hash = QuoteInline.qiQuote(a, quoter.isHidden); + } + } + if (Conf['JSON Navigation']) { + if (hash) { + Navigate.singleQuoteLink(hash); + } else if (!Conf['Quote Inlining']) { + Navigate.singleQuoteLink(a); } } return frag; @@ -16242,22 +16284,28 @@ return $.on(replyLink, 'click', Navigate.navigate); }, post: function() { - var boardID, hashlink, postID, postlink, threadID, _i, _len, _ref, _ref1; - if (Conf['Quote Hash Navigation']) { - _ref = $$('.hashlink', this.nodes.comment); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - hashlink = _ref[_i]; - _ref1 = Get.postDataFromLink(hashlink), boardID = _ref1.boardID, threadID = _ref1.threadID, postID = _ref1.postID; - if (boardID !== g.BOARD.ID || (threadID !== g.THREADID)) { - $.on(hashlink, 'click', Navigate.navigate); - } - } + var linktype; + if (!(g.VIEW === 'thread' && this.thread.ID === g.THREADID)) { + $.on($('a[title="Highlight this post"]', this.nodes.info), 'click', Navigate.navigate); } - if (g.VIEW === 'thread' && this.thread.ID === g.THREADID) { + if (!(linktype = Conf['Quote Inlining'] && Conf['Quote Hash Navigation'] ? '.hashlink' : !Conf['Quote Inlining'] ? '.quotelink' : null)) { return; } - postlink = $('a[title="Highlight this post"]', this.nodes.info); - return $.on(postlink, 'click', Navigate.navigate); + return Navigate.quoteLink($$(linktype, this.nodes.comment)); + }, + quoteLink: function(links) { + var link, _i, _len; + for (_i = 0, _len = links.length; _i < _len; _i++) { + link = links[_i]; + Navigate.singleQuoteLink(link); + } + }, + singleQuoteLink: function(link) { + var boardID, threadID, _ref; + _ref = Get.postDataFromLink(link), boardID = _ref.boardID, threadID = _ref.threadID; + if (g.VIEW === 'index' || boardID !== g.BOARD.ID || threadID !== g.THREADID) { + return $.on(link, 'click', Navigate.navigate); + } }, clean: function() { g.threads.forEach(function(thread) { diff --git a/src/General/Get.coffee b/src/General/Get.coffee index 11ea71b6b..f042fde45 100755 --- a/src/General/Get.coffee +++ b/src/General/Get.coffee @@ -8,7 +8,7 @@ Get = excerpt = "#{excerpt[...67]}..." "/#{thread.board}/ - #{excerpt}" threadFromRoot: (root) -> - g.threads["#{g.BOARD}.#{root.id[1..]}"] + g.threads[root.dataset.fullID] threadFromNode: (node) -> Get.threadFromRoot $.x 'ancestor::div[@class="thread"]', node postFromRoot: (root) -> @@ -17,8 +17,7 @@ Get = postFromNode: (node) -> Get.postFromRoot $.x 'ancestor::div[contains(@class,"postContainer")][1]', node contextFromNode: (node) -> - snapshot = $.X 'ancestor::div[contains(@class,"postContainer")]', node - Get.postFromRoot snapshot.snapshotItem(snapshot.length - 1) + Get.postFromRoot $.x('ancestor::div[@class="thread"]', node).firstElementChild postDataFromLink: (link) -> if link.hostname is 'boards.4chan.org' path = link.pathname.split '/' diff --git a/src/General/Index.coffee b/src/General/Index.coffee index df57d600b..5bd46bcd4 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -254,17 +254,21 @@ Index = $.event 'change', null, Index.selectMode cycleSortType: -> - types = [Index.selectSort.options...].filter (option) -> !option.disabled + types = [] + i = 0 + while option = Index.selectSort.options[i++] + types.push option if !option.disabled for type, i in types break if type.selected types[(i + 1) % types.length].selected = true $.event 'change', null, Index.selectSort catalogSwitch: -> - return if !Conf['JSON Navigation'] - $.set 'Index Mode', 'catalog' - {hash} = window.location - window.location = './' + hash + $.get 'JSON Navigation', true, (items) -> + return if !items['JSON Navigation'] + $.set 'Index Mode', 'catalog' + {hash} = window.location + window.location = './' + hash searchTest: -> return unless hash = window.location.hash @@ -333,13 +337,13 @@ Index = Index.buildIndex() target: -> - for threadID, thread of g.BOARD.threads when thread.catalogView + g.BOARD.threads.forEach (thread) -> + return if !thread.catalogView {thumb} = thread.catalogView.nodes if Conf['Open threads in a new tab'] thumb.target = '_blank' else thumb.removeAttribute 'target' - return replies: -> Index.buildThreads() @@ -618,9 +622,9 @@ Index = buildHRs: (threadRoots) -> nodes = [] - for node in threadRoots - nodes.push node - nodes.push $.el 'hr' + i = 0 + while node = threadRoots[i++] + nodes.push node, $.el 'hr' nodes buildReplies: (threads) -> @@ -653,7 +657,11 @@ Index = for thread in Index.sortedThreads when !thread.catalogView catalogThreads.push new CatalogThread Build.catalogThread(thread), thread Main.callbackNodes CatalogThread, catalogThreads - Index.sortedThreads.map (thread) -> thread.catalogView.nodes.root + nodes = [] + i = 0 + while thread = Index.sortedThreads[i++] + nodes.push thread.catalogView.nodes.root + return nodes sizeCatalogViews: (nodes) -> # XXX When browsers support CSS3 attr(), use it instead. @@ -668,24 +676,46 @@ Index = return sort: -> - switch Conf['Index Sort'] - when 'bump' + sortedThreads = [] + sortedThreadIDs = [] + + { + 'bump': -> sortedThreadIDs = Index.liveThreadIDs - when 'lastreply' - sortedThreadIDs = [Index.liveThreadData...].sort (a, b) -> + 'lastreply': -> + liveData = [Index.liveThreadData...].sort (a, b) -> [..., a] = a.last_replies if 'last_replies' of a [..., b] = b.last_replies if 'last_replies' of b b.no - a.no - .map (data) -> data.no - when 'birth' + i = 0 + while data = liveData[i++] + sortedThreadIDs.push data.no + return + 'birth': -> sortedThreadIDs = [Index.liveThreadIDs...].sort (a, b) -> b - a - when 'replycount' - sortedThreadIDs = [Index.liveThreadData...].sort((a, b) -> b.replies - a.replies).map (data) -> data.no - when 'filecount' - sortedThreadIDs = [Index.liveThreadData...].sort((a, b) -> b.images - a.images).map (data) -> data.no - Index.sortedThreads = sortedThreadIDs - .map (threadID) -> g.BOARD.threads[threadID] - .filter (thread) -> thread.isHidden is Index.showHiddenThreads + 'replycount': -> + liveData = [Index.liveThreadData...].sort((a, b) -> b.replies - a.replies) + i = 0 + while data = liveData[i++] + sortedThreadIDs.push data.no + return + 'filecount': -> + liveData = [Index.liveThreadData...].sort((a, b) -> b.images - a.images) + i = 0 + while data = liveData[i++] + sortedThreadIDs.push data.no + return + }[Conf['Index Sort']]() + + i = 0 + while threadID = sortedThreadIDs[i++] + sortedThreads.push g.BOARD.threads[threadID] + + Index.sortedThreads = [] + i = 0 + while thread = sortedThreads[i++] + Index.sortedThreads.push thread if thread.isHidden is Index.showHiddenThreads + if Index.isSearching Index.sortedThreads = Index.querySearch(Index.searchInput.value) or Index.sortedThreads # Sticky threads @@ -709,7 +739,8 @@ Index = return threadsPerPage = Index.getThreadsNumPerPage() threads = Index.sortedThreads[threadsPerPage * pageNum ... threadsPerPage * (pageNum + 1)] - nodes = threads.map (thread) -> thread.OP.nodes.root.parentNode + nodes = [] + nodes.push thread.OP.nodes.root.parentNode for thread in threads Index.buildReplies threads nodes = Index.buildHRs nodes Index.buildPagelist() @@ -718,7 +749,8 @@ Index = nodes = Index.buildCatalogViews() Index.sizeCatalogViews nodes else - nodes = Index.sortedThreads.map (thread) -> thread.OP.nodes.root.parentNode + nodes = [] + nodes.push thread.OP.nodes.root.parentNode for thread in Index.sortedThreads Index.buildReplies Index.sortedThreads nodes = Index.buildHRs nodes $.rmAll Index.root unless infinite @@ -763,8 +795,13 @@ Index = Index.search keywords search: (keywords) -> - Index.sortedThreads.filter (thread) -> - Index.searchMatch thread, keywords + filtered = [] + i = 0 + {sortedThreads} = Index + while thread = sortedThreads[i++] + filtered.push thread if Index.searchMatch thread, keywords + Index.sortedThreads = filtered + searchMatch: (thread, keywords) -> {info, file} = thread.OP diff --git a/src/General/Navigate.coffee b/src/General/Navigate.coffee index f7a10e59a..b233fcc0a 100644 --- a/src/General/Navigate.coffee +++ b/src/General/Navigate.coffee @@ -10,7 +10,7 @@ Navigate = $.add Index.navLinks, Navigate.el @title = -> return - + @el = $.el 'div', id: 'breadCrumb' @@ -28,16 +28,29 @@ Navigate = $.on replyLink, 'click', Navigate.navigate post: -> # Allows us to navigate via JSON from thread to thread by hashes and quote highlights. - if Conf['Quote Hash Navigation'] - for hashlink in $$ '.hashlink', @nodes.comment - {boardID, threadID, postID} = Get.postDataFromLink hashlink - if boardID isnt g.BOARD.ID or (threadID isnt g.THREADID) - $.on hashlink, 'click', Navigate.navigate - # We don't need to reload the thread inside the thread - return if g.VIEW is 'thread' and @thread.ID is g.THREADID - postlink = $ 'a[title="Highlight this post"]', @nodes.info - $.on postlink, 'click', Navigate.navigate + unless g.VIEW is 'thread' and @thread.ID is g.THREADID + $.on $('a[title="Highlight this post"]', @nodes.info), 'click', Navigate.navigate + + return unless (linktype = if Conf['Quote Inlining'] and Conf['Quote Hash Navigation'] + '.hashlink' + else if !Conf['Quote Inlining'] + '.quotelink' + else + null + ) + + Navigate.quoteLink $$ linktype, @nodes.comment + + quoteLink: (links) -> + for link in links + Navigate.singleQuoteLink link + return + + singleQuoteLink: (link) -> + {boardID, threadID} = Get.postDataFromLink link + if g.VIEW is 'index' or boardID isnt g.BOARD.ID or threadID isnt g.THREADID + $.on link, 'click', Navigate.navigate clean: -> # Garbage collection diff --git a/src/General/lib/post.class b/src/General/lib/post.class index 812274f7c..4be054b8a 100755 --- a/src/General/lib/post.class +++ b/src/General/lib/post.class @@ -23,6 +23,7 @@ class Post @thread.OP = @ @thread.isSticky = !!$ '.stickyIcon', info @thread.isClosed = !!$ '.closedIcon', info + root.parentElement.dataset.fullID = @fullID @info = {} if subject = $ '.subject', info diff --git a/src/Quotelinks/QuoteBacklink.coffee b/src/Quotelinks/QuoteBacklink.coffee index 81b1315bf..eaf989859 100755 --- a/src/Quotelinks/QuoteBacklink.coffee +++ b/src/Quotelinks/QuoteBacklink.coffee @@ -69,5 +69,10 @@ QuoteBacklink = if Conf['Quote Inlining'] $.on a, 'click', QuoteInline.toggle if Conf['Quote Hash Navigation'] - QuoteInline.qiQuote a, quoter.isHidden + hash = QuoteInline.qiQuote a, quoter.isHidden + if Conf['JSON Navigation'] + if hash + Navigate.singleQuoteLink hash + else unless Conf['Quote Inlining'] + Navigate.singleQuoteLink a frag