25use Wikimedia\Assert\Assert;
56 protected $origin = self::ORIGIN_USER_SITEWIDE;
87 if ( $options ===
null ) {
91 foreach ( $options as $member => $option ) {
97 $this->{$member} = $option;
125 foreach ( $this->scripts as $script ) {
126 $pages[$script] = [
'type' =>
'script' ];
131 foreach ( $this->styles as $style ) {
132 $pages[$style] = [
'type' =>
'style' ];
173 $title = Title::newFromText( $titleText );
183 $handler =
$content->getContentHandler();
192 return $content->serialize( $format );
206 $overrideCallback =
$context->getContentOverrideCallback();
207 $content = $overrideCallback ? call_user_func( $overrideCallback,
$title ) :
null;
211 'Bad content override for "{title}" in ' . __METHOD__,
212 [
'title' =>
$title->getPrefixedText() ]
221 $content = $revision->getContent( RevisionRecord::RAW );
225 'Failed to load content of JS/CSS page "{title}" in ' . __METHOD__,
226 [
'title' =>
$title->getPrefixedText() ]
233 if ( $maxRedirects ===
null ) {
234 $maxRedirects = $this->
getConfig()->get(
'MaxRedirects' ) ?: 0;
236 if ( $maxRedirects > 0 ) {
237 $newTitle =
$content->getRedirectTarget();
250 $overrideCallback =
$context->getContentOverrideCallback();
251 if ( $overrideCallback && $this->
getSource() ===
'local' ) {
253 $title = Title::newFromText( $page );
254 if (
$title && call_user_func( $overrideCallback,
$title ) !==
null ) {
260 return parent::shouldEmbedModule(
$context );
270 if ( $options[
'type'] !==
'script' ) {
274 if ( strval( $script ) !==
'' ) {
276 $scripts .= ResourceLoader::makeComment( $titleText ) . $script .
"\n";
289 if ( $options[
'type'] !==
'style' ) {
292 $media = $options[
'media'] ??
'all';
294 if ( strval( $style ) ===
'' ) {
298 $style = CSSJanus::transform( $style,
true,
false );
301 [ $style,
false, $this->
getConfig()->
get(
'ScriptPath' ),
true ] );
302 if ( !isset(
$styles[$media] ) ) {
305 $style = ResourceLoader::makeComment( $titleText ) . $style;
330 $summary = parent::getDefinitionSummary(
$context );
351 if ( $this->
getGroup() ===
'user' ) {
352 foreach ( $revisions as $revision ) {
353 if ( $revision[
'page_len'] > 0 ) {
364 return count( $revisions ) === 0;
368 $this->titleInfo[$batchKey] = $titleInfo;
373 return "{$title->getNamespace()}:{$title->getDBkey()}";
386 $batchKey = implode(
'|', $pageNames );
387 if ( !isset( $this->titleInfo[$batchKey] ) ) {
388 $this->titleInfo[$batchKey] = static::fetchTitleInfo(
$dbr, $pageNames, __METHOD__ );
394 $overrideCallback =
$context->getContentOverrideCallback();
395 if ( $overrideCallback ) {
396 foreach ( $pageNames as $page ) {
397 $title = Title::newFromText( $page );
402 'page_latest' =>
'TBD',
416 foreach ( $pages as $titleText ) {
417 $title = Title::newFromText( $titleText );
423 if ( !$batch->isEmpty() ) {
426 [
'page_namespace',
'page_title',
'page_touched',
'page_len',
'page_latest' ],
427 $batch->constructSet(
'page', $db ),
430 foreach (
$res as $row ) {
435 'page_len' => $row->page_len,
436 'page_latest' => $row->page_latest,
437 'page_touched' => $row->page_touched,
453 $rl =
$context->getResourceLoader();
459 foreach ( $moduleNames as
$name ) {
460 $module = $rl->getModule( $name );
461 if ( $module instanceof
self ) {
462 $mDB = $module->getDB();
464 if ( $mDB->getDomainID() === $db->
getDomainID() ) {
465 $wikiModules[] = $module;
466 $allPages += $module->getPages(
$context );
471 if ( !$wikiModules ) {
476 $pageNames = array_keys( $allPages );
478 $hash = sha1( implode(
'|', $pageNames ) );
481 $func = [ static::class,
'fetchTitleInfo' ];
484 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
485 $allInfo =
$cache->getWithSetCallback(
488 function ( $curVal, &$ttl, array &$setOpts ) use ( $func, $pageNames, $db, $fname ) {
489 $setOpts += Database::getCacheSetOptions( $db );
491 return call_user_func( $func, $db, $pageNames, $fname );
499 foreach ( $wikiModules as $wikiModule ) {
500 $pages = $wikiModule->getPages(
$context );
503 foreach ( $pages as $pageName => $unused ) {
504 $title = Title::newFromText( $pageName );
506 $intersect[ self::makeTitleKey(
$title ) ] = 1;
509 $rl->getLogger()->info(
510 'Invalid wiki page title "{title}" in ' . __METHOD__,
511 [
'title' => $pageName ]
515 $info = array_intersect_key( $allInfo, $intersect );
516 $pageNames = array_keys( $pages );
518 $batchKey = implode(
'|', $pageNames );
519 $wikiModule->setTitleInfo( $batchKey, $info );
538 Assert::parameterType(
'string', $domain,
'$domain' );
542 if ( $old && in_array( $old->getContentFormat(), $formats ) ) {
544 } elseif ( $new && in_array( $new->getContentFormat(), $formats ) ) {
547 $purge = (
$title->isSiteConfigPage() ||
$title->isUserConfigPage() );
551 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
552 $key =
$cache->makeGlobalKey(
'resourceloader-titleinfo', $domain );
553 $cache->touchCheckKey( $key );
565 return ( $this->styles && !$this->scripts ) ? self::LOAD_STYLES : self::LOAD_GENERAL;
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Class representing a list of titles The execute() method checks them all for existence and adds them ...
static call( $callable, array $args=[], $ttl=3600)
Shortcut method for creating a MemoizedCallable and invoking it with the specified arguments.
Context object that contains information about the state of a specific ResourceLoader web request.
Abstraction for ResourceLoader modules, with name registration and maxage functionality.
getDependencies(ResourceLoaderContext $context=null)
Get a list of modules this module depends on.
validateScriptFile( $fileName, $contents)
Validate a given script file; if valid returns the original source.
getFlip(ResourceLoaderContext $context)
string null $name
Module name.
getSource()
Get the source of this module.
Abstraction for ResourceLoader modules which pull from wiki pages.
getTitleInfo(ResourceLoaderContext $context)
Get the information about the wiki pages for a given context.
getDB()
Get the Database handle used for computing the module version.
__construct(array $options=null)
static preloadTitleInfo(ResourceLoaderContext $context, IDatabase $db, array $moduleNames)
enableModuleContentVersion()
Disable module content versioning.
getPages(ResourceLoaderContext $context)
Subclasses should return an associative array of resources in the module.
shouldEmbedModule(ResourceLoaderContext $context)
static fetchTitleInfo(IDatabase $db, array $pages, $fname=__METHOD__)
static makeTitleKey(LinkTarget $title)
getDefinitionSummary(ResourceLoaderContext $context)
setTitleInfo( $batchKey, array $titleInfo)
getStyles(ResourceLoaderContext $context)
isKnownEmpty(ResourceLoaderContext $context)
getGroup()
Get group name.
getContent( $titleText, ResourceLoaderContext $context)
getContentObj(Title $title, ResourceLoaderContext $context, $maxRedirects=null)
getScript(ResourceLoaderContext $context)
static invalidateModuleCache(Title $title, Revision $old=null, Revision $new=null, $domain)
Clear the preloadTitleInfo() cache for all wiki modules on this wiki on page change if it was a JS or...
Represents a page (or page fragment) title within MediaWiki.
Represents a title within MediaWiki.
const CONTENT_FORMAT_JAVASCRIPT
get( $name)
Get a configuration variable such as "Sitename" or "UploadMaintenance.".
Base interface for content objects.