90ff35636dedec8071ba09c2f7fba42f951aee17
[lhc/web/wiklou.git] / skins / common / protect.js
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 ) {
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
24 var check = document.createElement( 'input' );
25 check.id = 'mwProtectUnchained';
26 check.type = 'checkbox';
27 col.appendChild( check );
28 addClickHandler( check, protectChainUpdate );
29
30 col.appendChild( document.createTextNode( ' ' ) );
31 var label = document.createElement( 'label' );
32 label.setAttribute( 'for', 'mwProtectUnchained' );
33 label.appendChild( document.createTextNode( labelText ) );
34 col.appendChild( label );
35
36 check.checked = !protectAllMatch();
37 protectEnable( check.checked );
38
39 allowCascade();
40
41 return true;
42 }
43
44 function allowCascade() {
45 var lists = protectSelectors();
46 for( var i = 0; i < lists.length; i++ ) {
47 if( lists[i].selectedIndex > -1 ) {
48 var items = lists[i].getElementsByTagName( 'option' );
49 var selected = items[ lists[i].selectedIndex ].value;
50 if( !isCascadeableLevel(selected) ) {
51 document.getElementById( 'mwProtect-cascade' ).checked = false;
52 document.getElementById( 'mwProtect-cascade' ).disabled = true;
53 return false;
54 }
55 }
56 }
57 document.getElementById( 'mwProtect-cascade' ).disabled = false;
58 return true;
59 }
60
61 function isCascadeableLevel( level ) {
62 for (var k = 0; k < wgCascadeableLevels.length; k++) {
63 if ( wgCascadeableLevels[k] == level ) {
64 return true;
65 }
66 }
67 return false;
68 }
69
70 /**
71 * When protection levels are locked together, update the rest
72 * when one action's level changes
73 *
74 * @param Element source Level selector that changed
75 */
76 function protectLevelsUpdate(source) {
77 if( !protectUnchained() )
78 protectUpdateAll( source.selectedIndex );
79 allowCascade();
80 }
81
82 /**
83 * Update chain status and enable/disable various bits of the UI
84 * when the user changes the "unlock move permissions" checkbox
85 */
86 function protectChainUpdate() {
87 if( protectUnchained() ) {
88 protectEnable( true );
89 } else {
90 protectChain();
91 protectEnable( false );
92 }
93 allowCascade();
94 }
95
96 /**
97 * Are all actions protected at the same level?
98 *
99 * @return boolean
100 */
101 function protectAllMatch() {
102 var values = new Array();
103 protectForSelectors(function(set) {
104 values[values.length] = set.selectedIndex;
105 });
106 for (var i = 1; i < values.length; i++) {
107 if (values[i] != values[0]) {
108 return false;
109 }
110 }
111 return true;
112 }
113
114 /**
115 * Is protection chaining on or off?
116 *
117 * @return bool
118 */
119 function protectUnchained() {
120 var unchain = document.getElementById( 'mwProtectUnchained' );
121 return unchain
122 ? unchain.checked
123 : true; // No control, so we need to let the user set both levels
124 }
125
126 /**
127 * Find the highest-protected action and set all others to that level
128 */
129 function protectChain() {
130 var maxIndex = -1;
131 protectForSelectors(function(set) {
132 if (set.selectedIndex > maxIndex) {
133 maxIndex = set.selectedIndex;
134 }
135 });
136 protectUpdateAll(maxIndex);
137 }
138
139 /**
140 * Protect all actions at the specified level
141 *
142 * @param int index Protection level
143 */
144 function protectUpdateAll(index) {
145 protectForSelectors(function(set) {
146 if (set.selectedIndex != index) {
147 set.selectedIndex = index;
148 }
149 });
150 }
151
152 /**
153 * Apply a callback to each protection selector
154 *
155 * @param callable func Callback function
156 */
157 function protectForSelectors(func) {
158 var selectors = protectSelectors();
159 for (var i = 0; i < selectors.length; i++) {
160 func(selectors[i]);
161 }
162 }
163
164 /**
165 * Get a list of all protection selectors on the page
166 *
167 * @return Array
168 */
169 function protectSelectors() {
170 var all = document.getElementsByTagName("select");
171 var ours = new Array();
172 for (var i = 0; i < all.length; i++) {
173 var set = all[i];
174 if (set.id.match(/^mwProtect-level-/)) {
175 ours[ours.length] = set;
176 }
177 }
178 return ours;
179 }
180
181 /**
182 * Enable/disable protection selectors
183 *
184 * @param boolean val Enable?
185 */
186 function protectEnable(val) {
187 // fixme
188 var first = true;
189 protectForSelectors(function(set) {
190 if (first) {
191 first = false;
192 } else {
193 set.disabled = !val;
194 set.style.visible = val ? "visible" : "hidden";
195 }
196 });
197 }