jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/366511 )

Change subject: RCFilters: Add 'boolean' group
......................................................................


RCFilters: Add 'boolean' group

The group allows filters to be represented 'directly' with their
selected values corresponding to their parameter "1" or "0" value.

Change-Id: I56e9b52ff79a46227de71c905b2ecd97a3823624
---
M resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js
M resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js
M resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ItemModel.js
M tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js
4 files changed, 166 insertions(+), 38 deletions(-)

Approvals:
  Catrope: Looks good to me, approved
  jenkins-bot: Verified



diff --git 
a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js 
b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js
index 9a85291..8bedd68 100644
--- a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js
+++ b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js
@@ -52,6 +52,7 @@
 
                this.conflicts = config.conflicts || {};
                this.defaultParams = {};
+               this.defaultFilters = {};
 
                this.aggregate( { update: 'filterItemUpdate' } );
                this.connect( this, { filterItemUpdate: 'onFilterItemUpdate' } 
);
@@ -89,6 +90,7 @@
                        var subsetNames = [],
                                filterItem = new mw.rcfilters.dm.FilterItem( 
filter.name, model, {
                                        group: model.getName(),
+                                       useDefaultAsBaseValue: 
!!filter.useDefaultAsBaseValue,
                                        label: filter.label || filter.name,
                                        description: filter.description || '',
                                        labelPrefixKey: model.labelPrefixKey,
@@ -131,7 +133,10 @@
                        items.push( filterItem );
 
                        // Store default parameter state; in this case, default 
is defined per filter
-                       if ( model.getType() === 'send_unselected_if_any' ) {
+                       if (
+                               model.getType() === 'send_unselected_if_any' ||
+                               model.getType() === 'boolean'
+                       ) {
                                // Store the default parameter state
                                // For this group type, parameter values are 
direct
                                // We need to convert from a boolean to a 
string ('1' and '0')
@@ -176,6 +181,25 @@
                        // or select the first option
                        this.selectItemByParamName( defaultParam );
                }
+
+               // Store default filter state based on default params
+               this.defaultFilters = this.getFilterRepresentation( 
this.getDefaultParams() );
+
+               // Check for filters that should be initially selected by their 
default value
+               this.getItems().forEach( function ( item ) {
+                       if (
+                               item.isUsingDefaultAsBaseValue() &&
+                               (
+                                       // This setting can only be applied to 
these groups
+                                       // the other groups are way too complex 
for that
+                                       model.getType() === 'single_option' ||
+                                       model.getType() === 'boolean'
+                               )
+                       ) {
+                               // Apply selection
+                               item.toggleSelected( !!model.defaultFilters[ 
item.getName() ] );
+                       }
+               } );
        };
 
        /**
@@ -251,6 +275,15 @@
         */
        mw.rcfilters.dm.FilterGroup.prototype.getDefaultParams = function () {
                return this.defaultParams;
+       };
+
+       /**
+        * Get the default filter state of this group
+        *
+        * @return {Object} Default filter state
+        */
+       mw.rcfilters.dm.FilterGroup.prototype.getDefaultFilters = function () {
+               return this.defaultFilters;
        };
 
        /**
@@ -448,6 +481,7 @@
                var values,
                        areAnySelected = false,
                        buildFromCurrentState = !filterRepresentation,
+                       defaultFilters = this.getDefaultFilters(),
                        result = {},
                        model = this,
                        filterParamNames = {},
@@ -480,8 +514,22 @@
                        } else if ( !filterRepresentation[ item.getName() ] ) {
                                // We are given a filter representation, but we 
have to make
                                // sure that we fill in the missing filters if 
there are any
-                               // we will assume they are all falsey
-                               filterRepresentation[ item.getName() ] = false;
+                               // we will assume they are all falsey, unless 
they have
+                               // isUsingDefaultAsBaseValue, in which case 
they get their
+                               // default state
+                               if (
+                                       item.isUsingDefaultAsBaseValue() &&
+                                       (
+                                               // This setting can only be 
applied to these groups
+                                               // the other groups are way too 
complex for that
+                                               model.getType() === 
'single_option' ||
+                                               model.getType() === 'boolean'
+                                       )
+                               ) {
+                                       filterRepresentation[ item.getName() ] 
= !!defaultFilters[ item.getName() ];
+                               } else {
+                                       filterRepresentation[ item.getName() ] 
= false;
+                               }
                        }
 
                        if ( filterRepresentation[ item.getName() ] ) {
@@ -490,7 +538,10 @@
                } );
 
                // Build result
-               if ( this.getType() === 'send_unselected_if_any' ) {
+               if (
+                       this.getType() === 'send_unselected_if_any' ||
+                       this.getType() === 'boolean'
+               ) {
                        // First, check if any of the items are selected at all.
                        // If none is selected, we're treating it as if they are
                        // all false
@@ -498,9 +549,15 @@
                        // Go over the items and define the correct values
                        $.each( filterRepresentation, function ( name, value ) {
                                // We must store all parameter values as 
strings '0' or '1'
-                               result[ filterParamNames[ name ] ] = 
areAnySelected ?
-                                       String( Number( !value ) ) :
-                                       '0';
+                               if ( model.getType() === 
'send_unselected_if_any' ) {
+                                       result[ filterParamNames[ name ] ] = 
areAnySelected ?
+                                               String( Number( !value ) ) :
+                                               '0';
+                               } else if ( model.getType() === 'boolean' ) {
+                                       // Representation is straight-forward 
and direct from
+                                       // the parameter value to the filter 
state
+                                       result[ filterParamNames[ name ] ] = 
String( Number( !!value ) );
+                               }
                        } );
                } else if ( this.getType() === 'string_options' ) {
                        values = [];
@@ -525,26 +582,32 @@
         * Get the filter representation this group would provide
         * based on given parameter states.
         *
-        * @param {Object|string} [paramRepresentation] An object defining a 
parameter
+        * @param {Object} [paramRepresentation] An object defining a parameter
         *  state to translate the filter state from. If not given, an object
         *  representing all filters as falsey is returned; same as if the 
parameter
         *  given were an empty object, or had some of the filters missing.
         * @return {Object} Filter representation
         */
        mw.rcfilters.dm.FilterGroup.prototype.getFilterRepresentation = 
function ( paramRepresentation ) {
-               var areAnySelected, paramValues, defaultValue, item,
+               var areAnySelected, paramValues, defaultValue, item, 
currentValue,
                        oneWasSelected = false,
+                       defaultParams = this.getDefaultParams(),
+                       defaultFilters = this.getDefaultFilters(),
+                       expandedParams = $.extend( true, {}, 
paramRepresentation ),
                        model = this,
                        paramToFilterMap = {},
                        result = {};
 
-               if ( this.getType() === 'send_unselected_if_any' ) {
-                       paramRepresentation = paramRepresentation || {};
-                       // Expand param representation to include all filters 
in the group
+               paramRepresentation = paramRepresentation || {};
+               if (
+                       this.getType() === 'send_unselected_if_any' ||
+                       this.getType() === 'boolean'
+               ) {
+                       // Go over param representation; map and check for 
selections
                        this.getItems().forEach( function ( filterItem ) {
                                var paramName = filterItem.getParamName();
 
-                               paramRepresentation[ paramName ] = 
paramRepresentation[ paramName ] || '0';
+                               expandedParams[ paramName ] = 
paramRepresentation[ paramName ] || '0';
                                paramToFilterMap[ paramName ] = filterItem;
 
                                if ( Number( paramRepresentation[ 
filterItem.getParamName() ] ) ) {
@@ -552,25 +615,37 @@
                                }
                        } );
 
-                       $.each( paramRepresentation, function ( paramName, 
paramValue ) {
-                               var filterItem = paramToFilterMap[ paramName ];
+                       $.each( expandedParams, function ( paramName, 
paramValue ) {
+                               var value = paramValue,
+                                       filterItem = paramToFilterMap[ 
paramName ];
 
-                               // Flip the definition between the parameter
-                               // state and the filter state
-                               // This is what the 'toggleSelected' value of 
the filter is
-                               result[ filterItem.getName() ] = areAnySelected 
?
-                                       !Number( paramValue ) :
-                                       // Otherwise, there are no selected 
items in the
-                                       // group, which means the state is false
-                                       false;
+                               if ( model.getType() === 
'send_unselected_if_any' ) {
+                                       // Flip the definition between the 
parameter
+                                       // state and the filter state
+                                       // This is what the 'toggleSelected' 
value of the filter is
+                                       result[ filterItem.getName() ] = 
areAnySelected ?
+                                               !Number( paramValue ) :
+                                               // Otherwise, there are no 
selected items in the
+                                               // group, which means the state 
is false
+                                               false;
+                               } else if ( model.getType() === 'boolean' ) {
+                                       // Straight-forward definition of state
+                                       if (
+                                               
filterItem.isUsingDefaultAsBaseValue() &&
+                                               paramRepresentation[ 
filterItem.getParamName() ] === undefined
+                                       ) {
+                                               value = defaultParams[ 
filterItem.getParamName() ];
+                                       }
+                                       result[ filterItem.getName() ] = 
!!Number( value );
+                               }
                        } );
                } else if ( this.getType() === 'string_options' ) {
-                       paramRepresentation = paramRepresentation || '';
+                       currentValue = paramRepresentation[ this.getName() ] || 
'';
 
                        // Normalize the given parameter values
                        paramValues = mw.rcfilters.utils.normalizeParamOptions(
                                // Given
-                               paramRepresentation.split(
+                               currentValue.split(
                                        this.getSeparator()
                                ),
                                // Allowed values
@@ -595,15 +670,36 @@
                } else if ( this.getType() === 'single_option' ) {
                        // There is parameter that fits a single filter and if 
not, get the default
                        this.getItems().forEach( function ( filterItem ) {
-                               result[ filterItem.getName() ] = 
filterItem.getParamName() === paramRepresentation;
-                               oneWasSelected = oneWasSelected || 
filterItem.getParamName() === paramRepresentation;
+                               var selected = false;
+
+                               if (
+                                       filterItem.isUsingDefaultAsBaseValue() 
&&
+                                       paramRepresentation[ model.getName() ] 
=== undefined
+                               ) {
+                                       selected = !!Number( 
paramRepresentation[ model.getName() ] );
+                               } else {
+                                       selected = filterItem.getParamName() 
=== paramRepresentation[ model.getName() ];
+                               }
+                               result[ filterItem.getName() ] = selected;
+                               oneWasSelected = oneWasSelected || selected;
                        } );
                }
 
                // Go over result and make sure all filters are represented.
                // If any filters are missing, they will get a falsey value
                this.getItems().forEach( function ( filterItem ) {
-                       result[ filterItem.getName() ] = !!result[ 
filterItem.getName() ];
+                       if (
+                               (
+                                       // This setting can only be applied to 
these groups
+                                       // the other groups are way too complex 
for that
+                                       model.getType() === 'single_option' ||
+                                       model.getType() === 'boolean'
+                               ) &&
+                               result[ filterItem.getName() ] === undefined &&
+                               filterItem.isUsingDefaultAsBaseValue()
+                       ) {
+                               result[ filterItem.getName() ] = 
!!defaultFilters[ filterItem.getName() ];
+                       }
                        oneWasSelected = oneWasSelected || !!result[ 
filterItem.getName() ];
                } );
 
diff --git 
a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js 
b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js
index 06fa0aa..8f318ef 100644
--- a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js
+++ b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js
@@ -396,7 +396,10 @@
 
                // Create a map between known parameters and their models
                $.each( this.groups, function ( group, groupModel ) {
-                       if ( groupModel.getType() === 'send_unselected_if_any' 
) {
+                       if (
+                               groupModel.getType() === 
'send_unselected_if_any' ||
+                               groupModel.getType() === 'boolean'
+                       ) {
                                // Individual filters
                                groupModel.getItems().forEach( function ( 
filterItem ) {
                                        model.parameterMap[ 
filterItem.getParamName() ] = filterItem;
@@ -612,16 +615,15 @@
                //    group2: "param4|param5"
                // }
                $.each( params, function ( paramName, paramValue ) {
-                       var itemOrGroup = model.parameterMap[ paramName ];
+                       var groupName,
+                               itemOrGroup = model.parameterMap[ paramName ];
 
-                       if ( itemOrGroup instanceof mw.rcfilters.dm.FilterItem 
) {
-                               groupMap[ itemOrGroup.getGroupName() ] = 
groupMap[ itemOrGroup.getGroupName() ] || {};
-                               groupMap[ itemOrGroup.getGroupName() ][ 
itemOrGroup.getParamName() ] = paramValue;
-                       } else if ( itemOrGroup instanceof 
mw.rcfilters.dm.FilterGroup ) {
-                               // This parameter represents a group (values 
are the filters)
-                               // this is equivalent to checking if the group 
is 'string_options'
-                               groupMap[ itemOrGroup.getName() ] = groupMap[ 
itemOrGroup.getName() ] || {};
-                               groupMap[ itemOrGroup.getName() ] = paramValue;
+                       if ( itemOrGroup ) {
+                               groupName = itemOrGroup instanceof 
mw.rcfilters.dm.FilterItem ?
+                                       itemOrGroup.getGroupName() : 
itemOrGroup.getName();
+
+                               groupMap[ groupName ] = groupMap[ groupName ] 
|| {};
+                               groupMap[ groupName ][ paramName ] = paramValue;
                        }
                } );
 
diff --git a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ItemModel.js 
b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ItemModel.js
index aa82e21..54a4dbe 100644
--- a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ItemModel.js
+++ b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ItemModel.js
@@ -32,6 +32,7 @@
                this.namePrefix = config.namePrefix || 'item_';
                this.name = this.namePrefix + param;
 
+               this.useDefaultAsBaseValue = !!config.useDefaultAsBaseValue;
                this.label = config.label || this.name;
                this.labelPrefixKey = config.labelPrefixKey;
                this.description = config.description || '';
@@ -249,6 +250,15 @@
        };
 
        /**
+        * Check whether the item uses its default state as a base value
+        *
+        * @return {boolean} Use default as base value
+        */
+       mw.rcfilters.dm.ItemModel.prototype.isUsingDefaultAsBaseValue = 
function () {
+               return this.useDefaultAsBaseValue;
+       };
+
+       /**
         * Toggle the highlight feature on and off for this filter.
         * It only works if highlight is supported for this filter.
         *
diff --git 
a/tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js 
b/tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js
index edaef79..da7bafd 100644
--- 
a/tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js
+++ 
b/tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js
@@ -71,6 +71,14 @@
                                { name: 'option2', label: 
'group5option2-label', description: 'group5option2-desc' },
                                { name: 'option3', label: 
'group5option3-label', description: 'group5option3-desc' }
                        ]
+               }, {
+                       name: 'group6',
+                       type: 'boolean',
+                       filters: [
+                               { name: 'group6option1', label: 
'group6option1-label', description: 'group5option1-desc' },
+                               { name: 'group6option2', label: 
'group6option2-label', description: 'group5option2-desc', default: true, 
useDefaultAsBaseValue: true },
+                               { name: 'group6option3', label: 
'group6option3-label', description: 'group5option3-desc', default: true }
+                       ]
                } ],
                viewsDefinition = {
                        namespaces: {
@@ -100,6 +108,9 @@
                        group3: 'filter8',
                        group4: 'option2',
                        group5: 'option1',
+                       group6option1: '0',
+                       group6option2: '1',
+                       group6option3: '1',
                        namespace: ''
                },
                baseParamRepresentation = {
@@ -112,6 +123,9 @@
                        group3: '',
                        group4: 'option2',
                        group5: 'option1',
+                       group6option1: '0',
+                       group6option2: '1',
+                       group6option3: '0',
                        namespace: ''
                },
                baseFilterRepresentation = {
@@ -132,6 +146,9 @@
                        group5__option1: true, // No default set, first item is 
default value
                        group5__option2: false,
                        group5__option3: false,
+                       group6__group6option1: false,
+                       group6__group6option2: true,
+                       group6__group6option3: false,
                        namespace__0: false,
                        namespace__1: false,
                        namespace__2: false,
@@ -153,6 +170,9 @@
                        group5__option1: { selected: true, conflicted: false, 
included: false },
                        group5__option2: { selected: false, conflicted: false, 
included: false },
                        group5__option3: { selected: false, conflicted: false, 
included: false },
+                       group6__group6option1: { selected: false, conflicted: 
false, included: false },
+                       group6__group6option2: { selected: true, conflicted: 
false, included: false },
+                       group6__group6option3: { selected: false, conflicted: 
false, included: false },
                        namespace__0: { selected: false, conflicted: false, 
included: false },
                        namespace__1: { selected: false, conflicted: false, 
included: false },
                        namespace__2: { selected: false, conflicted: false, 
included: false },

-- 
To view, visit https://gerrit.wikimedia.org/r/366511
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I56e9b52ff79a46227de71c905b2ecd97a3823624
Gerrit-PatchSet: 6
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Mooeypoo <mor...@gmail.com>
Gerrit-Reviewer: Catrope <r...@wikimedia.org>
Gerrit-Reviewer: Jack Phoenix <j...@countervandalism.net>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to