From c1b213b1006b17d31efb7206d6cf85306fe6bf78 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 30 Apr 2013 04:03:17 +0200 Subject: [PATCH 1/8] Update archive redirection for many boards. --- 4chan_x.user.js | 63 ++++++++++++++++++++++++++++++++----------------- changelog | 2 ++ script.coffee | 52 ++++++++++++++++++++++++++++------------ 3 files changed, 80 insertions(+), 37 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 082a82d61..2fc5742f6 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -4930,7 +4930,6 @@ case 'm': case 'q': case 'tg': - case 'vg': case 'vp': case 'vr': case 'wsg': @@ -4939,6 +4938,17 @@ return "//nsfw.foolz.us/" + board + "/full_image/" + filename; case 'po': return "//archive.thedarkcave.org/" + board + "/full_image/" + filename; + case 'hr': + case 'tv': + return "http://archive.4plebs.org/" + board + "/full_image/" + filename; + case 'c': + case 'w': + case 'wg': + return "//archive.nyafuu.org/" + board + "/full_image/" + filename; + case 'vg': + return "http://archive.nihil-ad-rem.net/" + board + "/full_image/" + filename; + case 'd': + return "//loveisover.me/" + board + "/full_image/" + filename; case 'ck': case 'fa': case 'lit': @@ -4947,15 +4957,12 @@ case 'cgl': case 'g': case 'mu': - case 'w': return "//rbt.asia/" + board + "/full_image/" + filename; case 'an': case 'k': case 'toy': case 'x': return "http://archive.heinessen.com/" + board + "/full_image/" + filename; - case 'c': - return "//archive.nyafuu.org/" + board + "/full_image/" + filename; } }, post: function(board, postID) { @@ -4969,22 +4976,28 @@ case 'sp': case 'tg': case 'tv': - case 'v': - case 'vg': case 'vp': case 'vr': case 'wsg': - case 'dev': - case 'foolz': - return "//archive.foolz.us/_/api/chan/post/?board=" + board + "&num=" + postID; + return "https://archive.foolz.us/_/api/chan/post/?board=" + board + "&num=" + postID; case 'u': - case 'kuku': - return "//nsfw.foolz.us/_/api/chan/post/?board=" + board + "&num=" + postID; - case 'c': + return "https://nsfw.foolz.us/_/api/chan/post/?board=" + board + "&num=" + postID; case 'int': case 'out': case 'po': return "//archive.thedarkcave.org/_/api/chan/post/?board=" + board + "&num=" + postID; + case 'hr': + case 'x': + return "http://archive.4plebs.org/_/api/chan/post/?board=" + board + "&num=" + postID; + case 'c': + case 'w': + case 'wg': + return "//archive.nyafuu.org/_/api/chan/post/?board=" + board + "&num=" + postID; + case 'v': + case 'vg': + return "http://archive.nihil-ad-rem.net/_/api/chan/post/?board=" + board + "&num=" + postID; + case 'd': + return "//loveisover.me/_/api/chan/post/?board=" + board + "&num=" + postID; } }, to: function(data) { @@ -5003,17 +5016,12 @@ case 'sp': case 'tg': case 'tv': - case 'v': - case 'vg': case 'vp': case 'vr': case 'wsg': - case 'dev': - case 'foolz': url = Redirect.path('//archive.foolz.us', 'foolfuuka', data); break; case 'u': - case 'kuku': url = Redirect.path('//nsfw.foolz.us', 'foolfuuka', data); break; case 'int': @@ -5021,6 +5029,21 @@ case 'po': url = Redirect.path('//archive.thedarkcave.org', 'foolfuuka', data); break; + case 'hr': + url = Redirect.path('http://archive.4plebs.org', 'foolfuuka', data); + break; + case 'c': + case 'w': + case 'wg': + url = Redirect.path('//archive.nyafuu.org', 'foolfuuka', data); + break; + case 'v': + case 'vg': + url = Redirect.path('http://archive.nihil-ad-rem.net', 'foolfuuka', data); + break; + case 'd': + url = Redirect.path('//loveisover.me', 'foolfuuka', data); + break; case 'ck': case 'fa': case 'lit': @@ -5028,13 +5051,12 @@ url = Redirect.path('//fuuka.warosu.org', 'fuuka', data); break; case 'diy': + case 'g': case 'sci': url = Redirect.path('//archive.installgentoo.net', 'fuuka', data); break; case 'cgl': - case 'g': case 'mu': - case 'w': url = Redirect.path('//rbt.asia', 'fuuka', data); break; case 'an': @@ -5046,9 +5068,6 @@ case 'x': url = Redirect.path('http://archive.heinessen.com', 'fuuka', data); break; - case 'c': - url = Redirect.path('//archive.nyafuu.org', 'fuuka', data); - break; default: if (threadID) { url = "//boards.4chan.org/" + board + "/"; diff --git a/changelog b/changelog index 668d9c853..d8fdec0da 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master +- Mayhem + Update archive redirection for many boards. 2.39.3 - Mayhem diff --git a/script.coffee b/script.coffee index 96cb6bb09..c3439588b 100644 --- a/script.coffee +++ b/script.coffee @@ -4086,49 +4086,71 @@ Redirect = image: (board, filename) -> # Do not use g.BOARD, the image url can originate from a cross-quote. switch board - when 'a', 'gd', 'jp', 'm', 'q', 'tg', 'vg', 'vp', 'vr', 'wsg' + when 'a', 'gd', 'jp', 'm', 'q', 'tg', 'vp', 'vr', 'wsg' "//archive.foolz.us/#{board}/full_image/#{filename}" when 'u' "//nsfw.foolz.us/#{board}/full_image/#{filename}" when 'po' "//archive.thedarkcave.org/#{board}/full_image/#{filename}" + when 'hr', 'tv' + "http://archive.4plebs.org/#{board}/full_image/#{filename}" + when 'c', 'w', 'wg' + "//archive.nyafuu.org/#{board}/full_image/#{filename}" + when 'vg' + "http://archive.nihil-ad-rem.net/#{board}/full_image/#{filename}" + when 'd' + "//loveisover.me/#{board}/full_image/#{filename}" when 'ck', 'fa', 'lit', 's4s' "//fuuka.warosu.org/#{board}/full_image/#{filename}" - when 'cgl', 'g', 'mu', 'w' + when 'cgl', 'g', 'mu' "//rbt.asia/#{board}/full_image/#{filename}" when 'an', 'k', 'toy', 'x' "http://archive.heinessen.com/#{board}/full_image/#{filename}" - when 'c' - "//archive.nyafuu.org/#{board}/full_image/#{filename}" post: (board, 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 board - when 'a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'v', 'vg', 'vp', 'vr', 'wsg', 'dev', 'foolz' - "//archive.foolz.us/_/api/chan/post/?board=#{board}&num=#{postID}" - when 'u', 'kuku' - "//nsfw.foolz.us/_/api/chan/post/?board=#{board}&num=#{postID}" - when 'c', 'int', 'out', 'po' + when 'a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'vp', 'vr', 'wsg' + "https://archive.foolz.us/_/api/chan/post/?board=#{board}&num=#{postID}" + when 'u' + "https://nsfw.foolz.us/_/api/chan/post/?board=#{board}&num=#{postID}" + when 'int', 'out', 'po' "//archive.thedarkcave.org/_/api/chan/post/?board=#{board}&num=#{postID}" + when 'hr', 'x' + "http://archive.4plebs.org/_/api/chan/post/?board=#{board}&num=#{postID}" + when 'c', 'w', 'wg' + "//archive.nyafuu.org/_/api/chan/post/?board=#{board}&num=#{postID}" + when 'v', 'vg' + "http://archive.nihil-ad-rem.net/_/api/chan/post/?board=#{board}&num=#{postID}" + when 'd' + "//loveisover.me/_/api/chan/post/?board=#{board}&num=#{postID}" to: (data) -> unless data.isSearch {threadID} = data {board} = data switch board - when 'a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'v', 'vg', 'vp', 'vr', 'wsg', 'dev', 'foolz' + when 'a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'vp', 'vr', 'wsg' url = Redirect.path '//archive.foolz.us', 'foolfuuka', data - when 'u', 'kuku' + when 'u' url = Redirect.path '//nsfw.foolz.us', 'foolfuuka', data when 'int', 'out', 'po' url = Redirect.path '//archive.thedarkcave.org', 'foolfuuka', data + when 'hr' + url = Redirect.path 'http://archive.4plebs.org', 'foolfuuka', data + when 'c', 'w', 'wg' + url = Redirect.path '//archive.nyafuu.org', 'foolfuuka', data + when 'v', 'vg' + url = Redirect.path 'http://archive.nihil-ad-rem.net', 'foolfuuka', data + when 'd' + url = Redirect.path '//loveisover.me', 'foolfuuka', data when 'ck', 'fa', 'lit', 's4s' url = Redirect.path '//fuuka.warosu.org', 'fuuka', data - when 'diy', 'sci' + when 'diy', 'g', 'sci' url = Redirect.path '//archive.installgentoo.net', 'fuuka', data - when 'cgl', 'g', 'mu', 'w' + when 'cgl', 'mu' url = Redirect.path '//rbt.asia', 'fuuka', data when 'an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x' url = Redirect.path 'http://archive.heinessen.com', 'fuuka', data - when 'c' - url = Redirect.path '//archive.nyafuu.org', 'fuuka', data else if threadID url = "//boards.4chan.org/#{board}/" From 77461c91f37563c3a306f2ce2c242db6486ec630 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 30 Apr 2013 04:04:18 +0200 Subject: [PATCH 2/8] Release 2.39.4. --- 4chan_x.user.js | 6 +++--- Cakefile | 2 +- changelog | 2 ++ latest.js | 2 +- script.coffee | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 2fc5742f6..0f3f331ec 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan x -// @version 2.39.3 +// @version 2.39.4 // @namespace aeosynth // @description Adds various features. // @copyright 2009-2011 James Campos @@ -27,7 +27,7 @@ * Copyright (c) 2009-2011 James Campos * Copyright (c) 2012-2013 Nicolas Stepien * http://mayhemydg.github.io/4chan-x/ - * 4chan X 2.39.3 + * 4chan X 2.39.4 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -5841,7 +5841,7 @@ return $.globalEval(("(" + code + ")()").replace('_id_', bq.id)); }, namespace: '4chan_x.', - version: '2.39.3', + version: '2.39.4', callbacks: [], css: '\ /* dialog styling */\ diff --git a/Cakefile b/Cakefile index a96ed378a..8df549c52 100644 --- a/Cakefile +++ b/Cakefile @@ -2,7 +2,7 @@ {exec} = require 'child_process' fs = require 'fs' -VERSION = '2.39.3' +VERSION = '2.39.4' HEADER = """ // ==UserScript== diff --git a/changelog b/changelog index d8fdec0da..3ae38c38c 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master + +2.39.4 - Mayhem Update archive redirection for many boards. diff --git a/latest.js b/latest.js index deefc42d9..ec80c872c 100644 --- a/latest.js +++ b/latest.js @@ -1 +1 @@ -postMessage({version:'2.39.3'},'*') \ No newline at end of file +postMessage({version:'2.39.4'},'*') \ No newline at end of file diff --git a/script.coffee b/script.coffee index c3439588b..646001c19 100644 --- a/script.coffee +++ b/script.coffee @@ -4750,7 +4750,7 @@ Main = $.globalEval "(#{code})()".replace '_id_', bq.id namespace: '4chan_x.' - version: '2.39.3' + version: '2.39.4' callbacks: [] css: ' /* dialog styling */ From aace44479e4ed8c8d71aa6e87e97194b005811b6 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Fri, 10 May 2013 14:36:27 +0200 Subject: [PATCH 3/8] Fix #1095. --- src/Miscellaneous/ExpandThread.coffee | 2 +- src/Monitoring/ThreadUpdater.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Miscellaneous/ExpandThread.coffee b/src/Miscellaneous/ExpandThread.coffee index a31329482..4fd4d44a4 100644 --- a/src/Miscellaneous/ExpandThread.coffee +++ b/src/Miscellaneous/ExpandThread.coffee @@ -84,7 +84,7 @@ ExpandThread = if post = thread.posts[reply.no] nodes.push post.nodes.root continue - node = Build.postFromObject reply, thread.board + node = Build.postFromObject reply, thread.board.ID post = new Post node, thread, thread.board link = $ 'a[title="Highlight this post"]', node link.href = "res/#{thread}#p#{post}" diff --git a/src/Monitoring/ThreadUpdater.coffee b/src/Monitoring/ThreadUpdater.coffee index b1c50f2ef..a8ab419e9 100644 --- a/src/Monitoring/ThreadUpdater.coffee +++ b/src/Monitoring/ThreadUpdater.coffee @@ -210,7 +210,7 @@ ThreadUpdater = continue if num <= ThreadUpdater.lastPost # Insert new posts, not older ones. count++ - node = Build.postFromObject postObject, ThreadUpdater.thread.board + node = Build.postFromObject postObject, ThreadUpdater.thread.board.ID nodes.push node posts.push new Post node, ThreadUpdater.thread, ThreadUpdater.thread.board From 1857bf7545b0859f67b9c15d7440b7fcf92c7882 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sat, 11 May 2013 01:34:18 +0200 Subject: [PATCH 4/8] /vg/ is back! --- json/archives.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/json/archives.json b/json/archives.json index 3ac796df7..d5f527798 100644 --- a/json/archives.json +++ b/json/archives.json @@ -59,8 +59,8 @@ "http": true, "https": false, "software": "foolfuuka", - "boards": [], - "files": [] + "boards": ["vg"], + "files": ["vg"] }, { "uid": 11, "name": "Foolz a Shit", From cb3623eca3726347d61e3c14f2d03987c5729f0a Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sat, 11 May 2013 18:59:06 +0200 Subject: [PATCH 5/8] Update archive redirection for even more boards. --- changelog | 2 ++ script.coffee | 58 ++++++++++++++++++++++++++++----------------------- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/changelog b/changelog index 3ae38c38c..aae7b20fc 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master +- Mayhem + Update archive redirection for even more boards. 2.39.4 - Mayhem diff --git a/script.coffee b/script.coffee index 646001c19..1c58d0708 100644 --- a/script.coffee +++ b/script.coffee @@ -4092,20 +4092,22 @@ Redirect = "//nsfw.foolz.us/#{board}/full_image/#{filename}" when 'po' "//archive.thedarkcave.org/#{board}/full_image/#{filename}" - when 'hr', 'tv' + when 'hr', 'tv', 'x' "http://archive.4plebs.org/#{board}/full_image/#{filename}" when 'c', 'w', 'wg' "//archive.nyafuu.org/#{board}/full_image/#{filename}" - when 'vg' - "http://archive.nihil-ad-rem.net/#{board}/full_image/#{filename}" - when 'd' + when 'd', 'h', 'v' "//loveisover.me/#{board}/full_image/#{filename}" - when 'ck', 'fa', 'lit', 's4s' - "//fuuka.warosu.org/#{board}/full_image/#{filename}" + when 'vg' + "http://nth.pensivenonsen.se/#{board}/full_image/#{filename}" + when 'adv', 'asp', 'cm', 'e', 'i', 'lgbt', 'n', 'o', 'p', 's', 's4s', 't', 'trv', 'y' + "//archive.foolzashit.com/#{board}/full_image/#{filename}" when 'cgl', 'g', 'mu' "//rbt.asia/#{board}/full_image/#{filename}" - when 'an', 'k', 'toy', 'x' + when 'an', 'k', 'toy' "http://archive.heinessen.com/#{board}/full_image/#{filename}" + when '3', 'ck', 'fa', 'ic', 'lit' + "//fuuka.warosu.org/#{board}/full_image/#{filename}" post: (board, postID) -> # XXX foolz had HSTS set for 120 days, which broke XHR+CORS+Redirection when on HTTP. # Remove necessary HTTPS procotol in September 2013. @@ -4120,37 +4122,41 @@ Redirect = "http://archive.4plebs.org/_/api/chan/post/?board=#{board}&num=#{postID}" when 'c', 'w', 'wg' "//archive.nyafuu.org/_/api/chan/post/?board=#{board}&num=#{postID}" - when 'v', 'vg' - "http://archive.nihil-ad-rem.net/_/api/chan/post/?board=#{board}&num=#{postID}" - when 'd' + when 'd', 'h', 'v' "//loveisover.me/_/api/chan/post/?board=#{board}&num=#{postID}" + when 'vg' + "http://nth.pensivenonsen.se/_/api/chan/post/?board=#{board}&num=#{postID}" + when 'adv', 'asp', 'cm', 'e', 'i', 'lgbt', 'n', 'o', 'p', 's', 's4s', 't', 'trv', 'y' + "//archive.foolzashit.com/_/api/chan/post/?board=#{board}&num=#{postID}" to: (data) -> unless data.isSearch {threadID} = data {board} = data switch board when 'a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'vp', 'vr', 'wsg' - url = Redirect.path '//archive.foolz.us', 'foolfuuka', data + url = Redirect.path '//archive.foolz.us', 'foolfuuka', data when 'u' - url = Redirect.path '//nsfw.foolz.us', 'foolfuuka', data + url = Redirect.path '//nsfw.foolz.us', 'foolfuuka', data when 'int', 'out', 'po' - url = Redirect.path '//archive.thedarkcave.org', 'foolfuuka', data - when 'hr' - url = Redirect.path 'http://archive.4plebs.org', 'foolfuuka', data + url = Redirect.path '//archive.thedarkcave.org', 'foolfuuka', data + when 'hr', 'x' + url = Redirect.path 'http://archive.4plebs.org', 'foolfuuka', data when 'c', 'w', 'wg' - url = Redirect.path '//archive.nyafuu.org', 'foolfuuka', data - when 'v', 'vg' - url = Redirect.path 'http://archive.nihil-ad-rem.net', 'foolfuuka', data - when 'd' - url = Redirect.path '//loveisover.me', 'foolfuuka', data - when 'ck', 'fa', 'lit', 's4s' - url = Redirect.path '//fuuka.warosu.org', 'fuuka', data + url = Redirect.path '//archive.nyafuu.org', 'foolfuuka', data + when 'd', 'h', 'v' + url = Redirect.path '//loveisover.me', 'foolfuuka', data + when 'vg' + url = Redirect.path 'http://nth.pensivenonsen.se', 'foolfuuka', data + when 'adv', 'asp', 'cm', 'e', 'i', 'lgbt', 'n', 'o', 'p', 's', 's4s', 't', 'trv', 'y' + url = Redirect.path '//archive.foolzashit.com', 'foolfuuka', data when 'diy', 'g', 'sci' - url = Redirect.path '//archive.installgentoo.net', 'fuuka', data + url = Redirect.path '//archive.installgentoo.net', 'fuuka', data when 'cgl', 'mu' - url = Redirect.path '//rbt.asia', 'fuuka', data - when 'an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x' - url = Redirect.path 'http://archive.heinessen.com', 'fuuka', data + url = Redirect.path '//rbt.asia', 'fuuka', data + when 'an', 'fit', 'k', 'mlp', 'r9k', 'toy' + url = Redirect.path 'http://archive.heinessen.com', 'fuuka', data + when '3', 'ck', 'fa', 'ic', 'lit' + url = Redirect.path '//fuuka.warosu.org', 'fuuka', data else if threadID url = "//boards.4chan.org/#{board}/" From ecd111ea6cc2b43bf2458dfd2829bbd9a120f3a1 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Sat, 11 May 2013 18:59:21 +0200 Subject: [PATCH 6/8] Release 2.39.5. --- 4chan_x.user.js | 6 +++--- Cakefile | 2 +- changelog | 2 ++ latest.js | 2 +- script.coffee | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 0f3f331ec..2d813fe86 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan x -// @version 2.39.4 +// @version 2.39.5 // @namespace aeosynth // @description Adds various features. // @copyright 2009-2011 James Campos @@ -27,7 +27,7 @@ * Copyright (c) 2009-2011 James Campos * Copyright (c) 2012-2013 Nicolas Stepien * http://mayhemydg.github.io/4chan-x/ - * 4chan X 2.39.4 + * 4chan X 2.39.5 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -5841,7 +5841,7 @@ return $.globalEval(("(" + code + ")()").replace('_id_', bq.id)); }, namespace: '4chan_x.', - version: '2.39.4', + version: '2.39.5', callbacks: [], css: '\ /* dialog styling */\ diff --git a/Cakefile b/Cakefile index 8df549c52..9c25140f4 100644 --- a/Cakefile +++ b/Cakefile @@ -2,7 +2,7 @@ {exec} = require 'child_process' fs = require 'fs' -VERSION = '2.39.4' +VERSION = '2.39.5' HEADER = """ // ==UserScript== diff --git a/changelog b/changelog index aae7b20fc..2c8d39353 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ master + +2.39.5 - Mayhem Update archive redirection for even more boards. diff --git a/latest.js b/latest.js index ec80c872c..30b8eefce 100644 --- a/latest.js +++ b/latest.js @@ -1 +1 @@ -postMessage({version:'2.39.4'},'*') \ No newline at end of file +postMessage({version:'2.39.5'},'*') \ No newline at end of file diff --git a/script.coffee b/script.coffee index 1c58d0708..302d99bec 100644 --- a/script.coffee +++ b/script.coffee @@ -4756,7 +4756,7 @@ Main = $.globalEval "(#{code})()".replace '_id_', bq.id namespace: '4chan_x.' - version: '2.39.4' + version: '2.39.5' callbacks: [] css: ' /* dialog styling */ From 249a739bfc199340901996aa0269ee0095bcac2e Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sun, 12 May 2013 09:00:00 -0700 Subject: [PATCH 7/8] Add @MayhemYDG's archive redirection --- builds/4chan-X.js | 481 +++++++++++++++--------- builds/4chan-X.user.js | 481 +++++++++++++++--------- builds/crx/script.js | 481 +++++++++++++++--------- src/Archive/Redirect.coffee | 295 ++++++++------- src/General/Get.coffee | 6 +- src/General/Main.coffee | 9 +- src/General/Settings.coffee | 80 +++- src/General/html/Settings/Advanced.html | 5 - src/General/html/Settings/Archives.html | 12 + src/Images/ImageExpand.coffee | 5 +- src/Images/ImageHover.coffee | 5 +- src/Menu/ArchiveLink.coffee | 7 +- src/Quotelinks/Quotify.coffee | 4 +- 13 files changed, 1140 insertions(+), 731 deletions(-) create mode 100644 src/General/html/Settings/Archives.html diff --git a/builds/4chan-X.js b/builds/4chan-X.js index b8aa78939..26a197f7a 100644 --- a/builds/4chan-X.js +++ b/builds/4chan-X.js @@ -2048,7 +2048,10 @@ return $.cache("//api.4chan.org/" + boardID + "/res/" + threadID + ".json", function() { return Get.fetchedPost(this, boardID, threadID, postID, root, context); }); - } else if (url = Redirect.post(boardID, postID)) { + } else if (url = Redirect.to('post', { + boardID: boardID, + postID: postID + })) { return $.cache(url, function() { return Get.archivedPost(this, boardID, postID, root, context); }); @@ -2077,7 +2080,10 @@ } status = req.status; if (![200, 304].contains(status)) { - if (url = Redirect.post(boardID, postID)) { + if (url = Redirect.to('post', { + boardID: boardID, + postID: postID + })) { $.cache(url, function() { return Get.archivedPost(this, boardID, postID, root, context); }); @@ -2095,7 +2101,10 @@ break; } if (post.no > postID) { - if (url = Redirect.post(boardID, postID)) { + if (url = Redirect.to('post', { + boardID: boardID, + postID: postID + })) { $.cache(url, function() { return Get.archivedPost(this, boardID, postID, root, context); }); @@ -4223,7 +4232,7 @@ a.setAttribute('data-threadid', post.thread.ID); a.setAttribute('data-postid', postID); } - } else if (redirect = Redirect.to({ + } else if (redirect = Redirect.to('thread', { boardID: boardID, threadID: 0, postID: postID @@ -4234,7 +4243,10 @@ target: '_blank', textContent: "" + quote + "\u00A0(Dead)" }); - if (Redirect.post(boardID, postID)) { + if (Redirect.to('post', { + boardID: boardID, + postID: postID + })) { $.addClass(a, 'quotelink'); a.setAttribute('data-boardid', boardID); a.setAttribute('data-postid', postID); @@ -6233,7 +6245,11 @@ ImageExpand.contract(post); src = this.src.split('/'); if (src[2] === 'images.4chan.org') { - if (URL = Redirect.image(src[3], src[5])) { + URL = Redirect.to('image', { + boardID: src[3], + filename: src[5] + }); + if (URL) { setTimeout(ImageExpand.expand, 10000, post, URL); return; } @@ -6369,7 +6385,11 @@ post = g.posts[this.dataset.fullid]; src = this.src.split('/'); if (src[2] === 'images.4chan.org') { - if (URL = Redirect.image(src[3], src[5].replace(/\?.+$/, ''))) { + URL = Redirect.to('image', { + boardID: src[3], + filename: src[5].replace(/\?.+$/, '') + }); + if (URL) { this.src = URL; return; } @@ -6475,15 +6495,14 @@ el: div, order: 90, open: function(_arg) { - var ID, board, redirect, thread; + var ID, board, thread; ID = _arg.ID, thread = _arg.thread, board = _arg.board; - redirect = Redirect.to({ + return !!Redirect.to('thread', { postID: ID, threadID: thread.ID, boardID: board.ID }); - return redirect !== ("//boards.4chan.org/" + board + "/"); }, subEntries: [] }; @@ -6505,7 +6524,7 @@ var ID, board, thread; ID = _arg.ID, thread = _arg.thread, board = _arg.board; - el.href = Redirect.to({ + el.href = Redirect.to('thread', { postID: ID, threadID: thread.ID, boardID: board.ID @@ -6518,7 +6537,7 @@ if (!value) { return false; } - el.href = Redirect.to({ + el.href = Redirect.to('search', { boardID: post.board.ID, type: type, value: value, @@ -7731,185 +7750,197 @@ }; Redirect = { + thread: {}, + post: {}, + file: {}, init: function() { - return $.sync('archivers', this.updateArchives); - }, - updateArchives: function() { - return $.get('archivers', {}, function(_arg) { - var archivers; + var archive, arr, boardID, data, id, name, type, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3; - archivers = _arg.archivers; - return Conf['archivers'] = archivers; - }); - }, - imageArchives: (function() { - var o; - - o = { - a: "//archive.foolz.us/", - ck: "//fuuka.warosu.org/", - an: "http://archive.heinessen.com/", - cgl: "//rbt.asia/", - c: "//archive.nyafuu.org/", - d: "//loveisover.me/", - e: "http://archive.foolzashit.com", - hr: "http://archive.4plebs.org/", - u: "//nsfw.foolz.us/", - po: "//archive.thedarkcave.org/", - vg: "http://nth.pensivenonsen.se/", - c: "//archive.nyafuu.org/" - }; - o.adv = o.asp = o.cm = o.i = o.n = o.o = o.p = o.s = o.t = o.trv = o.y = o.lgbt = o.s4s = o.e; - o.gd = o.jp = o.m = o.q = o.tg = o.vp = o.vr = o.wsg = o.a; - o.fa = o.lit = o.ck; - o.k = o.toy = o.x = o.an; - o.g = o.mu = o.cgl; - o.w = o.wg = o.c; - o.h = o.v = o.d; - o.tv = o.hr; - return o; - })(), - image: function(boardID, filename) { - return "" + Redirect.imageArchives[boardID] + boardID + "/full_image/" + filename; - }, - post: function(boardID, 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; + _ref = Conf['selectedArchives']; + for (boardID in _ref) { + data = _ref[boardID]; + for (type in data) { + id = data[type]; + _ref1 = Redirect.archives; + for (name in _ref1) { + archive = _ref1[name]; + if (name !== id || type === 'post' && archive.software !== 'foolfuuka') { + continue; + } + arr = type === 'file' ? archive.files : archive.boards; + if (arr.contains(boardID)) { + Redirect[type][boardID] = archive; + } } } - (_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; + _ref2 = Redirect.archives; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + archive = _ref2[_i]; + _ref3 = archive.boards; + for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { + boardID = _ref3[_j]; + if (!(boardID in Redirect.thread)) { + Redirect.thread[boardID] = archive; + } + if (!(boardID in Redirect.post || archive.software !== 'foolfuuka')) { + Redirect.post[boardID] = archive; + } + if (!(boardID in Redirect.file || !archive.files.contains(boardID))) { + Redirect.file[boardID] = archive; + } } - _results.push(name); - } - return _results; - }, - to: function(data) { - var arch, archive, boardID; - - boardID = data.boardID; - 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); - if (!archive.boards.contains(g.BOARD.ID)) { - return Conf['archivers'] = archive; } }, - archiver: { + archives: { 'Foolz': { - base: 'https://archive.foolz.us', - boards: ['a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'vp', 'vr', 'wsg'], - type: 'foolfuuka' + 'domain': 'archive.foolz.us', + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'vp', 'vr', 'wsg'], + 'files': ['a', 'gd', 'jp', 'm', 'q', 'tg', 'vp', 'vr', 'wsg'] }, - 'NSFWFoolz': { - base: 'https://nsfw.foolz.us', - boards: ['u'], - type: 'foolfuuka' + 'NSFW Foolz': { + 'domain': 'nsfw.foolz.us', + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['u'], + 'files': ['u'] }, - 'TheDarkCave': { - base: 'http://archive.thedarkcave.org', - boards: ['c', 'int', 'out', 'po'], - type: 'foolfuuka' + 'The Dark Cave': { + 'domain': 'archive.thedarkcave.org', + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['c', 'int', 'out', 'po'], + 'files': ['c', 'po'] }, '4plebs': { - base: 'http://archive.4plebs.org', - boards: ['hr', 'tg', 'tv', 'x'], - base: 'foolfuuka' + 'domain': 'archive.4plebs.org', + 'http': true, + 'software': 'foolfuuka', + 'boards': ['hr', 'tg', 'tv', 'x'], + 'files': ['hr', 'tg', 'tv', 'x'] }, - 'NyaFuu': { - base: '//archive.nyafuu.org', - boards: ['c', 'w', 'wg'], - type: 'foolfuuka' + 'Nyafuu': { + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['c', 'w', 'wg'], + 'files': ['c', 'w', 'wg'] }, - 'LoveIsOver': { - base: '//loveisover.me', - boards: ['d', 'h', 'v'], - type: 'foolfuuka' + 'Love is Over': { + 'domain': 'loveisover.me', + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['d', 'h', 'v'], + 'files': ['d', 'h', 'v'] }, - 'PensiveNonsen': { - base: 'http://nth.pensivenonsen.se', - boards: ['vg'], - type: 'foolfuuka' + 'nth-chan': { + 'domain': 'nth.pensivenonsen.se', + 'http': true, + 'software': 'foolfuuka', + 'boards': ['vg'], + 'files': ['vg'] }, - 'FoolzaShit': { - base: 'http://archive.foolzashit.com', - boards: ["adv", "asp", "cm", "e", "i", "lgbt", "n", "o", "p", "s", "s4s", "t", "trv", "y"], - type: 'foolfuuka' + 'Foolz a Shit': { + 'domain': 'archive.foolzashit.com', + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['adv', 'asp', 'cm', 'e', 'i', 'lgbt', 'n', 'o', 'p', 's', 's4s', 't', 'trv', 'y'], + 'files': ['adv', 'asp', 'cm', 'e', 'i', 'lgbt', 'n', 'o', 'p', 's', 's4s', 't', 'trv', 'y'] }, - 'Warosu': { - base: '//fuuka.warosu.org', - boards: ['cgl', 'ck', 'fa', 'jp', 'lit', 's4s', 'q', 'tg', 'vr'], - type: 'fuuka' + 'Install Gentoo': { + 'domain': 'archive.installgentoo.net', + 'http': true, + 'https': true, + 'software': 'fuuka', + 'boards': ['diy', 'g', 'sci'], + 'files': [] }, - 'InstallGentoo': { - base: '//archive.installgentoo.net', - boards: ['diy', 'g', 'sci'], - type: 'fuuka' - }, - 'RebeccaBlackTech': { - base: '//rbt.asia', - boards: ['cgl', 'g', 'mu', 'w'], - type: 'fuuka_mail' + 'Rebecca Black Tech': { + 'domain': 'rbt.asia', + 'http': true, + 'https': true, + 'software': 'fuuka', + 'boards': ['cgl', 'g', 'mu', 'w'], + 'files': ['cgl', 'g', 'mu', 'w'] }, 'Heinessen': { - base: 'http://archive.heinessen.com', - boards: ['an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'], - type: 'fuuka' + 'domain': 'archive.heinessen.com', + 'http': true, + 'software': 'fuuka', + 'boards': ['an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'], + 'files': ['an', 'k', 'toy', 'x'] }, - 'Cliche': { - base: '//www.cliché.net/4chan/cgi-board.pl', - boards: ['e'], - type: 'fuuka' + 'warosu': { + 'domain': 'fuuka.warosu.org', + 'http': true, + 'https': true, + 'software': 'fuuka', + 'boards': ['3', 'cgl', 'ck', 'fa', 'ic', 'jp', 'lit', 'q', 's4s', 'tg', 'vr'], + 'files': ['3', 'cgl', 'ck', 'fa', 'ic', 'jp', 'lit', 'q', 's4s', 'vr'] } }, - path: function(base, archiver, data) { - var boardID, path, postID, threadID, type, value; + to: function(dest, data) { + var archive; - if (data.isSearch) { - boardID = data.boardID, type = data.type, value = data.value; - type = type === 'name' ? 'username' : type === 'MD5' ? 'image' : type; - value = encodeURIComponent(value); - if (archiver === 'foolfuuka') { - return "" + base + "/" + boardID + "/search/" + type + "/" + value; - } else if (type === 'image') { - return "" + base + "/" + boardID + "/?task=search2&search_media_hash=" + value; - } else { - return "" + base + "/" + boardID + "/?task=search2&search_" + type + "=" + value; - } + archive = (dest === 'search' ? Redirect.thread : Redirect[dest])[data.boardID]; + if (!archive) { + return ''; } - boardID = data.boardID, threadID = data.threadID, postID = data.postID; + return Redirect[dest](archive, data); + }, + protocol: function(archive) { + var protocol; + + protocol = location.protocol; + if (!archive[protocol.slice(0, -1)]) { + protocol = protocol === 'https:' ? 'http:' : 'https:'; + } + return "" + protocol + "//"; + }, + thread: function(archive, _arg) { + var boardID, path, postID, threadID; + + boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID; path = threadID ? "" + boardID + "/thread/" + threadID : "" + boardID + "/post/" + postID; - if (archiver === 'foolfuuka') { + if (archive.software === 'foolfuuka') { path += '/'; } if (threadID && postID) { - path += archiver === 'foolfuuka' ? "#" + postID : "#p" + postID; + path += archive.software === 'foolfuuka' ? "#" + postID : "#p" + postID; } - return "" + base + "/" + path; + return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path; + }, + post: function(archive, _arg) { + var boardID, postID, protocol; + + boardID = _arg.boardID, postID = _arg.postID; + protocol = Redirect.protocol(archive); + if (['Foolz', 'NSFW Foolz'].contains(archive.name)) { + protocol = 'https://'; + } + return "" + protocol + archive.domain + "/_/api/chan/post/?board=" + boardID + "&num=" + postID; + }, + file: function(archive, _arg) { + var boardID, filename; + + boardID = _arg.boardID, filename = _arg.filename; + return "" + (Redirect.protocol(archive)) + archive.domain + "/" + boardID + "/full_image/" + filename; + }, + search: function(archive, _arg) { + var boardID, path, type, value; + + boardID = _arg.boardID, type = _arg.type, value = _arg.value; + type = type === 'name' ? 'username' : type === 'MD5' ? 'image' : type; + value = encodeURIComponent(value); + path = archive.software === 'foolfuuka' ? "" + boardID + "/search/" + type + "/" + value : "" + boardID + "/?task=search2&search_" + (type === 'image' ? 'media_hash' : type) + "=" + value; + return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path; } }; @@ -9345,6 +9376,7 @@ Settings.addSection('Filter', Settings.filter); Settings.addSection('Sauce', Settings.sauce); Settings.addSection('Advanced', Settings.advanced); + Settings.addSection('Archives', Settings.archives); Settings.addSection('Keybinds', Settings.keybinds); $.on(d, 'AddSettingsSection', Settings.addSection); $.on(d, 'OpenSettings', function(e) { @@ -9725,9 +9757,9 @@ return $.on(ta, 'change', $.cb.value); }, advanced: function(section) { - var archiver, event, input, inputs, items, name, ta, toSelect, _i, _j, _len, _len1, _ref; + var event, input, inputs, items, name, ta, _i, _len, _ref; - section.innerHTML = "
Archiver\nSelect an Archiver for this board:\n
Custom Board Navigation
New lines will be converted into spaces.

In the following, board can translate to a board ID (a, b, etc...), the current board (current), or the Status/Twitter link (status, @).
\n For example:
[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]
\n will give you
[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
\n if you are on /g/.\n
Board link: board
Title link: board-title
Board link (Replace with title when on that board): board-replace
Full text link: board-full
Custom text link: board-text:\"VIP Board\"
Index-only link: board-index
Catalog-only link: board-catalog
External link: external-text:\"Google\",\"http://www.google.com\"
Combinations are possible: board-index-text:\"VIP Index\"
Full board list toggle: toggle-all
Time Formatting is disabled.
:
Day: %a, %A, %d, %e
Month: %m, %b, %B
Year: %y, %Y
Hour: %k, %H, %l, %I, %p, %P
Minute: %M
Second: %S
Quote Backlinks formatting is disabled.
:
File Info Formatting is disabled.
:
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Quick Reply Personas is disabled.

\n One item per line.
\n Items will be added in the relevant input's auto-completion list.
\n Password items will always be used, since there is no password input.
\n Lines starting with a # will be ignored.\n

    You can use these settings with each item, separate them with semicolons:\n
  • Possible items are: name, email, subject and password.
  • Wrap values of items with quotes, like this: email:\"sage\".
  • Force values as defaults with the always keyword, for example: email:\"sage\";always.
  • Select specific boards for an item, separated with commas, for example: email:\"sage\";boards:jp;always.
Unread Favicon is disabled.
Emoji is disabled.
\n Sage Icon:
\n Position:
Thread Updater is disabled.
\n Interval:
"; + section.innerHTML = "
Custom Board Navigation
New lines will be converted into spaces.

In the following, board can translate to a board ID (a, b, etc...), the current board (current), or the Status/Twitter link (status, @).
\n For example:
[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]
\n will give you
[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
\n if you are on /g/.\n
Board link: board
Title link: board-title
Board link (Replace with title when on that board): board-replace
Full text link: board-full
Custom text link: board-text:\"VIP Board\"
Index-only link: board-index
Catalog-only link: board-catalog
External link: external-text:\"Google\",\"http://www.google.com\"
Combinations are possible: board-index-text:\"VIP Index\"
Full board list toggle: toggle-all
Time Formatting is disabled.
:
Day: %a, %A, %d, %e
Month: %m, %b, %B
Year: %y, %Y
Hour: %k, %H, %l, %I, %p, %P
Minute: %M
Second: %S
Quote Backlinks formatting is disabled.
:
File Info Formatting is disabled.
:
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Quick Reply Personas is disabled.

\n One item per line.
\n Items will be added in the relevant input's auto-completion list.
\n Password items will always be used, since there is no password input.
\n Lines starting with a # will be ignored.\n

    You can use these settings with each item, separate them with semicolons:\n
  • Possible items are: name, email, subject and password.
  • Wrap values of items with quotes, like this: email:\"sage\".
  • Force values as defaults with the always keyword, for example: email:\"sage\";always.
  • Select specific boards for an item, separated with commas, for example: email:\"sage\";boards:jp;always.
Unread Favicon is disabled.
Emoji is disabled.
\n Sage Icon:
\n Position:
Thread Updater is disabled.
\n Interval:
"; items = {}; inputs = {}; _ref = ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'sageEmoji', 'emojiPos', 'usercss']; @@ -9744,31 +9776,12 @@ return ta.value = item['QR.personas']; }); $.on(ta, 'change', $.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; for (key in items) { val = items[key]; - if (['emojiPos', 'archiver'].contains(key)) { + if (['emojiPos'].contains(key)) { continue; } input = inputs[key]; @@ -9835,6 +9848,101 @@ usercss: function() { return CustomCSS.update(); }, + archives: function(section) { + var archive, boardID, boards, data, name, row, rows, _i, _j, _len, _len1, _ref, _ref1, _ref2; + + section.innerHTML = "
404 Redirect is disabled.

Disabled selections indicate that only one archive is available for that board and redirection type.

Archived boards
BoardThread redirectionPost fetchingFile redirection
"; + boards = {}; + _ref = Redirect.archives; + for (name in _ref) { + archive = _ref[name]; + _ref1 = archive.boards; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + boardID = _ref1[_i]; + data = boards[boardID] || (boards[boardID] = { + thread: [], + post: [], + file: [] + }); + data.thread.push(name); + if (archive.software === 'foolfuuka') { + data.post.push(name); + } + if (archive.files.contains(boardID)) { + data.file.push(name); + } + } + } + rows = []; + _ref2 = Object.keys(boards).sort(); + for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { + boardID = _ref2[_j]; + row = $.el('tr'); + rows.push(row); + $.add(row, $.el('th', { + textContent: "/" + boardID + "/", + className: boardID === g.BOARD.ID ? 'warning' : '' + })); + data = boards[boardID]; + Settings.addArchiveCell(row, boardID, data, 'thread'); + Settings.addArchiveCell(row, boardID, data, 'post'); + Settings.addArchiveCell(row, boardID, data, 'file'); + } + $.add($('tbody', section), rows); + return $.get('selectedArchives', Conf['selectedArchives'], function(_arg) { + var option, selectedArchives, type; + + selectedArchives = _arg.selectedArchives; + for (boardID in selectedArchives) { + data = selectedArchives[boardID]; + for (type in data) { + name = data[type]; + if (option = $("select[data-boardid='" + boardID + "'][data-type='" + type + "'] > option[value='" + name + "']", section)) { + option.selected = true; + } + } + } + }); + }, + addArchiveCell: function(row, boardID, data, type) { + var archive, length, options, select, td, _i, _len, _ref; + + options = []; + _ref = data[type]; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + archive = _ref[_i]; + options.push($.el('option', { + textContent: archive, + value: archive + })); + } + td = $.el('td'); + length = options.length; + if (length) { + td.innerHTML = ''; + select = td.firstElementChild; + if (!(select.disabled = length === 1)) { + select.setAttribute('data-boardid', boardID); + select.setAttribute('data-type', type); + $.on(select, 'change', Settings.saveSelectedArchive); + } + $.add(select, options); + } else { + td.textContent = 'N/A'; + } + return $.add(row, td); + }, + saveSelectedArchive: function() { + var _this = this; + + return $.get('selectedArchives', Conf['selectedArchives'], function(_arg) { + var selectedArchives, _name; + + selectedArchives = _arg.selectedArchives; + (selectedArchives[_name = _this.dataset.boardid] || (selectedArchives[_name] = {}))[_this.dataset.type] = _this.value; + return $.set('selectedArchives', selectedArchives); + }); + }, keybinds: function(section) { var arr, input, inputs, items, key, tbody, tr, _ref; @@ -9906,7 +10014,7 @@ boards: {} }; } - Conf['archivers'] = {}; + Conf['selectedArchives'] = {}; $.get(Conf, Main.initFeatures); return $.asap((function() { var _ref; @@ -9944,7 +10052,10 @@ var url; if (Conf['404 Redirect'] && d.title === '4chan - 404 Not Found') { - url = Redirect.image(pathname[1], pathname[3]); + url = Redirect.to('image', { + boardID: pathname[1], + filename: pathname[3] + }); if (url) { return location.href = url; } @@ -10080,7 +10191,7 @@ if (d.title === '4chan - 404 Not Found') { if (Conf['404 Redirect'] && g.VIEW === 'thread') { - href = Redirect.to({ + href = Redirect.to('thread', { boardID: g.BOARD.ID, threadID: g.THREADID, postID: +location.hash.match(/\d+/) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 49c0f065f..7807e6d74 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -2044,7 +2044,10 @@ return $.cache("//api.4chan.org/" + boardID + "/res/" + threadID + ".json", function() { return Get.fetchedPost(this, boardID, threadID, postID, root, context); }); - } else if (url = Redirect.post(boardID, postID)) { + } else if (url = Redirect.to('post', { + boardID: boardID, + postID: postID + })) { return $.cache(url, function() { return Get.archivedPost(this, boardID, postID, root, context); }); @@ -2073,7 +2076,10 @@ } status = req.status; if (![200, 304].contains(status)) { - if (url = Redirect.post(boardID, postID)) { + if (url = Redirect.to('post', { + boardID: boardID, + postID: postID + })) { $.cache(url, function() { return Get.archivedPost(this, boardID, postID, root, context); }); @@ -2091,7 +2097,10 @@ break; } if (post.no > postID) { - if (url = Redirect.post(boardID, postID)) { + if (url = Redirect.to('post', { + boardID: boardID, + postID: postID + })) { $.cache(url, function() { return Get.archivedPost(this, boardID, postID, root, context); }); @@ -4207,7 +4216,7 @@ a.setAttribute('data-threadid', post.thread.ID); a.setAttribute('data-postid', postID); } - } else if (redirect = Redirect.to({ + } else if (redirect = Redirect.to('thread', { boardID: boardID, threadID: 0, postID: postID @@ -4218,7 +4227,10 @@ target: '_blank', textContent: "" + quote + "\u00A0(Dead)" }); - if (Redirect.post(boardID, postID)) { + if (Redirect.to('post', { + boardID: boardID, + postID: postID + })) { $.addClass(a, 'quotelink'); a.setAttribute('data-boardid', boardID); a.setAttribute('data-postid', postID); @@ -6242,7 +6254,11 @@ ImageExpand.contract(post); src = this.src.split('/'); if (src[2] === 'images.4chan.org') { - if (URL = Redirect.image(src[3], src[5])) { + URL = Redirect.to('image', { + boardID: src[3], + filename: src[5] + }); + if (URL) { setTimeout(ImageExpand.expand, 10000, post, URL); return; } @@ -6378,7 +6394,11 @@ post = g.posts[this.dataset.fullid]; src = this.src.split('/'); if (src[2] === 'images.4chan.org') { - if (URL = Redirect.image(src[3], src[5].replace(/\?.+$/, ''))) { + URL = Redirect.to('image', { + boardID: src[3], + filename: src[5].replace(/\?.+$/, '') + }); + if (URL) { this.src = URL; return; } @@ -6484,15 +6504,14 @@ el: div, order: 90, open: function(_arg) { - var ID, board, redirect, thread; + var ID, board, thread; ID = _arg.ID, thread = _arg.thread, board = _arg.board; - redirect = Redirect.to({ + return !!Redirect.to('thread', { postID: ID, threadID: thread.ID, boardID: board.ID }); - return redirect !== ("//boards.4chan.org/" + board + "/"); }, subEntries: [] }; @@ -6514,7 +6533,7 @@ var ID, board, thread; ID = _arg.ID, thread = _arg.thread, board = _arg.board; - el.href = Redirect.to({ + el.href = Redirect.to('thread', { postID: ID, threadID: thread.ID, boardID: board.ID @@ -6527,7 +6546,7 @@ if (!value) { return false; } - el.href = Redirect.to({ + el.href = Redirect.to('search', { boardID: post.board.ID, type: type, value: value, @@ -7740,185 +7759,197 @@ }; Redirect = { + thread: {}, + post: {}, + file: {}, init: function() { - return $.sync('archivers', this.updateArchives); - }, - updateArchives: function() { - return $.get('archivers', {}, function(_arg) { - var archivers; + var archive, arr, boardID, data, id, name, type, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3; - archivers = _arg.archivers; - return Conf['archivers'] = archivers; - }); - }, - imageArchives: (function() { - var o; - - o = { - a: "//archive.foolz.us/", - ck: "//fuuka.warosu.org/", - an: "http://archive.heinessen.com/", - cgl: "//rbt.asia/", - c: "//archive.nyafuu.org/", - d: "//loveisover.me/", - e: "http://archive.foolzashit.com", - hr: "http://archive.4plebs.org/", - u: "//nsfw.foolz.us/", - po: "//archive.thedarkcave.org/", - vg: "http://nth.pensivenonsen.se/", - c: "//archive.nyafuu.org/" - }; - o.adv = o.asp = o.cm = o.i = o.n = o.o = o.p = o.s = o.t = o.trv = o.y = o.lgbt = o.s4s = o.e; - o.gd = o.jp = o.m = o.q = o.tg = o.vp = o.vr = o.wsg = o.a; - o.fa = o.lit = o.ck; - o.k = o.toy = o.x = o.an; - o.g = o.mu = o.cgl; - o.w = o.wg = o.c; - o.h = o.v = o.d; - o.tv = o.hr; - return o; - })(), - image: function(boardID, filename) { - return "" + Redirect.imageArchives[boardID] + boardID + "/full_image/" + filename; - }, - post: function(boardID, 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; + _ref = Conf['selectedArchives']; + for (boardID in _ref) { + data = _ref[boardID]; + for (type in data) { + id = data[type]; + _ref1 = Redirect.archives; + for (name in _ref1) { + archive = _ref1[name]; + if (name !== id || type === 'post' && archive.software !== 'foolfuuka') { + continue; + } + arr = type === 'file' ? archive.files : archive.boards; + if (arr.contains(boardID)) { + Redirect[type][boardID] = archive; + } } } - (_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; + _ref2 = Redirect.archives; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + archive = _ref2[_i]; + _ref3 = archive.boards; + for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { + boardID = _ref3[_j]; + if (!(boardID in Redirect.thread)) { + Redirect.thread[boardID] = archive; + } + if (!(boardID in Redirect.post || archive.software !== 'foolfuuka')) { + Redirect.post[boardID] = archive; + } + if (!(boardID in Redirect.file || !archive.files.contains(boardID))) { + Redirect.file[boardID] = archive; + } } - _results.push(name); - } - return _results; - }, - to: function(data) { - var arch, archive, boardID; - - boardID = data.boardID; - 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); - if (!archive.boards.contains(g.BOARD.ID)) { - return Conf['archivers'] = archive; } }, - archiver: { + archives: { 'Foolz': { - base: 'https://archive.foolz.us', - boards: ['a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'vp', 'vr', 'wsg'], - type: 'foolfuuka' + 'domain': 'archive.foolz.us', + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'vp', 'vr', 'wsg'], + 'files': ['a', 'gd', 'jp', 'm', 'q', 'tg', 'vp', 'vr', 'wsg'] }, - 'NSFWFoolz': { - base: 'https://nsfw.foolz.us', - boards: ['u'], - type: 'foolfuuka' + 'NSFW Foolz': { + 'domain': 'nsfw.foolz.us', + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['u'], + 'files': ['u'] }, - 'TheDarkCave': { - base: 'http://archive.thedarkcave.org', - boards: ['c', 'int', 'out', 'po'], - type: 'foolfuuka' + 'The Dark Cave': { + 'domain': 'archive.thedarkcave.org', + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['c', 'int', 'out', 'po'], + 'files': ['c', 'po'] }, '4plebs': { - base: 'http://archive.4plebs.org', - boards: ['hr', 'tg', 'tv', 'x'], - base: 'foolfuuka' + 'domain': 'archive.4plebs.org', + 'http': true, + 'software': 'foolfuuka', + 'boards': ['hr', 'tg', 'tv', 'x'], + 'files': ['hr', 'tg', 'tv', 'x'] }, - 'NyaFuu': { - base: '//archive.nyafuu.org', - boards: ['c', 'w', 'wg'], - type: 'foolfuuka' + 'Nyafuu': { + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['c', 'w', 'wg'], + 'files': ['c', 'w', 'wg'] }, - 'LoveIsOver': { - base: '//loveisover.me', - boards: ['d', 'h', 'v'], - type: 'foolfuuka' + 'Love is Over': { + 'domain': 'loveisover.me', + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['d', 'h', 'v'], + 'files': ['d', 'h', 'v'] }, - 'PensiveNonsen': { - base: 'http://nth.pensivenonsen.se', - boards: ['vg'], - type: 'foolfuuka' + 'nth-chan': { + 'domain': 'nth.pensivenonsen.se', + 'http': true, + 'software': 'foolfuuka', + 'boards': ['vg'], + 'files': ['vg'] }, - 'FoolzaShit': { - base: 'http://archive.foolzashit.com', - boards: ["adv", "asp", "cm", "e", "i", "lgbt", "n", "o", "p", "s", "s4s", "t", "trv", "y"], - type: 'foolfuuka' + 'Foolz a Shit': { + 'domain': 'archive.foolzashit.com', + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['adv', 'asp', 'cm', 'e', 'i', 'lgbt', 'n', 'o', 'p', 's', 's4s', 't', 'trv', 'y'], + 'files': ['adv', 'asp', 'cm', 'e', 'i', 'lgbt', 'n', 'o', 'p', 's', 's4s', 't', 'trv', 'y'] }, - 'Warosu': { - base: '//fuuka.warosu.org', - boards: ['cgl', 'ck', 'fa', 'jp', 'lit', 's4s', 'q', 'tg', 'vr'], - type: 'fuuka' + 'Install Gentoo': { + 'domain': 'archive.installgentoo.net', + 'http': true, + 'https': true, + 'software': 'fuuka', + 'boards': ['diy', 'g', 'sci'], + 'files': [] }, - 'InstallGentoo': { - base: '//archive.installgentoo.net', - boards: ['diy', 'g', 'sci'], - type: 'fuuka' - }, - 'RebeccaBlackTech': { - base: '//rbt.asia', - boards: ['cgl', 'g', 'mu', 'w'], - type: 'fuuka_mail' + 'Rebecca Black Tech': { + 'domain': 'rbt.asia', + 'http': true, + 'https': true, + 'software': 'fuuka', + 'boards': ['cgl', 'g', 'mu', 'w'], + 'files': ['cgl', 'g', 'mu', 'w'] }, 'Heinessen': { - base: 'http://archive.heinessen.com', - boards: ['an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'], - type: 'fuuka' + 'domain': 'archive.heinessen.com', + 'http': true, + 'software': 'fuuka', + 'boards': ['an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'], + 'files': ['an', 'k', 'toy', 'x'] }, - 'Cliche': { - base: '//www.cliché.net/4chan/cgi-board.pl', - boards: ['e'], - type: 'fuuka' + 'warosu': { + 'domain': 'fuuka.warosu.org', + 'http': true, + 'https': true, + 'software': 'fuuka', + 'boards': ['3', 'cgl', 'ck', 'fa', 'ic', 'jp', 'lit', 'q', 's4s', 'tg', 'vr'], + 'files': ['3', 'cgl', 'ck', 'fa', 'ic', 'jp', 'lit', 'q', 's4s', 'vr'] } }, - path: function(base, archiver, data) { - var boardID, path, postID, threadID, type, value; + to: function(dest, data) { + var archive; - if (data.isSearch) { - boardID = data.boardID, type = data.type, value = data.value; - type = type === 'name' ? 'username' : type === 'MD5' ? 'image' : type; - value = encodeURIComponent(value); - if (archiver === 'foolfuuka') { - return "" + base + "/" + boardID + "/search/" + type + "/" + value; - } else if (type === 'image') { - return "" + base + "/" + boardID + "/?task=search2&search_media_hash=" + value; - } else { - return "" + base + "/" + boardID + "/?task=search2&search_" + type + "=" + value; - } + archive = (dest === 'search' ? Redirect.thread : Redirect[dest])[data.boardID]; + if (!archive) { + return ''; } - boardID = data.boardID, threadID = data.threadID, postID = data.postID; + return Redirect[dest](archive, data); + }, + protocol: function(archive) { + var protocol; + + protocol = location.protocol; + if (!archive[protocol.slice(0, -1)]) { + protocol = protocol === 'https:' ? 'http:' : 'https:'; + } + return "" + protocol + "//"; + }, + thread: function(archive, _arg) { + var boardID, path, postID, threadID; + + boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID; path = threadID ? "" + boardID + "/thread/" + threadID : "" + boardID + "/post/" + postID; - if (archiver === 'foolfuuka') { + if (archive.software === 'foolfuuka') { path += '/'; } if (threadID && postID) { - path += archiver === 'foolfuuka' ? "#" + postID : "#p" + postID; + path += archive.software === 'foolfuuka' ? "#" + postID : "#p" + postID; } - return "" + base + "/" + path; + return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path; + }, + post: function(archive, _arg) { + var boardID, postID, protocol; + + boardID = _arg.boardID, postID = _arg.postID; + protocol = Redirect.protocol(archive); + if (['Foolz', 'NSFW Foolz'].contains(archive.name)) { + protocol = 'https://'; + } + return "" + protocol + archive.domain + "/_/api/chan/post/?board=" + boardID + "&num=" + postID; + }, + file: function(archive, _arg) { + var boardID, filename; + + boardID = _arg.boardID, filename = _arg.filename; + return "" + (Redirect.protocol(archive)) + archive.domain + "/" + boardID + "/full_image/" + filename; + }, + search: function(archive, _arg) { + var boardID, path, type, value; + + boardID = _arg.boardID, type = _arg.type, value = _arg.value; + type = type === 'name' ? 'username' : type === 'MD5' ? 'image' : type; + value = encodeURIComponent(value); + path = archive.software === 'foolfuuka' ? "" + boardID + "/search/" + type + "/" + value : "" + boardID + "/?task=search2&search_" + (type === 'image' ? 'media_hash' : type) + "=" + value; + return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path; } }; @@ -9354,6 +9385,7 @@ Settings.addSection('Filter', Settings.filter); Settings.addSection('Sauce', Settings.sauce); Settings.addSection('Advanced', Settings.advanced); + Settings.addSection('Archives', Settings.archives); Settings.addSection('Keybinds', Settings.keybinds); $.on(d, 'AddSettingsSection', Settings.addSection); $.on(d, 'OpenSettings', function(e) { @@ -9736,9 +9768,9 @@ return $.on(ta, 'change', $.cb.value); }, advanced: function(section) { - var archiver, event, input, inputs, items, name, ta, toSelect, _i, _j, _len, _len1, _ref; + var event, input, inputs, items, name, ta, _i, _len, _ref; - section.innerHTML = "
Archiver\nSelect an Archiver for this board:\n
Custom Board Navigation
New lines will be converted into spaces.

In the following, board can translate to a board ID (a, b, etc...), the current board (current), or the Status/Twitter link (status, @).
\n For example:
[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]
\n will give you
[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
\n if you are on /g/.\n
Board link: board
Title link: board-title
Board link (Replace with title when on that board): board-replace
Full text link: board-full
Custom text link: board-text:\"VIP Board\"
Index-only link: board-index
Catalog-only link: board-catalog
External link: external-text:\"Google\",\"http://www.google.com\"
Combinations are possible: board-index-text:\"VIP Index\"
Full board list toggle: toggle-all
Time Formatting is disabled.
:
Day: %a, %A, %d, %e
Month: %m, %b, %B
Year: %y, %Y
Hour: %k, %H, %l, %I, %p, %P
Minute: %M
Second: %S
Quote Backlinks formatting is disabled.
:
File Info Formatting is disabled.
:
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Quick Reply Personas is disabled.

\n One item per line.
\n Items will be added in the relevant input's auto-completion list.
\n Password items will always be used, since there is no password input.
\n Lines starting with a # will be ignored.\n

    You can use these settings with each item, separate them with semicolons:\n
  • Possible items are: name, email, subject and password.
  • Wrap values of items with quotes, like this: email:\"sage\".
  • Force values as defaults with the always keyword, for example: email:\"sage\";always.
  • Select specific boards for an item, separated with commas, for example: email:\"sage\";boards:jp;always.
Unread Favicon is disabled.
Emoji is disabled.
\n Sage Icon:
\n Position:
Thread Updater is disabled.
\n Interval:
"; + section.innerHTML = "
Custom Board Navigation
New lines will be converted into spaces.

In the following, board can translate to a board ID (a, b, etc...), the current board (current), or the Status/Twitter link (status, @).
\n For example:
[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]
\n will give you
[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
\n if you are on /g/.\n
Board link: board
Title link: board-title
Board link (Replace with title when on that board): board-replace
Full text link: board-full
Custom text link: board-text:\"VIP Board\"
Index-only link: board-index
Catalog-only link: board-catalog
External link: external-text:\"Google\",\"http://www.google.com\"
Combinations are possible: board-index-text:\"VIP Index\"
Full board list toggle: toggle-all
Time Formatting is disabled.
:
Day: %a, %A, %d, %e
Month: %m, %b, %B
Year: %y, %Y
Hour: %k, %H, %l, %I, %p, %P
Minute: %M
Second: %S
Quote Backlinks formatting is disabled.
:
File Info Formatting is disabled.
:
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Quick Reply Personas is disabled.

\n One item per line.
\n Items will be added in the relevant input's auto-completion list.
\n Password items will always be used, since there is no password input.
\n Lines starting with a # will be ignored.\n

    You can use these settings with each item, separate them with semicolons:\n
  • Possible items are: name, email, subject and password.
  • Wrap values of items with quotes, like this: email:\"sage\".
  • Force values as defaults with the always keyword, for example: email:\"sage\";always.
  • Select specific boards for an item, separated with commas, for example: email:\"sage\";boards:jp;always.
Unread Favicon is disabled.
Emoji is disabled.
\n Sage Icon:
\n Position:
Thread Updater is disabled.
\n Interval:
"; items = {}; inputs = {}; _ref = ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'sageEmoji', 'emojiPos', 'usercss']; @@ -9755,31 +9787,12 @@ return ta.value = item['QR.personas']; }); $.on(ta, 'change', $.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; for (key in items) { val = items[key]; - if (['emojiPos', 'archiver'].contains(key)) { + if (['emojiPos'].contains(key)) { continue; } input = inputs[key]; @@ -9846,6 +9859,101 @@ usercss: function() { return CustomCSS.update(); }, + archives: function(section) { + var archive, boardID, boards, data, name, row, rows, _i, _j, _len, _len1, _ref, _ref1, _ref2; + + section.innerHTML = "
404 Redirect is disabled.

Disabled selections indicate that only one archive is available for that board and redirection type.

Archived boards
BoardThread redirectionPost fetchingFile redirection
"; + boards = {}; + _ref = Redirect.archives; + for (name in _ref) { + archive = _ref[name]; + _ref1 = archive.boards; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + boardID = _ref1[_i]; + data = boards[boardID] || (boards[boardID] = { + thread: [], + post: [], + file: [] + }); + data.thread.push(name); + if (archive.software === 'foolfuuka') { + data.post.push(name); + } + if (archive.files.contains(boardID)) { + data.file.push(name); + } + } + } + rows = []; + _ref2 = Object.keys(boards).sort(); + for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { + boardID = _ref2[_j]; + row = $.el('tr'); + rows.push(row); + $.add(row, $.el('th', { + textContent: "/" + boardID + "/", + className: boardID === g.BOARD.ID ? 'warning' : '' + })); + data = boards[boardID]; + Settings.addArchiveCell(row, boardID, data, 'thread'); + Settings.addArchiveCell(row, boardID, data, 'post'); + Settings.addArchiveCell(row, boardID, data, 'file'); + } + $.add($('tbody', section), rows); + return $.get('selectedArchives', Conf['selectedArchives'], function(_arg) { + var option, selectedArchives, type; + + selectedArchives = _arg.selectedArchives; + for (boardID in selectedArchives) { + data = selectedArchives[boardID]; + for (type in data) { + name = data[type]; + if (option = $("select[data-boardid='" + boardID + "'][data-type='" + type + "'] > option[value='" + name + "']", section)) { + option.selected = true; + } + } + } + }); + }, + addArchiveCell: function(row, boardID, data, type) { + var archive, length, options, select, td, _i, _len, _ref; + + options = []; + _ref = data[type]; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + archive = _ref[_i]; + options.push($.el('option', { + textContent: archive, + value: archive + })); + } + td = $.el('td'); + length = options.length; + if (length) { + td.innerHTML = ''; + select = td.firstElementChild; + if (!(select.disabled = length === 1)) { + select.setAttribute('data-boardid', boardID); + select.setAttribute('data-type', type); + $.on(select, 'change', Settings.saveSelectedArchive); + } + $.add(select, options); + } else { + td.textContent = 'N/A'; + } + return $.add(row, td); + }, + saveSelectedArchive: function() { + var _this = this; + + return $.get('selectedArchives', Conf['selectedArchives'], function(_arg) { + var selectedArchives, _name; + + selectedArchives = _arg.selectedArchives; + (selectedArchives[_name = _this.dataset.boardid] || (selectedArchives[_name] = {}))[_this.dataset.type] = _this.value; + return $.set('selectedArchives', selectedArchives); + }); + }, keybinds: function(section) { var arr, input, inputs, items, key, tbody, tr, _ref; @@ -9917,7 +10025,7 @@ boards: {} }; } - Conf['archivers'] = {}; + Conf['selectedArchives'] = {}; $.get(Conf, Main.initFeatures); return $.asap((function() { var _ref; @@ -9955,7 +10063,10 @@ var url; if (Conf['404 Redirect'] && d.title === '4chan - 404 Not Found') { - url = Redirect.image(pathname[1], pathname[3]); + url = Redirect.to('image', { + boardID: pathname[1], + filename: pathname[3] + }); if (url) { return location.href = url; } @@ -10091,7 +10202,7 @@ if (d.title === '4chan - 404 Not Found') { if (Conf['404 Redirect'] && g.VIEW === 'thread') { - href = Redirect.to({ + href = Redirect.to('thread', { boardID: g.BOARD.ID, threadID: g.THREADID, postID: +location.hash.match(/\d+/) diff --git a/builds/crx/script.js b/builds/crx/script.js index df30bdc8c..da8850daa 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -2046,7 +2046,10 @@ return $.cache("//api.4chan.org/" + boardID + "/res/" + threadID + ".json", function() { return Get.fetchedPost(this, boardID, threadID, postID, root, context); }); - } else if (url = Redirect.post(boardID, postID)) { + } else if (url = Redirect.to('post', { + boardID: boardID, + postID: postID + })) { return $.cache(url, function() { return Get.archivedPost(this, boardID, postID, root, context); }); @@ -2075,7 +2078,10 @@ } status = req.status; if (![200, 304].contains(status)) { - if (url = Redirect.post(boardID, postID)) { + if (url = Redirect.to('post', { + boardID: boardID, + postID: postID + })) { $.cache(url, function() { return Get.archivedPost(this, boardID, postID, root, context); }); @@ -2093,7 +2099,10 @@ break; } if (post.no > postID) { - if (url = Redirect.post(boardID, postID)) { + if (url = Redirect.to('post', { + boardID: boardID, + postID: postID + })) { $.cache(url, function() { return Get.archivedPost(this, boardID, postID, root, context); }); @@ -4209,7 +4218,7 @@ a.setAttribute('data-threadid', post.thread.ID); a.setAttribute('data-postid', postID); } - } else if (redirect = Redirect.to({ + } else if (redirect = Redirect.to('thread', { boardID: boardID, threadID: 0, postID: postID @@ -4220,7 +4229,10 @@ target: '_blank', textContent: "" + quote + "\u00A0(Dead)" }); - if (Redirect.post(boardID, postID)) { + if (Redirect.to('post', { + boardID: boardID, + postID: postID + })) { $.addClass(a, 'quotelink'); a.setAttribute('data-boardid', boardID); a.setAttribute('data-postid', postID); @@ -6220,7 +6232,11 @@ ImageExpand.contract(post); src = this.src.split('/'); if (src[2] === 'images.4chan.org') { - if (URL = Redirect.image(src[3], src[5])) { + URL = Redirect.to('image', { + boardID: src[3], + filename: src[5] + }); + if (URL) { setTimeout(ImageExpand.expand, 10000, post, URL); return; } @@ -6356,7 +6372,11 @@ post = g.posts[this.dataset.fullid]; src = this.src.split('/'); if (src[2] === 'images.4chan.org') { - if (URL = Redirect.image(src[3], src[5].replace(/\?.+$/, ''))) { + URL = Redirect.to('image', { + boardID: src[3], + filename: src[5].replace(/\?.+$/, '') + }); + if (URL) { this.src = URL; return; } @@ -6462,15 +6482,14 @@ el: div, order: 90, open: function(_arg) { - var ID, board, redirect, thread; + var ID, board, thread; ID = _arg.ID, thread = _arg.thread, board = _arg.board; - redirect = Redirect.to({ + return !!Redirect.to('thread', { postID: ID, threadID: thread.ID, boardID: board.ID }); - return redirect !== ("//boards.4chan.org/" + board + "/"); }, subEntries: [] }; @@ -6492,7 +6511,7 @@ var ID, board, thread; ID = _arg.ID, thread = _arg.thread, board = _arg.board; - el.href = Redirect.to({ + el.href = Redirect.to('thread', { postID: ID, threadID: thread.ID, boardID: board.ID @@ -6505,7 +6524,7 @@ if (!value) { return false; } - el.href = Redirect.to({ + el.href = Redirect.to('search', { boardID: post.board.ID, type: type, value: value, @@ -7723,185 +7742,197 @@ }; Redirect = { + thread: {}, + post: {}, + file: {}, init: function() { - return $.sync('archivers', this.updateArchives); - }, - updateArchives: function() { - return $.get('archivers', {}, function(_arg) { - var archivers; + var archive, arr, boardID, data, id, name, type, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3; - archivers = _arg.archivers; - return Conf['archivers'] = archivers; - }); - }, - imageArchives: (function() { - var o; - - o = { - a: "//archive.foolz.us/", - ck: "//fuuka.warosu.org/", - an: "http://archive.heinessen.com/", - cgl: "//rbt.asia/", - c: "//archive.nyafuu.org/", - d: "//loveisover.me/", - e: "http://archive.foolzashit.com", - hr: "http://archive.4plebs.org/", - u: "//nsfw.foolz.us/", - po: "//archive.thedarkcave.org/", - vg: "http://nth.pensivenonsen.se/", - c: "//archive.nyafuu.org/" - }; - o.adv = o.asp = o.cm = o.i = o.n = o.o = o.p = o.s = o.t = o.trv = o.y = o.lgbt = o.s4s = o.e; - o.gd = o.jp = o.m = o.q = o.tg = o.vp = o.vr = o.wsg = o.a; - o.fa = o.lit = o.ck; - o.k = o.toy = o.x = o.an; - o.g = o.mu = o.cgl; - o.w = o.wg = o.c; - o.h = o.v = o.d; - o.tv = o.hr; - return o; - })(), - image: function(boardID, filename) { - return "" + Redirect.imageArchives[boardID] + boardID + "/full_image/" + filename; - }, - post: function(boardID, 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; + _ref = Conf['selectedArchives']; + for (boardID in _ref) { + data = _ref[boardID]; + for (type in data) { + id = data[type]; + _ref1 = Redirect.archives; + for (name in _ref1) { + archive = _ref1[name]; + if (name !== id || type === 'post' && archive.software !== 'foolfuuka') { + continue; + } + arr = type === 'file' ? archive.files : archive.boards; + if (arr.contains(boardID)) { + Redirect[type][boardID] = archive; + } } } - (_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; + _ref2 = Redirect.archives; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + archive = _ref2[_i]; + _ref3 = archive.boards; + for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { + boardID = _ref3[_j]; + if (!(boardID in Redirect.thread)) { + Redirect.thread[boardID] = archive; + } + if (!(boardID in Redirect.post || archive.software !== 'foolfuuka')) { + Redirect.post[boardID] = archive; + } + if (!(boardID in Redirect.file || !archive.files.contains(boardID))) { + Redirect.file[boardID] = archive; + } } - _results.push(name); - } - return _results; - }, - to: function(data) { - var arch, archive, boardID; - - boardID = data.boardID; - 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); - if (!archive.boards.contains(g.BOARD.ID)) { - return Conf['archivers'] = archive; } }, - archiver: { + archives: { 'Foolz': { - base: 'https://archive.foolz.us', - boards: ['a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'vp', 'vr', 'wsg'], - type: 'foolfuuka' + 'domain': 'archive.foolz.us', + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'vp', 'vr', 'wsg'], + 'files': ['a', 'gd', 'jp', 'm', 'q', 'tg', 'vp', 'vr', 'wsg'] }, - 'NSFWFoolz': { - base: 'https://nsfw.foolz.us', - boards: ['u'], - type: 'foolfuuka' + 'NSFW Foolz': { + 'domain': 'nsfw.foolz.us', + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['u'], + 'files': ['u'] }, - 'TheDarkCave': { - base: 'http://archive.thedarkcave.org', - boards: ['c', 'int', 'out', 'po'], - type: 'foolfuuka' + 'The Dark Cave': { + 'domain': 'archive.thedarkcave.org', + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['c', 'int', 'out', 'po'], + 'files': ['c', 'po'] }, '4plebs': { - base: 'http://archive.4plebs.org', - boards: ['hr', 'tg', 'tv', 'x'], - base: 'foolfuuka' + 'domain': 'archive.4plebs.org', + 'http': true, + 'software': 'foolfuuka', + 'boards': ['hr', 'tg', 'tv', 'x'], + 'files': ['hr', 'tg', 'tv', 'x'] }, - 'NyaFuu': { - base: '//archive.nyafuu.org', - boards: ['c', 'w', 'wg'], - type: 'foolfuuka' + 'Nyafuu': { + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['c', 'w', 'wg'], + 'files': ['c', 'w', 'wg'] }, - 'LoveIsOver': { - base: '//loveisover.me', - boards: ['d', 'h', 'v'], - type: 'foolfuuka' + 'Love is Over': { + 'domain': 'loveisover.me', + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['d', 'h', 'v'], + 'files': ['d', 'h', 'v'] }, - 'PensiveNonsen': { - base: 'http://nth.pensivenonsen.se', - boards: ['vg'], - type: 'foolfuuka' + 'nth-chan': { + 'domain': 'nth.pensivenonsen.se', + 'http': true, + 'software': 'foolfuuka', + 'boards': ['vg'], + 'files': ['vg'] }, - 'FoolzaShit': { - base: 'http://archive.foolzashit.com', - boards: ["adv", "asp", "cm", "e", "i", "lgbt", "n", "o", "p", "s", "s4s", "t", "trv", "y"], - type: 'foolfuuka' + 'Foolz a Shit': { + 'domain': 'archive.foolzashit.com', + 'http': true, + 'https': true, + 'software': 'foolfuuka', + 'boards': ['adv', 'asp', 'cm', 'e', 'i', 'lgbt', 'n', 'o', 'p', 's', 's4s', 't', 'trv', 'y'], + 'files': ['adv', 'asp', 'cm', 'e', 'i', 'lgbt', 'n', 'o', 'p', 's', 's4s', 't', 'trv', 'y'] }, - 'Warosu': { - base: '//fuuka.warosu.org', - boards: ['cgl', 'ck', 'fa', 'jp', 'lit', 's4s', 'q', 'tg', 'vr'], - type: 'fuuka' + 'Install Gentoo': { + 'domain': 'archive.installgentoo.net', + 'http': true, + 'https': true, + 'software': 'fuuka', + 'boards': ['diy', 'g', 'sci'], + 'files': [] }, - 'InstallGentoo': { - base: '//archive.installgentoo.net', - boards: ['diy', 'g', 'sci'], - type: 'fuuka' - }, - 'RebeccaBlackTech': { - base: '//rbt.asia', - boards: ['cgl', 'g', 'mu', 'w'], - type: 'fuuka_mail' + 'Rebecca Black Tech': { + 'domain': 'rbt.asia', + 'http': true, + 'https': true, + 'software': 'fuuka', + 'boards': ['cgl', 'g', 'mu', 'w'], + 'files': ['cgl', 'g', 'mu', 'w'] }, 'Heinessen': { - base: 'http://archive.heinessen.com', - boards: ['an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'], - type: 'fuuka' + 'domain': 'archive.heinessen.com', + 'http': true, + 'software': 'fuuka', + 'boards': ['an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'], + 'files': ['an', 'k', 'toy', 'x'] }, - 'Cliche': { - base: '//www.cliché.net/4chan/cgi-board.pl', - boards: ['e'], - type: 'fuuka' + 'warosu': { + 'domain': 'fuuka.warosu.org', + 'http': true, + 'https': true, + 'software': 'fuuka', + 'boards': ['3', 'cgl', 'ck', 'fa', 'ic', 'jp', 'lit', 'q', 's4s', 'tg', 'vr'], + 'files': ['3', 'cgl', 'ck', 'fa', 'ic', 'jp', 'lit', 'q', 's4s', 'vr'] } }, - path: function(base, archiver, data) { - var boardID, path, postID, threadID, type, value; + to: function(dest, data) { + var archive; - if (data.isSearch) { - boardID = data.boardID, type = data.type, value = data.value; - type = type === 'name' ? 'username' : type === 'MD5' ? 'image' : type; - value = encodeURIComponent(value); - if (archiver === 'foolfuuka') { - return "" + base + "/" + boardID + "/search/" + type + "/" + value; - } else if (type === 'image') { - return "" + base + "/" + boardID + "/?task=search2&search_media_hash=" + value; - } else { - return "" + base + "/" + boardID + "/?task=search2&search_" + type + "=" + value; - } + archive = (dest === 'search' ? Redirect.thread : Redirect[dest])[data.boardID]; + if (!archive) { + return ''; } - boardID = data.boardID, threadID = data.threadID, postID = data.postID; + return Redirect[dest](archive, data); + }, + protocol: function(archive) { + var protocol; + + protocol = location.protocol; + if (!archive[protocol.slice(0, -1)]) { + protocol = protocol === 'https:' ? 'http:' : 'https:'; + } + return "" + protocol + "//"; + }, + thread: function(archive, _arg) { + var boardID, path, postID, threadID; + + boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID; path = threadID ? "" + boardID + "/thread/" + threadID : "" + boardID + "/post/" + postID; - if (archiver === 'foolfuuka') { + if (archive.software === 'foolfuuka') { path += '/'; } if (threadID && postID) { - path += archiver === 'foolfuuka' ? "#" + postID : "#p" + postID; + path += archive.software === 'foolfuuka' ? "#" + postID : "#p" + postID; } - return "" + base + "/" + path; + return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path; + }, + post: function(archive, _arg) { + var boardID, postID, protocol; + + boardID = _arg.boardID, postID = _arg.postID; + protocol = Redirect.protocol(archive); + if (['Foolz', 'NSFW Foolz'].contains(archive.name)) { + protocol = 'https://'; + } + return "" + protocol + archive.domain + "/_/api/chan/post/?board=" + boardID + "&num=" + postID; + }, + file: function(archive, _arg) { + var boardID, filename; + + boardID = _arg.boardID, filename = _arg.filename; + return "" + (Redirect.protocol(archive)) + archive.domain + "/" + boardID + "/full_image/" + filename; + }, + search: function(archive, _arg) { + var boardID, path, type, value; + + boardID = _arg.boardID, type = _arg.type, value = _arg.value; + type = type === 'name' ? 'username' : type === 'MD5' ? 'image' : type; + value = encodeURIComponent(value); + path = archive.software === 'foolfuuka' ? "" + boardID + "/search/" + type + "/" + value : "" + boardID + "/?task=search2&search_" + (type === 'image' ? 'media_hash' : type) + "=" + value; + return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path; } }; @@ -9337,6 +9368,7 @@ Settings.addSection('Filter', Settings.filter); Settings.addSection('Sauce', Settings.sauce); Settings.addSection('Advanced', Settings.advanced); + Settings.addSection('Archives', Settings.archives); Settings.addSection('Keybinds', Settings.keybinds); $.on(d, 'AddSettingsSection', Settings.addSection); $.on(d, 'OpenSettings', function(e) { @@ -9717,9 +9749,9 @@ return $.on(ta, 'change', $.cb.value); }, advanced: function(section) { - var archiver, event, input, inputs, items, name, ta, toSelect, _i, _j, _len, _len1, _ref; + var event, input, inputs, items, name, ta, _i, _len, _ref; - section.innerHTML = "
Archiver\nSelect an Archiver for this board:\n
Custom Board Navigation
New lines will be converted into spaces.

In the following, board can translate to a board ID (a, b, etc...), the current board (current), or the Status/Twitter link (status, @).
\n For example:
[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]
\n will give you
[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
\n if you are on /g/.\n
Board link: board
Title link: board-title
Board link (Replace with title when on that board): board-replace
Full text link: board-full
Custom text link: board-text:\"VIP Board\"
Index-only link: board-index
Catalog-only link: board-catalog
External link: external-text:\"Google\",\"http://www.google.com\"
Combinations are possible: board-index-text:\"VIP Index\"
Full board list toggle: toggle-all
Time Formatting is disabled.
:
Day: %a, %A, %d, %e
Month: %m, %b, %B
Year: %y, %Y
Hour: %k, %H, %l, %I, %p, %P
Minute: %M
Second: %S
Quote Backlinks formatting is disabled.
:
File Info Formatting is disabled.
:
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Quick Reply Personas is disabled.

\n One item per line.
\n Items will be added in the relevant input's auto-completion list.
\n Password items will always be used, since there is no password input.
\n Lines starting with a # will be ignored.\n

    You can use these settings with each item, separate them with semicolons:\n
  • Possible items are: name, email, subject and password.
  • Wrap values of items with quotes, like this: email:\"sage\".
  • Force values as defaults with the always keyword, for example: email:\"sage\";always.
  • Select specific boards for an item, separated with commas, for example: email:\"sage\";boards:jp;always.
Unread Favicon is disabled.
Emoji is disabled.
\n Sage Icon:
\n Position:
Thread Updater is disabled.
\n Interval:
"; + section.innerHTML = "
Custom Board Navigation
New lines will be converted into spaces.

In the following, board can translate to a board ID (a, b, etc...), the current board (current), or the Status/Twitter link (status, @).
\n For example:
[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]
\n will give you
[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
\n if you are on /g/.\n
Board link: board
Title link: board-title
Board link (Replace with title when on that board): board-replace
Full text link: board-full
Custom text link: board-text:\"VIP Board\"
Index-only link: board-index
Catalog-only link: board-catalog
External link: external-text:\"Google\",\"http://www.google.com\"
Combinations are possible: board-index-text:\"VIP Index\"
Full board list toggle: toggle-all
Time Formatting is disabled.
:
Day: %a, %A, %d, %e
Month: %m, %b, %B
Year: %y, %Y
Hour: %k, %H, %l, %I, %p, %P
Minute: %M
Second: %S
Quote Backlinks formatting is disabled.
:
File Info Formatting is disabled.
:
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Quick Reply Personas is disabled.

\n One item per line.
\n Items will be added in the relevant input's auto-completion list.
\n Password items will always be used, since there is no password input.
\n Lines starting with a # will be ignored.\n

    You can use these settings with each item, separate them with semicolons:\n
  • Possible items are: name, email, subject and password.
  • Wrap values of items with quotes, like this: email:\"sage\".
  • Force values as defaults with the always keyword, for example: email:\"sage\";always.
  • Select specific boards for an item, separated with commas, for example: email:\"sage\";boards:jp;always.
Unread Favicon is disabled.
Emoji is disabled.
\n Sage Icon:
\n Position:
Thread Updater is disabled.
\n Interval:
"; items = {}; inputs = {}; _ref = ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'sageEmoji', 'emojiPos', 'usercss']; @@ -9736,31 +9768,12 @@ return ta.value = item['QR.personas']; }); $.on(ta, 'change', $.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; for (key in items) { val = items[key]; - if (['emojiPos', 'archiver'].contains(key)) { + if (['emojiPos'].contains(key)) { continue; } input = inputs[key]; @@ -9827,6 +9840,101 @@ usercss: function() { return CustomCSS.update(); }, + archives: function(section) { + var archive, boardID, boards, data, name, row, rows, _i, _j, _len, _len1, _ref, _ref1, _ref2; + + section.innerHTML = "
404 Redirect is disabled.

Disabled selections indicate that only one archive is available for that board and redirection type.

Archived boards
BoardThread redirectionPost fetchingFile redirection
"; + boards = {}; + _ref = Redirect.archives; + for (name in _ref) { + archive = _ref[name]; + _ref1 = archive.boards; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + boardID = _ref1[_i]; + data = boards[boardID] || (boards[boardID] = { + thread: [], + post: [], + file: [] + }); + data.thread.push(name); + if (archive.software === 'foolfuuka') { + data.post.push(name); + } + if (archive.files.contains(boardID)) { + data.file.push(name); + } + } + } + rows = []; + _ref2 = Object.keys(boards).sort(); + for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { + boardID = _ref2[_j]; + row = $.el('tr'); + rows.push(row); + $.add(row, $.el('th', { + textContent: "/" + boardID + "/", + className: boardID === g.BOARD.ID ? 'warning' : '' + })); + data = boards[boardID]; + Settings.addArchiveCell(row, boardID, data, 'thread'); + Settings.addArchiveCell(row, boardID, data, 'post'); + Settings.addArchiveCell(row, boardID, data, 'file'); + } + $.add($('tbody', section), rows); + return $.get('selectedArchives', Conf['selectedArchives'], function(_arg) { + var option, selectedArchives, type; + + selectedArchives = _arg.selectedArchives; + for (boardID in selectedArchives) { + data = selectedArchives[boardID]; + for (type in data) { + name = data[type]; + if (option = $("select[data-boardid='" + boardID + "'][data-type='" + type + "'] > option[value='" + name + "']", section)) { + option.selected = true; + } + } + } + }); + }, + addArchiveCell: function(row, boardID, data, type) { + var archive, length, options, select, td, _i, _len, _ref; + + options = []; + _ref = data[type]; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + archive = _ref[_i]; + options.push($.el('option', { + textContent: archive, + value: archive + })); + } + td = $.el('td'); + length = options.length; + if (length) { + td.innerHTML = ''; + select = td.firstElementChild; + if (!(select.disabled = length === 1)) { + select.setAttribute('data-boardid', boardID); + select.setAttribute('data-type', type); + $.on(select, 'change', Settings.saveSelectedArchive); + } + $.add(select, options); + } else { + td.textContent = 'N/A'; + } + return $.add(row, td); + }, + saveSelectedArchive: function() { + var _this = this; + + return $.get('selectedArchives', Conf['selectedArchives'], function(_arg) { + var selectedArchives, _name; + + selectedArchives = _arg.selectedArchives; + (selectedArchives[_name = _this.dataset.boardid] || (selectedArchives[_name] = {}))[_this.dataset.type] = _this.value; + return $.set('selectedArchives', selectedArchives); + }); + }, keybinds: function(section) { var arr, input, inputs, items, key, tbody, tr, _ref; @@ -9898,7 +10006,7 @@ boards: {} }; } - Conf['archivers'] = {}; + Conf['selectedArchives'] = {}; $.get(Conf, Main.initFeatures); return $.asap((function() { var _ref; @@ -9936,7 +10044,10 @@ var url; if (Conf['404 Redirect'] && d.title === '4chan - 404 Not Found') { - url = Redirect.image(pathname[1], pathname[3]); + url = Redirect.to('image', { + boardID: pathname[1], + filename: pathname[3] + }); if (url) { return location.href = url; } @@ -10073,7 +10184,7 @@ if (d.title === '4chan - 404 Not Found') { if (Conf['404 Redirect'] && g.VIEW === 'thread') { - href = Redirect.to({ + href = Redirect.to('thread', { boardID: g.BOARD.ID, threadID: g.THREADID, postID: +location.hash.match(/\d+/) diff --git a/src/Archive/Redirect.coffee b/src/Archive/Redirect.coffee index d3bbcb09f..c6669d478 100644 --- a/src/Archive/Redirect.coffee +++ b/src/Archive/Redirect.coffee @@ -1,159 +1,170 @@ Redirect = + thread: {} + post: {} + file: {} + init: -> - $.sync 'archivers', @updateArchives + for boardID, data of Conf['selectedArchives'] + for type, id of data + for name, archive of Redirect.archives + continue if name isnt id or type is 'post' and archive.software isnt 'foolfuuka' + arr = if type is 'file' + archive.files + else + archive.boards + Redirect[type][boardID] = archive if arr.contains boardID + for archive in Redirect.archives + for boardID in archive.boards + unless boardID of Redirect.thread + Redirect.thread[boardID] = archive + unless boardID of Redirect.post or archive.software isnt 'foolfuuka' + Redirect.post[boardID] = archive + unless boardID of Redirect.file or !archive.files.contains boardID + Redirect.file[boardID] = archive + return - updateArchives: -> - $.get 'archivers', {}, ({archivers}) -> - Conf['archivers'] = archivers - - imageArchives: do -> - o = - a: "//archive.foolz.us/" - ck: "//fuuka.warosu.org/" - an: "http://archive.heinessen.com/" - cgl: "//rbt.asia/" - c: "//archive.nyafuu.org/" - d: "//loveisover.me/" - e: "http://archive.foolzashit.com" - hr: "http://archive.4plebs.org/" - u: "//nsfw.foolz.us/" - po: "//archive.thedarkcave.org/" - vg: "http://nth.pensivenonsen.se/" - c: "//archive.nyafuu.org/" - - o.adv = o.asp = o.cm = o.i = o.n = o.o = o.p = o.s = o.t = o.trv = o.y = o.lgbt = o.s4s = o.e - o.gd = o.jp = o.m = o.q = o.tg = o.vp = o.vr = o.wsg = o.a - o.fa = o.lit = o.ck - o.k = o.toy = o.x = o.an - o.g = o.mu = o.cgl - o.w = o.wg = o.c - o.h = o.v = o.d - o.tv = o.hr - - return o - - image: (boardID, filename) -> - # Do not use g.BOARD, the image url can originate from a cross-quote. - # Fuck. Your. Shit. - "#{Redirect.imageArchives[boardID]}#{boardID}/full_image/#{filename}" - - post: (boardID, postID) -> - 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 - - 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) - - unless archive.boards.contains g.BOARD.ID - Conf['archivers'] = archive - - archiver: + archives: 'Foolz': - base: 'https://archive.foolz.us' - boards: ['a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', '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' + 'domain': 'archive.foolz.us' + 'http': true + 'https': true + 'software': 'foolfuuka' + 'boards': ['a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'vp', 'vr', 'wsg'] + 'files': ['a', 'gd', 'jp', 'm', 'q', 'tg', 'vp', 'vr', 'wsg'] + + 'NSFW Foolz': + 'domain': 'nsfw.foolz.us' + 'http': true + 'https': true + 'software': 'foolfuuka' + 'boards': ['u'] + 'files': ['u'] + + 'The Dark Cave': + 'domain': 'archive.thedarkcave.org' + 'http': true + 'https': true + 'software': 'foolfuuka' + 'boards': ['c', 'int', 'out', 'po'] + 'files': ['c', 'po'] + '4plebs': - base: 'http://archive.4plebs.org' - boards: ['hr', 'tg', 'tv', 'x'] - base: 'foolfuuka' - 'NyaFuu': - base: '//archive.nyafuu.org' - boards: ['c', 'w', 'wg'] - type: 'foolfuuka' - 'LoveIsOver': - base: '//loveisover.me' - boards: ['d', 'h', 'v'] - type: 'foolfuuka' - 'PensiveNonsen': - base: 'http://nth.pensivenonsen.se' - boards: ['vg'] - type: 'foolfuuka' - 'FoolzaShit': - base: 'http://archive.foolzashit.com' - boards: ["adv", "asp", "cm", "e", "i", "lgbt", "n", "o", "p", "s", "s4s", "t", "trv", "y"] - type: 'foolfuuka' - 'Warosu': - base: '//fuuka.warosu.org' - boards: ['cgl', 'ck', 'fa', 'jp', 'lit', 's4s', 'q', 'tg', 'vr'] - type: 'fuuka' - 'InstallGentoo': - base: '//archive.installgentoo.net' - boards: ['diy', 'g', 'sci'] - type: 'fuuka' - 'RebeccaBlackTech': - base: '//rbt.asia' - boards: ['cgl', 'g', 'mu', 'w'] - type: 'fuuka_mail' + 'domain': 'archive.4plebs.org' + 'http': true + 'software': 'foolfuuka' + 'boards': ['hr', 'tg', 'tv', 'x'] + 'files': ['hr', 'tg', 'tv', 'x'] + + 'Nyafuu': + 'http': true + 'https': true + 'software': 'foolfuuka' + 'boards': ['c', 'w', 'wg'] + 'files': ['c', 'w', 'wg'] + + 'Love is Over': + 'domain': 'loveisover.me' + 'http': true + 'https': true + 'software': 'foolfuuka' + 'boards': ['d', 'h', 'v'] + 'files': ['d', 'h', 'v'] + + 'nth-chan': + 'domain': 'nth.pensivenonsen.se' + 'http': true + 'software': 'foolfuuka' + 'boards': ['vg'] + 'files': ['vg'] + + 'Foolz a Shit': + 'domain': 'archive.foolzashit.com' + 'http': true + 'https': true + 'software': 'foolfuuka' + 'boards': ['adv', 'asp', 'cm', 'e', 'i', 'lgbt', 'n', 'o', 'p', 's', 's4s', 't', 'trv', 'y'] + 'files': ['adv', 'asp', 'cm', 'e', 'i', 'lgbt', 'n', 'o', 'p', 's', 's4s', 't', 'trv', 'y'] + + 'Install Gentoo': + 'domain': 'archive.installgentoo.net' + 'http': true + 'https': true + 'software': 'fuuka' + 'boards': ['diy', 'g', 'sci'] + 'files': [] + + 'Rebecca Black Tech': + 'domain': 'rbt.asia' + 'http': true + 'https': true + 'software': 'fuuka' + 'boards': ['cgl', 'g', 'mu', 'w'] + 'files': ['cgl', 'g', 'mu', 'w'] + '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' + 'domain': 'archive.heinessen.com' + 'http': true + 'software': 'fuuka' + 'boards': ['an', 'fit', 'k', 'mlp', 'r9k', 'toy', 'x'] + 'files': ['an', 'k', 'toy', 'x'] - path: (base, archiver, data) -> - if data.isSearch - {boardID, type, value} = data - type = if type is 'name' - 'username' - else if type is 'MD5' - 'image' - else - type - value = encodeURIComponent value - return if archiver is 'foolfuuka' - "#{base}/#{boardID}/search/#{type}/#{value}" - else if type is 'image' - "#{base}/#{boardID}/?task=search2&search_media_hash=#{value}" - else - "#{base}/#{boardID}/?task=search2&search_#{type}=#{value}" + 'warosu': + 'domain': 'fuuka.warosu.org' + 'http': true + 'https': true + 'software': 'fuuka' + 'boards': ['3', 'cgl', 'ck', 'fa', 'ic', 'jp', 'lit', 'q', 's4s', 'tg', 'vr'] + 'files': ['3', 'cgl', 'ck', 'fa', 'ic', 'jp', 'lit', 'q', 's4s', 'vr'] - {boardID, threadID, postID} = data - # keep the number only if the location.hash was sent f.e. + to: (dest, data) -> + archive = (if dest is 'search' then Redirect.thread else Redirect[dest])[data.boardID] + return '' unless archive + Redirect[dest] archive, data + + protocol: (archive) -> + protocol = location.protocol + unless archive[protocol[0...-1]] + protocol = if protocol is 'https:' then 'http:' else 'https:' + "#{protocol}//" + + thread: (archive, {boardID, threadID, postID}) -> + # Keep the post number only if the location.hash was sent f.e. path = if threadID "#{boardID}/thread/#{threadID}" else "#{boardID}/post/#{postID}" - if archiver is 'foolfuuka' + if archive.software is 'foolfuuka' path += '/' if threadID and postID - path += if archiver is 'foolfuuka' + path += if archive.software is 'foolfuuka' "##{postID}" else "#p#{postID}" - "#{base}/#{path}" + "#{Redirect.protocol archive}#{archive.domain}/#{path}" + + post: (archive, {boardID, postID}) -> + # For fuuka-based archives: + # https://github.com/eksopl/fuuka/issues/27 + protocol = Redirect.protocol archive + # XXX foolz had HSTS set for 120 days, which broke XHR+CORS+Redirection when on HTTP. + # Remove necessary HTTPS procotol in September 2013. + if ['Foolz', 'NSFW Foolz'].contains archive.name + protocol = 'https://' + "#{protocol}#{archive.domain}/_/api/chan/post/?board=#{boardID}&num=#{postID}" + + file: (archive, {boardID, filename}) -> + "#{Redirect.protocol archive}#{archive.domain}/#{boardID}/full_image/#{filename}" + + search: (archive, {boardID, type, value}) -> + type = if type is 'name' + 'username' + else if type is 'MD5' + 'image' + else + type + value = encodeURIComponent value + path = if archive.software is 'foolfuuka' + "#{boardID}/search/#{type}/#{value}" + else + "#{boardID}/?task=search2&search_#{if type is 'image' then 'media_hash' else type}=#{value}" + "#{Redirect.protocol archive}#{archive.domain}/#{path}" diff --git a/src/General/Get.coffee b/src/General/Get.coffee index dd5d591d6..b7332e5f6 100644 --- a/src/General/Get.coffee +++ b/src/General/Get.coffee @@ -71,7 +71,7 @@ Get = if threadID $.cache "//api.4chan.org/#{boardID}/res/#{threadID}.json", -> Get.fetchedPost @, boardID, threadID, postID, root, context - else if url = Redirect.post boardID, postID + else if url = Redirect.to 'post', {boardID, postID} $.cache url, -> Get.archivedPost @, boardID, postID, root, context insert: (post, root, context) -> @@ -97,7 +97,7 @@ Get = {status} = req unless [200, 304].contains status # The thread can die by the time we check a quote. - if url = Redirect.post boardID, postID + if url = Redirect.to 'post', {boardID, postID} $.cache url, -> Get.archivedPost @, boardID, postID, root, context else @@ -115,7 +115,7 @@ Get = break if post.no is postID # we found it! if post.no > postID # The post can be deleted by the time we check a quote. - if url = Redirect.post boardID, postID + if url = Redirect.to 'post', {boardID, postID} $.cache url, -> Get.archivedPost @, boardID, postID, root, context else diff --git a/src/General/Main.coffee b/src/General/Main.coffee index a057f03e0..a36d1f93b 100644 --- a/src/General/Main.coffee +++ b/src/General/Main.coffee @@ -14,7 +14,8 @@ Main = flatten null, Config for db in DataBoards Conf[db] = boards: {} - Conf['archivers'] = {} + Conf['selectedArchives'] = {} + $.get Conf, Main.initFeatures $.asap (-> d.head and $('link[rel="shortcut icon"]', d.head) or d.readyState in ['interactive', 'complete']),\ @@ -45,7 +46,9 @@ Main = when 'images.4chan.org' $.ready -> if Conf['404 Redirect'] and d.title is '4chan - 404 Not Found' - url = Redirect.image pathname[1], pathname[3] + url = Redirect.to 'image', + boardID: pathname[1] + filename: pathname[3] location.href = url if url return @@ -170,7 +173,7 @@ Main = initReady: -> if d.title is '4chan - 404 Not Found' if Conf['404 Redirect'] and g.VIEW is 'thread' - href = Redirect.to + href = Redirect.to 'thread', boardID: g.BOARD.ID threadID: g.THREADID postID: +location.hash.match /\d+/ # post number or 0 diff --git a/src/General/Settings.coffee b/src/General/Settings.coffee index 218e61118..f71a46f54 100644 --- a/src/General/Settings.coffee +++ b/src/General/Settings.coffee @@ -27,6 +27,7 @@ Settings = Settings.addSection 'Filter', Settings.filter Settings.addSection 'Sauce', Settings.sauce Settings.addSection 'Advanced', Settings.advanced + Settings.addSection 'Archives', Settings.archives Settings.addSection 'Keybinds', Settings.keybinds $.on d, 'AddSettingsSection', Settings.addSection @@ -329,23 +330,9 @@ Settings = ta.value = item['QR.personas'] $.on ta, 'change', $.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 - continue if ['emojiPos', 'archiver'].contains key + continue if ['emojiPos'].contains key input = inputs[key] input.value = val continue if key is 'usercss' @@ -398,6 +385,69 @@ Settings = usercss: -> CustomCSS.update() + archives: (section) -> + section.innerHTML = """ +<%= grunt.file.read('src/General/html/Settings/Archives.html').replace(/>\s+<').trim() %> +""" + + boards = {} + for name, archive of Redirect.archives + for boardID in archive.boards + data = boards[boardID] or= { + thread: [] + post: [] + file: [] + } + data.thread.push name + if archive.software is 'foolfuuka' + data.post.push name + if archive.files.contains boardID + data.file.push name + + rows = [] + for boardID in Object.keys(boards).sort() # Alphabetical order + row = $.el 'tr' + rows.push row + $.add row, $.el 'th', + textContent: "/#{boardID}/" + className: if boardID is g.BOARD.ID then 'warning' else '' + + data = boards[boardID] + Settings.addArchiveCell row, boardID, data, 'thread' + Settings.addArchiveCell row, boardID, data, 'post' + Settings.addArchiveCell row, boardID, data, 'file' + $.add $('tbody', section), rows + $.get 'selectedArchives', Conf['selectedArchives'], ({selectedArchives}) -> + for boardID, data of selectedArchives + for type, name of data + if option = $ "select[data-boardid='#{boardID}'][data-type='#{type}'] > option[value='#{name}']", section + option.selected = true + return + addArchiveCell: (row, boardID, data, type) -> + options = [] + for archive in data[type] + options.push $.el 'option', + textContent: archive + value: archive + td = $.el 'td' + {length} = options + if length + td.innerHTML = '' + select = td.firstElementChild + unless select.disabled = length is 1 + # XXX GM can't into datasets + select.setAttribute 'data-boardid', boardID + select.setAttribute 'data-type', type + $.on select, 'change', Settings.saveSelectedArchive + $.add select, options + else + td.textContent = 'N/A' + $.add row, td + saveSelectedArchive: -> + $.get 'selectedArchives', Conf['selectedArchives'], ({selectedArchives}) => + (selectedArchives[@dataset.boardid] or= {})[@dataset.type] = @value + $.set 'selectedArchives', selectedArchives + keybinds: (section) -> section.innerHTML = """ <%= grunt.file.read('src/General/html/Settings/Keybinds.html').replace(/>\s+<').trim() %> diff --git a/src/General/html/Settings/Advanced.html b/src/General/html/Settings/Advanced.html index 6251d7b7c..37a22355e 100644 --- a/src/General/html/Settings/Advanced.html +++ b/src/General/html/Settings/Advanced.html @@ -1,8 +1,3 @@ -
- Archiver - Select an Archiver for this board: - -
Custom Board Navigation
diff --git a/src/General/html/Settings/Archives.html b/src/General/html/Settings/Archives.html new file mode 100644 index 000000000..086b33d92 --- /dev/null +++ b/src/General/html/Settings/Archives.html @@ -0,0 +1,12 @@ +
404 Redirect is disabled.
+

Disabled selections indicate that only one archive is available for that board and redirection type.

+ + + + + + + + + +
Archived boards
BoardThread redirectionPost fetchingFile redirection
diff --git a/src/Images/ImageExpand.coffee b/src/Images/ImageExpand.coffee index 87eb99755..6d0f1d7ee 100644 --- a/src/Images/ImageExpand.coffee +++ b/src/Images/ImageExpand.coffee @@ -137,7 +137,10 @@ ImageExpand = src = @src.split '/' if src[2] is 'images.4chan.org' - if URL = Redirect.image src[3], src[5] + URL = Redirect.to 'image', + boardID: src[3] + filename: src[5] + if URL setTimeout ImageExpand.expand, 10000, post, URL return if g.DEAD or post.isDead or post.file.isDead diff --git a/src/Images/ImageHover.coffee b/src/Images/ImageHover.coffee index 639f37e0a..f4f3a82d2 100644 --- a/src/Images/ImageHover.coffee +++ b/src/Images/ImageHover.coffee @@ -28,7 +28,10 @@ ImageHover = src = @src.split '/' if src[2] is 'images.4chan.org' - if URL = Redirect.image src[3], src[5].replace /\?.+$/, '' + URL = Redirect.to 'image', + boardID: src[3] + filename: src[5].replace /\?.+$/, '' + if URL @src = URL return if g.DEAD or post.isDead or post.file.isDead diff --git a/src/Menu/ArchiveLink.coffee b/src/Menu/ArchiveLink.coffee index daa67bb9e..12b6e507d 100644 --- a/src/Menu/ArchiveLink.coffee +++ b/src/Menu/ArchiveLink.coffee @@ -10,8 +10,7 @@ ArchiveLink = el: div order: 90 open: ({ID, thread, board}) -> - redirect = Redirect.to {postID: ID, threadID: thread.ID, boardID: board.ID} - redirect isnt "//boards.4chan.org/#{board}/" + !!Redirect.to 'thread', {postID: ID, threadID: thread.ID, boardID: board.ID} subEntries: [] for type in [ @@ -35,14 +34,14 @@ ArchiveLink = open = if type is 'post' ({ID, thread, board}) -> - el.href = Redirect.to {postID: ID, threadID: thread.ID, boardID: board.ID} + el.href = Redirect.to 'thread', {postID: ID, threadID: thread.ID, boardID: board.ID} true else (post) -> value = Filter[type] post # We want to parse the exact same stuff as the filter does already. return false unless value - el.href = Redirect.to + el.href = Redirect.to 'search', boardID: post.board.ID type: type value: value diff --git a/src/Quotelinks/Quotify.coffee b/src/Quotelinks/Quotify.coffee index 182561de8..b537a7ae2 100644 --- a/src/Quotelinks/Quotify.coffee +++ b/src/Quotelinks/Quotify.coffee @@ -51,14 +51,14 @@ Quotify = a.setAttribute 'data-boardid', boardID a.setAttribute 'data-threadid', post.thread.ID a.setAttribute 'data-postid', postID - else if redirect = Redirect.to {boardID, threadID: 0, postID} + else if redirect = Redirect.to 'thread', {boardID, threadID: 0, postID} # Replace the .deadlink span if we can redirect. a = $.el 'a', href: redirect className: 'deadlink' target: '_blank' textContent: "#{quote}\u00A0(Dead)" - if Redirect.post boardID, postID + if Redirect.to 'post', {boardID, postID} # Make it function as a normal quote if we can fetch the post. $.addClass a, 'quotelink' a.setAttribute 'data-boardid', boardID From 36e11ff9216413d7d68f43e302f87e9b11052b54 Mon Sep 17 00:00:00 2001 From: Zixaphir Date: Sun, 12 May 2013 15:34:29 -0700 Subject: [PATCH 8/8] Fix file redirection. This was all my bad. --- builds/4chan-X.js | 17 +++++++++-------- builds/4chan-X.user.js | 17 +++++++++-------- builds/crx/script.js | 17 +++++++++-------- src/Archive/Redirect.coffee | 2 +- src/General/Main.coffee | 3 ++- src/Images/ImageExpand.coffee | 2 +- src/Images/ImageHover.coffee | 2 +- 7 files changed, 32 insertions(+), 28 deletions(-) diff --git a/builds/4chan-X.js b/builds/4chan-X.js index 26a197f7a..29132b8ec 100644 --- a/builds/4chan-X.js +++ b/builds/4chan-X.js @@ -6245,7 +6245,7 @@ ImageExpand.contract(post); src = this.src.split('/'); if (src[2] === 'images.4chan.org') { - URL = Redirect.to('image', { + URL = Redirect.to('file', { boardID: src[3], filename: src[5] }); @@ -6385,7 +6385,7 @@ post = g.posts[this.dataset.fullid]; src = this.src.split('/'); if (src[2] === 'images.4chan.org') { - URL = Redirect.to('image', { + URL = Redirect.to('file', { boardID: src[3], filename: src[5].replace(/\?.+$/, '') }); @@ -7754,7 +7754,7 @@ post: {}, file: {}, init: function() { - var archive, arr, boardID, data, id, name, type, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3; + var archive, arr, boardID, data, id, name, type, _i, _len, _ref, _ref1, _ref2, _ref3; _ref = Conf['selectedArchives']; for (boardID in _ref) { @@ -7775,11 +7775,11 @@ } } _ref2 = Redirect.archives; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - archive = _ref2[_i]; + for (name in _ref2) { + archive = _ref2[name]; _ref3 = archive.boards; - for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { - boardID = _ref3[_j]; + for (_i = 0, _len = _ref3.length; _i < _len; _i++) { + boardID = _ref3[_i]; if (!(boardID in Redirect.thread)) { Redirect.thread[boardID] = archive; } @@ -10052,7 +10052,8 @@ var url; if (Conf['404 Redirect'] && d.title === '4chan - 404 Not Found') { - url = Redirect.to('image', { + Redirect.init(); + url = Redirect.to('file', { boardID: pathname[1], filename: pathname[3] }); diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 7807e6d74..198f51b25 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -6254,7 +6254,7 @@ ImageExpand.contract(post); src = this.src.split('/'); if (src[2] === 'images.4chan.org') { - URL = Redirect.to('image', { + URL = Redirect.to('file', { boardID: src[3], filename: src[5] }); @@ -6394,7 +6394,7 @@ post = g.posts[this.dataset.fullid]; src = this.src.split('/'); if (src[2] === 'images.4chan.org') { - URL = Redirect.to('image', { + URL = Redirect.to('file', { boardID: src[3], filename: src[5].replace(/\?.+$/, '') }); @@ -7763,7 +7763,7 @@ post: {}, file: {}, init: function() { - var archive, arr, boardID, data, id, name, type, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3; + var archive, arr, boardID, data, id, name, type, _i, _len, _ref, _ref1, _ref2, _ref3; _ref = Conf['selectedArchives']; for (boardID in _ref) { @@ -7784,11 +7784,11 @@ } } _ref2 = Redirect.archives; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - archive = _ref2[_i]; + for (name in _ref2) { + archive = _ref2[name]; _ref3 = archive.boards; - for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { - boardID = _ref3[_j]; + for (_i = 0, _len = _ref3.length; _i < _len; _i++) { + boardID = _ref3[_i]; if (!(boardID in Redirect.thread)) { Redirect.thread[boardID] = archive; } @@ -10063,7 +10063,8 @@ var url; if (Conf['404 Redirect'] && d.title === '4chan - 404 Not Found') { - url = Redirect.to('image', { + Redirect.init(); + url = Redirect.to('file', { boardID: pathname[1], filename: pathname[3] }); diff --git a/builds/crx/script.js b/builds/crx/script.js index da8850daa..5d884ada0 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -6232,7 +6232,7 @@ ImageExpand.contract(post); src = this.src.split('/'); if (src[2] === 'images.4chan.org') { - URL = Redirect.to('image', { + URL = Redirect.to('file', { boardID: src[3], filename: src[5] }); @@ -6372,7 +6372,7 @@ post = g.posts[this.dataset.fullid]; src = this.src.split('/'); if (src[2] === 'images.4chan.org') { - URL = Redirect.to('image', { + URL = Redirect.to('file', { boardID: src[3], filename: src[5].replace(/\?.+$/, '') }); @@ -7746,7 +7746,7 @@ post: {}, file: {}, init: function() { - var archive, arr, boardID, data, id, name, type, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3; + var archive, arr, boardID, data, id, name, type, _i, _len, _ref, _ref1, _ref2, _ref3; _ref = Conf['selectedArchives']; for (boardID in _ref) { @@ -7767,11 +7767,11 @@ } } _ref2 = Redirect.archives; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - archive = _ref2[_i]; + for (name in _ref2) { + archive = _ref2[name]; _ref3 = archive.boards; - for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { - boardID = _ref3[_j]; + for (_i = 0, _len = _ref3.length; _i < _len; _i++) { + boardID = _ref3[_i]; if (!(boardID in Redirect.thread)) { Redirect.thread[boardID] = archive; } @@ -10044,7 +10044,8 @@ var url; if (Conf['404 Redirect'] && d.title === '4chan - 404 Not Found') { - url = Redirect.to('image', { + Redirect.init(); + url = Redirect.to('file', { boardID: pathname[1], filename: pathname[3] }); diff --git a/src/Archive/Redirect.coffee b/src/Archive/Redirect.coffee index c6669d478..5d26adb35 100644 --- a/src/Archive/Redirect.coffee +++ b/src/Archive/Redirect.coffee @@ -13,7 +13,7 @@ Redirect = else archive.boards Redirect[type][boardID] = archive if arr.contains boardID - for archive in Redirect.archives + for name, archive of Redirect.archives for boardID in archive.boards unless boardID of Redirect.thread Redirect.thread[boardID] = archive diff --git a/src/General/Main.coffee b/src/General/Main.coffee index a36d1f93b..0cfd6544a 100644 --- a/src/General/Main.coffee +++ b/src/General/Main.coffee @@ -46,7 +46,8 @@ Main = when 'images.4chan.org' $.ready -> if Conf['404 Redirect'] and d.title is '4chan - 404 Not Found' - url = Redirect.to 'image', + Redirect.init() + url = Redirect.to 'file', boardID: pathname[1] filename: pathname[3] location.href = url if url diff --git a/src/Images/ImageExpand.coffee b/src/Images/ImageExpand.coffee index 6d0f1d7ee..a2427365a 100644 --- a/src/Images/ImageExpand.coffee +++ b/src/Images/ImageExpand.coffee @@ -137,7 +137,7 @@ ImageExpand = src = @src.split '/' if src[2] is 'images.4chan.org' - URL = Redirect.to 'image', + URL = Redirect.to 'file', boardID: src[3] filename: src[5] if URL diff --git a/src/Images/ImageHover.coffee b/src/Images/ImageHover.coffee index f4f3a82d2..082aa4625 100644 --- a/src/Images/ImageHover.coffee +++ b/src/Images/ImageHover.coffee @@ -28,7 +28,7 @@ ImageHover = src = @src.split '/' if src[2] is 'images.4chan.org' - URL = Redirect.to 'image', + URL = Redirect.to 'file', boardID: src[3] filename: src[5].replace /\?.+$/, '' if URL