Merge "includes/api: Replace implicitly-Bugzilla bug numbers with Phab ones"
[lhc/web/wiklou.git] / resources / src / mediawiki.rcfilters / dm / mw.rcfilters.dm.FilterItem.js
1 ( function ( mw ) {
2 /**
3 * Filter item model
4 *
5 * @mixins OO.EventEmitter
6 *
7 * @constructor
8 * @param {string} name Filter name
9 * @param {mw.rcfilters.dm.FilterGroup} groupModel Filter group model
10 * @param {Object} config Configuration object
11 * @cfg {string} [group] The group this item belongs to
12 * @cfg {string} [label] The label for the filter
13 * @cfg {string} [description] The description of the filter
14 * @cfg {boolean} [active=true] The filter is active and affecting the result
15 * @cfg {string[]} [excludes=[]] A list of filter names this filter, if
16 * selected, makes inactive.
17 * @cfg {boolean} [selected] The item is selected
18 * @cfg {string[]} [subset] Defining the names of filters that are a subset of this filter
19 * @cfg {string[]} [conflictsWith] Defining the names of filters that conflict with this item
20 * @cfg {string} [cssClass] The class identifying the results that match this filter
21 */
22 mw.rcfilters.dm.FilterItem = function MwRcfiltersDmFilterItem( name, groupModel, config ) {
23 config = config || {};
24
25 // Mixin constructor
26 OO.EventEmitter.call( this );
27
28 this.name = name;
29 this.groupModel = groupModel;
30
31 this.label = config.label || this.name;
32 this.description = config.description;
33 this.selected = !!config.selected;
34
35 // Interaction definitions
36 this.subset = config.subset || [];
37 this.conflicts = config.conflicts || [];
38 this.superset = [];
39
40 // Interaction states
41 this.included = false;
42 this.conflicted = false;
43 this.fullyCovered = false;
44
45 // Highlight
46 this.cssClass = config.cssClass;
47 this.highlightColor = null;
48 this.highlightEnabled = false;
49 };
50
51 /* Initialization */
52
53 OO.initClass( mw.rcfilters.dm.FilterItem );
54 OO.mixinClass( mw.rcfilters.dm.FilterItem, OO.EventEmitter );
55
56 /* Events */
57
58 /**
59 * @event update
60 *
61 * The state of this filter has changed
62 */
63
64 /* Methods */
65
66 /**
67 * Get the name of this filter
68 *
69 * @return {string} Filter name
70 */
71 mw.rcfilters.dm.FilterItem.prototype.getName = function () {
72 return this.name;
73 };
74
75 /**
76 * Get the model of the group this filter belongs to
77 *
78 * @return {mw.rcfilters.dm.FilterGroup} Filter group model
79 */
80 mw.rcfilters.dm.FilterItem.prototype.getGroupModel = function () {
81 return this.groupModel;
82 };
83
84 /**
85 * Get the group name this filter belongs to
86 *
87 * @return {string} Filter group name
88 */
89 mw.rcfilters.dm.FilterItem.prototype.getGroupName = function () {
90 return this.groupModel.getName();
91 };
92
93 /**
94 * Get the label of this filter
95 *
96 * @return {string} Filter label
97 */
98 mw.rcfilters.dm.FilterItem.prototype.getLabel = function () {
99 return this.label;
100 };
101
102 /**
103 * Get the description of this filter
104 *
105 * @return {string} Filter description
106 */
107 mw.rcfilters.dm.FilterItem.prototype.getDescription = function () {
108 return this.description;
109 };
110
111 /**
112 * Get the default value of this filter
113 *
114 * @return {boolean} Filter default
115 */
116 mw.rcfilters.dm.FilterItem.prototype.getDefault = function () {
117 return this.default;
118 };
119
120 /**
121 * Get filter subset
122 * This is a list of filter names that are defined to be included
123 * when this filter is selected.
124 *
125 * @return {string[]} Filter subset
126 */
127 mw.rcfilters.dm.FilterItem.prototype.getSubset = function () {
128 return this.subset;
129 };
130
131 /**
132 * Get filter superset
133 * This is a generated list of filters that define this filter
134 * to be included when either of them is selected.
135 *
136 * @return {string[]} Filter superset
137 */
138 mw.rcfilters.dm.FilterItem.prototype.getSuperset = function () {
139 return this.superset;
140 };
141
142 /**
143 * Get the selected state of this filter
144 *
145 * @return {boolean} Filter is selected
146 */
147 mw.rcfilters.dm.FilterItem.prototype.isSelected = function () {
148 return this.selected;
149 };
150
151 /**
152 * Check whether the filter is currently in a conflict state
153 *
154 * @return {boolean} Filter is in conflict state
155 */
156 mw.rcfilters.dm.FilterItem.prototype.isConflicted = function () {
157 return this.conflicted;
158 };
159
160 /**
161 * Check whether the filter is currently in an already included subset
162 *
163 * @return {boolean} Filter is in an already-included subset
164 */
165 mw.rcfilters.dm.FilterItem.prototype.isIncluded = function () {
166 return this.included;
167 };
168
169 /**
170 * Check whether the filter is currently fully covered
171 *
172 * @return {boolean} Filter is in fully-covered state
173 */
174 mw.rcfilters.dm.FilterItem.prototype.isFullyCovered = function () {
175 return this.fullyCovered;
176 };
177
178 /**
179 * Get filter conflicts
180 *
181 * @return {string[]} Filter conflicts
182 */
183 mw.rcfilters.dm.FilterItem.prototype.getConflicts = function () {
184 return this.conflicts;
185 };
186
187 /**
188 * Set filter conflicts
189 *
190 * @param {string[]} conflicts Filter conflicts
191 */
192 mw.rcfilters.dm.FilterItem.prototype.setConflicts = function ( conflicts ) {
193 this.conflicts = conflicts || [];
194 };
195
196 /**
197 * Set filter superset
198 *
199 * @param {string[]} superset Filter superset
200 */
201 mw.rcfilters.dm.FilterItem.prototype.setSuperset = function ( superset ) {
202 this.superset = superset || [];
203 };
204
205 /**
206 * Check whether a filter exists in the subset list for this filter
207 *
208 * @param {string} filterName Filter name
209 * @return {boolean} Filter name is in the subset list
210 */
211 mw.rcfilters.dm.FilterItem.prototype.existsInSubset = function ( filterName ) {
212 return this.subset.indexOf( filterName ) > -1;
213 };
214
215 /**
216 * Check whether this item has a potential conflict with the given item
217 *
218 * This checks whether the given item is in the list of conflicts of
219 * the current item, but makes no judgment about whether the conflict
220 * is currently at play (either one of the items may not be selected)
221 *
222 * @param {mw.rcfilters.dm.FilterItem} filterItem Filter item
223 * @return {boolean} This item has a conflict with the given item
224 */
225 mw.rcfilters.dm.FilterItem.prototype.existsInConflicts = function ( filterItem ) {
226 return this.conflicts.indexOf( filterItem.getName() ) > -1;
227 };
228
229 /**
230 * Set the state of this filter as being conflicted
231 * (This means any filters in its conflicts are selected)
232 *
233 * @param {boolean} [conflicted] Filter is in conflict state
234 * @fires update
235 */
236 mw.rcfilters.dm.FilterItem.prototype.toggleConflicted = function ( conflicted ) {
237 conflicted = conflicted === undefined ? !this.conflicted : conflicted;
238
239 if ( this.conflicted !== conflicted ) {
240 this.conflicted = conflicted;
241 this.emit( 'update' );
242 }
243 };
244
245 /**
246 * Set the state of this filter as being already included
247 * (This means any filters in its superset are selected)
248 *
249 * @param {boolean} [included] Filter is included as part of a subset
250 * @fires update
251 */
252 mw.rcfilters.dm.FilterItem.prototype.toggleIncluded = function ( included ) {
253 included = included === undefined ? !this.included : included;
254
255 if ( this.included !== included ) {
256 this.included = included;
257 this.emit( 'update' );
258 }
259 };
260
261 /**
262 * Toggle the selected state of the item
263 *
264 * @param {boolean} [isSelected] Filter is selected
265 * @fires update
266 */
267 mw.rcfilters.dm.FilterItem.prototype.toggleSelected = function ( isSelected ) {
268 isSelected = isSelected === undefined ? !this.selected : isSelected;
269
270 if ( this.selected !== isSelected ) {
271 this.selected = isSelected;
272 this.emit( 'update' );
273 }
274 };
275
276 /**
277 * Toggle the fully covered state of the item
278 *
279 * @param {boolean} [isFullyCovered] Filter is fully covered
280 * @fires update
281 */
282 mw.rcfilters.dm.FilterItem.prototype.toggleFullyCovered = function ( isFullyCovered ) {
283 isFullyCovered = isFullyCovered === undefined ? !this.fullycovered : isFullyCovered;
284
285 if ( this.fullyCovered !== isFullyCovered ) {
286 this.fullyCovered = isFullyCovered;
287 this.emit( 'update' );
288 }
289 };
290
291 /**
292 * Set the highlight color
293 *
294 * @param {string|null} highlightColor
295 */
296 mw.rcfilters.dm.FilterItem.prototype.setHighlightColor = function ( highlightColor ) {
297 if ( this.highlightColor !== highlightColor ) {
298 this.highlightColor = highlightColor;
299 this.emit( 'update' );
300 }
301 };
302
303 /**
304 * Clear the highlight color
305 */
306 mw.rcfilters.dm.FilterItem.prototype.clearHighlightColor = function () {
307 this.setHighlightColor( null );
308 };
309
310 /**
311 * Get the highlight color, or null if none is configured
312 *
313 * @return {string|null}
314 */
315 mw.rcfilters.dm.FilterItem.prototype.getHighlightColor = function () {
316 return this.highlightColor;
317 };
318
319 /**
320 * Get the CSS class that matches changes that fit this filter
321 * or null if none is configured
322 *
323 * @return {string|null}
324 */
325 mw.rcfilters.dm.FilterItem.prototype.getCssClass = function () {
326 return this.cssClass;
327 };
328
329 /**
330 * Toggle the highlight feature on and off for this filter.
331 * It only works if highlight is supported for this filter.
332 *
333 * @param {boolean} enable Highlight should be enabled
334 */
335 mw.rcfilters.dm.FilterItem.prototype.toggleHighlight = function ( enable ) {
336 enable = enable === undefined ? !this.highlightEnabled : enable;
337
338 if ( !this.isHighlightSupported() ) {
339 return;
340 }
341
342 if ( enable === this.highlightEnabled ) {
343 return;
344 }
345
346 this.highlightEnabled = enable;
347 this.emit( 'update' );
348 };
349
350 /**
351 * Check if the highlight feature is currently enabled for this filter
352 *
353 * @return {boolean}
354 */
355 mw.rcfilters.dm.FilterItem.prototype.isHighlightEnabled = function () {
356 return !!this.highlightEnabled;
357 };
358
359 /**
360 * Check if the highlight feature is supported for this filter
361 *
362 * @return {boolean}
363 */
364 mw.rcfilters.dm.FilterItem.prototype.isHighlightSupported = function () {
365 return !!this.getCssClass();
366 };
367 }( mediaWiki ) );