PluginProbe
Authorizer / 2.5.1
Authorizer v2.5.1
3.15.3 3.15.2 3.15.1 3.15.0 3.14.3 3.14.4 3.14.2 3.14.1 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.9.0 2.9.1 2.9.10 2.9.11 2.9.12 2.9.13 2.9.2 2.9.3 2.9.6 All 126 releases
authorizer / js / authorizer.js

authorizer.js in Authorizer 2.5.1, at js/authorizer.js

1,078 lines 46.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 var animation_speed = 300;
2 var shake_speed = 600;
3
4
5
6 // Switch between option tabs.
7 function choose_tab( list_name, delay ) {
8 var $ = jQuery;
9
10 // default delay is 0
11 delay = typeof delay !== 'undefined' ? delay : 0;
12
13 // default to the access list tab
14 list_name = typeof list_name !== 'undefined' ? list_name : 'access_list';
15
16 // Hide all tab content, then show selected tab content
17 $( 'div.section_info, div.section_info + table' ).hide();
18 $( '#section_info_' + list_name + ', #section_info_' + list_name + ' + table' ).show();
19
20 // Set active tab
21 $( '.nav-tab-wrapper a' ).removeClass( 'nav-tab-active' );
22 $( 'a.nav-tab-' + list_name ).addClass( 'nav-tab-active' );
23
24 // Hide site options if they are overridden by a multisite setting.
25 setTimeout( hide_multisite_overridden_options, delay );
26
27 // Hide Save Changes button if we're on the access lists page (changing
28 // access lists saves automatically via AJAX).
29 $( 'body:not(.network-admin) #submit' ).toggle( list_name !== 'access_lists' );
30
31 // Save user's active tab to sessionStorage (so we can restore it on reload).
32 // Note: session storage persists until the browser tab is closed.
33 sessionStorage.setItem( 'tab', list_name );
34 }
35
36 // Update user's usermeta field.
37 function auth_update_usermeta( caller ) {
38 var $ = jQuery,
39 $caller = $( caller ),
40 $usermeta = $caller.parent().children( '.auth-usermeta' ),
41 email = $caller.siblings( '.auth-email' ).val(),
42 usermeta = $usermeta.val(),
43 nonce_save_auth_settings = $( '#nonce_save_auth_settings' ).val();
44
45 // Remove reference to caller if it's the usermeta field itself (not a button triggering the save).
46 if ( $caller.hasClass( 'auth-usermeta' ) ) {
47 $caller = $();
48 }
49
50 // Disable inputs, show spinner.
51 $caller.attr( 'disabled', 'disabled' );
52 $usermeta.attr( 'disabled', 'disabled' );
53 $usermeta.after( '<span class="spinner is-active"></span>' );
54 $( 'html' ).addClass( 'busy' );
55
56 // Call ajax save function.
57 $.post( ajaxurl, {
58 'action': 'update_auth_usermeta',
59 'email': email,
60 'usermeta': usermeta,
61 'nonce_save_auth_settings': nonce_save_auth_settings,
62 }, function ( response ) {
63 var succeeded = response === 'success';
64 var spinner_text = succeeded ? auth_L10n.saved + '.' : '<span style="color: red;">' + auth_L10n.failed + '.</span>';
65 var spinner_wait = succeeded ? 500 : 2000;
66
67 // Enable inputs, remove spinner.
68 $caller.removeAttr( 'disabled' );
69 $usermeta.removeAttr( 'disabled' );
70 $caller.css( 'display', 'none' );
71 $( 'form .spinner:not(:has(.spinner-text))' ).animate( { width: '60px' }, 'fast' ).append( '<span class="spinner-text">' + spinner_text + '</span>' ).delay( spinner_wait ).hide( animation_speed, function() {
72 $( this ).remove();
73 });
74 $( 'html' ).removeClass( 'busy' );
75
76 }).fail( function ( response ) {
77 var succeeded = false;
78 var spinner_text = succeeded ? auth_L10n.saved + '.' : '<span style="color: red;">' + auth_L10n.failed + '.</span>';
79 var spinner_wait = succeeded ? 500 : 2000;
80
81 // Enable inputs, remove spinner.
82 $caller.removeAttr( 'disabled' );
83 $usermeta.removeAttr( 'disabled' );
84 $caller.css( 'display', 'none' );
85 $( 'form .spinner:not(:has(.spinner-text))' ).animate( { width: '60px' }, 'fast' ).append( '<span class="spinner-text">' + spinner_text + '</span>' ).delay( spinner_wait ).hide( animation_speed, function() {
86 $( this ).remove();
87 });
88 $( 'html' ).removeClass( 'busy' );
89
90 });
91
92 }
93
94 // Update user's role (multisite options page).
95 function auth_multisite_change_role( caller ) {
96 var is_multisite = true;
97 auth_change_role( caller, is_multisite );
98 }
99
100 // Update user's role.
101 function auth_change_role( caller, is_multisite ) {
102 var $ = jQuery;
103
104 // Set default for multisite flag (run different save routine if multisite)
105 is_multisite = typeof is_multisite !== 'undefined' ? is_multisite : false;
106
107 var email = $( caller ).parent().find( '.auth-email' );
108 var role = $( caller ).parent().find( '.auth-role' );
109 var date_added = $( caller ).parent().find( '.auth-date-added' );
110
111 var user = {
112 'email': email.val(),
113 'role': role.val(),
114 'date_added': date_added.val(),
115 'edit_action': 'change_role',
116 'multisite_user': is_multisite,
117 };
118
119 // Update the options in the database with this change.
120 update_auth_user( caller, 'access_users_approved', user );
121
122 return true;
123 }
124
125 // Add user to list (multisite options page).
126 function auth_multisite_add_user( caller, list, create_local_account ) {
127 var is_multisite = true;
128
129 // Default to the approved list.
130 list = typeof list !== 'undefined' ? list : 'approved';
131
132 // Default to not creating a local account.
133 create_local_account = typeof create_local_account !== 'undefined' ? create_local_account : false;
134
135 // There currently is no multisite blocked list, so do nothing.
136 if ( list === 'blocked' ) {
137 return;
138 }
139
140 auth_add_user( caller, list, create_local_account, is_multisite );
141 }
142 // Add user to list (list = blocked or approved).
143 function auth_add_user( caller, list, create_local_account, is_multisite ) {
144 var $ = jQuery;
145
146 // Skip email address validation if adding from pending list (not user-editable).
147 var skip_validation = $( caller ).parent().parent().attr( 'id' ) === 'list_auth_settings_access_users_pending';
148
149 // Skip email address validation if we're banning an existing user (since they're already in a list).
150 skip_validation = skip_validation || $( caller ).attr( 'id' ).indexOf( 'block_user' ) > -1;
151
152 // Set default for multisite flag (run different save routine if multisite)
153 is_multisite = typeof is_multisite !== 'undefined' ? is_multisite : false;
154
155 // Default to the approved list.
156 list = typeof list !== 'undefined' ? list : 'approved';
157
158 // Default to not creating a local account.
159 create_local_account = typeof create_local_account !== 'undefined' ? create_local_account : false;
160
161 var email = $( caller ).parent().find( '.auth-email' );
162 var role = $( caller ).parent().find( '.auth-role' );
163 var date_added = $( caller ).parent().find( '.auth-date-added' );
164
165 // Helper variable for disabling buttons while processing. This will be
166 // set differently if our clicked button is nested in a div (below).
167 var buttons = caller;
168
169 // Button (caller) might be nested in a div, so we need to walk up one more level
170 if ( email.length === 0 || role.length === 0 ) {
171 email = $( caller ).parent().parent().find( '.auth-email' );
172 role = $( caller ).parent().parent().find( '.auth-role' );
173 date_added = $( caller ).parent().parent().find( '.auth-date-added' );
174 buttons = $( caller ).parent().children();
175 }
176
177 var user = {
178 'email': email.val(),
179 'role': role.val(),
180 'date_added': date_added.val(),
181 'edit_action': 'add',
182 'local_user': create_local_account,
183 'multisite_user': is_multisite,
184 };
185
186 var next_id = $( '#list_auth_settings_access_users_' + list + ' li' ).length;
187 var validated = true;
188
189 if ( $.trim( email.val() ) === '' ) {
190 return false;
191 }
192
193 $( buttons ).attr( 'disabled', 'disabled' );
194
195 // Check if the name being added already exists in any list.
196 if ( ! skip_validation && validated ) {
197 $( 'li > input.auth-email' ).each( function() {
198 if ( this.value == email.val() ) {
199 validated = false;
200 email.parent().effect( 'shake', shake_speed );
201 $( this ).parent().effect( 'shake', shake_speed );
202 $( buttons ).removeAttr( 'disabled' );
203 return false;
204 }
205 });
206 }
207
208 // Check if the user being added has a valid email address.
209 if ( ! skip_validation && validated ) {
210 if ( ! valid_email( email.val() ) ) {
211 validated = false;
212 $( '#new_' + list + '_user_email' ).parent().effect( 'shake', shake_speed );
213 $( buttons ).removeAttr( 'disabled' );
214 }
215 }
216
217 if ( validated ) {
218 // Add the new item.
219 var auth_js_prefix = is_multisite ? 'auth_multisite_' : 'auth_';
220 var local_icon = create_local_account ? '&nbsp;<a title="' + auth_L10n.local_wordpress_user + '" class="auth-local-user"><span class="glyphicon glyphicon-user"></span></a>' : '';
221 var ban_button = list === 'approved' && ! is_multisite ? '<a class="button" onclick="' + auth_js_prefix + 'add_user( this, \'blocked\', false ); ' + auth_js_prefix + 'ignore_user( this, \'approved\' );" title="' + auth_L10n.block_ban_user + '"><span class="glyphicon glyphicon-ban-circle"></span></a>' : '';
222 $( ' \
223 <li id="new_user_' + next_id + '" style="display: none;"> \
224 <input type="text" id="auth_settings_access_users_' + list + '_' + next_id + '" name="auth_settings[access_users_' + list + '][' + next_id + '][email]" value="' + email.val() + '" readonly="true" class="auth-email" /> \
225 <select name="auth_settings[access_users_' + list + '][' + next_id + '][role]" class="auth-role" onchange="' + auth_js_prefix + 'change_role( this );"> \
226 </select> \
227 <input type="text" name="auth_settings[access_users_' + list + '][' + next_id + '][date_added]" value="' + getShortDate() + '" readonly="true" class="auth-date-added" /> \
228 ' + ban_button + ' \
229 <a class="button" onclick="' + auth_js_prefix + 'ignore_user( this, \'approved\' );" title="' + auth_L10n.remove_user + '"><span class="glyphicon glyphicon-remove"></span></a> \
230 ' + local_icon + ' \
231 <span class="spinner is-active"></span> \
232 </li> \
233 ' ).appendTo( '#list_auth_settings_access_users_' + list + '' ).slideDown( 250 );
234
235 // Populate the role dropdown in the new element. Because clone() doesn't
236 // save selected state on select elements, set that too.
237 $( 'option', role ).clone().appendTo( '#new_user_' + next_id + ' .auth-role' );
238 $( '#new_user_' + next_id + ' .auth-role' ).val( role.val() );
239
240 // Remove the 'empty list' item if it exists.
241 $( '#list_auth_settings_access_users_' + list + ' li.auth-empty' ).remove();
242
243 // Update the options in the database with this change.
244 update_auth_user( buttons, 'access_users_' + list, user );
245
246 // Reset the new user textboxes
247 if ( email.hasClass( 'new' ) ) {
248 email.val( '' );
249 }
250
251 // Re-enable the action buttons now that we're done saving.
252 $( buttons ).removeAttr( 'disabled' );
253
254 return true;
255 }
256 }
257
258 // Remove user from list (multisite options page).
259 function auth_multisite_ignore_user( caller, list_name ) {
260 var is_multisite = true;
261
262 // Set default list if not provided.
263 list_name = typeof list_name !== 'undefined' ? list_name : '';
264
265 auth_ignore_user( caller, list_name, is_multisite );
266 }
267 // Remove user from list.
268 function auth_ignore_user( caller, list_name, is_multisite ) {
269 var $ = jQuery;
270
271 // Set default for multisite flag (run different save routine if multisite)
272 is_multisite = typeof is_multisite !== 'undefined' ? is_multisite : false;
273
274 // Set default list if not provided.
275 list_name = typeof list_name !== 'undefined' ? list_name : 'approved';
276
277 var email = $( caller ).parent().find( '.auth-email' );
278
279 var user = {
280 'email': email.val(),
281 'role': '',
282 'date_added': '',
283 'edit_action': 'remove',
284 'multisite_user': is_multisite,
285 };
286
287 // Show an 'empty list' message if we're deleting the last item
288 var list = $( caller ).closest( 'ul' );
289 if ( $( 'li', list ).length <= 1 ) {
290 $( list ).append( '<li class="auth-empty"><em>' + auth_L10n.no_users_in + ' ' + list_name + '</em></li>' );
291 }
292
293 $( caller ).parent().slideUp( 250, function() {
294 // Remove the list item.
295 $( this ).remove();
296
297 // Update the options in the database with this change.
298 update_auth_user( caller, 'access_users_' + list_name, user );
299 });
300 }
301
302
303 // Make changes to one of the user lists (pending, approved, blocked) via ajax.
304 function update_auth_user( caller, setting, user_to_edit ) {
305 var $ = jQuery,
306 access_users_pending = [],
307 access_users_approved = [],
308 access_users_blocked = [],
309 nonce_save_auth_settings = $( '#nonce_save_auth_settings' ).val();
310
311 // Defaults:
312 // setting = 'access_users_pending' or 'access_users_approved' or 'access_users_blocked',
313 // user_to_edit = {
314 // email: 'johndoe@example.com',
315 // role: 'subscriber',
316 // date_added: 'Jun 2014',
317 // edit_action: 'add' or 'remove' or 'change_role',
318 // local_user: true or false,
319 // multisite_user: true or false,
320 // }
321 setting = typeof setting !== 'undefined' ? setting : 'none';
322 user_to_edit = typeof user_to_edit !== 'undefined' ? user_to_edit : {};
323
324 // Enable wait cursor.
325 $( 'html' ).addClass( 'busy' );
326
327 // Enable spinner by element that triggered this event (caller).
328 $( caller ).attr( 'disabled', 'disabled' );
329 if ( $( caller ).val() === auth_L10n.save_changes ) {
330 $( caller ).last().after( '<span class="spinner is-active"></span>' );
331 } else if ( $( caller ).hasClass( 'auth-role' ) ) {
332 $( caller ).last().next().next().after( '<span class="spinner is-active"></span>' );
333 } else {
334 $( caller ).last().next().after( '<span class="spinner is-active"></span>' );
335 }
336 $( 'form .spinner' ).show();
337
338 // Grab the value of the setting we are saving.
339 if ( setting === 'access_users_pending' ) {
340 access_users_pending.push( user_to_edit );
341 } else if ( setting === 'access_users_approved' ) {
342 access_users_approved.push( user_to_edit );
343 } else if ( setting === 'access_users_blocked' ) {
344 access_users_blocked.push( user_to_edit );
345 }
346
347 $.post( ajaxurl, {
348 'action': 'update_auth_user',
349 'setting': setting,
350 'access_users_pending': access_users_pending,
351 'access_users_approved': access_users_approved,
352 'access_users_blocked': access_users_blocked,
353 'nonce_save_auth_settings': nonce_save_auth_settings,
354 }, function( response ) {
355 // Server responded, but if response isn't 'success' it failed to save.
356 var succeeded = response === 'success';
357 var spinner_text = succeeded ? auth_L10n.saved + '.' : '<span style="color: red;">' + auth_L10n.failed + '.</span>';
358 var spinner_wait = succeeded ? 500 : 2000;
359 $( 'form .spinner:not(:has(.spinner-text))' ).append( '<span class="spinner-text">' + spinner_text + '</span>' ).delay( spinner_wait ).hide( animation_speed, function() {
360 $( this ).remove();
361 });
362 $( caller ).removeAttr( 'disabled' );
363
364 // Disable wait cursor.
365 $( 'html' ).removeClass( 'busy' );
366 }).fail( function() {
367 // Fail fires if the server doesn't respond or responds with 500 codes
368 var succeeded = false;
369 var spinner_text = succeeded ? auth_L10n.saved + '.' : '<span style="color: red;">' + auth_L10n.failed + '.</span>';
370 var spinner_wait = succeeded ? 500 : 2000;
371 $( 'form .spinner:not(:has(.spinner-text))' ).append( '<span class="spinner-text">' + spinner_text + '</span>' ).delay( spinner_wait ).hide( animation_speed, function() {
372 $( this ).remove();
373 });
374 $( caller ).removeAttr( 'disabled' );
375
376 // Disable wait cursor.
377 $( 'html' ).removeClass( 'busy' );
378 });
379 }
380
381
382 // Multisite functions
383 function save_auth_multisite_settings( caller ) {
384 var $ = jQuery;
385
386 // Enable wait cursor.
387 $( 'html' ).addClass( 'busy' );
388
389 $( caller ).attr( 'disabled', 'disabled' );
390 if ( $( caller ).val() === auth_L10n.save_changes ) {
391 $( caller ).last().after( '<span class="spinner is-active"></span>' );
392 } else if ( $( caller ).hasClass( 'auth-role' ) ) {
393 $( caller ).last().next().next().after( '<span class="spinner is-active"></span>' );
394 } else {
395 $( caller ).last().next().after( '<span class="spinner is-active"></span>' );
396 }
397 $( 'form .spinner' ).show();
398
399 // Get form elements to save
400
401 var nonce_save_auth_settings = $( '#nonce_save_auth_settings' ).val();
402
403 var multisite_override = $( '#auth_settings_multisite_override' ).is( ':checked' ) ? '1' : '';
404
405 var access_who_can_login = $( 'form input[name="auth_settings[access_who_can_login]"]:checked' ).val();
406
407 var access_who_can_view = $( 'form input[name="auth_settings[access_who_can_view]"]:checked' ).val();
408
409 var access_users_approved = {};
410 $( '#list_auth_settings_access_users_approved li' ).each( function( index ) {
411 var user = {};
412 user.email = $( '.auth-email', this ).val();
413 user.role = $( '.auth-role', this ).val();
414 user.date_added = $( '.auth-date-added', this ).val();
415 user.local_user = $( '.auth-local-user', this ).length !== 0;
416 access_users_approved[index] = user;
417 });
418
419 var access_default_role = $( '#auth_settings_access_default_role' ).val();
420
421 var google = $( '#auth_settings_google' ).is( ':checked' ) ? '1' : '';
422 var google_clientid = $( '#auth_settings_google_clientid' ).val();
423 var google_clientsecret = $( '#auth_settings_google_clientsecret' ).val();
424
425 var cas = $( '#auth_settings_cas' ).is( ':checked' ) ? '1' : '';
426 var cas_custom_label = $( '#auth_settings_cas_custom_label' ).val();
427 var cas_host = $( '#auth_settings_cas_host' ).val();
428 var cas_port = $( '#auth_settings_cas_port' ).val();
429 var cas_path = $( '#auth_settings_cas_path' ).val();
430 var cas_version = $( '#auth_settings_cas_version' ).val();
431 var cas_attr_email = $( '#auth_settings_cas_attr_email' ).val();
432 var cas_attr_first_name = $( '#auth_settings_cas_attr_first_name' ).val();
433 var cas_attr_last_name = $( '#auth_settings_cas_attr_last_name' ).val();
434 var cas_attr_update_on_login = $( '#auth_settings_cas_attr_update_on_login' ).is( ':checked' ) ? '1' : '';
435 var cas_auto_login = $( '#auth_settings_cas_auto_login' ).is( ':checked' ) ? '1' : '';
436
437 var ldap = $( '#auth_settings_ldap' ).is( ':checked' ) ? '1' : '';
438 var ldap_host = $( '#auth_settings_ldap_host' ).val();
439 var ldap_port = $( '#auth_settings_ldap_port' ).val();
440 var ldap_search_base = $( '#auth_settings_ldap_search_base' ).val();
441 var ldap_uid = $( '#auth_settings_ldap_uid' ).val();
442 var ldap_attr_email = $( '#auth_settings_ldap_attr_email' ).val();
443 var ldap_user = $( '#auth_settings_ldap_user' ).val();
444 var ldap_password = $( '#auth_settings_ldap_password' ).val();
445 var ldap_tls = $( '#auth_settings_ldap_tls' ).is( ':checked' ) ? '1' : '';
446 var ldap_lostpassword_url = $( '#auth_settings_ldap_lostpassword_url' ).val();
447 var ldap_attr_first_name = $( '#auth_settings_ldap_attr_first_name' ).val();
448 var ldap_attr_last_name = $( '#auth_settings_ldap_attr_last_name' ).val();
449 var ldap_attr_update_on_login = $( '#auth_settings_ldap_attr_update_on_login' ).is( ':checked' ) ? '1' : '';
450
451 var advanced_lockouts = {
452 'attempts_1': $( '#auth_settings_advanced_lockouts_attempts_1' ).val(),
453 'duration_1': $( '#auth_settings_advanced_lockouts_duration_1' ).val(),
454 'attempts_2': $( '#auth_settings_advanced_lockouts_attempts_2' ).val(),
455 'duration_2': $( '#auth_settings_advanced_lockouts_duration_2' ).val(),
456 'reset_duration': $( '#auth_settings_advanced_lockouts_reset_duration' ).val()
457 };
458 var advanced_hide_wp_login = $( '#auth_settings_advanced_hide_wp_login' ).is( ':checked' ) ? '1' : '';
459
460 $.post( ajaxurl, {
461 action: 'save_auth_multisite_settings',
462 'nonce_save_auth_settings': nonce_save_auth_settings,
463 'multisite_override': multisite_override,
464 'access_who_can_login': access_who_can_login,
465 'access_who_can_view': access_who_can_view,
466 'access_users_approved': access_users_approved,
467 'access_default_role': access_default_role,
468 'google': google,
469 'google_clientid': google_clientid,
470 'google_clientsecret': google_clientsecret,
471 'cas': cas,
472 'cas_custom_label': cas_custom_label,
473 'cas_host': cas_host,
474 'cas_port': cas_port,
475 'cas_path': cas_path,
476 'cas_version': cas_version,
477 'cas_attr_email': cas_attr_email,
478 'cas_attr_first_name': cas_attr_first_name,
479 'cas_attr_last_name': cas_attr_last_name,
480 'cas_attr_update_on_login': cas_attr_update_on_login,
481 'cas_auto_login': cas_auto_login,
482 'ldap': ldap,
483 'ldap_host': ldap_host,
484 'ldap_port': ldap_port,
485 'ldap_search_base': ldap_search_base,
486 'ldap_uid': ldap_uid,
487 'ldap_attr_email': ldap_attr_email,
488 'ldap_user': ldap_user,
489 'ldap_password': ldap_password,
490 'ldap_tls': ldap_tls,
491 'ldap_lostpassword_url': ldap_lostpassword_url,
492 'ldap_attr_first_name': ldap_attr_first_name,
493 'ldap_attr_last_name': ldap_attr_last_name,
494 'ldap_attr_update_on_login': ldap_attr_update_on_login,
495 'advanced_lockouts': advanced_lockouts,
496 'advanced_hide_wp_login': advanced_hide_wp_login,
497 }, function( response ) {
498 var succeeded = response === 'success';
499 var spinner_text = succeeded ? auth_L10n.saved + '.' : '<span style="color: red;">' + auth_L10n.failed + '.</span>';
500 var spinner_wait = succeeded ? 500 : 2000;
501 $( 'form .spinner:not(:has(.spinner-text))' ).append( '<span class="spinner-text">' + spinner_text + '</span>' ).delay( spinner_wait ).hide( animation_speed, function() {
502 $( this ).remove();
503 });
504 $( caller ).removeAttr( 'disabled' );
505
506 // Disable wait cursor.
507 $( 'html' ).removeClass( 'busy' );
508 }).fail( function() {
509 // Fail fires if the server doesn't respond
510 var succeeded = false;
511 var spinner_text = succeeded ? auth_L10n.saved + '.' : '<span style="color: red;">' + auth_L10n.failed + '.</span>';
512 var spinner_wait = succeeded ? 500 : 2000;
513 $( 'form .spinner:not(:has(.spinner-text))' ).append( '<span class="spinner-text">' + spinner_text + '</span>' ).delay( spinner_wait ).hide( animation_speed, function() {
514 $( this ).remove();
515 });
516 $( caller ).removeAttr( 'disabled' );
517
518 // Disable wait cursor.
519 $( 'html' ).removeClass( 'busy' );
520 });
521 }
522
523 // Hide or show (with overlay) the multisite settings based on the "multisite override" setting.
524 function hide_multisite_settings_if_disabled() {
525 var $ = jQuery;
526
527 if ( $( '#auth_settings_multisite_override' ).length === 0 )
528 return;
529
530 var settings = $( '#auth_multisite_settings' );
531 var overlay = $( '#auth_multisite_settings_disabled_overlay' );
532
533 if ( $( '#auth_settings_multisite_override' ).is( ':checked' ) ) {
534 overlay.hide( animation_speed );
535 } else {
536 overlay.css({
537 'background-color': '#f1f1f1',
538 'z-index': 1,
539 'opacity': 0.8,
540 'position': 'absolute',
541 'top': settings.position().top,
542 'left': settings.position().left - 20,
543 'width': '100%',
544 'height': settings.height(),
545 'padding-left': 20,
546 });
547 overlay.show();
548 }
549 }
550
551 // Hide (with overlay) site options if overridden by a multisite option.
552 function hide_multisite_overridden_options() {
553 var $ = jQuery;
554
555 $( '.auth_multisite_override_overlay' ).each( function() {
556 // Option to hide is stored in the overlay's id with 'overlay-hide-' prefix.
557 var option_container_to_hide = $( this ).closest( 'tr' );
558 if ( option_container_to_hide.length > 0 ) {
559 $( this ).css({
560 'background-color': '#f1f1f1',
561 'z-index': 1,
562 'opacity': 0.8,
563 'position': 'absolute',
564 'top': option_container_to_hide.position().top,
565 'left': option_container_to_hide.position().left,
566 'width': '100%',
567 'height': option_container_to_hide.height(),
568 });
569 $( this ).show();
570 }
571 });
572 }
573
574
575
576 // Helper function to hide/show wordpress option
577 function animate_option( action, option ) {
578 var $ = jQuery;
579 if ( action === 'show' ) {
580 $( 'div.animated_wrapper', option ).slideDown( animation_speed );
581 $( 'th', option ).animate({ padding: '20px 10px 20px 0' }, { duration: animation_speed });
582 $( 'td', option ).animate({ padding: '15px 10px' }, { duration: animation_speed });
583 } else if ( action === 'hide' ) {
584 $( 'div.animated_wrapper', option ).slideUp( animation_speed );
585 $( 'td, th', option ).animate({ padding: '0px' }, { duration: animation_speed });
586 } else if ( action === 'hide_immediately' ) {
587 $( 'div.animated_wrapper', option ).hide();
588 $( 'td, th', option ).css({ padding: '0px' });
589 }
590 }
591
592 // Helper function to grab a querystring param value by name
593 function getParameterByName( needle, haystack ) {
594 needle = needle.replace( /[\[]/, "\\\[").replace(/[\]]/, "\\\]" );
595 var regex = new RegExp( "[\\?&]" + needle + "=([^&#]*)" );
596 var results = regex.exec( haystack );
597 if( results === null )
598 return '';
599 else
600 return decodeURIComponent( results[1].replace( /\+/g, " " ) );
601 }
602
603 // Helper function to generate a random string
604 function getRandomId() {
605 var text = "";
606 var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
607 for ( var i=0; i < 5; i++ )
608 text += possible.charAt( Math.floor( Math.random() * possible.length ) );
609 return text;
610 }
611
612 // Helper function to return a short date (e.g., Jul 2013) for today's date
613 function getShortDate( date ) {
614 date = typeof date !== 'undefined' ? date : new Date();
615 var month = '';
616 switch ( date.getMonth() ) {
617 case 0: month = 'Jan'; break;
618 case 1: month = 'Feb'; break;
619 case 2: month = 'Mar'; break;
620 case 3: month = 'Apr'; break;
621 case 4: month = 'May'; break;
622 case 5: month = 'Jun'; break;
623 case 6: month = 'Jul'; break;
624 case 7: month = 'Aug'; break;
625 case 8: month = 'Sep'; break;
626 case 9: month = 'Oct'; break;
627 case 10: month = 'Nov'; break;
628 case 11: month = 'Dec'; break;
629 }
630 return month + ' ' + date.getFullYear();
631 }
632
633 // Helper function to grab a querystring value
634 function querystring( key ) {
635 var re = new RegExp( '(?:\\?|&)'+key+'=(.*?)(?=&|$)', 'gi' );
636 var r = [], m;
637 while ( ( m = re.exec( document.location.search ) ) !== null )
638 r.push( m[1] );
639 return r;
640 }
641
642 // Helper function to check if an email address is valid.
643 function valid_email( email ) {
644 var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
645 return re.test( email );
646 }
647
648
649 jQuery( document ).ready( function( $ ) {
650 // Grab references to form elements that we will show/hide on page load
651 var auth_settings_access_users_pending = $( '#list_auth_settings_access_users_pending' ).closest( 'tr' );
652 var auth_settings_access_users_approved = $( '#list_auth_settings_access_users_approved' ).closest( 'tr' );
653 var auth_settings_access_users_blocked = $( '#list_auth_settings_access_users_blocked' ).closest( 'tr' );
654 var auth_settings_access_role_receive_pending_emails = $( '#auth_settings_access_role_receive_pending_emails' ).closest( 'tr' );
655 var auth_settings_access_pending_redirect_to_message = $( '#wp-auth_settings_access_pending_redirect_to_message-wrap' ).closest( 'tr' );
656 var auth_settings_access_blocked_redirect_to_message = $( '#wp-auth_settings_access_blocked_redirect_to_message-wrap' ).closest( 'tr' );
657 var auth_settings_access_should_email_approved_users = $( '#auth_settings_access_should_email_approved_users' ).closest( 'tr' );
658 var auth_settings_access_email_approved_users_subject = $( '#auth_settings_access_email_approved_users_subject' ).closest( 'tr' );
659 var auth_settings_access_email_approved_users_body = $( '#wp-auth_settings_access_email_approved_users_body-wrap' ).closest( 'tr' );
660 var auth_settings_access_public_pages = $( '#auth_settings_access_public_pages' ).closest( 'tr' );
661 var auth_settings_access_redirect_to_login = $( '#radio_auth_settings_access_redirect_to_login' ).closest( 'tr' );
662 var auth_settings_access_public_warning = $( '#radio_auth_settings_access_public_warning' ).closest( 'tr' );
663 var auth_settings_access_redirect_to_message = $( '#wp-auth_settings_access_redirect_to_message-wrap' ).closest( 'tr' );
664 var auth_settings_external_settings_table = $( '#auth_settings_google' ).closest( 'table' );
665 var auth_settings_external_google = $( '#auth_settings_google' ).closest( 'tr' );
666 var auth_settings_external_google_clientid = $( '#auth_settings_google_clientid' ).closest( 'tr' );
667 var auth_settings_external_google_clientsecret = $( '#auth_settings_google_clientsecret' ).closest( 'tr' );
668 var auth_settings_external_cas = $( '#auth_settings_cas' ).closest( 'tr' );
669 var auth_settings_external_cas_custom_label = $( '#auth_settings_cas_custom_label' ).closest( 'tr' );
670 var auth_settings_external_cas_host = $( '#auth_settings_cas_host' ).closest( 'tr' );
671 var auth_settings_external_cas_port = $( '#auth_settings_cas_port' ).closest( 'tr' );
672 var auth_settings_external_cas_path = $( '#auth_settings_cas_path' ).closest( 'tr' );
673 var auth_settings_external_cas_version = $( '#auth_settings_cas_version' ).closest( 'tr' );
674 var auth_settings_external_cas_attr_email = $( '#auth_settings_cas_attr_email' ).closest( 'tr' );
675 var auth_settings_external_cas_attr_first_name = $( '#auth_settings_cas_attr_first_name' ).closest( 'tr' );
676 var auth_settings_external_cas_attr_last_name = $( '#auth_settings_cas_attr_last_name' ).closest( 'tr' );
677 var auth_settings_external_cas_attr_update_on_login = $( '#auth_settings_cas_attr_update_on_login' ).closest( 'tr' );
678 var auth_settings_external_cas_auto_login = $( '#auth_settings_cas_auto_login' ).closest( 'tr' );
679 var auth_settings_external_ldap = $( '#auth_settings_ldap' ).closest( 'tr' );
680 var auth_settings_external_ldap_host = $( '#auth_settings_ldap_host' ).closest( 'tr' );
681 var auth_settings_external_ldap_port = $( '#auth_settings_ldap_port' ).closest( 'tr' );
682 var auth_settings_external_ldap_search_base = $( '#auth_settings_ldap_search_base' ).closest( 'tr' );
683 var auth_settings_external_ldap_uid = $( '#auth_settings_ldap_uid' ).closest( 'tr' );
684 var auth_settings_external_ldap_attr_email = $( '#auth_settings_ldap_attr_email' ).closest( 'tr' );
685 var auth_settings_external_ldap_user = $( '#auth_settings_ldap_user' ).closest( 'tr' );
686 var auth_settings_external_ldap_password = $( '#auth_settings_ldap_password' ).closest( 'tr' );
687 var auth_settings_external_ldap_tls = $( '#auth_settings_ldap_tls' ).closest( 'tr' );
688 var auth_settings_external_ldap_lostpassword_url = $( '#auth_settings_ldap_lostpassword_url' ).closest( 'tr' );
689 var auth_settings_external_ldap_attr_first_name = $( '#auth_settings_ldap_attr_first_name' ).closest( 'tr' );
690 var auth_settings_external_ldap_attr_last_name = $( '#auth_settings_ldap_attr_last_name' ).closest( 'tr' );
691 var auth_settings_external_ldap_attr_update_on_login = $( '#auth_settings_ldap_attr_update_on_login' ).closest( 'tr' );
692
693 // Wrap the th and td in the rows above so we can animate their heights (can't animate tr heights with jquery)
694 $( 'th, td', auth_settings_access_users_pending ).wrapInner( '<div class="animated_wrapper" />' );
695 $( 'th, td', auth_settings_access_users_approved ).wrapInner( '<div class="animated_wrapper" />' );
696 $( 'th, td', auth_settings_access_users_blocked ).wrapInner( '<div class="animated_wrapper" />' );
697 $( 'th, td', auth_settings_access_role_receive_pending_emails ).wrapInner( '<div class="animated_wrapper" />' );
698 $( 'th, td', auth_settings_access_pending_redirect_to_message ).wrapInner( '<div class="animated_wrapper" />' );
699 $( 'th, td', auth_settings_access_blocked_redirect_to_message ).wrapInner( '<div class="animated_wrapper" />' );
700 $( 'th, td', auth_settings_access_should_email_approved_users ).wrapInner( '<div class="animated_wrapper" />' );
701 $( 'th, td', auth_settings_access_email_approved_users_subject ).wrapInner( '<div class="animated_wrapper" />' );
702 $( 'th, td', auth_settings_access_email_approved_users_body ).wrapInner( '<div class="animated_wrapper" />' );
703 $( 'th, td', auth_settings_access_public_pages ).wrapInner( '<div class="animated_wrapper" />' );
704 $( 'th, td', auth_settings_access_redirect_to_login ).wrapInner( '<div class="animated_wrapper" />' );
705 $( 'th, td', auth_settings_access_public_warning ).wrapInner( '<div class="animated_wrapper" />' );
706 $( 'th, td', auth_settings_access_redirect_to_message ).wrapInner( '<div class="animated_wrapper" />' );
707 $( 'th, td', auth_settings_external_google_clientid ).wrapInner( '<div class="animated_wrapper" />' );
708 $( 'th, td', auth_settings_external_google_clientsecret ).wrapInner( '<div class="animated_wrapper" />' );
709 $( 'th, td', auth_settings_external_cas_custom_label ).wrapInner( '<div class="animated_wrapper" />' );
710 $( 'th, td', auth_settings_external_cas_host ).wrapInner( '<div class="animated_wrapper" />' );
711 $( 'th, td', auth_settings_external_cas_port ).wrapInner( '<div class="animated_wrapper" />' );
712 $( 'th, td', auth_settings_external_cas_path ).wrapInner( '<div class="animated_wrapper" />' );
713 $( 'th, td', auth_settings_external_cas_version ).wrapInner( '<div class="animated_wrapper" />' );
714 $( 'th, td', auth_settings_external_cas_attr_email ).wrapInner( '<div class="animated_wrapper" />' );
715 $( 'th, td', auth_settings_external_cas_attr_first_name ).wrapInner( '<div class="animated_wrapper" />' );
716 $( 'th, td', auth_settings_external_cas_attr_last_name ).wrapInner( '<div class="animated_wrapper" />' );
717 $( 'th, td', auth_settings_external_cas_attr_update_on_login ).wrapInner( '<div class="animated_wrapper" />' );
718 $( 'th, td', auth_settings_external_cas_auto_login ).wrapInner( '<div class="animated_wrapper" />' );
719 $( 'th, td', auth_settings_external_ldap_host ).wrapInner( '<div class="animated_wrapper" />' );
720 $( 'th, td', auth_settings_external_ldap_port ).wrapInner( '<div class="animated_wrapper" />' );
721 $( 'th, td', auth_settings_external_ldap_search_base ).wrapInner( '<div class="animated_wrapper" />' );
722 $( 'th, td', auth_settings_external_ldap_uid ).wrapInner( '<div class="animated_wrapper" />' );
723 $( 'th, td', auth_settings_external_ldap_attr_email ).wrapInner( '<div class="animated_wrapper" />' );
724 $( 'th, td', auth_settings_external_ldap_user ).wrapInner( '<div class="animated_wrapper" />' );
725 $( 'th, td', auth_settings_external_ldap_password ).wrapInner( '<div class="animated_wrapper" />' );
726 $( 'th, td', auth_settings_external_ldap_tls ).wrapInner( '<div class="animated_wrapper" />' );
727 $( 'th, td', auth_settings_external_ldap_lostpassword_url ).wrapInner( '<div class="animated_wrapper" />' );
728 $( 'th, td', auth_settings_external_ldap_attr_first_name ).wrapInner( '<div class="animated_wrapper" />' );
729 $( 'th, td', auth_settings_external_ldap_attr_last_name ).wrapInner( '<div class="animated_wrapper" />' );
730 $( 'th, td', auth_settings_external_ldap_attr_update_on_login ).wrapInner( '<div class="animated_wrapper" />' );
731
732 // If we're viewing the dashboard widget, reset a couple of the relevant
733 // option variables (since they're aren't nested in table rows).
734 if ( $( '#auth_dashboard_widget' ).length ) {
735 auth_settings_access_users_pending = $( '#list_auth_settings_access_users_pending' ).closest( 'div' );
736 auth_settings_access_users_approved = $( '#list_auth_settings_access_users_approved' ).closest( 'div' );
737 auth_settings_access_users_blocked = $( '#list_auth_settings_access_users_blocked' ).closest( 'div' );
738 $( auth_settings_access_users_pending ).wrapInner( '<div class="animated_wrapper" />' );
739 $( auth_settings_access_users_approved ).wrapInner( '<div class="animated_wrapper" />' );
740 $( auth_settings_access_users_blocked ).wrapInner( '<div class="animated_wrapper" />' );
741
742 // Remove the helper link, since there are no tabs on the dashboard widget
743 $( '#dashboard_link_approved_users' ).contents().unwrap();
744 }
745
746 // Hide Welcome email body/subject options if "Send welcome email" is off.
747 if ( ! $( '#auth_settings_access_should_email_approved_users' ).is( ':checked' ) ) {
748 animate_option( 'hide_immediately', auth_settings_access_email_approved_users_subject );
749 animate_option( 'hide_immediately', auth_settings_access_email_approved_users_body );
750 }
751
752 // On load: Show/hide public access options if everyone can see site
753 if ( ! $( '#radio_auth_settings_access_who_can_view_logged_in_users' ).is( ':checked' ) ) {
754 animate_option( 'hide_immediately', auth_settings_access_public_pages );
755 animate_option( 'hide_immediately', auth_settings_access_redirect_to_login );
756 animate_option( 'hide_immediately', auth_settings_access_public_warning );
757 animate_option( 'hide_immediately', auth_settings_access_redirect_to_message );
758 }
759
760 // Hide Google options if unchecked
761 if ( ! $( '#auth_settings_google' ).is( ':checked' ) ) {
762 animate_option( 'hide_immediately', auth_settings_external_google_clientid );
763 animate_option( 'hide_immediately', auth_settings_external_google_clientsecret );
764 }
765
766 // Hide CAS options if unchecked
767 if ( ! $( '#auth_settings_cas' ).is( ':checked' ) ) {
768 animate_option( 'hide_immediately', auth_settings_external_cas_custom_label );
769 animate_option( 'hide_immediately', auth_settings_external_cas_host );
770 animate_option( 'hide_immediately', auth_settings_external_cas_port );
771 animate_option( 'hide_immediately', auth_settings_external_cas_path );
772 animate_option( 'hide_immediately', auth_settings_external_cas_version );
773 animate_option( 'hide_immediately', auth_settings_external_cas_attr_email );
774 animate_option( 'hide_immediately', auth_settings_external_cas_attr_first_name );
775 animate_option( 'hide_immediately', auth_settings_external_cas_attr_last_name );
776 animate_option( 'hide_immediately', auth_settings_external_cas_attr_update_on_login );
777 animate_option( 'hide_immediately', auth_settings_external_cas_auto_login );
778 }
779
780 // Hide LDAP options if unchecked
781 if ( ! $( '#auth_settings_ldap' ).is( ':checked' ) ) {
782 animate_option( 'hide_immediately', auth_settings_external_ldap_host );
783 animate_option( 'hide_immediately', auth_settings_external_ldap_port );
784 animate_option( 'hide_immediately', auth_settings_external_ldap_search_base );
785 animate_option( 'hide_immediately', auth_settings_external_ldap_uid );
786 animate_option( 'hide_immediately', auth_settings_external_ldap_attr_email );
787 animate_option( 'hide_immediately', auth_settings_external_ldap_user );
788 animate_option( 'hide_immediately', auth_settings_external_ldap_password );
789 animate_option( 'hide_immediately', auth_settings_external_ldap_tls );
790 animate_option( 'hide_immediately', auth_settings_external_ldap_lostpassword_url );
791 animate_option( 'hide_immediately', auth_settings_external_ldap_attr_first_name );
792 animate_option( 'hide_immediately', auth_settings_external_ldap_attr_last_name );
793 animate_option( 'hide_immediately', auth_settings_external_ldap_attr_update_on_login );
794 }
795
796 // Event handler: Hide "Handle unauthorized visitors" option if access is granted to "Everyone"
797 $( 'input[name="auth_settings[access_who_can_login]"]' ).change( function() {
798 // Hide user whitelist unless "Only specific students below" is checked
799 var action = $( '#radio_auth_settings_access_who_can_login_approved_users' ).is( ':checked' ) ? 'show' : 'hide';
800 animate_option( action, auth_settings_access_role_receive_pending_emails );
801 animate_option( action, auth_settings_access_pending_redirect_to_message );
802 animate_option( action, auth_settings_access_blocked_redirect_to_message );
803 animate_option( action, auth_settings_access_should_email_approved_users );
804 animate_option( action, auth_settings_access_email_approved_users_subject );
805 animate_option( action, auth_settings_access_email_approved_users_body );
806 });
807
808 // Event handler: Hide Welcome email body/subject options if "Send welcome email" is off.
809 $( 'input[name="auth_settings[access_should_email_approved_users]"]' ).change( function() {
810 var action = $( this ).is( ':checked' ) ? 'show' : 'hide';
811 animate_option( action, auth_settings_access_email_approved_users_subject );
812 animate_option( action, auth_settings_access_email_approved_users_body );
813 });
814
815 // Event handler: Hide "Handle unauthorized visitors" option if access is granted to "Everyone"
816 $( 'input[name="auth_settings[access_who_can_view]"]' ).change( function() {
817 var action = $( '#radio_auth_settings_access_who_can_view_everyone' ).is( ':checked' ) ? 'hide' : 'show';
818 animate_option( action, auth_settings_access_redirect_to_login );
819 animate_option( action, auth_settings_access_redirect_to_message );
820 animate_option( action, auth_settings_access_public_pages );
821 animate_option( action, auth_settings_access_public_warning );
822 });
823
824 // Event handler: Show/hide Google options based on checkbox
825 $( 'input[name="auth_settings[google]"]' ).change( function() {
826 var action = $( this ).is( ':checked' ) ? 'show' : 'hide';
827 animate_option( action, auth_settings_external_google_clientid );
828 animate_option( action, auth_settings_external_google_clientsecret );
829 });
830
831 // Event handler: Show/hide CAS options based on checkbox
832 $( 'input[name="auth_settings[cas]"]' ).change( function() {
833 var action = $( this ).is( ':checked' ) ? 'show' : 'hide';
834 animate_option( action, auth_settings_external_cas_custom_label );
835 animate_option( action, auth_settings_external_cas_host );
836 animate_option( action, auth_settings_external_cas_port );
837 animate_option( action, auth_settings_external_cas_path );
838 animate_option( action, auth_settings_external_cas_version );
839 animate_option( action, auth_settings_external_cas_attr_email );
840 animate_option( action, auth_settings_external_cas_attr_first_name );
841 animate_option( action, auth_settings_external_cas_attr_last_name );
842 animate_option( action, auth_settings_external_cas_attr_update_on_login );
843 animate_option( action, auth_settings_external_cas_auto_login );
844 });
845
846 // Event handler: Show/hide LDAP options based on checkbox
847 $( 'input[name="auth_settings[ldap]"]' ).change( function() {
848 var action = $( this ).is( ':checked' ) ? 'show' : 'hide';
849 animate_option( action, auth_settings_external_ldap_host );
850 animate_option( action, auth_settings_external_ldap_port );
851 animate_option( action, auth_settings_external_ldap_search_base );
852 animate_option( action, auth_settings_external_ldap_uid );
853 animate_option( action, auth_settings_external_ldap_attr_email );
854 animate_option( action, auth_settings_external_ldap_user );
855 animate_option( action, auth_settings_external_ldap_password );
856 animate_option( action, auth_settings_external_ldap_tls );
857 animate_option( action, auth_settings_external_ldap_lostpassword_url );
858 animate_option( action, auth_settings_external_ldap_attr_first_name );
859 animate_option( action, auth_settings_external_ldap_attr_last_name );
860 animate_option( action, auth_settings_external_ldap_attr_update_on_login );
861 });
862
863 // Show save button if usermeta field is modified.
864 $( 'form input.auth-usermeta' ).bind( 'keyup', function ( event ) {
865 // Don't do anything if tab or arrow keys were pressed.
866 if ( event.which === 9 || event.which === 37 || event.which === 38 || event.which === 39 || event.which === 40 ) {
867 return;
868 }
869 $( this ).siblings( '.button' ).css( 'display', 'inline-block' );
870 });
871
872 // List management function: pressing enter in the new approved or new
873 // blocked user (email or role field) adds the user to the list.
874 $( '#new_approved_user_email, #new_approved_user_role, #new_blocked_user_email' ).bind( 'keyup', function( e ) {
875 if ( e.which == 13 ) { // Enter key
876 $( this ).parent().find( 'a' ).trigger( 'click' );
877 return false;
878 }
879 });
880
881 // Don't submit form (i.e., save options) when hitting enter in any user list field.
882 $( 'input.auth-email, select.auth-role, input.auth-date-added, input.auth-usermeta' ).bind( 'keydown', function( e ) {
883 if ( e.which == 13 ) { // Enter key
884 e.preventDefault();
885 return false;
886 }
887 });
888
889 // Enable the user-friendly multiselect form element on the options page.
890 $( '#auth_settings_access_public_pages' ).multiSelect({
891 selectableOptgroup: true,
892 selectableHeader: '<div class="custom-header">' + auth_L10n.private_pages + '</div>',
893 selectionHeader: '<div class="custom-header">' + auth_L10n.public_pages + '</div>',
894 });
895
896 // Switch to the first tab (or the tab indicated in sessionStorage, or the querystring).
897 var tab = '';
898 if ( querystring( 'tab' ).length > 0 ) {
899 tab = querystring( 'tab' )[0];
900 } else if ( sessionStorage.getItem( 'tab' ) ) {
901 tab = sessionStorage.getItem( 'tab' );
902 }
903 if ( $.inArray( tab, [ 'access_lists', 'access_login', 'access_public', 'external', 'advanced' ] ) < 0 ) {
904 tab = 'access_lists';
905 }
906 choose_tab( tab, animation_speed );
907
908 // Hide/show multisite settings based on override checkbox.
909 $( 'input[name="auth_settings[multisite_override]"]' ).change( function() {
910 hide_multisite_settings_if_disabled();
911 });
912 hide_multisite_settings_if_disabled();
913
914 });
915
916
917 /**
918 * Portions below from Bootstrap
919 * http://getbootstrap.com/getting-started/#download
920 */
921
922
923 /*!
924 * Bootstrap v3.1.1 (http://getbootstrap.com)
925 * Copyright 2011-2014 Twitter, Inc.
926 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
927 */
928
929 if ( typeof jQuery === 'undefined' ) { throw new Error( 'Bootstrap\'s JavaScript requires jQuery' ) }
930
931 /* ========================================================================
932 * Bootstrap: dropdown.js v3.1.1
933 * http://getbootstrap.com/javascript/#dropdowns
934 * ========================================================================
935 * Copyright 2011-2014 Twitter, Inc.
936 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
937 * ======================================================================== */
938
939
940 +function ($) {
941 'use strict';
942
943 // DROPDOWN CLASS DEFINITION
944 // =========================
945
946 var backdrop = '.dropdown-backdrop'
947 var toggle = '[data-toggle=dropdown]'
948 var Dropdown = function ( element ) {
949 $( element ).on( 'click.bs.dropdown', this.toggle)
950 }
951
952 Dropdown.prototype.toggle = function ( e ) {
953 var $this = $( this )
954
955 if ($this.is( '.disabled, :disabled' )) return
956
957 var $parent = getParent($this)
958 var isActive = $parent.hasClass( 'open' )
959
960 clearMenus()
961
962 if (!isActive) {
963 if ( 'ontouchstart' in document.documentElement && !$parent.closest( '.navbar-nav' ).length) {
964 // if mobile we use a backdrop because click events don't delegate
965 $( '<div class="dropdown-backdrop"/>' ).insertAfter($( this )).on( 'click', clearMenus)
966 }
967
968 var relatedTarget = { relatedTarget: this }
969 $parent.trigger( e = $.Event( 'show.bs.dropdown', relatedTarget ) )
970
971 if (e.isDefaultPrevented()) return
972
973 $parent
974 .toggleClass( 'open' )
975 .trigger( 'shown.bs.dropdown', relatedTarget)
976
977 $this.focus()
978 }
979
980 return false
981 }
982
983 Dropdown.prototype.keydown = function (e) {
984 if (!/(38|40|27)/.test(e.keyCode)) return
985
986 var $this = $( this )
987
988 e.preventDefault()
989 e.stopPropagation()
990
991 if ($this.is( '.disabled, :disabled' )) return
992
993 var $parent = getParent($this)
994 var isActive = $parent.hasClass( 'open' )
995
996 if (!isActive || (isActive && e.keyCode == 27)) {
997 if (e.which == 27) $parent.find(toggle).focus()
998 return $this.click()
999 }
1000
1001 var desc = ' li:not(.divider):visible a'
1002 var $items = $parent.find( '[role=menu]' + desc + ', [role=listbox]' + desc)
1003
1004 if (!$items.length) return
1005
1006 var index = $items.index($items.filter( ':focus' ))
1007
1008 if (e.keyCode == 38 && index > 0) index-- // up
1009 if (e.keyCode == 40 && index < $items.length - 1) index++ // down
1010 if (!~index) index = 0
1011
1012 $items.eq(index).focus()
1013 }
1014
1015 function clearMenus(e) {
1016 $(backdrop).remove()
1017 $(toggle).each(function () {
1018 var $parent = getParent($( this ))
1019 var relatedTarget = { relatedTarget: this }
1020 if (!$parent.hasClass( 'open' )) return
1021 $parent.trigger(e = $.Event( 'hide.bs.dropdown', relatedTarget))
1022 if (e.isDefaultPrevented()) return
1023 $parent.removeClass( 'open' ).trigger( 'hidden.bs.dropdown', relatedTarget)
1024 })
1025 }
1026
1027 function getParent($this) {
1028 var selector = $this.attr( 'data-target' )
1029
1030 if (!selector) {
1031 selector = $this.attr( 'href' )
1032 selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '' ) //strip for ie7
1033 }
1034
1035 var $parent = selector && $(selector)
1036
1037 return $parent && $parent.length ? $parent : $this.parent()
1038 }
1039
1040
1041 // DROPDOWN PLUGIN DEFINITION
1042 // ==========================
1043
1044 var old = $.fn.dropdown
1045
1046 $.fn.dropdown = function (option) {
1047 return this.each(function () {
1048 var $this = $( this )
1049 var data = $this.data( 'bs.dropdown' )
1050
1051 if (!data) $this.data( 'bs.dropdown', (data = new Dropdown( this )))
1052 if (typeof option == 'string' ) data[option].call($this)
1053 })
1054 }
1055
1056 $.fn.dropdown.Constructor = Dropdown
1057
1058
1059 // DROPDOWN NO CONFLICT
1060 // ====================
1061
1062 $.fn.dropdown.noConflict = function () {
1063 $.fn.dropdown = old
1064 return this
1065 }
1066
1067
1068 // APPLY TO STANDARD DROPDOWN ELEMENTS
1069 // ===================================
1070
1071 $(document)
1072 .on( 'click.bs.dropdown.data-api', clearMenus)
1073 .on( 'click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
1074 .on( 'click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
1075 .on( 'keydown.bs.dropdown.data-api', toggle + ', [role=menu], [role=listbox]', Dropdown.prototype.keydown)
1076
1077 }(jQuery);
1078