diff --git a/core/core.libraries.yml b/core/core.libraries.yml
index 3157e3a..326d55f 100644
--- a/core/core.libraries.yml
+++ b/core/core.libraries.yml
@@ -242,6 +242,15 @@ drupal.progress:
     - core/jquery
     - core/drupalSettings
 
+drupal.revealpass:
+  version: VERSION
+  js:
+    misc/revealpass.js: {}
+  dependencies:
+    - core/drupal
+    - core/jquery
+    - core/jquery.once
+
 drupal.states:
   version: VERSION
   js:
diff --git a/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php b/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php
index 07c3149..e31bc84 100644
--- a/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php
+++ b/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php
@@ -81,7 +81,10 @@ public static function processPasswordConfirm(&$element, FormStateInterface $for
       '#title' => t('Confirm password'),
       '#value' => empty($element['#value']) ? NULL : $element['#value']['pass2'],
       '#required' => $element['#required'],
-      '#attributes' => ['class' => ['password-confirm', 'js-password-confirm']],
+      '#attributes' => [
+        'class' => ['password-confirm', 'js-password-confirm'],
+        'data-drupal-password-strength' => TRUE,
+      ],
       '#error_no_message' => TRUE,
     ];
     $element['#element_validate'] = [[get_called_class(), 'validatePasswordConfirm']];
diff --git a/core/modules/system/tests/modules/form_test/form_test.routing.yml b/core/modules/system/tests/modules/form_test/form_test.routing.yml
index 9e178cd..41bfb13 100644
--- a/core/modules/system/tests/modules/form_test/form_test.routing.yml
+++ b/core/modules/system/tests/modules/form_test/form_test.routing.yml
@@ -505,3 +505,10 @@ form_test.optional_container:
     _title: 'Optional container testing'
   requirements:
     _access: 'TRUE'
+
+form_test.password_reveal:
+  path: '/form-test/password-reveal'
+  defaults:
+    _form: '\Drupal\form_test\Form\FormTestPasswordReveal'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/user/config/install/user.settings.yml b/core/modules/user/config/install/user.settings.yml
index 8372ccd..7e12609 100644
--- a/core/modules/user/config/install/user.settings.yml
+++ b/core/modules/user/config/install/user.settings.yml
@@ -13,4 +13,5 @@ register: visitors
 cancel_method: user_cancel_block
 password_reset_timeout: 86400
 password_strength: true
+password_type_reveal: false
 langcode: en
diff --git a/core/modules/user/config/schema/user.schema.yml b/core/modules/user/config/schema/user.schema.yml
index 2f9bda4..ad12b6c 100644
--- a/core/modules/user/config/schema/user.schema.yml
+++ b/core/modules/user/config/schema/user.schema.yml
@@ -50,6 +50,9 @@ user.settings:
     password_strength:
       type: boolean
       label: 'Enable password strength indicator'
+    password_type_reveal:
+      type: boolean
+      label: 'Use password reveal on account edit page'
 
 user.mail:
  type: config_object
diff --git a/core/modules/user/src/AccountForm.php b/core/modules/user/src/AccountForm.php
index d695968..5d37026 100644
--- a/core/modules/user/src/AccountForm.php
+++ b/core/modules/user/src/AccountForm.php
@@ -109,11 +109,21 @@ public function form(array $form, FormStateInterface $form_state) {
     // Display password field only for existing users or when user is allowed to
     // assign a password during registration.
     if (!$register) {
-      $form['account']['pass'] = [
-        '#type' => 'password_confirm',
-        '#size' => 25,
-        '#description' => $this->t('To change the current user password, enter the new password in both fields.'),
-      ];
+      if ($config->get('password_type_reveal')) {
+        $form['account']['pass'] = [
+          '#title' => $this->t('Password'),
+          '#type' => 'password_reveal',
+          '#size' => 25,
+          '#description' => $this->t('To change the current user password, enter the new password.'),
+        ];
+      }
+      else {
+        $form['account']['pass'] = [
+          '#type' => 'password_confirm',
+          '#size' => 25,
+          '#description' => $this->t('To change the current user password, enter the new password in both fields.'),
+        ];
+      }
 
       // To skip the current password field, the user must have logged in via a
       // one-time link and have the token in the URL. Store this in $form_state
@@ -151,12 +161,23 @@ public function form(array $form, FormStateInterface $form_state) {
       }
     }
     elseif (!$config->get('verify_mail') || $admin) {
-      $form['account']['pass'] = [
-        '#type' => 'password_confirm',
-        '#size' => 25,
-        '#description' => $this->t('Provide a password for the new account in both fields.'),
-        '#required' => TRUE,
-      ];
+      if ($config->get('password_type_reveal')) {
+        $form['account']['pass'] = [
+          '#title' => $this->t('Password'),
+          '#type' => 'password_reveal',
+          '#size' => 25,
+          '#description' => $this->t('Provide a password for the new account.'),
+          '#required' => TRUE,
+        ];
+      }
+      else {
+        $form['account']['pass'] = [
+          '#type' => 'password_confirm',
+          '#size' => 25,
+          '#description' => $this->t('Provide a password for the new account in both fields.'),
+          '#required' => TRUE,
+        ];
+      }
     }
 
     // When not building the user registration form, prevent web browsers from
diff --git a/core/modules/user/src/AccountSettingsForm.php b/core/modules/user/src/AccountSettingsForm.php
index bd80dd7..b8d43c6 100644
--- a/core/modules/user/src/AccountSettingsForm.php
+++ b/core/modules/user/src/AccountSettingsForm.php
@@ -167,6 +167,11 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#title' => $this->t('Enable password strength indicator'),
       '#default_value' => $config->get('password_strength'),
     ];
+    $form['registration_cancellation']['user_password_type_reveal'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Use password reveal, not password confirm, on account edit pages'),
+      '#default_value' => $config->get('password_type_reveal'),
+    ];
     $form['registration_cancellation']['user_cancel_method'] = [
       '#type' => 'radios',
       '#title' => $this->t('When cancelling a user account'),
@@ -431,6 +436,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       ->set('anonymous', $form_state->getValue('anonymous'))
       ->set('register', $form_state->getValue('user_register'))
       ->set('password_strength', $form_state->getValue('user_password_strength'))
+      ->set('password_type_reveal', $form_state->getValue('user_password_type_reveal'))
       ->set('verify_mail', $form_state->getValue('user_email_verification'))
       ->set('cancel_method', $form_state->getValue('user_cancel_method'))
       ->set('notify.status_activated', $form_state->getValue('user_mail_status_activated_notify'))
diff --git a/core/modules/user/tests/src/Functional/UserEditTest.php b/core/modules/user/tests/src/Functional/UserEditTest.php
index 0f75ff8..85e9343 100644
--- a/core/modules/user/tests/src/Functional/UserEditTest.php
+++ b/core/modules/user/tests/src/Functional/UserEditTest.php
@@ -108,6 +108,19 @@ public function testUserEdit() {
     $this->assertText(t('The changes have been saved.'));
     $this->assertNoFieldChecked('edit-status-0');
     $this->assertFieldChecked('edit-status-1');
+
+    // Test editing the user with a password_reveal field.
+    $config->set('password_type_reveal', TRUE)->save();
+    $config->set('password_strength', TRUE)->save();
+
+    $this->drupalGet("user/" . $admin_user->id() . "/edit");
+    $this->assertRaw('Password strength:', 'The password strength indicator is displayed.');
+
+    $edit = [];
+    $edit['pass'] = $this->randomMachineName();
+    $edit['current_pass'] = $admin_user->pass_raw;
+    $this->drupalPostForm("user/" . $admin_user->id() . "/edit", $edit, t('Save'));
+    $this->assertRaw(t("The changes have been saved."));
   }
 
   /**
diff --git a/core/modules/user/user.install b/core/modules/user/user.install
index 0af797a..d9f59f1 100644
--- a/core/modules/user/user.install
+++ b/core/modules/user/user.install
@@ -98,3 +98,10 @@ function user_update_8100() {
     $config->set('status_blocked', $mail)->save(TRUE);
   }
 }
+
+/**
+ * Add the configuration setting for password_type_reveal.
+ */
+function user_update_8101() {
+  \Drupal::configFactory()->getEditable('user.settings')->set('password_type_reveal', FALSE)->save();
+}
diff --git a/core/modules/user/user.js b/core/modules/user/user.js
index ec9735c..ef8f57f 100644
--- a/core/modules/user/user.js
+++ b/core/modules/user/user.js
@@ -153,4 +153,4 @@
       indicatorClass: indicatorClass
     };
   };
-})(jQuery, Drupal, drupalSettings);
\ No newline at end of file
+})(jQuery, Drupal, drupalSettings);
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index cabe189..d96e9d4 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -1248,6 +1248,9 @@ function user_element_info_alter(array &$types) {
   if (isset($types['password_confirm'])) {
     $types['password_confirm']['#process'][] = 'user_form_process_password_confirm';
   }
+  if (isset($types['password_reveal'])) {
+    $types['password_reveal']['#process'][] = 'user_form_process_password_reveal';
+  }
 }
 
 /**
@@ -1290,6 +1293,44 @@ function user_form_process_password_confirm($element) {
   return $element;
 }
 
+/**
+ * Form element process handler for client-side password validation.
+ *
+ * This #process handler is automatically invoked for 'password_reveal' form
+ * elements to add the JavaScript to display and hide the password and string
+ * translations for dynamic password validation.
+ */
+function user_form_process_password_reveal($element) {
+  $password_settings = [
+    'confirmTitle' => '',
+    'showStrengthIndicator' => FALSE,
+  ];
+
+  if (\Drupal::config('user.settings')->get('password_strength')) {
+    $password_settings['showStrengthIndicator'] = TRUE;
+    $password_settings += [
+      'strengthTitle' => t('Password strength:'),
+      'hasWeaknesses' => t('To make your password stronger:'),
+      'tooShort' => t('Make it at least 12 characters'),
+      'addLowerCase' => t('Add lowercase letters'),
+      'addUpperCase' => t('Add uppercase letters'),
+      'addNumbers' => t('Add numbers'),
+      'addPunctuation' => t('Add punctuation'),
+      'sameAsUsername' => t('Make it different from your username'),
+      'weak' => t('Weak'),
+      'fair' => t('Fair'),
+      'good' => t('Good'),
+      'strong' => t('Strong'),
+      'username' => \Drupal::currentUser()->getUsername(),
+    ];
+  }
+
+  $element['#attached']['library'][] = 'user/drupal.user';
+  $element['#attached']['drupalSettings']['password'] = $password_settings;
+
+  return $element;
+}
+
 /**
  * Implements hook_modules_uninstalled().
  */
diff --git a/core/themes/classy/css/components/user.css b/core/themes/classy/css/components/user.css
index d62ff25..5905e85 100644
--- a/core/themes/classy/css/components/user.css
+++ b/core/themes/classy/css/components/user.css
@@ -54,6 +54,11 @@
 [dir="rtl"] .password-parent {
   clear: right;
 }
+@media all and (min-width: 600px) {
+  .password-parent .toggle-password {
+    margin: 0 0.75em;
+  }
+}
 
 /* Styling for the status indicator of the passwords match test.  */
 .password-confirm .ok {
diff --git a/vendor/drupal/coder b/vendor/drupal/coder
--- a/vendor/drupal/coder
+++ b/vendor/drupal/coder
@@ -1 +1 @@
-Subproject commit 984c54a7b1e8f27ff1c32348df69712afd86b17f
+Subproject commit 984c54a7b1e8f27ff1c32348df69712afd86b17f-dirty
