backdrop / backdrop-issues

Issue tracker for Backdrop core.
144 stars 40 forks source link

[DX][UX][D8] Form API: Automatically trim leading/trailing whitespace from all text input fields by default #5381

Open klonos opened 2 years ago

klonos commented 2 years ago

This is a follow-up to #5348 and the respective of https://www.drupal.org/project/drupal/issues/67769

Problem

  • Form handlers and API code manually calls trim() on values too many times.
  • It's unclear who is responsible for trimming text values / user input.
  • The lack of custom trim() calls can trigger error messages that are hard to recognize and resolve by a user, in case a submitted form value contains leading or trailing white-space (which is not visible/apparent).

Proposed solution

  1. Introduce a generic #trim property for all form elements that accept #input.
  2. Make #trim default to TRUE for all form element types that accept text as user input.
  3. Process #trim directly in form_handle_input_element(). If the resulting #value is an empty string, trigger the regular processing flow that would be triggered for no user input - including #required validation.
  4. Allow code that does not want this behavior to opt-out by setting #trim to FALSE. (There's no use-case for that in core, but still...)
  5. Remove all manual calls of trim() from API code. Whoever is calling into APIs is expected to provide proper (trimmed) values.

Original summary

If the user registers and by mistake includes and extra space before or after their email address, the system will reject the email address with an error message that is difficult to understand (as there is nothing obviously wrong with the email address). I have seen this several times when I paste my email address into the email address box and mistakenly include a trailing space. I just tried it on the Drupal.org site and got the error:

The e-mail address testaccount@test.org is not valid.

My guess is that this problem might affect 2-3% of all users who ever try to set up Drupal accounts and leave them a bit frustrated.

It would be very easy to have the form on the page user/register trim the spaces off of the email address, to solve this problem.

quicksketch commented 2 years ago

Thanks @klonos, interesting suggestion here. This does trip me up from time to time. In reviewing the code, it seems a little magical that the values are trimmed before the #element_validate callbacks are called. Though with proper documentation of the new FormAPI #trim property I don't think that should be a hold-up.

klonos commented 2 years ago

Sorry @quicksketch ...the PR is not ready for review yet. I've been cleaning up trim() incrementally (module-by-module or file-file), so to be able to fix any failing tests easily as they may come up. I'm not done with that yet.

In the PR, you've asked: "Why no #trim on $types['password']?". Well I have intentionally left that out for a couple of reasons:

klonos commented 2 years ago

...by the way, did some further research on passwords and password fields, and I've found that we are in fact trimming leading/trailing whitespace in places like:

Still, I'll wait for more feedback before adding auto-trimming to password form elements and password validation/submission handlers.

quicksketch commented 2 years ago

did some further research on passwords and password fields, and I've found that we are in fact trimming leading/trailing whitespace in places like:

Good to hear that we're already doing trimming on passwords.

I wanted to get more feedback re the possibility of legitimate cases of passwords having leading/trailing spaces. If we trimmed those out, we'd break the login process for user accounts that intentionally use spaces that way. So thoughts on that anyone?

I don't think we should consider this a legitimate use-case. Empty spaces happen accidentally all the time when copy/pasting and we will help a lot more users by trimming the input that we would allowing it for the oddball case that intentionally wants a space at the beginning or end of their password (spaces in the middle are still fine). Worst-case scenario for such users would be they would need to do a password reset.

klonos commented 2 years ago

That's fine then @quicksketch 👍🏼 ...I've implemented the default trimming to form elements of '#type' => 'password' and '#type' => 'password_confirm' with backdrop/backdrop@111d2c3 (#3845) + more cleanup coming in other commits for module-specific form submissions/validations (such as in user.admin.inc and user.module).

Still WIP, as I'm going through each module one at a time, fixing any test failures along the way.

klonos commented 1 year ago

I have started working on this again (need to fix remaining test failures), but in the meantime I wanted to ask this: besides apparent input fields (those exposed to actual user input), should we also be automatically trimming the following types of fields?

I think so, but I'd like feedback from others.

bugfolder commented 1 year ago

How about making the value of #trim the name of the trimming function. Then it could be trim for ordinary trimming, but if someone had a custom trimmer (like, removing leading or trailing / from a path) they could use the name of that function.

klonos commented 1 year ago

Great suggestion @bugfolder! Thanks 👍🏼

Noting that trim() without any additional parameters removes whitespace (regular spaces, tabs, line returns etc.), but you can pass a series of characters as an additional pararameter. See: https://www.php.net/manual/en/function.trim.php

So, in the case of wanting to trim /s from the start/end of paths, you can do trim($path, '/').

bugfolder commented 1 year ago

This may be getting too baroque, but could this property also accept array('trim', '/') (more generally, array($func, $args) to accomplish the latter? Or do we just ask the user to create a function path_trim() (or we provide backdrop_path_trim()) and then they use that.

klonos commented 1 year ago

Yes, we have already existing patterns like #validate and #validation_arguments (although that one is for internal usage). So we could have something similar for trimming.

jenlampton commented 1 year ago

besides apparent input fields (those exposed to actual user input), should we also be automatically trimming the following types of fields?

I don't think we should be trimming whitespace on anything that can't be edited. We're trying to help people who put in the spaces accidentally, and you can't have that accident if you can't edit the form element. :)