MediaWiki  master
ResourceLoaderModule.php
Go to the documentation of this file.
1 <?php
26 use Psr\Log\LoggerAwareInterface;
27 use Psr\Log\LoggerInterface;
28 use Psr\Log\NullLogger;
29 use Wikimedia\RelPath;
30 
39 abstract class ResourceLoaderModule implements LoggerAwareInterface {
41  protected $config;
43  protected $logger;
44 
52  protected $origin = self::ORIGIN_CORE_SITEWIDE;
53 
55  protected $name = null;
57  protected $targets = [ 'desktop' ];
58 
60  protected $fileDeps = [];
62  protected $msgBlobs = [];
64  protected $versionHash = [];
66  protected $contents = [];
67 
69  private $hookRunner;
70 
75 
77  protected $deprecated = false;
78 
80  public const TYPE_SCRIPTS = 'scripts';
82  public const TYPE_STYLES = 'styles';
84  public const TYPE_COMBINED = 'combined';
85 
87  public const LOAD_STYLES = 'styles';
89  public const LOAD_GENERAL = 'general';
90 
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;
105 
107  private const USERJSPARSE_CACHE_VERSION = 2;
108 
115  public function getName() {
116  return $this->name;
117  }
118 
125  public function setName( $name ) {
126  $this->name = $name;
127  }
128 
138  public function setSkinStylesOverride( array $moduleSkinStyles ): void {
139  // Stub, only supported by FileModule currently.
140  }
141 
149  public function setDependencyAccessCallbacks( callable $loadCallback, callable $saveCallback ) {
150  $this->depLoadCallback = $loadCallback;
151  $this->depSaveCallback = $saveCallback;
152  }
153 
161  public function getOrigin() {
162  return $this->origin;
163  }
164 
169  public function getFlip( ResourceLoaderContext $context ) {
170  return MediaWikiServices::getInstance()->getContentLanguage()->getDir() !==
171  $context->getDirection();
172  }
173 
180  public function getDeprecationInformation( ResourceLoaderContext $context ) {
181  $deprecationInfo = $this->deprecated;
182  if ( $deprecationInfo ) {
183  $name = $this->getName();
184  $warning = 'This page is using the deprecated ResourceLoader module "' . $name . '".';
185  if ( is_string( $deprecationInfo ) ) {
186  $warning .= "\n" . $deprecationInfo;
187  }
188  return 'mw.log.warn(' . $context->encodeJson( $warning ) . ');';
189  } else {
190  return '';
191  }
192  }
193 
214  public function getScript( ResourceLoaderContext $context ) {
215  // Stub, override expected
216  return '';
217  }
218 
225  public function getTemplates() {
226  // Stub, override expected.
227  return [];
228  }
229 
234  public function getConfig() {
235  if ( $this->config === null ) {
236  throw new RuntimeException( 'Config accessed before it is set' );
237  }
238 
239  return $this->config;
240  }
241 
246  public function setConfig( Config $config ) {
247  $this->config = $config;
248  }
249 
254  public function setLogger( LoggerInterface $logger ) {
255  $this->logger = $logger;
256  }
257 
262  protected function getLogger() {
263  if ( !$this->logger ) {
264  $this->logger = new NullLogger();
265  }
266  return $this->logger;
267  }
268 
273  public function setHookContainer( HookContainer $hookContainer ): void {
274  $this->hookRunner = new HookRunner( $hookContainer );
275  }
276 
284  protected function getHookRunner(): HookRunner {
285  return $this->hookRunner;
286  }
287 
308  public function getScriptURLsForDebug( ResourceLoaderContext $context ) {
309  $rl = $context->getResourceLoader();
310  $derivative = new DerivativeResourceLoaderContext( $context );
311  $derivative->setModules( [ $this->getName() ] );
312  $derivative->setOnly( 'scripts' );
313  $derivative->setDebug( true );
314 
315  $url = $rl->createLoaderURL(
316  $this->getSource(),
317  $derivative
318  );
319 
320  // Expand debug URL in case we are another wiki's module source (T255367)
321  $url = $rl->expandUrl( $this->getConfig()->get( 'Server' ), $url );
322 
323  return [ $url ];
324  }
325 
334  public function supportsURLLoading() {
335  return true;
336  }
337 
347  public function getStyles( ResourceLoaderContext $context ) {
348  // Stub, override expected
349  return [];
350  }
351 
362  public function getStyleURLsForDebug( ResourceLoaderContext $context ) {
363  $resourceLoader = $context->getResourceLoader();
364  $derivative = new DerivativeResourceLoaderContext( $context );
365  $derivative->setModules( [ $this->getName() ] );
366  $derivative->setOnly( 'styles' );
367  $derivative->setDebug( true );
368 
369  $url = $resourceLoader->createLoaderURL(
370  $this->getSource(),
371  $derivative
372  );
373 
374  return [ 'all' => [ $url ] ];
375  }
376 
385  public function getMessages() {
386  // Stub, override expected
387  return [];
388  }
389 
396  public function getGroup() {
397  // Stub, override expected
398  return null;
399  }
400 
407  public function getSource() {
408  // Stub, override expected
409  return 'local';
410  }
411 
425  public function getDependencies( ResourceLoaderContext $context = null ) {
426  // Stub, override expected
427  return [];
428  }
429 
436  public function getTargets() {
437  return $this->targets;
438  }
439 
447  public function getType() {
448  return self::LOAD_GENERAL;
449  }
450 
466  public function getSkipFunction() {
467  return null;
468  }
469 
480  public function requiresES6() {
481  return false;
482  }
483 
499  protected function getFileDependencies( ResourceLoaderContext $context ) {
500  $variant = self::getVary( $context );
501 
502  if ( !isset( $this->fileDeps[$variant] ) ) {
503  if ( $this->depLoadCallback ) {
504  $this->fileDeps[$variant] =
505  call_user_func( $this->depLoadCallback, $this->getName(), $variant );
506  } else {
507  $this->getLogger()->info( __METHOD__ . ": no callback registered" );
508  $this->fileDeps[$variant] = [];
509  }
510  }
511 
512  return $this->fileDeps[$variant];
513  }
514 
526  public function setFileDependencies( ResourceLoaderContext $context, array $paths ) {
527  $variant = self::getVary( $context );
528  $this->fileDeps[$variant] = $paths;
529  }
530 
538  protected function saveFileDependencies( ResourceLoaderContext $context, array $curFileRefs ) {
539  if ( !$this->depSaveCallback ) {
540  $this->getLogger()->info( __METHOD__ . ": no callback registered" );
541 
542  return;
543  }
544 
545  try {
546  // Pitfalls and performance considerations:
547  // 1. Don't keep updating the tracked paths due to duplicates or sorting.
548  // 2. Use relative paths to avoid ghost entries when $IP changes. (T111481)
549  // 3. Don't needlessly replace tracked paths with the same value
550  // just because $IP changed (e.g. when upgrading a wiki).
551  // 4. Don't create an endless replace loop on every request for this
552  // module when '../' is used anywhere. Even though both are expanded
553  // (one expanded by getFileDependencies from the DB, the other is
554  // still raw as originally read by RL), the latter has not
555  // been normalized yet.
556  call_user_func(
557  $this->depSaveCallback,
558  $this->getName(),
559  self::getVary( $context ),
560  self::getRelativePaths( $curFileRefs ),
561  self::getRelativePaths( $this->getFileDependencies( $context ) )
562  );
563  } catch ( Exception $e ) {
564  $this->getLogger()->warning(
565  __METHOD__ . ": failed to update dependencies: {$e->getMessage()}",
566  [ 'exception' => $e ]
567  );
568  }
569  }
570 
581  public static function getRelativePaths( array $filePaths ) {
582  global $IP;
583  return array_map( static function ( $path ) use ( $IP ) {
584  return RelPath::getRelativePath( $path, $IP );
585  }, $filePaths );
586  }
587 
595  public static function expandRelativePaths( array $filePaths ) {
596  global $IP;
597  return array_map( static function ( $path ) use ( $IP ) {
598  return RelPath::joinPath( $IP, $path );
599  }, $filePaths );
600  }
601 
610  protected function getMessageBlob( ResourceLoaderContext $context ) {
611  if ( !$this->getMessages() ) {
612  // Don't bother consulting MessageBlobStore
613  return null;
614  }
615  // Message blobs may only vary language, not by context keys
616  $lang = $context->getLanguage();
617  if ( !isset( $this->msgBlobs[$lang] ) ) {
618  $this->getLogger()->warning( 'Message blob for {module} should have been preloaded', [
619  'module' => $this->getName(),
620  ] );
621  $store = $context->getResourceLoader()->getMessageBlobStore();
622  $this->msgBlobs[$lang] = $store->getBlob( $this, $lang );
623  }
624  return $this->msgBlobs[$lang];
625  }
626 
636  public function setMessageBlob( $blob, $lang ) {
637  $this->msgBlobs[$lang] = $blob;
638  }
639 
654  final public function getHeaders( ResourceLoaderContext $context ) {
655  $headers = [];
656 
657  $formattedLinks = [];
658  foreach ( $this->getPreloadLinks( $context ) as $url => $attribs ) {
659  $link = "<{$url}>;rel=preload";
660  foreach ( $attribs as $key => $val ) {
661  $link .= ";{$key}={$val}";
662  }
663  $formattedLinks[] = $link;
664  }
665  if ( $formattedLinks ) {
666  $headers[] = 'Link: ' . implode( ',', $formattedLinks );
667  }
668 
669  return $headers;
670  }
671 
713  protected function getPreloadLinks( ResourceLoaderContext $context ) {
714  return [];
715  }
716 
725  protected function getLessVars( ResourceLoaderContext $context ) {
726  return [];
727  }
728 
736  public function getModuleContent( ResourceLoaderContext $context ) {
737  $contextHash = $context->getHash();
738  // Cache this expensive operation. This calls builds the scripts, styles, and messages
739  // content which typically involves filesystem and/or database access.
740  if ( !array_key_exists( $contextHash, $this->contents ) ) {
741  $this->contents[$contextHash] = $this->buildContent( $context );
742  }
743  return $this->contents[$contextHash];
744  }
745 
753  final protected function buildContent( ResourceLoaderContext $context ) {
754  $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
755  $statStart = microtime( true );
756 
757  // This MUST build both scripts and styles, regardless of whether $context->getOnly()
758  // is 'scripts' or 'styles' because the result is used by getVersionHash which
759  // must be consistent regardless of the 'only' filter on the current request.
760  // Also, when introducing new module content resources (e.g. templates, headers),
761  // these should only be included in the array when they are non-empty so that
762  // existing modules not using them do not get their cache invalidated.
763  $content = [];
764 
765  // Scripts
766  // If we are in debug mode, we'll want to return an array of URLs if possible
767  // However, we can't do this if the module doesn't support it.
768  // We also can't do this if there is an only= parameter, because we have to give
769  // the module a way to return a load.php URL without causing an infinite loop
770  if ( $context->getDebug() && !$context->getOnly() && $this->supportsURLLoading() ) {
771  $scripts = $this->getScriptURLsForDebug( $context );
772  } else {
773  $scripts = $this->getScript( $context );
774  // Make the script safe to concatenate by making sure there is at least one
775  // trailing new line at the end of the content. Previously, this looked for
776  // a semi-colon instead, but that breaks concatenation if the semicolon
777  // is inside a comment like "// foo();". Instead, simply use a
778  // line break as separator which matches JavaScript native logic for implicitly
779  // ending statements even if a semi-colon is missing.
780  // Bugs: T29054, T162719.
781  if ( is_string( $scripts ) ) {
782  $scripts = ResourceLoader::ensureNewline( $scripts );
783  }
784  }
785  $content['scripts'] = $scripts;
786 
787  $styles = [];
788  // Don't create empty stylesheets like [ '' => '' ] for modules
789  // that don't *have* any stylesheets (T40024).
790  $stylePairs = $this->getStyles( $context );
791  if ( count( $stylePairs ) ) {
792  // If we are in debug mode without &only= set, we'll want to return an array of URLs
793  // See comment near shouldIncludeScripts() for more details
794  if ( $context->getDebug() && !$context->getOnly() && $this->supportsURLLoading() ) {
795  $styles = [
796  'url' => $this->getStyleURLsForDebug( $context )
797  ];
798  } else {
799  // Minify CSS before embedding in mw.loader.implement call
800  // (unless in debug mode)
801  if ( !$context->getDebug() ) {
802  foreach ( $stylePairs as $media => $style ) {
803  // Can be either a string or an array of strings.
804  if ( is_array( $style ) ) {
805  $stylePairs[$media] = [];
806  foreach ( $style as $cssText ) {
807  if ( is_string( $cssText ) ) {
808  $stylePairs[$media][] =
809  ResourceLoader::filter( 'minify-css', $cssText );
810  }
811  }
812  } elseif ( is_string( $style ) ) {
813  $stylePairs[$media] = ResourceLoader::filter( 'minify-css', $style );
814  }
815  }
816  }
817  // Wrap styles into @media groups as needed and flatten into a numerical array
818  $styles = [
819  'css' => ResourceLoader::makeCombinedStyles( $stylePairs )
820  ];
821  }
822  }
823  $content['styles'] = $styles;
824 
825  // Messages
826  $blob = $this->getMessageBlob( $context );
827  if ( $blob ) {
828  $content['messagesBlob'] = $blob;
829  }
830 
831  $templates = $this->getTemplates();
832  if ( $templates ) {
833  $content['templates'] = $templates;
834  }
835 
836  $headers = $this->getHeaders( $context );
837  if ( $headers ) {
838  $content['headers'] = $headers;
839  }
840 
841  $statTiming = microtime( true ) - $statStart;
842  $statName = strtr( $this->getName(), '.', '_' );
843  $stats->timing( "resourceloader_build.all", 1000 * $statTiming );
844  $stats->timing( "resourceloader_build.$statName", 1000 * $statTiming );
845 
846  return $content;
847  }
848 
867  final public function getVersionHash( ResourceLoaderContext $context ) {
868  if ( $context->getDebug() ) {
869  // In debug mode, make uncached startup module extra fast by not computing any hashes.
870  // Server responses from load.php for individual modules already have no-cache so
871  // we don't need them. This also makes breakpoint debugging easier, as each module
872  // gets its own consistent URL. (T235672)
873  return '';
874  }
875 
876  // Cache this somewhat expensive operation. Especially because some classes
877  // (e.g. startup module) iterate more than once over all modules to get versions.
878  $contextHash = $context->getHash();
879  if ( !array_key_exists( $contextHash, $this->versionHash ) ) {
880  if ( $this->enableModuleContentVersion() ) {
881  // Detect changes directly by hashing the module contents.
882  $str = json_encode( $this->getModuleContent( $context ) );
883  } else {
884  // Infer changes based on definition and other metrics
885  $summary = $this->getDefinitionSummary( $context );
886  if ( !isset( $summary['_class'] ) ) {
887  throw new LogicException( 'getDefinitionSummary must call parent method' );
888  }
889  $str = json_encode( $summary );
890  }
891 
892  $this->versionHash[$contextHash] = ResourceLoader::makeHash( $str );
893  }
894  return $this->versionHash[$contextHash];
895  }
896 
907  public function enableModuleContentVersion() {
908  return false;
909  }
910 
954  public function getDefinitionSummary( ResourceLoaderContext $context ) {
955  return [
956  '_class' => static::class,
957  // Make sure that when filter cache for minification is invalidated,
958  // we also change the HTTP urls and mw.loader.store keys (T176884).
959  '_cacheVersion' => ResourceLoader::CACHE_VERSION,
960  ];
961  }
962 
974  public function isKnownEmpty( ResourceLoaderContext $context ) {
975  return false;
976  }
977 
989  public function shouldEmbedModule( ResourceLoaderContext $context ) {
990  return $this->getGroup() === 'private';
991  }
992 
1001  protected function validateScriptFile( $fileName, $contents ) {
1002  $error = null;
1003 
1004  if ( $this->getConfig()->get( 'ResourceLoaderValidateJS' ) ) {
1005  $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
1006  // Cache potentially slow parsing of JavaScript code during the
1007  // critical path. This happens lazily when responding to requests
1008  // for modules=site, modules=user, and Gadgets.
1009  $error = $cache->getWithSetCallback(
1010  $cache->makeKey(
1011  'resourceloader-userjsparse',
1012  self::USERJSPARSE_CACHE_VERSION,
1013  md5( $contents ),
1014  $fileName
1015  ),
1016  $cache::TTL_WEEK,
1017  static function () use ( $contents, $fileName ) {
1018  $parser = new JSParser();
1019  try {
1020  // Ignore compiler warnings (T77169)
1021  // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
1022  @$parser->parse( $contents, $fileName, 1 );
1023  } catch ( Exception $e ) {
1024  return $e->getMessage();
1025  }
1026  // Cache success as null
1027  return null;
1028  }
1029  );
1030  }
1031 
1032  if ( $error ) {
1033  // Send the error to the browser console client-side.
1034  // By returning this as replacement for the actual script,
1035  // we ensure user-provided scripts are safe to include in a batch
1036  // request, without risk of a syntax error in this blob breaking
1037  // the response itself.
1038  return 'mw.log.error(' .
1039  json_encode(
1040  'JavaScript parse error (scripts need to be valid ECMAScript 5): ' .
1041  $error
1042  ) .
1043  ');';
1044  } else {
1045  return $contents;
1046  }
1047  }
1048 
1057  protected static function safeFileHash( $filePath ) {
1058  return FileContentsHasher::getFileContentsHash( $filePath );
1059  }
1060 
1068  public static function getVary( ResourceLoaderContext $context ) {
1069  return implode( '|', [
1070  $context->getSkin(),
1071  $context->getLanguage(),
1072  ] );
1073  }
1074 }
ResourceLoader\filter
static filter( $filter, $data, array $options=[])
Run JavaScript or CSS data through a filter, caching the filtered result for future calls.
Definition: ResourceLoader.php:182
ResourceLoaderContext
Context object that contains information about the state of a specific ResourceLoader web request.
Definition: ResourceLoaderContext.php:34
ResourceLoaderModule\supportsURLLoading
supportsURLLoading()
Whether this module supports URL loading.
Definition: ResourceLoaderModule.php:334
ResourceLoaderModule\$depLoadCallback
callback $depLoadCallback
Function of (module name, variant) to get indirect file dependencies.
Definition: ResourceLoaderModule.php:72
ResourceLoaderModule\getStyleURLsForDebug
getStyleURLsForDebug(ResourceLoaderContext $context)
Get the URL or URLs to load for this module's CSS in debug mode.
Definition: ResourceLoaderModule.php:362
ResourceLoaderModule\setMessageBlob
setMessageBlob( $blob, $lang)
Set in-object cache for message blobs.
Definition: ResourceLoaderModule.php:636
ResourceLoaderContext\getDirection
getDirection()
Definition: ResourceLoaderContext.php:201
ResourceLoader\ensureNewline
static ensureNewline( $str)
Ensure the string is either empty or ends in a line break.
Definition: ResourceLoader.php:1247
ResourceLoaderModule\getFlip
getFlip(ResourceLoaderContext $context)
Definition: ResourceLoaderModule.php:169
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:193
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
ResourceLoaderModule\setDependencyAccessCallbacks
setDependencyAccessCallbacks(callable $loadCallback, callable $saveCallback)
Inject the functions that load/save the indirect file path dependency list from storage.
Definition: ResourceLoaderModule.php:149
ResourceLoaderContext\getResourceLoader
getResourceLoader()
Definition: ResourceLoaderContext.php:150
ResourceLoaderModule\$contents
array $contents
Map of (context hash => cached module content)
Definition: ResourceLoaderModule.php:66
ResourceLoaderModule\getHookRunner
getHookRunner()
Get a HookRunner for running core hooks.
Definition: ResourceLoaderModule.php:284
ResourceLoaderModule\$depSaveCallback
callback $depSaveCallback
Function of (module name, variant) to get indirect file dependencies.
Definition: ResourceLoaderModule.php:74
ResourceLoaderModule\setName
setName( $name)
Set this module's name.
Definition: ResourceLoaderModule.php:125
ResourceLoaderModule\setLogger
setLogger(LoggerInterface $logger)
Definition: ResourceLoaderModule.php:254
ResourceLoaderModule\getHeaders
getHeaders(ResourceLoaderContext $context)
Get headers to send as part of a module web response.
Definition: ResourceLoaderModule.php:654
ResourceLoaderModule\getType
getType()
Get the module's load type.
Definition: ResourceLoaderModule.php:447
ResourceLoaderModule\getTargets
getTargets()
Get target(s) for the module, eg ['desktop'] or ['desktop', 'mobile'].
Definition: ResourceLoaderModule.php:436
ResourceLoaderModule\shouldEmbedModule
shouldEmbedModule(ResourceLoaderContext $context)
Check whether this module should be embeded rather than linked.
Definition: ResourceLoaderModule.php:989
ResourceLoader\HookRunner
Definition: HookRunner.php:18
ResourceLoaderModule\requiresES6
requiresES6()
Whether the module requires ES6 support in the client.
Definition: ResourceLoaderModule.php:480
ResourceLoaderModule\getVary
static getVary(ResourceLoaderContext $context)
Get vary string.
Definition: ResourceLoaderModule.php:1068
ResourceLoaderModule\getStyles
getStyles(ResourceLoaderContext $context)
Get all CSS for this module for a given skin.
Definition: ResourceLoaderModule.php:347
ResourceLoaderContext\getOnly
getOnly()
Definition: ResourceLoaderContext.php:272
ResourceLoaderModule\getTemplates
getTemplates()
Takes named templates by the module and returns an array mapping.
Definition: ResourceLoaderModule.php:225
ResourceLoaderModule\setFileDependencies
setFileDependencies(ResourceLoaderContext $context, array $paths)
Set the indirect dependencies for this module persuant to the skin/language context.
Definition: ResourceLoaderModule.php:526
ResourceLoaderModule\saveFileDependencies
saveFileDependencies(ResourceLoaderContext $context, array $curFileRefs)
Save the indirect dependencies for this module persuant to the skin/language context.
Definition: ResourceLoaderModule.php:538
ResourceLoaderModule\setSkinStylesOverride
setSkinStylesOverride(array $moduleSkinStyles)
Provide overrides for skinStyles to modules that support that.
Definition: ResourceLoaderModule.php:138
ResourceLoaderModule\setHookContainer
setHookContainer(HookContainer $hookContainer)
Definition: ResourceLoaderModule.php:273
ResourceLoaderModule\buildContent
buildContent(ResourceLoaderContext $context)
Bundle all resources attached to this module into an array.
Definition: ResourceLoaderModule.php:753
FileContentsHasher\getFileContentsHash
static getFileContentsHash( $filePaths, $algo='md4')
Get a hash of the combined contents of one or more files, either by retrieving a previously-computed ...
Definition: FileContentsHasher.php:88
ResourceLoaderModule\getLessVars
getLessVars(ResourceLoaderContext $context)
Get module-specific LESS variables, if any.
Definition: ResourceLoaderModule.php:725
ResourceLoaderModule\enableModuleContentVersion
enableModuleContentVersion()
Whether to generate version hash based on module content.
Definition: ResourceLoaderModule.php:907
Config
Interface for configuration instances.
Definition: Config.php:30
ResourceLoaderModule\getGroup
getGroup()
Get the group this module is in.
Definition: ResourceLoaderModule.php:396
ResourceLoaderModule\getLogger
getLogger()
Definition: ResourceLoaderModule.php:262
ResourceLoaderModule\getScript
getScript(ResourceLoaderContext $context)
Get all JS for this module for a given language and skin.
Definition: ResourceLoaderModule.php:214
$blob
$blob
Definition: testCompression.php:70
ResourceLoader\makeHash
static makeHash( $value)
Create a hash for module versioning purposes.
Definition: ResourceLoader.php:675
ResourceLoaderContext\getDebug
getDebug()
Definition: ResourceLoaderContext.php:265
ResourceLoaderModule\$origin
int $origin
Script and style modules form a hierarchy of trustworthiness, with core modules like skins and jQuery...
Definition: ResourceLoaderModule.php:52
ResourceLoaderModule\getDeprecationInformation
getDeprecationInformation(ResourceLoaderContext $context)
Get JS representing deprecation information for the current module if available.
Definition: ResourceLoaderModule.php:180
ResourceLoaderModule\expandRelativePaths
static expandRelativePaths(array $filePaths)
Expand directories relative to $IP.
Definition: ResourceLoaderModule.php:595
ResourceLoaderContext\getLanguage
getLanguage()
Definition: ResourceLoaderContext.php:183
ResourceLoaderModule\$versionHash
array $versionHash
Map of (context hash => cached module version hash)
Definition: ResourceLoaderModule.php:64
ResourceLoaderModule\getOrigin
getOrigin()
Get this module's origin.
Definition: ResourceLoaderModule.php:161
ResourceLoaderModule\$msgBlobs
array $msgBlobs
Map of (language => in-object cache for message blob)
Definition: ResourceLoaderModule.php:62
ResourceLoaderModule\getMessageBlob
getMessageBlob(ResourceLoaderContext $context)
Get the hash of the message blob.
Definition: ResourceLoaderModule.php:610
ResourceLoaderModule\isKnownEmpty
isKnownEmpty(ResourceLoaderContext $context)
Check whether this module is known to be empty.
Definition: ResourceLoaderModule.php:974
$content
$content
Definition: router.php:76
ResourceLoaderModule\$deprecated
string bool $deprecated
Deprecation string or true if deprecated; false otherwise.
Definition: ResourceLoaderModule.php:77
ResourceLoaderModule\$targets
string[] $targets
What client platforms the module targets (e.g.
Definition: ResourceLoaderModule.php:57
ResourceLoaderModule\safeFileHash
static safeFileHash( $filePath)
Compute a non-cryptographic string hash of a file's contents.
Definition: ResourceLoaderModule.php:1057
ResourceLoaderModule\$name
string null $name
Module name.
Definition: ResourceLoaderModule.php:55
ResourceLoaderModule\getDependencies
getDependencies(ResourceLoaderContext $context=null)
Get a list of modules this module depends on.
Definition: ResourceLoaderModule.php:425
ResourceLoader\makeCombinedStyles
static makeCombinedStyles(array $stylePairs)
Combines an associative array mapping media type to CSS into a single stylesheet with "@media" blocks...
Definition: ResourceLoader.php:1365
ResourceLoaderModule\getPreloadLinks
getPreloadLinks(ResourceLoaderContext $context)
Get a list of resources that web browsers may preload.
Definition: ResourceLoaderModule.php:713
DerivativeResourceLoaderContext
A mutable version of ResourceLoaderContext.
Definition: DerivativeResourceLoaderContext.php:33
ResourceLoaderModule\getMessages
getMessages()
Get the messages needed for this module.
Definition: ResourceLoaderModule.php:385
ResourceLoaderModule\validateScriptFile
validateScriptFile( $fileName, $contents)
Validate a user-provided JavaScript blob.
Definition: ResourceLoaderModule.php:1001
ResourceLoaderModule\getDefinitionSummary
getDefinitionSummary(ResourceLoaderContext $context)
Get the definition summary for this module.
Definition: ResourceLoaderModule.php:954
ResourceLoaderContext\getSkin
getSkin()
Definition: ResourceLoaderContext.php:215
ResourceLoaderModule\getModuleContent
getModuleContent(ResourceLoaderContext $context)
Get an array of this module's resources.
Definition: ResourceLoaderModule.php:736
ResourceLoaderModule\getSkipFunction
getSkipFunction()
Get the skip function.
Definition: ResourceLoaderModule.php:466
ResourceLoaderModule
Abstraction for ResourceLoader modules, with name registration and maxage functionality.
Definition: ResourceLoaderModule.php:39
ResourceLoaderModule\$config
Config $config
Definition: ResourceLoaderModule.php:41
ResourceLoaderModule\$logger
LoggerInterface $logger
Definition: ResourceLoaderModule.php:43
$cache
$cache
Definition: mcc.php:33
ResourceLoaderModule\setConfig
setConfig(Config $config)
Definition: ResourceLoaderModule.php:246
ResourceLoaderModule\getScriptURLsForDebug
getScriptURLsForDebug(ResourceLoaderContext $context)
Get the URLs to load this module's JS code in debug mode.
Definition: ResourceLoaderModule.php:308
$path
$path
Definition: NoLocalSettings.php:25
ResourceLoaderModule\getRelativePaths
static getRelativePaths(array $filePaths)
Make file paths relative to MediaWiki directory.
Definition: ResourceLoaderModule.php:581
ResourceLoaderModule\getFileDependencies
getFileDependencies(ResourceLoaderContext $context)
Get the indirect dependencies for this module persuant to the skin/language context.
Definition: ResourceLoaderModule.php:499
ResourceLoaderModule\getVersionHash
getVersionHash(ResourceLoaderContext $context)
Get a string identifying the current version of this module in a given context.
Definition: ResourceLoaderModule.php:867
ResourceLoaderModule\getSource
getSource()
Get the source of this module.
Definition: ResourceLoaderModule.php:407
JSParser
Definition: jsminplus.php:675
MediaWiki\HookContainer\HookContainer
HookContainer class.
Definition: HookContainer.php:45
ResourceLoaderContext\getHash
getHash()
All factors that uniquely identify this request, except 'modules'.
Definition: ResourceLoaderContext.php:384
ResourceLoaderModule\$fileDeps
array $fileDeps
Map of (variant => indirect file dependencies)
Definition: ResourceLoaderModule.php:60
$IP
$IP
Definition: WebStart.php:49
ResourceLoaderModule\$hookRunner
HookRunner null $hookRunner
Definition: ResourceLoaderModule.php:69
ResourceLoaderContext\encodeJson
encodeJson( $data)
Wrapper around json_encode that avoids needless escapes, and pretty-prints in debug mode.
Definition: ResourceLoaderContext.php:432
ResourceLoaderModule\getName
getName()
Get this module's name.
Definition: ResourceLoaderModule.php:115
ResourceLoaderModule\getConfig
getConfig()
Definition: ResourceLoaderModule.php:234