From 7df9e006501c8f545da8b50e0d09b6fc369b31fe Mon Sep 17 00:00:00 2001 From: sideshowbarker Date: Mon, 3 Mar 2025 18:16:31 +0900 Subject: [PATCH] LibWeb: Implement HTMLInputElement type=email constraint validation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change implements HTMLInputElement type=email constraint validation in conformance with the current spec requirements (which happens to also produce behavior that’s interoperable with other existing engines). --- Libraries/LibWeb/HTML/HTMLInputElement.cpp | 19 +++++++++++++++++-- .../form-validation-checkValidity.txt | 8 ++++---- .../form-validation-validity-typeMismatch.txt | 9 ++++----- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 6ed8ac531e3..552cab2a37c 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -3042,6 +3042,9 @@ bool HTMLInputElement::suffering_from_being_missing() const return false; } +// https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address +static Regex const valid_email_address_regex = Regex("^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"); + // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#suffering-from-a-type-mismatch bool HTMLInputElement::suffering_from_a_type_mismatch() const { @@ -3056,8 +3059,20 @@ bool HTMLInputElement::suffering_from_a_type_mismatch() const return !input.is_empty() && !URL::Parser::basic_parse(input).has_value(); case TypeAttributeState::Email: // https://html.spec.whatwg.org/multipage/input.html#email-state-(type%3Demail)%3Asuffering-from-a-type-mismatch - // While the value of the element is neither the empty string nor a single valid email address, the element is suffering from a type mismatch. - // FIXME: Implement this. + // When the multiple attribute is not specified on the element: While the value of the element is neither the + // empty string nor a single valid email address, the element is suffering from a type mismatch. + if (!has_attribute(HTML::AttributeNames::multiple)) + return !input.is_empty() && !valid_email_address_regex.match(input).success; + // When the multiple attribute is specified on the element: While the value of the element is not a valid email + // address list, the element is suffering from a type mismatch. + // https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address-list + // A valid email address list is a set of comma-separated tokens, where each token is itself a valid email + // address. To obtain the list of tokens from a valid email address list, an implementation must split the + // string on commas. + for (auto& address : MUST(input.split(','))) { + if (!valid_email_address_regex.match(address).success) + return true; + } break; default: break; diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-checkValidity.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-checkValidity.txt index 2dc073bf2c5..ec3e29e01ba 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-checkValidity.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-checkValidity.txt @@ -2,8 +2,8 @@ Harness status: OK Found 130 tests -114 Pass -16 Fail +116 Pass +14 Fail Pass [INPUT in TEXT status] no constraint Pass [INPUT in TEXT status] no constraint (in a form) Pass [INPUT in TEXT status] not suffering from being too long @@ -52,8 +52,8 @@ Pass [INPUT in EMAIL status] not suffering from being too long Pass [INPUT in EMAIL status] not suffering from being too long (in a form) Pass [INPUT in EMAIL status] suffering from a pattern mismatch Pass [INPUT in EMAIL status] suffering from a pattern mismatch (in a form) -Fail [INPUT in EMAIL status] suffering from a type mismatch -Fail [INPUT in EMAIL status] suffering from a type mismatch (in a form) +Pass [INPUT in EMAIL status] suffering from a type mismatch +Pass [INPUT in EMAIL status] suffering from a type mismatch (in a form) Pass [INPUT in EMAIL status] suffering from being missing Pass [INPUT in EMAIL status] suffering from being missing (in a form) Pass [INPUT in DATETIME-LOCAL status] no constraint diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-typeMismatch.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-typeMismatch.txt index db07b781542..6057f060236 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-typeMismatch.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-typeMismatch.txt @@ -2,15 +2,14 @@ Harness status: OK Found 11 tests -8 Pass -3 Fail +11 Pass Pass [INPUT in EMAIL status] The value is empty Pass [INPUT in EMAIL status] The value is a valid email address Pass [INPUT in EMAIL status] The value is a valid email address with some white spaces. -Fail [INPUT in EMAIL status] The value is not an email address -Fail [INPUT in EMAIL status] The value contains multiple email addresses +Pass [INPUT in EMAIL status] The value is not an email address +Pass [INPUT in EMAIL status] The value contains multiple email addresses Pass [INPUT in EMAIL status] The value is valid email addresses -Fail [INPUT in EMAIL status] The value contains invalid separator +Pass [INPUT in EMAIL status] The value contains invalid separator Pass [INPUT in URL status] The value is empty Pass [INPUT in URL status] The value is a valid url Pass [INPUT in URL status] The value is a valid url with some white spaces.