*
* See OutputPage::buildExemptModules() for use cases.
*
- * @param array $modules Module state keyed by module name
+ * @param array $states Module state keyed by module name
*/
public function setExemptStates( array $states ) {
$this->exemptStates = $states;
continue;
}
- $group = $module->getGroup();
-
- if ( $group === 'private' ) {
+ if ( $module->shouldEmbedModule( $this->context ) ) {
// Embed via mw.loader.implement per T36907.
$data['embed']['general'][] = $name;
// Avoid duplicate request from mw.loader
if ( $module->getType() !== ResourceLoaderModule::LOAD_STYLES ) {
$logger = $rl->getLogger();
- $logger->warning( 'Unexpected general module "{module}" in styles queue.', [
+ $logger->error( 'Unexpected general module "{module}" in styles queue.', [
'module' => $name,
] );
- } else {
- // Stylesheet doesn't trigger mw.loader callback.
- // Set "ready" state to allow dependencies and avoid duplicate requests. (T87871)
- $data['states'][$name] = 'ready';
+ continue;
}
+ // Stylesheet doesn't trigger mw.loader callback.
+ // Set "ready" state to allow dependencies and avoid duplicate requests. (T87871)
+ $data['states'][$name] = 'ready';
+
$group = $module->getGroup();
$context = $this->getContext( $group, ResourceLoaderModule::TYPE_STYLES );
if ( $module->isKnownEmpty( $context ) ) {
// Avoid needless request for empty module
$data['states'][$name] = 'ready';
} else {
- if ( $group === 'private' ) {
+ if ( $module->shouldEmbedModule( $this->context ) ) {
// Embed via style element
$data['embed']['styles'][] = $name;
// Avoid duplicate request from mw.loader
sort( $modules );
if ( $mainContext->getDebug() && count( $modules ) > 1 ) {
-
$chunks = [];
// Recursively call us for every item
foreach ( $modules as $name ) {
foreach ( $sortedModules as $source => $groups ) {
foreach ( $groups as $group => $grpModules ) {
$context = self::makeContext( $mainContext, $group, $only, $extraQuery );
- $context->setModules( array_keys( $grpModules ) );
-
- if ( $group === 'private' ) {
- // Decide whether to use style or script element
- if ( $only == ResourceLoaderModule::TYPE_STYLES ) {
- $chunks[] = Html::inlineStyle(
- $rl->makeModuleResponse( $context, $grpModules )
- );
- } else {
- $chunks[] = ResourceLoader::makeInlineScript(
- $rl->makeModuleResponse( $context, $grpModules )
- );
- }
- continue;
- }
-
- // See if we have one or more raw modules
- $isRaw = false;
- foreach ( $grpModules as $key => $module ) {
- $isRaw |= $module->isRaw();
- }
- // Special handling for the user group; because users might change their stuff
- // on-wiki like user pages, or user preferences; we need to find the highest
- // timestamp of these user-changeable modules so we can ensure cache misses on change
- // This should NOT be done for the site group (T29564) because anons get that too
- // and we shouldn't be putting timestamps in CDN-cached HTML
- if ( $group === 'user' ) {
- // Must setModules() before makeVersionQuery()
- $context->setVersion( $rl->makeVersionQuery( $context ) );
+ // Separate sets of linked and embedded modules while preserving order
+ $moduleSets = [];
+ $idx = -1;
+ foreach ( $grpModules as $name => $module ) {
+ $shouldEmbed = $module->shouldEmbedModule( $context );
+ if ( !$moduleSets || $moduleSets[$idx][0] !== $shouldEmbed ) {
+ $moduleSets[++$idx] = [ $shouldEmbed, [] ];
+ }
+ $moduleSets[$idx][1][$name] = $module;
}
- $url = $rl->createLoaderURL( $source, $context, $extraQuery );
-
- // Decide whether to use 'style' or 'script' element
- if ( $only === ResourceLoaderModule::TYPE_STYLES ) {
- $chunk = Html::linkedStyle( $url );
- } else {
- if ( $context->getRaw() || $isRaw ) {
- $chunk = Html::element( 'script', [
- // In SpecialJavaScriptTest, QUnit must load synchronous
- 'async' => !isset( $extraQuery['sync'] ),
- 'src' => $url
- ] );
+ // Link/embed each set
+ foreach ( $moduleSets as list( $embed, $moduleSet ) ) {
+ $context->setModules( array_keys( $moduleSet ) );
+ if ( $embed ) {
+ // Decide whether to use style or script element
+ if ( $only == ResourceLoaderModule::TYPE_STYLES ) {
+ $chunks[] = Html::inlineStyle(
+ $rl->makeModuleResponse( $context, $moduleSet )
+ );
+ } else {
+ $chunks[] = ResourceLoader::makeInlineScript(
+ $rl->makeModuleResponse( $context, $moduleSet )
+ );
+ }
} else {
- $chunk = ResourceLoader::makeInlineScript(
- Xml::encodeJsCall( 'mw.loader.load', [ $url ] )
- );
+ // See if we have one or more raw modules
+ $isRaw = false;
+ foreach ( $moduleSet as $key => $module ) {
+ $isRaw |= $module->isRaw();
+ }
+
+ // Special handling for the user group; because users might change their stuff
+ // on-wiki like user pages, or user preferences; we need to find the highest
+ // timestamp of these user-changeable modules so we can ensure cache misses on change
+ // This should NOT be done for the site group (T29564) because anons get that too
+ // and we shouldn't be putting timestamps in CDN-cached HTML
+ if ( $group === 'user' ) {
+ // Must setModules() before makeVersionQuery()
+ $context->setVersion( $rl->makeVersionQuery( $context ) );
+ }
+
+ $url = $rl->createLoaderURL( $source, $context, $extraQuery );
+
+ // Decide whether to use 'style' or 'script' element
+ if ( $only === ResourceLoaderModule::TYPE_STYLES ) {
+ $chunk = Html::linkedStyle( $url );
+ } else {
+ if ( $context->getRaw() || $isRaw ) {
+ $chunk = Html::element( 'script', [
+ // In SpecialJavaScriptTest, QUnit must load synchronous
+ 'async' => !isset( $extraQuery['sync'] ),
+ 'src' => $url
+ ] );
+ } else {
+ $chunk = ResourceLoader::makeInlineScript(
+ Xml::encodeJsCall( 'mw.loader.load', [ $url ] )
+ );
+ }
+ }
+
+ if ( $group == 'noscript' ) {
+ $chunks[] = Html::rawElement( 'noscript', [], $chunk );
+ } else {
+ $chunks[] = $chunk;
+ }
}
}
-
- if ( $group == 'noscript' ) {
- $chunks[] = Html::rawElement( 'noscript', [], $chunk );
- } else {
- $chunks[] = $chunk;
- }
}
}