resourceloader: Track state of page-style modules

This allows dynamically loaded modules to depend on page-style modules
without it causing the page-style module to be loaded a second time.

* New method Module::getType() indicates whether a module is
  a page-style module or supposed to be dynamically loaded.

* Emit warning from addModuleStyles() when given a module that is
  not a page-style module (to be enforced later)

Bug: T92459
Bug: T87871
Change-Id: I8b6c6a10d965e73965f877c42e995d04202524f3
This commit is contained in:
Timo Tijhof 2016-05-10 20:00:44 +01:00
parent a29c7cdede
commit a464d1d41d
6 changed files with 77 additions and 0 deletions

View file

@ -2785,6 +2785,17 @@ class OutputPage extends ContextSource {
continue;
}
if ( $only === ResourceLoaderModule::TYPE_STYLES ) {
if ( $module->getType() !== ResourceLoaderModule::LOAD_STYLES ) {
$logger = $resourceLoader->getLogger();
$logger->debug( 'Unexpected general module "{module}" in styles queue.', [
'module' => $name,
] );
} else {
$links['states'][$name] = 'ready';
}
}
$sortedModules[$module->getSource()][$module->getGroup()][$name] = $module;
}

View file

@ -922,6 +922,28 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
return $this->targets;
}
/**
* Get the module's load type.
*
* @since 1.28
* @return string
*/
public function getType() {
$canBeStylesOnly = !(
// All options except 'styles', 'skinStyles' and 'debugRaw'
$this->scripts
|| $this->debugScripts
|| $this->templates
|| $this->languageScripts
|| $this->skinScripts
|| $this->dependencies
|| $this->messages
|| $this->skipFunction
|| $this->raw
);
return $canBeStylesOnly ? self::LOAD_STYLES : self::LOAD_GENERAL;
}
/**
* Compile a LESS file into CSS.
*

View file

@ -35,6 +35,12 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
const TYPE_STYLES = 'styles';
const TYPE_COMBINED = 'combined';
# Desired load type
// Module only has styles (loaded via <style> or <link rel=stylesheet>)
const LOAD_STYLES = 'styles';
// Module may have other resources (loaded via mw.loader from a script)
const LOAD_GENERAL = 'general';
# sitewide core module like a skin file or jQuery component
const ORIGIN_CORE_SITEWIDE = 1;
@ -343,6 +349,16 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
return $this->targets;
}
/**
* Get the module's load type.
*
* @since 1.28
* @return string ResourceLoaderModule LOAD_* constant
*/
public function getType() {
return self::LOAD_GENERAL;
}
/**
* Get the skip function.
*

View file

@ -43,4 +43,11 @@ class ResourceLoaderSiteStylesModule extends ResourceLoaderWikiModule {
}
return $pages;
}
/**
* @return string
*/
public function getType() {
return self::LOAD_STYLES;
}
}

View file

@ -83,4 +83,11 @@ class ResourceLoaderUserCSSPrefsModule extends ResourceLoaderModule {
public function getGroup() {
return 'private';
}
/**
* @return string
*/
public function getType() {
return self::LOAD_STYLES;
}
}

View file

@ -321,7 +321,21 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
return $this->titleInfo[$key];
}
/**
* @return string
*/
public function getPosition() {
return $this->position;
}
/**
* @since 1.28
* @return string
*/
public function getType() {
// Check both because subclasses don't always pass pages via the constructor,
// they may also override getPages() instead, in which case we should keep
// defaulting to LOAD_GENERAL and allow them to override getType() separately.
return ( $this->styles && !$this->scripts ) ? self::LOAD_STYLES : self::LOAD_GENERAL;
}
}