Merge branch 'v3' of git://github.com/MayhemYDG/4chan-x into v3

Conflicts:
	src/General/Main.coffee
	src/General/lib/$.coffee
	src/Monitoring/Unread.coffee
	src/Posting/QuickReply.coffee
This commit is contained in:
Zixaphir 2013-08-07 13:53:35 -07:00
commit 80884e2bde
6 changed files with 137 additions and 142 deletions

View File

@ -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[<a href=\"https://github.com/seaweedchan/4chan-x/wiki/Frequently-Asked-Questions#what-does-4chan-x-encountered-an-error-while-posting-please-try-again-mean\" target=_blank>?</a>]"
innerHTML: "4chan X encountered an error while posting. Please try again.\n[<a href=\"https://github.com/seaweedchan/4chan-x/wiki/Frequently-Asked-Questions#what-does-4chan-x-encountered-an-error-while-posting-please-try-again-mean\" target=_blank>?</a>]"
}));
}
};
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 + "! ;_;<br>") + "Click <a href=//www.4chan.org/banned target=_blank>here</a> to see the reason." : ("You were issued a warning on " + board + " as " + ($('.nameBlock', tmpDoc).innerHTML) + ".<br>") + ("Reason: " + ($('.reason', tmpDoc).innerHTML))
innerHTML: ban.textContent.toLowerCase() === 'banned' ? "You are banned on " + board + "! ;_;<br>\nClick <a href=//www.4chan.org/banned target=_blank>here</a> to see the reason." : "You were issued a warning on " + board + " as " + ($('.nameBlock', resDoc).innerHTML) + ".<br>\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) {

View File

@ -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[<a href=\"https://github.com/seaweedchan/4chan-x/wiki/Frequently-Asked-Questions#what-does-4chan-x-encountered-an-error-while-posting-please-try-again-mean\" target=_blank>?</a>]"
innerHTML: "4chan X encountered an error while posting. Please try again.\n[<a href=\"https://github.com/seaweedchan/4chan-x/wiki/Frequently-Asked-Questions#what-does-4chan-x-encountered-an-error-while-posting-please-try-again-mean\" target=_blank>?</a>]"
}));
}
};
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 + "! ;_;<br>") + "Click <a href=//www.4chan.org/banned target=_blank>here</a> to see the reason." : ("You were issued a warning on " + board + " as " + ($('.nameBlock', tmpDoc).innerHTML) + ".<br>") + ("Reason: " + ($('.reason', tmpDoc).innerHTML))
innerHTML: ban.textContent.toLowerCase() === 'banned' ? "You are banned on " + board + "! ;_;<br>\nClick <a href=//www.4chan.org/banned target=_blank>here</a> to see the reason." : "You were issued a warning on " + board + " as " + ($('.nameBlock', resDoc).innerHTML) + ".<br>\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) {

View File

@ -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

View File

@ -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'

View File

@ -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

View File

@ -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.
[<a href="https://github.com/seaweedchan/4chan-x/wiki/Frequently-Asked-Questions#what-does-4chan-x-encountered-an-error-while-posting-please-try-again-mean" target=_blank>?</a>]
"""
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}! ;_;<br>" +
"Click <a href=//www.4chan.org/banned target=_blank>here</a> to see the reason."
"""
You are banned on #{board}! ;_;<br>
Click <a href=//www.4chan.org/banned target=_blank>here</a> to see the reason.
"""
else
"You were issued a warning on #{board} as #{$('.nameBlock', tmpDoc).innerHTML}.<br>" +
"Reason: #{$('.reason', tmpDoc).innerHTML}"
else if err = tmpDoc.getElementById 'errmsg' # error!
"""
You were issued a warning on #{board} as #{$('.nameBlock', resDoc).innerHTML}.<br>
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