21 use Wikimedia\WrappedString;
22 use Wikimedia\WrappedStringList;
79 foreach ( $vars as $key => $value ) {
80 $this->config[$key] = $value;
110 $this->exemptStates = $states;
136 'styleDeprecations' => [],
139 foreach ( $this->modules as $name ) {
140 $module = $rl->getModule( $name );
145 $group = $module->getGroup();
147 $shouldEmbed = $module->shouldEmbedModule( $this->context );
149 if ( ( $group ===
'user' || $shouldEmbed ) && $module->isKnownEmpty(
$context ) ) {
154 $data[
'states'][$name] =
'ready';
155 } elseif ( $group ===
'user' || $shouldEmbed ) {
161 $data[
'embed'][
'general'][] = $name;
163 $data[
'states'][$name] =
'loading';
166 $data[
'general'][] = $name;
170 foreach ( $this->moduleStyles as $name ) {
171 $module = $rl->getModule( $name );
176 if ( $module->getType() !== ResourceLoaderModule::LOAD_STYLES ) {
177 $logger = $rl->getLogger();
178 $logger->error(
'Unexpected general module "{module}" in styles queue.', [
187 $data[
'states'][$name] =
'ready';
189 $group = $module->getGroup();
191 if ( $module->shouldEmbedModule( $this->context ) ) {
194 if ( !$module->isKnownEmpty(
$context ) ) {
196 $data[
'embed'][
'styles'][] = $name;
212 } elseif ( $group !==
'user' || !$module->isKnownEmpty(
$context ) ) {
214 $data[
'styles'][] = $name;
216 $deprecation = $module->getDeprecationInformation(
$context );
217 if ( $deprecation ) {
218 $data[
'styleDeprecations'][] = $deprecation;
229 return [
'class' =>
'client-nojs' ];
248 $nonce = $this->options[
'nonce'];
256 $jsClass = preg_replace(
'/(^|\s)client-nojs(\s|$)/',
'$1client-js$2', $nojsClass );
257 $jsClassJson = $this->context->encodeJson( $jsClass );
258 $script = <<<JAVASCRIPT
259 document.documentElement.className = {$jsClassJson};
263 if ( $this->config ) {
264 $confJson = $this->context->encodeJson( $this->config );
265 $script .= <<<JAVASCRIPT
266 RLCONF = {$confJson};
271 $states = array_merge( $this->exemptStates,
$data[
'states'] );
273 $stateJson = $this->context->encodeJson( $states );
274 $script .= <<<JAVASCRIPT
275 RLSTATE = {$stateJson};
280 if (
$data[
'general'] ) {
281 $pageModulesJson = $this->context->encodeJson(
$data[
'general'] );
282 $script .= <<<JAVASCRIPT
283 RLPAGEMODULES = {$pageModulesJson};
287 if ( !$this->context->getDebug() ) {
288 $script = ResourceLoader::filter(
'minify-js', $script, [
'cache' =>
false ] );
291 $chunks[] = Html::inlineScript( $script, $nonce );
294 if (
$data[
'embed'][
'general'] ) {
296 $data[
'embed'][
'general'],
297 ResourceLoaderModule::TYPE_COMBINED,
303 if (
$data[
'styles'] ) {
306 ResourceLoaderModule::TYPE_STYLES,
312 if (
$data[
'embed'][
'styles'] ) {
314 $data[
'embed'][
'styles'],
315 ResourceLoaderModule::TYPE_STYLES,
322 $startupQuery = [
'raw' =>
'1' ];
323 foreach ( [
'target',
'safemode' ] as $param ) {
324 if ( $this->options[$param] !==
null ) {
325 $startupQuery[$param] = (string)$this->options[$param];
330 ResourceLoaderModule::TYPE_SCRIPTS,
335 return WrappedString::join(
"\n", $chunks );
346 if (
$data[
'styleDeprecations'] ) {
347 $chunks[] = ResourceLoader::makeInlineScript(
348 implode(
'',
$data[
'styleDeprecations'] ),
349 $this->options[
'nonce']
353 return WrappedString::join(
"\n", $chunks );
365 array $extraQuery = []
370 $req->setVal(
'only',
$type === ResourceLoaderModule::TYPE_COMBINED ?
null :
$type );
372 if ( $group !==
'user' && $group !==
'private' ) {
373 $req->setVal(
'user',
null );
394 array $extraQuery = [], $nonce =
null
406 $chunks[] =
self::makeLoad( $mainContext, [ $name ], $only, $extraQuery, $nonce );
408 return new WrappedStringList(
"\n", $chunks );
414 $module = $rl->getModule( $name );
416 $rl->getLogger()->warning(
'Unknown module "{module}"', [
'module' => $name ] );
419 $sortedModules[$module->getSource()][$module->getGroup()][$name] = $module;
422 foreach ( $sortedModules as
$source => $groups ) {
423 foreach ( $groups as $group => $grpModules ) {
429 foreach ( $grpModules as $name => $module ) {
430 $shouldEmbed = $module->shouldEmbedModule(
$context );
431 if ( !$moduleSets || $moduleSets[$idx][0] !== $shouldEmbed ) {
432 $moduleSets[++$idx] = [ $shouldEmbed, [] ];
434 $moduleSets[$idx][1][$name] = $module;
438 foreach ( $moduleSets as list( $embed, $moduleSet ) ) {
439 $moduleSetNames = array_keys( $moduleSet );
440 $context->setModules( $moduleSetNames );
443 if ( $only == ResourceLoaderModule::TYPE_STYLES ) {
444 $chunks[] = Html::inlineStyle(
445 $rl->makeModuleResponse(
$context, $moduleSet )
448 $chunks[] = ResourceLoader::makeInlineScript(
449 $rl->makeModuleResponse(
$context, $moduleSet ),
459 if ( $group ===
'user' ) {
467 if ( $only === ResourceLoaderModule::TYPE_STYLES ) {
468 $chunk = Html::linkedStyle( $url );
476 $chunk = Html::element(
'script', [
478 'async' => !isset( $extraQuery[
'sync'] ),
482 $chunk = ResourceLoader::makeInlineScript(
483 'mw.loader.load(' . $mainContext->
encodeJson( $url ) .
');',
488 if ( $group ==
'noscript' ) {
489 $chunks[] = Html::rawElement(
'noscript', [], $chunk );
498 return new WrappedStringList(
"\n", $chunks );