Merge branch 'master' into filter
This commit is contained in:
commit
a2725a16de
55
CHANGELOG.md
55
CHANGELOG.md
@ -2,8 +2,63 @@ Sometimes the changelog has notes (not comprehensive) acknowledging people's wor
|
||||
|
||||
The links to individual versions below are to copies of the script with the update URL removed. If you want automatic updates, install the script from the links on the [main page](https://github.com/ccd0/4chan-x).
|
||||
|
||||
### v1.10.11
|
||||
|
||||
**v1.10.11.1** *(2015-04-24)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.11.1/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.11.1/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- Merge v1.10.10.3: Fix original post form not showing when JS is disabled.
|
||||
|
||||
**v1.10.11.0** *(2015-04-24)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.11.0/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.11.0/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- Based on v1.10.10.2.
|
||||
- Fix whitespace being stripped from the comment before filtering. This makes it possible to filter whitespace spam.
|
||||
|
||||
### v1.10.10
|
||||
|
||||
**v1.10.10.3** *(2015-04-24)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.10.3/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.10.3/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- Fix original post form not showing when JS is disabled.
|
||||
|
||||
**v1.10.10.2** *(2015-04-21)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.10.2/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.10.2/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- Add focus indication to verify button in captcha popup.
|
||||
|
||||
**v1.10.10.1** *(2015-04-19)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.10.1/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.10.1/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- Merge v1.10.9.5: (thebladeee) Archive list: Transferred /w/ and /wg/ back to Nyafuu.
|
||||
|
||||
**v1.10.10.0** *(2015-04-18)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.10.0/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.10.0/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- Based on v1.10.9.4.
|
||||
- Make images in image captcha selectable with arrow keys.
|
||||
- Add `Captcha Fixes` option (on by default) to control whether 4chan X runs inside the Javascript-based captcha.
|
||||
|
||||
### v1.10.9
|
||||
|
||||
**v1.10.9.5** *(2015-04-19)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.9.5/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.9.5/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- (thebladeee) Archive list: Transferred /w/ and /wg/ back to Nyafuu.
|
||||
|
||||
**v1.10.9.4** *(2015-04-17)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.9.4/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.9.4/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- (Hasumi) Update archive.moe: Add /gif/.
|
||||
|
||||
**v1.10.9.3** *(2015-04-17)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.9.3/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.9.3/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- Resize report window as needed instead of opening it huge at beginning.
|
||||
|
||||
**v1.10.9.2** *(2015-04-16)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.9.2/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.9.2/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- (aCarbon) Normal report size box if pass is logged in.
|
||||
- Clean up leftover Recaptcha iframes to prevent memory leak.
|
||||
|
||||
**v1.10.9.1** *(2015-04-15)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.9.1/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.9.1/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- Merge v1.10.8.11: Increase report window size to accomodate increasingly common image captchas.
|
||||
- Fix report window closing before redirect.
|
||||
|
||||
**v1.10.9.0** *(2015-04-15)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.9.0/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.9.0/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- Based on v1.10.8.10.
|
||||
- Support reporting posts to fgts archive.
|
||||
- Add capcode to archive search menu.
|
||||
|
||||
### v1.10.8
|
||||
|
||||
**v1.10.8.11** *(2015-04-15)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.8.11/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.8.11/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- Increase report window size to accomodate increasingly common image captchas.
|
||||
|
||||
**v1.10.8.10** *(2015-04-13)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.8.10/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.8.10/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- Fix unwanted focusing on the submit button if you focus on the comment field too soon after entering the captcha.
|
||||
|
||||
**v1.10.8.9** *(2015-04-13)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.8.9/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.8.9/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- (fgts) Remove /fit/ from fgts archive.
|
||||
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
path = require 'path'
|
||||
crx = require 'crx'
|
||||
JSZip = require 'jszip'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
grunt.util.linefeed = '\n'
|
||||
@ -234,25 +236,6 @@ module.exports = (grunt) ->
|
||||
]
|
||||
tasks: 'build'
|
||||
|
||||
crx:
|
||||
prod:
|
||||
src: 'testbuilds/crx<%= pkg.meta.suffix[pkg.channel] %>/'
|
||||
dest: 'testbuilds/<%= pkg.name %><%= pkg.meta.suffix[pkg.channel] %>.crx'
|
||||
privateKey: '../<%= pkg.name %>-keys/<%= pkg.name %>.pem'
|
||||
|
||||
compress:
|
||||
crx:
|
||||
options:
|
||||
archive: 'testbuilds/<%= pkg.name %><%= pkg.meta.suffix[pkg.channel] %>.crx.zip'
|
||||
level: 9
|
||||
pretty: true
|
||||
expand: true
|
||||
flatten: true
|
||||
src: 'testbuilds/crx<%= pkg.meta.suffix[pkg.channel] %>/*'
|
||||
dest: '/'
|
||||
date: '<%= pkg.meta.date %>'
|
||||
mode: parseInt('644', 8)
|
||||
|
||||
clean:
|
||||
builds: 'builds'
|
||||
testbuilds: 'testbuilds'
|
||||
@ -335,7 +318,7 @@ module.exports = (grunt) ->
|
||||
grunt.registerTask 'build-crx-channel', [
|
||||
'concat:crx'
|
||||
'copy:crx'
|
||||
'compress:crx'
|
||||
'zip-crx'
|
||||
]
|
||||
|
||||
grunt.registerTask 'build-crx', [
|
||||
@ -354,6 +337,17 @@ module.exports = (grunt) ->
|
||||
'clean:tmpcrx'
|
||||
]
|
||||
|
||||
grunt.registerTask 'zip-crx', 'Pack CRX contents in ZIP file', ->
|
||||
pkg = grunt.config 'pkg'
|
||||
zip = new JSZip()
|
||||
for file in grunt.file.expand "testbuilds/crx#{pkg.meta.suffix[pkg.channel]}/*"
|
||||
zip.file path.basename(file), grunt.file.read(file, {encoding: null}), {date: new Date(pkg.meta.date)}
|
||||
output = zip.generate
|
||||
type: 'nodebuffer'
|
||||
compression: 'DEFLATE'
|
||||
compressionOptions: {level: 9}
|
||||
grunt.file.write "testbuilds/#{pkg.name}#{pkg.meta.suffix[pkg.channel]}.crx.zip", output
|
||||
|
||||
grunt.registerTask 'sign-channel', 'Sign CRX package', (channel) ->
|
||||
done = @async()
|
||||
pkg = grunt.config 'pkg'
|
||||
|
||||
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
// ==UserScript==
|
||||
// @name 4chan X beta
|
||||
// @version 1.10.8.9
|
||||
// @version 1.10.11.1
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -11,6 +11,7 @@
|
||||
// @match *://a.4cdn.org/*
|
||||
// @match *://i.4cdn.org/*
|
||||
// @match https://www.google.com/recaptcha/api2/anchor?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*
|
||||
// @match https://www.google.com/recaptcha/api2/frame?*&k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*
|
||||
// @match *://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc
|
||||
// @grant GM_getValue
|
||||
// @grant GM_setValue
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript
|
||||
// ==UserScript==
|
||||
// @name 4chan X beta
|
||||
// @version 1.10.8.9
|
||||
// @version 1.10.11.1
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -12,6 +12,7 @@
|
||||
// @match *://a.4cdn.org/*
|
||||
// @match *://i.4cdn.org/*
|
||||
// @match https://www.google.com/recaptcha/api2/anchor?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*
|
||||
// @match https://www.google.com/recaptcha/api2/frame?*&k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*
|
||||
// @match *://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc
|
||||
// @grant GM_getValue
|
||||
// @grant GM_setValue
|
||||
@ -109,7 +110,7 @@
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var $, $$, Anonymize, AntiAutoplay, ArchiveLink, Banner, Board, Build, Callbacks, Captcha, CatalogLinks, CatalogThread, Clone, Conf, Config, Connection, CrossOrigin, CustomCSS, DataBoard, DeleteLink, DownloadLink, E, Embedding, ExpandComment, ExpandThread, FappeTyme, Favicon, Fetcher, FileInfo, Filter, Flash, Fourchan, Gallery, Get, Header, IDColor, IDHighlight, ImageCommon, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, MarkNewIPs, Menu, Metadata, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, PostSuccessful, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, ReportLink, RevealSpoilers, Sauce, Settings, ShimSet, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, Volume, c, d, doc, g,
|
||||
var $, $$, Anonymize, AntiAutoplay, ArchiveLink, Banner, Board, Build, Callbacks, Captcha, CatalogLinks, CatalogThread, Clone, Conf, Config, Connection, CrossOrigin, CustomCSS, DataBoard, DeleteLink, DownloadLink, E, Embedding, ExpandComment, ExpandThread, FappeTyme, Favicon, Fetcher, FileInfo, Filter, Flash, Fourchan, Gallery, Get, Header, IDColor, IDHighlight, ImageCommon, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, MarkNewIPs, Menu, Metadata, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, PostSuccessful, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, ShimSet, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, Volume, c, d, doc, g,
|
||||
slice = [].slice,
|
||||
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
|
||||
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
||||
@ -127,6 +128,7 @@
|
||||
'Announcement Hiding': [true, 'Add button to hide 4chan announcements.'],
|
||||
'Desktop Notifications': [true, 'Enables desktop notifications across various 4chan X features.'],
|
||||
'404 Redirect': [true, 'Redirect dead threads and images to the archives.'],
|
||||
'Archive Report': [true, 'Enable reporting posts to supported archives.'],
|
||||
'Except Archives from Encryption': [false, 'Permit loading content from, and warningless redirects to, HTTP-only archives from HTTPS pages.'],
|
||||
'Keybinds': [true, 'Bind actions to keyboard shortcuts.'],
|
||||
'Time Formatting': [true, 'Localize and format timestamps.'],
|
||||
@ -235,7 +237,8 @@
|
||||
'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],
|
||||
'Bottom QR Link': [true, 'Places a link on the bottom of threads to open the QR.', 1]
|
||||
'Bottom QR Link': [true, 'Places a link on the bottom of threads to open the QR.', 1],
|
||||
'Captcha Fixes': [true, 'Make captcha more keyboard-navigable.']
|
||||
},
|
||||
'Quote Links': {
|
||||
'Quote Backlinks': [true, 'Add quote backlinks.'],
|
||||
@ -396,7 +399,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.10.8.9',
|
||||
VERSION: '1.10.11.1',
|
||||
NAMESPACE: '4chan X.',
|
||||
boards: {}
|
||||
};
|
||||
@ -627,9 +630,11 @@
|
||||
$.addStyle = function(css, id, test) {
|
||||
var style;
|
||||
style = $.el('style', {
|
||||
id: id,
|
||||
textContent: css
|
||||
});
|
||||
if (id != null) {
|
||||
style.id = id;
|
||||
}
|
||||
$.asap((function() {
|
||||
return d.head && ((test == null) || test());
|
||||
}), function() {
|
||||
@ -1291,28 +1296,33 @@
|
||||
}
|
||||
|
||||
Post.prototype.parseComment = function() {
|
||||
var bq, k, len1, node, ref, spoilers;
|
||||
var abbr, bq, commentDisplay, k, len1, len2, node, q, ref, spoilers;
|
||||
this.nodes.comment.normalize();
|
||||
bq = this.nodes.comment.cloneNode(true);
|
||||
ref = $$('.abbr, .exif, b, marquee', bq);
|
||||
ref = $$('.abbr + br, .exif, b, .fortune', bq);
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
node = ref[k];
|
||||
$.rm(node);
|
||||
}
|
||||
if (abbr = $('.abbr', bq)) {
|
||||
$.rm(abbr);
|
||||
}
|
||||
this.info.comment = this.nodesToText(bq);
|
||||
spoilers = $$('s', bq);
|
||||
return this.info.commentSpoilered = (function() {
|
||||
var len2, q;
|
||||
if (abbr) {
|
||||
this.info.comment = this.info.comment.replace(/\n\n$/, '');
|
||||
}
|
||||
commentDisplay = this.info.comment;
|
||||
if (!(Conf['Remove Spoilers'] || Conf['Reveal Spoilers'])) {
|
||||
spoilers = $$('s', bq);
|
||||
if (spoilers.length) {
|
||||
for (q = 0, len2 = spoilers.length; q < len2; q++) {
|
||||
node = spoilers[q];
|
||||
$.replace(node, $.tn('[spoiler]'));
|
||||
}
|
||||
return this.nodesToText(bq);
|
||||
} else {
|
||||
return this.info.comment;
|
||||
commentDisplay = this.nodesToText(bq);
|
||||
}
|
||||
}).call(this);
|
||||
}
|
||||
return this.info.commentDisplay = commentDisplay.trim().replace(/\s+$/gm, '');
|
||||
};
|
||||
|
||||
Post.prototype.nodesToText = function(bq) {
|
||||
@ -1323,7 +1333,7 @@
|
||||
while (node = nodes.snapshotItem(i++)) {
|
||||
text += node.data || '\n';
|
||||
}
|
||||
return text.trim().replace(/\s+$/gm, '');
|
||||
return text;
|
||||
};
|
||||
|
||||
Post.prototype.parseQuotes = function() {
|
||||
@ -4298,7 +4308,7 @@
|
||||
threadExcerpt: function(thread) {
|
||||
var OP, excerpt, ref;
|
||||
OP = thread.OP;
|
||||
excerpt = ("/" + thread.board + "/ - ") + (((ref = OP.info.subject) != null ? ref.trim() : void 0) || OP.info.comment.replace(/\n+/g, ' // ') || OP.info.nameBlock);
|
||||
excerpt = ("/" + thread.board + "/ - ") + (((ref = OP.info.subject) != null ? ref.trim() : void 0) || OP.info.commentDisplay.replace(/\n+/g, ' // ') || OP.info.nameBlock);
|
||||
if (excerpt.length > 73) {
|
||||
return excerpt.slice(0, 70) + "...";
|
||||
}
|
||||
@ -5070,18 +5080,18 @@
|
||||
},
|
||||
node: function() {
|
||||
var filter, k, key, len1, ref, ref1, result, value;
|
||||
if (this.isClone || this.isFetchedQuote) {
|
||||
if (this.isClone) {
|
||||
return;
|
||||
}
|
||||
for (key in Filter.filters) {
|
||||
if ((value = Filter[key](this)) !== false) {
|
||||
if ((value = Filter[key](this)) != null) {
|
||||
ref = Filter.filters[key];
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
filter = ref[k];
|
||||
if (!(result = filter(value, this.isReply))) {
|
||||
continue;
|
||||
}
|
||||
if (result.hide) {
|
||||
if (result.hide && !this.isFetchedQuote) {
|
||||
if (this.isReply) {
|
||||
PostHiding.hide(this, result.stub);
|
||||
} else if (g.VIEW === 'index') {
|
||||
@ -5103,73 +5113,41 @@
|
||||
}
|
||||
},
|
||||
name: function(post) {
|
||||
if ('name' in post.info) {
|
||||
return post.info.name;
|
||||
}
|
||||
return false;
|
||||
return post.info.name;
|
||||
},
|
||||
uniqueID: function(post) {
|
||||
if ('uniqueID' in post.info) {
|
||||
return post.info.uniqueID;
|
||||
}
|
||||
return false;
|
||||
return post.info.uniqueID;
|
||||
},
|
||||
tripcode: function(post) {
|
||||
if ('tripcode' in post.info) {
|
||||
return post.info.tripcode;
|
||||
}
|
||||
return false;
|
||||
return post.info.tripcode;
|
||||
},
|
||||
capcode: function(post) {
|
||||
if ('capcode' in post.info) {
|
||||
return post.info.capcode;
|
||||
}
|
||||
return false;
|
||||
return post.info.capcode;
|
||||
},
|
||||
subject: function(post) {
|
||||
if ('subject' in post.info) {
|
||||
return post.info.subject || false;
|
||||
}
|
||||
return false;
|
||||
return post.info.subject || void 0;
|
||||
},
|
||||
comment: function(post) {
|
||||
if ('comment' in post.info) {
|
||||
return post.info.comment;
|
||||
}
|
||||
return false;
|
||||
return post.info.comment;
|
||||
},
|
||||
flag: function(post) {
|
||||
if ('flag' in post.info) {
|
||||
return post.info.flag;
|
||||
}
|
||||
return false;
|
||||
return post.info.flag;
|
||||
},
|
||||
filename: function(post) {
|
||||
if (post.file) {
|
||||
return post.file.name;
|
||||
}
|
||||
return false;
|
||||
var ref;
|
||||
return (ref = post.file) != null ? ref.name : void 0;
|
||||
},
|
||||
dimensions: function(post) {
|
||||
var file;
|
||||
file = post.file;
|
||||
if (file != null ? file.dimensions : void 0) {
|
||||
return file.dimensions;
|
||||
}
|
||||
return false;
|
||||
var ref;
|
||||
return (ref = post.file) != null ? ref.dimensions : void 0;
|
||||
},
|
||||
filesize: function(post) {
|
||||
if (post.file) {
|
||||
return post.file.size;
|
||||
}
|
||||
return false;
|
||||
var ref;
|
||||
return (ref = post.file) != null ? ref.size : void 0;
|
||||
},
|
||||
MD5: function(post) {
|
||||
var ref;
|
||||
if ((ref = post.file) != null ? ref.MD5 : void 0) {
|
||||
return post.file.MD5;
|
||||
}
|
||||
return false;
|
||||
return (ref = post.file) != null ? ref.MD5 : void 0;
|
||||
},
|
||||
menu: {
|
||||
init: function() {
|
||||
@ -5209,7 +5187,7 @@
|
||||
open: function(post) {
|
||||
var value;
|
||||
value = Filter[type](post);
|
||||
return value !== false;
|
||||
return value != null;
|
||||
}
|
||||
};
|
||||
},
|
||||
@ -6696,8 +6674,8 @@
|
||||
if (g.VIEW === 'archive') {
|
||||
return;
|
||||
}
|
||||
$.globalEval('document.documentElement.dataset.jsEnabled = true;');
|
||||
noscript = Conf['Force Noscript Captcha'] || !doc.dataset.jsEnabled;
|
||||
$.globalEval('document.documentElement.classList.add("js-enabled");');
|
||||
noscript = Conf['Force Noscript Captcha'] || !$.hasClass(doc, 'js-enabled');
|
||||
this.captcha = Captcha[noscript ? 'noscript' : 'v2'];
|
||||
$.on(d, '4chanXInitFinished', this.initReady);
|
||||
Post.callbacks.push({
|
||||
@ -6726,7 +6704,7 @@
|
||||
}
|
||||
if (Conf['Hide Original Post Form']) {
|
||||
$.addClass(doc, 'hide-original-post-form');
|
||||
if (!doc.dataset.jsEnabled) {
|
||||
if (!$.hasClass(doc, 'js-enabled')) {
|
||||
return $.onExists(doc, '#postForm noscript', true, $.rm);
|
||||
}
|
||||
}
|
||||
@ -7630,6 +7608,104 @@
|
||||
|
||||
Captcha = {};
|
||||
|
||||
Captcha.fixes = {
|
||||
css: '.rc-imageselect-target > .rc-imageselect-tile > img:focus {\n outline: 2px solid #4a90e2;\n}\n.rc-button-default:focus {\n box-shadow: inset 0 0 0 2px #0063d6;\n}',
|
||||
init: function() {
|
||||
switch (location.pathname.split('/')[3]) {
|
||||
case 'anchor':
|
||||
return this.initMain();
|
||||
case 'frame':
|
||||
return this.initPopup();
|
||||
}
|
||||
},
|
||||
initMain: function() {
|
||||
return $.onExists(d.body, '#recaptcha-anchor', true, function(checkbox) {
|
||||
var focus;
|
||||
focus = function() {
|
||||
if (d.hasFocus() && d.activeElement !== checkbox) {
|
||||
return checkbox.focus();
|
||||
}
|
||||
};
|
||||
focus();
|
||||
return $.on(window, 'focus', function() {
|
||||
return $.queueTask(focus);
|
||||
});
|
||||
});
|
||||
},
|
||||
initPopup: function() {
|
||||
$.addStyle(this.css);
|
||||
this.fixImages();
|
||||
new MutationObserver((function(_this) {
|
||||
return function() {
|
||||
return _this.fixImages();
|
||||
};
|
||||
})(this)).observe(d.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
return $.on(d, 'keydown', this.keybinds.bind(this));
|
||||
},
|
||||
fixImages: function() {
|
||||
var focus, img, k, len1, ref;
|
||||
if (!(this.images = $$('.rc-imageselect-target > .rc-imageselect-tile > img')).length) {
|
||||
return;
|
||||
}
|
||||
focus = this.images[0].tabIndex !== 0;
|
||||
ref = this.images;
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
img = ref[k];
|
||||
img.tabIndex = 0;
|
||||
}
|
||||
if (focus) {
|
||||
return this.focusImage();
|
||||
}
|
||||
},
|
||||
focusImage: function() {
|
||||
var img;
|
||||
img = this.images[0];
|
||||
return $.asap(function() {
|
||||
if (!doc.contains(img)) {
|
||||
return true;
|
||||
}
|
||||
img.focus();
|
||||
return d.activeElement === img;
|
||||
}, function() {});
|
||||
},
|
||||
keybinds: function(e) {
|
||||
var dx, reload, verify, x;
|
||||
if (!(this.images && doc.contains(this.images[0]) && d.activeElement)) {
|
||||
return;
|
||||
}
|
||||
reload = $.id('recaptcha-reload-button');
|
||||
verify = $.id('recaptcha-verify-button');
|
||||
x = this.images.indexOf(d.activeElement);
|
||||
if (x < 0) {
|
||||
if (!$('.rc-controls').contains(d.activeElement)) {
|
||||
return;
|
||||
}
|
||||
x = d.activeElement === verify ? 11 : 9;
|
||||
}
|
||||
if (!(dx = {
|
||||
38: 9,
|
||||
40: 3,
|
||||
37: 11,
|
||||
39: 1
|
||||
}[e.keyCode])) {
|
||||
return;
|
||||
}
|
||||
x = (x + dx) % 12;
|
||||
if (x === 10) {
|
||||
x = dx === 11 ? 9 : 11;
|
||||
}
|
||||
(this.images[x] || {
|
||||
9: reload,
|
||||
11: verify
|
||||
}[x]).focus();
|
||||
e.preventDefault();
|
||||
return e.stopPropagation();
|
||||
}
|
||||
};
|
||||
|
||||
Captcha.noscript = {
|
||||
lifetime: 2 * $.MINUTE,
|
||||
iframeURL: '//www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc',
|
||||
@ -7989,20 +8065,6 @@
|
||||
};
|
||||
})(this));
|
||||
},
|
||||
initFrame: function() {
|
||||
$.globalEval('window.focus = function() {};');
|
||||
return $.on(window, 'focus', function() {
|
||||
return $.queueTask(function() {
|
||||
var checkbox;
|
||||
if (!(d.hasFocus() && (checkbox = $.id('recaptcha-anchor')))) {
|
||||
return;
|
||||
}
|
||||
if (d.activeElement !== checkbox) {
|
||||
return checkbox.focus();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
shouldFocus: false,
|
||||
timeouts: {},
|
||||
postsCount: 0,
|
||||
@ -8102,6 +8164,7 @@
|
||||
})(this));
|
||||
},
|
||||
destroy: function() {
|
||||
var garbage, ins, k, len1, ref;
|
||||
if (!this.isEnabled) {
|
||||
return;
|
||||
}
|
||||
@ -8110,7 +8173,15 @@
|
||||
if (this.nodes.container) {
|
||||
$.rm(this.nodes.container);
|
||||
}
|
||||
return delete this.nodes.container;
|
||||
delete this.nodes.container;
|
||||
ref = $$('div > .gc-bubbleDefault');
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
garbage = ref[k];
|
||||
if ((ins = garbage.parentNode.nextSibling) && ins.nodeName === 'INS') {
|
||||
$.rm(ins);
|
||||
}
|
||||
$.rm(garbage.parentNode);
|
||||
}
|
||||
},
|
||||
sync: function(captchas) {
|
||||
if (captchas == null) {
|
||||
@ -8132,7 +8203,7 @@
|
||||
}
|
||||
},
|
||||
save: function(pasted) {
|
||||
var base1;
|
||||
var base1, focus, ref, ref1;
|
||||
$.forceSync('captchas');
|
||||
this.captchas.push({
|
||||
response: $('textarea', this.nodes.container).value,
|
||||
@ -8148,6 +8219,7 @@
|
||||
}
|
||||
this.reload();
|
||||
} else {
|
||||
focus = ((ref = d.activeElement) != null ? ref.nodeName : void 0) === 'IFRAME' && ((ref1 = d.activeElement.src) != null ? ref1.slice(0, 38) : void 0) === 'https://www.google.com/recaptcha/api2/';
|
||||
if (pasted) {
|
||||
this.destroy();
|
||||
} else {
|
||||
@ -8155,7 +8227,9 @@
|
||||
base1.destroy = setTimeout(this.destroy.bind(this), 3 * $.SECOND);
|
||||
}
|
||||
}
|
||||
QR.nodes.status.focus();
|
||||
if (focus) {
|
||||
QR.nodes.status.focus();
|
||||
}
|
||||
}
|
||||
if (Conf['Post on Captcha Completion'] && !QR.cooldown.auto) {
|
||||
return QR.submit();
|
||||
@ -11441,7 +11515,7 @@
|
||||
},
|
||||
subEntries: []
|
||||
};
|
||||
ref1 = [['Post', 'post'], ['Name', 'name'], ['Tripcode', 'tripcode'], ['Subject', 'subject'], ['Filename', 'filename'], ['Image MD5', 'MD5']];
|
||||
ref1 = [['Post', 'post'], ['Name', 'name'], ['Tripcode', 'tripcode'], ['Capcode', 'capcode'], ['Subject', 'subject'], ['Filename', 'filename'], ['Image MD5', 'MD5']];
|
||||
for (k = 0, len1 = ref1.length; k < len1; k++) {
|
||||
type = ref1[k];
|
||||
entry.subEntries.push(this.createSubEntry(type[0], type[1]));
|
||||
@ -11708,17 +11782,19 @@
|
||||
el: a,
|
||||
order: 10,
|
||||
open: function(post) {
|
||||
ReportLink.post = post;
|
||||
return !post.isDead;
|
||||
ReportLink.url = !post.isDead ? "//sys.4chan.org/" + post.board + "/imgboard.php?mode=report&no=" + post : Conf['Archive Report'] ? Redirect.to('report', {
|
||||
boardID: post.board.ID,
|
||||
postID: post.ID
|
||||
}) : void 0;
|
||||
return !!ReportLink.url;
|
||||
}
|
||||
});
|
||||
},
|
||||
report: function() {
|
||||
var id, post, set, url;
|
||||
post = ReportLink.post;
|
||||
url = "//sys.4chan.org/" + post.board + "/imgboard.php?mode=report&no=" + post;
|
||||
var id, set, url;
|
||||
url = ReportLink.url;
|
||||
id = Date.now();
|
||||
set = "toolbar=0,scrollbars=0,location=0,status=1,menubar=0,resizable=1,width=685,height=285";
|
||||
set = "toolbar=0,scrollbars=1,location=0,status=1,menubar=0,resizable=1,width=685,height=200";
|
||||
return window.open(url, id, set);
|
||||
}
|
||||
};
|
||||
@ -13271,7 +13347,7 @@
|
||||
return;
|
||||
}
|
||||
notif = new Notification(post.info.nameBlock + " replied to you", {
|
||||
body: post.info[Conf['Remove Spoilers'] || Conf['Reveal Spoilers'] ? 'comment' : 'commentSpoilered'],
|
||||
body: post.info.commentDisplay,
|
||||
icon: Favicon.logo
|
||||
});
|
||||
notif.onclick = function() {
|
||||
@ -13411,7 +13487,8 @@
|
||||
o = {
|
||||
thread: {},
|
||||
post: {},
|
||||
file: {}
|
||||
file: {},
|
||||
report: {}
|
||||
};
|
||||
archives = {};
|
||||
ref = Redirect.archives;
|
||||
@ -13421,17 +13498,19 @@
|
||||
archives[name] = data;
|
||||
for (q = 0, len2 = boards.length; q < len2; q++) {
|
||||
boardID = boards[q];
|
||||
if (!(!withCredentials)) {
|
||||
continue;
|
||||
if (!withCredentials) {
|
||||
if (!(boardID in o.thread)) {
|
||||
o.thread[boardID] = data;
|
||||
}
|
||||
if (!(boardID in o.post || software !== 'foolfuuka')) {
|
||||
o.post[boardID] = data;
|
||||
}
|
||||
if (!(boardID in o.file || indexOf.call(files, boardID) < 0)) {
|
||||
o.file[boardID] = data;
|
||||
}
|
||||
}
|
||||
if (!(boardID in o.thread)) {
|
||||
o.thread[boardID] = data;
|
||||
}
|
||||
if (!(boardID in o.post || software !== 'foolfuuka')) {
|
||||
o.post[boardID] = data;
|
||||
}
|
||||
if (!(boardID in o.file || indexOf.call(files, boardID) < 0)) {
|
||||
o.file[boardID] = data;
|
||||
if (name === 'fgts') {
|
||||
o.report[boardID] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13452,7 +13531,7 @@
|
||||
}
|
||||
return Redirect.data = o;
|
||||
},
|
||||
archives: [{"uid":0,"name":"Moe","domain":"archive.moe","http":false,"https":true,"software":"foolfuuka","boards":["a","biz","c","co","diy","fit","gd","h","i","int","jp","k","m","mlp","out","po","qa","r9k","s4s","sci","tg","tv","u","v","vg","vp","vr","wsg"],"files":["a","biz","c","co","diy","fit","gd","h","i","jp","k","m","mlp","po","qa","r9k","s4s","sci","tg","u","v","vg","vp","vr","wsg"]},{"uid":3,"name":"4plebs Archive","domain":"archive.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["adv","f","hr","o","pol","s4s","tg","trv","tv","x"],"files":["adv","f","hr","o","pol","s4s","tg","trv","tv","x"]},{"uid":4,"name":"Nyafuu Archive","domain":"archive.nyafuu.org","http":true,"https":true,"software":"foolfuuka","boards":["c","e","w","wg"],"files":["c","e","w","wg"]},{"uid":5,"name":"Love is Over","domain":"archive.loveisover.me","http":true,"https":true,"software":"foolfuuka","boards":["c","d","e","i","lgbt","t","u","w","wg"],"files":["c","d","e","i","lgbt","t","u","w","wg"]},{"uid":8,"name":"Rebecca Black Tech","domain":"rbt.asia","http":false,"https":true,"software":"fuuka","boards":["cgl","g","mu","qa","w"],"files":["cgl","g","mu","qa","w"]},{"uid":10,"name":"warosu","domain":"warosu.org","http":false,"https":true,"software":"fuuka","boards":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"],"files":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"]},{"uid":15,"name":"fgts","domain":"fgts.jp","http":true,"https":true,"software":"foolfuuka","boards":["asp","b","cm","h","hc","hm","n","p","qa","r","s","soc","toy","y"],"files":["asp","b","cm","h","hc","hm","n","p","qa","r","s","soc","toy","y"]},{"uid":22,"name":"not4plebs","domain":"totally.not4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["sp"],"files":["sp"]},{"uid":23,"name":"DesuStorage","domain":"archive.desustorage.org","http":false,"https":true,"software":"foolfuuka","boards":["mlp","qa"],"files":["mlp","qa"]}],
|
||||
archives: [{"uid":0,"name":"Moe","domain":"archive.moe","http":false,"https":true,"software":"foolfuuka","boards":["a","biz","c","co","diy","fit","gd","gif","h","i","int","jp","k","m","mlp","out","po","qa","r9k","s4s","sci","tg","tv","u","v","vg","vp","vr","wsg"],"files":["a","biz","c","co","diy","fit","gd","h","i","jp","k","m","mlp","po","qa","r9k","s4s","sci","tg","u","v","vg","vp","vr","wsg"]},{"uid":3,"name":"4plebs Archive","domain":"archive.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["adv","f","hr","o","pol","s4s","tg","trv","tv","x"],"files":["adv","f","hr","o","pol","s4s","tg","trv","tv","x"]},{"uid":4,"name":"Nyafuu Archive","domain":"archive.nyafuu.org","http":true,"https":true,"software":"foolfuuka","boards":["c","e","w","wg"],"files":["c","e","w","wg"]},{"uid":5,"name":"Love is Over","domain":"archive.loveisover.me","http":true,"https":true,"software":"foolfuuka","boards":["c","d","e","i","lgbt","t","u"],"files":["c","d","e","i","lgbt","t","u"]},{"uid":8,"name":"Rebecca Black Tech","domain":"rbt.asia","http":false,"https":true,"software":"fuuka","boards":["cgl","g","mu","qa","w"],"files":["cgl","g","mu","qa","w"]},{"uid":10,"name":"warosu","domain":"warosu.org","http":false,"https":true,"software":"fuuka","boards":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"],"files":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"]},{"uid":15,"name":"fgts","domain":"fgts.jp","http":true,"https":true,"software":"foolfuuka","boards":["asp","b","cm","h","hc","hm","n","p","qa","r","s","soc","toy","y"],"files":["asp","b","cm","h","hc","hm","n","p","qa","r","s","soc","toy","y"]},{"uid":22,"name":"not4plebs","domain":"totally.not4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["sp"],"files":["sp"]},{"uid":23,"name":"DesuStorage","domain":"archive.desustorage.org","http":false,"https":true,"software":"foolfuuka","boards":["mlp","qa"],"files":["mlp","qa"]}],
|
||||
to: function(dest, data) {
|
||||
var archive;
|
||||
archive = (dest === 'search' || dest === 'board' ? Redirect.data.thread : Redirect.data[dest])[data.boardID];
|
||||
@ -13506,10 +13585,20 @@
|
||||
var boardID, path, type, value;
|
||||
boardID = arg.boardID, type = arg.type, value = arg.value;
|
||||
type = type === 'name' ? 'username' : type === 'MD5' ? 'image' : type;
|
||||
if (type === 'capcode') {
|
||||
value = {
|
||||
'Developer': 'dev'
|
||||
}[value] || value.toLowerCase();
|
||||
}
|
||||
value = encodeURIComponent(value);
|
||||
path = archive.software === 'foolfuuka' ? boardID + "/search/" + type + "/" + value : boardID + "/?task=search2&search_" + (type === 'image' ? 'media_hash' : type) + "=" + value;
|
||||
return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path;
|
||||
},
|
||||
report: function(archive, arg) {
|
||||
var boardID, postID;
|
||||
boardID = arg.boardID, postID = arg.postID;
|
||||
return "https://so.fgts.jp/report/?board=" + boardID + "&no=" + postID;
|
||||
},
|
||||
securityCheck: function(URL) {
|
||||
return /^https:\/\//.test(URL) || location.protocol === 'http:' || Conf['Except Archives from Encryption'];
|
||||
},
|
||||
@ -15229,6 +15318,63 @@
|
||||
}
|
||||
};
|
||||
|
||||
Report = {
|
||||
init: function() {
|
||||
var match;
|
||||
if (!(/\bmode=report\b/.test(location.search) && (match = location.search.match(/\bno=(\d+)/)))) {
|
||||
return;
|
||||
}
|
||||
this.postID = +match[1];
|
||||
return $.ready(this.ready);
|
||||
},
|
||||
ready: function() {
|
||||
new MutationObserver(Report.resize).observe(d.body, {
|
||||
childList: true,
|
||||
attributes: true,
|
||||
subtree: true
|
||||
});
|
||||
if (Conf['Archive Report']) {
|
||||
return Report.archive();
|
||||
}
|
||||
},
|
||||
resize: function() {
|
||||
var bubble, dy;
|
||||
if (!(bubble = $('.gc-bubbleDefault'))) {
|
||||
return;
|
||||
}
|
||||
dy = bubble.getBoundingClientRect().bottom - doc.clientHeight;
|
||||
if (dy > 0) {
|
||||
return window.resizeBy(0, dy);
|
||||
}
|
||||
},
|
||||
archive: function() {
|
||||
var link, message, url;
|
||||
Redirect.init();
|
||||
if (!(url = Redirect.to('report', {
|
||||
boardID: g.BOARD.ID,
|
||||
postID: Report.postID
|
||||
}))) {
|
||||
return;
|
||||
}
|
||||
if ((message = $('h3')) && /Report submitted!/.test(message.textContent)) {
|
||||
$.globalEval('self.close = function(){};');
|
||||
window.resizeTo(685, 320);
|
||||
location.replace(url);
|
||||
return;
|
||||
}
|
||||
link = $.el('a', {
|
||||
href: url,
|
||||
textContent: 'Report to fgts'
|
||||
});
|
||||
$.on(link, 'click', function(e) {
|
||||
if (!(e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0)) {
|
||||
return window.resizeTo(685, 320);
|
||||
}
|
||||
});
|
||||
return $.add(d.body, [$.tn(' ['), link, $.tn(']')]);
|
||||
}
|
||||
};
|
||||
|
||||
Time = {
|
||||
init: function() {
|
||||
var ref;
|
||||
@ -16018,12 +16164,24 @@
|
||||
|
||||
Main = {
|
||||
init: function() {
|
||||
var db, flatten, k, len1, pathname, ref, ref1, ref2, type;
|
||||
var db, flatten, k, len1, pathname, ref, ref1, ref2;
|
||||
if (location.hostname === 'www.google.com') {
|
||||
type = location.pathname === '/recaptcha/api/fallback' ? 'noscript' : 'v2';
|
||||
return $.ready(function() {
|
||||
return Captcha[type].initFrame();
|
||||
});
|
||||
if (location.pathname === '/recaptcha/api/fallback') {
|
||||
$.ready(function() {
|
||||
return Captcha.noscript.initFrame();
|
||||
});
|
||||
} else {
|
||||
$.get('Captcha Fixes', true, function(arg) {
|
||||
var enabled;
|
||||
enabled = arg['Captcha Fixes'];
|
||||
if (enabled) {
|
||||
return $.ready(function() {
|
||||
return Captcha.fixes.init();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
g.threads = new SimpleDict();
|
||||
g.posts = new SimpleDict();
|
||||
@ -16097,6 +16255,7 @@
|
||||
case 'a.4cdn.org':
|
||||
return;
|
||||
case 'sys.4chan.org':
|
||||
Report.init();
|
||||
if (g.VIEW === 'post') {
|
||||
PostSuccessful.init();
|
||||
}
|
||||
@ -17096,10 +17255,8 @@
|
||||
" /* party hats */\n" +
|
||||
" pointer-events: none;\n" +
|
||||
"}\n" +
|
||||
"marquee,\n" +
|
||||
".postMessage marquee + br,\n" +
|
||||
".postMessage marquee + br + br {\n" +
|
||||
" display: none;\n" +
|
||||
":root:not(.js-enabled) #postForm {\n" +
|
||||
" display: table;\n" +
|
||||
"}\n" +
|
||||
"/* Anti-autoplay */\n" +
|
||||
"audio.controls-added {\n" +
|
||||
|
||||
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.10.8.9
|
||||
// @version 1.10.11.1
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -12,6 +12,7 @@
|
||||
// @match *://a.4cdn.org/*
|
||||
// @match *://i.4cdn.org/*
|
||||
// @match https://www.google.com/recaptcha/api2/anchor?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*
|
||||
// @match https://www.google.com/recaptcha/api2/frame?*&k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*
|
||||
// @match *://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc
|
||||
// @grant GM_getValue
|
||||
// @grant GM_setValue
|
||||
@ -108,7 +109,7 @@
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var $, $$, Anonymize, AntiAutoplay, ArchiveLink, Banner, Board, Build, Callbacks, Captcha, CatalogLinks, CatalogThread, Clone, Conf, Config, Connection, CrossOrigin, CustomCSS, DataBoard, DeleteLink, DownloadLink, E, Embedding, ExpandComment, ExpandThread, FappeTyme, Favicon, Fetcher, FileInfo, Filter, Flash, Fourchan, Gallery, Get, Header, IDColor, IDHighlight, ImageCommon, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, MarkNewIPs, Menu, Metadata, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, PostSuccessful, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, ReportLink, RevealSpoilers, Sauce, Settings, ShimSet, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, Volume, c, d, doc, g,
|
||||
var $, $$, Anonymize, AntiAutoplay, ArchiveLink, Banner, Board, Build, Callbacks, Captcha, CatalogLinks, CatalogThread, Clone, Conf, Config, Connection, CrossOrigin, CustomCSS, DataBoard, DeleteLink, DownloadLink, E, Embedding, ExpandComment, ExpandThread, FappeTyme, Favicon, Fetcher, FileInfo, Filter, Flash, Fourchan, Gallery, Get, Header, IDColor, IDHighlight, ImageCommon, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, MarkNewIPs, Menu, Metadata, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, PostSuccessful, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, ShimSet, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, Volume, c, d, doc, g,
|
||||
slice = [].slice,
|
||||
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
|
||||
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
||||
@ -126,6 +127,7 @@
|
||||
'Announcement Hiding': [true, 'Add button to hide 4chan announcements.'],
|
||||
'Desktop Notifications': [true, 'Enables desktop notifications across various 4chan X features.'],
|
||||
'404 Redirect': [true, 'Redirect dead threads and images to the archives.'],
|
||||
'Archive Report': [true, 'Enable reporting posts to supported archives.'],
|
||||
'Except Archives from Encryption': [false, 'Permit loading content from, and warningless redirects to, HTTP-only archives from HTTPS pages.'],
|
||||
'Keybinds': [true, 'Bind actions to keyboard shortcuts.'],
|
||||
'Time Formatting': [true, 'Localize and format timestamps.'],
|
||||
@ -234,7 +236,8 @@
|
||||
'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],
|
||||
'Bottom QR Link': [true, 'Places a link on the bottom of threads to open the QR.', 1]
|
||||
'Bottom QR Link': [true, 'Places a link on the bottom of threads to open the QR.', 1],
|
||||
'Captcha Fixes': [true, 'Make captcha more keyboard-navigable.']
|
||||
},
|
||||
'Quote Links': {
|
||||
'Quote Backlinks': [true, 'Add quote backlinks.'],
|
||||
@ -395,7 +398,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.10.8.9',
|
||||
VERSION: '1.10.11.1',
|
||||
NAMESPACE: '4chan X.',
|
||||
boards: {}
|
||||
};
|
||||
@ -626,9 +629,11 @@
|
||||
$.addStyle = function(css, id, test) {
|
||||
var style;
|
||||
style = $.el('style', {
|
||||
id: id,
|
||||
textContent: css
|
||||
});
|
||||
if (id != null) {
|
||||
style.id = id;
|
||||
}
|
||||
$.asap((function() {
|
||||
return d.head && ((test == null) || test());
|
||||
}), function() {
|
||||
@ -1290,28 +1295,33 @@
|
||||
}
|
||||
|
||||
Post.prototype.parseComment = function() {
|
||||
var bq, k, len1, node, ref, spoilers;
|
||||
var abbr, bq, commentDisplay, k, len1, len2, node, q, ref, spoilers;
|
||||
this.nodes.comment.normalize();
|
||||
bq = this.nodes.comment.cloneNode(true);
|
||||
ref = $$('.abbr, .exif, b, marquee', bq);
|
||||
ref = $$('.abbr + br, .exif, b, .fortune', bq);
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
node = ref[k];
|
||||
$.rm(node);
|
||||
}
|
||||
if (abbr = $('.abbr', bq)) {
|
||||
$.rm(abbr);
|
||||
}
|
||||
this.info.comment = this.nodesToText(bq);
|
||||
spoilers = $$('s', bq);
|
||||
return this.info.commentSpoilered = (function() {
|
||||
var len2, q;
|
||||
if (abbr) {
|
||||
this.info.comment = this.info.comment.replace(/\n\n$/, '');
|
||||
}
|
||||
commentDisplay = this.info.comment;
|
||||
if (!(Conf['Remove Spoilers'] || Conf['Reveal Spoilers'])) {
|
||||
spoilers = $$('s', bq);
|
||||
if (spoilers.length) {
|
||||
for (q = 0, len2 = spoilers.length; q < len2; q++) {
|
||||
node = spoilers[q];
|
||||
$.replace(node, $.tn('[spoiler]'));
|
||||
}
|
||||
return this.nodesToText(bq);
|
||||
} else {
|
||||
return this.info.comment;
|
||||
commentDisplay = this.nodesToText(bq);
|
||||
}
|
||||
}).call(this);
|
||||
}
|
||||
return this.info.commentDisplay = commentDisplay.trim().replace(/\s+$/gm, '');
|
||||
};
|
||||
|
||||
Post.prototype.nodesToText = function(bq) {
|
||||
@ -1322,7 +1332,7 @@
|
||||
while (node = nodes.snapshotItem(i++)) {
|
||||
text += node.data || '\n';
|
||||
}
|
||||
return text.trim().replace(/\s+$/gm, '');
|
||||
return text;
|
||||
};
|
||||
|
||||
Post.prototype.parseQuotes = function() {
|
||||
@ -4297,7 +4307,7 @@
|
||||
threadExcerpt: function(thread) {
|
||||
var OP, excerpt, ref;
|
||||
OP = thread.OP;
|
||||
excerpt = ("/" + thread.board + "/ - ") + (((ref = OP.info.subject) != null ? ref.trim() : void 0) || OP.info.comment.replace(/\n+/g, ' // ') || OP.info.nameBlock);
|
||||
excerpt = ("/" + thread.board + "/ - ") + (((ref = OP.info.subject) != null ? ref.trim() : void 0) || OP.info.commentDisplay.replace(/\n+/g, ' // ') || OP.info.nameBlock);
|
||||
if (excerpt.length > 73) {
|
||||
return excerpt.slice(0, 70) + "...";
|
||||
}
|
||||
@ -5069,18 +5079,18 @@
|
||||
},
|
||||
node: function() {
|
||||
var filter, k, key, len1, ref, ref1, result, value;
|
||||
if (this.isClone || this.isFetchedQuote) {
|
||||
if (this.isClone) {
|
||||
return;
|
||||
}
|
||||
for (key in Filter.filters) {
|
||||
if ((value = Filter[key](this)) !== false) {
|
||||
if ((value = Filter[key](this)) != null) {
|
||||
ref = Filter.filters[key];
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
filter = ref[k];
|
||||
if (!(result = filter(value, this.isReply))) {
|
||||
continue;
|
||||
}
|
||||
if (result.hide) {
|
||||
if (result.hide && !this.isFetchedQuote) {
|
||||
if (this.isReply) {
|
||||
PostHiding.hide(this, result.stub);
|
||||
} else if (g.VIEW === 'index') {
|
||||
@ -5102,73 +5112,41 @@
|
||||
}
|
||||
},
|
||||
name: function(post) {
|
||||
if ('name' in post.info) {
|
||||
return post.info.name;
|
||||
}
|
||||
return false;
|
||||
return post.info.name;
|
||||
},
|
||||
uniqueID: function(post) {
|
||||
if ('uniqueID' in post.info) {
|
||||
return post.info.uniqueID;
|
||||
}
|
||||
return false;
|
||||
return post.info.uniqueID;
|
||||
},
|
||||
tripcode: function(post) {
|
||||
if ('tripcode' in post.info) {
|
||||
return post.info.tripcode;
|
||||
}
|
||||
return false;
|
||||
return post.info.tripcode;
|
||||
},
|
||||
capcode: function(post) {
|
||||
if ('capcode' in post.info) {
|
||||
return post.info.capcode;
|
||||
}
|
||||
return false;
|
||||
return post.info.capcode;
|
||||
},
|
||||
subject: function(post) {
|
||||
if ('subject' in post.info) {
|
||||
return post.info.subject || false;
|
||||
}
|
||||
return false;
|
||||
return post.info.subject || void 0;
|
||||
},
|
||||
comment: function(post) {
|
||||
if ('comment' in post.info) {
|
||||
return post.info.comment;
|
||||
}
|
||||
return false;
|
||||
return post.info.comment;
|
||||
},
|
||||
flag: function(post) {
|
||||
if ('flag' in post.info) {
|
||||
return post.info.flag;
|
||||
}
|
||||
return false;
|
||||
return post.info.flag;
|
||||
},
|
||||
filename: function(post) {
|
||||
if (post.file) {
|
||||
return post.file.name;
|
||||
}
|
||||
return false;
|
||||
var ref;
|
||||
return (ref = post.file) != null ? ref.name : void 0;
|
||||
},
|
||||
dimensions: function(post) {
|
||||
var file;
|
||||
file = post.file;
|
||||
if (file != null ? file.dimensions : void 0) {
|
||||
return file.dimensions;
|
||||
}
|
||||
return false;
|
||||
var ref;
|
||||
return (ref = post.file) != null ? ref.dimensions : void 0;
|
||||
},
|
||||
filesize: function(post) {
|
||||
if (post.file) {
|
||||
return post.file.size;
|
||||
}
|
||||
return false;
|
||||
var ref;
|
||||
return (ref = post.file) != null ? ref.size : void 0;
|
||||
},
|
||||
MD5: function(post) {
|
||||
var ref;
|
||||
if ((ref = post.file) != null ? ref.MD5 : void 0) {
|
||||
return post.file.MD5;
|
||||
}
|
||||
return false;
|
||||
return (ref = post.file) != null ? ref.MD5 : void 0;
|
||||
},
|
||||
menu: {
|
||||
init: function() {
|
||||
@ -5208,7 +5186,7 @@
|
||||
open: function(post) {
|
||||
var value;
|
||||
value = Filter[type](post);
|
||||
return value !== false;
|
||||
return value != null;
|
||||
}
|
||||
};
|
||||
},
|
||||
@ -6695,8 +6673,8 @@
|
||||
if (g.VIEW === 'archive') {
|
||||
return;
|
||||
}
|
||||
$.globalEval('document.documentElement.dataset.jsEnabled = true;');
|
||||
noscript = Conf['Force Noscript Captcha'] || !doc.dataset.jsEnabled;
|
||||
$.globalEval('document.documentElement.classList.add("js-enabled");');
|
||||
noscript = Conf['Force Noscript Captcha'] || !$.hasClass(doc, 'js-enabled');
|
||||
this.captcha = Captcha[noscript ? 'noscript' : 'v2'];
|
||||
$.on(d, '4chanXInitFinished', this.initReady);
|
||||
Post.callbacks.push({
|
||||
@ -6725,7 +6703,7 @@
|
||||
}
|
||||
if (Conf['Hide Original Post Form']) {
|
||||
$.addClass(doc, 'hide-original-post-form');
|
||||
if (!doc.dataset.jsEnabled) {
|
||||
if (!$.hasClass(doc, 'js-enabled')) {
|
||||
return $.onExists(doc, '#postForm noscript', true, $.rm);
|
||||
}
|
||||
}
|
||||
@ -7629,6 +7607,104 @@
|
||||
|
||||
Captcha = {};
|
||||
|
||||
Captcha.fixes = {
|
||||
css: '.rc-imageselect-target > .rc-imageselect-tile > img:focus {\n outline: 2px solid #4a90e2;\n}\n.rc-button-default:focus {\n box-shadow: inset 0 0 0 2px #0063d6;\n}',
|
||||
init: function() {
|
||||
switch (location.pathname.split('/')[3]) {
|
||||
case 'anchor':
|
||||
return this.initMain();
|
||||
case 'frame':
|
||||
return this.initPopup();
|
||||
}
|
||||
},
|
||||
initMain: function() {
|
||||
return $.onExists(d.body, '#recaptcha-anchor', true, function(checkbox) {
|
||||
var focus;
|
||||
focus = function() {
|
||||
if (d.hasFocus() && d.activeElement !== checkbox) {
|
||||
return checkbox.focus();
|
||||
}
|
||||
};
|
||||
focus();
|
||||
return $.on(window, 'focus', function() {
|
||||
return $.queueTask(focus);
|
||||
});
|
||||
});
|
||||
},
|
||||
initPopup: function() {
|
||||
$.addStyle(this.css);
|
||||
this.fixImages();
|
||||
new MutationObserver((function(_this) {
|
||||
return function() {
|
||||
return _this.fixImages();
|
||||
};
|
||||
})(this)).observe(d.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
return $.on(d, 'keydown', this.keybinds.bind(this));
|
||||
},
|
||||
fixImages: function() {
|
||||
var focus, img, k, len1, ref;
|
||||
if (!(this.images = $$('.rc-imageselect-target > .rc-imageselect-tile > img')).length) {
|
||||
return;
|
||||
}
|
||||
focus = this.images[0].tabIndex !== 0;
|
||||
ref = this.images;
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
img = ref[k];
|
||||
img.tabIndex = 0;
|
||||
}
|
||||
if (focus) {
|
||||
return this.focusImage();
|
||||
}
|
||||
},
|
||||
focusImage: function() {
|
||||
var img;
|
||||
img = this.images[0];
|
||||
return $.asap(function() {
|
||||
if (!doc.contains(img)) {
|
||||
return true;
|
||||
}
|
||||
img.focus();
|
||||
return d.activeElement === img;
|
||||
}, function() {});
|
||||
},
|
||||
keybinds: function(e) {
|
||||
var dx, reload, verify, x;
|
||||
if (!(this.images && doc.contains(this.images[0]) && d.activeElement)) {
|
||||
return;
|
||||
}
|
||||
reload = $.id('recaptcha-reload-button');
|
||||
verify = $.id('recaptcha-verify-button');
|
||||
x = this.images.indexOf(d.activeElement);
|
||||
if (x < 0) {
|
||||
if (!$('.rc-controls').contains(d.activeElement)) {
|
||||
return;
|
||||
}
|
||||
x = d.activeElement === verify ? 11 : 9;
|
||||
}
|
||||
if (!(dx = {
|
||||
38: 9,
|
||||
40: 3,
|
||||
37: 11,
|
||||
39: 1
|
||||
}[e.keyCode])) {
|
||||
return;
|
||||
}
|
||||
x = (x + dx) % 12;
|
||||
if (x === 10) {
|
||||
x = dx === 11 ? 9 : 11;
|
||||
}
|
||||
(this.images[x] || {
|
||||
9: reload,
|
||||
11: verify
|
||||
}[x]).focus();
|
||||
e.preventDefault();
|
||||
return e.stopPropagation();
|
||||
}
|
||||
};
|
||||
|
||||
Captcha.noscript = {
|
||||
lifetime: 2 * $.MINUTE,
|
||||
iframeURL: '//www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc',
|
||||
@ -7988,20 +8064,6 @@
|
||||
};
|
||||
})(this));
|
||||
},
|
||||
initFrame: function() {
|
||||
$.globalEval('window.focus = function() {};');
|
||||
return $.on(window, 'focus', function() {
|
||||
return $.queueTask(function() {
|
||||
var checkbox;
|
||||
if (!(d.hasFocus() && (checkbox = $.id('recaptcha-anchor')))) {
|
||||
return;
|
||||
}
|
||||
if (d.activeElement !== checkbox) {
|
||||
return checkbox.focus();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
shouldFocus: false,
|
||||
timeouts: {},
|
||||
postsCount: 0,
|
||||
@ -8101,6 +8163,7 @@
|
||||
})(this));
|
||||
},
|
||||
destroy: function() {
|
||||
var garbage, ins, k, len1, ref;
|
||||
if (!this.isEnabled) {
|
||||
return;
|
||||
}
|
||||
@ -8109,7 +8172,15 @@
|
||||
if (this.nodes.container) {
|
||||
$.rm(this.nodes.container);
|
||||
}
|
||||
return delete this.nodes.container;
|
||||
delete this.nodes.container;
|
||||
ref = $$('div > .gc-bubbleDefault');
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
garbage = ref[k];
|
||||
if ((ins = garbage.parentNode.nextSibling) && ins.nodeName === 'INS') {
|
||||
$.rm(ins);
|
||||
}
|
||||
$.rm(garbage.parentNode);
|
||||
}
|
||||
},
|
||||
sync: function(captchas) {
|
||||
if (captchas == null) {
|
||||
@ -8131,7 +8202,7 @@
|
||||
}
|
||||
},
|
||||
save: function(pasted) {
|
||||
var base1;
|
||||
var base1, focus, ref, ref1;
|
||||
$.forceSync('captchas');
|
||||
this.captchas.push({
|
||||
response: $('textarea', this.nodes.container).value,
|
||||
@ -8147,6 +8218,7 @@
|
||||
}
|
||||
this.reload();
|
||||
} else {
|
||||
focus = ((ref = d.activeElement) != null ? ref.nodeName : void 0) === 'IFRAME' && ((ref1 = d.activeElement.src) != null ? ref1.slice(0, 38) : void 0) === 'https://www.google.com/recaptcha/api2/';
|
||||
if (pasted) {
|
||||
this.destroy();
|
||||
} else {
|
||||
@ -8154,7 +8226,9 @@
|
||||
base1.destroy = setTimeout(this.destroy.bind(this), 3 * $.SECOND);
|
||||
}
|
||||
}
|
||||
QR.nodes.status.focus();
|
||||
if (focus) {
|
||||
QR.nodes.status.focus();
|
||||
}
|
||||
}
|
||||
if (Conf['Post on Captcha Completion'] && !QR.cooldown.auto) {
|
||||
return QR.submit();
|
||||
@ -11440,7 +11514,7 @@
|
||||
},
|
||||
subEntries: []
|
||||
};
|
||||
ref1 = [['Post', 'post'], ['Name', 'name'], ['Tripcode', 'tripcode'], ['Subject', 'subject'], ['Filename', 'filename'], ['Image MD5', 'MD5']];
|
||||
ref1 = [['Post', 'post'], ['Name', 'name'], ['Tripcode', 'tripcode'], ['Capcode', 'capcode'], ['Subject', 'subject'], ['Filename', 'filename'], ['Image MD5', 'MD5']];
|
||||
for (k = 0, len1 = ref1.length; k < len1; k++) {
|
||||
type = ref1[k];
|
||||
entry.subEntries.push(this.createSubEntry(type[0], type[1]));
|
||||
@ -11707,17 +11781,19 @@
|
||||
el: a,
|
||||
order: 10,
|
||||
open: function(post) {
|
||||
ReportLink.post = post;
|
||||
return !post.isDead;
|
||||
ReportLink.url = !post.isDead ? "//sys.4chan.org/" + post.board + "/imgboard.php?mode=report&no=" + post : Conf['Archive Report'] ? Redirect.to('report', {
|
||||
boardID: post.board.ID,
|
||||
postID: post.ID
|
||||
}) : void 0;
|
||||
return !!ReportLink.url;
|
||||
}
|
||||
});
|
||||
},
|
||||
report: function() {
|
||||
var id, post, set, url;
|
||||
post = ReportLink.post;
|
||||
url = "//sys.4chan.org/" + post.board + "/imgboard.php?mode=report&no=" + post;
|
||||
var id, set, url;
|
||||
url = ReportLink.url;
|
||||
id = Date.now();
|
||||
set = "toolbar=0,scrollbars=0,location=0,status=1,menubar=0,resizable=1,width=685,height=285";
|
||||
set = "toolbar=0,scrollbars=1,location=0,status=1,menubar=0,resizable=1,width=685,height=200";
|
||||
return window.open(url, id, set);
|
||||
}
|
||||
};
|
||||
@ -13270,7 +13346,7 @@
|
||||
return;
|
||||
}
|
||||
notif = new Notification(post.info.nameBlock + " replied to you", {
|
||||
body: post.info[Conf['Remove Spoilers'] || Conf['Reveal Spoilers'] ? 'comment' : 'commentSpoilered'],
|
||||
body: post.info.commentDisplay,
|
||||
icon: Favicon.logo
|
||||
});
|
||||
notif.onclick = function() {
|
||||
@ -13410,7 +13486,8 @@
|
||||
o = {
|
||||
thread: {},
|
||||
post: {},
|
||||
file: {}
|
||||
file: {},
|
||||
report: {}
|
||||
};
|
||||
archives = {};
|
||||
ref = Redirect.archives;
|
||||
@ -13420,17 +13497,19 @@
|
||||
archives[name] = data;
|
||||
for (q = 0, len2 = boards.length; q < len2; q++) {
|
||||
boardID = boards[q];
|
||||
if (!(!withCredentials)) {
|
||||
continue;
|
||||
if (!withCredentials) {
|
||||
if (!(boardID in o.thread)) {
|
||||
o.thread[boardID] = data;
|
||||
}
|
||||
if (!(boardID in o.post || software !== 'foolfuuka')) {
|
||||
o.post[boardID] = data;
|
||||
}
|
||||
if (!(boardID in o.file || indexOf.call(files, boardID) < 0)) {
|
||||
o.file[boardID] = data;
|
||||
}
|
||||
}
|
||||
if (!(boardID in o.thread)) {
|
||||
o.thread[boardID] = data;
|
||||
}
|
||||
if (!(boardID in o.post || software !== 'foolfuuka')) {
|
||||
o.post[boardID] = data;
|
||||
}
|
||||
if (!(boardID in o.file || indexOf.call(files, boardID) < 0)) {
|
||||
o.file[boardID] = data;
|
||||
if (name === 'fgts') {
|
||||
o.report[boardID] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13451,7 +13530,7 @@
|
||||
}
|
||||
return Redirect.data = o;
|
||||
},
|
||||
archives: [{"uid":0,"name":"Moe","domain":"archive.moe","http":false,"https":true,"software":"foolfuuka","boards":["a","biz","c","co","diy","fit","gd","h","i","int","jp","k","m","mlp","out","po","qa","r9k","s4s","sci","tg","tv","u","v","vg","vp","vr","wsg"],"files":["a","biz","c","co","diy","fit","gd","h","i","jp","k","m","mlp","po","qa","r9k","s4s","sci","tg","u","v","vg","vp","vr","wsg"]},{"uid":3,"name":"4plebs Archive","domain":"archive.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["adv","f","hr","o","pol","s4s","tg","trv","tv","x"],"files":["adv","f","hr","o","pol","s4s","tg","trv","tv","x"]},{"uid":4,"name":"Nyafuu Archive","domain":"archive.nyafuu.org","http":true,"https":true,"software":"foolfuuka","boards":["c","e","w","wg"],"files":["c","e","w","wg"]},{"uid":5,"name":"Love is Over","domain":"archive.loveisover.me","http":true,"https":true,"software":"foolfuuka","boards":["c","d","e","i","lgbt","t","u","w","wg"],"files":["c","d","e","i","lgbt","t","u","w","wg"]},{"uid":8,"name":"Rebecca Black Tech","domain":"rbt.asia","http":false,"https":true,"software":"fuuka","boards":["cgl","g","mu","qa","w"],"files":["cgl","g","mu","qa","w"]},{"uid":10,"name":"warosu","domain":"warosu.org","http":false,"https":true,"software":"fuuka","boards":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"],"files":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"]},{"uid":15,"name":"fgts","domain":"fgts.jp","http":true,"https":true,"software":"foolfuuka","boards":["asp","b","cm","h","hc","hm","n","p","qa","r","s","soc","toy","y"],"files":["asp","b","cm","h","hc","hm","n","p","qa","r","s","soc","toy","y"]},{"uid":22,"name":"not4plebs","domain":"totally.not4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["sp"],"files":["sp"]},{"uid":23,"name":"DesuStorage","domain":"archive.desustorage.org","http":false,"https":true,"software":"foolfuuka","boards":["mlp","qa"],"files":["mlp","qa"]}],
|
||||
archives: [{"uid":0,"name":"Moe","domain":"archive.moe","http":false,"https":true,"software":"foolfuuka","boards":["a","biz","c","co","diy","fit","gd","gif","h","i","int","jp","k","m","mlp","out","po","qa","r9k","s4s","sci","tg","tv","u","v","vg","vp","vr","wsg"],"files":["a","biz","c","co","diy","fit","gd","h","i","jp","k","m","mlp","po","qa","r9k","s4s","sci","tg","u","v","vg","vp","vr","wsg"]},{"uid":3,"name":"4plebs Archive","domain":"archive.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["adv","f","hr","o","pol","s4s","tg","trv","tv","x"],"files":["adv","f","hr","o","pol","s4s","tg","trv","tv","x"]},{"uid":4,"name":"Nyafuu Archive","domain":"archive.nyafuu.org","http":true,"https":true,"software":"foolfuuka","boards":["c","e","w","wg"],"files":["c","e","w","wg"]},{"uid":5,"name":"Love is Over","domain":"archive.loveisover.me","http":true,"https":true,"software":"foolfuuka","boards":["c","d","e","i","lgbt","t","u"],"files":["c","d","e","i","lgbt","t","u"]},{"uid":8,"name":"Rebecca Black Tech","domain":"rbt.asia","http":false,"https":true,"software":"fuuka","boards":["cgl","g","mu","qa","w"],"files":["cgl","g","mu","qa","w"]},{"uid":10,"name":"warosu","domain":"warosu.org","http":false,"https":true,"software":"fuuka","boards":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"],"files":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"]},{"uid":15,"name":"fgts","domain":"fgts.jp","http":true,"https":true,"software":"foolfuuka","boards":["asp","b","cm","h","hc","hm","n","p","qa","r","s","soc","toy","y"],"files":["asp","b","cm","h","hc","hm","n","p","qa","r","s","soc","toy","y"]},{"uid":22,"name":"not4plebs","domain":"totally.not4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["sp"],"files":["sp"]},{"uid":23,"name":"DesuStorage","domain":"archive.desustorage.org","http":false,"https":true,"software":"foolfuuka","boards":["mlp","qa"],"files":["mlp","qa"]}],
|
||||
to: function(dest, data) {
|
||||
var archive;
|
||||
archive = (dest === 'search' || dest === 'board' ? Redirect.data.thread : Redirect.data[dest])[data.boardID];
|
||||
@ -13505,10 +13584,20 @@
|
||||
var boardID, path, type, value;
|
||||
boardID = arg.boardID, type = arg.type, value = arg.value;
|
||||
type = type === 'name' ? 'username' : type === 'MD5' ? 'image' : type;
|
||||
if (type === 'capcode') {
|
||||
value = {
|
||||
'Developer': 'dev'
|
||||
}[value] || value.toLowerCase();
|
||||
}
|
||||
value = encodeURIComponent(value);
|
||||
path = archive.software === 'foolfuuka' ? boardID + "/search/" + type + "/" + value : boardID + "/?task=search2&search_" + (type === 'image' ? 'media_hash' : type) + "=" + value;
|
||||
return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path;
|
||||
},
|
||||
report: function(archive, arg) {
|
||||
var boardID, postID;
|
||||
boardID = arg.boardID, postID = arg.postID;
|
||||
return "https://so.fgts.jp/report/?board=" + boardID + "&no=" + postID;
|
||||
},
|
||||
securityCheck: function(URL) {
|
||||
return /^https:\/\//.test(URL) || location.protocol === 'http:' || Conf['Except Archives from Encryption'];
|
||||
},
|
||||
@ -15228,6 +15317,63 @@
|
||||
}
|
||||
};
|
||||
|
||||
Report = {
|
||||
init: function() {
|
||||
var match;
|
||||
if (!(/\bmode=report\b/.test(location.search) && (match = location.search.match(/\bno=(\d+)/)))) {
|
||||
return;
|
||||
}
|
||||
this.postID = +match[1];
|
||||
return $.ready(this.ready);
|
||||
},
|
||||
ready: function() {
|
||||
new MutationObserver(Report.resize).observe(d.body, {
|
||||
childList: true,
|
||||
attributes: true,
|
||||
subtree: true
|
||||
});
|
||||
if (Conf['Archive Report']) {
|
||||
return Report.archive();
|
||||
}
|
||||
},
|
||||
resize: function() {
|
||||
var bubble, dy;
|
||||
if (!(bubble = $('.gc-bubbleDefault'))) {
|
||||
return;
|
||||
}
|
||||
dy = bubble.getBoundingClientRect().bottom - doc.clientHeight;
|
||||
if (dy > 0) {
|
||||
return window.resizeBy(0, dy);
|
||||
}
|
||||
},
|
||||
archive: function() {
|
||||
var link, message, url;
|
||||
Redirect.init();
|
||||
if (!(url = Redirect.to('report', {
|
||||
boardID: g.BOARD.ID,
|
||||
postID: Report.postID
|
||||
}))) {
|
||||
return;
|
||||
}
|
||||
if ((message = $('h3')) && /Report submitted!/.test(message.textContent)) {
|
||||
$.globalEval('self.close = function(){};');
|
||||
window.resizeTo(685, 320);
|
||||
location.replace(url);
|
||||
return;
|
||||
}
|
||||
link = $.el('a', {
|
||||
href: url,
|
||||
textContent: 'Report to fgts'
|
||||
});
|
||||
$.on(link, 'click', function(e) {
|
||||
if (!(e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0)) {
|
||||
return window.resizeTo(685, 320);
|
||||
}
|
||||
});
|
||||
return $.add(d.body, [$.tn(' ['), link, $.tn(']')]);
|
||||
}
|
||||
};
|
||||
|
||||
Time = {
|
||||
init: function() {
|
||||
var ref;
|
||||
@ -16017,12 +16163,24 @@
|
||||
|
||||
Main = {
|
||||
init: function() {
|
||||
var db, flatten, k, len1, pathname, ref, ref1, ref2, type;
|
||||
var db, flatten, k, len1, pathname, ref, ref1, ref2;
|
||||
if (location.hostname === 'www.google.com') {
|
||||
type = location.pathname === '/recaptcha/api/fallback' ? 'noscript' : 'v2';
|
||||
return $.ready(function() {
|
||||
return Captcha[type].initFrame();
|
||||
});
|
||||
if (location.pathname === '/recaptcha/api/fallback') {
|
||||
$.ready(function() {
|
||||
return Captcha.noscript.initFrame();
|
||||
});
|
||||
} else {
|
||||
$.get('Captcha Fixes', true, function(arg) {
|
||||
var enabled;
|
||||
enabled = arg['Captcha Fixes'];
|
||||
if (enabled) {
|
||||
return $.ready(function() {
|
||||
return Captcha.fixes.init();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
g.threads = new SimpleDict();
|
||||
g.posts = new SimpleDict();
|
||||
@ -16096,6 +16254,7 @@
|
||||
case 'a.4cdn.org':
|
||||
return;
|
||||
case 'sys.4chan.org':
|
||||
Report.init();
|
||||
if (g.VIEW === 'post') {
|
||||
PostSuccessful.init();
|
||||
}
|
||||
@ -17095,10 +17254,8 @@
|
||||
" /* party hats */\n" +
|
||||
" pointer-events: none;\n" +
|
||||
"}\n" +
|
||||
"marquee,\n" +
|
||||
".postMessage marquee + br,\n" +
|
||||
".postMessage marquee + br + br {\n" +
|
||||
" display: none;\n" +
|
||||
":root:not(.js-enabled) #postForm {\n" +
|
||||
" display: table;\n" +
|
||||
"}\n" +
|
||||
"/* Anti-autoplay */\n" +
|
||||
"audio.controls-added {\n" +
|
||||
|
||||
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.10.8.9
|
||||
// @version 1.10.11.1
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -11,6 +11,7 @@
|
||||
// @match *://a.4cdn.org/*
|
||||
// @match *://i.4cdn.org/*
|
||||
// @match https://www.google.com/recaptcha/api2/anchor?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*
|
||||
// @match https://www.google.com/recaptcha/api2/frame?*&k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*
|
||||
// @match *://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc
|
||||
// @grant GM_getValue
|
||||
// @grant GM_setValue
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.10.8.9
|
||||
// @version 1.10.11.1
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -12,6 +12,7 @@
|
||||
// @match *://a.4cdn.org/*
|
||||
// @match *://i.4cdn.org/*
|
||||
// @match https://www.google.com/recaptcha/api2/anchor?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*
|
||||
// @match https://www.google.com/recaptcha/api2/frame?*&k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*
|
||||
// @match *://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc
|
||||
// @grant GM_getValue
|
||||
// @grant GM_setValue
|
||||
@ -109,7 +110,7 @@
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var $, $$, Anonymize, AntiAutoplay, ArchiveLink, Banner, Board, Build, Callbacks, Captcha, CatalogLinks, CatalogThread, Clone, Conf, Config, Connection, CrossOrigin, CustomCSS, DataBoard, DeleteLink, DownloadLink, E, Embedding, ExpandComment, ExpandThread, FappeTyme, Favicon, Fetcher, FileInfo, Filter, Flash, Fourchan, Gallery, Get, Header, IDColor, IDHighlight, ImageCommon, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, MarkNewIPs, Menu, Metadata, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, PostSuccessful, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, ReportLink, RevealSpoilers, Sauce, Settings, ShimSet, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, Volume, c, d, doc, g,
|
||||
var $, $$, Anonymize, AntiAutoplay, ArchiveLink, Banner, Board, Build, Callbacks, Captcha, CatalogLinks, CatalogThread, Clone, Conf, Config, Connection, CrossOrigin, CustomCSS, DataBoard, DeleteLink, DownloadLink, E, Embedding, ExpandComment, ExpandThread, FappeTyme, Favicon, Fetcher, FileInfo, Filter, Flash, Fourchan, Gallery, Get, Header, IDColor, IDHighlight, ImageCommon, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, MarkNewIPs, Menu, Metadata, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, PostSuccessful, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, ShimSet, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, Volume, c, d, doc, g,
|
||||
slice = [].slice,
|
||||
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
|
||||
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
||||
@ -127,6 +128,7 @@
|
||||
'Announcement Hiding': [true, 'Add button to hide 4chan announcements.'],
|
||||
'Desktop Notifications': [true, 'Enables desktop notifications across various 4chan X features.'],
|
||||
'404 Redirect': [true, 'Redirect dead threads and images to the archives.'],
|
||||
'Archive Report': [true, 'Enable reporting posts to supported archives.'],
|
||||
'Except Archives from Encryption': [false, 'Permit loading content from, and warningless redirects to, HTTP-only archives from HTTPS pages.'],
|
||||
'Keybinds': [true, 'Bind actions to keyboard shortcuts.'],
|
||||
'Time Formatting': [true, 'Localize and format timestamps.'],
|
||||
@ -235,7 +237,8 @@
|
||||
'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],
|
||||
'Bottom QR Link': [true, 'Places a link on the bottom of threads to open the QR.', 1]
|
||||
'Bottom QR Link': [true, 'Places a link on the bottom of threads to open the QR.', 1],
|
||||
'Captcha Fixes': [true, 'Make captcha more keyboard-navigable.']
|
||||
},
|
||||
'Quote Links': {
|
||||
'Quote Backlinks': [true, 'Add quote backlinks.'],
|
||||
@ -396,7 +399,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.10.8.9',
|
||||
VERSION: '1.10.11.1',
|
||||
NAMESPACE: '4chan X.',
|
||||
boards: {}
|
||||
};
|
||||
@ -627,9 +630,11 @@
|
||||
$.addStyle = function(css, id, test) {
|
||||
var style;
|
||||
style = $.el('style', {
|
||||
id: id,
|
||||
textContent: css
|
||||
});
|
||||
if (id != null) {
|
||||
style.id = id;
|
||||
}
|
||||
$.asap((function() {
|
||||
return d.head && ((test == null) || test());
|
||||
}), function() {
|
||||
@ -1291,28 +1296,33 @@
|
||||
}
|
||||
|
||||
Post.prototype.parseComment = function() {
|
||||
var bq, k, len1, node, ref, spoilers;
|
||||
var abbr, bq, commentDisplay, k, len1, len2, node, q, ref, spoilers;
|
||||
this.nodes.comment.normalize();
|
||||
bq = this.nodes.comment.cloneNode(true);
|
||||
ref = $$('.abbr, .exif, b, marquee', bq);
|
||||
ref = $$('.abbr + br, .exif, b, .fortune', bq);
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
node = ref[k];
|
||||
$.rm(node);
|
||||
}
|
||||
if (abbr = $('.abbr', bq)) {
|
||||
$.rm(abbr);
|
||||
}
|
||||
this.info.comment = this.nodesToText(bq);
|
||||
spoilers = $$('s', bq);
|
||||
return this.info.commentSpoilered = (function() {
|
||||
var len2, q;
|
||||
if (abbr) {
|
||||
this.info.comment = this.info.comment.replace(/\n\n$/, '');
|
||||
}
|
||||
commentDisplay = this.info.comment;
|
||||
if (!(Conf['Remove Spoilers'] || Conf['Reveal Spoilers'])) {
|
||||
spoilers = $$('s', bq);
|
||||
if (spoilers.length) {
|
||||
for (q = 0, len2 = spoilers.length; q < len2; q++) {
|
||||
node = spoilers[q];
|
||||
$.replace(node, $.tn('[spoiler]'));
|
||||
}
|
||||
return this.nodesToText(bq);
|
||||
} else {
|
||||
return this.info.comment;
|
||||
commentDisplay = this.nodesToText(bq);
|
||||
}
|
||||
}).call(this);
|
||||
}
|
||||
return this.info.commentDisplay = commentDisplay.trim().replace(/\s+$/gm, '');
|
||||
};
|
||||
|
||||
Post.prototype.nodesToText = function(bq) {
|
||||
@ -1323,7 +1333,7 @@
|
||||
while (node = nodes.snapshotItem(i++)) {
|
||||
text += node.data || '\n';
|
||||
}
|
||||
return text.trim().replace(/\s+$/gm, '');
|
||||
return text;
|
||||
};
|
||||
|
||||
Post.prototype.parseQuotes = function() {
|
||||
@ -4298,7 +4308,7 @@
|
||||
threadExcerpt: function(thread) {
|
||||
var OP, excerpt, ref;
|
||||
OP = thread.OP;
|
||||
excerpt = ("/" + thread.board + "/ - ") + (((ref = OP.info.subject) != null ? ref.trim() : void 0) || OP.info.comment.replace(/\n+/g, ' // ') || OP.info.nameBlock);
|
||||
excerpt = ("/" + thread.board + "/ - ") + (((ref = OP.info.subject) != null ? ref.trim() : void 0) || OP.info.commentDisplay.replace(/\n+/g, ' // ') || OP.info.nameBlock);
|
||||
if (excerpt.length > 73) {
|
||||
return excerpt.slice(0, 70) + "...";
|
||||
}
|
||||
@ -5070,18 +5080,18 @@
|
||||
},
|
||||
node: function() {
|
||||
var filter, k, key, len1, ref, ref1, result, value;
|
||||
if (this.isClone || this.isFetchedQuote) {
|
||||
if (this.isClone) {
|
||||
return;
|
||||
}
|
||||
for (key in Filter.filters) {
|
||||
if ((value = Filter[key](this)) !== false) {
|
||||
if ((value = Filter[key](this)) != null) {
|
||||
ref = Filter.filters[key];
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
filter = ref[k];
|
||||
if (!(result = filter(value, this.isReply))) {
|
||||
continue;
|
||||
}
|
||||
if (result.hide) {
|
||||
if (result.hide && !this.isFetchedQuote) {
|
||||
if (this.isReply) {
|
||||
PostHiding.hide(this, result.stub);
|
||||
} else if (g.VIEW === 'index') {
|
||||
@ -5103,73 +5113,41 @@
|
||||
}
|
||||
},
|
||||
name: function(post) {
|
||||
if ('name' in post.info) {
|
||||
return post.info.name;
|
||||
}
|
||||
return false;
|
||||
return post.info.name;
|
||||
},
|
||||
uniqueID: function(post) {
|
||||
if ('uniqueID' in post.info) {
|
||||
return post.info.uniqueID;
|
||||
}
|
||||
return false;
|
||||
return post.info.uniqueID;
|
||||
},
|
||||
tripcode: function(post) {
|
||||
if ('tripcode' in post.info) {
|
||||
return post.info.tripcode;
|
||||
}
|
||||
return false;
|
||||
return post.info.tripcode;
|
||||
},
|
||||
capcode: function(post) {
|
||||
if ('capcode' in post.info) {
|
||||
return post.info.capcode;
|
||||
}
|
||||
return false;
|
||||
return post.info.capcode;
|
||||
},
|
||||
subject: function(post) {
|
||||
if ('subject' in post.info) {
|
||||
return post.info.subject || false;
|
||||
}
|
||||
return false;
|
||||
return post.info.subject || void 0;
|
||||
},
|
||||
comment: function(post) {
|
||||
if ('comment' in post.info) {
|
||||
return post.info.comment;
|
||||
}
|
||||
return false;
|
||||
return post.info.comment;
|
||||
},
|
||||
flag: function(post) {
|
||||
if ('flag' in post.info) {
|
||||
return post.info.flag;
|
||||
}
|
||||
return false;
|
||||
return post.info.flag;
|
||||
},
|
||||
filename: function(post) {
|
||||
if (post.file) {
|
||||
return post.file.name;
|
||||
}
|
||||
return false;
|
||||
var ref;
|
||||
return (ref = post.file) != null ? ref.name : void 0;
|
||||
},
|
||||
dimensions: function(post) {
|
||||
var file;
|
||||
file = post.file;
|
||||
if (file != null ? file.dimensions : void 0) {
|
||||
return file.dimensions;
|
||||
}
|
||||
return false;
|
||||
var ref;
|
||||
return (ref = post.file) != null ? ref.dimensions : void 0;
|
||||
},
|
||||
filesize: function(post) {
|
||||
if (post.file) {
|
||||
return post.file.size;
|
||||
}
|
||||
return false;
|
||||
var ref;
|
||||
return (ref = post.file) != null ? ref.size : void 0;
|
||||
},
|
||||
MD5: function(post) {
|
||||
var ref;
|
||||
if ((ref = post.file) != null ? ref.MD5 : void 0) {
|
||||
return post.file.MD5;
|
||||
}
|
||||
return false;
|
||||
return (ref = post.file) != null ? ref.MD5 : void 0;
|
||||
},
|
||||
menu: {
|
||||
init: function() {
|
||||
@ -5209,7 +5187,7 @@
|
||||
open: function(post) {
|
||||
var value;
|
||||
value = Filter[type](post);
|
||||
return value !== false;
|
||||
return value != null;
|
||||
}
|
||||
};
|
||||
},
|
||||
@ -6696,8 +6674,8 @@
|
||||
if (g.VIEW === 'archive') {
|
||||
return;
|
||||
}
|
||||
$.globalEval('document.documentElement.dataset.jsEnabled = true;');
|
||||
noscript = Conf['Force Noscript Captcha'] || !doc.dataset.jsEnabled;
|
||||
$.globalEval('document.documentElement.classList.add("js-enabled");');
|
||||
noscript = Conf['Force Noscript Captcha'] || !$.hasClass(doc, 'js-enabled');
|
||||
this.captcha = Captcha[noscript ? 'noscript' : 'v2'];
|
||||
$.on(d, '4chanXInitFinished', this.initReady);
|
||||
Post.callbacks.push({
|
||||
@ -6726,7 +6704,7 @@
|
||||
}
|
||||
if (Conf['Hide Original Post Form']) {
|
||||
$.addClass(doc, 'hide-original-post-form');
|
||||
if (!doc.dataset.jsEnabled) {
|
||||
if (!$.hasClass(doc, 'js-enabled')) {
|
||||
return $.onExists(doc, '#postForm noscript', true, $.rm);
|
||||
}
|
||||
}
|
||||
@ -7630,6 +7608,104 @@
|
||||
|
||||
Captcha = {};
|
||||
|
||||
Captcha.fixes = {
|
||||
css: '.rc-imageselect-target > .rc-imageselect-tile > img:focus {\n outline: 2px solid #4a90e2;\n}\n.rc-button-default:focus {\n box-shadow: inset 0 0 0 2px #0063d6;\n}',
|
||||
init: function() {
|
||||
switch (location.pathname.split('/')[3]) {
|
||||
case 'anchor':
|
||||
return this.initMain();
|
||||
case 'frame':
|
||||
return this.initPopup();
|
||||
}
|
||||
},
|
||||
initMain: function() {
|
||||
return $.onExists(d.body, '#recaptcha-anchor', true, function(checkbox) {
|
||||
var focus;
|
||||
focus = function() {
|
||||
if (d.hasFocus() && d.activeElement !== checkbox) {
|
||||
return checkbox.focus();
|
||||
}
|
||||
};
|
||||
focus();
|
||||
return $.on(window, 'focus', function() {
|
||||
return $.queueTask(focus);
|
||||
});
|
||||
});
|
||||
},
|
||||
initPopup: function() {
|
||||
$.addStyle(this.css);
|
||||
this.fixImages();
|
||||
new MutationObserver((function(_this) {
|
||||
return function() {
|
||||
return _this.fixImages();
|
||||
};
|
||||
})(this)).observe(d.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
return $.on(d, 'keydown', this.keybinds.bind(this));
|
||||
},
|
||||
fixImages: function() {
|
||||
var focus, img, k, len1, ref;
|
||||
if (!(this.images = $$('.rc-imageselect-target > .rc-imageselect-tile > img')).length) {
|
||||
return;
|
||||
}
|
||||
focus = this.images[0].tabIndex !== 0;
|
||||
ref = this.images;
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
img = ref[k];
|
||||
img.tabIndex = 0;
|
||||
}
|
||||
if (focus) {
|
||||
return this.focusImage();
|
||||
}
|
||||
},
|
||||
focusImage: function() {
|
||||
var img;
|
||||
img = this.images[0];
|
||||
return $.asap(function() {
|
||||
if (!doc.contains(img)) {
|
||||
return true;
|
||||
}
|
||||
img.focus();
|
||||
return d.activeElement === img;
|
||||
}, function() {});
|
||||
},
|
||||
keybinds: function(e) {
|
||||
var dx, reload, verify, x;
|
||||
if (!(this.images && doc.contains(this.images[0]) && d.activeElement)) {
|
||||
return;
|
||||
}
|
||||
reload = $.id('recaptcha-reload-button');
|
||||
verify = $.id('recaptcha-verify-button');
|
||||
x = this.images.indexOf(d.activeElement);
|
||||
if (x < 0) {
|
||||
if (!$('.rc-controls').contains(d.activeElement)) {
|
||||
return;
|
||||
}
|
||||
x = d.activeElement === verify ? 11 : 9;
|
||||
}
|
||||
if (!(dx = {
|
||||
38: 9,
|
||||
40: 3,
|
||||
37: 11,
|
||||
39: 1
|
||||
}[e.keyCode])) {
|
||||
return;
|
||||
}
|
||||
x = (x + dx) % 12;
|
||||
if (x === 10) {
|
||||
x = dx === 11 ? 9 : 11;
|
||||
}
|
||||
(this.images[x] || {
|
||||
9: reload,
|
||||
11: verify
|
||||
}[x]).focus();
|
||||
e.preventDefault();
|
||||
return e.stopPropagation();
|
||||
}
|
||||
};
|
||||
|
||||
Captcha.noscript = {
|
||||
lifetime: 2 * $.MINUTE,
|
||||
iframeURL: '//www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc',
|
||||
@ -7989,20 +8065,6 @@
|
||||
};
|
||||
})(this));
|
||||
},
|
||||
initFrame: function() {
|
||||
$.globalEval('window.focus = function() {};');
|
||||
return $.on(window, 'focus', function() {
|
||||
return $.queueTask(function() {
|
||||
var checkbox;
|
||||
if (!(d.hasFocus() && (checkbox = $.id('recaptcha-anchor')))) {
|
||||
return;
|
||||
}
|
||||
if (d.activeElement !== checkbox) {
|
||||
return checkbox.focus();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
shouldFocus: false,
|
||||
timeouts: {},
|
||||
postsCount: 0,
|
||||
@ -8102,6 +8164,7 @@
|
||||
})(this));
|
||||
},
|
||||
destroy: function() {
|
||||
var garbage, ins, k, len1, ref;
|
||||
if (!this.isEnabled) {
|
||||
return;
|
||||
}
|
||||
@ -8110,7 +8173,15 @@
|
||||
if (this.nodes.container) {
|
||||
$.rm(this.nodes.container);
|
||||
}
|
||||
return delete this.nodes.container;
|
||||
delete this.nodes.container;
|
||||
ref = $$('div > .gc-bubbleDefault');
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
garbage = ref[k];
|
||||
if ((ins = garbage.parentNode.nextSibling) && ins.nodeName === 'INS') {
|
||||
$.rm(ins);
|
||||
}
|
||||
$.rm(garbage.parentNode);
|
||||
}
|
||||
},
|
||||
sync: function(captchas) {
|
||||
if (captchas == null) {
|
||||
@ -8132,7 +8203,7 @@
|
||||
}
|
||||
},
|
||||
save: function(pasted) {
|
||||
var base1;
|
||||
var base1, focus, ref, ref1;
|
||||
$.forceSync('captchas');
|
||||
this.captchas.push({
|
||||
response: $('textarea', this.nodes.container).value,
|
||||
@ -8148,6 +8219,7 @@
|
||||
}
|
||||
this.reload();
|
||||
} else {
|
||||
focus = ((ref = d.activeElement) != null ? ref.nodeName : void 0) === 'IFRAME' && ((ref1 = d.activeElement.src) != null ? ref1.slice(0, 38) : void 0) === 'https://www.google.com/recaptcha/api2/';
|
||||
if (pasted) {
|
||||
this.destroy();
|
||||
} else {
|
||||
@ -8155,7 +8227,9 @@
|
||||
base1.destroy = setTimeout(this.destroy.bind(this), 3 * $.SECOND);
|
||||
}
|
||||
}
|
||||
QR.nodes.status.focus();
|
||||
if (focus) {
|
||||
QR.nodes.status.focus();
|
||||
}
|
||||
}
|
||||
if (Conf['Post on Captcha Completion'] && !QR.cooldown.auto) {
|
||||
return QR.submit();
|
||||
@ -11441,7 +11515,7 @@
|
||||
},
|
||||
subEntries: []
|
||||
};
|
||||
ref1 = [['Post', 'post'], ['Name', 'name'], ['Tripcode', 'tripcode'], ['Subject', 'subject'], ['Filename', 'filename'], ['Image MD5', 'MD5']];
|
||||
ref1 = [['Post', 'post'], ['Name', 'name'], ['Tripcode', 'tripcode'], ['Capcode', 'capcode'], ['Subject', 'subject'], ['Filename', 'filename'], ['Image MD5', 'MD5']];
|
||||
for (k = 0, len1 = ref1.length; k < len1; k++) {
|
||||
type = ref1[k];
|
||||
entry.subEntries.push(this.createSubEntry(type[0], type[1]));
|
||||
@ -11708,17 +11782,19 @@
|
||||
el: a,
|
||||
order: 10,
|
||||
open: function(post) {
|
||||
ReportLink.post = post;
|
||||
return !post.isDead;
|
||||
ReportLink.url = !post.isDead ? "//sys.4chan.org/" + post.board + "/imgboard.php?mode=report&no=" + post : Conf['Archive Report'] ? Redirect.to('report', {
|
||||
boardID: post.board.ID,
|
||||
postID: post.ID
|
||||
}) : void 0;
|
||||
return !!ReportLink.url;
|
||||
}
|
||||
});
|
||||
},
|
||||
report: function() {
|
||||
var id, post, set, url;
|
||||
post = ReportLink.post;
|
||||
url = "//sys.4chan.org/" + post.board + "/imgboard.php?mode=report&no=" + post;
|
||||
var id, set, url;
|
||||
url = ReportLink.url;
|
||||
id = Date.now();
|
||||
set = "toolbar=0,scrollbars=0,location=0,status=1,menubar=0,resizable=1,width=685,height=285";
|
||||
set = "toolbar=0,scrollbars=1,location=0,status=1,menubar=0,resizable=1,width=685,height=200";
|
||||
return window.open(url, id, set);
|
||||
}
|
||||
};
|
||||
@ -13271,7 +13347,7 @@
|
||||
return;
|
||||
}
|
||||
notif = new Notification(post.info.nameBlock + " replied to you", {
|
||||
body: post.info[Conf['Remove Spoilers'] || Conf['Reveal Spoilers'] ? 'comment' : 'commentSpoilered'],
|
||||
body: post.info.commentDisplay,
|
||||
icon: Favicon.logo
|
||||
});
|
||||
notif.onclick = function() {
|
||||
@ -13411,7 +13487,8 @@
|
||||
o = {
|
||||
thread: {},
|
||||
post: {},
|
||||
file: {}
|
||||
file: {},
|
||||
report: {}
|
||||
};
|
||||
archives = {};
|
||||
ref = Redirect.archives;
|
||||
@ -13421,17 +13498,19 @@
|
||||
archives[name] = data;
|
||||
for (q = 0, len2 = boards.length; q < len2; q++) {
|
||||
boardID = boards[q];
|
||||
if (!(!withCredentials)) {
|
||||
continue;
|
||||
if (!withCredentials) {
|
||||
if (!(boardID in o.thread)) {
|
||||
o.thread[boardID] = data;
|
||||
}
|
||||
if (!(boardID in o.post || software !== 'foolfuuka')) {
|
||||
o.post[boardID] = data;
|
||||
}
|
||||
if (!(boardID in o.file || indexOf.call(files, boardID) < 0)) {
|
||||
o.file[boardID] = data;
|
||||
}
|
||||
}
|
||||
if (!(boardID in o.thread)) {
|
||||
o.thread[boardID] = data;
|
||||
}
|
||||
if (!(boardID in o.post || software !== 'foolfuuka')) {
|
||||
o.post[boardID] = data;
|
||||
}
|
||||
if (!(boardID in o.file || indexOf.call(files, boardID) < 0)) {
|
||||
o.file[boardID] = data;
|
||||
if (name === 'fgts') {
|
||||
o.report[boardID] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13452,7 +13531,7 @@
|
||||
}
|
||||
return Redirect.data = o;
|
||||
},
|
||||
archives: [{"uid":0,"name":"Moe","domain":"archive.moe","http":false,"https":true,"software":"foolfuuka","boards":["a","biz","c","co","diy","fit","gd","h","i","int","jp","k","m","mlp","out","po","qa","r9k","s4s","sci","tg","tv","u","v","vg","vp","vr","wsg"],"files":["a","biz","c","co","diy","fit","gd","h","i","jp","k","m","mlp","po","qa","r9k","s4s","sci","tg","u","v","vg","vp","vr","wsg"]},{"uid":3,"name":"4plebs Archive","domain":"archive.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["adv","f","hr","o","pol","s4s","tg","trv","tv","x"],"files":["adv","f","hr","o","pol","s4s","tg","trv","tv","x"]},{"uid":4,"name":"Nyafuu Archive","domain":"archive.nyafuu.org","http":true,"https":true,"software":"foolfuuka","boards":["c","e","w","wg"],"files":["c","e","w","wg"]},{"uid":5,"name":"Love is Over","domain":"archive.loveisover.me","http":true,"https":true,"software":"foolfuuka","boards":["c","d","e","i","lgbt","t","u","w","wg"],"files":["c","d","e","i","lgbt","t","u","w","wg"]},{"uid":8,"name":"Rebecca Black Tech","domain":"rbt.asia","http":false,"https":true,"software":"fuuka","boards":["cgl","g","mu","qa","w"],"files":["cgl","g","mu","qa","w"]},{"uid":10,"name":"warosu","domain":"warosu.org","http":false,"https":true,"software":"fuuka","boards":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"],"files":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"]},{"uid":15,"name":"fgts","domain":"fgts.jp","http":true,"https":true,"software":"foolfuuka","boards":["asp","b","cm","h","hc","hm","n","p","qa","r","s","soc","toy","y"],"files":["asp","b","cm","h","hc","hm","n","p","qa","r","s","soc","toy","y"]},{"uid":22,"name":"not4plebs","domain":"totally.not4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["sp"],"files":["sp"]},{"uid":23,"name":"DesuStorage","domain":"archive.desustorage.org","http":false,"https":true,"software":"foolfuuka","boards":["mlp","qa"],"files":["mlp","qa"]}],
|
||||
archives: [{"uid":0,"name":"Moe","domain":"archive.moe","http":false,"https":true,"software":"foolfuuka","boards":["a","biz","c","co","diy","fit","gd","gif","h","i","int","jp","k","m","mlp","out","po","qa","r9k","s4s","sci","tg","tv","u","v","vg","vp","vr","wsg"],"files":["a","biz","c","co","diy","fit","gd","h","i","jp","k","m","mlp","po","qa","r9k","s4s","sci","tg","u","v","vg","vp","vr","wsg"]},{"uid":3,"name":"4plebs Archive","domain":"archive.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["adv","f","hr","o","pol","s4s","tg","trv","tv","x"],"files":["adv","f","hr","o","pol","s4s","tg","trv","tv","x"]},{"uid":4,"name":"Nyafuu Archive","domain":"archive.nyafuu.org","http":true,"https":true,"software":"foolfuuka","boards":["c","e","w","wg"],"files":["c","e","w","wg"]},{"uid":5,"name":"Love is Over","domain":"archive.loveisover.me","http":true,"https":true,"software":"foolfuuka","boards":["c","d","e","i","lgbt","t","u"],"files":["c","d","e","i","lgbt","t","u"]},{"uid":8,"name":"Rebecca Black Tech","domain":"rbt.asia","http":false,"https":true,"software":"fuuka","boards":["cgl","g","mu","qa","w"],"files":["cgl","g","mu","qa","w"]},{"uid":10,"name":"warosu","domain":"warosu.org","http":false,"https":true,"software":"fuuka","boards":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"],"files":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"]},{"uid":15,"name":"fgts","domain":"fgts.jp","http":true,"https":true,"software":"foolfuuka","boards":["asp","b","cm","h","hc","hm","n","p","qa","r","s","soc","toy","y"],"files":["asp","b","cm","h","hc","hm","n","p","qa","r","s","soc","toy","y"]},{"uid":22,"name":"not4plebs","domain":"totally.not4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["sp"],"files":["sp"]},{"uid":23,"name":"DesuStorage","domain":"archive.desustorage.org","http":false,"https":true,"software":"foolfuuka","boards":["mlp","qa"],"files":["mlp","qa"]}],
|
||||
to: function(dest, data) {
|
||||
var archive;
|
||||
archive = (dest === 'search' || dest === 'board' ? Redirect.data.thread : Redirect.data[dest])[data.boardID];
|
||||
@ -13506,10 +13585,20 @@
|
||||
var boardID, path, type, value;
|
||||
boardID = arg.boardID, type = arg.type, value = arg.value;
|
||||
type = type === 'name' ? 'username' : type === 'MD5' ? 'image' : type;
|
||||
if (type === 'capcode') {
|
||||
value = {
|
||||
'Developer': 'dev'
|
||||
}[value] || value.toLowerCase();
|
||||
}
|
||||
value = encodeURIComponent(value);
|
||||
path = archive.software === 'foolfuuka' ? boardID + "/search/" + type + "/" + value : boardID + "/?task=search2&search_" + (type === 'image' ? 'media_hash' : type) + "=" + value;
|
||||
return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path;
|
||||
},
|
||||
report: function(archive, arg) {
|
||||
var boardID, postID;
|
||||
boardID = arg.boardID, postID = arg.postID;
|
||||
return "https://so.fgts.jp/report/?board=" + boardID + "&no=" + postID;
|
||||
},
|
||||
securityCheck: function(URL) {
|
||||
return /^https:\/\//.test(URL) || location.protocol === 'http:' || Conf['Except Archives from Encryption'];
|
||||
},
|
||||
@ -15229,6 +15318,63 @@
|
||||
}
|
||||
};
|
||||
|
||||
Report = {
|
||||
init: function() {
|
||||
var match;
|
||||
if (!(/\bmode=report\b/.test(location.search) && (match = location.search.match(/\bno=(\d+)/)))) {
|
||||
return;
|
||||
}
|
||||
this.postID = +match[1];
|
||||
return $.ready(this.ready);
|
||||
},
|
||||
ready: function() {
|
||||
new MutationObserver(Report.resize).observe(d.body, {
|
||||
childList: true,
|
||||
attributes: true,
|
||||
subtree: true
|
||||
});
|
||||
if (Conf['Archive Report']) {
|
||||
return Report.archive();
|
||||
}
|
||||
},
|
||||
resize: function() {
|
||||
var bubble, dy;
|
||||
if (!(bubble = $('.gc-bubbleDefault'))) {
|
||||
return;
|
||||
}
|
||||
dy = bubble.getBoundingClientRect().bottom - doc.clientHeight;
|
||||
if (dy > 0) {
|
||||
return window.resizeBy(0, dy);
|
||||
}
|
||||
},
|
||||
archive: function() {
|
||||
var link, message, url;
|
||||
Redirect.init();
|
||||
if (!(url = Redirect.to('report', {
|
||||
boardID: g.BOARD.ID,
|
||||
postID: Report.postID
|
||||
}))) {
|
||||
return;
|
||||
}
|
||||
if ((message = $('h3')) && /Report submitted!/.test(message.textContent)) {
|
||||
$.globalEval('self.close = function(){};');
|
||||
window.resizeTo(685, 320);
|
||||
location.replace(url);
|
||||
return;
|
||||
}
|
||||
link = $.el('a', {
|
||||
href: url,
|
||||
textContent: 'Report to fgts'
|
||||
});
|
||||
$.on(link, 'click', function(e) {
|
||||
if (!(e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0)) {
|
||||
return window.resizeTo(685, 320);
|
||||
}
|
||||
});
|
||||
return $.add(d.body, [$.tn(' ['), link, $.tn(']')]);
|
||||
}
|
||||
};
|
||||
|
||||
Time = {
|
||||
init: function() {
|
||||
var ref;
|
||||
@ -16018,12 +16164,24 @@
|
||||
|
||||
Main = {
|
||||
init: function() {
|
||||
var db, flatten, k, len1, pathname, ref, ref1, ref2, type;
|
||||
var db, flatten, k, len1, pathname, ref, ref1, ref2;
|
||||
if (location.hostname === 'www.google.com') {
|
||||
type = location.pathname === '/recaptcha/api/fallback' ? 'noscript' : 'v2';
|
||||
return $.ready(function() {
|
||||
return Captcha[type].initFrame();
|
||||
});
|
||||
if (location.pathname === '/recaptcha/api/fallback') {
|
||||
$.ready(function() {
|
||||
return Captcha.noscript.initFrame();
|
||||
});
|
||||
} else {
|
||||
$.get('Captcha Fixes', true, function(arg) {
|
||||
var enabled;
|
||||
enabled = arg['Captcha Fixes'];
|
||||
if (enabled) {
|
||||
return $.ready(function() {
|
||||
return Captcha.fixes.init();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
g.threads = new SimpleDict();
|
||||
g.posts = new SimpleDict();
|
||||
@ -16097,6 +16255,7 @@
|
||||
case 'a.4cdn.org':
|
||||
return;
|
||||
case 'sys.4chan.org':
|
||||
Report.init();
|
||||
if (g.VIEW === 'post') {
|
||||
PostSuccessful.init();
|
||||
}
|
||||
@ -17096,10 +17255,8 @@
|
||||
" /* party hats */\n" +
|
||||
" pointer-events: none;\n" +
|
||||
"}\n" +
|
||||
"marquee,\n" +
|
||||
".postMessage marquee + br,\n" +
|
||||
".postMessage marquee + br + br {\n" +
|
||||
" display: none;\n" +
|
||||
":root:not(.js-enabled) #postForm {\n" +
|
||||
" display: table;\n" +
|
||||
"}\n" +
|
||||
"/* Anti-autoplay */\n" +
|
||||
"audio.controls-added {\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.10.8.9' />
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X-beta.crx' version='1.10.11.1' />
|
||||
</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.10.8.9' />
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/4chan-X.crx' version='1.10.11.1' />
|
||||
</app>
|
||||
</gupdate>
|
||||
|
||||
|
||||
202
npm-shrinkwrap.json
generated
202
npm-shrinkwrap.json
generated
@ -465,198 +465,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"grunt-contrib-compress": {
|
||||
"version": "0.13.0",
|
||||
"resolved": "https://registry.npmjs.org/grunt-contrib-compress/-/grunt-contrib-compress-0.13.0.tgz",
|
||||
"dependencies": {
|
||||
"archiver": {
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmjs.org/archiver/-/archiver-0.13.1.tgz",
|
||||
"dependencies": {
|
||||
"async": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-0.9.0.tgz"
|
||||
},
|
||||
"buffer-crc32": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.5.tgz"
|
||||
},
|
||||
"glob": {
|
||||
"version": "4.3.5",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-4.3.5.tgz",
|
||||
"dependencies": {
|
||||
"inflight": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz",
|
||||
"dependencies": {
|
||||
"wrappy": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.1.tgz",
|
||||
"dependencies": {
|
||||
"brace-expansion": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.0.tgz",
|
||||
"dependencies": {
|
||||
"balanced-match": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz"
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.3.1.tgz",
|
||||
"dependencies": {
|
||||
"wrappy": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"lazystream": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lazystream/-/lazystream-0.1.0.tgz"
|
||||
},
|
||||
"lodash": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz"
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "1.0.33",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz",
|
||||
"dependencies": {
|
||||
"core-util-is": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz"
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
},
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tar-stream": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.1.2.tgz",
|
||||
"dependencies": {
|
||||
"bl": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-0.9.3.tgz"
|
||||
},
|
||||
"end-of-stream": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz",
|
||||
"dependencies": {
|
||||
"once": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.3.1.tgz",
|
||||
"dependencies": {
|
||||
"wrappy": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"zip-stream": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-0.5.0.tgz",
|
||||
"dependencies": {
|
||||
"compress-commons": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-0.2.0.tgz",
|
||||
"dependencies": {
|
||||
"crc32-stream": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-0.3.1.tgz"
|
||||
},
|
||||
"node-int64": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.3.3.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz"
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz"
|
||||
},
|
||||
"has-ansi": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"prettysize": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/prettysize/-/prettysize-0.0.3.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"grunt-contrib-concat": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/grunt-contrib-concat/-/grunt-contrib-concat-0.5.1.tgz",
|
||||
@ -1081,6 +889,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"jszip": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/jszip/-/jszip-2.5.0.tgz",
|
||||
"dependencies": {
|
||||
"pako": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-0.2.6.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"load-grunt-tasks": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.1.0.tgz",
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
||||
"meta": {
|
||||
"name": "4chan X",
|
||||
"version": "1.10.8.9",
|
||||
"date": "2015-04-13T15:07:30.185Z",
|
||||
"version": "1.10.11.1",
|
||||
"date": "2015-04-24T14:48:43.242Z",
|
||||
"repo": "https://github.com/ccd0/4chan-x/",
|
||||
"page": "https://github.com/ccd0/4chan-x",
|
||||
"downloads": "https://ccd0.github.io/4chan-x/builds/",
|
||||
@ -22,6 +22,7 @@
|
||||
"*://a.4cdn.org/*",
|
||||
"*://i.4cdn.org/*",
|
||||
"https://www.google.com/recaptcha/api2/anchor?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*",
|
||||
"https://www.google.com/recaptcha/api2/frame?*&k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*",
|
||||
"*://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc"
|
||||
],
|
||||
"suffix": {
|
||||
@ -49,7 +50,6 @@
|
||||
"grunt-concurrent": "^1.0.0",
|
||||
"grunt-contrib-clean": "^0.6.0",
|
||||
"grunt-contrib-coffee": "^0.13.0",
|
||||
"grunt-contrib-compress": "^0.13.0",
|
||||
"grunt-contrib-concat": "^0.5.1",
|
||||
"grunt-contrib-copy": "^0.8.0",
|
||||
"grunt-contrib-jshint": "^0.11.1",
|
||||
@ -57,6 +57,7 @@
|
||||
"grunt-markdown": "^0.7.0",
|
||||
"grunt-shell": "^1.1.2",
|
||||
"grunt-webstore-upload": "^0.8.2",
|
||||
"jszip": "^2.5.0",
|
||||
"load-grunt-tasks": "^3.1.0",
|
||||
"npm-shrinkwrap": "^5.3.0"
|
||||
},
|
||||
|
||||
@ -4,15 +4,18 @@ Redirect =
|
||||
thread: {}
|
||||
post: {}
|
||||
file: {}
|
||||
report: {}
|
||||
|
||||
archives = {}
|
||||
for data in Redirect.archives
|
||||
{name, boards, files, software, withCredentials} = data
|
||||
archives[name] = data
|
||||
for boardID in boards when !withCredentials
|
||||
o.thread[boardID] = data unless boardID of o.thread
|
||||
o.post[boardID] = data unless boardID of o.post or software isnt 'foolfuuka'
|
||||
o.file[boardID] = data unless boardID of o.file or boardID not in files
|
||||
for boardID in boards
|
||||
unless withCredentials
|
||||
o.thread[boardID] = data unless boardID of o.thread
|
||||
o.post[boardID] = data unless boardID of o.post or software isnt 'foolfuuka'
|
||||
o.file[boardID] = data unless boardID of o.file or boardID not in files
|
||||
o.report[boardID] = data if name is 'fgts'
|
||||
|
||||
for boardID, record of Conf['selectedArchives']
|
||||
for type, id of record
|
||||
@ -84,6 +87,9 @@ Redirect =
|
||||
"#{boardID}/?task=search2&search_#{if type is 'image' then 'media_hash' else type}=#{value}"
|
||||
"#{Redirect.protocol archive}#{archive.domain}/#{path}"
|
||||
|
||||
report: (archive, {boardID, postID}) ->
|
||||
"https://so.fgts.jp/report/?board=#{boardID}&no=#{postID}"
|
||||
|
||||
securityCheck: (URL) ->
|
||||
/^https:\/\//.test(URL) or
|
||||
location.protocol is 'http:' or
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
"http": false,
|
||||
"https": true,
|
||||
"software": "foolfuuka",
|
||||
"boards": ["a", "biz", "c", "co", "diy", "fit", "gd", "h", "i", "int", "jp", "k", "m", "mlp", "out", "po", "qa", "r9k", "s4s", "sci", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"],
|
||||
"boards": ["a", "biz", "c", "co", "diy", "fit", "gd", "gif", "h", "i", "int", "jp", "k", "m", "mlp", "out", "po", "qa", "r9k", "s4s", "sci", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"],
|
||||
"files": ["a", "biz", "c", "co", "diy", "fit", "gd", "h", "i", "jp", "k", "m", "mlp", "po", "qa", "r9k", "s4s", "sci", "tg", "u", "v", "vg", "vp", "vr", "wsg"]
|
||||
}, {
|
||||
"uid": 3,
|
||||
@ -32,8 +32,8 @@
|
||||
"http": true,
|
||||
"https": true,
|
||||
"software": "foolfuuka",
|
||||
"boards": ["c", "d", "e", "i", "lgbt", "t", "u", "w", "wg"],
|
||||
"files": ["c", "d", "e", "i", "lgbt", "t", "u", "w", "wg"]
|
||||
"boards": ["c", "d", "e", "i", "lgbt", "t", "u"],
|
||||
"files": ["c", "d", "e", "i", "lgbt", "t", "u"]
|
||||
}, {
|
||||
"uid": 8,
|
||||
"name": "Rebecca Black Tech",
|
||||
|
||||
@ -35,6 +35,10 @@ Config =
|
||||
true
|
||||
'Redirect dead threads and images to the archives.'
|
||||
]
|
||||
'Archive Report': [
|
||||
true
|
||||
'Enable reporting posts to supported archives.'
|
||||
]
|
||||
'Except Archives from Encryption': [
|
||||
false
|
||||
'Permit loading content from, and warningless redirects to, HTTP-only archives from HTTPS pages.'
|
||||
@ -474,6 +478,10 @@ Config =
|
||||
'Places a link on the bottom of threads to open the QR.'
|
||||
1
|
||||
]
|
||||
'Captcha Fixes': [
|
||||
true
|
||||
'Make captcha more keyboard-navigable.'
|
||||
]
|
||||
|
||||
'Quote Links':
|
||||
'Quote Backlinks': [
|
||||
|
||||
@ -3,7 +3,7 @@ Get =
|
||||
{OP} = thread
|
||||
excerpt = "/#{thread.board}/ - " + (
|
||||
OP.info.subject?.trim() or
|
||||
OP.info.comment.replace(/\n+/g, ' // ') or
|
||||
OP.info.commentDisplay.replace(/\n+/g, ' // ') or
|
||||
OP.info.nameBlock)
|
||||
return "#{excerpt[...70]}..." if excerpt.length > 73
|
||||
excerpt
|
||||
|
||||
@ -1,8 +1,13 @@
|
||||
Main =
|
||||
init: ->
|
||||
if location.hostname is 'www.google.com'
|
||||
type = if location.pathname is '/recaptcha/api/fallback' then 'noscript' else 'v2'
|
||||
return $.ready -> Captcha[type].initFrame()
|
||||
if location.pathname is '/recaptcha/api/fallback'
|
||||
$.ready -> Captcha.noscript.initFrame()
|
||||
else
|
||||
$.get 'Captcha Fixes', true, ({'Captcha Fixes': enabled}) ->
|
||||
if enabled
|
||||
$.ready -> Captcha.fixes.init()
|
||||
return
|
||||
|
||||
g.threads = new SimpleDict()
|
||||
g.posts = new SimpleDict()
|
||||
@ -56,6 +61,7 @@ Main =
|
||||
when 'a.4cdn.org'
|
||||
return
|
||||
when 'sys.4chan.org'
|
||||
Report.init()
|
||||
PostSuccessful.init() if g.VIEW is 'post'
|
||||
return
|
||||
when 'i.4cdn.org'
|
||||
|
||||
@ -105,10 +105,8 @@ hr + div.center:not(.ad-cnt):not(.topad):not(.middlead):not(.bottomad) {
|
||||
/* party hats */
|
||||
pointer-events: none;
|
||||
}
|
||||
marquee,
|
||||
.postMessage marquee + br,
|
||||
.postMessage marquee + br + br {
|
||||
display: none;
|
||||
:root:not(.js-enabled) #postForm {
|
||||
display: table;
|
||||
}
|
||||
|
||||
/* Anti-autoplay */
|
||||
@ -1282,6 +1280,7 @@ input.field.tripped:not(:hover):not(:focus) {
|
||||
background: linear-gradient(to bottom, #F8F8F8, #DCDCDC) no-repeat;
|
||||
border: 1px solid #BBB;
|
||||
border-radius: 2px;
|
||||
height: 100%;
|
||||
}
|
||||
#qr-file-button {
|
||||
width: 15%;
|
||||
|
||||
@ -125,8 +125,8 @@ $.onExists = (root, selector, subtree, cb) ->
|
||||
|
||||
$.addStyle = (css, id, test) ->
|
||||
style = $.el 'style',
|
||||
id: id
|
||||
textContent: css
|
||||
style.id = id if id?
|
||||
$.asap (-> d.head and (!test? or test())), ->
|
||||
$.add d.head, style
|
||||
style
|
||||
|
||||
@ -106,22 +106,28 @@ class Post
|
||||
# 'Comment too long'...
|
||||
# EXIF data. (/p/)
|
||||
# Rolls. (/tg/)
|
||||
# Marquees. (/pol/)
|
||||
# Fortunes. (/s4s/)
|
||||
bq = @nodes.comment.cloneNode true
|
||||
for node in $$ '.abbr + br, .exif, b, .fortune', bq
|
||||
$.rm node
|
||||
if abbr = $ '.abbr', bq
|
||||
$.rm abbr
|
||||
@info.comment = @nodesToText bq
|
||||
if abbr
|
||||
@info.comment = @info.comment.replace /\n\n$/, ''
|
||||
|
||||
# Hide spoilers.
|
||||
# Remove:
|
||||
# Preceding and following new lines.
|
||||
# Trailing spaces.
|
||||
bq = @nodes.comment.cloneNode true
|
||||
for node in $$ '.abbr, .exif, b, marquee', bq
|
||||
$.rm node
|
||||
@info.comment = @nodesToText bq
|
||||
|
||||
# Get the comment's text with spoilers hidden.
|
||||
spoilers = $$ 's', bq
|
||||
@info.commentSpoilered = if spoilers.length
|
||||
for node in spoilers
|
||||
$.replace node, $.tn '[spoiler]'
|
||||
@nodesToText bq
|
||||
else
|
||||
@info.comment
|
||||
commentDisplay = @info.comment
|
||||
unless Conf['Remove Spoilers'] or Conf['Reveal Spoilers']
|
||||
spoilers = $$ 's', bq
|
||||
if spoilers.length
|
||||
for node in spoilers
|
||||
$.replace node, $.tn '[spoiler]'
|
||||
commentDisplay = @nodesToText bq
|
||||
@info.commentDisplay = commentDisplay.trim().replace /\s+$/gm, ''
|
||||
|
||||
nodesToText: (bq) ->
|
||||
text = ""
|
||||
@ -129,7 +135,7 @@ class Post
|
||||
i = 0
|
||||
while node = nodes.snapshotItem i++
|
||||
text += node.data or '\n'
|
||||
text.trim().replace /\s+$/gm, ''
|
||||
text
|
||||
|
||||
parseQuotes: ->
|
||||
@quotes = []
|
||||
|
||||
@ -11,11 +11,14 @@ ReportLink =
|
||||
el: a
|
||||
order: 10
|
||||
open: (post) ->
|
||||
ReportLink.post = post
|
||||
!post.isDead
|
||||
ReportLink.url = unless post.isDead
|
||||
"//sys.4chan.org/#{post.board}/imgboard.php?mode=report&no=#{post}"
|
||||
else if Conf['Archive Report']
|
||||
Redirect.to 'report', {boardID: post.board.ID, postID: post.ID}
|
||||
!!ReportLink.url
|
||||
|
||||
report: ->
|
||||
{post} = ReportLink
|
||||
url = "//sys.4chan.org/#{post.board}/imgboard.php?mode=report&no=#{post}"
|
||||
{url} = ReportLink
|
||||
id = Date.now()
|
||||
set = "toolbar=0,scrollbars=0,location=0,status=1,menubar=0,resizable=1,width=685,height=285"
|
||||
set = "toolbar=0,scrollbars=1,location=0,status=1,menubar=0,resizable=1,width=685,height=200"
|
||||
window.open url, id, set
|
||||
|
||||
34
src/Miscellaneous/Report.coffee
Executable file
34
src/Miscellaneous/Report.coffee
Executable file
@ -0,0 +1,34 @@
|
||||
Report =
|
||||
init: ->
|
||||
return unless /\bmode=report\b/.test(location.search) and match = location.search.match /\bno=(\d+)/
|
||||
@postID = +match[1]
|
||||
$.ready @ready
|
||||
|
||||
ready: ->
|
||||
new MutationObserver(Report.resize).observe d.body,
|
||||
childList: true
|
||||
attributes: true
|
||||
subtree: true
|
||||
Report.archive() if Conf['Archive Report']
|
||||
|
||||
resize: ->
|
||||
return unless bubble = $ '.gc-bubbleDefault'
|
||||
dy = bubble.getBoundingClientRect().bottom - doc.clientHeight
|
||||
window.resizeBy 0, dy if dy > 0
|
||||
|
||||
archive: ->
|
||||
Redirect.init()
|
||||
return unless url = Redirect.to 'report', {boardID: g.BOARD.ID, postID: Report.postID}
|
||||
|
||||
if (message = $ 'h3') and /Report submitted!/.test(message.textContent)
|
||||
$.globalEval 'self.close = function(){};'
|
||||
window.resizeTo 685, 320
|
||||
location.replace url
|
||||
return
|
||||
link = $.el 'a',
|
||||
href: url
|
||||
textContent: 'Report to fgts'
|
||||
$.on link, 'click', (e) ->
|
||||
unless e.shiftKey or e.altKey or e.ctrlKey or e.metaKey or e.button isnt 0
|
||||
window.resizeTo 685, 320
|
||||
$.add d.body, [$.tn(' ['), link, $.tn(']')]
|
||||
@ -128,7 +128,7 @@ Unread =
|
||||
openNotification: (post) ->
|
||||
return unless Header.areNotificationsEnabled
|
||||
notif = new Notification "#{post.info.nameBlock} replied to you",
|
||||
body: post.info[if Conf['Remove Spoilers'] or Conf['Reveal Spoilers'] then 'comment' else 'commentSpoilered']
|
||||
body: post.info.commentDisplay
|
||||
icon: Favicon.logo
|
||||
notif.onclick = ->
|
||||
Header.scrollToIfNeeded post.nodes.root, true
|
||||
|
||||
61
src/Posting/Captcha.fixes.coffee
Normal file
61
src/Posting/Captcha.fixes.coffee
Normal file
@ -0,0 +1,61 @@
|
||||
Captcha.fixes =
|
||||
css: '''
|
||||
.rc-imageselect-target > .rc-imageselect-tile > img:focus {
|
||||
outline: 2px solid #4a90e2;
|
||||
}
|
||||
.rc-button-default:focus {
|
||||
box-shadow: inset 0 0 0 2px #0063d6;
|
||||
}
|
||||
'''
|
||||
|
||||
init: ->
|
||||
switch location.pathname.split('/')[3]
|
||||
when 'anchor' then @initMain()
|
||||
when 'frame' then @initPopup()
|
||||
|
||||
initMain: ->
|
||||
$.onExists d.body, '#recaptcha-anchor', true, (checkbox) ->
|
||||
focus = ->
|
||||
if d.hasFocus() and d.activeElement isnt checkbox
|
||||
checkbox.focus()
|
||||
focus()
|
||||
$.on window, 'focus', ->
|
||||
$.queueTask focus
|
||||
|
||||
initPopup: ->
|
||||
$.addStyle @css
|
||||
@fixImages()
|
||||
new MutationObserver(=> @fixImages()).observe d.body, {childList: true, subtree: true}
|
||||
$.on d, 'keydown', @keybinds.bind(@)
|
||||
|
||||
fixImages: ->
|
||||
return unless (@images = $$ '.rc-imageselect-target > .rc-imageselect-tile > img').length
|
||||
focus = @images[0].tabIndex isnt 0
|
||||
for img in @images
|
||||
img.tabIndex = 0
|
||||
@focusImage() if focus
|
||||
|
||||
focusImage: ->
|
||||
# XXX Image is not focusable at first in Firefox; to be refactored when I figure out why.
|
||||
img = @images[0]
|
||||
$.asap ->
|
||||
return true unless doc.contains img
|
||||
img.focus()
|
||||
d.activeElement is img
|
||||
, ->
|
||||
|
||||
keybinds: (e) ->
|
||||
return unless @images and doc.contains(@images[0]) and d.activeElement
|
||||
reload = $.id 'recaptcha-reload-button'
|
||||
verify = $.id 'recaptcha-verify-button'
|
||||
x = @images.indexOf d.activeElement
|
||||
if x < 0
|
||||
return unless $('.rc-controls').contains d.activeElement
|
||||
x = if d.activeElement is verify then 11 else 9
|
||||
return unless dx = {38: 9, 40: 3, 37: 11, 39: 1}[e.keyCode] # Up, Down, Left, Right
|
||||
x = (x + dx) % 12
|
||||
if x is 10
|
||||
x = if dx is 11 then 9 else 11
|
||||
(@images[x] or {9: reload, 11: verify}[x]).focus()
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
@ -25,13 +25,6 @@ Captcha.v2 =
|
||||
# XXX Greasemonkey 1.x workaround to gain access to GM_* functions.
|
||||
$.queueTask => @save false
|
||||
|
||||
initFrame: ->
|
||||
$.globalEval 'window.focus = function() {};'
|
||||
$.on window, 'focus', ->
|
||||
$.queueTask ->
|
||||
return unless d.hasFocus() and (checkbox = $.id 'recaptcha-anchor')
|
||||
checkbox.focus() unless d.activeElement is checkbox
|
||||
|
||||
shouldFocus: false
|
||||
timeouts: {}
|
||||
postsCount: 0
|
||||
@ -125,6 +118,11 @@ Captcha.v2 =
|
||||
$.rmClass QR.nodes.el, 'captcha-open'
|
||||
$.rm @nodes.container if @nodes.container
|
||||
delete @nodes.container
|
||||
# Clean up abandoned iframes.
|
||||
for garbage in $$ 'div > .gc-bubbleDefault'
|
||||
$.rm ins if (ins = garbage.parentNode.nextSibling) and ins.nodeName is 'INS'
|
||||
$.rm garbage.parentNode
|
||||
return
|
||||
|
||||
sync: (captchas=[]) ->
|
||||
@captchas = captchas
|
||||
@ -155,11 +153,12 @@ Captcha.v2 =
|
||||
QR.nodes.status.focus()
|
||||
@reload()
|
||||
else
|
||||
focus = d.activeElement?.nodeName is 'IFRAME' and d.activeElement.src?[...38] is 'https://www.google.com/recaptcha/api2/'
|
||||
if pasted
|
||||
@destroy()
|
||||
else
|
||||
@timeouts.destroy ?= setTimeout @destroy.bind(@), 3 * $.SECOND
|
||||
QR.nodes.status.focus()
|
||||
QR.nodes.status.focus() if focus
|
||||
|
||||
QR.submit() if Conf['Post on Captcha Completion'] and !QR.cooldown.auto
|
||||
|
||||
|
||||
@ -9,8 +9,8 @@ QR =
|
||||
|
||||
return if g.VIEW is 'archive'
|
||||
|
||||
$.globalEval 'document.documentElement.dataset.jsEnabled = true;'
|
||||
noscript = Conf['Force Noscript Captcha'] or !doc.dataset.jsEnabled
|
||||
$.globalEval 'document.documentElement.classList.add("js-enabled");'
|
||||
noscript = Conf['Force Noscript Captcha'] or not $.hasClass doc, 'js-enabled'
|
||||
@captcha = Captcha[if noscript then 'noscript' else 'v2']
|
||||
|
||||
$.on d, '4chanXInitFinished', @initReady
|
||||
@ -37,7 +37,7 @@ QR =
|
||||
|
||||
if Conf['Hide Original Post Form']
|
||||
$.addClass doc, 'hide-original-post-form'
|
||||
if !doc.dataset.jsEnabled
|
||||
unless $.hasClass doc, 'js-enabled'
|
||||
# Prevent unnecessary loading of fallback iframe.
|
||||
$.onExists doc, '#postForm noscript', true, $.rm
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user