Merge "Update list item newline handling to follow Parsoid's model"
[lhc/web/wiklou.git] / includes / resourceloader / ResourceLoader.php
index eac6a02..7765714 100644 (file)
  *    https://www.mediawiki.org/wiki/ResourceLoader
  */
 class ResourceLoader {
-
-       /**
-        * @var int
-        */
+       /** @var int */
        protected static $filterCacheVersion = 7;
-       /**
-        * @var array
-        */
+
+       /** @var array */
        protected static $requiredSourceProperties = array( 'loadScript' );
 
-       /**
-        * @var array Module name/ResourceLoaderModule object pairs
-        */
+       /** @var array Module name/ResourceLoaderModule object pairs */
        protected $modules = array();
 
-       /**
-        * @var array Associative array mapping module name to info associative array
-        */
+       /** @var array Associative array mapping module name to info associative array */
        protected $moduleInfos = array();
 
        /**
@@ -55,14 +47,10 @@ class ResourceLoader {
         */
        protected $testModuleNames = array();
 
-       /**
-        * @var array e.g. array( 'source-id' => array( 'loadScript' => 'http://.../load.php' ) )
-        */
+       /** @var array e.g. array( 'source-id' => array( 'loadScript' => 'http://.../load.php' ) ) */
        protected $sources = array();
 
-       /**
-        * @var bool
-        */
+       /** @var bool */
        protected $hasErrors = false;
 
        /**
@@ -225,7 +213,10 @@ class ResourceLoader {
                wfProfileIn( __METHOD__ );
 
                // Add 'local' source first
-               $this->addSource( 'local', array( 'loadScript' => $wgLoadScript, 'apiScript' => wfScript( 'api' ) ) );
+               $this->addSource(
+                       'local',
+                       array( 'loadScript' => $wgLoadScript, 'apiScript' => wfScript( 'api' ) )
+               );
 
                // Add other sources
                $this->addSource( $wgResourceLoaderSources );
@@ -250,10 +241,10 @@ class ResourceLoader {
         * @param array $info Module info array. For backwards compatibility with 1.17alpha,
         *   this may also be a ResourceLoaderModule object. Optional when using
         *   multiple-registration calling style.
-        * @throws MWException: If a duplicate module registration is attempted
-        * @throws MWException: If a module name contains illegal characters (pipes or commas)
-        * @throws MWException: If something other than a ResourceLoaderModule is being registered
-        * @return boolean False if there were any errors, in which case one or more modules were
+        * @throws MWException If a duplicate module registration is attempted
+        * @throws MWException If a module name contains illegal characters (pipes or commas)
+        * @throws MWException If something other than a ResourceLoaderModule is being registered
+        * @return bool False if there were any errors, in which case one or more modules were
         *   not registered
         */
        public function register( $name, $info = null ) {
@@ -275,7 +266,8 @@ class ResourceLoader {
                        // Check $name for validity
                        if ( !self::isValidModuleName( $name ) ) {
                                wfProfileOut( __METHOD__ );
-                               throw new MWException( "ResourceLoader module name '$name' is invalid, see ResourceLoader::isValidModuleName()" );
+                               throw new MWException( "ResourceLoader module name '$name' is invalid, "
+                                       . "see ResourceLoader::isValidModuleName()" );
                        }
 
                        // Attach module
@@ -304,7 +296,9 @@ class ResourceLoader {
                global $IP, $wgEnableJavaScriptTest;
 
                if ( $wgEnableJavaScriptTest !== true ) {
-                       throw new MWException( 'Attempt to register JavaScript test modules but <code>$wgEnableJavaScriptTest</code> is false. Edit your <code>LocalSettings.php</code> to enable it.' );
+                       throw new MWException( 'Attempt to register JavaScript test modules '
+                               . 'but <code>$wgEnableJavaScriptTest</code> is false. '
+                               . 'Edit your <code>LocalSettings.php</code> to enable it.' );
                }
 
                wfProfileIn( __METHOD__ );
@@ -325,7 +319,8 @@ class ResourceLoader {
                        $module['dependencies'][] = 'test.mediawiki.qunit.testrunner';
                }
 
-               $testModules['qunit'] = ( include "$IP/tests/qunit/QUnitTestResources.php" ) + $testModules['qunit'];
+               $testModules['qunit'] =
+                       ( include "$IP/tests/qunit/QUnitTestResources.php" ) + $testModules['qunit'];
 
                foreach ( $testModules as $id => $names ) {
                        // Register test modules
@@ -392,13 +387,15 @@ class ResourceLoader {
         *
         * @param string $framework Get only the test module names for one
         *   particular framework (optional)
-        * @return Array
+        * @return array
         */
        public function getTestModuleNames( $framework = 'all' ) {
-               /// @todo api siteinfo prop testmodulenames modulenames
+               /** @todo api siteinfo prop testmodulenames modulenames */
                if ( $framework == 'all' ) {
                        return $this->testModuleNames;
-               } elseif ( isset( $this->testModuleNames[$framework] ) && is_array( $this->testModuleNames[$framework] ) ) {
+               } elseif ( isset( $this->testModuleNames[$framework] )
+                       && is_array( $this->testModuleNames[$framework] )
+               ) {
                        return $this->testModuleNames[$framework];
                } else {
                        return array();
@@ -622,7 +619,7 @@ class ResourceLoader {
         * If there's an If-Modified-Since header, respond with a 304 appropriately
         * and clear out the output buffer. If the client cache is too old then do nothing.
         *
-        * @param $context ResourceLoaderContext
+        * @param ResourceLoaderContext $context
         * @param string $mtime The TS_MW timestamp to check the header against
         * @return bool True if 304 header sent and output handled
         */
@@ -721,8 +718,8 @@ class ResourceLoader {
        /**
         * Handle exception display.
         *
-        * @param Exception $e to be shown to the user
-        * @return string sanitized text that can be returned to the user
+        * @param Exception $e Exception to be shown to the user
+        * @return string Sanitized text that can be returned to the user
         */
        public static function formatException( $e ) {
                global $wgShowExceptionDetails;
@@ -737,7 +734,7 @@ class ResourceLoader {
        /**
         * Generate code for a response.
         *
-        * @param $context ResourceLoaderContext Context in which to generate a response
+        * @param ResourceLoaderContext $context Context in which to generate a response
         * @param array $modules List of module objects keyed by module name
         * @param array $missing List of requested module names that are unregistered (optional)
         * @return string Response data
@@ -763,7 +760,10 @@ class ResourceLoader {
                                $blobs = MessageBlobStore::get( $this, $modules, $context->getLanguage() );
                        } catch ( Exception $e ) {
                                MWExceptionHandler::logException( $e );
-                               wfDebugLog( 'resourceloader', __METHOD__ . ": pre-fetching blobs from MessageBlobStore failed: $e" );
+                               wfDebugLog(
+                                       'resourceloader',
+                                       __METHOD__ . ": pre-fetching blobs from MessageBlobStore failed: $e"
+                               );
                                $this->hasErrors = true;
                                // Add exception to the output as a comment
                                $exceptions .= self::formatException( $e );
@@ -795,9 +795,13 @@ class ResourceLoader {
                                                $scripts = $module->getScriptURLsForDebug( $context );
                                        } else {
                                                $scripts = $module->getScript( $context );
-                                               // rtrim() because there are usually a few line breaks after the last ';'.
-                                               // A new line at EOF, a new line added by ResourceLoaderFileModule::readScriptFiles, etc.
-                                               if ( is_string( $scripts ) && strlen( $scripts ) && substr( rtrim( $scripts ), -1 ) !== ';' ) {
+                                               // rtrim() because there are usually a few line breaks
+                                               // after the last ';'. A new line at EOF, a new line
+                                               // added by ResourceLoaderFileModule::readScriptFiles, etc.
+                                               if ( is_string( $scripts )
+                                                       && strlen( $scripts )
+                                                       && substr( rtrim( $scripts ), -1 ) !== ';'
+                                               ) {
                                                        // Append semicolon to prevent weird bugs caused by files not
                                                        // terminating their statements right (bug 27054)
                                                        $scripts .= ";\n";
@@ -810,7 +814,7 @@ class ResourceLoader {
                                        // Don't create empty stylesheets like array( '' => '' ) for modules
                                        // that don't *have* any stylesheets (bug 38024).
                                        $stylePairs = $module->getStyles( $context );
-                                       if ( count ( $stylePairs ) ) {
+                                       if ( count( $stylePairs ) ) {
                                                // If we are in debug mode without &only= set, we'll want to return an array of URLs
                                                // See comment near shouldIncludeScripts() for more details
                                                if ( $context->getDebug() && !$context->getOnly() && $module->supportsURLLoading() ) {
@@ -904,6 +908,12 @@ class ResourceLoader {
                        if ( count( $states ) ) {
                                $out .= self::makeLoaderStateScript( $states );
                        }
+               } else {
+                       if ( count( $states ) ) {
+                               $exceptions .= self::makeComment(
+                                       'Problematic modules: ' . FormatJson::encode( $states, ResourceLoader::inDebugMode() )
+                               );
+                       }
                }
 
                if ( !$context->getDebug() ) {
@@ -978,7 +988,7 @@ class ResourceLoader {
         * @param array $stylePairs Array keyed by media type containing (arrays of) CSS strings
         * @return array
         */
-       private static function makeCombinedStyles( array $stylePairs ) {
+       public static function makeCombinedStyles( array $stylePairs ) {
                $out = array();
                foreach ( $stylePairs as $media => $styles ) {
                        // ResourceLoaderFileModule::getStyle can return the styles
@@ -1016,7 +1026,7 @@ class ResourceLoader {
         *         Set the state of modules with the given names to the given states
         *
         * @param string $name
-        * @param $state
+        * @param string $state
         * @return string
         */
        public static function makeLoaderStateScript( $name, $state = null ) {
@@ -1049,7 +1059,9 @@ class ResourceLoader {
         * @param string $script JavaScript code
         * @return string
         */
-       public static function makeCustomLoaderScript( $name, $version, $dependencies, $group, $source, $script ) {
+       public static function makeCustomLoaderScript( $name, $version, $dependencies,
+               $group, $source, $script
+       ) {
                $script = str_replace( "\n", "\n\t", trim( $script ) );
                return Xml::encodeJsCall(
                        "( function ( name, version, dependencies, group, source ) {\n\t$script\n} )",
@@ -1111,8 +1123,8 @@ class ResourceLoader {
         *   - ResourceLoader::makeLoaderSourcesScript( array( $id1 => $props1, $id2 => $props2, ... ) );
         *       Register sources with the given IDs and properties.
         *
-        * @param string $id source ID
-        * @param array $properties source properties (see addSource())
+        * @param string $id Source ID
+        * @param array $properties Source properties (see addSource())
         * @return string
         */
        public static function makeLoaderSourcesScript( $id, $properties = null ) {
@@ -1200,7 +1212,7 @@ class ResourceLoader {
 
        /**
         * Build a load.php URL
-        * @param array $modules of module names (strings)
+        * @param array $modules Array of module names (strings)
         * @param string $lang Language code
         * @param string $skin Skin name
         * @param string|null $user User name. If null, the &user= parameter is omitted
@@ -1212,9 +1224,12 @@ class ResourceLoader {
         * @param array $extraQuery Extra query parameters to add
         * @return string URL to load.php. May be protocol-relative (if $wgLoadScript is procol-relative)
         */
-       public static function makeLoaderURL( $modules, $lang, $skin, $user = null, $version = null, $debug = false, $only = null,
-                       $printable = false, $handheld = false, $extraQuery = array() ) {
+       public static function makeLoaderURL( $modules, $lang, $skin, $user = null,
+               $version = null, $debug = false, $only = null, $printable = false,
+               $handheld = false, $extraQuery = array()
+       ) {
                global $wgLoadScript;
+
                $query = self::makeLoaderQuery( $modules, $lang, $skin, $user, $version, $debug,
                        $only, $printable, $handheld, $extraQuery
                );
@@ -1241,8 +1256,10 @@ class ResourceLoader {
         *
         * @return array
         */
-       public static function makeLoaderQuery( $modules, $lang, $skin, $user = null, $version = null, $debug = false, $only = null,
-                       $printable = false, $handheld = false, $extraQuery = array() ) {
+       public static function makeLoaderQuery( $modules, $lang, $skin, $user = null,
+               $version = null, $debug = false, $only = null, $printable = false,
+               $handheld = false, $extraQuery = array()
+       ) {
                $query = array(
                        'modules' => self::makePackedModulesString( $modules ),
                        'lang' => $lang,
@@ -1314,17 +1331,14 @@ class ResourceLoader {
         * Get global LESS variables.
         *
         * $since 1.22
-        * @return array: Map of variable names to string CSS values.
+        * @return array Map of variable names to string CSS values.
         */
        public static function getLESSVars() {
                global $wgResourceLoaderLESSVars;
 
-               static $lessVars = null;
-               if ( $lessVars === null ) {
-                       $lessVars = $wgResourceLoaderLESSVars;
-                       // Sort by key to ensure consistent hashing for cache lookups.
-                       ksort( $lessVars );
-               }
+               $lessVars = $wgResourceLoaderLESSVars;
+               // Sort by key to ensure consistent hashing for cache lookups.
+               ksort( $lessVars );
                return $lessVars;
        }
 }