]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-admin/js/user-profile.js
WordPress 4.3.1
[autoinstalls/wordpress.git] / wp-admin / js / user-profile.js
1 /* global ajaxurl, pwsL10n, userProfileL10n */
2 (function($) {
3         var updateLock = false,
4
5                 $pass1Row,
6                 $pass1Wrap,
7                 $pass1,
8                 $pass1Text,
9                 $pass1Label,
10                 $pass2,
11                 $weakRow,
12                 $weakCheckbox,
13                 $toggleButton,
14                 $submitButtons,
15                 $submitButton,
16                 currentPass,
17                 inputEvent;
18
19         /*
20          * Use feature detection to determine whether password inputs should use
21          * the `keyup` or `input` event. Input is preferred but lacks support
22          * in legacy browsers.
23          */
24         if ( 'oninput' in document.createElement( 'input' ) ) {
25                 inputEvent = 'input';
26         } else {
27                 inputEvent = 'keyup';
28         }
29
30         function generatePassword() {
31                 if ( typeof zxcvbn !== 'function' ) {
32                         setTimeout( generatePassword, 50 );
33                 } else {
34                         $pass1.val( $pass1.data( 'pw' ) );
35                         $pass1.trigger( 'pwupdate' ).trigger( 'wp-check-valid-field' );
36                         if ( 1 !== parseInt( $toggleButton.data( 'start-masked' ), 10 ) ) {
37                                 $pass1Wrap.addClass( 'show-password' );
38                         } else {
39                                 $toggleButton.trigger( 'click' );
40                         }
41                 }
42         }
43
44         function bindPass1() {
45                 var passStrength = $('#pass-strength-result')[0];
46
47                 currentPass = $pass1.val();
48
49                 $pass1Wrap = $pass1.parent();
50
51                 $pass1Text = $( '<input type="text"/>' )
52                         .attr( {
53                                 'id':           'pass1-text',
54                                 'name':         'pass1-text',
55                                 'autocomplete': 'off'
56                         } )
57                         .addClass( $pass1[0].className )
58                         .data( 'pw', $pass1.data( 'pw' ) )
59                         .val( $pass1.val() )
60                         .on( inputEvent, function () {
61                                 if ( $pass1Text.val() === currentPass ) {
62                                         return;
63                                 }
64                                 $pass2.val( $pass1Text.val() );
65                                 $pass1.val( $pass1Text.val() ).trigger( 'pwupdate' );
66                                 currentPass = $pass1Text.val();
67                         } );
68
69                 $pass1.after( $pass1Text );
70
71                 if ( 1 === parseInt( $pass1.data( 'reveal' ), 10 ) ) {
72                         generatePassword();
73                 }
74
75                 $pass1.on( inputEvent + ' pwupdate', function () {
76                         if ( $pass1.val() === currentPass ) {
77                                 return;
78                         }
79
80                         currentPass = $pass1.val();
81                         if ( $pass1Text.val() !== currentPass ) {
82                                 $pass1Text.val( currentPass );
83                         }
84                         $pass1.add( $pass1Text ).removeClass( 'short bad good strong' );
85
86                         if ( passStrength.className ) {
87                                 $pass1.add( $pass1Text ).addClass( passStrength.className );
88                                 if ( 'short' === passStrength.className || 'bad' === passStrength.className ) {
89                                         if ( ! $weakCheckbox.prop( 'checked' ) ) {
90                                                 $submitButtons.prop( 'disabled', true );
91                                         }
92                                         $weakRow.show();
93                                 } else {
94                                         $submitButtons.prop( 'disabled', false );
95                                         $weakRow.hide();
96                                 }
97                         }
98                 } );
99         }
100
101         function bindToggleButton() {
102                 $toggleButton = $pass1Row.find('.wp-hide-pw');
103                 $toggleButton.show().on( 'click', function () {
104                         if ( 1 === parseInt( $toggleButton.data( 'toggle' ), 10 ) ) {
105                                 $pass1Wrap.addClass( 'show-password' );
106                                 $toggleButton
107                                         .data( 'toggle', 0 )
108                                         .attr({
109                                                 'aria-label': userProfileL10n.ariaHide
110                                         })
111                                         .find( '.text' )
112                                                 .text( userProfileL10n.hide )
113                                         .end()
114                                         .find( '.dashicons' )
115                                                 .removeClass('dashicons-visibility')
116                                                 .addClass('dashicons-hidden');
117
118                                 $pass1Text.focus();
119
120                                 $pass1Label.attr( 'for', 'pass1-text' );
121
122                                 if ( ! _.isUndefined( $pass1Text[0].setSelectionRange ) ) {
123                                         $pass1Text[0].setSelectionRange( 0, 100 );
124                                 }
125                         } else {
126                                 $pass1Wrap.removeClass( 'show-password' );
127                                 $toggleButton
128                                         .data( 'toggle', 1 )
129                                         .attr({
130                                                 'aria-label': userProfileL10n.ariaShow
131                                         })
132                                         .find( '.text' )
133                                                 .text( userProfileL10n.show )
134                                         .end()
135                                         .find( '.dashicons' )
136                                                 .removeClass('dashicons-hidden')
137                                                 .addClass('dashicons-visibility');
138
139                                 $pass1.focus();
140
141                                 $pass1Label.attr( 'for', 'pass1' );
142
143                                 if ( ! _.isUndefined( $pass1[0].setSelectionRange ) ) {
144                                         $pass1[0].setSelectionRange( 0, 100 );
145                                 }
146                         }
147                 });
148         }
149
150         function bindPasswordForm() {
151                 var $passwordWrapper,
152                         $generateButton,
153                         $cancelButton;
154
155                 $pass1Row = $('.user-pass1-wrap');
156                 $pass1Label = $pass1Row.find('th label').attr( 'for', 'pass1-text' );
157
158                 // hide this
159                 $('.user-pass2-wrap').hide();
160
161                 $submitButton = $( '#submit' ).on( 'click', function () {
162                         updateLock = false;
163                 });
164
165                 $submitButtons = $submitButton.add( ' #createusersub' );
166
167                 $weakRow = $( '.pw-weak' );
168                 $weakCheckbox = $weakRow.find( '.pw-checkbox' );
169                 $weakCheckbox.change( function() {
170                         $submitButtons.prop( 'disabled', ! $weakCheckbox.prop( 'checked' ) );
171                 } );
172
173                 $pass1 = $('#pass1');
174                 if ( $pass1.length ) {
175                         bindPass1();
176                 }
177
178                 /**
179                  * Fix a LastPass mismatch issue, LastPass only changes pass2.
180                  *
181                  * This fixes the issue by copying any changes from the hidden
182                  * pass2 field to the pass1 field, then running check_pass_strength.
183                  */
184                 $pass2 = $('#pass2').on( inputEvent, function () {
185                         if ( $pass2.val().length > 0 ) {
186                                 $pass1.val( $pass2.val() );
187                                 $pass2.val('');
188                                 currentPass = '';
189                                 $pass1.trigger( 'pwupdate' );
190                         }
191                 } );
192
193                 $passwordWrapper = $pass1Row.find('.wp-pwd').hide();
194
195                 bindToggleButton();
196
197                 $generateButton = $pass1Row.find( 'button.wp-generate-pw' ).show();
198                 $generateButton.on( 'click', function () {
199                         updateLock = true;
200
201                         $generateButton.hide();
202                         $passwordWrapper.show();
203
204                         if ( $pass1Text.val().length === 0 ) {
205                                 generatePassword();
206                         }
207
208                         _.defer( function() {
209                                 $pass1Text.focus();
210                                 if ( ! _.isUndefined( $pass1Text[0].setSelectionRange ) ) {
211                                         $pass1Text[0].setSelectionRange( 0, 100 );
212                                 }
213                         }, 0 );
214                 } );
215
216                 $cancelButton = $pass1Row.find( 'button.wp-cancel-pw' );
217                 $cancelButton.on( 'click', function () {
218                         updateLock = false;
219
220                         $generateButton.show();
221                         $passwordWrapper.hide();
222
223                         // Clear password field to prevent update
224                         $pass1.val( '' ).trigger( 'pwupdate' );
225                         $submitButtons.prop( 'disabled', false );
226                 } );
227
228                 $pass1Row.closest('form').on( 'submit', function () {
229                         updateLock = false;
230
231                         $pass2.val( $pass1.val() );
232                         $pass1Wrap.removeClass( 'show-password' );
233                 });
234         }
235
236         function check_pass_strength() {
237                 var pass1 = $('#pass1').val(), strength;
238
239                 $('#pass-strength-result').removeClass('short bad good strong');
240                 if ( ! pass1 ) {
241                         $('#pass-strength-result').html( '&nbsp;' );
242                         return;
243                 }
244
245                 strength = wp.passwordStrength.meter( pass1, wp.passwordStrength.userInputBlacklist(), pass1 );
246
247                 switch ( strength ) {
248                         case 2:
249                                 $('#pass-strength-result').addClass('bad').html( pwsL10n.bad );
250                                 break;
251                         case 3:
252                                 $('#pass-strength-result').addClass('good').html( pwsL10n.good );
253                                 break;
254                         case 4:
255                                 $('#pass-strength-result').addClass('strong').html( pwsL10n.strong );
256                                 break;
257                         case 5:
258                                 $('#pass-strength-result').addClass('short').html( pwsL10n.mismatch );
259                                 break;
260                         default:
261                                 $('#pass-strength-result').addClass('short').html( pwsL10n['short'] );
262                 }
263         }
264
265         $(document).ready( function() {
266                 var $colorpicker, $stylesheet, user_id, current_user_id,
267                         select = $( '#display_name' );
268
269                 $('#pass1').val('').on( inputEvent + ' pwupdate', check_pass_strength );
270                 $('#pass-strength-result').show();
271                 $('.color-palette').click( function() {
272                         $(this).siblings('input[name="admin_color"]').prop('checked', true);
273                 });
274
275                 if ( select.length ) {
276                         $('#first_name, #last_name, #nickname').bind( 'blur.user_profile', function() {
277                                 var dub = [],
278                                         inputs = {
279                                                 display_nickname  : $('#nickname').val() || '',
280                                                 display_username  : $('#user_login').val() || '',
281                                                 display_firstname : $('#first_name').val() || '',
282                                                 display_lastname  : $('#last_name').val() || ''
283                                         };
284
285                                 if ( inputs.display_firstname && inputs.display_lastname ) {
286                                         inputs.display_firstlast = inputs.display_firstname + ' ' + inputs.display_lastname;
287                                         inputs.display_lastfirst = inputs.display_lastname + ' ' + inputs.display_firstname;
288                                 }
289
290                                 $.each( $('option', select), function( i, el ){
291                                         dub.push( el.value );
292                                 });
293
294                                 $.each(inputs, function( id, value ) {
295                                         if ( ! value ) {
296                                                 return;
297                                         }
298
299                                         var val = value.replace(/<\/?[a-z][^>]*>/gi, '');
300
301                                         if ( inputs[id].length && $.inArray( val, dub ) === -1 ) {
302                                                 dub.push(val);
303                                                 $('<option />', {
304                                                         'text': val
305                                                 }).appendTo( select );
306                                         }
307                                 });
308                         });
309                 }
310
311                 $colorpicker = $( '#color-picker' );
312                 $stylesheet = $( '#colors-css' );
313                 user_id = $( 'input#user_id' ).val();
314                 current_user_id = $( 'input[name="checkuser_id"]' ).val();
315
316                 $colorpicker.on( 'click.colorpicker', '.color-option', function() {
317                         var colors,
318                                 $this = $(this);
319
320                         if ( $this.hasClass( 'selected' ) ) {
321                                 return;
322                         }
323
324                         $this.siblings( '.selected' ).removeClass( 'selected' );
325                         $this.addClass( 'selected' ).find( 'input[type="radio"]' ).prop( 'checked', true );
326
327                         // Set color scheme
328                         if ( user_id === current_user_id ) {
329                                 // Load the colors stylesheet.
330                                 // The default color scheme won't have one, so we'll need to create an element.
331                                 if ( 0 === $stylesheet.length ) {
332                                         $stylesheet = $( '<link rel="stylesheet" />' ).appendTo( 'head' );
333                                 }
334                                 $stylesheet.attr( 'href', $this.children( '.css_url' ).val() );
335
336                                 // repaint icons
337                                 if ( typeof wp !== 'undefined' && wp.svgPainter ) {
338                                         try {
339                                                 colors = $.parseJSON( $this.children( '.icon_colors' ).val() );
340                                         } catch ( error ) {}
341
342                                         if ( colors ) {
343                                                 wp.svgPainter.setColors( colors );
344                                                 wp.svgPainter.paint();
345                                         }
346                                 }
347
348                                 // update user option
349                                 $.post( ajaxurl, {
350                                         action:       'save-user-color-scheme',
351                                         color_scheme: $this.children( 'input[name="admin_color"]' ).val(),
352                                         nonce:        $('#color-nonce').val()
353                                 }).done( function( response ) {
354                                         if ( response.success ) {
355                                                 $( 'body' ).removeClass( response.data.previousScheme ).addClass( response.data.currentScheme );
356                                         }
357                                 });
358                         }
359                 });
360
361                 bindPasswordForm();
362         });
363
364         $( '#destroy-sessions' ).on( 'click', function( e ) {
365                 var $this = $(this);
366
367                 wp.ajax.post( 'destroy-sessions', {
368                         nonce: $( '#_wpnonce' ).val(),
369                         user_id: $( '#user_id' ).val()
370                 }).done( function( response ) {
371                         $this.prop( 'disabled', true );
372                         $this.siblings( '.notice' ).remove();
373                         $this.before( '<div class="notice notice-success inline"><p>' + response.message + '</p></div>' );
374                 }).fail( function( response ) {
375                         $this.siblings( '.notice' ).remove();
376                         $this.before( '<div class="notice notice-error inline"><p>' + response.message + '</p></div>' );
377                 });
378
379                 e.preventDefault();
380         });
381
382         window.generatePassword = generatePassword;
383
384         /* Warn the user if password was generated but not saved */
385         $( window ).on( 'beforeunload', function () {
386                 if ( true === updateLock ) {
387                         return userProfileL10n.warn;
388                 }
389         } );
390
391 })(jQuery);