diff --git a/CHANGELOG.md b/CHANGELOG.md index fae924fc8..8723af655 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ Sometimes the changelog has notes (not comprehensive) acknowledging people's work. This does not mean the changes are their fault, only that their code was used. All changes to the script are chosen by and the fault of the maintainer (ccd0). +### v1.11.18 + +**v1.11.18.0** *(2015-11-21)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.18.0/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.18.0/builds/4chan-X-noupdate.crx "Chromium version")] +- Based on v1.11.17.8. +- The `Force Noscript Captcha` option now works on the original post form, report form, /banned, and /feedback. For consistency, `Force Noscript Captcha` now overrides `Use Recaptcha v1`. +- 4chan X will now automatically copy all the codes Recaptcha sometimes asks you to copy and paste. This is included as part of `Captcha Fixes`. +- Other captcha-related fixes/improvements. +- The link to open the original post form is now shown beneath the Quick Reply button in a smaller font. The `Hide Original Post Form` option has been removed. If you want to hide even the small link to the original post form, you can add `#togglePostFormLink {display: none;}` to your custom CSS. + ### v1.11.17 **v1.11.17.8** *(2015-11-20)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.17.8/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.17.8/builds/4chan-X-noupdate.crx "Chromium version")] diff --git a/builds/4chan-X-beta.crx b/builds/4chan-X-beta.crx index c559e7884..4f93d61de 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 3006345e5..124b37442 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.17.8 +// @version 1.11.18.0 // @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 62f3827b8..c29ff70c7 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.17.8 +// @version 1.11.18.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -239,16 +239,15 @@ 'Randomize Filename': [false, 'Set the filename to a random timestamp within the past year. Disabled on /f/.', 1], 'Show New Thread Option in Threads': [false, 'Show the option to post a new / different thread from inside a thread.', 1], 'Show Name and Subject': [false, 'Show the classic name, email, and subject fields in the QR, even when 4chan doesn\'t use them all.', 1], - '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], - 'Force Noscript Captcha': [false, 'Use the non-Javascript fallback captcha in the QR even if Javascript is enabled (Recaptcha v2 only).', 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], 'Bottom QR Link': [true, 'Places a link on the bottom of threads to open the QR.', 1], 'Captcha Fixes': [true, 'Make captcha easier to use, especially with the keyboard.'], 'Use Recaptcha v1': [false, 'Use the old text version of Recaptcha.'], 'Use Recaptcha v2 in Reports': [false, 'Use the image selection captcha in the report window.'], + 'Force Noscript Captcha': [false, 'Use the non-Javascript fallback captcha even if Javascript is enabled (Recaptcha v2 only).'], 'Pass Link': [true, 'Add a 4chan Pass login link to the bottom of the page.'] }, 'Quote Links': { @@ -433,7 +432,7 @@ doc = d.documentElement; g = { - VERSION: '1.11.17.8', + VERSION: '1.11.18.0', NAMESPACE: '4chan X.', boards: {} }; @@ -6965,7 +6964,7 @@ if (g.VIEW === 'archive') { return; } - version = Conf['Use Recaptcha v1'] ? 'v1' : 'v2'; + version = Conf['Use Recaptcha v1'] && !Conf['Force Noscript Captcha'] && Main.jsEnabled ? 'v1' : 'v2'; this.captcha = Captcha[version]; $.on(d, '4chanXInitFinished', this.initReady); Post.callbacks.push({ @@ -6990,17 +6989,11 @@ return QR.close(); } }); - Header.addShortcut(sc); - } - if (Conf['Hide Original Post Form']) { - $.addClass(doc, 'hide-original-post-form'); - if (!$.hasClass(doc, 'js-enabled')) { - return $.onExists(doc, '#postForm noscript', true, $.rm); - } + return Header.addShortcut(sc); } }, initReady: function() { - var link, linkBot; + var link, linkBot, origToggle; $.off(d, '4chanXInitFinished', this.initReady); QR.postingIsEnabled = !!$.id('postForm'); if (!QR.postingIsEnabled) { @@ -7030,7 +7023,9 @@ }); $.prepend($('.navLinksBot'), linkBot); } - $.before($.id('togglePostFormLink'), link); + origToggle = $.id('togglePostFormLink'); + $.before(origToggle, link); + origToggle.firstElementChild.textContent = 'Original Form'; $.on(d, 'QRGetFile', QR.getFile); $.on(d, 'QRSetFile', QR.setFile); $.on(d, 'paste', QR.paste); @@ -7956,7 +7951,7 @@ Captcha.fixes = { imageKeys: '789456123uiojklm'.split('').concat(['Comma', 'Period']), css: '.rc-imageselect-target > div:focus {\n outline: 2px solid #4a90e2;\n}\n.rc-imageselect-target td:focus {\n box-shadow: inset 0 0 0 2px #4a90e2;\n outline: none;\n}\n.rc-button-default:focus {\n box-shadow: inset 0 0 0 2px #0063d6;\n}', - cssNoscript: '.fbc-payload-imageselect {\n position: relative;\n}\n.fbc-payload-imageselect > label {\n position: absolute;\n display: block;\n height: 93.3px;\n width: 93.3px;\n}\nlabel[data-row="0"] {top: 0px;}\nlabel[data-row="1"] {top: 93.3px;}\nlabel[data-row="2"] {top: 186.6px;}\nlabel[data-col="0"] {left: 0px;}\nlabel[data-col="1"] {left: 93.3px;}\nlabel[data-col="2"] {left: 186.6px;}', + cssNoscript: '.fbc-payload-imageselect {\n position: relative;\n}\n.fbc-payload-imageselect > label {\n position: absolute;\n display: block;\n height: 93.3px;\n width: 93.3px;\n}\nlabel[data-row="0"] {top: 0px;}\nlabel[data-row="1"] {top: 93.3px;}\nlabel[data-row="2"] {top: 186.6px;}\nlabel[data-col="0"] {left: 0px;}\nlabel[data-col="1"] {left: 93.3px;}\nlabel[data-col="2"] {left: 186.6px;}\n.fbc-payload-imageselect > input:focus + label {\n outline: 2px solid #4a90e2;\n}\n.fbc-button-verify input:focus {\n box-shadow: inset 0 0 0 2px #0063d6;\n}\nbody.focus .fbc {\n box-shadow: inset 0 0 0 2px #4a90e2;\n}', init: function() { switch (location.pathname.split('/')[3]) { case 'anchor': @@ -7995,7 +7990,18 @@ return $.on(d, 'keydown', this.keybinds.bind(this)); }, initNoscript: function() { + var data, ref, token; this.noscript = true; + data = (token = (ref = $('.fbc-verification-token > textarea')) != null ? ref.value : void 0) ? { + token: token + } : { + working: true + }; + new Connection(window.parent, '*').send(data); + d.body.classList.toggle('focus', d.hasFocus()); + $.on(window, 'focus blur', function() { + return d.body.classList.toggle('focus', d.hasFocus()); + }); this.images = $$('.fbc-payload-imageselect > input'); if (this.images.length !== 9) { return; @@ -8048,11 +8054,11 @@ }); label.dataset.row = Math.floor(i / 3); label.dataset.col = i % 3; + $.after(checkbox, label); results.push(label); } return results; }).call(this); - $.add(imageSelect, labels); return this.addTooltips(labels); }, addTooltips: function(nodes) { @@ -8117,23 +8123,22 @@ Captcha.replace = { init: function() { - var jsEnabled; if (!(d.cookie.indexOf('pass_enabled=1') < 0)) { return; } - if (location.hostname === 'boards.4chan.org' && Conf['Hide Original Post Form']) { + if (Conf['Force Noscript Captcha'] && Main.jsEnabled) { + $.ready(Captcha.replace.noscript); return; } - jsEnabled = $.hasClass(doc, 'js-enabled'); - if (location.hostname === 'sys.4chan.org' && Conf['Use Recaptcha v2 in Reports'] && jsEnabled) { + if (location.hostname === 'sys.4chan.org' && Conf['Use Recaptcha v2 in Reports'] && Main.jsEnabled) { $.ready(Captcha.replace.v2); return; } - if (Conf['Use Recaptcha v1'] && jsEnabled && location.hostname !== 'www.4chan.org') { + if (Conf['Use Recaptcha v1'] && Main.jsEnabled && location.hostname !== 'www.4chan.org') { $.ready(Captcha.replace.v1); return; } - if (Conf['captchaLanguage'].trim()) { + if (Conf['captchaLanguage'].trim() || Conf['Captcha Fixes']) { if (location.hostname === 'boards.4chan.org') { return $.onExists(doc, '#captchaFormPart', true, function(node) { return $.onExists(node, 'iframe', true, Captcha.replace.iframe); @@ -8143,13 +8148,33 @@ } } }, + noscript: function() { + var insert, noscript, original, span, toggle; + if (!((original = $('#g-recaptcha, #captchaContainerAlt')) && (noscript = $('noscript')))) { + return; + } + span = $.el('span', { + id: 'captcha-forced-noscript' + }); + $.replace(noscript, span); + $.rm(original); + insert = function() { + span.innerHTML = noscript.textContent; + return Captcha.replace.iframe($('iframe', span)); + }; + if ((toggle = $('#togglePostFormLink a, #form-link'))) { + return $.on(toggle, 'click', insert); + } else { + return insert(); + } + }, v1: function() { var form, link; if (!$.id('g-recaptcha')) { return; } Captcha.v1.replace(); - if (link = $.id('form-link')) { + if ((link = $.id('form-link'))) { return $.on(link, 'click', function() { return Captcha.v1.create(); }); @@ -8176,23 +8201,48 @@ }); $.replace(old, container); url = 'https://www.google.com/recaptcha/api.js'; - if (lang = Conf['captchaLanguage'].trim()) { + if ((lang = Conf['captchaLanguage'].trim())) { url += "?hl=" + (encodeURIComponent(lang)); } script = $.el('script', { src: url }); - return $.add(d.head, script); + $.add(d.head, script); + return $.onExists(d.body, 'iframe', true, Captcha.replace.autocopy); }, - iframe: function(el) { + iframe: function(iframe) { var lang, src; - if (!(lang = Conf['captchaLanguage'].trim())) { + if ((lang = Conf['captchaLanguage'].trim())) { + src = /[?&]hl=/.test(iframe.src) ? iframe.src.replace(/([?&]hl=)[^&]*/, '$1' + encodeURIComponent(lang)) : iframe.src + ("&hl=" + (encodeURIComponent(lang))); + if (iframe.src !== src) { + iframe.src = src; + } + } + return Captcha.replace.autocopy(iframe); + }, + autocopy: function(iframe) { + if (!(Conf['Captcha Fixes'] && /^https:\/\/www\.google\.com\/recaptcha\/api\/fallback\?/.test(iframe.src))) { return; } - src = /[?&]hl=/.test(el.src) ? el.src.replace(/([?&]hl=)[^&]*/, '$1' + encodeURIComponent(lang)) : el.src + ("&hl=" + (encodeURIComponent(lang))); - if (el.src !== src) { - return el.src = src; - } + return new Connection(iframe, 'https://www.google.com', { + working: function() { + var ref, ref1; + if ((ref = $.id('qr')) != null ? ref.contains(iframe) : void 0) { + return (ref1 = $('#qr .captcha-container textarea')) != null ? ref1.parentNode.hidden = true : void 0; + } + }, + token: function(token) { + var node, textarea; + node = iframe; + while ((node = node.parentNode)) { + if ((textarea = $('textarea', node))) { + break; + } + } + textarea.value = token; + return $.event('input', null, textarea); + } + }); } }; @@ -8485,17 +8535,10 @@ if (d.cookie.indexOf('pass_enabled=1') >= 0) { return; } - if (!(this.isEnabled = !!$('#g-recaptcha, #captchaContainerAlt'))) { + if (!(this.isEnabled = !!$('#g-recaptcha, #captchaContainerAlt, #captcha-forced-noscript'))) { return; } - if (this.noscript = Conf['Force Noscript Captcha'] || !$.hasClass(doc, 'js-enabled')) { - this.conn = new Connection(null, location.protocol + "//www.google.com", { - token: (function(_this) { - return function(token) { - return _this.save(true, token); - }; - })(this) - }); + if ((this.noscript = Conf['Force Noscript Captcha'] || !Main.jsEnabled)) { $.addClass(QR.nodes.el, 'noscript-captcha'); } this.captchas = []; @@ -8541,21 +8584,12 @@ childList: true }); }, - initFrame: function() { - var conn, ref, token; - if (token = (ref = $('.fbc-verification-token > textarea')) != null ? ref.value : void 0) { - conn = new Connection(window.parent, location.protocol + "//boards.4chan.org"); - return conn.send({ - token: token - }); - } - }, timeouts: {}, postsCount: 0, noscriptURL: function() { var lang, url; - url = '//www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc'; - if (lang = Conf['captchaLanguage'].trim()) { + url = 'https://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc'; + if ((lang = Conf['captchaLanguage'].trim())) { url += "&hl=" + (encodeURIComponent(lang)); } return url; @@ -8591,7 +8625,6 @@ } }, setup: function(focus, force) { - var iframe; if (!(this.isEnabled && (this.needed() || force))) { return; } @@ -8604,10 +8637,15 @@ return this.reload(); } if (this.nodes.container) { - if (d.activeElement === this.nodes.counter && (iframe = $('iframe', this.nodes.container))) { - iframe.focus(); - QR.focus(); - } + $.queueTask((function(_this) { + return function() { + var iframe; + if (_this.nodes.container && d.activeElement === _this.nodes.counter && (iframe = $('iframe', _this.nodes.container))) { + iframe.focus(); + return QR.focus(); + } + }; + })(this)); return; } this.nodes.container = $.el('div', { @@ -8625,13 +8663,15 @@ } }, setupNoscript: function() { - var iframe; + var div, iframe, textarea; iframe = $.el('iframe', { id: 'qr-captcha-iframe', src: this.noscriptURL() }); - $.add(this.nodes.container, iframe); - return this.conn.target = iframe; + div = $.el('div'); + textarea = $.el('textarea'); + $.add(div, textarea); + return $.add(this.nodes.container, [iframe, div]); }, setupJS: function() { return $.globalEval('(function() {\n function render() {\n var container = document.querySelector("#qr .captcha-container");\n container.dataset.widgetID = window.grecaptcha.render(container, {\n sitekey: \'6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc\',\n theme: document.documentElement.classList.contains(\'tomorrow\') ? \'dark\' : \'light\',\n callback: function(response) {\n window.dispatchEvent(new CustomEvent("captcha:success", {detail: response}));\n }\n });\n }\n if (window.grecaptcha) {\n render();\n } else {\n var cbNative = window.onRecaptchaLoaded;\n window.onRecaptchaLoaded = function() {\n render();\n cbNative();\n }\n }\n})();'); @@ -8643,10 +8683,10 @@ ref = mutation.addedNodes; for (q = 0, len2 = ref.length; q < len2; q++) { node = ref[q]; - if (iframe = $.x('./descendant-or-self::iframe', node)) { + if ((iframe = $.x('./descendant-or-self::iframe', node))) { this.setupIFrame(iframe); } - if (textarea = $.x('./descendant-or-self::textarea', node)) { + if ((textarea = $.x('./descendant-or-self::textarea', node))) { this.setupTextArea(textarea); } } @@ -8706,7 +8746,7 @@ getOne: function() { var captcha; this.clear(); - if (captcha = this.captchas.shift()) { + if ((captcha = this.captchas.shift())) { $.set('captchas', this.captchas); this.count(); return captcha; @@ -8782,9 +8822,7 @@ } }, reload: function() { - if (this.noscript) { - return $('iframe', this.nodes.container).src = this.noscriptURL(); - } else if ($('iframe[src^="https://www.google.com/recaptcha/api/fallback?"]', this.nodes.container)) { + if ($('iframe[src^="https://www.google.com/recaptcha/api/fallback?"]', this.nodes.container)) { this.destroy(); return this.setup(false, true); } else { @@ -8806,7 +8844,7 @@ new MutationObserver(this.fixBubble.bind(this, node)).observe(node, { attributes: true }); - if (overlay = $('div[style*="position: fixed;"]', node)) { + if ((overlay = $('div[style*="position: fixed;"]', node))) { results1.push($.on(overlay, 'click', function() { var ref1; return (ref1 = $('#qr iframe')) != null ? ref1.blur() : void 0; @@ -16478,7 +16516,7 @@ }) ]); } - if (Conf['Use Recaptcha v2 in Reports'] && $.hasClass(doc, 'js-enabled')) { + if (Conf['Use Recaptcha v2 in Reports'] && !Conf['Force Noscript Captcha'] && Main.jsEnabled) { new MutationObserver(function() { Report.fit('iframe[src^="https://www.google.com/recaptcha/api2/frame"]'); return Report.fit('body'); @@ -16490,7 +16528,7 @@ } else { Report.fit('body'); } - if (!Conf['Use Recaptcha v2 in Reports'] && $.hasClass(doc, 'js-enabled') && d.cookie.indexOf('pass_enabled=1') < 0) { + if (!Conf['Use Recaptcha v2 in Reports'] && Main.jsEnabled && d.cookie.indexOf('pass_enabled=1') < 0) { $.onExists(d.body, '#recaptcha_image', true, function(image) { $.global(function() { return document.getElementById('recaptcha_image').removeEventListener('click', window.onAltCaptchaClick, false); @@ -17488,11 +17526,6 @@ } window['4chan X antidup'] = true; if (location.hostname === 'www.google.com') { - if (location.pathname === '/recaptcha/api/fallback') { - $.ready(function() { - return Captcha.v2.initFrame(); - }); - } $.get('Captcha Fixes', true, function(arg) { var enabled; enabled = arg['Captcha Fixes']; @@ -17586,6 +17619,7 @@ document.documentElement.classList.add('js-enabled'); return window.FCX = {}; }); + Main.jsEnabled = $.hasClass(doc, 'js-enabled'); } switch (hostname) { case 'www.4chan.org': @@ -19748,6 +19782,7 @@ "}\n" + ".qr-link-container {\n" + " text-align: center;\n" + +" margin: 16px 0;\n" + "}\n" + ".qr-link-container-bottom {\n" + " width: 200px;\n" + @@ -19765,6 +19800,11 @@ " border-width: 1px;\n" + " font-size: 10pt;\n" + "}\n" + +".qr-link-container + #togglePostFormLink {\n" + +" font-size: 10pt;\n" + +" font-weight: normal;\n" + +" margin: -8px 0 3.5px;\n" + +"}\n" + ".persona {\n" + " width: 100%;\n" + " display: -webkit-flex;\n" + @@ -21090,7 +21130,7 @@ cssWWW: "#captcha-cnt {\n" + " height: auto;\n" + "}", - features: [['Polyfill', Polyfill], ['Normalize URL', NormalizeURL], ['Captcha Replacement', Captcha.replace], ['Redirect', Redirect], ['Header', Header], ['Catalog Links', CatalogLinks], ['Settings', Settings], ['Index Generator', Index], ['Disable Autoplay', AntiAutoplay], ['Announcement Hiding', PSAHiding], ['Fourchan thingies', Fourchan], ['Color User IDs', IDColor], ['Highlight by User ID', IDHighlight], ['Custom CSS', CustomCSS], ['Thread Links', ThreadLinks], ['Linkify', Linkify], ['Reveal Spoilers', RemoveSpoilers], ['Resurrect Quotes', Quotify], ['Filter', Filter], ['Thread Hiding Buttons', ThreadHiding], ['Reply Hiding Buttons', PostHiding], ['Recursive', Recursive], ['Strike-through Quotes', QuoteStrikeThrough], ['Quick Reply', QR], ['Cooldown', QR.cooldown], ['Oekaki Links', QR.oekaki], ['Pass Link', PassLink], ['Menu', Menu], ['Index Generator (Menu)', Index.menu], ['Report Link', ReportLink], ['Thread Hiding (Menu)', ThreadHiding.menu], ['Reply Hiding (Menu)', PostHiding.menu], ['Delete Link', DeleteLink], ['Filter (Menu)', Filter.menu], ['Download Link', DownloadLink], ['Archive Link', ArchiveLink], ['Quote Inlining', QuoteInline], ['Quote Previewing', QuotePreview], ['Quote Backlinks', QuoteBacklink], ['Mark Quotes of You', QuoteYou], ['Mark OP Quotes', QuoteOP], ['Mark Cross-thread Quotes', QuoteCT], ['Anonymize', Anonymize], ['Time Formatting', Time], ['Relative Post Dates', RelativeDates], ['File Info Formatting', FileInfo], ['Fappe Tyme', FappeTyme], ['Gallery', Gallery], ['Gallery (menu)', Gallery.menu], ['Sauce', Sauce], ['Image Expansion', ImageExpand], ['Image Expansion (Menu)', ImageExpand.menu], ['Reveal Spoiler Thumbnails', RevealSpoilers], ['Image Loading', ImageLoader], ['Image Hover', ImageHover], ['Volume Control', Volume], ['WEBM Metadata', Metadata], ['Comment Expansion', ExpandComment], ['Thread Expansion', ExpandThread], ['Thread Excerpt', ThreadExcerpt], ['Favicon', Favicon], ['Unread', Unread], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats], ['Thread Updater', ThreadUpdater], ['Thread Watcher', ThreadWatcher], ['Thread Watcher (Menu)', ThreadWatcher.menu], ['Mark New IPs', MarkNewIPs], ['Index Navigation', Nav], ['Keybinds', Keybinds], ['Banner', Banner], ['Flash Features', Flash]] + features: [['Polyfill', Polyfill], ['Normalize URL', NormalizeURL], ['Captcha Configuration', Captcha.replace], ['Redirect', Redirect], ['Header', Header], ['Catalog Links', CatalogLinks], ['Settings', Settings], ['Index Generator', Index], ['Disable Autoplay', AntiAutoplay], ['Announcement Hiding', PSAHiding], ['Fourchan thingies', Fourchan], ['Color User IDs', IDColor], ['Highlight by User ID', IDHighlight], ['Custom CSS', CustomCSS], ['Thread Links', ThreadLinks], ['Linkify', Linkify], ['Reveal Spoilers', RemoveSpoilers], ['Resurrect Quotes', Quotify], ['Filter', Filter], ['Thread Hiding Buttons', ThreadHiding], ['Reply Hiding Buttons', PostHiding], ['Recursive', Recursive], ['Strike-through Quotes', QuoteStrikeThrough], ['Quick Reply', QR], ['Cooldown', QR.cooldown], ['Oekaki Links', QR.oekaki], ['Pass Link', PassLink], ['Menu', Menu], ['Index Generator (Menu)', Index.menu], ['Report Link', ReportLink], ['Thread Hiding (Menu)', ThreadHiding.menu], ['Reply Hiding (Menu)', PostHiding.menu], ['Delete Link', DeleteLink], ['Filter (Menu)', Filter.menu], ['Download Link', DownloadLink], ['Archive Link', ArchiveLink], ['Quote Inlining', QuoteInline], ['Quote Previewing', QuotePreview], ['Quote Backlinks', QuoteBacklink], ['Mark Quotes of You', QuoteYou], ['Mark OP Quotes', QuoteOP], ['Mark Cross-thread Quotes', QuoteCT], ['Anonymize', Anonymize], ['Time Formatting', Time], ['Relative Post Dates', RelativeDates], ['File Info Formatting', FileInfo], ['Fappe Tyme', FappeTyme], ['Gallery', Gallery], ['Gallery (menu)', Gallery.menu], ['Sauce', Sauce], ['Image Expansion', ImageExpand], ['Image Expansion (Menu)', ImageExpand.menu], ['Reveal Spoiler Thumbnails', RevealSpoilers], ['Image Loading', ImageLoader], ['Image Hover', ImageHover], ['Volume Control', Volume], ['WEBM Metadata', Metadata], ['Comment Expansion', ExpandComment], ['Thread Expansion', ExpandThread], ['Thread Excerpt', ThreadExcerpt], ['Favicon', Favicon], ['Unread', Unread], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats], ['Thread Updater', ThreadUpdater], ['Thread Watcher', ThreadWatcher], ['Thread Watcher (Menu)', ThreadWatcher.menu], ['Mark New IPs', MarkNewIPs], ['Index Navigation', Nav], ['Keybinds', Keybinds], ['Banner', Banner], ['Flash Features', Flash]] }; Main.init(); diff --git a/builds/4chan-X-noupdate.crx b/builds/4chan-X-noupdate.crx index 9765986b5..1c1179936 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 570728297..c0474f240 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.17.8 +// @version 1.11.18.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -239,16 +239,15 @@ 'Randomize Filename': [false, 'Set the filename to a random timestamp within the past year. Disabled on /f/.', 1], 'Show New Thread Option in Threads': [false, 'Show the option to post a new / different thread from inside a thread.', 1], 'Show Name and Subject': [false, 'Show the classic name, email, and subject fields in the QR, even when 4chan doesn\'t use them all.', 1], - '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], - 'Force Noscript Captcha': [false, 'Use the non-Javascript fallback captcha in the QR even if Javascript is enabled (Recaptcha v2 only).', 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], 'Bottom QR Link': [true, 'Places a link on the bottom of threads to open the QR.', 1], 'Captcha Fixes': [true, 'Make captcha easier to use, especially with the keyboard.'], 'Use Recaptcha v1': [false, 'Use the old text version of Recaptcha.'], 'Use Recaptcha v2 in Reports': [false, 'Use the image selection captcha in the report window.'], + 'Force Noscript Captcha': [false, 'Use the non-Javascript fallback captcha even if Javascript is enabled (Recaptcha v2 only).'], 'Pass Link': [true, 'Add a 4chan Pass login link to the bottom of the page.'] }, 'Quote Links': { @@ -433,7 +432,7 @@ doc = d.documentElement; g = { - VERSION: '1.11.17.8', + VERSION: '1.11.18.0', NAMESPACE: '4chan X.', boards: {} }; @@ -6965,7 +6964,7 @@ if (g.VIEW === 'archive') { return; } - version = Conf['Use Recaptcha v1'] ? 'v1' : 'v2'; + version = Conf['Use Recaptcha v1'] && !Conf['Force Noscript Captcha'] && Main.jsEnabled ? 'v1' : 'v2'; this.captcha = Captcha[version]; $.on(d, '4chanXInitFinished', this.initReady); Post.callbacks.push({ @@ -6990,17 +6989,11 @@ return QR.close(); } }); - Header.addShortcut(sc); - } - if (Conf['Hide Original Post Form']) { - $.addClass(doc, 'hide-original-post-form'); - if (!$.hasClass(doc, 'js-enabled')) { - return $.onExists(doc, '#postForm noscript', true, $.rm); - } + return Header.addShortcut(sc); } }, initReady: function() { - var link, linkBot; + var link, linkBot, origToggle; $.off(d, '4chanXInitFinished', this.initReady); QR.postingIsEnabled = !!$.id('postForm'); if (!QR.postingIsEnabled) { @@ -7030,7 +7023,9 @@ }); $.prepend($('.navLinksBot'), linkBot); } - $.before($.id('togglePostFormLink'), link); + origToggle = $.id('togglePostFormLink'); + $.before(origToggle, link); + origToggle.firstElementChild.textContent = 'Original Form'; $.on(d, 'QRGetFile', QR.getFile); $.on(d, 'QRSetFile', QR.setFile); $.on(d, 'paste', QR.paste); @@ -7956,7 +7951,7 @@ Captcha.fixes = { imageKeys: '789456123uiojklm'.split('').concat(['Comma', 'Period']), css: '.rc-imageselect-target > div:focus {\n outline: 2px solid #4a90e2;\n}\n.rc-imageselect-target td:focus {\n box-shadow: inset 0 0 0 2px #4a90e2;\n outline: none;\n}\n.rc-button-default:focus {\n box-shadow: inset 0 0 0 2px #0063d6;\n}', - cssNoscript: '.fbc-payload-imageselect {\n position: relative;\n}\n.fbc-payload-imageselect > label {\n position: absolute;\n display: block;\n height: 93.3px;\n width: 93.3px;\n}\nlabel[data-row="0"] {top: 0px;}\nlabel[data-row="1"] {top: 93.3px;}\nlabel[data-row="2"] {top: 186.6px;}\nlabel[data-col="0"] {left: 0px;}\nlabel[data-col="1"] {left: 93.3px;}\nlabel[data-col="2"] {left: 186.6px;}', + cssNoscript: '.fbc-payload-imageselect {\n position: relative;\n}\n.fbc-payload-imageselect > label {\n position: absolute;\n display: block;\n height: 93.3px;\n width: 93.3px;\n}\nlabel[data-row="0"] {top: 0px;}\nlabel[data-row="1"] {top: 93.3px;}\nlabel[data-row="2"] {top: 186.6px;}\nlabel[data-col="0"] {left: 0px;}\nlabel[data-col="1"] {left: 93.3px;}\nlabel[data-col="2"] {left: 186.6px;}\n.fbc-payload-imageselect > input:focus + label {\n outline: 2px solid #4a90e2;\n}\n.fbc-button-verify input:focus {\n box-shadow: inset 0 0 0 2px #0063d6;\n}\nbody.focus .fbc {\n box-shadow: inset 0 0 0 2px #4a90e2;\n}', init: function() { switch (location.pathname.split('/')[3]) { case 'anchor': @@ -7995,7 +7990,18 @@ return $.on(d, 'keydown', this.keybinds.bind(this)); }, initNoscript: function() { + var data, ref, token; this.noscript = true; + data = (token = (ref = $('.fbc-verification-token > textarea')) != null ? ref.value : void 0) ? { + token: token + } : { + working: true + }; + new Connection(window.parent, '*').send(data); + d.body.classList.toggle('focus', d.hasFocus()); + $.on(window, 'focus blur', function() { + return d.body.classList.toggle('focus', d.hasFocus()); + }); this.images = $$('.fbc-payload-imageselect > input'); if (this.images.length !== 9) { return; @@ -8048,11 +8054,11 @@ }); label.dataset.row = Math.floor(i / 3); label.dataset.col = i % 3; + $.after(checkbox, label); results.push(label); } return results; }).call(this); - $.add(imageSelect, labels); return this.addTooltips(labels); }, addTooltips: function(nodes) { @@ -8117,23 +8123,22 @@ Captcha.replace = { init: function() { - var jsEnabled; if (!(d.cookie.indexOf('pass_enabled=1') < 0)) { return; } - if (location.hostname === 'boards.4chan.org' && Conf['Hide Original Post Form']) { + if (Conf['Force Noscript Captcha'] && Main.jsEnabled) { + $.ready(Captcha.replace.noscript); return; } - jsEnabled = $.hasClass(doc, 'js-enabled'); - if (location.hostname === 'sys.4chan.org' && Conf['Use Recaptcha v2 in Reports'] && jsEnabled) { + if (location.hostname === 'sys.4chan.org' && Conf['Use Recaptcha v2 in Reports'] && Main.jsEnabled) { $.ready(Captcha.replace.v2); return; } - if (Conf['Use Recaptcha v1'] && jsEnabled && location.hostname !== 'www.4chan.org') { + if (Conf['Use Recaptcha v1'] && Main.jsEnabled && location.hostname !== 'www.4chan.org') { $.ready(Captcha.replace.v1); return; } - if (Conf['captchaLanguage'].trim()) { + if (Conf['captchaLanguage'].trim() || Conf['Captcha Fixes']) { if (location.hostname === 'boards.4chan.org') { return $.onExists(doc, '#captchaFormPart', true, function(node) { return $.onExists(node, 'iframe', true, Captcha.replace.iframe); @@ -8143,13 +8148,33 @@ } } }, + noscript: function() { + var insert, noscript, original, span, toggle; + if (!((original = $('#g-recaptcha, #captchaContainerAlt')) && (noscript = $('noscript')))) { + return; + } + span = $.el('span', { + id: 'captcha-forced-noscript' + }); + $.replace(noscript, span); + $.rm(original); + insert = function() { + span.innerHTML = noscript.textContent; + return Captcha.replace.iframe($('iframe', span)); + }; + if ((toggle = $('#togglePostFormLink a, #form-link'))) { + return $.on(toggle, 'click', insert); + } else { + return insert(); + } + }, v1: function() { var form, link; if (!$.id('g-recaptcha')) { return; } Captcha.v1.replace(); - if (link = $.id('form-link')) { + if ((link = $.id('form-link'))) { return $.on(link, 'click', function() { return Captcha.v1.create(); }); @@ -8176,23 +8201,48 @@ }); $.replace(old, container); url = 'https://www.google.com/recaptcha/api.js'; - if (lang = Conf['captchaLanguage'].trim()) { + if ((lang = Conf['captchaLanguage'].trim())) { url += "?hl=" + (encodeURIComponent(lang)); } script = $.el('script', { src: url }); - return $.add(d.head, script); + $.add(d.head, script); + return $.onExists(d.body, 'iframe', true, Captcha.replace.autocopy); }, - iframe: function(el) { + iframe: function(iframe) { var lang, src; - if (!(lang = Conf['captchaLanguage'].trim())) { + if ((lang = Conf['captchaLanguage'].trim())) { + src = /[?&]hl=/.test(iframe.src) ? iframe.src.replace(/([?&]hl=)[^&]*/, '$1' + encodeURIComponent(lang)) : iframe.src + ("&hl=" + (encodeURIComponent(lang))); + if (iframe.src !== src) { + iframe.src = src; + } + } + return Captcha.replace.autocopy(iframe); + }, + autocopy: function(iframe) { + if (!(Conf['Captcha Fixes'] && /^https:\/\/www\.google\.com\/recaptcha\/api\/fallback\?/.test(iframe.src))) { return; } - src = /[?&]hl=/.test(el.src) ? el.src.replace(/([?&]hl=)[^&]*/, '$1' + encodeURIComponent(lang)) : el.src + ("&hl=" + (encodeURIComponent(lang))); - if (el.src !== src) { - return el.src = src; - } + return new Connection(iframe, 'https://www.google.com', { + working: function() { + var ref, ref1; + if ((ref = $.id('qr')) != null ? ref.contains(iframe) : void 0) { + return (ref1 = $('#qr .captcha-container textarea')) != null ? ref1.parentNode.hidden = true : void 0; + } + }, + token: function(token) { + var node, textarea; + node = iframe; + while ((node = node.parentNode)) { + if ((textarea = $('textarea', node))) { + break; + } + } + textarea.value = token; + return $.event('input', null, textarea); + } + }); } }; @@ -8485,17 +8535,10 @@ if (d.cookie.indexOf('pass_enabled=1') >= 0) { return; } - if (!(this.isEnabled = !!$('#g-recaptcha, #captchaContainerAlt'))) { + if (!(this.isEnabled = !!$('#g-recaptcha, #captchaContainerAlt, #captcha-forced-noscript'))) { return; } - if (this.noscript = Conf['Force Noscript Captcha'] || !$.hasClass(doc, 'js-enabled')) { - this.conn = new Connection(null, location.protocol + "//www.google.com", { - token: (function(_this) { - return function(token) { - return _this.save(true, token); - }; - })(this) - }); + if ((this.noscript = Conf['Force Noscript Captcha'] || !Main.jsEnabled)) { $.addClass(QR.nodes.el, 'noscript-captcha'); } this.captchas = []; @@ -8541,21 +8584,12 @@ childList: true }); }, - initFrame: function() { - var conn, ref, token; - if (token = (ref = $('.fbc-verification-token > textarea')) != null ? ref.value : void 0) { - conn = new Connection(window.parent, location.protocol + "//boards.4chan.org"); - return conn.send({ - token: token - }); - } - }, timeouts: {}, postsCount: 0, noscriptURL: function() { var lang, url; - url = '//www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc'; - if (lang = Conf['captchaLanguage'].trim()) { + url = 'https://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc'; + if ((lang = Conf['captchaLanguage'].trim())) { url += "&hl=" + (encodeURIComponent(lang)); } return url; @@ -8591,7 +8625,6 @@ } }, setup: function(focus, force) { - var iframe; if (!(this.isEnabled && (this.needed() || force))) { return; } @@ -8604,10 +8637,15 @@ return this.reload(); } if (this.nodes.container) { - if (d.activeElement === this.nodes.counter && (iframe = $('iframe', this.nodes.container))) { - iframe.focus(); - QR.focus(); - } + $.queueTask((function(_this) { + return function() { + var iframe; + if (_this.nodes.container && d.activeElement === _this.nodes.counter && (iframe = $('iframe', _this.nodes.container))) { + iframe.focus(); + return QR.focus(); + } + }; + })(this)); return; } this.nodes.container = $.el('div', { @@ -8625,13 +8663,15 @@ } }, setupNoscript: function() { - var iframe; + var div, iframe, textarea; iframe = $.el('iframe', { id: 'qr-captcha-iframe', src: this.noscriptURL() }); - $.add(this.nodes.container, iframe); - return this.conn.target = iframe; + div = $.el('div'); + textarea = $.el('textarea'); + $.add(div, textarea); + return $.add(this.nodes.container, [iframe, div]); }, setupJS: function() { return $.globalEval('(function() {\n function render() {\n var container = document.querySelector("#qr .captcha-container");\n container.dataset.widgetID = window.grecaptcha.render(container, {\n sitekey: \'6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc\',\n theme: document.documentElement.classList.contains(\'tomorrow\') ? \'dark\' : \'light\',\n callback: function(response) {\n window.dispatchEvent(new CustomEvent("captcha:success", {detail: response}));\n }\n });\n }\n if (window.grecaptcha) {\n render();\n } else {\n var cbNative = window.onRecaptchaLoaded;\n window.onRecaptchaLoaded = function() {\n render();\n cbNative();\n }\n }\n})();'); @@ -8643,10 +8683,10 @@ ref = mutation.addedNodes; for (q = 0, len2 = ref.length; q < len2; q++) { node = ref[q]; - if (iframe = $.x('./descendant-or-self::iframe', node)) { + if ((iframe = $.x('./descendant-or-self::iframe', node))) { this.setupIFrame(iframe); } - if (textarea = $.x('./descendant-or-self::textarea', node)) { + if ((textarea = $.x('./descendant-or-self::textarea', node))) { this.setupTextArea(textarea); } } @@ -8706,7 +8746,7 @@ getOne: function() { var captcha; this.clear(); - if (captcha = this.captchas.shift()) { + if ((captcha = this.captchas.shift())) { $.set('captchas', this.captchas); this.count(); return captcha; @@ -8782,9 +8822,7 @@ } }, reload: function() { - if (this.noscript) { - return $('iframe', this.nodes.container).src = this.noscriptURL(); - } else if ($('iframe[src^="https://www.google.com/recaptcha/api/fallback?"]', this.nodes.container)) { + if ($('iframe[src^="https://www.google.com/recaptcha/api/fallback?"]', this.nodes.container)) { this.destroy(); return this.setup(false, true); } else { @@ -8806,7 +8844,7 @@ new MutationObserver(this.fixBubble.bind(this, node)).observe(node, { attributes: true }); - if (overlay = $('div[style*="position: fixed;"]', node)) { + if ((overlay = $('div[style*="position: fixed;"]', node))) { results1.push($.on(overlay, 'click', function() { var ref1; return (ref1 = $('#qr iframe')) != null ? ref1.blur() : void 0; @@ -16478,7 +16516,7 @@ }) ]); } - if (Conf['Use Recaptcha v2 in Reports'] && $.hasClass(doc, 'js-enabled')) { + if (Conf['Use Recaptcha v2 in Reports'] && !Conf['Force Noscript Captcha'] && Main.jsEnabled) { new MutationObserver(function() { Report.fit('iframe[src^="https://www.google.com/recaptcha/api2/frame"]'); return Report.fit('body'); @@ -16490,7 +16528,7 @@ } else { Report.fit('body'); } - if (!Conf['Use Recaptcha v2 in Reports'] && $.hasClass(doc, 'js-enabled') && d.cookie.indexOf('pass_enabled=1') < 0) { + if (!Conf['Use Recaptcha v2 in Reports'] && Main.jsEnabled && d.cookie.indexOf('pass_enabled=1') < 0) { $.onExists(d.body, '#recaptcha_image', true, function(image) { $.global(function() { return document.getElementById('recaptcha_image').removeEventListener('click', window.onAltCaptchaClick, false); @@ -17488,11 +17526,6 @@ } window['4chan X antidup'] = true; if (location.hostname === 'www.google.com') { - if (location.pathname === '/recaptcha/api/fallback') { - $.ready(function() { - return Captcha.v2.initFrame(); - }); - } $.get('Captcha Fixes', true, function(arg) { var enabled; enabled = arg['Captcha Fixes']; @@ -17586,6 +17619,7 @@ document.documentElement.classList.add('js-enabled'); return window.FCX = {}; }); + Main.jsEnabled = $.hasClass(doc, 'js-enabled'); } switch (hostname) { case 'www.4chan.org': @@ -19748,6 +19782,7 @@ "}\n" + ".qr-link-container {\n" + " text-align: center;\n" + +" margin: 16px 0;\n" + "}\n" + ".qr-link-container-bottom {\n" + " width: 200px;\n" + @@ -19765,6 +19800,11 @@ " border-width: 1px;\n" + " font-size: 10pt;\n" + "}\n" + +".qr-link-container + #togglePostFormLink {\n" + +" font-size: 10pt;\n" + +" font-weight: normal;\n" + +" margin: -8px 0 3.5px;\n" + +"}\n" + ".persona {\n" + " width: 100%;\n" + " display: -webkit-flex;\n" + @@ -21090,7 +21130,7 @@ cssWWW: "#captcha-cnt {\n" + " height: auto;\n" + "}", - features: [['Polyfill', Polyfill], ['Normalize URL', NormalizeURL], ['Captcha Replacement', Captcha.replace], ['Redirect', Redirect], ['Header', Header], ['Catalog Links', CatalogLinks], ['Settings', Settings], ['Index Generator', Index], ['Disable Autoplay', AntiAutoplay], ['Announcement Hiding', PSAHiding], ['Fourchan thingies', Fourchan], ['Color User IDs', IDColor], ['Highlight by User ID', IDHighlight], ['Custom CSS', CustomCSS], ['Thread Links', ThreadLinks], ['Linkify', Linkify], ['Reveal Spoilers', RemoveSpoilers], ['Resurrect Quotes', Quotify], ['Filter', Filter], ['Thread Hiding Buttons', ThreadHiding], ['Reply Hiding Buttons', PostHiding], ['Recursive', Recursive], ['Strike-through Quotes', QuoteStrikeThrough], ['Quick Reply', QR], ['Cooldown', QR.cooldown], ['Oekaki Links', QR.oekaki], ['Pass Link', PassLink], ['Menu', Menu], ['Index Generator (Menu)', Index.menu], ['Report Link', ReportLink], ['Thread Hiding (Menu)', ThreadHiding.menu], ['Reply Hiding (Menu)', PostHiding.menu], ['Delete Link', DeleteLink], ['Filter (Menu)', Filter.menu], ['Download Link', DownloadLink], ['Archive Link', ArchiveLink], ['Quote Inlining', QuoteInline], ['Quote Previewing', QuotePreview], ['Quote Backlinks', QuoteBacklink], ['Mark Quotes of You', QuoteYou], ['Mark OP Quotes', QuoteOP], ['Mark Cross-thread Quotes', QuoteCT], ['Anonymize', Anonymize], ['Time Formatting', Time], ['Relative Post Dates', RelativeDates], ['File Info Formatting', FileInfo], ['Fappe Tyme', FappeTyme], ['Gallery', Gallery], ['Gallery (menu)', Gallery.menu], ['Sauce', Sauce], ['Image Expansion', ImageExpand], ['Image Expansion (Menu)', ImageExpand.menu], ['Reveal Spoiler Thumbnails', RevealSpoilers], ['Image Loading', ImageLoader], ['Image Hover', ImageHover], ['Volume Control', Volume], ['WEBM Metadata', Metadata], ['Comment Expansion', ExpandComment], ['Thread Expansion', ExpandThread], ['Thread Excerpt', ThreadExcerpt], ['Favicon', Favicon], ['Unread', Unread], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats], ['Thread Updater', ThreadUpdater], ['Thread Watcher', ThreadWatcher], ['Thread Watcher (Menu)', ThreadWatcher.menu], ['Mark New IPs', MarkNewIPs], ['Index Navigation', Nav], ['Keybinds', Keybinds], ['Banner', Banner], ['Flash Features', Flash]] + features: [['Polyfill', Polyfill], ['Normalize URL', NormalizeURL], ['Captcha Configuration', Captcha.replace], ['Redirect', Redirect], ['Header', Header], ['Catalog Links', CatalogLinks], ['Settings', Settings], ['Index Generator', Index], ['Disable Autoplay', AntiAutoplay], ['Announcement Hiding', PSAHiding], ['Fourchan thingies', Fourchan], ['Color User IDs', IDColor], ['Highlight by User ID', IDHighlight], ['Custom CSS', CustomCSS], ['Thread Links', ThreadLinks], ['Linkify', Linkify], ['Reveal Spoilers', RemoveSpoilers], ['Resurrect Quotes', Quotify], ['Filter', Filter], ['Thread Hiding Buttons', ThreadHiding], ['Reply Hiding Buttons', PostHiding], ['Recursive', Recursive], ['Strike-through Quotes', QuoteStrikeThrough], ['Quick Reply', QR], ['Cooldown', QR.cooldown], ['Oekaki Links', QR.oekaki], ['Pass Link', PassLink], ['Menu', Menu], ['Index Generator (Menu)', Index.menu], ['Report Link', ReportLink], ['Thread Hiding (Menu)', ThreadHiding.menu], ['Reply Hiding (Menu)', PostHiding.menu], ['Delete Link', DeleteLink], ['Filter (Menu)', Filter.menu], ['Download Link', DownloadLink], ['Archive Link', ArchiveLink], ['Quote Inlining', QuoteInline], ['Quote Previewing', QuotePreview], ['Quote Backlinks', QuoteBacklink], ['Mark Quotes of You', QuoteYou], ['Mark OP Quotes', QuoteOP], ['Mark Cross-thread Quotes', QuoteCT], ['Anonymize', Anonymize], ['Time Formatting', Time], ['Relative Post Dates', RelativeDates], ['File Info Formatting', FileInfo], ['Fappe Tyme', FappeTyme], ['Gallery', Gallery], ['Gallery (menu)', Gallery.menu], ['Sauce', Sauce], ['Image Expansion', ImageExpand], ['Image Expansion (Menu)', ImageExpand.menu], ['Reveal Spoiler Thumbnails', RevealSpoilers], ['Image Loading', ImageLoader], ['Image Hover', ImageHover], ['Volume Control', Volume], ['WEBM Metadata', Metadata], ['Comment Expansion', ExpandComment], ['Thread Expansion', ExpandThread], ['Thread Excerpt', ThreadExcerpt], ['Favicon', Favicon], ['Unread', Unread], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats], ['Thread Updater', ThreadUpdater], ['Thread Watcher', ThreadWatcher], ['Thread Watcher (Menu)', ThreadWatcher.menu], ['Mark New IPs', MarkNewIPs], ['Index Navigation', Nav], ['Keybinds', Keybinds], ['Banner', Banner], ['Flash Features', Flash]] }; Main.init(); diff --git a/builds/4chan-X.crx b/builds/4chan-X.crx index 8188f7656..156539b1b 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 0f2367ef9..05a8856f0 100644 --- a/builds/4chan-X.meta.js +++ b/builds/4chan-X.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.11.17.8 +// @version 1.11.18.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index dd59e01c2..9a7fb2c0c 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.17.8 +// @version 1.11.18.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -239,16 +239,15 @@ 'Randomize Filename': [false, 'Set the filename to a random timestamp within the past year. Disabled on /f/.', 1], 'Show New Thread Option in Threads': [false, 'Show the option to post a new / different thread from inside a thread.', 1], 'Show Name and Subject': [false, 'Show the classic name, email, and subject fields in the QR, even when 4chan doesn\'t use them all.', 1], - '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], - 'Force Noscript Captcha': [false, 'Use the non-Javascript fallback captcha in the QR even if Javascript is enabled (Recaptcha v2 only).', 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], 'Bottom QR Link': [true, 'Places a link on the bottom of threads to open the QR.', 1], 'Captcha Fixes': [true, 'Make captcha easier to use, especially with the keyboard.'], 'Use Recaptcha v1': [false, 'Use the old text version of Recaptcha.'], 'Use Recaptcha v2 in Reports': [false, 'Use the image selection captcha in the report window.'], + 'Force Noscript Captcha': [false, 'Use the non-Javascript fallback captcha even if Javascript is enabled (Recaptcha v2 only).'], 'Pass Link': [true, 'Add a 4chan Pass login link to the bottom of the page.'] }, 'Quote Links': { @@ -433,7 +432,7 @@ doc = d.documentElement; g = { - VERSION: '1.11.17.8', + VERSION: '1.11.18.0', NAMESPACE: '4chan X.', boards: {} }; @@ -6965,7 +6964,7 @@ if (g.VIEW === 'archive') { return; } - version = Conf['Use Recaptcha v1'] ? 'v1' : 'v2'; + version = Conf['Use Recaptcha v1'] && !Conf['Force Noscript Captcha'] && Main.jsEnabled ? 'v1' : 'v2'; this.captcha = Captcha[version]; $.on(d, '4chanXInitFinished', this.initReady); Post.callbacks.push({ @@ -6990,17 +6989,11 @@ return QR.close(); } }); - Header.addShortcut(sc); - } - if (Conf['Hide Original Post Form']) { - $.addClass(doc, 'hide-original-post-form'); - if (!$.hasClass(doc, 'js-enabled')) { - return $.onExists(doc, '#postForm noscript', true, $.rm); - } + return Header.addShortcut(sc); } }, initReady: function() { - var link, linkBot; + var link, linkBot, origToggle; $.off(d, '4chanXInitFinished', this.initReady); QR.postingIsEnabled = !!$.id('postForm'); if (!QR.postingIsEnabled) { @@ -7030,7 +7023,9 @@ }); $.prepend($('.navLinksBot'), linkBot); } - $.before($.id('togglePostFormLink'), link); + origToggle = $.id('togglePostFormLink'); + $.before(origToggle, link); + origToggle.firstElementChild.textContent = 'Original Form'; $.on(d, 'QRGetFile', QR.getFile); $.on(d, 'QRSetFile', QR.setFile); $.on(d, 'paste', QR.paste); @@ -7956,7 +7951,7 @@ Captcha.fixes = { imageKeys: '789456123uiojklm'.split('').concat(['Comma', 'Period']), css: '.rc-imageselect-target > div:focus {\n outline: 2px solid #4a90e2;\n}\n.rc-imageselect-target td:focus {\n box-shadow: inset 0 0 0 2px #4a90e2;\n outline: none;\n}\n.rc-button-default:focus {\n box-shadow: inset 0 0 0 2px #0063d6;\n}', - cssNoscript: '.fbc-payload-imageselect {\n position: relative;\n}\n.fbc-payload-imageselect > label {\n position: absolute;\n display: block;\n height: 93.3px;\n width: 93.3px;\n}\nlabel[data-row="0"] {top: 0px;}\nlabel[data-row="1"] {top: 93.3px;}\nlabel[data-row="2"] {top: 186.6px;}\nlabel[data-col="0"] {left: 0px;}\nlabel[data-col="1"] {left: 93.3px;}\nlabel[data-col="2"] {left: 186.6px;}', + cssNoscript: '.fbc-payload-imageselect {\n position: relative;\n}\n.fbc-payload-imageselect > label {\n position: absolute;\n display: block;\n height: 93.3px;\n width: 93.3px;\n}\nlabel[data-row="0"] {top: 0px;}\nlabel[data-row="1"] {top: 93.3px;}\nlabel[data-row="2"] {top: 186.6px;}\nlabel[data-col="0"] {left: 0px;}\nlabel[data-col="1"] {left: 93.3px;}\nlabel[data-col="2"] {left: 186.6px;}\n.fbc-payload-imageselect > input:focus + label {\n outline: 2px solid #4a90e2;\n}\n.fbc-button-verify input:focus {\n box-shadow: inset 0 0 0 2px #0063d6;\n}\nbody.focus .fbc {\n box-shadow: inset 0 0 0 2px #4a90e2;\n}', init: function() { switch (location.pathname.split('/')[3]) { case 'anchor': @@ -7995,7 +7990,18 @@ return $.on(d, 'keydown', this.keybinds.bind(this)); }, initNoscript: function() { + var data, ref, token; this.noscript = true; + data = (token = (ref = $('.fbc-verification-token > textarea')) != null ? ref.value : void 0) ? { + token: token + } : { + working: true + }; + new Connection(window.parent, '*').send(data); + d.body.classList.toggle('focus', d.hasFocus()); + $.on(window, 'focus blur', function() { + return d.body.classList.toggle('focus', d.hasFocus()); + }); this.images = $$('.fbc-payload-imageselect > input'); if (this.images.length !== 9) { return; @@ -8048,11 +8054,11 @@ }); label.dataset.row = Math.floor(i / 3); label.dataset.col = i % 3; + $.after(checkbox, label); results.push(label); } return results; }).call(this); - $.add(imageSelect, labels); return this.addTooltips(labels); }, addTooltips: function(nodes) { @@ -8117,23 +8123,22 @@ Captcha.replace = { init: function() { - var jsEnabled; if (!(d.cookie.indexOf('pass_enabled=1') < 0)) { return; } - if (location.hostname === 'boards.4chan.org' && Conf['Hide Original Post Form']) { + if (Conf['Force Noscript Captcha'] && Main.jsEnabled) { + $.ready(Captcha.replace.noscript); return; } - jsEnabled = $.hasClass(doc, 'js-enabled'); - if (location.hostname === 'sys.4chan.org' && Conf['Use Recaptcha v2 in Reports'] && jsEnabled) { + if (location.hostname === 'sys.4chan.org' && Conf['Use Recaptcha v2 in Reports'] && Main.jsEnabled) { $.ready(Captcha.replace.v2); return; } - if (Conf['Use Recaptcha v1'] && jsEnabled && location.hostname !== 'www.4chan.org') { + if (Conf['Use Recaptcha v1'] && Main.jsEnabled && location.hostname !== 'www.4chan.org') { $.ready(Captcha.replace.v1); return; } - if (Conf['captchaLanguage'].trim()) { + if (Conf['captchaLanguage'].trim() || Conf['Captcha Fixes']) { if (location.hostname === 'boards.4chan.org') { return $.onExists(doc, '#captchaFormPart', true, function(node) { return $.onExists(node, 'iframe', true, Captcha.replace.iframe); @@ -8143,13 +8148,33 @@ } } }, + noscript: function() { + var insert, noscript, original, span, toggle; + if (!((original = $('#g-recaptcha, #captchaContainerAlt')) && (noscript = $('noscript')))) { + return; + } + span = $.el('span', { + id: 'captcha-forced-noscript' + }); + $.replace(noscript, span); + $.rm(original); + insert = function() { + span.innerHTML = noscript.textContent; + return Captcha.replace.iframe($('iframe', span)); + }; + if ((toggle = $('#togglePostFormLink a, #form-link'))) { + return $.on(toggle, 'click', insert); + } else { + return insert(); + } + }, v1: function() { var form, link; if (!$.id('g-recaptcha')) { return; } Captcha.v1.replace(); - if (link = $.id('form-link')) { + if ((link = $.id('form-link'))) { return $.on(link, 'click', function() { return Captcha.v1.create(); }); @@ -8176,23 +8201,48 @@ }); $.replace(old, container); url = 'https://www.google.com/recaptcha/api.js'; - if (lang = Conf['captchaLanguage'].trim()) { + if ((lang = Conf['captchaLanguage'].trim())) { url += "?hl=" + (encodeURIComponent(lang)); } script = $.el('script', { src: url }); - return $.add(d.head, script); + $.add(d.head, script); + return $.onExists(d.body, 'iframe', true, Captcha.replace.autocopy); }, - iframe: function(el) { + iframe: function(iframe) { var lang, src; - if (!(lang = Conf['captchaLanguage'].trim())) { + if ((lang = Conf['captchaLanguage'].trim())) { + src = /[?&]hl=/.test(iframe.src) ? iframe.src.replace(/([?&]hl=)[^&]*/, '$1' + encodeURIComponent(lang)) : iframe.src + ("&hl=" + (encodeURIComponent(lang))); + if (iframe.src !== src) { + iframe.src = src; + } + } + return Captcha.replace.autocopy(iframe); + }, + autocopy: function(iframe) { + if (!(Conf['Captcha Fixes'] && /^https:\/\/www\.google\.com\/recaptcha\/api\/fallback\?/.test(iframe.src))) { return; } - src = /[?&]hl=/.test(el.src) ? el.src.replace(/([?&]hl=)[^&]*/, '$1' + encodeURIComponent(lang)) : el.src + ("&hl=" + (encodeURIComponent(lang))); - if (el.src !== src) { - return el.src = src; - } + return new Connection(iframe, 'https://www.google.com', { + working: function() { + var ref, ref1; + if ((ref = $.id('qr')) != null ? ref.contains(iframe) : void 0) { + return (ref1 = $('#qr .captcha-container textarea')) != null ? ref1.parentNode.hidden = true : void 0; + } + }, + token: function(token) { + var node, textarea; + node = iframe; + while ((node = node.parentNode)) { + if ((textarea = $('textarea', node))) { + break; + } + } + textarea.value = token; + return $.event('input', null, textarea); + } + }); } }; @@ -8485,17 +8535,10 @@ if (d.cookie.indexOf('pass_enabled=1') >= 0) { return; } - if (!(this.isEnabled = !!$('#g-recaptcha, #captchaContainerAlt'))) { + if (!(this.isEnabled = !!$('#g-recaptcha, #captchaContainerAlt, #captcha-forced-noscript'))) { return; } - if (this.noscript = Conf['Force Noscript Captcha'] || !$.hasClass(doc, 'js-enabled')) { - this.conn = new Connection(null, location.protocol + "//www.google.com", { - token: (function(_this) { - return function(token) { - return _this.save(true, token); - }; - })(this) - }); + if ((this.noscript = Conf['Force Noscript Captcha'] || !Main.jsEnabled)) { $.addClass(QR.nodes.el, 'noscript-captcha'); } this.captchas = []; @@ -8541,21 +8584,12 @@ childList: true }); }, - initFrame: function() { - var conn, ref, token; - if (token = (ref = $('.fbc-verification-token > textarea')) != null ? ref.value : void 0) { - conn = new Connection(window.parent, location.protocol + "//boards.4chan.org"); - return conn.send({ - token: token - }); - } - }, timeouts: {}, postsCount: 0, noscriptURL: function() { var lang, url; - url = '//www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc'; - if (lang = Conf['captchaLanguage'].trim()) { + url = 'https://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc'; + if ((lang = Conf['captchaLanguage'].trim())) { url += "&hl=" + (encodeURIComponent(lang)); } return url; @@ -8591,7 +8625,6 @@ } }, setup: function(focus, force) { - var iframe; if (!(this.isEnabled && (this.needed() || force))) { return; } @@ -8604,10 +8637,15 @@ return this.reload(); } if (this.nodes.container) { - if (d.activeElement === this.nodes.counter && (iframe = $('iframe', this.nodes.container))) { - iframe.focus(); - QR.focus(); - } + $.queueTask((function(_this) { + return function() { + var iframe; + if (_this.nodes.container && d.activeElement === _this.nodes.counter && (iframe = $('iframe', _this.nodes.container))) { + iframe.focus(); + return QR.focus(); + } + }; + })(this)); return; } this.nodes.container = $.el('div', { @@ -8625,13 +8663,15 @@ } }, setupNoscript: function() { - var iframe; + var div, iframe, textarea; iframe = $.el('iframe', { id: 'qr-captcha-iframe', src: this.noscriptURL() }); - $.add(this.nodes.container, iframe); - return this.conn.target = iframe; + div = $.el('div'); + textarea = $.el('textarea'); + $.add(div, textarea); + return $.add(this.nodes.container, [iframe, div]); }, setupJS: function() { return $.globalEval('(function() {\n function render() {\n var container = document.querySelector("#qr .captcha-container");\n container.dataset.widgetID = window.grecaptcha.render(container, {\n sitekey: \'6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc\',\n theme: document.documentElement.classList.contains(\'tomorrow\') ? \'dark\' : \'light\',\n callback: function(response) {\n window.dispatchEvent(new CustomEvent("captcha:success", {detail: response}));\n }\n });\n }\n if (window.grecaptcha) {\n render();\n } else {\n var cbNative = window.onRecaptchaLoaded;\n window.onRecaptchaLoaded = function() {\n render();\n cbNative();\n }\n }\n})();'); @@ -8643,10 +8683,10 @@ ref = mutation.addedNodes; for (q = 0, len2 = ref.length; q < len2; q++) { node = ref[q]; - if (iframe = $.x('./descendant-or-self::iframe', node)) { + if ((iframe = $.x('./descendant-or-self::iframe', node))) { this.setupIFrame(iframe); } - if (textarea = $.x('./descendant-or-self::textarea', node)) { + if ((textarea = $.x('./descendant-or-self::textarea', node))) { this.setupTextArea(textarea); } } @@ -8706,7 +8746,7 @@ getOne: function() { var captcha; this.clear(); - if (captcha = this.captchas.shift()) { + if ((captcha = this.captchas.shift())) { $.set('captchas', this.captchas); this.count(); return captcha; @@ -8782,9 +8822,7 @@ } }, reload: function() { - if (this.noscript) { - return $('iframe', this.nodes.container).src = this.noscriptURL(); - } else if ($('iframe[src^="https://www.google.com/recaptcha/api/fallback?"]', this.nodes.container)) { + if ($('iframe[src^="https://www.google.com/recaptcha/api/fallback?"]', this.nodes.container)) { this.destroy(); return this.setup(false, true); } else { @@ -8806,7 +8844,7 @@ new MutationObserver(this.fixBubble.bind(this, node)).observe(node, { attributes: true }); - if (overlay = $('div[style*="position: fixed;"]', node)) { + if ((overlay = $('div[style*="position: fixed;"]', node))) { results1.push($.on(overlay, 'click', function() { var ref1; return (ref1 = $('#qr iframe')) != null ? ref1.blur() : void 0; @@ -16478,7 +16516,7 @@ }) ]); } - if (Conf['Use Recaptcha v2 in Reports'] && $.hasClass(doc, 'js-enabled')) { + if (Conf['Use Recaptcha v2 in Reports'] && !Conf['Force Noscript Captcha'] && Main.jsEnabled) { new MutationObserver(function() { Report.fit('iframe[src^="https://www.google.com/recaptcha/api2/frame"]'); return Report.fit('body'); @@ -16490,7 +16528,7 @@ } else { Report.fit('body'); } - if (!Conf['Use Recaptcha v2 in Reports'] && $.hasClass(doc, 'js-enabled') && d.cookie.indexOf('pass_enabled=1') < 0) { + if (!Conf['Use Recaptcha v2 in Reports'] && Main.jsEnabled && d.cookie.indexOf('pass_enabled=1') < 0) { $.onExists(d.body, '#recaptcha_image', true, function(image) { $.global(function() { return document.getElementById('recaptcha_image').removeEventListener('click', window.onAltCaptchaClick, false); @@ -17488,11 +17526,6 @@ } window['4chan X antidup'] = true; if (location.hostname === 'www.google.com') { - if (location.pathname === '/recaptcha/api/fallback') { - $.ready(function() { - return Captcha.v2.initFrame(); - }); - } $.get('Captcha Fixes', true, function(arg) { var enabled; enabled = arg['Captcha Fixes']; @@ -17586,6 +17619,7 @@ document.documentElement.classList.add('js-enabled'); return window.FCX = {}; }); + Main.jsEnabled = $.hasClass(doc, 'js-enabled'); } switch (hostname) { case 'www.4chan.org': @@ -19748,6 +19782,7 @@ "}\n" + ".qr-link-container {\n" + " text-align: center;\n" + +" margin: 16px 0;\n" + "}\n" + ".qr-link-container-bottom {\n" + " width: 200px;\n" + @@ -19765,6 +19800,11 @@ " border-width: 1px;\n" + " font-size: 10pt;\n" + "}\n" + +".qr-link-container + #togglePostFormLink {\n" + +" font-size: 10pt;\n" + +" font-weight: normal;\n" + +" margin: -8px 0 3.5px;\n" + +"}\n" + ".persona {\n" + " width: 100%;\n" + " display: -webkit-flex;\n" + @@ -21090,7 +21130,7 @@ cssWWW: "#captcha-cnt {\n" + " height: auto;\n" + "}", - features: [['Polyfill', Polyfill], ['Normalize URL', NormalizeURL], ['Captcha Replacement', Captcha.replace], ['Redirect', Redirect], ['Header', Header], ['Catalog Links', CatalogLinks], ['Settings', Settings], ['Index Generator', Index], ['Disable Autoplay', AntiAutoplay], ['Announcement Hiding', PSAHiding], ['Fourchan thingies', Fourchan], ['Color User IDs', IDColor], ['Highlight by User ID', IDHighlight], ['Custom CSS', CustomCSS], ['Thread Links', ThreadLinks], ['Linkify', Linkify], ['Reveal Spoilers', RemoveSpoilers], ['Resurrect Quotes', Quotify], ['Filter', Filter], ['Thread Hiding Buttons', ThreadHiding], ['Reply Hiding Buttons', PostHiding], ['Recursive', Recursive], ['Strike-through Quotes', QuoteStrikeThrough], ['Quick Reply', QR], ['Cooldown', QR.cooldown], ['Oekaki Links', QR.oekaki], ['Pass Link', PassLink], ['Menu', Menu], ['Index Generator (Menu)', Index.menu], ['Report Link', ReportLink], ['Thread Hiding (Menu)', ThreadHiding.menu], ['Reply Hiding (Menu)', PostHiding.menu], ['Delete Link', DeleteLink], ['Filter (Menu)', Filter.menu], ['Download Link', DownloadLink], ['Archive Link', ArchiveLink], ['Quote Inlining', QuoteInline], ['Quote Previewing', QuotePreview], ['Quote Backlinks', QuoteBacklink], ['Mark Quotes of You', QuoteYou], ['Mark OP Quotes', QuoteOP], ['Mark Cross-thread Quotes', QuoteCT], ['Anonymize', Anonymize], ['Time Formatting', Time], ['Relative Post Dates', RelativeDates], ['File Info Formatting', FileInfo], ['Fappe Tyme', FappeTyme], ['Gallery', Gallery], ['Gallery (menu)', Gallery.menu], ['Sauce', Sauce], ['Image Expansion', ImageExpand], ['Image Expansion (Menu)', ImageExpand.menu], ['Reveal Spoiler Thumbnails', RevealSpoilers], ['Image Loading', ImageLoader], ['Image Hover', ImageHover], ['Volume Control', Volume], ['WEBM Metadata', Metadata], ['Comment Expansion', ExpandComment], ['Thread Expansion', ExpandThread], ['Thread Excerpt', ThreadExcerpt], ['Favicon', Favicon], ['Unread', Unread], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats], ['Thread Updater', ThreadUpdater], ['Thread Watcher', ThreadWatcher], ['Thread Watcher (Menu)', ThreadWatcher.menu], ['Mark New IPs', MarkNewIPs], ['Index Navigation', Nav], ['Keybinds', Keybinds], ['Banner', Banner], ['Flash Features', Flash]] + features: [['Polyfill', Polyfill], ['Normalize URL', NormalizeURL], ['Captcha Configuration', Captcha.replace], ['Redirect', Redirect], ['Header', Header], ['Catalog Links', CatalogLinks], ['Settings', Settings], ['Index Generator', Index], ['Disable Autoplay', AntiAutoplay], ['Announcement Hiding', PSAHiding], ['Fourchan thingies', Fourchan], ['Color User IDs', IDColor], ['Highlight by User ID', IDHighlight], ['Custom CSS', CustomCSS], ['Thread Links', ThreadLinks], ['Linkify', Linkify], ['Reveal Spoilers', RemoveSpoilers], ['Resurrect Quotes', Quotify], ['Filter', Filter], ['Thread Hiding Buttons', ThreadHiding], ['Reply Hiding Buttons', PostHiding], ['Recursive', Recursive], ['Strike-through Quotes', QuoteStrikeThrough], ['Quick Reply', QR], ['Cooldown', QR.cooldown], ['Oekaki Links', QR.oekaki], ['Pass Link', PassLink], ['Menu', Menu], ['Index Generator (Menu)', Index.menu], ['Report Link', ReportLink], ['Thread Hiding (Menu)', ThreadHiding.menu], ['Reply Hiding (Menu)', PostHiding.menu], ['Delete Link', DeleteLink], ['Filter (Menu)', Filter.menu], ['Download Link', DownloadLink], ['Archive Link', ArchiveLink], ['Quote Inlining', QuoteInline], ['Quote Previewing', QuotePreview], ['Quote Backlinks', QuoteBacklink], ['Mark Quotes of You', QuoteYou], ['Mark OP Quotes', QuoteOP], ['Mark Cross-thread Quotes', QuoteCT], ['Anonymize', Anonymize], ['Time Formatting', Time], ['Relative Post Dates', RelativeDates], ['File Info Formatting', FileInfo], ['Fappe Tyme', FappeTyme], ['Gallery', Gallery], ['Gallery (menu)', Gallery.menu], ['Sauce', Sauce], ['Image Expansion', ImageExpand], ['Image Expansion (Menu)', ImageExpand.menu], ['Reveal Spoiler Thumbnails', RevealSpoilers], ['Image Loading', ImageLoader], ['Image Hover', ImageHover], ['Volume Control', Volume], ['WEBM Metadata', Metadata], ['Comment Expansion', ExpandComment], ['Thread Expansion', ExpandThread], ['Thread Excerpt', ThreadExcerpt], ['Favicon', Favicon], ['Unread', Unread], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats], ['Thread Updater', ThreadUpdater], ['Thread Watcher', ThreadWatcher], ['Thread Watcher (Menu)', ThreadWatcher.menu], ['Mark New IPs', MarkNewIPs], ['Index Navigation', Nav], ['Keybinds', Keybinds], ['Banner', Banner], ['Flash Features', Flash]] }; Main.init(); diff --git a/builds/4chan-X.zip b/builds/4chan-X.zip index 6d59eb4d1..54c1d438e 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 41bd1209b..b36cbd4ce 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 ed1e0607b..4291a3927 100644 --- a/builds/updates.xml +++ b/builds/updates.xml @@ -1,7 +1,7 @@ - + diff --git a/version.json b/version.json index 9abc458ba..ea51306d4 100644 --- a/version.json +++ b/version.json @@ -1,4 +1,4 @@ { - "version": "1.11.17.8", - "date": "2015-11-21T02:46:47.553Z" + "version": "1.11.18.0", + "date": "2015-11-21T09:40:59.277Z" }