Take messaging between iframes out of the qr code, get ready for ajaxing with images.4chan.org
This commit is contained in:
parent
6d41588e00
commit
dea285d389
371
4chan_x.user.js
371
4chan_x.user.js
@ -71,7 +71,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, SECOND, Time, VERSION, anonymize, conf, config, d, engine, expandComment, expandThread, filter, flatten, g, getTitle, imgExpand, imgGif, imgHover, key, keybinds, log, nav, options, qr, quoteBacklink, quoteDR, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher, _base,
|
var $, $$, DAY, Favicon, HOUR, MINUTE, Main, NAMESPACE, SECOND, Time, VERSION, anonymize, conf, config, d, engine, expandComment, expandThread, filter, flatten, g, getTitle, imgExpand, imgGif, imgHover, key, keybinds, log, message, nav, options, qr, quoteBacklink, quoteDR, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, strikethroughQuotes, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher, _base,
|
||||||
__slice = Array.prototype.slice;
|
__slice = Array.prototype.slice;
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
@ -1191,7 +1191,7 @@
|
|||||||
|
|
||||||
qr = {
|
qr = {
|
||||||
init: function() {
|
init: function() {
|
||||||
var form, iframe, link, loadChecking;
|
var form, link;
|
||||||
if (!$.id('recaptcha_challenge_field_holder')) return;
|
if (!$.id('recaptcha_challenge_field_holder')) return;
|
||||||
if (conf['Hide Original Post Form']) {
|
if (conf['Hide Original Post Form']) {
|
||||||
link = $.el('h1', {
|
link = $.el('h1', {
|
||||||
@ -1205,26 +1205,6 @@
|
|||||||
$.before(form, link);
|
$.before(form, link);
|
||||||
}
|
}
|
||||||
g.callbacks.push(this.node);
|
g.callbacks.push(this.node);
|
||||||
iframe = $.el('iframe', {
|
|
||||||
id: 'iframe',
|
|
||||||
hidden: true,
|
|
||||||
src: 'http://sys.4chan.org/robots.txt'
|
|
||||||
});
|
|
||||||
$.on(iframe, 'error', function() {
|
|
||||||
return this.src = this.src;
|
|
||||||
});
|
|
||||||
loadChecking = function(iframe) {
|
|
||||||
if (!qr.status.ready) {
|
|
||||||
iframe.src = 'about:blank';
|
|
||||||
return setTimeout((function() {
|
|
||||||
return iframe.src = 'http://sys.4chan.org/robots.txt';
|
|
||||||
}), 250);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
$.on(iframe, 'load', function() {
|
|
||||||
if (this.src !== 'about:blank') return setTimeout(loadChecking, 500, this);
|
|
||||||
});
|
|
||||||
$.add(d.body, iframe);
|
|
||||||
if (conf['Persistent QR']) {
|
if (conf['Persistent QR']) {
|
||||||
qr.dialog();
|
qr.dialog();
|
||||||
if (conf['Auto Hide QR']) qr.hide();
|
if (conf['Auto Hide QR']) qr.hide();
|
||||||
@ -1249,9 +1229,9 @@
|
|||||||
close: function() {
|
close: function() {
|
||||||
var i, spoiler, _i, _len, _ref;
|
var i, spoiler, _i, _len, _ref;
|
||||||
qr.el.hidden = true;
|
qr.el.hidden = true;
|
||||||
qr.message.send({
|
message.send({
|
||||||
req: 'abort'
|
req: 'abort'
|
||||||
});
|
}, 'sys');
|
||||||
d.activeElement.blur();
|
d.activeElement.blur();
|
||||||
$.removeClass(qr.el, 'dump');
|
$.removeClass(qr.el, 'dump');
|
||||||
_ref = qr.replies;
|
_ref = qr.replies;
|
||||||
@ -1721,7 +1701,6 @@
|
|||||||
qr.status();
|
qr.status();
|
||||||
qr.cooldown.init();
|
qr.cooldown.init();
|
||||||
qr.captcha.init();
|
qr.captcha.init();
|
||||||
qr.message.init();
|
|
||||||
$.add(d.body, qr.el);
|
$.add(d.body, qr.el);
|
||||||
e = d.createEvent('CustomEvent');
|
e = d.createEvent('CustomEvent');
|
||||||
e.initEvent('QRDialogCreation', true, false);
|
e.initEvent('QRDialogCreation', true, false);
|
||||||
@ -1735,9 +1714,9 @@
|
|||||||
qr.status();
|
qr.status();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qr.message.send({
|
message.send({
|
||||||
req: 'abort'
|
req: 'abort'
|
||||||
});
|
}, 'sys');
|
||||||
reply = qr.replies[0];
|
reply = qr.replies[0];
|
||||||
if (!(reply.com || reply.file)) {
|
if (!(reply.com || reply.file)) {
|
||||||
err = 'No file selected.';
|
err = 'No file selected.';
|
||||||
@ -1795,12 +1774,12 @@
|
|||||||
file.name = reply.file.name;
|
file.name = reply.file.name;
|
||||||
file.type = reply.file.type;
|
file.type = reply.file.type;
|
||||||
post.upfile = file;
|
post.upfile = file;
|
||||||
return qr.message.send(post);
|
return message.send(post, 'sys');
|
||||||
};
|
};
|
||||||
reader.readAsBinaryString(reply.file);
|
reader.readAsBinaryString(reply.file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return qr.message.send(post);
|
return message.send(post, 'sys');
|
||||||
},
|
},
|
||||||
response: function(html) {
|
response: function(html) {
|
||||||
var b, err, node, persona, postNumber, reply, thread, _, _ref;
|
var b, err, node, persona, postNumber, reply, thread, _, _ref;
|
||||||
@ -1852,150 +1831,93 @@
|
|||||||
qr.status();
|
qr.status();
|
||||||
return qr.resetFileInput();
|
return qr.resetFileInput();
|
||||||
},
|
},
|
||||||
message: {
|
post: function(data) {
|
||||||
init: function() {
|
var boundary, callbacks, form, i, name, opts, parts, toBin, url, val;
|
||||||
var code, ready, script;
|
url = "http://sys.4chan.org/" + data.board + "/post";
|
||||||
code = function(e) {
|
delete data.board;
|
||||||
var data, host;
|
if (engine === 'gecko' && data.upfile) {
|
||||||
data = e.data;
|
if (!data.binary) {
|
||||||
if (!data.changeContext) return;
|
toBin = function(data, name, val) {
|
||||||
delete data.changeContext;
|
var bb, r;
|
||||||
host = location.hostname;
|
bb = new MozBlobBuilder();
|
||||||
if (host === 'boards.4chan.org') {
|
bb.append(val);
|
||||||
return document.getElementById('iframe').contentWindow.postMessage(data, '*');
|
r = new FileReader();
|
||||||
} else if (host === 'sys.4chan.org') {
|
r.onload = function() {
|
||||||
return parent.postMessage(data, '*');
|
data[name] = r.result;
|
||||||
}
|
if (!--i) return qr.post(data);
|
||||||
};
|
|
||||||
script = $.el('script', {
|
|
||||||
textContent: "window.addEventListener('message'," + code + ",false)"
|
|
||||||
});
|
|
||||||
ready = function() {
|
|
||||||
$.add(d.documentElement, script);
|
|
||||||
if (location.hostname === 'sys.4chan.org') {
|
|
||||||
qr.message.send({
|
|
||||||
req: 'status',
|
|
||||||
ready: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return $.rm(script);
|
|
||||||
};
|
|
||||||
if (d.documentElement) {
|
|
||||||
return ready();
|
|
||||||
} else {
|
|
||||||
return $.ready(ready);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
send: function(data) {
|
|
||||||
data.changeContext = true;
|
|
||||||
data.qr = true;
|
|
||||||
return postMessage(data, '*');
|
|
||||||
},
|
|
||||||
receive: function(data) {
|
|
||||||
var _ref;
|
|
||||||
switch (data.req) {
|
|
||||||
case 'abort':
|
|
||||||
if ((_ref = qr.ajax) != null) _ref.abort();
|
|
||||||
return qr.message.send({
|
|
||||||
req: 'status'
|
|
||||||
});
|
|
||||||
case 'response':
|
|
||||||
return qr.response(data.html);
|
|
||||||
case 'status':
|
|
||||||
return qr.status(data);
|
|
||||||
default:
|
|
||||||
return qr.message.post(data);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
post: function(data) {
|
|
||||||
var boundary, callbacks, form, i, name, opts, parts, toBin, url, val;
|
|
||||||
url = "http://sys.4chan.org/" + data.board + "/post";
|
|
||||||
delete data.board;
|
|
||||||
delete data.qr;
|
|
||||||
if (engine === 'gecko' && data.upfile) {
|
|
||||||
if (!data.binary) {
|
|
||||||
toBin = function(data, name, val) {
|
|
||||||
var bb, r;
|
|
||||||
bb = new MozBlobBuilder();
|
|
||||||
bb.append(val);
|
|
||||||
r = new FileReader();
|
|
||||||
r.onload = function() {
|
|
||||||
data[name] = r.result;
|
|
||||||
if (!--i) return qr.message.post(data);
|
|
||||||
};
|
|
||||||
return r.readAsBinaryString(bb.getBlob('text/plain'));
|
|
||||||
};
|
};
|
||||||
i = Object.keys(data).length;
|
return r.readAsBinaryString(bb.getBlob('text/plain'));
|
||||||
for (name in data) {
|
};
|
||||||
val = data[name];
|
i = Object.keys(data).length;
|
||||||
if (typeof val === 'object') {
|
for (name in data) {
|
||||||
toBin(data.upfile, 'name', data.upfile.name);
|
val = data[name];
|
||||||
} else if (typeof val === 'boolean') {
|
if (typeof val === 'object') {
|
||||||
if (val) {
|
toBin(data.upfile, 'name', data.upfile.name);
|
||||||
toBin(data, name, String(val));
|
} else if (typeof val === 'boolean') {
|
||||||
} else {
|
if (val) {
|
||||||
i--;
|
toBin(data, name, String(val));
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
toBin(data, name, val);
|
i--;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
data.board = url.split('/')[3];
|
toBin(data, name, val);
|
||||||
data.binary = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
delete data.binary;
|
|
||||||
boundary = '-------------SMCD' + Date.now();
|
|
||||||
parts = [];
|
|
||||||
parts.push('Content-Disposition: form-data; name="upfile"; filename="' + data.upfile.name + '"\r\n' + 'Content-Type: ' + data.upfile.type + '\r\n\r\n' + data.upfile.buffer + '\r\n');
|
|
||||||
delete data.upfile;
|
|
||||||
for (name in data) {
|
|
||||||
val = data[name];
|
|
||||||
if (val) {
|
|
||||||
parts.push('Content-Disposition: form-data; name="' + name + '"\r\n\r\n' + val + '\r\n');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
form = '--' + boundary + '\r\n' + parts.join('--' + boundary + '\r\n') + '--' + boundary + '--\r\n';
|
data.board = url.split('/')[3];
|
||||||
} else {
|
data.binary = true;
|
||||||
form = new FormData();
|
return;
|
||||||
for (name in data) {
|
}
|
||||||
val = data[name];
|
delete data.binary;
|
||||||
if (val) form.append(name, val);
|
boundary = '-------------SMCD' + Date.now();
|
||||||
|
parts = [];
|
||||||
|
parts.push('Content-Disposition: form-data; name="upfile"; filename="' + data.upfile.name + '"\r\n' + 'Content-Type: ' + data.upfile.type + '\r\n\r\n' + data.upfile.buffer + '\r\n');
|
||||||
|
delete data.upfile;
|
||||||
|
for (name in data) {
|
||||||
|
val = data[name];
|
||||||
|
if (val) {
|
||||||
|
parts.push('Content-Disposition: form-data; name="' + name + '"\r\n\r\n' + val + '\r\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
callbacks = {
|
form = '--' + boundary + '\r\n' + parts.join('--' + boundary + '\r\n') + '--' + boundary + '--\r\n';
|
||||||
|
} else {
|
||||||
|
form = new FormData();
|
||||||
|
for (name in data) {
|
||||||
|
val = data[name];
|
||||||
|
if (val) form.append(name, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callbacks = {
|
||||||
|
onload: function() {
|
||||||
|
return message.send({
|
||||||
|
req: 'response',
|
||||||
|
html: this.response
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
opts = {
|
||||||
|
form: form,
|
||||||
|
type: 'post',
|
||||||
|
upCallbacks: {
|
||||||
onload: function() {
|
onload: function() {
|
||||||
return qr.message.send({
|
return message.send({
|
||||||
req: 'response',
|
req: 'status',
|
||||||
html: this.response
|
progress: '...'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onprogress: function(e) {
|
||||||
|
return message.send({
|
||||||
|
req: 'status',
|
||||||
|
progress: "" + (Math.round(e.loaded / e.total * 100)) + "%"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
|
||||||
opts = {
|
|
||||||
form: form,
|
|
||||||
type: 'post',
|
|
||||||
upCallbacks: {
|
|
||||||
onload: function() {
|
|
||||||
return qr.message.send({
|
|
||||||
req: 'status',
|
|
||||||
progress: '...'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onprogress: function(e) {
|
|
||||||
return qr.message.send({
|
|
||||||
req: 'status',
|
|
||||||
progress: "" + (Math.round(e.loaded / e.total * 100)) + "%"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (boundary) {
|
|
||||||
opts.headers = {
|
|
||||||
'Content-Type': 'multipart/form-data;boundary=' + boundary
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
return qr.ajax = $.ajax(url, callbacks, opts);
|
};
|
||||||
|
if (boundary) {
|
||||||
|
opts.headers = {
|
||||||
|
'Content-Type': 'multipart/form-data;boundary=' + boundary
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
return qr.ajax = $.ajax(url, callbacks, opts);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2430,9 +2352,9 @@
|
|||||||
d.title = d.title.match(/^.+-/)[0] + ' 404';
|
d.title = d.title.match(/^.+-/)[0] + ' 404';
|
||||||
}
|
}
|
||||||
unread.update(true);
|
unread.update(true);
|
||||||
qr.message.send({
|
message.send({
|
||||||
req: 'abort'
|
req: 'abort'
|
||||||
});
|
}, 'sys');
|
||||||
qr.status();
|
qr.status();
|
||||||
Favicon.update();
|
Favicon.update();
|
||||||
return;
|
return;
|
||||||
@ -3488,6 +3410,113 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
message = {
|
||||||
|
init: function() {
|
||||||
|
var code, script;
|
||||||
|
$.on(window, 'message', message.receive);
|
||||||
|
$.ready(function() {
|
||||||
|
var domain, domains, iframe, _i, _len, _results;
|
||||||
|
if (location.hostname !== 'boards.4chan.org') return;
|
||||||
|
domains = [];
|
||||||
|
if (conf['Quick Reply']) domains.push('sys');
|
||||||
|
if (conf['Image Expansion'] || conf['Sauce']) domains.push('images');
|
||||||
|
_results = [];
|
||||||
|
for (_i = 0, _len = domains.length; _i < _len; _i++) {
|
||||||
|
domain = domains[_i];
|
||||||
|
iframe = $.el('iframe', {
|
||||||
|
id: domain,
|
||||||
|
hidden: true,
|
||||||
|
src: "http://" + domain + ".4chan.org/robots.txt"
|
||||||
|
});
|
||||||
|
$.on(iframe, 'error', message.loadControl);
|
||||||
|
$.on(iframe, 'load', message.loadControl);
|
||||||
|
_results.push($.add(d.body, iframe));
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
});
|
||||||
|
code = function(e) {
|
||||||
|
var data;
|
||||||
|
data = e.data;
|
||||||
|
if (!data.changeContext) return;
|
||||||
|
delete data.changeContext;
|
||||||
|
if (location.hostname === 'boards.4chan.org') {
|
||||||
|
return document.getElementById(data.iframe).contentWindow.postMessage(data, '*');
|
||||||
|
} else {
|
||||||
|
return parent.postMessage(data, '*');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
script = $.el('script', {
|
||||||
|
textContent: "window.addEventListener('message'," + code + ",false)"
|
||||||
|
});
|
||||||
|
return $.ready(function() {
|
||||||
|
var host;
|
||||||
|
$.add(d.documentElement, script);
|
||||||
|
host = location.hostname;
|
||||||
|
if (host === 'sys.4chan.org') {
|
||||||
|
message.send({
|
||||||
|
req: 'status',
|
||||||
|
ready: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (host !== 'boards.4chan.org') {
|
||||||
|
message.send({
|
||||||
|
req: 'iframeLoad',
|
||||||
|
id: location.hostname.split('.')[0]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return $.rm(script);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
loadControl: function() {
|
||||||
|
var _this = this;
|
||||||
|
return setTimeout((function() {
|
||||||
|
if (_this.src === 'about:blank' || message[_this.id] === 'ready') return;
|
||||||
|
_this.src = 'about:blank';
|
||||||
|
return setTimeout((function() {
|
||||||
|
return _this.src = "http://" + _this.id + ".4chan.org/robots.txt";
|
||||||
|
}), 250);
|
||||||
|
}), 1000);
|
||||||
|
},
|
||||||
|
receive: function(e) {
|
||||||
|
var data, version;
|
||||||
|
data = e.data;
|
||||||
|
if (data.iframe) {
|
||||||
|
if (!data.changeContext) message.handle(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
version = data.version;
|
||||||
|
if (version && version !== VERSION && confirm('An updated version of 4chan X is available, would you like to install it now?')) {
|
||||||
|
return window.location = "https://raw.github.com/mayhemydg/4chan-x/" + version + "/4chan_x.user.js";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
send: function(data, iframe) {
|
||||||
|
data.changeContext = true;
|
||||||
|
data.iframe = iframe || 'boards';
|
||||||
|
return postMessage(data, '*');
|
||||||
|
},
|
||||||
|
handle: function(data) {
|
||||||
|
var req, _ref;
|
||||||
|
req = data.req;
|
||||||
|
delete data.req;
|
||||||
|
delete data.iframe;
|
||||||
|
switch (req) {
|
||||||
|
case 'iframeLoad':
|
||||||
|
return message[data.id] = 'ready';
|
||||||
|
case 'abort':
|
||||||
|
if ((_ref = qr.ajax) != null) _ref.abort();
|
||||||
|
return message.send({
|
||||||
|
req: 'status'
|
||||||
|
});
|
||||||
|
case 'response':
|
||||||
|
return qr.response(data.html);
|
||||||
|
case 'status':
|
||||||
|
return qr.status(data);
|
||||||
|
default:
|
||||||
|
return qr.post(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Main = {
|
Main = {
|
||||||
init: function() {
|
init: function() {
|
||||||
var cutoff, hiddenThreads, id, now, pathname, temp, timestamp, _ref;
|
var cutoff, hiddenThreads, id, now, pathname, temp, timestamp, _ref;
|
||||||
@ -3499,11 +3528,9 @@
|
|||||||
} else {
|
} else {
|
||||||
g.PAGENUM = parseInt(temp) || 0;
|
g.PAGENUM = parseInt(temp) || 0;
|
||||||
}
|
}
|
||||||
$.on(window, 'message', Main.message);
|
message.init();
|
||||||
if (location.hostname === 'sys.4chan.org') {
|
if (location.hostname === 'sys.4chan.org') {
|
||||||
if (location.pathname === '/robots.txt') {
|
if (/report/.test(location.search)) {
|
||||||
qr.message.init();
|
|
||||||
} else if (/report/.test(location.search)) {
|
|
||||||
$.ready(function() {
|
$.ready(function() {
|
||||||
return $.on($('#recaptcha_response_field'), 'keydown', function(e) {
|
return $.on($('#recaptcha_response_field'), 'keydown', function(e) {
|
||||||
if (e.keyCode === 8 && !e.target.value) {
|
if (e.keyCode === 8 && !e.target.value) {
|
||||||
@ -3619,16 +3646,6 @@
|
|||||||
return $.on(d, 'DOMNodeInserted', Main.addStyle);
|
return $.on(d, 'DOMNodeInserted', Main.addStyle);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
message: function(e) {
|
|
||||||
var data, version;
|
|
||||||
data = e.data;
|
|
||||||
version = data.version;
|
|
||||||
if (data.qr && !data.changeContext) {
|
|
||||||
return qr.message.receive(data);
|
|
||||||
} else if (version && version !== VERSION && confirm('An updated version of 4chan X is available, would you like to install it now?')) {
|
|
||||||
return window.location = "https://raw.github.com/mayhemydg/4chan-x/" + version + "/4chan_x.user.js";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
node: function(e) {
|
node: function(e) {
|
||||||
var callback, target, _i, _len, _ref, _results;
|
var callback, target, _i, _len, _ref, _results;
|
||||||
target = e.target;
|
target = e.target;
|
||||||
|
|||||||
297
script.coffee
297
script.coffee
@ -880,19 +880,6 @@ qr =
|
|||||||
$.before form, link
|
$.before form, link
|
||||||
g.callbacks.push @node
|
g.callbacks.push @node
|
||||||
|
|
||||||
iframe = $.el 'iframe',
|
|
||||||
id: 'iframe'
|
|
||||||
hidden: true
|
|
||||||
src: 'http://sys.4chan.org/robots.txt'
|
|
||||||
$.on iframe, 'error', -> @src = @src
|
|
||||||
# Greasemonkey ghetto fix
|
|
||||||
loadChecking = (iframe) ->
|
|
||||||
unless qr.status.ready
|
|
||||||
iframe.src = 'about:blank'
|
|
||||||
setTimeout (-> iframe.src = 'http://sys.4chan.org/robots.txt'), 250
|
|
||||||
$.on iframe, 'load', -> unless @src is 'about:blank' then setTimeout loadChecking, 500, @
|
|
||||||
$.add d.body, iframe
|
|
||||||
|
|
||||||
if conf['Persistent QR']
|
if conf['Persistent QR']
|
||||||
qr.dialog()
|
qr.dialog()
|
||||||
qr.hide() if conf['Auto Hide QR']
|
qr.hide() if conf['Auto Hide QR']
|
||||||
@ -914,7 +901,7 @@ qr =
|
|||||||
qr.dialog()
|
qr.dialog()
|
||||||
close: ->
|
close: ->
|
||||||
qr.el.hidden = true
|
qr.el.hidden = true
|
||||||
qr.message.send req: 'abort'
|
message.send req: 'abort', 'sys'
|
||||||
d.activeElement.blur()
|
d.activeElement.blur()
|
||||||
$.removeClass qr.el, 'dump'
|
$.removeClass qr.el, 'dump'
|
||||||
for i in qr.replies
|
for i in qr.replies
|
||||||
@ -1287,7 +1274,6 @@ qr =
|
|||||||
qr.status()
|
qr.status()
|
||||||
qr.cooldown.init()
|
qr.cooldown.init()
|
||||||
qr.captcha.init()
|
qr.captcha.init()
|
||||||
qr.message.init()
|
|
||||||
$.add d.body, qr.el
|
$.add d.body, qr.el
|
||||||
|
|
||||||
# Create a custom event when the QR dialog is first initialized.
|
# Create a custom event when the QR dialog is first initialized.
|
||||||
@ -1302,7 +1288,7 @@ qr =
|
|||||||
qr.cooldown.auto = !qr.cooldown.auto
|
qr.cooldown.auto = !qr.cooldown.auto
|
||||||
qr.status()
|
qr.status()
|
||||||
return
|
return
|
||||||
qr.message.send req: 'abort'
|
message.send req: 'abort', 'sys'
|
||||||
reply = qr.replies[0]
|
reply = qr.replies[0]
|
||||||
|
|
||||||
# prevent errors
|
# prevent errors
|
||||||
@ -1371,11 +1357,11 @@ qr =
|
|||||||
file.name = reply.file.name
|
file.name = reply.file.name
|
||||||
file.type = reply.file.type
|
file.type = reply.file.type
|
||||||
post.upfile = file
|
post.upfile = file
|
||||||
qr.message.send post
|
message.send post, 'sys'
|
||||||
reader.readAsBinaryString reply.file
|
reader.readAsBinaryString reply.file
|
||||||
return
|
return
|
||||||
|
|
||||||
qr.message.send post
|
message.send post, 'sys'
|
||||||
|
|
||||||
response: (html) ->
|
response: (html) ->
|
||||||
unless b = $ 'td b', $.el('a', innerHTML: html)
|
unless b = $ 'td b', $.el('a', innerHTML: html)
|
||||||
@ -1427,121 +1413,78 @@ qr =
|
|||||||
qr.status()
|
qr.status()
|
||||||
qr.resetFileInput()
|
qr.resetFileInput()
|
||||||
|
|
||||||
message:
|
post: (data) ->
|
||||||
init: ->
|
|
||||||
# http://code.google.com/p/chromium/issues/detail?id=20773
|
|
||||||
# Let content scripts see other frames (instead of them being undefined)
|
|
||||||
# To access the parent, we have to break out of the sandbox and evaluate
|
|
||||||
# in the global context.
|
|
||||||
code = (e) ->
|
|
||||||
{data} = e
|
|
||||||
return unless data.changeContext
|
|
||||||
delete data.changeContext
|
|
||||||
host = location.hostname
|
|
||||||
if host is 'boards.4chan.org'
|
|
||||||
document.getElementById('iframe').contentWindow.postMessage data, '*'
|
|
||||||
else if host is 'sys.4chan.org'
|
|
||||||
parent.postMessage data, '*'
|
|
||||||
script = $.el 'script', textContent: "window.addEventListener('message',#{code},false)"
|
|
||||||
ready = ->
|
|
||||||
$.add d.documentElement, script
|
|
||||||
if location.hostname is 'sys.4chan.org'
|
|
||||||
qr.message.send req: 'status', ready: true
|
|
||||||
$.rm script
|
|
||||||
# Chrome can access the documentElement on document-start
|
|
||||||
if d.documentElement
|
|
||||||
ready()
|
|
||||||
# other browsers will have to wait
|
|
||||||
else $.ready ready
|
|
||||||
send: (data) ->
|
|
||||||
data.changeContext = true
|
|
||||||
data.qr = true
|
|
||||||
postMessage data, '*'
|
|
||||||
receive: (data) ->
|
|
||||||
switch data.req
|
|
||||||
when 'abort'
|
|
||||||
qr.ajax?.abort()
|
|
||||||
qr.message.send req: 'status'
|
|
||||||
when 'response' # xhr response
|
|
||||||
qr.response data.html
|
|
||||||
when 'status'
|
|
||||||
qr.status data
|
|
||||||
else
|
|
||||||
qr.message.post data # Reply object: we're posting
|
|
||||||
|
|
||||||
post: (data) ->
|
url = "http://sys.4chan.org/#{data.board}/post"
|
||||||
|
# Do not append that value to the form.
|
||||||
|
delete data.board
|
||||||
|
|
||||||
url = "http://sys.4chan.org/#{data.board}/post"
|
# File with filename upload fix from desuwa
|
||||||
# Do not append these values to the form.
|
if engine is 'gecko' and data.upfile
|
||||||
delete data.board
|
# All of this is fucking retarded.
|
||||||
delete data.qr
|
unless data.binary
|
||||||
|
toBin = (data, name, val) ->
|
||||||
# File with filename upload fix from desuwa
|
bb = new MozBlobBuilder()
|
||||||
if engine is 'gecko' and data.upfile
|
bb.append val
|
||||||
# All of this is fucking retarded.
|
r = new FileReader()
|
||||||
unless data.binary
|
r.onload = ->
|
||||||
toBin = (data, name, val) ->
|
data[name] = r.result
|
||||||
bb = new MozBlobBuilder()
|
unless --i
|
||||||
bb.append val
|
qr.post data
|
||||||
r = new FileReader()
|
r.readAsBinaryString bb.getBlob 'text/plain'
|
||||||
r.onload = ->
|
i = Object.keys(data).length
|
||||||
data[name] = r.result
|
for name, val of data
|
||||||
unless --i
|
if typeof val is 'object' # File. toBin the filename.
|
||||||
qr.message.post data
|
toBin data.upfile, 'name', data.upfile.name
|
||||||
r.readAsBinaryString bb.getBlob 'text/plain'
|
else if typeof val is 'boolean'
|
||||||
i = Object.keys(data).length
|
if val
|
||||||
for name, val of data
|
toBin data, name, String val
|
||||||
if typeof val is 'object' # File. toBin the filename.
|
|
||||||
toBin data.upfile, 'name', data.upfile.name
|
|
||||||
else if typeof val is 'boolean'
|
|
||||||
if val
|
|
||||||
toBin data, name, String val
|
|
||||||
else
|
|
||||||
i--
|
|
||||||
else
|
else
|
||||||
toBin data, name, val
|
i--
|
||||||
data.board = url.split('/')[3]
|
else
|
||||||
data.binary = true
|
toBin data, name, val
|
||||||
return
|
data.board = url.split('/')[3]
|
||||||
|
data.binary = true
|
||||||
|
return
|
||||||
|
|
||||||
delete data.binary
|
delete data.binary
|
||||||
|
|
||||||
boundary = '-------------SMCD' + Date.now();
|
boundary = '-------------SMCD' + Date.now();
|
||||||
parts = []
|
parts = []
|
||||||
parts.push 'Content-Disposition: form-data; name="upfile"; filename="' + data.upfile.name + '"\r\n' + 'Content-Type: ' + data.upfile.type + '\r\n\r\n' + data.upfile.buffer + '\r\n'
|
parts.push 'Content-Disposition: form-data; name="upfile"; filename="' + data.upfile.name + '"\r\n' + 'Content-Type: ' + data.upfile.type + '\r\n\r\n' + data.upfile.buffer + '\r\n'
|
||||||
delete data.upfile
|
delete data.upfile
|
||||||
|
|
||||||
for name, val of data
|
for name, val of data
|
||||||
parts.push 'Content-Disposition: form-data; name="' + name + '"\r\n\r\n' + val + '\r\n' if val
|
parts.push 'Content-Disposition: form-data; name="' + name + '"\r\n\r\n' + val + '\r\n' if val
|
||||||
form = '--' + boundary + '\r\n' + parts.join('--' + boundary + '\r\n') + '--' + boundary + '--\r\n'
|
form = '--' + boundary + '\r\n' + parts.join('--' + boundary + '\r\n') + '--' + boundary + '--\r\n'
|
||||||
|
|
||||||
else
|
else
|
||||||
form = new FormData()
|
form = new FormData()
|
||||||
for name, val of data
|
for name, val of data
|
||||||
form.append name, val if val
|
form.append name, val if val
|
||||||
|
|
||||||
callbacks =
|
callbacks =
|
||||||
|
onload: ->
|
||||||
|
message.send
|
||||||
|
req: 'response'
|
||||||
|
html: @response
|
||||||
|
opts =
|
||||||
|
form: form
|
||||||
|
type: 'post'
|
||||||
|
upCallbacks:
|
||||||
onload: ->
|
onload: ->
|
||||||
qr.message.send
|
message.send
|
||||||
req: 'response'
|
req: 'status'
|
||||||
html: @response
|
progress: '...'
|
||||||
opts =
|
onprogress: (e) ->
|
||||||
form: form
|
message.send
|
||||||
type: 'post'
|
req: 'status'
|
||||||
upCallbacks:
|
progress: "#{Math.round e.loaded / e.total * 100}%"
|
||||||
onload: ->
|
if boundary
|
||||||
qr.message.send
|
opts.headers =
|
||||||
req: 'status'
|
'Content-Type': 'multipart/form-data;boundary=' + boundary
|
||||||
progress: '...'
|
|
||||||
onprogress: (e) ->
|
|
||||||
qr.message.send
|
|
||||||
req: 'status'
|
|
||||||
progress: "#{Math.round e.loaded / e.total * 100}%"
|
|
||||||
if boundary
|
|
||||||
opts.headers =
|
|
||||||
'Content-Type': 'multipart/form-data;boundary=' + boundary
|
|
||||||
|
|
||||||
qr.ajax = $.ajax url, callbacks, opts
|
qr.ajax = $.ajax url, callbacks, opts
|
||||||
|
|
||||||
options =
|
options =
|
||||||
init: ->
|
init: ->
|
||||||
@ -1921,7 +1864,7 @@ updater =
|
|||||||
else
|
else
|
||||||
d.title = d.title.match(/^.+-/)[0] + ' 404'
|
d.title = d.title.match(/^.+-/)[0] + ' 404'
|
||||||
unread.update true
|
unread.update true
|
||||||
qr.message.send req: 'abort'
|
message.send req: 'abort', 'sys'
|
||||||
qr.status()
|
qr.status()
|
||||||
Favicon.update()
|
Favicon.update()
|
||||||
return
|
return
|
||||||
@ -2713,6 +2656,98 @@ imgExpand =
|
|||||||
resize: ->
|
resize: ->
|
||||||
imgExpand.style.innerHTML = ".fitheight img[md5] + img {max-height:#{d.body.clientHeight}px;}"
|
imgExpand.style.innerHTML = ".fitheight img[md5] + img {max-height:#{d.body.clientHeight}px;}"
|
||||||
|
|
||||||
|
message =
|
||||||
|
init: ->
|
||||||
|
$.on window, 'message', message.receive
|
||||||
|
|
||||||
|
$.ready ->
|
||||||
|
return if location.hostname isnt 'boards.4chan.org'
|
||||||
|
domains = []
|
||||||
|
if conf['Quick Reply']
|
||||||
|
domains.push 'sys'
|
||||||
|
if conf['Image Expansion'] or conf['Sauce']
|
||||||
|
domains.push 'images'
|
||||||
|
for domain in domains
|
||||||
|
iframe = $.el 'iframe',
|
||||||
|
id: domain
|
||||||
|
hidden: true
|
||||||
|
src: "http://#{domain}.4chan.org/robots.txt"
|
||||||
|
$.on iframe, 'error', message.loadControl
|
||||||
|
$.on iframe, 'load', message.loadControl
|
||||||
|
$.add d.body, iframe
|
||||||
|
|
||||||
|
# http://code.google.com/p/chromium/issues/detail?id=20773
|
||||||
|
# Let content scripts see other frames (instead of them being undefined)
|
||||||
|
# To access the parent, we have to break out of the sandbox and evaluate
|
||||||
|
# in the global context.
|
||||||
|
code = (e) ->
|
||||||
|
{data} = e
|
||||||
|
return unless data.changeContext
|
||||||
|
delete data.changeContext
|
||||||
|
if location.hostname is 'boards.4chan.org'
|
||||||
|
document.getElementById(data.iframe).contentWindow.postMessage data, '*'
|
||||||
|
else
|
||||||
|
parent.postMessage data, '*'
|
||||||
|
|
||||||
|
script = $.el 'script',
|
||||||
|
textContent: "window.addEventListener('message',#{code},false)"
|
||||||
|
|
||||||
|
$.ready ->
|
||||||
|
$.add d.documentElement, script
|
||||||
|
host = location.hostname
|
||||||
|
if host is 'sys.4chan.org'
|
||||||
|
message.send req: 'status', ready: true
|
||||||
|
if host isnt 'boards.4chan.org'
|
||||||
|
message.send req: 'iframeLoad', id: location.hostname.split('.')[0]
|
||||||
|
$.rm script
|
||||||
|
|
||||||
|
loadControl: ->
|
||||||
|
# Make sure the iframe has loaded correctly.
|
||||||
|
# This is necessary for Greasemonkey users.
|
||||||
|
setTimeout (=>
|
||||||
|
return if @src is 'about:blank' or message[@id] is 'ready'
|
||||||
|
@src = 'about:blank'
|
||||||
|
setTimeout (=>
|
||||||
|
@src = "http://#{@id}.4chan.org/robots.txt"
|
||||||
|
), 250
|
||||||
|
), 1000
|
||||||
|
|
||||||
|
receive: (e) ->
|
||||||
|
{data} = e
|
||||||
|
if data.iframe
|
||||||
|
unless data.changeContext
|
||||||
|
message.handle data
|
||||||
|
return
|
||||||
|
|
||||||
|
{version} = data
|
||||||
|
if version and version isnt VERSION and confirm 'An updated version of 4chan X is available, would you like to install it now?'
|
||||||
|
window.location = "https://raw.github.com/mayhemydg/4chan-x/#{version}/4chan_x.user.js"
|
||||||
|
|
||||||
|
send: (data, iframe) ->
|
||||||
|
data.changeContext = true
|
||||||
|
data.iframe = iframe or 'boards'
|
||||||
|
postMessage data, '*'
|
||||||
|
|
||||||
|
handle: (data) ->
|
||||||
|
{req} = data
|
||||||
|
|
||||||
|
delete data.req
|
||||||
|
delete data.iframe
|
||||||
|
|
||||||
|
switch req
|
||||||
|
when 'iframeLoad'
|
||||||
|
message[data.id] = 'ready'
|
||||||
|
when 'abort'
|
||||||
|
qr.ajax?.abort()
|
||||||
|
message.send req: 'status'
|
||||||
|
when 'response' # xhr response
|
||||||
|
qr.response data.html
|
||||||
|
when 'status'
|
||||||
|
qr.status data
|
||||||
|
else
|
||||||
|
# Reply object: we're posting
|
||||||
|
qr.post data
|
||||||
|
|
||||||
Main =
|
Main =
|
||||||
init: ->
|
init: ->
|
||||||
pathname = location.pathname[1..].split('/')
|
pathname = location.pathname[1..].split('/')
|
||||||
@ -2723,12 +2758,10 @@ Main =
|
|||||||
else
|
else
|
||||||
g.PAGENUM = parseInt(temp) or 0
|
g.PAGENUM = parseInt(temp) or 0
|
||||||
|
|
||||||
$.on window, 'message', Main.message
|
message.init()
|
||||||
|
|
||||||
if location.hostname is 'sys.4chan.org'
|
if location.hostname is 'sys.4chan.org'
|
||||||
if location.pathname is '/robots.txt'
|
if /report/.test location.search
|
||||||
qr.message.init()
|
|
||||||
else if /report/.test location.search
|
|
||||||
$.ready ->
|
$.ready ->
|
||||||
$.on $('#recaptcha_response_field'), 'keydown', (e) ->
|
$.on $('#recaptcha_response_field'), 'keydown', (e) ->
|
||||||
window.location = 'javascript:Recaptcha.reload()' if e.keyCode is 8 and not e.target.value
|
window.location = 'javascript:Recaptcha.reload()' if e.keyCode is 8 and not e.target.value
|
||||||
@ -2887,14 +2920,6 @@ Main =
|
|||||||
else # XXX fox
|
else # XXX fox
|
||||||
$.on d, 'DOMNodeInserted', Main.addStyle
|
$.on d, 'DOMNodeInserted', Main.addStyle
|
||||||
|
|
||||||
message: (e) ->
|
|
||||||
{data} = e
|
|
||||||
{version} = data
|
|
||||||
if data.qr and not data.changeContext
|
|
||||||
qr.message.receive data
|
|
||||||
else if version and version isnt VERSION and confirm 'An updated version of 4chan X is available, would you like to install it now?'
|
|
||||||
window.location = "https://raw.github.com/mayhemydg/4chan-x/#{version}/4chan_x.user.js"
|
|
||||||
|
|
||||||
node: (e) ->
|
node: (e) ->
|
||||||
{target} = e
|
{target} = e
|
||||||
return unless target.nodeName is 'TABLE'
|
return unless target.nodeName is 'TABLE'
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user