diff --git a/4chan_x.coffee b/4chan_x.coffee index 5c20f868f..7bf6b3ec0 100644 --- a/4chan_x.coffee +++ b/4chan_x.coffee @@ -14,10 +14,11 @@ config = 'Thread Expansion': true 'Comment Expansion': true 'Quick Reply': true + 'Persistent QR': false 'Quick Report': true 'Auto Watch': true 'Anonymize': false -getValue = (name) -> +getConfig = (name) -> GM_getValue(name, config[name]) x = (path, root) -> root or= document.body @@ -242,7 +243,7 @@ options = -> position(div) html = '
4chan X
' for option of config - checked = if getValue(option) then "checked" else "" + checked = if getConfig(option) then "checked" else "" html += "
" html += "
" html += 'save cancel
' @@ -320,7 +321,7 @@ hideThread = (div) -> }) GM_setValue("hiddenThreads/#{BOARD}/", JSON.stringify(hiddenThreads)) hide(div) - if getValue('Show Stubs') + if getConfig('Show Stubs') a = tag('a') if span = $('.omittedposts', div) n = Number(span.textContent.match(/\d+/)[0]) @@ -387,7 +388,7 @@ hideReply = (reply) -> trip = $('span.postertrip', reply)?.textContent || '' table = x('ancestor::table', reply) hide(table) - if getValue('Show Stubs') + if getConfig('Show Stubs') a = tag('a') a.textContent = "[ + ] #{name} #{trip}" a.className = 'pointer' @@ -415,18 +416,18 @@ iframeLoad = -> return $('iframe').src = 'about:blank' + window.location = 'javascript:Recaptcha.reload()' + qr = $('#qr') if error = GM_getValue('error') $('form', qr).style.visibility = '' - span = tag('span') - span.textContent = error - span.className = 'error' + span = n 'span', { + textContent: error + className: 'error' + } qr.appendChild(span) - if error is 'You seem to have mistyped the verification.' - window.location = 'javascript:Recaptcha.reload()' - else - remove(qr) - window.location = 'javascript:Recaptcha.reload()' + else unless getConfig('Persistent QR') and REPLY + remove qr submit = (e) -> @@ -457,7 +458,6 @@ autohide = -> quickReply = (e) -> - e.preventDefault() if !qr = $('#qr') #make quick reply dialog qr = tag('div') @@ -489,9 +489,6 @@ quickReply = (e) -> form = $ 'form[name=post]' clone = form.cloneNode(true) - #hack - nuke the original recaptcha's id so it doesn't grab focus - # when reloading - $('input[name=recaptcha_response_field]', form).id = '' #remove recaptcha scripts for script in $$ 'script', clone remove script @@ -508,16 +505,19 @@ quickReply = (e) -> qr.appendChild(clone) document.body.appendChild(qr) - selection = window.getSelection() - id = x('preceding::span[@id][1]', selection.anchorNode)?.id - text = selection.toString() + if e + e.preventDefault() - textarea = $('textarea', qr) - textarea.focus() - #we can't just use @textContent b/c of the xxxs. goddamit moot. - textarea.value += '>>' + @parentNode.id.match(/\d+$/)[0] + '\n' - if text and id is this.parentNode.id - textarea.value += ">#{text}\n" + selection = window.getSelection() + id = x('preceding::span[@id][1]', selection.anchorNode)?.id + text = selection.toString() + + textarea = $('textarea', qr) + textarea.focus() + #we can't just use @textContent b/c of the xxxs. goddamit moot. + textarea.value += '>>' + @parentNode.id.match(/\d+$/)[0] + '\n' + if text and id is this.parentNode.id + textarea.value += ">#{text}\n" watch = -> id = this.nextSibling.name @@ -708,7 +708,7 @@ inBefore(text, a) for el in $$ '#recaptcha_table a' el.tabIndex = 1 -if getValue('Reply Hiding') +if getConfig('Reply Hiding') callbacks.push((root) -> tds = $$('td.doubledash', root) for td in tds @@ -725,10 +725,11 @@ if getValue('Reply Hiding') hideReply(next) ) -if getValue('Quick Reply') - iframe = tag('iframe') +if getConfig('Quick Reply') + iframe = n 'iframe', { + name: 'iframe' + } hide(iframe) - iframe.name = 'iframe' iframe.addEventListener('load', iframeLoad, true) document.body.appendChild(iframe) @@ -738,20 +739,25 @@ if getValue('Quick Reply') quote.addEventListener('click', quickReply, true) ) + #hack - nuke the original recaptcha's id so it doesn't grab focus + # when reloading + $('form[name=post] input[name=recaptcha_response_field]').id = '' -if getValue('Quick Report') + +if getConfig('Quick Report') callbacks.push((root) -> arr = $$('span[id^=no]', root) for el in arr - a = tag('a') - a.textContent = '[ ! ]' - a.className = 'pointer' + a = n 'a', { + textContent: '[ ! ]' + className: 'pointer' + } a.addEventListener('click', report, true) inAfter(el, a) inAfter(el, document.createTextNode(' ')) ) -if getValue('Thread Watcher') +if getConfig('Thread Watcher') #create watcher watcher = tag('div') watcher.innerHTML = '
Thread Watcher
' @@ -778,7 +784,7 @@ if getValue('Thread Watcher') img.addEventListener('click', watch, true) inBefore(input, img) -if getValue('Anonymize') +if getConfig('Anonymize') callbacks.push((root) -> names = $$('span.postername, span.commentpostername', root) for name in names @@ -791,7 +797,7 @@ if getValue('Anonymize') remove(trip) ) -if getValue('Reply Navigation') +if getConfig('Reply Navigation') callbacks.push((root) -> arr = $$('span[id^=norep]', root) for el in arr @@ -811,19 +817,23 @@ if getValue('Reply Navigation') inAfter(el, span) ) +if REPLY + if getConfig('Quick Reply') and getConfig('Persistent QR') + quickReply() + $('#qr input[title=autohide]').click() -if not REPLY - if getValue('Thread Hiding') +else # not reply + if getConfig('Thread Hiding') delform = $('form[name=delform]') #don't confuse other scripts document.addEventListener('DOMNodeInserted', stopPropagation, true) threadF(delform.firstChild) document.removeEventListener('DOMNodeInserted', stopPropagation, true) - if getValue('Auto Watch') + if getConfig('Auto Watch') $('form[name="post"]').addEventListener('submit', autoWatch, true) - if getValue('Thread Navigation') + if getConfig('Thread Navigation') arr = $$('div > span.filesize, form > span.filesize') i = 0 l = arr.length @@ -861,7 +871,7 @@ if not REPLY if location.hash is '#1' window.location = window.location - if getValue('Thread Expansion') + if getConfig('Thread Expansion') omitted = $$('span.omittedposts') for span in omitted a = tag('a') @@ -870,7 +880,7 @@ if not REPLY a.addEventListener('click', expandThread, true) replace(span, a) - if getValue('Comment Expansion') + if getConfig('Comment Expansion') as = $$('span.abbr a') for a in as a.addEventListener('click', expandComment, true) diff --git a/4chan_x.js b/4chan_x.js index 4abddc78d..fab6bdb46 100644 --- a/4chan_x.js +++ b/4chan_x.js @@ -1,5 +1,5 @@ (function() { - var $, $$, BOARD, DAY, PAGENUM, REPLY, _i, _j, _len, _len2, _ref, _ref2, a, arr, as, autoWatch, autohide, b, board, callback, callbacks, clearHidden, close, config, cutoff, delform, down, el, expandComment, expandThread, favEmpty, favNormal, favicon, getTime, getValue, head, hiddenReplies, hiddenThreads, hide, hideReply, hideThread, html, i, i1, id, iframe, iframeLoad, iframeLoop, img, inAfter, inBefore, input, inputs, l, l1, lastChecked, magic, mousedown, mousemove, mouseup, move, n, navtopr, nodeInserted, nop, now, omitted, onloadComment, onloadThread, options, optionsSave, parseResponse, position, quickReply, r, remove, replace, replyNav, report, show, showReply, showThread, slice, span, stopPropagation, submit, tag, text, thread, threadF, threads, up, watch, watchX, watched, watcher, watcherUpdate, x, xhrs; + var $, $$, BOARD, DAY, PAGENUM, REPLY, _i, _j, _len, _len2, _ref, _ref2, a, arr, as, autoWatch, autohide, b, board, callback, callbacks, clearHidden, close, config, cutoff, delform, down, el, expandComment, expandThread, favEmpty, favNormal, favicon, getConfig, getTime, head, hiddenReplies, hiddenThreads, hide, hideReply, hideThread, html, i, i1, id, iframe, iframeLoad, iframeLoop, img, inAfter, inBefore, input, inputs, l, l1, lastChecked, magic, mousedown, mousemove, mouseup, move, n, navtopr, nodeInserted, nop, now, omitted, onloadComment, onloadThread, options, optionsSave, parseResponse, position, quickReply, r, remove, replace, replyNav, report, show, showReply, showThread, slice, span, stopPropagation, submit, tag, text, thread, threadF, threads, up, watch, watchX, watched, watcher, watcherUpdate, x, xhrs; var __hasProp = Object.prototype.hasOwnProperty; config = { 'Thread Hiding': true, @@ -11,11 +11,12 @@ 'Thread Expansion': true, 'Comment Expansion': true, 'Quick Reply': true, + 'Persistent QR': false, 'Quick Report': true, 'Auto Watch': true, 'Anonymize': false }; - getValue = function(name) { + getConfig = function(name) { return GM_getValue(name, config[name]); }; x = function(path, root) { @@ -277,7 +278,7 @@ for (option in _ref2) { if (!__hasProp.call(_ref2, option)) continue; _i = _ref2[option]; - checked = getValue(option) ? "checked" : ""; + checked = getConfig(option) ? "checked" : ""; html += ("
"); } html += ("
"); @@ -354,7 +355,7 @@ GM_setValue("hiddenThreads/" + (BOARD) + "/", JSON.stringify(hiddenThreads)); } hide(div); - if (getValue('Show Stubs')) { + if (getConfig('Show Stubs')) { a = tag('a'); if (span = $('.omittedposts', div)) { n = Number(span.textContent.match(/\d+/)[0]); @@ -423,7 +424,7 @@ trip = ((typeof (_ref3 = ((_ref2 = $('span.postertrip', reply)))) === "undefined" || _ref3 === null) ? undefined : _ref3.textContent) || ''; table = x('ancestor::table', reply); hide(table); - if (getValue('Show Stubs')) { + if (getConfig('Show Stubs')) { a = tag('a'); a.textContent = ("[ + ] " + (name) + " " + (trip)); a.className = 'pointer'; @@ -455,17 +456,17 @@ return null; } $('iframe').src = 'about:blank'; + window.location = 'javascript:Recaptcha.reload()'; qr = $('#qr'); if (error = GM_getValue('error')) { $('form', qr).style.visibility = ''; - span = tag('span'); - span.textContent = error; - span.className = 'error'; - qr.appendChild(span); - return error === 'You seem to have mistyped the verification.' ? (window.location = 'javascript:Recaptcha.reload()') : null; + span = n('span', { + textContent: error, + className: 'error' + }); + return qr.appendChild(span); } else { - remove(qr); - return (window.location = 'javascript:Recaptcha.reload()'); + return !(getConfig('Persistent QR') && REPLY) ? remove(qr) : null; } }; submit = function(e) { @@ -500,7 +501,6 @@ }; quickReply = function(e) { var _i, _len, _ref2, _ref3, autohideB, clone, closeB, div, form, input, qr, script, selection, text, textarea, xpath; - e.preventDefault(); if (!(qr = $('#qr'))) { qr = tag('div'); qr.id = 'qr'; @@ -528,7 +528,6 @@ div.appendChild(closeB); form = $('form[name=post]'); clone = form.cloneNode(true); - $('input[name=recaptcha_response_field]', form).id = ''; _ref2 = $$('script', clone); for (_i = 0, _len = _ref2.length; _i < _len; _i++) { script = _ref2[_i]; @@ -548,13 +547,16 @@ qr.appendChild(clone); document.body.appendChild(qr); } - selection = window.getSelection(); - id = (typeof (_ref3 = ((_ref2 = x('preceding::span[@id][1]', selection.anchorNode)))) === "undefined" || _ref3 === null) ? undefined : _ref3.id; - text = selection.toString(); - textarea = $('textarea', qr); - textarea.focus(); - textarea.value += '>>' + this.parentNode.id.match(/\d+$/)[0] + '\n'; - return text && id === this.parentNode.id ? textarea.value += (">" + (text) + "\n") : null; + if (e) { + e.preventDefault(); + selection = window.getSelection(); + id = (typeof (_ref3 = ((_ref2 = x('preceding::span[@id][1]', selection.anchorNode)))) === "undefined" || _ref3 === null) ? undefined : _ref3.id; + text = selection.toString(); + textarea = $('textarea', qr); + textarea.focus(); + textarea.value += '>>' + this.parentNode.id.match(/\d+$/)[0] + '\n'; + return text && id === this.parentNode.id ? textarea.value += (">" + (text) + "\n") : null; + } }; watch = function() { var text; @@ -777,7 +779,7 @@ el = _ref[_i]; el.tabIndex = 1; } - if (getValue('Reply Hiding')) { + if (getConfig('Reply Hiding')) { callbacks.push(function(root) { var _j, _k, _len2, _len3, _ref2, _ref3, _result, _result2, next, obj, td, tds; tds = $$('td.doubledash', root); @@ -803,10 +805,11 @@ return _result; }); } - if (getValue('Quick Reply')) { - iframe = tag('iframe'); + if (getConfig('Quick Reply')) { + iframe = n('iframe', { + name: 'iframe' + }); hide(iframe); - iframe.name = 'iframe'; iframe.addEventListener('load', iframeLoad, true); document.body.appendChild(iframe); callbacks.push(function(root) { @@ -819,8 +822,9 @@ } return _result; }); + $('form[name=post] input[name=recaptcha_response_field]').id = ''; } - if (getValue('Quick Report')) { + if (getConfig('Quick Report')) { callbacks.push(function(root) { var _j, _len2, _ref2, _result, arr, el; arr = $$('span[id^=no]', root); @@ -828,9 +832,10 @@ for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { el = _ref2[_j]; _result.push((function() { - a = tag('a'); - a.textContent = '[ ! ]'; - a.className = 'pointer'; + a = n('a', { + textContent: '[ ! ]', + className: 'pointer' + }); a.addEventListener('click', report, true); inAfter(el, a); return inAfter(el, document.createTextNode(' ')); @@ -839,7 +844,7 @@ return _result; }); } - if (getValue('Thread Watcher')) { + if (getConfig('Thread Watcher')) { watcher = tag('div'); watcher.innerHTML = '
Thread Watcher
'; watcher.className = 'reply'; @@ -869,7 +874,7 @@ inBefore(input, img); } } - if (getValue('Anonymize')) { + if (getConfig('Anonymize')) { callbacks.push(function(root) { var _k, _len3, _ref3, _result, name, names, trip, trips; names = $$('span.postername, span.commentpostername', root); @@ -887,7 +892,7 @@ return _result; }); } - if (getValue('Reply Navigation')) { + if (getConfig('Reply Navigation')) { callbacks.push(function(root) { var _k, _len3, _ref3, _result, arr, down, el, span, up; arr = $$('span[id^=norep]', root); @@ -914,17 +919,22 @@ return _result; }); } - if (!REPLY) { - if (getValue('Thread Hiding')) { + if (REPLY) { + if (getConfig('Quick Reply') && getConfig('Persistent QR')) { + quickReply(); + $('#qr input[title=autohide]').click(); + } + } else { + if (getConfig('Thread Hiding')) { delform = $('form[name=delform]'); document.addEventListener('DOMNodeInserted', stopPropagation, true); threadF(delform.firstChild); document.removeEventListener('DOMNodeInserted', stopPropagation, true); } - if (getValue('Auto Watch')) { + if (getConfig('Auto Watch')) { $('form[name="post"]').addEventListener('submit', autoWatch, true); } - if (getValue('Thread Navigation')) { + if (getConfig('Thread Navigation')) { arr = $$('div > span.filesize, form > span.filesize'); i = 0; l = arr.length; @@ -966,7 +976,7 @@ window.location = window.location; } } - if (getValue('Thread Expansion')) { + if (getConfig('Thread Expansion')) { omitted = $$('span.omittedposts'); _ref = omitted; for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -978,7 +988,7 @@ replace(span, a); } } - if (getValue('Comment Expansion')) { + if (getConfig('Comment Expansion')) { as = $$('span.abbr a'); _ref = as; for (_i = 0, _len = _ref.length; _i < _len; _i++) {