diff --git a/CHANGELOG.md b/CHANGELOG.md index ca5c38922..97cb27427 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### v1.7.23 +*2014-04-29* + **ccd0** - Partly restore Mayhem's captcha changes reverted in last version. Captchas are now destroyed after posting instead of reloaded, unless `Auto-load captcha` is checked. Captcha caching is still enabled. - Update for changes in Recaptcha, in particular `Recaptcha.reload("t")` no longer working. diff --git a/LICENSE b/LICENSE index 5159e8ae2..0f459c8fc 100755 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ /* -* 4chan X - Version 1.7.22 - 2014-04-27 +* 4chan X - Version 1.7.23 - 2014-04-29 * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE diff --git a/builds/4chan-X.meta.js b/builds/4chan-X.meta.js index 2004b2290..c5d395051 100755 --- a/builds/4chan-X.meta.js +++ b/builds/4chan-X.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.7.22 +// @version 1.7.23 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 04122535e..34e979545 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1,7 +1,7 @@ // Generated by CoffeeScript // ==UserScript== // @name 4chan X -// @version 1.7.22 +// @version 1.7.23 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -24,7 +24,7 @@ // ==/UserScript== /* -* 4chan X - Version 1.7.22 - 2014-04-27 +* 4chan X - Version 1.7.23 - 2014-04-29 * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE @@ -224,7 +224,7 @@ 'Cooldown Prediction': [true, 'Decrease the cooldown time by taking into account upload speed. Disable it if it\'s inaccurate for you.'], 'Posting Success Notifications': [true, 'Show notifications on successful post creation or file uploading.'], 'Captcha Warning Notifications': [true, 'When disabled, shows a red border on the CAPTCHA input until a key is pressed instead of a notification.'], - 'Auto-load captcha': [false, 'Automatically load the captcha when you open a thread'] + 'Auto-load captcha': [false, 'Automatically load the captcha when you open a thread, and reload it after you post.'] }, 'Quote Links': { 'Quote Backlinks': [true, 'Add quote backlinks.'], @@ -372,7 +372,7 @@ doc = d.documentElement; g = { - VERSION: '1.7.22', + VERSION: '1.7.23', NAMESPACE: '4chan X.', boards: {} }; @@ -5807,7 +5807,10 @@ post["delete"](); } QR.cooldown.auto = false; - return QR.status(); + QR.status(); + if (QR.captcha.isEnabled && !Conf['Auto-load captcha']) { + return QR.captcha.destroy(); + } }, focusin: function() { return $.addClass(QR.nodes.el, 'focus'); @@ -5841,8 +5844,10 @@ el.removeAttribute('style'); } if (QR.captcha.isEnabled && /captcha|verification/i.test(el.textContent)) { - QR.captcha.nodes.input.focus(); - QR.captcha.setup(); + if (QR.captcha.captchas.length === 0) { + QR.captcha.nodes.input.focus(); + QR.captcha.setup(); + } if (Conf['Captcha Warning Notifications'] && !d.hidden) { QR.notify(el); } else { @@ -6517,7 +6522,7 @@ if (!(Conf['Persistent QR'] || QR.cooldown.auto)) { QR.close(); } else { - if (QR.posts.length > 1) { + if (QR.posts.length > 1 && QR.captcha.isEnabled && QR.captcha.captchas.length === 0) { QR.captcha.setup(); } post.rm(); @@ -6552,12 +6557,11 @@ QR.captcha = { init: function() { - var container, imgContainer, input; + var imgContainer, input; if (d.cookie.indexOf('pass_enabled=1') >= 0) { return; } - container = $.id('captchaContainer'); - if (!(this.isEnabled = !!container)) { + if (!(this.isEnabled = !!$.id('captchaContainer'))) { return; } if (Conf['Auto-load captcha']) { @@ -6566,13 +6570,11 @@ imgContainer = $.el('div', { className: 'captcha-img', title: 'Reload reCAPTCHA', - innerHTML: '', - hidden: true + innerHTML: '' }); input = $.el('input', { className: 'captcha-input field', title: 'Verification', - placeholder: 'Focus to load reCAPTCHA', autocomplete: 'off', spellcheck: false, tabIndex: 45 @@ -6581,16 +6583,35 @@ img: imgContainer.firstChild, input: input }; - $.on(input, 'focus', this.setup); $.on(input, 'blur', QR.focusout); $.on(input, 'focus', QR.focusin); + $.on(input, 'keydown', QR.captcha.keydown.bind(QR.captcha)); + $.on(this.nodes.img.parentNode, 'click', QR.captcha.reload.bind(QR.captcha)); $.addClass(QR.nodes.el, 'has-captcha'); $.after(QR.nodes.com.parentNode, [imgContainer, input]); + this.captchas = []; + $.get('captchas', [], function(_arg) { + var captchas; + captchas = _arg.captchas; + QR.captcha.sync(captchas); + return QR.captcha.clear(); + }); + $.sync('captchas', this.sync); + this.beforeSetup(); + return this.afterSetup(); + }, + beforeSetup: function() { + var img, input, _ref; + _ref = this.nodes, img = _ref.img, input = _ref.input; + img.parentNode.hidden = true; + input.value = ''; + input.placeholder = 'Focus to load reCAPTCHA'; + this.count(); + $.on(input, 'focus', this.setup); this.setupObserver = new MutationObserver(this.afterSetup); - this.setupObserver.observe(container, { + return this.setupObserver.observe($.id('captchaContainer'), { childList: true }); - return this.afterSetup(); }, setup: function() { return $.globalEval('loadRecaptcha()'); @@ -6610,15 +6631,9 @@ $.off(window, 'captcha:timeout', setLifetime); _ref = QR.captcha.nodes, img = _ref.img, input = _ref.input; img.parentNode.hidden = false; + input.placeholder = 'Verification'; + QR.captcha.count(); $.off(input, 'focus', QR.captcha.setup); - $.on(input, 'keydown', QR.captcha.keydown.bind(QR.captcha)); - $.on(img.parentNode, 'click', QR.captcha.reload.bind(QR.captcha)); - $.get('captchas', [], function(_arg) { - var captchas; - captchas = _arg.captchas; - return QR.captcha.sync(captchas); - }); - $.sync('captchas', QR.captcha.sync); QR.captcha.nodes.challenge = challenge; new MutationObserver(QR.captcha.load.bind(QR.captcha)).observe(challenge, { childList: true, @@ -6627,6 +6642,10 @@ }); return QR.captcha.load(); }, + destroy: function() { + $.globalEval('Recaptcha.destroy()'); + return this.beforeSetup(); + }, sync: function(captchas) { QR.captcha.captchas = captchas; return QR.captcha.count(); @@ -6641,7 +6660,11 @@ } else { challenge = this.nodes.img.alt; if (response = this.nodes.input.value) { - this.reload(); + if (Conf['Auto-load captcha']) { + this.reload(); + } else { + this.destroy(); + } } } if (response) { @@ -6660,6 +6683,7 @@ if (!(response = this.nodes.input.value.trim())) { return; } + this.nodes.input.value = ''; this.captchas.push({ challenge: this.nodes.img.alt, response: response, @@ -6690,34 +6714,44 @@ return $.set('captchas', this.captchas); }, load: function() { - var challenge; + var challenge, challenge_image; if (!this.nodes.challenge.firstChild) { return; } + if (!(challenge_image = $.id('recaptcha_challenge_image'))) { + return; + } this.timeout = Date.now() + this.lifetime * $.SECOND - $.MINUTE; challenge = this.nodes.challenge.firstChild.value; this.nodes.img.alt = challenge; - this.nodes.img.src = "//www.google.com/recaptcha/api/image?c=" + challenge; + this.nodes.img.src = challenge_image.src; this.nodes.input.value = null; return this.clear(); }, count: function() { - var count; + var count, placeholder; count = this.captchas ? this.captchas.length : 0; - this.nodes.input.placeholder = (function() { + placeholder = this.nodes.input.placeholder.replace(/\ \(.*\)$/, ''); + placeholder += (function() { switch (count) { case 0: - return 'Verification (Shift + Enter to cache)'; + if (placeholder === 'Verification') { + return ' (Shift + Enter to cache)'; + } else { + return ''; + } + break; case 1: - return 'Verification (1 cached captcha)'; + return ' (1 cached captcha)'; default: - return "Verification (" + count + " cached captchas)"; + return " (" + count + " cached captchas)"; } })(); + this.nodes.input.placeholder = placeholder; return this.nodes.input.alt = count; }, reload: function(focus) { - $.globalEval('Recaptcha.reload("t")'); + $.globalEval('Recaptcha.reload(); Recaptcha.should_focus = false;'); if (focus) { return this.nodes.input.focus(); } @@ -7166,7 +7200,7 @@ if (this === QR.selected) { this.showFileData(); } - if (!/^image/.test(file.type)) { + if (!/^(image|video)\//.test(file.type)) { this.nodes.el.style.backgroundImage = null; return; } @@ -7174,20 +7208,26 @@ }; _Class.prototype.setThumbnail = function() { - var fileURL, img; - img = $.el('img'); - img.onload = (function(_this) { + var fileURL, img, isVideo; + isVideo = /^video\//.test(this.file.type); + img = $.el((isVideo ? 'video' : 'img')); + $.on(img, (isVideo ? 'loadeddata' : 'load'), (function(_this) { return function() { var cv, height, s, width; s = 90 * 2 * window.devicePixelRatio; if (_this.file.type === 'image/gif') { s *= 3; } - height = img.height, width = img.width; - if (height < s || width < s) { - _this.URL = fileURL; - _this.nodes.el.style.backgroundImage = "url(" + _this.URL + ")"; - return; + if (isVideo) { + height = img.videoHeight; + width = img.videoWidth; + } else { + height = img.height, width = img.width; + if (height < s || width < s) { + _this.URL = fileURL; + _this.nodes.el.style.backgroundImage = "url(" + _this.URL + ")"; + return; + } } if (height <= width) { width = s / height * width; @@ -7206,7 +7246,7 @@ return _this.nodes.el.style.backgroundImage = "url(" + _this.URL + ")"; }); }; - })(this); + })(this)); fileURL = URL.createObjectURL(this.file); return img.src = fileURL; }; diff --git a/builds/crx.crx b/builds/crx.crx index 97c29f1f4..607e6aa00 100644 Binary files a/builds/crx.crx and b/builds/crx.crx differ diff --git a/builds/crx/manifest.json b/builds/crx/manifest.json index 54183dc52..511fe3356 100755 --- a/builds/crx/manifest.json +++ b/builds/crx/manifest.json @@ -1,6 +1,6 @@ { "name": "4chan X", - "version": "1.7.22", + "version": "1.7.23", "manifest_version": 2, "description": "Cross-browser userscript for maximum lurking on 4chan.", "icons": { diff --git a/builds/crx/script.js b/builds/crx/script.js index 3420004f7..7af3c6471 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript /* -* 4chan X - Version 1.7.22 - 2014-04-27 +* 4chan X - Version 1.7.23 - 2014-04-29 * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE @@ -200,7 +200,7 @@ 'Cooldown Prediction': [true, 'Decrease the cooldown time by taking into account upload speed. Disable it if it\'s inaccurate for you.'], 'Posting Success Notifications': [true, 'Show notifications on successful post creation or file uploading.'], 'Captcha Warning Notifications': [true, 'When disabled, shows a red border on the CAPTCHA input until a key is pressed instead of a notification.'], - 'Auto-load captcha': [false, 'Automatically load the captcha when you open a thread'] + 'Auto-load captcha': [false, 'Automatically load the captcha when you open a thread, and reload it after you post.'] }, 'Quote Links': { 'Quote Backlinks': [true, 'Add quote backlinks.'], @@ -348,7 +348,7 @@ doc = d.documentElement; g = { - VERSION: '1.7.22', + VERSION: '1.7.23', NAMESPACE: '4chan X.', boards: {} }; @@ -5842,7 +5842,10 @@ post["delete"](); } QR.cooldown.auto = false; - return QR.status(); + QR.status(); + if (QR.captcha.isEnabled && !Conf['Auto-load captcha']) { + return QR.captcha.destroy(); + } }, focusin: function() { return $.addClass(QR.nodes.el, 'focus'); @@ -5876,8 +5879,10 @@ el.removeAttribute('style'); } if (QR.captcha.isEnabled && /captcha|verification/i.test(el.textContent)) { - QR.captcha.nodes.input.focus(); - QR.captcha.setup(); + if (QR.captcha.captchas.length === 0) { + QR.captcha.nodes.input.focus(); + QR.captcha.setup(); + } if (Conf['Captcha Warning Notifications'] && !d.hidden) { QR.notify(el); } else { @@ -6542,7 +6547,7 @@ if (!(Conf['Persistent QR'] || QR.cooldown.auto)) { QR.close(); } else { - if (QR.posts.length > 1) { + if (QR.posts.length > 1 && QR.captcha.isEnabled && QR.captcha.captchas.length === 0) { QR.captcha.setup(); } post.rm(); @@ -6577,12 +6582,11 @@ QR.captcha = { init: function() { - var container, imgContainer, input; + var imgContainer, input; if (d.cookie.indexOf('pass_enabled=1') >= 0) { return; } - container = $.id('captchaContainer'); - if (!(this.isEnabled = !!container)) { + if (!(this.isEnabled = !!$.id('captchaContainer'))) { return; } if (Conf['Auto-load captcha']) { @@ -6591,13 +6595,11 @@ imgContainer = $.el('div', { className: 'captcha-img', title: 'Reload reCAPTCHA', - innerHTML: '', - hidden: true + innerHTML: '' }); input = $.el('input', { className: 'captcha-input field', title: 'Verification', - placeholder: 'Focus to load reCAPTCHA', autocomplete: 'off', spellcheck: false, tabIndex: 45 @@ -6606,16 +6608,35 @@ img: imgContainer.firstChild, input: input }; - $.on(input, 'focus', this.setup); $.on(input, 'blur', QR.focusout); $.on(input, 'focus', QR.focusin); + $.on(input, 'keydown', QR.captcha.keydown.bind(QR.captcha)); + $.on(this.nodes.img.parentNode, 'click', QR.captcha.reload.bind(QR.captcha)); $.addClass(QR.nodes.el, 'has-captcha'); $.after(QR.nodes.com.parentNode, [imgContainer, input]); + this.captchas = []; + $.get('captchas', [], function(_arg) { + var captchas; + captchas = _arg.captchas; + QR.captcha.sync(captchas); + return QR.captcha.clear(); + }); + $.sync('captchas', this.sync); + this.beforeSetup(); + return this.afterSetup(); + }, + beforeSetup: function() { + var img, input, _ref; + _ref = this.nodes, img = _ref.img, input = _ref.input; + img.parentNode.hidden = true; + input.value = ''; + input.placeholder = 'Focus to load reCAPTCHA'; + this.count(); + $.on(input, 'focus', this.setup); this.setupObserver = new MutationObserver(this.afterSetup); - this.setupObserver.observe(container, { + return this.setupObserver.observe($.id('captchaContainer'), { childList: true }); - return this.afterSetup(); }, setup: function() { return $.globalEval('loadRecaptcha()'); @@ -6635,15 +6656,9 @@ $.off(window, 'captcha:timeout', setLifetime); _ref = QR.captcha.nodes, img = _ref.img, input = _ref.input; img.parentNode.hidden = false; + input.placeholder = 'Verification'; + QR.captcha.count(); $.off(input, 'focus', QR.captcha.setup); - $.on(input, 'keydown', QR.captcha.keydown.bind(QR.captcha)); - $.on(img.parentNode, 'click', QR.captcha.reload.bind(QR.captcha)); - $.get('captchas', [], function(_arg) { - var captchas; - captchas = _arg.captchas; - return QR.captcha.sync(captchas); - }); - $.sync('captchas', QR.captcha.sync); QR.captcha.nodes.challenge = challenge; new MutationObserver(QR.captcha.load.bind(QR.captcha)).observe(challenge, { childList: true, @@ -6652,6 +6667,10 @@ }); return QR.captcha.load(); }, + destroy: function() { + $.globalEval('Recaptcha.destroy()'); + return this.beforeSetup(); + }, sync: function(captchas) { QR.captcha.captchas = captchas; return QR.captcha.count(); @@ -6666,7 +6685,11 @@ } else { challenge = this.nodes.img.alt; if (response = this.nodes.input.value) { - this.reload(); + if (Conf['Auto-load captcha']) { + this.reload(); + } else { + this.destroy(); + } } } if (response) { @@ -6685,6 +6708,7 @@ if (!(response = this.nodes.input.value.trim())) { return; } + this.nodes.input.value = ''; this.captchas.push({ challenge: this.nodes.img.alt, response: response, @@ -6715,34 +6739,44 @@ return $.set('captchas', this.captchas); }, load: function() { - var challenge; + var challenge, challenge_image; if (!this.nodes.challenge.firstChild) { return; } + if (!(challenge_image = $.id('recaptcha_challenge_image'))) { + return; + } this.timeout = Date.now() + this.lifetime * $.SECOND - $.MINUTE; challenge = this.nodes.challenge.firstChild.value; this.nodes.img.alt = challenge; - this.nodes.img.src = "//www.google.com/recaptcha/api/image?c=" + challenge; + this.nodes.img.src = challenge_image.src; this.nodes.input.value = null; return this.clear(); }, count: function() { - var count; + var count, placeholder; count = this.captchas ? this.captchas.length : 0; - this.nodes.input.placeholder = (function() { + placeholder = this.nodes.input.placeholder.replace(/\ \(.*\)$/, ''); + placeholder += (function() { switch (count) { case 0: - return 'Verification (Shift + Enter to cache)'; + if (placeholder === 'Verification') { + return ' (Shift + Enter to cache)'; + } else { + return ''; + } + break; case 1: - return 'Verification (1 cached captcha)'; + return ' (1 cached captcha)'; default: - return "Verification (" + count + " cached captchas)"; + return " (" + count + " cached captchas)"; } })(); + this.nodes.input.placeholder = placeholder; return this.nodes.input.alt = count; }, reload: function(focus) { - $.globalEval('Recaptcha.reload("t")'); + $.globalEval('Recaptcha.reload(); Recaptcha.should_focus = false;'); if (focus) { return this.nodes.input.focus(); } @@ -7185,7 +7219,7 @@ if (this === QR.selected) { this.showFileData(); } - if (!/^image/.test(file.type)) { + if (!/^(image|video)\//.test(file.type)) { this.nodes.el.style.backgroundImage = null; return; } @@ -7193,20 +7227,26 @@ }; _Class.prototype.setThumbnail = function() { - var fileURL, img; - img = $.el('img'); - img.onload = (function(_this) { + var fileURL, img, isVideo; + isVideo = /^video\//.test(this.file.type); + img = $.el((isVideo ? 'video' : 'img')); + $.on(img, (isVideo ? 'loadeddata' : 'load'), (function(_this) { return function() { var cv, height, s, width; s = 90 * 2 * window.devicePixelRatio; if (_this.file.type === 'image/gif') { s *= 3; } - height = img.height, width = img.width; - if (height < s || width < s) { - _this.URL = fileURL; - _this.nodes.el.style.backgroundImage = "url(" + _this.URL + ")"; - return; + if (isVideo) { + height = img.videoHeight; + width = img.videoWidth; + } else { + height = img.height, width = img.width; + if (height < s || width < s) { + _this.URL = fileURL; + _this.nodes.el.style.backgroundImage = "url(" + _this.URL + ")"; + return; + } } if (height <= width) { width = s / height * width; @@ -7225,7 +7265,7 @@ return _this.nodes.el.style.backgroundImage = "url(" + _this.URL + ")"; }); }; - })(this); + })(this)); fileURL = URL.createObjectURL(this.file); return img.src = fileURL; }; diff --git a/builds/updates.xml b/builds/updates.xml index 8c1cf6839..414436237 100644 --- a/builds/updates.xml +++ b/builds/updates.xml @@ -1,7 +1,7 @@ - + diff --git a/package.json b/package.json index ebff82fc9..a3e336e2c 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "4chan-X", - "version": "1.7.22", + "version": "1.7.23", "description": "Cross-browser userscript for maximum lurking on 4chan.", "meta": { "name": "4chan X",