From 8ddf2b4e5fb255fbbdaab1b48bde7763f2e525dc Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sat, 18 Jan 2014 02:33:54 -0700 Subject: [PATCH 1/5] Start working on tightening our control of the Navigation context Currently breaks posting. TODO: * Fix style switching from NSFW to SFW (SFW to NSFW works) - It is worth noting this used to work. * Fix post form not updating its currently selected thread. * Fix navigation between threads in different boards (same boards works? Maybe?) * Handle race conditions due to pop states. - I'm having a lot of trouble wrapping my mind around this one. Mostly due to the fact that I have no idea where to begin with it. But this isn't a big issue unless you pop state multiple times within seconds. I just need some exceptions when we try to disconnect features that haven't even finished connecting due to threads not being available yet. Most of the early issues, like double-backlinks, incorrect thumbnails, etc, have been fixed, I think. Or at least I'm no longer running into them all the time. --- LICENSE | 2 +- builds/4chan-X.user.js | 108 ++++++++++++++++++++-------- builds/crx/script.js | 70 +++++++++++++----- src/General/Navigate.coffee | 34 +++++---- src/General/lib/post.class | 2 +- src/Posting/QR.coffee | 62 +++++++++++++--- src/Quotelinks/QuoteBacklink.coffee | 2 +- 7 files changed, 209 insertions(+), 71 deletions(-) diff --git a/LICENSE b/LICENSE index 6d1b0a850..6c15e974c 100755 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ /* -* 4chan X - Version 1.3.2 - 2014-01-17 +* 4chan X - Version 1.3.2 - 2014-01-18 * * 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 50d08562d..ecbf17608 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -22,7 +22,7 @@ // ==/UserScript== /* -* 4chan X - Version 1.3.2 - 2014-01-17 +* 4chan X - Version 1.3.2 - 2014-01-18 * * Licensed under the MIT license. * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE @@ -1164,7 +1164,7 @@ if (!(!$.hasClass(quotelink, 'deadlink'))) { continue; } - $.add(quotelink, $.tn('\u00A0(Dead)')); + quotelink.textContent = quotelink.textContent + '\u00A0(Dead)'; $.addClass(quotelink, 'deadlink'); } }; @@ -4854,7 +4854,7 @@ if (Conf['Quote Inlining']) { $.on(link, 'click', QuoteInline.toggle); if (Conf['Quote Hash Navigation']) { - nodes.push.apply(nodes, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered'))); + nodes.push(QuoteInline.qiQuote(link, $.hasClass(link, 'filtered'))); } } $.add(container, nodes); @@ -5632,12 +5632,14 @@ $.on(d, 'dragover', QR.dragOver); $.on(d, 'drop', QR.dropFile); $.on(d, 'dragstart dragend', QR.drag); - switch (g.VIEW) { - case 'index': + return { + index: function() { return $.on(d, 'IndexRefresh', QR.generatePostableThreadsList); - case 'thread': + }, + thread: function() { return $.on(d, 'ThreadUpdate', QR.statusCheck); - } + } + }[g.VIEW](); }, statusCheck: function() { if (g.DEAD) { @@ -5972,7 +5974,7 @@ return list.value = g.VIEW === 'thread' ? g.THREADID : 'new'; }, dialog: function() { - var check, dialog, elm, event, flagSelector, i, items, key, mimeTypes, name, node, nodes, save, value, _ref; + var check, dialog, elm, event, i, items, key, mimeTypes, name, node, nodes, save, value, _ref; QR.nodes = nodes = { el: dialog = UI.dialog('qr', 'top:0;right:0;', "
×
No selected file×+
") }; @@ -6030,12 +6032,7 @@ nodes.flashTag.dataset["default"] = '4'; $.add(nodes.form, nodes.flashTag); } - if (flagSelector = $('.flagSelector')) { - nodes.flag = flagSelector.cloneNode(true); - nodes.flag.dataset.name = 'flag'; - nodes.flag.dataset["default"] = '0'; - $.add(nodes.form, nodes.flag); - } + QR.flagsInput(); $.on(nodes.filename.parentNode, 'click keydown', QR.openFileInput); items = $$('*', QR.nodes.el); i = 0; @@ -6096,6 +6093,40 @@ $.add(d.body, dialog); return $.event('QRDialogCreation', null, dialog); }, + flags: function() { + var flag, fn, select, _i, _len, _ref; + fn = function(val) { + return $.el('option', { + value: val[0], + textContent: val[1] + }); + }; + select = $.el('select', { + name: 'flag', + className: 'flagSelector' + }); + _ref = [['0', 'None'], ['US', 'American'], ['KP', 'Best Korean'], ['BL', 'Black Nationalist'], ['CM', 'Communist'], ['CF', 'Confederate'], ['RE', 'Conservative'], ['EU', 'European'], ['GY', 'Gay'], ['PC', 'Hippie'], ['IL', 'Israeli'], ['DM', 'Liberal'], ['RP', 'Libertarian'], ['MF', 'Muslim'], ['NZ', 'Nazi'], ['OB', 'Obama'], ['PR', 'Pirate'], ['RB', 'Rebel'], ['TP', 'Tea Partier'], ['TX', 'Texan'], ['TR', 'Tree Hugger'], ['WP', 'White Supremacist']]; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + flag = _ref[_i]; + $.add(select, fn(flag)); + } + return select; + }, + flagsInput: function() { + var flag, nodes; + nodes = QR.nodes; + if (nodes.flagSelector) { + $.rm(nodes.flagSelector); + delete nodes.flagSelector; + } + if (g.BOARD.ID === 'pol') { + flag = QR.flags(); + flag.dataset.name = 'flag'; + flag.dataset["default"] = '0'; + nodes.flag = flag; + return $.add(nodes.form, flag); + } + }, preSubmitHooks: [], submit: function(e) { var challenge, err, extra, filetag, formData, hook, options, post, response, textOnly, thread, threadID, _i, _len, _ref, _ref1; @@ -12125,21 +12156,34 @@ return QR.generatePostableThreadsList(); }, updateContext: function(view) { + var oldView; + if (view === g.VIEW) { + return; + } $.rmClass(doc, g.VIEW); $.addClass(doc, view); + oldView = g.VIEW; g.VIEW = view; - switch (view) { - case 'index': + 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); - case 'thread': + }, + 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); - } + } + }[g.VIEW](); }, updateBoard: function(boardID) { var fullBoardList, onload, req; @@ -12148,6 +12192,7 @@ $.rmClass($('.current', fullBoardList), 'current'); $.addClass($("a[href*='/" + boardID + "/']", fullBoardList), 'current'); Header.generateBoardList(Conf['boardnav'].replace(/(\r\n|\n|\r)/g, ' ')); + QR.flagsInput(); onload = function(e) { var aboard, board, err, _i, _len, _ref; if (e.type === 'abort') { @@ -12250,23 +12295,25 @@ pageNum = view; view = 'index'; } - if (view !== g.VIEW) { + Navigate.updateContext(view); + if (!(view === g.VIEW && boardID === g.BOARD.ID)) { Navigate.disconnect(); Navigate.clean(); - Navigate.updateContext(view); Navigate.reconnect(); } - if (view === 'index') { - if (boardID === g.BOARD.ID) { - Navigate.title = function() { + if (boardID === g.BOARD.ID) { + Navigate.title = function() { + if (view === 'index') { return d.title = $('.boardTitle').textContent; - }; - } else { - g.BOARD = new Board(boardID); - Navigate.title = function() { - return Navigate.updateBoard(boardID); - }; - } + } + }; + } else { + g.BOARD = new Board(boardID); + Navigate.title = function() { + return Navigate.updateBoard(boardID); + }; + } + if (view === 'index') { return Index.update(pageNum); } else { Navigate.updateFavicon(Favicon.SFW); @@ -12296,6 +12343,7 @@ new Notice('warning', "Failed to load thread." + (req.status ? " " + req.status : '')); return; } + Navigate.title(); try { return Navigate.parse(JSON.parse(req.response).posts); } catch (_error) { diff --git a/builds/crx/script.js b/builds/crx/script.js index b075a3689..1b14605d0 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript /* -* 4chan X - Version 1.3.2 - 2014-01-17 +* 4chan X - Version 1.3.2 - 2014-01-18 * * Licensed under the MIT license. * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE @@ -1170,7 +1170,7 @@ if (!(!$.hasClass(quotelink, 'deadlink'))) { continue; } - $.add(quotelink, $.tn('\u00A0(Dead)')); + quotelink.textContent = quotelink.textContent + '\u00A0(Dead)'; $.addClass(quotelink, 'deadlink'); } }; @@ -4857,7 +4857,7 @@ if (Conf['Quote Inlining']) { $.on(link, 'click', QuoteInline.toggle); if (Conf['Quote Hash Navigation']) { - nodes.push.apply(nodes, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered'))); + nodes.push(QuoteInline.qiQuote(link, $.hasClass(link, 'filtered'))); } } $.add(container, nodes); @@ -5636,12 +5636,14 @@ $.on(d, 'dragover', QR.dragOver); $.on(d, 'drop', QR.dropFile); $.on(d, 'dragstart dragend', QR.drag); - switch (g.VIEW) { - case 'index': + return { + index: function() { return $.on(d, 'IndexRefresh', QR.generatePostableThreadsList); - case 'thread': + }, + thread: function() { return $.on(d, 'ThreadUpdate', QR.statusCheck); - } + } + }[g.VIEW](); }, statusCheck: function() { if (g.DEAD) { @@ -5980,7 +5982,7 @@ return list.value = g.VIEW === 'thread' ? g.THREADID : 'new'; }, dialog: function() { - var check, dialog, event, flagSelector, i, items, key, mimeTypes, name, node, nodes, save, value, _ref; + var check, dialog, event, i, items, key, mimeTypes, name, node, nodes, save, value, _ref; QR.nodes = nodes = { el: dialog = UI.dialog('qr', 'top:0;right:0;', "
×
No selected file×+
") }; @@ -6038,12 +6040,7 @@ nodes.flashTag.dataset["default"] = '4'; $.add(nodes.form, nodes.flashTag); } - if (flagSelector = $('.flagSelector')) { - nodes.flag = flagSelector.cloneNode(true); - nodes.flag.dataset.name = 'flag'; - nodes.flag.dataset["default"] = '0'; - $.add(nodes.form, nodes.flag); - } + QR.flagsInput(); $.on(nodes.filename.parentNode, 'click keydown', QR.openFileInput); $.on(dialog, 'focusin', QR.focusin); $.on(dialog, 'focusout', QR.focusout); @@ -6087,6 +6084,40 @@ $.add(d.body, dialog); return $.event('QRDialogCreation', null, dialog); }, + flags: function() { + var flag, fn, select, _i, _len, _ref; + fn = function(val) { + return $.el('option', { + value: val[0], + textContent: val[1] + }); + }; + select = $.el('select', { + name: 'flag', + className: 'flagSelector' + }); + _ref = [['0', 'None'], ['US', 'American'], ['KP', 'Best Korean'], ['BL', 'Black Nationalist'], ['CM', 'Communist'], ['CF', 'Confederate'], ['RE', 'Conservative'], ['EU', 'European'], ['GY', 'Gay'], ['PC', 'Hippie'], ['IL', 'Israeli'], ['DM', 'Liberal'], ['RP', 'Libertarian'], ['MF', 'Muslim'], ['NZ', 'Nazi'], ['OB', 'Obama'], ['PR', 'Pirate'], ['RB', 'Rebel'], ['TP', 'Tea Partier'], ['TX', 'Texan'], ['TR', 'Tree Hugger'], ['WP', 'White Supremacist']]; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + flag = _ref[_i]; + $.add(select, fn(flag)); + } + return select; + }, + flagsInput: function() { + var flag, nodes; + nodes = QR.nodes; + if (nodes.flagSelector) { + $.rm(nodes.flagSelector); + delete nodes.flagSelector; + } + if (g.BOARD.ID === 'pol') { + flag = QR.flags(); + flag.dataset.name = 'flag'; + flag.dataset["default"] = '0'; + nodes.flag = flag; + return $.add(nodes.form, flag); + } + }, preSubmitHooks: [], submit: function(e) { var challenge, err, extra, filetag, formData, hook, options, post, response, textOnly, thread, threadID, _i, _len, _ref, _ref1; @@ -12117,18 +12148,20 @@ $.rmClass(doc, g.VIEW); $.addClass(doc, view); g.VIEW = view; - switch (view) { - case 'index': + return { + index: function() { delete g.THREADID; QR.link.textContent = 'Start a Thread'; $.off(d, 'ThreadUpdate', QR.statusCheck); return $.on(d, 'IndexRefresh', QR.generatePostableThreadsList); - case 'thread': + }, + thread: function() { g.THREADID = +window.location.pathname.split('/')[3]; QR.link.textContent = 'Reply to Thread'; $.on(d, 'ThreadUpdate', QR.statusCheck); return $.off(d, 'IndexRefresh', QR.generatePostableThreadsList); - } + } + }[g.VIEW](); }, updateBoard: function(boardID) { var fullBoardList, onload, req; @@ -12137,6 +12170,7 @@ $.rmClass($('.current', fullBoardList), 'current'); $.addClass($("a[href*='/" + boardID + "/']", fullBoardList), 'current'); Header.generateBoardList(Conf['boardnav'].replace(/(\r\n|\n|\r)/g, ' ')); + QR.flagsInput(); onload = function(e) { var aboard, board, err, _i, _len, _ref; if (e.type === 'abort') { diff --git a/src/General/Navigate.coffee b/src/General/Navigate.coffee index 8843d9a0c..819f2afdd 100644 --- a/src/General/Navigate.coffee +++ b/src/General/Navigate.coffee @@ -90,21 +90,26 @@ Navigate = QR.generatePostableThreadsList() updateContext: (view) -> + return if view is g.VIEW + $.rmClass doc, g.VIEW $.addClass doc, view + oldView = g.VIEW g.VIEW = view - - switch view - when 'index' + { + index: -> + return if oldView is g.VIEW delete g.THREADID QR.link.textContent = 'Start a Thread' $.off d, 'ThreadUpdate', QR.statusCheck $.on d, 'IndexRefresh', QR.generatePostableThreadsList - when 'thread' + thread: -> g.THREADID = +window.location.pathname.split('/')[3] + return if oldView is g.VIEW QR.link.textContent = 'Reply to Thread' $.on d, 'ThreadUpdate', QR.statusCheck $.off d, 'IndexRefresh', QR.generatePostableThreadsList + }[g.VIEW]() updateBoard: (boardID) -> req = null @@ -114,6 +119,8 @@ Navigate = $.addClass $("a[href*='/#{boardID}/']", fullBoardList), 'current' Header.generateBoardList Conf['boardnav'].replace /(\r\n|\n|\r)/g, ' ' + QR.flagsInput() + onload = (e) -> if e.type is 'abort' req.onloadend = null @@ -200,19 +207,20 @@ Navigate = pageNum = view view = 'index' # path is "/boardID/". See the problem? - if view isnt g.VIEW + Navigate.updateContext view + + unless view is g.VIEW and boardID is g.BOARD.ID # We've navigated somewhere we weren't before! Navigate.disconnect() Navigate.clean() - Navigate.updateContext view Navigate.reconnect() - if view is 'index' - if boardID is g.BOARD.ID - Navigate.title = -> d.title = $('.boardTitle').textContent - else - g.BOARD = new Board boardID - Navigate.title = -> Navigate.updateBoard boardID + if boardID is g.BOARD.ID + Navigate.title = -> d.title = $('.boardTitle').textContent if view is 'index' + else + g.BOARD = new Board boardID + Navigate.title = -> Navigate.updateBoard boardID + if view is 'index' Index.update pageNum # Moving from index to thread or thread to thread @@ -240,6 +248,8 @@ Navigate = new Notice 'warning', "Failed to load thread.#{if req.status then " #{req.status}" else ''}" return + Navigate.title() + try Navigate.parse JSON.parse(req.response).posts catch err diff --git a/src/General/lib/post.class b/src/General/lib/post.class index a5e6ebc6f..70d29fec3 100755 --- a/src/General/lib/post.class +++ b/src/General/lib/post.class @@ -180,7 +180,7 @@ class Post # Get quotelinks/backlinks to this post # and paint them (Dead). for quotelink in Get.allQuotelinksLinkingTo @ when not $.hasClass quotelink, 'deadlink' - $.add quotelink, $.tn '\u00A0(Dead)' + quotelink.textContent = quotelink.textContent + '\u00A0(Dead)' $.addClass quotelink, 'deadlink' return # XXX tmp fix for 4chan's racing condition diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee index 962362442..bc5831b73 100644 --- a/src/Posting/QR.coffee +++ b/src/Posting/QR.coffee @@ -68,11 +68,12 @@ QR = $.on d, 'dragover', QR.dragOver $.on d, 'drop', QR.dropFile $.on d, 'dragstart dragend', QR.drag - switch g.VIEW - when 'index' + { + index: -> $.on d, 'IndexRefresh', QR.generatePostableThreadsList - when 'thread' + thread: -> $.on d, 'ThreadUpdate', QR.statusCheck + }[g.VIEW]() statusCheck: -> if g.DEAD @@ -405,11 +406,8 @@ QR = """ nodes.flashTag.dataset.default = '4' $.add nodes.form, nodes.flashTag - if flagSelector = $ '.flagSelector' - nodes.flag = flagSelector.cloneNode true - nodes.flag.dataset.name = 'flag' - nodes.flag.dataset.default = '0' - $.add nodes.form, nodes.flag + + QR.flagsInput() $.on nodes.filename.parentNode, 'click keydown', QR.openFileInput @@ -464,6 +462,54 @@ QR = # Use it to extend the QR's functionalities, or for XTRM RICE. $.event 'QRDialogCreation', null, dialog + flags: -> + fn = (val) -> $.el 'option', + value: val[0] + textContent: val[1] + select = $.el 'select', + name: 'flag' + className: 'flagSelector' + + $.add select, fn flag for flag in [ + ['0', 'None'] + ['US', 'American'] + ['KP', 'Best Korean'] + ['BL', 'Black Nationalist'] + ['CM', 'Communist'] + ['CF', 'Confederate'] + ['RE', 'Conservative'] + ['EU', 'European'] + ['GY', 'Gay'] + ['PC', 'Hippie'] + ['IL', 'Israeli'] + ['DM', 'Liberal'] + ['RP', 'Libertarian'] + ['MF', 'Muslim'] + ['NZ', 'Nazi'] + ['OB', 'Obama'] + ['PR', 'Pirate'] + ['RB', 'Rebel'] + ['TP', 'Tea Partier'] + ['TX', 'Texan'] + ['TR', 'Tree Hugger'] + ['WP', 'White Supremacist'] + ] + + select + + flagsInput: -> + {nodes} = QR + if nodes.flagSelector + $.rm nodes.flagSelector + delete nodes.flagSelector + + if g.BOARD.ID is 'pol' + flag = QR.flags() + flag.dataset.name = 'flag' + flag.dataset.default = '0' + nodes.flag = flag + $.add nodes.form, flag + preSubmitHooks: [] submit: (e) -> diff --git a/src/Quotelinks/QuoteBacklink.coffee b/src/Quotelinks/QuoteBacklink.coffee index a9665b25d..42e01d0ad 100755 --- a/src/Quotelinks/QuoteBacklink.coffee +++ b/src/Quotelinks/QuoteBacklink.coffee @@ -41,7 +41,7 @@ QuoteBacklink = $.on link, 'mouseover', QuotePreview.mouseover if Conf['Quote Inlining'] $.on link, 'click', QuoteInline.toggle - nodes.push.apply nodes, QuoteInline.qiQuote link, $.hasClass link, 'filtered' if Conf['Quote Hash Navigation'] + nodes.push QuoteInline.qiQuote link, $.hasClass link, 'filtered' if Conf['Quote Hash Navigation'] $.add container, nodes return secondNode: -> From 7d4825dce0612e6df3a847ecdb51f4518bb92791 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sat, 18 Jan 2014 13:39:02 -0700 Subject: [PATCH 2/5] Add word boundaries to the style switcher regex --- builds/4chan-X.user.js | 16 +++++------ builds/crx/script.js | 54 ++++++++++++++++++++++--------------- src/General/Navigate.coffee | 17 +++++------- 3 files changed, 47 insertions(+), 40 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index ecbf17608..82b369bd0 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -12226,15 +12226,15 @@ return; } Navigate.updateTitle(board); - return Navigate.updateFavicon(!!board.ws_board); + return Navigate.updateSFW(!!board.ws_board); }; return req = $.ajax('//a.4cdn.org/boards.json', { onabort: onload, onloadend: onload }); }, - updateFavicon: function(sfw) { - var findStyle, mainStyleSheet, newStyleSheet, style; + updateSFW: function(sfw) { + var findStyle, style; Favicon.el.href = "//s.4cdn.org/image/favicon" + (sfw ? '-ws' : '') + ".ico"; $.add(d.head, Favicon.el); if (Favicon.SFW === sfw) { @@ -12244,14 +12244,12 @@ Favicon.update(); findStyle = function(type, base) { var style; - style = d.cookie.match(new RegExp("" + type + "\_style\=([^;]+)")); + 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 = findStyle.apply(null, (sfw ? ['ws', 'Yotsuba B New'] : ['nws', 'Yotsuba New'])); $.globalEval("var style_group = '" + style[0] + "'"); - mainStyleSheet = $('link[title=switch]', d.head); - newStyleSheet = $("link[title='" + style[1] + "']", d.head); - mainStyleSheet.href = newStyleSheet.href; + $('link[title=switch]', d.head).href = $("link[title='" + style[1] + "']", d.head).href; return Main.setClass(); }, updateTitle: function(_arg) { @@ -12316,7 +12314,7 @@ if (view === 'index') { return Index.update(pageNum); } else { - Navigate.updateFavicon(Favicon.SFW); + Navigate.updateSFW(Favicon.SFW); load = Navigate.load; Navigate.req = $.ajax("//a.4cdn.org/" + boardID + "/res/" + threadID + ".json", { onabort: load, diff --git a/builds/crx/script.js b/builds/crx/script.js index 1b14605d0..0b6a54afb 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -12145,11 +12145,19 @@ return QR.generatePostableThreadsList(); }, updateContext: function(view) { + var oldView; + if (view === g.VIEW) { + return; + } $.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); @@ -12157,6 +12165,9 @@ }, 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); @@ -12204,15 +12215,15 @@ return; } Navigate.updateTitle(board); - return Navigate.updateFavicon(!!board.ws_board); + return Navigate.updateSFW(!!board.ws_board); }; return req = $.ajax('//a.4cdn.org/boards.json', { onabort: onload, onloadend: onload }); }, - updateFavicon: function(sfw) { - var findStyle, mainStyleSheet, newStyleSheet, style; + updateSFW: function(sfw) { + var findStyle, style; Favicon.el.href = "//s.4cdn.org/image/favicon" + (sfw ? '-ws' : '') + ".ico"; $.add(d.head, Favicon.el); if (Favicon.SFW === sfw) { @@ -12222,14 +12233,12 @@ Favicon.update(); findStyle = function(type, base) { var style; - style = d.cookie.match(new RegExp("" + type + "\_style\=([^;]+)")); + 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 = findStyle.apply(null, (sfw ? ['ws', 'Yotsuba B New'] : ['nws', 'Yotsuba New'])); $.globalEval("var style_group = '" + style[0] + "'"); - mainStyleSheet = $('link[title=switch]', d.head); - newStyleSheet = $("link[title='" + style[1] + "']", d.head); - mainStyleSheet.href = newStyleSheet.href; + $('link[title=switch]', d.head).href = $("link[title='" + style[1] + "']", d.head).href; return Main.setClass(); }, updateTitle: function(_arg) { @@ -12273,26 +12282,28 @@ pageNum = view; view = 'index'; } - if (view !== g.VIEW) { + Navigate.updateContext(view); + if (!(view === g.VIEW && boardID === g.BOARD.ID)) { Navigate.disconnect(); Navigate.clean(); - Navigate.updateContext(view); Navigate.reconnect(); } - if (view === 'index') { - if (boardID === g.BOARD.ID) { - Navigate.title = function() { + if (boardID === g.BOARD.ID) { + Navigate.title = function() { + if (view === 'index') { return d.title = $('.boardTitle').textContent; - }; - } else { - g.BOARD = new Board(boardID); - Navigate.title = function() { - return Navigate.updateBoard(boardID); - }; - } + } + }; + } else { + g.BOARD = new Board(boardID); + Navigate.title = function() { + return Navigate.updateBoard(boardID); + }; + } + if (view === 'index') { return Index.update(pageNum); } else { - Navigate.updateFavicon(Favicon.SFW); + Navigate.updateSFW(Favicon.SFW); load = Navigate.load; Navigate.req = $.ajax("//a.4cdn.org/" + boardID + "/res/" + threadID + ".json", { onabort: load, @@ -12319,6 +12330,7 @@ new Notice('warning', "Failed to load thread." + (req.status ? " " + req.status : '')); return; } + Navigate.title(); try { return Navigate.parse(JSON.parse(req.response).posts); } catch (_error) { diff --git a/src/General/Navigate.coffee b/src/General/Navigate.coffee index 819f2afdd..594cb8fe6 100644 --- a/src/General/Navigate.coffee +++ b/src/General/Navigate.coffee @@ -142,13 +142,13 @@ Navigate = return unless board Navigate.updateTitle board - Navigate.updateFavicon !!board.ws_board + Navigate.updateSFW !!board.ws_board req = $.ajax '//a.4cdn.org/boards.json', onabort: onload onloadend: onload - updateFavicon: (sfw) -> + updateSFW: (sfw) -> # TODO: think of a better name for this. Changes style, too. Favicon.el.href = "//s.4cdn.org/image/favicon#{if sfw then '-ws' else ''}.ico" $.add d.head, Favicon.el # Changing the href alone doesn't update the icon on Firefox @@ -158,20 +158,17 @@ Navigate = Favicon.SFW = sfw Favicon.update() findStyle = (type, base) -> - style = d.cookie.match new RegExp "#{type}\_style\=([^;]+)" + style = d.cookie.match new RegExp "\b#{type}\_style\=([^;]+);\b" return ["#{type}_style", (if style then style[1] else base)] - style = findStyle.apply null, if sfw + style = findStyle (if sfw ['ws', 'Yotsuba B New'] else - ['nws', 'Yotsuba New'] + ['nws', 'Yotsuba New'])... $.globalEval "var style_group = '#{style[0]}'" - mainStyleSheet = $ 'link[title=switch]', d.head - newStyleSheet = $ "link[title='#{style[1]}']", d.head - - mainStyleSheet.href = newStyleSheet.href + $('link[title=switch]', d.head).href = $("link[title='#{style[1]}']", d.head).href Main.setClass() @@ -225,7 +222,7 @@ Navigate = # Moving from index to thread or thread to thread else - Navigate.updateFavicon Favicon.SFW + Navigate.updateSFW Favicon.SFW {load} = Navigate Navigate.req = $.ajax "//a.4cdn.org/#{boardID}/res/#{threadID}.json", onabort: load From e7b1c52dbf9f25aec32bea64c712ee4075f7ef6f Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sat, 18 Jan 2014 14:07:56 -0700 Subject: [PATCH 3/5] Fix updating the context of threads and index --- builds/4chan-X.user.js | 29 ++++++++++++++++------------- builds/crx/script.js | 29 ++++++++++++++++------------- src/General/Index.coffee | 13 +++++++------ src/General/Navigate.coffee | 7 ++++--- 4 files changed, 43 insertions(+), 35 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 82b369bd0..1111bfe16 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -2715,19 +2715,20 @@ Main.callbackNodes(Post, posts); return $.event('IndexRefresh'); }, - buildReplies: function(threadRoots) { - var data, err, errors, i, lastReplies, node, nodes, post, posts, thread, threadRoot, _i, _j, _len, _len1; + buildReplies: function(threads) { + var errors, posts; posts = []; - for (_i = 0, _len = threadRoots.length; _i < _len; _i++) { - threadRoot = threadRoots[_i]; - thread = Get.threadFromRoot(threadRoot); + errors = null; + threads.forEach(function(thread) { + var data, err, i, lastReplies, node, nodes, post, threadRoot, _i, _len; + threadRoot = thread.OP.nodes.root.parentElement; i = Index.liveThreadIDs.indexOf(thread.ID); if (!(lastReplies = Index.liveThreadData[i].last_replies)) { - continue; + return; } nodes = []; - for (_j = 0, _len1 = lastReplies.length; _j < _len1; _j++) { - data = lastReplies[_j]; + for (_i = 0, _len = lastReplies.length; _i < _len; _i++) { + data = lastReplies[_i]; if (post = thread.posts[data.no]) { nodes.push(post.nodes.root); continue; @@ -2746,8 +2747,8 @@ }); } } - $.add(threadRoot, nodes); - } + return $.add(threadRoot, nodes); + }); if (errors) { Main.handleErrors(errors); } @@ -2852,7 +2853,7 @@ $.rmAll(Index.root); $.rmAll(Header.hover); if (Conf['Show Replies']) { - Index.buildReplies(nodes); + Index.buildReplies(g.BOARD.threads); } return Index.buildStructure(nodes); }, @@ -12293,9 +12294,11 @@ pageNum = view; view = 'index'; } - Navigate.updateContext(view); - if (!(view === g.VIEW && boardID === g.BOARD.ID)) { + if (view === g.VIEW && boardID === g.BOARD.ID) { + Navigate.updateContext(view); + } else { Navigate.disconnect(); + Navigate.updateContext(view); Navigate.clean(); Navigate.reconnect(); } diff --git a/builds/crx/script.js b/builds/crx/script.js index 0b6a54afb..5712e0948 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -2725,19 +2725,20 @@ Main.callbackNodes(Post, posts); return $.event('IndexRefresh'); }, - buildReplies: function(threadRoots) { - var data, err, errors, i, lastReplies, node, nodes, post, posts, thread, threadRoot, _i, _j, _len, _len1; + buildReplies: function(threads) { + var errors, posts; posts = []; - for (_i = 0, _len = threadRoots.length; _i < _len; _i++) { - threadRoot = threadRoots[_i]; - thread = Get.threadFromRoot(threadRoot); + errors = null; + threads.forEach(function(thread) { + var data, err, i, lastReplies, node, nodes, post, threadRoot, _i, _len; + threadRoot = thread.OP.nodes.root.parentElement; i = Index.liveThreadIDs.indexOf(thread.ID); if (!(lastReplies = Index.liveThreadData[i].last_replies)) { - continue; + return; } nodes = []; - for (_j = 0, _len1 = lastReplies.length; _j < _len1; _j++) { - data = lastReplies[_j]; + for (_i = 0, _len = lastReplies.length; _i < _len; _i++) { + data = lastReplies[_i]; if (post = thread.posts[data.no]) { nodes.push(post.nodes.root); continue; @@ -2756,8 +2757,8 @@ }); } } - $.add(threadRoot, nodes); - } + return $.add(threadRoot, nodes); + }); if (errors) { Main.handleErrors(errors); } @@ -2862,7 +2863,7 @@ $.rmAll(Index.root); $.rmAll(Header.hover); if (Conf['Show Replies']) { - Index.buildReplies(nodes); + Index.buildReplies(g.BOARD.threads); } return Index.buildStructure(nodes); }, @@ -12282,9 +12283,11 @@ pageNum = view; view = 'index'; } - Navigate.updateContext(view); - if (!(view === g.VIEW && boardID === g.BOARD.ID)) { + if (view === g.VIEW && boardID === g.BOARD.ID) { + Navigate.updateContext(view); + } else { Navigate.disconnect(); + Navigate.updateContext(view); Navigate.clean(); Navigate.reconnect(); } diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 5b72b1882..7936962de 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -349,12 +349,13 @@ Index = Main.callbackNodes Post, posts $.event 'IndexRefresh' - buildReplies: (threadRoots) -> - posts = [] - for threadRoot in threadRoots - thread = Get.threadFromRoot threadRoot + buildReplies: (threads) -> + posts = [] + errors = null + threads.forEach (thread) -> + threadRoot = thread.OP.nodes.root.parentElement i = Index.liveThreadIDs.indexOf thread.ID - continue unless lastReplies = Index.liveThreadData[i].last_replies + return unless lastReplies = Index.liveThreadData[i].last_replies nodes = [] for data in lastReplies if post = thread.posts[data.no] @@ -436,7 +437,7 @@ Index = nodes.push target.data $.rmAll Index.root $.rmAll Header.hover - Index.buildReplies nodes if Conf['Show Replies'] + Index.buildReplies g.BOARD.threads if Conf['Show Replies'] Index.buildStructure nodes buildSinglePage: (pageNum) -> diff --git a/src/General/Navigate.coffee b/src/General/Navigate.coffee index 594cb8fe6..e2d87ef7f 100644 --- a/src/General/Navigate.coffee +++ b/src/General/Navigate.coffee @@ -204,10 +204,11 @@ Navigate = pageNum = view view = 'index' # path is "/boardID/". See the problem? - Navigate.updateContext view - - unless view is g.VIEW and boardID is g.BOARD.ID # We've navigated somewhere we weren't before! + if view is g.VIEW and boardID is g.BOARD.ID + Navigate.updateContext view + else # We've navigated somewhere we weren't before! Navigate.disconnect() + Navigate.updateContext view Navigate.clean() Navigate.reconnect() From b0ca427207d55d2bcb8e82f5cb7ecf0153088aa0 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sat, 18 Jan 2014 14:11:36 -0700 Subject: [PATCH 4/5] Revert "Fix updating the context of threads and index" This reverts commit e7b1c52dbf9f25aec32bea64c712ee4075f7ef6f. --- builds/4chan-X.user.js | 29 +++++++++++++---------------- builds/crx/script.js | 29 +++++++++++++---------------- src/General/Index.coffee | 13 ++++++------- src/General/Navigate.coffee | 7 +++---- 4 files changed, 35 insertions(+), 43 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 1111bfe16..82b369bd0 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -2715,20 +2715,19 @@ Main.callbackNodes(Post, posts); return $.event('IndexRefresh'); }, - buildReplies: function(threads) { - var errors, posts; + buildReplies: function(threadRoots) { + var data, err, errors, i, lastReplies, node, nodes, post, posts, thread, threadRoot, _i, _j, _len, _len1; posts = []; - errors = null; - threads.forEach(function(thread) { - var data, err, i, lastReplies, node, nodes, post, threadRoot, _i, _len; - threadRoot = thread.OP.nodes.root.parentElement; + for (_i = 0, _len = threadRoots.length; _i < _len; _i++) { + threadRoot = threadRoots[_i]; + thread = Get.threadFromRoot(threadRoot); i = Index.liveThreadIDs.indexOf(thread.ID); if (!(lastReplies = Index.liveThreadData[i].last_replies)) { - return; + continue; } nodes = []; - for (_i = 0, _len = lastReplies.length; _i < _len; _i++) { - data = lastReplies[_i]; + for (_j = 0, _len1 = lastReplies.length; _j < _len1; _j++) { + data = lastReplies[_j]; if (post = thread.posts[data.no]) { nodes.push(post.nodes.root); continue; @@ -2747,8 +2746,8 @@ }); } } - return $.add(threadRoot, nodes); - }); + $.add(threadRoot, nodes); + } if (errors) { Main.handleErrors(errors); } @@ -2853,7 +2852,7 @@ $.rmAll(Index.root); $.rmAll(Header.hover); if (Conf['Show Replies']) { - Index.buildReplies(g.BOARD.threads); + Index.buildReplies(nodes); } return Index.buildStructure(nodes); }, @@ -12294,11 +12293,9 @@ pageNum = view; view = 'index'; } - if (view === g.VIEW && boardID === g.BOARD.ID) { - Navigate.updateContext(view); - } else { + Navigate.updateContext(view); + if (!(view === g.VIEW && boardID === g.BOARD.ID)) { Navigate.disconnect(); - Navigate.updateContext(view); Navigate.clean(); Navigate.reconnect(); } diff --git a/builds/crx/script.js b/builds/crx/script.js index 5712e0948..0b6a54afb 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -2725,20 +2725,19 @@ Main.callbackNodes(Post, posts); return $.event('IndexRefresh'); }, - buildReplies: function(threads) { - var errors, posts; + buildReplies: function(threadRoots) { + var data, err, errors, i, lastReplies, node, nodes, post, posts, thread, threadRoot, _i, _j, _len, _len1; posts = []; - errors = null; - threads.forEach(function(thread) { - var data, err, i, lastReplies, node, nodes, post, threadRoot, _i, _len; - threadRoot = thread.OP.nodes.root.parentElement; + for (_i = 0, _len = threadRoots.length; _i < _len; _i++) { + threadRoot = threadRoots[_i]; + thread = Get.threadFromRoot(threadRoot); i = Index.liveThreadIDs.indexOf(thread.ID); if (!(lastReplies = Index.liveThreadData[i].last_replies)) { - return; + continue; } nodes = []; - for (_i = 0, _len = lastReplies.length; _i < _len; _i++) { - data = lastReplies[_i]; + for (_j = 0, _len1 = lastReplies.length; _j < _len1; _j++) { + data = lastReplies[_j]; if (post = thread.posts[data.no]) { nodes.push(post.nodes.root); continue; @@ -2757,8 +2756,8 @@ }); } } - return $.add(threadRoot, nodes); - }); + $.add(threadRoot, nodes); + } if (errors) { Main.handleErrors(errors); } @@ -2863,7 +2862,7 @@ $.rmAll(Index.root); $.rmAll(Header.hover); if (Conf['Show Replies']) { - Index.buildReplies(g.BOARD.threads); + Index.buildReplies(nodes); } return Index.buildStructure(nodes); }, @@ -12283,11 +12282,9 @@ pageNum = view; view = 'index'; } - if (view === g.VIEW && boardID === g.BOARD.ID) { - Navigate.updateContext(view); - } else { + Navigate.updateContext(view); + if (!(view === g.VIEW && boardID === g.BOARD.ID)) { Navigate.disconnect(); - Navigate.updateContext(view); Navigate.clean(); Navigate.reconnect(); } diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 7936962de..5b72b1882 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -349,13 +349,12 @@ Index = Main.callbackNodes Post, posts $.event 'IndexRefresh' - buildReplies: (threads) -> - posts = [] - errors = null - threads.forEach (thread) -> - threadRoot = thread.OP.nodes.root.parentElement + buildReplies: (threadRoots) -> + posts = [] + for threadRoot in threadRoots + thread = Get.threadFromRoot threadRoot i = Index.liveThreadIDs.indexOf thread.ID - return unless lastReplies = Index.liveThreadData[i].last_replies + continue unless lastReplies = Index.liveThreadData[i].last_replies nodes = [] for data in lastReplies if post = thread.posts[data.no] @@ -437,7 +436,7 @@ Index = nodes.push target.data $.rmAll Index.root $.rmAll Header.hover - Index.buildReplies g.BOARD.threads if Conf['Show Replies'] + Index.buildReplies nodes if Conf['Show Replies'] Index.buildStructure nodes buildSinglePage: (pageNum) -> diff --git a/src/General/Navigate.coffee b/src/General/Navigate.coffee index e2d87ef7f..594cb8fe6 100644 --- a/src/General/Navigate.coffee +++ b/src/General/Navigate.coffee @@ -204,11 +204,10 @@ Navigate = pageNum = view view = 'index' # path is "/boardID/". See the problem? - if view is g.VIEW and boardID is g.BOARD.ID - Navigate.updateContext view - else # We've navigated somewhere we weren't before! + Navigate.updateContext view + + unless view is g.VIEW and boardID is g.BOARD.ID # We've navigated somewhere we weren't before! Navigate.disconnect() - Navigate.updateContext view Navigate.clean() Navigate.reconnect() From 3a61ecafffdb641aa205de900a17593f2852a0f0 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sat, 18 Jan 2014 16:53:48 -0700 Subject: [PATCH 5/5] The good parts. --- builds/4chan-X.user.js | 6 ++++-- builds/crx/script.js | 6 ++++-- src/General/Navigate.coffee | 7 ++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 82b369bd0..75dbae7a6 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -12293,9 +12293,11 @@ pageNum = view; view = 'index'; } - Navigate.updateContext(view); - if (!(view === g.VIEW && boardID === g.BOARD.ID)) { + if (view === g.VIEW && boardID === g.BOARD.ID) { + Navigate.updateContext(view); + } else { Navigate.disconnect(); + Navigate.updateContext(view); Navigate.clean(); Navigate.reconnect(); } diff --git a/builds/crx/script.js b/builds/crx/script.js index 0b6a54afb..b2050c249 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -12282,9 +12282,11 @@ pageNum = view; view = 'index'; } - Navigate.updateContext(view); - if (!(view === g.VIEW && boardID === g.BOARD.ID)) { + if (view === g.VIEW && boardID === g.BOARD.ID) { + Navigate.updateContext(view); + } else { Navigate.disconnect(); + Navigate.updateContext(view); Navigate.clean(); Navigate.reconnect(); } diff --git a/src/General/Navigate.coffee b/src/General/Navigate.coffee index 594cb8fe6..e2d87ef7f 100644 --- a/src/General/Navigate.coffee +++ b/src/General/Navigate.coffee @@ -204,10 +204,11 @@ Navigate = pageNum = view view = 'index' # path is "/boardID/". See the problem? - Navigate.updateContext view - - unless view is g.VIEW and boardID is g.BOARD.ID # We've navigated somewhere we weren't before! + if view is g.VIEW and boardID is g.BOARD.ID + Navigate.updateContext view + else # We've navigated somewhere we weren't before! Navigate.disconnect() + Navigate.updateContext view Navigate.clean() Navigate.reconnect()