persistent qr

This commit is contained in:
James Campos 2010-10-08 16:12:11 -07:00
parent 72ef7eee7a
commit 4a0c13a8c1
2 changed files with 100 additions and 80 deletions

View File

@ -14,10 +14,11 @@ config =
'Thread Expansion': true 'Thread Expansion': true
'Comment Expansion': true 'Comment Expansion': true
'Quick Reply': true 'Quick Reply': true
'Persistent QR': false
'Quick Report': true 'Quick Report': true
'Auto Watch': true 'Auto Watch': true
'Anonymize': false 'Anonymize': false
getValue = (name) -> getConfig = (name) ->
GM_getValue(name, config[name]) GM_getValue(name, config[name])
x = (path, root) -> x = (path, root) ->
root or= document.body root or= document.body
@ -242,7 +243,7 @@ options = ->
position(div) position(div)
html = '<div class="move">4chan X</div><div>' html = '<div class="move">4chan X</div><div>'
for option of config for option of config
checked = if getValue(option) then "checked" else "" checked = if getConfig(option) then "checked" else ""
html += "<label>#{option}<input #{checked} name=\"#{option}\" type=\"checkbox\"></label><br>" html += "<label>#{option}<input #{checked} name=\"#{option}\" type=\"checkbox\"></label><br>"
html += "<input type=\"button\" value=\"hidden: #{hiddenNum}\"><br>" html += "<input type=\"button\" value=\"hidden: #{hiddenNum}\"><br>"
html += '<a name="save">save</a> <a name="cancel">cancel</a></div>' html += '<a name="save">save</a> <a name="cancel">cancel</a></div>'
@ -320,7 +321,7 @@ hideThread = (div) ->
}) })
GM_setValue("hiddenThreads/#{BOARD}/", JSON.stringify(hiddenThreads)) GM_setValue("hiddenThreads/#{BOARD}/", JSON.stringify(hiddenThreads))
hide(div) hide(div)
if getValue('Show Stubs') if getConfig('Show Stubs')
a = tag('a') a = tag('a')
if span = $('.omittedposts', div) if span = $('.omittedposts', div)
n = Number(span.textContent.match(/\d+/)[0]) n = Number(span.textContent.match(/\d+/)[0])
@ -387,7 +388,7 @@ hideReply = (reply) ->
trip = $('span.postertrip', reply)?.textContent || '' trip = $('span.postertrip', reply)?.textContent || ''
table = x('ancestor::table', reply) table = x('ancestor::table', reply)
hide(table) hide(table)
if getValue('Show Stubs') if getConfig('Show Stubs')
a = tag('a') a = tag('a')
a.textContent = "[ + ] #{name} #{trip}" a.textContent = "[ + ] #{name} #{trip}"
a.className = 'pointer' a.className = 'pointer'
@ -415,18 +416,18 @@ iframeLoad = ->
return return
$('iframe').src = 'about:blank' $('iframe').src = 'about:blank'
window.location = 'javascript:Recaptcha.reload()'
qr = $('#qr') qr = $('#qr')
if error = GM_getValue('error') if error = GM_getValue('error')
$('form', qr).style.visibility = '' $('form', qr).style.visibility = ''
span = tag('span') span = n 'span', {
span.textContent = error textContent: error
span.className = 'error' className: 'error'
}
qr.appendChild(span) qr.appendChild(span)
if error is 'You seem to have mistyped the verification.' else unless getConfig('Persistent QR') and REPLY
window.location = 'javascript:Recaptcha.reload()' remove qr
else
remove(qr)
window.location = 'javascript:Recaptcha.reload()'
submit = (e) -> submit = (e) ->
@ -457,7 +458,6 @@ autohide = ->
quickReply = (e) -> quickReply = (e) ->
e.preventDefault()
if !qr = $('#qr') if !qr = $('#qr')
#make quick reply dialog #make quick reply dialog
qr = tag('div') qr = tag('div')
@ -489,9 +489,6 @@ quickReply = (e) ->
form = $ 'form[name=post]' form = $ 'form[name=post]'
clone = form.cloneNode(true) 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 #remove recaptcha scripts
for script in $$ 'script', clone for script in $$ 'script', clone
remove script remove script
@ -508,16 +505,19 @@ quickReply = (e) ->
qr.appendChild(clone) qr.appendChild(clone)
document.body.appendChild(qr) document.body.appendChild(qr)
selection = window.getSelection() if e
id = x('preceding::span[@id][1]', selection.anchorNode)?.id e.preventDefault()
text = selection.toString()
textarea = $('textarea', qr) selection = window.getSelection()
textarea.focus() id = x('preceding::span[@id][1]', selection.anchorNode)?.id
#we can't just use @textContent b/c of the xxxs. goddamit moot. text = selection.toString()
textarea.value += '>>' + @parentNode.id.match(/\d+$/)[0] + '\n'
if text and id is this.parentNode.id textarea = $('textarea', qr)
textarea.value += ">#{text}\n" 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 = -> watch = ->
id = this.nextSibling.name id = this.nextSibling.name
@ -708,7 +708,7 @@ inBefore(text, a)
for el in $$ '#recaptcha_table a' for el in $$ '#recaptcha_table a'
el.tabIndex = 1 el.tabIndex = 1
if getValue('Reply Hiding') if getConfig('Reply Hiding')
callbacks.push((root) -> callbacks.push((root) ->
tds = $$('td.doubledash', root) tds = $$('td.doubledash', root)
for td in tds for td in tds
@ -725,10 +725,11 @@ if getValue('Reply Hiding')
hideReply(next) hideReply(next)
) )
if getValue('Quick Reply') if getConfig('Quick Reply')
iframe = tag('iframe') iframe = n 'iframe', {
name: 'iframe'
}
hide(iframe) hide(iframe)
iframe.name = 'iframe'
iframe.addEventListener('load', iframeLoad, true) iframe.addEventListener('load', iframeLoad, true)
document.body.appendChild(iframe) document.body.appendChild(iframe)
@ -738,20 +739,25 @@ if getValue('Quick Reply')
quote.addEventListener('click', quickReply, true) 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) -> callbacks.push((root) ->
arr = $$('span[id^=no]', root) arr = $$('span[id^=no]', root)
for el in arr for el in arr
a = tag('a') a = n 'a', {
a.textContent = '[ ! ]' textContent: '[ ! ]'
a.className = 'pointer' className: 'pointer'
}
a.addEventListener('click', report, true) a.addEventListener('click', report, true)
inAfter(el, a) inAfter(el, a)
inAfter(el, document.createTextNode(' ')) inAfter(el, document.createTextNode(' '))
) )
if getValue('Thread Watcher') if getConfig('Thread Watcher')
#create watcher #create watcher
watcher = tag('div') watcher = tag('div')
watcher.innerHTML = '<div class="move">Thread Watcher</div><div></div>' watcher.innerHTML = '<div class="move">Thread Watcher</div><div></div>'
@ -778,7 +784,7 @@ if getValue('Thread Watcher')
img.addEventListener('click', watch, true) img.addEventListener('click', watch, true)
inBefore(input, img) inBefore(input, img)
if getValue('Anonymize') if getConfig('Anonymize')
callbacks.push((root) -> callbacks.push((root) ->
names = $$('span.postername, span.commentpostername', root) names = $$('span.postername, span.commentpostername', root)
for name in names for name in names
@ -791,7 +797,7 @@ if getValue('Anonymize')
remove(trip) remove(trip)
) )
if getValue('Reply Navigation') if getConfig('Reply Navigation')
callbacks.push((root) -> callbacks.push((root) ->
arr = $$('span[id^=norep]', root) arr = $$('span[id^=norep]', root)
for el in arr for el in arr
@ -811,19 +817,23 @@ if getValue('Reply Navigation')
inAfter(el, span) inAfter(el, span)
) )
if REPLY
if getConfig('Quick Reply') and getConfig('Persistent QR')
quickReply()
$('#qr input[title=autohide]').click()
if not REPLY else # not reply
if getValue('Thread Hiding') if getConfig('Thread Hiding')
delform = $('form[name=delform]') delform = $('form[name=delform]')
#don't confuse other scripts #don't confuse other scripts
document.addEventListener('DOMNodeInserted', stopPropagation, true) document.addEventListener('DOMNodeInserted', stopPropagation, true)
threadF(delform.firstChild) threadF(delform.firstChild)
document.removeEventListener('DOMNodeInserted', stopPropagation, true) document.removeEventListener('DOMNodeInserted', stopPropagation, true)
if getValue('Auto Watch') if getConfig('Auto Watch')
$('form[name="post"]').addEventListener('submit', autoWatch, true) $('form[name="post"]').addEventListener('submit', autoWatch, true)
if getValue('Thread Navigation') if getConfig('Thread Navigation')
arr = $$('div > span.filesize, form > span.filesize') arr = $$('div > span.filesize, form > span.filesize')
i = 0 i = 0
l = arr.length l = arr.length
@ -861,7 +871,7 @@ if not REPLY
if location.hash is '#1' if location.hash is '#1'
window.location = window.location window.location = window.location
if getValue('Thread Expansion') if getConfig('Thread Expansion')
omitted = $$('span.omittedposts') omitted = $$('span.omittedposts')
for span in omitted for span in omitted
a = tag('a') a = tag('a')
@ -870,7 +880,7 @@ if not REPLY
a.addEventListener('click', expandThread, true) a.addEventListener('click', expandThread, true)
replace(span, a) replace(span, a)
if getValue('Comment Expansion') if getConfig('Comment Expansion')
as = $$('span.abbr a') as = $$('span.abbr a')
for a in as for a in as
a.addEventListener('click', expandComment, true) a.addEventListener('click', expandComment, true)

View File

@ -1,5 +1,5 @@
(function() { (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; var __hasProp = Object.prototype.hasOwnProperty;
config = { config = {
'Thread Hiding': true, 'Thread Hiding': true,
@ -11,11 +11,12 @@
'Thread Expansion': true, 'Thread Expansion': true,
'Comment Expansion': true, 'Comment Expansion': true,
'Quick Reply': true, 'Quick Reply': true,
'Persistent QR': false,
'Quick Report': true, 'Quick Report': true,
'Auto Watch': true, 'Auto Watch': true,
'Anonymize': false 'Anonymize': false
}; };
getValue = function(name) { getConfig = function(name) {
return GM_getValue(name, config[name]); return GM_getValue(name, config[name]);
}; };
x = function(path, root) { x = function(path, root) {
@ -277,7 +278,7 @@
for (option in _ref2) { for (option in _ref2) {
if (!__hasProp.call(_ref2, option)) continue; if (!__hasProp.call(_ref2, option)) continue;
_i = _ref2[option]; _i = _ref2[option];
checked = getValue(option) ? "checked" : ""; checked = getConfig(option) ? "checked" : "";
html += ("<label>" + (option) + "<input " + (checked) + " name=\"" + (option) + "\" type=\"checkbox\"></label><br>"); html += ("<label>" + (option) + "<input " + (checked) + " name=\"" + (option) + "\" type=\"checkbox\"></label><br>");
} }
html += ("<input type=\"button\" value=\"hidden: " + (hiddenNum) + "\"><br>"); html += ("<input type=\"button\" value=\"hidden: " + (hiddenNum) + "\"><br>");
@ -354,7 +355,7 @@
GM_setValue("hiddenThreads/" + (BOARD) + "/", JSON.stringify(hiddenThreads)); GM_setValue("hiddenThreads/" + (BOARD) + "/", JSON.stringify(hiddenThreads));
} }
hide(div); hide(div);
if (getValue('Show Stubs')) { if (getConfig('Show Stubs')) {
a = tag('a'); a = tag('a');
if (span = $('.omittedposts', div)) { if (span = $('.omittedposts', div)) {
n = Number(span.textContent.match(/\d+/)[0]); n = Number(span.textContent.match(/\d+/)[0]);
@ -423,7 +424,7 @@
trip = ((typeof (_ref3 = ((_ref2 = $('span.postertrip', reply)))) === "undefined" || _ref3 === null) ? undefined : _ref3.textContent) || ''; trip = ((typeof (_ref3 = ((_ref2 = $('span.postertrip', reply)))) === "undefined" || _ref3 === null) ? undefined : _ref3.textContent) || '';
table = x('ancestor::table', reply); table = x('ancestor::table', reply);
hide(table); hide(table);
if (getValue('Show Stubs')) { if (getConfig('Show Stubs')) {
a = tag('a'); a = tag('a');
a.textContent = ("[ + ] " + (name) + " " + (trip)); a.textContent = ("[ + ] " + (name) + " " + (trip));
a.className = 'pointer'; a.className = 'pointer';
@ -455,17 +456,17 @@
return null; return null;
} }
$('iframe').src = 'about:blank'; $('iframe').src = 'about:blank';
window.location = 'javascript:Recaptcha.reload()';
qr = $('#qr'); qr = $('#qr');
if (error = GM_getValue('error')) { if (error = GM_getValue('error')) {
$('form', qr).style.visibility = ''; $('form', qr).style.visibility = '';
span = tag('span'); span = n('span', {
span.textContent = error; textContent: error,
span.className = 'error'; className: 'error'
qr.appendChild(span); });
return error === 'You seem to have mistyped the verification.' ? (window.location = 'javascript:Recaptcha.reload()') : null; return qr.appendChild(span);
} else { } else {
remove(qr); return !(getConfig('Persistent QR') && REPLY) ? remove(qr) : null;
return (window.location = 'javascript:Recaptcha.reload()');
} }
}; };
submit = function(e) { submit = function(e) {
@ -500,7 +501,6 @@
}; };
quickReply = function(e) { quickReply = function(e) {
var _i, _len, _ref2, _ref3, autohideB, clone, closeB, div, form, input, qr, script, selection, text, textarea, xpath; var _i, _len, _ref2, _ref3, autohideB, clone, closeB, div, form, input, qr, script, selection, text, textarea, xpath;
e.preventDefault();
if (!(qr = $('#qr'))) { if (!(qr = $('#qr'))) {
qr = tag('div'); qr = tag('div');
qr.id = 'qr'; qr.id = 'qr';
@ -528,7 +528,6 @@
div.appendChild(closeB); div.appendChild(closeB);
form = $('form[name=post]'); form = $('form[name=post]');
clone = form.cloneNode(true); clone = form.cloneNode(true);
$('input[name=recaptcha_response_field]', form).id = '';
_ref2 = $$('script', clone); _ref2 = $$('script', clone);
for (_i = 0, _len = _ref2.length; _i < _len; _i++) { for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
script = _ref2[_i]; script = _ref2[_i];
@ -548,13 +547,16 @@
qr.appendChild(clone); qr.appendChild(clone);
document.body.appendChild(qr); document.body.appendChild(qr);
} }
selection = window.getSelection(); if (e) {
id = (typeof (_ref3 = ((_ref2 = x('preceding::span[@id][1]', selection.anchorNode)))) === "undefined" || _ref3 === null) ? undefined : _ref3.id; e.preventDefault();
text = selection.toString(); selection = window.getSelection();
textarea = $('textarea', qr); id = (typeof (_ref3 = ((_ref2 = x('preceding::span[@id][1]', selection.anchorNode)))) === "undefined" || _ref3 === null) ? undefined : _ref3.id;
textarea.focus(); text = selection.toString();
textarea.value += '>>' + this.parentNode.id.match(/\d+$/)[0] + '\n'; textarea = $('textarea', qr);
return text && id === this.parentNode.id ? textarea.value += (">" + (text) + "\n") : null; textarea.focus();
textarea.value += '>>' + this.parentNode.id.match(/\d+$/)[0] + '\n';
return text && id === this.parentNode.id ? textarea.value += (">" + (text) + "\n") : null;
}
}; };
watch = function() { watch = function() {
var text; var text;
@ -777,7 +779,7 @@
el = _ref[_i]; el = _ref[_i];
el.tabIndex = 1; el.tabIndex = 1;
} }
if (getValue('Reply Hiding')) { if (getConfig('Reply Hiding')) {
callbacks.push(function(root) { callbacks.push(function(root) {
var _j, _k, _len2, _len3, _ref2, _ref3, _result, _result2, next, obj, td, tds; var _j, _k, _len2, _len3, _ref2, _ref3, _result, _result2, next, obj, td, tds;
tds = $$('td.doubledash', root); tds = $$('td.doubledash', root);
@ -803,10 +805,11 @@
return _result; return _result;
}); });
} }
if (getValue('Quick Reply')) { if (getConfig('Quick Reply')) {
iframe = tag('iframe'); iframe = n('iframe', {
name: 'iframe'
});
hide(iframe); hide(iframe);
iframe.name = 'iframe';
iframe.addEventListener('load', iframeLoad, true); iframe.addEventListener('load', iframeLoad, true);
document.body.appendChild(iframe); document.body.appendChild(iframe);
callbacks.push(function(root) { callbacks.push(function(root) {
@ -819,8 +822,9 @@
} }
return _result; return _result;
}); });
$('form[name=post] input[name=recaptcha_response_field]').id = '';
} }
if (getValue('Quick Report')) { if (getConfig('Quick Report')) {
callbacks.push(function(root) { callbacks.push(function(root) {
var _j, _len2, _ref2, _result, arr, el; var _j, _len2, _ref2, _result, arr, el;
arr = $$('span[id^=no]', root); arr = $$('span[id^=no]', root);
@ -828,9 +832,10 @@
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
el = _ref2[_j]; el = _ref2[_j];
_result.push((function() { _result.push((function() {
a = tag('a'); a = n('a', {
a.textContent = '[ ! ]'; textContent: '[ ! ]',
a.className = 'pointer'; className: 'pointer'
});
a.addEventListener('click', report, true); a.addEventListener('click', report, true);
inAfter(el, a); inAfter(el, a);
return inAfter(el, document.createTextNode(' ')); return inAfter(el, document.createTextNode(' '));
@ -839,7 +844,7 @@
return _result; return _result;
}); });
} }
if (getValue('Thread Watcher')) { if (getConfig('Thread Watcher')) {
watcher = tag('div'); watcher = tag('div');
watcher.innerHTML = '<div class="move">Thread Watcher</div><div></div>'; watcher.innerHTML = '<div class="move">Thread Watcher</div><div></div>';
watcher.className = 'reply'; watcher.className = 'reply';
@ -869,7 +874,7 @@
inBefore(input, img); inBefore(input, img);
} }
} }
if (getValue('Anonymize')) { if (getConfig('Anonymize')) {
callbacks.push(function(root) { callbacks.push(function(root) {
var _k, _len3, _ref3, _result, name, names, trip, trips; var _k, _len3, _ref3, _result, name, names, trip, trips;
names = $$('span.postername, span.commentpostername', root); names = $$('span.postername, span.commentpostername', root);
@ -887,7 +892,7 @@
return _result; return _result;
}); });
} }
if (getValue('Reply Navigation')) { if (getConfig('Reply Navigation')) {
callbacks.push(function(root) { callbacks.push(function(root) {
var _k, _len3, _ref3, _result, arr, down, el, span, up; var _k, _len3, _ref3, _result, arr, down, el, span, up;
arr = $$('span[id^=norep]', root); arr = $$('span[id^=norep]', root);
@ -914,17 +919,22 @@
return _result; return _result;
}); });
} }
if (!REPLY) { if (REPLY) {
if (getValue('Thread Hiding')) { if (getConfig('Quick Reply') && getConfig('Persistent QR')) {
quickReply();
$('#qr input[title=autohide]').click();
}
} else {
if (getConfig('Thread Hiding')) {
delform = $('form[name=delform]'); delform = $('form[name=delform]');
document.addEventListener('DOMNodeInserted', stopPropagation, true); document.addEventListener('DOMNodeInserted', stopPropagation, true);
threadF(delform.firstChild); threadF(delform.firstChild);
document.removeEventListener('DOMNodeInserted', stopPropagation, true); document.removeEventListener('DOMNodeInserted', stopPropagation, true);
} }
if (getValue('Auto Watch')) { if (getConfig('Auto Watch')) {
$('form[name="post"]').addEventListener('submit', autoWatch, true); $('form[name="post"]').addEventListener('submit', autoWatch, true);
} }
if (getValue('Thread Navigation')) { if (getConfig('Thread Navigation')) {
arr = $$('div > span.filesize, form > span.filesize'); arr = $$('div > span.filesize, form > span.filesize');
i = 0; i = 0;
l = arr.length; l = arr.length;
@ -966,7 +976,7 @@
window.location = window.location; window.location = window.location;
} }
} }
if (getValue('Thread Expansion')) { if (getConfig('Thread Expansion')) {
omitted = $$('span.omittedposts'); omitted = $$('span.omittedposts');
_ref = omitted; _ref = omitted;
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@ -978,7 +988,7 @@
replace(span, a); replace(span, a);
} }
} }
if (getValue('Comment Expansion')) { if (getConfig('Comment Expansion')) {
as = $$('span.abbr a'); as = $$('span.abbr a');
_ref = as; _ref = as;
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {