Make mw.widgets.SearchInputWidget extend OO.ui.SearchInputWidget
authorBartosz Dziewoński <matma.rex@gmail.com>
Thu, 29 Jun 2017 20:04:34 +0000 (22:04 +0200)
committerBartosz Dziewoński <matma.rex@gmail.com>
Thu, 29 Jun 2017 20:25:56 +0000 (22:25 +0200)
Mixin mw.widgets.TitleWidget instead of extending mw.widgets.TitleInputWidget.

* Remove code that reimplemented pieces of OO.ui.SearchInputWidget.
* Remove code that overrode pieces of mw.widgets.TitleInputWidget.
* Copy the code from mw.widgets.TitleInputWidget that we actually want.

This should result in no functional changes, other than losing the
TitleInputWidget API (some methods and config options) that no one
relied on, as far as I can tell.

Bug: T169194
Change-Id: Ic1482b4c7cfde7d4cf0b8900654bd3a454776010

includes/widget/SearchInputWidget.php
resources/Resources.php
resources/src/mediawiki.widgets/mw.widgets.SearchInputWidget.js

index 90792fc..47d3717 100644 (file)
@@ -10,12 +10,10 @@ namespace MediaWiki\Widget;
 /**
  * Search input widget.
  */
-class SearchInputWidget extends TitleInputWidget {
+class SearchInputWidget extends \OOUI\TextInputWidget {
 
        protected $pushPending = false;
        protected $performSearchOnClick = true;
-       protected $validateTitle = false;
-       protected $highlightFirst = false;
        protected $dataLocation = 'header';
 
        /**
@@ -30,7 +28,6 @@ class SearchInputWidget extends TitleInputWidget {
         */
        public function __construct( array $config = [] ) {
                $config = array_merge( [
-                       'maxLength' => null,
                        'icon' => 'search',
                ], $config );
 
index ccfe970..4176fe6 100644 (file)
@@ -2538,9 +2538,9 @@ return [
                ],
                'dependencies' => [
                        'mediawiki.searchSuggest',
-                       'oojs-ui.styles.icons-interactions',
-                       // FIXME: Needs TitleInputWidget only
+                       // FIXME: Needs TitleWidget only
                        'mediawiki.widgets',
+                       'oojs-ui-widgets',
                ],
        ],
        'mediawiki.widgets.SearchInputWidget.styles' => [
index 08997aa..22e5874 100644 (file)
@@ -10,7 +10,9 @@
         * Creates a mw.widgets.SearchInputWidget object.
         *
         * @class
-        * @extends mw.widgets.TitleInputWidget
+        * @extends OO.ui.SearchInputWidget
+        * @mixins mw.widgets.TitleWidget
+        * @mixins OO.ui.mixin.LookupElement
         *
         * @constructor
         * @param {Object} [config] Configuration options
                var $form = config.$input ? config.$input.closest( 'form' ) : $();
 
                config = $.extend( {
-                       icon: 'search',
-                       maxLength: undefined,
                        performSearchOnClick: true,
-                       dataLocation: 'header',
-                       namespace: 0
+                       dataLocation: 'header'
                }, config );
 
                // Parent constructor
-               mw.widgets.SearchInputWidget.parent.call( this, config );
+               mw.widgets.SearchInputWidget.parent.call( this, $.extend( {}, config, {
+                       autocomplete: false
+               } ) );
+
+               // Mixin constructors
+               mw.widgets.TitleWidget.call( this, config );
+               OO.ui.mixin.LookupElement.call( this, config );
 
                // Initialization
                this.$element.addClass( 'mw-widget-searchInputWidget' );
                this.lookupMenu.$element.addClass( 'mw-widget-searchWidget-menu' );
                this.lastLookupItems = [];
                if ( !config.pushPending ) {
+                       // TODO This actually overrides a method, that's pretty crazy. Surely there's a better way?
                        this.pushPending = false;
                }
                if ( config.dataLocation ) {
                                )
                        } );
                }.bind( this ) );
-
-               this.$element.addClass( 'oo-ui-textInputWidget-type-search' );
-               this.updateSearchIndicator();
-               this.connect( this, {
-                       disable: 'onDisable'
-               } );
        };
 
        /* Setup */
 
-       OO.inheritClass( mw.widgets.SearchInputWidget, mw.widgets.TitleInputWidget );
+       OO.inheritClass( mw.widgets.SearchInputWidget, OO.ui.SearchInputWidget );
+       OO.mixinClass( mw.widgets.SearchInputWidget, mw.widgets.TitleWidget );
+       OO.mixinClass( mw.widgets.SearchInputWidget, OO.ui.mixin.LookupElement );
 
        /* Methods */
 
        /**
-        * @inheritdoc
-        * @protected
-        */
-       mw.widgets.SearchInputWidget.prototype.getInputElement = function () {
-               return $( '<input>' ).attr( 'type', 'search' );
-       };
-
-       /**
-        * @inheritdoc
-        */
-       mw.widgets.SearchInputWidget.prototype.onIndicatorMouseDown = function ( e ) {
-               if ( e.which === OO.ui.MouseButtons.LEFT ) {
-                       // Clear the text field
-                       this.setValue( '' );
-                       this.$input[ 0 ].focus();
-                       return false;
-               }
-       };
-
-       /**
-        * Update the 'clear' indicator displayed on type: 'search' text
-        * fields, hiding it when the field is already empty or when it's not
-        * editable.
-        */
-       mw.widgets.SearchInputWidget.prototype.updateSearchIndicator = function () {
-               if ( this.getValue() === '' || this.isDisabled() || this.isReadOnly() ) {
-                       this.setIndicator( null );
-               } else {
-                       this.setIndicator( 'clear' );
-               }
-       };
-
-       /**
-        * @see OO.ui.SearchInputWidget#onChange
-        */
-       mw.widgets.SearchInputWidget.prototype.onChange = function () {
-               mw.widgets.SearchInputWidget.parent.prototype.onChange.call( this );
-               this.updateSearchIndicator();
-       };
-
-       /**
-        * Handle disable events.
-        *
-        * @param {boolean} disabled Element is disabled
-        * @private
+        * @inheritdoc mw.widgets.TitleWidget
         */
-       mw.widgets.SearchInputWidget.prototype.onDisable = function () {
-               this.updateSearchIndicator();
+       mw.widgets.SearchInputWidget.prototype.getQueryValue = function () {
+               return this.getValue();
        };
 
        /**
-        * @inheritdoc
+        * @inheritdoc OO.ui.mixin.LookupElement
         */
-       mw.widgets.SearchInputWidget.prototype.setReadOnly = function ( state ) {
-               mw.widgets.SearchInputWidget.parent.prototype.setReadOnly.call( this, state );
-               this.updateSearchIndicator();
-               return this;
+       mw.widgets.SearchInputWidget.prototype.getLookupRequest = function () {
+               return this.getSuggestionsPromise();
        };
 
        /**
        };
 
        /**
-        * @inheritdoc mw.widgets.TitleInputWidget
+        * @inheritdoc OO.ui.mixin.LookupElement
         */
        mw.widgets.SearchInputWidget.prototype.getLookupCacheDataFromResponse = function ( response ) {
                var resp;
 
-               // mw.widgets.TitleInputWidget uses response.query, which doesn't exist for opensearch,
-               // so return the whole response (titles only, and links)
                resp = {
                        data: response || {},
                        metadata: {
        };
 
        /**
-        * @inheritdoc
+        * @inheritdoc OO.ui.mixin.LookupElement
         */
-       mw.widgets.SearchInputWidget.prototype.onLookupMenuItemChoose = function () {
-               mw.widgets.SearchInputWidget.parent.prototype.onLookupMenuItemChoose.apply( this, arguments );
+       mw.widgets.SearchInputWidget.prototype.onLookupMenuItemChoose = function ( item ) {
+               this.closeLookupMenu();
+               this.setLookupsDisabled( true );
+               this.setValue( item.getData() );
+               this.setLookupsDisabled( !this.suggestions );
 
                if ( this.performSearchOnClick ) {
                        this.$element.closest( 'form' ).submit();
        };
 
        /**
-        * @inheritdoc
+        * @inheritdoc OO.ui.mixin.LookupElement
         */
-       mw.widgets.SearchInputWidget.prototype.getLookupMenuOptionsFromData = function () {
-               var items = mw.widgets.SearchInputWidget.parent.prototype.getLookupMenuOptionsFromData.apply(
-                       this, arguments
-               );
+       mw.widgets.SearchInputWidget.prototype.getLookupMenuOptionsFromData = function ( response ) {
+               var items = this.getOptionsFromData( response );
 
                this.lastLookupItems = items.map( function ( item ) {
                        return item.data;
                return items;
        };
 
+       /**
+        * @inheritdoc
+        */
+       mw.widgets.SearchInputWidget.prototype.focus = function () {
+               var retval;
+
+               // Prevent programmatic focus from opening the menu
+               this.setLookupsDisabled( true );
+
+               // Parent method
+               retval = mw.widgets.SearchInputWidget.parent.prototype.focus.apply( this, arguments );
+
+               this.setLookupsDisabled( !this.suggestions );
+
+               return retval;
+       };
+
 }( jQuery, mediaWiki ) );