diff --git a/builds/4chan-X.js b/builds/4chan-X.js index 46f944d28..d903c28a3 100644 --- a/builds/4chan-X.js +++ b/builds/4chan-X.js @@ -5242,6 +5242,17 @@ }; Redirect = { + init: function() { + return $.sync('archs', this.updateArchives); + }, + updateArchives: function() { + return $.get('archivers', {}, function(_arg) { + var archivers; + + archivers = _arg.archivers; + return Conf['archivers'] = archivers; + }); + }, image: function(boardID, filename) { switch (boardID) { case 'a': @@ -5282,91 +5293,99 @@ } }, post: function(boardID, postID) { - switch (boardID) { - case 'a': - case 'co': - case 'gd': - case 'jp': - case 'm': - case 'q': - case 'sp': - case 'tg': - case 'tv': - case 'v': - case 'vg': - case 'vp': - case 'vr': - case 'wsg': - return "https://archive.foolz.us/_/api/chan/post/?board=" + boardID + "&num=" + postID; - case 'u': - return "https://nsfw.foolz.us/_/api/chan/post/?board=" + boardID + "&num=" + postID; - case 'c': - case 'int': - case 'out': - case 'po': - return "//archive.thedarkcave.org/_/api/chan/post/?board=" + boardID + "&num=" + postID; - case 'hr': - case 'x': - return "http://archive.4plebs.org/_/api/chan/post/?board=" + boardID + "&num=" + postID; + var archive, name, _base, _ref; + + if (Redirect.post[boardID] == null) { + _ref = this.archiver; + for (name in _ref) { + archive = _ref[name]; + if (archive.type === 'foolfuuka' && archive.boards.contains(boardID)) { + Redirect.post[boardID] = archive.base; + break; + } + } + (_base = Redirect.post)[boardID] || (_base[boardID] = false); + } + if (Redirect.post[boardID]) { + return "" + Redirect.post[boardID] + "/_/api/chan/post/?board=" + boardID + "&num=" + postID; + } else { + return null; } }, + select: function(board) { + var archive, name, _ref, _results; + + _ref = this.archiver; + _results = []; + for (name in _ref) { + archive = _ref[name]; + if (!archive.boards.contains(board)) { + continue; + } + _results.push(name); + } + return _results; + }, to: function(data) { - var boardID; + var arch, archive, boardID; boardID = data.boardID; - switch (boardID) { - case 'a': - case 'co': - case 'gd': - case 'jp': - case 'm': - case 'q': - case 'sp': - case 'tg': - case 'tv': - case 'v': - case 'vg': - case 'vp': - case 'vr': - case 'wsg': - return Redirect.path('//archive.foolz.us', 'foolfuuka', data); - case 'u': - return Redirect.path('//nsfw.foolz.us', 'foolfuuka', data); - case 'int': - case 'out': - case 'po': - return Redirect.path('//archive.thedarkcave.org', 'foolfuuka', data); - case 'hr': - return Redirect.path('http://archive.4plebs.org', 'foolfuuka', data); - case 'ck': - case 'fa': - case 'lit': - case 's4s': - return Redirect.path('//fuuka.warosu.org', 'fuuka', data); - case 'diy': - case 'g': - case 'sci': - return Redirect.path('//archive.installgentoo.net', 'fuuka', data); - case 'cgl': - case 'mu': - case 'w': - return Redirect.path('//rbt.asia', 'fuuka', data); - case 'an': - case 'fit': - case 'k': - case 'mlp': - case 'r9k': - case 'toy': - case 'x': - return Redirect.path('http://archive.heinessen.com', 'fuuka', data); - case 'c': - return Redirect.path('//archive.nyafuu.org', 'fuuka', data); - default: - if (data.threadID) { - return "//boards.4chan.org/" + boardID + "/"; - } else { - return ''; - } + if ((arch = Conf.archivers[boardID]) == null) { + Conf.archivers[boardID] = arch = this.select(boardID)[0]; + $.set('archivers', Conf.archivers); + } + return (arch && (archive = this.archiver[arch]) ? Redirect.path(archive.base, archive.type, data) : data.threadID ? "//boards.4chan.org/" + boardID + "/" : null); + }, + archiver: { + 'Foolz': { + base: 'https://archive.foolz.us', + boards: ['a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'v', 'vg', 'vp', 'vr', 'wsg'], + type: 'foolfuuka' + }, + 'NSFWFoolz': { + base: 'https://nsfw.foolz.us', + boards: ['u'], + type: 'foolfuuka' + }, + 'TheDarkCave': { + base: 'http://archive.thedarkcave.org', + boards: ['c', 'int', 'out', 'po'], + type: 'foolfuuka' + }, + '4plebs': { + base: 'http://archive.4plebs.org', + boards: ['hr', 'tg', 'tv', 'x'], + base: 'foolfuuka' + }, + 'Warosu': { + 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' + }, + 'Heinessen': { + base: 'http://archive.heinessen.com', + boards: ['an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'], + type: 'fuuka' + }, + 'Cliche': { + base: '//www.cliché.net/4chan/cgi-board.pl', + boards: ['e'], + type: 'fuuka' + }, + 'NyaFuu': { + base: '//archive.nyafuu.org', + boards: ['c', 'w'], + type: 'fuuka' } }, path: function(base, archiver, data) { @@ -6424,7 +6443,7 @@ }); } }, - scroll: function() { + scroll: function(posts) { var hash, root; if ((hash = location.hash.match(/\d+/)) && hash[0] in this.posts) { @@ -8977,9 +8996,9 @@ return $.on(sauce, 'change', $.cb.value); }, rice: function(section) { - var event, input, inputs, items, name, _i, _len, _ref; + var archiver, event, input, inputs, items, name, toSelect, _i, _j, _len, _len1, _ref; - section.innerHTML = "
\n Custom Board Navigation is disabled.\n
\n
In the following, board can translate to a board ID (a, b, etc...), the current board (current), or the Status/Twitter link (status, @).
\n
\n For example:
\n [ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]
\n will give you
\n [ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
\n if you are on /g/.\n
\n
Board link: board
\n
Title link: board-title
\n
Board link (Replace with title when on that board): board-replace
\n
Full text link: board-full
\n
Custom text link: board-text:\"VIP Board\"
\n
Index-only link: board-index
\n
Catalog-only link: board-catalog
\n
Combinations are possible: board-index-text:\"VIP Index\"
\n
Full board list toggle: toggle-all
\n
\n\n
\n Time Formatting is disabled.\n
:
\n
Supported format specifiers:
\n
Day: %a, %A, %d, %e
\n
Month: %m, %b, %B
\n
Year: %y
\n
Hour: %k, %H, %l, %I, %p, %P
\n
Minute: %M
\n
Second: %S
\n
\n\n
\n Quote Backlinks formatting is disabled.\n
:
\n
\n\n
\n File Info Formatting is disabled.\n
:
\n
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
\n
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
\n
Spoiler indicator: %p
\n
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
\n
Resolution: %r (Displays 'PDF' for PDF files)
\n
\n\n
\n Unread Tab Icon is disabled.\n \n \n
\n\n
\n \n \n \n \n \n
"; + section.innerHTML = "
\n Archiver\n Select an Archiver for this board:\n \n
\n
\n Custom Board Navigation is disabled.\n
\n
In the following, board can translate to a board ID (a, b, etc...), the current board (current), or the Status/Twitter link (status, @).
\n
\n For example:
\n [ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]
\n will give you
\n [ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
\n if you are on /g/.\n
\n
Board link: board
\n
Title link: board-title
\n
Board link (Replace with title when on that board): board-replace
\n
Full text link: board-full
\n
Custom text link: board-text:\"VIP Board\"
\n
Index-only link: board-index
\n
Catalog-only link: board-catalog
\n
Combinations are possible: board-index-text:\"VIP Index\"
\n
Full board list toggle: toggle-all
\n
\n\n
\n Time Formatting is disabled.\n
:
\n
Supported format specifiers:
\n
Day: %a, %A, %d, %e
\n
Month: %m, %b, %B
\n
Year: %y
\n
Hour: %k, %H, %l, %I, %p, %P
\n
Minute: %M
\n
Second: %S
\n
\n\n
\n Quote Backlinks formatting is disabled.\n
:
\n
\n\n
\n File Info Formatting is disabled.\n
:
\n
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
\n
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
\n
Spoiler indicator: %p
\n
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
\n
Resolution: %r (Displays 'PDF' for PDF files)
\n
\n\n
\n Unread Tab Icon is disabled.\n \n \n
\n\n
\n \n \n \n \n \n
"; items = {}; inputs = {}; _ref = ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'usercss']; @@ -8991,6 +9010,25 @@ event = ['favicon', 'usercss'].contains(name) ? 'change' : 'input'; $.on(input, event, $.cb.value); } + archiver = $('select[name=archiver]', section); + toSelect = Redirect.select(g.BOARD.ID); + if (!toSelect[0]) { + toSelect = ['No Archive Available']; + } + for (_j = 0, _len1 = toSelect.length; _j < _len1; _j++) { + name = toSelect[_j]; + $.add(archiver, $.el('option', { + textContent: name + })); + } + if (toSelect[1]) { + Conf['archivers'][g.BOARD]; + archiver.value = Conf['archivers'][g.BOARD] || toSelect[0]; + $.on(archiver, 'change', function() { + Conf['archivers'][g.BOARD] = this.value; + return $.set('archivers', Conf.archivers); + }); + } $.get(items, function(items) { var key, val; @@ -9126,6 +9164,7 @@ boards: {} }; } + Conf['archivers'] = {}; $.get(Conf, Main.initFeatures); return $.on(d, '4chanMainInit', Main.initStyle); }, @@ -9185,6 +9224,7 @@ }; init({ 'Polyfill': Polyfill, + 'Redirection': Redirect, 'Header': Header, 'Catalog Links': CatalogLinks, 'Settings': Settings, diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 8f3dc3ec6..d15e1b856 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -5233,6 +5233,17 @@ }; Redirect = { + init: function() { + return $.sync('archs', this.updateArchives); + }, + updateArchives: function() { + return $.get('archivers', {}, function(_arg) { + var archivers; + + archivers = _arg.archivers; + return Conf['archivers'] = archivers; + }); + }, image: function(boardID, filename) { switch (boardID) { case 'a': @@ -5273,91 +5284,99 @@ } }, post: function(boardID, postID) { - switch (boardID) { - case 'a': - case 'co': - case 'gd': - case 'jp': - case 'm': - case 'q': - case 'sp': - case 'tg': - case 'tv': - case 'v': - case 'vg': - case 'vp': - case 'vr': - case 'wsg': - return "https://archive.foolz.us/_/api/chan/post/?board=" + boardID + "&num=" + postID; - case 'u': - return "https://nsfw.foolz.us/_/api/chan/post/?board=" + boardID + "&num=" + postID; - case 'c': - case 'int': - case 'out': - case 'po': - return "//archive.thedarkcave.org/_/api/chan/post/?board=" + boardID + "&num=" + postID; - case 'hr': - case 'x': - return "http://archive.4plebs.org/_/api/chan/post/?board=" + boardID + "&num=" + postID; + var archive, name, _base, _ref; + + if (Redirect.post[boardID] == null) { + _ref = this.archiver; + for (name in _ref) { + archive = _ref[name]; + if (archive.type === 'foolfuuka' && archive.boards.contains(boardID)) { + Redirect.post[boardID] = archive.base; + break; + } + } + (_base = Redirect.post)[boardID] || (_base[boardID] = false); + } + if (Redirect.post[boardID]) { + return "" + Redirect.post[boardID] + "/_/api/chan/post/?board=" + boardID + "&num=" + postID; + } else { + return null; } }, + select: function(board) { + var archive, name, _ref, _results; + + _ref = this.archiver; + _results = []; + for (name in _ref) { + archive = _ref[name]; + if (!archive.boards.contains(board)) { + continue; + } + _results.push(name); + } + return _results; + }, to: function(data) { - var boardID; + var arch, archive, boardID; boardID = data.boardID; - switch (boardID) { - case 'a': - case 'co': - case 'gd': - case 'jp': - case 'm': - case 'q': - case 'sp': - case 'tg': - case 'tv': - case 'v': - case 'vg': - case 'vp': - case 'vr': - case 'wsg': - return Redirect.path('//archive.foolz.us', 'foolfuuka', data); - case 'u': - return Redirect.path('//nsfw.foolz.us', 'foolfuuka', data); - case 'int': - case 'out': - case 'po': - return Redirect.path('//archive.thedarkcave.org', 'foolfuuka', data); - case 'hr': - return Redirect.path('http://archive.4plebs.org', 'foolfuuka', data); - case 'ck': - case 'fa': - case 'lit': - case 's4s': - return Redirect.path('//fuuka.warosu.org', 'fuuka', data); - case 'diy': - case 'g': - case 'sci': - return Redirect.path('//archive.installgentoo.net', 'fuuka', data); - case 'cgl': - case 'mu': - case 'w': - return Redirect.path('//rbt.asia', 'fuuka', data); - case 'an': - case 'fit': - case 'k': - case 'mlp': - case 'r9k': - case 'toy': - case 'x': - return Redirect.path('http://archive.heinessen.com', 'fuuka', data); - case 'c': - return Redirect.path('//archive.nyafuu.org', 'fuuka', data); - default: - if (data.threadID) { - return "//boards.4chan.org/" + boardID + "/"; - } else { - return ''; - } + if ((arch = Conf.archivers[boardID]) == null) { + Conf.archivers[boardID] = arch = this.select(boardID)[0]; + $.set('archivers', Conf.archivers); + } + return (arch && (archive = this.archiver[arch]) ? Redirect.path(archive.base, archive.type, data) : data.threadID ? "//boards.4chan.org/" + boardID + "/" : null); + }, + archiver: { + 'Foolz': { + base: 'https://archive.foolz.us', + boards: ['a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'v', 'vg', 'vp', 'vr', 'wsg'], + type: 'foolfuuka' + }, + 'NSFWFoolz': { + base: 'https://nsfw.foolz.us', + boards: ['u'], + type: 'foolfuuka' + }, + 'TheDarkCave': { + base: 'http://archive.thedarkcave.org', + boards: ['c', 'int', 'out', 'po'], + type: 'foolfuuka' + }, + '4plebs': { + base: 'http://archive.4plebs.org', + boards: ['hr', 'tg', 'tv', 'x'], + base: 'foolfuuka' + }, + 'Warosu': { + 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' + }, + 'Heinessen': { + base: 'http://archive.heinessen.com', + boards: ['an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'], + type: 'fuuka' + }, + 'Cliche': { + base: '//www.cliché.net/4chan/cgi-board.pl', + boards: ['e'], + type: 'fuuka' + }, + 'NyaFuu': { + base: '//archive.nyafuu.org', + boards: ['c', 'w'], + type: 'fuuka' } }, path: function(base, archiver, data) { @@ -6415,7 +6434,7 @@ }); } }, - scroll: function() { + scroll: function(posts) { var hash, root; if ((hash = location.hash.match(/\d+/)) && hash[0] in this.posts) { @@ -8995,9 +9014,9 @@ return $.on(sauce, 'change', $.cb.value); }, rice: function(section) { - var event, input, inputs, items, name, _i, _len, _ref; + var archiver, event, input, inputs, items, name, toSelect, _i, _j, _len, _len1, _ref; - section.innerHTML = "
\n Custom Board Navigation is disabled.\n
\n
In the following, board can translate to a board ID (a, b, etc...), the current board (current), or the Status/Twitter link (status, @).
\n
\n For example:
\n [ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]
\n will give you
\n [ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
\n if you are on /g/.\n
\n
Board link: board
\n
Title link: board-title
\n
Board link (Replace with title when on that board): board-replace
\n
Full text link: board-full
\n
Custom text link: board-text:\"VIP Board\"
\n
Index-only link: board-index
\n
Catalog-only link: board-catalog
\n
Combinations are possible: board-index-text:\"VIP Index\"
\n
Full board list toggle: toggle-all
\n
\n\n
\n Time Formatting is disabled.\n
:
\n
Supported format specifiers:
\n
Day: %a, %A, %d, %e
\n
Month: %m, %b, %B
\n
Year: %y
\n
Hour: %k, %H, %l, %I, %p, %P
\n
Minute: %M
\n
Second: %S
\n
\n\n
\n Quote Backlinks formatting is disabled.\n
:
\n
\n\n
\n File Info Formatting is disabled.\n
:
\n
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
\n
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
\n
Spoiler indicator: %p
\n
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
\n
Resolution: %r (Displays 'PDF' for PDF files)
\n
\n\n
\n Unread Tab Icon is disabled.\n \n \n
\n\n
\n \n \n \n \n \n
"; + section.innerHTML = "
\n Archiver\n Select an Archiver for this board:\n \n
\n
\n Custom Board Navigation is disabled.\n
\n
In the following, board can translate to a board ID (a, b, etc...), the current board (current), or the Status/Twitter link (status, @).
\n
\n For example:
\n [ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]
\n will give you
\n [ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
\n if you are on /g/.\n
\n
Board link: board
\n
Title link: board-title
\n
Board link (Replace with title when on that board): board-replace
\n
Full text link: board-full
\n
Custom text link: board-text:\"VIP Board\"
\n
Index-only link: board-index
\n
Catalog-only link: board-catalog
\n
Combinations are possible: board-index-text:\"VIP Index\"
\n
Full board list toggle: toggle-all
\n
\n\n
\n Time Formatting is disabled.\n
:
\n
Supported format specifiers:
\n
Day: %a, %A, %d, %e
\n
Month: %m, %b, %B
\n
Year: %y
\n
Hour: %k, %H, %l, %I, %p, %P
\n
Minute: %M
\n
Second: %S
\n
\n\n
\n Quote Backlinks formatting is disabled.\n
:
\n
\n\n
\n File Info Formatting is disabled.\n
:
\n
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
\n
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
\n
Spoiler indicator: %p
\n
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
\n
Resolution: %r (Displays 'PDF' for PDF files)
\n
\n\n
\n Unread Tab Icon is disabled.\n \n \n
\n\n
\n \n \n \n \n \n
"; items = {}; inputs = {}; _ref = ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'usercss']; @@ -9009,6 +9028,25 @@ event = ['favicon', 'usercss'].contains(name) ? 'change' : 'input'; $.on(input, event, $.cb.value); } + archiver = $('select[name=archiver]', section); + toSelect = Redirect.select(g.BOARD.ID); + if (!toSelect[0]) { + toSelect = ['No Archive Available']; + } + for (_j = 0, _len1 = toSelect.length; _j < _len1; _j++) { + name = toSelect[_j]; + $.add(archiver, $.el('option', { + textContent: name + })); + } + if (toSelect[1]) { + Conf['archivers'][g.BOARD]; + archiver.value = Conf['archivers'][g.BOARD] || toSelect[0]; + $.on(archiver, 'change', function() { + Conf['archivers'][g.BOARD] = this.value; + return $.set('archivers', Conf.archivers); + }); + } $.get(items, function(items) { var key, val; @@ -9144,6 +9182,7 @@ boards: {} }; } + Conf['archivers'] = {}; $.get(Conf, Main.initFeatures); return $.on(d, '4chanMainInit', Main.initStyle); }, @@ -9203,6 +9242,7 @@ }; init({ 'Polyfill': Polyfill, + 'Redirection': Redirect, 'Header': Header, 'Catalog Links': CatalogLinks, 'Settings': Settings, diff --git a/builds/crx.crx b/builds/crx.crx index 5fe752f81..77e8f53c6 100644 Binary files a/builds/crx.crx and b/builds/crx.crx differ diff --git a/builds/crx/script.js b/builds/crx/script.js index d2955fe76..878bf7655 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -5156,6 +5156,17 @@ }; Redirect = { + init: function() { + return $.sync('archs', this.updateArchives); + }, + updateArchives: function() { + return $.get('archivers', {}, function(_arg) { + var archivers; + + archivers = _arg.archivers; + return Conf['archivers'] = archivers; + }); + }, image: function(boardID, filename) { switch (boardID) { case 'a': @@ -5196,91 +5207,99 @@ } }, post: function(boardID, postID) { - switch (boardID) { - case 'a': - case 'co': - case 'gd': - case 'jp': - case 'm': - case 'q': - case 'sp': - case 'tg': - case 'tv': - case 'v': - case 'vg': - case 'vp': - case 'vr': - case 'wsg': - return "https://archive.foolz.us/_/api/chan/post/?board=" + boardID + "&num=" + postID; - case 'u': - return "https://nsfw.foolz.us/_/api/chan/post/?board=" + boardID + "&num=" + postID; - case 'c': - case 'int': - case 'out': - case 'po': - return "//archive.thedarkcave.org/_/api/chan/post/?board=" + boardID + "&num=" + postID; - case 'hr': - case 'x': - return "http://archive.4plebs.org/_/api/chan/post/?board=" + boardID + "&num=" + postID; + var archive, name, _base, _ref; + + if (Redirect.post[boardID] == null) { + _ref = this.archiver; + for (name in _ref) { + archive = _ref[name]; + if (archive.type === 'foolfuuka' && archive.boards.contains(boardID)) { + Redirect.post[boardID] = archive.base; + break; + } + } + (_base = Redirect.post)[boardID] || (_base[boardID] = false); + } + if (Redirect.post[boardID]) { + return "" + Redirect.post[boardID] + "/_/api/chan/post/?board=" + boardID + "&num=" + postID; + } else { + return null; } }, + select: function(board) { + var archive, name, _ref, _results; + + _ref = this.archiver; + _results = []; + for (name in _ref) { + archive = _ref[name]; + if (!archive.boards.contains(board)) { + continue; + } + _results.push(name); + } + return _results; + }, to: function(data) { - var boardID; + var arch, archive, boardID; boardID = data.boardID; - switch (boardID) { - case 'a': - case 'co': - case 'gd': - case 'jp': - case 'm': - case 'q': - case 'sp': - case 'tg': - case 'tv': - case 'v': - case 'vg': - case 'vp': - case 'vr': - case 'wsg': - return Redirect.path('//archive.foolz.us', 'foolfuuka', data); - case 'u': - return Redirect.path('//nsfw.foolz.us', 'foolfuuka', data); - case 'int': - case 'out': - case 'po': - return Redirect.path('//archive.thedarkcave.org', 'foolfuuka', data); - case 'hr': - return Redirect.path('http://archive.4plebs.org', 'foolfuuka', data); - case 'ck': - case 'fa': - case 'lit': - case 's4s': - return Redirect.path('//fuuka.warosu.org', 'fuuka', data); - case 'diy': - case 'g': - case 'sci': - return Redirect.path('//archive.installgentoo.net', 'fuuka', data); - case 'cgl': - case 'mu': - case 'w': - return Redirect.path('//rbt.asia', 'fuuka', data); - case 'an': - case 'fit': - case 'k': - case 'mlp': - case 'r9k': - case 'toy': - case 'x': - return Redirect.path('http://archive.heinessen.com', 'fuuka', data); - case 'c': - return Redirect.path('//archive.nyafuu.org', 'fuuka', data); - default: - if (data.threadID) { - return "//boards.4chan.org/" + boardID + "/"; - } else { - return ''; - } + if ((arch = Conf.archivers[boardID]) == null) { + Conf.archivers[boardID] = arch = this.select(boardID)[0]; + $.set('archivers', Conf.archivers); + } + return (arch && (archive = this.archiver[arch]) ? Redirect.path(archive.base, archive.type, data) : data.threadID ? "//boards.4chan.org/" + boardID + "/" : null); + }, + archiver: { + 'Foolz': { + base: 'https://archive.foolz.us', + boards: ['a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'v', 'vg', 'vp', 'vr', 'wsg'], + type: 'foolfuuka' + }, + 'NSFWFoolz': { + base: 'https://nsfw.foolz.us', + boards: ['u'], + type: 'foolfuuka' + }, + 'TheDarkCave': { + base: 'http://archive.thedarkcave.org', + boards: ['c', 'int', 'out', 'po'], + type: 'foolfuuka' + }, + '4plebs': { + base: 'http://archive.4plebs.org', + boards: ['hr', 'tg', 'tv', 'x'], + base: 'foolfuuka' + }, + 'Warosu': { + 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' + }, + 'Heinessen': { + base: 'http://archive.heinessen.com', + boards: ['an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'], + type: 'fuuka' + }, + 'Cliche': { + base: '//www.cliché.net/4chan/cgi-board.pl', + boards: ['e'], + type: 'fuuka' + }, + 'NyaFuu': { + base: '//archive.nyafuu.org', + boards: ['c', 'w'], + type: 'fuuka' } }, path: function(base, archiver, data) { @@ -6338,7 +6357,7 @@ }); } }, - scroll: function() { + scroll: function(posts) { var hash, root; if ((hash = location.hash.match(/\d+/)) && hash[0] in this.posts) { @@ -8897,9 +8916,9 @@ return $.on(sauce, 'change', $.cb.value); }, rice: function(section) { - var event, input, inputs, items, name, _i, _len, _ref; + var archiver, event, input, inputs, items, name, toSelect, _i, _j, _len, _len1, _ref; - section.innerHTML = "
\n Custom Board Navigation is disabled.\n
\n
In the following, board can translate to a board ID (a, b, etc...), the current board (current), or the Status/Twitter link (status, @).
\n
\n For example:
\n [ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]
\n will give you
\n [ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
\n if you are on /g/.\n
\n
Board link: board
\n
Title link: board-title
\n
Board link (Replace with title when on that board): board-replace
\n
Full text link: board-full
\n
Custom text link: board-text:\"VIP Board\"
\n
Index-only link: board-index
\n
Catalog-only link: board-catalog
\n
Combinations are possible: board-index-text:\"VIP Index\"
\n
Full board list toggle: toggle-all
\n
\n\n
\n Time Formatting is disabled.\n
:
\n
Supported format specifiers:
\n
Day: %a, %A, %d, %e
\n
Month: %m, %b, %B
\n
Year: %y
\n
Hour: %k, %H, %l, %I, %p, %P
\n
Minute: %M
\n
Second: %S
\n
\n\n
\n Quote Backlinks formatting is disabled.\n
:
\n
\n\n
\n File Info Formatting is disabled.\n
:
\n
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
\n
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
\n
Spoiler indicator: %p
\n
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
\n
Resolution: %r (Displays 'PDF' for PDF files)
\n
\n\n
\n Unread Tab Icon is disabled.\n \n \n
\n\n
\n \n \n \n \n \n
"; + section.innerHTML = "
\n Archiver\n Select an Archiver for this board:\n \n
\n
\n Custom Board Navigation is disabled.\n
\n
In the following, board can translate to a board ID (a, b, etc...), the current board (current), or the Status/Twitter link (status, @).
\n
\n For example:
\n [ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]
\n will give you
\n [ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
\n if you are on /g/.\n
\n
Board link: board
\n
Title link: board-title
\n
Board link (Replace with title when on that board): board-replace
\n
Full text link: board-full
\n
Custom text link: board-text:\"VIP Board\"
\n
Index-only link: board-index
\n
Catalog-only link: board-catalog
\n
Combinations are possible: board-index-text:\"VIP Index\"
\n
Full board list toggle: toggle-all
\n
\n\n
\n Time Formatting is disabled.\n
:
\n
Supported format specifiers:
\n
Day: %a, %A, %d, %e
\n
Month: %m, %b, %B
\n
Year: %y
\n
Hour: %k, %H, %l, %I, %p, %P
\n
Minute: %M
\n
Second: %S
\n
\n\n
\n Quote Backlinks formatting is disabled.\n
:
\n
\n\n
\n File Info Formatting is disabled.\n
:
\n
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
\n
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
\n
Spoiler indicator: %p
\n
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
\n
Resolution: %r (Displays 'PDF' for PDF files)
\n
\n\n
\n Unread Tab Icon is disabled.\n \n \n
\n\n
\n \n \n \n \n \n
"; items = {}; inputs = {}; _ref = ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'usercss']; @@ -8911,6 +8930,25 @@ event = ['favicon', 'usercss'].contains(name) ? 'change' : 'input'; $.on(input, event, $.cb.value); } + archiver = $('select[name=archiver]', section); + toSelect = Redirect.select(g.BOARD.ID); + if (!toSelect[0]) { + toSelect = ['No Archive Available']; + } + for (_j = 0, _len1 = toSelect.length; _j < _len1; _j++) { + name = toSelect[_j]; + $.add(archiver, $.el('option', { + textContent: name + })); + } + if (toSelect[1]) { + Conf['archivers'][g.BOARD]; + archiver.value = Conf['archivers'][g.BOARD] || toSelect[0]; + $.on(archiver, 'change', function() { + Conf['archivers'][g.BOARD] = this.value; + return $.set('archivers', Conf.archivers); + }); + } $.get(items, function(items) { var key, val; @@ -9046,6 +9084,7 @@ boards: {} }; } + Conf['archivers'] = {}; $.get(Conf, Main.initFeatures); return $.on(d, '4chanMainInit', Main.initStyle); }, @@ -9105,6 +9144,7 @@ }; init({ 'Polyfill': Polyfill, + 'Redirection': Redirect, 'Header': Header, 'Catalog Links': CatalogLinks, 'Settings': Settings, diff --git a/src/features/misc/redirection.coffee b/src/features/misc/redirection.coffee index ad27d64ac..4b1ba3edd 100644 --- a/src/features/misc/redirection.coffee +++ b/src/features/misc/redirection.coffee @@ -1,4 +1,11 @@ Redirect = + init: -> + $.sync 'archs', @updateArchives + + updateArchives: -> + $.get 'archivers', {}, ({archivers}) -> + Conf['archivers'] = archivers + image: (boardID, filename) -> # Do not use g.BOARD, the image url can originate from a cross-quote. switch boardID @@ -9,7 +16,7 @@ Redirect = when 'po' "//archive.thedarkcave.org/#{boardID}/full_image/#{filename}" when 'hr', 'tv' - "http://archive.4plebs.org/#{boardID}/full_image/#{filename}" + "http://archive.4plebs.org/#{boardID}/full_image/#{filename}" when 'ck', 'fa', 'lit', 's4s' "//fuuka.warosu.org/#{boardID}/full_image/#{filename}" when 'cgl', 'g', 'mu', 'w' @@ -18,43 +25,81 @@ Redirect = "http://archive.heinessen.com/#{boardID}/full_image/#{filename}" when 'c' "//archive.nyafuu.org/#{boardID}/full_image/#{filename}" + post: (boardID, postID) -> - # XXX foolz had HSTS set for 120 days, which broke XHR+CORS+Redirection when on HTTP. - # Remove necessary HTTPS procotol in September 2013. - switch boardID - when 'a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'v', 'vg', 'vp', 'vr', 'wsg' - "https://archive.foolz.us/_/api/chan/post/?board=#{boardID}&num=#{postID}" - when 'u' - "https://nsfw.foolz.us/_/api/chan/post/?board=#{boardID}&num=#{postID}" - when 'c', 'int', 'out', 'po' - "//archive.thedarkcave.org/_/api/chan/post/?board=#{boardID}&num=#{postID}" - when 'hr', 'x' - "http://archive.4plebs.org/_/api/chan/post/?board=#{boardID}&num=#{postID}" - # for fuuka-based archives: - # https://github.com/eksopl/fuuka/issues/27 + unless Redirect.post[boardID]? + for name, archive of @archiver + if archive.type is 'foolfuuka' and archive.boards.contains boardID + Redirect.post[boardID] = archive.base + break + Redirect.post[boardID] or= false + + return if Redirect.post[boardID] + "#{Redirect.post[boardID]}/_/api/chan/post/?board=#{boardID}&num=#{postID}" + else + null + + select: (board) -> + for name, archive of @archiver + continue unless archive.boards.contains board + name + to: (data) -> {boardID} = data - switch boardID - when 'a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'v', 'vg', 'vp', 'vr', 'wsg' - Redirect.path '//archive.foolz.us', 'foolfuuka', data - when 'u' - Redirect.path '//nsfw.foolz.us', 'foolfuuka', data - when 'int', 'out', 'po' - Redirect.path '//archive.thedarkcave.org', 'foolfuuka', data - when 'hr' - Redirect.path 'http://archive.4plebs.org', 'foolfuuka', data - when 'ck', 'fa', 'lit', 's4s' - Redirect.path '//fuuka.warosu.org', 'fuuka', data - when 'diy', 'g', 'sci' - Redirect.path '//archive.installgentoo.net', 'fuuka', data - when 'cgl', 'mu', 'w' - Redirect.path '//rbt.asia', 'fuuka', data - when 'an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x' - Redirect.path 'http://archive.heinessen.com', 'fuuka', data - when 'c' - Redirect.path '//archive.nyafuu.org', 'fuuka', data - else - if data.threadID then "//boards.4chan.org/#{boardID}/" else '' + + unless (arch = Conf.archivers[boardID])? + Conf.archivers[boardID] = arch = @select(boardID)[0] + $.set 'archivers', Conf.archivers + + return (if arch and archive = @archiver[arch] + Redirect.path archive.base, archive.type, data + else if data.threadID + "//boards.4chan.org/#{boardID}/" + else + null) + + archiver: + 'Foolz': + base: 'https://archive.foolz.us' + boards: ['a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'v', 'vg', 'vp', 'vr', 'wsg'] + type: 'foolfuuka' + 'NSFWFoolz': + base: 'https://nsfw.foolz.us' + boards: ['u'] + type: 'foolfuuka' + 'TheDarkCave': + base: 'http://archive.thedarkcave.org' + boards: ['c', 'int', 'out', 'po'] + type: 'foolfuuka' + '4plebs': + base: 'http://archive.4plebs.org' + boards: ['hr', 'tg', 'tv', 'x'] + base: 'foolfuuka' + 'Warosu': + 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' + 'Heinessen': + base: 'http://archive.heinessen.com' + boards: ['an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'] + type: 'fuuka' + 'Cliche': + base: '//www.cliché.net/4chan/cgi-board.pl' + boards: ['e'] + type: 'fuuka' + 'NyaFuu': + base: '//archive.nyafuu.org' + boards: ['c', 'w'] + type: 'fuuka' + path: (base, archiver, data) -> if data.isSearch {boardID, type, value} = data diff --git a/src/features/monitoring/unread.coffee b/src/features/monitoring/unread.coffee index 18edbd94d..e51ebd721 100644 --- a/src/features/monitoring/unread.coffee +++ b/src/features/monitoring/unread.coffee @@ -30,7 +30,7 @@ Unread = $.on window, 'load', (posts) => Unread.scroll.apply @, posts - scroll: -> + 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 diff --git a/src/main.coffee b/src/main.coffee index 2ccbea66f..57a452eb5 100644 --- a/src/main.coffee +++ b/src/main.coffee @@ -14,6 +14,7 @@ Main = flatten null, Config for db in DataBoards Conf[db] = boards: {} + Conf['archivers'] = {} $.get Conf, Main.initFeatures $.on d, '4chanMainInit', Main.initStyle @@ -64,6 +65,7 @@ Main = init 'Polyfill': Polyfill + 'Redirection': Redirect 'Header': Header 'Catalog Links': CatalogLinks 'Settings': Settings diff --git a/src/settings.coffee b/src/settings.coffee index 67133b9ac..6f7ea2da4 100644 --- a/src/settings.coffee +++ b/src/settings.coffee @@ -32,6 +32,7 @@ Settings = Settings.addSection 'Sauce', Settings.sauce Settings.addSection 'Rice', Settings.rice Settings.addSection 'Keybinds', Settings.keybinds + $.on d, 'AddSettingsSection', Settings.addSection $.on d, 'OpenSettings', (e) -> Settings.open e.detail @@ -378,6 +379,11 @@ Settings = rice: (section) -> section.innerHTML = """ +
+ Archiver + Select an Archiver for this board: + +
Custom Board Navigation is disabled.
@@ -457,6 +463,21 @@ Settings = else 'input' $.on input, event, $.cb.value + + # Archiver + archiver = $ 'select[name=archiver]', section + toSelect = Redirect.select g.BOARD.ID + toSelect = ['No Archive Available'] unless toSelect[0] + + $.add archiver, $.el('option', {textContent: name}) for name in toSelect + + if toSelect[1] + Conf['archivers'][g.BOARD] + archiver.value = Conf['archivers'][g.BOARD] or toSelect[0] + $.on archiver, 'change', -> + Conf['archivers'][g.BOARD] = @value + $.set 'archivers', Conf.archivers + $.get items, (items) -> for key, val of items input = inputs[key]