resourceloader: Implement 'deprecated' option for FileModule

ResourceLoader modules can now carry a 'deprecated' option which can
be a boolean or an object with message key. This message or a default
deprecation message will be show whenever that module is used in production.

Note: This will not work in debug mode for ResourceLoaderFile modules
and this is deemed acceptable for the time being. We can revisit later.

Bug: T137772
Change-Id: Ib9ebd2d39a59fd41d8537e06884699f77b03580c
This commit is contained in:
jdlrobson 2016-07-14 15:09:06 -07:00 committed by Legoktm
parent 23c79b228c
commit 8af960e484
5 changed files with 76 additions and 1 deletions

View file

@ -417,6 +417,10 @@
"type": "string",
"description": "Group with which this module should be loaded"
},
"deprecated": {
"type": ["object", "boolean"],
"description": "Whether the module is deprecated and usage is discouraged. Either a boolean or an object with key message can be used to customise deprecation message."
},
"position": {
"type": "string",
"description": "Position on the page to load this module at",

View file

@ -417,6 +417,10 @@
"type": "string",
"description": "Group which this module should be loaded together with"
},
"deprecated": {
"type": ["object", "boolean"],
"description": "Whether the module is deprecated and usage is discouraged. Either a boolean or an object with key message can be used to customise deprecation message."
},
"position": {
"type": "string",
"description": "Position on the page to load this module at",

View file

@ -255,6 +255,9 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
$this->{$member}[$key] = (array)$value;
}
break;
case 'deprecated':
$this->deprecated = $option;
break;
// Lists of strings
case 'dependencies':
case 'messages':
@ -352,7 +355,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
*/
public function getScript( ResourceLoaderContext $context ) {
$files = $this->getScriptFiles( $context );
return $this->readScriptFiles( $files );
return $this->getDeprecationInformation() . $this->readScriptFiles( $files );
}
/**

View file

@ -82,6 +82,11 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
*/
protected $config;
/**
* @var array|bool
*/
protected $deprecated = false;
/**
* @var LoggerInterface
*/
@ -130,6 +135,28 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
return $wgContLang->getDir() !== $context->getDirection();
}
/**
* Get JS representing deprecation information for the current module if available
*
* @return string JavaScript code
*/
protected function getDeprecationInformation() {
$deprecationInfo = $this->deprecated;
if ( $deprecationInfo ) {
$name = $this->getName();
$warning = 'This page is using the deprecated ResourceLoader module "' . $name . '".';
if ( !is_bool( $deprecationInfo ) && isset( $deprecationInfo['message'] ) ) {
$warning .= "\n" . $deprecationInfo['message'];
}
return Xml::encodeJsCall(
'mw.log.warn',
[ $warning ]
);
} else {
return '';
}
}
/**
* Get all JS for this module for a given language and skin.
* Includes all relevant JS except loader scripts.

View file

@ -27,6 +27,15 @@ class ResourceLoaderFileModuleTest extends ResourceLoaderTestCase {
return [
'noTemplateModule' => [],
'deprecatedModule' => $base + [
'deprecated' => true,
],
'deprecatedTomorrow' => $base + [
'deprecated' => [
'message' => 'Will be removed tomorrow.'
],
],
'htmlTemplateModule' => $base + [
'templates' => [
'templates/template.html',
@ -96,6 +105,34 @@ class ResourceLoaderFileModuleTest extends ResourceLoaderTestCase {
$this->assertEquals( $rl->getDependencies(), $expected );
}
public static function providerDeprecatedModules() {
return [
[
'deprecatedModule',
'mw.log.warn("This page is using the deprecated ResourceLoader module \"deprecatedModule\".");',
],
[
'deprecatedTomorrow',
'mw.log.warn(' .
'"This page is using the deprecated ResourceLoader module \"deprecatedTomorrow\".\\n' .
"Will be removed tomorrow." .
'");'
]
];
}
/**
* @dataProvider providerDeprecatedModules
* @covers ResourceLoaderFileModule::getScripts
*/
public function testDeprecatedModules( $name, $expected ) {
$modules = self::getModules();
$rl = new ResourceLoaderFileModule( $modules[$name] );
$rl->setName( $name );
$ctx = $this->getResourceLoaderContext( 'en', 'ltr' );
$this->assertEquals( $rl->getScript( $ctx ), $expected );
}
/**
* @covers ResourceLoaderFileModule::getAllStyleFiles
* @covers ResourceLoaderFileModule::getAllSkinStyleFiles