diff --git a/CHANGELOG.md b/CHANGELOG.md index ad6ede1f8..4dd9feb19 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### v1.7.34 +*2014-05-11* + **Zixaphir** - JSON Navigation now works for backlinks (when Quote Inlining is disabled) and backlink hashlinks. - Many spiffy performance, state awareness, and sanity improvements to JSON Navigation. diff --git a/LICENSE b/LICENSE index 4c61c1763..11b60474e 100755 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ /* -* 4chan X - Version 1.7.33 - 2014-05-10 +* 4chan X - Version 1.7.34 - 2014-05-11 * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE diff --git a/builds/4chan-X.meta.js b/builds/4chan-X.meta.js index 972d23bba..886ccb23c 100755 --- a/builds/4chan-X.meta.js +++ b/builds/4chan-X.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.7.33 +// @version 1.7.34 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 8df0fbea2..9813286d3 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1,7 +1,7 @@ // Generated by CoffeeScript // ==UserScript== // @name 4chan X -// @version 1.7.33 +// @version 1.7.34 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -24,7 +24,7 @@ // ==/UserScript== /* -* 4chan X - Version 1.7.33 - 2014-05-10 +* 4chan X - Version 1.7.34 - 2014-05-11 * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE @@ -372,7 +372,7 @@ doc = d.documentElement; g = { - VERSION: '1.7.33', + VERSION: '1.7.34', NAMESPACE: '4chan X.', boards: {} }; @@ -1707,14 +1707,12 @@ }; SimpleDict.prototype.forEach = function(fn) { - var key, _i, _len, _ref, _results; + var key, _i, _len, _ref; _ref = __slice.call(this.keys); - _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { key = _ref[_i]; - _results.push(fn(this[key])); + fn(this[key]); } - return _results; }; return SimpleDict; @@ -2549,7 +2547,7 @@ return; } e.preventDefault(); - return Index.userPageNav(+a.pathname.split('/')[2]); + return Index.userPageNav(+a.pathname.split('/')[2] || 1); } }, scrollToIndex: function() { @@ -2634,7 +2632,7 @@ $.before(a, strong); return $.add(strong, a); }, - update: function(pageNum) { + update: function(pageNum, forceReparse) { var now, onload, _ref, _ref1; if (!navigator.onLine) { return; @@ -2673,7 +2671,7 @@ onabort: onload, onloadend: onload }, { - whenModified: Index.board === ("" + g.BOARD) + whenModified: !forceReparse }); return $.addClass(Index.button, 'fa-spin'); }, @@ -2704,7 +2702,6 @@ return; } Navigate.title(); - Index.board = "" + g.BOARD; try { if (req.status === 200) { Index.parse(req.response, pageNum); @@ -4915,7 +4912,7 @@ }); }, firstNode: function() { - var a, clone, container, containers, link, markYours, nodes, post, quote, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; + var a, clone, container, containers, hash, link, markYours, nodes, post, quote, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; if (this.isClone || !this.quotes.length) { return; } @@ -4949,7 +4946,15 @@ if (Conf['Quote Inlining']) { $.on(link, 'click', QuoteInline.toggle); if (Conf['Quote Hash Navigation']) { - nodes.push(QuoteInline.qiQuote(link, $.hasClass(link, 'filtered'))); + hash = QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')); + nodes.push(hash); + } + } + if (Conf['JSON Navigation']) { + if (hash) { + Navigate.singleQuoteLink(hash); + } else if (!Conf['Quote Inlining']) { + Navigate.singleQuoteLink(link); } } $.add(container, nodes); @@ -5664,7 +5669,6 @@ }); $.on(sc, 'click', function() { if (Conf['Persistent QR'] || !QR.nodes || QR.nodes.el.hidden) { - $.event('CloseMenu'); QR.open(); QR.nodes.com.focus(); return $.rmClass(this, 'disabled'); @@ -5729,22 +5733,15 @@ $.on(d, 'dragover', QR.dragOver); $.on(d, 'drop', QR.dropFile); $.on(d, 'dragstart dragend', QR.drag); - return { - catalog: function() { - if (Conf["Persistent QR"]) { - QR.open(); - } - if (Conf['Auto Hide QR']) { - return QR.hide(); - } - }, - index: function() { - return $.on(d, 'IndexRefresh', QR.generatePostableThreadsList); - }, - thread: function() { - return $.on(d, 'ThreadUpdate', QR.statusCheck); - } - }[g.VIEW](); + $.on(d, 'IndexRefresh', QR.generatePostableThreadsList); + $.on(d, 'ThreadUpdate', QR.statusCheck); + if (!Conf['Persistent QR']) { + return; + } + QR.open(); + if (Conf['Auto-Hide QR']) { + return QR.hide(); + } }, statusCheck: function() { if (g.DEAD) { @@ -10553,32 +10550,32 @@ return Unread.update(); }, addPosts: function(posts) { - var ID, post, _i, _len, _ref, _ref1; + var ID, post, _i, _len, _ref, _ref1, _ref2; for (_i = 0, _len = posts.length; _i < _len; _i++) { post = posts[_i]; ID = post.ID; - if (ID <= Unread.lastReadPost || post.isHidden || QR.db.get({ + if (ID <= Unread.lastReadPost || post.isHidden || ((_ref = QR.db) != null ? _ref.get({ boardID: post.board.ID, threadID: post.thread.ID, postID: ID - })) { + }) : void 0)) { continue; } Unread.posts.push(post); Unread.addPostQuotingYou(post); } if (Conf['Unread Line']) { - Unread.setLine((_ref = (_ref1 = Unread.posts.first) != null ? _ref1.data : void 0, __indexOf.call(posts, _ref) >= 0)); + Unread.setLine((_ref1 = (_ref2 = Unread.posts.first) != null ? _ref2.data : void 0, __indexOf.call(posts, _ref1) >= 0)); } Unread.read(); return Unread.update(); }, addPostQuotingYou: function(post) { - var quotelink, _i, _len, _ref; + var quotelink, _i, _len, _ref, _ref1; _ref = post.nodes.quotelinks; for (_i = 0, _len = _ref.length; _i < _len; _i++) { quotelink = _ref[_i]; - if (!(QR.db.get(Get.postDataFromLink(quotelink)))) { + if (!((_ref1 = QR.db) != null ? _ref1.get(Get.postDataFromLink(quotelink)) : void 0)) { continue; } Unread.postsQuotingYou.push(post); @@ -10644,7 +10641,7 @@ return arr.splice(0, i); }, read: $.debounce(100, function(e) { - var ID, data, height, post, posts; + var ID, data, height, post, posts, _ref; if (d.hidden || !Unread.posts.length) { return; } @@ -10656,11 +10653,11 @@ } ID = post.ID, data = post.data; posts.rm(ID); - if (Conf['Mark Quotes of You'] && QR.db.get({ + if (Conf['Mark Quotes of You'] && ((_ref = QR.db) != null ? _ref.get({ boardID: data.board.ID, threadID: data.thread.ID, postID: ID - })) { + }) : void 0)) { QuoteYou.lastRead = data.nodes.root; } } @@ -11773,7 +11770,9 @@ case Conf['Update']: switch (g.VIEW) { case 'thread': - ThreadUpdater.update(); + if (Conf['Thread Updater']) { + ThreadUpdater.update(); + } break; case 'index': if (Conf['JSON Navigation']) { @@ -12422,9 +12421,7 @@ if (g.VIEW === 'catalog' || g.BOARD.ID === 'f' || !Conf['JSON Navigation']) { return; } - $.ready(function() { - return $.on(window, 'popstate', Navigate.popstate); - }); + $.on(window, 'popstate', Navigate.popstate); this.title = function() {}; Thread.callbacks.push({ name: 'Navigate', @@ -12444,19 +12441,27 @@ return $.on(replyLink, 'click', Navigate.navigate); }, post: function() { - var hashlink, postlink, _i, _len, _ref; - if (g.VIEW === 'thread' && this.thread.ID === g.THREADID) { + var linktype; + if (!(g.VIEW === 'thread' && this.thread.ID === g.THREADID)) { + $.on($('a[title="Link to this post"]', this.nodes.info), 'click', Navigate.navigate); + } + if (!(linktype = Conf['Quote Inlining'] && Conf['Quote Hash Navigation'] ? '.hashlink' : !Conf['Quote Inlining'] ? '.quotelink' : null)) { return; } - postlink = $('a[title="Link to this post"]', this.nodes.info); - $.on(postlink, 'click', Navigate.navigate); - if (!Conf['Quote Hash Navigation']) { - return; + 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); } - _ref = $$('.hashlink', this.nodes.comment); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - hashlink = _ref[_i]; - $.on(hashlink, 'click', Navigate.navigate); + }, + 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() { @@ -12511,80 +12516,67 @@ Main.handleErrors(errors); } }, - ready: function(name, feature, condition) { - var err, error; - try { - if (condition) { - feature(); - } - } catch (_error) { - err = _error; - error = [ - { - message: "" + name + " Failed.", - error: err - } - ]; - } - if (error) { - Main.handleErrors(error); - } - return QR.generatePostableThreadsList(); - }, updateContext: function(view) { - var oldView; + var origFormThread, post, _i, _len, _ref; g.DEAD = false; + if (view === 'thread') { + g.THREADID = +window.location.pathname.split('/')[3]; + } if (view !== g.VIEW) { $.rmClass(doc, g.VIEW); $.addClass(doc, view); } - oldView = g.VIEW; - g.VIEW = view; - return { - index: function() { - if (oldView === g.VIEW) { - return; - } - delete g.THREADID; - QR.link.textContent = 'Start a Thread'; - $.off(d, 'ThreadUpdate', QR.statusCheck); - return $.on(d, 'IndexRefresh', QR.generatePostableThreadsList); - }, - thread: function() { - g.THREADID = +window.location.pathname.split('/')[3]; - if (oldView === g.VIEW) { - return; - } - QR.link.textContent = 'Reply to Thread'; - $.on(d, 'ThreadUpdate', QR.statusCheck); - return $.off(d, 'IndexRefresh', QR.generatePostableThreadsList); + if (view === 'index') { + delete g.THREADID; + } + origFormThread = $('form[name="post"] input[name="resto"]'); + if (view === 'thread') { + if (!origFormThread) { + origFormThread = $.el('input', { + type: 'hidden', + name: 'resto' + }); + $.after($.id('postPassword'), origFormThread); } - }[g.VIEW](); + origFormThread.value = g.THREADID; + } else { + $.rm(origFormThread); + } + if (Conf['Quick Reply']) { + QR.link.textContent = g.VIEW === 'thread' ? 'Reply to Thread' : 'Start a Thread'; + QR.status(); + _ref = QR.posts; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + post = _ref[_i]; + post.thread = g.THREADID || 'new'; + } + } + return g.VIEW = view; }, updateBoard: function(boardID) { - var fullBoardList, onload, req, _ref, _ref1; + var current, fullBoardList; fullBoardList = $('#full-board-list', Header.boardList); - if ((_ref = $('.current', fullBoardList)) != null) { - _ref.classList.remove('current'); + if (current = $('.current', fullBoardList)) { + $.rmClass(current, 'current'); } - if ((_ref1 = $("a[href*='/" + boardID + "/']", fullBoardList)) != null) { - _ref1.classList.add('current'); + if (current = $("a[href*='/" + boardID + "/']", fullBoardList)) { + $.addClass(current, 'current'); } Header.generateBoardList(Conf['boardnav'].replace(/(\r\n|\n|\r)/g, ' ')); - QR.flagsInput(); - onload = function(e) { - var aboard, board, err, _i, _len, _ref2; - if (e.type === 'abort') { - req.onloadend = null; - return; - } - if (req.status !== 200) { - return; - } + $('#returnlink a').href = "/" + g.BOARD + "/"; + $('form[name="post"]').action = "//sys.4chan.org/" + g.BOARD + "/post"; + if (Conf['Quick Reply']) { + QR.flagsInput(); + } + return $.cache('//a.4cdn.org/boards.json', function() { + var aboard, board, err, _i, _len, _ref; try { - _ref2 = req.response.boards; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - aboard = _ref2[_i]; + if (this.status !== 200) { + return; + } + _ref = this.response.boards; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + aboard = _ref[_i]; if (!(aboard.board === boardID)) { continue; } @@ -12599,22 +12591,17 @@ error: err } ]); - return false; } if (!board) { return; } Navigate.updateTitle(board); return Navigate.updateSFW(!!board.ws_board); - }; - return req = $.ajax('//a.4cdn.org/boards.json', { - onabort: onload, - onloadend: onload }); }, updateSFW: function(sfw) { var findStyle, style; - Favicon.el.href = "//s.4cdn.org/image/favicon" + (sfw ? '-ws' : '') + ".ico"; + Favicon.el.href = Favicon["default"] = "//s.4cdn.org/image/favicon" + (sfw ? '-ws' : '') + ".ico"; $.add(d.head, Favicon.el); if (Favicon.SFW === sfw) { return; @@ -12626,7 +12613,7 @@ style = d.cookie.match(new RegExp("\b" + type + "\_style\=([^;]+);\b")); return ["" + type + "_style", (style ? style[1] : base)]; }; - style = findStyle.apply(null, (sfw ? ['ws', 'Yotsuba B New'] : ['nws', 'Yotsuba New'])); + style = sfw ? findStyle('ws', 'Yotsuba B New') : findStyle('nws', 'Yotsuba New'); $.globalEval("var style_group = '" + style[0] + "'"); $('link[title=switch]', d.head).href = $("link[title='" + style[1] + "']", d.head).href; return Main.setClass(); @@ -12640,24 +12627,51 @@ return $('.boardTitle').textContent = d.title = "/" + board + "/ - " + title; }, navigate: function(e) { - var boardID, load, pageNum, path, threadID, view; - if (this.hostname !== 'boards.4chan.org' || window.location.hostname === 'rs.4chan.org' || (e && (e.shiftKey || e.ctrlKey || (e.type === 'click' && e.button !== 0)))) { - return; - } - $.addClass(Index.button, 'fa-spin'); - path = this.pathname.split('/'); - if (path[0] === '') { - path.shift(); - } - boardID = path[0], view = path[1], threadID = path[2]; - if (view === 'catalog' || ('f' === boardID || 'f' === g.BOARD.ID)) { + var boardID, load, pageNum, path, threadID, view, _, _ref; + if (this.hostname !== 'boards.4chan.org' || window.location.hostname === 'rs.4chan.org') { return; } if (e) { + if (e.shiftKey || e.ctrlKey || (e.type === 'click' && e.button !== 0)) { + return; + } + } + if (this.pathname === Navigate.path) { + if (this.id === 'popState') { + return; + } + if (g.VIEW === 'thread') { + if (Conf['Thread Updater']) { + ThreadUpdater.update(); + } + } else { + Index.update(); + } + if (e != null) { + e.preventDefault(); + } + return; + } + $.addClass(Index.button, 'fa-spin'); + if (Index.isSearching) { + Index.clearSearch(); + } + _ref = this.pathname.split('/'), _ = _ref[0], boardID = _ref[1], view = _ref[2], threadID = _ref[3]; + if (view === 'catalog' || ('f' === boardID || 'f' === g.BOARD.ID)) { + return; + } + if (e != null) { e.preventDefault(); } Navigate.title = function() {}; delete Index.pageNum; + $.rmAll(Header.hover); + if (threadID) { + view = 'thread'; + } else { + pageNum = +view || 1; + view = 'index'; + } path = this.pathname; if (this.hash) { path += this.hash; @@ -12666,15 +12680,7 @@ history.pushState(null, '', path); } Navigate.path = this.pathname; - if (threadID) { - view = 'thread'; - } else { - pageNum = +view || 1; - view = 'index'; - } - if (view === g.VIEW && boardID === g.BOARD.ID) { - Navigate.updateContext(view); - } else { + if (!(view === 'index' && 'index' === g.VIEW && boardID === g.BOARD.ID)) { Navigate.disconnect(); Navigate.updateContext(view); Navigate.clean(); @@ -12692,21 +12698,20 @@ return Navigate.updateBoard(boardID); }; } + Navigate.updateSFW(Favicon.SFW); if (view === 'index') { - return Index.update(pageNum); - } else { - Navigate.updateSFW(Favicon.SFW); - load = Navigate.load; - Navigate.req = $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", { - onabort: load, - onloadend: load - }); - return setTimeout((function() { - if (Navigate.req && !Navigate.notice) { - return Navigate.notice = new Notice('info', 'Loading thread...'); - } - }), 3 * $.SECOND); + return Index.update(pageNum, true); } + load = Navigate.load; + Navigate.req = $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", { + onabort: load, + onloadend: load + }); + return setTimeout((function() { + if (Navigate.req && !Navigate.notice) { + return Navigate.notice = new Notice('info', 'Loading thread...'); + } + }), 3 * $.SECOND); }, load: function(e) { var err, notice, req; @@ -12739,12 +12744,12 @@ } }, parse: function(data) { - var OP, board, errors, makePost, obj, post, posts, thread, threadRoot, _i, _len; - board = g.BOARD; - Navigate.threadRoot = threadRoot = Build.thread(board, OP = data.shift(), true); - thread = new Thread(OP.no, board); + var OP, board, errors, i, makePost, obj, post, posts, thread, threadRoot; posts = []; errors = null; + board = g.BOARD; + threadRoot = Build.thread(board, OP = data[0], true); + thread = new Thread(OP.no, board); makePost = function(postNode) { var err; try { @@ -12755,34 +12760,35 @@ errors = []; } return errors.push({ - message: "Parsing of Post No." + thread.ID + " failed. Post will be skipped.", + message: "Parsing of Post No." + postNode.ID + " failed. Post will be skipped.", error: err }); } }; makePost($('.opContainer', threadRoot)); - for (_i = 0, _len = data.length; _i < _len; _i++) { - obj = data[_i]; + i = 0; + while (obj = data[++i]) { post = Build.postFromObject(obj, board); makePost(post); $.add(threadRoot, post); } - if (errors) { - Main.handleErrors(errors); - } Main.callbackNodes(Thread, [thread]); Main.callbackNodes(Post, posts); - Navigate.ready('Quote Threading', QuoteThreading.force, Conf['Quote Threading'] && !Conf['Unread Count']); - Navigate.buildThread(); - return Header.hashScroll.call(window); - }, - buildThread: function() { - var board; + if (Conf['Quote Threading'] && !Conf['Unread Count']) { + QuoteThreading.force(); + } board = $('.board'); $.rmAll(board); - $.add(board, [Navigate.threadRoot, $.el('hr')]); + $.add(board, [threadRoot, $.el('hr')]); if (Conf['Unread Count']) { - return Navigate.ready('Unread Count', Unread.ready, Conf['Unread Count']); + Unread.ready(); + } + if (Conf['Quick Reply']) { + QR.generatePostableThreadsList(); + } + Header.hashScroll.call(window); + if (errors) { + return Main.handleErrors(errors); } }, pushState: function(path) { @@ -12791,9 +12797,6 @@ }, popstate: function() { var a; - if (window.location.pathname === Navigate.path) { - return; - } a = $.el('a', { href: window.location, id: 'popState' diff --git a/builds/crx.crx b/builds/crx.crx index ee155f3a8..37cd99be0 100644 Binary files a/builds/crx.crx and b/builds/crx.crx differ diff --git a/builds/crx/manifest.json b/builds/crx/manifest.json index fb9d409c3..0660e955d 100755 --- a/builds/crx/manifest.json +++ b/builds/crx/manifest.json @@ -1,6 +1,6 @@ { "name": "4chan X", - "version": "1.7.33", + "version": "1.7.34", "manifest_version": 2, "description": "Cross-browser userscript for maximum lurking on 4chan.", "icons": { diff --git a/builds/crx/script.js b/builds/crx/script.js index 76dbe255f..bf110b6be 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript /* -* 4chan X - Version 1.7.33 - 2014-05-10 +* 4chan X - Version 1.7.34 - 2014-05-11 * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE @@ -348,7 +348,7 @@ doc = d.documentElement; g = { - VERSION: '1.7.33', + VERSION: '1.7.34', NAMESPACE: '4chan X.', boards: {} }; @@ -1744,14 +1744,12 @@ }; SimpleDict.prototype.forEach = function(fn) { - var key, _i, _len, _ref, _results; + var key, _i, _len, _ref; _ref = __slice.call(this.keys); - _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { key = _ref[_i]; - _results.push(fn(this[key])); + fn(this[key]); } - return _results; }; return SimpleDict; @@ -2590,7 +2588,7 @@ return; } e.preventDefault(); - return Index.userPageNav(+a.pathname.split('/')[2]); + return Index.userPageNav(+a.pathname.split('/')[2] || 1); } }, scrollToIndex: function() { @@ -2675,7 +2673,7 @@ $.before(a, strong); return $.add(strong, a); }, - update: function(pageNum) { + update: function(pageNum, forceReparse) { var now, onload, _ref, _ref1; if (!navigator.onLine) { return; @@ -2714,7 +2712,7 @@ onabort: onload, onloadend: onload }, { - whenModified: Index.board === ("" + g.BOARD) + whenModified: !forceReparse }); return $.addClass(Index.button, 'fa-spin'); }, @@ -2745,7 +2743,6 @@ return; } Navigate.title(); - Index.board = "" + g.BOARD; try { if (req.status === 200) { Index.parse(req.response, pageNum); @@ -4949,7 +4946,7 @@ }); }, firstNode: function() { - var a, clone, container, containers, link, markYours, nodes, post, quote, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; + var a, clone, container, containers, hash, link, markYours, nodes, post, quote, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; if (this.isClone || !this.quotes.length) { return; } @@ -4983,7 +4980,15 @@ if (Conf['Quote Inlining']) { $.on(link, 'click', QuoteInline.toggle); if (Conf['Quote Hash Navigation']) { - nodes.push(QuoteInline.qiQuote(link, $.hasClass(link, 'filtered'))); + hash = QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')); + nodes.push(hash); + } + } + if (Conf['JSON Navigation']) { + if (hash) { + Navigate.singleQuoteLink(hash); + } else if (!Conf['Quote Inlining']) { + Navigate.singleQuoteLink(link); } } $.add(container, nodes); @@ -5698,7 +5703,6 @@ }); $.on(sc, 'click', function() { if (Conf['Persistent QR'] || !QR.nodes || QR.nodes.el.hidden) { - $.event('CloseMenu'); QR.open(); QR.nodes.com.focus(); return $.rmClass(this, 'disabled'); @@ -5764,22 +5768,15 @@ $.on(d, 'dragover', QR.dragOver); $.on(d, 'drop', QR.dropFile); $.on(d, 'dragstart dragend', QR.drag); - return { - catalog: function() { - if (Conf["Persistent QR"]) { - QR.open(); - } - if (Conf['Auto Hide QR']) { - return QR.hide(); - } - }, - index: function() { - return $.on(d, 'IndexRefresh', QR.generatePostableThreadsList); - }, - thread: function() { - return $.on(d, 'ThreadUpdate', QR.statusCheck); - } - }[g.VIEW](); + $.on(d, 'IndexRefresh', QR.generatePostableThreadsList); + $.on(d, 'ThreadUpdate', QR.statusCheck); + if (!Conf['Persistent QR']) { + return; + } + QR.open(); + if (Conf['Auto-Hide QR']) { + return QR.hide(); + } }, statusCheck: function() { if (g.DEAD) { @@ -10550,32 +10547,32 @@ return Unread.update(); }, addPosts: function(posts) { - var ID, post, _i, _len, _ref, _ref1; + var ID, post, _i, _len, _ref, _ref1, _ref2; for (_i = 0, _len = posts.length; _i < _len; _i++) { post = posts[_i]; ID = post.ID; - if (ID <= Unread.lastReadPost || post.isHidden || QR.db.get({ + if (ID <= Unread.lastReadPost || post.isHidden || ((_ref = QR.db) != null ? _ref.get({ boardID: post.board.ID, threadID: post.thread.ID, postID: ID - })) { + }) : void 0)) { continue; } Unread.posts.push(post); Unread.addPostQuotingYou(post); } if (Conf['Unread Line']) { - Unread.setLine((_ref = (_ref1 = Unread.posts.first) != null ? _ref1.data : void 0, __indexOf.call(posts, _ref) >= 0)); + Unread.setLine((_ref1 = (_ref2 = Unread.posts.first) != null ? _ref2.data : void 0, __indexOf.call(posts, _ref1) >= 0)); } Unread.read(); return Unread.update(); }, addPostQuotingYou: function(post) { - var quotelink, _i, _len, _ref; + var quotelink, _i, _len, _ref, _ref1; _ref = post.nodes.quotelinks; for (_i = 0, _len = _ref.length; _i < _len; _i++) { quotelink = _ref[_i]; - if (!(QR.db.get(Get.postDataFromLink(quotelink)))) { + if (!((_ref1 = QR.db) != null ? _ref1.get(Get.postDataFromLink(quotelink)) : void 0)) { continue; } Unread.postsQuotingYou.push(post); @@ -10641,7 +10638,7 @@ return arr.splice(0, i); }, read: $.debounce(100, function(e) { - var ID, data, height, post, posts; + var ID, data, height, post, posts, _ref; if (d.hidden || !Unread.posts.length) { return; } @@ -10653,11 +10650,11 @@ } ID = post.ID, data = post.data; posts.rm(ID); - if (Conf['Mark Quotes of You'] && QR.db.get({ + if (Conf['Mark Quotes of You'] && ((_ref = QR.db) != null ? _ref.get({ boardID: data.board.ID, threadID: data.thread.ID, postID: ID - })) { + }) : void 0)) { QuoteYou.lastRead = data.nodes.root; } } @@ -11776,7 +11773,9 @@ case Conf['Update']: switch (g.VIEW) { case 'thread': - ThreadUpdater.update(); + if (Conf['Thread Updater']) { + ThreadUpdater.update(); + } break; case 'index': if (Conf['JSON Navigation']) { @@ -12422,12 +12421,15 @@ Navigate = { path: window.location.pathname, init: function() { + var popstateHack; if (g.VIEW === 'catalog' || g.BOARD.ID === 'f' || !Conf['JSON Navigation']) { return; } - $.ready(function() { + popstateHack = function() { + $.off(window, 'popstate', popstateHack); return $.on(window, 'popstate', Navigate.popstate); - }); + }; + $.on(window, 'popstate', popstateHack); this.title = function() {}; Thread.callbacks.push({ name: 'Navigate', @@ -12447,19 +12449,27 @@ return $.on(replyLink, 'click', Navigate.navigate); }, post: function() { - var hashlink, postlink, _i, _len, _ref; - if (g.VIEW === 'thread' && this.thread.ID === g.THREADID) { + var linktype; + if (!(g.VIEW === 'thread' && this.thread.ID === g.THREADID)) { + $.on($('a[title="Link to this post"]', this.nodes.info), 'click', Navigate.navigate); + } + if (!(linktype = Conf['Quote Inlining'] && Conf['Quote Hash Navigation'] ? '.hashlink' : !Conf['Quote Inlining'] ? '.quotelink' : null)) { return; } - postlink = $('a[title="Link to this post"]', this.nodes.info); - $.on(postlink, 'click', Navigate.navigate); - if (!Conf['Quote Hash Navigation']) { - return; + 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); } - _ref = $$('.hashlink', this.nodes.comment); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - hashlink = _ref[_i]; - $.on(hashlink, 'click', Navigate.navigate); + }, + 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() { @@ -12514,80 +12524,67 @@ Main.handleErrors(errors); } }, - ready: function(name, feature, condition) { - var err, error; - try { - if (condition) { - feature(); - } - } catch (_error) { - err = _error; - error = [ - { - message: "" + name + " Failed.", - error: err - } - ]; - } - if (error) { - Main.handleErrors(error); - } - return QR.generatePostableThreadsList(); - }, updateContext: function(view) { - var oldView; + var origFormThread, post, _i, _len, _ref; g.DEAD = false; + if (view === 'thread') { + g.THREADID = +window.location.pathname.split('/')[3]; + } if (view !== g.VIEW) { $.rmClass(doc, g.VIEW); $.addClass(doc, view); } - oldView = g.VIEW; - g.VIEW = view; - return { - index: function() { - if (oldView === g.VIEW) { - return; - } - delete g.THREADID; - QR.link.textContent = 'Start a Thread'; - $.off(d, 'ThreadUpdate', QR.statusCheck); - return $.on(d, 'IndexRefresh', QR.generatePostableThreadsList); - }, - thread: function() { - g.THREADID = +window.location.pathname.split('/')[3]; - if (oldView === g.VIEW) { - return; - } - QR.link.textContent = 'Reply to Thread'; - $.on(d, 'ThreadUpdate', QR.statusCheck); - return $.off(d, 'IndexRefresh', QR.generatePostableThreadsList); + if (view === 'index') { + delete g.THREADID; + } + origFormThread = $('form[name="post"] input[name="resto"]'); + if (view === 'thread') { + if (!origFormThread) { + origFormThread = $.el('input', { + type: 'hidden', + name: 'resto' + }); + $.after($.id('postPassword'), origFormThread); } - }[g.VIEW](); + origFormThread.value = g.THREADID; + } else { + $.rm(origFormThread); + } + if (Conf['Quick Reply']) { + QR.link.textContent = g.VIEW === 'thread' ? 'Reply to Thread' : 'Start a Thread'; + QR.status(); + _ref = QR.posts; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + post = _ref[_i]; + post.thread = g.THREADID || 'new'; + } + } + return g.VIEW = view; }, updateBoard: function(boardID) { - var fullBoardList, onload, req, _ref, _ref1; + var current, fullBoardList; fullBoardList = $('#full-board-list', Header.boardList); - if ((_ref = $('.current', fullBoardList)) != null) { - _ref.classList.remove('current'); + if (current = $('.current', fullBoardList)) { + $.rmClass(current, 'current'); } - if ((_ref1 = $("a[href*='/" + boardID + "/']", fullBoardList)) != null) { - _ref1.classList.add('current'); + if (current = $("a[href*='/" + boardID + "/']", fullBoardList)) { + $.addClass(current, 'current'); } Header.generateBoardList(Conf['boardnav'].replace(/(\r\n|\n|\r)/g, ' ')); - QR.flagsInput(); - onload = function(e) { - var aboard, board, err, _i, _len, _ref2; - if (e.type === 'abort') { - req.onloadend = null; - return; - } - if (req.status !== 200) { - return; - } + $('#returnlink a').href = "/" + g.BOARD + "/"; + $('form[name="post"]').action = "//sys.4chan.org/" + g.BOARD + "/post"; + if (Conf['Quick Reply']) { + QR.flagsInput(); + } + return $.cache('//a.4cdn.org/boards.json', function() { + var aboard, board, err, _i, _len, _ref; try { - _ref2 = req.response.boards; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - aboard = _ref2[_i]; + if (this.status !== 200) { + return; + } + _ref = this.response.boards; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + aboard = _ref[_i]; if (!(aboard.board === boardID)) { continue; } @@ -12602,22 +12599,17 @@ error: err } ]); - return false; } if (!board) { return; } Navigate.updateTitle(board); return Navigate.updateSFW(!!board.ws_board); - }; - return req = $.ajax('//a.4cdn.org/boards.json', { - onabort: onload, - onloadend: onload }); }, updateSFW: function(sfw) { var findStyle, style; - Favicon.el.href = "//s.4cdn.org/image/favicon" + (sfw ? '-ws' : '') + ".ico"; + Favicon.el.href = Favicon["default"] = "//s.4cdn.org/image/favicon" + (sfw ? '-ws' : '') + ".ico"; $.add(d.head, Favicon.el); if (Favicon.SFW === sfw) { return; @@ -12629,7 +12621,7 @@ style = d.cookie.match(new RegExp("\b" + type + "\_style\=([^;]+);\b")); return ["" + type + "_style", (style ? style[1] : base)]; }; - style = findStyle.apply(null, (sfw ? ['ws', 'Yotsuba B New'] : ['nws', 'Yotsuba New'])); + style = sfw ? findStyle('ws', 'Yotsuba B New') : findStyle('nws', 'Yotsuba New'); $.globalEval("var style_group = '" + style[0] + "'"); $('link[title=switch]', d.head).href = $("link[title='" + style[1] + "']", d.head).href; return Main.setClass(); @@ -12643,24 +12635,51 @@ return $('.boardTitle').textContent = d.title = "/" + board + "/ - " + title; }, navigate: function(e) { - var boardID, load, pageNum, path, threadID, view; - if (this.hostname !== 'boards.4chan.org' || window.location.hostname === 'rs.4chan.org' || (e && (e.shiftKey || e.ctrlKey || (e.type === 'click' && e.button !== 0)))) { - return; - } - $.addClass(Index.button, 'fa-spin'); - path = this.pathname.split('/'); - if (path[0] === '') { - path.shift(); - } - boardID = path[0], view = path[1], threadID = path[2]; - if (view === 'catalog' || ('f' === boardID || 'f' === g.BOARD.ID)) { + var boardID, load, pageNum, path, threadID, view, _, _ref; + if (this.hostname !== 'boards.4chan.org' || window.location.hostname === 'rs.4chan.org') { return; } if (e) { + if (e.shiftKey || e.ctrlKey || (e.type === 'click' && e.button !== 0)) { + return; + } + } + if (this.pathname === Navigate.path) { + if (this.id === 'popState') { + return; + } + if (g.VIEW === 'thread') { + if (Conf['Thread Updater']) { + ThreadUpdater.update(); + } + } else { + Index.update(); + } + if (e != null) { + e.preventDefault(); + } + return; + } + $.addClass(Index.button, 'fa-spin'); + if (Index.isSearching) { + Index.clearSearch(); + } + _ref = this.pathname.split('/'), _ = _ref[0], boardID = _ref[1], view = _ref[2], threadID = _ref[3]; + if (view === 'catalog' || ('f' === boardID || 'f' === g.BOARD.ID)) { + return; + } + if (e != null) { e.preventDefault(); } Navigate.title = function() {}; delete Index.pageNum; + $.rmAll(Header.hover); + if (threadID) { + view = 'thread'; + } else { + pageNum = +view || 1; + view = 'index'; + } path = this.pathname; if (this.hash) { path += this.hash; @@ -12669,15 +12688,7 @@ history.pushState(null, '', path); } Navigate.path = this.pathname; - if (threadID) { - view = 'thread'; - } else { - pageNum = +view || 1; - view = 'index'; - } - if (view === g.VIEW && boardID === g.BOARD.ID) { - Navigate.updateContext(view); - } else { + if (!(view === 'index' && 'index' === g.VIEW && boardID === g.BOARD.ID)) { Navigate.disconnect(); Navigate.updateContext(view); Navigate.clean(); @@ -12695,21 +12706,20 @@ return Navigate.updateBoard(boardID); }; } + Navigate.updateSFW(Favicon.SFW); if (view === 'index') { - return Index.update(pageNum); - } else { - Navigate.updateSFW(Favicon.SFW); - load = Navigate.load; - Navigate.req = $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", { - onabort: load, - onloadend: load - }); - return setTimeout((function() { - if (Navigate.req && !Navigate.notice) { - return Navigate.notice = new Notice('info', 'Loading thread...'); - } - }), 3 * $.SECOND); + return Index.update(pageNum, true); } + load = Navigate.load; + Navigate.req = $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", { + onabort: load, + onloadend: load + }); + return setTimeout((function() { + if (Navigate.req && !Navigate.notice) { + return Navigate.notice = new Notice('info', 'Loading thread...'); + } + }), 3 * $.SECOND); }, load: function(e) { var err, notice, req; @@ -12742,12 +12752,12 @@ } }, parse: function(data) { - var OP, board, errors, makePost, obj, post, posts, thread, threadRoot, _i, _len; - board = g.BOARD; - Navigate.threadRoot = threadRoot = Build.thread(board, OP = data.shift(), true); - thread = new Thread(OP.no, board); + var OP, board, errors, i, makePost, obj, post, posts, thread, threadRoot; posts = []; errors = null; + board = g.BOARD; + threadRoot = Build.thread(board, OP = data[0], true); + thread = new Thread(OP.no, board); makePost = function(postNode) { var err; try { @@ -12758,34 +12768,35 @@ errors = []; } return errors.push({ - message: "Parsing of Post No." + thread.ID + " failed. Post will be skipped.", + message: "Parsing of Post No." + postNode.ID + " failed. Post will be skipped.", error: err }); } }; makePost($('.opContainer', threadRoot)); - for (_i = 0, _len = data.length; _i < _len; _i++) { - obj = data[_i]; + i = 0; + while (obj = data[++i]) { post = Build.postFromObject(obj, board); makePost(post); $.add(threadRoot, post); } - if (errors) { - Main.handleErrors(errors); - } Main.callbackNodes(Thread, [thread]); Main.callbackNodes(Post, posts); - Navigate.ready('Quote Threading', QuoteThreading.force, Conf['Quote Threading'] && !Conf['Unread Count']); - Navigate.buildThread(); - return Header.hashScroll.call(window); - }, - buildThread: function() { - var board; + if (Conf['Quote Threading'] && !Conf['Unread Count']) { + QuoteThreading.force(); + } board = $('.board'); $.rmAll(board); - $.add(board, [Navigate.threadRoot, $.el('hr')]); + $.add(board, [threadRoot, $.el('hr')]); if (Conf['Unread Count']) { - return Navigate.ready('Unread Count', Unread.ready, Conf['Unread Count']); + Unread.ready(); + } + if (Conf['Quick Reply']) { + QR.generatePostableThreadsList(); + } + Header.hashScroll.call(window); + if (errors) { + return Main.handleErrors(errors); } }, pushState: function(path) { @@ -12794,9 +12805,6 @@ }, popstate: function() { var a; - if (window.location.pathname === Navigate.path) { - return; - } a = $.el('a', { href: window.location, id: 'popState' diff --git a/builds/updates.xml b/builds/updates.xml index 786a7fdf3..1af1e33e8 100644 --- a/builds/updates.xml +++ b/builds/updates.xml @@ -1,7 +1,7 @@ - + diff --git a/package.json b/package.json index 4ea93ce42..3bfbcc631 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "4chan-X", - "version": "1.7.33", + "version": "1.7.34", "description": "Cross-browser userscript for maximum lurking on 4chan.", "meta": { "name": "4chan X",