From: Kunal Mehta Date: Fri, 6 Feb 2015 09:46:05 +0000 (-0800) Subject: registration: Add resource template-like functionality to extension.json X-Git-Tag: 1.31.0-rc.0~12482^2 X-Git-Url: http://git.cyclocoop.org/%24action?a=commitdiff_plain;h=912a5e5ec3b11a048214f4df04635c6709471b5d;p=lhc%2Fweb%2Fwiklou.git registration: Add resource template-like functionality to extension.json This allows for extensions to specify common arguments to ResourceLoader module definitions by only specifying them once. The only supported values are "localBasePath" (which is relative to the current directory), "remoteSkinPath", and "remoteExtPath". If a module is using a custom class or is already specifying paths, the default paths will not be added. Tests are included to cover existing functionality and newly added functionality. The convertExtensionToRegistration.php script was also extended to try and guess what the default paths should be. Bug: T88786 Change-Id: I802461796e8d8584dacf3b0c811b5ba97a4a8f7f --- diff --git a/docs/extension.schema.json b/docs/extension.schema.json index 4583559698..33029bd436 100644 --- a/docs/extension.schema.json +++ b/docs/extension.schema.json @@ -273,6 +273,25 @@ "Unlicense" ] }, + "ResourceFileModulePaths": { + "type": "object", + "description": "Default paths to use for all ResourceLoader file modules", + "additionalProperties": false, + "properties": { + "localBasePath": { + "type": "string", + "description": "Base path to prepend to all local paths, relative to current directory" + }, + "remoteExtPath": { + "type": "string", + "description": "Base path to prepend to all remote paths, relative to $wgExtensionAssetsPath" + }, + "remoteSkinPath": { + "type": "string", + "description": "Base path to prepend to all remote paths, relative to $wgStylePath" + } + } + }, "ResourceLoaderModules": { "type": "object", "description": "ResourceLoader modules to register", diff --git a/includes/registration/ExtensionProcessor.php b/includes/registration/ExtensionProcessor.php index 8a6530b940..587f766598 100644 --- a/includes/registration/ExtensionProcessor.php +++ b/includes/registration/ExtensionProcessor.php @@ -184,11 +184,21 @@ class ExtensionProcessor implements Processor { } protected function extractResourceLoaderModules( $dir, array $info ) { + $defaultPaths = isset( $info['ResourceFileModulePaths'] ) + ? $info['ResourceFileModulePaths'] + : false; + if ( isset( $defaultPaths['localBasePath'] ) ) { + $defaultPaths['localBasePath'] = "$dir/{$defaultPaths['localBasePath']}"; + } + if ( isset( $info['ResourceModules'] ) ) { foreach ( $info['ResourceModules'] as $name => $data ) { if ( isset( $data['localBasePath'] ) ) { $data['localBasePath'] = "$dir/{$data['localBasePath']}"; } + if ( $defaultPaths && !isset( $data['class'] ) ) { + $data += $defaultPaths; + } $this->globals['wgResourceModules'][$name] = $data; } } diff --git a/maintenance/convertExtensionToRegistration.php b/maintenance/convertExtensionToRegistration.php index a0dee3cc24..76bc982459 100644 --- a/maintenance/convertExtensionToRegistration.php +++ b/maintenance/convertExtensionToRegistration.php @@ -155,12 +155,36 @@ class ConvertExtensionToRegistration extends Maintenance { } protected function handleResourceModules( $realName, $value ) { + $defaults = array(); + $remote = $this->hasOption( 'skin' ) ? 'remoteSkinPath' : 'remoteExtPath'; foreach ( $value as $name => $data ) { if ( isset( $data['localBasePath'] ) ) { $data['localBasePath'] = $this->stripPath( $data['localBasePath'], $this->dir ); + if ( !$defaults ) { + $defaults['localBasePath'] = $data['localBasePath']; + unset( $data['localBasePath'] ); + if ( isset( $data[$remote] ) ) { + $defaults[$remote] = $data[$remote]; + unset( $data[$remote] ); + } + } else { + if ( $data['localBasePath'] === $defaults['localBasePath'] ) { + unset( $data['localBasePath'] ); + } + if ( isset( $data[$remote] ) && isset( $defaults[$remote] ) + && $data[$remote] === $defaults[$remote] + ) { + unset( $data[$remote] ); + } + } } + + $this->json[$realName][$name] = $data; } + if ( $defaults ) { + $this->json['ResourceFileModulePaths'] = $defaults; + } } } diff --git a/tests/phpunit/includes/registration/ExtensionProcessorTest.php b/tests/phpunit/includes/registration/ExtensionProcessorTest.php index 0d31878227..758a3c69b0 100644 --- a/tests/phpunit/includes/registration/ExtensionProcessorTest.php +++ b/tests/phpunit/includes/registration/ExtensionProcessorTest.php @@ -124,6 +124,105 @@ class ExtensionProcessorTest extends MediaWikiTestCase { } } + /** + * @covers ExtensionProcessor::extractResourceLoaderModules + * @dataProvider provideExtractResourceLoaderModules + */ + public function testExtractResourceLoaderModules( $input, $expected ) { + $processor = new ExtensionProcessor(); + $processor->extractInfo( $this->dir, $input + self::$default ); + $out = $processor->getExtractedInfo(); + foreach ( $expected as $key => $value ) { + $this->assertEquals( $value, $out['globals'][$key] ); + } + } + + public static function provideExtractResourceLoaderModules() { + $dir = __DIR__ . '/FooBar/'; + return array( + // Generic module with localBasePath/remoteExtPath specified + array( + // Input + array( + 'ResourceModules' => array( + 'test.foo' => array( + 'styles' => 'foobar.js', + 'localBasePath' => '', + 'remoteExtPath' => 'FooBar', + ), + ), + ), + // Expected + array( + 'wgResourceModules' => array( + 'test.foo' => array( + 'styles' => 'foobar.js', + 'localBasePath' => $dir, + 'remoteExtPath' => 'FooBar', + ), + ), + ), + ), + // ResourceFileModulePaths specified: + array( + // Input + array( + 'ResourceFileModulePaths' => array( + 'localBasePath' => '', + 'remoteExtPath' => 'FooBar', + ), + 'ResourceModules' => array( + // No paths + 'test.foo' => array( + 'styles' => 'foo.js', + ), + // Different paths set + 'test.bar' => array( + 'styles' => 'bar.js', + 'localBasePath' => 'subdir', + 'remoteExtPath' => 'FooBar/subdir', + ), + // Custom class with no paths set + 'test.class' => array( + 'class' => 'FooBarModule', + 'extra' => 'argument', + ), + // Custom class with a localBasePath + 'test.class.with.path' => array( + 'class' => 'FooBarPathModule', + 'extra' => 'argument', + 'localBasePath' => '', + ) + ), + ), + // Expected + array( + 'wgResourceModules' => array( + 'test.foo' => array( + 'styles' => 'foo.js', + 'localBasePath' => $dir, + 'remoteExtPath' => 'FooBar', + ), + 'test.bar' => array( + 'styles' => 'bar.js', + 'localBasePath' => $dir . 'subdir', + 'remoteExtPath' => 'FooBar/subdir', + ), + 'test.class' => array( + 'class' => 'FooBarModule', + 'extra' => 'argument', + ), + 'test.class.with.path' => array( + 'class' => 'FooBarPathModule', + 'extra' => 'argument', + 'localBasePath' => $dir, + ) + ), + ), + ), + ); + } + public static function provideSetToGlobal() { return array( array(