From 30b1147f4ff7f576a3fea1ca5cf0fe7dfbc0bfdb Mon Sep 17 00:00:00 2001 From: Moriel Schottlender Date: Mon, 31 Jul 2017 16:37:13 -0700 Subject: [PATCH] RCFilters: Normalize arbitrary values before adding them Bug: T172026 Change-Id: Iba0e20b6d4266e22b3e894742dd182291f741eb1 --- includes/specials/SpecialRecentchanges.php | 8 ++++ .../dm/mw.rcfilters.dm.FilterGroup.js | 24 ++++++++++ .../mw.rcfilters.Controller.js | 47 ++++++++++++++----- .../mw.rcfilters.UriProcessor.js | 29 +++++++++++- 4 files changed, 94 insertions(+), 14 deletions(-) diff --git a/includes/specials/SpecialRecentchanges.php b/includes/specials/SpecialRecentchanges.php index 157c3ed368..46f7927bb1 100644 --- a/includes/specials/SpecialRecentchanges.php +++ b/includes/specials/SpecialRecentchanges.php @@ -193,6 +193,14 @@ class SpecialRecentChanges extends ChangesListSpecialPage { 'wgRCFiltersChangeTags', $this->buildChangeTagList() ); + $out->addJsConfigVars( + 'StructuredChangeFiltersDisplayConfig', + [ + 'maxLimit' => (int)$this->getConfig()->get( 'RCMaxAge' ) / ( 24 * 3600 ), // Translate to days + 'arrayLimit' => $this->getConfig()->get( 'RCLinkLimits' ), + 'arrayDays' => $this->getConfig()->get( 'RCLinkDays' ), + ] + ); } } 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 5cca5d836e..536680e656 100644 --- a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js +++ b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterGroup.js @@ -17,6 +17,9 @@ * @cfg {boolean} [hidden] This group is hidden from the regular menu views * @cfg {boolean} [allowArbitrary] Allows for an arbitrary value to be added to the * group from the URL, even if it wasn't initially set up. + * @cfg {number} [range] An object defining minimum and maximum values for numeric + * groups. { min: x, max: y } + * @cfg {number} [minValue] Minimum value for numeric groups * @cfg {string} [separator='|'] Value separator for 'string_options' groups * @cfg {boolean} [active] Group is active * @cfg {boolean} [fullCoverage] This filters in this group collectively cover all results @@ -44,6 +47,7 @@ this.title = config.title || name; this.hidden = !!config.hidden; this.allowArbitrary = !!config.allowArbitrary; + this.numericRange = config.range; this.separator = config.separator || '|'; this.labelPrefixKey = config.labelPrefixKey; @@ -288,6 +292,26 @@ return this.allowArbitrary; }; + /** + * Get group maximum value for numeric groups + * + * @return {number|null} Group max value + */ + mw.rcfilters.dm.FilterGroup.prototype.getMaxValue = function () { + return this.numericRange && this.numericRange.max !== undefined ? + this.numericRange.max : null; + }; + + /** + * Get group minimum value for numeric groups + * + * @return {number|null} Group max value + */ + mw.rcfilters.dm.FilterGroup.prototype.getMinValue = function () { + return this.numericRange && this.numericRange.min !== undefined ? + this.numericRange.min : null; + }; + /** * Get group name * diff --git a/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js b/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js index fbd44fd414..79b3d6f1c6 100644 --- a/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js +++ b/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js @@ -33,6 +33,7 @@ */ mw.rcfilters.Controller.prototype.initialize = function ( filterStructure, namespaceStructure, tagList ) { var parsedSavedQueries, limitDefault, + displayConfig = mw.config.get( 'StructuredChangeFiltersDisplayConfig' ), controller = this, views = {}, items = [], @@ -103,6 +104,10 @@ hidden: true, allowArbitrary: true, validate: $.isNumeric, + range: { + min: 1, + max: 1000 + }, sortFunc: function ( a, b ) { return Number( a.name ) - Number( b.name ); }, 'default': String( limitDefault ), // Temporarily making this not sticky until we resolve the problem @@ -110,7 +115,7 @@ // we should remove all sticky behavior methods completely // See T172156 // isSticky: true, - filters: [ 50, 100, 250, 500 ].map( function ( num ) { + filters: displayConfig.arrayLimit.map( function ( num ) { return controller._createFilterDataFromNumber( num, num ); } ) }, @@ -121,6 +126,10 @@ hidden: true, allowArbitrary: true, validate: $.isNumeric, + range: { + min: 0, + max: displayConfig.maxLimit + }, sortFunc: function ( a, b ) { return Number( a.name ) - Number( b.name ); }, numToLabelFunc: function ( i ) { return Number( i ) < 1 ? @@ -132,16 +141,16 @@ // isSticky: true, filters: [ // Hours (1, 2, 6, 12) - 0.04166, 0.0833, 0.25, 0.5, - // Days - 1, 3, 7, 14, 30 - ].map( function ( num ) { - return controller._createFilterDataFromNumber( - num, - // Convert fractions of days to number of hours for the labels - num < 1 ? Math.round( num * 24 ) : num - ); - } ) + 0.04166, 0.0833, 0.25, 0.5 + // Days + ].concat( displayConfig.arrayDays ) + .map( function ( num ) { + return controller._createFilterDataFromNumber( + num, + // Convert fractions of days to number of hours for the labels + num < 1 ? Math.round( num * 24 ) : num + ); + } ) } ] }; @@ -257,6 +266,18 @@ arbitraryValues = Array.isArray( arbitraryValues ) ? arbitraryValues : [ arbitraryValues ]; + // Normalize the arbitrary values + if ( groupData.range ) { + arbitraryValues = arbitraryValues.map( function ( val ) { + if ( val < 0 ) { + return groupData.range.min; // Min + } else if ( val >= groupData.range.max ) { + return groupData.range.max; // Max + } + return val; + } ); + } + // This is only true for single_option group // We assume these are the only groups that will allow for // arbitrary, since it doesn't make any sense for the other @@ -274,9 +295,9 @@ // but if that value isn't already in the definition groupData.filters .map( function ( filterData ) { - return filterData.name; + return String( filterData.name ); } ) - .indexOf( val ) === -1 + .indexOf( String( val ) ) === -1 ) { // Add the filter information groupData.filters.push( controller._createFilterDataFromNumber( diff --git a/resources/src/mediawiki.rcfilters/mw.rcfilters.UriProcessor.js b/resources/src/mediawiki.rcfilters/mw.rcfilters.UriProcessor.js index ba61ba9f60..a1ef981aae 100644 --- a/resources/src/mediawiki.rcfilters/mw.rcfilters.UriProcessor.js +++ b/resources/src/mediawiki.rcfilters/mw.rcfilters.UriProcessor.js @@ -71,7 +71,34 @@ * @param {Object} [uriQuery] URI query */ mw.rcfilters.UriProcessor.prototype.updateModelBasedOnQuery = function ( uriQuery ) { - var parameters = this._getNormalizedQueryParams( uriQuery || new mw.Uri().query ); + var parameters; + + uriQuery = uriQuery || new mw.Uri().query; + + // For arbitrary numeric single_option values, check the uri and see if it's beyond the limit + $.each( this.filtersModel.getFilterGroups(), function ( groupName, groupModel ) { + if ( + groupModel.getType() === 'single_option' && + groupModel.isAllowArbitrary() + ) { + if ( + groupModel.getMaxValue() !== null && + uriQuery[ groupName ] > groupModel.getMaxValue() + ) { + // Change the value to the actual max value + uriQuery[ groupName ] = String( groupModel.getMaxValue() ); + } else if ( + groupModel.getMinValue() !== null && + uriQuery[ groupName ] < groupModel.getMinValue() + ) { + // Change the value to the actual min value + uriQuery[ groupName ] = String( groupModel.getMinValue() ); + } + } + } ); + + // Normalize + parameters = this._getNormalizedQueryParams( uriQuery ); // Update filter states this.filtersModel.toggleFiltersSelected( -- 2.20.1