userscripts/Wayback Machine Toolbar Tog...

154 lines
4.7 KiB
JavaScript

// ==UserScript==
// @name Wayback Machine Toolbar Toggler
// @namespace blankie-scripts
// @match https://web.archive.org/web/*
// @grant GM.getValue
// @grant GM.setValue
// @grant GM_addValueChangeListener
// @version 1.1.1
// @author blankie
// @description Replaces the "close this toolbar" button with one that lets you reopen the toolbar; its collapsed state is also saved
// @inject-into page
// @run-at document-start
// ==/UserScript==
"use strict";
let wmIppBase = null;
let wmIpp = null;
function hideToolbar(save = true) {
wmIpp.querySelector("#wm-ipp-inside").style.display = "none";
let openA = wmIpp.querySelector("#wmtt-open-toolbar");
let baseHeight = wmIpp.querySelector("#donato").offsetHeight + openA.offsetHeight + (wmIpp.querySelector("#wm-ipp-inside").offsetHeight - wmIpp.querySelector("#wm-capinfo").offsetHeight);
wmIppBase.style.height = `${baseHeight}px`;
openA.style.display = "";
if (!save) {
return;
}
GM.setValue("autoHideToolbar", true).catch(function(error) {
console.error("Failed to set autoHideToolbar to true:", error);
});
}
function showToolbar(save = true) {
wmIpp.querySelector("#wm-ipp-inside").style.display = "";
wmIppBase.style.height = "";
wmIpp.querySelector("#wmtt-open-toolbar").style.display = "none";
if (!save) {
return;
}
GM.setValue("autoHideToolbar", false).catch(function(error) {
console.error("Failed to set autoHideToolbar to false:", error);
});
}
function handleWmIpp() {
// Hook wm-tb-close for our own toolbar hider
let close = wmIpp.querySelector("#wm-tb-close");
let newClose = close.cloneNode(true);
newClose.addEventListener("click", function(event) {
event.preventDefault();
hideToolbar();
});
close.replaceWith(newClose);
// Add the "Open toolbar" button
let openWrapper = document.createElement("div");
openWrapper.style.paddingRight = "13px";
openWrapper.style.textAlign = "right";
openWrapper.style.whiteSpace = "nowrap";
wmIpp.append(openWrapper);
let openA = document.createElement("a");
openA.id = "wmtt-open-toolbar";
openA.className = "wm-btn wm-closed";
openA.addEventListener("click", function() {
showToolbar();
}, {passive: true});
// hide by default
openA.style.display = "none";
// copy of #wm-expand to avoid duplicate ids
openA.style.backgroundColor = "#666";
openA.style.padding = "0 5px 0 3px";
openA.style.borderRadius = "0 0 3px 3px";
openA.style.textDecoration = "none";
openA.setAttribute("role", "link");
openA.style.cursor = "pointer";
openWrapper.append(openA);
let openIcon = document.createElement("span");
openIcon.style.color = "white";
openIcon.className = "iconochive-down-solid";
openA.append(openIcon);
let openText = document.createElement("span");
openText.style.color = "white";
openText.style.fontSize = "80%";
// add leading whitespace
openText.innerText = " Open toolbar";
openA.append(openText);
// Automatically hide toolbar on startup
GM.getValue("autoHideToolbar", false).then(function(autoHideToolbar) {
if (autoHideToolbar) {
hideToolbar(false);
}
}).catch(function(error) {
console.error("Failed to fetch autoHideToolbar:", error);
});
GM_addValueChangeListener("autoHideToolbar", function(name, oldValue, autoHideToolbar, remote) {
if (!remote) {
return;
}
if (autoHideToolbar) {
hideToolbar(false);
} else {
showToolbar(false);
}
});
}
// i hate IIFEs.
// Hook Element.prototype.attachShadow to get wm-ipp-base and its (closed) shadow root
let realAttachShadow = Element.prototype.attachShadow;
Element.prototype.attachShadow = function() {
let shadowRoot = realAttachShadow.apply(this, arguments);
if (this.id === "wm-ipp-base") {
Element.prototype.attachShadow = realAttachShadow;
wmIppBase = this;
observer.observe(shadowRoot, {childList: true});
}
return shadowRoot;
};
// Hook wm-ipp-base's shadow root to get wm-ipp
let observer = new MutationObserver(function(mutations, observer) {
for (let mutation of mutations) {
if (mutation.type !== "childList") {
continue;
}
for (let node of mutation.addedNodes) {
let stop = handleNewNode(node, observer);
if (stop) {
observer.disconnect();
return;
}
}
}
});
function handleNewNode(node, observer) {
if (node.nodeType !== 1 || node.id !== "wm-ipp") {
return false;
}
wmIpp = node;
handleWmIpp();
return true;
}