SkinFactory: Allow skins to be registered as "skippable"

The existing method of hardcoding ApiOutput and Fallback is not
great, and there is a use case inside Vector as we split
Vector skin into two as well as inside ContentTranslation.

This adds to the existing wgSkipSkins configuration by allowing
skins to register themselves as skippable without a LocalSettings
change.

Bug: T291193
Change-Id: I9caa8deb5b58fa1ef1eb548db497ef095cbbd154
This commit is contained in:
jdlrobson 2021-09-14 17:26:48 -07:00 committed by Timo Tijhof
parent d88c00f283
commit 576006858d
3 changed files with 18 additions and 14 deletions

View file

@ -1531,14 +1531,16 @@ return [
if ( is_array( $skin ) ) {
$spec = $skin;
$displayName = $skin['displayname'] ?? $name;
$skippable = $skin['skippable'] ?? false;
} else {
$displayName = $skin;
$skippable = false;
$spec = [
'name' => $name,
'class' => "Skin$skin"
];
}
$factory->register( $name, $displayName, $spec );
$factory->register( $name, $displayName, $spec, $skippable );
}
// Register a hidden "fallback" skin
@ -1551,7 +1553,7 @@ return [
'templateDirectory' => __DIR__ . '/skins/templates/fallback',
]
]
] );
], true );
// Register a hidden skin for api output
$factory->register( 'apioutput', 'ApiOutput', [
'class' => SkinApi::class,
@ -1562,7 +1564,7 @@ return [
'templateDirectory' => __DIR__ . '/skins/templates/apioutput',
]
]
] );
], true );
return $factory;
},

View file

@ -79,9 +79,11 @@ class SkinFactory {
* available.
* @param array|callable $spec Callback that takes the skin name as an argument, or
* object factory spec specifying how to create the skin
* @param bool $skippable whether the skin is skippable and should be hidden
* in preferences.
* @throws InvalidArgumentException If an invalid callback is provided
*/
public function register( $name, $displayName, $spec ) {
public function register( $name, $displayName, $spec, $skippable = false ) {
if ( !is_callable( $spec ) ) {
if ( is_array( $spec ) ) {
if ( !isset( $spec['args'] ) ) {
@ -96,6 +98,10 @@ class SkinFactory {
}
$this->factoryFunctions[$name] = $spec;
$this->displayNames[$name] = $displayName;
// Register as hidden if necessary.
if ( $skippable ) {
$this->skipSkins[] = $name;
}
}
/**
@ -139,10 +145,6 @@ class SkinFactory {
public function getAllowedSkins() {
$skins = $this->getInstalledSkins();
// Internal skins not intended for general use
unset( $skins['fallback'] );
unset( $skins['apioutput'] );
foreach ( $this->skipSkins as $skip ) {
unset( $skins[$skip] );
}

View file

@ -32,7 +32,7 @@ class SkinFactoryTest extends \MediaWikiUnitTestCase {
$factory->register( 'fallback', 'Fallback', static function () use ( $instance ) {
return $instance;
} );
}, true );
$this->assertSame( $instance, $factory->makeSkin( 'fallback' ) );
}
@ -44,7 +44,7 @@ class SkinFactoryTest extends \MediaWikiUnitTestCase {
$factory = $this->createSkinFactory();
$factory->register( 'fallback', 'Fallback', [
'class' => SkinFallback::class
] );
], true );
$this->assertInstanceOf( SkinFallback::class, $factory->makeSkin( 'fallback' ) );
}
@ -145,9 +145,9 @@ class SkinFactoryTest extends \MediaWikiUnitTestCase {
public function testGetAllowedSkins() {
$sf = $this->createSkinFactory( null, [ 'quux' ] );
$sf->register( 'foo', 'Foo', [] );
$sf->register( 'apioutput', 'ApiOutput', [] );
$sf->register( 'apioutput', 'ApiOutput', [], true );
$sf->register( 'quux', 'Quux', [] );
$sf->register( 'fallback', 'Fallback', [] );
$sf->register( 'fallback', 'Fallback', [], true );
$sf->register( 'bar', 'Barbar', [] );
$this->assertEquals(
@ -161,8 +161,8 @@ class SkinFactoryTest extends \MediaWikiUnitTestCase {
*/
public function testGetAllowedSkinsEmpty() {
$sf = $this->createSkinFactory();
$sf->register( 'apioutput', 'ApiOutput', [] );
$sf->register( 'fallback', 'Fallback', [] );
$sf->register( 'apioutput', 'ApiOutput', [], true );
$sf->register( 'fallback', 'Fallback', [], true );
$this->assertEquals( [], $sf->getAllowedSkins() );
}