Go to the documentation of this file.
26 use Psr\Log\LoggerAwareInterface;
27 use Psr\Log\LoggerInterface;
28 use Psr\Log\NullLogger;
29 use Wikimedia\RelPath;
52 protected $origin = self::ORIGIN_CORE_SITEWIDE;
80 public const TYPE_SCRIPTS =
'scripts';
82 public const TYPE_STYLES =
'styles';
84 public const TYPE_COMBINED =
'combined';
87 public const LOAD_STYLES =
'styles';
89 public const LOAD_GENERAL =
'general';
92 public const ORIGIN_CORE_SITEWIDE = 1;
94 public const ORIGIN_CORE_INDIVIDUAL = 2;
100 public const ORIGIN_USER_SITEWIDE = 3;
102 public const ORIGIN_USER_INDIVIDUAL = 4;
104 public const ORIGIN_ALL = 10;
107 private const USERJSPARSE_CACHE_VERSION = 2;
137 $this->depLoadCallback = $loadCallback;
138 $this->depSaveCallback = $saveCallback;
157 return MediaWikiServices::getInstance()->getContentLanguage()->getDir() !==
169 if ( $deprecationInfo ) {
171 $warning =
'This page is using the deprecated ResourceLoader module "' .
$name .
'".';
172 if ( is_string( $deprecationInfo ) ) {
173 $warning .=
"\n" . $deprecationInfo;
175 return 'mw.log.warn(' . $context->
encodeJson( $warning ) .
');';
222 if ( $this->config ===
null ) {
224 $this->config = MediaWikiServices::getInstance()->getMainConfig();
251 if ( !$this->logger ) {
252 $this->logger =
new NullLogger();
262 $this->hookRunner =
new HookRunner( $hookContainer );
294 $derivative->setModules( [ $this->
getName() ] );
295 $derivative->setOnly(
'scripts' );
296 $derivative->setDebug(
true );
298 $url = $resourceLoader->createLoaderURL(
345 $derivative->setModules( [ $this->
getName() ] );
346 $derivative->setOnly(
'styles' );
347 $derivative->setDebug(
true );
349 $url = $resourceLoader->createLoaderURL(
354 return [
'all' => [ $url ] ];
428 return self::LOAD_GENERAL;
468 if ( !isset( $this->fileDeps[$variant] ) ) {
469 if ( $this->depLoadCallback ) {
470 $this->fileDeps[$variant] =
471 call_user_func( $this->depLoadCallback, $this->
getName(), $variant );
473 $this->
getLogger()->info( __METHOD__ .
": no callback registered" );
474 $this->fileDeps[$variant] = [];
478 return $this->fileDeps[$variant];
494 $this->fileDeps[$variant] = $paths;
505 if ( !$this->depSaveCallback ) {
506 $this->
getLogger()->info( __METHOD__ .
": no callback registered" );
523 $this->depSaveCallback,
525 self::getVary( $context ),
526 self::getRelativePaths( $curFileRefs ),
529 }
catch ( Exception $e ) {
531 __METHOD__ .
": failed to update dependencies: {$e->getMessage()}",
532 [
'exception' => $e ]
549 return array_map(
function (
$path ) use (
$IP ) {
550 return RelPath::getRelativePath(
$path,
$IP );
563 return array_map(
function (
$path ) use (
$IP ) {
564 return RelPath::joinPath(
$IP,
$path );
583 if ( !isset( $this->msgBlobs[
$lang] ) ) {
584 $this->
getLogger()->warning(
'Message blob for {module} should have been preloaded', [
588 $this->msgBlobs[
$lang] = $store->getBlob( $this,
$lang );
590 return $this->msgBlobs[
$lang];
623 $formattedLinks = [];
625 $link =
"<{$url}>;rel=preload";
626 foreach ( $attribs as $key => $val ) {
627 $link .=
";{$key}={$val}";
629 $formattedLinks[] = $link;
631 if ( $formattedLinks ) {
632 $headers[] =
'Link: ' . implode(
',', $formattedLinks );
703 $contextHash = $context->
getHash();
706 if ( !array_key_exists( $contextHash, $this->contents ) ) {
707 $this->contents[$contextHash] = $this->
buildContent( $context );
709 return $this->contents[$contextHash];
720 $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
721 $statStart = microtime(
true );
736 if ( $context->
getDebug() && !$context->
getOnly() && $this->supportsURLLoading() ) {
747 if ( is_string( $scripts )
748 && strlen( $scripts )
749 && substr( $scripts, -1 ) !==
"\n"
759 $stylePairs = $this->
getStyles( $context );
760 if ( count( $stylePairs ) ) {
763 if ( $context->
getDebug() && !$context->
getOnly() && $this->supportsURLLoading() ) {
771 foreach ( $stylePairs as $media => $style ) {
773 if ( is_array( $style ) ) {
774 $stylePairs[$media] = [];
775 foreach ( $style as $cssText ) {
776 if ( is_string( $cssText ) ) {
777 $stylePairs[$media][] =
781 } elseif ( is_string( $style ) ) {
810 $statTiming = microtime(
true ) - $statStart;
811 $statName = strtr( $this->
getName(),
'.',
'_' );
812 $stats->timing(
"resourceloader_build.all", 1000 * $statTiming );
813 $stats->timing(
"resourceloader_build.$statName", 1000 * $statTiming );
838 $contextHash = $context->
getHash();
839 if ( !array_key_exists( $contextHash, $this->versionHash ) ) {
846 if ( !isset( $summary[
'_class'] ) ) {
847 throw new LogicException(
'getDefinitionSummary must call parent method' );
849 $str = json_encode( $summary );
854 return $this->versionHash[$contextHash];
916 '_class' => static::class,
919 '_cacheVersion' => ResourceLoader::CACHE_VERSION,
950 return $this->
getGroup() ===
'private';
964 if ( $this->
getConfig()->
get(
'ResourceLoaderValidateJS' ) ) {
965 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
969 $error =
$cache->getWithSetCallback(
971 'resourceloader-userjsparse',
972 self::USERJSPARSE_CACHE_VERSION,
977 function () use (
$contents, $fileName ) {
982 @$parser->parse(
$contents, $fileName, 1 );
983 }
catch ( Exception $e ) {
984 return $e->getMessage();
998 return 'mw.log.error(' .
1000 'JavaScript parse error (scripts need to be valid ECMAScript 5): ' .
1029 return implode(
'|', [
static filter( $filter, $data, array $options=[])
Run JavaScript or CSS data through a filter, caching the filtered result for future calls.
Context object that contains information about the state of a specific ResourceLoader web request.
supportsURLLoading()
Whether this module supports URL loading.
callback $depLoadCallback
Function of (module name, variant) to get indirect file dependencies.
getStyleURLsForDebug(ResourceLoaderContext $context)
Get the URL or URLs to load for this module's CSS in debug mode.
setMessageBlob( $blob, $lang)
Set in-object cache for message blobs.
getFlip(ResourceLoaderContext $context)
if(!isset( $args[0])) $lang
setDependencyAccessCallbacks(callable $loadCallback, callable $saveCallback)
Inject the functions that load/save the indirect file path dependency list from storage.
array $contents
Map of (context hash => cached module content)
getHookRunner()
Get a HookRunner for running core hooks.
callback $depSaveCallback
Function of (module name, variant) to get indirect file dependencies.
setName( $name)
Set this module's name.
setLogger(LoggerInterface $logger)
getHeaders(ResourceLoaderContext $context)
Get headers to send as part of a module web response.
getType()
Get the module's load type.
getTargets()
Get target(s) for the module, eg ['desktop'] or ['desktop', 'mobile'].
shouldEmbedModule(ResourceLoaderContext $context)
Check whether this module should be embeded rather than linked.
static getVary(ResourceLoaderContext $context)
Get vary string.
getStyles(ResourceLoaderContext $context)
Get all CSS for this module for a given skin.
getTemplates()
Takes named templates by the module and returns an array mapping.
setFileDependencies(ResourceLoaderContext $context, array $paths)
Set the indirect dependencies for this module persuant to the skin/language context.
saveFileDependencies(ResourceLoaderContext $context, array $curFileRefs)
Save the indirect dependencies for this module persuant to the skin/language context.
setHookContainer(HookContainer $hookContainer)
buildContent(ResourceLoaderContext $context)
Bundle all resources attached to this module into an array.
static getFileContentsHash( $filePaths, $algo='md4')
Get a hash of the combined contents of one or more files, either by retrieving a previously-computed ...
getLessVars(ResourceLoaderContext $context)
Get module-specific LESS variables, if any.
enableModuleContentVersion()
Whether to generate version hash based on module content.
Interface for configuration instances.
getGroup()
Get the group this module is in.
getScript(ResourceLoaderContext $context)
Get all JS for this module for a given language and skin.
static makeHash( $value)
Create a hash for module versioning purposes.
int $origin
Script and style modules form a hierarchy of trustworthiness, with core modules like skins and jQuery...
getDeprecationInformation(ResourceLoaderContext $context)
Get JS representing deprecation information for the current module if available.
static expandRelativePaths(array $filePaths)
Expand directories relative to $IP.
array $versionHash
Map of (context hash => cached module version hash)
getOrigin()
Get this module's origin.
array $msgBlobs
Map of (language => in-object cache for message blob)
getMessageBlob(ResourceLoaderContext $context)
Get the hash of the message blob.
isKnownEmpty(ResourceLoaderContext $context)
Check whether this module is known to be empty.
string bool $deprecated
Deprecation string or true if deprecated; false otherwise.
string[] $targets
What client platforms the module targets (e.g.
static safeFileHash( $filePath)
Compute a non-cryptographic string hash of a file's contents.
string null $name
Module name.
getDependencies(ResourceLoaderContext $context=null)
Get a list of modules this module depends on.
static makeCombinedStyles(array $stylePairs)
Combines an associative array mapping media type to CSS into a single stylesheet with "@media" blocks...
getPreloadLinks(ResourceLoaderContext $context)
Get a list of resources that web browsers may preload.
A mutable version of ResourceLoaderContext.
getMessages()
Get the messages needed for this module.
validateScriptFile( $fileName, $contents)
Validate a user-provided JavaScript blob.
getDefinitionSummary(ResourceLoaderContext $context)
Get the definition summary for this module.
getModuleContent(ResourceLoaderContext $context)
Get an array of this module's resources.
getSkipFunction()
Get the skip function.
Abstraction for ResourceLoader modules, with name registration and maxage functionality.
setConfig(Config $config)
getScriptURLsForDebug(ResourceLoaderContext $context)
Get the URL or URLs to load for this module's JS in debug mode.
static getRelativePaths(array $filePaths)
Make file paths relative to MediaWiki directory.
getFileDependencies(ResourceLoaderContext $context)
Get the indirect dependencies for this module persuant to the skin/language context.
getVersionHash(ResourceLoaderContext $context)
Get a string identifying the current version of this module in a given context.
getSource()
Get the source of this module.
getHash()
All factors that uniquely identify this request, except 'modules'.
array $fileDeps
Map of (variant => indirect file dependencies)
HookRunner null $hookRunner
encodeJson( $data)
Wrapper around json_encode that avoids needless escapes, and pretty-prints in debug mode.
getName()
Get this module's name.