diff --git a/4chan_x.user.js b/4chan_x.user.js index 7b2a01f44..971398873 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -72,7 +72,7 @@ */ (function() { - var $, $$, Anonymize, AutoGif, Conf, Config, ExpandComment, ExpandThread, Favicon, FileInfo, Filter, GetTitle, ImageExpand, ImageHover, Keybinds, Main, Nav, Options, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, Quotify, Redirect, ReplyHiding, ReportButton, RevealSpoilers, Sauce, StrikethroughQuotes, ThreadHiding, ThreadStats, Threading, Time, TitlePost, UI, Unread, Updater, Watcher, d, g, _base; + var $, $$, Anonymize, AutoGif, Conf, Config, ExpandComment, ExpandThread, Favicon, FileInfo, Filter, GetTitle, ImageExpand, ImageHover, Keybinds, Main, Nav, Options, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, Quotify, Redirect, ReplyHiding, ReportButton, RevealSpoilers, Sauce, StrikethroughQuotes, ThreadHiding, ThreadStats, Time, TitlePost, UI, Unread, Updater, Watcher, d, g, _base; Config = { main: { @@ -791,7 +791,6 @@ } doc = d.implementation.createHTMLDocument(''); doc.documentElement.innerHTML = req.response; - Threading.op($('body > form', doc).firstChild); node = d.importNode(doc.getElementById(replyID)); quotes = node.getElementsByClassName('quotelink'); for (_i = 0, _len = quotes.length; _i < _len; _i++) { @@ -1347,7 +1346,7 @@ } return $('textarea', QR.el).focus(); }); - $.before($('form[name=post]'), link); + $.before($.id('postForm'), link); } script = $.el('script', { textContent: 'Recaptcha.focus_response_field=function(){}' @@ -1841,7 +1840,7 @@ }); ta.style.cssText = $.get('QR.size', ''); } - mimeTypes = $('.rules').firstChild.textContent.match(/: (.+) /)[1].toLowerCase().replace(/\w+/g, function(type) { + mimeTypes = $('ul.rules').firstElementChild.textContent.match(/: (.+) /)[1].toLowerCase().replace(/\w+/g, function(type) { switch (type) { case 'jpg': return 'image/jpeg'; @@ -2379,46 +2378,6 @@ } }; - Threading = { - op: function(node) { - var nodes, op; - nodes = []; - while (node.nodeName !== 'BLOCKQUOTE') { - nodes.push(node); - node = node.nextSibling; - } - nodes.push(node); - node = node.nextSibling; - op = $.el('div', { - className: 'op' - }); - $.add(op, nodes); - op.id = $('input', op).name; - return $.before(node, op); - }, - thread: function(node) { - var div, nodes; - node = Threading.op(node); - if (g.REPLY) { - return; - } - nodes = []; - while (node.nodeName !== 'HR') { - nodes.push(node); - node = node.nextElementSibling; - } - div = $.el('div', { - className: 'thread' - }); - $.add(div, nodes); - $.before(node, div); - node = node.nextElementSibling; - if (!(node.align || node.nodeName === 'CENTER')) { - return Threading.thread(node); - } - } - }; - ThreadHiding = { init: function() { var a, hiddenThreads, op, thread, _i, _len, _ref; @@ -3078,18 +3037,19 @@ }; GetTitle = function(thread) { - var el, span; - el = $('.filetitle', thread); + var el, op, span; + op = $('.op', thread); + el = $('.subject', op); if (!el.textContent) { - el = $('blockquote', thread); + el = $('blockquote', op); if (!el.textContent) { - el = $('.postername', thread); + el = $('.nameBlock', op); } } span = $.el('span', { innerHTML: el.innerHTML.replace(/
/g, ' ') }); - return "/" + g.BOARD + "/ - " + span.textContent; + return "/" + g.BOARD + "/ - " + (span.textContent.trim()); }; TitlePost = { @@ -3254,7 +3214,7 @@ } doc = d.implementation.createHTMLDocument(''); doc.documentElement.innerHTML = req.response; - node = id === threadID ? Threading.op($('body > form', doc).firstChild) : doc.getElementById(id); + node = doc.getElementById(id); newInline = QuoteInline.table(id, node.innerHTML); _ref = $$('.quotelink', newInline); for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -3355,7 +3315,7 @@ } doc = d.implementation.createHTMLDocument(''); doc.documentElement.innerHTML = req.response; - node = id === threadID ? Threading.op($('body > form', doc).firstChild) : doc.getElementById(id); + node = doc.getElementById(id); qp.innerHTML = node.innerHTML; post = { root: qp, @@ -3961,7 +3921,6 @@ val = Conf[key]; Conf[key] = $.get(key, val); } - $.on(window, 'message', Main.message); switch (location.hostname) { case 'sys.4chan.org': if (/report/.test(location.search)) { @@ -3984,11 +3943,12 @@ } $.ready(Options.init); if (Conf['Quick Reply'] && Conf['Hide Original Post Form'] && g.BOARD !== 'f') { - Main.css += 'form[name=post] { display: none; }'; + Main.css += '#postForm { display: none; }'; } Main.addStyle(); now = Date.now(); if (Conf['Check for Updates'] && $.get('lastUpdate', 0) < now - 6 * $.HOUR) { + $.on(window, 'message', Main.message); $.ready(function() { return $.add(d.head, $.el('script', { src: 'https://raw.github.com/mayhemydg/4chan-x/master/latest.js' @@ -4071,7 +4031,7 @@ return $.ready(Main.ready); }, ready: function() { - var MutationObserver, form, nav, node, nodes, observer, _i, _j, _len, _len1, _ref, _ref1; + var MutationObserver, a, board, nav, node, nodes, observer, _i, _j, _len, _len1, _ref, _ref1; if (d.title === '4chan - 404') { Redirect.init(); return; @@ -4081,13 +4041,13 @@ } $.addClass(d.body, "chanx_" + (Main.version.split('.')[1])); $.addClass(d.body, $.engine); - _ref = ['navtop', 'navbot']; + _ref = ['boardNavDesktop', 'boardNavDesktopFoot']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { nav = _ref[_i]; - $.addClass($("a[href$='/" + g.BOARD + "/']", $.id(nav)), 'current'); + if (a = $("a[href$='/" + g.BOARD + "/']", $.id(nav))) { + $.addClass(a, 'current'); + } } - form = $('form[name=delform]'); - Threading.thread(form.firstElementChild); Favicon.init(); if (Conf['Quick Reply']) { QR.init(); @@ -4147,8 +4107,9 @@ }); } } + board = $('.board'); nodes = []; - _ref1 = $$('.op, a + table', form); + _ref1 = $$('.post', board); for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { node = _ref1[_j]; nodes.push(Main.preParse(node)); @@ -4156,12 +4117,12 @@ Main.node(nodes, true); if (MutationObserver = window.WebKitMutationObserver || window.MozMutationObserver || window.OMutationObserver || window.MutationObserver) { observer = new MutationObserver(Main.observer); - return observer.observe(form, { + return observer.observe(board, { childList: true, subtree: true }); } else { - return $.on(form, 'DOMNodeInserted', Main.listener); + return $.on(board, 'DOMNodeInserted', Main.listener); } }, flatten: function(parent, obj) { @@ -4196,13 +4157,13 @@ var klass, post; klass = node.className; post = { - root: node, - el: klass === 'op' ? node : node.firstChild.firstChild.lastChild, + root: node.parentNode, + el: node, "class": klass, - id: node.getElementsByTagName('input')[0].name, - threadId: g.THREAD_ID || $.x('ancestor::div[@class="thread"]', node).firstChild.id, + id: node.id.slice(1), + threadId: g.THREAD_ID || $.x('ancestor::div[@class="thread"]', node).id.slice(1), isInlined: /\binline\b/.test(klass), - filesize: node.getElementsByClassName('filesize')[0] || false, + fileinfo: node.getElementsByClassName('fileInfo')[0] || false, quotes: node.getElementsByClassName('quotelink'), backlinks: node.getElementsByClassName('backlink') }; @@ -4275,6 +4236,9 @@ a[href="javascript:;"] {\ display: none;\ }\ \ +h1 {\ + text-align: center;\ +}\ .autohide:not(:hover) > form {\ display: none;\ }\ diff --git a/script.coffee b/script.coffee index 8e930ed96..fc88e1e05 100644 --- a/script.coffee +++ b/script.coffee @@ -628,7 +628,6 @@ ExpandComment = doc = d.implementation.createHTMLDocument '' doc.documentElement.innerHTML = req.response - Threading.op $('body > form', doc).firstChild # Import the node to fix quote.hashes # as they're empty when in a different document. node = d.importNode doc.getElementById replyID @@ -1014,9 +1013,9 @@ QR = link = $.el 'h1', innerHTML: "#{if g.REPLY then 'Quick Reply' else 'New Thread'}" $.on link.firstChild, 'click', -> QR.open() - $('select', QR.el).value = 'new' unless g.REPLY + $('select', QR.el).value = 'new' unless g.REPLY $('textarea', QR.el).focus() - $.before $('form[name=post]'), link + $.before $.id('postForm'), link # Prevent original captcha input from being focused on reload. script = $.el 'script', @@ -1405,7 +1404,7 @@ QR = ta.style.cssText = $.get 'QR.size', '' # Allow only this board's supported files. - mimeTypes = $('.rules').firstChild.textContent.match(/: (.+) /)[1].toLowerCase().replace /\w+/g, (type) -> + mimeTypes = $('ul.rules').firstElementChild.textContent.match(/: (.+) /)[1].toLowerCase().replace /\w+/g, (type) -> switch type when 'jpg' 'image/jpeg' @@ -1876,39 +1875,6 @@ Options = Unread.update true @nextElementSibling.innerHTML = " " -Threading = - op: (node) -> - nodes = [] - until node.nodeName is 'BLOCKQUOTE' - nodes.push node - node = node.nextSibling - nodes.push node # Add the blockquote. - node = node.nextSibling - op = $.el 'div', - className: 'op' - $.add op, nodes - op.id = $('input', op).name - $.before node, op - - thread: (node) -> - node = Threading.op node - - return if g.REPLY - - nodes = [] - until node.nodeName is 'HR' - nodes.push node - node = node.nextElementSibling # Skip text nodes. - div = $.el 'div', - className: 'thread' - $.add div, nodes - $.before node, div - - node = node.nextElementSibling - # {N,}SFW - unless node.align or node.nodeName is 'CENTER' - Threading.thread node - ThreadHiding = init: -> hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {} @@ -2407,13 +2373,14 @@ FileInfo = r: -> FileInfo.data.resolution GetTitle = (thread) -> - el = $ '.filetitle', thread - if not el.textContent - el = $ 'blockquote', thread - if not el.textContent - el = $ '.postername', thread + op = $ '.op', thread + el = $ '.subject', op + unless el.textContent + el = $ 'blockquote', op + unless el.textContent + el = $ '.nameBlock', op span = $.el 'span', innerHTML: el.innerHTML.replace /
/g, ' ' - "/#{g.BOARD}/ - #{span.textContent}" + "/#{g.BOARD}/ - #{span.textContent.trim()}" TitlePost = init: -> @@ -2525,11 +2492,7 @@ QuoteInline = doc = d.implementation.createHTMLDocument '' doc.documentElement.innerHTML = req.response - node = - if id is threadID #OP - Threading.op $('body > form', doc).firstChild - else - doc.getElementById id + node = doc.getElementById id newInline = QuoteInline.table id, node.innerHTML for quote in $$ '.quotelink', newInline if (href = quote.getAttribute 'href') is quote.hash #add pathname to normal quotes @@ -2599,11 +2562,7 @@ QuotePreview = doc = d.implementation.createHTMLDocument '' doc.documentElement.innerHTML = req.response - node = - if id is threadID #OP - Threading.op $('body > form', doc).firstChild - else - doc.getElementById id + node = doc.getElementById id qp.innerHTML = node.innerHTML post = root: qp @@ -3043,12 +3002,10 @@ Main = g.REPLY = true g.THREAD_ID = pathname[2] - #load values from localStorage + # Load values from localStorage. for key, val of Conf Conf[key] = $.get key, val - $.on window, 'message', Main.message - switch location.hostname when 'sys.4chan.org' if /report/.test location.search @@ -3063,12 +3020,13 @@ Main = $.ready Options.init if Conf['Quick Reply'] and Conf['Hide Original Post Form'] and g.BOARD isnt 'f' - Main.css += 'form[name=post] { display: none; }' + Main.css += '#postForm { display: none; }' Main.addStyle() now = Date.now() if Conf['Check for Updates'] and $.get('lastUpdate', 0) < now - 6*$.HOUR + $.on window, 'message', Main.message $.ready -> $.add d.head, $.el 'script', src: 'https://raw.github.com/mayhemydg/4chan-x/master/latest.js' $.set 'lastUpdate', now @@ -3153,10 +3111,10 @@ Main = return $.addClass d.body, "chanx_#{Main.version.split('.')[1]}" $.addClass d.body, $.engine - for nav in ['navtop', 'navbot'] - $.addClass $("a[href$='/#{g.BOARD}/']", $.id nav), 'current' - form = $ 'form[name=delform]' - Threading.thread form.firstElementChild + for nav in ['boardNavDesktop', 'boardNavDesktopFoot'] + if a = $ "a[href$='/#{g.BOARD}/']", $.id nav + # Gotta make it work in temporary boards. + $.addClass a, 'current' Favicon.init() # Major features. @@ -3201,18 +3159,19 @@ Main = if Conf['Index Navigation'] setTimeout -> Nav.init() + board = $ '.board' nodes = [] - for node in $$ '.op, a + table', form + for node in $$ '.post', board nodes.push Main.preParse node Main.node nodes, true if MutationObserver = window.WebKitMutationObserver or window.MozMutationObserver or window.OMutationObserver or window.MutationObserver observer = new MutationObserver Main.observer - observer.observe form, + observer.observe board, childList: true subtree: true else - $.on form, 'DOMNodeInserted', Main.listener + $.on board, 'DOMNodeInserted', Main.listener flatten: (parent, obj) -> if obj instanceof Array @@ -3239,13 +3198,13 @@ Main = preParse: (node) -> klass = node.className post = - root: node - el: if klass is 'op' then node else node.firstChild.firstChild.lastChild + root: node.parentNode + el: node class: klass - id: node.getElementsByTagName('input')[0].name - threadId: g.THREAD_ID or $.x('ancestor::div[@class="thread"]', node).firstChild.id + id: node.id[1..] + threadId: g.THREAD_ID or $.x('ancestor::div[@class="thread"]', node).id[1..] isInlined: /\binline\b/.test klass - filesize: node.getElementsByClassName('filesize')[0] or false + fileinfo: node.getElementsByClassName('fileInfo')[0] or false quotes: node.getElementsByClassName 'quotelink' backlinks: node.getElementsByClassName 'backlink' post.img = if post.filesize then node.getElementsByTagName('img')[0] else false @@ -3292,6 +3251,9 @@ a[href="javascript:;"] { display: none; } +h1 { + text-align: center; +} .autohide:not(:hover) > form { display: none; }