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",