Jump to content

User:Chlod/Scripts/GoToTitle.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Chlod (talk | contribs) at 06:55, 3 May 2024 (support v22 header). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// GoToTitle
// Author: Chlod
// Version: 1.0.1-REL

// Navigate to any page using an input box that opens when you click on the page title.
// Non-intrusive to work with other title-modifying userscripts.

(function() {
    
    var overlayId = "goto_titleOverlay";
    
    document.body.addEventListener("click", function(event) {
        var currentParent = event.target;
        
        // Traverse click event and check if it hits the title heading.
        do {
        	if (currentParent == null)
        		// Whoops, we went too far!
        		return;
            if (currentParent.id === overlayId) return;
            if (
            	// Standard heading
            	(currentParent.id === "firstHeading"
            	// Vector 2022 floating header
            	|| currentParent.classList.contains("mw-page-title-main"))
            	// No overlay existing
            	&& document.getElementById(overlayId) === null
        	) {
                var relativeContainer = document.createElement("div");
                var absoluteContainer = document.createElement("div");
                var titleInput = document.createElement("input");
                
                var titleHeight = currentParent.clientHeight;
                
                relativeContainer.id = overlayId;
                relativeContainer.style.position = "relative";
                relativeContainer.style.top = "-" + (+(titleHeight + 1)) + "px";
                relativeContainer.style.width = "100%";
                
                absoluteContainer.style.position = "absolute";
                absoluteContainer.style.width = "100%";
                absoluteContainer.style.height = titleHeight + "px";
                absoluteContainer.style.top = absoluteContainer.style.left = "0";
                
                titleInput.style.padding = "0";
                titleInput.style.width = titleInput.style.height = "100%";
                titleInput.style.border = "0";
                
                relativeContainer.style.fontSize = 
                    absoluteContainer.style.fontSize = 
                    titleInput.style.fontSize = "inherit";
                relativeContainer.style.fontFamily = 
                    absoluteContainer.style.fontFamily = 
                    titleInput.style.fontFamily = "inherit";
                
                titleInput.addEventListener("keydown", function(kdEvent) {
                    if (Array.isArray(window.GoToTitleHooks))
                        window.GoToTitleHooks.forEach(f => f(kdEvent));
                    if (kdEvent.key === "Escape")
                        relativeContainer.parentElement.removeChild(relativeContainer);
                    else if (kdEvent.key === "Enter")
                        window.location.href = mw.config.get("wgArticlePath")
                        	.replace('$1', mw.util.wikiUrlencode(titleInput.value));
                });
                    
                // Because there's no inbuilt value for plain title with namespace.
                var namespace = mw.config.get("wgFormattedNamespaces")[mw.config.get("wgNamespaceNumber")];
                titleInput.value = (namespace.length > 0 ? namespace + ":" : "") + mw.config.get("wgTitle");
                
                absoluteContainer.appendChild(titleInput);
                relativeContainer.appendChild(absoluteContainer);
                currentParent.appendChild(relativeContainer);
                
                titleInput.focus();
                
                return;
            }
        } while ((currentParent = currentParent.parentElement) !== document.body);
        
        // Did not hit event heading. Close if not found.
        var overlayElement = document.getElementById(overlayId);
        if (overlayElement != null) {
            overlayElement.parentElement.removeChild(overlayElement);
        }
        
    });
    
})();