User:Krinkle/preserveQueryParameters.js

From Meta, a Wikimedia project coordination wiki

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.
// Author: Krinkle, 2021 <https://meta.wikimedia.org/wiki/User:Krinkle/preserveQueryParameters.js>
// Author: Nirmos, 2019 <https://sv.wikipedia.org/wiki/User:Nirmos/PersistentQueryParameters.js>
'use strict';
$.when( mw.loader.using( [ 'mediawiki.util' ] ), $.ready ).then( function preserveQueryParameters() {
    const params = [];
    for ( let p of [ 'uselang', 'useskin' ] ) {
        const val = mw.util.getParamValue( p );
        if ( val !== null ) params.push( [ p, val ] );
    }

    function transform( href ) {
        const url = new URL( href );
        for ( let [ p, val ] of params ) {
            if ( !url.searchParams.has( p ) ) url.searchParams.set( p, val );
        }
        return url.toString();
    }

    if ( params.length ) {
        // This is a "delegated" handler, bound to only the body, not every <a> element.
        // This is 1000x faster and also works for links created later (e.g. live preview)
        $( document.body ).on( 'click', 'a[href]', ( e ) => {
            e.currentTarget.href = transform( e.currentTarget.href );
        } );
        $( 'form' ).each( ( i, el ) => {
            if ( el.action && !el.action.includes( '#' ) ) {
                // Works for both "get" and "post" forms. https://stackoverflow.com/a/732384/319266
                for ( let [ p, val ] of params ) {
                    el.append( Object.assign( document.createElement( 'input' ), {
                        type: 'hidden', name: p, value: val
                    } ) );
                }
            }
        } );
    }
} );