From Wikipedia, the free encyclopedia
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.

// vim: ts=4 sw=4 et ai

// <nowiki>

( function () {

    // sample value: {"a": {"b": "WP:RFA", "c": {"d": "WP:ANI"}}}

    var gMenuJson = null;



    // sample value: ["a", "b"]

    var gPressedKeys = [];



    var gGeneralKeyListener = null;



    // GUI components

    var gBackBtn;

    //var gBreadcrumb;



    var SUPERJUMP_PANEL_ID = "superjump-container-panel";

    var SUPERJUMP_TABLE_ID = "superjump-keys-table";

    var MENU_JSON_LOCALSTORAGE_KEY = "enwp_superjump_menu_json";

    var MENU_JSON_LOCALSTORAGE_SEPARATOR = "|";



    function initAccessKeyListeners() {

        for( var key in gMenuJson ) {

            initAccessKeyListener( key, function () { handleKey( key, gMenuJson, /* accessKey */ true ); } );

        }

    }



    function navigateToPath( keys ) {

        var menu = gMenuJson;

        for( var i = 0; i < keys.length - 1; i++ ) {

            menu = menu keysi ];

        }

        gPressedKeys = keys.slice( 0, keys.length - 1 );

        var lastKey = keys keys.length - 1 ];

        handleKey( lastKey, menu );

    }



    function handleKey( key, menu, accessKey ) {

        if( key == "Escape" ) {

            closeInterface();

            gPressedKeys = [];

            return;

        } else if( key == "Backspace" ) {

            if( gPressedKeys.length > 1 ) {

                navigateToPath( gPressedKeys.slice( 0, gPressedKeys.length - 1 ) );

            }

            return;

        }



        var submenu = menu key ];



        if( typeof submenu === typeof "" ) {

            window.location.href = mw.util.getUrl( submenu );

        } else if( submenu ) {

            gPressedKeys.push( key );

            displayOrUpdateInterface( makePanel( submenu ) );

            if( gGeneralKeyListener ) {

                document.removeEventListener( "keydown", gGeneralKeyListener );

                gGeneralKeyListener = null;

            }

            gGeneralKeyListener = function ( event ) {

                handleKey( event.key, submenu );

            };

            document.addEventListener( "keydown", gGeneralKeyListener );

        }

    }



    function displayOrUpdateInterface( panel ) {

        panel.id = SUPERJUMP_TABLE_ID;



        var containerPanel = document.getElementById( SUPERJUMP_PANEL_ID );

        if( !containerPanel ) {

            containerPanel = createInterface();

            document.body.appendChild( containerPanel );

        }

        containerPanel.replaceChild( panel, document.getElementById( SUPERJUMP_TABLE_ID ) );

        gBackBtn.disabled = gPressedKeys.length < 2;

        //gBreadcrumb.textContent = "Pressed: " + gPressedKeys.map( function ( x ) { return "[" + x + "]"; } ).join( " > " );

    }



    function createInterface() {

        containerPanel = document.createElement( "div" );

        containerPanel.id = SUPERJUMP_PANEL_ID;



        var topBar = document.createElement( "div" );

        gBackBtn = document.createElement( "button" );

        gBackBtn.textContent = "Back [Backspace]";

        gBackBtn.addEventListener( "click", function () {

            navigateToPath( gPressedKeys.slice( 0, gPressedKeys.length - 1 ) );

        } );

        topBar.appendChild( gBackBtn );

        var closeBtn = document.createElement( "button" );

        closeBtn.textContent = "Close [Esc]";

        closeBtn.addEventListener( "click", closeInterface );

        topBar.appendChild( closeBtn );

        containerPanel.appendChild( topBar );



        var startingPanel = document.createElement( "div" );

        startingPanel.id = SUPERJUMP_TABLE_ID;

        containerPanel.appendChild( startingPanel );



        //var bottomBar = document.createElement( "div" );

        //gBreadcrumb = document.createElement( "span" );

        //bottomBar.appendChild( gBreadcrumb );

        //var editConfigBtn = document.createElement( "button" );

        //editConfigBtn.textContent = "Edit configuration";

        //editConfigBtn.addEventListener( "click", function () {

        //    window.location.href = mw.util.getUrl( getMenuJsonPageTitle(), { action: "edit" } );

        //} );

        //bottomBar.appendChild( editConfigBtn );

        //containerPanel.appendChild( bottomBar );



        return containerPanel;

    }



    function closeInterface() {

        var panel = document.getElementById( SUPERJUMP_PANEL_ID );

        panel.parentNode.removeChild( panel );

        if( gGeneralKeyListener ) {

            document.removeEventListener( "keydown", gGeneralKeyListener );

        }

    }



    function makePanel( menu ) {

        var table = document.createElement( "table" );



        var keys = Object.keys( menu );

        var numItems = keys.length;

        var tds = new Array( numItems );

        for( var i = 0; i < numItems; i++ ) {

            var td = document.createElement( "td" );

            var keySpan = document.createElement( "span" );

            keySpan.className = "key-span";

            keySpan.textContent = "[" + keysi + "]";

            td.appendChild( keySpan );

            var actionSpan = document.createElement( "span" );

            var menuItem = menu keysi ];

            if( typeof menuItem === typeof "" ) {

                actionSpan.textContent = menuItem;

            } else {

                var numChoices = Object.keys( menuItem ).length;

                actionSpan.textContent = numChoices + " choice" + ( numChoices !== 1 ? "s" : "" );

            }



            td.appendChild( actionSpan );

            tdsi = td;

        }



        var numRows = Math.max( 2, Math.ceil( Math.sqrt( numItems ) ) );

        var numCols = numRows;

        for( var i = 0; i < numRows; i++ ) {

            var tr = document.createElement( "tr" );

            for( var j = 0; j < numCols; j++ ) {

                var cell = tds i * numCols + j ];

                if( cell ) {

                    tr.appendChild( cell );

                }

            }

            table.appendChild( tr );

        }



        return table;

    }



    function initAccessKeyListener( key, listener ) {

        var hasOurAccessKey = document.querySelectorAll( "a[accesskey=" + key + "]" );

        if( hasOurAccessKey.length ) {

            for( var i = 0; i < hasOurAccessKey.length; i++ ) {

                hasOurAccessKeyi].setAttribute( "accesskey", "" );

                $( hasOurAccessKeyi ).updateTooltipAccessKeys();

            }

        }



        $( "body" ).append( $( "<a>" )

            .attr( { href: "#", accesskey: key } )

            .css( { position: "fixed", opacity: "0" } )

            .text( "superjump-link-" + key )

            .addClass( "superjump-accesskey-sink" )

            .click( listener ) );

    }



    function setMenuJson() {

        var reqParams = {

            format: "json",

            action: "query",

            prop: "revisions",

            titles: getMenuJsonPageTitle(),

            rvprop: "content|ids",

            rvslots: "main"

        };



        var storedRevidAndMenuJson = getStoredRevidAndMenuJson();

        var storedRevid, storedMenuJson;

        if( storedRevidAndMenuJson ) {

            storedRevid = storedRevidAndMenuJson0];

            storedMenuJson = storedRevidAndMenuJson1];



            reqParams.rvstartid = parseInt( storedRevid ) + 1;

            reqParams.rvdir = "newer";

        }



        return $.getJSON(

            mw.util.wikiScript( "api" ),

            reqParams

        ).then( function ( data ) {

            if( !data || !data.query || !data.query.pages ) {

                mw.notify( "Error loading menu JSON page!" );

                return;

            }



            var pageId = Object.keys( data.query.pages )[0];

            var pageObj = data.query.pagespageId];

            if( pageObj.missing ) {

                mw.notify( "Error! You'll need to create " + getMenuJsonPageTitle() + " to use superjump." );

                return;

            }



            var revs = pageObj.revisions;

            if( !revs ) {

                gMenuJson = JSON.parse(storedMenuJson);

                return;

            }



            var mostRecentRev = revs revs.length - 1 ];

            var apiRevid = mostRecentRev.revid;

            var apiJson = mostRecentRev.slots.main"*"];



            if( isLocalStorageAvailable() ) {

                var storageValue = apiRevid + MENU_JSON_LOCALSTORAGE_SEPARATOR + apiJson;

                window.localStorage.setItem( MENU_JSON_LOCALSTORAGE_KEY, storageValue );

            }



            gMenuJson = JSON.parse(apiJson);

        } );

    }



    function getMenuJsonPageTitle() {

        return "User:" + mw.config.get( "wgUserName" ) + "/superjump-config.json";

    }



    function getStoredRevidAndMenuJson() {

        var localStorageAvailable = isLocalStorageAvailable();

        if( localStorageAvailable ) {

            var storedRevidAndMenuJson = window.localStorage.getItem( MENU_JSON_LOCALSTORAGE_KEY );

            if( storedRevidAndMenuJson && storedRevidAndMenuJson.indexOf( MENU_JSON_LOCALSTORAGE_SEPARATOR ) >= 0 ) {

                return storedRevidAndMenuJson.split( MENU_JSON_LOCALSTORAGE_SEPARATOR );

            }

        }



        return null;

    }



    function isLocalStorageAvailable() {

        try {

            var storage = window.localStorage,

                x = '__storage_test__';

            storage.setItem( x, x );

            storage.removeItem( x );

            return true;

        } catch( e ) {

            return false;

        }

    }



    $.when( $.ready, mw.loader.using( "mediawiki.util" ) )

        .then( setMenuJson )

        .then( function () {

            mw.util.addCSS( "#" + SUPERJUMP_PANEL_ID + "{ position: fixed; "+

                    "top: 50%; left: 50%; margin-right: -50%; transform: translate(-50%, -50%); " +

                "background-color:white; padding: 1em; border:thin solid gray;" +

                "box-shadow:0px 7px 7px 0px rgba(0,0,0,0.3)}"+

            "#" + SUPERJUMP_PANEL_ID + " > div * { margin-left: 0.75em; }"+

            "#" + SUPERJUMP_TABLE_ID + " td{padding: 0.5em;}"+

            "#" + SUPERJUMP_TABLE_ID + " .key-span{font-family:monospace; cursor:default; padding-right: 0.1em; font-size: 200%}"+

            "#" + SUPERJUMP_TABLE_ID + " span{vertical-align:middle;}");

            initAccessKeyListeners();

        } );

} )();

// </nowiki>
From Wikipedia, the free encyclopedia
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.

// vim: ts=4 sw=4 et ai

// <nowiki>

( function () {

    // sample value: {"a": {"b": "WP:RFA", "c": {"d": "WP:ANI"}}}

    var gMenuJson = null;



    // sample value: ["a", "b"]

    var gPressedKeys = [];



    var gGeneralKeyListener = null;



    // GUI components

    var gBackBtn;

    //var gBreadcrumb;



    var SUPERJUMP_PANEL_ID = "superjump-container-panel";

    var SUPERJUMP_TABLE_ID = "superjump-keys-table";

    var MENU_JSON_LOCALSTORAGE_KEY = "enwp_superjump_menu_json";

    var MENU_JSON_LOCALSTORAGE_SEPARATOR = "|";



    function initAccessKeyListeners() {

        for( var key in gMenuJson ) {

            initAccessKeyListener( key, function () { handleKey( key, gMenuJson, /* accessKey */ true ); } );

        }

    }



    function navigateToPath( keys ) {

        var menu = gMenuJson;

        for( var i = 0; i < keys.length - 1; i++ ) {

            menu = menu keysi ];

        }

        gPressedKeys = keys.slice( 0, keys.length - 1 );

        var lastKey = keys keys.length - 1 ];

        handleKey( lastKey, menu );

    }



    function handleKey( key, menu, accessKey ) {

        if( key == "Escape" ) {

            closeInterface();

            gPressedKeys = [];

            return;

        } else if( key == "Backspace" ) {

            if( gPressedKeys.length > 1 ) {

                navigateToPath( gPressedKeys.slice( 0, gPressedKeys.length - 1 ) );

            }

            return;

        }



        var submenu = menu key ];



        if( typeof submenu === typeof "" ) {

            window.location.href = mw.util.getUrl( submenu );

        } else if( submenu ) {

            gPressedKeys.push( key );

            displayOrUpdateInterface( makePanel( submenu ) );

            if( gGeneralKeyListener ) {

                document.removeEventListener( "keydown", gGeneralKeyListener );

                gGeneralKeyListener = null;

            }

            gGeneralKeyListener = function ( event ) {

                handleKey( event.key, submenu );

            };

            document.addEventListener( "keydown", gGeneralKeyListener );

        }

    }



    function displayOrUpdateInterface( panel ) {

        panel.id = SUPERJUMP_TABLE_ID;



        var containerPanel = document.getElementById( SUPERJUMP_PANEL_ID );

        if( !containerPanel ) {

            containerPanel = createInterface();

            document.body.appendChild( containerPanel );

        }

        containerPanel.replaceChild( panel, document.getElementById( SUPERJUMP_TABLE_ID ) );

        gBackBtn.disabled = gPressedKeys.length < 2;

        //gBreadcrumb.textContent = "Pressed: " + gPressedKeys.map( function ( x ) { return "[" + x + "]"; } ).join( " > " );

    }



    function createInterface() {

        containerPanel = document.createElement( "div" );

        containerPanel.id = SUPERJUMP_PANEL_ID;



        var topBar = document.createElement( "div" );

        gBackBtn = document.createElement( "button" );

        gBackBtn.textContent = "Back [Backspace]";

        gBackBtn.addEventListener( "click", function () {

            navigateToPath( gPressedKeys.slice( 0, gPressedKeys.length - 1 ) );

        } );

        topBar.appendChild( gBackBtn );

        var closeBtn = document.createElement( "button" );

        closeBtn.textContent = "Close [Esc]";

        closeBtn.addEventListener( "click", closeInterface );

        topBar.appendChild( closeBtn );

        containerPanel.appendChild( topBar );



        var startingPanel = document.createElement( "div" );

        startingPanel.id = SUPERJUMP_TABLE_ID;

        containerPanel.appendChild( startingPanel );



        //var bottomBar = document.createElement( "div" );

        //gBreadcrumb = document.createElement( "span" );

        //bottomBar.appendChild( gBreadcrumb );

        //var editConfigBtn = document.createElement( "button" );

        //editConfigBtn.textContent = "Edit configuration";

        //editConfigBtn.addEventListener( "click", function () {

        //    window.location.href = mw.util.getUrl( getMenuJsonPageTitle(), { action: "edit" } );

        //} );

        //bottomBar.appendChild( editConfigBtn );

        //containerPanel.appendChild( bottomBar );



        return containerPanel;

    }



    function closeInterface() {

        var panel = document.getElementById( SUPERJUMP_PANEL_ID );

        panel.parentNode.removeChild( panel );

        if( gGeneralKeyListener ) {

            document.removeEventListener( "keydown", gGeneralKeyListener );

        }

    }



    function makePanel( menu ) {

        var table = document.createElement( "table" );



        var keys = Object.keys( menu );

        var numItems = keys.length;

        var tds = new Array( numItems );

        for( var i = 0; i < numItems; i++ ) {

            var td = document.createElement( "td" );

            var keySpan = document.createElement( "span" );

            keySpan.className = "key-span";

            keySpan.textContent = "[" + keysi + "]";

            td.appendChild( keySpan );

            var actionSpan = document.createElement( "span" );

            var menuItem = menu keysi ];

            if( typeof menuItem === typeof "" ) {

                actionSpan.textContent = menuItem;

            } else {

                var numChoices = Object.keys( menuItem ).length;

                actionSpan.textContent = numChoices + " choice" + ( numChoices !== 1 ? "s" : "" );

            }



            td.appendChild( actionSpan );

            tdsi = td;

        }



        var numRows = Math.max( 2, Math.ceil( Math.sqrt( numItems ) ) );

        var numCols = numRows;

        for( var i = 0; i < numRows; i++ ) {

            var tr = document.createElement( "tr" );

            for( var j = 0; j < numCols; j++ ) {

                var cell = tds i * numCols + j ];

                if( cell ) {

                    tr.appendChild( cell );

                }

            }

            table.appendChild( tr );

        }



        return table;

    }



    function initAccessKeyListener( key, listener ) {

        var hasOurAccessKey = document.querySelectorAll( "a[accesskey=" + key + "]" );

        if( hasOurAccessKey.length ) {

            for( var i = 0; i < hasOurAccessKey.length; i++ ) {

                hasOurAccessKeyi].setAttribute( "accesskey", "" );

                $( hasOurAccessKeyi ).updateTooltipAccessKeys();

            }

        }



        $( "body" ).append( $( "<a>" )

            .attr( { href: "#", accesskey: key } )

            .css( { position: "fixed", opacity: "0" } )

            .text( "superjump-link-" + key )

            .addClass( "superjump-accesskey-sink" )

            .click( listener ) );

    }



    function setMenuJson() {

        var reqParams = {

            format: "json",

            action: "query",

            prop: "revisions",

            titles: getMenuJsonPageTitle(),

            rvprop: "content|ids",

            rvslots: "main"

        };



        var storedRevidAndMenuJson = getStoredRevidAndMenuJson();

        var storedRevid, storedMenuJson;

        if( storedRevidAndMenuJson ) {

            storedRevid = storedRevidAndMenuJson0];

            storedMenuJson = storedRevidAndMenuJson1];



            reqParams.rvstartid = parseInt( storedRevid ) + 1;

            reqParams.rvdir = "newer";

        }



        return $.getJSON(

            mw.util.wikiScript( "api" ),

            reqParams

        ).then( function ( data ) {

            if( !data || !data.query || !data.query.pages ) {

                mw.notify( "Error loading menu JSON page!" );

                return;

            }



            var pageId = Object.keys( data.query.pages )[0];

            var pageObj = data.query.pagespageId];

            if( pageObj.missing ) {

                mw.notify( "Error! You'll need to create " + getMenuJsonPageTitle() + " to use superjump." );

                return;

            }



            var revs = pageObj.revisions;

            if( !revs ) {

                gMenuJson = JSON.parse(storedMenuJson);

                return;

            }



            var mostRecentRev = revs revs.length - 1 ];

            var apiRevid = mostRecentRev.revid;

            var apiJson = mostRecentRev.slots.main"*"];



            if( isLocalStorageAvailable() ) {

                var storageValue = apiRevid + MENU_JSON_LOCALSTORAGE_SEPARATOR + apiJson;

                window.localStorage.setItem( MENU_JSON_LOCALSTORAGE_KEY, storageValue );

            }



            gMenuJson = JSON.parse(apiJson);

        } );

    }



    function getMenuJsonPageTitle() {

        return "User:" + mw.config.get( "wgUserName" ) + "/superjump-config.json";

    }



    function getStoredRevidAndMenuJson() {

        var localStorageAvailable = isLocalStorageAvailable();

        if( localStorageAvailable ) {

            var storedRevidAndMenuJson = window.localStorage.getItem( MENU_JSON_LOCALSTORAGE_KEY );

            if( storedRevidAndMenuJson && storedRevidAndMenuJson.indexOf( MENU_JSON_LOCALSTORAGE_SEPARATOR ) >= 0 ) {

                return storedRevidAndMenuJson.split( MENU_JSON_LOCALSTORAGE_SEPARATOR );

            }

        }



        return null;

    }



    function isLocalStorageAvailable() {

        try {

            var storage = window.localStorage,

                x = '__storage_test__';

            storage.setItem( x, x );

            storage.removeItem( x );

            return true;

        } catch( e ) {

            return false;

        }

    }



    $.when( $.ready, mw.loader.using( "mediawiki.util" ) )

        .then( setMenuJson )

        .then( function () {

            mw.util.addCSS( "#" + SUPERJUMP_PANEL_ID + "{ position: fixed; "+

                    "top: 50%; left: 50%; margin-right: -50%; transform: translate(-50%, -50%); " +

                "background-color:white; padding: 1em; border:thin solid gray;" +

                "box-shadow:0px 7px 7px 0px rgba(0,0,0,0.3)}"+

            "#" + SUPERJUMP_PANEL_ID + " > div * { margin-left: 0.75em; }"+

            "#" + SUPERJUMP_TABLE_ID + " td{padding: 0.5em;}"+

            "#" + SUPERJUMP_TABLE_ID + " .key-span{font-family:monospace; cursor:default; padding-right: 0.1em; font-size: 200%}"+

            "#" + SUPERJUMP_TABLE_ID + " span{vertical-align:middle;}");

            initAccessKeyListeners();

        } );

} )();

// </nowiki>

Videos

Youtube | Vimeo | Bing

Websites

Google | Yahoo | Bing

Encyclopedia

Google | Yahoo | Bing

Facebook