Make mediawiki.special.pageLanguage work again
[lhc/web/wiklou.git] / includes / htmlform / HTMLForm.php
index 2779d5a..2282dc2 100644 (file)
@@ -128,6 +128,7 @@ class HTMLForm extends ContextSource {
                'textwithbutton' => 'HTMLTextFieldWithButton',
                'textarea' => 'HTMLTextAreaField',
                'select' => 'HTMLSelectField',
+               'combobox' => 'HTMLComboboxField',
                'radio' => 'HTMLRadioField',
                'multiselect' => 'HTMLMultiSelectField',
                'limitselect' => 'HTMLSelectLimitField',
@@ -525,6 +526,21 @@ class HTMLForm extends ContextSource {
                return false;
        }
 
+       /**
+        * Same as self::show with the difference, that the form will be
+        * added to the output, no matter, if the validation was good or not.
+        * @return bool|Status Whether submission was successful.
+        */
+       function showAlways() {
+               $this->prepareForm();
+
+               $result = $this->tryAuthorizedSubmit();
+
+               $this->displayForm( $result );
+
+               return $result;
+       }
+
        /**
         * Validate all the fields, and call the submission callback
         * function if everything is kosher.
@@ -655,10 +671,10 @@ class HTMLForm extends ContextSource {
        }
 
        /**
-        * Set the introductory message, overwriting any existing message.
+        * Set the introductory message HTML, overwriting any existing message.
         * @since 1.19
         *
-        * @param string $msg Complete text of message to display
+        * @param string $msg Complete HTML of message to display
         *
         * @return HTMLForm $this for chaining calls (since 1.20)
         */
@@ -669,9 +685,9 @@ class HTMLForm extends ContextSource {
        }
 
        /**
-        * Add introductory text.
+        * Add HTML to introductory message.
         *
-        * @param string $msg Complete text of message to display
+        * @param string $msg Complete HTML of message to display
         *
         * @return HTMLForm $this for chaining calls (since 1.20)
         */
@@ -682,9 +698,9 @@ class HTMLForm extends ContextSource {
        }
 
        /**
-        * Add header text, inside the form.
+        * Add HTML to the header, inside the form.
         *
-        * @param string $msg Complete text of message to display
+        * @param string $msg Additional HTML to display in header
         * @param string|null $section The section to add the header to
         *
         * @return HTMLForm $this for chaining calls (since 1.20)
@@ -706,7 +722,7 @@ class HTMLForm extends ContextSource {
         * Set header text, inside the form.
         * @since 1.19
         *
-        * @param string $msg Complete text of message to display
+        * @param string $msg Complete HTML of header to display
         * @param string|null $section The section to add the header to
         *
         * @return HTMLForm $this for chaining calls (since 1.20)
@@ -726,7 +742,7 @@ class HTMLForm extends ContextSource {
         *
         * @param string|null $section The section to get the header text for
         * @since 1.26
-        * @return string
+        * @return string HTML
         */
        function getHeaderText( $section = null ) {
                if ( is_null( $section ) ) {
@@ -854,15 +870,53 @@ class HTMLForm extends ContextSource {
        /**
         * Add a button to the form
         *
-        * @param string $name Field name.
-        * @param string $value Field value
-        * @param string $id DOM id for the button (default: null)
-        * @param array $attribs
-        *
+        * @since 1.27 takes an array as shown. Earlier versions accepted
+        *  'name', 'value', 'id', and 'attribs' as separate parameters in that
+        *  order.
+        * @note Custom labels ('label', 'label-message', 'label-raw') are not
+        *  supported for IE6 and IE7 due to bugs in those browsers. If detected,
+        *  they will be served buttons using 'value' as the button label.
+        * @param array $data Data to define the button:
+        *  - name: (string) Button name.
+        *  - value: (string) Button value.
+        *  - label-message: (string, optional) Button label message key to use
+        *    instead of 'value'. Overrides 'label' and 'label-raw'.
+        *  - label: (string, optional) Button label text to use instead of
+        *    'value'. Overrides 'label-raw'.
+        *  - label-raw: (string, optional) Button label HTML to use instead of
+        *    'value'.
+        *  - id: (string, optional) DOM id for the button.
+        *  - attribs: (array, optional) Additional HTML attributes.
+        *  - flags: (string|string[], optional) OOUI flags.
         * @return HTMLForm $this for chaining calls (since 1.20)
         */
-       public function addButton( $name, $value, $id = null, $attribs = null ) {
-               $this->mButtons[] = compact( 'name', 'value', 'id', 'attribs' );
+       public function addButton( $data ) {
+               if ( !is_array( $data ) ) {
+                       $args = func_get_args();
+                       if ( count( $args ) < 2 || count( $args ) > 4 ) {
+                               throw new InvalidArgumentException(
+                                       'Incorrect number of arguments for deprecated calling style'
+                               );
+                       }
+                       $data = array(
+                               'name' => $args[0],
+                               'value' => $args[1],
+                               'id' => isset( $args[2] ) ? $args[2] : null,
+                               'attribs' => isset( $args[3] ) ? $args[3] : null,
+                       );
+               } else {
+                       if ( !isset( $data['name'] ) ) {
+                               throw new InvalidArgumentException( 'A name is required' );
+                       }
+                       if ( !isset( $data['value'] ) ) {
+                               throw new InvalidArgumentException( 'A value is required' );
+                       }
+               }
+               $this->mButtons[] = $data + array(
+                       'id' => null,
+                       'attribs' => null,
+                       'flags' => null,
+               );
 
                return $this;
        }
@@ -903,7 +957,7 @@ class HTMLForm extends ContextSource {
         *
         * @param bool|string|array|Status $submitResult Output from HTMLForm::trySubmit()
         *
-        * @return string
+        * @return string HTML
         */
        function getHTML( $submitResult ) {
                # For good measure (it is the default)
@@ -959,7 +1013,11 @@ class HTMLForm extends ContextSource {
                        $html = Xml::fieldset( $legend, $html );
                }
 
-               return Html::rawElement( 'form', $this->getFormAttributes() + array( 'class' => 'visualClear' ), $html );
+               return Html::rawElement(
+                       'form',
+                       $this->getFormAttributes() + array( 'class' => 'visualClear' ),
+                       $html
+               );
        }
 
        /**
@@ -1036,6 +1094,9 @@ class HTMLForm extends ContextSource {
                        ) . "\n";
                }
 
+               // IE<8 has bugs with <button>, so we'll need to avoid them.
+               $isBadIE = preg_match( '/MSIE [1-7]\./i', $this->getRequest()->getHeader( 'User-Agent' ) );
+
                foreach ( $this->mButtons as $button ) {
                        $attrs = array(
                                'type' => 'submit',
@@ -1043,6 +1104,16 @@ class HTMLForm extends ContextSource {
                                'value' => $button['value']
                        );
 
+                       if ( isset( $button['label-message'] ) ) {
+                               $label = $this->msg( $button['label-message'] )->parse();
+                       } elseif ( isset( $button['label'] ) ) {
+                               $label = htmlspecialchars( $button['label'] );
+                       } elseif ( isset( $button['label-raw'] ) ) {
+                               $label = $button['label-raw'];
+                       } else {
+                               $label = htmlspecialchars( $button['value'] );
+                       }
+
                        if ( $button['attribs'] ) {
                                $attrs += $button['attribs'];
                        }
@@ -1056,7 +1127,11 @@ class HTMLForm extends ContextSource {
                                $attrs['class'][] = 'mw-ui-button';
                        }
 
-                       $buttons .= Html::element( 'input', $attrs ) . "\n";
+                       if ( $isBadIE ) {
+                               $buttons .= Html::element( 'input', $attrs ) . "\n";
+                       } else {
+                               $buttons .= Html::rawElement( 'button', $attrs, $label ) . "\n";
+                       }
                }
 
                $html = Html::rawElement( 'span',
@@ -1355,6 +1430,18 @@ class HTMLForm extends ContextSource {
                return $this->mMethod;
        }
 
+       /**
+        * Wraps the given $section into an user-visible fieldset.
+        *
+        * @param string $legend Legend text for the fieldset
+        * @param string $section The section content in plain Html
+        * @param array $attributes Additional attributes for the fieldset
+        * @return string The fieldset's Html
+        */
+       protected function wrapFieldSetSection( $legend, $section, $attributes ) {
+               return Xml::fieldset( $legend, $section, $attributes ) . "\n";
+       }
+
        /**
         * @todo Document
         *
@@ -1379,6 +1466,7 @@ class HTMLForm extends ContextSource {
                $hasLabel = false;
 
                // Conveniently, PHP method names are case-insensitive.
+               // For grep: this can call getDiv, getRaw, getInline, getVForm, getOOUI
                $getFieldHtmlMethod = $displayFormat == 'table' ? 'getTableRow' : ( 'get' . $displayFormat );
 
                foreach ( $fields as $key => $value ) {
@@ -1386,16 +1474,19 @@ class HTMLForm extends ContextSource {
                                $v = empty( $value->mParams['nodata'] )
                                        ? $this->mFieldData[$key]
                                        : $value->getDefault();
-                               $html[] = $value->$getFieldHtmlMethod( $v );
 
-                               $labelValue = trim( $value->getLabel() );
-                               if ( $labelValue != '&#160;' && $labelValue !== '' ) {
-                                       $hasLabel = true;
-                               }
+                               $retval = $value->$getFieldHtmlMethod( $v );
+
+                               // check, if the form field should be added to
+                               // the output.
+                               if ( $value->hasVisibleOutput() ) {
+                                       $html[] = $retval;
+
+                                       $labelValue = trim( $value->getLabel() );
+                                       if ( $labelValue != '&#160;' && $labelValue !== '' ) {
+                                               $hasLabel = true;
+                                       }
 
-                               if ( get_class( $value ) !== 'HTMLHiddenField' &&
-                                       get_class( $value ) !== 'HTMLApiField'
-                               ) {
                                        $hasUserVisibleFields = true;
                                }
                        } elseif ( is_array( $value ) ) {
@@ -1421,7 +1512,7 @@ class HTMLForm extends ContextSource {
                                        if ( $fieldsetIDPrefix ) {
                                                $attributes['id'] = Sanitizer::escapeId( "$fieldsetIDPrefix$key" );
                                        }
-                                       $subsectionHtml .= Xml::fieldset( $legend, $section, $attributes ) . "\n";
+                                       $subsectionHtml .= $this->wrapFieldSetSection( $legend, $section, $attributes );
                                } else {
                                        // Just return the inputs, nothing fancy.
                                        $subsectionHtml .= $section;