88f32b4d9d952d7ff1e11989e745e67aaad599db
[lhc/web/wiklou.git] / resources / src / mediawiki.rcfilters / mw.rcfilters.Controller.js
1 ( function ( mw, $ ) {
2 /**
3 * Controller for the filters in Recent Changes
4 *
5 * @param {mw.rcfilters.dm.FiltersViewModel} filtersModel Filters view model
6 * @param {mw.rcfilters.dm.ChangesListViewModel} changesListModel Changes list view model
7 */
8 mw.rcfilters.Controller = function MwRcfiltersController( filtersModel, changesListModel ) {
9 this.filtersModel = filtersModel;
10 this.changesListModel = changesListModel;
11 this.requestCounter = 0;
12 };
13
14 /* Initialization */
15 OO.initClass( mw.rcfilters.Controller );
16
17 /**
18 * Initialize the filter and parameter states
19 */
20 mw.rcfilters.Controller.prototype.initialize = function () {
21 this.updateFromURL();
22 };
23
24 /**
25 * Update the model state based on the URL parameters.
26 */
27 mw.rcfilters.Controller.prototype.updateFromURL = function () {
28 var uri = new mw.Uri();
29
30 this.filtersModel.updateFilters(
31 // Translate the url params to filter select states
32 this.filtersModel.getFiltersFromParameters( uri.query )
33 );
34 };
35
36 /**
37 * Reset to default filters
38 */
39 mw.rcfilters.Controller.prototype.resetToDefaults = function () {
40 this.filtersModel.setFiltersToDefaults();
41 this.updateURL();
42 this.updateChangesList();
43 };
44
45 /**
46 * Empty all selected filters
47 */
48 mw.rcfilters.Controller.prototype.emptyFilters = function () {
49 this.filtersModel.emptyAllFilters();
50 this.updateURL();
51 this.updateChangesList();
52 };
53
54 /**
55 * Update the state of a filter
56 *
57 * @param {string} filterName Filter name
58 * @param {boolean} isSelected Filter selected state
59 */
60 mw.rcfilters.Controller.prototype.updateFilter = function ( filterName, isSelected ) {
61 var obj = {};
62
63 obj[ filterName ] = isSelected;
64 this.filtersModel.updateFilters( obj );
65 this.updateURL();
66 this.updateChangesList();
67 };
68
69 /**
70 * Update the URL of the page to reflect current filters
71 */
72 mw.rcfilters.Controller.prototype.updateURL = function () {
73 var uri = new mw.Uri();
74
75 // Add to existing queries in URL
76 // TODO: Clean up the list of filters; perhaps 'falsy' filters
77 // shouldn't appear at all? Or compare to existing query string
78 // and see if current state of a specific filter is needed?
79 uri.extend( this.filtersModel.getParametersFromFilters() );
80
81 // Update the URL itself
82 window.history.pushState( { tag: 'rcfilters' }, document.title, uri.toString() );
83 };
84
85 /**
86 * Fetch the list of changes from the server for the current filters
87 *
88 * @returns {jQuery.Promise} Promise object that will resolve with the changes list
89 */
90 mw.rcfilters.Controller.prototype.fetchChangesList = function () {
91 var uri = new mw.Uri(),
92 requestId = ++this.requestCounter,
93 latestRequest = function () {
94 return requestId === this.requestCounter;
95 }.bind( this );
96 uri.extend( this.filtersModel.getParametersFromFilters() );
97 return $.ajax( uri.toString(), { contentType: 'html' } )
98 .then( function ( html ) {
99 return latestRequest() ?
100 $( $.parseHTML( html ) ).find( '.mw-changeslist' ).first().contents() :
101 null;
102 } ).then( null, function () {
103 return latestRequest() ? 'NO_RESULTS' : null;
104 } );
105 };
106
107 /**
108 * Update the list of changes and notify the model
109 */
110 mw.rcfilters.Controller.prototype.updateChangesList = function () {
111 this.changesListModel.invalidate();
112 this.fetchChangesList()
113 .always( function ( changesListContent ) {
114 if ( changesListContent ) {
115 this.changesListModel.update( changesListContent );
116 }
117 }.bind( this ) );
118 };
119 }( mediaWiki, jQuery ) );