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