rewrite qr; encapsulate, html5 postmessage
This commit is contained in:
parent
dda969cac7
commit
0181da694f
411
4chan_x.js
411
4chan_x.js
@ -56,7 +56,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var $, $$, DAY, a, arr, as, autoWatch, autohide, b, board, callback, changeCheckbox, changeValue, clearHidden, closeQR, config, cooldown, cutoff, d, delform, down, editSauce, el, expand, expandComment, expandThread, formSubmit, g, getConfig, getThread, getTime, hide, hideReply, hideThread, href, html, i, id, iframe, iframeLoad, imageClick, imageExpand, imageExpandClick, imageHover, imageResize, imageThumb, imageToggle, imageType, imageTypeChange, img, inAfter, inBefore, input, inputs, keyModeInsert, keyModeNormal, keydown, keypress, l1, lastChecked, log, m, mv, n, navbotr, navtopr, nodeInserted, now, omitted, onloadComment, onloadThread, option, options, parseResponse, pathname, qrListener, qrText, quickReply, recaptcha, recaptchaListener, recaptchaReload, redirect, replace, replyNav, report, request, rm, scroll, scrollThread, show, showReply, showThread, slice, span, src, start, stopPropagation, temp, text, textContent, thread, threadF, threads, tn, tzOffset, ui, up, updateAuto, updateCallback, updateFavicon, updateInterval, updateNow, updateTime, updateTitle, updateVerbose, updaterMake, watch, watchX, watcher, watcherUpdate, x, zeroPad, _, _base, _i, _j, _k, _l, _len, _len2, _len3, _len4, _len5, _len6, _len7, _m, _n, _ref, _ref2, _ref3, _ref4, _ref5;
|
var $, $$, DAY, a, arr, as, autoWatch, callback, changeCheckbox, changeValue, clearHidden, closeQR, config, cooldown, cutoff, d, delform, down, editSauce, el, expand, expandComment, expandThread, g, getConfig, getThread, getTime, hide, hideReply, hideThread, href, html, i, id, imageClick, imageExpand, imageExpandClick, imageHover, imageResize, imageThumb, imageToggle, imageType, imageTypeChange, img, inAfter, inBefore, input, inputs, keyModeInsert, keyModeNormal, keydown, keypress, l1, lastChecked, log, m, mv, n, navbotr, navtopr, nodeInserted, now, omitted, onloadComment, onloadThread, option, options, parseResponse, pathname, qr, recaptcha, recaptchaListener, recaptchaReload, redirect, replace, replyNav, report, request, rm, scroll, scrollThread, show, showReply, showThread, slice, span, src, start, stopPropagation, temp, text, textContent, threadF, threads, tn, tzOffset, ui, up, updateAuto, updateCallback, updateFavicon, updateInterval, updateNow, updateTime, updateTitle, updateVerbose, updaterMake, watch, watchX, watcher, watcherUpdate, x, zeroPad, _i, _j, _k, _l, _len, _len2, _len3, _len4, _len5, _len6, _len7, _m, _n, _ref, _ref2, _ref3, _ref4;
|
||||||
var __slice = Array.prototype.slice;
|
var __slice = Array.prototype.slice;
|
||||||
if (typeof console != "undefined" && console !== null) {
|
if (typeof console != "undefined" && console !== null) {
|
||||||
log = console.log;
|
log = console.log;
|
||||||
@ -241,6 +241,29 @@
|
|||||||
return object;
|
return object;
|
||||||
};
|
};
|
||||||
$.extend($, {
|
$.extend($, {
|
||||||
|
addClass: function(el, className) {
|
||||||
|
return el.className += ' ' + className;
|
||||||
|
},
|
||||||
|
removeClass: function(el, className) {
|
||||||
|
return el.className = el.className.replace(' ' + className, '');
|
||||||
|
},
|
||||||
|
rm: function(el) {
|
||||||
|
return el.parentNode.removeChild(el);
|
||||||
|
},
|
||||||
|
append: function(parent, child) {
|
||||||
|
return parent.appendChild(child);
|
||||||
|
},
|
||||||
|
before: function(root, el) {
|
||||||
|
return root.parentNode.insertBefore(el, root);
|
||||||
|
},
|
||||||
|
el: function(tag, properties) {
|
||||||
|
var el;
|
||||||
|
el = d.createElement(tag);
|
||||||
|
if (properties) {
|
||||||
|
$.extend(el, properties);
|
||||||
|
}
|
||||||
|
return el;
|
||||||
|
},
|
||||||
bind: function(el, eventType, handler) {
|
bind: function(el, eventType, handler) {
|
||||||
return el.addEventListener(eventType, handler, true);
|
return el.addEventListener(eventType, handler, true);
|
||||||
},
|
},
|
||||||
@ -387,17 +410,6 @@
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
autohide = function() {
|
|
||||||
var klass, qr;
|
|
||||||
qr = $('#qr');
|
|
||||||
klass = qr.className;
|
|
||||||
if (this.checked) {
|
|
||||||
klass += ' auto';
|
|
||||||
} else {
|
|
||||||
klass = klass.replace(' auto', '');
|
|
||||||
}
|
|
||||||
return qr.className = klass;
|
|
||||||
};
|
|
||||||
autoWatch = function() {
|
autoWatch = function() {
|
||||||
var autoText;
|
var autoText;
|
||||||
autoText = $('textarea', this).value.slice(0, 25);
|
autoText = $('textarea', this).value.slice(0, 25);
|
||||||
@ -500,28 +512,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
formSubmit = function(e) {
|
|
||||||
var recaptcha, span, _ref;
|
|
||||||
if (span = this.nextSibling) {
|
|
||||||
rm(span);
|
|
||||||
}
|
|
||||||
recaptcha = $('input[name=recaptcha_response_field]', this);
|
|
||||||
if (recaptcha.value) {
|
|
||||||
if ((_ref = $('#qr input[title=autohide]:not(:checked)')) != null) {
|
|
||||||
_ref.click();
|
|
||||||
}
|
|
||||||
return g.sage = $('#qr input[name=email]').value === 'sage' ? true : false;
|
|
||||||
} else {
|
|
||||||
e.preventDefault();
|
|
||||||
span = n('span', {
|
|
||||||
className: 'error',
|
|
||||||
textContent: 'You forgot to type in the verification.'
|
|
||||||
});
|
|
||||||
mv(span, this.parentNode);
|
|
||||||
alert('You forgot to type in the verification.');
|
|
||||||
return recaptcha.focus();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
hideReply = function(reply) {
|
hideReply = function(reply) {
|
||||||
var a, div, name, p, table, trip, _ref;
|
var a, div, name, p, table, trip, _ref;
|
||||||
if (p = this.parentNode) {
|
if (p = this.parentNode) {
|
||||||
@ -576,42 +566,6 @@
|
|||||||
return inBefore(div, a);
|
return inBefore(div, a);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
iframeLoad = function() {
|
|
||||||
var auto, error, f, qr, span, submit, _ref, _ref2;
|
|
||||||
if (g.iframe = !g.iframe) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$('iframe').src = 'about:blank';
|
|
||||||
qr = $('#qr');
|
|
||||||
if (error = GM_getValue('error')) {
|
|
||||||
span = n('span', {
|
|
||||||
textContent: error,
|
|
||||||
className: 'error'
|
|
||||||
});
|
|
||||||
mv(span, qr);
|
|
||||||
if ((_ref = $('input[title=autohide]:checked', qr)) != null) {
|
|
||||||
_ref.click();
|
|
||||||
}
|
|
||||||
} else if (g.REPLY && getConfig('Persistent QR')) {
|
|
||||||
$('textarea', qr).value = '';
|
|
||||||
$('input[name=recaptcha_response_field]', qr).value = '';
|
|
||||||
f = $('input[type=file]', qr).parentNode;
|
|
||||||
f.innerHTML = f.innerHTML;
|
|
||||||
submit = $('input[type=submit]', qr);
|
|
||||||
submit.value = g.sage ? 60 : 30;
|
|
||||||
submit.disabled = true;
|
|
||||||
window.setTimeout(cooldown, 1000);
|
|
||||||
auto = submit.previousSibling.lastChild;
|
|
||||||
if (auto.checked) {
|
|
||||||
if ((_ref2 = $('input[title=autohide]:checked', qr)) != null) {
|
|
||||||
_ref2.click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rm(qr);
|
|
||||||
}
|
|
||||||
return recaptchaReload();
|
|
||||||
};
|
|
||||||
imageHover = {
|
imageHover = {
|
||||||
init: function() {
|
init: function() {
|
||||||
var img;
|
var img;
|
||||||
@ -830,9 +784,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (e.shiftKey) {
|
if (e.shiftKey) {
|
||||||
return quickReply(qrLink);
|
$.append(d.body, qr.dialog(qrLink));
|
||||||
|
return $('#qr textarea').focus();
|
||||||
} else {
|
} else {
|
||||||
return quickReply(qrLink, qrText(qrLink));
|
e = {
|
||||||
|
preventDefault: function() {},
|
||||||
|
target: qrLink
|
||||||
|
};
|
||||||
|
return qr.cb.quote(e);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "J":
|
case "J":
|
||||||
@ -926,7 +885,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
nodeInserted = function(e) {
|
nodeInserted = function(e) {
|
||||||
var callback, qr, target, _i, _len, _ref, _results;
|
var callback, dialog, target, _i, _len, _ref, _results;
|
||||||
target = e.target;
|
target = e.target;
|
||||||
if (target.nodeName === 'TABLE') {
|
if (target.nodeName === 'TABLE') {
|
||||||
_ref = g.callbacks;
|
_ref = g.callbacks;
|
||||||
@ -936,9 +895,9 @@
|
|||||||
_results.push(callback(target));
|
_results.push(callback(target));
|
||||||
}
|
}
|
||||||
return _results;
|
return _results;
|
||||||
} else if (target.id === 'recaptcha_challenge_field' && (qr = $('#qr'))) {
|
} else if (target.id === 'recaptcha_challenge_field' && (dialog = $('#qr'))) {
|
||||||
$('#recaptcha_image img', qr).src = "http://www.google.com/recaptcha/api/image?c=" + target.value;
|
$('#recaptcha_image img', dialog).src = "http://www.google.com/recaptcha/api/image?c=" + target.value;
|
||||||
return $('#recaptcha_challenge_field', qr).value = target.value;
|
return $('#recaptcha_challenge_field', dialog).value = target.value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
onloadComment = function(responseText, a, href) {
|
onloadComment = function(responseText, a, href) {
|
||||||
@ -1029,73 +988,200 @@
|
|||||||
opbq = $('blockquote', body);
|
opbq = $('blockquote', body);
|
||||||
return [replies, opbq];
|
return [replies, opbq];
|
||||||
};
|
};
|
||||||
qrListener = function(e) {
|
qr = {
|
||||||
var link, text;
|
init: function() {
|
||||||
e.preventDefault();
|
var iframe;
|
||||||
link = e.target;
|
g.callbacks.push(qr.cb.node);
|
||||||
text = qrText(link);
|
iframe = $.el('iframe', {
|
||||||
return quickReply(link, text);
|
name: 'iframe'
|
||||||
};
|
});
|
||||||
qrText = function(link) {
|
$.append(d.body, iframe);
|
||||||
var id, s, selection, text, _ref;
|
$.bind(iframe, 'load', qr.cb.load);
|
||||||
text = '>>' + link.parentNode.id.match(/\d+$/)[0] + '\n';
|
$.bind(window, 'message', qr.cb.messageTop);
|
||||||
selection = window.getSelection();
|
return $('#recaptcha_response_field').id = '';
|
||||||
id = (_ref = x('preceding::span[@id][1]', selection.anchorNode)) != null ? _ref.id : void 0;
|
},
|
||||||
if ((s = selection.toString()) && (id === link.parentNode.id)) {
|
autohide: {
|
||||||
text += ">" + s;
|
set: function() {
|
||||||
}
|
var _ref;
|
||||||
return text;
|
return (_ref = $('#qr input[title=autohide]:not(:checked)')) != null ? _ref.click() : void 0;
|
||||||
};
|
},
|
||||||
quickReply = function(link, text) {
|
unset: function() {
|
||||||
var auto, autoBox, clone, form, html, input, qr, script, submit, textarea, xpath, _i, _len, _ref, _ref2;
|
var _ref;
|
||||||
if (!(qr = $('#qr'))) {
|
return (_ref = $('#qr input[title=autohide]:checked')) != null ? _ref.click() : void 0;
|
||||||
html = "<div class=move>Quick Reply <input type=checkbox title=autohide><a name=close title=close>X</a></div>";
|
}
|
||||||
qr = ui.dialog('qr', 'topleft', html);
|
},
|
||||||
$('input[title=autohide]', qr).addEventListener('click', autohide, true);
|
cb: {
|
||||||
form = $('form[name=post]');
|
autohide: function(e) {
|
||||||
clone = form.cloneNode(true);
|
var dialog;
|
||||||
|
dialog = $('#qr');
|
||||||
|
if (this.checked) {
|
||||||
|
return $.addClass(dialog, 'auto');
|
||||||
|
} else {
|
||||||
|
return $.removeClass(dialog, 'auto');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
load: function(e) {
|
||||||
|
return e.target.contentWindow.postMessage('', '*');
|
||||||
|
},
|
||||||
|
messageIframe: function(e) {
|
||||||
|
var message;
|
||||||
|
message = $('table b').firstChild.textContent;
|
||||||
|
e.source.postMessage(message, '*');
|
||||||
|
return window.location = 'about:blank';
|
||||||
|
},
|
||||||
|
messageTop: function(e) {
|
||||||
|
var data, dialog, error;
|
||||||
|
data = e.data;
|
||||||
|
dialog = $('#qr');
|
||||||
|
if (data === 'Post successful!') {
|
||||||
|
if (dialog) {
|
||||||
|
if (getConfig('Persistent QR')) {
|
||||||
|
qr.refresh(dialog);
|
||||||
|
} else {
|
||||||
|
$.rm(dialog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error = $.el('span', {
|
||||||
|
className: 'error',
|
||||||
|
textContent: data
|
||||||
|
});
|
||||||
|
$.append(dialog, error);
|
||||||
|
qr.autohide.unset();
|
||||||
|
}
|
||||||
|
return recaptchaReload();
|
||||||
|
},
|
||||||
|
node: function(root) {
|
||||||
|
var quote, quotes, _i, _len, _results;
|
||||||
|
quotes = $$('a.quotejs:not(:first-child)', root);
|
||||||
|
_results = [];
|
||||||
|
for (_i = 0, _len = quotes.length; _i < _len; _i++) {
|
||||||
|
quote = quotes[_i];
|
||||||
|
_results.push($.bind(quote, 'click', qr.cb.quote));
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
},
|
||||||
|
submit: function(e) {
|
||||||
|
var recaptcha, span;
|
||||||
|
if (span = this.nextSibling) {
|
||||||
|
$.rm(span);
|
||||||
|
}
|
||||||
|
recaptcha = $('input[name=recaptcha_response_field]', this);
|
||||||
|
if (recaptcha.value) {
|
||||||
|
qr.autohide.set();
|
||||||
|
return g.sage = $('#qr input[name=email]').value === 'sage';
|
||||||
|
} else {
|
||||||
|
e.preventDefault();
|
||||||
|
span = $.el('span', {
|
||||||
|
className: 'error',
|
||||||
|
textContent: 'You forgot to type in the verification.'
|
||||||
|
});
|
||||||
|
$.append(this.parentNode, span);
|
||||||
|
alert('You forgot to type in the verification.');
|
||||||
|
return recaptcha.focus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
quote: function(e) {
|
||||||
|
var dialog, id, s, selection, selectionID, ta, target, text, _ref;
|
||||||
|
e.preventDefault();
|
||||||
|
target = e.target;
|
||||||
|
if (!(dialog = $('#qr'))) {
|
||||||
|
dialog = qr.dialog(target);
|
||||||
|
}
|
||||||
|
id = target.textContent;
|
||||||
|
text = ">>" + id + "\n";
|
||||||
|
selection = window.getSelection();
|
||||||
|
if (s = selection.toString()) {
|
||||||
|
selectionID = (_ref = x('preceding::input[@type="checkbox"][1]', selection.anchorNode)) != null ? _ref.name : void 0;
|
||||||
|
if (selectionID === id) {
|
||||||
|
text += ">" + s + "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ta = $('textarea', dialog);
|
||||||
|
ta.focus();
|
||||||
|
return ta.value += text;
|
||||||
|
},
|
||||||
|
refresh: function(dialog) {
|
||||||
|
var auto, f, submit, _ref;
|
||||||
|
$('textarea', dialog).value = '';
|
||||||
|
$('input[name=recaptcha_response_field]', dialog).value = '';
|
||||||
|
f = $('input[type=file]', dialog).parentNode;
|
||||||
|
f.innerHTML = f.innerHTML;
|
||||||
|
submit = $('input[type=submit]', qr);
|
||||||
|
submit.value = g.sage ? 60 : 30;
|
||||||
|
submit.disabled = true;
|
||||||
|
window.setTimeout(cooldown, 1000);
|
||||||
|
auto = submit.previousSibling.lastChild;
|
||||||
|
if (auto.checked) {
|
||||||
|
return (_ref = $('input[title=autohide]:checked', qr)) != null ? _ref.click() : void 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dialog: function(link) {
|
||||||
|
var auto, autobox, clone, dialog, el, html, input, script, submit, xpath, _i, _len, _ref;
|
||||||
|
html = "<div class=move>Quick Reply <input type=checkbox title=autohide> <a name=close title=close>X</a></div>";
|
||||||
|
dialog = ui.dialog('qr', {
|
||||||
|
top: '0px',
|
||||||
|
left: '0px'
|
||||||
|
}, html);
|
||||||
|
el = $('input[title=autohide]', dialog);
|
||||||
|
$.bind(el, 'click', qr.cb.autohide);
|
||||||
|
clone = $('form[name=post]').cloneNode(true);
|
||||||
_ref = $$('script', clone);
|
_ref = $$('script', clone);
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
script = _ref[_i];
|
script = _ref[_i];
|
||||||
rm(script);
|
$.rm(script);
|
||||||
}
|
}
|
||||||
m($('input[name=recaptcha_response_field]', clone), {
|
clone.target = 'iframe';
|
||||||
listener: ['keydown', recaptchaListener]
|
$.bind(clone, 'submit', qr.cb.submit);
|
||||||
});
|
$.bind($('input[name=recaptcha_response_field]', clone), 'keydown', recaptchaListener);
|
||||||
m(clone, {
|
|
||||||
listener: ['submit', formSubmit],
|
|
||||||
target: 'iframe'
|
|
||||||
});
|
|
||||||
if (!g.REPLY) {
|
if (!g.REPLY) {
|
||||||
xpath = 'preceding::span[@class="postername"][1]/preceding::input[1]';
|
xpath = 'preceding::span[@class="postername"][1]/preceding::input[1]';
|
||||||
input = n('input', {
|
input = $.el('input', {
|
||||||
type: 'hidden',
|
type: 'hidden',
|
||||||
name: 'resto',
|
name: 'resto',
|
||||||
value: x(xpath, link).name
|
value: x(xpath, link).name
|
||||||
});
|
});
|
||||||
mv(input, clone);
|
$.append(clone, input);
|
||||||
} else if (getConfig('Persistent QR')) {
|
} else if (getConfig('Persistent QR')) {
|
||||||
submit = $('input[type=submit]', clone);
|
submit = $('input[type=submit]', clone);
|
||||||
auto = n('label', {
|
auto = $.el('label', {
|
||||||
textContent: 'Auto'
|
textContent: 'Auto'
|
||||||
});
|
});
|
||||||
autoBox = n('input', {
|
autobox = $.el('input', {
|
||||||
type: 'checkbox'
|
type: 'checkbox'
|
||||||
});
|
});
|
||||||
mv(autoBox, auto);
|
$.append(auto, autobox);
|
||||||
inBefore(submit, auto);
|
$.before(submit, auto);
|
||||||
|
}
|
||||||
|
$.append(dialog, clone);
|
||||||
|
$.append(d.body, dialog);
|
||||||
|
dialog.style.width = dialog.offsetWidth;
|
||||||
|
return dialog;
|
||||||
|
},
|
||||||
|
persist: function() {
|
||||||
|
$.append(d.body, qr.dialog());
|
||||||
|
return qr.autohide.set();
|
||||||
|
},
|
||||||
|
sys: function() {
|
||||||
|
var board, html, id, recaptcha, thread, _, _base, _ref, _ref2;
|
||||||
|
$.bind(window, 'message', qr.cb.messageIframe);
|
||||||
|
if (recaptcha = $('#recaptcha_response_field')) {
|
||||||
|
$.bind(recaptcha, 'keydown', recaptchaListener);
|
||||||
|
}
|
||||||
|
if (getConfig('Auto Watch')) {
|
||||||
|
html = $('b').innerHTML;
|
||||||
|
_ref = html.match(/<!-- thread:(\d+),no:(\d+) -->/), _ = _ref[0], thread = _ref[1], id = _ref[2];
|
||||||
|
if (thread === '0') {
|
||||||
|
_ref2 = $('meta', d).content.match(/4chan.org\/(\w+)\//), _ = _ref2[0], board = _ref2[1];
|
||||||
|
(_base = g.watched)[board] || (_base[board] = []);
|
||||||
|
g.watched[board].push({
|
||||||
|
id: id,
|
||||||
|
text: GM_getValue('autoText')
|
||||||
|
});
|
||||||
|
return GM_setValue('watched', JSON.stringify(g.watched));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mv(clone, qr);
|
|
||||||
mv(qr, d.body);
|
|
||||||
qr.style.width = qr.offsetWidth;
|
|
||||||
}
|
|
||||||
if ((_ref2 = $('input[title=autohide]:checked', qr)) != null) {
|
|
||||||
_ref2.click();
|
|
||||||
}
|
|
||||||
textarea = $('textarea', qr);
|
|
||||||
textarea.focus();
|
|
||||||
if (text) {
|
|
||||||
return textarea.value += text;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
recaptchaListener = function(e) {
|
recaptchaListener = function(e) {
|
||||||
@ -1484,7 +1570,6 @@
|
|||||||
favDefault: ((_ref = $('link[rel="shortcut icon"]', d)) != null ? _ref.href : void 0) || '',
|
favDefault: ((_ref = $('link[rel="shortcut icon"]', d)) != null ? _ref.href : void 0) || '',
|
||||||
favEmpty: 'http://static.4chan.org/image/favicon-dis.ico',
|
favEmpty: 'http://static.4chan.org/image/favicon-dis.ico',
|
||||||
flavors: ['http://regex.info/exif.cgi?url=', 'http://iqdb.org/?url=', 'http://saucenao.com/search.php?db=999&url=', 'http://tineye.com/search?url='].join('\n'),
|
flavors: ['http://regex.info/exif.cgi?url=', 'http://iqdb.org/?url=', 'http://saucenao.com/search.php?db=999&url=', 'http://tineye.com/search?url='].join('\n'),
|
||||||
iframe: false,
|
|
||||||
watched: JSON.parse(GM_getValue('watched', '{}')),
|
watched: JSON.parse(GM_getValue('watched', '{}')),
|
||||||
xhrs: []
|
xhrs: []
|
||||||
};
|
};
|
||||||
@ -1504,31 +1589,6 @@
|
|||||||
if ($.isDST()) {
|
if ($.isDST()) {
|
||||||
g.chanOffset -= 1;
|
g.chanOffset -= 1;
|
||||||
}
|
}
|
||||||
if (location.hostname.split('.')[0] === 'sys') {
|
|
||||||
if (recaptcha = $('#recaptcha_response_field')) {
|
|
||||||
m(recaptcha, {
|
|
||||||
listener: ['keydown', recaptchaListener]
|
|
||||||
});
|
|
||||||
} else if (b = $('table font b')) {
|
|
||||||
GM_setValue('error', b.firstChild.textContent);
|
|
||||||
} else {
|
|
||||||
GM_setValue('error', '');
|
|
||||||
if (getConfig('Auto Watch')) {
|
|
||||||
html = $('b').innerHTML;
|
|
||||||
_ref2 = html.match(/<!-- thread:(\d+),no:(\d+) -->/), _ = _ref2[0], thread = _ref2[1], id = _ref2[2];
|
|
||||||
if (thread === '0') {
|
|
||||||
board = $('meta', d).content.match(/4chan.org\/(\w+)\//)[1];
|
|
||||||
(_base = g.watched)[board] || (_base[board] = []);
|
|
||||||
g.watched[board].push({
|
|
||||||
id: id,
|
|
||||||
text: GM_getValue('autoText')
|
|
||||||
});
|
|
||||||
GM_setValue('watched', JSON.stringify(g.watched));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lastChecked = GM_getValue('lastChecked', 0);
|
lastChecked = GM_getValue('lastChecked', 0);
|
||||||
now = getTime();
|
now = getTime();
|
||||||
DAY = 24 * 60 * 60;
|
DAY = 24 * 60 * 60;
|
||||||
@ -1628,6 +1688,10 @@
|
|||||||
background: lime;\
|
background: lime;\
|
||||||
}\
|
}\
|
||||||
');
|
');
|
||||||
|
if (location.hostname === 'sys.4chan.org') {
|
||||||
|
qr.sys();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (navtopr = $('#navtopr a')) {
|
if (navtopr = $('#navtopr a')) {
|
||||||
a = n('a', {
|
a = n('a', {
|
||||||
textContent: '4chan X',
|
textContent: '4chan X',
|
||||||
@ -1647,9 +1711,9 @@
|
|||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_ref3 = $$('#recaptcha_table a');
|
_ref2 = $$('#recaptcha_table a');
|
||||||
for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
|
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||||||
el = _ref3[_i];
|
el = _ref2[_i];
|
||||||
el.tabIndex = 1;
|
el.tabIndex = 1;
|
||||||
}
|
}
|
||||||
recaptcha = $('#recaptcha_response_field');
|
recaptcha = $('#recaptcha_response_field');
|
||||||
@ -1677,9 +1741,9 @@
|
|||||||
innerHTML: "<select id=imageType name=imageType><option>full</option><option>fit width</option><option>fit screen</option></select> <label>Expand Images<input type=checkbox id=imageExpand></label>"
|
innerHTML: "<select id=imageType name=imageType><option>full</option><option>fit width</option><option>fit screen</option></select> <label>Expand Images<input type=checkbox id=imageExpand></label>"
|
||||||
});
|
});
|
||||||
imageType = GM_getValue('imageType', 'full');
|
imageType = GM_getValue('imageType', 'full');
|
||||||
_ref4 = $$("option", expand);
|
_ref3 = $$("option", expand);
|
||||||
for (_j = 0, _len2 = _ref4.length; _j < _len2; _j++) {
|
for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) {
|
||||||
option = _ref4[_j];
|
option = _ref3[_j];
|
||||||
if (option.textContent === imageType) {
|
if (option.textContent === imageType) {
|
||||||
option.selected = true;
|
option.selected = true;
|
||||||
break;
|
break;
|
||||||
@ -1719,7 +1783,7 @@
|
|||||||
}
|
}
|
||||||
if (getConfig('Localize Time')) {
|
if (getConfig('Localize Time')) {
|
||||||
g.callbacks.push(function(root) {
|
g.callbacks.push(function(root) {
|
||||||
var date, day, dotw, hour, min_sec, month, s, span, spans, year, _i, _len, _ref, _results;
|
var date, day, dotw, hour, min_sec, month, s, span, spans, year, _, _i, _len, _ref, _results;
|
||||||
spans = $$('span[id^=no]', root);
|
spans = $$('span[id^=no]', root);
|
||||||
_results = [];
|
_results = [];
|
||||||
for (_i = 0, _len = spans.length; _i < _len; _i++) {
|
for (_i = 0, _len = spans.length; _i < _len; _i++) {
|
||||||
@ -1779,7 +1843,7 @@
|
|||||||
}
|
}
|
||||||
if (getConfig('Reply Hiding')) {
|
if (getConfig('Reply Hiding')) {
|
||||||
g.callbacks.push(function(root) {
|
g.callbacks.push(function(root) {
|
||||||
var next, obj, td, tds, _i, _len, _results;
|
var id, next, obj, td, tds, _i, _len, _results;
|
||||||
tds = $$('td.doubledash', root);
|
tds = $$('td.doubledash', root);
|
||||||
_results = [];
|
_results = [];
|
||||||
for (_i = 0, _len = tds.length; _i < _len; _i++) {
|
for (_i = 0, _len = tds.length; _i < _len; _i++) {
|
||||||
@ -1807,23 +1871,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (getConfig('Quick Reply')) {
|
if (getConfig('Quick Reply')) {
|
||||||
iframe = n('iframe', {
|
qr.init();
|
||||||
name: 'iframe',
|
|
||||||
listener: ['load', iframeLoad]
|
|
||||||
});
|
|
||||||
hide(iframe);
|
|
||||||
mv(iframe, d.body);
|
|
||||||
g.callbacks.push(function(root) {
|
|
||||||
var quote, quotes, _i, _len, _results;
|
|
||||||
quotes = $$('a.quotejs:not(:first-child)', root);
|
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = quotes.length; _i < _len; _i++) {
|
|
||||||
quote = quotes[_i];
|
|
||||||
_results.push(quote.addEventListener('click', qrListener, true));
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
});
|
|
||||||
recaptcha.id = '';
|
|
||||||
}
|
}
|
||||||
if (getConfig('Quick Report')) {
|
if (getConfig('Quick Report')) {
|
||||||
g.callbacks.push(function(root) {
|
g.callbacks.push(function(root) {
|
||||||
@ -1939,8 +1987,7 @@
|
|||||||
updaterMake();
|
updaterMake();
|
||||||
}
|
}
|
||||||
if (getConfig('Quick Reply') && getConfig('Persistent QR')) {
|
if (getConfig('Quick Reply') && getConfig('Persistent QR')) {
|
||||||
quickReply();
|
qr.persist();
|
||||||
$('#qr input[title=autohide]').click();
|
|
||||||
}
|
}
|
||||||
if (getConfig('Post in Title')) {
|
if (getConfig('Post in Title')) {
|
||||||
if (!(text = $('span.filetitle').textContent)) {
|
if (!(text = $('span.filetitle').textContent)) {
|
||||||
@ -2036,9 +2083,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ref5 = g.callbacks;
|
_ref4 = g.callbacks;
|
||||||
for (_n = 0, _len7 = _ref5.length; _n < _len7; _n++) {
|
for (_n = 0, _len7 = _ref4.length; _n < _len7; _n++) {
|
||||||
callback = _ref5[_n];
|
callback = _ref4[_n];
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
d.body.addEventListener('DOMNodeInserted', nodeInserted, true);
|
d.body.addEventListener('DOMNodeInserted', nodeInserted, true);
|
||||||
|
|||||||
313
script.coffee
313
script.coffee
@ -143,12 +143,26 @@ $.extend = (object, properties) ->
|
|||||||
object
|
object
|
||||||
|
|
||||||
$.extend $,
|
$.extend $,
|
||||||
|
addClass: (el, className) ->
|
||||||
|
el.className += ' ' + className
|
||||||
|
removeClass: (el, className) ->
|
||||||
|
el.className = el.className.replace ' ' + className, ''
|
||||||
|
rm: (el) ->
|
||||||
|
el.parentNode.removeChild el
|
||||||
|
append: (parent, child) ->
|
||||||
|
parent.appendChild child
|
||||||
|
before: (root, el) ->
|
||||||
|
root.parentNode.insertBefore el, root
|
||||||
|
el: (tag, properties) ->
|
||||||
|
el = d.createElement tag
|
||||||
|
$.extend el, properties if properties
|
||||||
|
el
|
||||||
bind: (el, eventType, handler) ->
|
bind: (el, eventType, handler) ->
|
||||||
el.addEventListener eventType, handler, true
|
el.addEventListener eventType, handler, true
|
||||||
unbind: (el, eventType, handler) ->
|
unbind: (el, eventType, handler) ->
|
||||||
el.removeEventListener eventType, handler, true
|
el.removeEventListener eventType, handler, true
|
||||||
isDST: ->
|
isDST: ->
|
||||||
# XXX this should be isDSTinNY
|
# XXX this should check for DST in NY
|
||||||
###
|
###
|
||||||
http://en.wikipedia.org/wiki/Daylight_saving_time_in_the_United_States
|
http://en.wikipedia.org/wiki/Daylight_saving_time_in_the_United_States
|
||||||
Since 2007, daylight saving time starts on the second Sunday of March
|
Since 2007, daylight saving time starts on the second Sunday of March
|
||||||
@ -249,15 +263,6 @@ zeroPad = (n) ->
|
|||||||
if n < 10 then '0' + n else n
|
if n < 10 then '0' + n else n
|
||||||
|
|
||||||
#funks
|
#funks
|
||||||
autohide = ->
|
|
||||||
qr = $ '#qr'
|
|
||||||
klass = qr.className
|
|
||||||
if @checked
|
|
||||||
klass += ' auto'
|
|
||||||
else
|
|
||||||
klass = klass.replace(' auto', '')
|
|
||||||
qr.className = klass
|
|
||||||
|
|
||||||
autoWatch = ->
|
autoWatch = ->
|
||||||
#TODO look for subject
|
#TODO look for subject
|
||||||
autoText = $('textarea', this).value.slice(0, 25)
|
autoText = $('textarea', this).value.slice(0, 25)
|
||||||
@ -345,22 +350,6 @@ getThread = ->
|
|||||||
if bottom > 0 #we have not scrolled past
|
if bottom > 0 #we have not scrolled past
|
||||||
return [thread, i]
|
return [thread, i]
|
||||||
|
|
||||||
formSubmit = (e) ->
|
|
||||||
if span = @nextSibling
|
|
||||||
rm span
|
|
||||||
recaptcha = $('input[name=recaptcha_response_field]', this)
|
|
||||||
if recaptcha.value
|
|
||||||
$('#qr input[title=autohide]:not(:checked)')?.click()
|
|
||||||
g.sage = if $('#qr input[name=email]').value is 'sage' then true else false
|
|
||||||
else
|
|
||||||
e.preventDefault()
|
|
||||||
span = n 'span',
|
|
||||||
className: 'error'
|
|
||||||
textContent: 'You forgot to type in the verification.'
|
|
||||||
mv span, @parentNode
|
|
||||||
alert 'You forgot to type in the verification.'
|
|
||||||
recaptcha.focus()
|
|
||||||
|
|
||||||
hideReply = (reply) ->
|
hideReply = (reply) ->
|
||||||
if p = @parentNode
|
if p = @parentNode
|
||||||
reply = p.nextSibling
|
reply = p.nextSibling
|
||||||
@ -406,35 +395,6 @@ hideThread = (div) ->
|
|||||||
listener: ['click', showThread]
|
listener: ['click', showThread]
|
||||||
inBefore div, a
|
inBefore div, a
|
||||||
|
|
||||||
iframeLoad = ->
|
|
||||||
if g.iframe = !g.iframe
|
|
||||||
return
|
|
||||||
$('iframe').src = 'about:blank'
|
|
||||||
qr = $ '#qr'
|
|
||||||
if error = GM_getValue 'error'
|
|
||||||
span = n 'span',
|
|
||||||
textContent: error
|
|
||||||
className: 'error'
|
|
||||||
mv span, qr
|
|
||||||
$('input[title=autohide]:checked', qr)?.click()
|
|
||||||
else if g.REPLY and getConfig 'Persistent QR'
|
|
||||||
$('textarea', qr).value = ''
|
|
||||||
$('input[name=recaptcha_response_field]', qr).value = ''
|
|
||||||
# XXX file.value = '' doesn't work in opera
|
|
||||||
f = $('input[type=file]', qr).parentNode
|
|
||||||
f.innerHTML = f.innerHTML
|
|
||||||
submit = $ 'input[type=submit]', qr
|
|
||||||
submit.value = if g.sage then 60 else 30
|
|
||||||
submit.disabled = true
|
|
||||||
window.setTimeout cooldown, 1000
|
|
||||||
auto = submit.previousSibling.lastChild
|
|
||||||
if auto.checked
|
|
||||||
#unhide the qr so you know it's ready for the next item
|
|
||||||
$('input[title=autohide]:checked', qr)?.click()
|
|
||||||
else
|
|
||||||
rm qr
|
|
||||||
recaptchaReload()
|
|
||||||
|
|
||||||
imageHover =
|
imageHover =
|
||||||
init: ->
|
init: ->
|
||||||
img = n 'img', id: 'iHover'
|
img = n 'img', id: 'iHover'
|
||||||
@ -615,9 +575,14 @@ keyModeNormal = (e) ->
|
|||||||
unless qrLink = $ 'td.replyhl span[id] a:not(:first-child)', thread
|
unless qrLink = $ 'td.replyhl span[id] a:not(:first-child)', thread
|
||||||
qrLink = $ "span#nothread#{thread.id} a:not(:first-child)", thread
|
qrLink = $ "span#nothread#{thread.id} a:not(:first-child)", thread
|
||||||
if e.shiftKey
|
if e.shiftKey
|
||||||
quickReply qrLink
|
$.append d.body, qr.dialog qrLink
|
||||||
|
$('#qr textarea').focus()
|
||||||
else
|
else
|
||||||
quickReply qrLink, qrText qrLink
|
# qrLink.click() doesn't work, so use this hack
|
||||||
|
e =
|
||||||
|
preventDefault: ->
|
||||||
|
target: qrLink
|
||||||
|
qr.cb.quote e
|
||||||
when "J"
|
when "J"
|
||||||
if e.shiftKey
|
if e.shiftKey
|
||||||
if not g.REPLY then [root] = getThread()
|
if not g.REPLY then [root] = getThread()
|
||||||
@ -687,9 +652,9 @@ nodeInserted = (e) ->
|
|||||||
if target.nodeName is 'TABLE'
|
if target.nodeName is 'TABLE'
|
||||||
for callback in g.callbacks
|
for callback in g.callbacks
|
||||||
callback target
|
callback target
|
||||||
else if target.id is 'recaptcha_challenge_field' and qr = $ '#qr'
|
else if target.id is 'recaptcha_challenge_field' and dialog = $ '#qr'
|
||||||
$('#recaptcha_image img', qr).src = "http://www.google.com/recaptcha/api/image?c=" + target.value
|
$('#recaptcha_image img', dialog).src = "http://www.google.com/recaptcha/api/image?c=" + target.value
|
||||||
$('#recaptcha_challenge_field', qr).value = target.value
|
$('#recaptcha_challenge_field', dialog).value = target.value
|
||||||
|
|
||||||
onloadComment = (responseText, a, href) ->
|
onloadComment = (responseText, a, href) ->
|
||||||
[_, op, id] = href.match /(\d+)#(\d+)/
|
[_, op, id] = href.match /(\d+)#(\d+)/
|
||||||
@ -760,63 +725,169 @@ parseResponse = (responseText) ->
|
|||||||
opbq = $ 'blockquote', body
|
opbq = $ 'blockquote', body
|
||||||
return [replies, opbq]
|
return [replies, opbq]
|
||||||
|
|
||||||
qrListener = (e) ->
|
qr =
|
||||||
e.preventDefault()
|
init: ->
|
||||||
link = e.target
|
g.callbacks.push qr.cb.node
|
||||||
text = qrText link
|
iframe = $.el 'iframe',
|
||||||
quickReply link, text
|
name: 'iframe'
|
||||||
|
$.append d.body, iframe
|
||||||
|
$.bind iframe, 'load', qr.cb.load
|
||||||
|
$.bind window, 'message', qr.cb.messageTop
|
||||||
|
|
||||||
qrText = (link) ->
|
#hack - nuke id so it doesn't grab focus when reloading
|
||||||
#we can't just use textContent b/c of the xxxs. goddamit moot.
|
$('#recaptcha_response_field').id = ''
|
||||||
text = '>>' + link.parentNode.id.match(/\d+$/)[0] + '\n'
|
|
||||||
|
|
||||||
selection = window.getSelection()
|
autohide:
|
||||||
id = x('preceding::span[@id][1]', selection.anchorNode)?.id
|
set: ->
|
||||||
if (s = selection.toString()) and (id is link.parentNode.id)
|
$('#qr input[title=autohide]:not(:checked)')?.click()
|
||||||
text += ">#{s}"
|
unset: ->
|
||||||
|
$('#qr input[title=autohide]:checked')?.click()
|
||||||
|
|
||||||
text
|
cb:
|
||||||
|
autohide: (e) ->
|
||||||
|
dialog = $ '#qr'
|
||||||
|
if @checked
|
||||||
|
$.addClass dialog, 'auto'
|
||||||
|
else
|
||||||
|
$.removeClass dialog, 'auto'
|
||||||
|
|
||||||
quickReply = (link, text) ->
|
load: (e) ->
|
||||||
unless qr = $ '#qr'
|
e.target.contentWindow.postMessage '', '*'
|
||||||
html = "<div class=move>Quick Reply <input type=checkbox title=autohide><a name=close title=close>X</a></div>"
|
|
||||||
qr = ui.dialog 'qr', 'topleft', html
|
|
||||||
$('input[title=autohide]', qr).addEventListener 'click', autohide, true
|
|
||||||
|
|
||||||
form = $ 'form[name=post]'
|
messageIframe: (e) ->
|
||||||
clone = form.cloneNode true
|
message = $('table b').firstChild.textContent
|
||||||
#remove recaptcha scripts
|
e.source.postMessage message, '*'
|
||||||
|
window.location = 'about:blank'
|
||||||
|
|
||||||
|
messageTop: (e) ->
|
||||||
|
{data} = e
|
||||||
|
dialog = $ '#qr'
|
||||||
|
if data is 'Post successful!'
|
||||||
|
if dialog
|
||||||
|
if getConfig 'Persistent QR'
|
||||||
|
qr.refresh dialog
|
||||||
|
else
|
||||||
|
$.rm dialog
|
||||||
|
else
|
||||||
|
error = $.el 'span',
|
||||||
|
className: 'error'
|
||||||
|
textContent: data
|
||||||
|
$.append dialog, error
|
||||||
|
qr.autohide.unset()
|
||||||
|
|
||||||
|
recaptchaReload()
|
||||||
|
|
||||||
|
node: (root) ->
|
||||||
|
quotes = $$ 'a.quotejs:not(:first-child)', root
|
||||||
|
for quote in quotes
|
||||||
|
$.bind quote, 'click', qr.cb.quote
|
||||||
|
|
||||||
|
submit: (e) ->
|
||||||
|
if span = @nextSibling
|
||||||
|
$.rm span
|
||||||
|
recaptcha = $('input[name=recaptcha_response_field]', this)
|
||||||
|
if recaptcha.value
|
||||||
|
qr.autohide.set()
|
||||||
|
g.sage = $('#qr input[name=email]').value == 'sage'
|
||||||
|
else
|
||||||
|
e.preventDefault()
|
||||||
|
span = $.el 'span',
|
||||||
|
className: 'error'
|
||||||
|
textContent: 'You forgot to type in the verification.'
|
||||||
|
$.append @parentNode, span
|
||||||
|
alert 'You forgot to type in the verification.'
|
||||||
|
recaptcha.focus()
|
||||||
|
|
||||||
|
quote: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
{target} = e
|
||||||
|
unless dialog = $ '#qr'
|
||||||
|
dialog = qr.dialog target
|
||||||
|
|
||||||
|
id = target.textContent
|
||||||
|
text = ">>#{id}\n"
|
||||||
|
|
||||||
|
selection = window.getSelection()
|
||||||
|
if s = selection.toString()
|
||||||
|
selectionID = x('preceding::input[@type="checkbox"][1]', selection.anchorNode)?.name
|
||||||
|
if selectionID == id
|
||||||
|
text += ">#{s}\n"
|
||||||
|
|
||||||
|
ta = $ 'textarea', dialog
|
||||||
|
ta.focus()
|
||||||
|
ta.value += text
|
||||||
|
|
||||||
|
refresh: (dialog) ->
|
||||||
|
$('textarea', dialog).value = ''
|
||||||
|
$('input[name=recaptcha_response_field]', dialog).value = ''
|
||||||
|
# XXX file.value = '' doesn't work in opera
|
||||||
|
f = $('input[type=file]', dialog).parentNode
|
||||||
|
f.innerHTML = f.innerHTML
|
||||||
|
submit = $ 'input[type=submit]', qr
|
||||||
|
submit.value = if g.sage then 60 else 30
|
||||||
|
submit.disabled = true
|
||||||
|
window.setTimeout cooldown, 1000
|
||||||
|
auto = submit.previousSibling.lastChild
|
||||||
|
if auto.checked
|
||||||
|
#unhide the qr so you know it's ready for the next item
|
||||||
|
$('input[title=autohide]:checked', qr)?.click()
|
||||||
|
|
||||||
|
dialog: (link) ->
|
||||||
|
html = "<div class=move>Quick Reply <input type=checkbox title=autohide> <a name=close title=close>X</a></div>"
|
||||||
|
dialog = ui.dialog 'qr', top: '0px', left: '0px', html
|
||||||
|
el = $ 'input[title=autohide]', dialog
|
||||||
|
$.bind el, 'click', qr.cb.autohide
|
||||||
|
|
||||||
|
clone = $('form[name=post]').cloneNode(true)
|
||||||
for script in $$ 'script', clone
|
for script in $$ 'script', clone
|
||||||
rm script
|
$.rm script
|
||||||
m $('input[name=recaptcha_response_field]', clone),
|
clone.target = 'iframe'
|
||||||
listener: ['keydown', recaptchaListener]
|
$.bind clone, 'submit', qr.cb.submit
|
||||||
m clone,
|
$.bind $('input[name=recaptcha_response_field]', clone), 'keydown', recaptchaListener
|
||||||
listener: ['submit', formSubmit]
|
|
||||||
target: 'iframe'
|
|
||||||
if not g.REPLY
|
if not g.REPLY
|
||||||
#figure out which thread we're replying to
|
#figure out which thread we're replying to
|
||||||
xpath = 'preceding::span[@class="postername"][1]/preceding::input[1]'
|
xpath = 'preceding::span[@class="postername"][1]/preceding::input[1]'
|
||||||
input = n 'input',
|
input = $.el 'input',
|
||||||
type: 'hidden'
|
type: 'hidden'
|
||||||
name: 'resto'
|
name: 'resto'
|
||||||
value: x(xpath, link).name
|
value: x(xpath, link).name
|
||||||
mv input, clone
|
$.append clone, input
|
||||||
else if getConfig 'Persistent QR'
|
else if getConfig 'Persistent QR'
|
||||||
submit = $ 'input[type=submit]', clone
|
submit = $ 'input[type=submit]', clone
|
||||||
auto = n 'label',
|
auto = $.el 'label',
|
||||||
textContent: 'Auto'
|
textContent: 'Auto'
|
||||||
autoBox = n 'input',
|
autobox = $.el 'input',
|
||||||
type: 'checkbox'
|
type: 'checkbox'
|
||||||
mv autoBox, auto
|
$.append auto, autobox
|
||||||
inBefore submit, auto
|
$.before submit, auto
|
||||||
mv clone, qr
|
|
||||||
mv qr, d.body
|
|
||||||
qr.style.width = qr.offsetWidth #lock
|
|
||||||
|
|
||||||
$('input[title=autohide]:checked', qr)?.click()
|
$.append dialog, clone
|
||||||
textarea = $('textarea', qr)
|
$.append d.body, dialog
|
||||||
textarea.focus()
|
dialog.style.width = dialog.offsetWidth # lock
|
||||||
if text then textarea.value += text
|
|
||||||
|
dialog
|
||||||
|
|
||||||
|
persist: ->
|
||||||
|
$.append d.body, qr.dialog()
|
||||||
|
qr.autohide.set()
|
||||||
|
|
||||||
|
sys: ->
|
||||||
|
$.bind window, 'message', qr.cb.messageIframe
|
||||||
|
if recaptcha = $ '#recaptcha_response_field'
|
||||||
|
# post reporting
|
||||||
|
$.bind recaptcha, 'keydown', recaptchaListener
|
||||||
|
if getConfig 'Auto Watch'
|
||||||
|
html = $('b').innerHTML
|
||||||
|
[_, thread, id] = html.match(/<!-- thread:(\d+),no:(\d+) -->/)
|
||||||
|
if thread is '0'
|
||||||
|
[_, board] = $('meta', d).content.match(/4chan.org\/(\w+)\//)
|
||||||
|
g.watched[board] or= []
|
||||||
|
g.watched[board].push {
|
||||||
|
id: id,
|
||||||
|
text: GM_getValue 'autoText'
|
||||||
|
}
|
||||||
|
GM_setValue 'watched', JSON.stringify g.watched
|
||||||
|
|
||||||
recaptchaListener = (e) ->
|
recaptchaListener = (e) ->
|
||||||
if e.keyCode is 8 and @value is ''
|
if e.keyCode is 8 and @value is ''
|
||||||
@ -1127,7 +1198,6 @@ g =
|
|||||||
'http://saucenao.com/search.php?db=999&url='
|
'http://saucenao.com/search.php?db=999&url='
|
||||||
'http://tineye.com/search?url='
|
'http://tineye.com/search?url='
|
||||||
].join '\n'
|
].join '\n'
|
||||||
iframe: false
|
|
||||||
watched: JSON.parse(GM_getValue('watched', '{}'))
|
watched: JSON.parse(GM_getValue('watched', '{}'))
|
||||||
xhrs: []
|
xhrs: []
|
||||||
g.favHalo = if /ws/.test g.favDefault then 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAZklEQVR4XrWRQQoAIQwD+6L97j7Ih9WTQQxhDqJQCk4Mranuvqod6LgwawSqSuUmWSPw/UNlJlnDAmA2ARjABLYj8ZyCzJHHqOg+GdAKZmKPIQUzuYrxicHqEgHzP9g7M0+hj45sAnRWxtPj3zSPAAAAAElFTkSuQmCC' else 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEUAAABmzDP///8AAABet0i+AAAAAXRSTlMAQObYZgAAAExJREFUeF4tyrENgDAMAMFXKuQswQLBG3mOlBnFS1gwDfIYLpEivvjq2MlqjmYvYg5jWEzCwtDSQlwcXKCVLrpFbvLvvSf9uZJ2HusDtJAY7Tkn1oYAAAAASUVORK5CYII='
|
g.favHalo = if /ws/.test g.favDefault then 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAZklEQVR4XrWRQQoAIQwD+6L97j7Ih9WTQQxhDqJQCk4Mranuvqod6LgwawSqSuUmWSPw/UNlJlnDAmA2ARjABLYj8ZyCzJHHqOg+GdAKZmKPIQUzuYrxicHqEgHzP9g7M0+hj45sAnRWxtPj3zSPAAAAAElFTkSuQmCC' else 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEUAAABmzDP///8AAABet0i+AAAAAXRSTlMAQObYZgAAAExJREFUeF4tyrENgDAMAMFXKuQswQLBG3mOlBnFS1gwDfIYLpEivvjq2MlqjmYvYg5jWEzCwtDSQlwcXKCVLrpFbvLvvSf9uZJ2HusDtJAY7Tkn1oYAAAAASUVORK5CYII='
|
||||||
@ -1145,26 +1215,6 @@ tzOffset = (new Date()).getTimezoneOffset() / 60
|
|||||||
g.chanOffset = 5 - tzOffset# 4chan = EST = GMT -5
|
g.chanOffset = 5 - tzOffset# 4chan = EST = GMT -5
|
||||||
if $.isDST() then g.chanOffset -= 1
|
if $.isDST() then g.chanOffset -= 1
|
||||||
|
|
||||||
if location.hostname.split('.')[0] is 'sys'
|
|
||||||
if recaptcha = $ '#recaptcha_response_field'
|
|
||||||
m recaptcha, listener: ['keydown', recaptchaListener]
|
|
||||||
else if b = $ 'table font b'
|
|
||||||
GM_setValue 'error', b.firstChild.textContent
|
|
||||||
else
|
|
||||||
GM_setValue 'error', ''
|
|
||||||
if getConfig 'Auto Watch'
|
|
||||||
html = $('b').innerHTML
|
|
||||||
[_, thread, id] = html.match(/<!-- thread:(\d+),no:(\d+) -->/)
|
|
||||||
if thread is '0'
|
|
||||||
board = $('meta', d).content.match(/4chan.org\/(\w+)\//)[1]
|
|
||||||
g.watched[board] or= []
|
|
||||||
g.watched[board].push {
|
|
||||||
id: id,
|
|
||||||
text: GM_getValue 'autoText'
|
|
||||||
}
|
|
||||||
GM_setValue 'watched', JSON.stringify g.watched
|
|
||||||
return
|
|
||||||
|
|
||||||
lastChecked = GM_getValue('lastChecked', 0)
|
lastChecked = GM_getValue('lastChecked', 0)
|
||||||
now = getTime()
|
now = getTime()
|
||||||
DAY = 24 * 60 * 60
|
DAY = 24 * 60 * 60
|
||||||
@ -1263,6 +1313,9 @@ GM_addStyle '
|
|||||||
}
|
}
|
||||||
'
|
'
|
||||||
|
|
||||||
|
if location.hostname is 'sys.4chan.org'
|
||||||
|
qr.sys()
|
||||||
|
return
|
||||||
if navtopr = $ '#navtopr a'
|
if navtopr = $ '#navtopr a'
|
||||||
a = n 'a',
|
a = n 'a',
|
||||||
textContent: '4chan X'
|
textContent: '4chan X'
|
||||||
@ -1388,20 +1441,7 @@ if getConfig 'Reply Hiding'
|
|||||||
hideReply(next)
|
hideReply(next)
|
||||||
|
|
||||||
if getConfig 'Quick Reply'
|
if getConfig 'Quick Reply'
|
||||||
iframe = n 'iframe',
|
qr.init()
|
||||||
name: 'iframe'
|
|
||||||
listener: ['load', iframeLoad]
|
|
||||||
hide(iframe)
|
|
||||||
mv iframe, d.body
|
|
||||||
|
|
||||||
g.callbacks.push (root) ->
|
|
||||||
quotes = $$('a.quotejs:not(:first-child)', root)
|
|
||||||
for quote in quotes
|
|
||||||
quote.addEventListener('click', qrListener, true)
|
|
||||||
|
|
||||||
#hack - nuke id so it doesn't grab focus when reloading
|
|
||||||
recaptcha.id = ''
|
|
||||||
|
|
||||||
|
|
||||||
if getConfig 'Quick Report'
|
if getConfig 'Quick Report'
|
||||||
g.callbacks.push (root) ->
|
g.callbacks.push (root) ->
|
||||||
@ -1481,8 +1521,7 @@ if g.REPLY
|
|||||||
if getConfig 'Thread Updater'
|
if getConfig 'Thread Updater'
|
||||||
updaterMake()
|
updaterMake()
|
||||||
if getConfig('Quick Reply') and getConfig 'Persistent QR'
|
if getConfig('Quick Reply') and getConfig 'Persistent QR'
|
||||||
quickReply()
|
qr.persist()
|
||||||
$('#qr input[title=autohide]').click()
|
|
||||||
if getConfig 'Post in Title'
|
if getConfig 'Post in Title'
|
||||||
unless text = $('span.filetitle').textContent
|
unless text = $('span.filetitle').textContent
|
||||||
text = $('blockquote').textContent
|
text = $('blockquote').textContent
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user