diff --git a/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php b/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php index 9bc32b7dfab7c39add669554ab18110a8db9d9de..f7f6240d92ee7be97a60835c5cc228cda9dd9410 100644 --- a/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php +++ b/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php @@ -52,14 +52,14 @@ public static function processPasswordConfirm(&$element, FormStateInterface $for '#title' => t('Password'), '#value' => empty($element['#value']) ? NULL : $element['#value']['pass1'], '#required' => $element['#required'], - '#attributes' => array('class' => array('password-field')), + '#attributes' => array('class' => array('password-field', 'js-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')), + '#attributes' => array('class' => array('password-confirm', 'js-password-confirm')), ); $element['#element_validate'] = array(array(get_called_class(), 'validatePasswordConfirm')); $element['#tree'] = TRUE; diff --git a/core/modules/user/src/Form/UserPermissionsForm.php b/core/modules/user/src/Form/UserPermissionsForm.php index a782f37282d65cd0b299dd28df200ed22a25d179..9bbb6b57e5308ec737a6e75b28bcdc26a76c231f 100644 --- a/core/modules/user/src/Form/UserPermissionsForm.php +++ b/core/modules/user/src/Form/UserPermissionsForm.php @@ -107,7 +107,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#type' => 'table', '#header' => array($this->t('Permission')), '#id' => 'permissions', - '#attributes' => ['class' => ['permissions']], + '#attributes' => ['class' => ['permissions', 'js-permissions']], '#sticky' => TRUE, ); foreach ($role_names as $name) { @@ -163,7 +163,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { ), '#type' => 'checkbox', '#default_value' => in_array($perm, $role_permissions[$rid]) ? 1 : 0, - '#attributes' => array('class' => array('rid-' . $rid)), + '#attributes' => array('class' => array('rid-' . $rid, 'js-rid-' . $rid)), '#parents' => array($rid, $perm), ); // Show a column of disabled but checked checkboxes. diff --git a/core/modules/user/user.js b/core/modules/user/user.js index 98d1d0e0542bdc72d2df52bcb4066d09e0eaf018..615689c21d652d71f9b3546da43d94f0df1a2cd4 100644 --- a/core/modules/user/user.js +++ b/core/modules/user/user.js @@ -1,4 +1,4 @@ -(function ($) { +(function ($, Drupal, drupalSettings) { "use strict"; @@ -8,37 +8,44 @@ */ Drupal.behaviors.password = { attach: function (context, settings) { - var translate = settings.password; - $(context).find('input.password-field').once('password').each(function () { - var passwordInput = $(this); - var innerWrapper = $(this).parent(); - var outerWrapper = $(this).parent().parent(); - var passwordDescription; + var $passwordInput = $(context).find('input.js-password-field').once('password'); + + if ($passwordInput.length) { + var translate = settings.password; + + var $passwordInputParent = $passwordInput.parent(); + var $passwordInputParentWrapper = $passwordInputParent.parent(); + var $passwordSuggestions; // Add identifying class to password element parent. - innerWrapper.addClass('password-parent'); + $passwordInputParent.addClass('password-parent'); // Add the password confirmation layer. - outerWrapper.find('input.password-confirm').parent().append('<div class="password-confirm-match">' + translate.confirmTitle + ' <span></span></div>').addClass('confirm-parent'); - var confirmInput = outerWrapper.find('input.password-confirm'); - var confirmResult = outerWrapper.find('div.password-confirm-match'); - var confirmChild = confirmResult.find('span'); + $passwordInputParentWrapper + .find('input.js-password-confirm') + .parent() + .append('<div class="password-confirm js-password-confirm">' + translate.confirmTitle + ' <span></span></div>') + .addClass('confirm-parent'); + + var $confirmInput = $passwordInputParentWrapper.find('input.js-password-confirm'); + var $confirmResult = $passwordInputParentWrapper.find('div.js-password-confirm'); + var $confirmChild = $confirmResult.find('span'); // If the password strength indicator is enabled, add its markup. if (settings.password.showStrengthIndicator) { - var passwordMeter = '<div class="password-strength"><div class="password-strength__meter"><div class="password-strength__indicator"></div></div><div class="password-strength__title">' + translate.strengthTitle + ' </div><div class="password-strength__text" aria-live="assertive"></div></div>'; - confirmInput.parent().after('<div class="password-suggestions description"></div>'); - innerWrapper.append(passwordMeter); - passwordDescription = outerWrapper.find('div.password-suggestions').hide(); + var passwordMeter = '<div class="password-strength"><div class="password-strength__meter"><div class="password-strength__indicator js-password-strength__indicator"></div></div><div class="password-strength__title">' + translate.strengthTitle + ' </div><div class="password-strength__text js-password-strength__text" aria-live="assertive"></div></div>'; + $confirmInput.parent().after('<div class="password-suggestions description"></div>'); + $passwordInputParent.append(passwordMeter); + $passwordSuggestions = $passwordInputParentWrapper.find('div.password-suggestions').hide(); } // Check that password and confirmation inputs match. var passwordCheckMatch = function (confirmInputVal) { - var success = passwordInput.val() === confirmInputVal; + var success = $passwordInput.val() === confirmInputVal; var confirmClass = success ? 'ok' : 'error'; // Fill in the success message and set the class accordingly. - confirmChild.html(translate['confirm' + (success ? 'Success' : 'Failure')]) + $confirmChild.html(translate['confirm' + (success ? 'Success' : 'Failure')]) .removeClass('ok error').addClass(confirmClass); }; @@ -46,40 +53,40 @@ var passwordCheck = function () { if (settings.password.showStrengthIndicator) { // Evaluate the password strength. - var result = Drupal.evaluatePasswordStrength(passwordInput.val(), settings.password); + var result = Drupal.evaluatePasswordStrength($passwordInput.val(), settings.password); // Update the suggestions for how to improve the password. - if (passwordDescription.html() !== result.message) { - passwordDescription.html(result.message); + if ($passwordSuggestions.html() !== result.message) { + $passwordSuggestions.html(result.message); } // Only show the description box if a weakness exists in the password. - passwordDescription.toggle(result.strength !== 100); + $passwordSuggestions.toggle(result.strength !== 100); // Adjust the length of the strength indicator. - innerWrapper.find('.password-strength__indicator') + $passwordInputParent.find('.js-password-strength__indicator') .css('width', result.strength + '%') .removeClass('is-weak is-fair is-good is-strong') .addClass(result.indicatorClass); // Update the strength indication text. - innerWrapper.find('.password-strength__text').html(result.indicatorText); + $passwordInputParent.find('.js-password-strength__text').html(result.indicatorText); } // Check the value in the confirm input and show results. - if (confirmInput.val()) { - passwordCheckMatch(confirmInput.val()); - confirmResult.css({visibility: 'visible'}); + if ($confirmInput.val()) { + passwordCheckMatch($confirmInput.val()); + $confirmResult.css({visibility: 'visible'}); } else { - confirmResult.css({visibility: 'hidden'}); + $confirmResult.css({visibility: 'hidden'}); } }; // Monitor input events. - passwordInput.on('input', passwordCheck); - confirmInput.on('input', passwordCheck); - }); + $passwordInput.on('input', passwordCheck); + $confirmInput.on('input', passwordCheck); + } } }; @@ -95,15 +102,15 @@ var strength = 100; var msg = []; - var hasLowercase = /[a-z]+/.test(password); - var hasUppercase = /[A-Z]+/.test(password); - var hasNumbers = /[0-9]+/.test(password); - var hasPunctuation = /[^a-zA-Z0-9]+/.test(password); + var hasLowercase = /[a-z]/.test(password); + var hasUppercase = /[A-Z]/.test(password); + var hasNumbers = /[0-9]/.test(password); + var hasPunctuation = /[^a-zA-Z0-9]/.test(password); // If there is a username edit box on the page, compare password to that, otherwise // use value from the database. - var usernameBox = $('input.username'); - var username = (usernameBox.length > 0) ? usernameBox.val() : translate.username; + var $usernameBox = $('input.username'); + var username = ($usernameBox.length > 0) ? $usernameBox.val() : translate.username; // Lose 5 points for every character less than 6, plus a 30 point penalty. if (password.length < 6) { @@ -175,8 +182,14 @@ // Assemble the final message. msg = translate.hasWeaknesses + '<ul><li>' + msg.join('</li><li>') + '</li></ul>'; - return {strength: strength, message: msg, indicatorText: indicatorText, indicatorClass: indicatorClass}; + + return { + strength: strength, + message: msg, + indicatorText: indicatorText, + indicatorClass: indicatorClass + }; }; -})(jQuery); +})(jQuery, Drupal, drupalSettings); diff --git a/core/modules/user/user.permissions.js b/core/modules/user/user.permissions.js index 6c28f070e4a33c8e32f86236fc776e237f94124b..6e473fa317410e60170e1ed86a346480085123de 100644 --- a/core/modules/user/user.permissions.js +++ b/core/modules/user/user.permissions.js @@ -32,16 +32,18 @@ // submitted form. If we'd automatically check existing checkboxes, the // permission table would be polluted with redundant entries. This // is deliberate, but desirable when we automatically check them. - var $dummy = $('<input type="checkbox" class="dummy-checkbox" disabled="disabled" checked="checked" />') + var $dummy = $('<input type="checkbox" class="dummy-checkbox js-dummy-checkbox" disabled="disabled" checked="checked" />') .attr('title', Drupal.t("This permission is inherited from the authenticated user role.")) .hide(); - $table.find('input[type=checkbox]').not('.rid-anonymous, .rid-authenticated').addClass('real-checkbox').each(function () { - $dummy.clone().insertAfter(this); - }); + $table + .find('input[type="checkbox"]') + .not('.js-rid-anonymous, .js-rid-authenticated') + .addClass('real-checkbox js-real-checkbox') + .after($dummy); // Initialize the authenticated user checkbox. - $table.find('input[type=checkbox].rid-authenticated') + $table.find('input[type=checkbox].js-rid-authenticated') .on('click.permissions', self.toggle) // .triggerHandler() cannot be used here, as it only affects the first // element. @@ -64,10 +66,10 @@ // jQuery performs too many layout calculations for .hide() and .show(), // leading to a major page rendering lag on sites with many roles and // permissions. Therefore, we toggle visibility directly. - $row.find('.real-checkbox').each(function () { + $row.find('.js-real-checkbox').each(function () { this.style.display = (authCheckbox.checked ? 'none' : ''); }); - $row.find('.dummy-checkbox').each(function () { + $row.find('.js-dummy-checkbox').each(function () { this.style.display = (authCheckbox.checked ? '' : 'none'); }); }