Merge "RCFilters: Move parameter operations to ViewModel"
[lhc/web/wiklou.git] / resources / src / mediawiki.rcfilters / dm / mw.rcfilters.dm.FilterGroup.js
index 6acc44d..b17355f 100644 (file)
@@ -93,6 +93,7 @@
         */
        mw.rcfilters.dm.FilterGroup.prototype.initializeFilters = function ( filterDefinition, groupDefault ) {
                var defaultParam,
+                       anyHighlighted,
                        supersetMap = {},
                        model = this,
                        items = [];
                                        description: filter.description || '',
                                        labelPrefixKey: model.labelPrefixKey,
                                        cssClass: filter.cssClass,
-                                       identifiers: filter.identifiers
+                                       identifiers: filter.identifiers,
+                                       defaultHighlightColor: filter.defaultHighlightColor
                                } );
 
                        if ( filter.subset ) {
                        this.defaultParams[ this.getName() ] = defaultParam;
                }
 
+               // add highlights to defaultParams
+               anyHighlighted = false;
+               this.getItems().forEach( function ( filterItem ) {
+                       if ( filterItem.isHighlighted() ) {
+                               anyHighlighted = true;
+                               this.defaultParams[ filterItem.getName() + '_color' ] = filterItem.getHighlightColor();
+                       }
+               }.bind( this ) );
+               if ( anyHighlighted ) {
+                       this.defaultParams.highlight = '1';
+               }
+
                // Store default filter state based on default params
                this.defaultFilters = this.getFilterRepresentation( this.getDefaultParams() );
 
        mw.rcfilters.dm.FilterGroup.prototype.onFilterItemUpdate = function ( item ) {
                // Update state
                var changed = false,
-                       active = this.areAnySelected();
-
-               if (
-                       item.isSelected() &&
-                       this.getType() === 'single_option' &&
-                       this.currSelected &&
-                       this.currSelected !== item
-               ) {
-                       this.currSelected.toggleSelected( false );
-               }
-
-               // For 'single_option' groups, check if we just unselected all
-               // items. This should never be the result. If we did unselect
-               // all (like resetting all filters to false) then this group
-               // must choose its default item or the first item in the group
-               if (
-                       this.getType() === 'single_option' &&
-                       !this.getItems().some( function ( filterItem ) {
-                               return filterItem.isSelected();
-                       } )
-               ) {
-                       // Single option means there must be a single option
-                       // selected, so we have to either select the default
-                       // or select the first option
-                       this.currSelected = this.getItemByParamName( this.defaultParams[ this.getName() ] ) ||
-                               this.getItems()[ 0 ];
-                       this.currSelected.toggleSelected( true );
-                       changed = true;
+                       active = this.areAnySelected(),
+                       model = this;
+
+               if ( this.getType() === 'single_option' ) {
+                       // This group must have one item selected always
+                       // and must never have more than one item selected at a time
+                       if ( this.getSelectedItems().length === 0 ) {
+                               // Nothing is selected anymore
+                               // Select the default or the first item
+                               this.currSelected = this.getItemByParamName( this.defaultParams[ this.getName() ] ) ||
+                                       this.getItems()[ 0 ];
+                               this.currSelected.toggleSelected( true );
+                               changed = true;
+                       } else if ( this.getSelectedItems().length > 1 ) {
+                               // There is more than one item selected
+                               // This should only happen if the item given
+                               // is the one that is selected, so unselect
+                               // all items that is not it
+                               this.getSelectedItems().forEach( function ( itemModel ) {
+                                       // Note that in case the given item is actually
+                                       // not selected, this loop will end up unselecting
+                                       // all items, which would trigger the case above
+                                       // when the last item is unselected anyways
+                                       var selected = itemModel.getName() === item.getName() &&
+                                               item.isSelected();
+
+                                       itemModel.toggleSelected( selected );
+                                       if ( selected ) {
+                                               model.currSelected = itemModel;
+                                       }
+                               } );
+                               changed = true;
+                       }
                }
 
                if (
                return this.type;
        };
 
+       /**
+        * Check whether this group is represented by a single parameter
+        * or whether each item is its own parameter
+        *
+        * @return {boolean} This group is a single parameter
+        */
+       mw.rcfilters.dm.FilterGroup.prototype.isPerGroupRequestParameter = function () {
+               return (
+                       this.getType() === 'string_options' ||
+                       this.getType() === 'single_option'
+               );
+       };
+
        /**
         * Get display group
         *
        mw.rcfilters.dm.FilterGroup.prototype.isExcludedFromSavedQueries = function () {
                return this.excludedFromSavedQueries;
        };
+
+       /**
+        * Normalize a value given to this group. This is mostly for correcting
+        * arbitrary values for 'single option' groups, given by the user settings
+        * or the URL that can go outside the limits that are allowed.
+        *
+        * @param  {string} value Given value
+        * @return {string} Corrected value
+        */
+       mw.rcfilters.dm.FilterGroup.prototype.normalizeArbitraryValue = function ( value ) {
+               if (
+                       this.getType() === 'single_option' &&
+                       this.isAllowArbitrary()
+               ) {
+                       if (
+                               this.getMaxValue() !== null &&
+                               value > this.getMaxValue()
+                       ) {
+                               // Change the value to the actual max value
+                               return String( this.getMaxValue() );
+                       } else if (
+                               this.getMinValue() !== null &&
+                               value < this.getMinValue()
+                       ) {
+                               // Change the value to the actual min value
+                               return String( this.getMinValue() );
+                       }
+               }
+
+               return value;
+       };
 }( mediaWiki ) );