Release 4chan X v1.11.30.0.
This commit is contained in:
parent
7e8011e9eb
commit
0065037bdc
12
CHANGELOG.md
12
CHANGELOG.md
@ -2,6 +2,18 @@
|
||||
|
||||
Sometimes the changelog has notes (not comprehensive) acknowledging people's work. This does not mean the changes are their fault, only that their code was used. All changes to the script are chosen by and the fault of the maintainer (ccd0).
|
||||
|
||||
### v1.11.30
|
||||
|
||||
**v1.11.30.0** *(2016-04-03)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.30.0/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.30.0/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
- Based on v1.11.29.6.
|
||||
- 4chan X now remembers the state of the `Threading` checkbox added to the header menu by the `Quote Threading` feature. This allows you to have threading off by default, yet turn it on when you want it without reloading the page. By default `Quote Threading` will now be on with the `Threading` checkbox off.
|
||||
- Pruning threads to the last 1000 replies (number adjustable) has been improved:
|
||||
- When the number of replies exceed the threshold, a link is placed at the top of the thread to show/hide the excess posts.
|
||||
- While still not compatible with quote threading, you can now switch between threading and pruning in the header menu without reloading.
|
||||
- The feature can be turned off entirely by unchecking `Reply Pruning` in the settings.
|
||||
- Pruning threads to the last 1000 replies is now on by default.
|
||||
- Various bugfixes.
|
||||
|
||||
### v1.11.29
|
||||
|
||||
**v1.11.29.6** *(2016-04-02)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.29.6/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.29.6/builds/4chan-X-noupdate.crx "Chromium version")]
|
||||
|
||||
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
// ==UserScript==
|
||||
// @name 4chan X beta
|
||||
// @version 1.11.29.6
|
||||
// @version 1.11.30.0
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript
|
||||
// ==UserScript==
|
||||
// @name 4chan X beta
|
||||
// @version 1.11.29.6
|
||||
// @version 1.11.30.0
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -119,7 +119,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, NormalizeURL, Notice, PSAHiding, PassLink, Polyfill, Post, PostHiding, PostSuccessful, PruneReplies, 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, ThreadLinks, 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, NormalizeURL, Notice, PSAHiding, PassLink, Polyfill, Post, PostHiding, PostSuccessful, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, ReplyPruning, Report, ReportLink, RevealSpoilers, Sauce, Settings, ShimSet, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadLinks, 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; },
|
||||
@ -230,7 +230,8 @@
|
||||
'Thread Watcher': [true, 'Bookmark threads.'],
|
||||
'Fixed Thread Watcher': [true, 'Makes the thread watcher scroll with the page.', 1],
|
||||
'Toggleable Thread Watcher': [true, 'Adds a shortcut for the thread watcher and hides the watcher by default.', 1],
|
||||
'Mark New IPs': [false, 'Label each post from a new IP with the thread\'s current IP count.']
|
||||
'Mark New IPs': [false, 'Label each post from a new IP with the thread\'s current IP count.'],
|
||||
'Reply Pruning': [true, 'Hide old replies in long threads. Number of replies shown can be set from header menu.']
|
||||
},
|
||||
'Posting and Captchas': {
|
||||
'Quick Reply': [true, 'All-in-one form to reply, create threads, automate dumping and more.'],
|
||||
@ -258,7 +259,7 @@
|
||||
'Quote Backlinks': [true, 'Add quote backlinks.'],
|
||||
'OP Backlinks': [true, 'Add backlinks to the OP.', 1],
|
||||
'Quote Inlining': [true, 'Inline quoted post on click.'],
|
||||
'Inline Cross-thread Quotes Only': [false, 'Only inline quote links when the posts are on another thread or board, or fetched from the archive.', 1],
|
||||
'Inline Cross-thread Quotes Only': [false, 'Don\'t inline quote links when the posts are visible in the thread.', 1],
|
||||
'Quote Hash Navigation': [false, 'Include an extra link after quotes for autoscrolling to quoted posts.', 1],
|
||||
'Forward Hiding': [true, 'Hide original posts of inlined backlinks.', 1],
|
||||
'Quote Previewing': [true, 'Show quoted post on hover.'],
|
||||
@ -270,7 +271,7 @@
|
||||
'Highlight Own Posts': [true, 'Highlights own posts.', 1],
|
||||
'Mark OP Quotes': [true, 'Add \'(OP)\' to OP quotes.'],
|
||||
'Mark Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes.'],
|
||||
'Quote Threading': [false, 'Thread conversations']
|
||||
'Quote Threading': [true, 'Add option in header menu to thread conversations.']
|
||||
}
|
||||
},
|
||||
imageExpansion: {
|
||||
@ -428,10 +429,12 @@
|
||||
},
|
||||
customCooldown: 0,
|
||||
customCooldownEnabled: true,
|
||||
pruneReplies: {
|
||||
'Prune Replies': false,
|
||||
'Thread Quotes': false,
|
||||
replyPruning: {
|
||||
'Prune Replies': true,
|
||||
'Max Replies': 1000
|
||||
}
|
||||
},
|
||||
'Autohiding Scrollbar': false
|
||||
};
|
||||
|
||||
Conf = {};
|
||||
@ -443,7 +446,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.11.29.6',
|
||||
VERSION: '1.11.30.0',
|
||||
NAMESPACE: '4chan X.',
|
||||
boards: {}
|
||||
};
|
||||
@ -2503,7 +2506,7 @@
|
||||
results.push(this.archiveTags[text]);
|
||||
} else {
|
||||
greentext = text[0] === '>';
|
||||
text = text.replace(/(\[\/?[a-z]+):lit(\])/, '$1$2');
|
||||
text = text.replace(/(\[\/?[a-z]+):lit(\])/g, '$1$2');
|
||||
text = (function() {
|
||||
var len2, q, ref, results1;
|
||||
ref = text.split(/(>>(?:>\/[a-z\d]+\/)?\d+)/g);
|
||||
@ -4539,17 +4542,22 @@
|
||||
}
|
||||
return container;
|
||||
},
|
||||
summary: function(boardID, threadID, posts, files) {
|
||||
summaryText: function(status, posts, files) {
|
||||
var text;
|
||||
text = [];
|
||||
text.push(posts + " post" + (posts > 1 ? 's' : ''));
|
||||
if (files) {
|
||||
text.push("and " + files + " image repl" + (files > 1 ? 'ies' : 'y'));
|
||||
text = '';
|
||||
if (status) {
|
||||
text += status + " ";
|
||||
}
|
||||
text.push('omitted.');
|
||||
text += posts + " post" + (posts > 1 ? 's' : '');
|
||||
if (+files) {
|
||||
text += " and " + files + " image repl" + (files > 1 ? 'ies' : 'y');
|
||||
}
|
||||
return text += " " + (status === '-' ? 'shown' : 'omitted') + ".";
|
||||
},
|
||||
summary: function(boardID, threadID, posts, files) {
|
||||
return $.el('a', {
|
||||
className: 'summary',
|
||||
textContent: text.join(' '),
|
||||
textContent: Build.summaryText('', posts, files),
|
||||
href: "/" + boardID + "/thread/" + threadID
|
||||
});
|
||||
},
|
||||
@ -6357,7 +6365,7 @@
|
||||
if (Conf['Quote Previewing']) {
|
||||
$.on(link, 'mouseover', QuotePreview.mouseover);
|
||||
}
|
||||
if (Conf['Quote Inlining'] && !(Conf['Inline Cross-thread Quotes Only'] && !QuoteInline.isCrossThread(link))) {
|
||||
if (Conf['Quote Inlining']) {
|
||||
$.on(link, 'click', QuoteInline.toggle);
|
||||
if (Conf['Quote Hash Navigation']) {
|
||||
hash = QuoteInline.qiQuote(link, $.hasClass(link, 'filtered'));
|
||||
@ -6457,9 +6465,6 @@
|
||||
}
|
||||
},
|
||||
process: function(link, clone) {
|
||||
if (Conf['Inline Cross-thread Quotes Only'] && !QuoteInline.isCrossThread(link)) {
|
||||
return;
|
||||
}
|
||||
if (Conf['Quote Hash Navigation']) {
|
||||
if (!clone) {
|
||||
$.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
|
||||
@ -6467,9 +6472,6 @@
|
||||
}
|
||||
return $.on(link, 'click', QuoteInline.toggle);
|
||||
},
|
||||
isCrossThread: function(link) {
|
||||
return link.pathname !== location.pathname || link.host !== location.host || link.protocol !== location.protocol;
|
||||
},
|
||||
qiQuote: function(link, hidden) {
|
||||
var name;
|
||||
name = "hashlink";
|
||||
@ -6483,12 +6485,15 @@
|
||||
});
|
||||
},
|
||||
toggle: function(e) {
|
||||
var boardID, context, postID, quoter, ref, threadID;
|
||||
var boardID, context, postID, quoter, ref, ref1, threadID;
|
||||
if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
ref = Get.postDataFromLink(this), boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID;
|
||||
if (Conf['Inline Cross-thread Quotes Only'] && g.VIEW === 'thread' && ((ref1 = g.posts[boardID + "." + postID]) != null ? ref1.nodes.root.offsetParent : void 0)) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
quoter = Get.postFromNode(this);
|
||||
context = quoter.context;
|
||||
if ($.hasClass(this, 'inlined')) {
|
||||
@ -6709,9 +6714,8 @@
|
||||
if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) {
|
||||
return;
|
||||
}
|
||||
this.enabled = true;
|
||||
this.controls = $.el('span', {
|
||||
innerHTML: "<label><input id=\"threadingControl\" type=\"checkbox\" checked> Threading</label>"
|
||||
this.controls = $.el('label', {
|
||||
innerHTML: "<input id=\"threadingControl\" name=\"Thread Quotes\" type=\"checkbox\"> Threading"
|
||||
});
|
||||
this.threadNewLink = $.el('span', {
|
||||
className: 'brackets-wrap threadnewlink',
|
||||
@ -6721,8 +6725,15 @@
|
||||
innerHTML: "<a href=\"javascript:;\">Thread New Posts</a>"
|
||||
});
|
||||
this.input = $('input', this.controls);
|
||||
this.input.checked = Conf['Thread Quotes'];
|
||||
$.on(this.input, 'change', this.setEnabled);
|
||||
$.on(this.input, 'change', this.rethread);
|
||||
$.on(this.threadNewLink.firstElementChild, 'click', this.rethread);
|
||||
$.on(d, '4chanXInitFinished', (function(_this) {
|
||||
return function() {
|
||||
return _this.ready = true;
|
||||
};
|
||||
})(this));
|
||||
Header.menu.addEntry(this.entry = {
|
||||
el: this.controls,
|
||||
order: 99
|
||||
@ -6739,6 +6750,15 @@
|
||||
parent: {},
|
||||
children: {},
|
||||
inserted: {},
|
||||
setEnabled: function() {
|
||||
var other, ref;
|
||||
other = (ref = ReplyPruning.inputs) != null ? ref.enabled : void 0;
|
||||
if (this.checked && (other != null ? other.checked : void 0)) {
|
||||
other.checked = false;
|
||||
$.event('change', null, other);
|
||||
}
|
||||
return $.cb.checked.call(this);
|
||||
},
|
||||
setThread: function() {
|
||||
QuoteThreading.thread = this;
|
||||
return $.asap((function() {
|
||||
@ -6793,7 +6813,7 @@
|
||||
},
|
||||
insert: function(post) {
|
||||
var base1, child, children, descendants, i, k, len1, name1, next, nodes, order, parent, prev, prev2, q, threadContainer, u, x;
|
||||
if (!(QuoteThreading.enabled && (parent = QuoteThreading.parent[post.fullID]) && !QuoteThreading.inserted[post.fullID])) {
|
||||
if (!(Conf['Thread Quotes'] && (parent = QuoteThreading.parent[post.fullID]) && !QuoteThreading.inserted[post.fullID])) {
|
||||
return false;
|
||||
}
|
||||
descendants = QuoteThreading.descendants(post);
|
||||
@ -6857,10 +6877,13 @@
|
||||
},
|
||||
rethread: function() {
|
||||
var nodes, posts, thread;
|
||||
if (!QuoteThreading.ready) {
|
||||
return;
|
||||
}
|
||||
thread = QuoteThreading.thread;
|
||||
posts = thread.posts;
|
||||
QuoteThreading.threadNewLink.hidden = true;
|
||||
if (QuoteThreading.enabled = QuoteThreading.input.checked) {
|
||||
if (Conf['Thread Quotes']) {
|
||||
posts.forEach(QuoteThreading.insert);
|
||||
} else {
|
||||
nodes = [];
|
||||
@ -9811,8 +9834,7 @@
|
||||
switch (name) {
|
||||
case 'thread':
|
||||
(this.thread !== 'new' ? $.addClass : $.rmClass)(QR.nodes.el, 'reply-to-thread');
|
||||
QR.status();
|
||||
return this.updateFlashURL();
|
||||
return QR.status();
|
||||
case 'com':
|
||||
this.updateComment();
|
||||
if (QR.cooldown.auto && this === QR.posts[0] && (0 < (ref = QR.cooldown.seconds) && ref <= 5)) {
|
||||
@ -9824,8 +9846,7 @@
|
||||
return;
|
||||
}
|
||||
this.saveFilename();
|
||||
this.updateFilename();
|
||||
return this.updateFlashURL();
|
||||
return this.updateFilename();
|
||||
case 'name':
|
||||
return QR.persona.set(this);
|
||||
}
|
||||
@ -9958,7 +9979,6 @@
|
||||
} else {
|
||||
this.updateFilename();
|
||||
}
|
||||
this.updateFlashURL();
|
||||
this.nodes.el.style.backgroundImage = null;
|
||||
if (ref = this.file.type, indexOf.call(QR.mimeTypes, ref) < 0) {
|
||||
return this.fileError('Unsupported file type.');
|
||||
@ -10088,7 +10108,6 @@
|
||||
this.nodes.el.style.backgroundImage = null;
|
||||
$.rmClass(this.nodes.el, 'has-file');
|
||||
this.showFileData();
|
||||
this.updateFlashURL();
|
||||
URL.revokeObjectURL(this.URL);
|
||||
return this.dismissErrors(function(error) {
|
||||
return $.hasClass(error, 'file-error');
|
||||
@ -10131,31 +10150,6 @@
|
||||
return QR.nodes.spoiler.checked = this.spoiler;
|
||||
};
|
||||
|
||||
_Class.prototype.updateFlashURL = function() {
|
||||
var com, oldURL, ref, url;
|
||||
if (g.BOARD.ID !== 'f') {
|
||||
return;
|
||||
}
|
||||
if (this.thread === 'new' || !this.file) {
|
||||
url = '';
|
||||
} else {
|
||||
url = this.file.newName;
|
||||
if ((ref = $.engine) === 'blink' || ref === 'webkit') {
|
||||
url = url.replace(/"/g, '%22');
|
||||
}
|
||||
url = url.replace(/[\t\n\f\r \xa0\u200B\u2029\u3000]+/g, ' ').replace(/(^ | $)/g, '').replace(/\.[0-9A-Za-z]+$/, '');
|
||||
url = "https://i.4cdn.org/f/" + (encodeURIComponent(E(url))) + ".swf\n";
|
||||
}
|
||||
oldURL = this.flashURL || '';
|
||||
if (url !== oldURL) {
|
||||
com = this.com || '';
|
||||
if (com.slice(0, oldURL.length) === oldURL) {
|
||||
this.setComment(url + com.slice(oldURL.length));
|
||||
}
|
||||
return this.flashURL = url;
|
||||
}
|
||||
};
|
||||
|
||||
_Class.prototype.pasteText = function(file) {
|
||||
var reader;
|
||||
this.pasting = true;
|
||||
@ -13251,12 +13245,28 @@
|
||||
}
|
||||
};
|
||||
|
||||
PruneReplies = {
|
||||
ReplyPruning = {
|
||||
init: function() {
|
||||
var el, label;
|
||||
if (!(g.VIEW === 'thread' && !Conf['Quote Threading'])) {
|
||||
if (!(g.VIEW === 'thread' && Conf['Reply Pruning'])) {
|
||||
return;
|
||||
}
|
||||
if (Conf['Quote Threading'] && Conf['Thread Quotes'] && Conf['Prune Replies']) {
|
||||
Conf['Prune Replies'] = false;
|
||||
$.set('Prune Replies', false);
|
||||
}
|
||||
this.container = $.frag();
|
||||
this.summary = $.el('span', {
|
||||
hidden: true,
|
||||
className: 'summary',
|
||||
style: 'cursor: pointer;'
|
||||
});
|
||||
$.on(this.summary, 'click', (function(_this) {
|
||||
return function() {
|
||||
_this.inputs.enabled.checked = !_this.inputs.enabled.checked;
|
||||
return $.event('change', null, _this.inputs.enabled);
|
||||
};
|
||||
})(this));
|
||||
label = UI.checkbox('Prune Replies', 'Show Last');
|
||||
el = $.el('span', {
|
||||
title: 'Maximum number of replies to show.'
|
||||
@ -13268,68 +13278,94 @@
|
||||
enabled: label.firstElementChild,
|
||||
replies: el.lastElementChild
|
||||
};
|
||||
$.on(this.inputs.enabled, 'change', $.cb.checked);
|
||||
$.on(this.inputs.enabled, 'change', this.setEnabled);
|
||||
$.on(this.inputs.replies, 'change', $.cb.value);
|
||||
Header.menu.addEntry({
|
||||
el: el,
|
||||
order: 190
|
||||
});
|
||||
return Thread.callbacks.push({
|
||||
name: 'Prune Replies',
|
||||
name: 'Reply Pruning',
|
||||
cb: this.node
|
||||
});
|
||||
},
|
||||
position: 0,
|
||||
hidden: 0,
|
||||
hiddenFiles: 0,
|
||||
total: 0,
|
||||
node: function() {
|
||||
PruneReplies.thread = this;
|
||||
PruneReplies.total = this.posts.keys.length - 1;
|
||||
$.on(PruneReplies.inputs.enabled, 'change', PruneReplies.setEnabled);
|
||||
$.on(PruneReplies.inputs.enabled, 'change', PruneReplies.update);
|
||||
if (Conf['Prune Replies']) {
|
||||
PruneReplies.setEnabled();
|
||||
return PruneReplies.update();
|
||||
}
|
||||
},
|
||||
totalFiles: 0,
|
||||
setEnabled: function() {
|
||||
var onOff;
|
||||
PruneReplies.container || (PruneReplies.container = $.frag());
|
||||
onOff = Conf['Prune Replies'] ? $.on : $.off;
|
||||
onOff(PruneReplies.inputs.replies, 'change', PruneReplies.update);
|
||||
return onOff(d, 'ThreadUpdate', PruneReplies.update);
|
||||
},
|
||||
update: function(e) {
|
||||
var OP, frag, hidden2, post, posts, ref, results;
|
||||
if (e && e.type === 'ThreadUpdate' && !e.detail[404]) {
|
||||
PruneReplies.total += e.detail.newPosts.length;
|
||||
var other;
|
||||
other = QuoteThreading.input;
|
||||
if (this.checked && (other != null ? other.checked : void 0)) {
|
||||
other.checked = false;
|
||||
$.event('change', null, other);
|
||||
}
|
||||
hidden2 = Conf['Prune Replies'] ? Math.max(PruneReplies.total - +Conf["Max Replies"], 0) : 0;
|
||||
ref = PruneReplies.thread, posts = ref.posts, OP = ref.OP;
|
||||
if (PruneReplies.hidden < hidden2) {
|
||||
results = [];
|
||||
while (PruneReplies.hidden < hidden2 && PruneReplies.position < posts.keys.length) {
|
||||
post = posts[posts.keys[PruneReplies.position++]];
|
||||
if (post.isReply && !post.isFetchedQuote) {
|
||||
$.add(PruneReplies.container, post.nodes.root);
|
||||
results.push(PruneReplies.hidden++);
|
||||
} else {
|
||||
results.push(void 0);
|
||||
return $.cb.checked.call(this);
|
||||
},
|
||||
node: function() {
|
||||
ReplyPruning.thread = this;
|
||||
this.posts.forEach(function(post) {
|
||||
if (post.isReply) {
|
||||
ReplyPruning.total++;
|
||||
if (post.file) {
|
||||
return ReplyPruning.totalFiles++;
|
||||
}
|
||||
}
|
||||
return results;
|
||||
} else if (PruneReplies.hidden > hidden2) {
|
||||
});
|
||||
$.after(this.OP.nodes.root, ReplyPruning.summary);
|
||||
$.on(ReplyPruning.inputs.enabled, 'change', ReplyPruning.update);
|
||||
$.on(ReplyPruning.inputs.replies, 'change', ReplyPruning.update);
|
||||
$.on(d, 'ThreadUpdate', ReplyPruning.updateCount);
|
||||
$.on(d, 'ThreadUpdate', ReplyPruning.update);
|
||||
return ReplyPruning.update();
|
||||
},
|
||||
updateCount: function(e) {
|
||||
var fullID, k, len1, ref;
|
||||
if (e.detail[404]) {
|
||||
return;
|
||||
}
|
||||
ref = e.detail.newPosts;
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
fullID = ref[k];
|
||||
ReplyPruning.total++;
|
||||
if (g.posts[fullID].file) {
|
||||
ReplyPruning.totalFiles++;
|
||||
}
|
||||
}
|
||||
},
|
||||
update: function() {
|
||||
var frag, hidden2, post, posts;
|
||||
hidden2 = Conf['Prune Replies'] ? Math.max(ReplyPruning.total - +Conf["Max Replies"], 0) : 0;
|
||||
posts = ReplyPruning.thread.posts;
|
||||
if (ReplyPruning.hidden < hidden2) {
|
||||
while (ReplyPruning.hidden < hidden2 && ReplyPruning.position < posts.keys.length) {
|
||||
post = posts[posts.keys[ReplyPruning.position++]];
|
||||
if (post.isReply && !post.isFetchedQuote) {
|
||||
$.add(ReplyPruning.container, post.nodes.root);
|
||||
ReplyPruning.hidden++;
|
||||
if (post.file) {
|
||||
ReplyPruning.hiddenFiles++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ReplyPruning.hidden > hidden2) {
|
||||
frag = $.frag();
|
||||
while (PruneReplies.hidden > hidden2 && PruneReplies.position > 0) {
|
||||
post = posts[posts.keys[--PruneReplies.position]];
|
||||
while (ReplyPruning.hidden > hidden2 && ReplyPruning.position > 0) {
|
||||
post = posts[posts.keys[--ReplyPruning.position]];
|
||||
if (post.isReply && !post.isFetchedQuote) {
|
||||
$.prepend(frag, post.nodes.root);
|
||||
PruneReplies.hidden--;
|
||||
ReplyPruning.hidden--;
|
||||
if (post.file) {
|
||||
ReplyPruning.hiddenFiles--;
|
||||
}
|
||||
}
|
||||
}
|
||||
$.after(OP.nodes.root, frag);
|
||||
return $.event('PostsInserted');
|
||||
$.after(ReplyPruning.summary, frag);
|
||||
$.event('PostsInserted');
|
||||
}
|
||||
ReplyPruning.summary.textContent = Conf['Prune Replies'] ? Build.summaryText('+', ReplyPruning.hidden, ReplyPruning.hiddenFiles) : Build.summaryText('-', ReplyPruning.total, ReplyPruning.totalFiles);
|
||||
return ReplyPruning.summary.hidden = ReplyPruning.total <= +Conf["Max Replies"];
|
||||
}
|
||||
};
|
||||
|
||||
@ -13601,10 +13637,7 @@
|
||||
}));
|
||||
$.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost);
|
||||
$.on(d, 'visibilitychange', ThreadUpdater.cb.visibility);
|
||||
ThreadUpdater.setInterval();
|
||||
if (this.board.ID === 'f') {
|
||||
return ThreadUpdater.update();
|
||||
}
|
||||
return ThreadUpdater.setInterval();
|
||||
},
|
||||
|
||||
/*
|
||||
@ -13832,12 +13865,6 @@
|
||||
if (postObject.fsize) {
|
||||
files.push(ID);
|
||||
}
|
||||
if (board.ID === 'f' && postObject.fsize && (post = thread.posts[ID]) && !post.file) {
|
||||
node = Build.postFromObject(postObject, board.ID);
|
||||
$.after(post.nodes.info, $('.file', node));
|
||||
post.parseFile();
|
||||
Post.callbacks.execute(post, ['Filter', 'File Info Formatting', 'Fappe Tyme', 'Sauce']);
|
||||
}
|
||||
if (ID <= lastPost) {
|
||||
continue;
|
||||
}
|
||||
@ -15497,7 +15524,7 @@
|
||||
}
|
||||
},
|
||||
initBoardList: function() {
|
||||
if (!Conf['Catalog Links']) {
|
||||
if (!CatalogLinks.el) {
|
||||
return;
|
||||
}
|
||||
return CatalogLinks.set(Conf['Header catalog links']);
|
||||
@ -15703,7 +15730,7 @@
|
||||
if (!(a = $.x('following-sibling::*[contains(@class,"summary")][1]', thread.OP.nodes.root))) {
|
||||
return;
|
||||
}
|
||||
a.textContent = ExpandThread.text.apply(ExpandThread, ['+'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
a.textContent = Build.summaryText.apply(Build, ['+'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
a.style.cursor = 'pointer';
|
||||
return $.on(a, 'click', ExpandThread.cbToggle);
|
||||
},
|
||||
@ -15730,9 +15757,6 @@
|
||||
return ExpandThread.setButton(thread);
|
||||
});
|
||||
},
|
||||
text: function(status, posts, files) {
|
||||
return (status + " " + posts + " post" + (posts > 1 ? 's' : '')) + (+files ? " and " + files + " image repl" + (files > 1 ? 'ies' : 'y') : "") + (" " + (status === '-' ? 'shown' : 'omitted') + ".");
|
||||
},
|
||||
cbToggle: function(e) {
|
||||
if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) {
|
||||
return;
|
||||
@ -15755,7 +15779,7 @@
|
||||
expand: function(thread, a) {
|
||||
var status;
|
||||
ExpandThread.statuses[thread] = status = {};
|
||||
a.textContent = ExpandThread.text.apply(ExpandThread, ['...'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
a.textContent = Build.summaryText.apply(Build, ['...'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
return status.req = $.cache("//a.4cdn.org/" + thread.board + "/thread/" + thread + ".json", function() {
|
||||
delete status.req;
|
||||
return ExpandThread.parse(this, thread, a);
|
||||
@ -15768,7 +15792,7 @@
|
||||
if (status.req) {
|
||||
status.req.abort();
|
||||
if (a) {
|
||||
a.textContent = ExpandThread.text.apply(ExpandThread, ['+'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
a.textContent = Build.summaryText.apply(Build, ['+'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -15806,7 +15830,7 @@
|
||||
}
|
||||
$.rm(reply);
|
||||
}
|
||||
return a.textContent = ExpandThread.text('+', postsCount, filesCount);
|
||||
return a.textContent = Build.summaryText('+', postsCount, filesCount);
|
||||
},
|
||||
parse: function(req, thread, a) {
|
||||
var filesCount, k, len1, post, postData, posts, postsCount, postsRoot, ref, ref1, root;
|
||||
@ -15843,7 +15867,7 @@
|
||||
$.after(a, postsRoot);
|
||||
$.event('PostsInserted');
|
||||
postsCount = postsRoot.length;
|
||||
return a.textContent = ExpandThread.text('-', postsCount, filesCount);
|
||||
return a.textContent = Build.summaryText('-', postsCount, filesCount);
|
||||
}
|
||||
};
|
||||
|
||||
@ -17704,6 +17728,11 @@
|
||||
set('Inline Cross-thread Quotes Only', true);
|
||||
}
|
||||
}
|
||||
if (compareString < '00001.00011.00030.00000') {
|
||||
if (data['Quote Threading'] && (data['Thread Quotes'] == null)) {
|
||||
set('Thread Quotes', true);
|
||||
}
|
||||
}
|
||||
return changes;
|
||||
},
|
||||
loadSettings: function(data, cb) {
|
||||
@ -18291,6 +18320,16 @@
|
||||
return $.addClass(doc, 'ads-loaded');
|
||||
});
|
||||
});
|
||||
if (Conf['Autohiding Scrollbar']) {
|
||||
$.addClass(doc, 'autohiding-scrollbar');
|
||||
}
|
||||
$.ready(function() {
|
||||
if (d.body.clientHeight > doc.clientHeight && (window.innerWidth === doc.clientWidth) !== Conf['Autohiding Scrollbar']) {
|
||||
Conf['Autohiding Scrollbar'] = !Conf['Autohiding Scrollbar'];
|
||||
$.set('Autohiding Scrollbar', Conf['Autohiding Scrollbar']);
|
||||
return $.toggleClass(doc, 'autohiding-scrollbar');
|
||||
}
|
||||
});
|
||||
$.addStyle(Main.css, 'fourchanx-css');
|
||||
Main.bgColorStyle = $.el('style', {
|
||||
id: 'fourchanx-bgcolor-css'
|
||||
@ -19518,6 +19557,9 @@
|
||||
"#shortcuts {\n" +
|
||||
" float: right;\n" +
|
||||
"}\n" +
|
||||
":root.autohiding-scrollbar #shortcuts {\n" +
|
||||
" margin-right: 12px;\n" +
|
||||
"}\n" +
|
||||
".shortcut {\n" +
|
||||
" margin-left: 3px;\n" +
|
||||
" vertical-align: middle;\n" +
|
||||
@ -21878,7 +21920,7 @@
|
||||
cssWWW: "#captcha-cnt {\n" +
|
||||
" height: auto;\n" +
|
||||
"}",
|
||||
features: [['Polyfill', Polyfill], ['Normalize URL', NormalizeURL], ['Captcha Configuration', Captcha.replace], ['Redirect', Redirect], ['Header', Header], ['Catalog Links', CatalogLinks], ['Settings', Settings], ['Index Generator', Index], ['Disable Autoplay', AntiAutoplay], ['Announcement Hiding', PSAHiding], ['Fourchan thingies', Fourchan], ['Color User IDs', IDColor], ['Highlight by User ID', IDHighlight], ['Custom CSS', CustomCSS], ['Thread Links', ThreadLinks], ['Linkify', Linkify], ['Reveal Spoilers', RemoveSpoilers], ['Resurrect Quotes', Quotify], ['Filter', Filter], ['Thread Hiding Buttons', ThreadHiding], ['Reply Hiding Buttons', PostHiding], ['Recursive', Recursive], ['Strike-through Quotes', QuoteStrikeThrough], ['Quick Reply', QR], ['Cooldown', QR.cooldown], ['Pass Link', PassLink], ['Menu', Menu], ['Index Generator (Menu)', Index.menu], ['Report Link', ReportLink], ['Thread Hiding (Menu)', ThreadHiding.menu], ['Reply Hiding (Menu)', PostHiding.menu], ['Delete Link', DeleteLink], ['Filter (Menu)', Filter.menu], ['Edit Link', QR.oekaki.menu], ['Download Link', DownloadLink], ['Archive Link', ArchiveLink], ['Quote Inlining', QuoteInline], ['Quote Previewing', QuotePreview], ['Quote Backlinks', QuoteBacklink], ['Mark Quotes of You', QuoteYou], ['Mark OP Quotes', QuoteOP], ['Mark Cross-thread Quotes', QuoteCT], ['Anonymize', Anonymize], ['Time Formatting', Time], ['Relative Post Dates', RelativeDates], ['File Info Formatting', FileInfo], ['Fappe Tyme', FappeTyme], ['Gallery', Gallery], ['Gallery (menu)', Gallery.menu], ['Sauce', Sauce], ['Image Expansion', ImageExpand], ['Image Expansion (Menu)', ImageExpand.menu], ['Reveal Spoiler Thumbnails', RevealSpoilers], ['Image Loading', ImageLoader], ['Image Hover', ImageHover], ['Volume Control', Volume], ['WEBM Metadata', Metadata], ['Comment Expansion', ExpandComment], ['Thread Expansion', ExpandThread], ['Thread Excerpt', ThreadExcerpt], ['Favicon', Favicon], ['Unread', Unread], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats], ['Thread Updater', ThreadUpdater], ['Thread Watcher', ThreadWatcher], ['Thread Watcher (Menu)', ThreadWatcher.menu], ['Mark New IPs', MarkNewIPs], ['Index Navigation', Nav], ['Keybinds', Keybinds], ['Banner', Banner], ['Flash Features', Flash], ['Prune Replies', PruneReplies]]
|
||||
features: [['Polyfill', Polyfill], ['Normalize URL', NormalizeURL], ['Captcha Configuration', Captcha.replace], ['Redirect', Redirect], ['Header', Header], ['Catalog Links', CatalogLinks], ['Settings', Settings], ['Index Generator', Index], ['Disable Autoplay', AntiAutoplay], ['Announcement Hiding', PSAHiding], ['Fourchan thingies', Fourchan], ['Color User IDs', IDColor], ['Highlight by User ID', IDHighlight], ['Custom CSS', CustomCSS], ['Thread Links', ThreadLinks], ['Linkify', Linkify], ['Reveal Spoilers', RemoveSpoilers], ['Resurrect Quotes', Quotify], ['Filter', Filter], ['Thread Hiding Buttons', ThreadHiding], ['Reply Hiding Buttons', PostHiding], ['Recursive', Recursive], ['Strike-through Quotes', QuoteStrikeThrough], ['Quick Reply', QR], ['Cooldown', QR.cooldown], ['Pass Link', PassLink], ['Menu', Menu], ['Index Generator (Menu)', Index.menu], ['Report Link', ReportLink], ['Thread Hiding (Menu)', ThreadHiding.menu], ['Reply Hiding (Menu)', PostHiding.menu], ['Delete Link', DeleteLink], ['Filter (Menu)', Filter.menu], ['Edit Link', QR.oekaki.menu], ['Download Link', DownloadLink], ['Archive Link', ArchiveLink], ['Quote Inlining', QuoteInline], ['Quote Previewing', QuotePreview], ['Quote Backlinks', QuoteBacklink], ['Mark Quotes of You', QuoteYou], ['Mark OP Quotes', QuoteOP], ['Mark Cross-thread Quotes', QuoteCT], ['Anonymize', Anonymize], ['Time Formatting', Time], ['Relative Post Dates', RelativeDates], ['File Info Formatting', FileInfo], ['Fappe Tyme', FappeTyme], ['Gallery', Gallery], ['Gallery (menu)', Gallery.menu], ['Sauce', Sauce], ['Image Expansion', ImageExpand], ['Image Expansion (Menu)', ImageExpand.menu], ['Reveal Spoiler Thumbnails', RevealSpoilers], ['Image Loading', ImageLoader], ['Image Hover', ImageHover], ['Volume Control', Volume], ['WEBM Metadata', Metadata], ['Comment Expansion', ExpandComment], ['Thread Expansion', ExpandThread], ['Thread Excerpt', ThreadExcerpt], ['Favicon', Favicon], ['Unread', Unread], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats], ['Thread Updater', ThreadUpdater], ['Thread Watcher', ThreadWatcher], ['Thread Watcher (Menu)', ThreadWatcher.menu], ['Mark New IPs', MarkNewIPs], ['Index Navigation', Nav], ['Keybinds', Keybinds], ['Banner', Banner], ['Flash Features', Flash], ['Reply Pruning', ReplyPruning]]
|
||||
};
|
||||
|
||||
Main.init();
|
||||
|
||||
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.11.29.6
|
||||
// @version 1.11.30.0
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -119,7 +119,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, NormalizeURL, Notice, PSAHiding, PassLink, Polyfill, Post, PostHiding, PostSuccessful, PruneReplies, 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, ThreadLinks, 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, NormalizeURL, Notice, PSAHiding, PassLink, Polyfill, Post, PostHiding, PostSuccessful, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, ReplyPruning, Report, ReportLink, RevealSpoilers, Sauce, Settings, ShimSet, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadLinks, 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; },
|
||||
@ -230,7 +230,8 @@
|
||||
'Thread Watcher': [true, 'Bookmark threads.'],
|
||||
'Fixed Thread Watcher': [true, 'Makes the thread watcher scroll with the page.', 1],
|
||||
'Toggleable Thread Watcher': [true, 'Adds a shortcut for the thread watcher and hides the watcher by default.', 1],
|
||||
'Mark New IPs': [false, 'Label each post from a new IP with the thread\'s current IP count.']
|
||||
'Mark New IPs': [false, 'Label each post from a new IP with the thread\'s current IP count.'],
|
||||
'Reply Pruning': [true, 'Hide old replies in long threads. Number of replies shown can be set from header menu.']
|
||||
},
|
||||
'Posting and Captchas': {
|
||||
'Quick Reply': [true, 'All-in-one form to reply, create threads, automate dumping and more.'],
|
||||
@ -258,7 +259,7 @@
|
||||
'Quote Backlinks': [true, 'Add quote backlinks.'],
|
||||
'OP Backlinks': [true, 'Add backlinks to the OP.', 1],
|
||||
'Quote Inlining': [true, 'Inline quoted post on click.'],
|
||||
'Inline Cross-thread Quotes Only': [false, 'Only inline quote links when the posts are on another thread or board, or fetched from the archive.', 1],
|
||||
'Inline Cross-thread Quotes Only': [false, 'Don\'t inline quote links when the posts are visible in the thread.', 1],
|
||||
'Quote Hash Navigation': [false, 'Include an extra link after quotes for autoscrolling to quoted posts.', 1],
|
||||
'Forward Hiding': [true, 'Hide original posts of inlined backlinks.', 1],
|
||||
'Quote Previewing': [true, 'Show quoted post on hover.'],
|
||||
@ -270,7 +271,7 @@
|
||||
'Highlight Own Posts': [true, 'Highlights own posts.', 1],
|
||||
'Mark OP Quotes': [true, 'Add \'(OP)\' to OP quotes.'],
|
||||
'Mark Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes.'],
|
||||
'Quote Threading': [false, 'Thread conversations']
|
||||
'Quote Threading': [true, 'Add option in header menu to thread conversations.']
|
||||
}
|
||||
},
|
||||
imageExpansion: {
|
||||
@ -428,10 +429,12 @@
|
||||
},
|
||||
customCooldown: 0,
|
||||
customCooldownEnabled: true,
|
||||
pruneReplies: {
|
||||
'Prune Replies': false,
|
||||
'Thread Quotes': false,
|
||||
replyPruning: {
|
||||
'Prune Replies': true,
|
||||
'Max Replies': 1000
|
||||
}
|
||||
},
|
||||
'Autohiding Scrollbar': false
|
||||
};
|
||||
|
||||
Conf = {};
|
||||
@ -443,7 +446,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.11.29.6',
|
||||
VERSION: '1.11.30.0',
|
||||
NAMESPACE: '4chan X.',
|
||||
boards: {}
|
||||
};
|
||||
@ -2503,7 +2506,7 @@
|
||||
results.push(this.archiveTags[text]);
|
||||
} else {
|
||||
greentext = text[0] === '>';
|
||||
text = text.replace(/(\[\/?[a-z]+):lit(\])/, '$1$2');
|
||||
text = text.replace(/(\[\/?[a-z]+):lit(\])/g, '$1$2');
|
||||
text = (function() {
|
||||
var len2, q, ref, results1;
|
||||
ref = text.split(/(>>(?:>\/[a-z\d]+\/)?\d+)/g);
|
||||
@ -4539,17 +4542,22 @@
|
||||
}
|
||||
return container;
|
||||
},
|
||||
summary: function(boardID, threadID, posts, files) {
|
||||
summaryText: function(status, posts, files) {
|
||||
var text;
|
||||
text = [];
|
||||
text.push(posts + " post" + (posts > 1 ? 's' : ''));
|
||||
if (files) {
|
||||
text.push("and " + files + " image repl" + (files > 1 ? 'ies' : 'y'));
|
||||
text = '';
|
||||
if (status) {
|
||||
text += status + " ";
|
||||
}
|
||||
text.push('omitted.');
|
||||
text += posts + " post" + (posts > 1 ? 's' : '');
|
||||
if (+files) {
|
||||
text += " and " + files + " image repl" + (files > 1 ? 'ies' : 'y');
|
||||
}
|
||||
return text += " " + (status === '-' ? 'shown' : 'omitted') + ".";
|
||||
},
|
||||
summary: function(boardID, threadID, posts, files) {
|
||||
return $.el('a', {
|
||||
className: 'summary',
|
||||
textContent: text.join(' '),
|
||||
textContent: Build.summaryText('', posts, files),
|
||||
href: "/" + boardID + "/thread/" + threadID
|
||||
});
|
||||
},
|
||||
@ -6357,7 +6365,7 @@
|
||||
if (Conf['Quote Previewing']) {
|
||||
$.on(link, 'mouseover', QuotePreview.mouseover);
|
||||
}
|
||||
if (Conf['Quote Inlining'] && !(Conf['Inline Cross-thread Quotes Only'] && !QuoteInline.isCrossThread(link))) {
|
||||
if (Conf['Quote Inlining']) {
|
||||
$.on(link, 'click', QuoteInline.toggle);
|
||||
if (Conf['Quote Hash Navigation']) {
|
||||
hash = QuoteInline.qiQuote(link, $.hasClass(link, 'filtered'));
|
||||
@ -6457,9 +6465,6 @@
|
||||
}
|
||||
},
|
||||
process: function(link, clone) {
|
||||
if (Conf['Inline Cross-thread Quotes Only'] && !QuoteInline.isCrossThread(link)) {
|
||||
return;
|
||||
}
|
||||
if (Conf['Quote Hash Navigation']) {
|
||||
if (!clone) {
|
||||
$.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
|
||||
@ -6467,9 +6472,6 @@
|
||||
}
|
||||
return $.on(link, 'click', QuoteInline.toggle);
|
||||
},
|
||||
isCrossThread: function(link) {
|
||||
return link.pathname !== location.pathname || link.host !== location.host || link.protocol !== location.protocol;
|
||||
},
|
||||
qiQuote: function(link, hidden) {
|
||||
var name;
|
||||
name = "hashlink";
|
||||
@ -6483,12 +6485,15 @@
|
||||
});
|
||||
},
|
||||
toggle: function(e) {
|
||||
var boardID, context, postID, quoter, ref, threadID;
|
||||
var boardID, context, postID, quoter, ref, ref1, threadID;
|
||||
if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
ref = Get.postDataFromLink(this), boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID;
|
||||
if (Conf['Inline Cross-thread Quotes Only'] && g.VIEW === 'thread' && ((ref1 = g.posts[boardID + "." + postID]) != null ? ref1.nodes.root.offsetParent : void 0)) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
quoter = Get.postFromNode(this);
|
||||
context = quoter.context;
|
||||
if ($.hasClass(this, 'inlined')) {
|
||||
@ -6709,9 +6714,8 @@
|
||||
if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) {
|
||||
return;
|
||||
}
|
||||
this.enabled = true;
|
||||
this.controls = $.el('span', {
|
||||
innerHTML: "<label><input id=\"threadingControl\" type=\"checkbox\" checked> Threading</label>"
|
||||
this.controls = $.el('label', {
|
||||
innerHTML: "<input id=\"threadingControl\" name=\"Thread Quotes\" type=\"checkbox\"> Threading"
|
||||
});
|
||||
this.threadNewLink = $.el('span', {
|
||||
className: 'brackets-wrap threadnewlink',
|
||||
@ -6721,8 +6725,15 @@
|
||||
innerHTML: "<a href=\"javascript:;\">Thread New Posts</a>"
|
||||
});
|
||||
this.input = $('input', this.controls);
|
||||
this.input.checked = Conf['Thread Quotes'];
|
||||
$.on(this.input, 'change', this.setEnabled);
|
||||
$.on(this.input, 'change', this.rethread);
|
||||
$.on(this.threadNewLink.firstElementChild, 'click', this.rethread);
|
||||
$.on(d, '4chanXInitFinished', (function(_this) {
|
||||
return function() {
|
||||
return _this.ready = true;
|
||||
};
|
||||
})(this));
|
||||
Header.menu.addEntry(this.entry = {
|
||||
el: this.controls,
|
||||
order: 99
|
||||
@ -6739,6 +6750,15 @@
|
||||
parent: {},
|
||||
children: {},
|
||||
inserted: {},
|
||||
setEnabled: function() {
|
||||
var other, ref;
|
||||
other = (ref = ReplyPruning.inputs) != null ? ref.enabled : void 0;
|
||||
if (this.checked && (other != null ? other.checked : void 0)) {
|
||||
other.checked = false;
|
||||
$.event('change', null, other);
|
||||
}
|
||||
return $.cb.checked.call(this);
|
||||
},
|
||||
setThread: function() {
|
||||
QuoteThreading.thread = this;
|
||||
return $.asap((function() {
|
||||
@ -6793,7 +6813,7 @@
|
||||
},
|
||||
insert: function(post) {
|
||||
var base1, child, children, descendants, i, k, len1, name1, next, nodes, order, parent, prev, prev2, q, threadContainer, u, x;
|
||||
if (!(QuoteThreading.enabled && (parent = QuoteThreading.parent[post.fullID]) && !QuoteThreading.inserted[post.fullID])) {
|
||||
if (!(Conf['Thread Quotes'] && (parent = QuoteThreading.parent[post.fullID]) && !QuoteThreading.inserted[post.fullID])) {
|
||||
return false;
|
||||
}
|
||||
descendants = QuoteThreading.descendants(post);
|
||||
@ -6857,10 +6877,13 @@
|
||||
},
|
||||
rethread: function() {
|
||||
var nodes, posts, thread;
|
||||
if (!QuoteThreading.ready) {
|
||||
return;
|
||||
}
|
||||
thread = QuoteThreading.thread;
|
||||
posts = thread.posts;
|
||||
QuoteThreading.threadNewLink.hidden = true;
|
||||
if (QuoteThreading.enabled = QuoteThreading.input.checked) {
|
||||
if (Conf['Thread Quotes']) {
|
||||
posts.forEach(QuoteThreading.insert);
|
||||
} else {
|
||||
nodes = [];
|
||||
@ -9811,8 +9834,7 @@
|
||||
switch (name) {
|
||||
case 'thread':
|
||||
(this.thread !== 'new' ? $.addClass : $.rmClass)(QR.nodes.el, 'reply-to-thread');
|
||||
QR.status();
|
||||
return this.updateFlashURL();
|
||||
return QR.status();
|
||||
case 'com':
|
||||
this.updateComment();
|
||||
if (QR.cooldown.auto && this === QR.posts[0] && (0 < (ref = QR.cooldown.seconds) && ref <= 5)) {
|
||||
@ -9824,8 +9846,7 @@
|
||||
return;
|
||||
}
|
||||
this.saveFilename();
|
||||
this.updateFilename();
|
||||
return this.updateFlashURL();
|
||||
return this.updateFilename();
|
||||
case 'name':
|
||||
return QR.persona.set(this);
|
||||
}
|
||||
@ -9958,7 +9979,6 @@
|
||||
} else {
|
||||
this.updateFilename();
|
||||
}
|
||||
this.updateFlashURL();
|
||||
this.nodes.el.style.backgroundImage = null;
|
||||
if (ref = this.file.type, indexOf.call(QR.mimeTypes, ref) < 0) {
|
||||
return this.fileError('Unsupported file type.');
|
||||
@ -10088,7 +10108,6 @@
|
||||
this.nodes.el.style.backgroundImage = null;
|
||||
$.rmClass(this.nodes.el, 'has-file');
|
||||
this.showFileData();
|
||||
this.updateFlashURL();
|
||||
URL.revokeObjectURL(this.URL);
|
||||
return this.dismissErrors(function(error) {
|
||||
return $.hasClass(error, 'file-error');
|
||||
@ -10131,31 +10150,6 @@
|
||||
return QR.nodes.spoiler.checked = this.spoiler;
|
||||
};
|
||||
|
||||
_Class.prototype.updateFlashURL = function() {
|
||||
var com, oldURL, ref, url;
|
||||
if (g.BOARD.ID !== 'f') {
|
||||
return;
|
||||
}
|
||||
if (this.thread === 'new' || !this.file) {
|
||||
url = '';
|
||||
} else {
|
||||
url = this.file.newName;
|
||||
if ((ref = $.engine) === 'blink' || ref === 'webkit') {
|
||||
url = url.replace(/"/g, '%22');
|
||||
}
|
||||
url = url.replace(/[\t\n\f\r \xa0\u200B\u2029\u3000]+/g, ' ').replace(/(^ | $)/g, '').replace(/\.[0-9A-Za-z]+$/, '');
|
||||
url = "https://i.4cdn.org/f/" + (encodeURIComponent(E(url))) + ".swf\n";
|
||||
}
|
||||
oldURL = this.flashURL || '';
|
||||
if (url !== oldURL) {
|
||||
com = this.com || '';
|
||||
if (com.slice(0, oldURL.length) === oldURL) {
|
||||
this.setComment(url + com.slice(oldURL.length));
|
||||
}
|
||||
return this.flashURL = url;
|
||||
}
|
||||
};
|
||||
|
||||
_Class.prototype.pasteText = function(file) {
|
||||
var reader;
|
||||
this.pasting = true;
|
||||
@ -13251,12 +13245,28 @@
|
||||
}
|
||||
};
|
||||
|
||||
PruneReplies = {
|
||||
ReplyPruning = {
|
||||
init: function() {
|
||||
var el, label;
|
||||
if (!(g.VIEW === 'thread' && !Conf['Quote Threading'])) {
|
||||
if (!(g.VIEW === 'thread' && Conf['Reply Pruning'])) {
|
||||
return;
|
||||
}
|
||||
if (Conf['Quote Threading'] && Conf['Thread Quotes'] && Conf['Prune Replies']) {
|
||||
Conf['Prune Replies'] = false;
|
||||
$.set('Prune Replies', false);
|
||||
}
|
||||
this.container = $.frag();
|
||||
this.summary = $.el('span', {
|
||||
hidden: true,
|
||||
className: 'summary',
|
||||
style: 'cursor: pointer;'
|
||||
});
|
||||
$.on(this.summary, 'click', (function(_this) {
|
||||
return function() {
|
||||
_this.inputs.enabled.checked = !_this.inputs.enabled.checked;
|
||||
return $.event('change', null, _this.inputs.enabled);
|
||||
};
|
||||
})(this));
|
||||
label = UI.checkbox('Prune Replies', 'Show Last');
|
||||
el = $.el('span', {
|
||||
title: 'Maximum number of replies to show.'
|
||||
@ -13268,68 +13278,94 @@
|
||||
enabled: label.firstElementChild,
|
||||
replies: el.lastElementChild
|
||||
};
|
||||
$.on(this.inputs.enabled, 'change', $.cb.checked);
|
||||
$.on(this.inputs.enabled, 'change', this.setEnabled);
|
||||
$.on(this.inputs.replies, 'change', $.cb.value);
|
||||
Header.menu.addEntry({
|
||||
el: el,
|
||||
order: 190
|
||||
});
|
||||
return Thread.callbacks.push({
|
||||
name: 'Prune Replies',
|
||||
name: 'Reply Pruning',
|
||||
cb: this.node
|
||||
});
|
||||
},
|
||||
position: 0,
|
||||
hidden: 0,
|
||||
hiddenFiles: 0,
|
||||
total: 0,
|
||||
node: function() {
|
||||
PruneReplies.thread = this;
|
||||
PruneReplies.total = this.posts.keys.length - 1;
|
||||
$.on(PruneReplies.inputs.enabled, 'change', PruneReplies.setEnabled);
|
||||
$.on(PruneReplies.inputs.enabled, 'change', PruneReplies.update);
|
||||
if (Conf['Prune Replies']) {
|
||||
PruneReplies.setEnabled();
|
||||
return PruneReplies.update();
|
||||
}
|
||||
},
|
||||
totalFiles: 0,
|
||||
setEnabled: function() {
|
||||
var onOff;
|
||||
PruneReplies.container || (PruneReplies.container = $.frag());
|
||||
onOff = Conf['Prune Replies'] ? $.on : $.off;
|
||||
onOff(PruneReplies.inputs.replies, 'change', PruneReplies.update);
|
||||
return onOff(d, 'ThreadUpdate', PruneReplies.update);
|
||||
},
|
||||
update: function(e) {
|
||||
var OP, frag, hidden2, post, posts, ref, results;
|
||||
if (e && e.type === 'ThreadUpdate' && !e.detail[404]) {
|
||||
PruneReplies.total += e.detail.newPosts.length;
|
||||
var other;
|
||||
other = QuoteThreading.input;
|
||||
if (this.checked && (other != null ? other.checked : void 0)) {
|
||||
other.checked = false;
|
||||
$.event('change', null, other);
|
||||
}
|
||||
hidden2 = Conf['Prune Replies'] ? Math.max(PruneReplies.total - +Conf["Max Replies"], 0) : 0;
|
||||
ref = PruneReplies.thread, posts = ref.posts, OP = ref.OP;
|
||||
if (PruneReplies.hidden < hidden2) {
|
||||
results = [];
|
||||
while (PruneReplies.hidden < hidden2 && PruneReplies.position < posts.keys.length) {
|
||||
post = posts[posts.keys[PruneReplies.position++]];
|
||||
if (post.isReply && !post.isFetchedQuote) {
|
||||
$.add(PruneReplies.container, post.nodes.root);
|
||||
results.push(PruneReplies.hidden++);
|
||||
} else {
|
||||
results.push(void 0);
|
||||
return $.cb.checked.call(this);
|
||||
},
|
||||
node: function() {
|
||||
ReplyPruning.thread = this;
|
||||
this.posts.forEach(function(post) {
|
||||
if (post.isReply) {
|
||||
ReplyPruning.total++;
|
||||
if (post.file) {
|
||||
return ReplyPruning.totalFiles++;
|
||||
}
|
||||
}
|
||||
return results;
|
||||
} else if (PruneReplies.hidden > hidden2) {
|
||||
});
|
||||
$.after(this.OP.nodes.root, ReplyPruning.summary);
|
||||
$.on(ReplyPruning.inputs.enabled, 'change', ReplyPruning.update);
|
||||
$.on(ReplyPruning.inputs.replies, 'change', ReplyPruning.update);
|
||||
$.on(d, 'ThreadUpdate', ReplyPruning.updateCount);
|
||||
$.on(d, 'ThreadUpdate', ReplyPruning.update);
|
||||
return ReplyPruning.update();
|
||||
},
|
||||
updateCount: function(e) {
|
||||
var fullID, k, len1, ref;
|
||||
if (e.detail[404]) {
|
||||
return;
|
||||
}
|
||||
ref = e.detail.newPosts;
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
fullID = ref[k];
|
||||
ReplyPruning.total++;
|
||||
if (g.posts[fullID].file) {
|
||||
ReplyPruning.totalFiles++;
|
||||
}
|
||||
}
|
||||
},
|
||||
update: function() {
|
||||
var frag, hidden2, post, posts;
|
||||
hidden2 = Conf['Prune Replies'] ? Math.max(ReplyPruning.total - +Conf["Max Replies"], 0) : 0;
|
||||
posts = ReplyPruning.thread.posts;
|
||||
if (ReplyPruning.hidden < hidden2) {
|
||||
while (ReplyPruning.hidden < hidden2 && ReplyPruning.position < posts.keys.length) {
|
||||
post = posts[posts.keys[ReplyPruning.position++]];
|
||||
if (post.isReply && !post.isFetchedQuote) {
|
||||
$.add(ReplyPruning.container, post.nodes.root);
|
||||
ReplyPruning.hidden++;
|
||||
if (post.file) {
|
||||
ReplyPruning.hiddenFiles++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ReplyPruning.hidden > hidden2) {
|
||||
frag = $.frag();
|
||||
while (PruneReplies.hidden > hidden2 && PruneReplies.position > 0) {
|
||||
post = posts[posts.keys[--PruneReplies.position]];
|
||||
while (ReplyPruning.hidden > hidden2 && ReplyPruning.position > 0) {
|
||||
post = posts[posts.keys[--ReplyPruning.position]];
|
||||
if (post.isReply && !post.isFetchedQuote) {
|
||||
$.prepend(frag, post.nodes.root);
|
||||
PruneReplies.hidden--;
|
||||
ReplyPruning.hidden--;
|
||||
if (post.file) {
|
||||
ReplyPruning.hiddenFiles--;
|
||||
}
|
||||
}
|
||||
}
|
||||
$.after(OP.nodes.root, frag);
|
||||
return $.event('PostsInserted');
|
||||
$.after(ReplyPruning.summary, frag);
|
||||
$.event('PostsInserted');
|
||||
}
|
||||
ReplyPruning.summary.textContent = Conf['Prune Replies'] ? Build.summaryText('+', ReplyPruning.hidden, ReplyPruning.hiddenFiles) : Build.summaryText('-', ReplyPruning.total, ReplyPruning.totalFiles);
|
||||
return ReplyPruning.summary.hidden = ReplyPruning.total <= +Conf["Max Replies"];
|
||||
}
|
||||
};
|
||||
|
||||
@ -13601,10 +13637,7 @@
|
||||
}));
|
||||
$.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost);
|
||||
$.on(d, 'visibilitychange', ThreadUpdater.cb.visibility);
|
||||
ThreadUpdater.setInterval();
|
||||
if (this.board.ID === 'f') {
|
||||
return ThreadUpdater.update();
|
||||
}
|
||||
return ThreadUpdater.setInterval();
|
||||
},
|
||||
|
||||
/*
|
||||
@ -13832,12 +13865,6 @@
|
||||
if (postObject.fsize) {
|
||||
files.push(ID);
|
||||
}
|
||||
if (board.ID === 'f' && postObject.fsize && (post = thread.posts[ID]) && !post.file) {
|
||||
node = Build.postFromObject(postObject, board.ID);
|
||||
$.after(post.nodes.info, $('.file', node));
|
||||
post.parseFile();
|
||||
Post.callbacks.execute(post, ['Filter', 'File Info Formatting', 'Fappe Tyme', 'Sauce']);
|
||||
}
|
||||
if (ID <= lastPost) {
|
||||
continue;
|
||||
}
|
||||
@ -15497,7 +15524,7 @@
|
||||
}
|
||||
},
|
||||
initBoardList: function() {
|
||||
if (!Conf['Catalog Links']) {
|
||||
if (!CatalogLinks.el) {
|
||||
return;
|
||||
}
|
||||
return CatalogLinks.set(Conf['Header catalog links']);
|
||||
@ -15703,7 +15730,7 @@
|
||||
if (!(a = $.x('following-sibling::*[contains(@class,"summary")][1]', thread.OP.nodes.root))) {
|
||||
return;
|
||||
}
|
||||
a.textContent = ExpandThread.text.apply(ExpandThread, ['+'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
a.textContent = Build.summaryText.apply(Build, ['+'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
a.style.cursor = 'pointer';
|
||||
return $.on(a, 'click', ExpandThread.cbToggle);
|
||||
},
|
||||
@ -15730,9 +15757,6 @@
|
||||
return ExpandThread.setButton(thread);
|
||||
});
|
||||
},
|
||||
text: function(status, posts, files) {
|
||||
return (status + " " + posts + " post" + (posts > 1 ? 's' : '')) + (+files ? " and " + files + " image repl" + (files > 1 ? 'ies' : 'y') : "") + (" " + (status === '-' ? 'shown' : 'omitted') + ".");
|
||||
},
|
||||
cbToggle: function(e) {
|
||||
if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) {
|
||||
return;
|
||||
@ -15755,7 +15779,7 @@
|
||||
expand: function(thread, a) {
|
||||
var status;
|
||||
ExpandThread.statuses[thread] = status = {};
|
||||
a.textContent = ExpandThread.text.apply(ExpandThread, ['...'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
a.textContent = Build.summaryText.apply(Build, ['...'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
return status.req = $.cache("//a.4cdn.org/" + thread.board + "/thread/" + thread + ".json", function() {
|
||||
delete status.req;
|
||||
return ExpandThread.parse(this, thread, a);
|
||||
@ -15768,7 +15792,7 @@
|
||||
if (status.req) {
|
||||
status.req.abort();
|
||||
if (a) {
|
||||
a.textContent = ExpandThread.text.apply(ExpandThread, ['+'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
a.textContent = Build.summaryText.apply(Build, ['+'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -15806,7 +15830,7 @@
|
||||
}
|
||||
$.rm(reply);
|
||||
}
|
||||
return a.textContent = ExpandThread.text('+', postsCount, filesCount);
|
||||
return a.textContent = Build.summaryText('+', postsCount, filesCount);
|
||||
},
|
||||
parse: function(req, thread, a) {
|
||||
var filesCount, k, len1, post, postData, posts, postsCount, postsRoot, ref, ref1, root;
|
||||
@ -15843,7 +15867,7 @@
|
||||
$.after(a, postsRoot);
|
||||
$.event('PostsInserted');
|
||||
postsCount = postsRoot.length;
|
||||
return a.textContent = ExpandThread.text('-', postsCount, filesCount);
|
||||
return a.textContent = Build.summaryText('-', postsCount, filesCount);
|
||||
}
|
||||
};
|
||||
|
||||
@ -17704,6 +17728,11 @@
|
||||
set('Inline Cross-thread Quotes Only', true);
|
||||
}
|
||||
}
|
||||
if (compareString < '00001.00011.00030.00000') {
|
||||
if (data['Quote Threading'] && (data['Thread Quotes'] == null)) {
|
||||
set('Thread Quotes', true);
|
||||
}
|
||||
}
|
||||
return changes;
|
||||
},
|
||||
loadSettings: function(data, cb) {
|
||||
@ -18291,6 +18320,16 @@
|
||||
return $.addClass(doc, 'ads-loaded');
|
||||
});
|
||||
});
|
||||
if (Conf['Autohiding Scrollbar']) {
|
||||
$.addClass(doc, 'autohiding-scrollbar');
|
||||
}
|
||||
$.ready(function() {
|
||||
if (d.body.clientHeight > doc.clientHeight && (window.innerWidth === doc.clientWidth) !== Conf['Autohiding Scrollbar']) {
|
||||
Conf['Autohiding Scrollbar'] = !Conf['Autohiding Scrollbar'];
|
||||
$.set('Autohiding Scrollbar', Conf['Autohiding Scrollbar']);
|
||||
return $.toggleClass(doc, 'autohiding-scrollbar');
|
||||
}
|
||||
});
|
||||
$.addStyle(Main.css, 'fourchanx-css');
|
||||
Main.bgColorStyle = $.el('style', {
|
||||
id: 'fourchanx-bgcolor-css'
|
||||
@ -19518,6 +19557,9 @@
|
||||
"#shortcuts {\n" +
|
||||
" float: right;\n" +
|
||||
"}\n" +
|
||||
":root.autohiding-scrollbar #shortcuts {\n" +
|
||||
" margin-right: 12px;\n" +
|
||||
"}\n" +
|
||||
".shortcut {\n" +
|
||||
" margin-left: 3px;\n" +
|
||||
" vertical-align: middle;\n" +
|
||||
@ -21878,7 +21920,7 @@
|
||||
cssWWW: "#captcha-cnt {\n" +
|
||||
" height: auto;\n" +
|
||||
"}",
|
||||
features: [['Polyfill', Polyfill], ['Normalize URL', NormalizeURL], ['Captcha Configuration', Captcha.replace], ['Redirect', Redirect], ['Header', Header], ['Catalog Links', CatalogLinks], ['Settings', Settings], ['Index Generator', Index], ['Disable Autoplay', AntiAutoplay], ['Announcement Hiding', PSAHiding], ['Fourchan thingies', Fourchan], ['Color User IDs', IDColor], ['Highlight by User ID', IDHighlight], ['Custom CSS', CustomCSS], ['Thread Links', ThreadLinks], ['Linkify', Linkify], ['Reveal Spoilers', RemoveSpoilers], ['Resurrect Quotes', Quotify], ['Filter', Filter], ['Thread Hiding Buttons', ThreadHiding], ['Reply Hiding Buttons', PostHiding], ['Recursive', Recursive], ['Strike-through Quotes', QuoteStrikeThrough], ['Quick Reply', QR], ['Cooldown', QR.cooldown], ['Pass Link', PassLink], ['Menu', Menu], ['Index Generator (Menu)', Index.menu], ['Report Link', ReportLink], ['Thread Hiding (Menu)', ThreadHiding.menu], ['Reply Hiding (Menu)', PostHiding.menu], ['Delete Link', DeleteLink], ['Filter (Menu)', Filter.menu], ['Edit Link', QR.oekaki.menu], ['Download Link', DownloadLink], ['Archive Link', ArchiveLink], ['Quote Inlining', QuoteInline], ['Quote Previewing', QuotePreview], ['Quote Backlinks', QuoteBacklink], ['Mark Quotes of You', QuoteYou], ['Mark OP Quotes', QuoteOP], ['Mark Cross-thread Quotes', QuoteCT], ['Anonymize', Anonymize], ['Time Formatting', Time], ['Relative Post Dates', RelativeDates], ['File Info Formatting', FileInfo], ['Fappe Tyme', FappeTyme], ['Gallery', Gallery], ['Gallery (menu)', Gallery.menu], ['Sauce', Sauce], ['Image Expansion', ImageExpand], ['Image Expansion (Menu)', ImageExpand.menu], ['Reveal Spoiler Thumbnails', RevealSpoilers], ['Image Loading', ImageLoader], ['Image Hover', ImageHover], ['Volume Control', Volume], ['WEBM Metadata', Metadata], ['Comment Expansion', ExpandComment], ['Thread Expansion', ExpandThread], ['Thread Excerpt', ThreadExcerpt], ['Favicon', Favicon], ['Unread', Unread], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats], ['Thread Updater', ThreadUpdater], ['Thread Watcher', ThreadWatcher], ['Thread Watcher (Menu)', ThreadWatcher.menu], ['Mark New IPs', MarkNewIPs], ['Index Navigation', Nav], ['Keybinds', Keybinds], ['Banner', Banner], ['Flash Features', Flash], ['Prune Replies', PruneReplies]]
|
||||
features: [['Polyfill', Polyfill], ['Normalize URL', NormalizeURL], ['Captcha Configuration', Captcha.replace], ['Redirect', Redirect], ['Header', Header], ['Catalog Links', CatalogLinks], ['Settings', Settings], ['Index Generator', Index], ['Disable Autoplay', AntiAutoplay], ['Announcement Hiding', PSAHiding], ['Fourchan thingies', Fourchan], ['Color User IDs', IDColor], ['Highlight by User ID', IDHighlight], ['Custom CSS', CustomCSS], ['Thread Links', ThreadLinks], ['Linkify', Linkify], ['Reveal Spoilers', RemoveSpoilers], ['Resurrect Quotes', Quotify], ['Filter', Filter], ['Thread Hiding Buttons', ThreadHiding], ['Reply Hiding Buttons', PostHiding], ['Recursive', Recursive], ['Strike-through Quotes', QuoteStrikeThrough], ['Quick Reply', QR], ['Cooldown', QR.cooldown], ['Pass Link', PassLink], ['Menu', Menu], ['Index Generator (Menu)', Index.menu], ['Report Link', ReportLink], ['Thread Hiding (Menu)', ThreadHiding.menu], ['Reply Hiding (Menu)', PostHiding.menu], ['Delete Link', DeleteLink], ['Filter (Menu)', Filter.menu], ['Edit Link', QR.oekaki.menu], ['Download Link', DownloadLink], ['Archive Link', ArchiveLink], ['Quote Inlining', QuoteInline], ['Quote Previewing', QuotePreview], ['Quote Backlinks', QuoteBacklink], ['Mark Quotes of You', QuoteYou], ['Mark OP Quotes', QuoteOP], ['Mark Cross-thread Quotes', QuoteCT], ['Anonymize', Anonymize], ['Time Formatting', Time], ['Relative Post Dates', RelativeDates], ['File Info Formatting', FileInfo], ['Fappe Tyme', FappeTyme], ['Gallery', Gallery], ['Gallery (menu)', Gallery.menu], ['Sauce', Sauce], ['Image Expansion', ImageExpand], ['Image Expansion (Menu)', ImageExpand.menu], ['Reveal Spoiler Thumbnails', RevealSpoilers], ['Image Loading', ImageLoader], ['Image Hover', ImageHover], ['Volume Control', Volume], ['WEBM Metadata', Metadata], ['Comment Expansion', ExpandComment], ['Thread Expansion', ExpandThread], ['Thread Excerpt', ThreadExcerpt], ['Favicon', Favicon], ['Unread', Unread], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats], ['Thread Updater', ThreadUpdater], ['Thread Watcher', ThreadWatcher], ['Thread Watcher (Menu)', ThreadWatcher.menu], ['Mark New IPs', MarkNewIPs], ['Index Navigation', Nav], ['Keybinds', Keybinds], ['Banner', Banner], ['Flash Features', Flash], ['Reply Pruning', ReplyPruning]]
|
||||
};
|
||||
|
||||
Main.init();
|
||||
|
||||
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.11.29.6
|
||||
// @version 1.11.30.0
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.11.29.6
|
||||
// @version 1.11.30.0
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -119,7 +119,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, NormalizeURL, Notice, PSAHiding, PassLink, Polyfill, Post, PostHiding, PostSuccessful, PruneReplies, 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, ThreadLinks, 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, NormalizeURL, Notice, PSAHiding, PassLink, Polyfill, Post, PostHiding, PostSuccessful, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, ReplyPruning, Report, ReportLink, RevealSpoilers, Sauce, Settings, ShimSet, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadLinks, 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; },
|
||||
@ -230,7 +230,8 @@
|
||||
'Thread Watcher': [true, 'Bookmark threads.'],
|
||||
'Fixed Thread Watcher': [true, 'Makes the thread watcher scroll with the page.', 1],
|
||||
'Toggleable Thread Watcher': [true, 'Adds a shortcut for the thread watcher and hides the watcher by default.', 1],
|
||||
'Mark New IPs': [false, 'Label each post from a new IP with the thread\'s current IP count.']
|
||||
'Mark New IPs': [false, 'Label each post from a new IP with the thread\'s current IP count.'],
|
||||
'Reply Pruning': [true, 'Hide old replies in long threads. Number of replies shown can be set from header menu.']
|
||||
},
|
||||
'Posting and Captchas': {
|
||||
'Quick Reply': [true, 'All-in-one form to reply, create threads, automate dumping and more.'],
|
||||
@ -258,7 +259,7 @@
|
||||
'Quote Backlinks': [true, 'Add quote backlinks.'],
|
||||
'OP Backlinks': [true, 'Add backlinks to the OP.', 1],
|
||||
'Quote Inlining': [true, 'Inline quoted post on click.'],
|
||||
'Inline Cross-thread Quotes Only': [false, 'Only inline quote links when the posts are on another thread or board, or fetched from the archive.', 1],
|
||||
'Inline Cross-thread Quotes Only': [false, 'Don\'t inline quote links when the posts are visible in the thread.', 1],
|
||||
'Quote Hash Navigation': [false, 'Include an extra link after quotes for autoscrolling to quoted posts.', 1],
|
||||
'Forward Hiding': [true, 'Hide original posts of inlined backlinks.', 1],
|
||||
'Quote Previewing': [true, 'Show quoted post on hover.'],
|
||||
@ -270,7 +271,7 @@
|
||||
'Highlight Own Posts': [true, 'Highlights own posts.', 1],
|
||||
'Mark OP Quotes': [true, 'Add \'(OP)\' to OP quotes.'],
|
||||
'Mark Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes.'],
|
||||
'Quote Threading': [false, 'Thread conversations']
|
||||
'Quote Threading': [true, 'Add option in header menu to thread conversations.']
|
||||
}
|
||||
},
|
||||
imageExpansion: {
|
||||
@ -428,10 +429,12 @@
|
||||
},
|
||||
customCooldown: 0,
|
||||
customCooldownEnabled: true,
|
||||
pruneReplies: {
|
||||
'Prune Replies': false,
|
||||
'Thread Quotes': false,
|
||||
replyPruning: {
|
||||
'Prune Replies': true,
|
||||
'Max Replies': 1000
|
||||
}
|
||||
},
|
||||
'Autohiding Scrollbar': false
|
||||
};
|
||||
|
||||
Conf = {};
|
||||
@ -443,7 +446,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.11.29.6',
|
||||
VERSION: '1.11.30.0',
|
||||
NAMESPACE: '4chan X.',
|
||||
boards: {}
|
||||
};
|
||||
@ -2503,7 +2506,7 @@
|
||||
results.push(this.archiveTags[text]);
|
||||
} else {
|
||||
greentext = text[0] === '>';
|
||||
text = text.replace(/(\[\/?[a-z]+):lit(\])/, '$1$2');
|
||||
text = text.replace(/(\[\/?[a-z]+):lit(\])/g, '$1$2');
|
||||
text = (function() {
|
||||
var len2, q, ref, results1;
|
||||
ref = text.split(/(>>(?:>\/[a-z\d]+\/)?\d+)/g);
|
||||
@ -4539,17 +4542,22 @@
|
||||
}
|
||||
return container;
|
||||
},
|
||||
summary: function(boardID, threadID, posts, files) {
|
||||
summaryText: function(status, posts, files) {
|
||||
var text;
|
||||
text = [];
|
||||
text.push(posts + " post" + (posts > 1 ? 's' : ''));
|
||||
if (files) {
|
||||
text.push("and " + files + " image repl" + (files > 1 ? 'ies' : 'y'));
|
||||
text = '';
|
||||
if (status) {
|
||||
text += status + " ";
|
||||
}
|
||||
text.push('omitted.');
|
||||
text += posts + " post" + (posts > 1 ? 's' : '');
|
||||
if (+files) {
|
||||
text += " and " + files + " image repl" + (files > 1 ? 'ies' : 'y');
|
||||
}
|
||||
return text += " " + (status === '-' ? 'shown' : 'omitted') + ".";
|
||||
},
|
||||
summary: function(boardID, threadID, posts, files) {
|
||||
return $.el('a', {
|
||||
className: 'summary',
|
||||
textContent: text.join(' '),
|
||||
textContent: Build.summaryText('', posts, files),
|
||||
href: "/" + boardID + "/thread/" + threadID
|
||||
});
|
||||
},
|
||||
@ -6357,7 +6365,7 @@
|
||||
if (Conf['Quote Previewing']) {
|
||||
$.on(link, 'mouseover', QuotePreview.mouseover);
|
||||
}
|
||||
if (Conf['Quote Inlining'] && !(Conf['Inline Cross-thread Quotes Only'] && !QuoteInline.isCrossThread(link))) {
|
||||
if (Conf['Quote Inlining']) {
|
||||
$.on(link, 'click', QuoteInline.toggle);
|
||||
if (Conf['Quote Hash Navigation']) {
|
||||
hash = QuoteInline.qiQuote(link, $.hasClass(link, 'filtered'));
|
||||
@ -6457,9 +6465,6 @@
|
||||
}
|
||||
},
|
||||
process: function(link, clone) {
|
||||
if (Conf['Inline Cross-thread Quotes Only'] && !QuoteInline.isCrossThread(link)) {
|
||||
return;
|
||||
}
|
||||
if (Conf['Quote Hash Navigation']) {
|
||||
if (!clone) {
|
||||
$.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
|
||||
@ -6467,9 +6472,6 @@
|
||||
}
|
||||
return $.on(link, 'click', QuoteInline.toggle);
|
||||
},
|
||||
isCrossThread: function(link) {
|
||||
return link.pathname !== location.pathname || link.host !== location.host || link.protocol !== location.protocol;
|
||||
},
|
||||
qiQuote: function(link, hidden) {
|
||||
var name;
|
||||
name = "hashlink";
|
||||
@ -6483,12 +6485,15 @@
|
||||
});
|
||||
},
|
||||
toggle: function(e) {
|
||||
var boardID, context, postID, quoter, ref, threadID;
|
||||
var boardID, context, postID, quoter, ref, ref1, threadID;
|
||||
if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
ref = Get.postDataFromLink(this), boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID;
|
||||
if (Conf['Inline Cross-thread Quotes Only'] && g.VIEW === 'thread' && ((ref1 = g.posts[boardID + "." + postID]) != null ? ref1.nodes.root.offsetParent : void 0)) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
quoter = Get.postFromNode(this);
|
||||
context = quoter.context;
|
||||
if ($.hasClass(this, 'inlined')) {
|
||||
@ -6709,9 +6714,8 @@
|
||||
if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) {
|
||||
return;
|
||||
}
|
||||
this.enabled = true;
|
||||
this.controls = $.el('span', {
|
||||
innerHTML: "<label><input id=\"threadingControl\" type=\"checkbox\" checked> Threading</label>"
|
||||
this.controls = $.el('label', {
|
||||
innerHTML: "<input id=\"threadingControl\" name=\"Thread Quotes\" type=\"checkbox\"> Threading"
|
||||
});
|
||||
this.threadNewLink = $.el('span', {
|
||||
className: 'brackets-wrap threadnewlink',
|
||||
@ -6721,8 +6725,15 @@
|
||||
innerHTML: "<a href=\"javascript:;\">Thread New Posts</a>"
|
||||
});
|
||||
this.input = $('input', this.controls);
|
||||
this.input.checked = Conf['Thread Quotes'];
|
||||
$.on(this.input, 'change', this.setEnabled);
|
||||
$.on(this.input, 'change', this.rethread);
|
||||
$.on(this.threadNewLink.firstElementChild, 'click', this.rethread);
|
||||
$.on(d, '4chanXInitFinished', (function(_this) {
|
||||
return function() {
|
||||
return _this.ready = true;
|
||||
};
|
||||
})(this));
|
||||
Header.menu.addEntry(this.entry = {
|
||||
el: this.controls,
|
||||
order: 99
|
||||
@ -6739,6 +6750,15 @@
|
||||
parent: {},
|
||||
children: {},
|
||||
inserted: {},
|
||||
setEnabled: function() {
|
||||
var other, ref;
|
||||
other = (ref = ReplyPruning.inputs) != null ? ref.enabled : void 0;
|
||||
if (this.checked && (other != null ? other.checked : void 0)) {
|
||||
other.checked = false;
|
||||
$.event('change', null, other);
|
||||
}
|
||||
return $.cb.checked.call(this);
|
||||
},
|
||||
setThread: function() {
|
||||
QuoteThreading.thread = this;
|
||||
return $.asap((function() {
|
||||
@ -6793,7 +6813,7 @@
|
||||
},
|
||||
insert: function(post) {
|
||||
var base1, child, children, descendants, i, k, len1, name1, next, nodes, order, parent, prev, prev2, q, threadContainer, u, x;
|
||||
if (!(QuoteThreading.enabled && (parent = QuoteThreading.parent[post.fullID]) && !QuoteThreading.inserted[post.fullID])) {
|
||||
if (!(Conf['Thread Quotes'] && (parent = QuoteThreading.parent[post.fullID]) && !QuoteThreading.inserted[post.fullID])) {
|
||||
return false;
|
||||
}
|
||||
descendants = QuoteThreading.descendants(post);
|
||||
@ -6857,10 +6877,13 @@
|
||||
},
|
||||
rethread: function() {
|
||||
var nodes, posts, thread;
|
||||
if (!QuoteThreading.ready) {
|
||||
return;
|
||||
}
|
||||
thread = QuoteThreading.thread;
|
||||
posts = thread.posts;
|
||||
QuoteThreading.threadNewLink.hidden = true;
|
||||
if (QuoteThreading.enabled = QuoteThreading.input.checked) {
|
||||
if (Conf['Thread Quotes']) {
|
||||
posts.forEach(QuoteThreading.insert);
|
||||
} else {
|
||||
nodes = [];
|
||||
@ -9811,8 +9834,7 @@
|
||||
switch (name) {
|
||||
case 'thread':
|
||||
(this.thread !== 'new' ? $.addClass : $.rmClass)(QR.nodes.el, 'reply-to-thread');
|
||||
QR.status();
|
||||
return this.updateFlashURL();
|
||||
return QR.status();
|
||||
case 'com':
|
||||
this.updateComment();
|
||||
if (QR.cooldown.auto && this === QR.posts[0] && (0 < (ref = QR.cooldown.seconds) && ref <= 5)) {
|
||||
@ -9824,8 +9846,7 @@
|
||||
return;
|
||||
}
|
||||
this.saveFilename();
|
||||
this.updateFilename();
|
||||
return this.updateFlashURL();
|
||||
return this.updateFilename();
|
||||
case 'name':
|
||||
return QR.persona.set(this);
|
||||
}
|
||||
@ -9958,7 +9979,6 @@
|
||||
} else {
|
||||
this.updateFilename();
|
||||
}
|
||||
this.updateFlashURL();
|
||||
this.nodes.el.style.backgroundImage = null;
|
||||
if (ref = this.file.type, indexOf.call(QR.mimeTypes, ref) < 0) {
|
||||
return this.fileError('Unsupported file type.');
|
||||
@ -10088,7 +10108,6 @@
|
||||
this.nodes.el.style.backgroundImage = null;
|
||||
$.rmClass(this.nodes.el, 'has-file');
|
||||
this.showFileData();
|
||||
this.updateFlashURL();
|
||||
URL.revokeObjectURL(this.URL);
|
||||
return this.dismissErrors(function(error) {
|
||||
return $.hasClass(error, 'file-error');
|
||||
@ -10131,31 +10150,6 @@
|
||||
return QR.nodes.spoiler.checked = this.spoiler;
|
||||
};
|
||||
|
||||
_Class.prototype.updateFlashURL = function() {
|
||||
var com, oldURL, ref, url;
|
||||
if (g.BOARD.ID !== 'f') {
|
||||
return;
|
||||
}
|
||||
if (this.thread === 'new' || !this.file) {
|
||||
url = '';
|
||||
} else {
|
||||
url = this.file.newName;
|
||||
if ((ref = $.engine) === 'blink' || ref === 'webkit') {
|
||||
url = url.replace(/"/g, '%22');
|
||||
}
|
||||
url = url.replace(/[\t\n\f\r \xa0\u200B\u2029\u3000]+/g, ' ').replace(/(^ | $)/g, '').replace(/\.[0-9A-Za-z]+$/, '');
|
||||
url = "https://i.4cdn.org/f/" + (encodeURIComponent(E(url))) + ".swf\n";
|
||||
}
|
||||
oldURL = this.flashURL || '';
|
||||
if (url !== oldURL) {
|
||||
com = this.com || '';
|
||||
if (com.slice(0, oldURL.length) === oldURL) {
|
||||
this.setComment(url + com.slice(oldURL.length));
|
||||
}
|
||||
return this.flashURL = url;
|
||||
}
|
||||
};
|
||||
|
||||
_Class.prototype.pasteText = function(file) {
|
||||
var reader;
|
||||
this.pasting = true;
|
||||
@ -13251,12 +13245,28 @@
|
||||
}
|
||||
};
|
||||
|
||||
PruneReplies = {
|
||||
ReplyPruning = {
|
||||
init: function() {
|
||||
var el, label;
|
||||
if (!(g.VIEW === 'thread' && !Conf['Quote Threading'])) {
|
||||
if (!(g.VIEW === 'thread' && Conf['Reply Pruning'])) {
|
||||
return;
|
||||
}
|
||||
if (Conf['Quote Threading'] && Conf['Thread Quotes'] && Conf['Prune Replies']) {
|
||||
Conf['Prune Replies'] = false;
|
||||
$.set('Prune Replies', false);
|
||||
}
|
||||
this.container = $.frag();
|
||||
this.summary = $.el('span', {
|
||||
hidden: true,
|
||||
className: 'summary',
|
||||
style: 'cursor: pointer;'
|
||||
});
|
||||
$.on(this.summary, 'click', (function(_this) {
|
||||
return function() {
|
||||
_this.inputs.enabled.checked = !_this.inputs.enabled.checked;
|
||||
return $.event('change', null, _this.inputs.enabled);
|
||||
};
|
||||
})(this));
|
||||
label = UI.checkbox('Prune Replies', 'Show Last');
|
||||
el = $.el('span', {
|
||||
title: 'Maximum number of replies to show.'
|
||||
@ -13268,68 +13278,94 @@
|
||||
enabled: label.firstElementChild,
|
||||
replies: el.lastElementChild
|
||||
};
|
||||
$.on(this.inputs.enabled, 'change', $.cb.checked);
|
||||
$.on(this.inputs.enabled, 'change', this.setEnabled);
|
||||
$.on(this.inputs.replies, 'change', $.cb.value);
|
||||
Header.menu.addEntry({
|
||||
el: el,
|
||||
order: 190
|
||||
});
|
||||
return Thread.callbacks.push({
|
||||
name: 'Prune Replies',
|
||||
name: 'Reply Pruning',
|
||||
cb: this.node
|
||||
});
|
||||
},
|
||||
position: 0,
|
||||
hidden: 0,
|
||||
hiddenFiles: 0,
|
||||
total: 0,
|
||||
node: function() {
|
||||
PruneReplies.thread = this;
|
||||
PruneReplies.total = this.posts.keys.length - 1;
|
||||
$.on(PruneReplies.inputs.enabled, 'change', PruneReplies.setEnabled);
|
||||
$.on(PruneReplies.inputs.enabled, 'change', PruneReplies.update);
|
||||
if (Conf['Prune Replies']) {
|
||||
PruneReplies.setEnabled();
|
||||
return PruneReplies.update();
|
||||
}
|
||||
},
|
||||
totalFiles: 0,
|
||||
setEnabled: function() {
|
||||
var onOff;
|
||||
PruneReplies.container || (PruneReplies.container = $.frag());
|
||||
onOff = Conf['Prune Replies'] ? $.on : $.off;
|
||||
onOff(PruneReplies.inputs.replies, 'change', PruneReplies.update);
|
||||
return onOff(d, 'ThreadUpdate', PruneReplies.update);
|
||||
},
|
||||
update: function(e) {
|
||||
var OP, frag, hidden2, post, posts, ref, results;
|
||||
if (e && e.type === 'ThreadUpdate' && !e.detail[404]) {
|
||||
PruneReplies.total += e.detail.newPosts.length;
|
||||
var other;
|
||||
other = QuoteThreading.input;
|
||||
if (this.checked && (other != null ? other.checked : void 0)) {
|
||||
other.checked = false;
|
||||
$.event('change', null, other);
|
||||
}
|
||||
hidden2 = Conf['Prune Replies'] ? Math.max(PruneReplies.total - +Conf["Max Replies"], 0) : 0;
|
||||
ref = PruneReplies.thread, posts = ref.posts, OP = ref.OP;
|
||||
if (PruneReplies.hidden < hidden2) {
|
||||
results = [];
|
||||
while (PruneReplies.hidden < hidden2 && PruneReplies.position < posts.keys.length) {
|
||||
post = posts[posts.keys[PruneReplies.position++]];
|
||||
if (post.isReply && !post.isFetchedQuote) {
|
||||
$.add(PruneReplies.container, post.nodes.root);
|
||||
results.push(PruneReplies.hidden++);
|
||||
} else {
|
||||
results.push(void 0);
|
||||
return $.cb.checked.call(this);
|
||||
},
|
||||
node: function() {
|
||||
ReplyPruning.thread = this;
|
||||
this.posts.forEach(function(post) {
|
||||
if (post.isReply) {
|
||||
ReplyPruning.total++;
|
||||
if (post.file) {
|
||||
return ReplyPruning.totalFiles++;
|
||||
}
|
||||
}
|
||||
return results;
|
||||
} else if (PruneReplies.hidden > hidden2) {
|
||||
});
|
||||
$.after(this.OP.nodes.root, ReplyPruning.summary);
|
||||
$.on(ReplyPruning.inputs.enabled, 'change', ReplyPruning.update);
|
||||
$.on(ReplyPruning.inputs.replies, 'change', ReplyPruning.update);
|
||||
$.on(d, 'ThreadUpdate', ReplyPruning.updateCount);
|
||||
$.on(d, 'ThreadUpdate', ReplyPruning.update);
|
||||
return ReplyPruning.update();
|
||||
},
|
||||
updateCount: function(e) {
|
||||
var fullID, k, len1, ref;
|
||||
if (e.detail[404]) {
|
||||
return;
|
||||
}
|
||||
ref = e.detail.newPosts;
|
||||
for (k = 0, len1 = ref.length; k < len1; k++) {
|
||||
fullID = ref[k];
|
||||
ReplyPruning.total++;
|
||||
if (g.posts[fullID].file) {
|
||||
ReplyPruning.totalFiles++;
|
||||
}
|
||||
}
|
||||
},
|
||||
update: function() {
|
||||
var frag, hidden2, post, posts;
|
||||
hidden2 = Conf['Prune Replies'] ? Math.max(ReplyPruning.total - +Conf["Max Replies"], 0) : 0;
|
||||
posts = ReplyPruning.thread.posts;
|
||||
if (ReplyPruning.hidden < hidden2) {
|
||||
while (ReplyPruning.hidden < hidden2 && ReplyPruning.position < posts.keys.length) {
|
||||
post = posts[posts.keys[ReplyPruning.position++]];
|
||||
if (post.isReply && !post.isFetchedQuote) {
|
||||
$.add(ReplyPruning.container, post.nodes.root);
|
||||
ReplyPruning.hidden++;
|
||||
if (post.file) {
|
||||
ReplyPruning.hiddenFiles++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ReplyPruning.hidden > hidden2) {
|
||||
frag = $.frag();
|
||||
while (PruneReplies.hidden > hidden2 && PruneReplies.position > 0) {
|
||||
post = posts[posts.keys[--PruneReplies.position]];
|
||||
while (ReplyPruning.hidden > hidden2 && ReplyPruning.position > 0) {
|
||||
post = posts[posts.keys[--ReplyPruning.position]];
|
||||
if (post.isReply && !post.isFetchedQuote) {
|
||||
$.prepend(frag, post.nodes.root);
|
||||
PruneReplies.hidden--;
|
||||
ReplyPruning.hidden--;
|
||||
if (post.file) {
|
||||
ReplyPruning.hiddenFiles--;
|
||||
}
|
||||
}
|
||||
}
|
||||
$.after(OP.nodes.root, frag);
|
||||
return $.event('PostsInserted');
|
||||
$.after(ReplyPruning.summary, frag);
|
||||
$.event('PostsInserted');
|
||||
}
|
||||
ReplyPruning.summary.textContent = Conf['Prune Replies'] ? Build.summaryText('+', ReplyPruning.hidden, ReplyPruning.hiddenFiles) : Build.summaryText('-', ReplyPruning.total, ReplyPruning.totalFiles);
|
||||
return ReplyPruning.summary.hidden = ReplyPruning.total <= +Conf["Max Replies"];
|
||||
}
|
||||
};
|
||||
|
||||
@ -13601,10 +13637,7 @@
|
||||
}));
|
||||
$.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost);
|
||||
$.on(d, 'visibilitychange', ThreadUpdater.cb.visibility);
|
||||
ThreadUpdater.setInterval();
|
||||
if (this.board.ID === 'f') {
|
||||
return ThreadUpdater.update();
|
||||
}
|
||||
return ThreadUpdater.setInterval();
|
||||
},
|
||||
|
||||
/*
|
||||
@ -13832,12 +13865,6 @@
|
||||
if (postObject.fsize) {
|
||||
files.push(ID);
|
||||
}
|
||||
if (board.ID === 'f' && postObject.fsize && (post = thread.posts[ID]) && !post.file) {
|
||||
node = Build.postFromObject(postObject, board.ID);
|
||||
$.after(post.nodes.info, $('.file', node));
|
||||
post.parseFile();
|
||||
Post.callbacks.execute(post, ['Filter', 'File Info Formatting', 'Fappe Tyme', 'Sauce']);
|
||||
}
|
||||
if (ID <= lastPost) {
|
||||
continue;
|
||||
}
|
||||
@ -15497,7 +15524,7 @@
|
||||
}
|
||||
},
|
||||
initBoardList: function() {
|
||||
if (!Conf['Catalog Links']) {
|
||||
if (!CatalogLinks.el) {
|
||||
return;
|
||||
}
|
||||
return CatalogLinks.set(Conf['Header catalog links']);
|
||||
@ -15703,7 +15730,7 @@
|
||||
if (!(a = $.x('following-sibling::*[contains(@class,"summary")][1]', thread.OP.nodes.root))) {
|
||||
return;
|
||||
}
|
||||
a.textContent = ExpandThread.text.apply(ExpandThread, ['+'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
a.textContent = Build.summaryText.apply(Build, ['+'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
a.style.cursor = 'pointer';
|
||||
return $.on(a, 'click', ExpandThread.cbToggle);
|
||||
},
|
||||
@ -15730,9 +15757,6 @@
|
||||
return ExpandThread.setButton(thread);
|
||||
});
|
||||
},
|
||||
text: function(status, posts, files) {
|
||||
return (status + " " + posts + " post" + (posts > 1 ? 's' : '')) + (+files ? " and " + files + " image repl" + (files > 1 ? 'ies' : 'y') : "") + (" " + (status === '-' ? 'shown' : 'omitted') + ".");
|
||||
},
|
||||
cbToggle: function(e) {
|
||||
if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) {
|
||||
return;
|
||||
@ -15755,7 +15779,7 @@
|
||||
expand: function(thread, a) {
|
||||
var status;
|
||||
ExpandThread.statuses[thread] = status = {};
|
||||
a.textContent = ExpandThread.text.apply(ExpandThread, ['...'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
a.textContent = Build.summaryText.apply(Build, ['...'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
return status.req = $.cache("//a.4cdn.org/" + thread.board + "/thread/" + thread + ".json", function() {
|
||||
delete status.req;
|
||||
return ExpandThread.parse(this, thread, a);
|
||||
@ -15768,7 +15792,7 @@
|
||||
if (status.req) {
|
||||
status.req.abort();
|
||||
if (a) {
|
||||
a.textContent = ExpandThread.text.apply(ExpandThread, ['+'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
a.textContent = Build.summaryText.apply(Build, ['+'].concat(slice.call(a.textContent.match(/\d+/g))));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -15806,7 +15830,7 @@
|
||||
}
|
||||
$.rm(reply);
|
||||
}
|
||||
return a.textContent = ExpandThread.text('+', postsCount, filesCount);
|
||||
return a.textContent = Build.summaryText('+', postsCount, filesCount);
|
||||
},
|
||||
parse: function(req, thread, a) {
|
||||
var filesCount, k, len1, post, postData, posts, postsCount, postsRoot, ref, ref1, root;
|
||||
@ -15843,7 +15867,7 @@
|
||||
$.after(a, postsRoot);
|
||||
$.event('PostsInserted');
|
||||
postsCount = postsRoot.length;
|
||||
return a.textContent = ExpandThread.text('-', postsCount, filesCount);
|
||||
return a.textContent = Build.summaryText('-', postsCount, filesCount);
|
||||
}
|
||||
};
|
||||
|
||||
@ -17704,6 +17728,11 @@
|
||||
set('Inline Cross-thread Quotes Only', true);
|
||||
}
|
||||
}
|
||||
if (compareString < '00001.00011.00030.00000') {
|
||||
if (data['Quote Threading'] && (data['Thread Quotes'] == null)) {
|
||||
set('Thread Quotes', true);
|
||||
}
|
||||
}
|
||||
return changes;
|
||||
},
|
||||
loadSettings: function(data, cb) {
|
||||
@ -18291,6 +18320,16 @@
|
||||
return $.addClass(doc, 'ads-loaded');
|
||||
});
|
||||
});
|
||||
if (Conf['Autohiding Scrollbar']) {
|
||||
$.addClass(doc, 'autohiding-scrollbar');
|
||||
}
|
||||
$.ready(function() {
|
||||
if (d.body.clientHeight > doc.clientHeight && (window.innerWidth === doc.clientWidth) !== Conf['Autohiding Scrollbar']) {
|
||||
Conf['Autohiding Scrollbar'] = !Conf['Autohiding Scrollbar'];
|
||||
$.set('Autohiding Scrollbar', Conf['Autohiding Scrollbar']);
|
||||
return $.toggleClass(doc, 'autohiding-scrollbar');
|
||||
}
|
||||
});
|
||||
$.addStyle(Main.css, 'fourchanx-css');
|
||||
Main.bgColorStyle = $.el('style', {
|
||||
id: 'fourchanx-bgcolor-css'
|
||||
@ -19518,6 +19557,9 @@
|
||||
"#shortcuts {\n" +
|
||||
" float: right;\n" +
|
||||
"}\n" +
|
||||
":root.autohiding-scrollbar #shortcuts {\n" +
|
||||
" margin-right: 12px;\n" +
|
||||
"}\n" +
|
||||
".shortcut {\n" +
|
||||
" margin-left: 3px;\n" +
|
||||
" vertical-align: middle;\n" +
|
||||
@ -21878,7 +21920,7 @@
|
||||
cssWWW: "#captcha-cnt {\n" +
|
||||
" height: auto;\n" +
|
||||
"}",
|
||||
features: [['Polyfill', Polyfill], ['Normalize URL', NormalizeURL], ['Captcha Configuration', Captcha.replace], ['Redirect', Redirect], ['Header', Header], ['Catalog Links', CatalogLinks], ['Settings', Settings], ['Index Generator', Index], ['Disable Autoplay', AntiAutoplay], ['Announcement Hiding', PSAHiding], ['Fourchan thingies', Fourchan], ['Color User IDs', IDColor], ['Highlight by User ID', IDHighlight], ['Custom CSS', CustomCSS], ['Thread Links', ThreadLinks], ['Linkify', Linkify], ['Reveal Spoilers', RemoveSpoilers], ['Resurrect Quotes', Quotify], ['Filter', Filter], ['Thread Hiding Buttons', ThreadHiding], ['Reply Hiding Buttons', PostHiding], ['Recursive', Recursive], ['Strike-through Quotes', QuoteStrikeThrough], ['Quick Reply', QR], ['Cooldown', QR.cooldown], ['Pass Link', PassLink], ['Menu', Menu], ['Index Generator (Menu)', Index.menu], ['Report Link', ReportLink], ['Thread Hiding (Menu)', ThreadHiding.menu], ['Reply Hiding (Menu)', PostHiding.menu], ['Delete Link', DeleteLink], ['Filter (Menu)', Filter.menu], ['Edit Link', QR.oekaki.menu], ['Download Link', DownloadLink], ['Archive Link', ArchiveLink], ['Quote Inlining', QuoteInline], ['Quote Previewing', QuotePreview], ['Quote Backlinks', QuoteBacklink], ['Mark Quotes of You', QuoteYou], ['Mark OP Quotes', QuoteOP], ['Mark Cross-thread Quotes', QuoteCT], ['Anonymize', Anonymize], ['Time Formatting', Time], ['Relative Post Dates', RelativeDates], ['File Info Formatting', FileInfo], ['Fappe Tyme', FappeTyme], ['Gallery', Gallery], ['Gallery (menu)', Gallery.menu], ['Sauce', Sauce], ['Image Expansion', ImageExpand], ['Image Expansion (Menu)', ImageExpand.menu], ['Reveal Spoiler Thumbnails', RevealSpoilers], ['Image Loading', ImageLoader], ['Image Hover', ImageHover], ['Volume Control', Volume], ['WEBM Metadata', Metadata], ['Comment Expansion', ExpandComment], ['Thread Expansion', ExpandThread], ['Thread Excerpt', ThreadExcerpt], ['Favicon', Favicon], ['Unread', Unread], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats], ['Thread Updater', ThreadUpdater], ['Thread Watcher', ThreadWatcher], ['Thread Watcher (Menu)', ThreadWatcher.menu], ['Mark New IPs', MarkNewIPs], ['Index Navigation', Nav], ['Keybinds', Keybinds], ['Banner', Banner], ['Flash Features', Flash], ['Prune Replies', PruneReplies]]
|
||||
features: [['Polyfill', Polyfill], ['Normalize URL', NormalizeURL], ['Captcha Configuration', Captcha.replace], ['Redirect', Redirect], ['Header', Header], ['Catalog Links', CatalogLinks], ['Settings', Settings], ['Index Generator', Index], ['Disable Autoplay', AntiAutoplay], ['Announcement Hiding', PSAHiding], ['Fourchan thingies', Fourchan], ['Color User IDs', IDColor], ['Highlight by User ID', IDHighlight], ['Custom CSS', CustomCSS], ['Thread Links', ThreadLinks], ['Linkify', Linkify], ['Reveal Spoilers', RemoveSpoilers], ['Resurrect Quotes', Quotify], ['Filter', Filter], ['Thread Hiding Buttons', ThreadHiding], ['Reply Hiding Buttons', PostHiding], ['Recursive', Recursive], ['Strike-through Quotes', QuoteStrikeThrough], ['Quick Reply', QR], ['Cooldown', QR.cooldown], ['Pass Link', PassLink], ['Menu', Menu], ['Index Generator (Menu)', Index.menu], ['Report Link', ReportLink], ['Thread Hiding (Menu)', ThreadHiding.menu], ['Reply Hiding (Menu)', PostHiding.menu], ['Delete Link', DeleteLink], ['Filter (Menu)', Filter.menu], ['Edit Link', QR.oekaki.menu], ['Download Link', DownloadLink], ['Archive Link', ArchiveLink], ['Quote Inlining', QuoteInline], ['Quote Previewing', QuotePreview], ['Quote Backlinks', QuoteBacklink], ['Mark Quotes of You', QuoteYou], ['Mark OP Quotes', QuoteOP], ['Mark Cross-thread Quotes', QuoteCT], ['Anonymize', Anonymize], ['Time Formatting', Time], ['Relative Post Dates', RelativeDates], ['File Info Formatting', FileInfo], ['Fappe Tyme', FappeTyme], ['Gallery', Gallery], ['Gallery (menu)', Gallery.menu], ['Sauce', Sauce], ['Image Expansion', ImageExpand], ['Image Expansion (Menu)', ImageExpand.menu], ['Reveal Spoiler Thumbnails', RevealSpoilers], ['Image Loading', ImageLoader], ['Image Hover', ImageHover], ['Volume Control', Volume], ['WEBM Metadata', Metadata], ['Comment Expansion', ExpandComment], ['Thread Expansion', ExpandThread], ['Thread Excerpt', ThreadExcerpt], ['Favicon', Favicon], ['Unread', Unread], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats], ['Thread Updater', ThreadUpdater], ['Thread Watcher', ThreadWatcher], ['Thread Watcher (Menu)', ThreadWatcher.menu], ['Mark New IPs', MarkNewIPs], ['Index Navigation', Nav], ['Keybinds', Keybinds], ['Banner', Banner], ['Flash Features', Flash], ['Reply Pruning', ReplyPruning]]
|
||||
};
|
||||
|
||||
Main.init();
|
||||
|
||||
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://www.4chan-x.net/builds/4chan-X-beta.crx' version='1.11.29.6' />
|
||||
<updatecheck codebase='https://www.4chan-x.net/builds/4chan-X-beta.crx' version='1.11.30.0' />
|
||||
</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://www.4chan-x.net/builds/4chan-X.crx' version='1.11.29.6' />
|
||||
<updatecheck codebase='https://www.4chan-x.net/builds/4chan-X.crx' version='1.11.30.0' />
|
||||
</app>
|
||||
</gupdate>
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
{
|
||||
"version": "1.11.29.6",
|
||||
"date": "2016-04-02T19:42:39.447Z"
|
||||
"version": "1.11.30.0",
|
||||
"date": "2016-04-04T00:26:46.773Z"
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user