wikimedia/mediawiki-core

View on GitHub
resources/src/jquery.spinner/spinner.js

Summary

Maintainability
A
0 mins
Test Coverage
/**
 * jQuery Spinner
 *
 * Simple jQuery plugin to create, inject and remove spinners.
 */
( function () {

    /**
     * Default options for new spinners,
     * stored outside the function to share between calls.
     *
     * @type {jQueryPlugins~SpinnerOpts}
     */
    var defaults = {
        id: undefined,
        size: 'small',
        type: 'inline'
    };

    /**
     * @typedef {Object} jQueryPlugins~SpinnerOpts Options for {@link jQueryPlugins.injectSpinner}.
     * @property {string} [id] If given, spinner will be given an id of "mw-spinner-{id}".
     * @property {'small'|'large'} [size='small'] 'small' or 'large' for a 20-pixel or 32-pixel spinner.
     * @property {'inline'|'block'} [type='inline'] 'inline' or 'block'. Inline creates an inline-block with
     *   width and height equal to spinner size. Block is a block-level element with width 100%,
     *   height equal to spinner size.
     */

    $.extend( {
        /**
         * Create a spinner element
         *
         * The argument is an object with options used to construct the spinner (see below).
         *
         * It is a good practice to keep a reference to the created spinner to be able to remove it
         * later. Alternatively, one can use the 'id' option and #removeSpinner (but make sure to choose
         * an id that's unlikely to cause conflicts, e.g. with extensions, gadgets or user scripts).
         *
         * CSS classes used:
         *
         * - .mw-spinner for every spinner
         * - .mw-spinner-small / .mw-spinner-large for size
         * - .mw-spinner-block / .mw-spinner-inline for display types
         *
         * Example:
         *
         *     // Create a large spinner reserving all available horizontal space.
         *     var $spinner = $.createSpinner( { size: 'large', type: 'block' } );
         *     // Insert above page content.
         *     $( '#mw-content-text' ).prepend( $spinner );
         *
         *     // Place a small inline spinner next to the "Save" button
         *     var $spinner = $.createSpinner( { size: 'small', type: 'inline' } );
         *     // Alternatively, just `$.createSpinner();` as these are the default options.
         *     $( '#wpSave' ).after( $spinner );
         *
         *     // The following two are equivalent:
         *     $.createSpinner( 'magic' );
         *     $.createSpinner( { id: 'magic' } );
         *
         * @ignore
         * @static
         * @inheritable
         * @param {jQueryPlugins~SpinnerOpts|string} [opts] Options. If a string is given, it will be treated as the value
         *   of the {@link jQueryPlugins~SpinnerOpts#id} option.
         * @return {jQuery}
         */
        createSpinner: function ( opts ) {
            var i, $spinner, $container;

            if ( typeof opts === 'string' ) {
                opts = {
                    id: opts
                };
            }

            opts = $.extend( {}, defaults, opts );

            $spinner = $( '<div>' ).addClass( 'mw-spinner' );
            if ( opts.id !== undefined ) {
                $spinner.attr( 'id', 'mw-spinner-' + opts.id );
            }

            $spinner
                .addClass( opts.size === 'large' ? 'mw-spinner-large' : 'mw-spinner-small' )
                .addClass( opts.type === 'block' ? 'mw-spinner-block' : 'mw-spinner-inline' );

            $container = $( '<div>' ).addClass( 'mw-spinner-container' ).appendTo( $spinner );
            for ( i = 0; i < 12; i++ ) {
                $container.append( $( '<div>' ) );
            }

            return $spinner;
        },

        /**
         * Remove a spinner element
         *
         * @ignore
         * @inheritable
         * @param {string} id Id of the spinner, as passed to #createSpinner
         * @return {jQuery} The (now detached) spinner element
         */
        removeSpinner: function ( id ) {
            return $( '#mw-spinner-' + id ).remove();
        }
    } );

    /**
     * Inject a spinner after each element in the collection.
     * Provided by the jquery.spinner ResourceLoader module.
     *
     * Inserts spinner as siblings (not children) of the target elements.
     * Collection contents remain unchanged.
     *
     * @example
     * mw.loader.using( 'jquery.spinner' ).then( () => {
     *       $( '#bodyContent' ).injectSpinner();
     * } );
     * @memberof jQueryPlugins
     * @method injectSpinner
     * @param {jQueryPlugins~SpinnerOpts|string} [opts] Options. If a string is given, it will be treated as the value
     *   of the {@link jQueryPlugins~SpinnerOpts#id} option.
     * @return {jQuery}
     */
    $.fn.injectSpinner = function ( opts ) {
        return this.after( $.createSpinner( opts ) );
    };

    /**
     * @class jQuery
     * @mixes jQuery.plugin.spinner
     */

}() );