Merge branch 'v3'
Conflicts: CHANGELOG.md LICENSE builds/4chan-X.meta.js builds/appchan-x.user.js builds/crx/manifest.json builds/crx/script.js latest.js package.json src/Menu/Menu.coffee
This commit is contained in:
commit
94dd0e555f
@ -1,5 +1,6 @@
|
|||||||
**seaweeedchan**:
|
**seaweeedchan**:
|
||||||
- Convert infinite scrolling into an Index Mode, rather than being forced
|
- Convert infinite scrolling into an Index Mode, rather than being forced
|
||||||
|
- Fix Menu errors on older Firefox versions, such as the ESR
|
||||||
|
|
||||||
**Zixaphir**:
|
**Zixaphir**:
|
||||||
- Fix an issue where changing the current archive would crash the redirect features.
|
- Fix an issue where changing the current archive would crash the redirect features.
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* appchan x - Version 2.8.0 - 2014-01-12
|
* appchan x - Version 2.8.0 - 2014-01-13
|
||||||
*
|
*
|
||||||
* 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
|
||||||
|
|||||||
21
builds/4chan-X.meta.js
Executable file
21
builds/4chan-X.meta.js
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
// ==UserScript==
|
||||||
|
// @name 4chan X
|
||||||
|
// @version 1.3.2
|
||||||
|
// @minGMVer 1.13
|
||||||
|
// @minFFVer 26
|
||||||
|
// @namespace 4chan-X
|
||||||
|
// @description Cross-browser userscript for maximum lurking on 4chan.
|
||||||
|
// @license MIT; https://github.com/seaweedchan/4chan-x/blob/master/LICENSE
|
||||||
|
// @match *://boards.4chan.org/*
|
||||||
|
// @match *://sys.4chan.org/*
|
||||||
|
// @match *://a.4cdn.org/*
|
||||||
|
// @match *://i.4cdn.org/*
|
||||||
|
// @grant GM_getValue
|
||||||
|
// @grant GM_setValue
|
||||||
|
// @grant GM_deleteValue
|
||||||
|
// @grant GM_openInTab
|
||||||
|
// @run-at document-start
|
||||||
|
// @updateURL https://github.com/seaweedchan/4chan-x/raw/stable/builds/4chan-X.meta.js
|
||||||
|
// @downloadURL https://github.com/seaweedchan/4chan-x/raw/stable/builds/4chan-X.user.js
|
||||||
|
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAgMAAAAqbBEUAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAHFJREFUKFOt0LENACEIBdBv4Qju4wgWanEj3D6OcIVMKaitYHEU/jwTCQj8W75kiVCSBvdQ5/AvfVHBin11BgdRq3ysBgfwBDRrj3MCIA+oAQaku/Q1cNctrAmyDl577tOThYt/Y1RBM4DgOHzM0HFTAyLukH/cmRnqAAAAAElFTkSuQmCC
|
||||||
|
// ==/UserScript==
|
||||||
@ -22,7 +22,7 @@
|
|||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* appchan x - Version 2.8.0 - 2014-01-12
|
* appchan x - Version 2.8.0 - 2014-01-13
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@ -117,15 +117,17 @@
|
|||||||
__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) {
|
Array.prototype.indexOf = function(val, i) {
|
||||||
var i;
|
var len;
|
||||||
i = this.length;
|
i || (i = 0);
|
||||||
while (i--) {
|
len = this.length;
|
||||||
|
while (i < len) {
|
||||||
if (this[i] === val) {
|
if (this[i] === val) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
return i;
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
__indexOf = [].indexOf;
|
__indexOf = [].indexOf;
|
||||||
@ -4576,7 +4578,7 @@
|
|||||||
});
|
});
|
||||||
this.navLinks = $.el('div', {
|
this.navLinks = $.el('div', {
|
||||||
className: 'navLinks',
|
className: 'navLinks',
|
||||||
innerHTML: "<a href=.././ id=returnlink>Return</a> [<a href=javascript:; id=cataloglink>Catalog</a>] <a href=\"#bottom\" id=bottomlink>Bottom</a> <time id=\"index-last-refresh\" title=\"Last index refresh\">...</time> <input type=\"search\" id=\"index-search\" class=\"field\" placeholder=\"Search\"><a id=\"index-search-clear\" class=\"fa\" href=\"javascript:;\">\uf057</a>"
|
innerHTML: "<span class=brackets-wrap id=returnlink><a href=.././>Return</a></span> <span class=brackets-wrap id=cataloglink><a href=javascript:;>Catalog</a></span> <span class=brackets-wrap id=bottomlink><a href=\"#bottom\">Bottom</a></span> <span class=brackets-wrap id=\"index-last-refresh\"><time title=\"Last index refresh\">...</time></span> <input type=\"search\" id=\"index-search\" class=\"field\" placeholder=\"Search\"><a id=\"index-search-clear\" class=\"fa\" href=\"javascript:;\">\uf057</a>"
|
||||||
});
|
});
|
||||||
this.searchInput = $('#index-search', this.navLinks);
|
this.searchInput = $('#index-search', this.navLinks);
|
||||||
this.currentPage = this.getCurrentPage();
|
this.currentPage = this.getCurrentPage();
|
||||||
@ -4584,8 +4586,8 @@
|
|||||||
$.on(this.pagelist, 'click', this.cb.pageNav);
|
$.on(this.pagelist, 'click', this.cb.pageNav);
|
||||||
$.on(this.searchInput, 'input', this.onSearchInput);
|
$.on(this.searchInput, 'input', this.onSearchInput);
|
||||||
$.on($('#index-search-clear', this.navLinks), 'click', this.clearSearch);
|
$.on($('#index-search-clear', this.navLinks), 'click', this.clearSearch);
|
||||||
$.on($('#returnlink', this.navLinks), 'click', Navigate.navigate);
|
$.on($('#returnlink a', this.navLinks), 'click', Navigate.navigate);
|
||||||
$.on($('#cataloglink', this.navLinks), 'click', function() {
|
$.on($('#cataloglink a', this.navLinks), 'click', function() {
|
||||||
return window.location = "//boards.4chan.org/" + g.BOARD + "/catalog";
|
return window.location = "//boards.4chan.org/" + g.BOARD + "/catalog";
|
||||||
});
|
});
|
||||||
if (g.VIEW === 'index') {
|
if (g.VIEW === 'index') {
|
||||||
@ -4861,7 +4863,7 @@
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
timeEl = $('#index-last-refresh', Index.navLinks);
|
timeEl = $('#index-last-refresh time', Index.navLinks);
|
||||||
timeEl.dataset.utc = Date.parse(req.getResponseHeader('Last-Modified'));
|
timeEl.dataset.utc = Date.parse(req.getResponseHeader('Last-Modified'));
|
||||||
RelativeDates.update(timeEl);
|
RelativeDates.update(timeEl);
|
||||||
return Index.scrollToIndex();
|
return Index.scrollToIndex();
|
||||||
@ -5397,36 +5399,36 @@
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
allQuotelinksLinkingTo: function(post) {
|
allQuotelinksLinkingTo: function(post) {
|
||||||
var ID, quote, quotedPost, quotelinks, quoterPost, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4;
|
var ID, handleQuotes, quote, quotedPost, quotelinks, quoterPost, _i, _len, _ref, _ref1, _ref2;
|
||||||
quotelinks = [];
|
quotelinks = [];
|
||||||
|
handleQuotes = function(post, type) {
|
||||||
|
var clone, _i, _len, _ref;
|
||||||
|
quotelinks.push.apply(quotelinks, post.nodes[type]);
|
||||||
|
_ref = post.clones;
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
clone = _ref[_i];
|
||||||
|
quotelinks.push.apply(quotelinks, clone.nodes[type]);
|
||||||
|
}
|
||||||
|
};
|
||||||
_ref = g.posts;
|
_ref = g.posts;
|
||||||
for (ID in _ref) {
|
for (ID in _ref) {
|
||||||
quoterPost = _ref[ID];
|
quoterPost = _ref[ID];
|
||||||
if (_ref1 = post.fullID, __indexOf.call(quoterPost.quotes, _ref1) >= 0) {
|
if (_ref1 = post.fullID, __indexOf.call(quoterPost.quotes, _ref1) >= 0) {
|
||||||
_ref2 = [quoterPost].concat(quoterPost.clones);
|
handleQuotes(quoterPost, 'quotelinks');
|
||||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
|
||||||
quoterPost = _ref2[_i];
|
|
||||||
quotelinks.push.apply(quotelinks, quoterPost.nodes.quotelinks);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Conf['Quote Backlinks']) {
|
if (Conf['Quote Backlinks']) {
|
||||||
_ref3 = post.quotes;
|
_ref2 = post.quotes;
|
||||||
for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
|
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||||||
quote = _ref3[_j];
|
quote = _ref2[_i];
|
||||||
if (!(quotedPost = g.posts[quote])) {
|
if (quotedPost = g.posts[quote]) {
|
||||||
continue;
|
handleQuotes(quotedPost, 'backlinks');
|
||||||
}
|
|
||||||
_ref4 = [quotedPost].concat(quotedPost.clones);
|
|
||||||
for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
|
|
||||||
quotedPost = _ref4[_k];
|
|
||||||
quotelinks.push.apply(quotelinks, __slice.call(quotedPost.nodes.backlinks));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return quotelinks.filter(function(quotelink) {
|
return quotelinks.filter(function(quotelink) {
|
||||||
var boardID, postID, _ref5;
|
var boardID, postID, _ref3;
|
||||||
_ref5 = Get.postDataFromLink(quotelink), boardID = _ref5.boardID, postID = _ref5.postID;
|
_ref3 = Get.postDataFromLink(quotelink), boardID = _ref3.boardID, postID = _ref3.postID;
|
||||||
return boardID === post.board.ID && postID === post.ID;
|
return boardID === post.board.ID && postID === post.ID;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -7100,28 +7102,14 @@
|
|||||||
if (g.VIEW === 'catalog' || !Conf['Quote Inlining']) {
|
if (g.VIEW === 'catalog' || !Conf['Quote Inlining']) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Conf['Quote Hash Navigation']) {
|
this.process = Conf['Quote Hash Navigation'] ? function(link, clone) {
|
||||||
this.node = function() {
|
if (!clone) {
|
||||||
var link, _i, _len, _ref;
|
$.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
|
||||||
_ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks));
|
}
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
return $.on(link, 'click', QuoteInline.toggle);
|
||||||
link = _ref[_i];
|
} : function(link) {
|
||||||
if (!this.isClone) {
|
return $.on(link, 'click', QuoteInline.toggle);
|
||||||
$.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
|
};
|
||||||
}
|
|
||||||
$.on(link, 'click', QuoteInline.toggle);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
this.node = function() {
|
|
||||||
var link, _i, _len, _ref;
|
|
||||||
_ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks));
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
link = _ref[_i];
|
|
||||||
$.on(link, 'click', QuoteInline.toggle);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (Conf['Comment Expansion']) {
|
if (Conf['Comment Expansion']) {
|
||||||
ExpandComment.callbacks.push(this.node);
|
ExpandComment.callbacks.push(this.node);
|
||||||
}
|
}
|
||||||
@ -7130,14 +7118,27 @@
|
|||||||
cb: this.node
|
cb: this.node
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
node: function() {
|
||||||
|
var isClone, link, process, _i, _j, _len, _len1, _ref, _ref1;
|
||||||
|
process = QuoteInline.process;
|
||||||
|
isClone = this.isClone;
|
||||||
|
_ref = this.nodes.quotelinks;
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
link = _ref[_i];
|
||||||
|
process(link, isClone);
|
||||||
|
}
|
||||||
|
_ref1 = this.nodes.backlinks;
|
||||||
|
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||||
|
link = _ref1[_j];
|
||||||
|
process(link, isClone);
|
||||||
|
}
|
||||||
|
},
|
||||||
qiQuote: function(link, hidden) {
|
qiQuote: function(link, hidden) {
|
||||||
return [
|
return $.el('a', {
|
||||||
$.tn(' '), $.el('a', {
|
className: "hashlink" + (hidden ? ' filtered' : ''),
|
||||||
className: hidden ? 'hashlink filtered' : 'hashlink',
|
textContent: '#',
|
||||||
textContent: '#',
|
href: link.href
|
||||||
href: link.href
|
});
|
||||||
})
|
|
||||||
];
|
|
||||||
},
|
},
|
||||||
toggle: function(e) {
|
toggle: function(e) {
|
||||||
var boardID, context, postID, threadID, _ref;
|
var boardID, context, postID, threadID, _ref;
|
||||||
@ -10905,21 +10906,16 @@
|
|||||||
return $.add(this.nodes.info, Menu.makeButton());
|
return $.add(this.nodes.info, Menu.makeButton());
|
||||||
},
|
},
|
||||||
makeButton: (function() {
|
makeButton: (function() {
|
||||||
var frag;
|
var a;
|
||||||
frag = null;
|
a = $.el('a', {
|
||||||
|
className: 'menu-button',
|
||||||
|
innerHTML: '<i class=fa>\uf107</i>',
|
||||||
|
href: 'javascript:;'
|
||||||
|
});
|
||||||
return function() {
|
return function() {
|
||||||
var clone;
|
var clone;
|
||||||
if (frag == null) {
|
clone = a.cloneNode(true);
|
||||||
frag = $.nodes([
|
$.on(clone, 'click', Menu.toggle);
|
||||||
$.tn(' '), $.el('a', {
|
|
||||||
className: 'menu-button',
|
|
||||||
innerHTML: '<i class=fa>\uf107</i>',
|
|
||||||
href: 'javascript:;'
|
|
||||||
})
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
clone = frag.cloneNode(true);
|
|
||||||
$.on(clone.lastElementChild, 'click', Menu.toggle);
|
|
||||||
return clone;
|
return clone;
|
||||||
};
|
};
|
||||||
})(),
|
})(),
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Generated by CoffeeScript
|
// Generated by CoffeeScript
|
||||||
/*
|
/*
|
||||||
* appchan x - Version 2.8.0 - 2014-01-12
|
* appchan x - Version 2.8.0 - 2014-01-13
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@ -95,15 +95,17 @@
|
|||||||
__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) {
|
Array.prototype.indexOf = function(val, i) {
|
||||||
var i;
|
var len;
|
||||||
i = this.length;
|
i || (i = 0);
|
||||||
while (i--) {
|
len = this.length;
|
||||||
|
while (i < len) {
|
||||||
if (this[i] === val) {
|
if (this[i] === val) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
return i;
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
__indexOf = [].indexOf;
|
__indexOf = [].indexOf;
|
||||||
@ -4587,7 +4589,7 @@
|
|||||||
});
|
});
|
||||||
this.navLinks = $.el('div', {
|
this.navLinks = $.el('div', {
|
||||||
className: 'navLinks',
|
className: 'navLinks',
|
||||||
innerHTML: "<a href=.././ id=returnlink>Return</a> [<a href=javascript:; id=cataloglink>Catalog</a>] <a href=\"#bottom\" id=bottomlink>Bottom</a> <time id=\"index-last-refresh\" title=\"Last index refresh\">...</time> <input type=\"search\" id=\"index-search\" class=\"field\" placeholder=\"Search\"><a id=\"index-search-clear\" class=\"fa\" href=\"javascript:;\">\uf057</a>"
|
innerHTML: "<span class=brackets-wrap id=returnlink><a href=.././>Return</a></span> <span class=brackets-wrap id=cataloglink><a href=javascript:;>Catalog</a></span> <span class=brackets-wrap id=bottomlink><a href=\"#bottom\">Bottom</a></span> <span class=brackets-wrap id=\"index-last-refresh\"><time title=\"Last index refresh\">...</time></span> <input type=\"search\" id=\"index-search\" class=\"field\" placeholder=\"Search\"><a id=\"index-search-clear\" class=\"fa\" href=\"javascript:;\">\uf057</a>"
|
||||||
});
|
});
|
||||||
this.searchInput = $('#index-search', this.navLinks);
|
this.searchInput = $('#index-search', this.navLinks);
|
||||||
this.currentPage = this.getCurrentPage();
|
this.currentPage = this.getCurrentPage();
|
||||||
@ -4595,8 +4597,8 @@
|
|||||||
$.on(this.pagelist, 'click', this.cb.pageNav);
|
$.on(this.pagelist, 'click', this.cb.pageNav);
|
||||||
$.on(this.searchInput, 'input', this.onSearchInput);
|
$.on(this.searchInput, 'input', this.onSearchInput);
|
||||||
$.on($('#index-search-clear', this.navLinks), 'click', this.clearSearch);
|
$.on($('#index-search-clear', this.navLinks), 'click', this.clearSearch);
|
||||||
$.on($('#returnlink', this.navLinks), 'click', Navigate.navigate);
|
$.on($('#returnlink a', this.navLinks), 'click', Navigate.navigate);
|
||||||
$.on($('#cataloglink', this.navLinks), 'click', function() {
|
$.on($('#cataloglink a', this.navLinks), 'click', function() {
|
||||||
return window.location = "//boards.4chan.org/" + g.BOARD + "/catalog";
|
return window.location = "//boards.4chan.org/" + g.BOARD + "/catalog";
|
||||||
});
|
});
|
||||||
if (g.VIEW === 'index') {
|
if (g.VIEW === 'index') {
|
||||||
@ -4872,7 +4874,7 @@
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
timeEl = $('#index-last-refresh', Index.navLinks);
|
timeEl = $('#index-last-refresh time', Index.navLinks);
|
||||||
timeEl.dataset.utc = Date.parse(req.getResponseHeader('Last-Modified'));
|
timeEl.dataset.utc = Date.parse(req.getResponseHeader('Last-Modified'));
|
||||||
RelativeDates.update(timeEl);
|
RelativeDates.update(timeEl);
|
||||||
return Index.scrollToIndex();
|
return Index.scrollToIndex();
|
||||||
@ -5408,36 +5410,36 @@
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
allQuotelinksLinkingTo: function(post) {
|
allQuotelinksLinkingTo: function(post) {
|
||||||
var ID, quote, quotedPost, quotelinks, quoterPost, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4;
|
var ID, handleQuotes, quote, quotedPost, quotelinks, quoterPost, _i, _len, _ref, _ref1, _ref2;
|
||||||
quotelinks = [];
|
quotelinks = [];
|
||||||
|
handleQuotes = function(post, type) {
|
||||||
|
var clone, _i, _len, _ref;
|
||||||
|
quotelinks.push.apply(quotelinks, post.nodes[type]);
|
||||||
|
_ref = post.clones;
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
clone = _ref[_i];
|
||||||
|
quotelinks.push.apply(quotelinks, clone.nodes[type]);
|
||||||
|
}
|
||||||
|
};
|
||||||
_ref = g.posts;
|
_ref = g.posts;
|
||||||
for (ID in _ref) {
|
for (ID in _ref) {
|
||||||
quoterPost = _ref[ID];
|
quoterPost = _ref[ID];
|
||||||
if (_ref1 = post.fullID, __indexOf.call(quoterPost.quotes, _ref1) >= 0) {
|
if (_ref1 = post.fullID, __indexOf.call(quoterPost.quotes, _ref1) >= 0) {
|
||||||
_ref2 = [quoterPost].concat(quoterPost.clones);
|
handleQuotes(quoterPost, 'quotelinks');
|
||||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
|
||||||
quoterPost = _ref2[_i];
|
|
||||||
quotelinks.push.apply(quotelinks, quoterPost.nodes.quotelinks);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Conf['Quote Backlinks']) {
|
if (Conf['Quote Backlinks']) {
|
||||||
_ref3 = post.quotes;
|
_ref2 = post.quotes;
|
||||||
for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
|
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||||||
quote = _ref3[_j];
|
quote = _ref2[_i];
|
||||||
if (!(quotedPost = g.posts[quote])) {
|
if (quotedPost = g.posts[quote]) {
|
||||||
continue;
|
handleQuotes(quotedPost, 'backlinks');
|
||||||
}
|
|
||||||
_ref4 = [quotedPost].concat(quotedPost.clones);
|
|
||||||
for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
|
|
||||||
quotedPost = _ref4[_k];
|
|
||||||
quotelinks.push.apply(quotelinks, __slice.call(quotedPost.nodes.backlinks));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return quotelinks.filter(function(quotelink) {
|
return quotelinks.filter(function(quotelink) {
|
||||||
var boardID, postID, _ref5;
|
var boardID, postID, _ref3;
|
||||||
_ref5 = Get.postDataFromLink(quotelink), boardID = _ref5.boardID, postID = _ref5.postID;
|
_ref3 = Get.postDataFromLink(quotelink), boardID = _ref3.boardID, postID = _ref3.postID;
|
||||||
return boardID === post.board.ID && postID === post.ID;
|
return boardID === post.board.ID && postID === post.ID;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -7104,28 +7106,14 @@
|
|||||||
if (g.VIEW === 'catalog' || !Conf['Quote Inlining']) {
|
if (g.VIEW === 'catalog' || !Conf['Quote Inlining']) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Conf['Quote Hash Navigation']) {
|
this.process = Conf['Quote Hash Navigation'] ? function(link, clone) {
|
||||||
this.node = function() {
|
if (!clone) {
|
||||||
var link, _i, _len, _ref;
|
$.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
|
||||||
_ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks));
|
}
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
return $.on(link, 'click', QuoteInline.toggle);
|
||||||
link = _ref[_i];
|
} : function(link) {
|
||||||
if (!this.isClone) {
|
return $.on(link, 'click', QuoteInline.toggle);
|
||||||
$.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
|
};
|
||||||
}
|
|
||||||
$.on(link, 'click', QuoteInline.toggle);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
this.node = function() {
|
|
||||||
var link, _i, _len, _ref;
|
|
||||||
_ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks));
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
link = _ref[_i];
|
|
||||||
$.on(link, 'click', QuoteInline.toggle);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (Conf['Comment Expansion']) {
|
if (Conf['Comment Expansion']) {
|
||||||
ExpandComment.callbacks.push(this.node);
|
ExpandComment.callbacks.push(this.node);
|
||||||
}
|
}
|
||||||
@ -7134,14 +7122,27 @@
|
|||||||
cb: this.node
|
cb: this.node
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
node: function() {
|
||||||
|
var isClone, link, process, _i, _j, _len, _len1, _ref, _ref1;
|
||||||
|
process = QuoteInline.process;
|
||||||
|
isClone = this.isClone;
|
||||||
|
_ref = this.nodes.quotelinks;
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
link = _ref[_i];
|
||||||
|
process(link, isClone);
|
||||||
|
}
|
||||||
|
_ref1 = this.nodes.backlinks;
|
||||||
|
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||||
|
link = _ref1[_j];
|
||||||
|
process(link, isClone);
|
||||||
|
}
|
||||||
|
},
|
||||||
qiQuote: function(link, hidden) {
|
qiQuote: function(link, hidden) {
|
||||||
return [
|
return $.el('a', {
|
||||||
$.tn(' '), $.el('a', {
|
className: "hashlink" + (hidden ? ' filtered' : ''),
|
||||||
className: hidden ? 'hashlink filtered' : 'hashlink',
|
textContent: '#',
|
||||||
textContent: '#',
|
href: link.href
|
||||||
href: link.href
|
});
|
||||||
})
|
|
||||||
];
|
|
||||||
},
|
},
|
||||||
toggle: function(e) {
|
toggle: function(e) {
|
||||||
var boardID, context, postID, threadID, _ref;
|
var boardID, context, postID, threadID, _ref;
|
||||||
@ -10889,21 +10890,16 @@
|
|||||||
return $.add(this.nodes.info, Menu.makeButton());
|
return $.add(this.nodes.info, Menu.makeButton());
|
||||||
},
|
},
|
||||||
makeButton: (function() {
|
makeButton: (function() {
|
||||||
var frag;
|
var a;
|
||||||
frag = null;
|
a = $.el('a', {
|
||||||
|
className: 'menu-button',
|
||||||
|
innerHTML: '<i class=fa>\uf107</i>',
|
||||||
|
href: 'javascript:;'
|
||||||
|
});
|
||||||
return function() {
|
return function() {
|
||||||
var clone;
|
var clone;
|
||||||
if (frag == null) {
|
clone = a.cloneNode(true);
|
||||||
frag = $.nodes([
|
$.on(clone, 'click', Menu.toggle);
|
||||||
$.tn(' '), $.el('a', {
|
|
||||||
className: 'menu-button',
|
|
||||||
innerHTML: '<i class=fa>\uf107</i>',
|
|
||||||
href: 'javascript:;'
|
|
||||||
})
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
clone = frag.cloneNode(true);
|
|
||||||
$.on(clone.lastElementChild, 'click', Menu.toggle);
|
|
||||||
return clone;
|
return clone;
|
||||||
};
|
};
|
||||||
})(),
|
})(),
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
# I am bad at JavaScript and if you reuse this, so are you.
|
# I am bad at JavaScript and if you reuse this, so are you.
|
||||||
Array::indexOf = (val) ->
|
Array::indexOf = (val, i) ->
|
||||||
i = @length
|
i or= 0
|
||||||
while i--
|
len = @length
|
||||||
|
while i < len
|
||||||
return i if @[i] is val
|
return i if @[i] is val
|
||||||
return i
|
i++
|
||||||
|
return -1
|
||||||
|
|
||||||
# Update CoffeeScript's reference to [].indexOf
|
# Update CoffeeScript's reference to [].indexOf
|
||||||
# Reserved keywords are ignored in embedded javascript.
|
# Reserved keywords are ignored in embedded javascript.
|
||||||
|
|||||||
@ -40,24 +40,22 @@ Get =
|
|||||||
allQuotelinksLinkingTo: (post) ->
|
allQuotelinksLinkingTo: (post) ->
|
||||||
# Get quotelinks & backlinks linking to the given post.
|
# Get quotelinks & backlinks linking to the given post.
|
||||||
quotelinks = []
|
quotelinks = []
|
||||||
|
handleQuotes = (post, type) ->
|
||||||
|
quotelinks.push post.nodes[type]...
|
||||||
|
quotelinks.push clone.nodes[type]... for clone in post.clones
|
||||||
|
return
|
||||||
# First:
|
# First:
|
||||||
# In every posts,
|
# In every posts,
|
||||||
# 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
|
handleQuotes quoterPost, 'quotelinks' for ID, quoterPost of g.posts when post.fullID in quoterPost.quotes
|
||||||
if post.fullID in quoterPost.quotes
|
|
||||||
for quoterPost in [quoterPost].concat quoterPost.clones
|
|
||||||
quotelinks.push.apply quotelinks, quoterPost.nodes.quotelinks
|
|
||||||
# Second:
|
# Second:
|
||||||
# If we have quote backlinks:
|
# If we have quote backlinks:
|
||||||
# in all posts this post quoted
|
# in all posts this post quoted
|
||||||
# and their clones,
|
# and their clones,
|
||||||
# get all of their backlinks.
|
# get all of their backlinks.
|
||||||
if Conf['Quote Backlinks']
|
if Conf['Quote Backlinks']
|
||||||
for quote in post.quotes
|
handleQuotes quotedPost, 'backlinks' for quote in post.quotes when quotedPost = g.posts[quote]
|
||||||
continue unless quotedPost = g.posts[quote]
|
|
||||||
for quotedPost in [quotedPost].concat quotedPost.clones
|
|
||||||
quotelinks.push.apply quotelinks, [quotedPost.nodes.backlinks...]
|
|
||||||
# Third:
|
# Third:
|
||||||
# Filter out irrelevant quotelinks.
|
# Filter out irrelevant quotelinks.
|
||||||
quotelinks.filter (quotelink) ->
|
quotelinks.filter (quotelink) ->
|
||||||
|
|||||||
@ -83,9 +83,8 @@ Index =
|
|||||||
$.on @pagelist, 'click', @cb.pageNav
|
$.on @pagelist, 'click', @cb.pageNav
|
||||||
$.on @searchInput, 'input', @onSearchInput
|
$.on @searchInput, 'input', @onSearchInput
|
||||||
$.on $('#index-search-clear', @navLinks), 'click', @clearSearch
|
$.on $('#index-search-clear', @navLinks), 'click', @clearSearch
|
||||||
$.on $('#returnlink', @navLinks), 'click', Navigate.navigate
|
$.on $('#returnlink a', @navLinks), 'click', Navigate.navigate
|
||||||
$.on $('#cataloglink', @navLinks), 'click', -> window.location = "//boards.4chan.org/#{g.BOARD}/catalog"
|
$.on $('#cataloglink a', @navLinks), 'click', -> window.location = "//boards.4chan.org/#{g.BOARD}/catalog"
|
||||||
|
|
||||||
|
|
||||||
@update() if g.VIEW is 'index'
|
@update() if g.VIEW is 'index'
|
||||||
$.asap (-> $('.board', doc) or d.readyState isnt 'loading'), ->
|
$.asap (-> $('.board', doc) or d.readyState isnt 'loading'), ->
|
||||||
@ -287,7 +286,7 @@ Index =
|
|||||||
new Notice 'error', 'Index refresh failed.', 1
|
new Notice 'error', 'Index refresh failed.', 1
|
||||||
return
|
return
|
||||||
|
|
||||||
timeEl = $ '#index-last-refresh', Index.navLinks
|
timeEl = $ '#index-last-refresh time', Index.navLinks
|
||||||
timeEl.dataset.utc = Date.parse req.getResponseHeader 'Last-Modified'
|
timeEl.dataset.utc = Date.parse req.getResponseHeader 'Last-Modified'
|
||||||
RelativeDates.update timeEl
|
RelativeDates.update timeEl
|
||||||
Index.scrollToIndex()
|
Index.scrollToIndex()
|
||||||
|
|||||||
@ -90,6 +90,11 @@ div.navLinks {
|
|||||||
.reply > .file > .fileText {
|
.reply > .file > .fileText {
|
||||||
margin: 0 20px;
|
margin: 0 20px;
|
||||||
}
|
}
|
||||||
|
.hashlink::before {
|
||||||
|
content: ' ';
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.inline + .hashlink,
|
||||||
[hidden] {
|
[hidden] {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
@ -273,12 +278,12 @@ div.center:not(.ad-cnt) {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
/* 4chan X link brackets */
|
/* 4chan X link brackets */
|
||||||
.brackets-wrap::after {
|
|
||||||
content: "]";
|
|
||||||
}
|
|
||||||
.brackets-wrap::before {
|
.brackets-wrap::before {
|
||||||
content: "[";
|
content: "[";
|
||||||
}
|
}
|
||||||
|
.brackets-wrap::after {
|
||||||
|
content: "]";
|
||||||
|
}
|
||||||
/* Notifications */
|
/* Notifications */
|
||||||
#notifications {
|
#notifications {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -508,16 +513,6 @@ div.center:not(.ad-cnt) {
|
|||||||
.thread #index-search {
|
.thread #index-search {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#returnlink::before,
|
|
||||||
#bottomlink::before,
|
|
||||||
#index-last-refresh::before {
|
|
||||||
content: '[';
|
|
||||||
}
|
|
||||||
#returnlink::after,
|
|
||||||
#bottomlink::after,
|
|
||||||
#index-last-refresh::after {
|
|
||||||
content: ']';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Announcement Hiding */
|
/* Announcement Hiding */
|
||||||
:root.hide-announcement #globalMessage {
|
:root.hide-announcement #globalMessage {
|
||||||
@ -1115,7 +1110,7 @@ a:only-of-type > .remove {
|
|||||||
.reply .menu-button,
|
.reply .menu-button,
|
||||||
.op .menu-button,
|
.op .menu-button,
|
||||||
#thread-watcher .menu-button {
|
#thread-watcher .menu-button {
|
||||||
margin-left: -5px !important;
|
margin-left: -1px !important;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.op .menu-button,
|
.op .menu-button,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<a href=.././ id=returnlink>Return</a>
|
<span class=brackets-wrap id=returnlink><a href=.././>Return</a></span>
|
||||||
[<a href=javascript:; id=cataloglink>Catalog</a>]
|
<span class=brackets-wrap id=cataloglink><a href=javascript:;>Catalog</a></span>
|
||||||
<a href="#bottom" id=bottomlink>Bottom</a>
|
<span class=brackets-wrap id=bottomlink><a href="#bottom">Bottom</a></span>
|
||||||
<time id="index-last-refresh" title="Last index refresh">...</time>
|
<span class=brackets-wrap id="index-last-refresh"><time title="Last index refresh">...</time></span>
|
||||||
<input type="search" id="index-search" class="field" placeholder="Search">
|
<input type="search" id="index-search" class="field" placeholder="Search">
|
||||||
<a id="index-search-clear" class="fa" href="javascript:;">\uf057</a>
|
<a id="index-search-clear" class="fa" href="javascript:;">\uf057</a>
|
||||||
|
|||||||
@ -14,18 +14,13 @@ Menu =
|
|||||||
$.add @nodes.info, Menu.makeButton()
|
$.add @nodes.info, Menu.makeButton()
|
||||||
|
|
||||||
makeButton: do ->
|
makeButton: do ->
|
||||||
frag = null
|
a = $.el 'a',
|
||||||
|
className: 'menu-button'
|
||||||
|
innerHTML: '<i class=fa>\uf107</i>'
|
||||||
|
href: 'javascript:;'
|
||||||
->
|
->
|
||||||
unless frag?
|
clone = a.cloneNode true
|
||||||
frag = $.nodes [
|
$.on clone, 'click', Menu.toggle
|
||||||
$.tn(' ')
|
|
||||||
$.el 'a',
|
|
||||||
className: 'menu-button'
|
|
||||||
innerHTML: '<i class=fa>\uf107</i>'
|
|
||||||
href: 'javascript:;'
|
|
||||||
]
|
|
||||||
clone = frag.cloneNode true
|
|
||||||
$.on clone.lastElementChild, 'click', Menu.toggle
|
|
||||||
clone
|
clone
|
||||||
|
|
||||||
toggle: (e) ->
|
toggle: (e) ->
|
||||||
|
|||||||
@ -2,18 +2,14 @@ QuoteInline =
|
|||||||
init: ->
|
init: ->
|
||||||
return if g.VIEW is 'catalog' or !Conf['Quote Inlining']
|
return if g.VIEW is 'catalog' or !Conf['Quote Inlining']
|
||||||
|
|
||||||
if Conf['Quote Hash Navigation']
|
@process = if Conf['Quote Hash Navigation']
|
||||||
@node = ->
|
(link, clone) ->
|
||||||
for link in @nodes.quotelinks.concat [@nodes.backlinks...]
|
$.after link, QuoteInline.qiQuote link, $.hasClass link, 'filtered' unless clone
|
||||||
$.after link, QuoteInline.qiQuote link, $.hasClass link, 'filtered' unless @isClone
|
$.on link, 'click', QuoteInline.toggle
|
||||||
$.on link, 'click', QuoteInline.toggle
|
|
||||||
return
|
|
||||||
|
|
||||||
else
|
else
|
||||||
@node = ->
|
(link) ->
|
||||||
for link in @nodes.quotelinks.concat [@nodes.backlinks...]
|
$.on link, 'click', QuoteInline.toggle
|
||||||
$.on link, 'click', QuoteInline.toggle
|
|
||||||
return
|
|
||||||
|
|
||||||
if Conf['Comment Expansion']
|
if Conf['Comment Expansion']
|
||||||
ExpandComment.callbacks.push @node
|
ExpandComment.callbacks.push @node
|
||||||
@ -22,14 +18,18 @@ QuoteInline =
|
|||||||
name: 'Quote Inlining'
|
name: 'Quote Inlining'
|
||||||
cb: @node
|
cb: @node
|
||||||
|
|
||||||
|
node: ->
|
||||||
|
{process} = QuoteInline
|
||||||
|
{isClone} = @
|
||||||
|
process link, isClone for link in @nodes.quotelinks
|
||||||
|
process link, isClone for link in @nodes.backlinks
|
||||||
|
return
|
||||||
|
|
||||||
qiQuote: (link, hidden) ->
|
qiQuote: (link, hidden) ->
|
||||||
[
|
$.el 'a',
|
||||||
$.tn(' ')
|
className: "hashlink#{if hidden then ' filtered' else ''}"
|
||||||
$.el 'a',
|
textContent: '#'
|
||||||
className: if hidden then 'hashlink filtered' else 'hashlink'
|
href: link.href
|
||||||
textContent: '#'
|
|
||||||
href: link.href
|
|
||||||
]
|
|
||||||
|
|
||||||
toggle: (e) ->
|
toggle: (e) ->
|
||||||
return if e.shiftKey or e.altKey or e.ctrlKey or e.metaKey or e.button isnt 0
|
return if e.shiftKey or e.altKey or e.ctrlKey or e.metaKey or e.button isnt 0
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user