// Check all filter interactions
this.filtersModel.reassessFilterInteractions();
- this.updateURL();
this.updateChangesList();
};
// Check all filter interactions
this.filtersModel.reassessFilterInteractions();
- this.updateURL();
this.updateChangesList();
};
/**
- * Update the state of a filter
+ * Update the selected state of a filter
*
* @param {string} filterName Filter name
- * @param {boolean} isSelected Filter selected state
+ * @param {boolean} [isSelected] Filter selected state
*/
- mw.rcfilters.Controller.prototype.updateFilter = function ( filterName, isSelected ) {
+ mw.rcfilters.Controller.prototype.toggleFilterSelect = function ( filterName, isSelected ) {
var obj = {},
filterItem = this.filtersModel.getItemByName( filterName );
+ isSelected = isSelected === undefined ? !filterItem.isSelected() : isSelected;
+
if ( filterItem.isSelected() !== isSelected ) {
obj[ filterName ] = isSelected;
this.filtersModel.updateFilters( obj );
- this.updateURL();
this.updateChangesList();
// Check filter interactions
/**
* 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.
+ *
+ * @private
+ * @param {Object} [params] Extra parameters to add to the API call
*/
- mw.rcfilters.Controller.prototype.updateURL = function () {
- var uri = this.getUpdatedUri();
+ mw.rcfilters.Controller.prototype.updateURL = function ( params ) {
+ var uri;
+
+ params = params || {};
+
+ uri = this.getUpdatedUri();
+ uri.extend( params );
+
window.history.pushState( { tag: 'rcfilters' }, document.title, uri.toString() );
};
* Fetch the list of changes from the server for the current filters
*
* @return {jQuery.Promise} Promise object that will resolve with the changes list
+ * or with a string denoting no results.
*/
mw.rcfilters.Controller.prototype.fetchChangesList = function () {
var uri = this.getUpdatedUri(),
latestRequest = function () {
return requestId === this.requestCounter;
}.bind( this );
- uri.extend( this.filtersModel.getParametersFromFilters() );
+
return $.ajax( uri.toString(), { contentType: 'html' } )
- .then( function ( html ) {
- return latestRequest() ?
- $( $.parseHTML( html ) ).find( '.mw-changeslist' ).first().contents() :
- null;
- } ).then( null, function () {
- return latestRequest() ? 'NO_RESULTS' : null;
- } );
+ .then(
+ // Success
+ function ( html ) {
+ var $parsed;
+ if ( !latestRequest() ) {
+ return $.Deferred().reject();
+ }
+
+ $parsed = $( $.parseHTML( html ) );
+
+ return {
+ // Changes list
+ changes: $parsed.find( '.mw-changeslist' ).first().contents(),
+ // Fieldset
+ fieldset: $parsed.find( 'fieldset.rcoptions' ).first()
+ };
+ },
+ // Failure
+ function ( responseObj ) {
+ var $parsed;
+
+ if ( !latestRequest() ) {
+ return $.Deferred().reject();
+ }
+
+ $parsed = $( $.parseHTML( responseObj.responseText ) );
+
+ // Force a resolve state to this promise
+ return $.Deferred().resolve( {
+ changes: 'NO_RESULTS',
+ fieldset: $parsed.find( 'fieldset.rcoptions' ).first()
+ } ).promise();
+ }
+ );
};
/**
* Update the list of changes and notify the model
+ *
+ * @param {Object} [params] Extra parameters to add to the API call
*/
- mw.rcfilters.Controller.prototype.updateChangesList = function () {
+ mw.rcfilters.Controller.prototype.updateChangesList = function ( params ) {
+ this.updateURL( params );
this.changesListModel.invalidate();
this.fetchChangesList()
- .always( function ( changesListContent ) {
- if ( changesListContent ) {
- this.changesListModel.update( changesListContent );
- }
- }.bind( this ) );
+ .then(
+ // Success
+ function ( pieces ) {
+ var $changesListContent = pieces.changes,
+ $fieldset = pieces.fieldset;
+
+ this.changesListModel.update( $changesListContent, $fieldset );
+ }.bind( this )
+ // Do nothing for failure
+ );
};
/**
icon: 'feedback',
flags: [ 'progressive' ],
label: mw.msg( 'rcfilters-filterlist-feedbacklink' ),
- href: 'https://www.mediawiki.org/wiki/Help_talk:Edit_Review_Improvements/RC_filters'
+ href: 'https://www.mediawiki.org/wiki/Help_talk:New_filters_for_edit_review'
} ).$element
);
itemUpdate: 'onModelItemUpdate'
} );
this.textInput.connect( this, {
- change: 'onTextInputChange'
+ change: 'onTextInputChange',
+ enter: 'onTextInputEnter'
} );
this.capsule.connect( this, { capsuleItemClick: 'onCapsuleItemClick' } );
this.capsule.popup.connect( this, { toggle: 'onCapsulePopupToggle' } );
// Initialize
this.$element
.addClass( 'mw-rcfilters-ui-filterWrapperWidget' )
+ .addClass( 'mw-rcfilters-ui-ready' )
.append( this.capsule.$element, this.textInput.$element );
};
*/
mw.rcfilters.ui.FilterWrapperWidget.prototype.onCapsulePopupToggle = function ( isVisible ) {
if ( !isVisible ) {
- this.filterPopup.resetSelection();
- this.capsule.resetSelection();
+ if ( !this.textInput.getValue() ) {
+ // Only reset selection if we are not filtering
+ this.filterPopup.resetSelection();
+ this.capsule.resetSelection();
+ }
} else {
this.scrollToTop( this.capsule.$element, 10 );
}
* @param {string} newValue Current value
*/
mw.rcfilters.ui.FilterWrapperWidget.prototype.onTextInputChange = function ( newValue ) {
- this.filterPopup.resetSelection();
-
// Filter the results
this.filterPopup.filter( this.model.findMatches( newValue ) );
+
+ if ( !newValue ) {
+ // If the value is empty, we didn't actually
+ // filter anything. the filter method will run
+ // and show all, but then will select the
+ // top item - but in this case, no selection
+ // should be made.
+ this.filterPopup.resetSelection();
+ }
this.capsule.popup.clip();
};
+ /**
+ * Respond to text input enter event
+ */
+ mw.rcfilters.ui.FilterWrapperWidget.prototype.onTextInputEnter = function () {
+ var filter = this.filterPopup.getSelectedFilter();
+
+ // Toggle the filter
+ this.controller.toggleFilterSelect( filter );
+ };
+
/**
* Respond to model update event and set up the available filters to choose
* from.
* any actual interaction with the system resets the selection state of any item.
*/
mw.rcfilters.ui.FilterWrapperWidget.prototype.onModelItemUpdate = function () {
- this.filterPopup.resetSelection();
+ if ( !this.textInput.getValue() ) {
+ this.filterPopup.resetSelection();
+ }
};
/**