Merge "Use HTML::hidden to create input fields"
[lhc/web/wiklou.git] / resources / src / mediawiki.rcfilters / dm / mw.rcfilters.dm.SavedQueriesModel.js
1 ( function ( mw, $ ) {
2 /**
3 * View model for saved queries
4 *
5 * @class
6 * @mixins OO.EventEmitter
7 * @mixins OO.EmitterList
8 *
9 * @constructor
10 * @param {Object} [config] Configuration options
11 * @cfg {string} [default] Default query ID
12 */
13 mw.rcfilters.dm.SavedQueriesModel = function MwRcfiltersDmSavedQueriesModel( config ) {
14 config = config || {};
15
16 // Mixin constructor
17 OO.EventEmitter.call( this );
18 OO.EmitterList.call( this );
19
20 this.default = config.default;
21
22 // Events
23 this.aggregate( { update: 'itemUpdate' } );
24 };
25
26 /* Initialization */
27
28 OO.initClass( mw.rcfilters.dm.SavedQueriesModel );
29 OO.mixinClass( mw.rcfilters.dm.SavedQueriesModel, OO.EventEmitter );
30 OO.mixinClass( mw.rcfilters.dm.SavedQueriesModel, OO.EmitterList );
31
32 /* Events */
33
34 /**
35 * @event initialize
36 *
37 * Model is initialized
38 */
39
40 /**
41 * @event itemUpdate
42 * @param {mw.rcfilters.dm.SavedQueryItemModel} Changed item
43 *
44 * An item has changed
45 */
46
47 /* Methods */
48
49 /**
50 * Initialize the saved queries model by reading it from the user's settings.
51 * The structure of the saved queries is:
52 * {
53 * default: (string) Query ID
54 * queries:{
55 * query_id_1: {
56 * data:{
57 * filters: (Object) Minimal definition of the filters
58 * highlights: (Object) Definition of the highlights
59 * },
60 * label: (optional) Name of this query
61 * }
62 * }
63 * }
64 *
65 * @param {Object} [savedQueries] An object with the saved queries with
66 * the above structure.
67 * @param {Object} [baseState] An object representing the base state
68 * so we can normalize the data
69 * @param {string[]} [ignoreFilters] Filters to ignore and remove from
70 * the data
71 * @fires initialize
72 */
73 mw.rcfilters.dm.SavedQueriesModel.prototype.initialize = function ( savedQueries, baseState, ignoreFilters ) {
74 var items = [],
75 defaultItem = null;
76
77 savedQueries = savedQueries || {};
78 ignoreFilters = ignoreFilters || {};
79
80 this.baseState = baseState;
81
82 this.clearItems();
83 $.each( savedQueries.queries || {}, function ( id, obj ) {
84 var item,
85 normalizedData = $.extend( true, {}, baseState, obj.data ),
86 isDefault = String( savedQueries.default ) === String( id );
87
88 // Backwards-compat fix: We stored the 'highlight' state with
89 // "1" and "0" instead of true/false; for already-stored states,
90 // we need to fix that.
91 // NOTE: Since this feature is only available in beta, we should
92 // not need this line when we release this to the general wikis.
93 // This method will automatically fix all saved queries anyways
94 // for existing users, who are only betalabs users at the moment.
95 normalizedData.highlights.highlight = !!Number( normalizedData.highlights.highlight );
96
97 // Backwards-compat fix: Remove sticky parameters from the 'ignoreFilters' list
98 ignoreFilters.forEach( function ( name ) {
99 delete normalizedData.filters[ name ];
100 } );
101
102 item = new mw.rcfilters.dm.SavedQueryItemModel(
103 id,
104 obj.label,
105 normalizedData,
106 { 'default': isDefault }
107 );
108
109 if ( isDefault ) {
110 defaultItem = item;
111 }
112
113 items.push( item );
114 } );
115
116 if ( defaultItem ) {
117 this.default = defaultItem.getID();
118 }
119
120 this.addItems( items );
121
122 this.emit( 'initialize' );
123 };
124
125 /**
126 * Add a query item
127 *
128 * @param {string} label Label for the new query
129 * @param {Object} data Data for the new query
130 * @return {string} ID of the newly added query
131 */
132 mw.rcfilters.dm.SavedQueriesModel.prototype.addNewQuery = function ( label, data ) {
133 var randomID = ( new Date() ).getTime(),
134 normalizedData = $.extend( true, {}, this.baseState, data );
135
136 // Add item
137 this.addItems( [
138 new mw.rcfilters.dm.SavedQueryItemModel(
139 randomID,
140 label,
141 normalizedData
142 )
143 ] );
144
145 return randomID;
146 };
147
148 /**
149 * Remove query from model
150 *
151 * @param {string} queryID Query ID
152 */
153 mw.rcfilters.dm.SavedQueriesModel.prototype.removeQuery = function ( queryID ) {
154 var query = this.getItemByID( queryID );
155
156 if ( query ) {
157 // Check if this item was the default
158 if ( String( this.getDefault() ) === String( queryID ) ) {
159 // Nulify the default
160 this.setDefault( null );
161 }
162
163 this.removeItems( [ query ] );
164 }
165 };
166
167 /**
168 * Get an item that matches the requested query
169 *
170 * @param {Object} fullQueryComparison Object representing all filters and highlights to compare
171 * @return {mw.rcfilters.dm.SavedQueryItemModel} Matching item model
172 */
173 mw.rcfilters.dm.SavedQueriesModel.prototype.findMatchingQuery = function ( fullQueryComparison ) {
174 return this.getItems().filter( function ( item ) {
175 return OO.compare(
176 item.getData(),
177 fullQueryComparison
178 );
179 } )[ 0 ];
180 };
181
182 /**
183 * Get query by its identifier
184 *
185 * @param {string} queryID Query identifier
186 * @return {mw.rcfilters.dm.SavedQueryItemModel|undefined} Item matching
187 * the search. Undefined if not found.
188 */
189 mw.rcfilters.dm.SavedQueriesModel.prototype.getItemByID = function ( queryID ) {
190 return this.getItems().filter( function ( item ) {
191 return item.getID() === queryID;
192 } )[ 0 ];
193 };
194
195 /**
196 * Get the object representing the state of the entire model and items
197 *
198 * @return {Object} Object representing the state of the model and items
199 */
200 mw.rcfilters.dm.SavedQueriesModel.prototype.getState = function () {
201 var obj = { queries: {} };
202
203 // Translate the items to the saved object
204 this.getItems().forEach( function ( item ) {
205 var itemState = item.getState();
206
207 obj.queries[ item.getID() ] = itemState;
208 } );
209
210 if ( this.getDefault() ) {
211 obj.default = this.getDefault();
212 }
213
214 return obj;
215 };
216
217 /**
218 * Set a default query. Null to unset default.
219 *
220 * @param {string} itemID Query identifier
221 * @fires default
222 */
223 mw.rcfilters.dm.SavedQueriesModel.prototype.setDefault = function ( itemID ) {
224 if ( this.default !== itemID ) {
225 this.default = itemID;
226
227 // Set for individual itens
228 this.getItems().forEach( function ( item ) {
229 item.toggleDefault( item.getID() === itemID );
230 } );
231 }
232 };
233
234 /**
235 * Get the default query ID
236 *
237 * @return {string} Default query identifier
238 */
239 mw.rcfilters.dm.SavedQueriesModel.prototype.getDefault = function () {
240 return this.default;
241 };
242 }( mediaWiki, jQuery ) );