Merge "Add 'autocomplete' option to HTMLTextField"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 18 Nov 2016 18:41:16 +0000 (18:41 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 18 Nov 2016 18:41:16 +0000 (18:41 +0000)
1  2 
includes/htmlform/fields/HTMLAutoCompleteSelectField.php
includes/htmlform/fields/HTMLTextField.php

   *   options-messages - As for HTMLSelectField
   *   options - As for HTMLSelectField
   *   options-message - As for HTMLSelectField
-  *   autocomplete - Associative array mapping display text to values.
-  *   autocomplete-messages - Like autocomplete, but keys are message names.
+  *   autocomplete-data - Associative array mapping display text to values.
+  *   autocomplete-data-messages - Like autocomplete, but keys are message names.
   *   require-match - Boolean, if true the value must be in the options or the
   *     autocomplete.
   *   other-message - Message to use instead of htmlform-selectorother-other for
   *      the 'other' message.
   *   other - Raw text to use for the 'other' message
+  *
+  * The old name of autocomplete-data[-messages] was autocomplete[-messages] which is still
+  * recognized but deprecated since MediaWiki 1.29 since it conflicts with how autocomplete is
+  * used in HTMLTextField.
   */
  class HTMLAutoCompleteSelectField extends HTMLTextField {
-       protected $autocomplete = [];
+       protected $autocompleteData = [];
  
 -      function __construct( $params ) {
 +      public function __construct( $params ) {
                $params += [
                        'require-match' => false,
                ];
  
+               // FIXME B/C, remove in 1.30
+               if (
+                       array_key_exists( 'autocomplete', $params )
+                       && !array_key_exists( 'autocomplete-data', $params )
+               ) {
+                       $params['autocomplete-data'] = $params['autocomplete'];
+                       unset( $params['autocomplete'] );
+               }
+               if (
+                       array_key_exists( 'autocomplete-messages', $params )
+                       && !array_key_exists( 'autocomplete-data-messages', $params )
+               ) {
+                       $params['autocomplete-data-messages'] = $params['autocomplete-messages'];
+                       unset( $params['autocomplete-messages'] );
+               }
                parent::__construct( $params );
  
-               if ( array_key_exists( 'autocomplete-messages', $this->mParams ) ) {
-                       foreach ( $this->mParams['autocomplete-messages'] as $key => $value ) {
+               if ( array_key_exists( 'autocomplete-data-messages', $this->mParams ) ) {
+                       foreach ( $this->mParams['autocomplete-data-messages'] as $key => $value ) {
                                $key = $this->msg( $key )->plain();
-                               $this->autocomplete[$key] = strval( $value );
+                               $this->autocompleteData[$key] = strval( $value );
                        }
-               } elseif ( array_key_exists( 'autocomplete', $this->mParams ) ) {
-                       foreach ( $this->mParams['autocomplete'] as $key => $value ) {
-                               $this->autocomplete[$key] = strval( $value );
+               } elseif ( array_key_exists( 'autocomplete-data', $this->mParams ) ) {
+                       foreach ( $this->mParams['autocomplete-data'] as $key => $value ) {
+                               $this->autocompleteData[$key] = strval( $value );
                        }
                }
-               if ( !is_array( $this->autocomplete ) || !$this->autocomplete ) {
+               if ( !is_array( $this->autocompleteData ) || !$this->autocompleteData ) {
                        throw new MWException( 'HTMLAutoCompleteSelectField called without any autocompletions' );
                }
  
                }
        }
  
 -      function loadDataFromRequest( $request ) {
 +      public function loadDataFromRequest( $request ) {
                if ( $request->getCheck( $this->mName ) ) {
                        $val = $request->getText( $this->mName . '-select', 'other' );
  
                        if ( $val === 'other' ) {
                                $val = $request->getText( $this->mName );
-                               if ( isset( $this->autocomplete[$val] ) ) {
-                                       $val = $this->autocomplete[$val];
+                               if ( isset( $this->autocompleteData[$val] ) ) {
+                                       $val = $this->autocompleteData[$val];
                                }
                        }
  
                }
        }
  
 -      function validate( $value, $alldata ) {
 +      public function validate( $value, $alldata ) {
                $p = parent::validate( $value, $alldata );
  
                if ( $p !== true ) {
                        return $p;
                }
  
-               $validOptions = HTMLFormField::flattenOptions( $this->getOptions() );
+               $validOptions = HTMLFormField::flattenOptions( $this->getOptions() ?: [] );
  
                if ( in_array( strval( $value ), $validOptions, true ) ) {
                        return true;
-               } elseif ( in_array( strval( $value ), $this->autocomplete, true ) ) {
+               } elseif ( in_array( strval( $value ), $this->autocompleteData, true ) ) {
                        return true;
                } elseif ( $this->mParams['require-match'] ) {
                        return $this->msg( 'htmlform-select-badoption' )->parse();
        public function getAttributes( array $list ) {
                $attribs = [
                        'type' => 'text',
-                       'data-autocomplete' => FormatJson::encode( array_keys( $this->autocomplete ) ),
+                       'data-autocomplete' => FormatJson::encode( array_keys( $this->autocompleteData ) ),
                ] + parent::getAttributes( $list );
  
                if ( $this->getOptions() ) {
                return $attribs;
        }
  
 -      function getInputHTML( $value ) {
 +      public function getInputHTML( $value ) {
                $oldClass = $this->mClass;
                $this->mClass = (array)$this->mClass;
  
                if ( $valInSelect ) {
                        $value = '';
                } else {
-                       $key = array_search( strval( $value ), $this->autocomplete, true );
+                       $key = array_search( strval( $value ), $this->autocompleteData, true );
                        if ( $key !== false ) {
                                $value = $key;
                        }
         * @param string $value
         * @return false
         */
 -      function getInputOOUI( $value ) {
 +      public function getInputOOUI( $value ) {
                // To be implemented, for now override the function from HTMLTextField
                return false;
        }
@@@ -1,8 -1,19 +1,19 @@@
  <?php
  
+ /**
+  * <input> field.
+  *
+  * Besides the parameters recognized by HTMLFormField, the following are
+  * recognized:
+  *   autocomplete - HTML autocomplete value (a boolean for on/off or a string according to
+  *     https://html.spec.whatwg.org/multipage/forms.html#autofill )
+  */
  class HTMLTextField extends HTMLFormField {
        protected $mPlaceholder = '';
  
+       /** @var bool HTML autocomplete attribute */
+       protected $autocomplete;
        /**
         * @param array $params
         *   - type: HTML textfield type
         *     for password fields)
         */
        public function __construct( $params ) {
+               if ( isset( $params['autocomplete'] ) && is_bool( $params['autocomplete'] ) ) {
+                       $params['autocomplete'] = $params['autocomplete'] ? 'on' : 'off';
+               }
                parent::__construct( $params );
  
                if ( isset( $params['placeholder-message'] ) ) {
                }
        }
  
 -      function getSize() {
 +      public function getSize() {
                return isset( $this->mParams['size'] ) ? $this->mParams['size'] : 45;
        }
  
 -      function getSpellCheck() {
 +      public function getSpellCheck() {
                $val = isset( $this->mParams['spellcheck'] ) ? $this->mParams['spellcheck'] : null;
                if ( is_bool( $val ) ) {
                        // "spellcheck" attribute literally requires "true" or "false" to work.
@@@ -43,7 -58,7 +58,7 @@@
                return !( isset( $this->mParams['type'] ) && $this->mParams['type'] === 'password' );
        }
  
 -      function getInputHTML( $value ) {
 +      public function getInputHTML( $value ) {
                if ( !$this->isPersistent() ) {
                        $value = '';
                }
@@@ -80,7 -95,8 +95,8 @@@
                        'required',
                        'autofocus',
                        'multiple',
-                       'readonly'
+                       'readonly',
+                       'autocomplete',
                ];
  
                $attribs += $this->getAttributes( $allowedParams );
                return $type;
        }
  
 -      function getInputOOUI( $value ) {
 +      public function getInputOOUI( $value ) {
                if ( !$this->isPersistent() ) {
                        $value = '';
                }
                        'required',
                        'tabindex',
                        'type',
+                       'autocomplete',
                ];
  
                $attribs += OOUI\Element::configFromHtmlAttributes(
                        $this->getAttributes( $allowedParams )
                );
  
+               // FIXME T150983 downgrade autocomplete
+               if ( isset( $attribs['autocomplete'] ) ) {
+                       if ( $attribs['autocomplete'] === 'on' ) {
+                               $attribs['autocomplete'] = true;
+                       } elseif ( $attribs['autocomplete'] === 'off' ) {
+                               $attribs['autocomplete'] = false;
+                       } else {
+                               unset( $attribs['autocomplete'] );
+                       }
+               }
                $type = $this->getType( $attribs );
  
                return $this->getInputWidget( [