Make each gadget a separate preference, instead of one huge multiselect

This gives each section and each gadget's entry an `id` attribute,
which can be used for linking, as requested in T126962. Existing user
options still match the new preferences.

It also probably makes future improvements easier. No one understands
multiselects with subsections.

Bug: T126962
Change-Id: Ifaca96e288c475017636c2408712d6a20aa77da9
This commit is contained in:
Bartosz Dziewoński 2021-09-29 14:53:39 +02:00
parent 0007744ee6
commit 82281d82d0
3 changed files with 39 additions and 40 deletions

View file

@ -90,6 +90,7 @@
"EditFilterMergedContent": "GadgetHooks::onEditFilterMergedContent",
"UserGetDefaultOptions": "GadgetHooks::userGetDefaultOptions",
"GetPreferences": "GadgetHooks::getPreferences",
"PreferencesGetLegend": "GadgetHooks::onPreferencesGetLegend",
"ResourceLoaderRegisterModules": "GadgetHooks::registerModules",
"wgQueryPages": "GadgetHooks::onwgQueryPages",
"DeleteUnknownPreferences": "GadgetHooks::onDeleteUnknownPreferences"

View file

@ -93,8 +93,13 @@ class GadgetHooks {
return;
}
$options = [];
$default = [];
$preferences['gadgets-intro'] = [
'type' => 'info',
'default' => wfMessage( 'gadgets-prefstext' )->parseAsBlock(),
'section' => 'gadgets',
'raw' => true,
];
$skin = RequestContext::getMain()->getSkin();
foreach ( $gadgets as $section => $thisSection ) {
$available = [];
@ -109,43 +114,37 @@ class GadgetHooks {
&& $gadget->isSkinSupported( $skin )
) {
$gname = $gadget->getName();
$available[$gadget->getDescriptionMessageKey()] = $gname;
if ( $gadget->isEnabled( $user ) ) {
$default[] = $gname;
}
$sectionLabelMsg = "gadget-section-$section";
$preferences["gadget-$gname"] = [
'type' => 'check',
'label-message' => $gadget->getDescriptionMessageKey(),
'section' => $section !== '' ? "gadgets/$sectionLabelMsg" : 'gadgets',
'default' => $gadget->isEnabled( $user ),
'noglobal' => true,
];
}
}
if ( $available === [] ) {
continue;
}
if ( $section !== '' ) {
$options["gadget-section-$section"] = $available;
} else {
$options = array_merge( $options, $available );
}
}
}
$preferences['gadgets-intro'] =
[
'type' => 'info',
'default' => wfMessage( 'gadgets-prefstext' )->parseAsBlock(),
'section' => 'gadgets',
'raw' => true,
];
$preferences['gadgets'] =
[
'type' => 'multiselect',
'options-messages' => $options,
'options-messages-parse' => true,
'section' => 'gadgets',
'label' => ' ',
'prefix' => 'gadget-',
'default' => $default,
'noglobal' => true,
];
/**
* PreferencesGetLegend hook handler.
*
* Used to override the subsection heading labels for the gadget groups. The default message would
* be "prefs-$key", but we've previously used different messages, and they have on-wiki overrides
* that would have to be moved if the message keys changed.
*
* @param HTMLForm $form the HTMLForm object. This is a ContextSource as well
* @param string $key the section name
* @param string &$legend the legend text. Defaults to wfMessage( "prefs-$key" )->text() but may
* be overridden
* @return bool|void True or no return value to continue or false to abort
*/
public static function onPreferencesGetLegend( $form, $key, &$legend ) {
if ( str_starts_with( $key, 'gadget-section-' ) ) {
$legend = new OOUI\HtmlSnippet( $form->msg( $key )->parse() );
}
}
/**

View file

@ -52,10 +52,9 @@ class GadgetHooksTest extends MediaWikiIntegrationTestCase {
$repo->definitionCache = $gadgets;
GadgetHooks::getPreferences( $this->user, $prefs );
$options = $prefs['gadgets']['options-messages'];
$this->assertArrayNotHasKey( 'gadget-section-remove-section', $options,
'Must not show empty sections' );
$this->assertArrayHasKey( 'gadget-section-keep-section1', $options );
$this->assertArrayHasKey( 'gadget-section-keep-section2', $options );
$this->assertArrayHasKey( 'gadget-bar', $prefs );
$this->assertArrayNotHasKey( 'gadget-baz', $prefs,
'Must not show unavailable gadgets' );
$this->assertEquals( 'gadgets/gadget-section-keep-section2', $prefs['gadget-quux']['section'] );
}
}