mediawiki.js: Correct a typo in documentation
[lhc/web/wiklou.git] / resources / src / mediawiki / mediawiki.js
index 9d799db..8d42b98 100644 (file)
                },
 
                /**
-                * Add (does not replace) parameters for `N$` placeholder values.
+                * Add (does not replace) parameters for `$N` placeholder values.
                 *
                 * @param {Array} parameters
                 * @chainable
                                 */
                                jobs = [],
 
-                               // Selector cache for the marker element. Use getMarker() to get/use the marker!
-                               $marker = null,
+                               // For getMarker()
+                               marker = null,
 
-                               // For #addEmbeddedCSS
+                               // For addEmbeddedCSS()
                                cssBuffer = '',
                                cssBufferTimer = null,
-                               cssCallbacks = $.Callbacks();
+                               cssCallbacks = $.Callbacks(),
+                               isIE9 = document.documentMode === 9;
 
                        function getMarker() {
-                               if ( !$marker ) {
+                               if ( !marker ) {
                                        // Cache
-                                       $marker = $( 'meta[name="ResourceLoaderDynamicStyles"]' );
-                                       if ( !$marker.length ) {
-                                               mw.log( 'No <meta name="ResourceLoaderDynamicStyles"> found, inserting dynamically' );
-                                               $marker = $( '<meta>' ).attr( 'name', 'ResourceLoaderDynamicStyles' ).appendTo( 'head' );
+                                       marker = document.querySelector( 'meta[name="ResourceLoaderDynamicStyles"]' );
+                                       if ( !marker ) {
+                                               mw.log( 'Create <meta name="ResourceLoaderDynamicStyles"> dynamically' );
+                                               marker = $( '<meta>' ).attr( 'name', 'ResourceLoaderDynamicStyles' ).appendTo( 'head' )[ 0 ];
                                        }
                                }
-                               return $marker;
+                               return marker;
                        }
 
                        /**
                         *
                         * @private
                         * @param {string} text CSS text
-                        * @param {HTMLElement|jQuery} [nextnode=document.head] The element where the style tag
+                        * @param {Node} [nextNode] The element where the style tag
                         *  should be inserted before
                         * @return {HTMLElement} Reference to the created style element
                         */
-                       function newStyleTag( text, nextnode ) {
+                       function newStyleTag( text, nextNode ) {
                                var s = document.createElement( 'style' );
-                               // Support: IE
-                               // Must attach to document before setting cssText (bug 33305)
-                               if ( nextnode ) {
-                                       $( nextnode ).before( s );
+
+                               s.appendChild( document.createTextNode( text ) );
+                               if ( nextNode && nextNode.parentNode ) {
+                                       nextNode.parentNode.insertBefore( s, nextNode );
                                } else {
                                        document.getElementsByTagName( 'head' )[ 0 ].appendChild( s );
                                }
-                               if ( s.styleSheet ) {
-                                       // Support: IE6-10
-                                       // Old IE ignores appended text nodes, access stylesheet directly.
-                                       s.styleSheet.cssText = text;
-                               } else {
-                                       // Standard behaviour
-                                       s.appendChild( document.createTextNode( text ) );
-                               }
+
                                return s;
                        }
 
                         * @param {Function} [callback]
                         */
                        function addEmbeddedCSS( cssText, callback ) {
-                               var $style, styleEl, newCssText;
+                               var $style, styleEl;
 
                                function fireCallbacks() {
                                        var oldCallbacks = cssCallbacks;
                                        cssBuffer = '';
                                }
 
-                               // By default, always create a new <style>. Appending text to a <style>
-                               // tag is bad as it means the contents have to be re-parsed (bug 45810).
+                               // By default, always create a new <style>. Appending text to a <style> tag is
+                               // is a performance anti-pattern as it requires CSS to be reparsed (T47810).
                                //
-                               // Except, of course, in IE 9 and below. In there we default to re-using and
-                               // appending to a <style> tag due to the IE stylesheet limit (bug 31676).
-                               if ( 'documentMode' in document && document.documentMode <= 9 ) {
-
-                                       $style = getMarker().prev();
-                                       // Verify that the element before the marker actually is a
-                                       // <style> tag and one that came from ResourceLoader
-                                       // (not some other style tag or even a `<meta>` or `<script>`).
+                               // Support: IE 6-9
+                               // Try to re-use existing <style> tags due to the IE stylesheet limit (T33676).
+                               if ( isIE9 ) {
+                                       $style = $( getMarker() ).prev();
+                                       // Verify that the element before the marker actually is a <style> tag created
+                                       // by mw.loader (not some other style tag, or e.g. a <meta> tag).
                                        if ( $style.data( 'ResourceLoaderDynamicStyleTag' ) ) {
-                                               // There's already a dynamic <style> tag present and
-                                               // we are able to append more to it.
-                                               styleEl = $style.get( 0 );
-                                               // Support: IE6-10
-                                               if ( styleEl.styleSheet ) {
-                                                       try {
-                                                               // Support: IE9
-                                                               // We can't do styleSheet.cssText += cssText, since IE9 mangles this property on
-                                                               // write, dropping @media queries from the CSS text. If we read it and used its
-                                                               // value, we would accidentally apply @media-specific styles to all media. (T108727)
-                                                               if ( document.documentMode === 9 ) {
-                                                                       newCssText = $style.data( 'ResourceLoaderDynamicStyleTag' ) + cssText;
-                                                                       styleEl.styleSheet.cssText = newCssText;
-                                                                       $style.data( 'ResourceLoaderDynamicStyleTag', newCssText );
-                                                               } else {
-                                                                       styleEl.styleSheet.cssText += cssText;
-                                                               }
-                                                       } catch ( e ) {
-                                                               mw.track( 'resourceloader.exception', { exception: e, source: 'stylesheet' } );
-                                                       }
-                                               } else {
-                                                       styleEl.appendChild( document.createTextNode( cssText ) );
-                                               }
+                                               styleEl = $style[ 0 ];
+                                               styleEl.appendChild( document.createTextNode( cssText ) );
                                                fireCallbacks();
                                                return;
                                        }
+                                       // Else: No existing tag to reuse. Continue below and create the first one.
                                }
 
                                $style = $( newStyleTag( cssText, getMarker() ) );
 
-                               if ( document.documentMode === 9 ) {
-                                       // Support: IE9
-                                       // Preserve original CSS text because IE9 mangles it on write
-                                       $style.data( 'ResourceLoaderDynamicStyleTag', cssText );
-                               } else {
+                               if ( isIE9 ) {
                                        $style.data( 'ResourceLoaderDynamicStyleTag', true );
                                }
 
                         * @param {string} [moduleName] Name of currently executing module
                         * @return {jQuery.Promise}
                         */
-                       function queueModuleScript( src ) {
+                       function queueModuleScript( src, moduleName ) {
                                var r = $.Deferred();
 
                                pendingRequests.push( function () {
+                                       if ( moduleName && hasOwn.call( registry, moduleName ) ) {
+                                               window.require = mw.loader.require;
+                                               window.module = registry[ moduleName ].module;
+                                       }
                                        addScript( src ).always( function () {
+                                               // Clear environment
+                                               delete window.require;
+                                               delete window.module;
                                                r.resolve();
 
                                                // Start the next one (if any)
                         */
                        function addLink( media, url ) {
                                var el = document.createElement( 'link' );
-                               // Support: IE
-                               // Insert in document *before* setting href
-                               getMarker().before( el );
+
                                el.rel = 'stylesheet';
                                if ( media && media !== 'all' ) {
                                        el.media = media;
                                // If you end up here from an IE exception "SCRIPT: Invalid property value.",
                                // see #addEmbeddedCSS, bug 31676, and bug 47277 for details.
                                el.href = url;
+
+                               $( getMarker() ).before( el );
                        }
 
                        /**
                                                }
                                                return;
                                        }
-                                       // Validate input
-                                       if ( typeof module !== 'string' ) {
-                                               throw new Error( 'module must be a string, not a ' + typeof module );
-                                       }
                                        if ( hasOwn.call( registry, module ) ) {
                                                throw new Error( 'module already registered: ' + module );
                                        }
                                 * @param {Object} [templates] List of key/value pairs to be added to mw#templates.
                                 */
                                implement: function ( module, script, style, messages, templates ) {
-                                       // Validate input
-                                       if ( typeof module !== 'string' ) {
-                                               throw new Error( 'module must be of type string, not ' + typeof module );
-                                       }
-                                       if ( script && !$.isFunction( script ) && !$.isArray( script ) && typeof script !== 'string' ) {
-                                               throw new Error( 'script must be of type function, array, or script; not ' + typeof script );
-                                       }
-                                       if ( style && !$.isPlainObject( style ) ) {
-                                               throw new Error( 'style must be of type object, not ' + typeof style );
-                                       }
-                                       if ( messages && !$.isPlainObject( messages ) ) {
-                                               throw new Error( 'messages must be of type object, not a ' + typeof messages );
-                                       }
-                                       if ( templates && !$.isPlainObject( templates ) ) {
-                                               throw new Error( 'templates must be of type object, not a ' + typeof templates );
-                                       }
                                        // Automatically register module
                                        if ( !hasOwn.call( registry, module ) ) {
                                                mw.loader.register( module );
                                        // Allow calling with a single dependency as a string
                                        if ( typeof dependencies === 'string' ) {
                                                dependencies = [ dependencies ];
-                                       } else if ( !$.isArray( dependencies ) ) {
-                                               // Invalid input
-                                               throw new Error( 'Dependencies must be a string or an array' );
                                        }
 
                                        if ( ready ) {
                                load: function ( modules, type ) {
                                        var filtered, l;
 
-                                       // Validate input
-                                       if ( typeof modules !== 'object' && typeof modules !== 'string' ) {
-                                               throw new Error( 'modules must be a string or an array, not a ' + typeof modules );
-                                       }
                                        // Allow calling with a url or single dependency as a string
                                        if ( typeof modules === 'string' ) {
                                                // "https://example.org/x.js", "http://example.org/x.js", "//example.org/x.js", "/x.js"