Merge branch 'v3'
Conflicts: CHANGELOG.md LICENSE builds/crx/script.js src/General/Config.coffee src/Images/FappeTyme.coffee src/Linkification/Linkify.coffee
This commit is contained in:
commit
e156cc8e9c
23
CHANGELOG.md
23
CHANGELOG.md
@ -1,11 +1,14 @@
|
||||
### v2.6.4
|
||||
*2013-12-06*
|
||||
**MayhemYDG**:
|
||||
- More Index Improvements:
|
||||
- New setting: `Anchor Hidden Threads`, enabled by default. Hidden threads will be moved at the end of the index to fill the first pages.
|
||||
- New setting: `Refreshed Navigation`, disabled by default. When enabled, navigating through pages will refresh the index.
|
||||
- The last index refresh timer will now indicate the last time the index changed from 4chan's side, instead of the last time you refreshed the index.
|
||||
|
||||
### v2.6.3
|
||||
*2013-11-27*
|
||||
**noface**:
|
||||
- Strawpoll.me embedding support (as usual, only works on HTTP 4chan due to lack of HTTPS)
|
||||
|
||||
### v2.6.2
|
||||
*2013-11-27*
|
||||
**Zixaphir**:
|
||||
- FappeTyme and WerkTyme now persist across sessions.
|
||||
|
||||
### v2.6.1
|
||||
*2013-11-27*
|
||||
@ -22,7 +25,7 @@
|
||||
- You cannot post an image reply immediately after a non-image reply anymore.
|
||||
- **New option**: `Auto-hide header on scroll`.
|
||||
- Added support for `4cdn.org`.
|
||||
- More index navigation improvements:
|
||||
- Index navigation improvements:
|
||||
- Searching in the index is now possible and will show matched OPs by:
|
||||
<ul>
|
||||
<li> comment
|
||||
@ -40,8 +43,9 @@
|
||||
</ul>
|
||||
- The elapsed time since the last index refresh is now indicated at the top of the index.
|
||||
- New setting: `Show replies`, enabled by default. Disable it to only show OPs in the index.
|
||||
- The index refreshing notification will now only appear on initial page load with slow connections.
|
||||
- Index navigation improvements:
|
||||
- New setting: `Anchor Hidden Threads`, enabled by default. Hidden threads will be moved at the end of the index to fill the first pages.
|
||||
- New setting: `Refreshed Navigation`, disabled by default. When enabled, navigating through pages will refresh the index.
|
||||
- The last index refresh timer will now indicate the last time the index changed from 4chan's side, instead of the last time you refreshed the index.
|
||||
- You can now refresh the index page you are on with the refresh shortcut in the header bar or the same keybind for refreshing threads.
|
||||
- You can now switch between paged and all-threads index modes via the "Index Navigation" header sub-menu:<br>
|
||||

|
||||
@ -54,6 +58,7 @@
|
||||
<li> File count
|
||||
</ul>
|
||||
- Navigating across index pages is now instantaneous.
|
||||
- The index refreshing notification will now only appear on initial page load with slow connections.
|
||||
- Added a keybind to open the catalog search field on index pages.
|
||||
- Minor cooldown fix:
|
||||
- You cannot post an image reply immediately after a non-image reply anymore.
|
||||
|
||||
2
LICENSE
2
LICENSE
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* appchan x - Version 2.6.4 - 2013-12-06
|
||||
* appchan x - Version 2.6.4 - 2013-12-16
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.2.43
|
||||
// @minGMVer 1.12
|
||||
// @minFFVer 22
|
||||
// @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==
|
||||
12898
builds/4chan-X.user.js
12898
builds/4chan-X.user.js
File diff suppressed because one or more lines are too long
@ -22,7 +22,7 @@
|
||||
// ==/UserScript==
|
||||
|
||||
/*
|
||||
* appchan x - Version 2.6.4 - 2013-12-06
|
||||
* appchan x - Version 2.6.4 - 2013-12-16
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
|
||||
@ -347,11 +347,17 @@
|
||||
MD5: ''
|
||||
},
|
||||
sauces: "https://www.google.com/searchbyimage?image_url=%TURL\nhttp://iqdb.org/?url=%TURL\n#//tineye.com/search?url=%TURL\n#http://saucenao.com/search.php?url=%TURL\n#http://3d.iqdb.org/?url=%TURL\n#http://regex.info/exif.cgi?imgurl=%URL\n# uploaders:\n#http://imgur.com/upload?url=%URL;text:Upload to imgur\n#http://ompldr.org/upload?url1=%URL;text:Upload to ompldr\n# \"View Same\" in archives:\n#//archive.foolz.us/_/search/image/%MD5/;text:View same on foolz\n#//archive.foolz.us/%board/search/image/%MD5/;text:View same on foolz /%board/\n#//archive.installgentoo.net/%board/image/%MD5;text:View same on installgentoo /%board/",
|
||||
FappeT: {
|
||||
fappe: false,
|
||||
werk: true
|
||||
},
|
||||
'Custom CSS': false,
|
||||
Index: {
|
||||
'Index Mode': 'paged',
|
||||
'Index Sort': 'bump',
|
||||
'Show Replies': true
|
||||
'Show Replies': true,
|
||||
'Anchor Hidden Threads': true,
|
||||
'Refreshed Navigation': false
|
||||
},
|
||||
Header: {
|
||||
'Fixed Header': true,
|
||||
@ -4329,7 +4335,7 @@
|
||||
|
||||
Index = {
|
||||
init: function() {
|
||||
var input, label, modeEntry, repliesEntry, sortEntry, _i, _j, _len, _len1, _ref, _ref1;
|
||||
var anchorEntry, input, label, modeEntry, name, refNavEntry, repliesEntry, sortEntry, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2;
|
||||
|
||||
if (g.VIEW !== 'index' || g.BOARD.ID === 'f') {
|
||||
return;
|
||||
@ -4407,17 +4413,40 @@
|
||||
innerHTML: '<input type=checkbox name="Show Replies"> Show replies'
|
||||
})
|
||||
};
|
||||
input = repliesEntry.el.firstChild;
|
||||
input.checked = Conf['Show Replies'];
|
||||
$.on(input, 'change', $.cb.checked);
|
||||
$.on(input, 'change', this.cb.replies);
|
||||
anchorEntry = {
|
||||
el: $.el('label', {
|
||||
innerHTML: '<input type=checkbox name="Anchor Hidden Threads"> Anchor hidden threads',
|
||||
title: 'Move hidden threads at the end of the index.'
|
||||
})
|
||||
};
|
||||
refNavEntry = {
|
||||
el: $.el('label', {
|
||||
innerHTML: '<input type=checkbox name="Refreshed Navigation"> Refreshed navigation',
|
||||
title: 'Refresh index when navigating through pages.'
|
||||
})
|
||||
};
|
||||
_ref2 = [repliesEntry, anchorEntry, refNavEntry];
|
||||
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
|
||||
label = _ref2[_k];
|
||||
input = label.el.firstChild;
|
||||
name = input.name;
|
||||
input.checked = Conf[name];
|
||||
$.on(input, 'change', $.cb.checked);
|
||||
switch (name) {
|
||||
case 'Show Replies':
|
||||
$.on(input, 'change', this.cb.replies);
|
||||
break;
|
||||
case 'Anchor Hidden Threads':
|
||||
$.on(input, 'change', this.cb.sort);
|
||||
}
|
||||
}
|
||||
$.event('AddMenuEntry', {
|
||||
type: 'header',
|
||||
el: $.el('span', {
|
||||
textContent: 'Index Navigation'
|
||||
}),
|
||||
order: 90,
|
||||
subEntries: [modeEntry, sortEntry, repliesEntry]
|
||||
subEntries: [modeEntry, sortEntry, repliesEntry, anchorEntry, refNavEntry]
|
||||
});
|
||||
$.addClass(doc, 'index-loading');
|
||||
this.update();
|
||||
@ -4442,14 +4471,14 @@
|
||||
return $.asap((function() {
|
||||
return $('.board', doc) || d.readyState !== 'loading';
|
||||
}), function() {
|
||||
var board, navLink, _k, _len2, _ref2;
|
||||
var board, navLink, _l, _len3, _ref3;
|
||||
|
||||
board = $('.board');
|
||||
$.replace(board, Index.root);
|
||||
d.implementation.createDocument(null, null, null).appendChild(board);
|
||||
_ref2 = $$('.navLinks');
|
||||
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
|
||||
navLink = _ref2[_k];
|
||||
_ref3 = $$('.navLinks');
|
||||
for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
|
||||
navLink = _ref3[_l];
|
||||
$.rm(navLink);
|
||||
}
|
||||
$.after($.x('child::form/preceding-sibling::hr[1]'), Index.navLinks);
|
||||
@ -4503,7 +4532,7 @@
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
return Index.pageNav(+a.pathname.split('/')[2]);
|
||||
return Index.userPageNav(+a.pathname.split('/')[2]);
|
||||
}
|
||||
},
|
||||
scrollToIndex: function() {
|
||||
@ -4512,6 +4541,13 @@
|
||||
getCurrentPage: function() {
|
||||
return +window.location.pathname.split('/')[2];
|
||||
},
|
||||
userPageNav: function(pageNum) {
|
||||
if (Conf['Refreshed Navigation'] && Conf['Index Mode'] === 'paged') {
|
||||
return Index.update(pageNum);
|
||||
} else {
|
||||
return Index.pageNav(pageNum);
|
||||
}
|
||||
},
|
||||
pageNav: function(pageNum) {
|
||||
if (Index.currentPage === pageNum) {
|
||||
return;
|
||||
@ -4586,8 +4622,8 @@
|
||||
$.before(a, strong);
|
||||
return $.add(strong, a);
|
||||
},
|
||||
update: function() {
|
||||
var now, _ref, _ref1;
|
||||
update: function(pageNum) {
|
||||
var now, onload, _ref, _ref1;
|
||||
|
||||
if (!navigator.onLine) {
|
||||
return;
|
||||
@ -4611,15 +4647,21 @@
|
||||
}), 5 * $.SECOND - (Date.now() - now));
|
||||
});
|
||||
}
|
||||
if (typeof pageNum !== 'number') {
|
||||
pageNum = null;
|
||||
}
|
||||
onload = function(e) {
|
||||
return Index.load(e, pageNum);
|
||||
};
|
||||
Index.req = $.ajax("//a.4cdn.org/" + g.BOARD + "/catalog.json", {
|
||||
onabort: Index.load,
|
||||
onloadend: Index.load
|
||||
onabort: onload,
|
||||
onloadend: onload
|
||||
}, {
|
||||
whenModified: true
|
||||
});
|
||||
return $.addClass(Index.button, 'fa-spin');
|
||||
},
|
||||
load: function(e) {
|
||||
load: function(e, pageNum) {
|
||||
var err, notice, req, timeEl;
|
||||
|
||||
$.rmClass(Index.button, 'fa-spin');
|
||||
@ -4633,7 +4675,9 @@
|
||||
}
|
||||
try {
|
||||
if (req.status === 200) {
|
||||
Index.parse(JSON.parse(req.response));
|
||||
Index.parse(JSON.parse(req.response), pageNum);
|
||||
} else if (req.status === 304 && (pageNum != null)) {
|
||||
Index.pageNav(pageNum);
|
||||
}
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
@ -4653,16 +4697,20 @@
|
||||
setTimeout(notice.close, $.SECOND);
|
||||
}
|
||||
timeEl = $('#index-last-refresh', Index.navLinks);
|
||||
timeEl.dataset.utc = e.timeStamp / 1000;
|
||||
timeEl.dataset.utc = Date.parse(req.getResponseHeader('Last-Modified'));
|
||||
RelativeDates.update(timeEl);
|
||||
return Index.scrollToIndex();
|
||||
},
|
||||
parse: function(pages) {
|
||||
parse: function(pages, pageNum) {
|
||||
Index.parseThreadList(pages);
|
||||
Index.buildThreads();
|
||||
Index.sort();
|
||||
Index.buildIndex();
|
||||
Index.buildPagelist();
|
||||
if (pageNum != null) {
|
||||
Index.pageNav(pageNum);
|
||||
return;
|
||||
}
|
||||
Index.buildIndex();
|
||||
return Index.setPage();
|
||||
},
|
||||
parseThreadList: function(pages) {
|
||||
@ -4767,7 +4815,7 @@
|
||||
return Main.callbackNodes(Post, posts);
|
||||
},
|
||||
sort: function() {
|
||||
var i, offset, sortedThreadIDs, threadID, threadRoot, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3;
|
||||
var i, sortedThreadIDs, threadID, _i, _len;
|
||||
|
||||
switch (Conf['Index Sort']) {
|
||||
case 'bump':
|
||||
@ -4814,25 +4862,31 @@
|
||||
if (Index.isSearching) {
|
||||
Index.sortedNodes = Index.querySearch(Index.searchInput.value) || Index.sortedNodes;
|
||||
}
|
||||
Index.sortOnTop(function(thread) {
|
||||
return thread.isSticky;
|
||||
});
|
||||
if (Conf['Filter']) {
|
||||
Index.sortOnTop(function(thread) {
|
||||
return thread.isOnTop;
|
||||
});
|
||||
}
|
||||
if (Conf['Anchor Hidden Threads']) {
|
||||
return Index.sortOnTop(function(thread) {
|
||||
return !thread.isHidden;
|
||||
});
|
||||
}
|
||||
},
|
||||
sortOnTop: function(match) {
|
||||
var i, offset, threadRoot, _i, _len, _ref, _ref1;
|
||||
|
||||
offset = 0;
|
||||
_ref = Index.sortedNodes;
|
||||
for (i = _j = 0, _len1 = _ref.length; _j < _len1; i = _j += 2) {
|
||||
for (i = _i = 0, _len = _ref.length; _i < _len; i = _i += 2) {
|
||||
threadRoot = _ref[i];
|
||||
if (Get.threadFromRoot(threadRoot).isSticky) {
|
||||
if (match(Get.threadFromRoot(threadRoot))) {
|
||||
(_ref1 = Index.sortedNodes).splice.apply(_ref1, [offset++ * 2, 0].concat(__slice.call(Index.sortedNodes.splice(i, 2))));
|
||||
}
|
||||
}
|
||||
if (!Conf['Filter']) {
|
||||
return;
|
||||
}
|
||||
offset = 0;
|
||||
_ref2 = Index.sortedNodes;
|
||||
for (i = _k = 0, _len2 = _ref2.length; _k < _len2; i = _k += 2) {
|
||||
threadRoot = _ref2[i];
|
||||
if (Get.threadFromRoot(threadRoot).isOnTop) {
|
||||
(_ref3 = Index.sortedNodes).splice.apply(_ref3, [offset++ * 2, 0].concat(__slice.call(Index.sortedNodes.splice(i, 2))));
|
||||
}
|
||||
}
|
||||
},
|
||||
buildIndex: function() {
|
||||
var nodes, nodesPerPage, pageNum;
|
||||
@ -5036,7 +5090,7 @@
|
||||
}
|
||||
flag = !flagCode ? '' : boardID === 'pol' ? " <img src='" + staticPath + "country/troll/" + (flagCode.toLowerCase()) + ".gif' alt=" + flagCode + " title='" + flagName + "' class=countryFlag>" : " <span title='" + flagName + "' class='flag flag-" + (flagCode.toLowerCase()) + "'></span>";
|
||||
if (file != null ? file.isDeleted : void 0) {
|
||||
fileHTML = isOP ? ("<div class=file id=f" + postID + "><div class=fileInfo></div><span class=fileThumb>") + ("<img src='" + staticPath + "filedeleted" + gifIcon + "' alt='File deleted.' class=fileDeleted>") + "</span></div>" : ("<div class=file id=f" + postID + "><span class=fileThumb>") + ("<img src='" + staticPath + "filedeleted-res" + gifIcon + "' alt='File deleted.' class=fileDeletedRes>") + "</span></div>";
|
||||
fileHTML = isOP ? ("<div class=file id=f" + postID + "><span class=fileThumb>") + ("<img src='" + staticPath + "filedeleted" + gifIcon + "' alt='File deleted.' class=fileDeleted>") + "</span></div>" : ("<div class=file id=f" + postID + "><span class=fileThumb>") + ("<img src='" + staticPath + "filedeleted-res" + gifIcon + "' alt='File deleted.' class=fileDeletedRes>") + "</span></div>";
|
||||
} else if (file) {
|
||||
ext = file.name.slice(-3);
|
||||
if (!file.twidth && !file.theight && ext === 'gif') {
|
||||
@ -9729,31 +9783,35 @@
|
||||
|
||||
FappeTyme = {
|
||||
init: function() {
|
||||
var el;
|
||||
var el, lc, type, _i, _len, _ref;
|
||||
|
||||
if (!(Conf['Fappe Tyme'] || Conf['Werk Tyme']) || g.VIEW === 'catalog' || g.BOARD === 'f') {
|
||||
return;
|
||||
}
|
||||
if (Conf['Fappe Tyme']) {
|
||||
_ref = ["Fappe", "Werk"];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
type = _ref[_i];
|
||||
if (!Conf["" + type + " Tyme"]) {
|
||||
continue;
|
||||
}
|
||||
lc = type.toLowerCase();
|
||||
el = $.el('a', {
|
||||
href: 'javascript:;',
|
||||
id: 'fappeTyme',
|
||||
title: 'Fappe Tyme',
|
||||
id: "" + lc + "Tyme",
|
||||
title: "" + type + " Tyme",
|
||||
className: 'a-icon'
|
||||
});
|
||||
$.on(el, 'click', FappeTyme.cb.fappe);
|
||||
Header.addShortcut(el, true);
|
||||
}
|
||||
if (Conf['Werk Tyme']) {
|
||||
el = $.el('a', {
|
||||
href: 'javascript:;',
|
||||
id: 'werkTyme',
|
||||
title: 'Werk Tyme',
|
||||
className: 'fa',
|
||||
textContent: '\uf0b1'
|
||||
});
|
||||
$.on(el, 'click', FappeTyme.cb.werk);
|
||||
if (type === 'Werk') {
|
||||
el.textContent = '\uf0b1';
|
||||
el.className = 'fa';
|
||||
}
|
||||
$.on(el, 'click', FappeTyme.cb.toggle.bind({
|
||||
name: "" + lc
|
||||
}));
|
||||
Header.addShortcut(el, true);
|
||||
if (Conf[lc]) {
|
||||
FappeTyme.cb.set(type);
|
||||
}
|
||||
}
|
||||
return Post.callbacks.push({
|
||||
name: 'Fappe Tyme',
|
||||
@ -9767,11 +9825,17 @@
|
||||
return $.addClass(this.nodes.root, "noFile");
|
||||
},
|
||||
cb: {
|
||||
fappe: function() {
|
||||
return $.toggleClass(doc, 'fappeTyme');
|
||||
set: function(type) {
|
||||
FappeTyme[type].checked = Conf[type];
|
||||
return $["" + (Conf[type] ? 'add' : 'rm') + "Class"](doc, "" + type + "Tyme");
|
||||
},
|
||||
werk: function() {
|
||||
return $.toggleClass(doc, 'werkTyme');
|
||||
toggle: function() {
|
||||
Conf[this.name] = !Conf[this.name];
|
||||
FappeTyme.cb.set(this.name);
|
||||
return $.cb.checked.call({
|
||||
name: this.name,
|
||||
checked: Conf[this.name]
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -12304,8 +12368,8 @@
|
||||
http: true,
|
||||
https: true,
|
||||
software: "foolfuuka",
|
||||
boards: ["hr", "tg", "tv", "x"],
|
||||
files: ["hr", "tg", "tv", "x"]
|
||||
boards: ["hr", "pol", "s4s", "tg", "tv", "x"],
|
||||
files: ["hr", "pol", "s4s", "tg", "tv", "x"]
|
||||
},
|
||||
"Nyafuu": {
|
||||
domain: "archive.nyafuu.org",
|
||||
@ -12315,14 +12379,6 @@
|
||||
boards: ["c", "w", "wg"],
|
||||
files: ["c", "w", "wg"]
|
||||
},
|
||||
"fap archive": {
|
||||
domain: "fuuka.worldathleticproject.org",
|
||||
http: true,
|
||||
https: true,
|
||||
software: "foolfuuka",
|
||||
boards: ["adv", "b", "cm", "d", "e", "h", "hc", "lgbt", "pol", "r", "s", "s4s", "soc", "trv", "u", "y"],
|
||||
files: ["b", "cm", "d", "e", "h", "hc", "pol", "r", "s", "s4s", "soc", "u", "y"]
|
||||
},
|
||||
"Install Gentoo": {
|
||||
domain: "archive.installgentoo.net",
|
||||
http: false,
|
||||
@ -12344,7 +12400,7 @@
|
||||
http: true,
|
||||
software: "fuuka",
|
||||
boards: ["an", "fit", "k", "mlp", "r9k", "toy"],
|
||||
files: ["an", "k", "toy"]
|
||||
files: ["an", "fit", "k", "r9k", "toy"]
|
||||
},
|
||||
"warosu": {
|
||||
domain: "fuuka.warosu.org",
|
||||
@ -12354,6 +12410,14 @@
|
||||
boards: ["3", "cgl", "ck", "fa", "ic", "jp", "lit", "tg", "vr"],
|
||||
files: ["3", "cgl", "ck", "fa", "ic", "jp", "lit", "tg", "vr"]
|
||||
},
|
||||
"Bui's Archive": {
|
||||
domain: "archive.bui.pm",
|
||||
http: true,
|
||||
https: true,
|
||||
software: "foolfuuka",
|
||||
boards: ["b"],
|
||||
files: ["b"]
|
||||
},
|
||||
"Foolz Beta": {
|
||||
domain: "beta.foolz.us",
|
||||
http: true,
|
||||
@ -14448,7 +14512,7 @@
|
||||
if (!this.file || this.isClone) {
|
||||
return;
|
||||
}
|
||||
return this.file.text.innerHTML = FileInfo.funk(FileInfo, this);
|
||||
return this.file.text.innerHTML = "<span class=file-info>" + (FileInfo.funk(FileInfo, this)) + "</span>";
|
||||
},
|
||||
createFunc: function(format) {
|
||||
var code;
|
||||
@ -14952,14 +15016,18 @@
|
||||
Gallery.cb.toggle();
|
||||
break;
|
||||
case Conf['fappeTyme']:
|
||||
FappeTyme.cb.fappe();
|
||||
FappeTyme.cb.toggle.call({
|
||||
name: 'fappe'
|
||||
});
|
||||
break;
|
||||
case Conf['werkTyme']:
|
||||
FappeTyme.cb.werk();
|
||||
FappeTyme.cb.toggle.call({
|
||||
name: 'werk'
|
||||
});
|
||||
break;
|
||||
case Conf['Front page']:
|
||||
if (g.VIEW === 'index') {
|
||||
Index.pageNav(0);
|
||||
Index.userPageNav(0);
|
||||
} else {
|
||||
window.location = "/" + g.BOARD + "/";
|
||||
}
|
||||
@ -15020,7 +15088,7 @@
|
||||
Keybinds.hl(0, threadRoot);
|
||||
break;
|
||||
case Conf['Hide']:
|
||||
if (g.VIEW === 'index') {
|
||||
if (ThreadHiding.db) {
|
||||
ThreadHiding.toggle(thread);
|
||||
}
|
||||
break;
|
||||
@ -15133,7 +15201,7 @@
|
||||
}
|
||||
},
|
||||
hl: function(delta, thread) {
|
||||
var axe, height, next, postEl, replies, reply, root, _i, _len;
|
||||
var axis, height, next, postEl, replies, reply, root, _i, _len;
|
||||
|
||||
postEl = $('.reply.highlight', thread);
|
||||
if (!delta) {
|
||||
@ -15146,8 +15214,8 @@
|
||||
height = postEl.getBoundingClientRect().height;
|
||||
if (Header.getTopOf(postEl) >= -height && Header.getBottomOf(postEl) >= -height) {
|
||||
root = postEl.parentNode;
|
||||
axe = delta === +1 ? 'following' : 'preceding';
|
||||
if (!(next = $.x("" + axe + "-sibling::div[contains(@class,'replyContainer')][1]/child::div[contains(@class,'reply')]", root))) {
|
||||
axis = delta === +1 ? 'following' : 'preceding';
|
||||
if (!(next = $.x("" + axis + "-sibling::div[contains(@class,'replyContainer') and not(@hidden) and not(child::div[@class='stub'])][1]/child::div[contains(@class,'reply')]", root))) {
|
||||
return;
|
||||
}
|
||||
Header.scrollToIfNeeded(next, delta === +1);
|
||||
@ -15236,11 +15304,11 @@
|
||||
return $('.board');
|
||||
},
|
||||
scroll: function(delta) {
|
||||
var axe, next, thread, top;
|
||||
var axis, next, thread, top;
|
||||
|
||||
thread = Nav.getThread();
|
||||
axe = delta === +1 ? 'following' : 'preceding';
|
||||
if (next = $.x("" + axe + "-sibling::div[contains(@class,'thread') and not(@hidden)][1]", thread)) {
|
||||
axis = delta === +1 ? 'following' : 'preceding';
|
||||
if (next = $.x("" + axis + "-sibling::div[contains(@class,'thread') and not(@hidden)][1]", thread)) {
|
||||
top = Header.getTopOf(thread);
|
||||
if (delta === +1 && top < 5 || delta === -1 && top > -5) {
|
||||
thread = next;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// Generated by CoffeeScript
|
||||
/*
|
||||
* appchan x - Version 2.6.4 - 2013-12-06
|
||||
* appchan x - Version 2.6.4 - 2013-12-16
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
|
||||
@ -326,11 +326,17 @@
|
||||
MD5: ''
|
||||
},
|
||||
sauces: "https://www.google.com/searchbyimage?image_url=%TURL\nhttp://iqdb.org/?url=%TURL\n#//tineye.com/search?url=%TURL\n#http://saucenao.com/search.php?url=%TURL\n#http://3d.iqdb.org/?url=%TURL\n#http://regex.info/exif.cgi?imgurl=%URL\n# uploaders:\n#http://imgur.com/upload?url=%URL;text:Upload to imgur\n#http://ompldr.org/upload?url1=%URL;text:Upload to ompldr\n# \"View Same\" in archives:\n#//archive.foolz.us/_/search/image/%MD5/;text:View same on foolz\n#//archive.foolz.us/%board/search/image/%MD5/;text:View same on foolz /%board/\n#//archive.installgentoo.net/%board/image/%MD5;text:View same on installgentoo /%board/",
|
||||
FappeT: {
|
||||
fappe: false,
|
||||
werk: true
|
||||
},
|
||||
'Custom CSS': false,
|
||||
Index: {
|
||||
'Index Mode': 'paged',
|
||||
'Index Sort': 'bump',
|
||||
'Show Replies': true
|
||||
'Show Replies': true,
|
||||
'Anchor Hidden Threads': true,
|
||||
'Refreshed Navigation': false
|
||||
},
|
||||
Header: {
|
||||
'Fixed Header': true,
|
||||
@ -4342,7 +4348,7 @@
|
||||
|
||||
Index = {
|
||||
init: function() {
|
||||
var input, label, modeEntry, repliesEntry, sortEntry, _i, _j, _len, _len1, _ref, _ref1;
|
||||
var anchorEntry, input, label, modeEntry, name, refNavEntry, repliesEntry, sortEntry, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2;
|
||||
|
||||
if (g.VIEW !== 'index' || g.BOARD.ID === 'f') {
|
||||
return;
|
||||
@ -4420,17 +4426,40 @@
|
||||
innerHTML: '<input type=checkbox name="Show Replies"> Show replies'
|
||||
})
|
||||
};
|
||||
input = repliesEntry.el.firstChild;
|
||||
input.checked = Conf['Show Replies'];
|
||||
$.on(input, 'change', $.cb.checked);
|
||||
$.on(input, 'change', this.cb.replies);
|
||||
anchorEntry = {
|
||||
el: $.el('label', {
|
||||
innerHTML: '<input type=checkbox name="Anchor Hidden Threads"> Anchor hidden threads',
|
||||
title: 'Move hidden threads at the end of the index.'
|
||||
})
|
||||
};
|
||||
refNavEntry = {
|
||||
el: $.el('label', {
|
||||
innerHTML: '<input type=checkbox name="Refreshed Navigation"> Refreshed navigation',
|
||||
title: 'Refresh index when navigating through pages.'
|
||||
})
|
||||
};
|
||||
_ref2 = [repliesEntry, anchorEntry, refNavEntry];
|
||||
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
|
||||
label = _ref2[_k];
|
||||
input = label.el.firstChild;
|
||||
name = input.name;
|
||||
input.checked = Conf[name];
|
||||
$.on(input, 'change', $.cb.checked);
|
||||
switch (name) {
|
||||
case 'Show Replies':
|
||||
$.on(input, 'change', this.cb.replies);
|
||||
break;
|
||||
case 'Anchor Hidden Threads':
|
||||
$.on(input, 'change', this.cb.sort);
|
||||
}
|
||||
}
|
||||
$.event('AddMenuEntry', {
|
||||
type: 'header',
|
||||
el: $.el('span', {
|
||||
textContent: 'Index Navigation'
|
||||
}),
|
||||
order: 90,
|
||||
subEntries: [modeEntry, sortEntry, repliesEntry]
|
||||
subEntries: [modeEntry, sortEntry, repliesEntry, anchorEntry, refNavEntry]
|
||||
});
|
||||
$.addClass(doc, 'index-loading');
|
||||
this.update();
|
||||
@ -4455,14 +4484,14 @@
|
||||
return $.asap((function() {
|
||||
return $('.board', doc) || d.readyState !== 'loading';
|
||||
}), function() {
|
||||
var board, navLink, _k, _len2, _ref2;
|
||||
var board, navLink, _l, _len3, _ref3;
|
||||
|
||||
board = $('.board');
|
||||
$.replace(board, Index.root);
|
||||
d.implementation.createDocument(null, null, null).appendChild(board);
|
||||
_ref2 = $$('.navLinks');
|
||||
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
|
||||
navLink = _ref2[_k];
|
||||
_ref3 = $$('.navLinks');
|
||||
for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
|
||||
navLink = _ref3[_l];
|
||||
$.rm(navLink);
|
||||
}
|
||||
$.after($.x('child::form/preceding-sibling::hr[1]'), Index.navLinks);
|
||||
@ -4516,7 +4545,7 @@
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
return Index.pageNav(+a.pathname.split('/')[2]);
|
||||
return Index.userPageNav(+a.pathname.split('/')[2]);
|
||||
}
|
||||
},
|
||||
scrollToIndex: function() {
|
||||
@ -4525,6 +4554,13 @@
|
||||
getCurrentPage: function() {
|
||||
return +window.location.pathname.split('/')[2];
|
||||
},
|
||||
userPageNav: function(pageNum) {
|
||||
if (Conf['Refreshed Navigation'] && Conf['Index Mode'] === 'paged') {
|
||||
return Index.update(pageNum);
|
||||
} else {
|
||||
return Index.pageNav(pageNum);
|
||||
}
|
||||
},
|
||||
pageNav: function(pageNum) {
|
||||
if (Index.currentPage === pageNum) {
|
||||
return;
|
||||
@ -4599,8 +4635,8 @@
|
||||
$.before(a, strong);
|
||||
return $.add(strong, a);
|
||||
},
|
||||
update: function() {
|
||||
var now, _ref, _ref1;
|
||||
update: function(pageNum) {
|
||||
var now, onload, _ref, _ref1;
|
||||
|
||||
if (!navigator.onLine) {
|
||||
return;
|
||||
@ -4624,15 +4660,21 @@
|
||||
}), 5 * $.SECOND - (Date.now() - now));
|
||||
});
|
||||
}
|
||||
if (typeof pageNum !== 'number') {
|
||||
pageNum = null;
|
||||
}
|
||||
onload = function(e) {
|
||||
return Index.load(e, pageNum);
|
||||
};
|
||||
Index.req = $.ajax("//a.4cdn.org/" + g.BOARD + "/catalog.json", {
|
||||
onabort: Index.load,
|
||||
onloadend: Index.load
|
||||
onabort: onload,
|
||||
onloadend: onload
|
||||
}, {
|
||||
whenModified: true
|
||||
});
|
||||
return $.addClass(Index.button, 'fa-spin');
|
||||
},
|
||||
load: function(e) {
|
||||
load: function(e, pageNum) {
|
||||
var err, notice, req, timeEl;
|
||||
|
||||
$.rmClass(Index.button, 'fa-spin');
|
||||
@ -4646,7 +4688,9 @@
|
||||
}
|
||||
try {
|
||||
if (req.status === 200) {
|
||||
Index.parse(JSON.parse(req.response));
|
||||
Index.parse(JSON.parse(req.response), pageNum);
|
||||
} else if (req.status === 304 && (pageNum != null)) {
|
||||
Index.pageNav(pageNum);
|
||||
}
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
@ -4666,16 +4710,20 @@
|
||||
setTimeout(notice.close, $.SECOND);
|
||||
}
|
||||
timeEl = $('#index-last-refresh', Index.navLinks);
|
||||
timeEl.dataset.utc = e.timeStamp;
|
||||
timeEl.dataset.utc = Date.parse(req.getResponseHeader('Last-Modified'));
|
||||
RelativeDates.update(timeEl);
|
||||
return Index.scrollToIndex();
|
||||
},
|
||||
parse: function(pages) {
|
||||
parse: function(pages, pageNum) {
|
||||
Index.parseThreadList(pages);
|
||||
Index.buildThreads();
|
||||
Index.sort();
|
||||
Index.buildIndex();
|
||||
Index.buildPagelist();
|
||||
if (pageNum != null) {
|
||||
Index.pageNav(pageNum);
|
||||
return;
|
||||
}
|
||||
Index.buildIndex();
|
||||
return Index.setPage();
|
||||
},
|
||||
parseThreadList: function(pages) {
|
||||
@ -4780,7 +4828,7 @@
|
||||
return Main.callbackNodes(Post, posts);
|
||||
},
|
||||
sort: function() {
|
||||
var i, offset, sortedThreadIDs, threadID, threadRoot, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3;
|
||||
var i, sortedThreadIDs, threadID, _i, _len;
|
||||
|
||||
switch (Conf['Index Sort']) {
|
||||
case 'bump':
|
||||
@ -4827,25 +4875,31 @@
|
||||
if (Index.isSearching) {
|
||||
Index.sortedNodes = Index.querySearch(Index.searchInput.value) || Index.sortedNodes;
|
||||
}
|
||||
Index.sortOnTop(function(thread) {
|
||||
return thread.isSticky;
|
||||
});
|
||||
if (Conf['Filter']) {
|
||||
Index.sortOnTop(function(thread) {
|
||||
return thread.isOnTop;
|
||||
});
|
||||
}
|
||||
if (Conf['Anchor Hidden Threads']) {
|
||||
return Index.sortOnTop(function(thread) {
|
||||
return !thread.isHidden;
|
||||
});
|
||||
}
|
||||
},
|
||||
sortOnTop: function(match) {
|
||||
var i, offset, threadRoot, _i, _len, _ref, _ref1;
|
||||
|
||||
offset = 0;
|
||||
_ref = Index.sortedNodes;
|
||||
for (i = _j = 0, _len1 = _ref.length; _j < _len1; i = _j += 2) {
|
||||
for (i = _i = 0, _len = _ref.length; _i < _len; i = _i += 2) {
|
||||
threadRoot = _ref[i];
|
||||
if (Get.threadFromRoot(threadRoot).isSticky) {
|
||||
if (match(Get.threadFromRoot(threadRoot))) {
|
||||
(_ref1 = Index.sortedNodes).splice.apply(_ref1, [offset++ * 2, 0].concat(__slice.call(Index.sortedNodes.splice(i, 2))));
|
||||
}
|
||||
}
|
||||
if (!Conf['Filter']) {
|
||||
return;
|
||||
}
|
||||
offset = 0;
|
||||
_ref2 = Index.sortedNodes;
|
||||
for (i = _k = 0, _len2 = _ref2.length; _k < _len2; i = _k += 2) {
|
||||
threadRoot = _ref2[i];
|
||||
if (Get.threadFromRoot(threadRoot).isOnTop) {
|
||||
(_ref3 = Index.sortedNodes).splice.apply(_ref3, [offset++ * 2, 0].concat(__slice.call(Index.sortedNodes.splice(i, 2))));
|
||||
}
|
||||
}
|
||||
},
|
||||
buildIndex: function() {
|
||||
var nodes, nodesPerPage, pageNum;
|
||||
@ -5049,7 +5103,7 @@
|
||||
}
|
||||
flag = !flagCode ? '' : boardID === 'pol' ? " <img src='" + staticPath + "country/troll/" + (flagCode.toLowerCase()) + ".gif' alt=" + flagCode + " title='" + flagName + "' class=countryFlag>" : " <span title='" + flagName + "' class='flag flag-" + (flagCode.toLowerCase()) + "'></span>";
|
||||
if (file != null ? file.isDeleted : void 0) {
|
||||
fileHTML = isOP ? ("<div class=file id=f" + postID + "><div class=fileInfo></div><span class=fileThumb>") + ("<img src='" + staticPath + "filedeleted" + gifIcon + "' alt='File deleted.' class=fileDeleted>") + "</span></div>" : ("<div class=file id=f" + postID + "><span class=fileThumb>") + ("<img src='" + staticPath + "filedeleted-res" + gifIcon + "' alt='File deleted.' class=fileDeletedRes>") + "</span></div>";
|
||||
fileHTML = isOP ? ("<div class=file id=f" + postID + "><span class=fileThumb>") + ("<img src='" + staticPath + "filedeleted" + gifIcon + "' alt='File deleted.' class=fileDeleted>") + "</span></div>" : ("<div class=file id=f" + postID + "><span class=fileThumb>") + ("<img src='" + staticPath + "filedeleted-res" + gifIcon + "' alt='File deleted.' class=fileDeletedRes>") + "</span></div>";
|
||||
} else if (file) {
|
||||
ext = file.name.slice(-3);
|
||||
if (!file.twidth && !file.theight && ext === 'gif') {
|
||||
@ -9715,31 +9769,35 @@
|
||||
|
||||
FappeTyme = {
|
||||
init: function() {
|
||||
var el;
|
||||
var el, lc, type, _i, _len, _ref;
|
||||
|
||||
if (!(Conf['Fappe Tyme'] || Conf['Werk Tyme']) || g.VIEW === 'catalog' || g.BOARD === 'f') {
|
||||
return;
|
||||
}
|
||||
if (Conf['Fappe Tyme']) {
|
||||
_ref = ["Fappe", "Werk"];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
type = _ref[_i];
|
||||
if (!Conf["" + type + " Tyme"]) {
|
||||
continue;
|
||||
}
|
||||
lc = type.toLowerCase();
|
||||
el = $.el('a', {
|
||||
href: 'javascript:;',
|
||||
id: 'fappeTyme',
|
||||
title: 'Fappe Tyme',
|
||||
id: "" + lc + "Tyme",
|
||||
title: "" + type + " Tyme",
|
||||
className: 'a-icon'
|
||||
});
|
||||
$.on(el, 'click', FappeTyme.cb.fappe);
|
||||
Header.addShortcut(el, true);
|
||||
}
|
||||
if (Conf['Werk Tyme']) {
|
||||
el = $.el('a', {
|
||||
href: 'javascript:;',
|
||||
id: 'werkTyme',
|
||||
title: 'Werk Tyme',
|
||||
className: 'fa',
|
||||
textContent: '\uf0b1'
|
||||
});
|
||||
$.on(el, 'click', FappeTyme.cb.werk);
|
||||
if (type === 'Werk') {
|
||||
el.textContent = '\uf0b1';
|
||||
el.className = 'fa';
|
||||
}
|
||||
$.on(el, 'click', FappeTyme.cb.toggle.bind({
|
||||
name: "" + lc
|
||||
}));
|
||||
Header.addShortcut(el, true);
|
||||
if (Conf[lc]) {
|
||||
FappeTyme.cb.set(type);
|
||||
}
|
||||
}
|
||||
return Post.callbacks.push({
|
||||
name: 'Fappe Tyme',
|
||||
@ -9753,11 +9811,17 @@
|
||||
return $.addClass(this.nodes.root, "noFile");
|
||||
},
|
||||
cb: {
|
||||
fappe: function() {
|
||||
return $.toggleClass(doc, 'fappeTyme');
|
||||
set: function(type) {
|
||||
FappeTyme[type].checked = Conf[type];
|
||||
return $["" + (Conf[type] ? 'add' : 'rm') + "Class"](doc, "" + type + "Tyme");
|
||||
},
|
||||
werk: function() {
|
||||
return $.toggleClass(doc, 'werkTyme');
|
||||
toggle: function() {
|
||||
Conf[this.name] = !Conf[this.name];
|
||||
FappeTyme.cb.set(this.name);
|
||||
return $.cb.checked.call({
|
||||
name: this.name,
|
||||
checked: Conf[this.name]
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -12296,8 +12360,8 @@
|
||||
http: true,
|
||||
https: true,
|
||||
software: "foolfuuka",
|
||||
boards: ["hr", "tg", "tv", "x"],
|
||||
files: ["hr", "tg", "tv", "x"]
|
||||
boards: ["hr", "pol", "s4s", "tg", "tv", "x"],
|
||||
files: ["hr", "pol", "s4s", "tg", "tv", "x"]
|
||||
},
|
||||
"Nyafuu": {
|
||||
domain: "archive.nyafuu.org",
|
||||
@ -12307,14 +12371,6 @@
|
||||
boards: ["c", "w", "wg"],
|
||||
files: ["c", "w", "wg"]
|
||||
},
|
||||
"fap archive": {
|
||||
domain: "fuuka.worldathleticproject.org",
|
||||
http: true,
|
||||
https: true,
|
||||
software: "foolfuuka",
|
||||
boards: ["adv", "b", "cm", "d", "e", "h", "hc", "lgbt", "pol", "r", "s", "s4s", "soc", "trv", "u", "y"],
|
||||
files: ["b", "cm", "d", "e", "h", "hc", "pol", "r", "s", "s4s", "soc", "u", "y"]
|
||||
},
|
||||
"Install Gentoo": {
|
||||
domain: "archive.installgentoo.net",
|
||||
http: false,
|
||||
@ -12336,7 +12392,7 @@
|
||||
http: true,
|
||||
software: "fuuka",
|
||||
boards: ["an", "fit", "k", "mlp", "r9k", "toy"],
|
||||
files: ["an", "k", "toy"]
|
||||
files: ["an", "fit", "k", "r9k", "toy"]
|
||||
},
|
||||
"warosu": {
|
||||
domain: "fuuka.warosu.org",
|
||||
@ -12346,6 +12402,14 @@
|
||||
boards: ["3", "cgl", "ck", "fa", "ic", "jp", "lit", "tg", "vr"],
|
||||
files: ["3", "cgl", "ck", "fa", "ic", "jp", "lit", "tg", "vr"]
|
||||
},
|
||||
"Bui's Archive": {
|
||||
domain: "archive.bui.pm",
|
||||
http: true,
|
||||
https: true,
|
||||
software: "foolfuuka",
|
||||
boards: ["b"],
|
||||
files: ["b"]
|
||||
},
|
||||
"Foolz Beta": {
|
||||
domain: "beta.foolz.us",
|
||||
http: true,
|
||||
@ -14440,7 +14504,7 @@
|
||||
if (!this.file || this.isClone) {
|
||||
return;
|
||||
}
|
||||
return this.file.text.innerHTML = FileInfo.funk(FileInfo, this);
|
||||
return this.file.text.innerHTML = "<span class=file-info>" + (FileInfo.funk(FileInfo, this)) + "</span>";
|
||||
},
|
||||
createFunc: function(format) {
|
||||
var code;
|
||||
@ -14944,14 +15008,18 @@
|
||||
Gallery.cb.toggle();
|
||||
break;
|
||||
case Conf['fappeTyme']:
|
||||
FappeTyme.cb.fappe();
|
||||
FappeTyme.cb.toggle.call({
|
||||
name: 'fappe'
|
||||
});
|
||||
break;
|
||||
case Conf['werkTyme']:
|
||||
FappeTyme.cb.werk();
|
||||
FappeTyme.cb.toggle.call({
|
||||
name: 'werk'
|
||||
});
|
||||
break;
|
||||
case Conf['Front page']:
|
||||
if (g.VIEW === 'index') {
|
||||
Index.pageNav(0);
|
||||
Index.userPageNav(0);
|
||||
} else {
|
||||
window.location = "/" + g.BOARD + "/";
|
||||
}
|
||||
@ -15012,7 +15080,7 @@
|
||||
Keybinds.hl(0, threadRoot);
|
||||
break;
|
||||
case Conf['Hide']:
|
||||
if (g.VIEW === 'index') {
|
||||
if (ThreadHiding.db) {
|
||||
ThreadHiding.toggle(thread);
|
||||
}
|
||||
break;
|
||||
@ -15125,7 +15193,7 @@
|
||||
}
|
||||
},
|
||||
hl: function(delta, thread) {
|
||||
var axe, height, next, postEl, replies, reply, root, _i, _len;
|
||||
var axis, height, next, postEl, replies, reply, root, _i, _len;
|
||||
|
||||
postEl = $('.reply.highlight', thread);
|
||||
if (!delta) {
|
||||
@ -15138,8 +15206,8 @@
|
||||
height = postEl.getBoundingClientRect().height;
|
||||
if (Header.getTopOf(postEl) >= -height && Header.getBottomOf(postEl) >= -height) {
|
||||
root = postEl.parentNode;
|
||||
axe = delta === +1 ? 'following' : 'preceding';
|
||||
if (!(next = $.x("" + axe + "-sibling::div[contains(@class,'replyContainer')][1]/child::div[contains(@class,'reply')]", root))) {
|
||||
axis = delta === +1 ? 'following' : 'preceding';
|
||||
if (!(next = $.x("" + axis + "-sibling::div[contains(@class,'replyContainer') and not(@hidden) and not(child::div[@class='stub'])][1]/child::div[contains(@class,'reply')]", root))) {
|
||||
return;
|
||||
}
|
||||
Header.scrollToIfNeeded(next, delta === +1);
|
||||
@ -15228,11 +15296,11 @@
|
||||
return $('.board');
|
||||
},
|
||||
scroll: function(delta) {
|
||||
var axe, next, thread, top;
|
||||
var axis, next, thread, top;
|
||||
|
||||
thread = Nav.getThread();
|
||||
axe = delta === +1 ? 'following' : 'preceding';
|
||||
if (next = $.x("" + axe + "-sibling::div[contains(@class,'thread') and not(@hidden)][1]", thread)) {
|
||||
axis = delta === +1 ? 'following' : 'preceding';
|
||||
if (next = $.x("" + axis + "-sibling::div[contains(@class,'thread') and not(@hidden)][1]", thread)) {
|
||||
top = Header.getTopOf(thread);
|
||||
if (delta === +1 && top < 5 || delta === -1 && top > -5) {
|
||||
thread = next;
|
||||
|
||||
@ -540,8 +540,8 @@ a.hide-announcement {
|
||||
}
|
||||
|
||||
/* File */
|
||||
.fileText:hover .fntrunc,
|
||||
.fileText:not(:hover) .fnfull,
|
||||
.file-info:hover .fntrunc,
|
||||
.file-info:not(:hover) .fnfull,
|
||||
.expanded-image > .post > .file > .fileThumb > img[data-md5],
|
||||
:not(.expanded-image) > .post > .file > .fileThumb > .full-image {
|
||||
display: none;
|
||||
|
||||
@ -51,8 +51,8 @@ Redirect =
|
||||
http: true
|
||||
https: true
|
||||
software: "foolfuuka"
|
||||
boards: ["hr", "tg", "tv", "x"]
|
||||
files: ["hr", "tg", "tv", "x"]
|
||||
boards: ["hr", "pol", "s4s", "tg", "tv", "x"]
|
||||
files: ["hr", "pol", "s4s", "tg", "tv", "x"]
|
||||
|
||||
"Nyafuu":
|
||||
domain: "archive.nyafuu.org"
|
||||
@ -62,14 +62,6 @@ Redirect =
|
||||
boards: ["c", "w", "wg"]
|
||||
files: ["c", "w", "wg"]
|
||||
|
||||
"fap archive":
|
||||
domain: "fuuka.worldathleticproject.org"
|
||||
http: true
|
||||
https: true
|
||||
software: "foolfuuka"
|
||||
boards: ["adv", "b", "cm", "d", "e", "h", "hc", "lgbt", "pol", "r", "s", "s4s", "soc", "trv", "u", "y"]
|
||||
files: ["b", "cm", "d", "e", "h", "hc", "pol", "r", "s", "s4s", "soc", "u", "y"]
|
||||
|
||||
"Install Gentoo":
|
||||
domain: "archive.installgentoo.net"
|
||||
http: false
|
||||
@ -91,7 +83,7 @@ Redirect =
|
||||
http: true
|
||||
software: "fuuka"
|
||||
boards: ["an", "fit", "k", "mlp", "r9k", "toy"]
|
||||
files: ["an", "k", "toy"]
|
||||
files: ["an", "fit", "k", "r9k", "toy"]
|
||||
|
||||
"warosu":
|
||||
domain: "fuuka.warosu.org"
|
||||
@ -101,6 +93,14 @@ Redirect =
|
||||
boards: ["3", "cgl", "ck", "fa", "ic", "jp", "lit", "tg", "vr"]
|
||||
files: ["3", "cgl", "ck", "fa", "ic", "jp", "lit", "tg", "vr"]
|
||||
|
||||
"Bui's Archive":
|
||||
domain: "archive.bui.pm"
|
||||
http: true
|
||||
https: true
|
||||
software: "foolfuuka"
|
||||
boards: ["b"]
|
||||
files: ["b"]
|
||||
|
||||
"Foolz Beta":
|
||||
domain: "beta.foolz.us"
|
||||
http: true
|
||||
|
||||
@ -124,7 +124,7 @@ Build =
|
||||
|
||||
if file?.isDeleted
|
||||
fileHTML = if isOP
|
||||
"<div class=file id=f#{postID}><div class=fileInfo></div><span class=fileThumb>" +
|
||||
"<div class=file id=f#{postID}><span class=fileThumb>" +
|
||||
"<img src='#{staticPath}filedeleted#{gifIcon}' alt='File deleted.' class=fileDeleted>" +
|
||||
"</span></div>"
|
||||
else
|
||||
|
||||
@ -836,12 +836,18 @@ http://iqdb.org/?url=%TURL
|
||||
#//archive.installgentoo.net/%board/image/%MD5;text:View same on installgentoo /%board/
|
||||
"""
|
||||
|
||||
FappeT:
|
||||
fappe: false
|
||||
werk: true
|
||||
|
||||
'Custom CSS': false
|
||||
|
||||
Index:
|
||||
'Index Mode': 'paged'
|
||||
'Index Sort': 'bump'
|
||||
'Show Replies': true
|
||||
'Anchor Hidden Threads': true
|
||||
'Refreshed Navigation': false
|
||||
|
||||
Header:
|
||||
'Fixed Header': true
|
||||
|
||||
@ -38,18 +38,33 @@ Index =
|
||||
$.on input, 'change', @cb.sort
|
||||
|
||||
repliesEntry =
|
||||
el: $.el 'label', innerHTML: '<input type=checkbox name="Show Replies"> Show replies'
|
||||
input = repliesEntry.el.firstChild
|
||||
input.checked = Conf['Show Replies']
|
||||
$.on input, 'change', $.cb.checked
|
||||
$.on input, 'change', @cb.replies
|
||||
el: $.el 'label',
|
||||
innerHTML: '<input type=checkbox name="Show Replies"> Show replies'
|
||||
anchorEntry =
|
||||
el: $.el 'label',
|
||||
innerHTML: '<input type=checkbox name="Anchor Hidden Threads"> Anchor hidden threads'
|
||||
title: 'Move hidden threads at the end of the index.'
|
||||
refNavEntry =
|
||||
el: $.el 'label',
|
||||
innerHTML: '<input type=checkbox name="Refreshed Navigation"> Refreshed navigation'
|
||||
title: 'Refresh index when navigating through pages.'
|
||||
for label in [repliesEntry, anchorEntry, refNavEntry]
|
||||
input = label.el.firstChild
|
||||
{name} = input
|
||||
input.checked = Conf[name]
|
||||
$.on input, 'change', $.cb.checked
|
||||
switch name
|
||||
when 'Show Replies'
|
||||
$.on input, 'change', @cb.replies
|
||||
when 'Anchor Hidden Threads'
|
||||
$.on input, 'change', @cb.sort
|
||||
|
||||
$.event 'AddMenuEntry',
|
||||
type: 'header'
|
||||
el: $.el 'span',
|
||||
textContent: 'Index Navigation'
|
||||
order: 90
|
||||
subEntries: [modeEntry, sortEntry, repliesEntry]
|
||||
subEntries: [modeEntry, sortEntry, repliesEntry, anchorEntry, refNavEntry]
|
||||
|
||||
$.addClass doc, 'index-loading'
|
||||
@update()
|
||||
@ -111,13 +126,18 @@ Index =
|
||||
return
|
||||
return if a.textContent is 'Catalog'
|
||||
e.preventDefault()
|
||||
Index.pageNav +a.pathname.split('/')[2]
|
||||
Index.userPageNav +a.pathname.split('/')[2]
|
||||
|
||||
scrollToIndex: ->
|
||||
Header.scrollToIfNeeded Index.root
|
||||
|
||||
getCurrentPage: ->
|
||||
+window.location.pathname.split('/')[2]
|
||||
userPageNav: (pageNum) ->
|
||||
if Conf['Refreshed Navigation'] and Conf['Index Mode'] is 'paged'
|
||||
Index.update pageNum
|
||||
else
|
||||
Index.pageNav pageNum
|
||||
pageNav: (pageNum) ->
|
||||
return if Index.currentPage is pageNum
|
||||
history.pushState null, '', if pageNum is 0 then './' else pageNum
|
||||
@ -174,7 +194,7 @@ Index =
|
||||
$.before a, strong
|
||||
$.add strong, a
|
||||
|
||||
update: ->
|
||||
update: (pageNum) ->
|
||||
return unless navigator.onLine
|
||||
Index.req?.abort()
|
||||
Index.notice?.close()
|
||||
@ -189,13 +209,15 @@ Index =
|
||||
return unless Index.req and !Index.notice
|
||||
Index.notice = new Notice 'info', 'Refreshing index...'
|
||||
), 5 * $.SECOND - (Date.now() - now)
|
||||
pageNum = null if typeof pageNum isnt 'number' # event
|
||||
onload = (e) -> Index.load e, pageNum
|
||||
Index.req = $.ajax "//a.4cdn.org/#{g.BOARD}/catalog.json",
|
||||
onabort: Index.load
|
||||
onloadend: Index.load
|
||||
onabort: onload
|
||||
onloadend: onload
|
||||
,
|
||||
whenModified: true
|
||||
$.addClass Index.button, 'fa-spin'
|
||||
load: (e) ->
|
||||
load: (e, pageNum) ->
|
||||
$.rmClass Index.button, 'fa-spin'
|
||||
{req, notice} = Index
|
||||
delete Index.req
|
||||
@ -207,7 +229,10 @@ Index =
|
||||
return
|
||||
|
||||
try
|
||||
Index.parse JSON.parse req.response if req.status is 200
|
||||
if req.status is 200
|
||||
Index.parse JSON.parse(req.response), pageNum
|
||||
else if req.status is 304 and pageNum?
|
||||
Index.pageNav pageNum
|
||||
catch err
|
||||
c.error 'Index failure:', err.stack
|
||||
# network error or non-JSON content for example.
|
||||
@ -225,15 +250,18 @@ Index =
|
||||
setTimeout notice.close, $.SECOND
|
||||
|
||||
timeEl = $ '#index-last-refresh', Index.navLinks
|
||||
timeEl.dataset.utc = e.timeStamp <% if (type === 'userscript') { %>/ 1000<% } %>
|
||||
timeEl.dataset.utc = Date.parse req.getResponseHeader 'Last-Modified'
|
||||
RelativeDates.update timeEl
|
||||
Index.scrollToIndex()
|
||||
parse: (pages) ->
|
||||
parse: (pages, pageNum) ->
|
||||
Index.parseThreadList pages
|
||||
Index.buildThreads()
|
||||
Index.sort()
|
||||
Index.buildIndex()
|
||||
Index.buildPagelist()
|
||||
if pageNum?
|
||||
Index.pageNav pageNum
|
||||
return
|
||||
Index.buildIndex()
|
||||
Index.setPage()
|
||||
parseThreadList: (pages) ->
|
||||
Index.pagesNum = pages.length
|
||||
@ -319,15 +347,15 @@ Index =
|
||||
Index.sortedNodes.push Index.nodes[i], Index.nodes[i + 1]
|
||||
if Index.isSearching
|
||||
Index.sortedNodes = Index.querySearch(Index.searchInput.value) or Index.sortedNodes
|
||||
# Put the sticky threads on top of the index.
|
||||
# Sticky threads
|
||||
Index.sortOnTop (thread) -> thread.isSticky
|
||||
# Highlighted threads
|
||||
Index.sortOnTop((thread) -> thread.isOnTop) if Conf['Filter']
|
||||
# Non-hidden threads
|
||||
Index.sortOnTop((thread) -> !thread.isHidden) if Conf['Anchor Hidden Threads']
|
||||
sortOnTop: (match) ->
|
||||
offset = 0
|
||||
for threadRoot, i in Index.sortedNodes by 2 when Get.threadFromRoot(threadRoot).isSticky
|
||||
Index.sortedNodes.splice offset++ * 2, 0, Index.sortedNodes.splice(i, 2)...
|
||||
return unless Conf['Filter']
|
||||
# Put the highlighted thread & <hr> on top of the index
|
||||
# while keeping the original order they appear in.
|
||||
offset = 0
|
||||
for threadRoot, i in Index.sortedNodes by 2 when Get.threadFromRoot(threadRoot).isOnTop
|
||||
for threadRoot, i in Index.sortedNodes by 2 when match Get.threadFromRoot threadRoot
|
||||
Index.sortedNodes.splice offset++ * 2, 0, Index.sortedNodes.splice(i, 2)...
|
||||
return
|
||||
buildIndex: ->
|
||||
|
||||
@ -150,11 +150,11 @@ a {
|
||||
.fixed.top-header #header-bar {
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
.fixed.bottom #header-bar {
|
||||
.fixed.bottom-header #header-bar {
|
||||
box-shadow: 0 -1px 2px rgba(0, 0, 0, .15);
|
||||
border-top-width: 1px;
|
||||
}
|
||||
.fixed.bottom #header-bar .menu-button i {
|
||||
.fixed.bottom-header #header-bar .menu-button i {
|
||||
border-top: none;
|
||||
border-bottom: 6px solid;
|
||||
}
|
||||
@ -170,7 +170,7 @@ a {
|
||||
-webkit-transform: translateY(-100%);
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
.fixed.bottom #header-bar.autohide:not(:hover) {
|
||||
.fixed.bottom-header #header-bar.autohide:not(:hover) {
|
||||
-webkit-transform: translateY(100%);
|
||||
transform: translateY(100%);
|
||||
}
|
||||
@ -666,10 +666,15 @@ a.hide-announcement {
|
||||
max-width: 75%;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
/* Fappe Tyme */
|
||||
.fappeTyme .thread > .noFile,
|
||||
.fappeTyme .threadContainer > .noFile {
|
||||
display: none;
|
||||
}
|
||||
/* Werk Tyme */
|
||||
.werkTyme .post .file {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Index/Reply Navigation */
|
||||
#navlinks {
|
||||
|
||||
@ -2,28 +2,21 @@ FappeTyme =
|
||||
init: ->
|
||||
return if !(Conf['Fappe Tyme'] or Conf['Werk Tyme']) or g.VIEW is 'catalog' or g.BOARD is 'f'
|
||||
|
||||
if Conf['Fappe Tyme']
|
||||
for type in ["Fappe", "Werk"] when Conf["#{type} Tyme"]
|
||||
lc = type.toLowerCase()
|
||||
el = $.el 'a',
|
||||
href: 'javascript:;'
|
||||
id: 'fappeTyme'
|
||||
title: 'Fappe Tyme'
|
||||
id: "#{lc}Tyme"
|
||||
title: "#{type} Tyme"
|
||||
className: 'a-icon'
|
||||
|
||||
if type is 'Werk'
|
||||
el.textContent = '\uf0b1'
|
||||
el.className = 'fa'
|
||||
|
||||
$.on el, 'click', FappeTyme.cb.fappe
|
||||
|
||||
Header.addShortcut el, true
|
||||
|
||||
if Conf['Werk Tyme']
|
||||
el = $.el 'a',
|
||||
href: 'javascript:;'
|
||||
id: 'werkTyme'
|
||||
title: 'Werk Tyme'
|
||||
className: 'fa'
|
||||
textContent: '\uf0b1'
|
||||
|
||||
$.on el, 'click', FappeTyme.cb.werk
|
||||
|
||||
$.on el, 'click', FappeTyme.cb.toggle.bind {name: "#{lc}"}
|
||||
Header.addShortcut el, true
|
||||
FappeTyme.cb.set type if Conf[lc]
|
||||
|
||||
Post.callbacks.push
|
||||
name: 'Fappe Tyme'
|
||||
@ -34,7 +27,11 @@ FappeTyme =
|
||||
$.addClass @nodes.root, "noFile"
|
||||
|
||||
cb:
|
||||
fappe: ->
|
||||
$.toggleClass doc, 'fappeTyme'
|
||||
werk: ->
|
||||
$.toggleClass doc, 'werkTyme'
|
||||
set: (type) ->
|
||||
FappeTyme[type].checked = Conf[type]
|
||||
$["#{if Conf[type] then 'add' else 'rm'}Class"] doc, "#{type}Tyme"
|
||||
|
||||
toggle: ->
|
||||
Conf[@name] = !Conf[@name]
|
||||
FappeTyme.cb.set @name
|
||||
$.cb.checked.call {name: @name, checked: Conf[@name]}
|
||||
@ -8,7 +8,7 @@ FileInfo =
|
||||
cb: @node
|
||||
node: ->
|
||||
return if !@file or @isClone
|
||||
@file.text.innerHTML = FileInfo.funk FileInfo, @
|
||||
@file.text.innerHTML = "<span class=file-info>#{FileInfo.funk FileInfo, @}</span>"
|
||||
createFunc: (format) ->
|
||||
code = format.replace /%(.)/g, (s, c) ->
|
||||
if c of FileInfo.formatters
|
||||
@ -21,11 +21,10 @@ FileInfo =
|
||||
return "#{size.toFixed()} Bytes"
|
||||
i = 1 + ['KB', 'MB'].indexOf unit
|
||||
size /= 1024 while i--
|
||||
size =
|
||||
if unit is 'MB'
|
||||
Math.round(size * 100) / 100
|
||||
else
|
||||
size.toFixed()
|
||||
size = if unit is 'MB'
|
||||
Math.round(size * 100) / 100
|
||||
else
|
||||
size.toFixed()
|
||||
"#{size} #{unit}"
|
||||
escape: (name) ->
|
||||
name.replace /<|>/g, (c) ->
|
||||
|
||||
@ -81,13 +81,13 @@ Keybinds =
|
||||
when Conf['Open Gallery']
|
||||
Gallery.cb.toggle()
|
||||
when Conf['fappeTyme']
|
||||
FappeTyme.cb.fappe()
|
||||
FappeTyme.cb.toggle.call {name: 'fappe'}
|
||||
when Conf['werkTyme']
|
||||
FappeTyme.cb.werk()
|
||||
FappeTyme.cb.toggle.call {name: 'werk'}
|
||||
# Board Navigation
|
||||
when Conf['Front page']
|
||||
if g.VIEW is 'index'
|
||||
Index.pageNav 0
|
||||
Index.userPageNav 0
|
||||
else
|
||||
window.location = "/#{g.BOARD}/"
|
||||
when Conf['Open front page']
|
||||
@ -126,7 +126,7 @@ Keybinds =
|
||||
when Conf['Deselect reply']
|
||||
Keybinds.hl 0, threadRoot
|
||||
when Conf['Hide']
|
||||
ThreadHiding.toggle thread if g.VIEW is 'index'
|
||||
ThreadHiding.toggle thread if ThreadHiding.db
|
||||
when Conf['Previous Post Quoting You']
|
||||
QuoteYou.cb.seek 'preceding'
|
||||
when Conf['Next Post Quoting You']
|
||||
@ -223,11 +223,11 @@ Keybinds =
|
||||
{height} = postEl.getBoundingClientRect()
|
||||
if Header.getTopOf(postEl) >= -height and Header.getBottomOf(postEl) >= -height # We're at least partially visible
|
||||
root = postEl.parentNode
|
||||
axe = if delta is +1
|
||||
axis = if delta is +1
|
||||
'following'
|
||||
else
|
||||
'preceding'
|
||||
return unless next = $.x "#{axe}-sibling::div[contains(@class,'replyContainer')][1]/child::div[contains(@class,'reply')]", root
|
||||
return unless next = $.x "#{axis}-sibling::div[contains(@class,'replyContainer') and not(@hidden) and not(child::div[@class='stub'])][1]/child::div[contains(@class,'reply')]", root
|
||||
Header.scrollToIfNeeded next, delta is +1
|
||||
@focus next
|
||||
$.rmClass postEl, 'highlight'
|
||||
|
||||
@ -43,11 +43,11 @@ Nav =
|
||||
|
||||
scroll: (delta) ->
|
||||
thread = Nav.getThread()
|
||||
axe = if delta is +1
|
||||
axis = if delta is +1
|
||||
'following'
|
||||
else
|
||||
'preceding'
|
||||
if next = $.x "#{axe}-sibling::div[contains(@class,'thread') and not(@hidden)][1]", thread
|
||||
if next = $.x "#{axis}-sibling::div[contains(@class,'thread') and not(@hidden)][1]", thread
|
||||
# Unless we're not at the beginning of the current thread,
|
||||
# and thus wanting to move to beginning,
|
||||
# or we're above the first thread and don't want to skip it.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user