2013-10-18 13:34:50 +00:00
|
|
|
<?php
|
|
|
|
|
|
2022-05-16 14:43:33 +00:00
|
|
|
class ResourceLoaderModuleTest extends ResourceLoaderTestCase {
|
2013-10-18 13:34:50 +00:00
|
|
|
|
|
|
|
|
/**
|
2022-05-16 14:43:33 +00:00
|
|
|
* @covers ResourceLoaderModule::getVersionHash
|
2013-10-18 13:34:50 +00:00
|
|
|
*/
|
2015-06-18 18:57:16 +00:00
|
|
|
public function testGetVersionHash() {
|
resourceloader: Skip version hash calculation in debug mode
=== Why
* More speed
In debug mode, the server should regenerate the startup manifest
on each page view to ensure immediate effect of changes. But,
this also means more version recomputation work on the server.
For most modules, this was already quite fast on repeat views
because of OS-level file caches, and our file-hash caches and
LESS compile caches in php-apcu from ResourceLoader.
But, this makes it even faster.
* Better integration with browser devtools.
Breakpoints stay more consistently across browsers when the
URL stays the same even after you have changed the file and
reloaded the page. For static files, I believe most browsers ignore
query parameters. But for package files that come from load.php,
this was harder for browsers to guess correctly which old script URL
is logically replaced by a different one on the next page view.
=== How
Change Module::getVersionHash to return empty strings in debug mode.
I considered approaching this from StartupModule::getModuleRegistrations
instead to make the change apply only to the client-side manifest.
I decided against this because we have other calls to getVersionHash
on the server-side (such as for E-Tag calculation, and formatting
cross-wiki URLs) which would then not match the version queries that
mw.loader formats in debug mode.
Also, those calls would still be incurring some the avoidable costs.
=== Notes
* The two test cases for verifying the graceful fallback in production
if version hash computations throw an exception, were moved to a
non-debug test case as no longer happen now during the debug
(unminified) test cases.
* Avoid "PHP Notice: Undefined offset 0" in testMakeModuleResponseStartupError
by adding a fallback to empty string so that if the test fails,
it fails in a more useful way instead of aborting with this error
before the assertion happens. (Since PHPUnit generally stops on the
first error.)
* In practice, there are still "version" query parameters and E-Tag
headers in debug mode. These are not module versions, but URL
"combined versions" crafted by getCombinedVersion() in JS and PHP.
These return the constant "ztntf" in debug mode, which is the hash
of an empty string. We could alter these methods to special-case
when all inputs are and join to a still-empty string, or maybe we
just leave them be. I've done the latter for now.
Bug: T235672
Bug: T85805
Change-Id: I0e63eef4f85b13089a0aa3806a5b6f821d527a92
2021-08-28 02:53:36 +00:00
|
|
|
$context = $this->getResourceLoaderContext( [ 'debug' => 'false' ] );
|
2013-10-18 13:34:50 +00:00
|
|
|
|
2016-02-17 09:09:32 +00:00
|
|
|
$baseParams = [
|
|
|
|
|
'scripts' => [ 'foo.js', 'bar.js' ],
|
|
|
|
|
'dependencies' => [ 'jquery', 'mediawiki' ],
|
|
|
|
|
'messages' => [ 'hello', 'world' ],
|
|
|
|
|
];
|
2013-10-18 13:34:50 +00:00
|
|
|
|
2022-05-16 14:43:33 +00:00
|
|
|
$module = new ResourceLoaderFileModule( $baseParams );
|
2015-06-18 18:57:16 +00:00
|
|
|
$version = json_encode( $module->getVersionHash( $context ) );
|
2013-10-18 13:34:50 +00:00
|
|
|
|
|
|
|
|
// Exactly the same
|
2022-05-16 14:43:33 +00:00
|
|
|
$module = new ResourceLoaderFileModule( $baseParams );
|
2013-10-18 13:34:50 +00:00
|
|
|
$this->assertEquals(
|
2015-06-18 18:57:16 +00:00
|
|
|
$version,
|
|
|
|
|
json_encode( $module->getVersionHash( $context ) ),
|
2013-10-18 13:34:50 +00:00
|
|
|
'Instance is insignificant'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Re-order dependencies
|
2022-05-16 14:43:33 +00:00
|
|
|
$module = new ResourceLoaderFileModule( [
|
2016-02-17 09:09:32 +00:00
|
|
|
'dependencies' => [ 'mediawiki', 'jquery' ],
|
|
|
|
|
] + $baseParams );
|
2013-10-18 13:34:50 +00:00
|
|
|
$this->assertEquals(
|
2015-06-18 18:57:16 +00:00
|
|
|
$version,
|
|
|
|
|
json_encode( $module->getVersionHash( $context ) ),
|
2013-10-18 13:34:50 +00:00
|
|
|
'Order of dependencies is insignificant'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Re-order messages
|
2022-05-16 14:43:33 +00:00
|
|
|
$module = new ResourceLoaderFileModule( [
|
2016-02-17 09:09:32 +00:00
|
|
|
'messages' => [ 'world', 'hello' ],
|
|
|
|
|
] + $baseParams );
|
2013-10-18 13:34:50 +00:00
|
|
|
$this->assertEquals(
|
2015-06-18 18:57:16 +00:00
|
|
|
$version,
|
|
|
|
|
json_encode( $module->getVersionHash( $context ) ),
|
2013-10-18 13:34:50 +00:00
|
|
|
'Order of messages is insignificant'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Re-order scripts
|
2022-05-16 14:43:33 +00:00
|
|
|
$module = new ResourceLoaderFileModule( [
|
2016-02-17 09:09:32 +00:00
|
|
|
'scripts' => [ 'bar.js', 'foo.js' ],
|
|
|
|
|
] + $baseParams );
|
2013-10-18 13:34:50 +00:00
|
|
|
$this->assertNotEquals(
|
2015-06-18 18:57:16 +00:00
|
|
|
$version,
|
|
|
|
|
json_encode( $module->getVersionHash( $context ) ),
|
2013-10-18 13:34:50 +00:00
|
|
|
'Order of scripts is significant'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Subclass
|
2019-06-19 14:38:32 +00:00
|
|
|
$module = new ResourceLoaderFileModuleTestingSubclass( $baseParams );
|
2013-10-18 13:34:50 +00:00
|
|
|
$this->assertNotEquals(
|
2015-06-18 18:57:16 +00:00
|
|
|
$version,
|
|
|
|
|
json_encode( $module->getVersionHash( $context ) ),
|
2013-10-18 13:34:50 +00:00
|
|
|
'Class is significant'
|
|
|
|
|
);
|
|
|
|
|
}
|
2015-06-02 22:48:47 +00:00
|
|
|
|
2021-09-24 23:08:51 +00:00
|
|
|
/**
|
2022-05-16 14:43:33 +00:00
|
|
|
* @covers ResourceLoaderModule::getVersionHash
|
2021-09-24 23:08:51 +00:00
|
|
|
*/
|
|
|
|
|
public function testGetVersionHash_debug() {
|
|
|
|
|
$module = new ResourceLoaderTestModule( [ 'script' => 'foo();' ] );
|
|
|
|
|
$context = $this->getResourceLoaderContext( [ 'debug' => 'true' ] );
|
|
|
|
|
$this->assertSame( '', $module->getVersionHash( $context ) );
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-28 01:50:11 +00:00
|
|
|
/**
|
2022-05-16 14:43:33 +00:00
|
|
|
* @covers ResourceLoaderModule::getVersionHash
|
2021-08-28 01:50:11 +00:00
|
|
|
*/
|
|
|
|
|
public function testGetVersionHash_length() {
|
resourceloader: Skip version hash calculation in debug mode
=== Why
* More speed
In debug mode, the server should regenerate the startup manifest
on each page view to ensure immediate effect of changes. But,
this also means more version recomputation work on the server.
For most modules, this was already quite fast on repeat views
because of OS-level file caches, and our file-hash caches and
LESS compile caches in php-apcu from ResourceLoader.
But, this makes it even faster.
* Better integration with browser devtools.
Breakpoints stay more consistently across browsers when the
URL stays the same even after you have changed the file and
reloaded the page. For static files, I believe most browsers ignore
query parameters. But for package files that come from load.php,
this was harder for browsers to guess correctly which old script URL
is logically replaced by a different one on the next page view.
=== How
Change Module::getVersionHash to return empty strings in debug mode.
I considered approaching this from StartupModule::getModuleRegistrations
instead to make the change apply only to the client-side manifest.
I decided against this because we have other calls to getVersionHash
on the server-side (such as for E-Tag calculation, and formatting
cross-wiki URLs) which would then not match the version queries that
mw.loader formats in debug mode.
Also, those calls would still be incurring some the avoidable costs.
=== Notes
* The two test cases for verifying the graceful fallback in production
if version hash computations throw an exception, were moved to a
non-debug test case as no longer happen now during the debug
(unminified) test cases.
* Avoid "PHP Notice: Undefined offset 0" in testMakeModuleResponseStartupError
by adding a fallback to empty string so that if the test fails,
it fails in a more useful way instead of aborting with this error
before the assertion happens. (Since PHPUnit generally stops on the
first error.)
* In practice, there are still "version" query parameters and E-Tag
headers in debug mode. These are not module versions, but URL
"combined versions" crafted by getCombinedVersion() in JS and PHP.
These return the constant "ztntf" in debug mode, which is the hash
of an empty string. We could alter these methods to special-case
when all inputs are and join to a still-empty string, or maybe we
just leave them be. I've done the latter for now.
Bug: T235672
Bug: T85805
Change-Id: I0e63eef4f85b13089a0aa3806a5b6f821d527a92
2021-08-28 02:53:36 +00:00
|
|
|
$context = $this->getResourceLoaderContext( [ 'debug' => 'false' ] );
|
2021-08-28 01:50:11 +00:00
|
|
|
$module = new ResourceLoaderTestModule( [
|
|
|
|
|
'script' => 'foo();'
|
|
|
|
|
] );
|
|
|
|
|
$version = $module->getVersionHash( $context );
|
|
|
|
|
$this->assertSame( ResourceLoader::HASH_LENGTH, strlen( $version ), 'Hash length' );
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-26 15:24:31 +00:00
|
|
|
/**
|
2022-05-16 14:43:33 +00:00
|
|
|
* @covers ResourceLoaderModule::getVersionHash
|
2018-06-26 15:24:31 +00:00
|
|
|
*/
|
|
|
|
|
public function testGetVersionHash_parentDefinition() {
|
resourceloader: Skip version hash calculation in debug mode
=== Why
* More speed
In debug mode, the server should regenerate the startup manifest
on each page view to ensure immediate effect of changes. But,
this also means more version recomputation work on the server.
For most modules, this was already quite fast on repeat views
because of OS-level file caches, and our file-hash caches and
LESS compile caches in php-apcu from ResourceLoader.
But, this makes it even faster.
* Better integration with browser devtools.
Breakpoints stay more consistently across browsers when the
URL stays the same even after you have changed the file and
reloaded the page. For static files, I believe most browsers ignore
query parameters. But for package files that come from load.php,
this was harder for browsers to guess correctly which old script URL
is logically replaced by a different one on the next page view.
=== How
Change Module::getVersionHash to return empty strings in debug mode.
I considered approaching this from StartupModule::getModuleRegistrations
instead to make the change apply only to the client-side manifest.
I decided against this because we have other calls to getVersionHash
on the server-side (such as for E-Tag calculation, and formatting
cross-wiki URLs) which would then not match the version queries that
mw.loader formats in debug mode.
Also, those calls would still be incurring some the avoidable costs.
=== Notes
* The two test cases for verifying the graceful fallback in production
if version hash computations throw an exception, were moved to a
non-debug test case as no longer happen now during the debug
(unminified) test cases.
* Avoid "PHP Notice: Undefined offset 0" in testMakeModuleResponseStartupError
by adding a fallback to empty string so that if the test fails,
it fails in a more useful way instead of aborting with this error
before the assertion happens. (Since PHPUnit generally stops on the
first error.)
* In practice, there are still "version" query parameters and E-Tag
headers in debug mode. These are not module versions, but URL
"combined versions" crafted by getCombinedVersion() in JS and PHP.
These return the constant "ztntf" in debug mode, which is the hash
of an empty string. We could alter these methods to special-case
when all inputs are and join to a still-empty string, or maybe we
just leave them be. I've done the latter for now.
Bug: T235672
Bug: T85805
Change-Id: I0e63eef4f85b13089a0aa3806a5b6f821d527a92
2021-08-28 02:53:36 +00:00
|
|
|
$context = $this->getResourceLoaderContext( [ 'debug' => 'false' ] );
|
2022-05-16 14:43:33 +00:00
|
|
|
$module = $this->getMockBuilder( ResourceLoaderModule::class )
|
2021-03-20 15:18:58 +00:00
|
|
|
->onlyMethods( [ 'getDefinitionSummary' ] )->getMock();
|
2018-06-26 15:24:31 +00:00
|
|
|
$module->method( 'getDefinitionSummary' )->willReturn( [ 'a' => 'summary' ] );
|
|
|
|
|
|
2019-10-05 15:42:53 +00:00
|
|
|
$this->expectException( LogicException::class );
|
|
|
|
|
$this->expectExceptionMessage( 'must call parent' );
|
2018-06-26 15:24:31 +00:00
|
|
|
$module->getVersionHash( $context );
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-24 22:52:05 +00:00
|
|
|
/**
|
2022-05-16 14:43:33 +00:00
|
|
|
* @covers ResourceLoaderModule::getScriptURLsForDebug
|
|
|
|
|
* @covers ResourceLoader
|
|
|
|
|
* @covers ResourceLoaderModule::getScriptURLsForDebug
|
2021-09-24 22:52:05 +00:00
|
|
|
*/
|
|
|
|
|
public function testGetURLsForDebug() {
|
|
|
|
|
$module = new ResourceLoaderTestModule( [
|
|
|
|
|
'script' => 'foo();',
|
|
|
|
|
'styles' => '.foo { color: blue; }',
|
|
|
|
|
] );
|
|
|
|
|
$context = $this->getResourceLoaderContext( [ 'debug' => 'true' ] );
|
|
|
|
|
$module->setConfig( $context->getResourceLoader()->getConfig() );
|
|
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
|
[
|
|
|
|
|
'https://example.org/w/load.php?debug=1&lang=en&modules=&only=scripts'
|
|
|
|
|
],
|
|
|
|
|
$module->getScriptURLsForDebug( $context ),
|
|
|
|
|
'script urls debug=true'
|
|
|
|
|
);
|
|
|
|
|
$this->assertEquals(
|
|
|
|
|
[ 'all' => [
|
|
|
|
|
'/w/load.php?debug=1&lang=en&modules=&only=styles'
|
|
|
|
|
] ],
|
|
|
|
|
$module->getStyleURLsForDebug( $context ),
|
|
|
|
|
'style urls debug=true'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$context = $this->getResourceLoaderContext( [ 'debug' => '2' ] );
|
|
|
|
|
$this->assertEquals(
|
|
|
|
|
[
|
|
|
|
|
'https://example.org/w/load.php?debug=2&lang=en&modules=&only=scripts'
|
|
|
|
|
],
|
|
|
|
|
$module->getScriptURLsForDebug( $context ),
|
|
|
|
|
'script urls debug=2'
|
|
|
|
|
);
|
|
|
|
|
$this->assertEquals(
|
|
|
|
|
[ 'all' => [
|
|
|
|
|
'/w/load.php?debug=2&lang=en&modules=&only=styles'
|
|
|
|
|
] ],
|
|
|
|
|
$module->getStyleURLsForDebug( $context ),
|
|
|
|
|
'style urls debug=2'
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-02 22:48:47 +00:00
|
|
|
/**
|
2022-05-16 14:43:33 +00:00
|
|
|
* @covers ResourceLoaderModule::validateScriptFile
|
2015-06-02 22:48:47 +00:00
|
|
|
*/
|
|
|
|
|
public function testValidateScriptFile() {
|
2015-12-07 16:38:28 +00:00
|
|
|
$this->setMwGlobals( 'wgResourceLoaderValidateJS', true );
|
|
|
|
|
|
2015-06-02 22:48:47 +00:00
|
|
|
$context = $this->getResourceLoaderContext();
|
|
|
|
|
|
2016-02-17 09:09:32 +00:00
|
|
|
$module = new ResourceLoaderTestModule( [
|
2019-07-11 19:48:57 +00:00
|
|
|
'mayValidateScript' => true,
|
2015-06-02 22:48:47 +00:00
|
|
|
'script' => "var a = 'this is';\n {\ninvalid"
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
2021-06-11 15:11:37 +00:00
|
|
|
$module->setConfig( $context->getResourceLoader()->getConfig() );
|
2015-06-02 22:48:47 +00:00
|
|
|
$this->assertEquals(
|
2015-09-26 19:48:17 +00:00
|
|
|
'mw.log.error(' .
|
2020-05-30 22:02:03 +00:00
|
|
|
'"JavaScript parse error (scripts need to be valid ECMAScript 5): ' .
|
|
|
|
|
'Parse error: Unexpected token; token } expected in file \'input\' on line 3"' .
|
2015-09-26 19:48:17 +00:00
|
|
|
');',
|
2017-03-31 13:24:14 +00:00
|
|
|
$module->getScript( $context ),
|
2015-06-02 22:48:47 +00:00
|
|
|
'Replace invalid syntax with error logging'
|
|
|
|
|
);
|
|
|
|
|
|
2016-02-17 09:09:32 +00:00
|
|
|
$module = new ResourceLoaderTestModule( [
|
2015-06-02 22:48:47 +00:00
|
|
|
'script' => "\n'valid';"
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
2015-06-02 22:48:47 +00:00
|
|
|
$this->assertEquals(
|
|
|
|
|
"\n'valid';",
|
2017-03-31 13:24:14 +00:00
|
|
|
$module->getScript( $context ),
|
2015-06-02 22:48:47 +00:00
|
|
|
'Leave valid scripts as-is'
|
|
|
|
|
);
|
|
|
|
|
}
|
2015-09-23 01:35:38 +00:00
|
|
|
|
2017-06-27 05:04:21 +00:00
|
|
|
public static function provideBuildContentScripts() {
|
|
|
|
|
return [
|
|
|
|
|
[
|
|
|
|
|
"mw.foo()",
|
2017-06-28 02:51:03 +00:00
|
|
|
"mw.foo()\n",
|
2017-06-27 05:04:21 +00:00
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
"mw.foo();",
|
2017-06-28 02:51:03 +00:00
|
|
|
"mw.foo();\n",
|
2017-06-27 05:04:21 +00:00
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
"mw.foo();\n",
|
|
|
|
|
"mw.foo();\n",
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
"mw.foo()\n",
|
2017-06-28 02:51:03 +00:00
|
|
|
"mw.foo()\n",
|
2017-06-27 05:04:21 +00:00
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
"mw.foo()\n// mw.bar();",
|
2017-06-28 02:51:03 +00:00
|
|
|
"mw.foo()\n// mw.bar();\n",
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
"mw.foo()\n// mw.bar()",
|
|
|
|
|
"mw.foo()\n// mw.bar()\n",
|
2017-06-27 05:04:21 +00:00
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
"mw.foo()// mw.bar();",
|
2017-06-28 02:51:03 +00:00
|
|
|
"mw.foo()// mw.bar();\n",
|
2017-06-27 05:04:21 +00:00
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provideBuildContentScripts
|
2022-05-16 14:43:33 +00:00
|
|
|
* @covers ResourceLoaderModule::buildContent
|
2017-06-27 05:04:21 +00:00
|
|
|
*/
|
2019-11-02 04:05:36 +00:00
|
|
|
public function testBuildContentScripts( $raw, $build, $message = '' ) {
|
2017-06-27 05:04:21 +00:00
|
|
|
$context = $this->getResourceLoaderContext();
|
|
|
|
|
$module = new ResourceLoaderTestModule( [
|
|
|
|
|
'script' => $raw
|
|
|
|
|
] );
|
|
|
|
|
$this->assertEquals( $raw, $module->getScript( $context ), 'Raw script' );
|
|
|
|
|
$this->assertEquals(
|
resourceloader: Remove selective build optimisation from getModuleContent()
This follows 5ddd7f91c7, which factored out response building
from ResourceLoader.php to ResourceLoaderModule::buildContent.
As optimisation, I made this method only return the array keys
needed for the current response; based $context->getOnly().
The reason for this refactoring was the creation of the
'enableModuleContentVersion' option to getVersionHash(), which
would use this method to create a module response, and hash it.
During the implementation of that option, I ran into a problem.
getVersionHash() is called by the startup module for each
registered module, to create the manifest. The context for the
StartupModule request itself has "only=scripts". But, we must
still compute the version hashes for whole modules, not just
their scripts.
I worked around that problem in aac831f9fa by creating a mock
context in getVersionHash() that stubs out the 'only' parameter.
This worked, but made the assumption that the scripts and styles
of a module cannot differ based on the 'only' parameter.
This assumption was wrong, because the 'only' parameter is part
of ResourceLoaderContext and available to all getters to vary on.
Fortunately, the 'enableModuleContentVersion' option is off by
default and nobody currently using it was differing its output
by the 'only' parameter.
I intend to make use of the 'enableModuleContentVersion' option
in StartupModule to fix T201686. And StartupModule outputs a
manifest if the request specifies only=scripts, and outputs
a warning otherwise. As such, it cannot compute its version
if the 'only' parameter is stubbed out.
* Remove the 'only' parameter stubbing.
* Remove the selective building from the buildContent() method.
This was not very useful because we need to build the whole
module regardless when computing the version.
As benefit, this means the in-process cache is now shared between
the call from getVersionHash and the call from makeModuleResponse.
Bug: T201686
Change-Id: I8a17888f95f86ac795bc2de43086225b8a8f4b78
2018-08-30 01:42:24 +00:00
|
|
|
$build,
|
|
|
|
|
$module->getModuleContent( $context )[ 'scripts' ],
|
2017-06-27 05:04:21 +00:00
|
|
|
$message
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-23 01:35:38 +00:00
|
|
|
/**
|
2022-05-16 14:43:33 +00:00
|
|
|
* @covers ResourceLoaderModule::getRelativePaths
|
|
|
|
|
* @covers ResourceLoaderModule::expandRelativePaths
|
2015-09-23 01:35:38 +00:00
|
|
|
*/
|
|
|
|
|
public function testPlaceholderize() {
|
2022-05-16 14:43:33 +00:00
|
|
|
$getRelativePaths = new ReflectionMethod( ResourceLoaderModule::class, 'getRelativePaths' );
|
2015-09-23 01:35:38 +00:00
|
|
|
$getRelativePaths->setAccessible( true );
|
2022-05-16 14:43:33 +00:00
|
|
|
$expandRelativePaths = new ReflectionMethod( ResourceLoaderModule::class, 'expandRelativePaths' );
|
2015-09-23 01:35:38 +00:00
|
|
|
$expandRelativePaths->setAccessible( true );
|
|
|
|
|
|
2016-02-17 09:09:32 +00:00
|
|
|
$this->setMwGlobals( [
|
2015-09-23 01:35:38 +00:00
|
|
|
'IP' => '/srv/example/mediawiki/core',
|
2016-02-17 09:09:32 +00:00
|
|
|
] );
|
|
|
|
|
$raw = [
|
2015-09-23 01:35:38 +00:00
|
|
|
'/srv/example/mediawiki/core/resources/foo.js',
|
|
|
|
|
'/srv/example/mediawiki/core/extensions/Example/modules/bar.js',
|
|
|
|
|
'/srv/example/mediawiki/skins/Example/baz.css',
|
|
|
|
|
'/srv/example/mediawiki/skins/Example/images/quux.png',
|
2016-02-17 09:09:32 +00:00
|
|
|
];
|
|
|
|
|
$canonical = [
|
2015-09-23 01:35:38 +00:00
|
|
|
'resources/foo.js',
|
|
|
|
|
'extensions/Example/modules/bar.js',
|
|
|
|
|
'../skins/Example/baz.css',
|
|
|
|
|
'../skins/Example/images/quux.png',
|
2016-02-17 09:09:32 +00:00
|
|
|
];
|
2015-09-23 01:35:38 +00:00
|
|
|
$this->assertEquals(
|
|
|
|
|
$canonical,
|
2017-03-31 13:24:14 +00:00
|
|
|
$getRelativePaths->invoke( null, $raw ),
|
2015-09-23 01:35:38 +00:00
|
|
|
'Insert placeholders'
|
|
|
|
|
);
|
|
|
|
|
$this->assertEquals(
|
|
|
|
|
$raw,
|
2017-03-31 13:24:14 +00:00
|
|
|
$expandRelativePaths->invoke( null, $canonical ),
|
2015-09-23 01:35:38 +00:00
|
|
|
'Substitute placeholders'
|
|
|
|
|
);
|
|
|
|
|
}
|
resourceloader: Add support for modules sending preload headers
ResourceLoaderModule objects gain a new method getPreloadLinks() which
returns an array with the meta data required to build a Link rel=preload
header according to the current draft for W3C Preload.
<https://w3c.github.io/preload/>
Another implementation of this is already in use in OutputPage for
preloading the logo image.
This array is formatted by the ResourceLoaderModule::getHeaders method,
which is implemented as "final" at this time, thus restricting use to
the Link rel=preload header.
Headers are exposed and process-cached, like all other content
(scripts, styles, etc.), through ResourceLoaderModule::getModuleContent,
and aggregated by ResoureLoader::makeModuleResponse.
I had hoped for the getPreloadLinks to be stateless (not vary on $context).
Whether something should be preloaded and what, should not vary on the
skin or language. However, while that conceptually holds true, the exact
url for any given resource may still vary. Even the main use case for this
feature (T164299, preloading base modules request) require $context to pass
down skin and lang to the load.php url.
Add full test coverage and example documentation.
Bug: T164299
Change-Id: I2bfe0796ceaa0c82579c501f5b10e931f2175681
2017-07-18 02:36:01 +00:00
|
|
|
|
|
|
|
|
/**
|
2022-05-16 14:43:33 +00:00
|
|
|
* @covers ResourceLoaderModule::getHeaders
|
|
|
|
|
* @covers ResourceLoaderModule::getPreloadLinks
|
resourceloader: Add support for modules sending preload headers
ResourceLoaderModule objects gain a new method getPreloadLinks() which
returns an array with the meta data required to build a Link rel=preload
header according to the current draft for W3C Preload.
<https://w3c.github.io/preload/>
Another implementation of this is already in use in OutputPage for
preloading the logo image.
This array is formatted by the ResourceLoaderModule::getHeaders method,
which is implemented as "final" at this time, thus restricting use to
the Link rel=preload header.
Headers are exposed and process-cached, like all other content
(scripts, styles, etc.), through ResourceLoaderModule::getModuleContent,
and aggregated by ResoureLoader::makeModuleResponse.
I had hoped for the getPreloadLinks to be stateless (not vary on $context).
Whether something should be preloaded and what, should not vary on the
skin or language. However, while that conceptually holds true, the exact
url for any given resource may still vary. Even the main use case for this
feature (T164299, preloading base modules request) require $context to pass
down skin and lang to the load.php url.
Add full test coverage and example documentation.
Bug: T164299
Change-Id: I2bfe0796ceaa0c82579c501f5b10e931f2175681
2017-07-18 02:36:01 +00:00
|
|
|
*/
|
|
|
|
|
public function testGetHeaders() {
|
|
|
|
|
$context = $this->getResourceLoaderContext();
|
|
|
|
|
|
|
|
|
|
$module = new ResourceLoaderTestModule();
|
|
|
|
|
$this->assertSame( [], $module->getHeaders( $context ), 'Default' );
|
|
|
|
|
|
|
|
|
|
$module = $this->getMockBuilder( ResourceLoaderTestModule::class )
|
2021-03-20 15:18:58 +00:00
|
|
|
->onlyMethods( [ 'getPreloadLinks' ] )->getMock();
|
resourceloader: Add support for modules sending preload headers
ResourceLoaderModule objects gain a new method getPreloadLinks() which
returns an array with the meta data required to build a Link rel=preload
header according to the current draft for W3C Preload.
<https://w3c.github.io/preload/>
Another implementation of this is already in use in OutputPage for
preloading the logo image.
This array is formatted by the ResourceLoaderModule::getHeaders method,
which is implemented as "final" at this time, thus restricting use to
the Link rel=preload header.
Headers are exposed and process-cached, like all other content
(scripts, styles, etc.), through ResourceLoaderModule::getModuleContent,
and aggregated by ResoureLoader::makeModuleResponse.
I had hoped for the getPreloadLinks to be stateless (not vary on $context).
Whether something should be preloaded and what, should not vary on the
skin or language. However, while that conceptually holds true, the exact
url for any given resource may still vary. Even the main use case for this
feature (T164299, preloading base modules request) require $context to pass
down skin and lang to the load.php url.
Add full test coverage and example documentation.
Bug: T164299
Change-Id: I2bfe0796ceaa0c82579c501f5b10e931f2175681
2017-07-18 02:36:01 +00:00
|
|
|
$module->method( 'getPreloadLinks' )->willReturn( [
|
2021-09-03 22:52:31 +00:00
|
|
|
'https://example.org/script.js' => [ 'as' => 'script' ],
|
resourceloader: Add support for modules sending preload headers
ResourceLoaderModule objects gain a new method getPreloadLinks() which
returns an array with the meta data required to build a Link rel=preload
header according to the current draft for W3C Preload.
<https://w3c.github.io/preload/>
Another implementation of this is already in use in OutputPage for
preloading the logo image.
This array is formatted by the ResourceLoaderModule::getHeaders method,
which is implemented as "final" at this time, thus restricting use to
the Link rel=preload header.
Headers are exposed and process-cached, like all other content
(scripts, styles, etc.), through ResourceLoaderModule::getModuleContent,
and aggregated by ResoureLoader::makeModuleResponse.
I had hoped for the getPreloadLinks to be stateless (not vary on $context).
Whether something should be preloaded and what, should not vary on the
skin or language. However, while that conceptually holds true, the exact
url for any given resource may still vary. Even the main use case for this
feature (T164299, preloading base modules request) require $context to pass
down skin and lang to the load.php url.
Add full test coverage and example documentation.
Bug: T164299
Change-Id: I2bfe0796ceaa0c82579c501f5b10e931f2175681
2017-07-18 02:36:01 +00:00
|
|
|
] );
|
|
|
|
|
$this->assertSame(
|
|
|
|
|
[
|
|
|
|
|
'Link: <https://example.org/script.js>;rel=preload;as=script'
|
|
|
|
|
],
|
|
|
|
|
$module->getHeaders( $context ),
|
|
|
|
|
'Preload one resource'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$module = $this->getMockBuilder( ResourceLoaderTestModule::class )
|
2021-03-20 15:18:58 +00:00
|
|
|
->onlyMethods( [ 'getPreloadLinks' ] )->getMock();
|
resourceloader: Add support for modules sending preload headers
ResourceLoaderModule objects gain a new method getPreloadLinks() which
returns an array with the meta data required to build a Link rel=preload
header according to the current draft for W3C Preload.
<https://w3c.github.io/preload/>
Another implementation of this is already in use in OutputPage for
preloading the logo image.
This array is formatted by the ResourceLoaderModule::getHeaders method,
which is implemented as "final" at this time, thus restricting use to
the Link rel=preload header.
Headers are exposed and process-cached, like all other content
(scripts, styles, etc.), through ResourceLoaderModule::getModuleContent,
and aggregated by ResoureLoader::makeModuleResponse.
I had hoped for the getPreloadLinks to be stateless (not vary on $context).
Whether something should be preloaded and what, should not vary on the
skin or language. However, while that conceptually holds true, the exact
url for any given resource may still vary. Even the main use case for this
feature (T164299, preloading base modules request) require $context to pass
down skin and lang to the load.php url.
Add full test coverage and example documentation.
Bug: T164299
Change-Id: I2bfe0796ceaa0c82579c501f5b10e931f2175681
2017-07-18 02:36:01 +00:00
|
|
|
$module->method( 'getPreloadLinks' )->willReturn( [
|
2021-09-03 22:52:31 +00:00
|
|
|
'https://example.org/script.js' => [ 'as' => 'script' ],
|
|
|
|
|
'/example.png' => [ 'as' => 'image' ],
|
resourceloader: Add support for modules sending preload headers
ResourceLoaderModule objects gain a new method getPreloadLinks() which
returns an array with the meta data required to build a Link rel=preload
header according to the current draft for W3C Preload.
<https://w3c.github.io/preload/>
Another implementation of this is already in use in OutputPage for
preloading the logo image.
This array is formatted by the ResourceLoaderModule::getHeaders method,
which is implemented as "final" at this time, thus restricting use to
the Link rel=preload header.
Headers are exposed and process-cached, like all other content
(scripts, styles, etc.), through ResourceLoaderModule::getModuleContent,
and aggregated by ResoureLoader::makeModuleResponse.
I had hoped for the getPreloadLinks to be stateless (not vary on $context).
Whether something should be preloaded and what, should not vary on the
skin or language. However, while that conceptually holds true, the exact
url for any given resource may still vary. Even the main use case for this
feature (T164299, preloading base modules request) require $context to pass
down skin and lang to the load.php url.
Add full test coverage and example documentation.
Bug: T164299
Change-Id: I2bfe0796ceaa0c82579c501f5b10e931f2175681
2017-07-18 02:36:01 +00:00
|
|
|
] );
|
|
|
|
|
$this->assertSame(
|
|
|
|
|
[
|
|
|
|
|
'Link: <https://example.org/script.js>;rel=preload;as=script,' .
|
|
|
|
|
'</example.png>;rel=preload;as=image'
|
|
|
|
|
],
|
|
|
|
|
$module->getHeaders( $context ),
|
|
|
|
|
'Preload two resources'
|
|
|
|
|
);
|
|
|
|
|
}
|
2013-10-18 13:34:50 +00:00
|
|
|
}
|