3 * Controller for the filters in Recent Changes
5 * @param {mw.rcfilters.dm.FiltersViewModel} filtersModel Filters view model
6 * @param {mw.rcfilters.dm.ChangesListViewModel} changesListModel Changes list view model
8 mw
.rcfilters
.Controller
= function MwRcfiltersController( filtersModel
, changesListModel
) {
9 this.filtersModel
= filtersModel
;
10 this.changesListModel
= changesListModel
;
11 this.requestCounter
= 0;
15 OO
.initClass( mw
.rcfilters
.Controller
);
18 * Initialize the filter and parameter states
20 * @param {Object} filterStructure Filter definition and structure for the model
22 mw
.rcfilters
.Controller
.prototype.initialize = function ( filterStructure
) {
23 var uri
= new mw
.Uri();
25 // Initialize the model
26 this.filtersModel
.initializeFilters( filterStructure
);
28 // Set filter states based on defaults and URL params
29 this.filtersModel
.updateFilters(
30 this.filtersModel
.getFiltersFromParameters(
31 // Merge defaults with URL params for initialization
35 this.filtersModel
.getDefaultParams(),
36 // URI query overrides defaults
42 // Initialize highlights
43 this.filtersModel
.toggleHighlight( !!uri
.query
.highlight
);
44 this.filtersModel
.getItems().forEach( function ( filterItem
) {
45 var color
= uri
.query
[ filterItem
.getName() + '_color' ];
50 filterItem
.setHighlightColor( color
);
53 // Check all filter interactions
54 this.filtersModel
.reassessFilterInteractions();
58 * Reset to default filters
60 mw
.rcfilters
.Controller
.prototype.resetToDefaults = function () {
61 this.filtersModel
.setFiltersToDefaults();
62 this.filtersModel
.clearAllHighlightColors();
63 // Check all filter interactions
64 this.filtersModel
.reassessFilterInteractions();
66 this.updateChangesList();
70 * Empty all selected filters
72 mw
.rcfilters
.Controller
.prototype.emptyFilters = function () {
73 this.filtersModel
.emptyAllFilters();
74 this.filtersModel
.clearAllHighlightColors();
75 // Check all filter interactions
76 this.filtersModel
.reassessFilterInteractions();
78 this.updateChangesList();
82 * Update the selected state of a filter
84 * @param {string} filterName Filter name
85 * @param {boolean} [isSelected] Filter selected state
87 mw
.rcfilters
.Controller
.prototype.toggleFilterSelect = function ( filterName
, isSelected
) {
89 filterItem
= this.filtersModel
.getItemByName( filterName
);
91 isSelected
= isSelected
=== undefined ? !filterItem
.isSelected() : isSelected
;
93 if ( filterItem
.isSelected() !== isSelected
) {
94 obj
[ filterName
] = isSelected
;
95 this.filtersModel
.updateFilters( obj
);
97 this.updateChangesList();
99 // Check filter interactions
100 this.filtersModel
.reassessFilterInteractions( this.filtersModel
.getItemByName( filterName
) );
105 * Update the URL of the page to reflect current filters
107 * This should not be called directly from outside the controller.
108 * If an action requires changing the URL, it should either use the
109 * highlighting actions below, or call #updateChangesList which does
110 * the uri corrections already.
113 * @param {Object} [params] Extra parameters to add to the API call
115 mw
.rcfilters
.Controller
.prototype.updateURL = function ( params
) {
118 params
= params
|| {};
120 uri
= this.getUpdatedUri();
121 uri
.extend( params
);
123 window
.history
.pushState( { tag
: 'rcfilters' }, document
.title
, uri
.toString() );
127 * Get an updated mw.Uri object based on the model state
129 * @return {mw.Uri} Updated Uri
131 mw
.rcfilters
.Controller
.prototype.getUpdatedUri = function () {
132 var uri
= new mw
.Uri(),
133 highlightParams
= this.filtersModel
.getHighlightParameters();
135 // Add to existing queries in URL
136 // TODO: Clean up the list of filters; perhaps 'falsy' filters
137 // shouldn't appear at all? Or compare to existing query string
138 // and see if current state of a specific filter is needed?
139 uri
.extend( this.filtersModel
.getParametersFromFilters() );
142 Object
.keys( highlightParams
).forEach( function ( paramName
) {
143 if ( highlightParams
[ paramName
] ) {
144 uri
.query
[ paramName
] = highlightParams
[ paramName
];
146 delete uri
.query
[ paramName
];
154 * Fetch the list of changes from the server for the current filters
156 * @return {jQuery.Promise} Promise object that will resolve with the changes list
157 * or with a string denoting no results.
159 mw
.rcfilters
.Controller
.prototype.fetchChangesList = function () {
160 var uri
= this.getUpdatedUri(),
161 requestId
= ++this.requestCounter
,
162 latestRequest = function () {
163 return requestId
=== this.requestCounter
;
166 return $.ajax( uri
.toString(), { contentType
: 'html' } )
171 if ( !latestRequest() ) {
172 return $.Deferred().reject();
175 $parsed
= $( $.parseHTML( html
) );
179 changes
: $parsed
.find( '.mw-changeslist' ).first().contents(),
181 fieldset
: $parsed
.find( 'fieldset.rcoptions' ).first()
185 function ( responseObj
) {
188 if ( !latestRequest() ) {
189 return $.Deferred().reject();
192 $parsed
= $( $.parseHTML( responseObj
.responseText
) );
194 // Force a resolve state to this promise
195 return $.Deferred().resolve( {
196 changes
: 'NO_RESULTS',
197 fieldset
: $parsed
.find( 'fieldset.rcoptions' ).first()
204 * Update the list of changes and notify the model
206 * @param {Object} [params] Extra parameters to add to the API call
208 mw
.rcfilters
.Controller
.prototype.updateChangesList = function ( params
) {
209 this.updateURL( params
);
210 this.changesListModel
.invalidate();
211 this.fetchChangesList()
214 function ( pieces
) {
215 var $changesListContent
= pieces
.changes
,
216 $fieldset
= pieces
.fieldset
;
217 this.changesListModel
.update( $changesListContent
, $fieldset
);
219 // Do nothing for failure
224 * Toggle the highlight feature on and off
226 mw
.rcfilters
.Controller
.prototype.toggleHighlight = function () {
227 this.filtersModel
.toggleHighlight();
232 * Set the highlight color for a filter item
234 * @param {string} filterName Name of the filter item
235 * @param {string} color Selected color
237 mw
.rcfilters
.Controller
.prototype.setHighlightColor = function ( filterName
, color
) {
238 this.filtersModel
.setHighlightColor( filterName
, color
);
243 * Clear highlight for a filter item
245 * @param {string} filterName Name of the filter item
247 mw
.rcfilters
.Controller
.prototype.clearHighlightColor = function ( filterName
) {
248 this.filtersModel
.clearHighlightColor( filterName
);
251 }( mediaWiki
, jQuery
) );