diff --git a/Archive Site Links.user.js b/Archive Site Links.user.js new file mode 100644 index 0000000..742f555 --- /dev/null +++ b/Archive Site Links.user.js @@ -0,0 +1,111 @@ +// ==UserScript== +// @name Archive Site Links +// @namespace blankie-scripts +// @match http*://*/* +// @grant GM_openInTab +// @grant GM_registerMenuCommand +// @version 1.0.0 +// @author blankie +// @description Adds buttons to the monkey menu to open/archive in the Wayback Machine and archive.today +// @inject-into content +// @noframes +// ==/UserScript== + +"use strict"; + +const ARCHIVE_SITES = [ + { + name: "Wayback Machine", + getArchiveUrl: function(url) { + let newUrl = new URL("https://web.archive.org/save"); + let search = new URLSearchParams([["asl_url", url]]); + newUrl.search = search.toString(); + return newUrl.href; + }, + getArchivedUrl: function(url) { + return `https://web.archive.org/web/2/${url}`; + }, + getArchivedUrlBase: function() { + if (window.location.host !== "web.archive.org") return null; + let match = /^\/web\/[0-9a-z_*]+\/(.+)$/.exec(window.location.pathname); + return match ? match[1] : null; + }, + }, + { + name: "archive.today", + getArchiveUrl: function(url) { + let newUrl = new URL("https://archive.today"); + newUrl.searchParams.append("url", url); + return newUrl.href; + }, + getArchivedUrl: function(url) { + return `https://archive.today/newest/${url}`; + }, + getArchivedUrlBase: function() { + // https://en.wikipedia.org/wiki/Archive.today?useskin=vector& + if (!/^archive\.(today|ph|is|li|vn|fo|md)$/.test(window.location.host)) return null; + let q = document.querySelector("center form input[name=q]"); + return q ? q.value : null; + } + } +]; + +let url = window.location.href; +let onArchiveSite; +for (const ARCHIVE_SITE of ARCHIVE_SITES) { + let urlBase = ARCHIVE_SITE.getArchivedUrlBase(url); + if (!urlBase) { + continue; + } + + if (!/^https?:\/\/|\/\//.test(urlBase)) { + urlBase = `http://${urlBase}` + }; + + let urlObject = new URL(urlBase); + urlObject.search = window.location.search; + urlObject.hash = window.location.hash; + url = urlObject.href; + onArchiveSite = ARCHIVE_SITE; + break; +} + +let archiveSites = 0; +for (const ARCHIVE_SITE of ARCHIVE_SITES) { + if (onArchiveSite === ARCHIVE_SITE) { + continue; + } + + if (archiveSites !== 0) { + GM_registerMenuCommand("=".repeat(20) + "\u200B".repeat(archiveSites), function() {}); + } + archiveSites++; + + GM_registerMenuCommand(`Open in ${ARCHIVE_SITE.name}`, function() { + window.location.href = ARCHIVE_SITE.getArchivedUrl(url); + }); + GM_registerMenuCommand(`Open in ${ARCHIVE_SITE.name} (new tab)`, function() { + GM_openInTab(ARCHIVE_SITE.getArchivedUrl(url)); + }); + + let urlObject = new URL(url); + urlObject.hash = ""; + let hashlessUrl = urlObject.href; + + GM_registerMenuCommand(`Archive in ${ARCHIVE_SITE.name}`, function() { + window.location.href = ARCHIVE_SITE.getArchiveUrl(hashlessUrl); + }); + GM_registerMenuCommand(`Archive in ${ARCHIVE_SITE.name} (new tab)`, function() { + GM_openInTab(ARCHIVE_SITE.getArchiveUrl(hashlessUrl)); + }); +} + +// workaround for the wayback machine not exposing a way to prefill the url input box +let searchParams = new URLSearchParams(window.location.search); +if (window.location.host === "web.archive.org" && window.location.pathname === "/save" && searchParams.has("asl_url")) { + document.querySelector("#web-save-url-input").value = searchParams.get("asl_url"); + + let urlObject = new URL(window.location); + urlObject.searchParams.delete("asl_url"); + history.replaceState(null, "", urlObject.href); +} \ No newline at end of file diff --git a/README.md b/README.md index 6940406..e3d29dd 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,11 @@ User scripts I made to deal with some itches Hacky script to get rid of thot notifications +## Archive Site Links + +A userscript that adds buttons to the monkey menu that lets you open sites in +the Wayback Machine and archive.today; also lets you archive pages + ## Auto Cloudflare Email Protection Decoder A reimplementation of Cloudflare's email protection code so that I don't have