$skin = $context->getSkin();
$lang = $context->getLanguage();
- // Get file dependency information
+ // Batched version of ResourceLoaderModule::getFileDependencies
+ $vary = "$skin|$lang";
$res = $dbr->select( 'module_deps', array( 'md_module', 'md_deps' ), array(
'md_module' => $modules,
- 'md_skin' => $skin
+ 'md_skin' => $vary,
), __METHOD__
);
-
- // Set modules' dependencies
+ // Prime in-object cache values for each module
$modulesWithDeps = array();
foreach ( $res as $row ) {
$module = $this->getModule( $row->md_module );
if ( $module ) {
- $module->setFileDependencies( $skin, FormatJson::decode( $row->md_deps, true ) );
+ $module->setFileDependencies( $context, FormatJson::decode( $row->md_deps, true ) );
$modulesWithDeps[] = $row->md_module;
}
}
-
// Register the absence of a dependency row too
foreach ( array_diff( $modules, $modulesWithDeps ) as $name ) {
$module = $this->getModule( $name );
if ( $module ) {
- $this->getModule( $name )->setFileDependencies( $skin, array() );
+ $this->getModule( $name )->setFileDependencies( $context, array() );
}
}
if ( !$options['cache'] ) {
$result = self::applyFilter( $filter, $data, $this->config );
} else {
- $key = wfGlobalCacheKey( 'resourceloader', 'filter', $filter, self::$filterCacheVersion, md5( $data ) );
+ $key = wfGlobalCacheKey(
+ 'resourceloader',
+ 'filter',
+ $filter,
+ self::$filterCacheVersion, md5( $data )
+ );
$cache = wfGetCache( wfIsHHVM() ? CACHE_ACCEL : CACHE_ANYTHING );
$cacheEntry = $cache->get( $key );
if ( is_string( $cacheEntry ) ) {
$this->register( include "$IP/resources/Resources.php" );
$this->register( include "$IP/resources/ResourcesOOUI.php" );
// Register extension modules
- Hooks::run( 'ResourceLoaderRegisterModules', array( &$this ) );
$this->register( $config->get( 'ResourceModules' ) );
+ Hooks::run( 'ResourceLoaderRegisterModules', array( &$this ) );
if ( $config->get( 'EnableJavaScriptTest' ) === true ) {
$this->registerTestModules();
if ( $context->getImageObj() && $this->errors ) {
// We can't show both the error messages and the response when it's an image.
- $errorText = '';
- foreach ( $this->errors as $error ) {
- $errorText .= $error . "\n";
- }
- $response = $errorText;
+ $response = implode( "\n\n", $this->errors );
} elseif ( $this->errors ) {
- // Prepend comments indicating errors
- $errorText = '';
- foreach ( $this->errors as $error ) {
- $errorText .= self::makeComment( $error );
+ $errorText = implode( "\n\n", $this->errors );
+ $errorResponse = self::makeComment( $errorText );
+ if ( $context->shouldIncludeScripts() ) {
+ $errorResponse .= 'if (window.console && console.error) {'
+ . Xml::encodeJsCall( 'console.error', array( $errorText ) )
+ . "}\n";
}
- $response = $errorText . $response;
+
+ // Prepend error info to the response
+ $response = $errorResponse . $response;
}
$this->errors = array();
global $wgShowExceptionDetails;
if ( !$wgShowExceptionDetails ) {
- return 'Internal error';
+ return MWExceptionHandler::getPublicLogMessage( $e );
}
- return $e->__toString();
+ return MWExceptionHandler::getLogMessage( $e );
}
/**
* Generate code for 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)
+ * @param ResourceLoaderModule[] $modules List of module objects keyed by module name
+ * @param string[] $missing List of requested module names that are unregistered (optional)
* @return string Response data
*/
public function makeModuleResponse( ResourceLoaderContext $context,
}
private static function isEmptyObject( stdClass $obj ) {
- foreach ( $obj as $key => &$value ) {
+ foreach ( $obj as $key => $value ) {
return false;
}
return true;
* @return string
*/
public static function makeLoaderConditionalScript( $script ) {
- return "window.RLQ = window.RLQ || []; window.RLQ.push( function () {\n" . trim( $script ) . "\n} );";
+ return "window.RLQ = window.RLQ || []; window.RLQ.push( function () {\n" .
+ trim( $script ) . "\n} );";
}
/**
/**
* Returns LESS compiler set up for use with MediaWiki
*
+ * @since 1.22
+ * @since 1.26 added $extraVars parameter
* @param Config $config
+ * @param array $extraVars Associative array of extra (i.e., other than the
+ * globally-configured ones) that should be used for compilation.
* @throws MWException
- * @since 1.22
- * @return lessc
+ * @return Less_Parser
*/
- public static function getLessCompiler( Config $config ) {
+ public static function getLessCompiler( Config $config, $extraVars = array() ) {
// When called from the installer, it is possible that a required PHP extension
// is missing (at least for now; see bug 47564). If this is the case, throw an
// exception (caught by the installer) to prevent a fatal error later on.
- if ( !class_exists( 'lessc' ) ) {
- throw new MWException( 'MediaWiki requires the lessphp compiler' );
- }
- if ( !function_exists( 'ctype_digit' ) ) {
- throw new MWException( 'lessc requires the Ctype extension' );
+ if ( !class_exists( 'Less_Parser' ) ) {
+ throw new MWException( 'MediaWiki requires the less.php parser' );
}
- $less = new lessc();
- $less->setPreserveComments( true );
- $less->setVariables( self::getLessVars( $config ) );
- $less->setImportDir( $config->get( 'ResourceLoaderLESSImportPaths' ) );
- return $less;
+ $parser = new Less_Parser;
+ $parser->ModifyVars( array_merge( self::getLessVars( $config ), $extraVars ) );
+ $parser->SetImportDirs( array_fill_keys( $config->get( 'ResourceLoaderLESSImportPaths' ), '' ) );
+ $parser->SetOption( 'relativeUrls', false );
+ $parser->SetCacheDir( $config->get( 'CacheDirectory' ) ?: wfTempDir() );
+
+ return $parser;
}
/**
if ( !self::$lessVars ) {
$lessVars = $config->get( 'ResourceLoaderLESSVars' );
Hooks::run( 'ResourceLoaderGetLessVars', array( &$lessVars ) );
- // Sort by key to ensure consistent hashing for cache lookups.
- ksort( $lessVars );
self::$lessVars = $lessVars;
}
return self::$lessVars;