diff --git a/src/Posting/Captcha.cache.coffee b/src/Posting/Captcha.cache.coffee new file mode 100644 index 000000000..4b8a78a68 --- /dev/null +++ b/src/Posting/Captcha.cache.coffee @@ -0,0 +1,55 @@ +Captcha.cache = + init: -> + $.get 'captchas', [], ({captchas}) => + @sync captchas + @clear() + $.sync 'captchas', @sync.bind(@) + + captchas: [] + + getCount: -> + @captchas.length + + needed: -> + captchaCount = @captchas.length + captchaCount++ if QR.req + postsCount = QR.posts.length + postsCount = 0 if postsCount is 1 and !Conf['Auto-load captcha'] and !QR.posts[0].com and !QR.posts[0].file + captchaCount < postsCount + + sync: (captchas=[]) -> + @captchas = captchas + @count() + + getOne: -> + @clear() + if (captcha = @captchas.shift()) + $.set 'captchas', @captchas + @count() + captcha + else + null + + save: (captcha) -> + $.forceSync 'captchas' + @captchas.push captcha + @captchas.sort (a, b) -> a.timeout - b.timeout + $.set 'captchas', @captchas + @count() + + clear: -> + $.forceSync 'captchas' + if @captchas.length + now = Date.now() + for captcha, i in @captchas + break if captcha.timeout > now + if i + @captchas = @captchas[i..] + $.set 'captchas', @captchas + @count() + + count: -> + clearTimeout @timer + if @captchas.length + @timer = setTimeout @clear.bind(@), @captchas[0].timeout - Date.now() + $.event 'CaptchaCount', @captchas.length diff --git a/src/Posting/Captcha.v1.coffee b/src/Posting/Captcha.v1.coffee index d230fc748..4d4197a79 100644 --- a/src/Posting/Captcha.v1.coffee +++ b/src/Posting/Captcha.v1.coffee @@ -26,11 +26,8 @@ Captcha.v1 = $.addClass QR.nodes.el, 'has-captcha', 'captcha-v1' $.after QR.nodes.com.parentNode, [imgContainer, input] - @captchas = [] - $.get 'captchas', [], ({captchas}) -> - QR.captcha.sync captchas - QR.captcha.clear() - $.sync 'captchas', @sync + Captcha.cache.init() + $.on d, 'CaptchaCount', @count.bind(@) @replace() @beforeSetup() @@ -94,17 +91,10 @@ Captcha.v1 = @count() $.on input, 'focus click', @cb.focus - needed: -> - captchaCount = @captchas.length - captchaCount++ if QR.req - postsCount = QR.posts.length - postsCount = 0 if postsCount is 1 and !Conf['Auto-load captcha'] and !QR.posts[0].com and !QR.posts[0].file - captchaCount < postsCount - moreNeeded: -> setup: (focus, force) -> - return unless @isEnabled and (force or @needed()) + return unless @isEnabled and (force or Captcha.cache.needed()) @create() if focus $.addClass QR.nodes.el, 'focus' @@ -142,15 +132,8 @@ Captcha.v1 = delete @occupied @beforeSetup() if @nodes - sync: (captchas=[]) -> - QR.captcha.captchas = captchas - QR.captcha.count() - getOne: -> - @clear() - if captcha = @captchas.shift() - @count() - $.set 'captchas', @captchas + if (captcha = Captcha.cache.getOne()) captcha else challenge = @nodes.img.alt @@ -164,27 +147,12 @@ Captcha.v1 = save: -> return unless /\S/.test(response = @nodes.input.value) @nodes.input.value = '' - $.forceSync 'captchas' - @captchas.push + Captcha.cache.save challenge: @nodes.img.alt response: response timeout: @timeout - @captchas.sort (a, b) -> a.timeout - b.timeout - @count() @destroy() @setup false, true - $.set 'captchas', @captchas - - clear: -> - $.forceSync 'captchas' - return unless @captchas.length - now = Date.now() - for captcha, i in @captchas - break if captcha.timeout > now - return unless i - @captchas = @captchas[i..] - @count() - $.set 'captchas', @captchas load: -> if $('#captchaContainerAlt[class~="recaptcha_is_showing_audio"]') @@ -198,10 +166,10 @@ Captcha.v1 = @nodes.img.alt = challenge @nodes.img.src = challenge_image.src @nodes.input.value = '' - @clear() + Captcha.cache.clear() count: -> - count = if @captchas then @captchas.length else 0 + count = Captcha.cache.getCount() placeholder = @nodes.input.placeholder.replace /\ \(.*\)$/, '' placeholder += switch count when 0 @@ -212,9 +180,6 @@ Captcha.v1 = " (#{count} cached captchas)" @nodes.input.placeholder = placeholder @nodes.input.alt = count # For XTRM RICE. - clearTimeout @timer - if count - @timer = setTimeout @clear.bind(@), @captchas[0].timeout - Date.now() reload: (focus) -> # Recaptcha.should_focus = false: Hack to prevent the input from being focused diff --git a/src/Posting/Captcha.v2.coffee b/src/Posting/Captcha.v2.coffee index 63784e92d..d014054cc 100644 --- a/src/Posting/Captcha.v2.coffee +++ b/src/Posting/Captcha.v2.coffee @@ -8,11 +8,8 @@ Captcha.v2 = if (@noscript = Conf['Force Noscript Captcha'] or not Main.jsEnabled) $.addClass QR.nodes.el, 'noscript-captcha' - @captchas = [] - $.get 'captchas', [], ({captchas}) -> - QR.captcha.sync captchas - QR.captcha.clear() - $.sync 'captchas', @sync.bind @ + Captcha.cache.init() + $.on d, 'CaptchaCount', @count.bind(@) root = $.el 'div', className: 'captcha-root' $.extend root, <%= html( @@ -43,17 +40,10 @@ Captcha.v2 = url += "&hl=#{encodeURIComponent lang}" url - needed: -> - captchaCount = @captchas.length - captchaCount++ if QR.req - postsCount = QR.posts.length - postsCount = 0 if postsCount is 1 and !Conf['Auto-load captcha'] and !QR.posts[0].com and !QR.posts[0].file - captchaCount < postsCount - moreNeeded: -> # Post count temporarily off by 1 when called from QR.post.rm, QR.close, or QR.submit $.queueTask => - needed = @needed() + needed = Captcha.cache.needed() if needed and not @prevNeeded @setup(QR.cooldown.auto and d.activeElement is QR.nodes.status) @prevNeeded = needed @@ -65,7 +55,7 @@ Captcha.v2 = @setup true, true setup: (focus, force) -> - return unless @isEnabled and (@needed() or force) + return unless @isEnabled and (Captcha.cache.needed() or force) if focus $.addClass QR.nodes.el, 'focus' @@ -167,30 +157,16 @@ Captcha.v2 = $.rm node return - sync: (captchas=[]) -> - @captchas = captchas - @count() - getOne: -> - @clear() - if (captcha = @captchas.shift()) - $.set 'captchas', @captchas - @count() - captcha - else - null + Captcha.cache.getOne() save: (pasted, token) -> - $.forceSync 'captchas' - @captchas.push + Captcha.cache.save response: token or $('textarea', @nodes.container).value timeout: Date.now() + @lifetime - @captchas.sort (a, b) -> a.timeout - b.timeout - $.set 'captchas', @captchas - @count() focus = d.activeElement?.nodeName is 'IFRAME' and /https?:\/\/www\.google\.com\/recaptcha\//.test(d.activeElement.src) - if @needed() + if Captcha.cache.needed() if focus if QR.cooldown.auto or Conf['Post on Captcha Completion'] @nodes.counter.focus() @@ -206,23 +182,10 @@ Captcha.v2 = QR.submit() if Conf['Post on Captcha Completion'] and !QR.cooldown.auto - clear: -> - $.forceSync 'captchas' - return unless @captchas.length - now = Date.now() - for captcha, i in @captchas - break if captcha.timeout > now - return unless i - @captchas = @captchas[i..] - @count() - $.set 'captchas', @captchas - count: -> - @nodes.counter.textContent = "Captchas: #{@captchas.length}" + count = Captcha.cache.getCount() + @nodes.counter.textContent = "Captchas: #{count}" @moreNeeded() - clearTimeout @timeouts.clear - if @captchas.length - @timeouts.clear = setTimeout @clear.bind(@), @captchas[0].timeout - Date.now() reload: -> if $ 'iframe[src^="https://www.google.com/recaptcha/api/fallback?"]', @nodes.container diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee index 0e031c4f2..4df53c72b 100644 --- a/src/Posting/QR.coffee +++ b/src/Posting/QR.coffee @@ -696,7 +696,7 @@ QR = else delete QR.req post.unlock() - QR.cooldown.auto = !!QR.captcha.captchas.length + QR.cooldown.auto = !!Captcha.cache.getCount() QR.status() else cb captcha @@ -749,7 +749,7 @@ QR = else # stop auto-posting QR.cooldown.auto = false QR.captcha.setup(QR.cooldown.auto and d.activeElement in [QR.nodes.status, d.body]) - QR.cooldown.auto = false if QR.captcha.isEnabled and !QR.captcha.captchas.length + QR.cooldown.auto = false if QR.captcha.isEnabled and !Captcha.cache.getCount() QR.status() QR.error err return