From: Moriel Schottlender Date: Wed, 21 Jun 2017 00:37:17 +0000 (-0700) Subject: RCFilters: Have the model accept multiple views X-Git-Tag: 1.31.0-rc.0~2910^2~1 X-Git-Url: https://git.heureux-cyclage.org/?a=commitdiff_plain;h=11d7c69377d9b9af640e9e962cbd8d378d23632d;p=lhc%2Fweb%2Fwiklou.git RCFilters: Have the model accept multiple views Organize the way we create and process multiple views, to stop hard-coding namespaces and tags. Change-Id: Ib28c166052781b23a3b35c1b7b0af7d26f102e3f --- 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 bec40b4d99..d3fb66e8f5 100644 --- a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js +++ b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js @@ -35,7 +35,7 @@ this.name = name; this.type = config.type || 'send_unselected_if_any'; this.view = config.view || 'default'; - this.title = config.title; + this.title = config.title || name; this.separator = config.separator || '|'; this.labelPrefixKey = config.labelPrefixKey; 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 6825fa456c..ad0794e5f5 100644 --- a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js +++ b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js @@ -206,15 +206,34 @@ * Set filters and preserve a group relationship based on * the definition given by an object * - * @param {Array} filters Filter group definition - * @param {Object} [namespaces] Namespace definition - * @param {Object[]} [tags] Tag array definition + * @param {Array} filters Filters definition + * @param {Object} [views] Extra views definition + * Expected in the following format: + * { + * namespaces: { + * label: 'namespaces', // Message key + * trigger: ':', + * groups: [ + * { + * // Group info + * name: 'namespaces' // Parameter name + * definition: { + * title: 'namespaces' // Message key + * type: 'string_options', + * separator: ';', + * labelPrefixKey: { 'default': 'rcfilters-tag-prefix-namespace', inverted: 'rcfilters-tag-prefix-namespace-inverted' }, + * fullCoverage: true + * }, + * items: [] + * } + * ] + * } + * } */ - mw.rcfilters.dm.FiltersViewModel.prototype.initializeFilters = function ( filters, namespaces, tags ) { + mw.rcfilters.dm.FiltersViewModel.prototype.initializeFilters = function ( filters, views ) { var filterItem, filterConflictResult, groupConflictResult, model = this, items = [], - namespaceDefinition = [], groupConflictMap = {}, filterConflictMap = {}, /*! @@ -280,6 +299,8 @@ this.groups = {}; this.views = {}; + views = views || {}; + // Filters this.views.default = { name: 'default', label: mw.msg( 'rcfilters-filterlist-title' ) }; filters.forEach( function ( data ) { @@ -326,70 +347,28 @@ } } ); - namespaces = namespaces || {}; - if ( - mw.config.get( 'wgStructuredChangeFiltersEnableExperimentalViews' ) && - !$.isEmptyObject( namespaces ) - ) { - // Namespaces group - this.views.namespaces = { name: 'namespaces', label: mw.msg( 'namespaces' ), trigger: ':' }; - $.each( namespaces, function ( namespaceID, label ) { - // Build and clean up the definition - namespaceDefinition.push( { - name: namespaceID, - label: label || mw.msg( 'blanknamespace' ), - description: '', - identifiers: [ - ( namespaceID < 0 || namespaceID % 2 === 0 ) ? - 'subject' : 'talk' - ], - cssClass: 'mw-changeslist-ns-' + namespaceID - } ); - } ); - - // Add the group - model.groups.namespace = new mw.rcfilters.dm.FilterGroup( - 'namespace', // Parameter name is singular - { - type: 'string_options', - view: 'namespaces', - title: 'namespaces', // Message key - separator: ';', - labelPrefixKey: { 'default': 'rcfilters-tag-prefix-namespace', inverted: 'rcfilters-tag-prefix-namespace-inverted' }, - fullCoverage: true - } - ); - // Add namespace items to group - model.groups.namespace.initializeFilters( namespaceDefinition ); - items = items.concat( model.groups.namespace.getItems() ); - } + if ( mw.config.get( 'wgStructuredChangeFiltersEnableExperimentalViews' ) ) { + $.each( views, function ( viewName, viewData ) { + model.views[ viewName ] = { + name: viewData.name, + title: viewData.title, + trigger: viewData.trigger + }; - tags = tags || []; - if ( - mw.config.get( 'wgStructuredChangeFiltersEnableExperimentalViews' ) && - tags.length > 0 - ) { - // Define view - this.views.tags = { name: 'tags', label: mw.msg( 'rcfilters-view-tags' ), trigger: '#' }; - - // Add the group - model.groups.tagfilter = new mw.rcfilters.dm.FilterGroup( - 'tagfilter', - { - type: 'string_options', - view: 'tags', - title: 'rcfilters-view-tags', // Message key - labelPrefixKey: 'rcfilters-tag-prefix-tags', - separator: '|', - fullCoverage: false - } - ); + // Group + viewData.groups.forEach( function ( groupData ) { + model.groups[ groupData.name ] = new mw.rcfilters.dm.FilterGroup( + groupData.name, + $.extend( true, {}, groupData.definition, { view: viewName } ) + ); - // Add tag items to group - model.groups.tagfilter.initializeFilters( tags ); + // Add items + model.groups[ groupData.name ].initializeFilters( groupData.items ); - // Add item references to the model, for lookup - items = items.concat( model.groups.tagfilter.getItems() ); + // Add to global search list + items = items.concat( model.groups[ groupData.name ].getItems() ); + } ); + } ); } // Add item references to the model, for lookup @@ -929,7 +908,7 @@ * @return {string} Label for the current view */ mw.rcfilters.dm.FiltersViewModel.prototype.getCurrentViewLabel = function () { - return this.views[ this.getCurrentView() ].label; + return this.views[ this.getCurrentView() ].title; }; /** diff --git a/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js b/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js index 95e11d59f3..23398e5b88 100644 --- a/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js +++ b/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js @@ -29,11 +29,66 @@ */ mw.rcfilters.Controller.prototype.initialize = function ( filterStructure, namespaceStructure, tagList ) { var parsedSavedQueries, + views = {}, + items = [], uri = new mw.Uri(), $changesList = $( '.mw-changeslist' ).first().contents(); + // Prepare views + if ( namespaceStructure ) { + items = []; + $.each( namespaceStructure, function ( namespaceID, label ) { + // Build and clean up the individual namespace items definition + items.push( { + name: namespaceID, + label: label || mw.msg( 'blanknamespace' ), + description: '', + identifiers: [ + ( namespaceID < 0 || namespaceID % 2 === 0 ) ? + 'subject' : 'talk' + ], + cssClass: 'mw-changeslist-ns-' + namespaceID + } ); + } ); + + views.namespaces = { + title: mw.msg( 'namespaces' ), + trigger: ':', + groups: [ { + // Group definition (single group) + name: 'namespaces', + definition: { + type: 'string_options', + title: mw.msg( 'namespaces' ), + labelPrefixKey: { 'default': 'rcfilters-tag-prefix-namespace', inverted: 'rcfilters-tag-prefix-namespace-inverted' }, + separator: ';', + fullCoverage: true + }, + items: items + } ] + }; + } + if ( tagList ) { + views.tags = { + title: mw.msg( 'rcfilters-view-tags' ), + trigger: '#', + groups: [ { + // Group definition (single group) + name: 'tagfilter', // Parameter name + definition: { + type: 'string_options', + title: 'rcfilters-view-tags', // Message key + labelPrefixKey: 'rcfilters-tag-prefix-tags', + separator: '|', + fullCoverage: false + }, + items: tagList + } ] + }; + } + // Initialize the model - this.filtersModel.initializeFilters( filterStructure, namespaceStructure, tagList ); + this.filtersModel.initializeFilters( filterStructure, views ); this._buildBaseFilterState(); 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 233ec761ee..13c8c3dbf3 100644 --- a/tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js +++ b/tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js @@ -66,15 +66,26 @@ } ] } ], - namespaces = { - 0: 'Main', - 1: 'Talk', - 2: 'User', - 3: 'User talk' + views = { + namespaces: { + label: 'Namespaces', + trigger: ':', + groups: [ { + name: 'namespace', + label: 'Namespaces', + separator: ';', + items: [ + { name: 0, label: 'Main' }, + { name: 1, label: 'Talk' }, + { name: 2, label: 'User' }, + { name: 3, label: 'User talk' } + ] + } ] + } }, model = new mw.rcfilters.dm.FiltersViewModel(); - model.initializeFilters( definition, namespaces ); + model.initializeFilters( definition, views ); assert.ok( model.getItemByName( 'group1__filter1' ) instanceof mw.rcfilters.dm.FilterItem && @@ -256,11 +267,22 @@ } ] } ], - namespaces = { - 0: 'Main', - 1: 'Talk', - 2: 'User', - 3: 'User talk' + views = { + namespaces: { + label: 'Namespaces', + trigger: ':', + groups: [ { + name: 'namespace', + label: 'Namespaces', + separator: ';', + items: [ + { name: 0, label: 'Main' }, + { name: 1, label: 'Talk' }, + { name: 2, label: 'User' }, + { name: 3, label: 'User talk' } + ] + } ] + } }, testCases = [ { @@ -311,7 +333,7 @@ return result; }; - model.initializeFilters( definition, namespaces ); + model.initializeFilters( definition, views ); testCases.forEach( function ( testCase ) { matches = model.findMatches( testCase.query );