Greasy Fork

Switch to Mobile Wikipedia/Wiktionary and back

Automatically loads Mobile Wikipedia if you visit the desktop version of Wikipedia from a different site; provides a shortcut to switch between the two and stays on the version you switched to.

目前为 2021-11-27 提交的版本。查看 最新版本

// ==UserScript==
// @name         Switch to Mobile Wikipedia/Wiktionary and back
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  Automatically loads Mobile Wikipedia if you visit the desktop version of Wikipedia from a different site; provides a shortcut to switch between the two and stays on the version you switched to.
// @author       https://greasyfork.org/en/users/728793-keyboard-shortcuts
// @icon         https://en.wikipedia.org/favicon.ico
// @include      https://*.wikipedia.org/*
// @include      https://*.wiktionary.org/*
// @grant        none
// @license      MIT
// ==/UserScript==

/* jshint esversion: 6 */

function swallowEvent(event) {
    if (event) {
        event.preventDefault();
        event.stopPropagation();
    }
}

function isMobile(match) {
    return match[1].endsWith('.m');
}

function changeLocation(newHref) {
    window.location.replace(newHref);
}

function switchToMobile(event, match) {
    swallowEvent(event);
    changeLocation(match[1] + '.m' + match[2]);
}

function switchToMobileOrBack(event, match) {
    if (isMobile(match)) { // mobile: remove tailing '.m'
        swallowEvent(event);
        changeLocation(match[1].substr(0, match[1].length - 2) + match[2]);
    } else {
        switchToMobile(event, match);
    }
}


function switchToEditMode(event, match) {
    const editSuffix = '?action=edit';
    const currentlyEditing = (location.href.indexOf(editSuffix) != -1 || location.href.indexOf('#/editor/') != -1);
    swallowEvent(event);
    if (!currentlyEditing) {
        if (isMobile(match)) { // mobile: switch back to non-mobile page and add edit suffix
            changeLocation(match[1].substr(0, match[1].length - 2) + match[2] + editSuffix);
        } else {
            changeLocation(location.href + editSuffix);
        }
    } else {
        const newUrl = isMobile(match) ? location.href : match[1] + '.m' + match[2];
        changeLocation(newUrl.replaceAll(/#\/editor\/.*/g, '').replaceAll(editSuffix, '')); // was editing: go back to regular mobile page
    }
}

(function() {
    'use strict';
    const websiteRegex = /^(https?:\/\/[^\/]*)(\.(wikipedia|wiktionary)\.org\/.*)/;

    const previousHref = document.referrer || '';
    const referrerWiki = websiteRegex.exec(previousHref); // match object for the referrer
    const currentWiki = websiteRegex.exec(location.href); // match object for the current address

    if (!referrerWiki) { // referrer is *not* Wikimedia: make sure we hit the mobile website first
        if (currentWiki && !isMobile(currentWiki)) { // First visit: switch to mobile by default
            switchToMobile(null, currentWiki);
        }
    } else { // referrer is a Wikimedia site; check if it's a different language and switch to mobile if so
        const languageRegex = /^(https?:\/\/)(?<lang>[a-z]+)(\.(wikipedia|wiktionary)\.org\/.*)/;
        const curLangMatch = languageRegex.exec(location.href);
        const prevLangMatch = languageRegex.exec(previousHref);
        if (curLangMatch && prevLangMatch && curLangMatch.groups.lang !== prevLangMatch.groups.lang) {
            const willSwitch = (currentWiki && !isMobile(currentWiki));
            if (willSwitch) { // Language change: switch to mobile as if we came from a third-party website
                switchToMobile(null, currentWiki);
            }
        }
    }

    function handleEvent(e) {
        if (!currentWiki) { // not on a Wikimedia website
            return true;
        }
        if (e.target.getAttribute("contenteditable") == "true") { // not for edit modes
            return true;
        }

        const isEditing = (location.href.indexOf('action=edit') !== -1);
        if ((e.altKey || e.ctrlKey) && e.code === 'KeyM') { // ctrl-m or alt-m
            switchToMobileOrBack(e, currentWiki);
        } else if ((e.altKey || e.ctrlKey) && e.code === 'KeyE') { // ctrl-e or alt-e
            switchToEditMode(e, currentWiki);
        } else {
            return true;
        }
        return false; // we moved to a different page
    }

    addEventListener("keydown", handleEvent);
    addEventListener("keypress", handleEvent);

})();