diff --git a/4chan_x.user.js b/4chan_x.user.js index 974a1205b..763c1e9c2 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1406,6 +1406,71 @@ return _Class; })(), + captcha: { + init: function() { + var _this = this; + this.img = $('.captcha > img', qr.el); + this.input = $('[name=captcha]', qr.el); + this.challenge = $.id('recaptcha_challenge_field_holder'); + $.on(this.img.parentNode, 'click', this.reload); + $.on(this.input, 'keydown', this.keydown); + $.on(this.challenge, 'DOMNodeInserted', function() { + return _this.load(); + }); + $.on(window, 'storage', function(e) { + if (e.key === ("" + NAMESPACE + "captchas")) { + return _this.count(JSON.parse(e.newValue).length); + } + }); + this.count($.get('captchas', []).length); + this.load(); + return window.location = 'javascript:Recaptcha.focus_response_field=function(){}'; + }, + save: function() { + var captchas, length, now, response; + if (!(response = this.input.value)) return; + captchas = $.get('captchas', []); + now = Date.now(); + while (captchas[0].time < now) { + captchas.shift(); + } + length = captchas.push({ + challenge: this.challenge.firstChild.value, + response: response, + time: this.timeout + }); + $.set('captchas', captchas); + this.count(length); + return this.reload(); + }, + load: function() { + var challenge; + this.timeout = Date.now() + 25 * MINUTE; + challenge = this.challenge.firstChild.value; + this.img.alt = challenge; + this.img.src = "http://www.google.com/recaptcha/api/image?c=" + challenge; + return this.input.value = null; + }, + count: function(count) { + return this.input.placeholder = "Verification (" + count + " cached captchas)"; + }, + reload: function() { + window.location = 'javascript:Recaptcha.reload()'; + return qr.captcha.input.focus(); + }, + keydown: function(e) { + var c; + c = qr.captcha; + if (e.keyCode === 8 && !c.input.value) { + c.reload(); + } else if (e.keyCode === 13 && e.shiftKey) { + c.save(); + } else { + return; + } + return e.preventDefault(); + } + }, dialog: function() { var input, mimeTypes, thread, threads, _i, _j, _len, _len2, _ref, _ref2; if (!g.REPLY) { @@ -1428,7 +1493,7 @@ } }); qr.mimeTypes = mimeTypes.split(', '); - qr.el = ui.dialog('qr', 'top:0;right:0;', "
Quick Reply " + (g.REPLY ? '' : threads) + " x
+
Spoiler Image?
"); + qr.el = ui.dialog('qr', 'top:0;right:0;', "
Quick Reply " + (g.REPLY ? '' : threads) + " x
+
Spoiler Image?
"); if (!g.REPLY) { $.on($('select', qr.el), 'mousedown', function(e) { return e.stopPropagation(); @@ -1458,6 +1523,7 @@ return qr.selected[this.name] = this.value; }); } + qr.captcha.init(); return $.add(d.body, qr.el); }, submit: function(e) { @@ -3265,6 +3331,8 @@ textarea.field {\ }\ .captcha {\ background: #FFF;\ + outline: 1px solid #CCC;\ + outline-offset: -1px;\ text-align: center;\ }\ .captcha > img {\ diff --git a/script.coffee b/script.coffee index cc5e2fb91..4301a0677 100644 --- a/script.coffee +++ b/script.coffee @@ -1046,6 +1046,53 @@ qr = url.revokeObjectURL @url delete @ + captcha: + init: -> + @img = $ '.captcha > img', qr.el + @input = $ '[name=captcha]', qr.el + @challenge = $.id 'recaptcha_challenge_field_holder' + $.on @img.parentNode, 'click', @reload + $.on @input, 'keydown', @keydown + $.on @challenge, 'DOMNodeInserted', => @load() + $.on window, 'storage', (e) => @count JSON.parse(e.newValue).length if e.key is "#{NAMESPACE}captchas" + @count $.get('captchas', []).length + @load() + # prevent original captcha input from being focused on reload + window.location = 'javascript:Recaptcha.focus_response_field=function(){}' + save: -> + return unless response = @input.value + captchas = $.get 'captchas', [] + # remove old captchas + now = Date.now() + while captchas[0].time < now + captchas.shift() + length = captchas.push + challenge: @challenge.firstChild.value + response: response + time: @timeout + $.set 'captchas', captchas + @count length + @reload() + load: -> + @timeout = Date.now() + 25*MINUTE + challenge = @challenge.firstChild.value + @img.alt = challenge + @img.src = "http://www.google.com/recaptcha/api/image?c=#{challenge}" + @input.value = null + count: (count) -> + @input.placeholder = "Verification (#{count} cached captchas)" + reload: -> + window.location = 'javascript:Recaptcha.reload()' + qr.captcha.input.focus() + keydown: (e) -> + c = qr.captcha + if e.keyCode is 8 and not c.input.value + c.reload() + else if e.keyCode is 13 and e.shiftKey + c.save() + else + return + e.preventDefault() dialog: -> # create a new thread or select thread to reply to @@ -1073,8 +1120,8 @@ qr =
-
-
+
+
Spoiler Image?
@@ -1099,6 +1146,7 @@ qr = # if match = e.key.match /qr_(.+)$/ # qr.inputs[match[1]].value = JSON.parse e.newValue + qr.captcha.init() $.add d.body, qr.el submit: (e) -> @@ -2607,6 +2655,8 @@ textarea.field { } .captcha { background: #FFF; + outline: 1px solid #CCC; + outline-offset: -1px; text-align: center; } .captcha > img {