RCFilters: Invert the muted state of inverted namespace options
authorMoriel Schottlender <moriel@gmail.com>
Wed, 21 Jun 2017 21:16:51 +0000 (14:16 -0700)
committerMoriel Schottlender <moriel@gmail.com>
Mon, 26 Jun 2017 22:03:01 +0000 (15:03 -0700)
Since the inversion happened, the background of selected items was
overridden by "muted" background, so we had to change a few more
details to get things to work properly:
- Override selected color even if the item is muted (previously,
  'selected' cannot be muted by definition, but this patch changes
  that and hence needs to make sure selected color overrides the
  muted color state)
- Set correct muted state on the namespace items to be reversed.
- The highlight/select/mute background issue exposed a secondary
  issue when switching views by clicking the 'tag' item, whereby
  the change of view itself causes the input to empty, and triggers
  the updateItemVisibility in MenuSelectWidget, which then selects
  the first item. This shouldn't happen when the user is actively
  selecting an item from the tags, so a method of recognizing that
  the user is actively selecting an item was added.

Change-Id: Idf5c2232216ad6a38b29bbc103bbca66f56533b7

resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterMenuOptionWidget.less
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuOptionWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterTagMultiselectWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MenuSelectWidget.js

index 28aae6c..ea93247 100644 (file)
@@ -2,7 +2,13 @@
 
 .mw-rcfilters-ui-filterMenuOptionWidget {
        &.oo-ui-flaggedElement-muted {
-               background-color: #f8f9fa; // Base90 AAA
+               &:not( .oo-ui-optionWidget-selected ) {
+                       // Namespaces are muted 'the other way around' when they
+                       // are also inverted, so if they are also selected, we
+                       // should make sure the selected background is shown rather
+                       // than the muted one
+                       background-color: #f8f9fa; // Base90 AAA
+               }
 
                .mw-rcfilters-ui-itemMenuOptionWidget-label-title,
                .mw-rcfilters-ui-itemMenuOptionWidget-label-desc {
index d235c39..5198c69 100644 (file)
         * Set the current muted view of the widget based on its state
         */
        mw.rcfilters.ui.FilterMenuOptionWidget.prototype.setCurrentMuteState = function () {
-               this.setFlags( {
-                       muted: (
-                               this.model.isConflicted() ||
-                               (
-                                       // Item is also muted when any of the items in its group is active
-                                       this.model.getGroupModel().isActive() &&
-                                       // But it isn't selected
-                                       !this.model.isSelected() &&
-                                       // And also not included
-                                       !this.model.isIncluded()
+               if (
+                       this.model.getGroupModel().getView() === 'namespaces' &&
+                       this.model.isInverted()
+               ) {
+                       // This is an inverted behavior than the other rules, specifically
+                       // for inverted namespaces
+                       this.setFlags( {
+                               muted: this.model.isSelected()
+                       } );
+               } else {
+                       this.setFlags( {
+                               muted: (
+                                       this.model.isConflicted() ||
+                                       (
+                                               // Item is also muted when any of the items in its group is active
+                                               this.model.getGroupModel().isActive() &&
+                                               // But it isn't selected
+                                               !this.model.isSelected() &&
+                                               // And also not included
+                                               !this.model.isIncluded()
+                                       )
                                )
-                       )
-               } );
+                       } );
+               }
        };
 }( mediaWiki ) );
index 5b00dfe..70381f2 100644 (file)
                        menuOption = this.menu.getItemFromModel( tagItem.getModel() ),
                        oldInputValue = this.input.getValue();
 
+               this.menu.setUserSelecting( true );
+
                // Reset input
                this.input.setValue( '' );
 
                        // user filtered the results
                        this.getMenu().once(
                                'itemVisibilityChange',
-                               function () { widget.scrollToTop( menuOption.$element ); }
+                               function () {
+                                       widget.scrollToTop( menuOption.$element );
+                                       widget.menu.setUserSelecting( false );
+                               }
                        );
                } else {
                        this.scrollToTop( menuOption.$element );
+                       this.menu.setUserSelecting( false );
                }
+
        };
 
        /**
index dda4ac5..c70e00b 100644 (file)
@@ -30,6 +30,7 @@
                this.model = model;
                this.currentView = '';
                this.views = {};
+               this.userSelecting = false;
 
                this.inputValue = '';
                this.$overlay = config.$overlay || this.$element;
 
                // Since the method hides/shows items, we don't want to
                // call it unless the input actually changed
-               if ( this.inputValue !== inputVal ) {
+               if (
+                       !this.userSelecting &&
+                       this.inputValue !== inputVal
+               ) {
                        // Parent method
                        mw.rcfilters.ui.MenuSelectWidget.parent.prototype.updateItemVisibility.call( this );
 
        mw.rcfilters.ui.MenuSelectWidget.prototype.scrollToTop = function () {
                this.$body.scrollTop( 0 );
        };
+
+       /**
+        * Set whether the user is currently selecting an item.
+        * This is important when the user selects an item that is in between
+        * different views, and makes sure we do not re-select a different
+        * item (like the item on top) when this is happening.
+        *
+        * @param {boolean} isSelecting User is selecting
+        */
+       mw.rcfilters.ui.MenuSelectWidget.prototype.setUserSelecting = function ( isSelecting ) {
+               this.userSelecting = !!isSelecting;
+       };
 }( mediaWiki ) );