Clear timed-out cached captchas when the captcha is (re)loaded.

That will avoid showing an incorrect count of cached captchas.
Reorganize some captcha code.
Also a tiny fix.
This commit is contained in:
Nicolas Stepien 2013-02-24 21:29:54 +01:00
parent 1246df80af
commit f4b6063439
2 changed files with 99 additions and 72 deletions

View File

@ -6250,7 +6250,7 @@
index = QR.replies.indexOf(this); index = QR.replies.indexOf(this);
if (QR.replies.length === 1) { if (QR.replies.length === 1) {
new QR.reply().select(); new QR.reply().select();
} else if (this.el.id === 'selected') { } else if (this === QR.selected) {
(QR.replies[index - 1] || QR.replies[index + 1]).select(); (QR.replies[index - 1] || QR.replies[index + 1]).select();
} }
QR.replies.splice(index, 1); QR.replies.splice(index, 1);
@ -6303,29 +6303,70 @@
} }
$.on(imgContainer, 'click', this.reload.bind(this)); $.on(imgContainer, 'click', this.reload.bind(this));
$.on(this.nodes.input, 'keydown', this.keydown.bind(this)); $.on(this.nodes.input, 'keydown', this.keydown.bind(this));
$.sync('captchas', this.count.bind(this)); $.sync('captchas', this.sync.bind(this));
this.count($.get('captchas', [])); this.sync($.get('captchas', []));
this.reload(); this.reload();
$.addClass(QR.nodes.el, 'has-captcha'); $.addClass(QR.nodes.el, 'has-captcha');
return $.after(QR.nodes.com.parentNode, [imgContainer, inputContainer]); return $.after(QR.nodes.com.parentNode, [imgContainer, inputContainer]);
}, },
sync: function(captchas) {
this.captchas = captchas;
return this.count();
},
getOne: function() {
var captcha, challenge, response;
this.clear();
if (captcha = this.captchas.shift()) {
challenge = captcha.challenge, response = captcha.response;
this.count();
$.set('captchas', this.captchas);
} else {
challenge = this.nodes.img.alt;
if (response = this.nodes.input.value) {
this.reload();
}
}
if (response) {
response = response.trim();
if (!/\s/.test(response)) {
response = "" + response + " " + response;
}
}
return {
challenge: challenge,
response: response
};
},
save: function() { save: function() {
var captcha, captchas, response; var response;
if (!(response = this.nodes.input.value.trim())) { if (!(response = this.nodes.input.value.trim())) {
return; return;
} }
captchas = $.get('captchas', []); this.captchas.push({
while ((captcha = captchas[0]) && captcha.time < Date.now()) {
captchas.shift();
}
captchas.push({
challenge: this.nodes.challenge.firstChild.value, challenge: this.nodes.challenge.firstChild.value,
response: response, response: response,
time: this.timeout timeout: this.timeout
}); });
$.set('captchas', captchas); this.count();
this.count(captchas); this.reload();
return this.reload(); return $.set('captchas', this.captchas);
},
clear: function() {
var captcha, i, now, _i, _len, _ref;
now = Date.now();
_ref = this.captchas;
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
captcha = _ref[i];
if (captcha.timeout > now) {
break;
}
}
if (!i) {
return;
}
this.captchas = this.captchas.slice(i);
this.count();
return $.set('captchas', this.captchas);
}, },
load: function() { load: function() {
var challenge; var challenge;
@ -6333,11 +6374,12 @@
challenge = this.nodes.challenge.firstChild.value; challenge = this.nodes.challenge.firstChild.value;
this.nodes.img.alt = challenge; this.nodes.img.alt = challenge;
this.nodes.img.src = "//www.google.com/recaptcha/api/image?c=" + challenge; this.nodes.img.src = "//www.google.com/recaptcha/api/image?c=" + challenge;
return this.nodes.input.value = null; this.nodes.input.value = null;
return this.clear();
}, },
count: function(arr) { count: function() {
var count; var count;
count = arr.length; count = this.captchas.length;
this.nodes.input.placeholder = (function() { this.nodes.input.placeholder = (function() {
switch (count) { switch (count) {
case 0: case 0:
@ -6466,7 +6508,7 @@
return $.event('QRDialogCreation', null, dialog); return $.event('QRDialogCreation', null, dialog);
}, },
submit: function(e) { submit: function(e) {
var callbacks, captcha, captchas, challenge, err, filetag, m, opts, post, reply, response, textOnly, threadID, _ref; var callbacks, challenge, err, filetag, m, opts, post, reply, response, textOnly, threadID, _ref, _ref1;
if (e != null) { if (e != null) {
e.preventDefault(); e.preventDefault();
} }
@ -6508,28 +6550,9 @@
err = 'No file selected.'; err = 'No file selected.';
} }
if (QR.captcha.isEnabled && !err) { if (QR.captcha.isEnabled && !err) {
captchas = $.get('captchas', []); _ref1 = QR.captcha.getOne(), challenge = _ref1.challenge, response = _ref1.response;
while ((captcha = captchas[0]) && captcha.time < Date.now()) {
captchas.shift();
}
if (captcha = captchas.shift()) {
challenge = captcha.challenge;
response = captcha.response;
} else {
challenge = QR.captcha.nodes.img.alt;
if (response = QR.captcha.nodes.input.value) {
QR.captcha.reload();
}
}
$.set('captchas', captchas);
QR.captcha.count(captchas);
if (!response) { if (!response) {
err = 'No valid captcha.'; err = 'No valid captcha.';
} else {
response = response.trim();
if (!/\s/.test(response)) {
response = "" + response + " " + response;
}
} }
} }
if (err) { if (err) {
@ -6620,7 +6643,7 @@
if (/mistyped/i.test(err.textContent)) { if (/mistyped/i.test(err.textContent)) {
err = 'Error: You seem to have mistyped the CAPTCHA.'; err = 'Error: You seem to have mistyped the CAPTCHA.';
} }
QR.cooldown.auto = QR.captcha.isEnabled ? !!$.get('captchas', []).length : err === 'Connection error with sys.4chan.org.' ? true : false; QR.cooldown.auto = QR.captcha.isEnabled ? !!QR.captcha.captchas.length : err === 'Connection error with sys.4chan.org.' ? true : false;
QR.cooldown.set({ QR.cooldown.set({
delay: 2 delay: 2
}); });

View File

@ -496,7 +496,7 @@ QR =
index = QR.replies.indexOf @ index = QR.replies.indexOf @
if QR.replies.length is 1 if QR.replies.length is 1
new QR.reply().select() new QR.reply().select()
else if @el.id is 'selected' else if @ is QR.selected
(QR.replies[index-1] or QR.replies[index+1]).select() (QR.replies[index-1] or QR.replies[index+1]).select()
QR.replies.splice index, 1 QR.replies.splice index, 1
return unless window.URL return unless window.URL
@ -531,26 +531,47 @@ QR =
$.on imgContainer, 'click', @reload.bind @ $.on imgContainer, 'click', @reload.bind @
$.on @nodes.input, 'keydown', @keydown.bind @ $.on @nodes.input, 'keydown', @keydown.bind @
$.sync 'captchas', @count.bind @ $.sync 'captchas', @sync.bind @
@count $.get 'captchas', [] @sync $.get 'captchas', []
# start with an uncached captcha # start with an uncached captcha
@reload() @reload()
$.addClass QR.nodes.el, 'has-captcha' $.addClass QR.nodes.el, 'has-captcha'
$.after QR.nodes.com.parentNode, [imgContainer, inputContainer] $.after QR.nodes.com.parentNode, [imgContainer, inputContainer]
sync: (@captchas) ->
@count()
getOne: ->
@clear()
if captcha = @captchas.shift()
{challenge, response} = captcha
@count()
$.set 'captchas', @captchas
else
challenge = @nodes.img.alt
if response = @nodes.input.value then @reload()
if response
response = response.trim()
# one-word-captcha:
# If there's only one word, duplicate it.
response = "#{response} #{response}" unless /\s/.test response
{challenge, response}
save: -> save: ->
return unless response = @nodes.input.value.trim() return unless response = @nodes.input.value.trim()
captchas = $.get 'captchas', [] @captchas.push
# Remove old captchas.
while (captcha = captchas[0]) and captcha.time < Date.now()
captchas.shift()
captchas.push
challenge: @nodes.challenge.firstChild.value challenge: @nodes.challenge.firstChild.value
response: response response: response
time: @timeout timeout: @timeout
$.set 'captchas', captchas @count()
@count captchas
@reload() @reload()
$.set 'captchas', @captchas
clear: ->
now = Date.now()
for captcha, i in @captchas
break if captcha.timeout > now
return unless i
@captchas = @captchas[i..]
@count()
$.set 'captchas', @captchas
load: -> load: ->
# -1 minute to give upload some time. # -1 minute to give upload some time.
@timeout = Date.now() + $.unsafeWindow.RecaptchaState.timeout * $.SECOND - $.MINUTE @timeout = Date.now() + $.unsafeWindow.RecaptchaState.timeout * $.SECOND - $.MINUTE
@ -558,8 +579,9 @@ QR =
@nodes.img.alt = challenge @nodes.img.alt = challenge
@nodes.img.src = "//www.google.com/recaptcha/api/image?c=#{challenge}" @nodes.img.src = "//www.google.com/recaptcha/api/image?c=#{challenge}"
@nodes.input.value = null @nodes.input.value = null
count: (arr) -> @clear()
count = arr.length count: ->
count = @captchas.length
@nodes.input.placeholder = switch count @nodes.input.placeholder = switch count
when 0 when 0
'Verification (Shift + Enter to cache)' 'Verification (Shift + Enter to cache)'
@ -709,26 +731,8 @@ QR =
err = 'No file selected.' err = 'No file selected.'
if QR.captcha.isEnabled and !err if QR.captcha.isEnabled and !err
# get oldest valid captcha {challenge, response} = QR.captcha.getOne()
captchas = $.get 'captchas', [] err = 'No valid captcha.' unless response
# remove old captchas
while (captcha = captchas[0]) and captcha.time < Date.now()
captchas.shift()
if captcha = captchas.shift()
challenge = captcha.challenge
response = captcha.response
else
challenge = QR.captcha.nodes.img.alt
if response = QR.captcha.nodes.input.value then QR.captcha.reload()
$.set 'captchas', captchas
QR.captcha.count captchas
unless response
err = 'No valid captcha.'
else
response = response.trim()
# one-word-captcha:
# If there's only one word, duplicate it.
response = "#{response} #{response}" unless /\s/.test response
if err if err
# stop auto-posting # stop auto-posting
@ -818,7 +822,7 @@ QR =
err = 'Error: You seem to have mistyped the CAPTCHA.' err = 'Error: You seem to have mistyped the CAPTCHA.'
# Enable auto-post if we have some cached captchas. # Enable auto-post if we have some cached captchas.
QR.cooldown.auto = if QR.captcha.isEnabled QR.cooldown.auto = if QR.captcha.isEnabled
!!$.get('captchas', []).length !!QR.captcha.captchas.length
else if err is 'Connection error with sys.4chan.org.' else if err is 'Connection error with sys.4chan.org.'
true true
else else