X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=resources%2Fsrc%2Fmediawiki.rcfilters%2Fmw.rcfilters.UriProcessor.js;h=53557f641fe6520f0c44aec427c926074c32b78b;hp=ba61ba9f60f3b40f3f78fa587e7747e2fdc70b71;hb=20fcae98034d264bdc1979d543c9ebf1f1b4506b;hpb=8804850f4489fc628df550ae1305fe9f4140bcab diff --git a/resources/src/mediawiki.rcfilters/mw.rcfilters.UriProcessor.js b/resources/src/mediawiki.rcfilters/mw.rcfilters.UriProcessor.js index ba61ba9f60..53557f641f 100644 --- a/resources/src/mediawiki.rcfilters/mw.rcfilters.UriProcessor.js +++ b/resources/src/mediawiki.rcfilters/mw.rcfilters.UriProcessor.js @@ -6,11 +6,7 @@ * @param {mw.rcfilters.dm.FiltersViewModel} filtersModel Filters view model */ mw.rcfilters.UriProcessor = function MwRcfiltersController( filtersModel ) { - this.emptyParameterState = {}; this.filtersModel = filtersModel; - - // Initialize - this._buildEmptyParameterState(); }; /* Initialization */ @@ -59,81 +55,110 @@ }; /** - * Update the filters model based on the URI query - * This happens on initialization, and from this moment on, - * we consider the system synchronized, and the model serves - * as the source of truth for the URL. - * - * This methods should only be called once on initialiation. - * After initialization, the model updates the URL, not the - * other way around. - * - * @param {Object} [uriQuery] URI query + * Replace the current URI with an updated one from the model state */ - mw.rcfilters.UriProcessor.prototype.updateModelBasedOnQuery = function ( uriQuery ) { - var parameters = this._getNormalizedQueryParams( uriQuery || new mw.Uri().query ); + mw.rcfilters.UriProcessor.prototype.replaceUpdatedUri = function () { + this.constructor.static.replaceState( this.getUpdatedUri() ); + }; - // Update filter states - this.filtersModel.toggleFiltersSelected( - this.filtersModel.getFiltersFromParameters( - parameters + /** + * Get an updated mw.Uri object based on the model state + * + * @param {Object} [uriQuery] An external URI query to build the new uri + * with. This is mainly for tests, to be able to supply external parameters + * and make sure they are retained. + * @return {mw.Uri} Updated Uri + */ + mw.rcfilters.UriProcessor.prototype.getUpdatedUri = function ( uriQuery ) { + var uri = new mw.Uri(), + unrecognizedParams = this.getUnrecognizedParams( uriQuery || uri.query ); + + if ( uriQuery ) { + // This is mainly for tests, to be able to give the method + // an initial URI Query and test that it retains parameters + uri.query = uriQuery; + } + + uri.query = this.filtersModel.getMinimizedParamRepresentation( + $.extend( + true, + {}, + uri.query, + // The representation must be expanded so it can + // override the uri query params but we then output + // a minimized version for the entire URI representation + // for the method + this.filtersModel.getExpandedParamRepresentation() ) ); - this.filtersModel.toggleInvertedNamespaces( !!Number( parameters.invert ) ); + // Reapply unrecognized params and url version + uri.query = $.extend( true, {}, uri.query, unrecognizedParams, { urlversion: '2' } ); + + return uri; + }; - // Update highlight state - this.filtersModel.toggleHighlight( !!Number( parameters.highlight ) ); - this.filtersModel.getItems().forEach( function ( filterItem ) { - var color = parameters[ filterItem.getName() + '_color' ]; - if ( color ) { - filterItem.setHighlightColor( color ); - } else { - filterItem.clearHighlightColor(); + /** + * Get an object representing given parameters that are unrecognized by the model + * + * @param {Object} params Full params object + * @return {Object} Unrecognized params + */ + mw.rcfilters.UriProcessor.prototype.getUnrecognizedParams = function ( params ) { + // Start with full representation + var givenParamNames = Object.keys( params ), + unrecognizedParams = $.extend( true, {}, params ); + + // Extract unrecognized parameters + Object.keys( this.filtersModel.getEmptyParameterState() ).forEach( function ( paramName ) { + // Remove recognized params + if ( givenParamNames.indexOf( paramName ) > -1 ) { + delete unrecognizedParams[ paramName ]; } } ); - // Check all filter interactions - this.filtersModel.reassessFilterInteractions(); + return unrecognizedParams; }; /** - * Get parameters representing the current state of the model + * Update the URL of the page to reflect current filters + * + * This should not be called directly from outside the controller. + * If an action requires changing the URL, it should either use the + * highlighting actions below, or call #updateChangesList which does + * the uri corrections already. * - * @return {Object} Uri query parameters + * @param {Object} [params] Extra parameters to add to the API call */ - mw.rcfilters.UriProcessor.prototype.getUriParametersFromModel = function () { - return $.extend( - true, - {}, - this.filtersModel.getParametersFromFilters(), - this.filtersModel.getHighlightParameters(), - { - highlight: String( Number( this.filtersModel.isHighlightEnabled() ) ), - invert: String( Number( this.filtersModel.areNamespacesInverted() ) ) - } - ); + mw.rcfilters.UriProcessor.prototype.updateURL = function ( params ) { + var currentUri = new mw.Uri(), + updatedUri = this.getUpdatedUri(); + + updatedUri.extend( params || {} ); + + if ( + this.getVersion( currentUri.query ) !== 2 || + this.isNewState( currentUri.query, updatedUri.query ) + ) { + this.constructor.static.replaceState( updatedUri ); + } }; /** - * Build the full parameter representation based on given query parameters + * Update the filters model based on the URI query + * This happens on initialization, and from this moment on, + * we consider the system synchronized, and the model serves + * as the source of truth for the URL. * - * @private - * @param {Object} uriQuery Given URI query - * @return {Object} Full parameter state representing the URI query + * This methods should only be called once on initialiation. + * After initialization, the model updates the URL, not the + * other way around. + * + * @param {Object} [uriQuery] URI query */ - mw.rcfilters.UriProcessor.prototype._expandModelParameters = function ( uriQuery ) { - var filterRepresentation = this.filtersModel.getFiltersFromParameters( uriQuery ); - - return $.extend( true, - {}, - uriQuery, - this.filtersModel.getParametersFromFilters( filterRepresentation ), - this.filtersModel.extractHighlightValues( uriQuery ), - { - highlight: String( Number( uriQuery.highlight ) ), - invert: String( Number( uriQuery.invert ) ) - } + mw.rcfilters.UriProcessor.prototype.updateModelBasedOnQuery = function ( uriQuery ) { + this.filtersModel.updateStateFromParams( + this._getNormalizedQueryParams( uriQuery || new mw.Uri().query ) ); }; @@ -158,8 +183,18 @@ // This will allow us to always have a proper check of whether // the requested new url is one to change or not, regardless of // actual parameter visibility/representation in the URL - currentParamState = this._expandModelParameters( currentUriQuery ); - updatedParamState = this._expandModelParameters( updatedUriQuery ); + currentParamState = $.extend( + true, + {}, + this.filtersModel.getMinimizedParamRepresentation( currentUriQuery ), + this.getUnrecognizedParams( currentUriQuery ) + ); + updatedParamState = $.extend( + true, + {}, + this.filtersModel.getMinimizedParamRepresentation( updatedUriQuery ), + this.getUnrecognizedParams( updatedUriQuery ) + ); return notEquivalent( currentParamState, updatedParamState ); }; @@ -173,13 +208,7 @@ */ mw.rcfilters.UriProcessor.prototype.doesQueryContainRecognizedParams = function ( uriQuery ) { var anyValidInUrl, - validParameterNames = Object.keys( this._getEmptyParameterState() ) - .filter( function ( param ) { - // Remove 'highlight' parameter from this check; - // if it's the only parameter in the URL we still - // want to consider the URL 'empty' for defaults to load - return param !== 'highlight'; - } ); + validParameterNames = Object.keys( this.filtersModel.getEmptyParameterState() ); uriQuery = uriQuery || new mw.Uri().query; @@ -191,35 +220,11 @@ return anyValidInUrl || this.getVersion( uriQuery ) === 2; }; - /** - * Remove all parameters that have the same value as the base state - * This method expects uri queries of the urlversion=2 format - * - * @private - * @param {Object} uriQuery Current uri query - * @return {Object} Minimized query - */ - mw.rcfilters.UriProcessor.prototype.minimizeQuery = function ( uriQuery ) { - var baseParams = this._getEmptyParameterState(), - uriResult = $.extend( true, {}, uriQuery ); - - $.each( uriResult, function ( paramName, paramValue ) { - if ( - baseParams[ paramName ] !== undefined && - baseParams[ paramName ] === paramValue - ) { - // Remove parameter from query - delete uriResult[ paramName ]; - } - } ); - - return uriResult; - }; - /** * Get the adjusted URI params based on the url version * If the urlversion is not 2, the parameters are merged with * the model's defaults. + * Always merge in the hidden parameter defaults. * * @private * @param {Object} uriQuery Current URI query @@ -234,53 +239,18 @@ // wiki default. // Any subsequent change of the URL through the RCFilters // system will receive 'urlversion=2' - var hiddenParamDefaults = {}, + var hiddenParamDefaults = this.filtersModel.getDefaultHiddenParams(), base = this.getVersion( uriQuery ) === 2 ? {} : this.filtersModel.getDefaultParams(); - // Go over the model and get all hidden parameters' defaults - // These defaults should be applied regardless of the urlversion - // but be overridden by the URL params if they exist - $.each( this.filtersModel.getFilterGroups(), function ( groupName, groupModel ) { - if ( groupModel.isHidden() ) { - $.extend( true, hiddenParamDefaults, groupModel.getDefaultParams() ); - } - } ); - - return this.minimizeQuery( - $.extend( true, {}, hiddenParamDefaults, base, uriQuery, { urlversion: '2' } ) - ); - }; - - /** - * Get the representation of an empty parameter state - * - * @private - * @return {Object} Empty parameter state - */ - mw.rcfilters.UriProcessor.prototype._getEmptyParameterState = function () { - // Override empty parameter state with the sticky parameter values - return $.extend( true, {}, this.emptyParameterState, this.filtersModel.getStickyParams() ); - }; - - /** - * Build an empty representation of the parameters, where all parameters - * are either set to '0' or '' depending on their type. - * This must run during initialization, before highlights are set. - * - * @private - */ - mw.rcfilters.UriProcessor.prototype._buildEmptyParameterState = function () { - var emptyParams = this.filtersModel.getParametersFromFilters( {} ), - emptyHighlights = this.filtersModel.getHighlightParameters(); - - this.emptyParameterState = $.extend( + return $.extend( true, {}, - emptyParams, - emptyHighlights, - { highlight: '0', invert: '0' } + this.filtersModel.getMinimizedParamRepresentation( + $.extend( true, {}, hiddenParamDefaults, base, uriQuery ) + ), + { urlversion: '2' } ); }; }( mediaWiki, jQuery ) );