| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225 |
1×
46761×
46761×
46761×
46761×
46761×
1×
1×
1×
46761×
46761×
46761×
1×
703522×
1×
25×
1×
3731×
3731×
3731×
3731×
239×
239×
239×
239×
3731×
3731×
3731×
3731×
3731×
1×
58311×
58311×
58311×
58311×
58311×
5002×
5002×
5002×
5002×
53309×
1395×
1396×
1396×
1396×
1396×
1396×
1396×
51914×
7817×
7818×
7818×
336×
170×
170×
170×
7482×
2×
2×
2×
58311×
11550×
58311×
58311×
58311×
| /**
* The FlaggedElement class is an attribute mixin, meaning that it is used to add
* additional functionality to an element created by another class. The class provides
* a ‘flags’ property assigned the name (or an array of names) of styling flags,
* which are used to customize the look and feel of a widget to better describe its
* importance and functionality.
*
* The library currently contains the following styling flags for general use:
*
* - **progressive**: Progressive styling is applied to convey that the widget will move the user
* forward in a process.
* - **destructive**: Destructive styling is applied to convey that the widget will remove
* something.
*
* {@link OO.ui.ActionWidget ActionWidgets}, which are a special kind of button that execute an
* action, use these flags: **primary** and **safe**.
* Please see the [OOUI documentation on MediaWiki][1] for more information.
*
* [1]: https://www.mediawiki.org/wiki/OOUI/Elements/Flagged
*
* The flags affect the appearance of the buttons:
*
* @example
* // FlaggedElement is mixed into ButtonWidget to provide styling flags
* const button1 = new OO.ui.ButtonWidget( {
* label: 'Progressive',
* flags: 'progressive'
* } ),
* button2 = new OO.ui.ButtonWidget( {
* label: 'Destructive',
* flags: 'destructive'
* } );
* $( document.body ).append( button1.$element, button2.$element );
*
* @abstract
* @class
*
* @constructor
* @param {Object} [config] Configuration options
* @param {string|string[]} [config.flags] The name or names of the flags (e.g., 'progressive' or 'primary')
* to apply.
* Please see the [OOUI documentation on MediaWiki][2] for more information about available flags.
* [2]: https://www.mediawiki.org/wiki/OOUI/Elements/Flagged
* @param {jQuery} [config.$flagged] The flagged element. By default,
* the flagged functionality is applied to the element created by the class ($element).
* If a different element is specified, the flagged functionality will be applied to it instead.
*/
OO.ui.mixin.FlaggedElement = function OoUiMixinFlaggedElement( config ) {
// Configuration initialization
config = config || {};
// Properties
this.flags = {};
this.$flagged = null;
// Initialization
this.setFlags( config.flags || this.constructor.static.flags );
this.setFlaggedElement( config.$flagged || this.$element );
};
/* Setup */
OO.initClass( OO.ui.mixin.FlaggedElement );
/* Events */
/**
* A flag event is emitted when the #clearFlags or #setFlags methods are used. The `changes`
* parameter contains the name of each modified flag and indicates whether it was
* added or removed.
*
* @event OO.ui.mixin.FlaggedElement#flag
* @param {Object.<string,boolean>} changes Object keyed by flag name. A Boolean `true` indicates
* that the flag was added, `false` that the flag was removed.
*/
/* Static Properties */
/**
* Initial value to pass to setFlags if no value is provided in config.
*
* @static
* @property {string|string[]|Object.<string, boolean>}
*/
OO.ui.mixin.FlaggedElement.static.flags = null;
/* Methods */
/**
* Set the flagged element.
*
* This method is used to retarget a flagged mixin so that its functionality applies to the
* specified element.
* If an element is already set, the method will remove the mixin’s effect on that element.
*
* @param {jQuery} $flagged Element that should be flagged
*/
OO.ui.mixin.FlaggedElement.prototype.setFlaggedElement = function ( $flagged ) {
const classNames = Object.keys( this.flags ).map( ( flag ) => 'oo-ui-flaggedElement-' + flag );
Iif ( this.$flagged ) {
this.$flagged.removeClass( classNames );
}
this.$flagged = $flagged.addClass( classNames );
};
/**
* Check if the specified flag is set.
*
* @param {string} flag Name of flag
* @return {boolean} The flag is set
*/
OO.ui.mixin.FlaggedElement.prototype.hasFlag = function ( flag ) {
// This may be called before the constructor, thus before this.flags is set
return this.flags && ( flag in this.flags );
};
/**
* Get the names of all flags set.
*
* @return {string[]} Flag names
*/
OO.ui.mixin.FlaggedElement.prototype.getFlags = function () {
// This may be called before the constructor, thus before this.flags is set
return Object.keys( this.flags || {} );
};
/**
* Clear all flags.
*
* @chainable
* @return {OO.ui.Element} The element, for chaining
* @fires OO.ui.mixin.FlaggedElement#flag
*/
OO.ui.mixin.FlaggedElement.prototype.clearFlags = function () {
const changes = {},
remove = [],
classPrefix = 'oo-ui-flaggedElement-';
for ( const flag in this.flags ) {
const className = classPrefix + flag;
changes[ flag ] = false;
delete this.flags[ flag ];
remove.push( className );
}
Eif ( this.$flagged ) {
this.$flagged.removeClass( remove );
}
this.updateThemeClasses();
this.emit( 'flag', changes );
return this;
};
/**
* Add one or more flags.
*
* @param {string|string[]|Object.<string, boolean>} flags A flag name, an array of flag names,
* or an object keyed by flag name with a boolean value that indicates whether the flag should
* be added (`true`) or removed (`false`).
* @chainable
* @return {OO.ui.Element} The element, for chaining
* @fires OO.ui.mixin.FlaggedElement#flag
*/
OO.ui.mixin.FlaggedElement.prototype.setFlags = function ( flags ) {
const changes = {},
add = [],
remove = [],
classPrefix = 'oo-ui-flaggedElement-';
let className, flag;
if ( typeof flags === 'string' ) {
className = classPrefix + flags;
// Set
Eif ( !this.flags[ flags ] ) {
this.flags[ flags ] = true;
add.push( className );
}
} else if ( Array.isArray( flags ) ) {
for ( let i = 0, len = flags.length; i < len; i++ ) {
flag = flags[ i ];
className = classPrefix + flag;
// Set
Eif ( !this.flags[ flag ] ) {
changes[ flag ] = true;
this.flags[ flag ] = true;
add.push( className );
}
}
} else if ( OO.isPlainObject( flags ) ) {
for ( flag in flags ) {
className = classPrefix + flag;
if ( flags[ flag ] ) {
// Set
if ( !this.flags[ flag ] ) {
changes[ flag ] = true;
this.flags[ flag ] = true;
add.push( className );
}
} else {
// Remove
if ( this.flags[ flag ] ) {
changes[ flag ] = false;
delete this.flags[ flag ];
remove.push( className );
}
}
}
}
if ( this.$flagged ) {
this.$flagged
.addClass( add )
.removeClass( remove );
}
this.updateThemeClasses();
this.emit( 'flag', changes );
return this;
};
|