wikimedia/mediawiki-core

View on GitHub
resources/src/mediawiki.special.preferences.ooui/confirmClose.js

Summary

Maintainability
A
1 hr
Test Coverage
/*!
 * JavaScript for Special:Preferences: Enable save button and prevent the window being accidentally
 * closed when any form field is changed.
 */
( function () {
    $( function () {
        // Check if all of the form values are unchanged.
        // (This function could be changed to infuse and check OOUI widgets, but that would only make it
        // slower and more complicated. It works fine to treat them as HTML elements.)
        function isPrefsChanged() {
            // eslint-disable-next-line no-jquery/no-sizzle
            var $inputs = $( '#mw-prefs-form :input[name]' );

            for ( var index = 0; index < $inputs.length; index++ ) {
                var input = $inputs[ index ];
                var $input = $( input );

                // Different types of inputs have different methods for accessing defaults
                if ( $input.is( 'select' ) ) {
                    // <select> has the property defaultSelected for each option
                    for ( var optIndex = 0; optIndex < input.options.length; optIndex++ ) {
                        var opt = input.options[ optIndex ];
                        if ( opt.selected !== opt.defaultSelected ) {
                            return true;
                        }
                    }
                } else if ( $input.is( 'input' ) || $input.is( 'textarea' ) ) {
                    // <input> has defaultValue or defaultChecked
                    var inputType = input.type;
                    if ( inputType === 'radio' || inputType === 'checkbox' ) {
                        if ( input.checked !== input.defaultChecked ) {
                            return true;
                        }
                    } else if ( input.value !== input.defaultValue ) {
                        return true;
                    }
                }
            }

            return false;
        }

        var saveButton = OO.ui.infuse( $( '#prefcontrol' ) );

        // Disable the button to save preferences unless preferences have changed
        // Check if preferences have been changed before JS has finished loading
        saveButton.setDisabled( !isPrefsChanged() );
        // Attach capturing event handlers to the document, to catch events inside OOUI dropdowns:
        // * Use capture because OO.ui.SelectWidget also does, and it stops event propagation,
        //   so the event is not fired on descendant elements
        // * Attach to the document because the dropdowns are in the .oo-ui-defaultOverlay element
        //   (and it doesn't exist yet at this point, so we can't attach them to it)
        [ 'change', 'keyup', 'mouseup' ].forEach( function ( eventType ) {
            document.addEventListener( eventType, function () {
                // Make sure SelectWidget's event handlers run first
                setTimeout( function () {
                    saveButton.setDisabled( !isPrefsChanged() );
                } );
            }, true );
        } );

        // Prompt users if they try to leave the page without saving.
        var allowCloseWindow = mw.confirmCloseWindow( {
            test: isPrefsChanged
        } );
        $( '#mw-prefs-form' ).on( 'submit', allowCloseWindow.release );
    } );
}() );