Mooeypoo has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/335177 )
Change subject: [wip^2] Make 'groups' a model in the FiltersViewModel ...................................................................... [wip^2] Make 'groups' a model in the FiltersViewModel Bug: T156533 Change-Id: Iebde3138e16bac7f62e8f557e5ce08f41a9535cb --- M resources/Resources.php A 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/ui/mw.rcfilters.ui.FilterGroupWidget.js M resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js M resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FiltersListWidget.js 6 files changed, 193 insertions(+), 67 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core refs/changes/77/335177/1 diff --git a/resources/Resources.php b/resources/Resources.php index f14787f..94d7d99 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -1737,6 +1737,7 @@ 'scripts' => [ 'resources/src/mediawiki.rcfilters/mw.rcfilters.js', 'resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterItem.js', + 'resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js', 'resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js', 'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FiltersListWidget.js', 'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterGroupWidget.js', diff --git a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js new file mode 100644 index 0000000..9c8da19 --- /dev/null +++ b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js @@ -0,0 +1,88 @@ +( function ( mw, $ ) { + /** + * View model for a filter group + * + * @mixins OO.EventEmitter + * @mixins OO.EmitterList + * + * @constructor + * @param {Object} [config] Configuration options + * @cfg {string} [type='send_unselected_if_any'] Group type + * @cfg {string} [title] Group title + * @cfg {string} [separator='|'] Value separator for 'string_options' groups + * @cfg {string} [exclusionType='default'] Group exclusion type + * @cfg {boolean} [active] Group is active + */ + mw.rcfilters.dm.FilterGroup = function MwRcfiltersDmFilterGroup( config ) { + config = config || {}; + + // Mixin constructor + OO.EventEmitter.call( this ); + OO.EmitterList.call( this ); + + this.type = config.type || 'send_unselected_if_any'; + this.title = config.title; + this.separator = config.separator || '|'; + this.exclusionType = config.exclusionType || 'default'; + this.active = !!config.active; + }; + + /* Initialization */ + OO.initClass( mw.rcfilters.dm.FilterGroup ); + OO.mixinClass( mw.rcfilters.dm.FilterGroup, OO.EventEmitter ); + + /* Events */ + + /** + * @event update + * + * Group state has been updated + */ + + /* Methods */ + + /** + * Check the active status of the group and set it accordingly. + * + * @fires update + */ + mw.rcfilters.dm.FilterGroup.prototype.checkActive = function () { + var active, + count = 0; + + // Recheck group activity + this.getItems().forEach( function ( filterItem ) { + count += Number( filterItem.isSelected() ); + } ); + + active = ( + count > 0 && + count < filters.length + ); + + if ( this.active !== active ) { + this.active = active; + this.emit( 'update' ); + } + }; + + mw.rcfilters.dm.FilterGroup.prototype.isActive = function ( active ) { + return this.active; + }; + + mw.rcfilters.dm.FilterGroup.prototype.getType = function () { + return this.type; + }; + + mw.rcfilters.dm.FilterGroup.prototype.getTitle = function () { + return this.title; + }; + + mw.rcfilters.dm.FilterGroup.prototype.getSeparator = function () { + return this.separator; + }; + + mw.rcfilters.dm.FilterGroup.prototype.getExclusionType = function () { + return this.exclusionType; + }; +}( mediaWiki, jQuery ) ); 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 3f7fa53..472f823 100644 --- a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js +++ b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js @@ -54,8 +54,33 @@ // Reapply the active state of filters this.reapplyActiveFilters( item ); + // Recheck group activity state + this.groups[ item.getGroup() ].checkActive(); + this.emit( 'itemUpdate', item ); }; + + /** + * Get the current state of the filters. + * + * Checks whether the filter group is active. This means at least one + * filter is selected, but not all filters are selected. + * + * @param {string} groupName Group name + * @return {boolean} Filter group is active + */ + // mw.rcfilters.dm.FiltersViewModel.prototype.isFilterGroupActive = function ( groupName ) { + // var count = 0; + + // this.groups[ groupName ].getItems().forEach( function ( filterItem ) { + // count += Number( filterItem.isSelected() ); + // } ); + + // return ( + // count > 0 && + // count < filters.length + // ); + // }; /** * Calculate the active state of the filters, based on selected filters in the group. @@ -67,8 +92,8 @@ group = item.getGroup(), model = this; if ( - !this.groups[ group ].exclusionType || - this.groups[ group ].exclusionType === 'default' + !this.groups[ group ].getExclusionType() || + this.groups[ group ].getExclusionType() === 'default' ) { // Default behavior // If any parameter is selected, but: @@ -76,16 +101,16 @@ // - If the entire group is selected, all are inactive // Check what's selected in the group - selectedItemsCount = this.groups[ group ].filters.filter( function ( filterItem ) { + selectedItemsCount = this.groups[ group ].getItems().filter( function ( filterItem ) { return filterItem.isSelected(); } ).length; - this.groups[ group ].filters.forEach( function ( filterItem ) { + this.groups[ group ].getItems().forEach( function ( filterItem ) { filterItem.toggleActive( selectedItemsCount > 0 ? // If some items are selected ( - selectedItemsCount === model.groups[ group ].filters.length ? + selectedItemsCount === model.groups[ group ].getItemCount() ? // If **all** items are selected, they're all inactive false : // If not all are selected, then the selected are active @@ -96,7 +121,7 @@ true ); } ); - } else if ( this.groups[ group ].exclusionType === 'explicit' ) { + } else if ( this.groups[ group ].getExclusionType() === 'explicit' ) { // Explicit behavior // - Go over the list of excluded filters to change their // active states accordingly @@ -157,13 +182,14 @@ this.excludedByMap = {}; $.each( filters, function ( group, data ) { - model.groups[ group ] = model.groups[ group ] || {}; - model.groups[ group ].filters = model.groups[ group ].filters || []; - - model.groups[ group ].title = data.title; - model.groups[ group ].type = data.type; - model.groups[ group ].separator = data.separator || '|'; - model.groups[ group ].exclusionType = data.exclusionType || 'default'; + if ( !model.groups[ group ] ) { + model.groups[ group ] = new mw.rcfilters.dm.FilterGroup( { + type: data.type, + title: data.title, + separator: data.separator, + exclusionType: data.exclusionType + } ); + } selectedFilterNames = []; for ( i = 0; i < data.filters.length; i++ ) { @@ -192,7 +218,7 @@ selectedFilterNames.push( data.filters[ i ].name ); } - model.groups[ group ].filters.push( filterItem ); + model.groups[ group ].addItems( filterItem ); items.push( filterItem ); } @@ -200,7 +226,7 @@ // Store the default parameter group state // For this group, the parameter is group name and value is the names // of selected items - model.defaultParams[ group ] = model.sanitizeStringOptionGroup( group, selectedFilterNames ).join( model.groups[ group ].separator ); + model.defaultParams[ group ] = model.sanitizeStringOptionGroup( group, selectedFilterNames ).join( model.groups[ group ].getSeparator() ); } } ); @@ -231,9 +257,19 @@ * * @return {Object} Filter groups */ - mw.rcfilters.dm.FiltersViewModel.prototype.getFilterGroups = function () { - return this.groups; - }; + // mw.rcfilters.dm.FiltersViewModel.prototype.getFilterGroups = function () { + // return this.groups; + // }; + + + + + + + + + + /** * Get the current state of the filters. @@ -244,19 +280,18 @@ * @param {string} groupName Group name * @return {boolean} Filter group is active */ - mw.rcfilters.dm.FiltersViewModel.prototype.isFilterGroupActive = function ( groupName ) { - var count = 0, - filters = this.groups[ groupName ].filters; + // mw.rcfilters.dm.FiltersViewModel.prototype.isFilterGroupActive = function ( groupName ) { + // var count = 0; - filters.forEach( function ( filterItem ) { - count += Number( filterItem.isSelected() ); - } ); + // this.groups[ groupName ].getItems().forEach( function ( filterItem ) { + // count += Number( filterItem.isSelected() ); + // } ); - return ( - count > 0 && - count < filters.length - ); - }; + // return ( + // count > 0 && + // count < filters.length + // ); + // }; /** * Update the representation of the parameters. These are the back-end @@ -404,7 +439,7 @@ */ mw.rcfilters.dm.FiltersViewModel.prototype.sanitizeStringOptionGroup = function( groupName, valueArray ) { var result = [], - validNames = this.groups[ groupName ].filters.map( function ( filterItem ) { + validNames = this.groups[ groupName ].getItems().map( function ( filterItem ) { return filterItem.getName(); } ); @@ -500,7 +535,7 @@ } else if ( model.groups.hasOwnProperty( paramName ) ) { // This parameter represents a group (values are the filters) // this is equivalent to checking if the group is 'string_options' - groupMap[ paramName ] = { filters: model.groups[ paramName ].filters }; + groupMap[ paramName ] = { filters: model.groups[ paramName ].getItems() }; } } ); @@ -510,7 +545,7 @@ var paramValues, filterItem, allItemsInGroup = data.filters; - if ( model.groups[ group ].type === 'send_unselected_if_any' ) { + if ( model.groups[ group ].getType() === 'send_unselected_if_any' ) { for ( i = 0; i < allItemsInGroup.length; i++ ) { filterItem = allItemsInGroup[ i ]; @@ -523,8 +558,8 @@ // group, which means the state is false false; } - } else if ( model.groups[ group ].type === 'string_options' ) { - paramValues = model.sanitizeStringOptionGroup( group, params[ group ].split( model.groups[ group ].separator ) ); + } else if ( model.groups[ group ].getType() === 'string_options' ) { + paramValues = model.sanitizeStringOptionGroup( group, params[ group ].split( model.groups[ group ].getSeparator() ) ); for ( i = 0; i < allItemsInGroup.length; i++ ) { filterItem = allItemsInGroup[ i ]; @@ -533,7 +568,7 @@ // If it is the word 'all' paramValues.length === 1 && paramValues[ 0 ] === 'all' || // All values are written - paramValues.length === model.groups[ group ].filters.length + paramValues.length === model.groups[ group ].getItemCount() ) ? // All true (either because all values are written or the term 'all' is written) // is the same as all filters set to false diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterGroupWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterGroupWidget.js index 27232585d..58d5b45 100644 --- a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterGroupWidget.js +++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterGroupWidget.js @@ -7,22 +7,27 @@ * @mixins OO.ui.mixin.LabelElement * * @constructor - * @param {string} name Group name + * @param {mw.rcfilters.dm.FilterGroup} model Filter group model * @param {Object} config Configuration object */ - mw.rcfilters.ui.FilterGroupWidget = function MwRcfiltersUiFilterGroupWidget( name, config ) { + mw.rcfilters.ui.FilterGroupWidget = function MwRcfiltersUiFilterGroupWidget( model, config ) { config = config || {}; // Parent mw.rcfilters.ui.FilterGroupWidget.parent.call( this, config ); + + this.model = model; + // Mixin constructors OO.ui.mixin.GroupWidget.call( this, config ); OO.ui.mixin.LabelElement.call( this, $.extend( {}, config, { + label: this.model.getTitle(), $label: $( '<div>' ) .addClass( 'mw-rcfilters-ui-filterGroupWidget-title' ) } ) ); - this.name = name; + + this.model.connect( this, { update: 'onModelUpdate' } ); this.$element .addClass( 'mw-rcfilters-ui-filterGroupWidget' ) @@ -40,12 +45,22 @@ OO.mixinClass( mw.rcfilters.ui.FilterGroupWidget, OO.ui.mixin.LabelElement ); /** + * Respond to model update event + */ + mw.rcfilters.ui.FilterGroupWidget.prototype.onModelUpdate = function () { + this.$element.toggleClass( + 'mw-rcfilters-ui-filterGroupWidget-active', + this.model.isActive() + ); + }; + + /** * Get the group name * * @return {string} Group name */ mw.rcfilters.ui.FilterGroupWidget.prototype.getName = function () { - return this.name; + return this.model.getName(); }; /** @@ -54,7 +69,6 @@ * @param {boolean} isActive The group is active */ mw.rcfilters.ui.FilterGroupWidget.prototype.toggleActiveState = function ( isActive ) { - this.$element.toggleClass( 'mw-rcfilters-ui-filterGroupWidget-active', isActive ); }; }( mediaWiki, jQuery ) ); diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js index 34cc240..aa656e8 100644 --- a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js +++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js @@ -139,13 +139,6 @@ } else { this.capsule.removeItemsFromData( [ item.getName() ] ); } - - // Toggle the active state of the group - this.filterPopup.getItems().forEach( function ( groupWidget ) { - if ( groupWidget.getName() === item.getGroup() ) { - groupWidget.toggleActiveState( widget.model.isFilterGroupActive( groupWidget.getName() ) ); - } - } ); }; /** diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FiltersListWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FiltersListWidget.js index f5ec1fc..8ce3863 100644 --- a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FiltersListWidget.js +++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FiltersListWidget.js @@ -60,7 +60,8 @@ * Respond to initialize event from the model */ mw.rcfilters.ui.FiltersListWidget.prototype.onModelInitialize = function () { - var i, group, groupWidget, + var i, group, groupWidget, groupModel, + widget = this, itemWidgets = [], groupWidgets = [], groups = this.model.getFilterGroups(); @@ -69,28 +70,22 @@ this.clearItems(); for ( group in groups ) { - groupWidget = new mw.rcfilters.ui.FilterGroupWidget( group, { - label: groups[ group ].title - } ); + groupModel = groups[ group ]; + groupWidget = new mw.rcfilters.ui.FilterGroupWidget( groupModel ); groupWidgets.push( groupWidget ); - itemWidgets = []; - if ( groups[ group ].filters ) { - for ( i = 0; i < groups[ group ].filters.length; i++ ) { - itemWidgets.push( - new mw.rcfilters.ui.FilterItemWidget( - this.controller, - groups[ group ].filters[ i ], - { - label: groups[ group ].filters[ i ].getLabel(), - description: groups[ group ].filters[ i ].getDescription() - } - ) - ); - } + itemWidgets = groupModel.getItems().map( function ( filterItem ) { + return new mw.rcfilters.ui.FilterItemWidget( + widget.controller, + filterItem, + { + label: filterItem.getLabel(), + description: filterItem.getDescription() + } + ); + } ); - groupWidget.addItems( itemWidgets ); - } + groupWidget.addItems( itemWidgets ); } this.addItems( groupWidgets ); -- To view, visit https://gerrit.wikimedia.org/r/335177 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iebde3138e16bac7f62e8f557e5ce08f41a9535cb Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/core Gerrit-Branch: master Gerrit-Owner: Mooeypoo <mor...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits