Bartosz Dziewoński has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/364831 )

Change subject: Reduce code duplication for parsing messages into dropdown menus
......................................................................

Reduce code duplication for parsing messages into dropdown menus

The same behavior was implemented by Xml::listDropDown(),
HTMLFormField::getOptions() and Article::confirmDelete().

All three are now changed to use a new function
Xml::listDropDownOptions().

Additionally, Xml::listDropDownOptionsOoui() is introduced
to handle converting the existing format to the OOUI format,
which was previously duplicated in Article::confirmDelete()
and HTMLFormField::getOptionsOOUI().

(This change also allows HTMLForm 'select' fields to support
nested options in OOUI mode.)

Change-Id: I0a088f61eb32ec59677113583c7ecdcbc3fd2af0
---
M includes/Xml.php
M includes/htmlform/HTMLFormField.php
M includes/page/Article.php
3 files changed, 85 insertions(+), 83 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/31/364831/1

diff --git a/includes/Xml.php b/includes/Xml.php
index d016433..11357b3 100644
--- a/includes/Xml.php
+++ b/includes/Xml.php
@@ -507,38 +507,19 @@
        public static function listDropDown( $name = '', $list = '', $other = 
'',
                $selected = '', $class = '', $tabindex = null
        ) {
-               $optgroup = false;
+               $options = self::listDropDownOptions( $list, [ 'other' => 
$other ] );
+               $optionsHtml = '';
 
-               $options = self::option( $other, 'other', $selected === 'other' 
);
-
-               foreach ( explode( "\n", $list ) as $option ) {
-                       $value = trim( $option );
-                       if ( $value == '' ) {
-                               continue;
-                       } elseif ( substr( $value, 0, 1 ) == '*' && substr( 
$value, 1, 1 ) != '*' ) {
-                               // A new group is starting ...
-                               $value = trim( substr( $value, 1 ) );
-                               if ( $optgroup ) {
-                                       $options .= self::closeElement( 
'optgroup' );
+               foreach ( $options as $text => $value ) {
+                       if ( is_array( $value ) ) {
+                               $optionsHtml .= self::openElement( 'optgroup', 
[ 'label' => $text ] );
+                               foreach ( $value as $text2 => $value2 ) {
+                                       $optionsHtml .= self::option( $text2, 
$value2, $selected === $value );
                                }
-                               $options .= self::openElement( 'optgroup', [ 
'label' => $value ] );
-                               $optgroup = true;
-                       } elseif ( substr( $value, 0, 2 ) == '**' ) {
-                               // groupmember
-                               $value = trim( substr( $value, 2 ) );
-                               $options .= self::option( $value, $value, 
$selected === $value );
+                               $optionsHtml .= self::closeElement( 'optgroup' 
);
                        } else {
-                               // groupless reason list
-                               if ( $optgroup ) {
-                                       $options .= self::closeElement( 
'optgroup' );
-                               }
-                               $options .= self::option( $value, $value, 
$selected === $value );
-                               $optgroup = false;
+                               $optionsHtml .= self::option( $text, $value, 
$selected === $value );
                        }
-               }
-
-               if ( $optgroup ) {
-                       $options .= self::closeElement( 'optgroup' );
                }
 
                $attribs = [];
@@ -558,12 +539,80 @@
 
                return Xml::openElement( 'select', $attribs )
                        . "\n"
-                       . $options
+                       . $optionsHtml
                        . "\n"
                        . Xml::closeElement( 'select' );
        }
 
        /**
+        * Build options for a drop-down box from a textual list.
+        *
+        * @param string $list Correctly formatted text (newline delimited) to 
be
+        *   used to generate the options.
+        * @param array $params Extra parameters
+        * @param string $params['other'] If set, add an option with this as 
text and a value of 'other'
+        * @return array Array keys are textual labels, values are internal 
values
+        */
+       public static function listDropDownOptions( $list, $params = [] ) {
+               $options = [];
+
+               if ( isset( $params['other'] ) ) {
+                       $options[ $params['other'] ] = 'other';
+               }
+
+               $optgroup = false;
+               foreach ( explode( "\n", $list ) as $option ) {
+                       $value = trim( $option );
+                       if ( $value == '' ) {
+                               continue;
+                       } elseif ( substr( $value, 0, 1 ) == '*' && substr( 
$value, 1, 1 ) != '*' ) {
+                               # A new group is starting...
+                               $value = trim( substr( $value, 1 ) );
+                               $optgroup = $value;
+                       } elseif ( substr( $value, 0, 2 ) == '**' ) {
+                               # groupmember
+                               $opt = trim( substr( $value, 2 ) );
+                               if ( $optgroup === false ) {
+                                       $options[$opt] = $opt;
+                               } else {
+                                       $options[$optgroup][$opt] = $opt;
+                               }
+                       } else {
+                               # groupless reason list
+                               $optgroup = false;
+                               $options[$option] = $option;
+                       }
+               }
+
+               return $options;
+       }
+
+       /**
+        * Convert options for a drop-down box into a format accepted by 
OOUI\DropdownInputWidget etc.
+        *
+        * TODO Find a better home for this function.
+        *
+        * @param array $options Options, as returned e.g. by 
Xml::listDropDownOptions()
+        * @return array
+        */
+       public static function listDropDownOptionsOoui( $options ) {
+               $optionsOoui = [];
+
+               foreach ( $options as $text => $value ) {
+                       if ( is_array( $value ) ) {
+                               $optionsOoui[] = [ 'optgroup' => (string)$text 
];
+                               foreach ( $value as $value2 => $text2 ) {
+                                       $optionsOoui[] = [ 'data' => 
(string)$value2, 'label' => (string)$text2 ];
+                               }
+                       } else {
+                               $optionsOoui[] = [ 'data' => (string)$value, 
'label' => (string)$text ];
+                       }
+               }
+
+               return $optionsOoui;
+       }
+
+       /**
         * Shortcut for creating fieldsets.
         *
         * @param string|bool $legend Legend of the fieldset. If evaluates to 
false,
diff --git a/includes/htmlform/HTMLFormField.php 
b/includes/htmlform/HTMLFormField.php
index 83a8023..7a23f2c 100644
--- a/includes/htmlform/HTMLFormField.php
+++ b/includes/htmlform/HTMLFormField.php
@@ -1058,33 +1058,8 @@
                                $this->mOptionsLabelsNotFromMessage = true;
                                $this->mOptions = self::forceToStringRecursive( 
$this->mParams['options'] );
                        } elseif ( array_key_exists( 'options-message', 
$this->mParams ) ) {
-                               /** @todo This is copied from 
Xml::listDropDown(), deprecate/avoid duplication? */
                                $message = $this->getMessage( 
$this->mParams['options-message'] )->inContentLanguage()->plain();
-
-                               $optgroup = false;
-                               $this->mOptions = [];
-                               foreach ( explode( "\n", $message ) as $option 
) {
-                                       $value = trim( $option );
-                                       if ( $value == '' ) {
-                                               continue;
-                                       } elseif ( substr( $value, 0, 1 ) == 
'*' && substr( $value, 1, 1 ) != '*' ) {
-                                               # A new group is starting...
-                                               $value = trim( substr( $value, 
1 ) );
-                                               $optgroup = $value;
-                                       } elseif ( substr( $value, 0, 2 ) == 
'**' ) {
-                                               # groupmember
-                                               $opt = trim( substr( $value, 2 
) );
-                                               if ( $optgroup === false ) {
-                                                       $this->mOptions[$opt] = 
$opt;
-                                               } else {
-                                                       
$this->mOptions[$optgroup][$opt] = $opt;
-                                               }
-                                       } else {
-                                               # groupless reason list
-                                               $optgroup = false;
-                                               $this->mOptions[$option] = 
$option;
-                                       }
-                               }
+                               $this->mOptions = Xml::listDropDownOptions( 
$message );
                        } else {
                                $this->mOptions = null;
                        }
@@ -1104,16 +1079,7 @@
                        return null;
                }
 
-               $options = [];
-
-               foreach ( $oldoptions as $text => $data ) {
-                       $options[] = [
-                               'data' => (string)$data,
-                               'label' => (string)$text,
-                       ];
-               }
-
-               return $options;
+               return Xml::listDropDownOptionsOoui( $oldoptions );
        }
 
        /**
diff --git a/includes/page/Article.php b/includes/page/Article.php
index 16328bc..ab615fa 100644
--- a/includes/page/Article.php
+++ b/includes/page/Article.php
@@ -1695,24 +1695,11 @@
 
                $outputPage->enableOOUI();
 
-               $options = [];
-               $options[] = [
-                       'data' => 'other',
-                       'label' => $ctx->msg( 'deletereasonotherlist' 
)->inContentLanguage()->text(),
-               ];
-               $list = $ctx->msg( 'deletereason-dropdown' 
)->inContentLanguage()->text();
-               foreach ( explode( "\n", $list ) as $option ) {
-                       $value = trim( $option );
-                       if ( $value == '' ) {
-                               continue;
-                       } elseif ( substr( $value, 0, 1 ) == '*' && substr( 
$value, 1, 1 ) != '*' ) {
-                               $options[] = [ 'optgroup' => trim( substr( 
$value, 1 ) ) ];
-                       } elseif ( substr( $value, 0, 2 ) == '**' ) {
-                               $options[] = [ 'data' => trim( substr( $value, 
2 ) ) ];
-                       } else {
-                               $options[] = [ 'data' => trim( $value ) ];
-                       }
-               }
+               $options = Xml::listDropDownOptions(
+                       $ctx->msg( 'deletereason-dropdown' 
)->inContentLanguage()->text(),
+                       [ 'other' => $ctx->msg( 'deletereasonotherlist' 
)->inContentLanguage()->text() ]
+               );
+               $options = Xml::listDropDownOptionsOoui( $options );
 
                $fields[] = new OOUI\FieldLayout(
                        new OOUI\DropdownInputWidget( [

-- 
To view, visit https://gerrit.wikimedia.org/r/364831
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I0a088f61eb32ec59677113583c7ecdcbc3fd2af0
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Bartosz Dziewoński <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to