2 window
.ProtectionForm
= {
3 'existingMatch': false,
6 * Set up the protection chaining interface (i.e. "unlock move permissions" checkbox)
7 * on the protection form
9 * @param opts Object : parameters with members:
10 * tableId Identifier of the table containing UI bits
11 * labelText Text to use for the checkbox label
12 * numTypes The number of protection types
13 * existingMatch True if all the existing expiry times match
15 'init': function( opts
) {
16 if( !( document
.createTextNode
&& document
.getElementById
&& document
.getElementsByTagName
) )
19 var box
= document
.getElementById( opts
.tableId
);
23 var boxbody
= box
.getElementsByTagName('tbody')[0]
24 var row
= document
.createElement( 'tr' );
25 boxbody
.insertBefore( row
, boxbody
.firstChild
.nextSibling
);
27 this.existingMatch
= opts
.existingMatch
;
29 var cell
= document
.createElement( 'td' );
30 row
.appendChild( cell
);
31 // If there is only one protection type, there is nothing to chain
32 if( opts
.numTypes
> 1 ) {
33 var check
= document
.createElement( 'input' );
34 check
.id
= 'mwProtectUnchained';
35 check
.type
= 'checkbox';
36 cell
.appendChild( check
);
37 addClickHandler( check
, function() { ProtectionForm
.onChainClick(); } );
39 cell
.appendChild( document
.createTextNode( ' ' ) );
40 var label
= document
.createElement( 'label' );
41 label
.htmlFor
= 'mwProtectUnchained';
42 label
.appendChild( document
.createTextNode( opts
.labelText
) );
43 cell
.appendChild( label
);
45 check
.checked
= !this.areAllTypesMatching();
46 this.enableUnchainedInputs( check
.checked
);
49 this.updateCascadeCheckbox();
55 * Sets the disabled attribute on the cascade checkbox depending on the current selected levels
57 'updateCascadeCheckbox': function() {
58 // For non-existent titles, there is no cascade option
59 if( !document
.getElementById( 'mwProtect-cascade' ) ) {
62 var lists
= this.getLevelSelectors();
63 for( var i
= 0; i
< lists
.length
; i
++ ) {
64 if( lists
[i
].selectedIndex
> -1 ) {
65 var items
= lists
[i
].getElementsByTagName( 'option' );
66 var selected
= items
[ lists
[i
].selectedIndex
].value
;
67 if( !this.isCascadeableLevel(selected
) ) {
68 document
.getElementById( 'mwProtect-cascade' ).checked
= false;
69 document
.getElementById( 'mwProtect-cascade' ).disabled
= true;
74 document
.getElementById( 'mwProtect-cascade' ).disabled
= false;
78 * Is this protection level cascadeable?
84 'isCascadeableLevel': function( level
) {
85 for (var k
= 0; k
< wgCascadeableLevels
.length
; k
++) {
86 if ( wgCascadeableLevels
[k
] == level
) {
94 * When protection levels are locked together, update the rest
95 * when one action's level changes
97 * @param source Element Level selector that changed
99 'updateLevels': function(source
) {
100 if( !this.isUnchained() )
101 this.setAllSelectors( source
.selectedIndex
);
102 this.updateCascadeCheckbox();
106 * When protection levels are locked together, update the
107 * expiries when one changes
109 * @param source Element expiry input that changed
112 'updateExpiry': function(source
) {
113 if( !this.isUnchained() ) {
114 var expiry
= source
.value
;
115 this.forEachExpiryInput(function(element
) {
116 element
.value
= expiry
;
119 var listId
= source
.id
.replace( /^mwProtect-(\w+)-expires$/, 'mwProtectExpirySelection-$1' );
120 var list
= document
.getElementById( listId
);
121 if (list
&& list
.value
!= 'othertime' ) {
122 if ( this.isUnchained() ) {
123 list
.value
= 'othertime';
125 this.forEachExpirySelector(function(element
) {
126 element
.value
= 'othertime';
133 * When protection levels are locked together, update the
134 * expiry lists when one changes and clear the custom inputs
136 * @param source Element expiry selector that changed
138 'updateExpiryList': function(source
) {
139 if( !this.isUnchained() ) {
140 var expiry
= source
.value
;
141 this.forEachExpirySelector(function(element
) {
142 element
.value
= expiry
;
144 this.forEachExpiryInput(function(element
) {
151 * Update chain status and enable/disable various bits of the UI
152 * when the user changes the "unlock move permissions" checkbox
154 'onChainClick': function() {
155 if( this.isUnchained() ) {
156 this.enableUnchainedInputs( true );
158 this.setAllSelectors( this.getMaxLevel() );
159 this.enableUnchainedInputs( false );
161 this.updateCascadeCheckbox();
165 * Returns true if the named attribute in all objects in the given array are matching
167 'matchAttribute' : function( objects
, attrName
) {
171 for ( var i
= 0; i
< objects
.length
; i
++ ) {
172 var element
= objects
[i
];
173 if ( value
== null ) {
174 value
= element
[attrName
];
176 if ( value
!= element
[attrName
] ) {
185 * Are all actions protected at the same level, with the same expiry time?
189 'areAllTypesMatching': function() {
190 return this.existingMatch
191 && this.matchAttribute( this.getLevelSelectors(), 'selectedIndex' )
192 && this.matchAttribute( this.getExpirySelectors(), 'selectedIndex' )
193 && this.matchAttribute( this.getExpiryInputs(), 'value' );
197 * Is protection chaining off?
201 'isUnchained': function() {
202 var element
= document
.getElementById( 'mwProtectUnchained' );
205 : true; // No control, so we need to let the user set both levels
209 * Find the highest protection level in any selector
211 'getMaxLevel': function() {
213 this.forEachLevelSelector(function(element
) {
214 if (element
.selectedIndex
> maxIndex
) {
215 maxIndex
= element
.selectedIndex
;
222 * Protect all actions at the specified level
224 * @param index int Protection level
226 'setAllSelectors': function(index
) {
227 this.forEachLevelSelector(function(element
) {
228 if (element
.selectedIndex
!= index
) {
229 element
.selectedIndex
= index
;
235 * Apply a callback to each protection selector
237 * @param func callable Callback function
239 'forEachLevelSelector': function(func
) {
240 var selectors
= this.getLevelSelectors();
241 for (var i
= 0; i
< selectors
.length
; i
++) {
247 * Get a list of all protection selectors on the page
251 'getLevelSelectors': function() {
252 var all
= document
.getElementsByTagName("select");
253 var ours
= new Array();
254 for (var i
= 0; i
< all
.length
; i
++) {
255 var element
= all
[i
];
256 if (element
.id
.match(/^mwProtect-level-/)) {
257 ours
[ours
.length
] = element
;
264 * Apply a callback to each expiry input
266 * @param callable func Callback function
268 'forEachExpiryInput': function(func
) {
269 var inputs
= this.getExpiryInputs();
270 for (var i
= 0; i
< inputs
.length
; i
++) {
276 * Get a list of all expiry inputs on the page
280 'getExpiryInputs': function() {
281 var all
= document
.getElementsByTagName("input");
282 var ours
= new Array();
283 for (var i
= 0; i
< all
.length
; i
++) {
284 var element
= all
[i
];
285 if (element
.name
.match(/^mwProtect-expiry-/)) {
286 ours
[ours
.length
] = element
;
293 * Apply a callback to each expiry selector list
294 * @param callable func Callback function
296 'forEachExpirySelector': function(func
) {
297 var inputs
= this.getExpirySelectors();
298 for (var i
= 0; i
< inputs
.length
; i
++) {
304 * Get a list of all expiry selector lists on the page
308 'getExpirySelectors': function() {
309 var all
= document
.getElementsByTagName("select");
310 var ours
= new Array();
311 for (var i
= 0; i
< all
.length
; i
++) {
312 var element
= all
[i
];
313 if (element
.id
.match(/^mwProtectExpirySelection-/)) {
314 ours
[ours
.length
] = element
;
321 * Enable/disable protection selectors and expiry inputs
323 * @param boolean val Enable?
325 'enableUnchainedInputs': function(val
) {
327 this.forEachLevelSelector(function(element
) {
331 element
.disabled
= !val
;
335 this.forEachExpiryInput(function(element
) {
339 element
.disabled
= !val
;
343 this.forEachExpirySelector(function(element
) {
347 element
.disabled
= !val
;