User:Enterprisey/user-script-helper.js

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.
$( function () {
    if( mw.config.get( "wgPageName" ) === "User:" + mw.config.get( "wgUserName" ) + "/common.js" ) {
        var ADVERT = " ([[User:Enterprisey/user-script-helper|user-script-helper]])";
        mw.loader.using( [ "mediawiki.api" ], function () {
            var api = new mw.Api();

            function getPageText( pageTitle ) {
                return api.get( {
                    prop: "revisions",
                    rvprop: "content",
                    rvslots: "main",
                    rvlimit: 1,
                    titles: mw.config.get( "wgPageName" ),
                    formatversion: 2
                } ).then( function ( data ) {
                    return data.query.pages[0].revisions[0].slots.main.content;
                } );
            }

            function editPageWithFunction( pageTitle, editSummary, textFunction ) {
                return getPageText( pageTitle ).then( function ( wikitext ) {
                    var newWikitext = textFunction( wikitext );
                    if( newWikitext === undefined ) {
                        throw new Error( "textFunction returned undefined; please return the wikitext" );
                    }

                    return api.postWithEditToken( {
                        action: "edit",
                        title: pageTitle,
                        summary: editSummary + ADVERT,
                        text: textFunction( wikitext )
                    } ).then( function ( result ) {
                        if( result.edit.result === "Success" ) {
                            mw.notify( "Done!" );
                        } else {
                            mw.notify( "Error!" );
                            console.error( result );
                        }
                        return result;
                    } );
                } );
            }

            function startDev () {
                var scriptName = document.getElementById( "user-script-helper-script-name" ).value;
                document.getElementById( "user-script-helper-start-dev" ).disabled = true;
                document.getElementById( "user-script-helper-start-dev" ).textContent = "Starting dev of " + scriptName + "...";
                editPageWithFunction( mw.config.get( "wgPageName" ), "Start dev of " + scriptName, function ( wikitext ) {
                    var importRegexSource = "(//\\s*)?importScript\\('User:" +
                        mw.config.get( "wgUserName" ) + "/" +
                        "(" + scriptName + ".js" + "|" + scriptName +
                        "-dev.js" + ")'\\).*?(\\n|$)";
                    var importRegex = new RegExp( importRegexSource, "gm" );
                    wikitext = wikitext.replace( importRegex, "" );
                    wikitext += "\nmw.loader.load('https://localhost:4443/" + scriptName + ".js');";
                    return wikitext;
                } ).then( function ( _ ) { document.location.reload( true ); } );
            }

            var container = $( "<div>" )
                .insertBefore( $( ".mw-parser-output" ).last() )
                .append(
                    "Script name (no extension): ",
                    $( "<input>", { "type": "text", "id": "user-script-helper-script-name", "placeholder": "reply-link" } )
                        .keydown( function ( event ) {
                            if( event.which === 13 ) {
                                startDev();
                                event.preventDefault();
                            }
                        } ),
                    $( "<button>", { "id": "user-script-helper-start-dev" } )
                        .text( "Start dev" )
                        .click( startDev )
                );

            getPageText( mw.config.get( "wgPageName" ) ).then( function ( wikitext ) {
                var LOCALHOST_LOADS = /\nmw\.loader\.load\('https:\/\/localhost:4443\/(.+?)\.js'\);/g;
                var loadMatch = LOCALHOST_LOADS.exec( wikitext );
                while( loadMatch ) {
                    container.append( $( "<button>" )
                        .text( "Stop dev of " + loadMatch[1] )
                        .click( ( function ( loadMatch ) {
                            var scriptName = loadMatch[1];
                            return function () {
                                $( this )
                                    .text( "Stopping dev of " + scriptName + "..." )
                                    .prop( "disabled", true );
                                editPageWithFunction( mw.config.get( "wgPageName" ), "Stop dev of " + scriptName, function ( currentWikitext ) {
                                    currentWikitext = currentWikitext.replace( loadMatch[0], "" );
                                    var scriptPage = "User:" + mw.config.get( "wgUserName" ) + "/" + scriptName + ".js";
                                    currentWikitext += "\nimportScript('" + scriptPage + "'); // Backlink: [[" + scriptPage + "]]";
                                    return currentWikitext;
                                } )
                                    .then( function ( _ ) { document.location.reload( true ); } );
                            };
                        } )( loadMatch ) ) );
                    loadMatch = LOCALHOST_LOADS.exec( wikitext );
                }
            } );
        } );
    }
} );