diff --git a/CHANGELOG.md b/CHANGELOG.md
index e07bbc313..6f3aef3d6 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,10 @@ The links to individual versions below are to copies of the script with the upda
## v1.11.0
+**v1.11.0.9** *(2015-06-21)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.0.9/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.0.9/builds/4chan-X-noupdate.crx "Chromium version")]
+- Fix caching of v1 captchas.
+- Other minor bugfixes.
+
**v1.11.0.8** *(2015-06-21)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.0.8/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.0.8/builds/4chan-X-noupdate.crx "Chromium version")]
- Support noscript version of Recaptcha v1.
- Captcha-related bugfixes/improvements.
diff --git a/builds/4chan-X-beta.crx b/builds/4chan-X-beta.crx
index d8242d82f..bd52d825e 100644
Binary files a/builds/4chan-X-beta.crx and b/builds/4chan-X-beta.crx differ
diff --git a/builds/4chan-X-beta.meta.js b/builds/4chan-X-beta.meta.js
index 87ec7d95f..8a3a66685 100644
--- a/builds/4chan-X-beta.meta.js
+++ b/builds/4chan-X-beta.meta.js
@@ -1,6 +1,6 @@
// ==UserScript==
// @name 4chan X beta
-// @version 1.11.0.8
+// @version 1.11.0.9
// @minGMVer 1.14
// @minFFVer 26
// @namespace 4chan-X
diff --git a/builds/4chan-X-beta.user.js b/builds/4chan-X-beta.user.js
index 3b0985d84..624570623 100644
--- a/builds/4chan-X-beta.user.js
+++ b/builds/4chan-X-beta.user.js
@@ -1,7 +1,7 @@
// Generated by CoffeeScript
// ==UserScript==
// @name 4chan X beta
-// @version 1.11.0.8
+// @version 1.11.0.9
// @minGMVer 1.14
// @minFFVer 26
// @namespace 4chan-X
@@ -402,7 +402,7 @@
doc = d.documentElement;
g = {
- VERSION: '1.11.0.8',
+ VERSION: '1.11.0.9',
NAMESPACE: '4chan X.',
boards: {}
};
@@ -7807,7 +7807,7 @@
};
Captcha.noscript = {
- lifetime: 10 * $.MINUTE,
+ lifetime: 30 * $.MINUTE,
init: function() {
var container, input;
if (d.cookie.indexOf('pass_enabled=1') >= 0) {
@@ -8183,6 +8183,13 @@
$.addClass(QR.nodes.el, 'has-captcha', 'captcha-v1');
$.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);
new MutationObserver(this.afterSetup).observe($.id('captchaContainer'), {
childList: true
});
@@ -8202,6 +8209,7 @@
img.parentNode.hidden = true;
input.value = '';
input.placeholder = 'Focus to load reCAPTCHA';
+ this.count();
return $.on(input, 'focus click', this.cb.focus);
},
needed: function() {
@@ -8244,6 +8252,7 @@
ref = QR.captcha.nodes, img = ref.img, input = ref.input;
img.parentNode.hidden = false;
input.placeholder = 'Verification';
+ QR.captcha.count();
$.off(input, 'focus click', QR.captcha.cb.focus);
QR.captcha.nodes.challenge = challenge;
new MutationObserver(QR.captcha.load.bind(QR.captcha)).observe(challenge, {
@@ -8264,18 +8273,69 @@
$.globalEval('Recaptcha.destroy()');
return this.beforeSetup();
},
- getOne: function() {
- var challenge, response;
- challenge = this.nodes.img.alt;
- if (/\S/.test(response = this.nodes.input.value)) {
- this.destroy();
- return {
- challenge: challenge,
- response: response
- };
- } else {
- return null;
+ sync: function(captchas) {
+ if (captchas == null) {
+ captchas = [];
}
+ QR.captcha.captchas = captchas;
+ return QR.captcha.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 (/\S/.test(response = this.nodes.input.value)) {
+ this.destroy();
+ } else {
+ return null;
+ }
+ }
+ return {
+ challenge: challenge,
+ response: response
+ };
+ },
+ save: function() {
+ var response;
+ if (!/\S/.test(response = this.nodes.input.value)) {
+ return;
+ }
+ this.nodes.input.value = '';
+ this.captchas.push({
+ challenge: this.nodes.img.alt,
+ response: response,
+ timeout: this.timeout
+ });
+ this.count();
+ this.destroy();
+ this.setup(false, true);
+ return $.set('captchas', this.captchas);
+ },
+ clear: function() {
+ var captcha, i, k, len1, now, ref;
+ if (!this.captchas.length) {
+ return;
+ }
+ $.forceSync('captchas');
+ now = Date.now();
+ ref = this.captchas;
+ for (i = k = 0, len1 = ref.length; k < len1; i = ++k) {
+ 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() {
var challenge, challenge_image;
@@ -8289,7 +8349,30 @@
challenge = this.nodes.challenge.firstChild.value;
this.nodes.img.alt = challenge;
this.nodes.img.src = challenge_image.src;
- return this.nodes.input.value = null;
+ this.nodes.input.value = null;
+ return this.clear();
+ },
+ count: function() {
+ var count, placeholder;
+ count = this.captchas ? this.captchas.length : 0;
+ placeholder = this.nodes.input.placeholder.replace(/\ \(.*\)$/, '');
+ placeholder += (function() {
+ switch (count) {
+ case 0:
+ if (placeholder === 'Verification') {
+ return ' (Shift + Enter to cache)';
+ } else {
+ return '';
+ }
+ break;
+ case 1:
+ return ' (1 cached captcha)';
+ default:
+ return " (" + count + " cached captchas)";
+ }
+ })();
+ this.nodes.input.placeholder = placeholder;
+ return this.nodes.input.alt = count;
},
reload: function(focus) {
$.globalEval('Recaptcha.reload(); Recaptcha.should_focus = false;');
@@ -8300,6 +8383,8 @@
keydown: function(e) {
if (e.keyCode === 8 && !this.nodes.input.value) {
this.reload();
+ } else if (e.keyCode === 13 && e.shiftKey) {
+ this.save();
} else {
return;
}
@@ -19546,7 +19631,7 @@
" width: 4em;\n" +
"}\n" +
":root.gallery-open.fixed #header-bar:not(.autohide),\n" +
-":root.gallery-open.fixed #header-bar:not(.autohide) .fa::before {\n" +
+":root.gallery-open.fixed #header-bar:not(.autohide) #shortcuts .fa::before {\n" +
" visibility: hidden;\n" +
"}\n" +
"/* General */\n" +
diff --git a/builds/4chan-X-noupdate.crx b/builds/4chan-X-noupdate.crx
index ba6bfd8e0..dae68a468 100644
Binary files a/builds/4chan-X-noupdate.crx and b/builds/4chan-X-noupdate.crx differ
diff --git a/builds/4chan-X-noupdate.user.js b/builds/4chan-X-noupdate.user.js
index cf885a54a..2c2471207 100644
--- a/builds/4chan-X-noupdate.user.js
+++ b/builds/4chan-X-noupdate.user.js
@@ -1,7 +1,7 @@
// Generated by CoffeeScript
// ==UserScript==
// @name 4chan X
-// @version 1.11.0.8
+// @version 1.11.0.9
// @minGMVer 1.14
// @minFFVer 26
// @namespace 4chan-X
@@ -401,7 +401,7 @@
doc = d.documentElement;
g = {
- VERSION: '1.11.0.8',
+ VERSION: '1.11.0.9',
NAMESPACE: '4chan X.',
boards: {}
};
@@ -7806,7 +7806,7 @@
};
Captcha.noscript = {
- lifetime: 10 * $.MINUTE,
+ lifetime: 30 * $.MINUTE,
init: function() {
var container, input;
if (d.cookie.indexOf('pass_enabled=1') >= 0) {
@@ -8182,6 +8182,13 @@
$.addClass(QR.nodes.el, 'has-captcha', 'captcha-v1');
$.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);
new MutationObserver(this.afterSetup).observe($.id('captchaContainer'), {
childList: true
});
@@ -8201,6 +8208,7 @@
img.parentNode.hidden = true;
input.value = '';
input.placeholder = 'Focus to load reCAPTCHA';
+ this.count();
return $.on(input, 'focus click', this.cb.focus);
},
needed: function() {
@@ -8243,6 +8251,7 @@
ref = QR.captcha.nodes, img = ref.img, input = ref.input;
img.parentNode.hidden = false;
input.placeholder = 'Verification';
+ QR.captcha.count();
$.off(input, 'focus click', QR.captcha.cb.focus);
QR.captcha.nodes.challenge = challenge;
new MutationObserver(QR.captcha.load.bind(QR.captcha)).observe(challenge, {
@@ -8263,18 +8272,69 @@
$.globalEval('Recaptcha.destroy()');
return this.beforeSetup();
},
- getOne: function() {
- var challenge, response;
- challenge = this.nodes.img.alt;
- if (/\S/.test(response = this.nodes.input.value)) {
- this.destroy();
- return {
- challenge: challenge,
- response: response
- };
- } else {
- return null;
+ sync: function(captchas) {
+ if (captchas == null) {
+ captchas = [];
}
+ QR.captcha.captchas = captchas;
+ return QR.captcha.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 (/\S/.test(response = this.nodes.input.value)) {
+ this.destroy();
+ } else {
+ return null;
+ }
+ }
+ return {
+ challenge: challenge,
+ response: response
+ };
+ },
+ save: function() {
+ var response;
+ if (!/\S/.test(response = this.nodes.input.value)) {
+ return;
+ }
+ this.nodes.input.value = '';
+ this.captchas.push({
+ challenge: this.nodes.img.alt,
+ response: response,
+ timeout: this.timeout
+ });
+ this.count();
+ this.destroy();
+ this.setup(false, true);
+ return $.set('captchas', this.captchas);
+ },
+ clear: function() {
+ var captcha, i, k, len1, now, ref;
+ if (!this.captchas.length) {
+ return;
+ }
+ $.forceSync('captchas');
+ now = Date.now();
+ ref = this.captchas;
+ for (i = k = 0, len1 = ref.length; k < len1; i = ++k) {
+ 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() {
var challenge, challenge_image;
@@ -8288,7 +8348,30 @@
challenge = this.nodes.challenge.firstChild.value;
this.nodes.img.alt = challenge;
this.nodes.img.src = challenge_image.src;
- return this.nodes.input.value = null;
+ this.nodes.input.value = null;
+ return this.clear();
+ },
+ count: function() {
+ var count, placeholder;
+ count = this.captchas ? this.captchas.length : 0;
+ placeholder = this.nodes.input.placeholder.replace(/\ \(.*\)$/, '');
+ placeholder += (function() {
+ switch (count) {
+ case 0:
+ if (placeholder === 'Verification') {
+ return ' (Shift + Enter to cache)';
+ } else {
+ return '';
+ }
+ break;
+ case 1:
+ return ' (1 cached captcha)';
+ default:
+ return " (" + count + " cached captchas)";
+ }
+ })();
+ this.nodes.input.placeholder = placeholder;
+ return this.nodes.input.alt = count;
},
reload: function(focus) {
$.globalEval('Recaptcha.reload(); Recaptcha.should_focus = false;');
@@ -8299,6 +8382,8 @@
keydown: function(e) {
if (e.keyCode === 8 && !this.nodes.input.value) {
this.reload();
+ } else if (e.keyCode === 13 && e.shiftKey) {
+ this.save();
} else {
return;
}
@@ -19545,7 +19630,7 @@
" width: 4em;\n" +
"}\n" +
":root.gallery-open.fixed #header-bar:not(.autohide),\n" +
-":root.gallery-open.fixed #header-bar:not(.autohide) .fa::before {\n" +
+":root.gallery-open.fixed #header-bar:not(.autohide) #shortcuts .fa::before {\n" +
" visibility: hidden;\n" +
"}\n" +
"/* General */\n" +
diff --git a/builds/4chan-X.crx b/builds/4chan-X.crx
index aede57ed8..c15cc2ac4 100644
Binary files a/builds/4chan-X.crx and b/builds/4chan-X.crx differ
diff --git a/builds/4chan-X.meta.js b/builds/4chan-X.meta.js
index e2f04beba..2334f2bfe 100644
--- a/builds/4chan-X.meta.js
+++ b/builds/4chan-X.meta.js
@@ -1,6 +1,6 @@
// ==UserScript==
// @name 4chan X
-// @version 1.11.0.8
+// @version 1.11.0.9
// @minGMVer 1.14
// @minFFVer 26
// @namespace 4chan-X
diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js
index be661b546..8fcf59c20 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.11.0.8
+// @version 1.11.0.9
// @minGMVer 1.14
// @minFFVer 26
// @namespace 4chan-X
@@ -402,7 +402,7 @@
doc = d.documentElement;
g = {
- VERSION: '1.11.0.8',
+ VERSION: '1.11.0.9',
NAMESPACE: '4chan X.',
boards: {}
};
@@ -7807,7 +7807,7 @@
};
Captcha.noscript = {
- lifetime: 10 * $.MINUTE,
+ lifetime: 30 * $.MINUTE,
init: function() {
var container, input;
if (d.cookie.indexOf('pass_enabled=1') >= 0) {
@@ -8183,6 +8183,13 @@
$.addClass(QR.nodes.el, 'has-captcha', 'captcha-v1');
$.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);
new MutationObserver(this.afterSetup).observe($.id('captchaContainer'), {
childList: true
});
@@ -8202,6 +8209,7 @@
img.parentNode.hidden = true;
input.value = '';
input.placeholder = 'Focus to load reCAPTCHA';
+ this.count();
return $.on(input, 'focus click', this.cb.focus);
},
needed: function() {
@@ -8244,6 +8252,7 @@
ref = QR.captcha.nodes, img = ref.img, input = ref.input;
img.parentNode.hidden = false;
input.placeholder = 'Verification';
+ QR.captcha.count();
$.off(input, 'focus click', QR.captcha.cb.focus);
QR.captcha.nodes.challenge = challenge;
new MutationObserver(QR.captcha.load.bind(QR.captcha)).observe(challenge, {
@@ -8264,18 +8273,69 @@
$.globalEval('Recaptcha.destroy()');
return this.beforeSetup();
},
- getOne: function() {
- var challenge, response;
- challenge = this.nodes.img.alt;
- if (/\S/.test(response = this.nodes.input.value)) {
- this.destroy();
- return {
- challenge: challenge,
- response: response
- };
- } else {
- return null;
+ sync: function(captchas) {
+ if (captchas == null) {
+ captchas = [];
}
+ QR.captcha.captchas = captchas;
+ return QR.captcha.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 (/\S/.test(response = this.nodes.input.value)) {
+ this.destroy();
+ } else {
+ return null;
+ }
+ }
+ return {
+ challenge: challenge,
+ response: response
+ };
+ },
+ save: function() {
+ var response;
+ if (!/\S/.test(response = this.nodes.input.value)) {
+ return;
+ }
+ this.nodes.input.value = '';
+ this.captchas.push({
+ challenge: this.nodes.img.alt,
+ response: response,
+ timeout: this.timeout
+ });
+ this.count();
+ this.destroy();
+ this.setup(false, true);
+ return $.set('captchas', this.captchas);
+ },
+ clear: function() {
+ var captcha, i, k, len1, now, ref;
+ if (!this.captchas.length) {
+ return;
+ }
+ $.forceSync('captchas');
+ now = Date.now();
+ ref = this.captchas;
+ for (i = k = 0, len1 = ref.length; k < len1; i = ++k) {
+ 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() {
var challenge, challenge_image;
@@ -8289,7 +8349,30 @@
challenge = this.nodes.challenge.firstChild.value;
this.nodes.img.alt = challenge;
this.nodes.img.src = challenge_image.src;
- return this.nodes.input.value = null;
+ this.nodes.input.value = null;
+ return this.clear();
+ },
+ count: function() {
+ var count, placeholder;
+ count = this.captchas ? this.captchas.length : 0;
+ placeholder = this.nodes.input.placeholder.replace(/\ \(.*\)$/, '');
+ placeholder += (function() {
+ switch (count) {
+ case 0:
+ if (placeholder === 'Verification') {
+ return ' (Shift + Enter to cache)';
+ } else {
+ return '';
+ }
+ break;
+ case 1:
+ return ' (1 cached captcha)';
+ default:
+ return " (" + count + " cached captchas)";
+ }
+ })();
+ this.nodes.input.placeholder = placeholder;
+ return this.nodes.input.alt = count;
},
reload: function(focus) {
$.globalEval('Recaptcha.reload(); Recaptcha.should_focus = false;');
@@ -8300,6 +8383,8 @@
keydown: function(e) {
if (e.keyCode === 8 && !this.nodes.input.value) {
this.reload();
+ } else if (e.keyCode === 13 && e.shiftKey) {
+ this.save();
} else {
return;
}
@@ -19546,7 +19631,7 @@
" width: 4em;\n" +
"}\n" +
":root.gallery-open.fixed #header-bar:not(.autohide),\n" +
-":root.gallery-open.fixed #header-bar:not(.autohide) .fa::before {\n" +
+":root.gallery-open.fixed #header-bar:not(.autohide) #shortcuts .fa::before {\n" +
" visibility: hidden;\n" +
"}\n" +
"/* General */\n" +
diff --git a/builds/4chan-X.zip b/builds/4chan-X.zip
index 3dc874015..e00f87cde 100644
Binary files a/builds/4chan-X.zip and b/builds/4chan-X.zip differ
diff --git a/builds/updates-beta.xml b/builds/updates-beta.xml
index fc794c866..8bc05405e 100644
--- a/builds/updates-beta.xml
+++ b/builds/updates-beta.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/builds/updates.xml b/builds/updates.xml
index 1eeca5801..f7f746085 100644
--- a/builds/updates.xml
+++ b/builds/updates.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/package.json b/package.json
index 98020470d..e32d3e0ba 100755
--- a/package.json
+++ b/package.json
@@ -3,8 +3,8 @@
"description": "Cross-browser userscript for maximum lurking on 4chan.",
"meta": {
"name": "4chan X",
- "version": "1.11.0.8",
- "date": "2015-06-21T22:29:51.283Z",
+ "version": "1.11.0.9",
+ "date": "2015-06-22T00:44:15.370Z",
"repo": "https://github.com/ccd0/4chan-x/",
"page": "https://github.com/ccd0/4chan-x",
"downloads": "https://ccd0.github.io/4chan-x/builds/",