Merge "Remove double escaping of group member name on Special:ListUsers"
[lhc/web/wiklou.git] / includes / resourceloader / ResourceLoaderModule.php
index 0996a33..3f95ce6 100644 (file)
@@ -26,7 +26,6 @@
  * Abstraction for resource loader modules, with name registration and maxage functionality.
  */
 abstract class ResourceLoaderModule {
-
        # Type of resource
        const TYPE_SCRIPTS = 'scripts';
        const TYPE_STYLES = 'styles';
@@ -65,6 +64,11 @@ abstract class ResourceLoaderModule {
        // In-object cache for message blob mtime
        protected $msgBlobMtime = array();
 
+       /**
+        * @var Config
+        */
+       protected $config;
+
        /* Methods */
 
        /**
@@ -130,6 +134,37 @@ abstract class ResourceLoaderModule {
                return '';
        }
 
+       /**
+        * Takes named templates by the module and returns an array mapping.
+        *
+        * @return array of templates mapping template alias to content
+        */
+       public function getTemplates() {
+               // Stub, override expected.
+               return array();
+       }
+
+       /**
+        * @return Config
+        * @since 1.24
+        */
+       public function getConfig() {
+               if ( $this->config === null ) {
+                       // Ugh, fall back to default
+                       $this->config = ConfigFactory::getDefaultInstance()->makeConfig( 'main' );
+               }
+
+               return $this->config;
+       }
+
+       /**
+        * @param Config $config
+        * @since 1.24
+        */
+       public function setConfig( Config $config ) {
+               $this->config = $config;
+       }
+
        /**
         * Get the URL or URLs to load for this module's JS in debug mode.
         * The default behavior is to return a load.php?only=scripts URL for
@@ -145,17 +180,17 @@ abstract class ResourceLoaderModule {
         * @return array Array of URLs
         */
        public function getScriptURLsForDebug( ResourceLoaderContext $context ) {
-               $url = ResourceLoader::makeLoaderURL(
-                       array( $this->getName() ),
-                       $context->getLanguage(),
-                       $context->getSkin(),
-                       $context->getUser(),
-                       $context->getVersion(),
-                       true, // debug
-                       'scripts', // only
-                       $context->getRequest()->getBool( 'printable' ),
-                       $context->getRequest()->getBool( 'handheld' )
+               $resourceLoader = $context->getResourceLoader();
+               $derivative = new DerivativeResourceLoaderContext( $context );
+               $derivative->setModules( array( $this->getName() ) );
+               $derivative->setOnly( 'scripts' );
+               $derivative->setDebug( true );
+
+               $url = $resourceLoader->createLoaderURL(
+                       $this->getSource(),
+                       $derivative
                );
+
                return array( $url );
        }
 
@@ -189,20 +224,20 @@ abstract class ResourceLoaderModule {
         * load the files directly. See also getScriptURLsForDebug()
         *
         * @param ResourceLoaderContext $context
-        * @return array array( mediaType => array( URL1, URL2, ... ), ... )
+        * @return array Array( mediaType => array( URL1, URL2, ... ), ... )
         */
        public function getStyleURLsForDebug( ResourceLoaderContext $context ) {
-               $url = ResourceLoader::makeLoaderURL(
-                       array( $this->getName() ),
-                       $context->getLanguage(),
-                       $context->getSkin(),
-                       $context->getUser(),
-                       $context->getVersion(),
-                       true, // debug
-                       'styles', // only
-                       $context->getRequest()->getBool( 'printable' ),
-                       $context->getRequest()->getBool( 'handheld' )
+               $resourceLoader = $context->getResourceLoader();
+               $derivative = new DerivativeResourceLoaderContext( $context );
+               $derivative->setModules( array( $this->getName() ) );
+               $derivative->setOnly( 'styles' );
+               $derivative->setDebug( true );
+
+               $url = $resourceLoader->createLoaderURL(
+                       $this->getSource(),
+                       $derivative
                );
+
                return array( 'all' => array( $url ) );
        }
 
@@ -294,6 +329,24 @@ abstract class ResourceLoaderModule {
                return $this->targets;
        }
 
+       /**
+        * Get the skip function.
+        *
+        * Modules that provide fallback functionality can provide a "skip function". This
+        * function, if provided, will be passed along to the module registry on the client.
+        * When this module is loaded (either directly or as a dependency of another module),
+        * then this function is executed first. If the function returns true, the module will
+        * instantly be considered "ready" without requesting the associated module resources.
+        *
+        * The value returned here must be valid javascript for execution in a private function.
+        * It must not contain the "function () {" and "}" wrapper though.
+        *
+        * @return string|null A JavaScript function body returning a boolean value, or null
+        */
+       public function getSkipFunction() {
+               return null;
+       }
+
        /**
         * Get the files this module depends on indirectly for a given skin.
         * Currently these are only image files referenced by the module's CSS.
@@ -335,12 +388,12 @@ abstract class ResourceLoaderModule {
         * Get the last modification timestamp of the message blob for this
         * module in a given language.
         * @param string $lang Language code
-        * @return int UNIX timestamp, or 0 if the module doesn't have messages
+        * @return int UNIX timestamp
         */
        public function getMsgBlobMtime( $lang ) {
                if ( !isset( $this->msgBlobMtime[$lang] ) ) {
                        if ( !count( $this->getMessages() ) ) {
-                               return 0;
+                               return 1;
                        }
 
                        $dbr = wfGetDB( DB_SLAVE );
@@ -363,7 +416,7 @@ abstract class ResourceLoaderModule {
         * Set a preloaded message blob last modification timestamp. Used so we
         * can load this information for all modules at once.
         * @param string $lang Language code
-        * @param int $mtime UNIX timestamp or 0 if there is no such blob
+        * @param int $mtime UNIX timestamp
         */
        public function setMsgBlobMtime( $lang, $mtime ) {
                $this->msgBlobMtime[$lang] = $mtime;
@@ -390,7 +443,6 @@ abstract class ResourceLoaderModule {
         * @return int UNIX timestamp
         */
        public function getModifiedTime( ResourceLoaderContext $context ) {
-               // 0 would mean now
                return 1;
        }
 
@@ -398,13 +450,12 @@ abstract class ResourceLoaderModule {
         * Helper method for calculating when the module's hash (if it has one) changed.
         *
         * @param ResourceLoaderContext $context
-        * @return int UNIX timestamp or 0 if no hash was provided
-        *  by getModifiedHash()
+        * @return int UNIX timestamp
         */
        public function getHashMtime( ResourceLoaderContext $context ) {
                $hash = $this->getModifiedHash( $context );
                if ( !is_string( $hash ) ) {
-                       return 0;
+                       return 1;
                }
 
                $cache = wfGetCache( CACHE_ANYTHING );
@@ -416,7 +467,7 @@ abstract class ResourceLoaderModule {
                        return $data['timestamp'];
                }
 
-               $timestamp = wfTimestamp();
+               $timestamp = time();
                $cache->set( $key, array(
                        'hash' => $hash,
                        'timestamp' => $timestamp,
@@ -443,15 +494,15 @@ abstract class ResourceLoaderModule {
         *
         * @since 1.23
         *
-        * @return int UNIX timestamp or 0 if no definition summary was provided
-        *  by getDefinitionSummary()
+        * @param ResourceLoaderContext $context
+        * @return int UNIX timestamp
         */
        public function getDefinitionMtime( ResourceLoaderContext $context ) {
                wfProfileIn( __METHOD__ );
                $summary = $this->getDefinitionSummary( $context );
                if ( $summary === null ) {
                        wfProfileOut( __METHOD__ );
-                       return 0;
+                       return 1;
                }
 
                $hash = md5( json_encode( $summary ) );
@@ -476,7 +527,8 @@ abstract class ResourceLoaderModule {
                        return $data;
                }
 
-               wfDebugLog( 'resourceloader', __METHOD__ . ": New definition hash for module {$this->getName()} in context {$context->getHash()}: $hash." );
+               wfDebugLog( 'resourceloader', __METHOD__ . ": New definition hash for module "
+                       . "{$this->getName()} in context {$context->getHash()}: $hash." );
 
                $timestamp = time();
                $cache->set( $key, $timestamp );
@@ -509,6 +561,7 @@ abstract class ResourceLoaderModule {
         *
         * @since 1.23
         *
+        * @param ResourceLoaderContext $context
         * @return array|null
         */
        public function getDefinitionSummary( ResourceLoaderContext $context ) {
@@ -530,7 +583,7 @@ abstract class ResourceLoaderModule {
                return false;
        }
 
-       /** @var JSParser lazy-initialized; use self::javaScriptParser() */
+       /** @var JSParser Lazy-initialized; use self::javaScriptParser() */
        private static $jsParser;
        private static $parseCacheVersion = 1;
 
@@ -543,8 +596,7 @@ abstract class ResourceLoaderModule {
         * @return string JS with the original, or a replacement error
         */
        protected function validateScriptFile( $fileName, $contents ) {
-               global $wgResourceLoaderValidateJS;
-               if ( $wgResourceLoaderValidateJS ) {
+               if ( $this->getConfig()->get( 'ResourceLoaderValidateJS' ) ) {
                        // Try for cache hit
                        // Use CACHE_ANYTHING since filtering is very slow compared to DB queries
                        $key = wfMemcKey( 'resourceloader', 'jsparse', self::$parseCacheVersion, md5( $contents ) );
@@ -585,16 +637,12 @@ abstract class ResourceLoaderModule {
         * Safe version of filemtime(), which doesn't throw a PHP warning if the file doesn't exist
         * but returns 1 instead.
         * @param string $filename File name
-        * @return int UNIX timestamp, or 1 if the file doesn't exist
+        * @return int UNIX timestamp
         */
        protected static function safeFilemtime( $filename ) {
-               if ( file_exists( $filename ) ) {
-                       return filemtime( $filename );
-               } else {
-                       // We only ever map this function on an array if we're gonna call max() after,
-                       // so return our standard minimum timestamps here. This is 1, not 0, because
-                       // wfTimestamp(0) == NOW
+               if ( !file_exists( $filename ) ) {
                        return 1;
                }
+               return filemtime( $filename );
        }
 }