Add comment
[mediawiki.git] / skins / common / protect.js
blob863b95bd80c3a9759e77cb49bf62a5423f3652d9
1 /**
2  * Set up the protection chaining interface (i.e. "unlock move permissions" checkbox)
3  * on the protection form
4  *
5  * @param String tableId Identifier of the table containing UI bits
6  * @param String labelText Text to use for the checkbox label
7  */
8 function protectInitialize( tableId, labelText, types ) {
9         if( !( document.createTextNode && document.getElementById && document.getElementsByTagName ) )
10                 return false;
11                 
12         var box = document.getElementById( tableId );
13         if( !box )
14                 return false;
15                 
16         var tbody = box.getElementsByTagName( 'tbody' )[0];
17         var row = document.createElement( 'tr' );
18         tbody.appendChild( row );
19         
20         row.appendChild( document.createElement( 'td' ) );
21         var col = document.createElement( 'td' );
22         row.appendChild( col );
23         // If there is only one protection type, there is nothing to chain
24         if( types > 1 ) {
25                 var check = document.createElement( 'input' );
26                 check.id = 'mwProtectUnchained';
27                 check.type = 'checkbox';
28                 col.appendChild( check );
29                 addClickHandler( check, protectChainUpdate );
31                 col.appendChild( document.createTextNode( ' ' ) );
32                 var label = document.createElement( 'label' );
33                 label.htmlFor = 'mwProtectUnchained';
34                 label.appendChild( document.createTextNode( labelText ) );
35                 col.appendChild( label );
37                 check.checked = !protectAllMatch();
38                 protectEnable( check.checked );
39         }
40         
41         setCascadeCheckbox();
42         
43         return true;
46 /**
47 * Determine if, given the cascadeable protection levels
48 * and what is currently selected, if the cascade box 
49 * can be checked
51 * @return boolean
54 function setCascadeCheckbox() {
55         // For non-existent titles, there is no cascade option
56         if( !document.getElementById( 'mwProtect-cascade' ) ) {
57                 return false;
58         }
59         var lists = protectSelectors();
60         for( var i = 0; i < lists.length; i++ ) {
61                 if( lists[i].selectedIndex > -1 ) {
62                         var items = lists[i].getElementsByTagName( 'option' );
63                         var selected = items[ lists[i].selectedIndex ].value;
64                         if( !isCascadeableLevel(selected) ) {
65                                 document.getElementById( 'mwProtect-cascade' ).checked = false;
66                                 document.getElementById( 'mwProtect-cascade' ).disabled = true;
67                                 return false;
68                         }
69                 }
70         }
71         document.getElementById( 'mwProtect-cascade' ).disabled = false;
72         return true;
75 /**
76 * Is this protection level cascadeable?
77 * @param String level
79 * @return boolean
82 function isCascadeableLevel( level ) {   
83         for (var k = 0; k < wgCascadeableLevels.length; k++) {   
84                 if ( wgCascadeableLevels[k] == level ) {         
85                         return true;     
86                 } 
87         }        
88         return false;    
91 /**
92  * When protection levels are locked together, update the rest
93  * when one action's level changes
94  *
95  * @param Element source Level selector that changed
96  */
97 function protectLevelsUpdate(source) {
98         if( !protectUnchained() )
99                 protectUpdateAll( source.selectedIndex );
100         setCascadeCheckbox();
104  * Update chain status and enable/disable various bits of the UI
105  * when the user changes the "unlock move permissions" checkbox
106  */
107 function protectChainUpdate() {
108         if( protectUnchained() ) {
109                 protectEnable( true );
110         } else {
111                 protectChain();
112                 protectEnable( false );
113         }
114         setCascadeCheckbox();
118  * Are all actions protected at the same level?
120  * @return boolean
121  */
122 function protectAllMatch() {
123         var values = new Array();
124         protectForSelectors(function(set) {
125                 values[values.length] = set.selectedIndex;
126         });
127         for (var i = 1; i < values.length; i++) {
128                 if (values[i] != values[0]) {
129                         return false;
130                 }
131         }
132         return true;
136  * Is protection chaining on or off?
138  * @return bool
139  */
140 function protectUnchained() {
141         var unchain = document.getElementById( 'mwProtectUnchained' );
142         return unchain
143                 ? unchain.checked
144                 : true; // No control, so we need to let the user set both levels
148  * Find the highest-protected action and set all others to that level
149  */
150 function protectChain() {
151         var maxIndex = -1;
152         protectForSelectors(function(set) {
153                 if (set.selectedIndex > maxIndex) {
154                         maxIndex = set.selectedIndex;
155                 }
156         });
157         protectUpdateAll(maxIndex);
161  * Protect all actions at the specified level
163  * @param int index Protection level
164  */
165 function protectUpdateAll(index) {
166         protectForSelectors(function(set) {
167                 if (set.selectedIndex != index) {
168                         set.selectedIndex = index;
169                 }
170         });
174  * Apply a callback to each protection selector
176  * @param callable func Callback function
177  */
178 function protectForSelectors(func) {
179         var selectors = protectSelectors();
180         for (var i = 0; i < selectors.length; i++) {
181                 func(selectors[i]);
182         }
186  * Get a list of all protection selectors on the page
188  * @return Array
189  */
190 function protectSelectors() {
191         var all = document.getElementsByTagName("select");
192         var ours = new Array();
193         for (var i = 0; i < all.length; i++) {
194                 var set = all[i];
195                 if (set.id.match(/^mwProtect-level-/)) {
196                         ours[ours.length] = set;
197                 }
198         }
199         return ours;
203  * Enable/disable protection selectors
205  * @param boolean val Enable?
206  */
207 function protectEnable(val) {
208         // fixme
209         var first = true;
210         protectForSelectors(function(set) {
211                 if (first) {
212                         first = false;
213                 } else {
214                         set.disabled = !val;
215                         set.style.visible = val ? "visible" : "hidden";
216                 }
217         });