// ==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; }