Release 4chan X v1.11.0.7.
This commit is contained in:
parent
70e1f5c802
commit
ab931069e1
@ -4,6 +4,9 @@ The links to individual versions below are to copies of the script with the upda
|
||||
|
||||
## v1.11.0
|
||||
|
||||
**v1.11.0.7** *(2015-06-21)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.0.7/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.0.7/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- Add `Use Recaptcha v1` option to use the old text-based captchas in the Quick Reply.
|
||||
|
||||
**v1.11.0.6** *(2015-06-20)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.0.6/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.0.6/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- Support toggling images in the captcha with the number keys (as arranged in the numpad) and the UIOJKLM,. keys.
|
||||
- Arrow key navigation now works in noscript captcha.
|
||||
|
||||
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
// ==UserScript==
|
||||
// @name 4chan X beta
|
||||
// @version 1.11.0.6
|
||||
// @version 1.11.0.7
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript
|
||||
// ==UserScript==
|
||||
// @name 4chan X beta
|
||||
// @version 1.11.0.6
|
||||
// @version 1.11.0.7
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -233,6 +233,7 @@
|
||||
'Hide Original Post Form': [true, 'Hide the normal post form.', 1],
|
||||
'Cooldown': [true, 'Indicate the remaining time before posting again.', 1],
|
||||
'Posting Success Notifications': [true, 'Show notifications on successful post creation or file uploading.', 1],
|
||||
'Use Recaptcha v1': [false, 'Use the old text version of Recaptcha.', 1],
|
||||
'Force Noscript Captcha': [false, 'Use the non-Javascript fallback captcha in the QR even if Javascript is enabled.', 1],
|
||||
'Auto-load captcha': [false, 'Automatically load the captcha in the QR even if your post is empty.', 1],
|
||||
'Post on Captcha Completion': [false, 'Submit the post immediately when the captcha is completed.', 1],
|
||||
@ -400,7 +401,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.11.0.6',
|
||||
VERSION: '1.11.0.7',
|
||||
NAMESPACE: '4chan X.',
|
||||
boards: {}
|
||||
};
|
||||
@ -6671,7 +6672,7 @@
|
||||
QR = {
|
||||
mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'application/vnd.adobe.flash.movie', 'application/x-shockwave-flash', 'video/webm'],
|
||||
init: function() {
|
||||
var sc;
|
||||
var sc, version;
|
||||
if (!Conf['Quick Reply']) {
|
||||
return;
|
||||
}
|
||||
@ -6680,7 +6681,8 @@
|
||||
if (g.VIEW === 'archive') {
|
||||
return;
|
||||
}
|
||||
this.captcha = Captcha.v2;
|
||||
version = Conf['Use Recaptcha v1'] ? 'v1' : 'v2';
|
||||
this.captcha = Captcha[version];
|
||||
$.on(d, '4chanXInitFinished', this.initReady);
|
||||
Post.callbacks.push({
|
||||
name: 'Quick Reply',
|
||||
@ -7456,7 +7458,12 @@
|
||||
};
|
||||
cb = function(response) {
|
||||
if (response != null) {
|
||||
extra.form.append('g-recaptcha-response', response);
|
||||
if (response.challenge != null) {
|
||||
extra.form.append('recaptcha_challenge_field', response.challenge);
|
||||
extra.form.append('recaptcha_response_field', response.response);
|
||||
} else {
|
||||
extra.form.append('g-recaptcha-response', response);
|
||||
}
|
||||
}
|
||||
QR.req = $.ajax("https://sys.4chan.org/" + g.BOARD + "/post", options, extra);
|
||||
return QR.req.progress = '...';
|
||||
@ -7790,6 +7797,172 @@
|
||||
}
|
||||
};
|
||||
|
||||
Captcha.v1 = {
|
||||
init: function() {
|
||||
var captchaContainer, imgContainer, input, script;
|
||||
if (d.cookie.indexOf('pass_enabled=1') >= 0) {
|
||||
return;
|
||||
}
|
||||
if (!(this.isEnabled = !!$.id('g-recaptcha'))) {
|
||||
return;
|
||||
}
|
||||
script = $.el('script', {
|
||||
src: '//www.google.com/recaptcha/api/js/recaptcha_ajax.js'
|
||||
});
|
||||
$.add(d.head, script);
|
||||
captchaContainer = $.el('div', {
|
||||
id: 'captchaContainer',
|
||||
hidden: true
|
||||
});
|
||||
$.add(d.body, captchaContainer);
|
||||
imgContainer = $.el('div', {
|
||||
className: 'captcha-img',
|
||||
title: 'Reload reCAPTCHA'
|
||||
});
|
||||
$.extend(imgContainer, {
|
||||
innerHTML: "<img>"
|
||||
});
|
||||
input = $.el('input', {
|
||||
className: 'captcha-input field',
|
||||
title: 'Verification',
|
||||
autocomplete: 'off',
|
||||
spellcheck: false
|
||||
});
|
||||
this.nodes = {
|
||||
img: imgContainer.firstChild,
|
||||
input: input
|
||||
};
|
||||
$.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 = [];
|
||||
new MutationObserver(this.afterSetup).observe($.id('captchaContainer'), {
|
||||
childList: true
|
||||
});
|
||||
this.beforeSetup();
|
||||
if (Conf['Auto-load captcha']) {
|
||||
return this.setup();
|
||||
}
|
||||
},
|
||||
cb: {
|
||||
focus: function() {
|
||||
return QR.captcha.setup(false, true);
|
||||
}
|
||||
},
|
||||
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';
|
||||
return $.on(input, 'focus click', this.cb.focus);
|
||||
},
|
||||
needed: function() {
|
||||
var captchaCount, postsCount;
|
||||
captchaCount = this.captchas.length;
|
||||
if (QR.req) {
|
||||
captchaCount++;
|
||||
}
|
||||
postsCount = QR.posts.length;
|
||||
if (postsCount === 1 && !Conf['Auto-load captcha'] && !QR.posts[0].com && !QR.posts[0].file) {
|
||||
postsCount = 0;
|
||||
}
|
||||
return captchaCount < postsCount;
|
||||
},
|
||||
onNewPost: function() {},
|
||||
onPostChange: function() {},
|
||||
setup: function(focus, force) {
|
||||
if (!(this.isEnabled && (this.needed() || force))) {
|
||||
return;
|
||||
}
|
||||
$.globalEval('(function() {\n var captchaContainer = document.getElementById("captchaContainer");\n if (captchaContainer.firstChild) return;\n function setup() {\n if (window.Recaptcha) {\n Recaptcha.create(recaptchaKey, captchaContainer, {theme: "clean"});\n } else {\n setTimeout(setup, 25);\n }\n }\n setup();\n})()');
|
||||
if (focus) {
|
||||
return this.nodes.input.focus();
|
||||
}
|
||||
},
|
||||
afterSetup: function() {
|
||||
var challenge, img, input, ref, setLifetime;
|
||||
if (!(challenge = $.id('recaptcha_challenge_field_holder'))) {
|
||||
return;
|
||||
}
|
||||
if (challenge === QR.captcha.nodes.challenge) {
|
||||
return;
|
||||
}
|
||||
setLifetime = function(e) {
|
||||
return QR.captcha.lifetime = e.detail;
|
||||
};
|
||||
$.on(window, 'captcha:timeout', setLifetime);
|
||||
$.globalEval('window.dispatchEvent(new CustomEvent("captcha:timeout", {detail: RecaptchaState.timeout}))');
|
||||
$.off(window, 'captcha:timeout', setLifetime);
|
||||
ref = QR.captcha.nodes, img = ref.img, input = ref.input;
|
||||
img.parentNode.hidden = false;
|
||||
input.placeholder = 'Verification';
|
||||
$.off(input, 'focus click', QR.captcha.cb.focus);
|
||||
QR.captcha.nodes.challenge = challenge;
|
||||
new MutationObserver(QR.captcha.load.bind(QR.captcha)).observe(challenge, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
attributes: true
|
||||
});
|
||||
QR.captcha.load();
|
||||
if (QR.nodes.el.getBoundingClientRect().bottom > doc.clientHeight) {
|
||||
QR.nodes.el.style.top = null;
|
||||
return QR.nodes.el.style.bottom = '0px';
|
||||
}
|
||||
},
|
||||
destroy: function() {
|
||||
if (!this.isEnabled) {
|
||||
return;
|
||||
}
|
||||
$.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;
|
||||
}
|
||||
},
|
||||
load: function() {
|
||||
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 = challenge_image.src;
|
||||
return this.nodes.input.value = null;
|
||||
},
|
||||
reload: function(focus) {
|
||||
$.globalEval('Recaptcha.reload(); Recaptcha.should_focus = false;');
|
||||
if (focus) {
|
||||
return this.nodes.input.focus();
|
||||
}
|
||||
},
|
||||
keydown: function(e) {
|
||||
if (e.keyCode === 8 && !this.nodes.input.value) {
|
||||
this.reload();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
return e.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
Captcha.v2 = {
|
||||
lifetime: 2 * $.MINUTE,
|
||||
init: function() {
|
||||
@ -18280,6 +18453,7 @@
|
||||
"#qr > form {\n" +
|
||||
" max-height: calc(100vh - 75px);\n" +
|
||||
" overflow-y: auto;\n" +
|
||||
" overflow-x: hidden;\n" +
|
||||
"}\n" +
|
||||
"#qrtab {\n" +
|
||||
" border-radius: 3px 3px 0 0;\n" +
|
||||
@ -18352,7 +18526,20 @@
|
||||
" position: relative;\n" +
|
||||
" top: 2px;\n" +
|
||||
"}\n" +
|
||||
"/* Captcha */\n" +
|
||||
"/* Recaptcha v1 */\n" +
|
||||
".captcha-img {\n" +
|
||||
" margin: 0px;\n" +
|
||||
" text-align: center;\n" +
|
||||
" background-image: #fff;\n" +
|
||||
" font-size: 0px;\n" +
|
||||
" min-height: 59px;\n" +
|
||||
" min-width: 302px;\n" +
|
||||
"}\n" +
|
||||
".captcha-input{\n" +
|
||||
" width: 100%;\n" +
|
||||
" margin: 1px 0 0;\n" +
|
||||
"}\n" +
|
||||
"/* Recaptcha v2 */\n" +
|
||||
"#qr .captcha-root {\n" +
|
||||
" position: relative;\n" +
|
||||
"}\n" +
|
||||
|
||||
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.11.0.6
|
||||
// @version 1.11.0.7
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -232,6 +232,7 @@
|
||||
'Hide Original Post Form': [true, 'Hide the normal post form.', 1],
|
||||
'Cooldown': [true, 'Indicate the remaining time before posting again.', 1],
|
||||
'Posting Success Notifications': [true, 'Show notifications on successful post creation or file uploading.', 1],
|
||||
'Use Recaptcha v1': [false, 'Use the old text version of Recaptcha.', 1],
|
||||
'Force Noscript Captcha': [false, 'Use the non-Javascript fallback captcha in the QR even if Javascript is enabled.', 1],
|
||||
'Auto-load captcha': [false, 'Automatically load the captcha in the QR even if your post is empty.', 1],
|
||||
'Post on Captcha Completion': [false, 'Submit the post immediately when the captcha is completed.', 1],
|
||||
@ -399,7 +400,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.11.0.6',
|
||||
VERSION: '1.11.0.7',
|
||||
NAMESPACE: '4chan X.',
|
||||
boards: {}
|
||||
};
|
||||
@ -6670,7 +6671,7 @@
|
||||
QR = {
|
||||
mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'application/vnd.adobe.flash.movie', 'application/x-shockwave-flash', 'video/webm'],
|
||||
init: function() {
|
||||
var sc;
|
||||
var sc, version;
|
||||
if (!Conf['Quick Reply']) {
|
||||
return;
|
||||
}
|
||||
@ -6679,7 +6680,8 @@
|
||||
if (g.VIEW === 'archive') {
|
||||
return;
|
||||
}
|
||||
this.captcha = Captcha.v2;
|
||||
version = Conf['Use Recaptcha v1'] ? 'v1' : 'v2';
|
||||
this.captcha = Captcha[version];
|
||||
$.on(d, '4chanXInitFinished', this.initReady);
|
||||
Post.callbacks.push({
|
||||
name: 'Quick Reply',
|
||||
@ -7455,7 +7457,12 @@
|
||||
};
|
||||
cb = function(response) {
|
||||
if (response != null) {
|
||||
extra.form.append('g-recaptcha-response', response);
|
||||
if (response.challenge != null) {
|
||||
extra.form.append('recaptcha_challenge_field', response.challenge);
|
||||
extra.form.append('recaptcha_response_field', response.response);
|
||||
} else {
|
||||
extra.form.append('g-recaptcha-response', response);
|
||||
}
|
||||
}
|
||||
QR.req = $.ajax("https://sys.4chan.org/" + g.BOARD + "/post", options, extra);
|
||||
return QR.req.progress = '...';
|
||||
@ -7789,6 +7796,172 @@
|
||||
}
|
||||
};
|
||||
|
||||
Captcha.v1 = {
|
||||
init: function() {
|
||||
var captchaContainer, imgContainer, input, script;
|
||||
if (d.cookie.indexOf('pass_enabled=1') >= 0) {
|
||||
return;
|
||||
}
|
||||
if (!(this.isEnabled = !!$.id('g-recaptcha'))) {
|
||||
return;
|
||||
}
|
||||
script = $.el('script', {
|
||||
src: '//www.google.com/recaptcha/api/js/recaptcha_ajax.js'
|
||||
});
|
||||
$.add(d.head, script);
|
||||
captchaContainer = $.el('div', {
|
||||
id: 'captchaContainer',
|
||||
hidden: true
|
||||
});
|
||||
$.add(d.body, captchaContainer);
|
||||
imgContainer = $.el('div', {
|
||||
className: 'captcha-img',
|
||||
title: 'Reload reCAPTCHA'
|
||||
});
|
||||
$.extend(imgContainer, {
|
||||
innerHTML: "<img>"
|
||||
});
|
||||
input = $.el('input', {
|
||||
className: 'captcha-input field',
|
||||
title: 'Verification',
|
||||
autocomplete: 'off',
|
||||
spellcheck: false
|
||||
});
|
||||
this.nodes = {
|
||||
img: imgContainer.firstChild,
|
||||
input: input
|
||||
};
|
||||
$.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 = [];
|
||||
new MutationObserver(this.afterSetup).observe($.id('captchaContainer'), {
|
||||
childList: true
|
||||
});
|
||||
this.beforeSetup();
|
||||
if (Conf['Auto-load captcha']) {
|
||||
return this.setup();
|
||||
}
|
||||
},
|
||||
cb: {
|
||||
focus: function() {
|
||||
return QR.captcha.setup(false, true);
|
||||
}
|
||||
},
|
||||
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';
|
||||
return $.on(input, 'focus click', this.cb.focus);
|
||||
},
|
||||
needed: function() {
|
||||
var captchaCount, postsCount;
|
||||
captchaCount = this.captchas.length;
|
||||
if (QR.req) {
|
||||
captchaCount++;
|
||||
}
|
||||
postsCount = QR.posts.length;
|
||||
if (postsCount === 1 && !Conf['Auto-load captcha'] && !QR.posts[0].com && !QR.posts[0].file) {
|
||||
postsCount = 0;
|
||||
}
|
||||
return captchaCount < postsCount;
|
||||
},
|
||||
onNewPost: function() {},
|
||||
onPostChange: function() {},
|
||||
setup: function(focus, force) {
|
||||
if (!(this.isEnabled && (this.needed() || force))) {
|
||||
return;
|
||||
}
|
||||
$.globalEval('(function() {\n var captchaContainer = document.getElementById("captchaContainer");\n if (captchaContainer.firstChild) return;\n function setup() {\n if (window.Recaptcha) {\n Recaptcha.create(recaptchaKey, captchaContainer, {theme: "clean"});\n } else {\n setTimeout(setup, 25);\n }\n }\n setup();\n})()');
|
||||
if (focus) {
|
||||
return this.nodes.input.focus();
|
||||
}
|
||||
},
|
||||
afterSetup: function() {
|
||||
var challenge, img, input, ref, setLifetime;
|
||||
if (!(challenge = $.id('recaptcha_challenge_field_holder'))) {
|
||||
return;
|
||||
}
|
||||
if (challenge === QR.captcha.nodes.challenge) {
|
||||
return;
|
||||
}
|
||||
setLifetime = function(e) {
|
||||
return QR.captcha.lifetime = e.detail;
|
||||
};
|
||||
$.on(window, 'captcha:timeout', setLifetime);
|
||||
$.globalEval('window.dispatchEvent(new CustomEvent("captcha:timeout", {detail: RecaptchaState.timeout}))');
|
||||
$.off(window, 'captcha:timeout', setLifetime);
|
||||
ref = QR.captcha.nodes, img = ref.img, input = ref.input;
|
||||
img.parentNode.hidden = false;
|
||||
input.placeholder = 'Verification';
|
||||
$.off(input, 'focus click', QR.captcha.cb.focus);
|
||||
QR.captcha.nodes.challenge = challenge;
|
||||
new MutationObserver(QR.captcha.load.bind(QR.captcha)).observe(challenge, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
attributes: true
|
||||
});
|
||||
QR.captcha.load();
|
||||
if (QR.nodes.el.getBoundingClientRect().bottom > doc.clientHeight) {
|
||||
QR.nodes.el.style.top = null;
|
||||
return QR.nodes.el.style.bottom = '0px';
|
||||
}
|
||||
},
|
||||
destroy: function() {
|
||||
if (!this.isEnabled) {
|
||||
return;
|
||||
}
|
||||
$.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;
|
||||
}
|
||||
},
|
||||
load: function() {
|
||||
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 = challenge_image.src;
|
||||
return this.nodes.input.value = null;
|
||||
},
|
||||
reload: function(focus) {
|
||||
$.globalEval('Recaptcha.reload(); Recaptcha.should_focus = false;');
|
||||
if (focus) {
|
||||
return this.nodes.input.focus();
|
||||
}
|
||||
},
|
||||
keydown: function(e) {
|
||||
if (e.keyCode === 8 && !this.nodes.input.value) {
|
||||
this.reload();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
return e.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
Captcha.v2 = {
|
||||
lifetime: 2 * $.MINUTE,
|
||||
init: function() {
|
||||
@ -18279,6 +18452,7 @@
|
||||
"#qr > form {\n" +
|
||||
" max-height: calc(100vh - 75px);\n" +
|
||||
" overflow-y: auto;\n" +
|
||||
" overflow-x: hidden;\n" +
|
||||
"}\n" +
|
||||
"#qrtab {\n" +
|
||||
" border-radius: 3px 3px 0 0;\n" +
|
||||
@ -18351,7 +18525,20 @@
|
||||
" position: relative;\n" +
|
||||
" top: 2px;\n" +
|
||||
"}\n" +
|
||||
"/* Captcha */\n" +
|
||||
"/* Recaptcha v1 */\n" +
|
||||
".captcha-img {\n" +
|
||||
" margin: 0px;\n" +
|
||||
" text-align: center;\n" +
|
||||
" background-image: #fff;\n" +
|
||||
" font-size: 0px;\n" +
|
||||
" min-height: 59px;\n" +
|
||||
" min-width: 302px;\n" +
|
||||
"}\n" +
|
||||
".captcha-input{\n" +
|
||||
" width: 100%;\n" +
|
||||
" margin: 1px 0 0;\n" +
|
||||
"}\n" +
|
||||
"/* Recaptcha v2 */\n" +
|
||||
"#qr .captcha-root {\n" +
|
||||
" position: relative;\n" +
|
||||
"}\n" +
|
||||
|
||||
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.11.0.6
|
||||
// @version 1.11.0.7
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.11.0.6
|
||||
// @version 1.11.0.7
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -233,6 +233,7 @@
|
||||
'Hide Original Post Form': [true, 'Hide the normal post form.', 1],
|
||||
'Cooldown': [true, 'Indicate the remaining time before posting again.', 1],
|
||||
'Posting Success Notifications': [true, 'Show notifications on successful post creation or file uploading.', 1],
|
||||
'Use Recaptcha v1': [false, 'Use the old text version of Recaptcha.', 1],
|
||||
'Force Noscript Captcha': [false, 'Use the non-Javascript fallback captcha in the QR even if Javascript is enabled.', 1],
|
||||
'Auto-load captcha': [false, 'Automatically load the captcha in the QR even if your post is empty.', 1],
|
||||
'Post on Captcha Completion': [false, 'Submit the post immediately when the captcha is completed.', 1],
|
||||
@ -400,7 +401,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.11.0.6',
|
||||
VERSION: '1.11.0.7',
|
||||
NAMESPACE: '4chan X.',
|
||||
boards: {}
|
||||
};
|
||||
@ -6671,7 +6672,7 @@
|
||||
QR = {
|
||||
mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'application/vnd.adobe.flash.movie', 'application/x-shockwave-flash', 'video/webm'],
|
||||
init: function() {
|
||||
var sc;
|
||||
var sc, version;
|
||||
if (!Conf['Quick Reply']) {
|
||||
return;
|
||||
}
|
||||
@ -6680,7 +6681,8 @@
|
||||
if (g.VIEW === 'archive') {
|
||||
return;
|
||||
}
|
||||
this.captcha = Captcha.v2;
|
||||
version = Conf['Use Recaptcha v1'] ? 'v1' : 'v2';
|
||||
this.captcha = Captcha[version];
|
||||
$.on(d, '4chanXInitFinished', this.initReady);
|
||||
Post.callbacks.push({
|
||||
name: 'Quick Reply',
|
||||
@ -7456,7 +7458,12 @@
|
||||
};
|
||||
cb = function(response) {
|
||||
if (response != null) {
|
||||
extra.form.append('g-recaptcha-response', response);
|
||||
if (response.challenge != null) {
|
||||
extra.form.append('recaptcha_challenge_field', response.challenge);
|
||||
extra.form.append('recaptcha_response_field', response.response);
|
||||
} else {
|
||||
extra.form.append('g-recaptcha-response', response);
|
||||
}
|
||||
}
|
||||
QR.req = $.ajax("https://sys.4chan.org/" + g.BOARD + "/post", options, extra);
|
||||
return QR.req.progress = '...';
|
||||
@ -7790,6 +7797,172 @@
|
||||
}
|
||||
};
|
||||
|
||||
Captcha.v1 = {
|
||||
init: function() {
|
||||
var captchaContainer, imgContainer, input, script;
|
||||
if (d.cookie.indexOf('pass_enabled=1') >= 0) {
|
||||
return;
|
||||
}
|
||||
if (!(this.isEnabled = !!$.id('g-recaptcha'))) {
|
||||
return;
|
||||
}
|
||||
script = $.el('script', {
|
||||
src: '//www.google.com/recaptcha/api/js/recaptcha_ajax.js'
|
||||
});
|
||||
$.add(d.head, script);
|
||||
captchaContainer = $.el('div', {
|
||||
id: 'captchaContainer',
|
||||
hidden: true
|
||||
});
|
||||
$.add(d.body, captchaContainer);
|
||||
imgContainer = $.el('div', {
|
||||
className: 'captcha-img',
|
||||
title: 'Reload reCAPTCHA'
|
||||
});
|
||||
$.extend(imgContainer, {
|
||||
innerHTML: "<img>"
|
||||
});
|
||||
input = $.el('input', {
|
||||
className: 'captcha-input field',
|
||||
title: 'Verification',
|
||||
autocomplete: 'off',
|
||||
spellcheck: false
|
||||
});
|
||||
this.nodes = {
|
||||
img: imgContainer.firstChild,
|
||||
input: input
|
||||
};
|
||||
$.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 = [];
|
||||
new MutationObserver(this.afterSetup).observe($.id('captchaContainer'), {
|
||||
childList: true
|
||||
});
|
||||
this.beforeSetup();
|
||||
if (Conf['Auto-load captcha']) {
|
||||
return this.setup();
|
||||
}
|
||||
},
|
||||
cb: {
|
||||
focus: function() {
|
||||
return QR.captcha.setup(false, true);
|
||||
}
|
||||
},
|
||||
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';
|
||||
return $.on(input, 'focus click', this.cb.focus);
|
||||
},
|
||||
needed: function() {
|
||||
var captchaCount, postsCount;
|
||||
captchaCount = this.captchas.length;
|
||||
if (QR.req) {
|
||||
captchaCount++;
|
||||
}
|
||||
postsCount = QR.posts.length;
|
||||
if (postsCount === 1 && !Conf['Auto-load captcha'] && !QR.posts[0].com && !QR.posts[0].file) {
|
||||
postsCount = 0;
|
||||
}
|
||||
return captchaCount < postsCount;
|
||||
},
|
||||
onNewPost: function() {},
|
||||
onPostChange: function() {},
|
||||
setup: function(focus, force) {
|
||||
if (!(this.isEnabled && (this.needed() || force))) {
|
||||
return;
|
||||
}
|
||||
$.globalEval('(function() {\n var captchaContainer = document.getElementById("captchaContainer");\n if (captchaContainer.firstChild) return;\n function setup() {\n if (window.Recaptcha) {\n Recaptcha.create(recaptchaKey, captchaContainer, {theme: "clean"});\n } else {\n setTimeout(setup, 25);\n }\n }\n setup();\n})()');
|
||||
if (focus) {
|
||||
return this.nodes.input.focus();
|
||||
}
|
||||
},
|
||||
afterSetup: function() {
|
||||
var challenge, img, input, ref, setLifetime;
|
||||
if (!(challenge = $.id('recaptcha_challenge_field_holder'))) {
|
||||
return;
|
||||
}
|
||||
if (challenge === QR.captcha.nodes.challenge) {
|
||||
return;
|
||||
}
|
||||
setLifetime = function(e) {
|
||||
return QR.captcha.lifetime = e.detail;
|
||||
};
|
||||
$.on(window, 'captcha:timeout', setLifetime);
|
||||
$.globalEval('window.dispatchEvent(new CustomEvent("captcha:timeout", {detail: RecaptchaState.timeout}))');
|
||||
$.off(window, 'captcha:timeout', setLifetime);
|
||||
ref = QR.captcha.nodes, img = ref.img, input = ref.input;
|
||||
img.parentNode.hidden = false;
|
||||
input.placeholder = 'Verification';
|
||||
$.off(input, 'focus click', QR.captcha.cb.focus);
|
||||
QR.captcha.nodes.challenge = challenge;
|
||||
new MutationObserver(QR.captcha.load.bind(QR.captcha)).observe(challenge, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
attributes: true
|
||||
});
|
||||
QR.captcha.load();
|
||||
if (QR.nodes.el.getBoundingClientRect().bottom > doc.clientHeight) {
|
||||
QR.nodes.el.style.top = null;
|
||||
return QR.nodes.el.style.bottom = '0px';
|
||||
}
|
||||
},
|
||||
destroy: function() {
|
||||
if (!this.isEnabled) {
|
||||
return;
|
||||
}
|
||||
$.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;
|
||||
}
|
||||
},
|
||||
load: function() {
|
||||
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 = challenge_image.src;
|
||||
return this.nodes.input.value = null;
|
||||
},
|
||||
reload: function(focus) {
|
||||
$.globalEval('Recaptcha.reload(); Recaptcha.should_focus = false;');
|
||||
if (focus) {
|
||||
return this.nodes.input.focus();
|
||||
}
|
||||
},
|
||||
keydown: function(e) {
|
||||
if (e.keyCode === 8 && !this.nodes.input.value) {
|
||||
this.reload();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
return e.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
Captcha.v2 = {
|
||||
lifetime: 2 * $.MINUTE,
|
||||
init: function() {
|
||||
@ -18280,6 +18453,7 @@
|
||||
"#qr > form {\n" +
|
||||
" max-height: calc(100vh - 75px);\n" +
|
||||
" overflow-y: auto;\n" +
|
||||
" overflow-x: hidden;\n" +
|
||||
"}\n" +
|
||||
"#qrtab {\n" +
|
||||
" border-radius: 3px 3px 0 0;\n" +
|
||||
@ -18352,7 +18526,20 @@
|
||||
" position: relative;\n" +
|
||||
" top: 2px;\n" +
|
||||
"}\n" +
|
||||
"/* Captcha */\n" +
|
||||
"/* Recaptcha v1 */\n" +
|
||||
".captcha-img {\n" +
|
||||
" margin: 0px;\n" +
|
||||
" text-align: center;\n" +
|
||||
" background-image: #fff;\n" +
|
||||
" font-size: 0px;\n" +
|
||||
" min-height: 59px;\n" +
|
||||
" min-width: 302px;\n" +
|
||||
"}\n" +
|
||||
".captcha-input{\n" +
|
||||
" width: 100%;\n" +
|
||||
" margin: 1px 0 0;\n" +
|
||||
"}\n" +
|
||||
"/* Recaptcha v2 */\n" +
|
||||
"#qr .captcha-root {\n" +
|
||||
" position: relative;\n" +
|
||||
"}\n" +
|
||||
|
||||
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
||||
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X-beta.crx' version='1.11.0.6' />
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X-beta.crx' version='1.11.0.7' />
|
||||
</app>
|
||||
</gupdate>
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
|
||||
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X.crx' version='1.11.0.6' />
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X.crx' version='1.11.0.7' />
|
||||
</app>
|
||||
</gupdate>
|
||||
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
||||
"meta": {
|
||||
"name": "4chan X",
|
||||
"version": "1.11.0.6",
|
||||
"date": "2015-06-21T06:05:51.745Z",
|
||||
"version": "1.11.0.7",
|
||||
"date": "2015-06-21T17:20:52.716Z",
|
||||
"repo": "https://github.com/ccd0/4chan-x/",
|
||||
"page": "https://github.com/ccd0/4chan-x",
|
||||
"downloads": "https://ccd0.github.io/4chan-x/builds/",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user