Merge branch 'v3'

Conflicts:
	LICENSE
	builds/appchan-x.user.js
	builds/crx/script.js
	src/General/Index.coffee
	src/General/Settings.coffee
	src/General/lib/$.coffee
	src/Posting/QuickReply.coffee
This commit is contained in:
Zixaphir 2013-12-24 16:18:47 -07:00
commit ae789f4ad8
30 changed files with 294 additions and 310 deletions

View File

@ -16,6 +16,7 @@ module.exports = (grunt) ->
) )
coffee: coffee:
src: [ src: [
'src/General/Cheats.coffee'
'src/General/Config.coffee' 'src/General/Config.coffee'
'src/General/Globals.coffee' 'src/General/Globals.coffee'
'src/General/lib/*.coffee' 'src/General/lib/*.coffee'

View File

@ -1,5 +1,5 @@
/* /*
* appchan x - Version 2.7.0 - 2013-12-18 * appchan x - Version 2.7.0 - 2013-12-24
* *
* Licensed under the MIT license. * Licensed under the MIT license.
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE * https://github.com/zixaphir/appchan-x/blob/master/LICENSE

View File

@ -22,7 +22,7 @@
// ==/UserScript== // ==/UserScript==
/* /*
* appchan x - Version 2.7.0 - 2013-12-18 * appchan x - Version 2.7.0 - 2013-12-24
* *
* Licensed under the MIT license. * Licensed under the MIT license.
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE * https://github.com/zixaphir/appchan-x/blob/master/LICENSE
@ -111,11 +111,25 @@
(function() { (function() {
var $, $$, Anonymize, ArchiveLink, AutoGIF, Banner, Board, Build, CatalogLinks, Clone, Conf, Config, CustomCSS, DataBoard, DeleteLink, Dice, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, GlobalMessage, Header, IDColor, ImageExpand, ImageHover, ImageLoader, Index, InfiniScroll, JSColor, Keybinds, Linkify, Main, MascotTools, Mascots, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Rice, Sauce, Settings, Style, ThemeTools, Themes, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, c, d, doc, editMascot, editTheme, g, userNavigation, var $, $$, Anonymize, ArchiveLink, AutoGIF, Banner, Board, Build, CatalogLinks, Clone, Conf, Config, CustomCSS, DataBoard, DeleteLink, Dice, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, GlobalMessage, Header, IDColor, ImageExpand, ImageHover, ImageLoader, Index, InfiniScroll, JSColor, Keybinds, Linkify, Main, MascotTools, Mascots, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Rice, Sauce, Settings, Style, ThemeTools, Themes, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, c, d, doc, editMascot, editTheme, g, userNavigation,
__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; },
__slice = [].slice, __slice = [].slice,
__hasProp = {}.hasOwnProperty, __hasProp = {}.hasOwnProperty,
__extends = 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; }, __extends = 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; },
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
__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; };
Array.prototype.indexOf = function(val) {
var i;
i = this.length;
while (i--) {
if (this[i] === val) {
return i;
}
}
return i;
};
__indexOf = [].indexOf;
Config = { Config = {
main: { main: {
@ -2708,26 +2722,6 @@
} }
}; };
String.prototype.contains = function(string) {
return this.indexOf(string) > -1;
};
Array.prototype.contains = function(value) {
return this.indexOf(value) > -1;
};
Array.prototype.indexOf = function(value) {
var i;
i = this.length;
while (i--) {
if (this[i] === value) {
return i;
}
}
return i;
};
$ = function(selector, root) { $ = function(selector, root) {
if (root == null) { if (root == null) {
root = d.body; root = d.body;
@ -2735,15 +2729,14 @@
return root.querySelector(selector); return root.querySelector(selector);
}; };
$.extend = function(object, properties) { $.extend = function(obj, prop) {
var key, val; var key, val;
for (key in properties) { for (key in prop) {
val = properties[key]; val = prop[key];
if (!properties.hasOwnProperty(key)) { if (prop.hasOwnProperty(key)) {
continue; obj[key] = val;
} }
object[key] = val;
} }
}; };
@ -2923,7 +2916,7 @@
}; };
$.hasClass = function(el, className) { $.hasClass = function(el, className) {
return el.classList.contains(className); return __indexOf.call(el.classList, className) >= 0;
}; };
$.rm = (function() { $.rm = (function() {
@ -3427,7 +3420,7 @@
return; return;
} }
fullID = "" + match[1] + "." + match[2]; fullID = "" + match[1] + "." + match[2];
if (!this.quotes.contains(fullID)) { if (__indexOf.call(this.quotes, fullID) < 0) {
return this.quotes.push(fullID); return this.quotes.push(fullID);
} }
}; };
@ -5245,38 +5238,38 @@
}; };
}, },
allQuotelinksLinkingTo: function(post) { allQuotelinksLinkingTo: function(post) {
var ID, quote, quotedPost, quotelinks, quoterPost, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3; var ID, quote, quotedPost, quotelinks, quoterPost, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4;
quotelinks = []; quotelinks = [];
_ref = g.posts; _ref = g.posts;
for (ID in _ref) { for (ID in _ref) {
quoterPost = _ref[ID]; quoterPost = _ref[ID];
if (quoterPost.quotes.contains(post.fullID)) { if (_ref1 = post.fullID, __indexOf.call(quoterPost.quotes, _ref1) >= 0) {
_ref1 = [quoterPost].concat(quoterPost.clones); _ref2 = [quoterPost].concat(quoterPost.clones);
for (_i = 0, _len = _ref1.length; _i < _len; _i++) { for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
quoterPost = _ref1[_i]; quoterPost = _ref2[_i];
quotelinks.push.apply(quotelinks, quoterPost.nodes.quotelinks); quotelinks.push.apply(quotelinks, quoterPost.nodes.quotelinks);
} }
} }
} }
if (Conf['Quote Backlinks']) { if (Conf['Quote Backlinks']) {
_ref2 = post.quotes; _ref3 = post.quotes;
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
quote = _ref2[_j]; quote = _ref3[_j];
if (!(quotedPost = g.posts[quote])) { if (!(quotedPost = g.posts[quote])) {
continue; continue;
} }
_ref3 = [quotedPost].concat(quotedPost.clones); _ref4 = [quotedPost].concat(quotedPost.clones);
for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
quotedPost = _ref3[_k]; quotedPost = _ref4[_k];
quotelinks.push.apply(quotelinks, __slice.call(quotedPost.nodes.backlinks)); quotelinks.push.apply(quotelinks, __slice.call(quotedPost.nodes.backlinks));
} }
} }
} }
return quotelinks.filter(function(quotelink) { return quotelinks.filter(function(quotelink) {
var boardID, postID, _ref4; var boardID, postID, _ref5;
_ref4 = Get.postDataFromLink(quotelink), boardID = _ref4.boardID, postID = _ref4.postID; _ref5 = Get.postDataFromLink(quotelink), boardID = _ref5.boardID, postID = _ref5.postID;
return boardID === post.board.ID && postID === post.ID; return boardID === post.board.ID && postID === post.ID;
}); });
}, },
@ -5325,7 +5318,7 @@
return; return;
} }
status = req.status; status = req.status;
if (![200, 304].contains(status)) { if (status !== 200 && status !== 304) {
if (url = Redirect.to('post', { if (url = Redirect.to('post', {
boardID: boardID, boardID: boardID,
postID: postID postID: postID
@ -5847,7 +5840,9 @@
} }
$.on(root, 'mousemove', o.hover); $.on(root, 'mousemove', o.hover);
o.workaround = function(e) { o.workaround = function(e) {
if (!root.contains(e.target)) { var _ref;
if (_ref = e.target, __indexOf.call(root, _ref) < 0) {
return o.hoverend(); return o.hoverend();
} }
}; };
@ -5921,7 +5916,7 @@
Filter = { Filter = {
filters: {}, filters: {},
init: function() { init: function() {
var boards, err, filter, hl, key, op, regexp, stub, top, _i, _len, _ref, _ref1, _ref2, _ref3, _ref4; var boards, err, filter, hl, key, op, regexp, stub, top, _i, _len, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
if (g.VIEW === 'catalog' || !Conf['Filter']) { if (g.VIEW === 'catalog' || !Conf['Filter']) {
return; return;
@ -5942,10 +5937,10 @@
} }
filter = filter.replace(regexp[0], ''); filter = filter.replace(regexp[0], '');
boards = ((_ref1 = filter.match(/boards:([^;]+)/)) != null ? _ref1[1].toLowerCase() : void 0) || 'global'; boards = ((_ref1 = filter.match(/boards:([^;]+)/)) != null ? _ref1[1].toLowerCase() : void 0) || 'global';
if (boards !== 'global' && !(boards.split(',')).contains(g.BOARD.ID)) { if (boards !== 'global' && (_ref2 = !g.BOARD.ID, __indexOf.call(boards.split(','), _ref2) >= 0)) {
continue; continue;
} }
if (['uniqueID', 'MD5'].contains(key)) { if (key === 'uniqueID' || key === 'MD5') {
regexp = regexp[1]; regexp = regexp[1];
} else { } else {
try { try {
@ -5956,11 +5951,11 @@
continue; continue;
} }
} }
op = ((_ref2 = filter.match(/[^t]op:(yes|no|only)/)) != null ? _ref2[1] : void 0) || 'yes'; op = ((_ref3 = filter.match(/[^t]op:(yes|no|only)/)) != null ? _ref3[1] : void 0) || 'yes';
stub = (function() { stub = (function() {
var _ref3; var _ref4;
switch ((_ref3 = filter.match(/stub:(yes|no)/)) != null ? _ref3[1] : void 0) { switch ((_ref4 = filter.match(/stub:(yes|no)/)) != null ? _ref4[1] : void 0) {
case 'yes': case 'yes':
return true; return true;
case 'no': case 'no':
@ -5970,8 +5965,8 @@
} }
})(); })();
if (hl = /highlight/.test(filter)) { if (hl = /highlight/.test(filter)) {
hl = ((_ref3 = filter.match(/highlight:(\w+)/)) != null ? _ref3[1] : void 0) || 'filter-highlight'; hl = ((_ref4 = filter.match(/highlight:(\w+)/)) != null ? _ref4[1] : void 0) || 'filter-highlight';
top = ((_ref4 = filter.match(/top:(yes|no)/)) != null ? _ref4[1] : void 0) || 'yes'; top = ((_ref5 = filter.match(/top:(yes|no)/)) != null ? _ref5[1] : void 0) || 'yes';
top = top === 'yes'; top = top === 'yes';
} }
this.filters[key].push(this.createFilter(regexp, op, stub, hl, top)); this.filters[key].push(this.createFilter(regexp, op, stub, hl, top));
@ -6169,7 +6164,7 @@
type = this.dataset.type; type = this.dataset.type;
value = Filter[type](Filter.menu.post); value = Filter[type](Filter.menu.post);
re = ['uniqueID', 'MD5'].contains(type) ? value : value.replace(/\/|\\|\^|\$|\n|\.|\(|\)|\{|\}|\[|\]|\?|\*|\+|\|/g, function(c) { re = type === 'uniqueID' || type === 'MD5' ? value : value.replace(/\/|\\|\^|\$|\n|\.|\(|\)|\{|\}|\[|\]|\?|\*|\+|\|/g, function(c) {
if (c === '\n') { if (c === '\n') {
return '\\n'; return '\\n';
} else if (c === '\\') { } else if (c === '\\') {
@ -6178,7 +6173,7 @@
return "\\" + c; return "\\" + c;
} }
}); });
re = ['uniqueID', 'MD5'].contains(type) ? "/" + re + "/" : "/^" + re + "$/"; re = type === 'uniqueID' || type === 'MD5' ? "/" + re + "/" : "/^" + re + "$/";
return $.get(type, Conf[type], function(item) { return $.get(type, Conf[type], function(item) {
var save, section, select, ta, tl; var save, section, select, ta, tl;
@ -6568,7 +6563,7 @@
_ref = g.posts; _ref = g.posts;
for (ID in _ref) { for (ID in _ref) {
post = _ref[ID]; post = _ref[ID];
if (post.quotes.contains(fullID)) { if (__indexOf.call(post.quotes, fullID) >= 0) {
recursive.apply(null, [post].concat(__slice.call(args))); recursive.apply(null, [post].concat(__slice.call(args)));
} }
} }
@ -6603,7 +6598,7 @@
return $.prepend(this.OP.nodes.info, ThreadHiding.makeButton(this, 'hide')); return $.prepend(this.OP.nodes.info, ThreadHiding.makeButton(this, 'hide'));
}, },
onIndexBuild: function(_arg) { onIndexBuild: function(_arg) {
var i, nodes, root, thread, _i, _len; var i, nodes, root, thread, _i, _len, _ref;
nodes = _arg.detail; nodes = _arg.detail;
for (i = _i = 0, _len = nodes.length; _i < _len; i = _i += 2) { for (i = _i = 0, _len = nodes.length; _i < _len; i = _i += 2) {
@ -6614,7 +6609,7 @@
} }
if (!thread.stub) { if (!thread.stub) {
nodes[i + 1].hidden = true; nodes[i + 1].hidden = true;
} else if (!root.contains(thread.stub)) { } else if (_ref = thread.stub, __indexOf.call(root, _ref) < 0) {
ThreadHiding.makeStub(thread, root); ThreadHiding.makeStub(thread, root);
} }
} }
@ -7133,7 +7128,7 @@
}); });
}, },
node: function() { node: function() {
var boardID, fullID, i, postID, quotelink, quotelinks, quotes, _ref; var boardID, fullID, i, postID, quotelink, quotelinks, quotes, _ref, _ref1;
if (this.isClone && this.thread === this.context.thread) { if (this.isClone && this.thread === this.context.thread) {
return; return;
@ -7142,19 +7137,19 @@
return; return;
} }
quotelinks = this.nodes.quotelinks; quotelinks = this.nodes.quotelinks;
if (this.isClone && quotes.contains(this.thread.fullID)) { if (this.isClone && (_ref = this.thread.fullID, __indexOf.call(quotes, _ref) >= 0)) {
i = 0; i = 0;
while (quotelink = quotelinks[i++]) { while (quotelink = quotelinks[i++]) {
quotelink.textContent = quotelink.textContent.replace(QuoteOP.text, ''); quotelink.textContent = quotelink.textContent.replace(QuoteOP.text, '');
} }
} }
fullID = (this.isClone ? this.context : this).thread.fullID; fullID = (this.isClone ? this.context : this).thread.fullID;
if (!quotes.contains(fullID)) { if (__indexOf.call(quotes, fullID) < 0) {
return; return;
} }
i = 0; i = 0;
while (quotelink = quotelinks[i++]) { while (quotelink = quotelinks[i++]) {
_ref = Get.postDataFromLink(quotelink), boardID = _ref.boardID, postID = _ref.postID; _ref1 = Get.postDataFromLink(quotelink), boardID = _ref1.boardID, postID = _ref1.postID;
if (("" + boardID + "." + postID) === fullID) { if (("" + boardID + "." + postID) === fullID) {
$.add(quotelink, $.tn(QuoteOP.text)); $.add(quotelink, $.tn(QuoteOP.text));
} }
@ -7359,7 +7354,7 @@
if (QuoteThreading.hasRun) { if (QuoteThreading.hasRun) {
height = doc.clientHeight; height = doc.clientHeight;
_ref = qpost.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; _ref = qpost.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top;
if (!(Unread.posts.contains(qpost) || ((bottom < height) && (top > 0)))) { if (!(__indexOf.call(Unread.posts, qpost) >= 0 || ((bottom < height) && (top > 0)))) {
return false; return false;
} }
} }
@ -7596,12 +7591,11 @@
}); });
} }
} }
if (!this.quotes.contains(quoteID)) { if (__indexOf.call(this.quotes, quoteID) < 0) {
this.quotes.push(quoteID); this.quotes.push(quoteID);
} }
if (!a) { if (!a) {
deadlink.textContent = "" + quote + "\u00A0(Dead)"; return deadlink.textContent = "" + quote + "\u00A0(Dead)";
return;
} }
$.replace(deadlink, a); $.replace(deadlink, a);
if ($.hasClass(a, 'quotelink')) { if ($.hasClass(a, 'quotelink')) {
@ -7982,7 +7976,7 @@
var embed, file, files, status, type, _i, _j, _len, _len1, _ref; var embed, file, files, status, type, _i, _j, _len, _len1, _ref;
status = this.status; status = this.status;
if (![200, 304].contains(status)) { if (status !== 200 && status !== 304) {
return div.innerHTML = "ERROR " + status; return div.innerHTML = "ERROR " + status;
} }
files = JSON.parse(this.response).files; files = JSON.parse(this.response).files;
@ -8420,7 +8414,7 @@
}); });
}, },
parseItem: function(item, types) { parseItem: function(item, types) {
var boards, match, type, val, _ref, _ref1; var boards, match, type, val, _ref, _ref1, _ref2;
if (item[0] === '#') { if (item[0] === '#') {
return; return;
@ -8431,7 +8425,7 @@
_ref = match, match = _ref[0], type = _ref[1], val = _ref[2]; _ref = match, match = _ref[0], type = _ref[1], val = _ref[2];
item = item.replace(match, ''); item = item.replace(match, '');
boards = ((_ref1 = item.match(/boards:([^;]+)/i)) != null ? _ref1[1].toLowerCase() : void 0) || 'global'; boards = ((_ref1 = item.match(/boards:([^;]+)/i)) != null ? _ref1[1].toLowerCase() : void 0) || 'global';
if (boards !== 'global' && !((boards.split(',')).contains(g.BOARD.ID))) { if (boards !== 'global' && (_ref2 = !g.BOARD.ID, __indexOf.call(boards.split(','), _ref2) >= 0)) {
return; return;
} }
if (type === 'password') { if (type === 'password') {
@ -8444,7 +8438,7 @@
if (/always/i.test(item)) { if (/always/i.test(item)) {
QR.persona.always[type] = val; QR.persona.always[type] = val;
} }
if (!types[type].contains(val)) { if (__indexOf.call(types[type], val) < 0) {
return types[type].push(val); return types[type].push(val);
} }
}, },
@ -8741,12 +8735,12 @@
} }
}, },
handleFile: function(file, isSingle, max) { handleFile: function(file, isSingle, max) {
var post; var post, _ref;
if (file.size > max) { if (file.size > max) {
QR.error("" + file.name + ": File too large (file: " + ($.bytesToString(file.size)) + ", max: " + ($.bytesToString(max)) + ")."); QR.error("" + file.name + ": File too large (file: " + ($.bytesToString(file.size)) + ", max: " + ($.bytesToString(max)) + ").");
return; return;
} else if (!QR.mimeTypes.contains(file.type)) { } else if (_ref = file.type, __indexOf.call(QR.mimeTypes, _ref) < 0) {
if (!/^text/.test(file.type)) { if (!/^text/.test(file.type)) {
QR.error("" + file.name + ": Unsupported file type."); QR.error("" + file.name + ": Unsupported file type.");
return; return;
@ -8767,6 +8761,8 @@
return post.setFile(file); return post.setFile(file);
}, },
openFileInput: function(e) { openFileInput: function(e) {
var _ref;
e.stopPropagation(); e.stopPropagation();
if (e.shiftKey && e.type === 'click') { if (e.shiftKey && e.type === 'click') {
return QR.selected.rmFile(); return QR.selected.rmFile();
@ -8776,7 +8772,7 @@
QR.nodes.filename.focus(); QR.nodes.filename.focus();
return; return;
} }
if (e.target.nodeName === 'INPUT' || (e.keyCode && ![32, 13].contains(e.keyCode)) || e.ctrlKey) { if (e.target.nodeName === 'INPUT' || (e.keyCode && ((_ref = !e.keyCode) === 32 || _ref === 13)) || e.ctrlKey) {
return; return;
} }
e.preventDefault(); e.preventDefault();
@ -10124,7 +10120,7 @@
innerHTML: "<input type=checkbox name='" + name + "'> " + name innerHTML: "<input type=checkbox name='" + name + "'> " + name
}); });
input = label.firstElementChild; input = label.firstElementChild;
if (['Fit Width', 'Fit Height', 'Hide Thumbnails'].contains(name)) { if (name === 'Fit Width' || name === 'Fit Height' || name === 'Hide Thumbnails') {
$.on(input, 'change', Gallery.cb.setFitness); $.on(input, 'change', Gallery.cb.setFitness);
} }
input.checked = Conf[name]; input.checked = Conf[name];
@ -10181,7 +10177,7 @@
return ImageExpand.toggle(Get.postFromNode(this)); return ImageExpand.toggle(Get.postFromNode(this));
}, },
toggleAll: function() { toggleAll: function() {
var ID, file, func, post, _i, _len, _ref, _ref1; var ID, file, func, post, _i, _len, _ref, _ref1, _ref2;
$.event('CloseMenu'); $.event('CloseMenu');
if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) { if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) {
@ -10200,7 +10196,7 @@
for (_i = 0, _len = _ref1.length; _i < _len; _i++) { for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
post = _ref1[_i]; post = _ref1[_i];
file = post.file; file = post.file;
if (!(file && file.isImage && doc.contains(post.nodes.root))) { if (!(file && file.isImage && (_ref2 = post.nodes.root, __indexOf.call(doc, _ref2) >= 0))) {
continue; continue;
} }
if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) { if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) {
@ -10444,7 +10440,7 @@
var URL, post, src, timeoutID, var URL, post, src, timeoutID,
_this = this; _this = this;
if (!doc.contains(this)) { if (__indexOf.call(doc, this) < 0) {
return; return;
} }
post = g.posts[this.dataset.fullID]; post = g.posts[this.dataset.fullID];
@ -11437,12 +11433,12 @@
for (ID in _ref) { for (ID in _ref) {
post = _ref[ID]; post = _ref[ID];
ID = +ID; ID = +ID;
if (post.isDead && index.contains(ID)) { if (__indexOf.call(index, ID) < 0) {
post.resurrect();
} else if (!index.contains(ID)) {
post.kill(); post.kill();
deletedPosts.push(post); deletedPosts.push(post);
} else if (post.file && !post.file.isDead && !files.contains(ID)) { } else if (post.isDead) {
post.resurrect();
} else if (post.file && !(post.file.isDead || __indexOf.call(files, ID) >= 0)) {
post.kill(true); post.kill(true);
deletedFiles.push(post); deletedFiles.push(post);
} }
@ -12115,7 +12111,7 @@
return Unread.update(); return Unread.update();
}, },
addPosts: function(posts) { addPosts: function(posts) {
var ID, data, post, _i, _len; var ID, data, post, _i, _len, _ref;
for (_i = 0, _len = posts.length; _i < _len; _i++) { for (_i = 0, _len = posts.length; _i < _len; _i++) {
post = posts[_i]; post = posts[_i];
@ -12137,7 +12133,7 @@
Unread.addPostQuotingYou(post); Unread.addPostQuotingYou(post);
} }
if (Conf['Unread Line']) { if (Conf['Unread Line']) {
Unread.setLine(posts.contains(Unread.posts[0])); Unread.setLine((_ref = Unread.posts[0], __indexOf.call(posts, _ref) >= 0));
} }
Unread.read(); Unread.read();
return Unread.update(); return Unread.update();
@ -12302,7 +12298,7 @@
file: {} file: {}
}, },
init: function() { init: function() {
var archive, boardID, boards, data, id, name, type, _i, _len, _ref, _ref1, _ref2; var archive, boardID, boards, data, id, name, type, _i, _len, _ref, _ref1, _ref2, _ref3;
_ref = Conf['selectedArchives']; _ref = Conf['selectedArchives'];
for (boardID in _ref) { for (boardID in _ref) {
@ -12311,7 +12307,7 @@
id = data[type]; id = data[type];
if (archive = Redirect.archives[id]) { if (archive = Redirect.archives[id]) {
boards = archive[type] || archive['boards']; boards = archive[type] || archive['boards'];
if (!boards.contains(boardID)) { if (__indexOf.call(boards, boardID) < 0) {
continue; continue;
} }
Redirect.data[type][boardID] = archive; Redirect.data[type][boardID] = archive;
@ -12330,7 +12326,7 @@
if (!(boardID in Redirect.data.post || archive.software !== 'foolfuuka')) { if (!(boardID in Redirect.data.post || archive.software !== 'foolfuuka')) {
Redirect.data.post[boardID] = archive; Redirect.data.post[boardID] = archive;
} }
if (!(boardID in Redirect.data.file || !archive.files.contains(boardID))) { if (!(boardID in Redirect.data.file || (_ref3 = !boardID, __indexOf.call(archive.files, _ref3) >= 0))) {
Redirect.data.file[boardID] = archive; Redirect.data.file[boardID] = archive;
} }
} }
@ -13305,7 +13301,7 @@
_ref = ["Enabled Mascots", "Enabled Mascots sfw", "Enabled Mascots nsfw"]; _ref = ["Enabled Mascots", "Enabled Mascots sfw", "Enabled Mascots nsfw"];
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
type = _ref[_i]; type = _ref[_i];
if (!Conf[type].contains(name)) { if (__indexOf.call(Conf[type], name) < 0) {
Conf[type].push(name); Conf[type].push(name);
$.set(type, Conf[type]); $.set(type, Conf[type]);
} }
@ -13595,13 +13591,13 @@
} }
}, },
remStyle: function(_arg) { remStyle: function(_arg) {
var addedNodes, href, i, node; var addedNodes, href, i, node, _ref;
addedNodes = _arg.addedNodes; addedNodes = _arg.addedNodes;
i = addedNodes.length; i = addedNodes.length;
while (i--) { while (i--) {
node = addedNodes[i]; node = addedNodes[i];
if (!(node.nodeName === 'STYLE' && node.id || !['LINK', 'STYLE'].contains(node.nodeName) || node.rel && (!/stylesheet/.test(node.rel) || /flags.*\.css$/.test(href = node.href) || href.slice(0, 4) === 'data') || /\.typeset/.test(node.textContent))) { if (!(node.nodeName === 'STYLE' && node.id || ((_ref = node.nodeName) !== 'LINK' && _ref !== 'STYLE') || node.rel && (!/stylesheet/.test(node.rel) || /flags.*\.css$/.test(href = node.href) || href.slice(0, 4) === 'data') || /\.typeset/.test(node.textContent))) {
$.rm(node); $.rm(node);
} }
} }
@ -14156,7 +14152,7 @@
return CatalogLinks.set(this.checked); return CatalogLinks.set(this.checked);
}, },
set: function(useCatalog) { set: function(useCatalog) {
var a, board, generateURL, path, _i, _len, _ref; var a, board, generateURL, path, _i, _len, _ref, _ref1;
path = useCatalog ? 'catalog' : ''; path = useCatalog ? 'catalog' : '';
generateURL = useCatalog && Conf['External Catalog'] ? CatalogLinks.external : function(board) { generateURL = useCatalog && Conf['External Catalog'] ? CatalogLinks.external : function(board) {
@ -14165,7 +14161,7 @@
_ref = $$("#board-list a:not(.catalog), #boardNavDesktopFoot a"); _ref = $$("#board-list a:not(.catalog), #boardNavDesktopFoot a");
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
a = _ref[_i]; a = _ref[_i];
if (!['boards.4chan.org', 'catalog.neet.tv', '4index.gropes.us'].contains(a.hostname) || !(board = a.pathname.split('/')[1]) || ['f', 'status', '4chan'].contains(board)) { if (((_ref1 = !a.hostname) === 'boards.4chan.org' || _ref1 === 'catalog.neet.tv' || _ref1 === '4index.gropes.us') || !(board = a.pathname.split('/')[1]) || (board === 'f' || board === 'status' || board === '4chan')) {
continue; continue;
} }
a.href = generateURL(board); a.href = generateURL(board);
@ -14350,7 +14346,7 @@
var callback, clone, comment, href, postObj, posts, quote, spoilerRange, status, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; var callback, clone, comment, href, postObj, posts, quote, spoilerRange, status, _i, _j, _k, _len, _len1, _len2, _ref, _ref1;
status = req.status; status = req.status;
if (![200, 304].contains(status)) { if (status !== 200 && status !== 304) {
a.textContent = "Error " + req.statusText + " (" + status + ")"; a.textContent = "Error " + req.statusText + " (" + status + ")";
return; return;
} }
@ -14959,13 +14955,13 @@
return Conf[hotkey] = key; return Conf[hotkey] = key;
}, },
keydown: function(e) { keydown: function(e) {
var key, notification, notifications, op, target, thread, threadRoot, _i, _len; var key, notification, notifications, op, target, thread, threadRoot, _i, _len, _ref;
if (!(key = Keybinds.keyCode(e))) { if (!(key = Keybinds.keyCode(e))) {
return; return;
} }
target = e.target; target = e.target;
if (['INPUT', 'TEXTAREA'].contains(target.nodeName)) { if ((_ref = target.nodeName) === 'INPUT' || _ref === 'TEXTAREA') {
if (!/(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test(key)) { if (!/(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test(key)) {
return; return;
} }
@ -16038,7 +16034,7 @@
input = $("[name='" + name + "']", section); input = $("[name='" + name + "']", section);
items[name] = Conf[name]; items[name] = Conf[name];
inputs[name] = input; inputs[name] = input;
event = ['favicon', 'usercss'].contains(name) ? 'change' : 'input'; event = name === 'favicon' || name === 'usercss' ? 'change' : 'input';
$.on(input, event, $.cb.value); $.on(input, event, $.cb.value);
} }
ta = $('.personafield', section); ta = $('.personafield', section);
@ -16080,7 +16076,7 @@
if (archive.software === 'foolfuuka') { if (archive.software === 'foolfuuka') {
data.post.push(name); data.post.push(name);
} }
if (archive.files.contains(boardID)) { if (__indexOf.call(archive.files, boardID) >= 0) {
data.file.push(name); data.file.push(name);
} }
} }
@ -16493,11 +16489,11 @@
id: name, id: name,
className: "mascots-container", className: "mascots-container",
innerHTML: "<h3 class=mascotHeader>" + name + "</h3>", innerHTML: "<h3 class=mascotHeader>" + name + "</h3>",
hidden: Conf["Hidden Categories"].contains(name) hidden: __indexOf.call(Conf["Hidden Categories"], name) >= 0
}); });
option = $.el("label", { option = $.el("label", {
name: name, name: name,
innerHTML: "<input name='" + name + "' type=checkbox " + (Conf["Hidden Categories"].contains(name) ? 'checked' : '') + ">" + name innerHTML: "<input name='" + name + "' type=checkbox " + (__indexOf.call(Conf["Hidden Categories"], name) >= 0 ? 'checked' : '') + ">" + name
}); });
$.on($('input', option), 'change', cb.category); $.on($('input', option), 'change', cb.category);
$.add(suboptions, div); $.add(suboptions, div);
@ -16505,13 +16501,13 @@
} }
for (_j = 0, _len1 = keys.length; _j < _len1; _j++) { for (_j = 0, _len1 = keys.length; _j < _len1; _j++) {
name = keys[_j]; name = keys[_j];
if (Conf["Deleted Mascots"].contains(name)) { if (__indexOf.call(Conf["Deleted Mascots"], name) >= 0) {
continue; continue;
} }
mascot = Mascots[name]; mascot = Mascots[name];
mascotEl = $.el('div', { mascotEl = $.el('div', {
id: name, id: name,
className: Conf[g.MASCOTSTRING].contains(name) ? 'mascot enabled' : 'mascot', className: __indexOf.call(Conf[g.MASCOTSTRING], name) >= 0 ? 'mascot enabled' : 'mascot',
innerHTML: "<div class='mascotname'>" + (name.replace(/_/g, " ")) + "</div><div class='mascotcontainer " + (mascot.silhouette ? 'silhouette' : '') + "'><div class='mAlign " + mascot.category + "'><img class=mascotimg src='" + mascot.image + "'></div></div>" innerHTML: "<div class='mascotname'>" + (name.replace(/_/g, " ")) + "</div><div class='mascotcontainer " + (mascot.silhouette ? 'silhouette' : '') + "'><div class='mAlign " + mascot.category + "'><img class=mascotimg src='" + mascot.image + "'></div></div>"
}); });
$.on(mascotEl, 'click', cb.select); $.on(mascotEl, 'click', cb.select);
@ -16533,9 +16529,11 @@
return $.set(g.MASCOTSTRING, Conf[g.MASCOTSTRING] = []); return $.set(g.MASCOTSTRING, Conf[g.MASCOTSTRING] = []);
}); });
$.on($('#selectAll', batchmascots), 'click', function() { $.on($('#selectAll', batchmascots), 'click', function() {
var _ref1;
for (name in Mascots) { for (name in Mascots) {
mascot = Mascots[name]; mascot = Mascots[name];
if (!(Conf["Hidden Categories"].contains(mascot.category) || Conf[g.MASCOTSTRING].contains(name) || Conf["Deleted Mascots"].contains(name))) { if (!((_ref1 = mascot.category, __indexOf.call(Conf["Hidden Categories"], _ref1) >= 0) || __indexOf.call(Conf[g.MASCOTSTRING], name) >= 0 || __indexOf.call(Conf["Deleted Mascots"], name) >= 0)) {
$.addClass($.id(name), 'enabled'); $.addClass($.id(name), 'enabled');
Conf[g.MASCOTSTRING].push(name); Conf[g.MASCOTSTRING].push(name);
} }
@ -16571,7 +16569,7 @@
}); });
for (_k = 0, _len2 = keys.length; _k < _len2; _k++) { for (_k = 0, _len2 = keys.length; _k < _len2; _k++) {
name = keys[_k]; name = keys[_k];
if (!Conf["Deleted Mascots"].contains(name)) { if (!(__indexOf.call(Conf["Deleted Mascots"], name) >= 0)) {
continue; continue;
} }
mascot = Mascots[name]; mascot = Mascots[name];
@ -16872,7 +16870,7 @@
}); });
}, },
initFeatures: function() { initFeatures: function() {
var init, pathname, _ref; var init, pathname, _ref, _ref1;
pathname = location.pathname.split('/'); pathname = location.pathname.split('/');
g.BOARD = new Board(pathname[1]); g.BOARD = new Board(pathname[1]);
@ -16889,11 +16887,7 @@
if (g.VIEW === 'thread') { if (g.VIEW === 'thread') {
g.THREADID = +pathname[3]; g.THREADID = +pathname[3];
} }
if (['b', 'd', 'e', 'gif', 'h', 'hc', 'hm', 'hr', 'pol', 'r', 'r9k', 'rs', 's', 's4s', 'soc', 't', 'u', 'y'].contains(g.BOARD.ID)) { g.TYPE = (_ref = g.BOARD.ID) === 'b' || _ref === 'd' || _ref === 'e' || _ref === 'gif' || _ref === 'h' || _ref === 'hc' || _ref === 'hm' || _ref === 'hr' || _ref === 'pol' || _ref === 'r' || _ref === 'r9k' || _ref === 'rs' || _ref === 's' || _ref === 's4s' || _ref === 'soc' || _ref === 't' || _ref === 'u' || _ref === 'y' ? 'nsfw' : 'sfw';
g.TYPE = 'nsfw';
} else {
g.TYPE = 'sfw';
}
$.extend(Themes, Conf["userThemes"]); $.extend(Themes, Conf["userThemes"]);
$.extend(Mascots, Conf["userMascots"]); $.extend(Mascots, Conf["userMascots"]);
if (Conf["NSFW/SFW Mascots"]) { if (Conf["NSFW/SFW Mascots"]) {
@ -16904,7 +16898,7 @@
if (Conf["NSFW/SFW Themes"]) { if (Conf["NSFW/SFW Themes"]) {
Conf["theme"] = Conf["theme_" + g.TYPE]; Conf["theme"] = Conf["theme_" + g.TYPE];
} }
if ((_ref = g.BOARD.ID) === 'z' || _ref === 'fk') { if ((_ref1 = g.BOARD.ID) === 'z' || _ref1 === 'fk') {
return Style.init(); return Style.init();
} }
switch (location.hostname) { switch (location.hostname) {
@ -16922,9 +16916,9 @@
return; return;
case 'i.4cdn.org': case 'i.4cdn.org':
$.ready(function() { $.ready(function() {
var URL; var URL, _ref2;
if (Conf['404 Redirect'] && ['4chan - Temporarily Offline', '4chan - 404 Not Found'].contains(d.title)) { if (Conf['404 Redirect'] && ((_ref2 = d.title) === '4chan - Temporarily Offline' || _ref2 === '4chan - 404 Not Found')) {
Redirect.init(); Redirect.init();
pathname = location.pathname.split('/'); pathname = location.pathname.split('/');
URL = Redirect.to('file', { URL = Redirect.to('file', {
@ -17024,9 +17018,9 @@
return $.ready(Main.initReady); return $.ready(Main.initReady);
}, },
initReady: function() { initReady: function() {
var GMver, err, errors, href, i, passLink, postRoot, posts, styleSelector, thread, threadRoot, v, _i, _j, _len, _len1, _ref, _ref1; var GMver, err, errors, href, i, passLink, postRoot, posts, styleSelector, thread, threadRoot, v, _i, _j, _len, _len1, _ref, _ref1, _ref2;
if (['4chan - Temporarily Offline', '4chan - 404 Not Found'].contains(d.title)) { if ((_ref = d.title) === '4chan - Temporarily Offline' || _ref === '4chan - 404 Not Found') {
if (Conf['404 Redirect'] && g.VIEW === 'thread') { if (Conf['404 Redirect'] && g.VIEW === 'thread') {
href = Redirect.to('thread', { href = Redirect.to('thread', {
boardID: g.BOARD.ID, boardID: g.BOARD.ID,
@ -17040,9 +17034,9 @@
if (g.VIEW === 'thread' && (threadRoot = $('.thread'))) { if (g.VIEW === 'thread' && (threadRoot = $('.thread'))) {
thread = new Thread(+threadRoot.id.slice(1), g.BOARD); thread = new Thread(+threadRoot.id.slice(1), g.BOARD);
posts = []; posts = [];
_ref = $$('.thread > .postContainer', threadRoot); _ref1 = $$('.thread > .postContainer', threadRoot);
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
postRoot = _ref[_i]; postRoot = _ref1[_i];
try { try {
posts.push(new Post(postRoot, thread, g.BOARD)); posts.push(new Post(postRoot, thread, g.BOARD));
} catch (_error) { } catch (_error) {
@ -17076,9 +17070,9 @@
return; return;
} }
GMver = GM_info.version.split('.'); GMver = GM_info.version.split('.');
_ref1 = "1.12".split('.'); _ref2 = "1.12".split('.');
for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) { for (i = _j = 0, _len1 = _ref2.length; _j < _len1; i = ++_j) {
v = _ref1[i]; v = _ref2[i];
if (v < GMver[i]) { if (v < GMver[i]) {
break; break;
} }

View File

@ -1,6 +1,6 @@
// Generated by CoffeeScript // Generated by CoffeeScript
/* /*
* appchan x - Version 2.7.0 - 2013-12-18 * appchan x - Version 2.7.0 - 2013-12-24
* *
* Licensed under the MIT license. * Licensed under the MIT license.
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE * https://github.com/zixaphir/appchan-x/blob/master/LICENSE
@ -89,12 +89,26 @@
(function() { (function() {
var $, $$, Anonymize, ArchiveLink, AutoGIF, Banner, Board, Build, CatalogLinks, Clone, Conf, Config, CustomCSS, DataBoard, DeleteLink, Dice, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, GlobalMessage, Header, IDColor, ImageExpand, ImageHover, ImageLoader, Index, InfiniScroll, JSColor, Keybinds, Linkify, Main, MascotTools, Mascots, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Rice, Sauce, Settings, Style, ThemeTools, Themes, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, c, d, doc, editMascot, editTheme, g, userNavigation, var $, $$, Anonymize, ArchiveLink, AutoGIF, Banner, Board, Build, CatalogLinks, Clone, Conf, Config, CustomCSS, DataBoard, DeleteLink, Dice, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, GlobalMessage, Header, IDColor, ImageExpand, ImageHover, ImageLoader, Index, InfiniScroll, JSColor, Keybinds, Linkify, Main, MascotTools, Mascots, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Rice, Sauce, Settings, Style, ThemeTools, Themes, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, c, d, doc, editMascot, editTheme, g, userNavigation,
__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; }, __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; },
__slice = [].slice,
__hasProp = {}.hasOwnProperty, __hasProp = {}.hasOwnProperty,
__extends = 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; }, __extends = 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; },
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
Array.prototype.indexOf = function(val) {
var i;
i = this.length;
while (i--) {
if (this[i] === val) {
return i;
}
}
return i;
};
__indexOf = [].indexOf;
Config = { Config = {
main: { main: {
'Miscellaneous': { 'Miscellaneous': {
@ -2687,26 +2701,6 @@
} }
}; };
String.prototype.contains = function(string) {
return this.indexOf(string) > -1;
};
Array.prototype.contains = function(value) {
return this.indexOf(value) > -1;
};
Array.prototype.indexOf = function(value) {
var i;
i = this.length;
while (i--) {
if (this[i] === value) {
return i;
}
}
return i;
};
$ = function(selector, root) { $ = function(selector, root) {
if (root == null) { if (root == null) {
root = d.body; root = d.body;
@ -2714,15 +2708,14 @@
return root.querySelector(selector); return root.querySelector(selector);
}; };
$.extend = function(object, properties) { $.extend = function(obj, prop) {
var key, val; var key, val;
for (key in properties) { for (key in prop) {
val = properties[key]; val = prop[key];
if (!properties.hasOwnProperty(key)) { if (prop.hasOwnProperty(key)) {
continue; obj[key] = val;
} }
object[key] = val;
} }
}; };
@ -2902,7 +2895,7 @@
}; };
$.hasClass = function(el, className) { $.hasClass = function(el, className) {
return el.classList.contains(className); return __indexOf.call(el.classList, className) >= 0;
}; };
$.rm = (function() { $.rm = (function() {
@ -3435,7 +3428,7 @@
return; return;
} }
fullID = "" + match[1] + "." + match[2]; fullID = "" + match[1] + "." + match[2];
if (!this.quotes.contains(fullID)) { if (__indexOf.call(this.quotes, fullID) < 0) {
return this.quotes.push(fullID); return this.quotes.push(fullID);
} }
}; };
@ -5258,38 +5251,38 @@
}; };
}, },
allQuotelinksLinkingTo: function(post) { allQuotelinksLinkingTo: function(post) {
var ID, quote, quotedPost, quotelinks, quoterPost, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3; var ID, quote, quotedPost, quotelinks, quoterPost, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4;
quotelinks = []; quotelinks = [];
_ref = g.posts; _ref = g.posts;
for (ID in _ref) { for (ID in _ref) {
quoterPost = _ref[ID]; quoterPost = _ref[ID];
if (quoterPost.quotes.contains(post.fullID)) { if (_ref1 = post.fullID, __indexOf.call(quoterPost.quotes, _ref1) >= 0) {
_ref1 = [quoterPost].concat(quoterPost.clones); _ref2 = [quoterPost].concat(quoterPost.clones);
for (_i = 0, _len = _ref1.length; _i < _len; _i++) { for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
quoterPost = _ref1[_i]; quoterPost = _ref2[_i];
quotelinks.push.apply(quotelinks, quoterPost.nodes.quotelinks); quotelinks.push.apply(quotelinks, quoterPost.nodes.quotelinks);
} }
} }
} }
if (Conf['Quote Backlinks']) { if (Conf['Quote Backlinks']) {
_ref2 = post.quotes; _ref3 = post.quotes;
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
quote = _ref2[_j]; quote = _ref3[_j];
if (!(quotedPost = g.posts[quote])) { if (!(quotedPost = g.posts[quote])) {
continue; continue;
} }
_ref3 = [quotedPost].concat(quotedPost.clones); _ref4 = [quotedPost].concat(quotedPost.clones);
for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
quotedPost = _ref3[_k]; quotedPost = _ref4[_k];
quotelinks.push.apply(quotelinks, __slice.call(quotedPost.nodes.backlinks)); quotelinks.push.apply(quotelinks, __slice.call(quotedPost.nodes.backlinks));
} }
} }
} }
return quotelinks.filter(function(quotelink) { return quotelinks.filter(function(quotelink) {
var boardID, postID, _ref4; var boardID, postID, _ref5;
_ref4 = Get.postDataFromLink(quotelink), boardID = _ref4.boardID, postID = _ref4.postID; _ref5 = Get.postDataFromLink(quotelink), boardID = _ref5.boardID, postID = _ref5.postID;
return boardID === post.board.ID && postID === post.ID; return boardID === post.board.ID && postID === post.ID;
}); });
}, },
@ -5338,7 +5331,7 @@
return; return;
} }
status = req.status; status = req.status;
if (![200, 304].contains(status)) { if (status !== 200 && status !== 304) {
if (url = Redirect.to('post', { if (url = Redirect.to('post', {
boardID: boardID, boardID: boardID,
postID: postID postID: postID
@ -5927,7 +5920,7 @@
Filter = { Filter = {
filters: {}, filters: {},
init: function() { init: function() {
var boards, err, filter, hl, key, op, regexp, stub, top, _i, _len, _ref, _ref1, _ref2, _ref3, _ref4; var boards, err, filter, hl, key, op, regexp, stub, top, _i, _len, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
if (g.VIEW === 'catalog' || !Conf['Filter']) { if (g.VIEW === 'catalog' || !Conf['Filter']) {
return; return;
@ -5948,10 +5941,10 @@
} }
filter = filter.replace(regexp[0], ''); filter = filter.replace(regexp[0], '');
boards = ((_ref1 = filter.match(/boards:([^;]+)/)) != null ? _ref1[1].toLowerCase() : void 0) || 'global'; boards = ((_ref1 = filter.match(/boards:([^;]+)/)) != null ? _ref1[1].toLowerCase() : void 0) || 'global';
if (boards !== 'global' && !(boards.split(',')).contains(g.BOARD.ID)) { if (boards !== 'global' && (_ref2 = !g.BOARD.ID, __indexOf.call(boards.split(','), _ref2) >= 0)) {
continue; continue;
} }
if (['uniqueID', 'MD5'].contains(key)) { if (key === 'uniqueID' || key === 'MD5') {
regexp = regexp[1]; regexp = regexp[1];
} else { } else {
try { try {
@ -5962,11 +5955,11 @@
continue; continue;
} }
} }
op = ((_ref2 = filter.match(/[^t]op:(yes|no|only)/)) != null ? _ref2[1] : void 0) || 'yes'; op = ((_ref3 = filter.match(/[^t]op:(yes|no|only)/)) != null ? _ref3[1] : void 0) || 'yes';
stub = (function() { stub = (function() {
var _ref3; var _ref4;
switch ((_ref3 = filter.match(/stub:(yes|no)/)) != null ? _ref3[1] : void 0) { switch ((_ref4 = filter.match(/stub:(yes|no)/)) != null ? _ref4[1] : void 0) {
case 'yes': case 'yes':
return true; return true;
case 'no': case 'no':
@ -5976,8 +5969,8 @@
} }
})(); })();
if (hl = /highlight/.test(filter)) { if (hl = /highlight/.test(filter)) {
hl = ((_ref3 = filter.match(/highlight:(\w+)/)) != null ? _ref3[1] : void 0) || 'filter-highlight'; hl = ((_ref4 = filter.match(/highlight:(\w+)/)) != null ? _ref4[1] : void 0) || 'filter-highlight';
top = ((_ref4 = filter.match(/top:(yes|no)/)) != null ? _ref4[1] : void 0) || 'yes'; top = ((_ref5 = filter.match(/top:(yes|no)/)) != null ? _ref5[1] : void 0) || 'yes';
top = top === 'yes'; top = top === 'yes';
} }
this.filters[key].push(this.createFilter(regexp, op, stub, hl, top)); this.filters[key].push(this.createFilter(regexp, op, stub, hl, top));
@ -6175,7 +6168,7 @@
type = this.dataset.type; type = this.dataset.type;
value = Filter[type](Filter.menu.post); value = Filter[type](Filter.menu.post);
re = ['uniqueID', 'MD5'].contains(type) ? value : value.replace(/\/|\\|\^|\$|\n|\.|\(|\)|\{|\}|\[|\]|\?|\*|\+|\|/g, function(c) { re = type === 'uniqueID' || type === 'MD5' ? value : value.replace(/\/|\\|\^|\$|\n|\.|\(|\)|\{|\}|\[|\]|\?|\*|\+|\|/g, function(c) {
if (c === '\n') { if (c === '\n') {
return '\\n'; return '\\n';
} else if (c === '\\') { } else if (c === '\\') {
@ -6184,7 +6177,7 @@
return "\\" + c; return "\\" + c;
} }
}); });
re = ['uniqueID', 'MD5'].contains(type) ? "/" + re + "/" : "/^" + re + "$/"; re = type === 'uniqueID' || type === 'MD5' ? "/" + re + "/" : "/^" + re + "$/";
return $.get(type, Conf[type], function(item) { return $.get(type, Conf[type], function(item) {
var save, section, select, ta, tl; var save, section, select, ta, tl;
@ -6574,7 +6567,7 @@
_ref = g.posts; _ref = g.posts;
for (ID in _ref) { for (ID in _ref) {
post = _ref[ID]; post = _ref[ID];
if (post.quotes.contains(fullID)) { if (__indexOf.call(post.quotes, fullID) >= 0) {
recursive.apply(null, [post].concat(__slice.call(args))); recursive.apply(null, [post].concat(__slice.call(args)));
} }
} }
@ -6609,7 +6602,7 @@
return $.prepend(this.OP.nodes.info, ThreadHiding.makeButton(this, 'hide')); return $.prepend(this.OP.nodes.info, ThreadHiding.makeButton(this, 'hide'));
}, },
onIndexBuild: function(_arg) { onIndexBuild: function(_arg) {
var i, nodes, root, thread, _i, _len; var i, nodes, root, thread, _i, _len, _ref;
nodes = _arg.detail; nodes = _arg.detail;
for (i = _i = 0, _len = nodes.length; _i < _len; i = _i += 2) { for (i = _i = 0, _len = nodes.length; _i < _len; i = _i += 2) {
@ -6620,7 +6613,7 @@
} }
if (!thread.stub) { if (!thread.stub) {
nodes[i + 1].hidden = true; nodes[i + 1].hidden = true;
} else if (!root.contains(thread.stub)) { } else if (_ref = thread.stub, __indexOf.call(root, _ref) < 0) {
ThreadHiding.makeStub(thread, root); ThreadHiding.makeStub(thread, root);
} }
} }
@ -7139,7 +7132,7 @@
}); });
}, },
node: function() { node: function() {
var boardID, fullID, i, postID, quotelink, quotelinks, quotes, _ref; var boardID, fullID, i, postID, quotelink, quotelinks, quotes, _ref, _ref1;
if (this.isClone && this.thread === this.context.thread) { if (this.isClone && this.thread === this.context.thread) {
return; return;
@ -7148,19 +7141,19 @@
return; return;
} }
quotelinks = this.nodes.quotelinks; quotelinks = this.nodes.quotelinks;
if (this.isClone && quotes.contains(this.thread.fullID)) { if (this.isClone && (_ref = this.thread.fullID, __indexOf.call(quotes, _ref) >= 0)) {
i = 0; i = 0;
while (quotelink = quotelinks[i++]) { while (quotelink = quotelinks[i++]) {
quotelink.textContent = quotelink.textContent.replace(QuoteOP.text, ''); quotelink.textContent = quotelink.textContent.replace(QuoteOP.text, '');
} }
} }
fullID = (this.isClone ? this.context : this).thread.fullID; fullID = (this.isClone ? this.context : this).thread.fullID;
if (!quotes.contains(fullID)) { if (__indexOf.call(quotes, fullID) < 0) {
return; return;
} }
i = 0; i = 0;
while (quotelink = quotelinks[i++]) { while (quotelink = quotelinks[i++]) {
_ref = Get.postDataFromLink(quotelink), boardID = _ref.boardID, postID = _ref.postID; _ref1 = Get.postDataFromLink(quotelink), boardID = _ref1.boardID, postID = _ref1.postID;
if (("" + boardID + "." + postID) === fullID) { if (("" + boardID + "." + postID) === fullID) {
$.add(quotelink, $.tn(QuoteOP.text)); $.add(quotelink, $.tn(QuoteOP.text));
} }
@ -7365,7 +7358,7 @@
if (QuoteThreading.hasRun) { if (QuoteThreading.hasRun) {
height = doc.clientHeight; height = doc.clientHeight;
_ref = qpost.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top; _ref = qpost.nodes.root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top;
if (!(Unread.posts.contains(qpost) || ((bottom < height) && (top > 0)))) { if (!(__indexOf.call(Unread.posts, qpost) >= 0 || ((bottom < height) && (top > 0)))) {
return false; return false;
} }
} }
@ -7602,12 +7595,11 @@
}); });
} }
} }
if (!this.quotes.contains(quoteID)) { if (__indexOf.call(this.quotes, quoteID) < 0) {
this.quotes.push(quoteID); this.quotes.push(quoteID);
} }
if (!a) { if (!a) {
deadlink.textContent = "" + quote + "\u00A0(Dead)"; return deadlink.textContent = "" + quote + "\u00A0(Dead)";
return;
} }
$.replace(deadlink, a); $.replace(deadlink, a);
if ($.hasClass(a, 'quotelink')) { if ($.hasClass(a, 'quotelink')) {
@ -7988,7 +7980,7 @@
var embed, file, files, status, type, _i, _j, _len, _len1, _ref; var embed, file, files, status, type, _i, _j, _len, _len1, _ref;
status = this.status; status = this.status;
if (![200, 304].contains(status)) { if (status !== 200 && status !== 304) {
return div.innerHTML = "ERROR " + status; return div.innerHTML = "ERROR " + status;
} }
files = JSON.parse(this.response).files; files = JSON.parse(this.response).files;
@ -8431,7 +8423,7 @@
}); });
}, },
parseItem: function(item, types) { parseItem: function(item, types) {
var boards, match, type, val, _ref, _ref1; var boards, match, type, val, _ref, _ref1, _ref2;
if (item[0] === '#') { if (item[0] === '#') {
return; return;
@ -8442,7 +8434,7 @@
_ref = match, match = _ref[0], type = _ref[1], val = _ref[2]; _ref = match, match = _ref[0], type = _ref[1], val = _ref[2];
item = item.replace(match, ''); item = item.replace(match, '');
boards = ((_ref1 = item.match(/boards:([^;]+)/i)) != null ? _ref1[1].toLowerCase() : void 0) || 'global'; boards = ((_ref1 = item.match(/boards:([^;]+)/i)) != null ? _ref1[1].toLowerCase() : void 0) || 'global';
if (boards !== 'global' && !((boards.split(',')).contains(g.BOARD.ID))) { if (boards !== 'global' && (_ref2 = !g.BOARD.ID, __indexOf.call(boards.split(','), _ref2) >= 0)) {
return; return;
} }
if (type === 'password') { if (type === 'password') {
@ -8455,7 +8447,7 @@
if (/always/i.test(item)) { if (/always/i.test(item)) {
QR.persona.always[type] = val; QR.persona.always[type] = val;
} }
if (!types[type].contains(val)) { if (__indexOf.call(types[type], val) < 0) {
return types[type].push(val); return types[type].push(val);
} }
}, },
@ -8752,12 +8744,12 @@
} }
}, },
handleFile: function(file, isSingle, max) { handleFile: function(file, isSingle, max) {
var post; var post, _ref;
if (file.size > max) { if (file.size > max) {
QR.error("" + file.name + ": File too large (file: " + ($.bytesToString(file.size)) + ", max: " + ($.bytesToString(max)) + ")."); QR.error("" + file.name + ": File too large (file: " + ($.bytesToString(file.size)) + ", max: " + ($.bytesToString(max)) + ").");
return; return;
} else if (!QR.mimeTypes.contains(file.type)) { } else if (_ref = file.type, __indexOf.call(QR.mimeTypes, _ref) < 0) {
if (!/^text/.test(file.type)) { if (!/^text/.test(file.type)) {
QR.error("" + file.name + ": Unsupported file type."); QR.error("" + file.name + ": Unsupported file type.");
return; return;
@ -8778,6 +8770,8 @@
return post.setFile(file); return post.setFile(file);
}, },
openFileInput: function(e) { openFileInput: function(e) {
var _ref;
e.stopPropagation(); e.stopPropagation();
if (e.shiftKey && e.type === 'click') { if (e.shiftKey && e.type === 'click') {
return QR.selected.rmFile(); return QR.selected.rmFile();
@ -8787,7 +8781,7 @@
QR.nodes.filename.focus(); QR.nodes.filename.focus();
return; return;
} }
if (e.target.nodeName === 'INPUT' || (e.keyCode && ![32, 13].contains(e.keyCode)) || e.ctrlKey) { if (e.target.nodeName === 'INPUT' || (e.keyCode && ((_ref = !e.keyCode) === 32 || _ref === 13)) || e.ctrlKey) {
return; return;
} }
e.preventDefault(); e.preventDefault();
@ -10110,7 +10104,7 @@
innerHTML: "<input type=checkbox name='" + name + "'> " + name innerHTML: "<input type=checkbox name='" + name + "'> " + name
}); });
input = label.firstElementChild; input = label.firstElementChild;
if (['Fit Width', 'Fit Height', 'Hide Thumbnails'].contains(name)) { if (name === 'Fit Width' || name === 'Fit Height' || name === 'Hide Thumbnails') {
$.on(input, 'change', Gallery.cb.setFitness); $.on(input, 'change', Gallery.cb.setFitness);
} }
input.checked = Conf[name]; input.checked = Conf[name];
@ -10167,7 +10161,7 @@
return ImageExpand.toggle(Get.postFromNode(this)); return ImageExpand.toggle(Get.postFromNode(this));
}, },
toggleAll: function() { toggleAll: function() {
var ID, file, func, post, _i, _len, _ref, _ref1; var ID, file, func, post, _i, _len, _ref, _ref1, _ref2;
$.event('CloseMenu'); $.event('CloseMenu');
if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) { if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) {
@ -10186,7 +10180,7 @@
for (_i = 0, _len = _ref1.length; _i < _len; _i++) { for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
post = _ref1[_i]; post = _ref1[_i];
file = post.file; file = post.file;
if (!(file && file.isImage && doc.contains(post.nodes.root))) { if (!(file && file.isImage && (_ref2 = post.nodes.root, __indexOf.call(doc, _ref2) >= 0))) {
continue; continue;
} }
if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) { if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) {
@ -10430,7 +10424,7 @@
var URL, post, src, timeoutID, var URL, post, src, timeoutID,
_this = this; _this = this;
if (!doc.contains(this)) { if (__indexOf.call(doc, this) < 0) {
return; return;
} }
post = g.posts[this.dataset.fullID]; post = g.posts[this.dataset.fullID];
@ -11423,12 +11417,12 @@
for (ID in _ref) { for (ID in _ref) {
post = _ref[ID]; post = _ref[ID];
ID = +ID; ID = +ID;
if (post.isDead && index.contains(ID)) { if (__indexOf.call(index, ID) < 0) {
post.resurrect();
} else if (!index.contains(ID)) {
post.kill(); post.kill();
deletedPosts.push(post); deletedPosts.push(post);
} else if (post.file && !post.file.isDead && !files.contains(ID)) { } else if (post.isDead) {
post.resurrect();
} else if (post.file && !(post.file.isDead || __indexOf.call(files, ID) >= 0)) {
post.kill(true); post.kill(true);
deletedFiles.push(post); deletedFiles.push(post);
} }
@ -12101,7 +12095,7 @@
return Unread.update(); return Unread.update();
}, },
addPosts: function(posts) { addPosts: function(posts) {
var ID, data, post, _i, _len; var ID, data, post, _i, _len, _ref;
for (_i = 0, _len = posts.length; _i < _len; _i++) { for (_i = 0, _len = posts.length; _i < _len; _i++) {
post = posts[_i]; post = posts[_i];
@ -12123,7 +12117,7 @@
Unread.addPostQuotingYou(post); Unread.addPostQuotingYou(post);
} }
if (Conf['Unread Line']) { if (Conf['Unread Line']) {
Unread.setLine(posts.contains(Unread.posts[0])); Unread.setLine((_ref = Unread.posts[0], __indexOf.call(posts, _ref) >= 0));
} }
Unread.read(); Unread.read();
return Unread.update(); return Unread.update();
@ -12294,7 +12288,7 @@
file: {} file: {}
}, },
init: function() { init: function() {
var archive, boardID, boards, data, id, name, type, _i, _len, _ref, _ref1, _ref2; var archive, boardID, boards, data, id, name, type, _i, _len, _ref, _ref1, _ref2, _ref3;
_ref = Conf['selectedArchives']; _ref = Conf['selectedArchives'];
for (boardID in _ref) { for (boardID in _ref) {
@ -12303,7 +12297,7 @@
id = data[type]; id = data[type];
if (archive = Redirect.archives[id]) { if (archive = Redirect.archives[id]) {
boards = archive[type] || archive['boards']; boards = archive[type] || archive['boards'];
if (!boards.contains(boardID)) { if (__indexOf.call(boards, boardID) < 0) {
continue; continue;
} }
Redirect.data[type][boardID] = archive; Redirect.data[type][boardID] = archive;
@ -12322,7 +12316,7 @@
if (!(boardID in Redirect.data.post || archive.software !== 'foolfuuka')) { if (!(boardID in Redirect.data.post || archive.software !== 'foolfuuka')) {
Redirect.data.post[boardID] = archive; Redirect.data.post[boardID] = archive;
} }
if (!(boardID in Redirect.data.file || !archive.files.contains(boardID))) { if (!(boardID in Redirect.data.file || (_ref3 = !boardID, __indexOf.call(archive.files, _ref3) >= 0))) {
Redirect.data.file[boardID] = archive; Redirect.data.file[boardID] = archive;
} }
} }
@ -13297,7 +13291,7 @@
_ref = ["Enabled Mascots", "Enabled Mascots sfw", "Enabled Mascots nsfw"]; _ref = ["Enabled Mascots", "Enabled Mascots sfw", "Enabled Mascots nsfw"];
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
type = _ref[_i]; type = _ref[_i];
if (!Conf[type].contains(name)) { if (__indexOf.call(Conf[type], name) < 0) {
Conf[type].push(name); Conf[type].push(name);
$.set(type, Conf[type]); $.set(type, Conf[type]);
} }
@ -13587,13 +13581,13 @@
} }
}, },
remStyle: function(_arg) { remStyle: function(_arg) {
var addedNodes, href, i, node; var addedNodes, href, i, node, _ref;
addedNodes = _arg.addedNodes; addedNodes = _arg.addedNodes;
i = addedNodes.length; i = addedNodes.length;
while (i--) { while (i--) {
node = addedNodes[i]; node = addedNodes[i];
if (!(node.nodeName === 'STYLE' && node.id || !['LINK', 'STYLE'].contains(node.nodeName) || node.rel && (!/stylesheet/.test(node.rel) || /flags.*\.css$/.test(href = node.href) || href.slice(0, 4) === 'data') || /\.typeset/.test(node.textContent))) { if (!(node.nodeName === 'STYLE' && node.id || ((_ref = node.nodeName) !== 'LINK' && _ref !== 'STYLE') || node.rel && (!/stylesheet/.test(node.rel) || /flags.*\.css$/.test(href = node.href) || href.slice(0, 4) === 'data') || /\.typeset/.test(node.textContent))) {
$.rm(node); $.rm(node);
} }
} }
@ -14148,7 +14142,7 @@
return CatalogLinks.set(this.checked); return CatalogLinks.set(this.checked);
}, },
set: function(useCatalog) { set: function(useCatalog) {
var a, board, generateURL, path, _i, _len, _ref; var a, board, generateURL, path, _i, _len, _ref, _ref1;
path = useCatalog ? 'catalog' : ''; path = useCatalog ? 'catalog' : '';
generateURL = useCatalog && Conf['External Catalog'] ? CatalogLinks.external : function(board) { generateURL = useCatalog && Conf['External Catalog'] ? CatalogLinks.external : function(board) {
@ -14157,7 +14151,7 @@
_ref = $$("#board-list a:not(.catalog), #boardNavDesktopFoot a"); _ref = $$("#board-list a:not(.catalog), #boardNavDesktopFoot a");
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
a = _ref[_i]; a = _ref[_i];
if (!['boards.4chan.org', 'catalog.neet.tv', '4index.gropes.us'].contains(a.hostname) || !(board = a.pathname.split('/')[1]) || ['f', 'status', '4chan'].contains(board)) { if (((_ref1 = !a.hostname) === 'boards.4chan.org' || _ref1 === 'catalog.neet.tv' || _ref1 === '4index.gropes.us') || !(board = a.pathname.split('/')[1]) || (board === 'f' || board === 'status' || board === '4chan')) {
continue; continue;
} }
a.href = generateURL(board); a.href = generateURL(board);
@ -14342,7 +14336,7 @@
var callback, clone, comment, href, postObj, posts, quote, spoilerRange, status, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; var callback, clone, comment, href, postObj, posts, quote, spoilerRange, status, _i, _j, _k, _len, _len1, _len2, _ref, _ref1;
status = req.status; status = req.status;
if (![200, 304].contains(status)) { if (status !== 200 && status !== 304) {
a.textContent = "Error " + req.statusText + " (" + status + ")"; a.textContent = "Error " + req.statusText + " (" + status + ")";
return; return;
} }
@ -14951,13 +14945,13 @@
return Conf[hotkey] = key; return Conf[hotkey] = key;
}, },
keydown: function(e) { keydown: function(e) {
var key, notification, notifications, op, target, thread, threadRoot, _i, _len; var key, notification, notifications, op, target, thread, threadRoot, _i, _len, _ref;
if (!(key = Keybinds.keyCode(e))) { if (!(key = Keybinds.keyCode(e))) {
return; return;
} }
target = e.target; target = e.target;
if (['INPUT', 'TEXTAREA'].contains(target.nodeName)) { if ((_ref = target.nodeName) === 'INPUT' || _ref === 'TEXTAREA') {
if (!/(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test(key)) { if (!/(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test(key)) {
return; return;
} }
@ -16028,7 +16022,7 @@
input = $("[name='" + name + "']", section); input = $("[name='" + name + "']", section);
items[name] = Conf[name]; items[name] = Conf[name];
inputs[name] = input; inputs[name] = input;
event = ['favicon', 'usercss'].contains(name) ? 'change' : 'input'; event = name === 'favicon' || name === 'usercss' ? 'change' : 'input';
$.on(input, event, $.cb.value); $.on(input, event, $.cb.value);
} }
ta = $('.personafield', section); ta = $('.personafield', section);
@ -16070,7 +16064,7 @@
if (archive.software === 'foolfuuka') { if (archive.software === 'foolfuuka') {
data.post.push(name); data.post.push(name);
} }
if (archive.files.contains(boardID)) { if (__indexOf.call(archive.files, boardID) >= 0) {
data.file.push(name); data.file.push(name);
} }
} }
@ -16483,11 +16477,11 @@
id: name, id: name,
className: "mascots-container", className: "mascots-container",
innerHTML: "<h3 class=mascotHeader>" + name + "</h3>", innerHTML: "<h3 class=mascotHeader>" + name + "</h3>",
hidden: Conf["Hidden Categories"].contains(name) hidden: __indexOf.call(Conf["Hidden Categories"], name) >= 0
}); });
option = $.el("label", { option = $.el("label", {
name: name, name: name,
innerHTML: "<input name='" + name + "' type=checkbox " + (Conf["Hidden Categories"].contains(name) ? 'checked' : '') + ">" + name innerHTML: "<input name='" + name + "' type=checkbox " + (__indexOf.call(Conf["Hidden Categories"], name) >= 0 ? 'checked' : '') + ">" + name
}); });
$.on($('input', option), 'change', cb.category); $.on($('input', option), 'change', cb.category);
$.add(suboptions, div); $.add(suboptions, div);
@ -16495,13 +16489,13 @@
} }
for (_j = 0, _len1 = keys.length; _j < _len1; _j++) { for (_j = 0, _len1 = keys.length; _j < _len1; _j++) {
name = keys[_j]; name = keys[_j];
if (Conf["Deleted Mascots"].contains(name)) { if (__indexOf.call(Conf["Deleted Mascots"], name) >= 0) {
continue; continue;
} }
mascot = Mascots[name]; mascot = Mascots[name];
mascotEl = $.el('div', { mascotEl = $.el('div', {
id: name, id: name,
className: Conf[g.MASCOTSTRING].contains(name) ? 'mascot enabled' : 'mascot', className: __indexOf.call(Conf[g.MASCOTSTRING], name) >= 0 ? 'mascot enabled' : 'mascot',
innerHTML: "<div class='mascotname'>" + (name.replace(/_/g, " ")) + "</div><div class='mascotcontainer " + (mascot.silhouette ? 'silhouette' : '') + "'><div class='mAlign " + mascot.category + "'><img class=mascotimg src='" + mascot.image + "'></div></div>" innerHTML: "<div class='mascotname'>" + (name.replace(/_/g, " ")) + "</div><div class='mascotcontainer " + (mascot.silhouette ? 'silhouette' : '') + "'><div class='mAlign " + mascot.category + "'><img class=mascotimg src='" + mascot.image + "'></div></div>"
}); });
$.on(mascotEl, 'click', cb.select); $.on(mascotEl, 'click', cb.select);
@ -16523,9 +16517,11 @@
return $.set(g.MASCOTSTRING, Conf[g.MASCOTSTRING] = []); return $.set(g.MASCOTSTRING, Conf[g.MASCOTSTRING] = []);
}); });
$.on($('#selectAll', batchmascots), 'click', function() { $.on($('#selectAll', batchmascots), 'click', function() {
var _ref1;
for (name in Mascots) { for (name in Mascots) {
mascot = Mascots[name]; mascot = Mascots[name];
if (!(Conf["Hidden Categories"].contains(mascot.category) || Conf[g.MASCOTSTRING].contains(name) || Conf["Deleted Mascots"].contains(name))) { if (!((_ref1 = mascot.category, __indexOf.call(Conf["Hidden Categories"], _ref1) >= 0) || __indexOf.call(Conf[g.MASCOTSTRING], name) >= 0 || __indexOf.call(Conf["Deleted Mascots"], name) >= 0)) {
$.addClass($.id(name), 'enabled'); $.addClass($.id(name), 'enabled');
Conf[g.MASCOTSTRING].push(name); Conf[g.MASCOTSTRING].push(name);
} }
@ -16561,7 +16557,7 @@
}); });
for (_k = 0, _len2 = keys.length; _k < _len2; _k++) { for (_k = 0, _len2 = keys.length; _k < _len2; _k++) {
name = keys[_k]; name = keys[_k];
if (!Conf["Deleted Mascots"].contains(name)) { if (!(__indexOf.call(Conf["Deleted Mascots"], name) >= 0)) {
continue; continue;
} }
mascot = Mascots[name]; mascot = Mascots[name];
@ -16856,7 +16852,7 @@
}); });
}, },
initFeatures: function() { initFeatures: function() {
var init, pathname, _ref; var init, pathname, _ref, _ref1;
pathname = location.pathname.split('/'); pathname = location.pathname.split('/');
g.BOARD = new Board(pathname[1]); g.BOARD = new Board(pathname[1]);
@ -16873,11 +16869,7 @@
if (g.VIEW === 'thread') { if (g.VIEW === 'thread') {
g.THREADID = +pathname[3]; g.THREADID = +pathname[3];
} }
if (['b', 'd', 'e', 'gif', 'h', 'hc', 'hm', 'hr', 'pol', 'r', 'r9k', 'rs', 's', 's4s', 'soc', 't', 'u', 'y'].contains(g.BOARD.ID)) { g.TYPE = (_ref = g.BOARD.ID) === 'b' || _ref === 'd' || _ref === 'e' || _ref === 'gif' || _ref === 'h' || _ref === 'hc' || _ref === 'hm' || _ref === 'hr' || _ref === 'pol' || _ref === 'r' || _ref === 'r9k' || _ref === 'rs' || _ref === 's' || _ref === 's4s' || _ref === 'soc' || _ref === 't' || _ref === 'u' || _ref === 'y' ? 'nsfw' : 'sfw';
g.TYPE = 'nsfw';
} else {
g.TYPE = 'sfw';
}
$.extend(Themes, Conf["userThemes"]); $.extend(Themes, Conf["userThemes"]);
$.extend(Mascots, Conf["userMascots"]); $.extend(Mascots, Conf["userMascots"]);
if (Conf["NSFW/SFW Mascots"]) { if (Conf["NSFW/SFW Mascots"]) {
@ -16888,7 +16880,7 @@
if (Conf["NSFW/SFW Themes"]) { if (Conf["NSFW/SFW Themes"]) {
Conf["theme"] = Conf["theme_" + g.TYPE]; Conf["theme"] = Conf["theme_" + g.TYPE];
} }
if ((_ref = g.BOARD.ID) === 'z' || _ref === 'fk') { if ((_ref1 = g.BOARD.ID) === 'z' || _ref1 === 'fk') {
return Style.init(); return Style.init();
} }
switch (location.hostname) { switch (location.hostname) {
@ -16906,9 +16898,9 @@
return; return;
case 'i.4cdn.org': case 'i.4cdn.org':
$.ready(function() { $.ready(function() {
var URL; var URL, _ref2;
if (Conf['404 Redirect'] && ['4chan - Temporarily Offline', '4chan - 404 Not Found'].contains(d.title)) { if (Conf['404 Redirect'] && ((_ref2 = d.title) === '4chan - Temporarily Offline' || _ref2 === '4chan - 404 Not Found')) {
Redirect.init(); Redirect.init();
pathname = location.pathname.split('/'); pathname = location.pathname.split('/');
URL = Redirect.to('file', { URL = Redirect.to('file', {
@ -17008,9 +17000,9 @@
return $.ready(Main.initReady); return $.ready(Main.initReady);
}, },
initReady: function() { initReady: function() {
var err, errors, href, passLink, postRoot, posts, styleSelector, thread, threadRoot, _i, _len, _ref; var err, errors, href, passLink, postRoot, posts, styleSelector, thread, threadRoot, _i, _len, _ref, _ref1;
if (['4chan - Temporarily Offline', '4chan - 404 Not Found'].contains(d.title)) { if ((_ref = d.title) === '4chan - Temporarily Offline' || _ref === '4chan - 404 Not Found') {
if (Conf['404 Redirect'] && g.VIEW === 'thread') { if (Conf['404 Redirect'] && g.VIEW === 'thread') {
href = Redirect.to('thread', { href = Redirect.to('thread', {
boardID: g.BOARD.ID, boardID: g.BOARD.ID,
@ -17024,9 +17016,9 @@
if (g.VIEW === 'thread' && (threadRoot = $('.thread'))) { if (g.VIEW === 'thread' && (threadRoot = $('.thread'))) {
thread = new Thread(+threadRoot.id.slice(1), g.BOARD); thread = new Thread(+threadRoot.id.slice(1), g.BOARD);
posts = []; posts = [];
_ref = $$('.thread > .postContainer', threadRoot); _ref1 = $$('.thread > .postContainer', threadRoot);
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
postRoot = _ref[_i]; postRoot = _ref1[_i];
try { try {
posts.push(new Post(postRoot, thread, g.BOARD)); posts.push(new Post(postRoot, thread, g.BOARD));
} catch (_error) { } catch (_error) {

View File

@ -9,7 +9,7 @@ Redirect =
for type, id of data for type, id of data
if archive = Redirect.archives[id] if archive = Redirect.archives[id]
boards = archive[type] or archive['boards'] boards = archive[type] or archive['boards']
continue unless boards.contains boardID continue unless boardID in boards
Redirect.data[type][boardID] = archive Redirect.data[type][boardID] = archive
for name, archive of Redirect.archives for name, archive of Redirect.archives
for boardID in archive.boards for boardID in archive.boards
@ -17,7 +17,7 @@ Redirect =
Redirect.data.thread[boardID] = archive Redirect.data.thread[boardID] = archive
unless boardID of Redirect.data.post or archive.software isnt 'foolfuuka' unless boardID of Redirect.data.post or archive.software isnt 'foolfuuka'
Redirect.data.post[boardID] = archive Redirect.data.post[boardID] = archive
unless boardID of Redirect.data.file or !archive.files.contains boardID unless boardID of Redirect.data.file or not boardID in archive.files
Redirect.data.file[boardID] = archive Redirect.data.file[boardID] = archive
return return

View File

@ -21,10 +21,10 @@ Filter =
# and it's not specifically applicable to the current board. # and it's not specifically applicable to the current board.
# Defaults to global. # Defaults to global.
boards = filter.match(/boards:([^;]+)/)?[1].toLowerCase() or 'global' boards = filter.match(/boards:([^;]+)/)?[1].toLowerCase() or 'global'
if boards isnt 'global' and not (boards.split ',').contains g.BOARD.ID if boards isnt 'global' and not g.BOARD.ID in boards.split ','
continue continue
if ['uniqueID', 'MD5'].contains key if key in ['uniqueID', 'MD5']
# MD5 filter will use strings instead of regular expressions. # MD5 filter will use strings instead of regular expressions.
regexp = regexp[1] regexp = regexp[1]
else else
@ -218,7 +218,7 @@ Filter =
{type} = @dataset {type} = @dataset
# Convert value -> regexp, unless type is MD5 # Convert value -> regexp, unless type is MD5
value = Filter[type] Filter.menu.post value = Filter[type] Filter.menu.post
re = if ['uniqueID', 'MD5'].contains type then value else value.replace /// re = if type in ['uniqueID', 'MD5'] then value else value.replace ///
/ /
| \\ | \\
| \^ | \^
@ -243,7 +243,7 @@ Filter =
else else
"\\#{c}" "\\#{c}"
re = if ['uniqueID', 'MD5'].contains type re = if type in ['uniqueID', 'MD5']
"/#{re}/" "/#{re}/"
else else
"/^#{re}$/" "/^#{re}$/"

View File

@ -33,6 +33,6 @@ Recursive =
apply: (recursive, post, args...) -> apply: (recursive, post, args...) ->
{fullID} = post {fullID} = post
for ID, post of g.posts for ID, post of g.posts
if post.quotes.contains fullID if fullID in post.quotes
recursive post, args... recursive post, args...
return return

View File

@ -21,7 +21,7 @@ ThreadHiding =
continue unless thread.isHidden continue unless thread.isHidden
unless thread.stub unless thread.stub
nodes[i + 1].hidden = true nodes[i + 1].hidden = true
else unless root.contains thread.stub else unless thread.stub in root
# When we come back to a page, the stub is already there. # When we come back to a page, the stub is already there.
ThreadHiding.makeStub thread, root ThreadHiding.makeStub thread, root
return return

10
src/General/Cheats.coffee Normal file
View File

@ -0,0 +1,10 @@
# I am bad at JavaScript and if you reuse this, so are you.
Array::indexOf = (val) ->
i = @length
while i--
return i if @[i] is val
return i
# Update CoffeeScript's reference to [].indexOf
# Reserved keywords are ignored in embedded javascript.
`__indexOf = [].indexOf`

View File

@ -45,7 +45,7 @@ Get =
# if it did quote this post, # if it did quote this post,
# get all their backlinks. # get all their backlinks.
for ID, quoterPost of g.posts for ID, quoterPost of g.posts
if quoterPost.quotes.contains post.fullID if post.fullID in quoterPost.quotes
for quoterPost in [quoterPost].concat quoterPost.clones for quoterPost in [quoterPost].concat quoterPost.clones
quotelinks.push.apply quotelinks, quoterPost.nodes.quotelinks quotelinks.push.apply quotelinks, quoterPost.nodes.quotelinks
# Second: # Second:
@ -98,7 +98,7 @@ Get =
return return
{status} = req {status} = req
unless [200, 304].contains status unless status in [200, 304]
# The thread can die by the time we check a quote. # The thread can die by the time we check a quote.
if url = Redirect.to 'post', {boardID, postID} if url = Redirect.to 'post', {boardID, postID}
$.cache url, $.cache url,

View File

@ -51,10 +51,11 @@ Main =
g.THREADID = +pathname[3] g.THREADID = +pathname[3]
# Check if the current board we're on is SFW or not, so we can handle options that need to know that. # Check if the current board we're on is SFW or not, so we can handle options that need to know that.
if ['b', 'd', 'e', 'gif', 'h', 'hc', 'hm', 'hr', 'pol', 'r', 'r9k', 'rs', 's', 's4s', 'soc', 't', 'u', 'y'].contains g.BOARD.ID g.TYPE =
g.TYPE = 'nsfw' if g.BOARD.ID in ['b', 'd', 'e', 'gif', 'h', 'hc', 'hm', 'hr', 'pol', 'r', 'r9k', 'rs', 's', 's4s', 'soc', 't', 'u', 'y']
else 'nsfw'
g.TYPE = 'sfw' else
'sfw'
$.extend Themes, Conf["userThemes"] $.extend Themes, Conf["userThemes"]
$.extend Mascots, Conf["userMascots"] $.extend Mascots, Conf["userMascots"]
@ -83,7 +84,7 @@ Main =
return return
when 'i.4cdn.org' when 'i.4cdn.org'
$.ready -> $.ready ->
if Conf['404 Redirect'] and ['4chan - Temporarily Offline', '4chan - 404 Not Found'].contains d.title if Conf['404 Redirect'] and d.title in ['4chan - Temporarily Offline', '4chan - 404 Not Found']
Redirect.init() Redirect.init()
pathname = location.pathname.split '/' pathname = location.pathname.split '/'
URL = Redirect.to 'file', URL = Redirect.to 'file',
@ -177,7 +178,7 @@ Main =
$.ready Main.initReady $.ready Main.initReady
initReady: -> initReady: ->
if ['4chan - Temporarily Offline', '4chan - 404 Not Found'].contains d.title if d.title in ['4chan - Temporarily Offline', '4chan - 404 Not Found']
if Conf['404 Redirect'] and g.VIEW is 'thread' if Conf['404 Redirect'] and g.VIEW is 'thread'
href = Redirect.to 'thread', href = Redirect.to 'thread',
boardID: g.BOARD.ID boardID: g.BOARD.ID

View File

@ -284,7 +284,7 @@ Settings =
input = $ "[name='#{name}']", section input = $ "[name='#{name}']", section
items[name] = Conf[name] items[name] = Conf[name]
inputs[name] = input inputs[name] = input
event = if ['favicon', 'usercss'].contains name event = if name in ['favicon', 'usercss']
'change' 'change'
else else
'input' 'input'
@ -318,7 +318,7 @@ Settings =
file: [] file: []
data.thread.push name data.thread.push name
data.post.push name if archive.software is 'foolfuuka' data.post.push name if archive.software is 'foolfuuka'
data.file.push name if archive.files.contains boardID data.file.push name if boardID in archive.files
rows = [] rows = []
boardOptions = [] boardOptions = []
@ -679,11 +679,11 @@ Settings =
id: name id: name
className: "mascots-container" className: "mascots-container"
innerHTML: "<h3 class=mascotHeader>#{name}</h3>" innerHTML: "<h3 class=mascotHeader>#{name}</h3>"
hidden: Conf["Hidden Categories"].contains name hidden: name in Conf["Hidden Categories"]
option = $.el "label", option = $.el "label",
name: name name: name
innerHTML: "<input name='#{name}' type=checkbox #{if Conf["Hidden Categories"].contains(name) then 'checked' else ''}>#{name}" innerHTML: "<input name='#{name}' type=checkbox #{if name in Conf["Hidden Categories"] then 'checked' else ''}>#{name}"
$.on $('input', option), 'change', cb.category $.on $('input', option), 'change', cb.category
@ -691,11 +691,11 @@ Settings =
$.add menu, option $.add menu, option
for name in keys for name in keys
continue if Conf["Deleted Mascots"].contains name continue if name in Conf["Deleted Mascots"]
mascot = Mascots[name] mascot = Mascots[name]
mascotEl = $.el 'div', mascotEl = $.el 'div',
id: name id: name
className: if Conf[g.MASCOTSTRING].contains name then 'mascot enabled' else 'mascot' className: if name in Conf[g.MASCOTSTRING] then 'mascot enabled' else 'mascot'
innerHTML: "<%= grunt.file.read('src/General/html/Settings/Mascot.html') %>" innerHTML: "<%= grunt.file.read('src/General/html/Settings/Mascot.html') %>"
$.on mascotEl, 'click', cb.select $.on mascotEl, 'click', cb.select
@ -715,7 +715,7 @@ Settings =
$.on $('#selectAll', batchmascots), 'click', -> $.on $('#selectAll', batchmascots), 'click', ->
for name, mascot of Mascots for name, mascot of Mascots
unless Conf["Hidden Categories"].contains(mascot.category) or Conf[g.MASCOTSTRING].contains(name) or Conf["Deleted Mascots"].contains(name) unless mascot.category in Conf["Hidden Categories"] or name in Conf[g.MASCOTSTRING] or name in Conf["Deleted Mascots"]
$.addClass $.id(name), 'enabled' $.addClass $.id(name), 'enabled'
Conf[g.MASCOTSTRING].push name Conf[g.MASCOTSTRING].push name
$.set g.MASCOTSTRING, Conf[g.MASCOTSTRING] $.set g.MASCOTSTRING, Conf[g.MASCOTSTRING]
@ -743,8 +743,7 @@ Settings =
container = $.el "div", container = $.el "div",
className: "mascots" className: "mascots"
for name in keys for name in keys when name in Conf["Deleted Mascots"]
continue unless Conf["Deleted Mascots"].contains name
mascot = Mascots[name] mascot = Mascots[name]
mascotEl = $.el 'div', mascotEl = $.el 'div',
className: 'mascot' className: 'mascot'

View File

@ -324,7 +324,7 @@ UI = do ->
$.on root, 'mousemove', o.hover $.on root, 'mousemove', o.hover
<% if (type === 'userscript') { %> <% if (type === 'userscript') { %>
# Workaround for https://github.com/MayhemYDG/4chan-x/issues/377 # Workaround for https://github.com/MayhemYDG/4chan-x/issues/377
o.workaround = (e) -> o.hoverend() unless root.contains e.target o.workaround = (e) -> o.hoverend() unless e.target in root
$.on doc, 'mousemove', o.workaround $.on doc, 'mousemove', o.workaround
<% } %> <% } %>

View File

@ -1,28 +1,17 @@
String::contains = (string) ->
@indexOf(string) > -1
Array::contains = (value) ->
@indexOf(value) > -1
Array::indexOf = (value) ->
i = @length
while i--
return i if @[i] is value
return i
# loosely follows the jquery api: # loosely follows the jquery api:
# http://api.jquery.com/ # http://api.jquery.com/
# not chainable # not chainable
$ = (selector, root=d.body) -> $ = (selector, root=d.body) ->
root.querySelector selector root.querySelector selector
$.extend = (object, properties) -> $.extend = (obj, prop) ->
for key, val of properties obj[key] = val for key, val of prop when prop.hasOwnProperty key
continue unless properties.hasOwnProperty key
object[key] = val
return return
$.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000))) $.DAY = 24 *
$.HOUR = 60 *
$.MINUTE = 60 *
$.SECOND = 1000
$.id = (id) -> $.id = (id) ->
d.getElementById id d.getElementById id
@ -134,7 +123,7 @@ $.toggleClass = (el, className) ->
el.classList.toggle className el.classList.toggle className
$.hasClass = (el, className) -> $.hasClass = (el, className) ->
el.classList.contains className className in el.classList
$.rm = do -> $.rm = do ->
if 'remove' of Element:: if 'remove' of Element::

View File

@ -111,7 +111,7 @@ class Post
# ES6 Set when? # ES6 Set when?
fullID = "#{match[1]}.#{match[2]}" fullID = "#{match[1]}.#{match[2]}"
@quotes.push fullID unless @quotes.contains fullID @quotes.push fullID unless fullID in @quotes
parseFile: (that) -> parseFile: (that) ->
return unless (fileEl = $ '.file', @nodes.post) and thumb = $ 'img[data-md5]', fileEl return unless (fileEl = $ '.file', @nodes.post) and thumb = $ 'img[data-md5]', fileEl

View File

@ -249,7 +249,7 @@ Gallery =
label = $.el 'label', label = $.el 'label',
innerHTML: "<input type=checkbox name='#{name}'> #{name}" innerHTML: "<input type=checkbox name='#{name}'> #{name}"
input = label.firstElementChild input = label.firstElementChild
if ['Fit Width', 'Fit Height', 'Hide Thumbnails'].contains name if name in ['Fit Width', 'Fit Height', 'Hide Thumbnails']
$.on input, 'change', Gallery.cb.setFitness $.on input, 'change', Gallery.cb.setFitness
input.checked = Conf[name] input.checked = Conf[name]
$.event 'change', null, input $.event 'change', null, input

View File

@ -46,7 +46,7 @@ ImageExpand =
for ID, post of g.posts for ID, post of g.posts
for post in [post].concat post.clones for post in [post].concat post.clones
{file} = post {file} = post
continue unless file and file.isImage and doc.contains post.nodes.root continue unless file and file.isImage and post.nodes.root in doc
if ImageExpand.on and if ImageExpand.on and
(!Conf['Expand spoilers'] and file.isSpoiler or (!Conf['Expand spoilers'] and file.isSpoiler or
Conf['Expand from here'] and Header.getTopOf(file.thumb) < 0) Conf['Expand from here'] and Header.getTopOf(file.thumb) < 0)

View File

@ -23,7 +23,7 @@ ImageHover =
asapTest: -> el.naturalHeight asapTest: -> el.naturalHeight
$.on el, 'error', ImageHover.error $.on el, 'error', ImageHover.error
error: -> error: ->
return unless doc.contains @ return unless @ in doc
post = g.posts[@dataset.fullID] post = g.posts[@dataset.fullID]
src = @src.split '/' src = @src.split '/'

View File

@ -303,7 +303,7 @@ Linkify =
el = $.el 'div' el = $.el 'div'
$.cache "https://mediacru.sh/#{a.dataset.uid}.json", -> $.cache "https://mediacru.sh/#{a.dataset.uid}.json", ->
{status} = @ {status} = @
return div.innerHTML = "ERROR #{status}" unless [200, 304].contains status return div.innerHTML = "ERROR #{status}" unless status in [200, 304]
{files} = JSON.parse @response {files} = JSON.parse @response
for type in ['video/mp4', 'video/ogv', 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg', 'image/svg', 'audio/mpeg'] for type in ['video/mp4', 'video/ogv', 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg', 'image/svg', 'audio/mpeg']
for file in files for file in files

View File

@ -34,9 +34,9 @@ CatalogLinks =
(board) -> a.href = "/#{board}/#{path}" (board) -> a.href = "/#{board}/#{path}"
for a in $$ """#board-list a:not(.catalog), #boardNavDesktopFoot a""" for a in $$ """#board-list a:not(.catalog), #boardNavDesktopFoot a"""
continue if !['boards.4chan.org', 'catalog.neet.tv', '4index.gropes.us'].contains(a.hostname) or continue if not a.hostname in ['boards.4chan.org', 'catalog.neet.tv', '4index.gropes.us'] or
!(board = a.pathname.split('/')[1]) or !(board = a.pathname.split('/')[1]) or
['f', 'status', '4chan'].contains board board in ['f', 'status', '4chan']
# Href is easier than pathname because then we don't have # Href is easier than pathname because then we don't have
# conditions where External Catalog has been disabled between switches. # conditions where External Catalog has been disabled between switches.

View File

@ -37,7 +37,7 @@ ExpandComment =
parse: (req, a, post) -> parse: (req, a, post) ->
{status} = req {status} = req
unless [200, 304].contains status unless status in [200, 304]
a.textContent = "Error #{req.statusText} (#{status})" a.textContent = "Error #{req.statusText} (#{status})"
return return

View File

@ -19,7 +19,7 @@ Keybinds =
keydown: (e) -> keydown: (e) ->
return unless key = Keybinds.keyCode e return unless key = Keybinds.keyCode e
{target} = e {target} = e
if ['INPUT', 'TEXTAREA'].contains target.nodeName if target.nodeName in ['INPUT', 'TEXTAREA']
return unless /(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test key return unless /(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test key
threadRoot = Nav.getThread() threadRoot = Nav.getThread()
if op = $ '.op', threadRoot if op = $ '.op', threadRoot

View File

@ -255,18 +255,20 @@ ThreadUpdater =
deletedPosts = [] deletedPosts = []
deletedFiles = [] deletedFiles = []
# Check for deleted posts/files. # Check for deleted posts/files.
for ID, post of ThreadUpdater.thread.posts for ID, post of ThreadUpdater.thread.posts
# XXX tmp fix for 4chan's racing condition # XXX tmp fix for 4chan's racing condition
# giving us false-positive dead posts. # giving us false-positive dead posts.
# continue if post.isDead # continue if post.isDead
ID = +ID ID = +ID
if post.isDead and index.contains ID
post.resurrect() unless ID in index
else unless index.contains ID
post.kill() post.kill()
deletedPosts.push post deletedPosts.push post
else if post.file and !post.file.isDead and not files.contains ID else if post.isDead
post.resurrect()
else if post.file and not (post.file.isDead or ID in files)
post.kill true post.kill true
deletedFiles.push post deletedFiles.push post

View File

@ -79,7 +79,7 @@ Unread =
Unread.addPostQuotingYou post Unread.addPostQuotingYou post
if Conf['Unread Line'] if Conf['Unread Line']
# Force line on visible threads if there were no unread posts previously. # Force line on visible threads if there were no unread posts previously.
Unread.setLine posts.contains Unread.posts[0] Unread.setLine Unread.posts[0] in posts
Unread.read() Unread.read()
Unread.update() Unread.update()

View File

@ -228,8 +228,7 @@ QR =
item = item.replace match, '' item = item.replace match, ''
boards = item.match(/boards:([^;]+)/i)?[1].toLowerCase() or 'global' boards = item.match(/boards:([^;]+)/i)?[1].toLowerCase() or 'global'
if boards isnt 'global' and not ((boards.split ',').contains g.BOARD.ID) return if boards isnt 'global' and not g.BOARD.ID in boards.split ','
return
if type is 'password' if type is 'password'
QR.persona.pwd = val QR.persona.pwd = val
@ -240,7 +239,7 @@ QR =
if /always/i.test item if /always/i.test item
QR.persona.always[type] = val QR.persona.always[type] = val
unless types[type].contains val unless val in types[type]
types[type].push val types[type].push val
loadPersonas: (type, arr) -> loadPersonas: (type, arr) ->
@ -469,7 +468,7 @@ QR =
if file.size > max if file.size > max
QR.error "#{file.name}: File too large (file: #{$.bytesToString file.size}, max: #{$.bytesToString max})." QR.error "#{file.name}: File too large (file: #{$.bytesToString file.size}, max: #{$.bytesToString max})."
return return
else unless QR.mimeTypes.contains file.type else unless file.type in QR.mimeTypes
unless /^text/.test file.type unless /^text/.test file.type
QR.error "#{file.name}: Unsupported file type." QR.error "#{file.name}: Unsupported file type."
return return
@ -493,7 +492,7 @@ QR =
$.addClass QR.nodes.filename, 'edit' $.addClass QR.nodes.filename, 'edit'
QR.nodes.filename.focus() QR.nodes.filename.focus()
return return
return if e.target.nodeName is 'INPUT' or (e.keyCode and not [32, 13].contains e.keyCode) or e.ctrlKey return if e.target.nodeName is 'INPUT' or (e.keyCode and not e.keyCode in [32, 13]) or e.ctrlKey
e.preventDefault() e.preventDefault()
QR.nodes.fileInput.click() QR.nodes.fileInput.click()

View File

@ -19,7 +19,7 @@ QuoteOP =
{quotelinks} = @nodes {quotelinks} = @nodes
# rm (OP) from cross-thread quotes. # rm (OP) from cross-thread quotes.
if @isClone and quotes.contains @thread.fullID if @isClone and @thread.fullID in quotes
i = 0 i = 0
while quotelink = quotelinks[i++] while quotelink = quotelinks[i++]
quotelink.textContent = quotelink.textContent.replace QuoteOP.text, '' quotelink.textContent = quotelink.textContent.replace QuoteOP.text, ''
@ -27,7 +27,7 @@ QuoteOP =
{fullID} = (if @isClone then @context else @).thread {fullID} = (if @isClone then @context else @).thread
# add (OP) to quotes quoting this context's OP. # add (OP) to quotes quoting this context's OP.
return unless quotes.contains fullID return unless fullID in quotes
i = 0 i = 0
while quotelink = quotelinks[i++] while quotelink = quotelinks[i++]
{boardID, postID} = Get.postDataFromLink quotelink {boardID, postID} = Get.postDataFromLink quotelink

View File

@ -68,7 +68,7 @@ QuoteThreading =
{bottom, top} = qpost.nodes.root.getBoundingClientRect() {bottom, top} = qpost.nodes.root.getBoundingClientRect()
# Post is unread or is fully visible. # Post is unread or is fully visible.
return false unless Unread.posts.contains(qpost) or ((bottom < height) and (top > 0)) return false unless qpost in Unread.posts or ((bottom < height) and (top > 0))
qroot = qpost.nodes.root qroot = qpost.nodes.root
unless $.hasClass qroot, 'threadOP' unless $.hasClass qroot, 'threadOP'

View File

@ -69,19 +69,16 @@ Quotify =
$.addClass a, 'quotelink' $.addClass a, 'quotelink'
$.extend a.dataset, {boardID, postID} $.extend a.dataset, {boardID, postID}
unless @quotes.contains quoteID @quotes.push quoteID unless quoteID in @quotes
@quotes.push quoteID
unless a return deadlink.textContent = "#{quote}\u00A0(Dead)" unless a
deadlink.textContent = "#{quote}\u00A0(Dead)"
return
$.replace deadlink, a $.replace deadlink, a
if $.hasClass a, 'quotelink' if $.hasClass a, 'quotelink'
@nodes.quotelinks.push a @nodes.quotelinks.push a
fixDeadlink: (deadlink) -> fixDeadlink: (deadlink) ->
if !(el = deadlink.previousSibling) or el.nodeName is 'BR' if not (el = deadlink.previousSibling) or el.nodeName is 'BR'
green = $.el 'span', green = $.el 'span',
className: 'quote' className: 'quote'
$.before deadlink, green $.before deadlink, green

View File

@ -308,7 +308,7 @@ MascotTools =
Conf["mascot"] = name Conf["mascot"] = name
for type in ["Enabled Mascots", "Enabled Mascots sfw", "Enabled Mascots nsfw"] for type in ["Enabled Mascots", "Enabled Mascots sfw", "Enabled Mascots nsfw"]
unless Conf[type].contains name unless name in Conf[type]
Conf[type].push name Conf[type].push name
$.set type, Conf[type] $.set type, Conf[type]
alert "Mascot \"#{name}\" saved." alert "Mascot \"#{name}\" saved."

View File

@ -87,7 +87,7 @@ Style =
node = addedNodes[i] node = addedNodes[i]
$.rm node unless node.nodeName is 'STYLE' and node.id or $.rm node unless node.nodeName is 'STYLE' and node.id or
!['LINK', 'STYLE'].contains(node.nodeName) or node.nodeName not in ['LINK', 'STYLE'] or
node.rel and ((!/stylesheet/.test(node.rel) or /flags.*\.css$/.test(href = node.href) or href[..3] is 'data')) or node.rel and ((!/stylesheet/.test(node.rel) or /flags.*\.css$/.test(href = node.href) or href[..3] is 'data')) or
/\.typeset/.test node.textContent /\.typeset/.test node.textContent