Merge branch 'v3' into Av2

Conflicts:
	builds/4chan-X.js
	builds/4chan-X.user.js
	builds/crx/script.js
	src/css/style.css
	src/features/filtering/replyhiding.coffee
	src/features/filtering/threadhiding.coffee
	src/features/misc/header.coffee
	src/settings.coffee
This commit is contained in:
Zixaphir 2013-04-22 23:48:42 -07:00
commit de26c643b2
14 changed files with 248 additions and 257 deletions

View File

@ -50,7 +50,7 @@
Config = {
main: {
'Miscellaneous': {
'Catalog Links': [true, 'Turn Navigation links into links to each board\'s catalog.'],
'Catalog Links': [true, 'Add toggle link in header menu to turn Navigation links into links to each board\'s catalog.'],
'External Catalog': [false, 'Link to external catalog instead of the internal one.'],
'Custom Board Navigation': [false, 'Show custom links instead of the full board list.'],
'QR Shortcut': [false, 'Adds a small [QR] link in the header.'],
@ -76,8 +76,8 @@
'Anonymize': [false, 'Make everyone Anonymous.'],
'Filter': [true, 'Self-moderation placebo.'],
'Recursive Hiding': [true, 'Hide replies of hidden posts, recursively.'],
'Thread Hiding': [true, 'Add buttons to hide entire threads.'],
'Reply Hiding': [true, 'Add buttons to hide single replies.'],
'Thread Hiding Buttons': [true, 'Add buttons to hide entire threads.'],
'Reply Hiding Buttons': [true, 'Add buttons to hide single replies.'],
'Stubs': [true, 'Show stubs of hidden threads / replies.']
},
'Images': {
@ -102,7 +102,7 @@
'Thread Updater': [true, 'Fetch and insert new replies. Has more options in its own dialog.'],
'Unread Count': [true, 'Show the unread posts count in the tab title.'],
'Hide Unread Count at (0)': [false, 'Hide the unread posts count when it reaches 0.'],
'Unread Tab Icon': [true, 'Show a different favicon when there are unread posts.'],
'Unread Favicon': [true, 'Show a different favicon when there are unread posts.'],
'Unread Line': [true, 'Show a line to distinguish read posts from unread ones.'],
'Scroll to Last Read Post': [true, 'Scroll back to the last read post when reopening a thread.'],
'Thread Excerpt': [true, 'Show an excerpt of the thread in the tab title.'],
@ -247,19 +247,19 @@
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/",
'Boards Navigation': 'sticky top',
'Custom CSS': false,
'Boards Navigation': 'sticky top',
'Boards Navigation': 'Sticky top',
'Header auto-hide': false,
'Header catalog links': false,
boardnav: '[ toggle-all ] [current-title]',
time: '%m/%d/%y(%a)%H:%M:%S',
backlink: '>>%id',
fileInfo: '%l (%p%s, %r)',
fileInfo: '%L (%p%s, %r)',
favicon: 'ferongr',
usercss: "/* Tripcode Italics: */\n/*\nspan.postertrip {\nfont-style: italic;\n}\n*/\n\n/* Add a rounded border to thumbnails (but not expanded images): */\n/*\n.fileThumb > img:first-child {\nborder: solid 2px rgba(0,0,100,0.5);\nborder-radius: 10px;\n}\n*/\n\n/* Make highlighted posts look inset on the page: */\n/*\ndiv.post:target,\ndiv.post.highlight {\nbox-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);\n}\n*/",
hotkeys: {
'Toggle board list': ['Ctrl+b', 'Toggle the full board list.'],
'Open empty QR': ['q', 'Open QR without post number inserted.'],
'Open QR': ['Shift+q', 'Open QR with post number inserted.'],
'Open empty QR': ['l', 'Open QR without post number inserted.'],
'Open QR': ['Shift+l', 'Open QR with post number inserted.'],
'Open settings': ['Alt+o', 'Open Settings.'],
'Close': ['Esc', 'Close Settings, Notifications or QR.'],
'Spoiler tags': ['Ctrl+s', 'Insert spoiler tags.'],
@ -4738,7 +4738,7 @@
PostHiding = {
init: function() {
if (g.VIEW === 'catalog' || !Conf['Reply Hiding'] && !Conf['Reply Hiding Link']) {
if (g.VIEW === 'catalog' || !Conf['Reply Hiding Buttons'] && !Conf['Reply Hiding Link']) {
return;
}
this.db = new DataBoard('hiddenPosts');
@ -4765,7 +4765,7 @@
Recursive.add(PostHiding.hide, this, data.makeStub, true);
}
}
if (!Conf['Reply Hiding']) {
if (!Conf['Reply Hiding Buttons']) {
return;
}
return $.add($('.postInfo', this.nodes.post), PostHiding.makeButton(this, 'hide'));
@ -5016,7 +5016,7 @@
QuoteStrikeThrough = {
init: function() {
if (g.VIEW === 'catalog' || !Conf['Reply Hiding'] && !Conf['Reply Hiding Link'] && !Conf['Filter']) {
if (g.VIEW === 'catalog' || !Conf['Reply Hiding Buttons'] && !Conf['Reply Hiding Link'] && !Conf['Filter']) {
return;
}
return Post.prototype.callbacks.push({
@ -5043,7 +5043,7 @@
ThreadHiding = {
init: function() {
if (g.VIEW !== 'index' || !Conf['Thread Hiding'] && !Conf['Thread Hiding Link']) {
if (g.VIEW !== 'index' || !Conf['Thread Hiding Buttons'] && !Conf['Thread Hiding Link']) {
return;
}
this.db = new DataBoard('hiddenThreads');
@ -5062,7 +5062,7 @@
})) {
ThreadHiding.hide(this, data.makeStub);
}
if (!Conf['Thread Hiding']) {
if (!Conf['Thread Hiding Buttons']) {
return;
}
return $.prepend(this.OP.nodes.info, ThreadHiding.makeButton(this, 'hide'));
@ -6406,7 +6406,7 @@
el = $.el('label', {
id: 'toggleCatalog',
href: 'javascript:;',
innerHTML: "<input type=checkbox " + (Conf['Header catalog links'] ? 'checked' : '') + ">Catalog",
innerHTML: "<input type=checkbox " + (Conf['Header catalog links'] ? 'checked' : '') + ">Catalog Links",
title: "Turn catalog links " + (Conf['Header catalog links'] ? 'off' : 'on') + "."
});
input = $('input', el);
@ -6879,7 +6879,7 @@
$.on(this.headerToggler, 'change', this.toggleBarVisibility);
createSubEntry = Header.createSubEntry;
subEntries = [];
_ref = ['sticky top', 'sticky bottom', 'top', 'hide'];
_ref = ['Sticky top', 'Sticky bottom', 'Top', 'Hide'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
setting = _ref[_i];
subEntries.push(createSubEntry(setting));
@ -6920,7 +6920,7 @@
id: 'hoverUI'
}),
toggle: $.el('div', {
id: 'toggle-header-bar'
id: 'scroll-marker'
}),
createSubEntry: function(setting) {
var label;
@ -7055,15 +7055,15 @@
$.rmClass(doc, 'bottom');
$.rmClass(doc, 'hide');
switch (setting) {
case 'sticky top':
$.addClass(doc, 'fixed');
return $.addClass(doc, 'top');
case 'sticky bottom':
case 'Sticky top':
$.addClass(doc, 'top');
return $.addClass(doc, 'fixed');
case 'Sticky bottom':
$.addClass(doc, 'fixed');
return $.addClass(doc, 'bottom');
case 'top':
case 'Top':
return $.addClass(doc, 'top');
case 'hide':
case 'Hide':
return $.addClass(doc, 'hide');
}
},
@ -7121,7 +7121,7 @@
var headRect, top;
top = post.getBoundingClientRect().top;
if (Conf['Boards Navigation'] === 'sticky top') {
if (Conf['Boards Navigation'] === 'Sticky top') {
headRect = Header.bar.getBoundingClientRect();
top += -headRect.top - headRect.height;
}
@ -7574,16 +7574,16 @@
boards: ['cgl', 'ck', 'fa', 'jp', 'lit', 's4s', 'q', 'tg'],
type: 'fuuka'
},
'RebeccaBlackTech': {
base: '//rbt.asia',
boards: ['an', 'cgl', 'g', 'mu', 'w'],
type: 'fuuka_mail'
},
'InstallGentoo': {
base: '//archive.installgentoo.net',
boards: ['diy', 'g', 'sci'],
type: 'fuuka'
},
'RebeccaBlackTech': {
base: '//rbt.asia',
boards: ['an', 'cgl', 'g', 'mu', 'w'],
type: 'fuuka_mail'
},
'Heinessen': {
base: 'http://archive.heinessen.com',
boards: ['an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'],
@ -8629,7 +8629,7 @@
Unread = {
init: function() {
if (g.VIEW !== 'thread' || !Conf['Unread Count'] && !Conf['Unread Tab Icon']) {
if (g.VIEW !== 'thread' || !Conf['Unread Count'] && !Conf['Unread Favicon']) {
return;
}
this.db = new DataBoard('lastReadPosts', this.sync);
@ -8644,8 +8644,7 @@
});
},
node: function() {
var ID, post, posts, _ref,
_this = this;
var ID, post, posts, _ref;
Unread.thread = this;
Unread.title = d.title;
@ -8668,31 +8667,29 @@
if (Conf['Unread Line']) {
$.on(d, 'visibilitychange', Unread.setLine);
}
if (Conf['Scroll to Last Read Post']) {
return $.on(window, 'load', function(posts) {
return Unread.scroll.apply(_this, posts);
});
}
},
scroll: function(posts) {
var hash, root;
if ((hash = location.hash.match(/\d+/)) && hash[0] in this.posts) {
if (!Conf['Scroll to Last Read Post']) {
return;
}
if (Unread.posts.length) {
while (root = $.x('preceding-sibling::div[contains(@class,"postContainer")][1]', Unread.posts[0].nodes.root)) {
if (!(Get.postFromRoot(root)).isHidden) {
break;
}
}
if (!root) {
return $.on(window, 'load', function() {
var hash, root;
if ((hash = location.hash.match(/\d+/)) && hash[0] in this.posts) {
return;
}
return root.scrollIntoView(false);
} else if (posts.length) {
return Header.scrollToPost(posts[post.length - 1].nodes.root);
}
if (Unread.posts.length) {
while (root = $.x('preceding-sibling::div[contains(@class,"postContainer")][1]', Unread.posts[0].nodes.root)) {
if (!(Get.postFromRoot(root)).isHidden) {
break;
}
}
if (!root) {
return;
}
return root.scrollIntoView(false);
} else if (posts.length) {
return Header.scrollToPost(posts[posts.length - 1].nodes.root);
}
});
},
sync: function() {
var lastReadPost;
@ -8843,7 +8840,7 @@
if (Conf['Unread Count']) {
d.title = "" + (count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : '') + (g.DEAD ? "/" + g.BOARD + "/ - 404" : "" + Unread.title);
}
if (!Conf['Unread Tab Icon']) {
if (!Conf['Unread Favicon']) {
return;
}
Favicon.el.href = g.DEAD ? Unread.postsQuotingYou.length ? Favicon.unreadDeadY : count ? Favicon.unreadDead : Favicon.dead : count ? Unread.postsQuotingYou.length ? Favicon.unreadY : Favicon.unread : Favicon["default"];
@ -10539,7 +10536,7 @@
$.event('AddMenuEntry', {
type: 'header',
el: this.controls,
order: 115
order: 98
});
$.on(d, '4chanXInitFinished', this.setup);
return Post.prototype.callbacks.push({
@ -12532,11 +12529,14 @@
Settings.dialog = dialog = $.el('div', {
id: 'appchanx-settings',
"class": 'dialog',
innerHTML: "<nav>\n <div class=sections-list></div>\n <div class=credits>\n <a href='http://zixaphir.github.com/appchan-x/' target=_blank>appchan x</a> |\n <a href='https://github.com/zixaphir/appchan-x/blob/Av2/CHANGELOG.md' target=_blank>" + g.VERSION + "</a> |\n <a href='https://github.com/zixaphir/appchan-x/blob/Av2/CONTRIBUTING.md#reporting-bugs-and-suggestions' target=_blank>Issues</a> |\n <a href=javascript:; class=close title=Close>×</a>\n </div>\n</nav>\n<hr>\n<div class=section-container><section></section></div>"
innerHTML: "<nav>\n <div class=sections-list></div>\n <p class='imp-exp-result warning'></p>\n <div class=credits>\n <a class=export>Export</a> |\n <a class=import>Import</a> |\n <input type=file style='display: none;'>\n <a href='http://zixaphir.github.com/appchan-x/' target=_blank>appchan x</a> |\n <a href='https://github.com/zixaphir/appchan-x/blob/Av2/CHANGELOG.md' target=_blank>" + g.VERSION + "</a> |\n <a href='https://github.com/zixaphir/appchan-x/blob/Av2/CONTRIBUTING.md#reporting-bugs-and-suggestions' target=_blank>Issues</a> |\n <a href=javascript:; class=close title=Close>×</a>\n </div>\n</nav>\n<hr>\n<div class=section-container><section></section></div>"
});
Settings.overlay = overlay = $.el('div', {
id: 'overlay'
});
$.on($('.export', Settings.dialog), 'click', Settings["export"]);
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
$.on($('input', Settings.dialog), 'change', Settings.onImport);
links = [];
_ref = Settings.sections;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@ -12601,10 +12601,6 @@
main: function(section) {
var arr, button, description, div, fs, hiddenNum, input, inputs, items, key, obj, _ref;
section.innerHTML = "<div class=imp-exp>\n <button class=export>Export Settings</button>\n <button class=import>Import Settings</button>\n <input type=file style='visibility:hidden'>\n</div>\n<p class=imp-exp-result></p>";
$.on($('.export', section), 'click', Settings["export"]);
$.on($('.import', section), 'click', Settings["import"]);
$.on($('input', section), 'change', Settings.onImport);
items = {};
inputs = {};
_ref = Config.main;
@ -12732,7 +12728,7 @@
if (!(file = this.files[0])) {
return;
}
output = this.parentNode.nextElementSibling;
output = $('.imp-exp-result');
if (!confirm('Your current settings will be entirely overwritten, are you sure?')) {
output.textContent = 'Import aborted.';
return;
@ -12767,7 +12763,7 @@
'Show Stubs': 'Stubs',
'Image Auto-Gif': 'Auto-GIF',
'Expand From Current': '',
'Unread Favicon': 'Unread Tab Icon',
'Unread Tab Icon': 'Unread Favicon',
'Post in Title': 'Thread Excerpt',
'Auto Hide QR': '',
'Open Reply in New Tab': '',
@ -12776,6 +12772,8 @@
'Quote Preview': 'Quote Previewing',
'Indicate OP quote': 'Mark OP Quotes',
'Indicate Cross-thread Quotes': 'Mark Cross-thread Quotes',
'Reply Hiding': 'Reply Hiding Buttons',
'Thread Hiding': 'Thread Hiding Buttons',
'uniqueid': 'uniqueID',
'mod': 'capcode',
'country': 'flag',
@ -12889,7 +12887,7 @@
rice: function(section) {
var archiver, event, input, inputs, items, name, toSelect, _i, _j, _len, _len1, _ref;
section.innerHTML = "<fieldset>\n <legend>Archiver</legend>\n Select an Archiver for this board:\n <select name=archiver></select>\n</fieldset>\n<fieldset>\n <legend>Custom Board Navigation <span class=warning " + (Conf['Custom Board Navigation'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=boardnav class=field spellcheck=false></div>\n <div>In the following, <code>board</code> can translate to a board ID (<code>a</code>, <code>b</code>, etc...), the current board (<code>current</code>), or the Status/Twitter link (<code>status</code>, <code>@</code>).</div>\n <div>\n For example:<br>\n <code>[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]</code><br>\n will give you<br>\n <code>[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]</code><br>\n if you are on /g/.\n </div>\n <div>Board link: <code>board</code></div>\n <div>Title link: <code>board-title</code></div>\n <div>Board link (Replace with title when on that board): <code>board-replace</code></div>\n <div>Full text link: <code>board-full</code></div>\n <div>Custom text link: <code>board-text:\"VIP Board\"</code></div>\n <div>Index-only link: <code>board-index</code></div>\n <div>Catalog-only link: <code>board-catalog</code></div>\n <div>Combinations are possible: <code>board-index-text:\"VIP Index\"</code></div>\n <div>Full board list toggle: <code>toggle-all</code></div>\n</fieldset>\n\n<fieldset>\n <legend>Time Formatting <span class=warning " + (Conf['Time Formatting'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=time class=field spellcheck=false>: <span class=time-preview></span></div>\n <div>Supported <a href=//en.wikipedia.org/wiki/Date_%28Unix%29#Formatting>format specifiers</a>:</div>\n <div>Day: <code>%a</code>, <code>%A</code>, <code>%d</code>, <code>%e</code></div>\n <div>Month: <code>%m</code>, <code>%b</code>, <code>%B</code></div>\n <div>Year: <code>%y</code></div>\n <div>Hour: <code>%k</code>, <code>%H</code>, <code>%l</code>, <code>%I</code>, <code>%p</code>, <code>%P</code></div>\n <div>Minute: <code>%M</code></div>\n <div>Second: <code>%S</code></div>\n</fieldset>\n\n<fieldset>\n <legend>Quote Backlinks formatting <span class=warning " + (Conf['Quote Backlinks'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=backlink class=field spellcheck=false>: <span class=backlink-preview></span></div>\n</fieldset>\n\n<fieldset>\n <legend>File Info Formatting <span class=warning " + (Conf['File Info Formatting'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=fileInfo class=field spellcheck=false>: <span class='fileText file-info-preview'></span></div>\n <div>Link: <code>%l</code> (truncated), <code>%L</code> (untruncated), <code>%T</code> (Unix timestamp)</div>\n <div>Original file name: <code>%n</code> (truncated), <code>%N</code> (untruncated), <code>%t</code> (Unix timestamp)</div>\n <div>Spoiler indicator: <code>%p</code></div>\n <div>Size: <code>%B</code> (Bytes), <code>%K</code> (KB), <code>%M</code> (MB), <code>%s</code> (4chan default)</div>\n <div>Resolution: <code>%r</code> (Displays 'PDF' for PDF files)</div>\n</fieldset>\n\n<fieldset>\n <legend>Unread Tab Icon <span class=warning " + (Conf['Unread Tab Icon'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <select name=favicon>\n <option value=ferongr>ferongr</option>\n <option value=xat->xat-</option>\n <option value=Mayhem>Mayhem</option>\n <option value=Original>Original</option>\n </select>\n <span class=favicon-preview></span>\n</fieldset>\n\n<fieldset>\n <legend><input type=checkbox name='Custom CSS' " + (Conf['Custom CSS'] ? 'checked' : '') + "> Custom CSS</legend>\n <button id=apply-css>Apply CSS</button>\n <textarea name=usercss class=field spellcheck=false " + (Conf['Custom CSS'] ? '' : 'disabled') + "></textarea>\n</fieldset>";
section.innerHTML = "<fieldset>\n <legend>Archiver</legend>\n Select an Archiver for this board:\n <select name=archiver></select>\n</fieldset>\n<fieldset>\n <legend>Custom Board Navigation <span class=warning " + (Conf['Custom Board Navigation'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=boardnav class=field spellcheck=false></div>\n <div>In the following, <code>board</code> can translate to a board ID (<code>a</code>, <code>b</code>, etc...), the current board (<code>current</code>), or the Status/Twitter link (<code>status</code>, <code>@</code>).</div>\n <div>\n For example:<br>\n <code>[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]</code><br>\n will give you<br>\n <code>[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]</code><br>\n if you are on /g/.\n </div>\n <div>Board link: <code>board</code></div>\n <div>Title link: <code>board-title</code></div>\n <div>Board link (Replace with title when on that board): <code>board-replace</code></div>\n <div>Full text link: <code>board-full</code></div>\n <div>Custom text link: <code>board-text:\"VIP Board\"</code></div>\n <div>Index-only link: <code>board-index</code></div>\n <div>Catalog-only link: <code>board-catalog</code></div>\n <div>Combinations are possible: <code>board-index-text:\"VIP Index\"</code></div>\n <div>Full board list toggle: <code>toggle-all</code></div>\n</fieldset>\n\n<fieldset>\n <legend>Time Formatting <span class=warning " + (Conf['Time Formatting'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=time class=field spellcheck=false>: <span class=time-preview></span></div>\n <div>Supported <a href=//en.wikipedia.org/wiki/Date_%28Unix%29#Formatting>format specifiers</a>:</div>\n <div>Day: <code>%a</code>, <code>%A</code>, <code>%d</code>, <code>%e</code></div>\n <div>Month: <code>%m</code>, <code>%b</code>, <code>%B</code></div>\n <div>Year: <code>%y</code></div>\n <div>Hour: <code>%k</code>, <code>%H</code>, <code>%l</code>, <code>%I</code>, <code>%p</code>, <code>%P</code></div>\n <div>Minute: <code>%M</code></div>\n <div>Second: <code>%S</code></div>\n</fieldset>\n\n<fieldset>\n <legend>Quote Backlinks formatting <span class=warning " + (Conf['Quote Backlinks'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=backlink class=field spellcheck=false>: <span class=backlink-preview></span></div>\n</fieldset>\n\n<fieldset>\n <legend>File Info Formatting <span class=warning " + (Conf['File Info Formatting'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=fileInfo class=field spellcheck=false>: <span class='fileText file-info-preview'></span></div>\n <div>Link: <code>%l</code> (truncated), <code>%L</code> (untruncated), <code>%T</code> (Unix timestamp)</div>\n <div>Original file name: <code>%n</code> (truncated), <code>%N</code> (untruncated), <code>%t</code> (Unix timestamp)</div>\n <div>Spoiler indicator: <code>%p</code></div>\n <div>Size: <code>%B</code> (Bytes), <code>%K</code> (KB), <code>%M</code> (MB), <code>%s</code> (4chan default)</div>\n <div>Resolution: <code>%r</code> (Displays 'PDF' for PDF files)</div>\n</fieldset>\n\n<fieldset>\n <legend>Unread Favicon <span class=warning " + (Conf['Unread Favicon'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <select name=favicon>\n <option value=ferongr>ferongr</option>\n <option value=xat->xat-</option>\n <option value=Mayhem>Mayhem</option>\n <option value=Original>Original</option>\n </select>\n <span class=favicon-preview></span>\n</fieldset>\n\n<fieldset>\n <legend><input type=checkbox name='Custom CSS' " + (Conf['Custom CSS'] ? 'checked' : '') + "> Custom CSS</legend>\n <button id=apply-css>Apply CSS</button>\n <textarea name=usercss class=field spellcheck=false " + (Conf['Custom CSS'] ? '' : 'disabled') + "></textarea>\n</fieldset>";
items = {};
inputs = {};
_ref = ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'usercss'];
@ -12969,7 +12967,7 @@
},
favicon: function() {
Favicon["switch"]();
if (g.VIEW === 'thread' && Conf['Unread Tab Icon']) {
if (g.VIEW === 'thread' && Conf['Unread Favicon']) {
Unread.update();
}
return this.nextElementSibling.innerHTML = "<img src=" + Favicon["default"] + ">\n<img src=" + Favicon.unreadSFW + ">\n<img src=" + Favicon.unreadNSFW + ">\n<img src=" + Favicon.unreadDead + ">";
@ -13645,8 +13643,8 @@
'Linkify': Linkify,
'Resurrect Quotes': Quotify,
'Filter': Filter,
'Thread Hiding': ThreadHiding,
'Reply Hiding': PostHiding,
'Thread Hiding Buttons': ThreadHiding,
'Reply Hiding Buttons': PostHiding,
'Recursive': Recursive,
'Strike-through Quotes': QuoteStrikeThrough,
'Quick Reply': QR,

View File

@ -50,7 +50,7 @@
Config = {
main: {
'Miscellaneous': {
'Catalog Links': [true, 'Turn Navigation links into links to each board\'s catalog.'],
'Catalog Links': [true, 'Add toggle link in header menu to turn Navigation links into links to each board\'s catalog.'],
'External Catalog': [false, 'Link to external catalog instead of the internal one.'],
'Custom Board Navigation': [false, 'Show custom links instead of the full board list.'],
'QR Shortcut': [false, 'Adds a small [QR] link in the header.'],
@ -76,8 +76,8 @@
'Anonymize': [false, 'Make everyone Anonymous.'],
'Filter': [true, 'Self-moderation placebo.'],
'Recursive Hiding': [true, 'Hide replies of hidden posts, recursively.'],
'Thread Hiding': [true, 'Add buttons to hide entire threads.'],
'Reply Hiding': [true, 'Add buttons to hide single replies.'],
'Thread Hiding Buttons': [true, 'Add buttons to hide entire threads.'],
'Reply Hiding Buttons': [true, 'Add buttons to hide single replies.'],
'Stubs': [true, 'Show stubs of hidden threads / replies.']
},
'Images': {
@ -102,7 +102,7 @@
'Thread Updater': [true, 'Fetch and insert new replies. Has more options in its own dialog.'],
'Unread Count': [true, 'Show the unread posts count in the tab title.'],
'Hide Unread Count at (0)': [false, 'Hide the unread posts count when it reaches 0.'],
'Unread Tab Icon': [true, 'Show a different favicon when there are unread posts.'],
'Unread Favicon': [true, 'Show a different favicon when there are unread posts.'],
'Unread Line': [true, 'Show a line to distinguish read posts from unread ones.'],
'Scroll to Last Read Post': [true, 'Scroll back to the last read post when reopening a thread.'],
'Thread Excerpt': [true, 'Show an excerpt of the thread in the tab title.'],
@ -248,19 +248,19 @@
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/",
'Boards Navigation': 'sticky top',
'Custom CSS': false,
'Boards Navigation': 'sticky top',
'Boards Navigation': 'Sticky top',
'Header auto-hide': false,
'Header catalog links': false,
boardnav: '[ toggle-all ] [current-title]',
time: '%m/%d/%y(%a)%H:%M:%S',
backlink: '>>%id',
fileInfo: '%l (%p%s, %r)',
fileInfo: '%L (%p%s, %r)',
favicon: 'ferongr',
usercss: "/* Tripcode Italics: */\n/*\nspan.postertrip {\nfont-style: italic;\n}\n*/\n\n/* Add a rounded border to thumbnails (but not expanded images): */\n/*\n.fileThumb > img:first-child {\nborder: solid 2px rgba(0,0,100,0.5);\nborder-radius: 10px;\n}\n*/\n\n/* Make highlighted posts look inset on the page: */\n/*\ndiv.post:target,\ndiv.post.highlight {\nbox-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);\n}\n*/",
hotkeys: {
'Toggle board list': ['Ctrl+b', 'Toggle the full board list.'],
'Open empty QR': ['q', 'Open QR without post number inserted.'],
'Open QR': ['Shift+q', 'Open QR with post number inserted.'],
'Open empty QR': ['l', 'Open QR without post number inserted.'],
'Open QR': ['Shift+l', 'Open QR with post number inserted.'],
'Open settings': ['Alt+o', 'Open Settings.'],
'Close': ['Esc', 'Close Settings, Notifications or QR.'],
'Spoiler tags': ['Ctrl+s', 'Insert spoiler tags.'],
@ -4729,7 +4729,7 @@
PostHiding = {
init: function() {
if (g.VIEW === 'catalog' || !Conf['Reply Hiding'] && !Conf['Reply Hiding Link']) {
if (g.VIEW === 'catalog' || !Conf['Reply Hiding Buttons'] && !Conf['Reply Hiding Link']) {
return;
}
this.db = new DataBoard('hiddenPosts');
@ -4756,7 +4756,7 @@
Recursive.add(PostHiding.hide, this, data.makeStub, true);
}
}
if (!Conf['Reply Hiding']) {
if (!Conf['Reply Hiding Buttons']) {
return;
}
return $.add($('.postInfo', this.nodes.post), PostHiding.makeButton(this, 'hide'));
@ -5007,7 +5007,7 @@
QuoteStrikeThrough = {
init: function() {
if (g.VIEW === 'catalog' || !Conf['Reply Hiding'] && !Conf['Reply Hiding Link'] && !Conf['Filter']) {
if (g.VIEW === 'catalog' || !Conf['Reply Hiding Buttons'] && !Conf['Reply Hiding Link'] && !Conf['Filter']) {
return;
}
return Post.prototype.callbacks.push({
@ -5034,7 +5034,7 @@
ThreadHiding = {
init: function() {
if (g.VIEW !== 'index' || !Conf['Thread Hiding'] && !Conf['Thread Hiding Link']) {
if (g.VIEW !== 'index' || !Conf['Thread Hiding Buttons'] && !Conf['Thread Hiding Link']) {
return;
}
this.db = new DataBoard('hiddenThreads');
@ -5053,7 +5053,7 @@
})) {
ThreadHiding.hide(this, data.makeStub);
}
if (!Conf['Thread Hiding']) {
if (!Conf['Thread Hiding Buttons']) {
return;
}
return $.prepend(this.OP.nodes.info, ThreadHiding.makeButton(this, 'hide'));
@ -6397,7 +6397,7 @@
el = $.el('label', {
id: 'toggleCatalog',
href: 'javascript:;',
innerHTML: "<input type=checkbox " + (Conf['Header catalog links'] ? 'checked' : '') + ">Catalog",
innerHTML: "<input type=checkbox " + (Conf['Header catalog links'] ? 'checked' : '') + ">Catalog Links",
title: "Turn catalog links " + (Conf['Header catalog links'] ? 'off' : 'on') + "."
});
input = $('input', el);
@ -6870,7 +6870,7 @@
$.on(this.headerToggler, 'change', this.toggleBarVisibility);
createSubEntry = Header.createSubEntry;
subEntries = [];
_ref = ['sticky top', 'sticky bottom', 'top', 'hide'];
_ref = ['Sticky top', 'Sticky bottom', 'Top', 'Hide'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
setting = _ref[_i];
subEntries.push(createSubEntry(setting));
@ -6911,7 +6911,7 @@
id: 'hoverUI'
}),
toggle: $.el('div', {
id: 'toggle-header-bar'
id: 'scroll-marker'
}),
createSubEntry: function(setting) {
var label;
@ -7046,15 +7046,15 @@
$.rmClass(doc, 'bottom');
$.rmClass(doc, 'hide');
switch (setting) {
case 'sticky top':
$.addClass(doc, 'fixed');
return $.addClass(doc, 'top');
case 'sticky bottom':
case 'Sticky top':
$.addClass(doc, 'top');
return $.addClass(doc, 'fixed');
case 'Sticky bottom':
$.addClass(doc, 'fixed');
return $.addClass(doc, 'bottom');
case 'top':
case 'Top':
return $.addClass(doc, 'top');
case 'hide':
case 'Hide':
return $.addClass(doc, 'hide');
}
},
@ -7112,7 +7112,7 @@
var headRect, top;
top = post.getBoundingClientRect().top;
if (Conf['Boards Navigation'] === 'sticky top') {
if (Conf['Boards Navigation'] === 'Sticky top') {
headRect = Header.bar.getBoundingClientRect();
top += -headRect.top - headRect.height;
}
@ -7565,16 +7565,16 @@
boards: ['cgl', 'ck', 'fa', 'jp', 'lit', 's4s', 'q', 'tg'],
type: 'fuuka'
},
'RebeccaBlackTech': {
base: '//rbt.asia',
boards: ['an', 'cgl', 'g', 'mu', 'w'],
type: 'fuuka_mail'
},
'InstallGentoo': {
base: '//archive.installgentoo.net',
boards: ['diy', 'g', 'sci'],
type: 'fuuka'
},
'RebeccaBlackTech': {
base: '//rbt.asia',
boards: ['an', 'cgl', 'g', 'mu', 'w'],
type: 'fuuka_mail'
},
'Heinessen': {
base: 'http://archive.heinessen.com',
boards: ['an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'],
@ -8620,7 +8620,7 @@
Unread = {
init: function() {
if (g.VIEW !== 'thread' || !Conf['Unread Count'] && !Conf['Unread Tab Icon']) {
if (g.VIEW !== 'thread' || !Conf['Unread Count'] && !Conf['Unread Favicon']) {
return;
}
this.db = new DataBoard('lastReadPosts', this.sync);
@ -8635,8 +8635,7 @@
});
},
node: function() {
var ID, post, posts, _ref,
_this = this;
var ID, post, posts, _ref;
Unread.thread = this;
Unread.title = d.title;
@ -8659,31 +8658,29 @@
if (Conf['Unread Line']) {
$.on(d, 'visibilitychange', Unread.setLine);
}
if (Conf['Scroll to Last Read Post']) {
return $.on(window, 'load', function(posts) {
return Unread.scroll.apply(_this, posts);
});
}
},
scroll: function(posts) {
var hash, root;
if ((hash = location.hash.match(/\d+/)) && hash[0] in this.posts) {
if (!Conf['Scroll to Last Read Post']) {
return;
}
if (Unread.posts.length) {
while (root = $.x('preceding-sibling::div[contains(@class,"postContainer")][1]', Unread.posts[0].nodes.root)) {
if (!(Get.postFromRoot(root)).isHidden) {
break;
}
}
if (!root) {
return $.on(window, 'load', function() {
var hash, root;
if ((hash = location.hash.match(/\d+/)) && hash[0] in this.posts) {
return;
}
return root.scrollIntoView(false);
} else if (posts.length) {
return Header.scrollToPost(posts[post.length - 1].nodes.root);
}
if (Unread.posts.length) {
while (root = $.x('preceding-sibling::div[contains(@class,"postContainer")][1]', Unread.posts[0].nodes.root)) {
if (!(Get.postFromRoot(root)).isHidden) {
break;
}
}
if (!root) {
return;
}
return root.scrollIntoView(false);
} else if (posts.length) {
return Header.scrollToPost(posts[posts.length - 1].nodes.root);
}
});
},
sync: function() {
var lastReadPost;
@ -8834,7 +8831,7 @@
if (Conf['Unread Count']) {
d.title = "" + (count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : '') + (g.DEAD ? "/" + g.BOARD + "/ - 404" : "" + Unread.title);
}
if (!Conf['Unread Tab Icon']) {
if (!Conf['Unread Favicon']) {
return;
}
Favicon.el.href = g.DEAD ? Unread.postsQuotingYou.length ? Favicon.unreadDeadY : count ? Favicon.unreadDead : Favicon.dead : count ? Unread.postsQuotingYou.length ? Favicon.unreadY : Favicon.unread : Favicon["default"];
@ -10555,7 +10552,7 @@
$.event('AddMenuEntry', {
type: 'header',
el: this.controls,
order: 115
order: 98
});
$.on(d, '4chanXInitFinished', this.setup);
return Post.prototype.callbacks.push({
@ -12548,11 +12545,14 @@
Settings.dialog = dialog = $.el('div', {
id: 'appchanx-settings',
"class": 'dialog',
innerHTML: "<nav>\n <div class=sections-list></div>\n <div class=credits>\n <a href='http://zixaphir.github.com/appchan-x/' target=_blank>appchan x</a> |\n <a href='https://github.com/zixaphir/appchan-x/blob/Av2/CHANGELOG.md' target=_blank>" + g.VERSION + "</a> |\n <a href='https://github.com/zixaphir/appchan-x/blob/Av2/CONTRIBUTING.md#reporting-bugs-and-suggestions' target=_blank>Issues</a> |\n <a href=javascript:; class=close title=Close>×</a>\n </div>\n</nav>\n<hr>\n<div class=section-container><section></section></div>"
innerHTML: "<nav>\n <div class=sections-list></div>\n <p class='imp-exp-result warning'></p>\n <div class=credits>\n <a class=export>Export</a> |\n <a class=import>Import</a> |\n <input type=file style='display: none;'>\n <a href='http://zixaphir.github.com/appchan-x/' target=_blank>appchan x</a> |\n <a href='https://github.com/zixaphir/appchan-x/blob/Av2/CHANGELOG.md' target=_blank>" + g.VERSION + "</a> |\n <a href='https://github.com/zixaphir/appchan-x/blob/Av2/CONTRIBUTING.md#reporting-bugs-and-suggestions' target=_blank>Issues</a> |\n <a href=javascript:; class=close title=Close>×</a>\n </div>\n</nav>\n<hr>\n<div class=section-container><section></section></div>"
});
Settings.overlay = overlay = $.el('div', {
id: 'overlay'
});
$.on($('.export', Settings.dialog), 'click', Settings["export"]);
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
$.on($('input', Settings.dialog), 'change', Settings.onImport);
links = [];
_ref = Settings.sections;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@ -12617,10 +12617,6 @@
main: function(section) {
var arr, button, description, div, fs, hiddenNum, input, inputs, items, key, obj, _ref;
section.innerHTML = "<div class=imp-exp>\n <button class=export>Export Settings</button>\n <button class=import>Import Settings</button>\n <input type=file style='visibility:hidden'>\n</div>\n<p class=imp-exp-result></p>";
$.on($('.export', section), 'click', Settings["export"]);
$.on($('.import', section), 'click', Settings["import"]);
$.on($('input', section), 'change', Settings.onImport);
items = {};
inputs = {};
_ref = Config.main;
@ -12750,7 +12746,7 @@
if (!(file = this.files[0])) {
return;
}
output = this.parentNode.nextElementSibling;
output = $('.imp-exp-result');
if (!confirm('Your current settings will be entirely overwritten, are you sure?')) {
output.textContent = 'Import aborted.';
return;
@ -12785,7 +12781,7 @@
'Show Stubs': 'Stubs',
'Image Auto-Gif': 'Auto-GIF',
'Expand From Current': '',
'Unread Favicon': 'Unread Tab Icon',
'Unread Tab Icon': 'Unread Favicon',
'Post in Title': 'Thread Excerpt',
'Auto Hide QR': '',
'Open Reply in New Tab': '',
@ -12794,6 +12790,8 @@
'Quote Preview': 'Quote Previewing',
'Indicate OP quote': 'Mark OP Quotes',
'Indicate Cross-thread Quotes': 'Mark Cross-thread Quotes',
'Reply Hiding': 'Reply Hiding Buttons',
'Thread Hiding': 'Thread Hiding Buttons',
'uniqueid': 'uniqueID',
'mod': 'capcode',
'country': 'flag',
@ -12907,7 +12905,7 @@
rice: function(section) {
var archiver, event, input, inputs, items, name, toSelect, _i, _j, _len, _len1, _ref;
section.innerHTML = "<fieldset>\n <legend>Archiver</legend>\n Select an Archiver for this board:\n <select name=archiver></select>\n</fieldset>\n<fieldset>\n <legend>Custom Board Navigation <span class=warning " + (Conf['Custom Board Navigation'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=boardnav class=field spellcheck=false></div>\n <div>In the following, <code>board</code> can translate to a board ID (<code>a</code>, <code>b</code>, etc...), the current board (<code>current</code>), or the Status/Twitter link (<code>status</code>, <code>@</code>).</div>\n <div>\n For example:<br>\n <code>[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]</code><br>\n will give you<br>\n <code>[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]</code><br>\n if you are on /g/.\n </div>\n <div>Board link: <code>board</code></div>\n <div>Title link: <code>board-title</code></div>\n <div>Board link (Replace with title when on that board): <code>board-replace</code></div>\n <div>Full text link: <code>board-full</code></div>\n <div>Custom text link: <code>board-text:\"VIP Board\"</code></div>\n <div>Index-only link: <code>board-index</code></div>\n <div>Catalog-only link: <code>board-catalog</code></div>\n <div>Combinations are possible: <code>board-index-text:\"VIP Index\"</code></div>\n <div>Full board list toggle: <code>toggle-all</code></div>\n</fieldset>\n\n<fieldset>\n <legend>Time Formatting <span class=warning " + (Conf['Time Formatting'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=time class=field spellcheck=false>: <span class=time-preview></span></div>\n <div>Supported <a href=//en.wikipedia.org/wiki/Date_%28Unix%29#Formatting>format specifiers</a>:</div>\n <div>Day: <code>%a</code>, <code>%A</code>, <code>%d</code>, <code>%e</code></div>\n <div>Month: <code>%m</code>, <code>%b</code>, <code>%B</code></div>\n <div>Year: <code>%y</code></div>\n <div>Hour: <code>%k</code>, <code>%H</code>, <code>%l</code>, <code>%I</code>, <code>%p</code>, <code>%P</code></div>\n <div>Minute: <code>%M</code></div>\n <div>Second: <code>%S</code></div>\n</fieldset>\n\n<fieldset>\n <legend>Quote Backlinks formatting <span class=warning " + (Conf['Quote Backlinks'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=backlink class=field spellcheck=false>: <span class=backlink-preview></span></div>\n</fieldset>\n\n<fieldset>\n <legend>File Info Formatting <span class=warning " + (Conf['File Info Formatting'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=fileInfo class=field spellcheck=false>: <span class='fileText file-info-preview'></span></div>\n <div>Link: <code>%l</code> (truncated), <code>%L</code> (untruncated), <code>%T</code> (Unix timestamp)</div>\n <div>Original file name: <code>%n</code> (truncated), <code>%N</code> (untruncated), <code>%t</code> (Unix timestamp)</div>\n <div>Spoiler indicator: <code>%p</code></div>\n <div>Size: <code>%B</code> (Bytes), <code>%K</code> (KB), <code>%M</code> (MB), <code>%s</code> (4chan default)</div>\n <div>Resolution: <code>%r</code> (Displays 'PDF' for PDF files)</div>\n</fieldset>\n\n<fieldset>\n <legend>Unread Tab Icon <span class=warning " + (Conf['Unread Tab Icon'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <select name=favicon>\n <option value=ferongr>ferongr</option>\n <option value=xat->xat-</option>\n <option value=Mayhem>Mayhem</option>\n <option value=Original>Original</option>\n </select>\n <span class=favicon-preview></span>\n</fieldset>\n\n<fieldset>\n <legend><input type=checkbox name='Custom CSS' " + (Conf['Custom CSS'] ? 'checked' : '') + "> Custom CSS</legend>\n <button id=apply-css>Apply CSS</button>\n <textarea name=usercss class=field spellcheck=false " + (Conf['Custom CSS'] ? '' : 'disabled') + "></textarea>\n</fieldset>";
section.innerHTML = "<fieldset>\n <legend>Archiver</legend>\n Select an Archiver for this board:\n <select name=archiver></select>\n</fieldset>\n<fieldset>\n <legend>Custom Board Navigation <span class=warning " + (Conf['Custom Board Navigation'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=boardnav class=field spellcheck=false></div>\n <div>In the following, <code>board</code> can translate to a board ID (<code>a</code>, <code>b</code>, etc...), the current board (<code>current</code>), or the Status/Twitter link (<code>status</code>, <code>@</code>).</div>\n <div>\n For example:<br>\n <code>[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]</code><br>\n will give you<br>\n <code>[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]</code><br>\n if you are on /g/.\n </div>\n <div>Board link: <code>board</code></div>\n <div>Title link: <code>board-title</code></div>\n <div>Board link (Replace with title when on that board): <code>board-replace</code></div>\n <div>Full text link: <code>board-full</code></div>\n <div>Custom text link: <code>board-text:\"VIP Board\"</code></div>\n <div>Index-only link: <code>board-index</code></div>\n <div>Catalog-only link: <code>board-catalog</code></div>\n <div>Combinations are possible: <code>board-index-text:\"VIP Index\"</code></div>\n <div>Full board list toggle: <code>toggle-all</code></div>\n</fieldset>\n\n<fieldset>\n <legend>Time Formatting <span class=warning " + (Conf['Time Formatting'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=time class=field spellcheck=false>: <span class=time-preview></span></div>\n <div>Supported <a href=//en.wikipedia.org/wiki/Date_%28Unix%29#Formatting>format specifiers</a>:</div>\n <div>Day: <code>%a</code>, <code>%A</code>, <code>%d</code>, <code>%e</code></div>\n <div>Month: <code>%m</code>, <code>%b</code>, <code>%B</code></div>\n <div>Year: <code>%y</code></div>\n <div>Hour: <code>%k</code>, <code>%H</code>, <code>%l</code>, <code>%I</code>, <code>%p</code>, <code>%P</code></div>\n <div>Minute: <code>%M</code></div>\n <div>Second: <code>%S</code></div>\n</fieldset>\n\n<fieldset>\n <legend>Quote Backlinks formatting <span class=warning " + (Conf['Quote Backlinks'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=backlink class=field spellcheck=false>: <span class=backlink-preview></span></div>\n</fieldset>\n\n<fieldset>\n <legend>File Info Formatting <span class=warning " + (Conf['File Info Formatting'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=fileInfo class=field spellcheck=false>: <span class='fileText file-info-preview'></span></div>\n <div>Link: <code>%l</code> (truncated), <code>%L</code> (untruncated), <code>%T</code> (Unix timestamp)</div>\n <div>Original file name: <code>%n</code> (truncated), <code>%N</code> (untruncated), <code>%t</code> (Unix timestamp)</div>\n <div>Spoiler indicator: <code>%p</code></div>\n <div>Size: <code>%B</code> (Bytes), <code>%K</code> (KB), <code>%M</code> (MB), <code>%s</code> (4chan default)</div>\n <div>Resolution: <code>%r</code> (Displays 'PDF' for PDF files)</div>\n</fieldset>\n\n<fieldset>\n <legend>Unread Favicon <span class=warning " + (Conf['Unread Favicon'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <select name=favicon>\n <option value=ferongr>ferongr</option>\n <option value=xat->xat-</option>\n <option value=Mayhem>Mayhem</option>\n <option value=Original>Original</option>\n </select>\n <span class=favicon-preview></span>\n</fieldset>\n\n<fieldset>\n <legend><input type=checkbox name='Custom CSS' " + (Conf['Custom CSS'] ? 'checked' : '') + "> Custom CSS</legend>\n <button id=apply-css>Apply CSS</button>\n <textarea name=usercss class=field spellcheck=false " + (Conf['Custom CSS'] ? '' : 'disabled') + "></textarea>\n</fieldset>";
items = {};
inputs = {};
_ref = ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'usercss'];
@ -12987,7 +12985,7 @@
},
favicon: function() {
Favicon["switch"]();
if (g.VIEW === 'thread' && Conf['Unread Tab Icon']) {
if (g.VIEW === 'thread' && Conf['Unread Favicon']) {
Unread.update();
}
return this.nextElementSibling.innerHTML = "<img src=" + Favicon["default"] + ">\n<img src=" + Favicon.unreadSFW + ">\n<img src=" + Favicon.unreadNSFW + ">\n<img src=" + Favicon.unreadDead + ">";
@ -13663,8 +13661,8 @@
'Linkify': Linkify,
'Resurrect Quotes': Quotify,
'Filter': Filter,
'Thread Hiding': ThreadHiding,
'Reply Hiding': PostHiding,
'Thread Hiding Buttons': ThreadHiding,
'Reply Hiding Buttons': PostHiding,
'Recursive': Recursive,
'Strike-through Quotes': QuoteStrikeThrough,
'Quick Reply': QR,

View File

@ -7,7 +7,7 @@
Config = {
main: {
'Miscellaneous': {
'Catalog Links': [true, 'Turn Navigation links into links to each board\'s catalog.'],
'Catalog Links': [true, 'Add toggle link in header menu to turn Navigation links into links to each board\'s catalog.'],
'External Catalog': [false, 'Link to external catalog instead of the internal one.'],
'Custom Board Navigation': [false, 'Show custom links instead of the full board list.'],
'QR Shortcut': [false, 'Adds a small [QR] link in the header.'],
@ -33,8 +33,8 @@
'Anonymize': [false, 'Make everyone Anonymous.'],
'Filter': [true, 'Self-moderation placebo.'],
'Recursive Hiding': [true, 'Hide replies of hidden posts, recursively.'],
'Thread Hiding': [true, 'Add buttons to hide entire threads.'],
'Reply Hiding': [true, 'Add buttons to hide single replies.'],
'Thread Hiding Buttons': [true, 'Add buttons to hide entire threads.'],
'Reply Hiding Buttons': [true, 'Add buttons to hide single replies.'],
'Stubs': [true, 'Show stubs of hidden threads / replies.']
},
'Images': {
@ -60,7 +60,7 @@
'Thread Updater': [true, 'Fetch and insert new replies. Has more options in its own dialog.'],
'Unread Count': [true, 'Show the unread posts count in the tab title.'],
'Hide Unread Count at (0)': [false, 'Hide the unread posts count when it reaches 0.'],
'Unread Tab Icon': [true, 'Show a different favicon when there are unread posts.'],
'Unread Favicon': [true, 'Show a different favicon when there are unread posts.'],
'Unread Line': [true, 'Show a line to distinguish read posts from unread ones.'],
'Scroll to Last Read Post': [true, 'Scroll back to the last read post when reopening a thread.'],
'Thread Excerpt': [true, 'Show an excerpt of the thread in the tab title.'],
@ -205,19 +205,19 @@
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/",
'Boards Navigation': 'sticky top',
'Custom CSS': false,
'Boards Navigation': 'sticky top',
'Boards Navigation': 'Sticky top',
'Header auto-hide': false,
'Header catalog links': false,
boardnav: '[ toggle-all ] [current-title]',
time: '%m/%d/%y(%a)%H:%M:%S',
backlink: '>>%id',
fileInfo: '%l (%p%s, %r)',
fileInfo: '%L (%p%s, %r)',
favicon: 'ferongr',
usercss: "/* Tripcode Italics: */\n/*\nspan.postertrip {\nfont-style: italic;\n}\n*/\n\n/* Add a rounded border to thumbnails (but not expanded images): */\n/*\n.fileThumb > img:first-child {\nborder: solid 2px rgba(0,0,100,0.5);\nborder-radius: 10px;\n}\n*/\n\n/* Make highlighted posts look inset on the page: */\n/*\ndiv.post:target,\ndiv.post.highlight {\nbox-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);\n}\n*/",
hotkeys: {
'Toggle board list': ['Ctrl+b', 'Toggle the full board list.'],
'Open empty QR': ['q', 'Open QR without post number inserted.'],
'Open QR': ['Shift+q', 'Open QR with post number inserted.'],
'Open empty QR': ['l', 'Open QR without post number inserted.'],
'Open QR': ['Shift+l', 'Open QR with post number inserted.'],
'Open settings': ['Alt+o', 'Open Settings.'],
'Close': ['Esc', 'Close Settings, Notifications or QR.'],
'Spoiler tags': ['Ctrl+s', 'Insert spoiler tags.'],
@ -4653,7 +4653,7 @@
PostHiding = {
init: function() {
if (g.VIEW === 'catalog' || !Conf['Reply Hiding'] && !Conf['Reply Hiding Link']) {
if (g.VIEW === 'catalog' || !Conf['Reply Hiding Buttons'] && !Conf['Reply Hiding Link']) {
return;
}
this.db = new DataBoard('hiddenPosts');
@ -4680,7 +4680,7 @@
Recursive.add(PostHiding.hide, this, data.makeStub, true);
}
}
if (!Conf['Reply Hiding']) {
if (!Conf['Reply Hiding Buttons']) {
return;
}
return $.add($('.postInfo', this.nodes.post), PostHiding.makeButton(this, 'hide'));
@ -4931,7 +4931,7 @@
QuoteStrikeThrough = {
init: function() {
if (g.VIEW === 'catalog' || !Conf['Reply Hiding'] && !Conf['Reply Hiding Link'] && !Conf['Filter']) {
if (g.VIEW === 'catalog' || !Conf['Reply Hiding Buttons'] && !Conf['Reply Hiding Link'] && !Conf['Filter']) {
return;
}
return Post.prototype.callbacks.push({
@ -4958,7 +4958,7 @@
ThreadHiding = {
init: function() {
if (g.VIEW !== 'index' || !Conf['Thread Hiding'] && !Conf['Thread Hiding Link']) {
if (g.VIEW !== 'index' || !Conf['Thread Hiding Buttons'] && !Conf['Thread Hiding Link']) {
return;
}
this.db = new DataBoard('hiddenThreads');
@ -4977,7 +4977,7 @@
})) {
ThreadHiding.hide(this, data.makeStub);
}
if (!Conf['Thread Hiding']) {
if (!Conf['Thread Hiding Buttons']) {
return;
}
return $.prepend(this.OP.nodes.info, ThreadHiding.makeButton(this, 'hide'));
@ -6321,7 +6321,7 @@
el = $.el('label', {
id: 'toggleCatalog',
href: 'javascript:;',
innerHTML: "<input type=checkbox " + (Conf['Header catalog links'] ? 'checked' : '') + ">Catalog",
innerHTML: "<input type=checkbox " + (Conf['Header catalog links'] ? 'checked' : '') + ">Catalog Links",
title: "Turn catalog links " + (Conf['Header catalog links'] ? 'off' : 'on') + "."
});
input = $('input', el);
@ -6794,7 +6794,7 @@
$.on(this.headerToggler, 'change', this.toggleBarVisibility);
createSubEntry = Header.createSubEntry;
subEntries = [];
_ref = ['sticky top', 'sticky bottom', 'top', 'hide'];
_ref = ['Sticky top', 'Sticky bottom', 'Top', 'Hide'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
setting = _ref[_i];
subEntries.push(createSubEntry(setting));
@ -6835,7 +6835,7 @@
id: 'hoverUI'
}),
toggle: $.el('div', {
id: 'toggle-header-bar'
id: 'scroll-marker'
}),
createSubEntry: function(setting) {
var label;
@ -6970,15 +6970,15 @@
$.rmClass(doc, 'bottom');
$.rmClass(doc, 'hide');
switch (setting) {
case 'sticky top':
$.addClass(doc, 'fixed');
return $.addClass(doc, 'top');
case 'sticky bottom':
case 'Sticky top':
$.addClass(doc, 'top');
return $.addClass(doc, 'fixed');
case 'Sticky bottom':
$.addClass(doc, 'fixed');
return $.addClass(doc, 'bottom');
case 'top':
case 'Top':
return $.addClass(doc, 'top');
case 'hide':
case 'Hide':
return $.addClass(doc, 'hide');
}
},
@ -7036,7 +7036,7 @@
var headRect, top;
top = post.getBoundingClientRect().top;
if (Conf['Boards Navigation'] === 'sticky top') {
if (Conf['Boards Navigation'] === 'Sticky top') {
headRect = Header.bar.getBoundingClientRect();
top += -headRect.top - headRect.height;
}
@ -7489,16 +7489,16 @@
boards: ['cgl', 'ck', 'fa', 'jp', 'lit', 's4s', 'q', 'tg'],
type: 'fuuka'
},
'RebeccaBlackTech': {
base: '//rbt.asia',
boards: ['an', 'cgl', 'g', 'mu', 'w'],
type: 'fuuka_mail'
},
'InstallGentoo': {
base: '//archive.installgentoo.net',
boards: ['diy', 'g', 'sci'],
type: 'fuuka'
},
'RebeccaBlackTech': {
base: '//rbt.asia',
boards: ['an', 'cgl', 'g', 'mu', 'w'],
type: 'fuuka_mail'
},
'Heinessen': {
base: 'http://archive.heinessen.com',
boards: ['an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'],
@ -8544,7 +8544,7 @@
Unread = {
init: function() {
if (g.VIEW !== 'thread' || !Conf['Unread Count'] && !Conf['Unread Tab Icon']) {
if (g.VIEW !== 'thread' || !Conf['Unread Count'] && !Conf['Unread Favicon']) {
return;
}
this.db = new DataBoard('lastReadPosts', this.sync);
@ -8559,8 +8559,7 @@
});
},
node: function() {
var ID, post, posts, _ref,
_this = this;
var ID, post, posts, _ref;
Unread.thread = this;
Unread.title = d.title;
@ -8583,31 +8582,29 @@
if (Conf['Unread Line']) {
$.on(d, 'visibilitychange', Unread.setLine);
}
if (Conf['Scroll to Last Read Post']) {
return $.on(window, 'load', function(posts) {
return Unread.scroll.apply(_this, posts);
});
}
},
scroll: function(posts) {
var hash, root;
if ((hash = location.hash.match(/\d+/)) && hash[0] in this.posts) {
if (!Conf['Scroll to Last Read Post']) {
return;
}
if (Unread.posts.length) {
while (root = $.x('preceding-sibling::div[contains(@class,"postContainer")][1]', Unread.posts[0].nodes.root)) {
if (!(Get.postFromRoot(root)).isHidden) {
break;
}
}
if (!root) {
return $.on(window, 'load', function() {
var hash, root;
if ((hash = location.hash.match(/\d+/)) && hash[0] in this.posts) {
return;
}
return root.scrollIntoView(false);
} else if (posts.length) {
return Header.scrollToPost(posts[post.length - 1].nodes.root);
}
if (Unread.posts.length) {
while (root = $.x('preceding-sibling::div[contains(@class,"postContainer")][1]', Unread.posts[0].nodes.root)) {
if (!(Get.postFromRoot(root)).isHidden) {
break;
}
}
if (!root) {
return;
}
return root.scrollIntoView(false);
} else if (posts.length) {
return Header.scrollToPost(posts[posts.length - 1].nodes.root);
}
});
},
sync: function() {
var lastReadPost;
@ -8764,7 +8761,7 @@
}, $.SECOND);
}
}
if (!Conf['Unread Tab Icon']) {
if (!Conf['Unread Favicon']) {
return;
}
return Favicon.el.href = g.DEAD ? Unread.postsQuotingYou.length ? Favicon.unreadDeadY : count ? Favicon.unreadDead : Favicon.dead : count ? Unread.postsQuotingYou.length ? Favicon.unreadY : Favicon.unread : Favicon["default"];
@ -10460,7 +10457,7 @@
$.event('AddMenuEntry', {
type: 'header',
el: this.controls,
order: 115
order: 98
});
$.on(d, '4chanXInitFinished', this.setup);
return Post.prototype.callbacks.push({
@ -12453,11 +12450,14 @@
Settings.dialog = dialog = $.el('div', {
id: 'appchanx-settings',
"class": 'dialog',
innerHTML: "<nav>\n <div class=sections-list></div>\n <div class=credits>\n <a href='http://zixaphir.github.com/appchan-x/' target=_blank>appchan x</a> |\n <a href='https://github.com/zixaphir/appchan-x/blob/Av2/CHANGELOG.md' target=_blank>" + g.VERSION + "</a> |\n <a href='https://github.com/zixaphir/appchan-x/blob/Av2/CONTRIBUTING.md#reporting-bugs-and-suggestions' target=_blank>Issues</a> |\n <a href=javascript:; class=close title=Close>×</a>\n </div>\n</nav>\n<hr>\n<div class=section-container><section></section></div>"
innerHTML: "<nav>\n <div class=sections-list></div>\n <p class='imp-exp-result warning'></p>\n <div class=credits>\n <a class=export>Export</a> |\n <a class=import>Import</a> |\n <input type=file style='display: none;'>\n <a href='http://zixaphir.github.com/appchan-x/' target=_blank>appchan x</a> |\n <a href='https://github.com/zixaphir/appchan-x/blob/Av2/CHANGELOG.md' target=_blank>" + g.VERSION + "</a> |\n <a href='https://github.com/zixaphir/appchan-x/blob/Av2/CONTRIBUTING.md#reporting-bugs-and-suggestions' target=_blank>Issues</a> |\n <a href=javascript:; class=close title=Close>×</a>\n </div>\n</nav>\n<hr>\n<div class=section-container><section></section></div>"
});
Settings.overlay = overlay = $.el('div', {
id: 'overlay'
});
$.on($('.export', Settings.dialog), 'click', Settings["export"]);
$.on($('.import', Settings.dialog), 'click', Settings["import"]);
$.on($('input', Settings.dialog), 'change', Settings.onImport);
links = [];
_ref = Settings.sections;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@ -12522,10 +12522,6 @@
main: function(section) {
var arr, button, description, div, fs, hiddenNum, input, inputs, items, key, obj, _ref;
section.innerHTML = "<div class=imp-exp>\n <button class=export>Export Settings</button>\n <button class=import>Import Settings</button>\n <input type=file style='visibility:hidden'>\n</div>\n<p class=imp-exp-result></p>";
$.on($('.export', section), 'click', Settings["export"]);
$.on($('.import', section), 'click', Settings["import"]);
$.on($('input', section), 'change', Settings.onImport);
items = {};
inputs = {};
_ref = Config.main;
@ -12655,7 +12651,7 @@
if (!(file = this.files[0])) {
return;
}
output = this.parentNode.nextElementSibling;
output = $('.imp-exp-result');
if (!confirm('Your current settings will be entirely overwritten, are you sure?')) {
output.textContent = 'Import aborted.';
return;
@ -12690,7 +12686,7 @@
'Show Stubs': 'Stubs',
'Image Auto-Gif': 'Auto-GIF',
'Expand From Current': '',
'Unread Favicon': 'Unread Tab Icon',
'Unread Tab Icon': 'Unread Favicon',
'Post in Title': 'Thread Excerpt',
'Auto Hide QR': '',
'Open Reply in New Tab': '',
@ -12699,6 +12695,8 @@
'Quote Preview': 'Quote Previewing',
'Indicate OP quote': 'Mark OP Quotes',
'Indicate Cross-thread Quotes': 'Mark Cross-thread Quotes',
'Reply Hiding': 'Reply Hiding Buttons',
'Thread Hiding': 'Thread Hiding Buttons',
'uniqueid': 'uniqueID',
'mod': 'capcode',
'country': 'flag',
@ -12812,7 +12810,7 @@
rice: function(section) {
var archiver, event, input, inputs, items, name, toSelect, _i, _j, _len, _len1, _ref;
section.innerHTML = "<fieldset>\n <legend>Archiver</legend>\n Select an Archiver for this board:\n <select name=archiver></select>\n</fieldset>\n<fieldset>\n <legend>Custom Board Navigation <span class=warning " + (Conf['Custom Board Navigation'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=boardnav class=field spellcheck=false></div>\n <div>In the following, <code>board</code> can translate to a board ID (<code>a</code>, <code>b</code>, etc...), the current board (<code>current</code>), or the Status/Twitter link (<code>status</code>, <code>@</code>).</div>\n <div>\n For example:<br>\n <code>[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]</code><br>\n will give you<br>\n <code>[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]</code><br>\n if you are on /g/.\n </div>\n <div>Board link: <code>board</code></div>\n <div>Title link: <code>board-title</code></div>\n <div>Board link (Replace with title when on that board): <code>board-replace</code></div>\n <div>Full text link: <code>board-full</code></div>\n <div>Custom text link: <code>board-text:\"VIP Board\"</code></div>\n <div>Index-only link: <code>board-index</code></div>\n <div>Catalog-only link: <code>board-catalog</code></div>\n <div>Combinations are possible: <code>board-index-text:\"VIP Index\"</code></div>\n <div>Full board list toggle: <code>toggle-all</code></div>\n</fieldset>\n\n<fieldset>\n <legend>Time Formatting <span class=warning " + (Conf['Time Formatting'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=time class=field spellcheck=false>: <span class=time-preview></span></div>\n <div>Supported <a href=//en.wikipedia.org/wiki/Date_%28Unix%29#Formatting>format specifiers</a>:</div>\n <div>Day: <code>%a</code>, <code>%A</code>, <code>%d</code>, <code>%e</code></div>\n <div>Month: <code>%m</code>, <code>%b</code>, <code>%B</code></div>\n <div>Year: <code>%y</code></div>\n <div>Hour: <code>%k</code>, <code>%H</code>, <code>%l</code>, <code>%I</code>, <code>%p</code>, <code>%P</code></div>\n <div>Minute: <code>%M</code></div>\n <div>Second: <code>%S</code></div>\n</fieldset>\n\n<fieldset>\n <legend>Quote Backlinks formatting <span class=warning " + (Conf['Quote Backlinks'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=backlink class=field spellcheck=false>: <span class=backlink-preview></span></div>\n</fieldset>\n\n<fieldset>\n <legend>File Info Formatting <span class=warning " + (Conf['File Info Formatting'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=fileInfo class=field spellcheck=false>: <span class='fileText file-info-preview'></span></div>\n <div>Link: <code>%l</code> (truncated), <code>%L</code> (untruncated), <code>%T</code> (Unix timestamp)</div>\n <div>Original file name: <code>%n</code> (truncated), <code>%N</code> (untruncated), <code>%t</code> (Unix timestamp)</div>\n <div>Spoiler indicator: <code>%p</code></div>\n <div>Size: <code>%B</code> (Bytes), <code>%K</code> (KB), <code>%M</code> (MB), <code>%s</code> (4chan default)</div>\n <div>Resolution: <code>%r</code> (Displays 'PDF' for PDF files)</div>\n</fieldset>\n\n<fieldset>\n <legend>Unread Tab Icon <span class=warning " + (Conf['Unread Tab Icon'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <select name=favicon>\n <option value=ferongr>ferongr</option>\n <option value=xat->xat-</option>\n <option value=Mayhem>Mayhem</option>\n <option value=Original>Original</option>\n </select>\n <span class=favicon-preview></span>\n</fieldset>\n\n<fieldset>\n <legend><input type=checkbox name='Custom CSS' " + (Conf['Custom CSS'] ? 'checked' : '') + "> Custom CSS</legend>\n <button id=apply-css>Apply CSS</button>\n <textarea name=usercss class=field spellcheck=false " + (Conf['Custom CSS'] ? '' : 'disabled') + "></textarea>\n</fieldset>";
section.innerHTML = "<fieldset>\n <legend>Archiver</legend>\n Select an Archiver for this board:\n <select name=archiver></select>\n</fieldset>\n<fieldset>\n <legend>Custom Board Navigation <span class=warning " + (Conf['Custom Board Navigation'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=boardnav class=field spellcheck=false></div>\n <div>In the following, <code>board</code> can translate to a board ID (<code>a</code>, <code>b</code>, etc...), the current board (<code>current</code>), or the Status/Twitter link (<code>status</code>, <code>@</code>).</div>\n <div>\n For example:<br>\n <code>[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]</code><br>\n will give you<br>\n <code>[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]</code><br>\n if you are on /g/.\n </div>\n <div>Board link: <code>board</code></div>\n <div>Title link: <code>board-title</code></div>\n <div>Board link (Replace with title when on that board): <code>board-replace</code></div>\n <div>Full text link: <code>board-full</code></div>\n <div>Custom text link: <code>board-text:\"VIP Board\"</code></div>\n <div>Index-only link: <code>board-index</code></div>\n <div>Catalog-only link: <code>board-catalog</code></div>\n <div>Combinations are possible: <code>board-index-text:\"VIP Index\"</code></div>\n <div>Full board list toggle: <code>toggle-all</code></div>\n</fieldset>\n\n<fieldset>\n <legend>Time Formatting <span class=warning " + (Conf['Time Formatting'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=time class=field spellcheck=false>: <span class=time-preview></span></div>\n <div>Supported <a href=//en.wikipedia.org/wiki/Date_%28Unix%29#Formatting>format specifiers</a>:</div>\n <div>Day: <code>%a</code>, <code>%A</code>, <code>%d</code>, <code>%e</code></div>\n <div>Month: <code>%m</code>, <code>%b</code>, <code>%B</code></div>\n <div>Year: <code>%y</code></div>\n <div>Hour: <code>%k</code>, <code>%H</code>, <code>%l</code>, <code>%I</code>, <code>%p</code>, <code>%P</code></div>\n <div>Minute: <code>%M</code></div>\n <div>Second: <code>%S</code></div>\n</fieldset>\n\n<fieldset>\n <legend>Quote Backlinks formatting <span class=warning " + (Conf['Quote Backlinks'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=backlink class=field spellcheck=false>: <span class=backlink-preview></span></div>\n</fieldset>\n\n<fieldset>\n <legend>File Info Formatting <span class=warning " + (Conf['File Info Formatting'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <div><input name=fileInfo class=field spellcheck=false>: <span class='fileText file-info-preview'></span></div>\n <div>Link: <code>%l</code> (truncated), <code>%L</code> (untruncated), <code>%T</code> (Unix timestamp)</div>\n <div>Original file name: <code>%n</code> (truncated), <code>%N</code> (untruncated), <code>%t</code> (Unix timestamp)</div>\n <div>Spoiler indicator: <code>%p</code></div>\n <div>Size: <code>%B</code> (Bytes), <code>%K</code> (KB), <code>%M</code> (MB), <code>%s</code> (4chan default)</div>\n <div>Resolution: <code>%r</code> (Displays 'PDF' for PDF files)</div>\n</fieldset>\n\n<fieldset>\n <legend>Unread Favicon <span class=warning " + (Conf['Unread Favicon'] ? 'hidden' : '') + ">is disabled.</span></legend>\n <select name=favicon>\n <option value=ferongr>ferongr</option>\n <option value=xat->xat-</option>\n <option value=Mayhem>Mayhem</option>\n <option value=Original>Original</option>\n </select>\n <span class=favicon-preview></span>\n</fieldset>\n\n<fieldset>\n <legend><input type=checkbox name='Custom CSS' " + (Conf['Custom CSS'] ? 'checked' : '') + "> Custom CSS</legend>\n <button id=apply-css>Apply CSS</button>\n <textarea name=usercss class=field spellcheck=false " + (Conf['Custom CSS'] ? '' : 'disabled') + "></textarea>\n</fieldset>";
items = {};
inputs = {};
_ref = ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'usercss'];
@ -12892,7 +12890,7 @@
},
favicon: function() {
Favicon["switch"]();
if (g.VIEW === 'thread' && Conf['Unread Tab Icon']) {
if (g.VIEW === 'thread' && Conf['Unread Favicon']) {
Unread.update();
}
return this.nextElementSibling.innerHTML = "<img src=" + Favicon["default"] + ">\n<img src=" + Favicon.unreadSFW + ">\n<img src=" + Favicon.unreadNSFW + ">\n<img src=" + Favicon.unreadDead + ">";
@ -13568,8 +13566,8 @@
'Linkify': Linkify,
'Resurrect Quotes': Quotify,
'Filter': Filter,
'Thread Hiding': ThreadHiding,
'Reply Hiding': PostHiding,
'Thread Hiding Buttons': ThreadHiding,
'Reply Hiding Buttons': PostHiding,
'Recursive': Recursive,
'Strike-through Quotes': QuoteStrikeThrough,
'Quick Reply': QR,

View File

@ -3,7 +3,7 @@ Config =
'Miscellaneous':
'Catalog Links': [
true
'Turn Navigation links into links to each board\'s catalog.'
'Add toggle link in header menu to turn Navigation links into links to each board\'s catalog.'
]
'External Catalog': [
false
@ -93,11 +93,11 @@ Config =
true
'Hide replies of hidden posts, recursively.'
]
'Thread Hiding': [
'Thread Hiding Buttons': [
true
'Add buttons to hide entire threads.'
]
'Reply Hiding': [
'Reply Hiding Buttons': [
true
'Add buttons to hide single replies.'
]
@ -185,7 +185,7 @@ Config =
false
'Hide the unread posts count when it reaches 0.'
]
'Unread Tab Icon': [
'Unread Favicon': [
true
'Show a different favicon when there are unread posts.'
]
@ -739,7 +739,7 @@ http://iqdb.org/?url=%TURL
'Custom CSS': false
'Boards Navigation': 'sticky top'
'Boards Navigation': 'Sticky top'
'Header auto-hide': false
@ -751,7 +751,7 @@ http://iqdb.org/?url=%TURL
backlink: '>>%id'
fileInfo: '%l (%p%s, %r)'
fileInfo: '%L (%p%s, %r)'
favicon: 'ferongr'
@ -787,11 +787,11 @@ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
'Toggle the full board list.'
]
'Open empty QR': [
'q'
'l'
'Open QR without post number inserted.'
]
'Open QR': [
'Shift+q'
'Shift+l'
'Open QR with post number inserted.'
]
'Open settings': [

View File

@ -1,6 +1,6 @@
PostHiding =
init: ->
return if g.VIEW is 'catalog' or !Conf['Reply Hiding'] and !Conf['Reply Hiding Link']
return if g.VIEW is 'catalog' or !Conf['Reply Hiding Buttons'] and !Conf['Reply Hiding Link']
@db = new DataBoard 'hiddenPosts'
Post::callbacks.push
@ -15,7 +15,7 @@ PostHiding =
else
Recursive.apply PostHiding.hide, @, data.makeStub, true
Recursive.add PostHiding.hide, @, data.makeStub, true
return unless Conf['Reply Hiding']
return unless Conf['Reply Hiding Buttons']
$.add $('.postInfo', @nodes.post), PostHiding.makeButton @, 'hide'
menu:

View File

@ -1,6 +1,6 @@
QuoteStrikeThrough =
init: ->
return if g.VIEW is 'catalog' or !Conf['Reply Hiding'] and !Conf['Reply Hiding Link'] and !Conf['Filter']
return if g.VIEW is 'catalog' or !Conf['Reply Hiding Buttons'] and !Conf['Reply Hiding Link'] and !Conf['Filter']
Post::callbacks.push
name: 'Strike-through Quotes'

View File

@ -1,6 +1,6 @@
ThreadHiding =
init: ->
return if g.VIEW isnt 'index' or !Conf['Thread Hiding'] and !Conf['Thread Hiding Link']
return if g.VIEW isnt 'index' or !Conf['Thread Hiding Buttons'] and !Conf['Thread Hiding Link']
@db = new DataBoard 'hiddenThreads'
@syncCatalog()
@ -11,7 +11,7 @@ ThreadHiding =
node: ->
if data = ThreadHiding.db.get {boardID: @board.ID, threadID: @ID}
ThreadHiding.hide @, data.makeStub
return unless Conf['Thread Hiding']
return unless Conf['Thread Hiding Buttons']
$.prepend @OP.nodes.info, ThreadHiding.makeButton @, 'hide'
syncCatalog: ->

View File

@ -5,7 +5,7 @@ CatalogLinks =
el = $.el 'label',
id: 'toggleCatalog'
href: 'javascript:;'
innerHTML: "<input type=checkbox #{if Conf['Header catalog links'] then 'checked' else ''}>Catalog"
innerHTML: "<input type=checkbox #{if Conf['Header catalog links'] then 'checked' else ''}>Catalog Links"
title: "Turn catalog links #{if Conf['Header catalog links'] then 'off' else 'on'}."
input = $ 'input', el

View File

@ -17,7 +17,7 @@ Header =
{createSubEntry} = Header
subEntries = []
for setting in ['sticky top', 'sticky bottom', 'top', 'hide']
for setting in ['Sticky top', 'Sticky bottom', 'Top', 'Hide']
subEntries.push createSubEntry setting
subEntries.push {el: headerToggler}
@ -50,7 +50,7 @@ Header =
id: 'hoverUI'
toggle: $.el 'div',
id: 'toggle-header-bar'
id: 'scroll-marker'
createSubEntry: (setting) ->
label = $.el 'label',
@ -167,15 +167,15 @@ Header =
$.rmClass doc, 'bottom'
$.rmClass doc, 'hide'
switch setting
when 'sticky top'
$.addClass doc, 'fixed'
when 'Sticky top'
$.addClass doc, 'top'
when 'sticky bottom'
$.addClass doc, 'fixed'
when 'Sticky bottom'
$.addClass doc, 'fixed'
$.addClass doc, 'bottom'
when 'top'
when 'Top'
$.addClass doc, 'top'
when 'hide'
when 'Hide'
$.addClass doc, 'hide'
setBarVisibility: (hide) ->
@ -217,7 +217,7 @@ Header =
scrollToPost: (post) ->
{top} = post.getBoundingClientRect()
if Conf['Boards Navigation'] is 'sticky top'
if Conf['Boards Navigation'] is 'Sticky top'
headRect = Header.bar.getBoundingClientRect()
top += - headRect.top - headRect.height
<% if (type === 'crx') { %>d.body<% } else { %>doc<% } %>.scrollTop += top

View File

@ -79,14 +79,14 @@ Redirect =
base: '//fuuka.warosu.org'
boards: ['cgl', 'ck', 'fa', 'jp', 'lit', 's4s', 'q', 'tg']
type: 'fuuka'
'RebeccaBlackTech':
base: '//rbt.asia'
boards: ['an', 'cgl', 'g', 'mu', 'w']
type: 'fuuka_mail'
'InstallGentoo':
base: '//archive.installgentoo.net'
boards: ['diy', 'g', 'sci']
type: 'fuuka'
'RebeccaBlackTech':
base: '//rbt.asia'
boards: ['an', 'cgl', 'g', 'mu', 'w']
type: 'fuuka_mail'
'Heinessen':
base: 'http://archive.heinessen.com'
boards: ['an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x']

View File

@ -1,6 +1,6 @@
Unread =
init: ->
return if g.VIEW isnt 'thread' or !Conf['Unread Count'] and !Conf['Unread Tab Icon']
return if g.VIEW isnt 'thread' or !Conf['Unread Count'] and !Conf['Unread Favicon']
@db = new DataBoard 'lastReadPosts', @sync
@hr = $.el 'hr',
@ -26,22 +26,21 @@ Unread =
$.on d, 'ThreadUpdate', Unread.onUpdate
$.on d, 'scroll visibilitychange', Unread.read
$.on d, 'visibilitychange', Unread.setLine if Conf['Unread Line']
if Conf['Scroll to Last Read Post']
$.on window, 'load', (posts) =>
Unread.scroll.apply @, posts
scroll: (posts) ->
# Let the header's onload callback handle it.
return if (hash = location.hash.match /\d+/) and hash[0] of @posts
if Unread.posts.length
# Scroll to before the first unread post.
while root = $.x 'preceding-sibling::div[contains(@class,"postContainer")][1]', Unread.posts[0].nodes.root
break unless (Get.postFromRoot root).isHidden
return unless root
root.scrollIntoView false
else if posts.length
# Scroll to the last read post.
Header.scrollToPost (posts[post.length - 1]).nodes.root
return unless Conf['Scroll to Last Read Post']
$.on window, 'load', ->
# Let the header's onload callback handle it.
return if (hash = location.hash.match /\d+/) and hash[0] of @posts
if Unread.posts.length
# Scroll to before the first unread post.
while root = $.x 'preceding-sibling::div[contains(@class,"postContainer")][1]', Unread.posts[0].nodes.root
break unless (Get.postFromRoot root).isHidden
return unless root
root.scrollIntoView false
else if posts.length
# Scroll to the last read post.
Header.scrollToPost (posts[posts.length - 1]).nodes.root
sync: ->
lastReadPost = Unread.db.get
@ -153,7 +152,7 @@ Unread =
, $.SECOND
<% } %>
return unless Conf['Unread Tab Icon']
return unless Conf['Unread Favicon']
Favicon.el.href =
if g.DEAD

View File

@ -16,7 +16,7 @@ QuoteThreading =
$.event 'AddMenuEntry',
type: 'header'
el: @controls
order: 115
order: 98
$.on d, '4chanXInitFinished', @setup

View File

@ -103,8 +103,8 @@ Main =
'Linkify': Linkify
'Resurrect Quotes': Quotify
'Filter': Filter
'Thread Hiding': ThreadHiding
'Reply Hiding': PostHiding
'Thread Hiding Buttons': ThreadHiding
'Reply Hiding Buttons': PostHiding
'Recursive': Recursive
'Strike-through Quotes': QuoteStrikeThrough
'Quick Reply': QR

View File

@ -71,7 +71,11 @@ Settings =
innerHTML: """
<nav>
<div class=sections-list></div>
<p class='imp-exp-result warning'></p>
<div class=credits>
<a class=export>Export</a> |
<a class=import>Import</a> |
<input type=file style='display: none;'>
<a href='<%= meta.page %>' target=_blank><%= meta.name %></a> |
<a href='<%= meta.repo %>blob/<%= meta.mainBranch %>/CHANGELOG.md' target=_blank>#{g.VERSION}</a> |
<a href='<%= meta.repo %>blob/<%= meta.mainBranch %>/CONTRIBUTING.md#reporting-bugs-and-suggestions' target=_blank>Issues</a> |
@ -84,6 +88,10 @@ Settings =
Settings.overlay = overlay = $.el 'div',
id: 'overlay'
$.on $('.export', Settings.dialog), 'click', Settings.export
$.on $('.import', Settings.dialog), 'click', Settings.import
$.on $('input', Settings.dialog), 'change', Settings.onImport
links = []
for section in Settings.sections
link = $.el 'a',
@ -131,18 +139,6 @@ Settings =
section.scrollTop = 0
main: (section) ->
section.innerHTML = """
<div class=imp-exp>
<button class=export>Export Settings</button>
<button class=import>Import Settings</button>
<input type=file style='visibility:hidden'>
</div>
<p class=imp-exp-result></p>
"""
$.on $('.export', section), 'click', Settings.export
$.on $('.import', section), 'click', Settings.import
$.on $('input', section), 'change', Settings.onImport
items = {}
inputs = {}
for key, obj of Config.main
@ -223,7 +219,7 @@ Settings =
onImport: ->
return unless file = @files[0]
output = @parentNode.nextElementSibling
output = $('.imp-exp-result')
unless confirm 'Your current settings will be entirely overwritten, are you sure?'
output.textContent = 'Import aborted.'
return
@ -250,7 +246,7 @@ Settings =
'Show Stubs': 'Stubs'
'Image Auto-Gif': 'Auto-GIF'
'Expand From Current': ''
'Unread Favicon': 'Unread Tab Icon'
'Unread Tab Icon': 'Unread Favicon'
'Post in Title': 'Thread Excerpt'
'Auto Hide QR': ''
'Open Reply in New Tab': ''
@ -259,6 +255,8 @@ Settings =
'Quote Preview': 'Quote Previewing'
'Indicate OP quote': 'Mark OP Quotes'
'Indicate Cross-thread Quotes': 'Mark Cross-thread Quotes'
'Reply Hiding': 'Reply Hiding Buttons'
'Thread Hiding': 'Thread Hiding Buttons'
# filter
'uniqueid': 'uniqueID'
'mod': 'capcode'
@ -459,7 +457,7 @@ Settings =
</fieldset>
<fieldset>
<legend>Unread Tab Icon <span class=warning #{if Conf['Unread Tab Icon'] then 'hidden' else ''}>is disabled.</span></legend>
<legend>Unread Favicon <span class=warning #{if Conf['Unread Favicon'] then 'hidden' else ''}>is disabled.</span></legend>
<select name=favicon>
<option value=ferongr>ferongr</option>
<option value=xat->xat-</option>
@ -539,7 +537,7 @@ Settings =
favicon: ->
Favicon.switch()
Unread.update() if g.VIEW is 'thread' and Conf['Unread Tab Icon']
Unread.update() if g.VIEW is 'thread' and Conf['Unread Favicon']
@nextElementSibling.innerHTML = """
<img src=#{Favicon.default}>
<img src=#{Favicon.unreadSFW}>