MediaWiki  1.34.0
ResourceLoaderModule.php
Go to the documentation of this file.
1 <?php
24 use Psr\Log\LoggerAwareInterface;
25 use Psr\Log\LoggerInterface;
26 use Psr\Log\NullLogger;
27 use Wikimedia\AtEase\AtEase;
28 use Wikimedia\RelPath;
29 use Wikimedia\ScopedCallback;
30 
37 abstract class ResourceLoaderModule implements LoggerAwareInterface {
39  protected $config;
41  protected $logger;
42 
50  protected $origin = self::ORIGIN_CORE_SITEWIDE;
51 
53  protected $name = null;
55  protected $targets = [ 'desktop' ];
56 
58  protected $fileDeps = [];
60  protected $msgBlobs = [];
62  protected $versionHash = [];
64  protected $contents = [];
65 
67  protected $deprecated = false;
68 
70  const TYPE_SCRIPTS = 'scripts';
72  const TYPE_STYLES = 'styles';
74  const TYPE_COMBINED = 'combined';
75 
77  const LOAD_STYLES = 'styles';
79  const LOAD_GENERAL = 'general';
80 
82  const ORIGIN_CORE_SITEWIDE = 1;
84  const ORIGIN_CORE_INDIVIDUAL = 2;
90  const ORIGIN_USER_SITEWIDE = 3;
92  const ORIGIN_USER_INDIVIDUAL = 4;
94  const ORIGIN_ALL = 10;
95 
102  public function getName() {
103  return $this->name;
104  }
105 
112  public function setName( $name ) {
113  $this->name = $name;
114  }
115 
123  public function getOrigin() {
124  return $this->origin;
125  }
126 
132  return MediaWikiServices::getInstance()->getContentLanguage()->getDir() !==
133  $context->getDirection();
134  }
135 
143  if ( $context === null ) {
144  wfDeprecated( __METHOD__ . ' without a ResourceLoader context', '1.34' );
145  }
146  $deprecationInfo = $this->deprecated;
147  if ( $deprecationInfo ) {
148  $name = $this->getName();
149  $warning = 'This page is using the deprecated ResourceLoader module "' . $name . '".';
150  if ( is_string( $deprecationInfo ) ) {
151  $warning .= "\n" . $deprecationInfo;
152  }
153  if ( $context === null ) {
154  return 'mw.log.warn(' . ResourceLoader::encodeJsonForScript( $warning ) . ');';
155  }
156  return 'mw.log.warn(' . $context->encodeJson( $warning ) . ');';
157  } else {
158  return '';
159  }
160  }
161 
182  // Stub, override expected
183  return '';
184  }
185 
191  public function getTemplates() {
192  // Stub, override expected.
193  return [];
194  }
195 
200  public function getConfig() {
201  if ( $this->config === null ) {
202  // Ugh, fall back to default
203  $this->config = MediaWikiServices::getInstance()->getMainConfig();
204  }
205 
206  return $this->config;
207  }
208 
213  public function setConfig( Config $config ) {
214  $this->config = $config;
215  }
216 
221  public function setLogger( LoggerInterface $logger ) {
222  $this->logger = $logger;
223  }
224 
229  protected function getLogger() {
230  if ( !$this->logger ) {
231  $this->logger = new NullLogger();
232  }
233  return $this->logger;
234  }
235 
251  $resourceLoader = $context->getResourceLoader();
252  $derivative = new DerivativeResourceLoaderContext( $context );
253  $derivative->setModules( [ $this->getName() ] );
254  $derivative->setOnly( 'scripts' );
255  $derivative->setDebug( true );
256 
257  $url = $resourceLoader->createLoaderURL(
258  $this->getSource(),
259  $derivative
260  );
261 
262  return [ $url ];
263  }
264 
271  public function supportsURLLoading() {
272  return true;
273  }
274 
284  // Stub, override expected
285  return [];
286  }
287 
298  $resourceLoader = $context->getResourceLoader();
299  $derivative = new DerivativeResourceLoaderContext( $context );
300  $derivative->setModules( [ $this->getName() ] );
301  $derivative->setOnly( 'styles' );
302  $derivative->setDebug( true );
303 
304  $url = $resourceLoader->createLoaderURL(
305  $this->getSource(),
306  $derivative
307  );
308 
309  return [ 'all' => [ $url ] ];
310  }
311 
319  public function getMessages() {
320  // Stub, override expected
321  return [];
322  }
323 
329  public function getGroup() {
330  // Stub, override expected
331  return null;
332  }
333 
339  public function getSource() {
340  // Stub, override expected
341  return 'local';
342  }
343 
356  public function getDependencies( ResourceLoaderContext $context = null ) {
357  // Stub, override expected
358  return [];
359  }
360 
366  public function getTargets() {
367  return $this->targets;
368  }
369 
376  public function getType() {
377  return self::LOAD_GENERAL;
378  }
379 
394  public function getSkipFunction() {
395  return null;
396  }
397 
407  $vary = self::getVary( $context );
408 
409  // Try in-object cache first
410  if ( !isset( $this->fileDeps[$vary] ) ) {
411  $dbr = wfGetDB( DB_REPLICA );
412  $deps = $dbr->selectField( 'module_deps',
413  'md_deps',
414  [
415  'md_module' => $this->getName(),
416  'md_skin' => $vary,
417  ],
418  __METHOD__
419  );
420 
421  if ( !is_null( $deps ) ) {
422  $this->fileDeps[$vary] = self::expandRelativePaths(
423  (array)json_decode( $deps, true )
424  );
425  } else {
426  $this->fileDeps[$vary] = [];
427  }
428  }
429  return $this->fileDeps[$vary];
430  }
431 
442  $vary = self::getVary( $context );
443  $this->fileDeps[$vary] = $files;
444  }
445 
453  protected function saveFileDependencies( ResourceLoaderContext $context, $localFileRefs ) {
454  try {
455  // Related bugs and performance considerations:
456  // 1. Don't needlessly change the database value with the same list in a
457  // different order or with duplicates.
458  // 2. Use relative paths to avoid ghost entries when $IP changes. (T111481)
459  // 3. Don't needlessly replace the database with the same value
460  // just because $IP changed (e.g. when upgrading a wiki).
461  // 4. Don't create an endless replace loop on every request for this
462  // module when '../' is used anywhere. Even though both are expanded
463  // (one expanded by getFileDependencies from the DB, the other is
464  // still raw as originally read by RL), the latter has not
465  // been normalized yet.
466 
467  // Normalise
468  $localFileRefs = array_values( array_unique( $localFileRefs ) );
469  sort( $localFileRefs );
470  $localPaths = self::getRelativePaths( $localFileRefs );
471  $storedPaths = self::getRelativePaths( $this->getFileDependencies( $context ) );
472 
473  if ( $localPaths === $storedPaths ) {
474  // Unchanged. Avoid needless database query (especially master conn!).
475  return;
476  }
477 
478  // The file deps list has changed, we want to update it.
479  $vary = self::getVary( $context );
481  $key = $cache->makeKey( __METHOD__, $this->getName(), $vary );
482  $scopeLock = $cache->getScopedLock( $key, 0 );
483  if ( !$scopeLock ) {
484  // Another request appears to be doing this update already.
485  // Avoid write slams (T124649).
486  return;
487  }
488 
489  // No needless escaping as this isn't HTML output.
490  // Only stored in the database and parsed in PHP.
491  $deps = json_encode( $localPaths, JSON_UNESCAPED_SLASHES );
492  $dbw = wfGetDB( DB_MASTER );
493  $dbw->upsert( 'module_deps',
494  [
495  'md_module' => $this->getName(),
496  'md_skin' => $vary,
497  'md_deps' => $deps,
498  ],
499  [ [ 'md_module', 'md_skin' ] ],
500  [
501  'md_deps' => $deps,
502  ],
503  __METHOD__
504  );
505 
506  if ( $dbw->trxLevel() ) {
507  $dbw->onTransactionResolution(
508  function () use ( &$scopeLock ) {
509  ScopedCallback::consume( $scopeLock ); // release after commit
510  },
511  __METHOD__
512  );
513  }
514  } catch ( Exception $e ) {
515  // Probably a DB failure. Either the read query from getFileDependencies(),
516  // or the write query above.
517  wfDebugLog( 'resourceloader', __METHOD__ . ": failed to update DB: $e" );
518  }
519  }
520 
531  public static function getRelativePaths( array $filePaths ) {
532  global $IP;
533  return array_map( function ( $path ) use ( $IP ) {
534  return RelPath::getRelativePath( $path, $IP );
535  }, $filePaths );
536  }
537 
545  public static function expandRelativePaths( array $filePaths ) {
546  global $IP;
547  return array_map( function ( $path ) use ( $IP ) {
548  return RelPath::joinPath( $IP, $path );
549  }, $filePaths );
550  }
551 
560  if ( !$this->getMessages() ) {
561  // Don't bother consulting MessageBlobStore
562  return null;
563  }
564  // Message blobs may only vary language, not by context keys
565  $lang = $context->getLanguage();
566  if ( !isset( $this->msgBlobs[$lang] ) ) {
567  $this->getLogger()->warning( 'Message blob for {module} should have been preloaded', [
568  'module' => $this->getName(),
569  ] );
570  $store = $context->getResourceLoader()->getMessageBlobStore();
571  $this->msgBlobs[$lang] = $store->getBlob( $this, $lang );
572  }
573  return $this->msgBlobs[$lang];
574  }
575 
585  public function setMessageBlob( $blob, $lang ) {
586  $this->msgBlobs[$lang] = $blob;
587  }
588 
603  final public function getHeaders( ResourceLoaderContext $context ) {
604  $headers = [];
605 
606  $formattedLinks = [];
607  foreach ( $this->getPreloadLinks( $context ) as $url => $attribs ) {
608  $link = "<{$url}>;rel=preload";
609  foreach ( $attribs as $key => $val ) {
610  $link .= ";{$key}={$val}";
611  }
612  $formattedLinks[] = $link;
613  }
614  if ( $formattedLinks ) {
615  $headers[] = 'Link: ' . implode( ',', $formattedLinks );
616  }
617 
618  return $headers;
619  }
620 
661  return [];
662  }
663 
672  return [];
673  }
674 
683  $contextHash = $context->getHash();
684  // Cache this expensive operation. This calls builds the scripts, styles, and messages
685  // content which typically involves filesystem and/or database access.
686  if ( !array_key_exists( $contextHash, $this->contents ) ) {
687  $this->contents[$contextHash] = $this->buildContent( $context );
688  }
689  return $this->contents[$contextHash];
690  }
691 
699  final protected function buildContent( ResourceLoaderContext $context ) {
700  $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
701  $statStart = microtime( true );
702 
703  // This MUST build both scripts and styles, regardless of whether $context->getOnly()
704  // is 'scripts' or 'styles' because the result is used by getVersionHash which
705  // must be consistent regardless of the 'only' filter on the current request.
706  // Also, when introducing new module content resources (e.g. templates, headers),
707  // these should only be included in the array when they are non-empty so that
708  // existing modules not using them do not get their cache invalidated.
709  $content = [];
710 
711  // Scripts
712  // If we are in debug mode, we'll want to return an array of URLs if possible
713  // However, we can't do this if the module doesn't support it.
714  // We also can't do this if there is an only= parameter, because we have to give
715  // the module a way to return a load.php URL without causing an infinite loop
716  if ( $context->getDebug() && !$context->getOnly() && $this->supportsURLLoading() ) {
717  $scripts = $this->getScriptURLsForDebug( $context );
718  } else {
719  $scripts = $this->getScript( $context );
720  // Make the script safe to concatenate by making sure there is at least one
721  // trailing new line at the end of the content. Previously, this looked for
722  // a semi-colon instead, but that breaks concatenation if the semicolon
723  // is inside a comment like "// foo();". Instead, simply use a
724  // line break as separator which matches JavaScript native logic for implicitly
725  // ending statements even if a semi-colon is missing.
726  // Bugs: T29054, T162719.
727  if ( is_string( $scripts )
728  && strlen( $scripts )
729  && substr( $scripts, -1 ) !== "\n"
730  ) {
731  $scripts .= "\n";
732  }
733  }
734  $content['scripts'] = $scripts;
735 
736  $styles = [];
737  // Don't create empty stylesheets like [ '' => '' ] for modules
738  // that don't *have* any stylesheets (T40024).
739  $stylePairs = $this->getStyles( $context );
740  if ( count( $stylePairs ) ) {
741  // If we are in debug mode without &only= set, we'll want to return an array of URLs
742  // See comment near shouldIncludeScripts() for more details
743  if ( $context->getDebug() && !$context->getOnly() && $this->supportsURLLoading() ) {
744  $styles = [
745  'url' => $this->getStyleURLsForDebug( $context )
746  ];
747  } else {
748  // Minify CSS before embedding in mw.loader.implement call
749  // (unless in debug mode)
750  if ( !$context->getDebug() ) {
751  foreach ( $stylePairs as $media => $style ) {
752  // Can be either a string or an array of strings.
753  if ( is_array( $style ) ) {
754  $stylePairs[$media] = [];
755  foreach ( $style as $cssText ) {
756  if ( is_string( $cssText ) ) {
757  $stylePairs[$media][] =
758  ResourceLoader::filter( 'minify-css', $cssText );
759  }
760  }
761  } elseif ( is_string( $style ) ) {
762  $stylePairs[$media] = ResourceLoader::filter( 'minify-css', $style );
763  }
764  }
765  }
766  // Wrap styles into @media groups as needed and flatten into a numerical array
767  $styles = [
768  'css' => ResourceLoader::makeCombinedStyles( $stylePairs )
769  ];
770  }
771  }
772  $content['styles'] = $styles;
773 
774  // Messages
775  $blob = $this->getMessageBlob( $context );
776  if ( $blob ) {
777  $content['messagesBlob'] = $blob;
778  }
779 
780  $templates = $this->getTemplates();
781  if ( $templates ) {
782  $content['templates'] = $templates;
783  }
784 
785  $headers = $this->getHeaders( $context );
786  if ( $headers ) {
787  $content['headers'] = $headers;
788  }
789 
790  $statTiming = microtime( true ) - $statStart;
791  $statName = strtr( $this->getName(), '.', '_' );
792  $stats->timing( "resourceloader_build.all", 1000 * $statTiming );
793  $stats->timing( "resourceloader_build.$statName", 1000 * $statTiming );
794 
795  return $content;
796  }
797 
816  // Cache this somewhat expensive operation. Especially because some classes
817  // (e.g. startup module) iterate more than once over all modules to get versions.
818  $contextHash = $context->getHash();
819  if ( !array_key_exists( $contextHash, $this->versionHash ) ) {
820  if ( $this->enableModuleContentVersion() ) {
821  // Detect changes directly by hashing the module contents.
822  $str = json_encode( $this->getModuleContent( $context ) );
823  } else {
824  // Infer changes based on definition and other metrics
825  $summary = $this->getDefinitionSummary( $context );
826  if ( !isset( $summary['_class'] ) ) {
827  throw new LogicException( 'getDefinitionSummary must call parent method' );
828  }
829  $str = json_encode( $summary );
830  }
831 
832  $this->versionHash[$contextHash] = ResourceLoader::makeHash( $str );
833  }
834  return $this->versionHash[$contextHash];
835  }
836 
846  public function enableModuleContentVersion() {
847  return false;
848  }
849 
894  return [
895  '_class' => static::class,
896  // Make sure that when filter cache for minification is invalidated,
897  // we also change the HTTP urls and mw.loader.store keys (T176884).
898  '_cacheVersion' => ResourceLoader::CACHE_VERSION,
899  ];
900  }
901 
912  return false;
913  }
914 
926  return $this->getGroup() === 'private';
927  }
928 
930  private static $jsParser;
931  private static $parseCacheVersion = 1;
932 
941  protected function validateScriptFile( $fileName, $contents ) {
942  if ( !$this->getConfig()->get( 'ResourceLoaderValidateJS' ) ) {
943  return $contents;
944  }
945  $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
946  return $cache->getWithSetCallback(
947  $cache->makeGlobalKey(
948  'resourceloader-jsparse',
949  self::$parseCacheVersion,
950  md5( $contents ),
951  $fileName
952  ),
953  $cache::TTL_WEEK,
954  function () use ( $contents, $fileName ) {
955  $parser = self::javaScriptParser();
956  $err = null;
957  try {
958  AtEase::suppressWarnings();
959  $parser->parse( $contents, $fileName, 1 );
960  } catch ( Exception $e ) {
961  $err = $e;
962  } finally {
963  AtEase::restoreWarnings();
964  }
965  if ( $err ) {
966  // Send the error to the browser console client-side.
967  // By returning this as replacement for the actual script,
968  // we ensure modules are safe to load in a batch request,
969  // without causing other unrelated modules to break.
970  return 'mw.log.error(' .
971  Xml::encodeJsVar( 'JavaScript parse error: ' . $err->getMessage() ) .
972  ');';
973  }
974  return $contents;
975  }
976  );
977  }
978 
982  protected static function javaScriptParser() {
983  if ( !self::$jsParser ) {
984  self::$jsParser = new JSParser();
985  }
986  return self::$jsParser;
987  }
988 
996  protected static function safeFilemtime( $filePath ) {
997  AtEase::suppressWarnings();
998  $mtime = filemtime( $filePath ) ?: 1;
999  AtEase::restoreWarnings();
1000  return $mtime;
1001  }
1002 
1011  protected static function safeFileHash( $filePath ) {
1012  return FileContentsHasher::getFileContentsHash( $filePath );
1013  }
1014 
1022  public static function getVary( ResourceLoaderContext $context ) {
1023  return implode( '|', [
1024  $context->getSkin(),
1025  $context->getLanguage(),
1026  ] );
1027  }
1028 }
ResourceLoaderContext
Context object that contains information about the state of a specific ResourceLoader web request.
Definition: ResourceLoaderContext.php:33
ResourceLoaderModule\supportsURLLoading
supportsURLLoading()
Whether this module supports URL loading.
Definition: ResourceLoaderModule.php:271
ResourceLoaderModule\getStyleURLsForDebug
getStyleURLsForDebug(ResourceLoaderContext $context)
Get the URL or URLs to load for this module's CSS in debug mode.
Definition: ResourceLoaderModule.php:297
ResourceLoaderModule\setMessageBlob
setMessageBlob( $blob, $lang)
Set in-object cache for message blobs.
Definition: ResourceLoaderModule.php:585
ResourceLoaderModule\setFileDependencies
setFileDependencies(ResourceLoaderContext $context, $files)
Set in-object cache for file dependencies.
Definition: ResourceLoaderModule.php:441
ObjectCache\getLocalClusterInstance
static getLocalClusterInstance()
Get the main cluster-local cache object.
Definition: ObjectCache.php:342
ResourceLoaderModule\getFlip
getFlip(ResourceLoaderContext $context)
Definition: ResourceLoaderModule.php:131
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:117
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:33
ResourceLoaderModule\$contents
array $contents
Map of (context hash => cached module content)
Definition: ResourceLoaderModule.php:64
ResourceLoaderModule\safeFilemtime
static safeFilemtime( $filePath)
Safe version of filemtime(), which doesn't throw a PHP warning if the file doesn't exist.
Definition: ResourceLoaderModule.php:996
ResourceLoaderModule\setName
setName( $name)
Set this module's name.
Definition: ResourceLoaderModule.php:112
ResourceLoaderModule\setLogger
setLogger(LoggerInterface $logger)
Definition: ResourceLoaderModule.php:221
ResourceLoaderModule\saveFileDependencies
saveFileDependencies(ResourceLoaderContext $context, $localFileRefs)
Set the files this module depends on indirectly for a given skin.
Definition: ResourceLoaderModule.php:453
$resourceLoader
$resourceLoader
Definition: load.php:44
ResourceLoaderModule\getHeaders
getHeaders(ResourceLoaderContext $context)
Get headers to send as part of a module web response.
Definition: ResourceLoaderModule.php:603
ResourceLoaderModule\getType
getType()
Get the module's load type.
Definition: ResourceLoaderModule.php:376
ResourceLoaderModule\getTargets
getTargets()
Get target(s) for the module, eg ['desktop'] or ['desktop', 'mobile'].
Definition: ResourceLoaderModule.php:366
ResourceLoaderModule\shouldEmbedModule
shouldEmbedModule(ResourceLoaderContext $context)
Check whether this module should be embeded rather than linked.
Definition: ResourceLoaderModule.php:925
ResourceLoaderModule\getVary
static getVary(ResourceLoaderContext $context)
Get vary string.
Definition: ResourceLoaderModule.php:1022
ResourceLoaderModule\getStyles
getStyles(ResourceLoaderContext $context)
Get all CSS for this module for a given skin.
Definition: ResourceLoaderModule.php:283
ResourceLoaderModule\getTemplates
getTemplates()
Takes named templates by the module and returns an array mapping.
Definition: ResourceLoaderModule.php:191
Xml\encodeJsVar
static encodeJsVar( $value, $pretty=false)
Encode a variable of arbitrary type to JavaScript.
Definition: Xml.php:659
wfDebugLog
wfDebugLog( $logGroup, $text, $dest='all', array $context=[])
Send a line to a supplementary debug log file, if configured, or main debug log if not.
Definition: GlobalFunctions.php:1007
ResourceLoaderModule\getDeprecationInformation
getDeprecationInformation(ResourceLoaderContext $context=null)
Get JS representing deprecation information for the current module if available.
Definition: ResourceLoaderModule.php:142
ResourceLoaderModule\buildContent
buildContent(ResourceLoaderContext $context)
Bundle all resources attached to this module into an array.
Definition: ResourceLoaderModule.php:699
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:89
ResourceLoaderModule\getLessVars
getLessVars(ResourceLoaderContext $context)
Get module-specific LESS variables, if any.
Definition: ResourceLoaderModule.php:671
$dbr
$dbr
Definition: testCompression.php:50
ResourceLoaderModule\enableModuleContentVersion
enableModuleContentVersion()
Whether to generate version hash based on module content.
Definition: ResourceLoaderModule.php:846
Config
Interface for configuration instances.
Definition: Config.php:28
ResourceLoaderModule\getGroup
getGroup()
Get the group this module is in.
Definition: ResourceLoaderModule.php:329
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
Definition: GlobalFunctions.php:1044
ResourceLoaderModule\$jsParser
static JSParser $jsParser
Lazy-initialized; use self::javaScriptParser()
Definition: ResourceLoaderModule.php:930
ResourceLoaderModule\getLogger
getLogger()
Definition: ResourceLoaderModule.php:229
ResourceLoaderModule\getScript
getScript(ResourceLoaderContext $context)
Get all JS for this module for a given language and skin.
Definition: ResourceLoaderModule.php:181
$blob
$blob
Definition: testCompression.php:65
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:2575
ResourceLoaderModule\$origin
int $origin
Script and style modules form a hierarchy of trustworthiness, with core modules like skins and jQuery...
Definition: ResourceLoaderModule.php:50
$IP
$IP
Definition: update.php:3
ResourceLoaderModule\expandRelativePaths
static expandRelativePaths(array $filePaths)
Expand directories relative to $IP.
Definition: ResourceLoaderModule.php:545
DB_REPLICA
const DB_REPLICA
Definition: defines.php:25
ResourceLoaderContext\getLanguage
getLanguage()
Definition: ResourceLoaderContext.php:166
ResourceLoaderModule\$versionHash
array $versionHash
Map of (context hash => cached module version hash)
Definition: ResourceLoaderModule.php:62
DB_MASTER
const DB_MASTER
Definition: defines.php:26
ResourceLoaderModule\getOrigin
getOrigin()
Get this module's origin.
Definition: ResourceLoaderModule.php:123
ResourceLoaderModule\$msgBlobs
array $msgBlobs
Map of (language => in-object cache for message blob)
Definition: ResourceLoaderModule.php:60
ResourceLoaderModule\getMessageBlob
getMessageBlob(ResourceLoaderContext $context)
Get the hash of the message blob.
Definition: ResourceLoaderModule.php:559
ResourceLoaderModule\$parseCacheVersion
static $parseCacheVersion
Definition: ResourceLoaderModule.php:931
ResourceLoaderModule\isKnownEmpty
isKnownEmpty(ResourceLoaderContext $context)
Check whether this module is known to be empty.
Definition: ResourceLoaderModule.php:911
$content
$content
Definition: router.php:78
ResourceLoaderModule\$deprecated
string bool $deprecated
Deprecation string or true if deprecated; false otherwise.
Definition: ResourceLoaderModule.php:67
ResourceLoaderModule\$targets
string[] $targets
What client platforms the module targets (e.g.
Definition: ResourceLoaderModule.php:55
ResourceLoaderModule\safeFileHash
static safeFileHash( $filePath)
Compute a non-cryptographic string hash of a file's contents.
Definition: ResourceLoaderModule.php:1011
ResourceLoaderModule\$name
string null $name
Module name.
Definition: ResourceLoaderModule.php:53
ResourceLoaderModule\getDependencies
getDependencies(ResourceLoaderContext $context=null)
Get a list of modules this module depends on.
Definition: ResourceLoaderModule.php:356
ResourceLoaderModule\getPreloadLinks
getPreloadLinks(ResourceLoaderContext $context)
Get a list of resources that web browsers may preload.
Definition: ResourceLoaderModule.php:660
DerivativeResourceLoaderContext
A mutable version of ResourceLoaderContext.
Definition: DerivativeResourceLoaderContext.php:31
ResourceLoaderModule\getMessages
getMessages()
Get the messages needed for this module.
Definition: ResourceLoaderModule.php:319
ResourceLoaderModule\validateScriptFile
validateScriptFile( $fileName, $contents)
Validate a given script file; if valid returns the original source.
Definition: ResourceLoaderModule.php:941
ResourceLoaderModule\getDefinitionSummary
getDefinitionSummary(ResourceLoaderContext $context)
Get the definition summary for this module.
Definition: ResourceLoaderModule.php:893
ResourceLoaderModule\getModuleContent
getModuleContent(ResourceLoaderContext $context)
Get an array of this module's resources.
Definition: ResourceLoaderModule.php:682
ResourceLoaderModule\getSkipFunction
getSkipFunction()
Get the skip function.
Definition: ResourceLoaderModule.php:394
$context
$context
Definition: load.php:45
ResourceLoaderModule
Abstraction for ResourceLoader modules, with name registration and maxage functionality.
Definition: ResourceLoaderModule.php:37
ResourceLoaderModule\$config
Config $config
Definition: ResourceLoaderModule.php:39
ResourceLoaderModule\$logger
LoggerInterface $logger
Definition: ResourceLoaderModule.php:41
$cache
$cache
Definition: mcc.php:33
ResourceLoaderModule\setConfig
setConfig(Config $config)
Definition: ResourceLoaderModule.php:213
ResourceLoaderModule\getScriptURLsForDebug
getScriptURLsForDebug(ResourceLoaderContext $context)
Get the URL or URLs to load for this module's JS in debug mode.
Definition: ResourceLoaderModule.php:250
$path
$path
Definition: NoLocalSettings.php:25
ResourceLoaderModule\getRelativePaths
static getRelativePaths(array $filePaths)
Make file paths relative to MediaWiki directory.
Definition: ResourceLoaderModule.php:531
ResourceLoaderModule\getFileDependencies
getFileDependencies(ResourceLoaderContext $context)
Get the files this module depends on indirectly for a given skin.
Definition: ResourceLoaderModule.php:406
ResourceLoaderModule\getVersionHash
getVersionHash(ResourceLoaderContext $context)
Get a string identifying the current version of this module in a given context.
Definition: ResourceLoaderModule.php:815
ResourceLoaderModule\getSource
getSource()
Get the source of this module.
Definition: ResourceLoaderModule.php:339
JSParser
Definition: jsminplus.php:674
ResourceLoaderModule\javaScriptParser
static javaScriptParser()
Definition: ResourceLoaderModule.php:982
ResourceLoaderModule\$fileDeps
array $fileDeps
Map of (variant => indirect file dependencies)
Definition: ResourceLoaderModule.php:58
ResourceLoaderModule\getName
getName()
Get this module's name.
Definition: ResourceLoaderModule.php:102
ResourceLoaderModule\getConfig
getConfig()
Definition: ResourceLoaderModule.php:200