Merge "Use Language::userTime in Preferences::datetimePreferences"
[lhc/web/wiklou.git] / includes / resourceloader / ResourceLoader.php
index 803afbf..3d5cc51 100644 (file)
@@ -72,6 +72,11 @@ class ResourceLoader {
         */
        protected $errors = array();
 
+       /**
+        * @var MessageBlobStore
+        */
+       protected $blobStore;
+
        /**
         * Load information stored in the database about modules.
         *
@@ -250,6 +255,7 @@ class ResourceLoader {
                        $this->registerTestModules();
                }
 
+               $this->setMessageBlobStore( new MessageBlobStore() );
        }
 
        /**
@@ -259,6 +265,14 @@ class ResourceLoader {
                return $this->config;
        }
 
+       /**
+        * @param MessageBlobStore $blobStore
+        * @since 1.25
+        */
+       public function setMessageBlobStore( MessageBlobStore $blobStore ) {
+               $this->blobStore = $blobStore;
+       }
+
        /**
         * Register a module with the ResourceLoader system.
         *
@@ -332,12 +346,9 @@ class ResourceLoader {
                                        }
 
                                        // Add new file paths, remapping them to refer to our directories and not use settings
-                                       // from the module we're modifying. These can come from the base definition or be defined
-                                       // for each module.
+                                       // from the module we're modifying, which come from the base definition.
                                        list( $localBasePath, $remoteBasePath ) =
                                                ResourceLoaderFileModule::extractBasePaths( $skinStyles );
-                                       list( $localBasePath, $remoteBasePath ) =
-                                               ResourceLoaderFileModule::extractBasePaths( $paths, $localBasePath, $remoteBasePath );
 
                                        foreach ( $paths as $path ) {
                                                $styleFiles[] = new ResourceLoaderFilePath( $path, $localBasePath, $remoteBasePath );
@@ -885,7 +896,7 @@ MESSAGE;
                // Pre-fetch blobs
                if ( $context->shouldIncludeMessages() ) {
                        try {
-                               $blobs = MessageBlobStore::getInstance()->get( $this, $modules, $context->getLanguage() );
+                               $blobs = $this->blobStore->get( $this, $modules, $context->getLanguage() );
                        } catch ( Exception $e ) {
                                MWExceptionHandler::logException( $e );
                                wfDebugLog(
@@ -1081,23 +1092,19 @@ MESSAGE;
                } elseif ( !is_array( $scripts ) ) {
                        throw new MWException( 'Invalid scripts error. Array of URLs or string of code expected.' );
                }
-
-               return Xml::encodeJsCall(
-                       'mw.loader.implement',
-                       array(
-                               $name,
-                               $scripts,
-                               // Force objects. mw.loader.implement requires them to be javascript objects.
-                               // Although these variables are associative arrays, which become javascript
-                               // objects through json_encode. In many cases they will be empty arrays, and
-                               // PHP/json_encode() consider empty arrays to be numerical arrays and
-                               // output javascript "[]" instead of "{}". This fixes that.
-                               (object)$styles,
-                               (object)$messages,
-                               (object)$templates,
-                       ),
-                       ResourceLoader::inDebugMode()
+               // mw.loader.implement requires 'styles', 'messages' and 'templates' to be objects (not
+               // arrays). json_encode considers empty arrays to be numerical and outputs "[]" instead
+               // of "{}". Force them to objects.
+               $module = array(
+                       $name,
+                       $scripts,
+                       (object) $styles,
+                       (object) $messages,
+                       (object) $templates,
                );
+               self::trimArray( $module );
+
+               return Xml::encodeJsCall( 'mw.loader.implement', $module, ResourceLoader::inDebugMode() );
        }
 
        /**
@@ -1204,20 +1211,33 @@ MESSAGE;
                );
        }
 
+       private static function isEmptyObject( stdClass $obj ) {
+               foreach ( $obj as $key => &$value ) {
+                       return false;
+               }
+               return true;
+       }
+
        /**
         * Remove empty values from the end of an array.
         *
         * Values considered empty:
         *
         * - null
-        * - empty array
+        * - array()
+        * - new XmlJsCode( '{}' )
+        * - new stdClass() // (object) array()
         *
         * @param Array $array
         */
        private static function trimArray( Array &$array ) {
                $i = count( $array );
                while ( $i-- ) {
-                       if ( $array[$i] === null || $array[$i] === array() ) {
+                       if ( $array[$i] === null
+                               || $array[$i] === array()
+                               || ( $array[$i] instanceof XmlJsCode && $array[$i]->value === '{}' )
+                               || ( $array[$i] instanceof stdClass && self::isEmptyObject( $array[$i] ) )
+                       ) {
                                unset( $array[$i] );
                        } else {
                                break;
@@ -1326,7 +1346,6 @@ MESSAGE;
         * Returns JS code which runs given JS code if the client-side framework is
         * present.
         *
-        * @deprecated since 1.25; use makeInlineScript instead
         * @param string $script JavaScript code
         * @return string
         */
@@ -1334,20 +1353,6 @@ MESSAGE;
                return "if(window.mw){\n" . trim( $script ) . "\n}";
        }
 
-       /**
-        * Construct an inline script tag with given JS code.
-        *
-        * The code will be wrapped in a closure, and it will be executed by ResourceLoader
-        * only if the client has adequate support for MediaWiki JavaScript code.
-        *
-        * @param string $script JavaScript code
-        * @return string HTML
-        */
-       public static function makeInlineScript( $script ) {
-               $js = 'var _mwq = _mwq || []; _mwq.push( function ( mw ) { ' . $script . ' } );';
-               return Html::inlineScript( $js );
-       }
-
        /**
         * Returns JS code which will set the MediaWiki configuration array to
         * the given value.