wp/wp-admin/js/user-profile.js
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
     1 /**
     1 /**
     2  * @output wp-admin/js/user-profile.js
     2  * @output wp-admin/js/user-profile.js
     3  */
     3  */
     4 
     4 
     5 /* global ajaxurl, pwsL10n, userProfileL10n */
     5 /* global ajaxurl, pwsL10n */
     6 (function($) {
     6 (function($) {
     7 	var updateLock = false,
     7 	var updateLock = false,
     8 
     8 		__ = wp.i18n.__,
     9 		$pass1Row,
     9 		$pass1Row,
    10 		$pass1Wrap,
       
    11 		$pass1,
    10 		$pass1,
    12 		$pass1Text,
       
    13 		$pass1Label,
       
    14 		$pass2,
    11 		$pass2,
    15 		$weakRow,
    12 		$weakRow,
    16 		$weakCheckbox,
    13 		$weakCheckbox,
    17 		$toggleButton,
    14 		$toggleButton,
    18 		$submitButtons,
    15 		$submitButtons,
    34 			check_pass_strength();
    31 			check_pass_strength();
    35 			showOrHideWeakPasswordCheckbox();
    32 			showOrHideWeakPasswordCheckbox();
    36 		}
    33 		}
    37 
    34 
    38 		if ( 1 !== parseInt( $toggleButton.data( 'start-masked' ), 10 ) ) {
    35 		if ( 1 !== parseInt( $toggleButton.data( 'start-masked' ), 10 ) ) {
    39 			$pass1Wrap.addClass( 'show-password' );
    36 			$pass1.attr( 'type', 'text' );
    40 		} else {
    37 		} else {
    41 			$toggleButton.trigger( 'click' );
    38 			$toggleButton.trigger( 'click' );
    42 		}
    39 		}
    43 
    40 
    44 		// Once zxcvbn loads, passwords strength is known.
    41 		// Once zxcvbn loads, passwords strength is known.
    45 		$( '#pw-weak-text-label' ).html( userProfileL10n.warnWeak );
    42 		$( '#pw-weak-text-label' ).text( __( 'Confirm use of weak password' ) );
    46 	}
    43 	}
    47 
    44 
    48 	function bindPass1() {
    45 	function bindPass1() {
    49 		currentPass = $pass1.val();
    46 		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 
    47 
    73 		if ( 1 === parseInt( $pass1.data( 'reveal' ), 10 ) ) {
    48 		if ( 1 === parseInt( $pass1.data( 'reveal' ), 10 ) ) {
    74 			generatePassword();
    49 			generatePassword();
    75 		}
    50 		}
    76 
    51 
    78 			if ( $pass1.val() === currentPass ) {
    53 			if ( $pass1.val() === currentPass ) {
    79 				return;
    54 				return;
    80 			}
    55 			}
    81 
    56 
    82 			currentPass = $pass1.val();
    57 			currentPass = $pass1.val();
    83 			if ( $pass1Text.val() !== currentPass ) {
    58 
    84 				$pass1Text.val( currentPass );
    59 			$pass1.removeClass( 'short bad good strong' );
    85 			}
       
    86 			$pass1.add( $pass1Text ).removeClass( 'short bad good strong' );
       
    87 			showOrHideWeakPasswordCheckbox();
    60 			showOrHideWeakPasswordCheckbox();
    88 		} );
    61 		} );
    89 	}
    62 	}
    90 
    63 
    91 	function resetToggle() {
    64 	function resetToggle( show ) {
    92 		$toggleButton
    65 		$toggleButton
    93 			.data( 'toggle', 0 )
       
    94 			.attr({
    66 			.attr({
    95 				'aria-label': userProfileL10n.ariaHide
    67 				'aria-label': show ? __( 'Show password' ) : __( 'Hide password' )
    96 			})
    68 			})
    97 			.find( '.text' )
    69 			.find( '.text' )
    98 				.text( userProfileL10n.hide )
    70 				.text( show ? __( 'Show' ) : __( 'Hide' ) )
    99 			.end()
    71 			.end()
   100 			.find( '.dashicons' )
    72 			.find( '.dashicons' )
   101 				.removeClass( 'dashicons-visibility' )
    73 				.removeClass( show ? 'dashicons-hidden' : 'dashicons-visibility' )
   102 				.addClass( 'dashicons-hidden' );
    74 				.addClass( show ? 'dashicons-visibility' : 'dashicons-hidden' );
   103 
       
   104 		$pass1Text.focus();
       
   105 
       
   106 		$pass1Label.attr( 'for', 'pass1-text' );
       
   107 	}
    75 	}
   108 
    76 
   109 	function bindToggleButton() {
    77 	function bindToggleButton() {
   110 		$toggleButton = $pass1Row.find('.wp-hide-pw');
    78 		$toggleButton = $pass1Row.find('.wp-hide-pw');
   111 		$toggleButton.show().on( 'click', function () {
    79 		$toggleButton.show().on( 'click', function () {
   112 			if ( 1 === parseInt( $toggleButton.data( 'toggle' ), 10 ) ) {
    80 			if ( 'password' === $pass1.attr( 'type' ) ) {
   113 				$pass1Wrap.addClass( 'show-password' );
    81 				$pass1.attr( 'type', 'text' );
   114 
    82 				resetToggle( false );
   115 				resetToggle();
       
   116 
       
   117 				if ( ! _.isUndefined( $pass1Text[0].setSelectionRange ) ) {
       
   118 					$pass1Text[0].setSelectionRange( 0, 100 );
       
   119 				}
       
   120 			} else {
    83 			} else {
   121 				$pass1Wrap.removeClass( 'show-password' );
    84 				$pass1.attr( 'type', 'password' );
   122 				$toggleButton
    85 				resetToggle( true );
   123 					.data( 'toggle', 1 )
    86 			}
   124 					.attr({
    87 
   125 						'aria-label': userProfileL10n.ariaShow
    88 			$pass1.focus();
   126 					})
    89 
   127 					.find( '.text' )
    90 			if ( ! _.isUndefined( $pass1[0].setSelectionRange ) ) {
   128 						.text( userProfileL10n.show )
    91 				$pass1[0].setSelectionRange( 0, 100 );
   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 			}
    92 			}
   142 		});
    93 		});
   143 	}
    94 	}
   144 
    95 
   145 	function bindPasswordForm() {
    96 	function bindPasswordForm() {
   146 		var $passwordWrapper,
    97 		var $passwordWrapper,
   147 			$generateButton,
    98 			$generateButton,
   148 			$cancelButton;
    99 			$cancelButton;
   149 
   100 
   150 		$pass1Row = $('.user-pass1-wrap');
   101 		$pass1Row = $( '.user-pass1-wrap, .user-pass-wrap' );
   151 		$pass1Label = $pass1Row.find('th label').attr( 'for', 'pass1-text' );
   102 
   152 
   103 		// Hide the confirm password field when JavaScript support is enabled.
   153 		// hide this
       
   154 		$('.user-pass2-wrap').hide();
   104 		$('.user-pass2-wrap').hide();
   155 
   105 
   156 		$submitButton = $( '#submit, #wp-submit' ).on( 'click', function () {
   106 		$submitButton = $( '#submit, #wp-submit' ).on( 'click', function () {
   157 			updateLock = false;
   107 			updateLock = false;
   158 		});
   108 		});
   166 		} );
   116 		} );
   167 
   117 
   168 		$pass1 = $('#pass1');
   118 		$pass1 = $('#pass1');
   169 		if ( $pass1.length ) {
   119 		if ( $pass1.length ) {
   170 			bindPass1();
   120 			bindPass1();
       
   121 		} else {
       
   122 			// Password field for the login form.
       
   123 			$pass1 = $( '#user_pass' );
   171 		}
   124 		}
   172 
   125 
   173 		/**
   126 		/**
   174 		 * Fix a LastPass mismatch issue, LastPass only changes pass2.
   127 		 * Fix a LastPass mismatch issue, LastPass only changes pass2.
   175 		 *
   128 		 *
   187 
   140 
   188 		// Disable hidden inputs to prevent autofill and submission.
   141 		// Disable hidden inputs to prevent autofill and submission.
   189 		if ( $pass1.is( ':hidden' ) ) {
   142 		if ( $pass1.is( ':hidden' ) ) {
   190 			$pass1.prop( 'disabled', true );
   143 			$pass1.prop( 'disabled', true );
   191 			$pass2.prop( 'disabled', true );
   144 			$pass2.prop( 'disabled', true );
   192 			$pass1Text.prop( 'disabled', true );
       
   193 		}
   145 		}
   194 
   146 
   195 		$passwordWrapper = $pass1Row.find( '.wp-pwd' );
   147 		$passwordWrapper = $pass1Row.find( '.wp-pwd' );
   196 		$generateButton  = $pass1Row.find( 'button.wp-generate-pw' );
   148 		$generateButton  = $pass1Row.find( 'button.wp-generate-pw' );
   197 
   149 
   209 			$passwordWrapper.show();
   161 			$passwordWrapper.show();
   210 
   162 
   211 			// Enable the inputs when showing.
   163 			// Enable the inputs when showing.
   212 			$pass1.attr( 'disabled', false );
   164 			$pass1.attr( 'disabled', false );
   213 			$pass2.attr( 'disabled', false );
   165 			$pass2.attr( 'disabled', false );
   214 			$pass1Text.attr( 'disabled', false );
   166 
   215 
   167 			if ( $pass1.val().length === 0 ) {
   216 			if ( $pass1Text.val().length === 0 ) {
       
   217 				generatePassword();
   168 				generatePassword();
   218 			}
   169 			}
   219 
       
   220 			_.defer( function() {
       
   221 				$pass1Text.focus();
       
   222 				if ( ! _.isUndefined( $pass1Text[0].setSelectionRange ) ) {
       
   223 					$pass1Text[0].setSelectionRange( 0, 100 );
       
   224 				}
       
   225 			}, 0 );
       
   226 		} );
   170 		} );
   227 
   171 
   228 		$cancelButton = $pass1Row.find( 'button.wp-cancel-pw' );
   172 		$cancelButton = $pass1Row.find( 'button.wp-cancel-pw' );
   229 		$cancelButton.on( 'click', function () {
   173 		$cancelButton.on( 'click', function () {
   230 			updateLock = false;
   174 			updateLock = false;
   231 
   175 
   232 			// Clear any entered password.
   176 			// Clear any entered password.
   233 			$pass1Text.val( '' );
   177 			$pass1.val( '' );
   234 
   178 
   235 			// Generate a new password.
   179 			// Generate a new password.
   236 			wp.ajax.post( 'generate-password' )
   180 			wp.ajax.post( 'generate-password' )
   237 				.done( function( data ) {
   181 				.done( function( data ) {
   238 					$pass1.data( 'pw', data );
   182 					$pass1.data( 'pw', data );
   246 			} );
   190 			} );
   247 
   191 
   248 			// Disable the inputs when hiding to prevent autofill and submission.
   192 			// Disable the inputs when hiding to prevent autofill and submission.
   249 			$pass1.prop( 'disabled', true );
   193 			$pass1.prop( 'disabled', true );
   250 			$pass2.prop( 'disabled', true );
   194 			$pass2.prop( 'disabled', true );
   251 			$pass1Text.prop( 'disabled', true );
   195 
   252 
   196 			resetToggle( false );
   253 			resetToggle();
       
   254 
   197 
   255 			if ( $pass1Row.closest( 'form' ).is( '#your-profile' ) ) {
   198 			if ( $pass1Row.closest( 'form' ).is( '#your-profile' ) ) {
   256 				// Clear password field to prevent update
   199 				// Clear password field to prevent update.
   257 				$pass1.val( '' ).trigger( 'pwupdate' );
   200 				$pass1.val( '' ).trigger( 'pwupdate' );
   258 				$submitButtons.prop( 'disabled', false );
   201 				$submitButtons.prop( 'disabled', false );
   259 			}
   202 			}
   260 		} );
   203 		} );
   261 
   204 
   263 			updateLock = false;
   206 			updateLock = false;
   264 
   207 
   265 			$pass1.prop( 'disabled', false );
   208 			$pass1.prop( 'disabled', false );
   266 			$pass2.prop( 'disabled', false );
   209 			$pass2.prop( 'disabled', false );
   267 			$pass2.val( $pass1.val() );
   210 			$pass2.val( $pass1.val() );
   268 			$pass1Wrap.removeClass( 'show-password' );
       
   269 		});
   211 		});
   270 	}
   212 	}
   271 
   213 
   272 	function check_pass_strength() {
   214 	function check_pass_strength() {
   273 		var pass1 = $('#pass1').val(), strength;
   215 		var pass1 = $('#pass1').val(), strength;
   274 
   216 
   275 		$('#pass-strength-result').removeClass('short bad good strong');
   217 		$('#pass-strength-result').removeClass('short bad good strong empty');
   276 		if ( ! pass1 ) {
   218 		if ( ! pass1 ) {
   277 			$('#pass-strength-result').html( '&nbsp;' );
   219 			$( '#pass-strength-result' ).addClass( 'empty' ).html( '&nbsp;' );
   278 			return;
   220 			return;
   279 		}
   221 		}
   280 
   222 
   281 		strength = wp.passwordStrength.meter( pass1, wp.passwordStrength.userInputBlacklist(), pass1 );
   223 		strength = wp.passwordStrength.meter( pass1, wp.passwordStrength.userInputDisallowedList(), pass1 );
   282 
   224 
   283 		switch ( strength ) {
   225 		switch ( strength ) {
   284 			case -1:
   226 			case -1:
   285 				$( '#pass-strength-result' ).addClass( 'bad' ).html( pwsL10n.unknown );
   227 				$( '#pass-strength-result' ).addClass( 'bad' ).html( pwsL10n.unknown );
   286 				break;
   228 				break;
   303 
   245 
   304 	function showOrHideWeakPasswordCheckbox() {
   246 	function showOrHideWeakPasswordCheckbox() {
   305 		var passStrength = $('#pass-strength-result')[0];
   247 		var passStrength = $('#pass-strength-result')[0];
   306 
   248 
   307 		if ( passStrength.className ) {
   249 		if ( passStrength.className ) {
   308 			$pass1.add( $pass1Text ).addClass( passStrength.className );
   250 			$pass1.addClass( passStrength.className );
   309 			if ( $( passStrength ).is( '.short, .bad' ) ) {
   251 			if ( $( passStrength ).is( '.short, .bad' ) ) {
   310 				if ( ! $weakCheckbox.prop( 'checked' ) ) {
   252 				if ( ! $weakCheckbox.prop( 'checked' ) ) {
   311 					$submitButtons.prop( 'disabled', true );
   253 					$submitButtons.prop( 'disabled', true );
   312 				}
   254 				}
   313 				$weakRow.show();
   255 				$weakRow.show();
   314 			} else {
   256 			} else {
   315 				$submitButtons.prop( 'disabled', false );
   257 				if ( $( passStrength ).is( '.empty' ) ) {
       
   258 					$submitButtons.prop( 'disabled', true );
       
   259 					$weakCheckbox.prop( 'checked', false );
       
   260 				} else {
       
   261 					$submitButtons.prop( 'disabled', false );
       
   262 				}
   316 				$weakRow.hide();
   263 				$weakRow.hide();
   317 			}
   264 			}
   318 		}
   265 		}
   319 	}
   266 	}
   320 
   267 
   393 			}
   340 			}
   394 
   341 
   395 			$this.siblings( '.selected' ).removeClass( 'selected' );
   342 			$this.siblings( '.selected' ).removeClass( 'selected' );
   396 			$this.addClass( 'selected' ).find( 'input[type="radio"]' ).prop( 'checked', true );
   343 			$this.addClass( 'selected' ).find( 'input[type="radio"]' ).prop( 'checked', true );
   397 
   344 
   398 			// Set color scheme
   345 			// Set color scheme.
   399 			if ( user_id === current_user_id ) {
   346 			if ( user_id === current_user_id ) {
   400 				// Load the colors stylesheet.
   347 				// Load the colors stylesheet.
   401 				// The default color scheme won't have one, so we'll need to create an element.
   348 				// The default color scheme won't have one, so we'll need to create an element.
   402 				if ( 0 === $stylesheet.length ) {
   349 				if ( 0 === $stylesheet.length ) {
   403 					$stylesheet = $( '<link rel="stylesheet" />' ).appendTo( 'head' );
   350 					$stylesheet = $( '<link rel="stylesheet" />' ).appendTo( 'head' );
   404 				}
   351 				}
   405 				$stylesheet.attr( 'href', $this.children( '.css_url' ).val() );
   352 				$stylesheet.attr( 'href', $this.children( '.css_url' ).val() );
   406 
   353 
   407 				// repaint icons
   354 				// Repaint icons.
   408 				if ( typeof wp !== 'undefined' && wp.svgPainter ) {
   355 				if ( typeof wp !== 'undefined' && wp.svgPainter ) {
   409 					try {
   356 					try {
   410 						colors = $.parseJSON( $this.children( '.icon_colors' ).val() );
   357 						colors = $.parseJSON( $this.children( '.icon_colors' ).val() );
   411 					} catch ( error ) {}
   358 					} catch ( error ) {}
   412 
   359 
   414 						wp.svgPainter.setColors( colors );
   361 						wp.svgPainter.setColors( colors );
   415 						wp.svgPainter.paint();
   362 						wp.svgPainter.paint();
   416 					}
   363 					}
   417 				}
   364 				}
   418 
   365 
   419 				// update user option
   366 				// Update user option.
   420 				$.post( ajaxurl, {
   367 				$.post( ajaxurl, {
   421 					action:       'save-user-color-scheme',
   368 					action:       'save-user-color-scheme',
   422 					color_scheme: $this.children( 'input[name="admin_color"]' ).val(),
   369 					color_scheme: $this.children( 'input[name="admin_color"]' ).val(),
   423 					nonce:        $('#color-nonce').val()
   370 					nonce:        $('#color-nonce').val()
   424 				}).done( function( response ) {
   371 				}).done( function( response ) {
   453 	window.generatePassword = generatePassword;
   400 	window.generatePassword = generatePassword;
   454 
   401 
   455 	/* Warn the user if password was generated but not saved */
   402 	/* Warn the user if password was generated but not saved */
   456 	$( window ).on( 'beforeunload', function () {
   403 	$( window ).on( 'beforeunload', function () {
   457 		if ( true === updateLock ) {
   404 		if ( true === updateLock ) {
   458 			return userProfileL10n.warn;
   405 			return __( 'Your new password has not been saved.' );
   459 		}
   406 		}
   460 	} );
   407 	} );
   461 
   408 
   462 })(jQuery);
   409 })(jQuery);