resourceloader: Remove top/bottom queue distinction
* The styles queue has always been top-only
(except for a few months in 2015).
* The top queue loads asynchronous since mid-2015. (T107399)
And LocalStorage eval, previously the last remaining non-async part
of module loading, is also async as of October 2016. (T142129)
* This change merges the bottom 'mw.loader.load()' queue with the top queue.
It also moves any other snippets potentially in the bottom queue still:
- embed: I couldn't find any private modules with position=bottom
(doesn't make sense due to their blocking nature). If any do exist,
(third-party extensions?), they'll now be embedded in the <head>.
- scripts: Any legacy 'only=scripts' requests will now initiate
from the <head>.
Bug: T109837
Change-Id: I6c21e3e47c23df33a04c42ce94bd4c1964599c7f
This commit is contained in:
parent
2196833990
commit
bc374082fa
3 changed files with 23 additions and 69 deletions
|
|
@ -130,26 +130,15 @@ class ResourceLoaderClientHtml {
|
|||
'states' => [
|
||||
// moduleName => state
|
||||
],
|
||||
'general' => [
|
||||
// position => [ moduleName ]
|
||||
'top' => [],
|
||||
'bottom' => [],
|
||||
],
|
||||
'general' => [],
|
||||
'styles' => [
|
||||
// moduleName
|
||||
],
|
||||
'scripts' => [
|
||||
// position => [ moduleName ]
|
||||
'top' => [],
|
||||
'bottom' => [],
|
||||
],
|
||||
'scripts' => [],
|
||||
// Embedding for private modules
|
||||
'embed' => [
|
||||
'styles' => [],
|
||||
'general' => [
|
||||
'top' => [],
|
||||
'bottom' => [],
|
||||
],
|
||||
'general' => [],
|
||||
],
|
||||
|
||||
];
|
||||
|
|
@ -161,16 +150,15 @@ class ResourceLoaderClientHtml {
|
|||
}
|
||||
|
||||
$group = $module->getGroup();
|
||||
$position = $module->getPosition();
|
||||
|
||||
if ( $group === 'private' ) {
|
||||
// Embed via mw.loader.implement per T36907.
|
||||
$data['embed']['general'][$position][] = $name;
|
||||
$data['embed']['general'][] = $name;
|
||||
// Avoid duplicate request from mw.loader
|
||||
$data['states'][$name] = 'loading';
|
||||
} else {
|
||||
// Load via mw.loader.load()
|
||||
$data['general'][$position][] = $name;
|
||||
$data['general'][] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -216,14 +204,13 @@ class ResourceLoaderClientHtml {
|
|||
}
|
||||
|
||||
$group = $module->getGroup();
|
||||
$position = $module->getPosition();
|
||||
$context = $this->getContext( $group, ResourceLoaderModule::TYPE_SCRIPTS );
|
||||
if ( $module->isKnownEmpty( $context ) ) {
|
||||
// Avoid needless request for empty module
|
||||
$data['states'][$name] = 'ready';
|
||||
} else {
|
||||
// Load from load.php?only=scripts via <script src></script>
|
||||
$data['scripts'][$position][] = $name;
|
||||
$data['scripts'][] = $name;
|
||||
|
||||
// Avoid duplicate request from mw.loader
|
||||
$data['states'][$name] = 'loading';
|
||||
|
|
@ -282,24 +269,24 @@ class ResourceLoaderClientHtml {
|
|||
}
|
||||
|
||||
// Inline RLQ: Embedded modules
|
||||
if ( $data['embed']['general']['top'] ) {
|
||||
if ( $data['embed']['general'] ) {
|
||||
$chunks[] = $this->getLoad(
|
||||
$data['embed']['general']['top'],
|
||||
$data['embed']['general'],
|
||||
ResourceLoaderModule::TYPE_COMBINED
|
||||
);
|
||||
}
|
||||
|
||||
// Inline RLQ: Load general modules
|
||||
if ( $data['general']['top'] ) {
|
||||
if ( $data['general'] ) {
|
||||
$chunks[] = ResourceLoader::makeInlineScript(
|
||||
Xml::encodeJsCall( 'mw.loader.load', [ $data['general']['top'] ] )
|
||||
Xml::encodeJsCall( 'mw.loader.load', [ $data['general'] ] )
|
||||
);
|
||||
}
|
||||
|
||||
// Inline RLQ: Load only=scripts
|
||||
if ( $data['scripts']['top'] ) {
|
||||
if ( $data['scripts'] ) {
|
||||
$chunks[] = $this->getLoad(
|
||||
$data['scripts']['top'],
|
||||
$data['scripts'],
|
||||
ResourceLoaderModule::TYPE_SCRIPTS
|
||||
);
|
||||
}
|
||||
|
|
@ -336,33 +323,7 @@ class ResourceLoaderClientHtml {
|
|||
* @return string|WrappedStringList HTML
|
||||
*/
|
||||
public function getBodyHtml() {
|
||||
$data = $this->getData();
|
||||
$chunks = [];
|
||||
|
||||
// Inline RLQ: Embedded modules
|
||||
if ( $data['embed']['general']['bottom'] ) {
|
||||
$chunks[] = $this->getLoad(
|
||||
$data['embed']['general']['bottom'],
|
||||
ResourceLoaderModule::TYPE_COMBINED
|
||||
);
|
||||
}
|
||||
|
||||
// Inline RLQ: Load only=scripts
|
||||
if ( $data['scripts']['bottom'] ) {
|
||||
$chunks[] = $this->getLoad(
|
||||
$data['scripts']['bottom'],
|
||||
ResourceLoaderModule::TYPE_SCRIPTS
|
||||
);
|
||||
}
|
||||
|
||||
// Inline RLQ: Load general modules
|
||||
if ( $data['general']['bottom'] ) {
|
||||
$chunks[] = ResourceLoader::makeInlineScript(
|
||||
Xml::encodeJsCall( 'mw.loader.load', [ $data['general']['bottom'] ] )
|
||||
);
|
||||
}
|
||||
|
||||
return WrappedStringList::join( "\n", $chunks );
|
||||
return '';
|
||||
}
|
||||
|
||||
private function getContext( $group, $type ) {
|
||||
|
|
|
|||
|
|
@ -330,14 +330,13 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
|
|||
}
|
||||
|
||||
/**
|
||||
* Where on the HTML page should this module's JS be loaded?
|
||||
* - 'top': in the "<head>"
|
||||
* - 'bottom': at the bottom of the "<body>"
|
||||
* From where in the page HTML should this module be loaded?
|
||||
*
|
||||
* @deprecated since 1.29 Obsolete. All modules load async from `<head>`.
|
||||
* @return string
|
||||
*/
|
||||
public function getPosition() {
|
||||
return 'bottom';
|
||||
return 'top';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -114,22 +114,22 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
|
|||
'test.scripts.mixed.user.empty' => 'ready',
|
||||
],
|
||||
'general' => [
|
||||
'top' => [ 'test.top' ],
|
||||
'bottom' => [ 'test' ],
|
||||
'test',
|
||||
'test.top',
|
||||
],
|
||||
'styles' => [
|
||||
'test.styles.mixed',
|
||||
'test.styles.pure',
|
||||
],
|
||||
'scripts' => [
|
||||
'top' => [ 'test.scripts.top' ],
|
||||
'bottom' => [ 'test.scripts' ],
|
||||
'test.scripts',
|
||||
'test.scripts.top',
|
||||
],
|
||||
'embed' => [
|
||||
'styles' => [ 'test.styles.private' ],
|
||||
'general' => [
|
||||
'top' => [ 'test.private.top' ],
|
||||
'bottom' => [ 'test.private.bottom' ],
|
||||
'test.private.bottom',
|
||||
'test.private.top',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
|
@ -202,13 +202,7 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
|
|||
'test.scripts',
|
||||
] );
|
||||
|
||||
// @codingStandardsIgnoreStart Generic.Files.LineLength
|
||||
$expected = '<script>(window.RLQ=window.RLQ||[]).push(function(){'
|
||||
. 'mw.loader.implement("test.private.bottom@{blankVer}",function($,jQuery,require,module){},{"css":[]});'
|
||||
. 'mw.loader.load("/w/load.php?debug=false\u0026lang=nl\u0026modules=test.scripts\u0026only=scripts\u0026skin=fallback");'
|
||||
. 'mw.loader.load(["test"]);'
|
||||
. '});</script>';
|
||||
// @codingStandardsIgnoreEnd
|
||||
$expected = '';
|
||||
$expected = self::expandVariables( $expected );
|
||||
|
||||
$this->assertEquals( $expected, $client->getBodyHtml() );
|
||||
|
|
|
|||
Loading…
Reference in a new issue