RCFilters: Allows specifying default highlights from the server
[lhc/web/wiklou.git] / resources / src / mediawiki.rcfilters / dm / mw.rcfilters.dm.ItemModel.js
1 ( function ( mw ) {
2 /**
3 * RCFilter base item model
4 *
5 * @mixins OO.EventEmitter
6 *
7 * @constructor
8 * @param {string} param Filter param name
9 * @param {Object} config Configuration object
10 * @cfg {string} [label] The label for the filter
11 * @cfg {string} [description] The description of the filter
12 * @cfg {string|Object} [labelPrefixKey] An i18n key defining the prefix label for this
13 * group. If the prefix has 'invert' state, the parameter is expected to be an object
14 * with 'default' and 'inverted' as keys.
15 * @cfg {boolean} [active=true] The filter is active and affecting the result
16 * @cfg {boolean} [selected] The item is selected
17 * @cfg {boolean} [inverted] The item is inverted, meaning the search is excluding
18 * this parameter.
19 * @cfg {string} [namePrefix='item_'] A prefix to add to the param name to act as a unique
20 * identifier
21 * @cfg {string} [cssClass] The class identifying the results that match this filter
22 * @cfg {string[]} [identifiers] An array of identifiers for this item. They will be
23 * added and considered in the view.
24 * @cfg {string} [defaultHighlightColor] If set, highlight this filter by default with this color
25 */
26 mw.rcfilters.dm.ItemModel = function MwRcfiltersDmItemModel( param, config ) {
27 config = config || {};
28
29 // Mixin constructor
30 OO.EventEmitter.call( this );
31
32 this.param = param;
33 this.namePrefix = config.namePrefix || 'item_';
34 this.name = this.namePrefix + param;
35
36 this.label = config.label || this.name;
37 this.labelPrefixKey = config.labelPrefixKey;
38 this.description = config.description || '';
39 this.selected = !!config.selected;
40
41 this.inverted = !!config.inverted;
42 this.identifiers = config.identifiers || [];
43
44 // Highlight
45 this.cssClass = config.cssClass;
46 this.highlightColor = config.defaultHighlightColor;
47 this.highlightEnabled = !!config.defaultHighlightColor;
48 };
49
50 /* Initialization */
51
52 OO.initClass( mw.rcfilters.dm.ItemModel );
53 OO.mixinClass( mw.rcfilters.dm.ItemModel, OO.EventEmitter );
54
55 /* Events */
56
57 /**
58 * @event update
59 *
60 * The state of this filter has changed
61 */
62
63 /* Methods */
64
65 /**
66 * Return the representation of the state of this item.
67 *
68 * @return {Object} State of the object
69 */
70 mw.rcfilters.dm.ItemModel.prototype.getState = function () {
71 return {
72 selected: this.isSelected(),
73 inverted: this.isInverted()
74 };
75 };
76
77 /**
78 * Get the name of this filter
79 *
80 * @return {string} Filter name
81 */
82 mw.rcfilters.dm.ItemModel.prototype.getName = function () {
83 return this.name;
84 };
85
86 /**
87 * Get a prefixed label
88 *
89 * @return {string} Prefixed label
90 */
91 mw.rcfilters.dm.ItemModel.prototype.getPrefixedLabel = function () {
92 if ( this.labelPrefixKey ) {
93 if ( typeof this.labelPrefixKey === 'string' ) {
94 return mw.message( this.labelPrefixKey, this.getLabel() ).parse();
95 } else {
96 return mw.message(
97 this.labelPrefixKey[
98 // Only use inverted-prefix if the item is selected
99 // Highlight-only an inverted item makes no sense
100 this.isInverted() && this.isSelected() ?
101 'inverted' : 'default'
102 ],
103 this.getLabel()
104 ).parse();
105 }
106 } else {
107 return this.getLabel();
108 }
109 };
110
111 /**
112 * Get the param name or value of this filter
113 *
114 * @return {string} Filter param name
115 */
116 mw.rcfilters.dm.ItemModel.prototype.getParamName = function () {
117 return this.param;
118 };
119
120 /**
121 * Get the message representing the state of this model.
122 *
123 * @return {string} State message
124 */
125 mw.rcfilters.dm.ItemModel.prototype.getStateMessage = function () {
126 // Display description
127 return this.getDescription();
128 };
129
130 /**
131 * Get the label of this filter
132 *
133 * @return {string} Filter label
134 */
135 mw.rcfilters.dm.ItemModel.prototype.getLabel = function () {
136 return this.label;
137 };
138
139 /**
140 * Get the description of this filter
141 *
142 * @return {string} Filter description
143 */
144 mw.rcfilters.dm.ItemModel.prototype.getDescription = function () {
145 return this.description;
146 };
147
148 /**
149 * Get the default value of this filter
150 *
151 * @return {boolean} Filter default
152 */
153 mw.rcfilters.dm.ItemModel.prototype.getDefault = function () {
154 return this.default;
155 };
156
157 /**
158 * Get the selected state of this filter
159 *
160 * @return {boolean} Filter is selected
161 */
162 mw.rcfilters.dm.ItemModel.prototype.isSelected = function () {
163 return this.selected;
164 };
165
166 /**
167 * Toggle the selected state of the item
168 *
169 * @param {boolean} [isSelected] Filter is selected
170 * @fires update
171 */
172 mw.rcfilters.dm.ItemModel.prototype.toggleSelected = function ( isSelected ) {
173 isSelected = isSelected === undefined ? !this.selected : isSelected;
174
175 if ( this.selected !== isSelected ) {
176 this.selected = isSelected;
177 this.emit( 'update' );
178 }
179 };
180
181 /**
182 * Get the inverted state of this item
183 *
184 * @return {boolean} Item is inverted
185 */
186 mw.rcfilters.dm.ItemModel.prototype.isInverted = function () {
187 return this.inverted;
188 };
189
190 /**
191 * Toggle the inverted state of the item
192 *
193 * @param {boolean} [isInverted] Item is inverted
194 * @fires update
195 */
196 mw.rcfilters.dm.ItemModel.prototype.toggleInverted = function ( isInverted ) {
197 isInverted = isInverted === undefined ? !this.inverted : isInverted;
198
199 if ( this.inverted !== isInverted ) {
200 this.inverted = isInverted;
201 this.emit( 'update' );
202 }
203 };
204
205 /**
206 * Set the highlight color
207 *
208 * @param {string|null} highlightColor
209 */
210 mw.rcfilters.dm.ItemModel.prototype.setHighlightColor = function ( highlightColor ) {
211 if ( this.highlightColor !== highlightColor ) {
212 this.highlightColor = highlightColor;
213 this.emit( 'update' );
214 }
215 };
216
217 /**
218 * Clear the highlight color
219 */
220 mw.rcfilters.dm.ItemModel.prototype.clearHighlightColor = function () {
221 this.setHighlightColor( null );
222 };
223
224 /**
225 * Get the highlight color, or null if none is configured
226 *
227 * @return {string|null}
228 */
229 mw.rcfilters.dm.ItemModel.prototype.getHighlightColor = function () {
230 return this.highlightColor;
231 };
232
233 /**
234 * Get the CSS class that matches changes that fit this filter
235 * or null if none is configured
236 *
237 * @return {string|null}
238 */
239 mw.rcfilters.dm.ItemModel.prototype.getCssClass = function () {
240 return this.cssClass;
241 };
242
243 /**
244 * Get the item's identifiers
245 *
246 * @return {string[]}
247 */
248 mw.rcfilters.dm.ItemModel.prototype.getIdentifiers = function () {
249 return this.identifiers;
250 };
251
252 /**
253 * Toggle the highlight feature on and off for this filter.
254 * It only works if highlight is supported for this filter.
255 *
256 * @param {boolean} enable Highlight should be enabled
257 */
258 mw.rcfilters.dm.ItemModel.prototype.toggleHighlight = function ( enable ) {
259 enable = enable === undefined ? !this.highlightEnabled : enable;
260
261 if ( !this.isHighlightSupported() ) {
262 return;
263 }
264
265 if ( enable === this.highlightEnabled ) {
266 return;
267 }
268
269 this.highlightEnabled = enable;
270 this.emit( 'update' );
271 };
272
273 /**
274 * Check if the highlight feature is currently enabled for this filter
275 *
276 * @return {boolean}
277 */
278 mw.rcfilters.dm.ItemModel.prototype.isHighlightEnabled = function () {
279 return !!this.highlightEnabled;
280 };
281
282 /**
283 * Check if the highlight feature is supported for this filter
284 *
285 * @return {boolean}
286 */
287 mw.rcfilters.dm.ItemModel.prototype.isHighlightSupported = function () {
288 return !!this.getCssClass();
289 };
290
291 /**
292 * Check if the filter is currently highlighted
293 *
294 * @return {boolean}
295 */
296 mw.rcfilters.dm.ItemModel.prototype.isHighlighted = function () {
297 return this.isHighlightEnabled() && !!this.getHighlightColor();
298 };
299 }( mediaWiki ) );