diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js
index a54e6a059..41c542a2f 100644
--- a/builds/4chan-X.user.js
+++ b/builds/4chan-X.user.js
@@ -441,13 +441,22 @@
return fd;
};
- $.ajax = function(url, callbacks, opts) {
- var cred, err, form, headers, key, r, sync, type, upCallbacks, val;
+ $.extend = function(object, properties) {
+ var key, val;
- if (opts == null) {
- opts = {};
+ for (key in properties) {
+ val = properties[key];
+ object[key] = val;
}
- type = opts.type, cred = opts.cred, headers = opts.headers, upCallbacks = opts.upCallbacks, form = opts.form, sync = opts.sync;
+ };
+
+ $.ajax = function(url, options, extra) {
+ var form, headers, key, r, sync, type, upCallbacks, val;
+
+ if (extra == null) {
+ extra = {};
+ }
+ type = extra.type, headers = extra.headers, upCallbacks = extra.upCallbacks, form = extra.form, sync = extra.sync;
r = new XMLHttpRequest();
r.overrideMimeType('text/html');
type || (type = form && 'post' || 'get');
@@ -456,13 +465,8 @@
val = headers[key];
r.setRequestHeader(key, val);
}
- $.extend(r, callbacks);
+ $.extend(r, options);
$.extend(r.upload, upCallbacks);
- try {
- r.withCredentials = cred;
- } catch (_error) {
- err = _error;
- }
r.send(form);
return r;
};
@@ -5968,7 +5972,7 @@
},
preSubmitHooks: [],
submit: function(e) {
- var callbacks, challenge, err, filetag, hook, opts, post, postData, response, textOnly, thread, threadID, _i, _len, _ref, _ref1;
+ var challenge, err, extra, filetag, hook, options, post, postData, response, textOnly, thread, threadID, _i, _len, _ref, _ref1;
if (e != null) {
e.preventDefault();
@@ -6047,7 +6051,9 @@
recaptcha_challenge_field: challenge,
recaptcha_response_field: response
};
- callbacks = {
+ options = {
+ responseType: 'document',
+ withCredentials: true,
onload: QR.response,
onerror: function() {
delete QR.req;
@@ -6055,12 +6061,11 @@
QR.cooldown.auto = false;
QR.status();
return QR.error($.el('span', {
- innerHTML: "4chan X encountered an error while posting. Please try again. \n[?]"
+ innerHTML: "4chan X encountered an error while posting. Please try again.\n[?]"
}));
}
};
- opts = {
- cred: true,
+ extra = {
form: $.formData(postData),
upCallbacks: {
onload: function() {
@@ -6075,30 +6080,29 @@
}
}
};
- QR.req = $.ajax($.id('postForm').parentNode.action, callbacks, opts);
+ QR.req = $.ajax($.id('postForm').parentNode.action, options, extra);
QR.req.uploadStartTime = Date.now();
QR.req.progress = '...';
return QR.status();
},
response: function() {
- var URL, ban, board, err, h1, isReply, m, post, postID, req, threadID, tmpDoc, _, _ref, _ref1;
+ var URL, ban, board, err, h1, isReply, m, post, postID, req, resDoc, threadID, _, _ref, _ref1;
req = QR.req;
delete QR.req;
post = QR.posts[0];
post.unlock();
- tmpDoc = d.implementation.createHTMLDocument('');
- tmpDoc.documentElement.innerHTML = req.response;
- if (ban = $('.banType', tmpDoc)) {
- board = $('.board', tmpDoc).innerHTML;
+ resDoc = req.response;
+ if (ban = $('.banType', resDoc)) {
+ board = $('.board', resDoc).innerHTML;
err = $.el('span', {
- innerHTML: ban.textContent.toLowerCase() === 'banned' ? ("You are banned on " + board + "! ;_;
") + "Click here to see the reason." : ("You were issued a warning on " + board + " as " + ($('.nameBlock', tmpDoc).innerHTML) + ".
") + ("Reason: " + ($('.reason', tmpDoc).innerHTML))
+ innerHTML: ban.textContent.toLowerCase() === 'banned' ? "You are banned on " + board + "! ;_;
\nClick here to see the reason." : "You were issued a warning on " + board + " as " + ($('.nameBlock', resDoc).innerHTML) + ".
\nReason: " + ($('.reason', resDoc).innerHTML)
});
- } else if (err = tmpDoc.getElementById('errmsg')) {
+ } else if (err = resDoc.getElementById('errmsg')) {
if ((_ref = $('a', err)) != null) {
_ref.target = '_blank';
}
- } else if (tmpDoc.title !== 'Post successful!') {
+ } else if (resDoc.title !== 'Post successful!') {
err = 'Connection error with sys.4chan.org.';
} else if (req.status !== 200) {
err = "Error " + req.statusText + " (" + req.status + ")";
@@ -6124,8 +6128,8 @@
QR.error(err);
return;
}
+ h1 = $('h1', resDoc);
QR.cleanNotifications();
- h1 = $('h1', tmpDoc);
if (Conf['Posting Success Notifications']) {
QR.notifications.push(new Notification('success', h1.textContent, 5));
}
@@ -6879,6 +6883,8 @@
form[post.ID] = 'delete';
link = this;
return $.ajax($.id('delform').action.replace("/" + g.BOARD + "/", "/" + post.board + "/"), {
+ responseType: 'document',
+ withCredentials: true,
onload: function() {
return DeleteLink.load(link, post, fileOnly, this.response);
},
@@ -6886,22 +6892,19 @@
return DeleteLink.error(link);
}
}, {
- cred: true,
form: $.formData(form)
});
},
- load: function(link, post, fileOnly, html) {
- var msg, s, tmpDoc;
+ load: function(link, post, fileOnly, resDoc) {
+ var msg, s;
- tmpDoc = d.implementation.createHTMLDocument('');
- tmpDoc.documentElement.innerHTML = html;
- if (tmpDoc.title === '4chan - Banned') {
+ if (resDoc.title === '4chan - Banned') {
s = 'Banned!';
- } else if (msg = tmpDoc.getElementById('errmsg')) {
+ } else if (msg = resDoc.getElementById('errmsg')) {
s = msg.textContent;
$.on(link, 'click', DeleteLink["delete"]);
} else {
- if (tmpDoc.title === 'Updating index...') {
+ if (resDoc.title === 'Updating index...') {
(post.origin || post).kill(fileOnly);
}
s = 'Deleted';
@@ -7930,8 +7933,7 @@
if (Conf['Unread Line']) {
Unread.setLine(posts.contains(Unread.posts[0]));
}
- Unread.read();
- return Unread.update();
+ return Unread.read();
},
addPostQuotingYou: function(post) {
var quotelink, _i, _len, _ref;
@@ -7981,17 +7983,16 @@
}
return arr.splice(0, i);
},
- read: $.debounce(50, function(e) {
- var ID, bottom, height, i, post, posts, read;
+ read: $.debounce(50, function() {
+ var ID, bottom, height, i, post, posts;
if (d.hidden || !Unread.posts.length) {
return;
}
height = doc.clientHeight;
posts = Unread.posts;
- read = [];
- i = posts.length;
- while (post = posts[--i]) {
+ i = 0;
+ while (post = posts[i++]) {
bottom = post.nodes.root.getBoundingClientRect().bottom;
if (bottom < height) {
ID = post.ID;
@@ -8004,9 +8005,7 @@
Unread.lastReadPost = ID;
Unread.saveLastReadPost();
Unread.readArray(Unread.postsQuotingYou);
- if (e) {
- return Unread.update();
- }
+ return Unread.update();
}),
saveLastReadPost: $.debounce(2 * $.SECOND, function() {
if (Unread.thread.isDead) {
diff --git a/builds/crx/script.js b/builds/crx/script.js
index 29c696204..e88002f09 100644
--- a/builds/crx/script.js
+++ b/builds/crx/script.js
@@ -422,13 +422,22 @@
return fd;
};
- $.ajax = function(url, callbacks, opts) {
- var cred, err, form, headers, key, r, sync, type, upCallbacks, val;
+ $.extend = function(object, properties) {
+ var key, val;
- if (opts == null) {
- opts = {};
+ for (key in properties) {
+ val = properties[key];
+ object[key] = val;
}
- type = opts.type, cred = opts.cred, headers = opts.headers, upCallbacks = opts.upCallbacks, form = opts.form, sync = opts.sync;
+ };
+
+ $.ajax = function(url, options, extra) {
+ var form, headers, key, r, sync, type, upCallbacks, val;
+
+ if (extra == null) {
+ extra = {};
+ }
+ type = extra.type, headers = extra.headers, upCallbacks = extra.upCallbacks, form = extra.form, sync = extra.sync;
r = new XMLHttpRequest();
r.overrideMimeType('text/html');
type || (type = form && 'post' || 'get');
@@ -437,13 +446,8 @@
val = headers[key];
r.setRequestHeader(key, val);
}
- $.extend(r, callbacks);
+ $.extend(r, options);
$.extend(r.upload, upCallbacks);
- try {
- r.withCredentials = cred;
- } catch (_error) {
- err = _error;
- }
r.send(form);
return r;
};
@@ -5949,7 +5953,7 @@
},
preSubmitHooks: [],
submit: function(e) {
- var callbacks, challenge, err, filetag, hook, opts, post, postData, response, textOnly, thread, threadID, _i, _len, _ref, _ref1;
+ var challenge, err, extra, filetag, hook, options, post, postData, response, textOnly, thread, threadID, _i, _len, _ref, _ref1;
if (e != null) {
e.preventDefault();
@@ -6028,7 +6032,9 @@
recaptcha_challenge_field: challenge,
recaptcha_response_field: response
};
- callbacks = {
+ options = {
+ responseType: 'document',
+ withCredentials: true,
onload: QR.response,
onerror: function() {
delete QR.req;
@@ -6036,12 +6042,11 @@
QR.cooldown.auto = false;
QR.status();
return QR.error($.el('span', {
- innerHTML: "4chan X encountered an error while posting. Please try again. \n[?]"
+ innerHTML: "4chan X encountered an error while posting. Please try again.\n[?]"
}));
}
};
- opts = {
- cred: true,
+ extra = {
form: $.formData(postData),
upCallbacks: {
onload: function() {
@@ -6056,30 +6061,29 @@
}
}
};
- QR.req = $.ajax($.id('postForm').parentNode.action, callbacks, opts);
+ QR.req = $.ajax($.id('postForm').parentNode.action, options, extra);
QR.req.uploadStartTime = Date.now();
QR.req.progress = '...';
return QR.status();
},
response: function() {
- var URL, ban, board, err, h1, isReply, m, post, postID, req, threadID, tmpDoc, _, _ref, _ref1;
+ var URL, ban, board, err, h1, isReply, m, post, postID, req, resDoc, threadID, _, _ref, _ref1;
req = QR.req;
delete QR.req;
post = QR.posts[0];
post.unlock();
- tmpDoc = d.implementation.createHTMLDocument('');
- tmpDoc.documentElement.innerHTML = req.response;
- if (ban = $('.banType', tmpDoc)) {
- board = $('.board', tmpDoc).innerHTML;
+ resDoc = req.response;
+ if (ban = $('.banType', resDoc)) {
+ board = $('.board', resDoc).innerHTML;
err = $.el('span', {
- innerHTML: ban.textContent.toLowerCase() === 'banned' ? ("You are banned on " + board + "! ;_;
") + "Click here to see the reason." : ("You were issued a warning on " + board + " as " + ($('.nameBlock', tmpDoc).innerHTML) + ".
") + ("Reason: " + ($('.reason', tmpDoc).innerHTML))
+ innerHTML: ban.textContent.toLowerCase() === 'banned' ? "You are banned on " + board + "! ;_;
\nClick here to see the reason." : "You were issued a warning on " + board + " as " + ($('.nameBlock', resDoc).innerHTML) + ".
\nReason: " + ($('.reason', resDoc).innerHTML)
});
- } else if (err = tmpDoc.getElementById('errmsg')) {
+ } else if (err = resDoc.getElementById('errmsg')) {
if ((_ref = $('a', err)) != null) {
_ref.target = '_blank';
}
- } else if (tmpDoc.title !== 'Post successful!') {
+ } else if (resDoc.title !== 'Post successful!') {
err = 'Connection error with sys.4chan.org.';
} else if (req.status !== 200) {
err = "Error " + req.statusText + " (" + req.status + ")";
@@ -6105,8 +6109,8 @@
QR.error(err);
return;
}
+ h1 = $('h1', resDoc);
QR.cleanNotifications();
- h1 = $('h1', tmpDoc);
if (Conf['Posting Success Notifications']) {
QR.notifications.push(new Notification('success', h1.textContent, 5));
}
@@ -6860,6 +6864,8 @@
form[post.ID] = 'delete';
link = this;
return $.ajax($.id('delform').action.replace("/" + g.BOARD + "/", "/" + post.board + "/"), {
+ responseType: 'document',
+ withCredentials: true,
onload: function() {
return DeleteLink.load(link, post, fileOnly, this.response);
},
@@ -6867,22 +6873,19 @@
return DeleteLink.error(link);
}
}, {
- cred: true,
form: $.formData(form)
});
},
- load: function(link, post, fileOnly, html) {
- var msg, s, tmpDoc;
+ load: function(link, post, fileOnly, resDoc) {
+ var msg, s;
- tmpDoc = d.implementation.createHTMLDocument('');
- tmpDoc.documentElement.innerHTML = html;
- if (tmpDoc.title === '4chan - Banned') {
+ if (resDoc.title === '4chan - Banned') {
s = 'Banned!';
- } else if (msg = tmpDoc.getElementById('errmsg')) {
+ } else if (msg = resDoc.getElementById('errmsg')) {
s = msg.textContent;
$.on(link, 'click', DeleteLink["delete"]);
} else {
- if (tmpDoc.title === 'Updating index...') {
+ if (resDoc.title === 'Updating index...') {
(post.origin || post).kill(fileOnly);
}
s = 'Deleted';
@@ -7911,8 +7914,7 @@
if (Conf['Unread Line']) {
Unread.setLine(posts.contains(Unread.posts[0]));
}
- Unread.read();
- return Unread.update();
+ return Unread.read();
},
addPostQuotingYou: function(post) {
var quotelink, _i, _len, _ref;
@@ -7962,17 +7964,16 @@
}
return arr.splice(0, i);
},
- read: $.debounce(50, function(e) {
- var ID, bottom, height, i, post, posts, read;
+ read: $.debounce(50, function() {
+ var ID, bottom, height, i, post, posts;
if (d.hidden || !Unread.posts.length) {
return;
}
height = doc.clientHeight;
posts = Unread.posts;
- read = [];
- i = posts.length;
- while (post = posts[--i]) {
+ i = 0;
+ while (post = posts[i++]) {
bottom = post.nodes.root.getBoundingClientRect().bottom;
if (bottom < height) {
ID = post.ID;
@@ -7985,9 +7986,7 @@
Unread.lastReadPost = ID;
Unread.saveLastReadPost();
Unread.readArray(Unread.postsQuotingYou);
- if (e) {
- return Unread.update();
- }
+ return Unread.update();
}),
saveLastReadPost: $.debounce(2 * $.SECOND, function() {
if (Unread.thread.isDead) {
diff --git a/src/General/lib/$.coffee b/src/General/lib/$.coffee
index 0bdf1df75..1569f960e 100644
--- a/src/General/lib/$.coffee
+++ b/src/General/lib/$.coffee
@@ -70,24 +70,21 @@ $.formData = (form) ->
fd.append key, val
fd
-$.ajax = (url, callbacks, opts={}) ->
- {type, cred, headers, upCallbacks, form, sync} = opts
+$.extend = (object, properties) ->
+ for key, val of properties
+ object[key] = val
+ return
+
+$.ajax = (url, options, extra={}) ->
+ {type, headers, upCallbacks, form, sync} = extra
r = new XMLHttpRequest()
r.overrideMimeType 'text/html'
type or= form and 'post' or 'get'
r.open type, url, !sync
for key, val of headers
r.setRequestHeader key, val
- $.extend r, callbacks
+ $.extend r, options
$.extend r.upload, upCallbacks
- try
- # Firefox throws an error if you try
- # to set this on a synchronous XHR.
- # Only cookies from the remote domain
- # are used in a request withCredentials.
- r.withCredentials = cred
- catch err
- # do nothing
r.send form
r
diff --git a/src/Menu/DeleteLink.coffee b/src/Menu/DeleteLink.coffee
index 7f71d7f6e..1912733c6 100644
--- a/src/Menu/DeleteLink.coffee
+++ b/src/Menu/DeleteLink.coffee
@@ -55,21 +55,20 @@ DeleteLink =
link = @
$.ajax $.id('delform').action.replace("/#{g.BOARD}/", "/#{post.board}/"),
+ responseType: 'document'
+ withCredentials: true
onload: -> DeleteLink.load link, post, fileOnly, @response
onerror: -> DeleteLink.error link
,
- cred: true
form: $.formData form
- load: (link, post, fileOnly, html) ->
- tmpDoc = d.implementation.createHTMLDocument ''
- tmpDoc.documentElement.innerHTML = html
- if tmpDoc.title is '4chan - Banned' # Ban/warn check
+ load: (link, post, fileOnly, resDoc) ->
+ if resDoc.title is '4chan - Banned' # Ban/warn check
s = 'Banned!'
- else if msg = tmpDoc.getElementById 'errmsg' # error!
+ else if msg = resDoc.getElementById 'errmsg' # error!
s = msg.textContent
$.on link, 'click', DeleteLink.delete
else
- if tmpDoc.title is 'Updating index...'
+ if resDoc.title is 'Updating index...'
# We're 100% sure.
(post.origin or post).kill fileOnly
s = 'Deleted'
diff --git a/src/Monitoring/Unread.coffee b/src/Monitoring/Unread.coffee
index 5ae97a370..1979f3bbb 100644
--- a/src/Monitoring/Unread.coffee
+++ b/src/Monitoring/Unread.coffee
@@ -86,7 +86,6 @@ Unread =
# Force line on visible threads if there were no unread posts previously.
Unread.setLine posts.contains Unread.posts[0]
Unread.read()
- Unread.update()
addPostQuotingYou: (post) ->
return unless QR.db
@@ -116,24 +115,23 @@ Unread =
break if post.ID > Unread.lastReadPost
arr.splice 0, i
- read: $.debounce 50, (e) ->
+ read: $.debounce 50, ->
return if d.hidden or !Unread.posts.length
height = doc.clientHeight
{posts} = Unread
- read = []
- i = posts.length
+ i = 0
- while post = posts[--i]
+ while post = posts[i++]
{bottom} = post.nodes.root.getBoundingClientRect()
if (bottom < height) # post is completely read
- ID = post.ID
+ {ID} = post
posts.remove post
return unless ID
Unread.lastReadPost = ID
Unread.saveLastReadPost()
Unread.readArray Unread.postsQuotingYou
- Unread.update() if e
+ Unread.update()
saveLastReadPost: $.debounce 2 * $.SECOND, ->
return if Unread.thread.isDead
diff --git a/src/Posting/QuickReply.coffee b/src/Posting/QuickReply.coffee
index e923dddb0..d0ccd85e2 100644
--- a/src/Posting/QuickReply.coffee
+++ b/src/Posting/QuickReply.coffee
@@ -142,7 +142,7 @@ QR =
else
QR.notifications.push new Notification 'warning', el
alert el.textContent if d.hidden
-
+
notifications: []
cleanNotifications: ->
for notification in QR.notifications
@@ -718,7 +718,7 @@ QR =
dragOver: (e) ->
e.preventDefault()
e.dataTransfer.dropEffect = 'move'
-
+
drop: ->
$.rmClass @, 'over'
return unless @draggable
@@ -736,7 +736,7 @@ QR =
return if d.cookie.indexOf('pass_enabled=1') >= 0
return unless @isEnabled = !!$.id 'captchaFormPart'
$.asap (-> $.id 'recaptcha_challenge_field_holder'), @ready.bind @
-
+
ready: ->
setLifetime = (e) => @lifetime = e.detail
$.on window, 'captcha:timeout', setLifetime
@@ -784,7 +784,7 @@ QR =
sync: (captchas) ->
QR.captcha.captchas = captchas
QR.captcha.count()
-
+
getOne: ->
@clear()
if captcha = @captchas.shift()
@@ -800,7 +800,7 @@ QR =
# If there's only one word, duplicate it.
response = "#{response} #{response}" unless /\s/.test response
{challenge, response}
-
+
save: ->
return unless response = @nodes.input.value.trim()
@captchas.push
@@ -810,7 +810,7 @@ QR =
@count()
@reload()
$.set 'captchas', @captchas
-
+
clear: ->
now = Date.now()
for captcha, i in @captchas
@@ -819,7 +819,7 @@ QR =
@captchas = @captchas[i..]
@count()
$.set 'captchas', @captchas
-
+
load: ->
return unless @nodes.challenge.firstChild
# -1 minute to give upload some time.
@@ -829,7 +829,7 @@ QR =
@nodes.img.src = "//www.google.com/recaptcha/api/image?c=#{challenge}"
@nodes.input.value = null
@clear()
-
+
count: ->
count = @captchas.length
@nodes.input.placeholder = switch count
@@ -840,13 +840,13 @@ QR =
else
"Verification (#{count} cached captchas)"
@nodes.input.alt = count
-
+
reload: (focus) ->
# the 't' argument prevents the input from being focused
$.globalEval 'Recaptcha.reload("t")'
# Focus if we meant to.
@nodes.input.focus() if focus
-
+
keydown: (e) ->
if e.keyCode is 8 and not @nodes.input.value
@reload()
@@ -971,7 +971,7 @@ QR =
$.event 'QRDialogCreation', null, dialog
preSubmitHooks: []
-
+
submit: (e) ->
e?.preventDefault()
@@ -1045,7 +1045,9 @@ QR =
recaptcha_challenge_field: challenge
recaptcha_response_field: response
- callbacks =
+ options =
+ responseType: 'document'
+ withCredentials: true
onload: QR.response
onerror: ->
# Connection error, or
@@ -1056,11 +1058,10 @@ QR =
QR.status()
QR.error $.el 'span',
innerHTML: """
- 4chan X encountered an error while posting. Please try again.
+ 4chan X encountered an error while posting. Please try again.
[?]
"""
- opts =
- cred: true
+ extra =
form: $.formData postData
upCallbacks:
onload: ->
@@ -1074,7 +1075,7 @@ QR =
QR.req.progress = "#{Math.round e.loaded / e.total * 100}%"
QR.status()
- QR.req = $.ajax $.id('postForm').parentNode.action, callbacks, opts
+ QR.req = $.ajax $.id('postForm').parentNode.action, options, extra
# Starting to upload might take some time.
# Provide some feedback that we're starting to submit.
QR.req.uploadStartTime = Date.now()
@@ -1088,20 +1089,23 @@ QR =
post = QR.posts[0]
post.unlock()
- tmpDoc = d.implementation.createHTMLDocument ''
- tmpDoc.documentElement.innerHTML = req.response
- if ban = $ '.banType', tmpDoc # banned/warning
- board = $('.board', tmpDoc).innerHTML
+ resDoc = req.response
+ if ban = $ '.banType', resDoc # banned/warning
+ board = $('.board', resDoc).innerHTML
err = $.el 'span', innerHTML:
if ban.textContent.toLowerCase() is 'banned'
- "You are banned on #{board}! ;_;
" +
- "Click here to see the reason."
+ """
+ You are banned on #{board}! ;_;
+ Click here to see the reason.
+ """
else
- "You were issued a warning on #{board} as #{$('.nameBlock', tmpDoc).innerHTML}.
" +
- "Reason: #{$('.reason', tmpDoc).innerHTML}"
- else if err = tmpDoc.getElementById 'errmsg' # error!
+ """
+ You were issued a warning on #{board} as #{$('.nameBlock', resDoc).innerHTML}.
+ Reason: #{$('.reason', resDoc).innerHTML}
+ """
+ else if err = resDoc.getElementById 'errmsg' # error!
$('a', err)?.target = '_blank' # duplicate image link
- else if tmpDoc.title isnt 'Post successful!'
+ else if resDoc.title isnt 'Post successful!'
err = 'Connection error with sys.4chan.org.'
else if req.status isnt 200
err = "Error #{req.statusText} (#{req.status})"
@@ -1134,11 +1138,10 @@ QR =
QR.status()
QR.error err
return
-
+ h1 = $ 'h1', resDoc
QR.cleanNotifications()
- h1 = $ 'h1', tmpDoc
-
+
if Conf['Posting Success Notifications']
QR.notifications.push new Notification 'success', h1.textContent, 5