[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-admin/js/ -> user-profile.js (source)

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


Generated: Wed Sep 18 01:00:03 2019 Cross-referenced by PHPXref 0.7.1