We CORS now. At least on sys.4chan.org, so ban detection on non Chrom* browsers is still inaccurate. Close #368
This commit is contained in:
parent
f1ef6dfd2b
commit
8a0e70b19c
303
4chan_x.user.js
303
4chan_x.user.js
@ -9,7 +9,6 @@
|
||||
// @include http*://boards.4chan.org/*
|
||||
// @include http*://images.4chan.org/*
|
||||
// @include http*://sys.4chan.org/*
|
||||
// @include http*://www.4chan.org/*
|
||||
// @run-at document-start
|
||||
// @updateURL https://raw.github.com/MayhemYDG/4chan-x/stable/4chan_x.user.js
|
||||
// @icon http://mayhemydg.github.com/4chan-x/favicon.gif
|
||||
@ -1226,46 +1225,17 @@
|
||||
return setTimeout(this.asyncInit);
|
||||
},
|
||||
asyncInit: function() {
|
||||
var form, iframe, link, loadChecking, script, src;
|
||||
form = $('form[name=post]');
|
||||
var link, script;
|
||||
if (Conf['Hide Original Post Form']) {
|
||||
link = $.el('h1', {
|
||||
innerHTML: "<a href=javascript:;>" + (g.REPLY ? 'Quick Reply' : 'New Thread') + "</a>"
|
||||
});
|
||||
$.on($('a', link), 'click', function() {
|
||||
$.on(link.firstChild, 'click', function() {
|
||||
QR.open();
|
||||
if (!g.REPLY) $('select', QR.el).value = 'new';
|
||||
return $('textarea', QR.el).focus();
|
||||
});
|
||||
$.before(form, link);
|
||||
}
|
||||
if (/chrome/i.test(navigator.userAgent)) {
|
||||
QR.status({
|
||||
ready: true
|
||||
});
|
||||
} else {
|
||||
src = "http" + (/^https/.test(form.action) ? 's' : '') + "://sys.4chan.org/robots.txt";
|
||||
iframe = $.el('iframe', {
|
||||
id: 'iframe',
|
||||
src: src
|
||||
});
|
||||
$.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 = src;
|
||||
}), 100);
|
||||
}
|
||||
};
|
||||
$.on(iframe, 'load', function() {
|
||||
if (this.src !== 'about:blank') {
|
||||
return setTimeout(loadChecking, 500, this);
|
||||
}
|
||||
});
|
||||
$.add(d.head, iframe);
|
||||
$.before($('form[name=post]'), link);
|
||||
}
|
||||
script = $.el('script', {
|
||||
textContent: 'Recaptcha.focus_response_field=function(){}'
|
||||
@ -1294,9 +1264,7 @@
|
||||
close: function() {
|
||||
var i, spoiler, _i, _len, _ref;
|
||||
QR.el.hidden = true;
|
||||
QR.message.send({
|
||||
req: 'abort'
|
||||
});
|
||||
QR.abort();
|
||||
d.activeElement.blur();
|
||||
$.removeClass(QR.el, 'dump');
|
||||
_ref = QR.replies;
|
||||
@ -1341,23 +1309,12 @@
|
||||
status: function(data) {
|
||||
var disabled, input, value;
|
||||
if (data == null) data = {};
|
||||
if (data.ready) {
|
||||
QR.status.ready = true;
|
||||
QR.status.banned = data.banned;
|
||||
} else if (!QR.status.ready) {
|
||||
value = 'Loading';
|
||||
disabled = true;
|
||||
}
|
||||
if (g.dead) {
|
||||
value = 404;
|
||||
disabled = true;
|
||||
QR.cooldown.auto = false;
|
||||
} else if (QR.status.banned) {
|
||||
value = 'Banned';
|
||||
disabled = true;
|
||||
} else {
|
||||
value = QR.cooldown.seconds || data.progress || value;
|
||||
}
|
||||
value = QR.cooldown.seconds || data.progress || value;
|
||||
if (!QR.el) return;
|
||||
input = QR.status.input;
|
||||
input.value = QR.cooldown.auto && Conf['Cooldown'] ? value ? "Auto " + value : 'Auto' : value || 'Submit';
|
||||
@ -1823,16 +1780,14 @@
|
||||
return QR.el.dispatchEvent(e);
|
||||
},
|
||||
submit: function(e) {
|
||||
var captcha, captchas, challenge, err, file, m, post, reader, reply, response, threadID;
|
||||
var callbacks, captcha, captchas, challenge, err, form, m, name, opts, post, reply, response, threadID, val;
|
||||
if (e != null) e.preventDefault();
|
||||
if (QR.cooldown.seconds) {
|
||||
QR.cooldown.auto = !QR.cooldown.auto;
|
||||
QR.status();
|
||||
return;
|
||||
}
|
||||
QR.message.send({
|
||||
req: 'abort'
|
||||
});
|
||||
QR.abort();
|
||||
reply = QR.replies[0];
|
||||
if (!(reply.com || reply.file)) {
|
||||
err = 'No file selected.';
|
||||
@ -1865,8 +1820,10 @@
|
||||
if (Conf['Thread Watcher'] && Conf['Auto Watch Reply'] && threadID !== 'new') {
|
||||
Watcher.watch(threadID);
|
||||
}
|
||||
QR.status({
|
||||
progress: '...'
|
||||
});
|
||||
post = {
|
||||
postURL: $('form[name=post]').action,
|
||||
resto: threadID,
|
||||
name: reply.name,
|
||||
email: reply.email,
|
||||
@ -1879,37 +1836,51 @@
|
||||
recaptcha_challenge_field: challenge,
|
||||
recaptcha_response_field: response + ' '
|
||||
};
|
||||
QR.status({
|
||||
progress: '...'
|
||||
});
|
||||
if ($.engine === 'gecko' && reply.file) {
|
||||
file = {};
|
||||
reader = new FileReader();
|
||||
reader.onload = function() {
|
||||
file.buffer = this.result;
|
||||
file.name = reply.file.name;
|
||||
file.type = reply.file.type;
|
||||
post.upfile = file;
|
||||
return QR.message.send(post);
|
||||
};
|
||||
reader.readAsBinaryString(reply.file);
|
||||
return;
|
||||
form = new FormData();
|
||||
for (name in post) {
|
||||
val = post[name];
|
||||
if (val) form.append(name, val);
|
||||
}
|
||||
if (/chrome/i.test(navigator.userAgent)) {
|
||||
QR.message.post(post);
|
||||
return;
|
||||
}
|
||||
return QR.message.send(post);
|
||||
callbacks = {
|
||||
onload: function() {
|
||||
return QR.response(this.response);
|
||||
},
|
||||
onerror: function() {
|
||||
return QR.error('_', $.el('a', {
|
||||
href: '//www.4chan.org/banned',
|
||||
target: '_blank',
|
||||
textContent: 'Connection error, or you are banned.'
|
||||
}));
|
||||
}
|
||||
};
|
||||
opts = {
|
||||
form: form,
|
||||
type: 'POST',
|
||||
upCallbacks: {
|
||||
onload: function() {
|
||||
return QR.status({
|
||||
progress: '...'
|
||||
});
|
||||
},
|
||||
onprogress: function(e) {
|
||||
return QR.status({
|
||||
progress: "" + (Math.round(e.loaded / e.total * 100)) + "%"
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
return QR.ajax = $.ajax($('form[name=post]').action, callbacks, opts);
|
||||
},
|
||||
response: function(html) {
|
||||
var b, doc, err, node, persona, postNumber, reply, thread, _, _ref;
|
||||
doc = $.el('a', {
|
||||
innerHTML: html
|
||||
});
|
||||
if ($('title', doc).textContent === '4chan - Banned') {
|
||||
QR.message.receive({
|
||||
req: 'banned'
|
||||
});
|
||||
doc = d.implementation.createHTMLDocument(null);
|
||||
doc.documentElement.innerHTML = html;
|
||||
if (doc.title === '4chan - Banned') {
|
||||
QR.error('_', $.el('a', {
|
||||
href: '//www.4chan.org/banned',
|
||||
target: '_blank',
|
||||
textContent: 'You are banned.'
|
||||
}));
|
||||
return;
|
||||
}
|
||||
if (!(b = $('td b', doc))) {
|
||||
@ -1967,146 +1938,10 @@
|
||||
QR.status();
|
||||
return QR.resetFileInput();
|
||||
},
|
||||
message: {
|
||||
send: function(data) {
|
||||
var host, window;
|
||||
if (/chrome/i.test(navigator.userAgent)) {
|
||||
QR.message.receive(data);
|
||||
return;
|
||||
}
|
||||
data.QR = true;
|
||||
host = location.hostname;
|
||||
window = host === 'boards.4chan.org' ? $.id('iframe').contentWindow : parent;
|
||||
return window.postMessage(data, '*');
|
||||
},
|
||||
receive: function(data) {
|
||||
var req, _ref;
|
||||
req = data.req;
|
||||
delete data.req;
|
||||
delete data.QR;
|
||||
switch (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);
|
||||
case 'connection error':
|
||||
return QR.error('_', $.el('a', {
|
||||
href: '//www.4chan.org/banned',
|
||||
target: '_blank',
|
||||
textContent: 'Connection error, or you are banned.'
|
||||
}));
|
||||
case 'banned':
|
||||
QR.error('_', $.el('a', {
|
||||
href: '//www.4chan.org/banned',
|
||||
target: '_blank',
|
||||
textContent: 'You are banned.'
|
||||
}));
|
||||
return QR.status({
|
||||
ready: true,
|
||||
banned: true
|
||||
});
|
||||
default:
|
||||
return QR.message.post(data);
|
||||
}
|
||||
},
|
||||
post: function(data) {
|
||||
var boundary, callbacks, form, i, name, opts, parts, toBin, url, val;
|
||||
url = data.postURL;
|
||||
delete data.postURL;
|
||||
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;
|
||||
for (name in data) {
|
||||
val = data[name];
|
||||
if (typeof val === 'object') {
|
||||
toBin(data.upfile, 'name', data.upfile.name);
|
||||
} else if (typeof val === 'boolean') {
|
||||
if (val) {
|
||||
toBin(data, name, String(val));
|
||||
} else {
|
||||
i--;
|
||||
}
|
||||
} else {
|
||||
toBin(data, name, val);
|
||||
}
|
||||
}
|
||||
data.postURL = url;
|
||||
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';
|
||||
} else {
|
||||
form = new FormData();
|
||||
for (name in data) {
|
||||
val = data[name];
|
||||
if (val) form.append(name, val);
|
||||
}
|
||||
}
|
||||
callbacks = {
|
||||
onload: function() {
|
||||
return QR.message.send({
|
||||
req: 'response',
|
||||
html: this.response
|
||||
});
|
||||
},
|
||||
onerror: function() {
|
||||
return QR.message.send({
|
||||
req: 'connection error'
|
||||
});
|
||||
}
|
||||
};
|
||||
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);
|
||||
}
|
||||
abort: function() {
|
||||
var _ref;
|
||||
if ((_ref = QR.ajax) != null) _ref.abort();
|
||||
return QR.status();
|
||||
}
|
||||
};
|
||||
|
||||
@ -2566,10 +2401,7 @@
|
||||
d.title = d.title.match(/^.+-/)[0] + ' 404';
|
||||
}
|
||||
Unread.update(true);
|
||||
QR.message.send({
|
||||
req: 'abort'
|
||||
});
|
||||
QR.status();
|
||||
QR.abort();
|
||||
return;
|
||||
}
|
||||
Updater.retryCoef = 10;
|
||||
@ -3811,12 +3643,7 @@
|
||||
$.on(window, 'message', Main.message);
|
||||
switch (location.hostname) {
|
||||
case 'sys.4chan.org':
|
||||
if (path === '/robots.txt') {
|
||||
QR.message.send({
|
||||
req: 'status',
|
||||
ready: true
|
||||
});
|
||||
} else if (/report/.test(location.search)) {
|
||||
if (/report/.test(location.search)) {
|
||||
$.ready(function() {
|
||||
return $.on($.id('recaptcha_response_field'), 'keydown', function(e) {
|
||||
if (e.keyCode === 8 && !e.target.value) {
|
||||
@ -3826,13 +3653,6 @@
|
||||
});
|
||||
}
|
||||
return;
|
||||
case 'www.4chan.org':
|
||||
if (path === '/banned') {
|
||||
QR.message.send({
|
||||
req: 'banned'
|
||||
});
|
||||
}
|
||||
return;
|
||||
case 'images.4chan.org':
|
||||
$.ready(function() {
|
||||
if (d.title === '4chan - 404') return Redirect.init();
|
||||
@ -3993,13 +3813,8 @@
|
||||
}
|
||||
},
|
||||
message: function(e) {
|
||||
var data, version;
|
||||
data = e.data;
|
||||
if (data.QR) {
|
||||
QR.message.receive(data);
|
||||
return;
|
||||
}
|
||||
version = data.version;
|
||||
var version;
|
||||
version = e.data.version;
|
||||
if (version && version !== Main.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";
|
||||
}
|
||||
|
||||
1
Cakefile
1
Cakefile
@ -16,7 +16,6 @@ HEADER = """
|
||||
// @include http*://boards.4chan.org/*
|
||||
// @include http*://images.4chan.org/*
|
||||
// @include http*://sys.4chan.org/*
|
||||
// @include http*://www.4chan.org/*
|
||||
// @run-at document-start
|
||||
// @updateURL https://raw.github.com/MayhemYDG/4chan-x/stable/4chan_x.user.js
|
||||
// @icon http://mayhemydg.github.com/4chan-x/favicon.gif
|
||||
|
||||
240
script.coffee
240
script.coffee
@ -1010,34 +1010,17 @@ QR =
|
||||
setTimeout @asyncInit
|
||||
|
||||
asyncInit: ->
|
||||
form = $ 'form[name=post]'
|
||||
if Conf['Hide Original Post Form']
|
||||
link = $.el 'h1', innerHTML: "<a href=javascript:;>#{if g.REPLY then 'Quick Reply' else 'New Thread'}</a>"
|
||||
$.on $('a', link), 'click', ->
|
||||
$.on link.firstChild, 'click', ->
|
||||
QR.open()
|
||||
$('select', QR.el).value = 'new' unless g.REPLY
|
||||
$('textarea', QR.el).focus()
|
||||
$.before form, link
|
||||
|
||||
# CORS is ignored for content script on Chrome, but not Safari/Oprah/Firefox.
|
||||
if /chrome/i.test navigator.userAgent
|
||||
QR.status ready: true
|
||||
else
|
||||
src = "http#{if /^https/.test form.action then 's' else ''}://sys.4chan.org/robots.txt"
|
||||
iframe = $.el 'iframe',
|
||||
id: 'iframe'
|
||||
src: src
|
||||
$.on iframe, 'error', -> @src = @src
|
||||
# Greasemonkey ghetto fix
|
||||
loadChecking = (iframe) ->
|
||||
unless QR.status.ready
|
||||
iframe.src = 'about:blank'
|
||||
setTimeout (-> iframe.src = src), 100
|
||||
$.on iframe, 'load', -> if @src isnt 'about:blank' then setTimeout loadChecking, 500, @
|
||||
$.add d.head, iframe
|
||||
$.before $('form[name=post]'), link
|
||||
|
||||
# Prevent original captcha input from being focused on reload.
|
||||
script = $.el 'script', textContent: 'Recaptcha.focus_response_field=function(){}'
|
||||
script = $.el 'script',
|
||||
textContent: 'Recaptcha.focus_response_field=function(){}'
|
||||
$.add d.head, script
|
||||
$.rm script
|
||||
|
||||
@ -1059,7 +1042,7 @@ QR =
|
||||
QR.dialog()
|
||||
close: ->
|
||||
QR.el.hidden = true
|
||||
QR.message.send req: 'abort'
|
||||
QR.abort()
|
||||
d.activeElement.blur()
|
||||
$.removeClass QR.el, 'dump'
|
||||
for i in QR.replies
|
||||
@ -1093,22 +1076,11 @@ QR =
|
||||
$('.warning', QR.el).textContent = null
|
||||
|
||||
status: (data={}) ->
|
||||
if data.ready
|
||||
QR.status.ready = true
|
||||
QR.status.banned = data.banned
|
||||
else unless QR.status.ready
|
||||
value = 'Loading'
|
||||
disabled = true
|
||||
if g.dead
|
||||
value = 404
|
||||
disabled = true
|
||||
QR.cooldown.auto = false
|
||||
else if QR.status.banned
|
||||
value = 'Banned'
|
||||
disabled = true
|
||||
else
|
||||
# do not cancel `value = 'Loading'` once the cooldown is over
|
||||
value = QR.cooldown.seconds or data.progress or value
|
||||
value = QR.cooldown.seconds or data.progress or value
|
||||
return unless QR.el
|
||||
{input} = QR.status
|
||||
input.value =
|
||||
@ -1509,7 +1481,7 @@ QR =
|
||||
QR.cooldown.auto = !QR.cooldown.auto
|
||||
QR.status()
|
||||
return
|
||||
QR.message.send req: 'abort'
|
||||
QR.abort()
|
||||
reply = QR.replies[0]
|
||||
|
||||
# prevent errors
|
||||
@ -1549,8 +1521,11 @@ QR =
|
||||
if Conf['Thread Watcher'] and Conf['Auto Watch Reply'] and threadID isnt 'new'
|
||||
Watcher.watch threadID
|
||||
|
||||
# Starting to upload might take some time.
|
||||
# Provide some feedback that we're starting to submit.
|
||||
QR.status progress: '...'
|
||||
|
||||
post =
|
||||
postURL: $('form[name=post]').action
|
||||
resto: threadID
|
||||
name: reply.name
|
||||
email: reply.email
|
||||
@ -1563,36 +1538,42 @@ QR =
|
||||
recaptcha_challenge_field: challenge
|
||||
recaptcha_response_field: response + ' '
|
||||
|
||||
# Starting to upload might take some time.
|
||||
# Provide some feedback that we're starting to submit.
|
||||
QR.status progress: '...'
|
||||
form = new FormData()
|
||||
for name, val of post
|
||||
form.append name, val if val
|
||||
|
||||
if $.engine is 'gecko' and reply.file
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=673742
|
||||
# We plan to allow postMessaging Files and FileLists across origins,
|
||||
# that just needs a more in depth security review.
|
||||
file = {}
|
||||
reader = new FileReader()
|
||||
reader.onload = ->
|
||||
file.buffer = @result
|
||||
file.name = reply.file.name
|
||||
file.type = reply.file.type
|
||||
post.upfile = file
|
||||
QR.message.send post
|
||||
reader.readAsBinaryString reply.file
|
||||
return
|
||||
callbacks =
|
||||
onload: ->
|
||||
QR.response @response
|
||||
onerror: ->
|
||||
# Connection error, or
|
||||
# CORS disabled error on www.4chan.org/banned
|
||||
QR.error '_', $.el 'a',
|
||||
href: '//www.4chan.org/banned'
|
||||
target: '_blank'
|
||||
textContent: 'Connection error, or you are banned.'
|
||||
opts =
|
||||
form: form
|
||||
type: 'POST'
|
||||
upCallbacks:
|
||||
onload: ->
|
||||
# Upload done, waiting for response.
|
||||
QR.status progress: '...'
|
||||
onprogress: (e) ->
|
||||
# Uploading...
|
||||
QR.status progress: "#{Math.round e.loaded / e.total * 100}%"
|
||||
|
||||
# CORS is ignored for content script on Chrome, but not Safari/Oprah/Firefox.
|
||||
if /chrome/i.test navigator.userAgent
|
||||
QR.message.post post
|
||||
return
|
||||
QR.message.send post
|
||||
QR.ajax = $.ajax $('form[name=post]').action, callbacks, opts
|
||||
|
||||
response: (html) ->
|
||||
doc = $.el 'a', innerHTML: html
|
||||
doc = d.implementation.createHTMLDocument null
|
||||
doc.documentElement.innerHTML = html
|
||||
# Check for ban.
|
||||
if $('title', doc).textContent is '4chan - Banned'
|
||||
QR.message.receive req: 'banned'
|
||||
if doc.title is '4chan - Banned'
|
||||
QR.error '_', $.el 'a',
|
||||
href: '//www.4chan.org/banned'
|
||||
target: '_blank'
|
||||
textContent: 'You are banned.'
|
||||
return
|
||||
unless b = $ 'td b', doc
|
||||
err = 'Connection error with sys.4chan.org.'
|
||||
@ -1650,123 +1631,9 @@ QR =
|
||||
QR.status()
|
||||
QR.resetFileInput()
|
||||
|
||||
message:
|
||||
send: (data) ->
|
||||
# CORS is ignored for content script on Chrome, but not Safari/Oprah/Firefox.
|
||||
if /chrome/i.test navigator.userAgent
|
||||
QR.message.receive data
|
||||
return
|
||||
data.QR = true
|
||||
host = location.hostname
|
||||
window =
|
||||
if host is 'boards.4chan.org'
|
||||
$.id('iframe').contentWindow
|
||||
else
|
||||
parent
|
||||
window.postMessage data, '*'
|
||||
receive: (data) ->
|
||||
req = data.req
|
||||
delete data.req
|
||||
delete data.QR
|
||||
switch req
|
||||
when 'abort'
|
||||
QR.ajax?.abort()
|
||||
QR.message.send req: 'status'
|
||||
when 'response' # xhr response
|
||||
QR.response data.html
|
||||
when 'status'
|
||||
QR.status data
|
||||
when 'connection error'
|
||||
QR.error '_', $.el 'a',
|
||||
href: '//www.4chan.org/banned'
|
||||
target: '_blank'
|
||||
textContent: 'Connection error, or you are banned.'
|
||||
when 'banned'
|
||||
QR.error '_', $.el 'a',
|
||||
href: '//www.4chan.org/banned'
|
||||
target: '_blank'
|
||||
textContent: 'You are banned.'
|
||||
# Disable iframe reloading
|
||||
QR.status ready: true, banned: true
|
||||
else
|
||||
QR.message.post data # Reply object: we're posting
|
||||
|
||||
post: (data) ->
|
||||
|
||||
url = data.postURL
|
||||
# Do not append these values to the form.
|
||||
delete data.postURL
|
||||
|
||||
# File with filename upload fix from desuwa
|
||||
if $.engine is 'gecko' and data.upfile
|
||||
# All of this is fucking retarded.
|
||||
unless data.binary
|
||||
toBin = (data, name, val) ->
|
||||
bb = new MozBlobBuilder()
|
||||
bb.append val
|
||||
r = new FileReader()
|
||||
r.onload = ->
|
||||
data[name] = r.result
|
||||
unless --i
|
||||
QR.message.post data
|
||||
r.readAsBinaryString bb.getBlob 'text/plain'
|
||||
i = Object.keys(data).length
|
||||
for name, val of data
|
||||
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
|
||||
toBin data, name, val
|
||||
data.postURL = url
|
||||
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, val of data
|
||||
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'
|
||||
|
||||
else
|
||||
form = new FormData()
|
||||
for name, val of data
|
||||
form.append name, val if val
|
||||
|
||||
callbacks =
|
||||
onload: ->
|
||||
QR.message.send
|
||||
req: 'response'
|
||||
html: @response
|
||||
onerror: ->
|
||||
# Connection error, or
|
||||
# CORS disabled error: redirecting to banned page ;_;
|
||||
QR.message.send req: 'connection error'
|
||||
opts =
|
||||
form: form
|
||||
type: 'post'
|
||||
upCallbacks:
|
||||
onload: ->
|
||||
QR.message.send
|
||||
req: 'status'
|
||||
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
|
||||
abort: ->
|
||||
QR.ajax?.abort()
|
||||
QR.status()
|
||||
|
||||
Options =
|
||||
init: ->
|
||||
@ -2179,8 +2046,7 @@ Updater =
|
||||
else
|
||||
d.title = d.title.match(/^.+-/)[0] + ' 404'
|
||||
Unread.update true
|
||||
QR.message.send req: 'abort'
|
||||
QR.status()
|
||||
QR.abort()
|
||||
return
|
||||
|
||||
Updater.retryCoef = 10
|
||||
@ -3178,17 +3044,11 @@ Main =
|
||||
|
||||
switch location.hostname
|
||||
when 'sys.4chan.org'
|
||||
if path is '/robots.txt'
|
||||
QR.message.send req: 'status', ready: true
|
||||
else if /report/.test location.search
|
||||
if /report/.test location.search
|
||||
$.ready ->
|
||||
$.on $.id('recaptcha_response_field'), 'keydown', (e) ->
|
||||
window.location = 'javascript:Recaptcha.reload()' if e.keyCode is 8 and not e.target.value
|
||||
return
|
||||
when 'www.4chan.org'
|
||||
if path is '/banned'
|
||||
QR.message.send req: 'banned'
|
||||
return
|
||||
when 'images.4chan.org'
|
||||
$.ready -> Redirect.init() if d.title is '4chan - 404'
|
||||
return
|
||||
@ -3365,11 +3225,7 @@ Main =
|
||||
$.on d, 'DOMNodeInserted', Main.addStyle
|
||||
|
||||
message: (e) ->
|
||||
{data} = e
|
||||
if data.QR
|
||||
QR.message.receive data
|
||||
return
|
||||
{version} = data
|
||||
{version} = e.data
|
||||
if version and version isnt Main.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"
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user