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


Generated: Sun Feb 28 01:00:03 2021 Cross-referenced by PHPXref 0.7.1