Problem/Motivation
The user.js in Drupal core (it is attached to the password_confirm form element) uses specific markup for constructing the password strength message, password strength bar, the password match message and the password improvement tips.
Currently, markup of these elements is not overridable by themes, therefore Claro had to override the user.js file completely
We want to be able to remove Claro's user.js replacement, and only use Drupal.theme() functions (and overridden JS settings) for theming the password confirm widget.
Proposed resolution
Introduce new Drupal.theme callbacks for these components and refactor user.js to use the new Drupal.theme callbacks. Remove Claro user.js and leverage the newly added theme functions instead.
Remaining tasks
- Provide patch
- Create change record
User interface changes
Nothing.
API changes
Data model changes
Release notes snippet
The user module has added JavaScript theme functions have to allow customizing password confirm widget markup. Information on using these functions can be found in user.theme.es6.js.
| Comment | File | Size | Author |
|---|---|---|---|
| #53 | interdiff.txt | 4.59 KB | effulgentsia |
| #53 | 3067523-53.patch | 93.2 KB | effulgentsia |
| #49 | 3067523-49.patch | 93.22 KB | bnjmnm |
| #49 | interdiff_45-49.txt | 3.67 KB | bnjmnm |
| #45 | interdiff__41--45.txt | 26.51 KB | bnjmnm |
Comments
Comment #3
huzookaComment #4
huzookaAdding a raw test for ensuring that we will ship the original markup for the password confirm widget.
I'll refactor and simplify this test asap.
Comment #5
huzookaComment #6
huzookaAdded the first patch that ships the needed new Drupal.theme callbacks:
Drupal.theme.passwordStrength()Drupal.theme.passwordSuggestions()Comment #7
huzookaComment #8
huzookaIS updated:
The most important motivation here is that we want to be able to remove Claro's
user.jsreplacement, and only useDrupal.theme()functions (and overridden settings) for the password confirm widget.Comment #9
huzookaComment #10
huzookaThis patch cleans up Claro after #9 is applied.
Comment #11
huzookaSome summary:
The attached test-only patch ensures that we will have the pre-existing markup and functionality before; and even after the complete patch was applied.
The complete patch contains the test and the needed changes of the user module (mainly
user.jsand theuser.theme.js) and Claro theme.The
user-fix-onlyfile contains the changes made onuser.module; theclaro-fix-onlyfile show the changes of Claro theme. These are for making the review easier.Comment #12
bnjmnmReroll for working from 9.1.x
Comment #13
bnjmnmThere are a few places in this test, where inline comments begin and/or end with empty lines. Those empty lines can be removed. I can see the appeal of using them for emphasis, but blank inline comments should only be used for separating paragraphs.
This one isn't in the code standards, but I had a committer state a strong preference for adding a blank line above inline comments if the previous line has the same indentation. I don't mind making those folks happy.
This and a few other function definitions need to be JSDoc'd.
The phrasing here sounds uncertain. Could this be changed to something more definite sounding? If there *is* some uncertainty, it would be good to confirm the exact behavior before rewriting the comment.
This can just be an anonymous
() =>s/Constucts/Constructs
could change "has to contains a" to "must contain a"
Not sure it would pass prettier, but is there a way to put the population of confirmMessage.textWrapper on its own line? It would be helpful to have the creation of both required keys be explicit in the example.
s/Constucts/Constructs
s/strenght/strength
Look for these typos throughout the patch, some appear in Claro's JS too.
Maybe change "jQuery element" to "jQuery object" for consistency with the other property definitions.
r/that's/whose
@@ -16,103 +16,189 @@
+ const $passwordWidget = $mainInput.closest(
+ '.js-form-type-password-confirm',
+ );
+ const $confirmInput = $passwordWidget.find(
+ 'input.js-password-confirm',
+ );
+ const passwordConfirmMessage = Drupal.theme(
+ 'passwordConfirmMessage',
+ settings.password,
+ );
+
+ const $confirmMessage =
+ typeof passwordConfirmMessage === 'string'
+ ? $(passwordConfirmMessage)
+ : passwordConfirmMessage.item;
+ const $confirmTextWrapper =
+ typeof passwordConfirmMessage === 'string'
+ ? $confirmMessage.find('span')
+ : passwordConfirmMessage.textWrapper;
+ const $confirmInputParent = $confirmInput
+ .parent()
+ .addClass('confirm-parent')
+ .append($confirmMessage);
+ const password = {};
+ const passwordStrengthBarClassesToRemove = [
+ settings.password.cssClassPasswordWeak || '',
+ settings.password.cssClassPasswordFair || '',
+ settings.password.cssClassPasswordGood || '',
+ settings.password.cssClassPasswordStrong || '',
+ ]
+ .join(' ')
+ .trim();
+ const confirmTextWrapperClassesToRemove = [
+ settings.password.cssClassPasswordsMatch || '',
+ settings.password.cssClassPasswordsNotMatch || '',
+ ]
+ .join(' ')
+ .trim();
+ const widgetClassesToRemove = [
+ settings.password.cssClassWidgetInitial || '',
+ settings.password.cssClassPasswordEmpty || '',
+ settings.password.cssClassPasswordFilled || '',
+ settings.password.cssClassConfirmEmpty || '',
+ settings.password.cssClassConfirmFilled || '',
+ ]
+ .join(' ')
+ .trim();
This is a pretty large chunk of logic without any comments. The variable names are good, which is helpful, but this should get commented at least as well as what it replaced.
Move the indentation of "Example:" back two spaces.
s/outputEmtpyList/outputEmptyList (this happens a few times in this patch)
Comment #14
lauriiiThis should address #13.
Comment #16
lauriiiThis should fix the failing test
Comment #17
bnjmnmAll of my feedback in #13 is addressed.
I'd like to see a change record before I'd RTBC as that would help me do a final round of review on a pretty large patch.
Also tagging with "Needs issue summary update" as the issue summary has this scoped to just creating the theme functions, but this patch also leverages those in Claro. The IS either needs to include the Claro changes, or they should be split to another issue.
Comment #18
lauriiiComment #19
lauriiiChange record has been added
Comment #20
bnjmnmAll my review items have been addressed , and the change record is consistent with my understanding of what the patch is doing, so this can RTBC.
Comment #21
xjmLooks like it no longer applies (already).
Comment #22
bnjmnmReroll attached
Comment #23
lauriiiI'm not sure if we should use the
drupalSettingsfor overriding CSS classes 🤔 I'm inclined to solving this in a follow-up, but on the other hand, solving this in a follow-up would be more difficult because we would have to mindful of breaking the API.If we decide to go with this approach, should we convert these to empty strings? Currently this is relying on jQuery processing boolean values correctly. As far as I can see in their documentation, this behavior isn't documented so it might not be a good idea to rely on it.
Comment #24
nod_Lot of comments! thanks for that :)
The passwordStrength and passwordConfirmMessage theme function are too smart. And it is not integrator-friendly.
I would rather add data attributes in the html tags (and get rid of the js-* classes, for some history #1090592: [meta] Use HTML5 data-drupal-* attributes instead of #ID selectors in Drupal.settings) and do
Theme functions should return strings, not objects.
Also there is #2293803: Replace confirm password element with a new element that allows toggling to view the typed password to keep in mind
Comment #25
nod_After all these years I finally got dreditor on my main browser :p
Better to make a variable like
const settingsPassword = settings.password;We can add a level here: password.css.match, password.css.notMatch, etc.
feels a bit old-school to go with that much capitalization :)
Like lauriii a bit conflicted by putting class names in the settings, but it is a setting so... why not. It could also be put in a theme function, it'd be closer to the experience of overring CSS/JS, than for a themer to try to remember how to override libraries settings.
$element['#attached']['drupalSettings']['password'] += $password_settings;?Comment #26
nod_Thinking about it, shouldn't be in drupalsettings (it's for PHP to JS data) and shouldn't be in a theme function, have the list somewhere in the JS file and expose it through Drupal.password.css or something.
Comment #27
lauriiiStarted with a reroll
Comment #28
lauriiiI had some reservations on the approach too. However, based on
Drupal.themedocumentation, it seemed like it would be an accepted return value for theme functions:We could probably change the approach to use the data-drupal-selector if we agree that it's a preferred approach, but I just wanted to point out that the way I understand the documentation, this would be allowed. Maybe the documentation is incorrect or misleading and needs to be updated.
Comment #29
nod_The docs are definitely not correct, this is wording from at least 2007. Definitely not in line with what we've been doing for a few years now.
Comment #30
lauriiiLet's open an issue for discussing and changing that
Comment #31
lauriiiThis should address #25. We will still have to address #24.
Comment #32
lauriiiChanges in this patch:
Remaining work:
Comment #34
lauriiiThis should address the test failure
Comment #35
lauriiiOpened follow-up #3152042: Update Drupal.theme documentation to only allow returning string.
Comment #36
nod_Quick review:
The rest of core use
@prop, not@property.Shouldn't that use
Drupal.theme('passwordSuggestions')?It says returns string but it return an jQuery object.
A bit too eager, this still depends on
core/drupalsince it uses the main Drupal object.missing the compiled file no?
Comment #37
lauriiiI've added another CR draft to address #32.
This should also address #36, and also adds BC layer for rest of the selectors where we switched from a js- prefixed class to data-drupal-selector.
Comment #38
nod_Nice I didn't know we had that for deprecated JS :)
Understood why we kept the code I pointed out in #36.2
Still an issue with the dependencies, core/jquery is not used in the theme file anymore :) some estlint stuff as well as a typo in the claro theme file.
Comment #39
lauriiiI added the jQuery dependency for this. Maybe we should use Object.assign instead?
Comment #40
nod_oh right didn't saw that one. objec assign would be better yes
Comment #41
lauriiiChanged to using
Object.assigninsteadComment #42
nod_Looks good :)
Comment #43
alexpottIs possible to test the deprecations? There seem to be quite a few new deprecations added by the patch. Also the list of things that have been deprecated doesn't appear to tally with what's listed in the change records.
There doesn't appear to be test coverage of this deprecation.
This doesn't seem to have any detail in the CR.
The return now contains messageTips and message is deprecated. This deprecation is not mentioned in the CR's as far as I can see.
The CR mentions password-confirm-message but not password-confirm-test - having both is confusing - what's the difference?
Comment #44
bnjmnmWorking on #43
Comment #45
bnjmnm#43.1
Added a test that covers all deprecations introduced in this patch.
#43.2 CR rewritten to make this clearer.
#43.3 Created a new CR for this as it did not fit into the others https://www.drupal.org/node/3160593
#43.4 Once pointed out, I agree this is confusing. Did some rewriting of the CR and password-confirm-message/password-confirm-text and some associated variables are renamed to make their purpose clearer.
Comment #46
lauriii+1 on adding test coverage for the deprecations. Reviewed the interdiff between #45 and #41 The test coverage looks sufficient for me. I also think that the
password-match-status-textis clearer thanpassword-confirm-textso +1 for that change 👍Comment #47
effulgentsia commentedI've started to review this, and haven't finished yet, but so far, I'm confused about these 2 small things:
What's the
falseargument for?How are these CSS changes related to the scope of this issue?
Comment #48
lauriiiShould we add the tips to the same object?
Are these changes actually needed?
Comment #49
bnjmnm#47.1
, looks like it's for an arg that was present in an earlier iteration of the function. It's no longer used so I removed it from the patch.
#47.2
I had assumed they were added to maintain behavior that would otherwise be regressed by this patch, but after comparing to HEAD this does appear to be out of scope. I added #3167508: [PP-1] Add transition to password confirm reveal as a followup to add these transitions within an appropriate scope.
#48.1 Regarding adding tips to the same object in
({ hasWeaknesses }, tips) =>, the{ hasWeaknesses }is a string that is destructured from the fullpasswordSettingsobject, whiletipsis a value that varies depending on what the aspiring password needs. It seems more appropriate to me to keep the passwordSettings and dynamic values separate, but open to hearing why it may be more beneficial to combine them in a single object.#48.2 items are reviewed.
Comment #50
lauriiiThank you for explaining #48.1 and sorry for the rushed review. I somehow thought it was an options object and I thought we could have used it for passing the tips too.
Confirmed that #49 addresses #47 and #48 so moving back to RTBC.
Comment #52
lauriiiComment #53
effulgentsia commented#49 looks great. This just fixes some coding standards violations.
Comment #54
effulgentsia commentedRemoving credit from myself (#53 interdiff is too trivial), and adding credit to @alexpott for #43.
Comment #56
effulgentsia commentedPushed to 9.1.x. Great work on this!