Merge "RCFilters: refactor highlight state"
[lhc/web/wiklou.git] / resources / src / mediawiki.rcfilters / ui / mw.rcfilters.ui.FilterTagMultiselectWidget.js
index b15b034..404cb98 100644 (file)
                                click: 'onSaveQueryButtonClick',
                                saveCurrent: 'setSavedQueryVisibility'
                        } );
-                       this.queriesModel.connect( this, { itemUpdate: 'onSavedQueriesItemUpdate' } );
+                       this.queriesModel.connect( this, {
+                               itemUpdate: 'onSavedQueriesItemUpdate',
+                               initialize: 'onSavedQueriesInitialize',
+                               'default': 'reevaluateResetRestoreState'
+                       } );
                }
 
                this.emptyFilterMessage = new OO.ui.LabelWidget( {
                this.getMenu().toggle( false );
        };
 
+       /**
+        * Respond to save query model initialization
+        */
+       mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onSavedQueriesInitialize = function () {
+               this.setSavedQueryVisibility();
+       };
+
        /**
         * Respond to save query item change. Mainly this is done to update the label in case
         * a query item has been edited
                // Parent
                mw.rcfilters.ui.FilterTagMultiselectWidget.parent.prototype.onInputFocus.call( this );
 
-               // Scroll to top
-               this.scrollToTop( this.$element );
+               // Only scroll to top of the viewport if:
+               // - The widget is more than 20px from the top
+               // - The widget is not above the top of the viewport (do not scroll downwards)
+               //   (This isn't represented because >20 is, anyways and always, bigger than 0)
+               this.scrollToTop( this.$element, 0, { min: 20, max: Infinity } );
        };
 
        /**
                        this.matchingQuery ? this.matchingQuery.getLabel() : ''
                );
                this.savedQueryTitle.toggle( !!this.matchingQuery );
-               this.saveQueryButton.toggle(
-                       !this.isEmpty() &&
-                       !this.matchingQuery
-               );
+               this.saveQueryButton.toggle( !this.matchingQuery );
 
                if ( this.matchingQuery ) {
                        this.emphasize();
 
        /**
         * Respond to model itemUpdate event
+        * fixme: when a new state is applied to the model this function is called 60+ times in a row
         *
         * @param {mw.rcfilters.dm.FilterItem} item Filter item model
         */
        mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onModelItemUpdate = function ( item ) {
-               if ( item.getGroupModel().isHidden() ) {
-                       return;
-               }
-
-               if (
-                       item.isSelected() ||
-                       (
-                               this.model.isHighlightEnabled() &&
-                               item.isHighlightSupported() &&
-                               item.getHighlightColor()
-                       )
-               ) {
-                       this.addTag( item.getName(), item.getLabel() );
-               } else {
-                       this.removeTagByData( item.getName() );
+               if ( !item.getGroupModel().isHidden() ) {
+                       if (
+                               item.isSelected() ||
+                               (
+                                       this.model.isHighlightEnabled() &&
+                                       item.getHighlightColor()
+                               )
+                       ) {
+                               this.addTag( item.getName(), item.getLabel() );
+                       } else {
+                               this.removeTagByData( item.getName() );
+                       }
                }
 
                this.setSavedQueryVisibility();
                                }
                        }.bind( this ) );
                }
+
+               this.setSavedQueryVisibility();
        };
 
        /**
         * Reevaluate the restore state for the widget between setting to defaults and clearing all filters
         */
        mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.reevaluateResetRestoreState = function () {
-               var defaultsAreEmpty = this.model.areDefaultFiltersEmpty(),
+               var defaultsAreEmpty = this.controller.areDefaultsEmpty(),
                        currFiltersAreEmpty = this.model.areCurrentFiltersEmpty(),
                        hideResetButton = currFiltersAreEmpty && defaultsAreEmpty;
 
                if ( filterItem ) {
                        return new mw.rcfilters.ui.FilterTagItemWidget(
                                this.controller,
+                               this.model,
+                               this.model.getInvertModel(),
                                filterItem,
                                {
                                        $overlay: this.$overlay
         *
         * @private
         * @param {jQuery} $element Element to position
-        * @param {number} [marginFromTop] When scrolling the entire widget to the top, leave this
+        * @param {number} [marginFromTop=0] When scrolling the entire widget to the top, leave this
         *  much space (in pixels) above the widget.
+        * @param {Object} [threshold] Minimum distance from the top of the element to scroll at all
+        * @param {number} [threshold.min] Minimum distance above the element
+        * @param {number} [threshold.max] Minimum distance below the element
         */
-       mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.scrollToTop = function ( $element, marginFromTop ) {
+       mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.scrollToTop = function ( $element, marginFromTop, threshold ) {
                var container = OO.ui.Element.static.getClosestScrollableContainer( $element[ 0 ], 'y' ),
                        pos = OO.ui.Element.static.getRelativePosition( $element, $( container ) ),
-                       containerScrollTop = $( container ).is( 'body, html' ) ? 0 : $( container ).scrollTop();
+                       containerScrollTop = $( container ).scrollTop(),
+                       effectiveScrollTop = $( container ).is( 'body, html' ) ? 0 : containerScrollTop,
+                       newScrollTop = effectiveScrollTop + pos.top - ( marginFromTop || 0 );
 
                // Scroll to item
-               $( container ).animate( {
-                       scrollTop: containerScrollTop + pos.top - ( marginFromTop || 0 )
-               } );
+               if (
+                       threshold === undefined ||
+                       (
+                               (
+                                       threshold.min === undefined ||
+                                       newScrollTop - containerScrollTop >= threshold.min
+                               ) &&
+                               (
+                                       threshold.max === undefined ||
+                                       newScrollTop - containerScrollTop <= threshold.max
+                               )
+                       )
+               ) {
+                       $( container ).animate( {
+                               scrollTop: newScrollTop
+                       } );
+               }
        };
 }( mediaWiki ) );