diff --git a/core/core.libraries.yml b/core/core.libraries.yml index c76d865..7c73121 100644 --- a/core/core.libraries.yml +++ b/core/core.libraries.yml @@ -206,6 +206,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/includes/form.inc b/core/includes/form.inc index 7131a7b..dccc828 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -525,8 +525,8 @@ function form_type_tableselect_value($element, $input = FALSE) { */ function form_type_password_confirm_value($element, $input = FALSE) { if ($input === FALSE) { - $element += array('#default_value' => array()); - return $element['#default_value'] + array('pass1' => '', 'pass2' => ''); + $element += array('#default_value' => ''); + return $element['#default_value']; } } @@ -968,53 +968,9 @@ function template_preprocess_radios(&$variables) { * Expand a password_confirm field into two text boxes. */ function form_process_password_confirm($element) { - $element['pass1'] = array( - '#type' => 'password', - '#title' => t('Password'), - '#value' => empty($element['#value']) ? NULL : $element['#value']['pass1'], - '#required' => $element['#required'], - '#attributes' => array('class' => array('password-field')), - ); - $element['pass2'] = array( - '#type' => 'password', - '#title' => t('Confirm password'), - '#value' => empty($element['#value']) ? NULL : $element['#value']['pass2'], - '#required' => $element['#required'], - '#attributes' => array('class' => array('password-confirm')), - ); - $element['#element_validate'] = array('password_confirm_validate'); - $element['#tree'] = TRUE; - - if (isset($element['#size'])) { - $element['pass1']['#size'] = $element['pass2']['#size'] = $element['#size']; - } - - return $element; -} - -/** - * Validates a password_confirm element. - */ -function password_confirm_validate($element, &$element_state) { - $pass1 = trim($element['pass1']['#value']); - $pass2 = trim($element['pass2']['#value']); - if (!empty($pass1) || !empty($pass2)) { - if (strcmp($pass1, $pass2)) { - form_error($element, $element_state, t('The specified passwords do not match.')); - } - } - elseif ($element['#required'] && !empty($element_state['input'])) { - form_error($element, $element_state, t('Password field is required.')); - } - - // Password field must be converted from a two-element array into a single - // string regardless of validation results. - form_set_value($element['pass1'], NULL, $element_state); - form_set_value($element['pass2'], NULL, $element_state); - form_set_value($element, $pass1, $element_state); - + $element['#attached']['library'][] = 'core/drupal.revealpass'; + $element['#attributes']['data-drupal-revealpass'] = TRUE; return $element; - } /** diff --git a/core/lib/Drupal/Core/Form/FormBuilderInterface.php b/core/lib/Drupal/Core/Form/FormBuilderInterface.php index bb4d953..5e38c84 100644 --- a/core/lib/Drupal/Core/Form/FormBuilderInterface.php +++ b/core/lib/Drupal/Core/Form/FormBuilderInterface.php @@ -168,8 +168,7 @@ public function setCache($form_build_id, $form, FormStateInterface $form_state); * $form_state = new FormState(); * $form_state['values']['name'] = 'robo-user'; * $form_state['values']['mail'] = 'robouser@example.com'; - * $form_state['values']['pass']['pass1'] = 'password'; - * $form_state['values']['pass']['pass2'] = 'password'; + * $form_state['values']['pass'] = 'password'; * $form_state['values']['op'] = t('Create new account'); * drupal_form_submit('user_register_form', $form_state); * @endcode diff --git a/core/misc/revealpass.js b/core/misc/revealpass.js new file mode 100644 index 0000000..e563f40 --- /dev/null +++ b/core/misc/revealpass.js @@ -0,0 +1,37 @@ +(function ($, Drupal) { + + "use strict"; + + var showPass = Drupal.t('Show password'); + var hidePass = Drupal.t('Hide password'); + + function revealClickHandle(event) { + var $pass = $(event.data.password); + var $button = $(event.target); + + if ($pass.attr('type') === 'password') { + $pass.attr('type', 'text'); + $button.text(hidePass); + } + else { + $pass.attr('type', 'password'); + $button.text(showPass); + } + } + + function revealLink(index, element) { + var $trigger = $(''); + + $trigger.on('click', {password: element}, revealClickHandle); + $trigger.insertAfter(element); + } + + Drupal.behaviors.revealPass = { + attach: function (context) { + $(context).find('input[type=password][data-drupal-revealpass]') + .once('revealpass') + .each(revealLink); + } + }; + +})(jQuery, Drupal); diff --git a/core/modules/contact/src/Tests/ContactPersonalTest.php b/core/modules/contact/src/Tests/ContactPersonalTest.php index f004d39..eda3a5c 100644 --- a/core/modules/contact/src/Tests/ContactPersonalTest.php +++ b/core/modules/contact/src/Tests/ContactPersonalTest.php @@ -251,8 +251,7 @@ protected function checkContactAccess($response, $contact_value = NULL) { $edit = array( 'name' => $name, 'mail' => $this->randomName() . '@example.com', - 'pass[pass1]' => $pass = $this->randomString(), - 'pass[pass2]' => $pass, + 'pass' => $this->randomString(), 'notify' => FALSE, ); if (isset($contact_value)) { diff --git a/core/modules/dblog/src/Tests/DbLogTest.php b/core/modules/dblog/src/Tests/DbLogTest.php index 683479f..90391e4 100644 --- a/core/modules/dblog/src/Tests/DbLogTest.php +++ b/core/modules/dblog/src/Tests/DbLogTest.php @@ -229,8 +229,7 @@ private function doUser() { $edit = array(); $edit['name'] = $name; $edit['mail'] = $name . '@example.com'; - $edit['pass[pass1]'] = $pass; - $edit['pass[pass2]'] = $pass; + $edit['pass'] = $pass; $edit['status'] = 1; $this->drupalPostForm('admin/people/create', $edit, t('Create new account')); $this->assertResponse(200); diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php index 956080a..5282526 100644 --- a/core/modules/simpletest/src/WebTestBase.php +++ b/core/modules/simpletest/src/WebTestBase.php @@ -985,10 +985,7 @@ protected function installParameters() { 'account' => array( 'name' => $this->root_user->name, 'mail' => $this->root_user->getEmail(), - 'pass' => array( - 'pass1' => $this->root_user->pass_raw, - 'pass2' => $this->root_user->pass_raw, - ), + 'pass' => $this->root_user->pass_raw, ), // form_type_checkboxes_value() requires NULL instead of FALSE values // for programmatic form submissions to disable a checkbox. diff --git a/core/modules/system/src/Tests/Form/FormTest.php b/core/modules/system/src/Tests/Form/FormTest.php index 12d78ea..3c026f5 100644 --- a/core/modules/system/src/Tests/Form/FormTest.php +++ b/core/modules/system/src/Tests/Form/FormTest.php @@ -72,10 +72,7 @@ function testRequiredFields() { $elements['password']['empty_values'] = $empty_strings; $elements['password_confirm']['element'] = array('#title' => $this->randomName(), '#type' => 'password_confirm'); - // Provide empty values for both password fields. - foreach ($empty_strings as $key => $value) { - $elements['password_confirm']['empty_values'][$key] = array('pass1' => $value, 'pass2' => $value); - } + $elements['password_confirm']['empty_values'] = $empty_strings; $elements['textarea']['element'] = array('#title' => $this->randomName(), '#type' => 'textarea'); $elements['textarea']['empty_values'] = $empty_strings; diff --git a/core/modules/system/system.module b/core/modules/system/system.module index f421e6b..be8d9cd 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -466,7 +466,9 @@ function system_element_info() { ); $types['password_confirm'] = array( '#input' => TRUE, - '#process' => array('form_process_password_confirm', 'user_form_process_password_confirm'), + '#process' => array('ajax_process_form', 'form_process_pattern', 'form_process_password_confirm', 'user_form_process_password_confirm'), + '#pre_render' => array('form_pre_render_password'), + '#theme' => 'input__password', '#theme_wrappers' => array('form_element'), ); $types['textarea'] = array( diff --git a/core/modules/user/src/Tests/UserCreateFailMailTest.php b/core/modules/user/src/Tests/UserCreateFailMailTest.php index c07b77e..c613c15 100644 --- a/core/modules/user/src/Tests/UserCreateFailMailTest.php +++ b/core/modules/user/src/Tests/UserCreateFailMailTest.php @@ -37,8 +37,7 @@ protected function testUserAdd() { $edit = array( 'name' => $name, 'mail' => $this->randomName() . '@example.com', - 'pass[pass1]' => $pass = $this->randomString(), - 'pass[pass2]' => $pass, + 'pass' => $this->randomString(), 'notify' => TRUE, ); $this->drupalPostForm('admin/people/create', $edit, t('Create new account')); diff --git a/core/modules/user/src/Tests/UserCreateTest.php b/core/modules/user/src/Tests/UserCreateTest.php index d1bba88..8b09c68 100644 --- a/core/modules/user/src/Tests/UserCreateTest.php +++ b/core/modules/user/src/Tests/UserCreateTest.php @@ -88,8 +88,7 @@ protected function testUserAdd() { $edit = array( 'name' => $name, 'mail' => $this->randomName() . '@example.com', - 'pass[pass1]' => $pass = $this->randomString(), - 'pass[pass2]' => $pass, + 'pass' => $this->randomString(), 'notify' => $notify, ); $this->drupalPostForm('admin/people/create', $edit, t('Create new account')); diff --git a/core/modules/user/src/Tests/UserEditTest.php b/core/modules/user/src/Tests/UserEditTest.php index 68747a1..378a914 100644 --- a/core/modules/user/src/Tests/UserEditTest.php +++ b/core/modules/user/src/Tests/UserEditTest.php @@ -30,18 +30,6 @@ function testUserEdit() { $this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save')); $this->assertRaw(t('The name %name is already taken.', array('%name' => $edit['name']))); - // Check that filling out a single password field does not validate. - $edit = array(); - $edit['pass[pass1]'] = ''; - $edit['pass[pass2]'] = $this->randomName(); - $this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save')); - $this->assertText(t("The specified passwords do not match."), 'Typing mismatched passwords displays an error message.'); - - $edit['pass[pass1]'] = $this->randomName(); - $edit['pass[pass2]'] = ''; - $this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save')); - $this->assertText(t("The specified passwords do not match."), 'Typing mismatched passwords displays an error message.'); - // Test that the error message appears when attempting to change the mail or // pass without the current password. $edit = array(); @@ -55,8 +43,7 @@ function testUserEdit() { // Test that the user must enter current password before changing passwords. $edit = array(); - $edit['pass[pass1]'] = $new_pass = $this->randomName(); - $edit['pass[pass2]'] = $new_pass; + $edit['pass'] = $new_pass = $this->randomName(); $this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save')); $this->assertRaw(t("Your current password is missing or incorrect; it's required to change the %name.", array('%name' => t('Password')))); diff --git a/core/modules/user/src/Tests/UserLanguageCreationTest.php b/core/modules/user/src/Tests/UserLanguageCreationTest.php index e32718a..234d8f5 100644 --- a/core/modules/user/src/Tests/UserLanguageCreationTest.php +++ b/core/modules/user/src/Tests/UserLanguageCreationTest.php @@ -56,8 +56,7 @@ function testLocalUserCreation() { $edit = array( 'name' => $username, 'mail' => $this->randomName(4) . '@example.com', - 'pass[pass1]' => $username, - 'pass[pass2]' => $username, + 'pass' => $username, ); $this->drupalPostForm($langcode . '/admin/people/create', $edit, t('Create new account')); @@ -95,8 +94,7 @@ function testLocalUserCreation() { // Set pass_raw so we can login the new user. $user->pass_raw = $this->randomName(10); $edit = array( - 'pass[pass1]' => $user->pass_raw, - 'pass[pass2]' => $user->pass_raw, + 'pass' => $user->pass_raw, ); $this->drupalPostForm($user_edit, $edit, t('Save')); diff --git a/core/modules/user/src/Tests/UserPasswordResetTest.php b/core/modules/user/src/Tests/UserPasswordResetTest.php index 1045e2c..4e8df3c 100644 --- a/core/modules/user/src/Tests/UserPasswordResetTest.php +++ b/core/modules/user/src/Tests/UserPasswordResetTest.php @@ -79,7 +79,7 @@ function testUserPasswordReset() { // Change the forgotten password. $password = user_password(); - $edit = array('pass[pass1]' => $password, 'pass[pass2]' => $password); + $edit = array('pass' => $password); $this->drupalPostForm(NULL, $edit, t('Save')); $this->assertText(t('The changes have been saved.'), 'Forgotten password changed.'); diff --git a/core/modules/user/src/Tests/UserRegistrationTest.php b/core/modules/user/src/Tests/UserRegistrationTest.php index 97aed33..d04f15d 100644 --- a/core/modules/user/src/Tests/UserRegistrationTest.php +++ b/core/modules/user/src/Tests/UserRegistrationTest.php @@ -70,15 +70,8 @@ function testRegistrationWithoutEmailVerification() { $edit['name'] = $name = $this->randomName(); $edit['mail'] = $mail = $edit['name'] . '@example.com'; - // Try entering a mismatching password. - $edit['pass[pass1]'] = '99999.0'; - $edit['pass[pass2]'] = '99999'; - $this->drupalPostForm('user/register', $edit, t('Create new account')); - $this->assertText(t('The specified passwords do not match.'), 'Typing mismatched passwords displays an error message.'); - // Enter a correct password. - $edit['pass[pass1]'] = $new_pass = $this->randomName(); - $edit['pass[pass2]'] = $new_pass; + $edit['pass'] = $this->randomName(); $this->drupalPostForm('user/register', $edit, t('Create new account')); $this->container->get('entity.manager')->getStorage('user')->resetCache(); $accounts = entity_load_multiple_by_properties('user', array('name' => $name, 'mail' => $mail)); @@ -92,8 +85,7 @@ function testRegistrationWithoutEmailVerification() { $edit = array(); $edit['name'] = $name = $this->randomName(); $edit['mail'] = $mail = $edit['name'] . '@example.com'; - $edit['pass[pass1]'] = $pass = $this->randomName(); - $edit['pass[pass2]'] = $pass; + $edit['pass'] = $pass = $this->randomName(); $this->drupalPostForm('user/register', $edit, t('Create new account')); $this->assertText(t('Thank you for applying for an account. Your account is currently pending approval by the site administrator.'), 'Users are notified of pending approval'); @@ -169,8 +161,7 @@ function testRegistrationDefaultValues() { $edit = array(); $edit['name'] = $name = $this->randomName(); $edit['mail'] = $mail = $edit['name'] . '@example.com'; - $edit['pass[pass1]'] = $new_pass = $this->randomName(); - $edit['pass[pass2]'] = $new_pass; + $edit['pass'] = $this->randomName(); $this->drupalPostForm(NULL, $edit, t('Create new account')); // Check user fields. diff --git a/core/modules/user/src/Tests/UserRolesAssignmentTest.php b/core/modules/user/src/Tests/UserRolesAssignmentTest.php index 70ef6f6..b750b98 100644 --- a/core/modules/user/src/Tests/UserRolesAssignmentTest.php +++ b/core/modules/user/src/Tests/UserRolesAssignmentTest.php @@ -54,8 +54,7 @@ function testCreateUserWithRole() { $edit = array( 'name' => $this->randomName(), 'mail' => $this->randomName() . '@example.com', - 'pass[pass1]' => $pass = $this->randomString(), - 'pass[pass2]' => $pass, + 'pass' => $this->randomString(), "roles[$rid]" => $rid, ); $this->drupalPostForm('admin/people/create', $edit, t('Create new account')); diff --git a/core/modules/user/user.module b/core/modules/user/user.module index c23cc2c..a72e6d8 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -1373,9 +1373,6 @@ function _user_mail_notify($op, $account, $langcode = NULL) { */ function user_form_process_password_confirm($element) { $password_settings = array( - 'confirmTitle' => t('Passwords match:'), - 'confirmSuccess' => t('yes'), - 'confirmFailure' => t('no'), 'showStrengthIndicator' => FALSE, );