* 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 bool */
+ protected static $debugMode = null;
+
+ /** @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();
/**
*/
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;
/**
*
* @param string $filter Name of filter to run
* @param string $data Text to filter, such as JavaScript or CSS text
+ * @param string $cacheReport Whether to include the cache key report
* @return string Filtered data, or a comment containing an error message
*/
- protected function filter( $filter, $data ) {
+ public function filter( $filter, $data, $cacheReport = true ) {
global $wgResourceLoaderMinifierStatementsOnOwnLine, $wgResourceLoaderMinifierMaxLineLength;
wfProfileIn( __METHOD__ );
$wgResourceLoaderMinifierStatementsOnOwnLine,
$wgResourceLoaderMinifierMaxLineLength
);
- $result .= "\n/* cache key: $key */";
+ if ( $cacheReport ) {
+ $result .= "\n/* cache key: $key */";
+ }
break;
case 'minify-css':
$result = CSSMin::minify( $data );
- $result .= "\n/* cache key: $key */";
+ if ( $cacheReport ) {
+ $result .= "\n/* cache key: $key */";
+ }
break;
}
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 );
// 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
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__ );
$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
* @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();
$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 );
$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";
// 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() ) {
* @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
* @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} )",
* Returns JS code which calls mw.loader.register with the given
* parameters. Has three calling conventions:
*
- * - ResourceLoader::makeLoaderRegisterScript( $name, $version, $dependencies, $group, $source ):
+ * - ResourceLoader::makeLoaderRegisterScript( $name, $version, $dependencies, $group, $source, $skip ):
* Register a single module.
*
* - ResourceLoader::makeLoaderRegisterScript( array( $name1, $name2 ) ):
* Register modules with the given names.
*
* - ResourceLoader::makeLoaderRegisterScript( array(
- * array( $name1, $version1, $dependencies1, $group1, $source1 ),
- * array( $name2, $version2, $dependencies1, $group2, $source2 ),
+ * array( $name1, $version1, $dependencies1, $group1, $source1, $skip1 ),
+ * array( $name2, $version2, $dependencies1, $group2, $source2, $skip2 ),
* ...
* ) ):
* Registers modules with the given names and parameters.
* @param array $dependencies List of module names on which this module depends
* @param string $group Group which the module is in
* @param string $source Source of the module, or 'local' if not foreign
+ * @param string $skip Script body of the skip function
* @return string
*/
public static function makeLoaderRegisterScript( $name, $version = null,
- $dependencies = null, $group = null, $source = null
+ $dependencies = null, $group = null, $source = null, $skip = null
) {
if ( is_array( $name ) ) {
return Xml::encodeJsCall(
$version = (int)$version > 1 ? (int)$version : 1;
return Xml::encodeJsCall(
'mw.loader.register',
- array( $name, $version, $dependencies, $group, $source ),
+ array( $name, $version, $dependencies, $group, $source, $skip ),
ResourceLoader::inDebugMode()
);
}
* @return bool
*/
public static function inDebugMode() {
- global $wgRequest, $wgResourceLoaderDebug;
- static $retval = null;
- if ( is_null( $retval ) ) {
- $retval = $wgRequest->getFuzzyBool( 'debug',
- $wgRequest->getCookie( 'resourceLoaderDebug', '', $wgResourceLoaderDebug ) );
+ if ( self::$debugMode === null ) {
+ global $wgRequest, $wgResourceLoaderDebug;
+ self::$debugMode = $wgRequest->getFuzzyBool( 'debug',
+ $wgRequest->getCookie( 'resourceLoaderDebug', '', $wgResourceLoaderDebug )
+ );
}
- return $retval;
+ return self::$debugMode;
+ }
+
+ /**
+ * Reset static members used for caching.
+ *
+ * Global state and $wgRequest are evil, but we're using it right
+ * now and sometimes we need to be able to force ResourceLoader to
+ * re-evaluate the context because it has changed (e.g. in the test suite).
+ */
+ public static function clearCache() {
+ self::$debugMode = null;
}
/**
* @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
);
*
* @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,