Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Please sign up or log in to edit the wiki.

MediaWiki:Timeless.js

MediaWiki interface page

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/* All JavaScript here will be loaded for users of the Timeless skin */
var BACKGROUND_IMAGE_CLASS = "timeless-background-ready";
var BACKGROUND_IMAGE_URL = "/w/resources/assets/tg-map-compressed.webp";

/**
 * Wait for first paint before calling this function.
 *
 * @return {void}
 */
function enableBackgroundImage() {
    document.documentElement.classList.add(BACKGROUND_IMAGE_CLASS);
}

/**
 * Check if the background image is cached by sending a HEAD request to the specified URL.
 *
 * @returns {boolean} A boolean indicating whether the background image is cached (status 200) or not.
 */
function isBackgroundImageCached() {
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open("HEAD", BACKGROUND_IMAGE_URL);
        xhr.onload = function () {
            if (xhr.status === 200) {
                resolve(true);
            } else {
                resolve(false);
            }
        };
        xhr.onerror = function () {
            console.error("Error checking image cache:", xhr.statusText);
            resolve(false);
        };
        xhr.send();
    });
}

/**
 * Asynchronously loads the background image by checking if it is cached, and enabling it if cached or when the document is ready.
 * If the background image is cached, it is immediately enabled. If not cached, it waits for the document to be interactive or complete before enabling the background image.
 * If the document is not yet interactive or complete, it adds an event listener for the 'DOMContentLoaded' event to enable the background image when the document is fully loaded.
 */
function loadBackgroundImage() {
    isBackgroundImageCached().then(function (cached) {
        if (cached) {
            enableBackgroundImage();
        } else if (
            document.readyState === "interactive" ||
            document.readyState === "complete"
        ) {
            enableBackgroundImage();
        } else {
            document.addEventListener(
                "DOMContentLoaded",
                function onLoad() {
                    enableBackgroundImage();
                    document.removeEventListener("DOMContentLoaded", onLoad);
                },
                { once: true }
            );
        }
    });
}

/**
 * Check if the element is a HTML form element or content editable
 * This is to prevent trigger search box when user is typing on a textfield, input, etc.
 *
 * @param {HTMLElement} element
 * @return {boolean}
 */
function isFormField(element) {
    if (!(element instanceof HTMLElement)) {
        return false;
    }
    var name = element.nodeName.toLowerCase();
    var type = (element.getAttribute("type") || "").toLowerCase();
    return (
        name === "select" ||
        name === "textarea" ||
        (name === "input" &&
            type !== "submit" &&
            type !== "reset" &&
            type !== "checkbox" &&
            type !== "radio") ||
        element.isContentEditable
    );
}

/**
 * Focus on search box when the keyboard button is SLASH is pressed.
 *
 * @param {HTMLInputElement} input
 * @return {void}
 */
function bindSearchOnSlash(input) {
    function onSlash(event) {
        function isKeyPressed() {
            // "/" key is standard on many sites
            if (event.key === "/") {
                return true;
                // "Alt" + "Shift" + "F" is the MW standard key
                // Shift key might makes F key goes capital, so we need to make it lowercase
            } else if (
                event.altKey &&
                event.shiftKey &&
                event.key.toLowerCase() === "f"
            ) {
                return true;
            } else {
                return false;
            }
        }

        if (isKeyPressed() && !isFormField(event.target)) {
            // Since Firefox quickfind interfere with this
            event.preventDefault();
            input.focus();
        }
    }

    window.addEventListener("keydown", onSlash, true);
}

function init() {
    var searchInput = document.getElementById("searchInput");
    if (searchInput) {
        bindSearchOnSlash(searchInput);
    }
    loadBackgroundImage();
}

init();