From 3fd1538191b9e3f50590562cfcdedb91cdbc7baf Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Thu, 27 Feb 2025 10:13:52 +0000 Subject: [PATCH] LibWeb: Implement the `HTMLInputElement` pattern attribute --- Libraries/LibWeb/HTML/HTMLInputElement.cpp | 76 +++++++++++++++- Libraries/LibWeb/HTML/HTMLInputElement.h | 5 + Libraries/LibWeb/HTML/HTMLInputElement.idl | 2 +- .../form-validation-checkValidity.txt | 28 +++--- ...rm-validation-validity-patternMismatch.txt | 91 +++++++++++++++++++ .../input-pattern-dynamic-value.txt | 6 ++ .../the-input-element/pattern_attribute.txt | 10 ++ .../pseudo-classes/valid-invalid.txt | 12 +-- ...m-validation-validity-patternMismatch.html | 53 +++++++++++ .../input-pattern-dynamic-value.html | 17 ++++ .../the-input-element/pattern_attribute.html | 55 +++++++++++ 11 files changed, 332 insertions(+), 23 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-patternMismatch.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/input-pattern-dynamic-value.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/pattern_attribute.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-patternMismatch.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/input-pattern-dynamic-value.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/pattern_attribute.html diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 960770021e7..046c224d811 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -188,6 +189,31 @@ void HTMLInputElement::set_indeterminate(bool value) m_indeterminate = value; } +// https://html.spec.whatwg.org/multipage/input.html#compiled-pattern-regular-expression +Optional> HTMLInputElement::compiled_pattern_regular_expression() const +{ + // 1. If the element does not have a pattern attribute specified, then return nothing. The element has no compiled pattern regular expression. + auto maybe_pattern = get_attribute(HTML::AttributeNames::pattern); + if (!maybe_pattern.has_value()) + return {}; + + // 2. Let pattern be the value of the pattern attribute of the element. + auto pattern = maybe_pattern.release_value().to_byte_string(); + + // 3. Let regexpCompletion be RegExpCreate(pattern, "v"). + Regex regexp_completion(pattern, JS::RegExpObject::default_flags | ECMAScriptFlags::UnicodeSets); + + // 4. If regexpCompletion is an abrupt completion, then return nothing. The element has no compiled pattern regular expression. + if (regexp_completion.parser_result.error != regex::Error::NoError) + return {}; + + // 5. Let anchoredPattern be the string "^(?:", followed by pattern, followed by ")$". + auto anchored_pattern = ByteString::formatted("^(?:{})$", pattern); + + // 6. Return ! RegExpCreate(anchoredPattern, "v"). + return Regex(anchored_pattern, JS::RegExpObject::default_flags | ECMAScriptFlags::UnicodeSets); +} + // https://html.spec.whatwg.org/multipage/input.html#dom-input-files GC::Ptr HTMLInputElement::files() { @@ -2760,6 +2786,34 @@ bool HTMLInputElement::selection_direction_applies() const } } +// https://html.spec.whatwg.org/multipage/input.html#do-not-apply +bool HTMLInputElement::pattern_applies() const +{ + switch (type_state()) { + case TypeAttributeState::Text: + case TypeAttributeState::Search: + case TypeAttributeState::Telephone: + case TypeAttributeState::URL: + case TypeAttributeState::Email: + case TypeAttributeState::Password: + return true; + default: + return false; + } +} + +// https://html.spec.whatwg.org/multipage/input.html#do-not-apply +bool HTMLInputElement::multiple_applies() const +{ + switch (type_state()) { + case TypeAttributeState::Email: + case TypeAttributeState::FileUpload: + return true; + default: + return false; + } +} + bool HTMLInputElement::has_selectable_text() const { // Potential FIXME: Date, Month, Week, Time and LocalDateAndTime are rendered as a basic text input for now, @@ -2988,8 +3042,26 @@ bool HTMLInputElement::suffering_from_a_pattern_mismatch() const // If the element's value is not the empty string, and either the element's multiple attribute is not specified or it does not apply to the input element given its // type attribute's current state, and the element has a compiled pattern regular expression but that regular expression does not match the element's value, then the element is // suffering from a pattern mismatch. - // FIXME: Implement this. - return false; + + // FIXME: If the element's value is not the empty string, and the element's multiple attribute is specified and applies to the input element, + // and the element has a compiled pattern regular expression but that regular expression does not match each of the element's values, + // then the element is suffering from a pattern mismatch. + + if (!pattern_applies()) + return false; + + auto value = this->value(); + if (value.is_empty()) + return false; + + if (has_attribute(HTML::AttributeNames::multiple) && multiple_applies()) + return false; + + auto regexp_object = compiled_pattern_regular_expression(); + if (!regexp_object.has_value()) + return false; + + return !regexp_object->match(value).success; } // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#suffering-from-an-underflow diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.h b/Libraries/LibWeb/HTML/HTMLInputElement.h index eb4c5313946..2fad8b4d2f1 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.h +++ b/Libraries/LibWeb/HTML/HTMLInputElement.h @@ -9,6 +9,7 @@ #pragma once +#include #include #include #include @@ -215,6 +216,8 @@ public: bool select_applies() const; bool selection_or_range_applies() const; bool selection_direction_applies() const; + bool pattern_applies() const; + bool multiple_applies() const; bool has_selectable_text() const; bool supports_a_picker() const; @@ -345,6 +348,8 @@ private: GC::Ptr m_resource_request; SelectedCoordinate m_selected_coordinate; + Optional> compiled_pattern_regular_expression() const; + Optional m_load_event_delayer; // https://html.spec.whatwg.org/multipage/input.html#dom-input-indeterminate diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.idl b/Libraries/LibWeb/HTML/HTMLInputElement.idl index 94d3a9817ab..ebacce7ebec 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.idl +++ b/Libraries/LibWeb/HTML/HTMLInputElement.idl @@ -32,7 +32,7 @@ interface HTMLInputElement : HTMLElement { [CEReactions] attribute long minLength; [CEReactions, Reflect] attribute boolean multiple; [CEReactions, Reflect] attribute DOMString name; - [FIXME, CEReactions] attribute DOMString pattern; + [CEReactions, Reflect] attribute DOMString pattern; [CEReactions, Reflect] attribute DOMString placeholder; [CEReactions, Reflect=readonly] attribute boolean readOnly; [CEReactions, Reflect] attribute boolean required; 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 26fd33f3c55..ce83c6ac33b 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,46 +2,46 @@ Harness status: OK Found 130 tests -78 Pass -52 Fail +90 Pass +40 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 Pass [INPUT in TEXT status] not suffering from being too long (in a form) -Fail [INPUT in TEXT status] suffering from a pattern mismatch -Fail [INPUT in TEXT status] suffering from a pattern mismatch (in a form) +Pass [INPUT in TEXT status] suffering from a pattern mismatch +Pass [INPUT in TEXT status] suffering from a pattern mismatch (in a form) Pass [INPUT in TEXT status] suffering from being missing Pass [INPUT in TEXT status] suffering from being missing (in a form) Pass [INPUT in SEARCH status] no constraint Pass [INPUT in SEARCH status] no constraint (in a form) Pass [INPUT in SEARCH status] not suffering from being too long Pass [INPUT in SEARCH status] not suffering from being too long (in a form) -Fail [INPUT in SEARCH status] suffering from a pattern mismatch -Fail [INPUT in SEARCH status] suffering from a pattern mismatch (in a form) +Pass [INPUT in SEARCH status] suffering from a pattern mismatch +Pass [INPUT in SEARCH status] suffering from a pattern mismatch (in a form) Pass [INPUT in SEARCH status] suffering from being missing Pass [INPUT in SEARCH status] suffering from being missing (in a form) Pass [INPUT in TEL status] no constraint Pass [INPUT in TEL status] no constraint (in a form) Pass [INPUT in TEL status] not suffering from being too long Pass [INPUT in TEL status] not suffering from being too long (in a form) -Fail [INPUT in TEL status] suffering from a pattern mismatch -Fail [INPUT in TEL status] suffering from a pattern mismatch (in a form) +Pass [INPUT in TEL status] suffering from a pattern mismatch +Pass [INPUT in TEL status] suffering from a pattern mismatch (in a form) Pass [INPUT in TEL status] suffering from being missing Pass [INPUT in TEL status] suffering from being missing (in a form) Pass [INPUT in PASSWORD status] no constraint Pass [INPUT in PASSWORD status] no constraint (in a form) Pass [INPUT in PASSWORD status] not suffering from being too long Pass [INPUT in PASSWORD status] not suffering from being too long (in a form) -Fail [INPUT in PASSWORD status] suffering from a pattern mismatch -Fail [INPUT in PASSWORD status] suffering from a pattern mismatch (in a form) +Pass [INPUT in PASSWORD status] suffering from a pattern mismatch +Pass [INPUT in PASSWORD status] suffering from a pattern mismatch (in a form) Pass [INPUT in PASSWORD status] suffering from being missing Pass [INPUT in PASSWORD status] suffering from being missing (in a form) Pass [INPUT in URL status] no constraint Pass [INPUT in URL status] no constraint (in a form) Pass [INPUT in URL status] suffering from being too long Pass [INPUT in URL status] suffering from being too long (in a form) -Fail [INPUT in URL status] suffering from a pattern mismatch -Fail [INPUT in URL status] suffering from a pattern mismatch (in a form) +Pass [INPUT in URL status] suffering from a pattern mismatch +Pass [INPUT in URL status] suffering from a pattern mismatch (in a form) Fail [INPUT in URL status] suffering from a type mismatch Fail [INPUT in URL status] suffering from a type mismatch (in a form) Pass [INPUT in URL status] suffering from being missing @@ -50,8 +50,8 @@ Pass [INPUT in EMAIL status] no constraint Pass [INPUT in EMAIL status] no constraint (in a form) 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) -Fail [INPUT in EMAIL status] suffering from a pattern mismatch -Fail [INPUT in EMAIL status] suffering from a pattern mismatch (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 being missing diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-patternMismatch.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-patternMismatch.txt new file mode 100644 index 00000000000..6b413ae42ff --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-patternMismatch.txt @@ -0,0 +1,91 @@ +Harness status: OK + +Found 85 tests + +69 Pass +16 Fail +Pass [INPUT in TEXT status] The pattern attribute is not set +Pass [INPUT in TEXT status] The value attibute is empty string +Pass [INPUT in TEXT status] The value attribute matches the pattern attribute +Pass [INPUT in TEXT status] The value(ABC) in unicode attribute matches the pattern attribute +Pass [INPUT in TEXT status] The value attribute mismatches the pattern attribute +Pass [INPUT in TEXT status] The value attribute mismatches the pattern attribute even when a subset matches +Pass [INPUT in TEXT status] Invalid regular expression gets ignored +Pass [INPUT in TEXT status] Invalid `v` regular expression gets ignored +Pass [INPUT in TEXT status] The pattern attribute tries to escape a group +Fail [INPUT in TEXT status] The pattern attribute uses Unicode features +Pass [INPUT in TEXT status] The value attribute matches JavaScript-specific regular expression +Fail [INPUT in TEXT status] The value attribute mismatches JavaScript-specific regular expression +Pass [INPUT in SEARCH status] The pattern attribute is not set +Pass [INPUT in SEARCH status] The value attibute is empty string +Pass [INPUT in SEARCH status] The value attribute matches the pattern attribute +Pass [INPUT in SEARCH status] The value(ABC) in unicode attribute matches the pattern attribute +Pass [INPUT in SEARCH status] The value attribute mismatches the pattern attribute +Pass [INPUT in SEARCH status] The value attribute mismatches the pattern attribute even when a subset matches +Pass [INPUT in SEARCH status] Invalid regular expression gets ignored +Pass [INPUT in SEARCH status] Invalid `v` regular expression gets ignored +Pass [INPUT in SEARCH status] The pattern attribute tries to escape a group +Fail [INPUT in SEARCH status] The pattern attribute uses Unicode features +Pass [INPUT in SEARCH status] The value attribute matches JavaScript-specific regular expression +Fail [INPUT in SEARCH status] The value attribute mismatches JavaScript-specific regular expression +Pass [INPUT in TEL status] The pattern attribute is not set +Pass [INPUT in TEL status] The value attibute is empty string +Pass [INPUT in TEL status] The value attribute matches the pattern attribute +Pass [INPUT in TEL status] The value(ABC) in unicode attribute matches the pattern attribute +Pass [INPUT in TEL status] The value attribute mismatches the pattern attribute +Pass [INPUT in TEL status] The value attribute mismatches the pattern attribute even when a subset matches +Pass [INPUT in TEL status] Invalid regular expression gets ignored +Pass [INPUT in TEL status] Invalid `v` regular expression gets ignored +Pass [INPUT in TEL status] The pattern attribute tries to escape a group +Fail [INPUT in TEL status] The pattern attribute uses Unicode features +Pass [INPUT in TEL status] The value attribute matches JavaScript-specific regular expression +Fail [INPUT in TEL status] The value attribute mismatches JavaScript-specific regular expression +Pass [INPUT in URL status] The pattern attribute is not set +Pass [INPUT in URL status] The value attibute is empty string +Pass [INPUT in URL status] The value attribute matches the pattern attribute +Pass [INPUT in URL status] The value(ABC) in unicode attribute matches the pattern attribute +Pass [INPUT in URL status] The value attribute mismatches the pattern attribute +Pass [INPUT in URL status] The value attribute mismatches the pattern attribute even when a subset matches +Pass [INPUT in URL status] Invalid regular expression gets ignored +Pass [INPUT in URL status] Invalid `v` regular expression gets ignored +Pass [INPUT in URL status] The pattern attribute tries to escape a group +Fail [INPUT in URL status] The pattern attribute uses Unicode features +Pass [INPUT in URL status] The value attribute matches JavaScript-specific regular expression +Fail [INPUT in URL status] The value attribute mismatches JavaScript-specific regular expression +Pass [INPUT in EMAIL status] The pattern attribute is not set +Pass [INPUT in EMAIL status] The value attibute is empty string +Pass [INPUT in EMAIL status] The value attribute matches the pattern attribute +Pass [INPUT in EMAIL status] The value(ABC) in unicode attribute matches the pattern attribute +Pass [INPUT in EMAIL status] The value attribute mismatches the pattern attribute +Pass [INPUT in EMAIL status] The value attribute mismatches the pattern attribute even when a subset matches +Pass [INPUT in EMAIL status] Invalid regular expression gets ignored +Pass [INPUT in EMAIL status] Invalid `v` regular expression gets ignored +Pass [INPUT in EMAIL status] The pattern attribute tries to escape a group +Fail [INPUT in EMAIL status] The pattern attribute uses Unicode features +Pass [INPUT in EMAIL status] The value attribute matches JavaScript-specific regular expression +Fail [INPUT in EMAIL status] The value attribute mismatches JavaScript-specific regular expression +Pass [INPUT in PASSWORD status] The pattern attribute is not set +Pass [INPUT in PASSWORD status] The value attibute is empty string +Pass [INPUT in PASSWORD status] The value attribute matches the pattern attribute +Pass [INPUT in PASSWORD status] The value(ABC) in unicode attribute matches the pattern attribute +Pass [INPUT in PASSWORD status] The value attribute mismatches the pattern attribute +Pass [INPUT in PASSWORD status] The value attribute mismatches the pattern attribute even when a subset matches +Pass [INPUT in PASSWORD status] Invalid regular expression gets ignored +Pass [INPUT in PASSWORD status] Invalid `v` regular expression gets ignored +Pass [INPUT in PASSWORD status] The pattern attribute tries to escape a group +Fail [INPUT in PASSWORD status] The pattern attribute uses Unicode features +Pass [INPUT in PASSWORD status] The value attribute matches JavaScript-specific regular expression +Fail [INPUT in PASSWORD status] The value attribute mismatches JavaScript-specific regular expression +Pass [INPUT in EMAIL status] The pattern attribute is not set, if multiple is present +Pass [INPUT in EMAIL status] The value attibute is empty string, if multiple is present +Pass [INPUT in EMAIL status] The value attribute matches the pattern attribute, if multiple is present +Pass [INPUT in EMAIL status] The value(ABC) in unicode attribute matches the pattern attribute, if multiple is present +Fail [INPUT in EMAIL status] The value attribute mismatches the pattern attribute, if multiple is present +Fail [INPUT in EMAIL status] The value attribute mismatches the pattern attribute even when a subset matches, if multiple is present +Pass [INPUT in EMAIL status] Invalid regular expression gets ignored, if multiple is present +Pass [INPUT in EMAIL status] Invalid `v` regular expression gets ignored, if multiple is present +Pass [INPUT in EMAIL status] The pattern attribute tries to escape a group, if multiple is present +Pass [INPUT in EMAIL status] The pattern attribute uses Unicode features, if multiple is present +Pass [INPUT in EMAIL status] The value attribute matches JavaScript-specific regular expression, if multiple is present +Fail [INPUT in EMAIL status] The value attribute mismatches JavaScript-specific regular expression, if multiple is present +Fail [INPUT in EMAIL status] Commas should be stripped from regex input, if multiple is present \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/input-pattern-dynamic-value.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/input-pattern-dynamic-value.txt new file mode 100644 index 00000000000..4b2d788cbb9 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/input-pattern-dynamic-value.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass input validation is updated after pattern attribute change \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/pattern_attribute.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/pattern_attribute.txt new file mode 100644 index 00000000000..c90c858f2e1 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/pattern_attribute.txt @@ -0,0 +1,10 @@ +Harness status: OK + +Found 4 tests + +3 Pass +1 Fail +Pass basic support +Fail is Unicode code point-aware +Pass supports Unicode property escape syntax +Pass supports Unicode property escape syntax for properties of strings \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/selectors/pseudo-classes/valid-invalid.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/selectors/pseudo-classes/valid-invalid.txt index e0a9239feee..feb9aa6ff88 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/selectors/pseudo-classes/valid-invalid.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/selectors/pseudo-classes/valid-invalid.txt @@ -2,22 +2,22 @@ Harness status: OK Found 30 tests -18 Pass -12 Fail +22 Pass +8 Fail Pass ':valid' matches elements that satisfy their constraints Pass ':valid' matches form elements that are not the form owner of any elements that themselves are candidates for constraint validation but do not satisfy their constraints Pass ':valid' matches fieldset elements that have no descendant elements that themselves are candidates for constraint validation but do not satisfy their constraints -Fail ':valid' matches elements that satisfy their pattern constraints +Pass ':valid' matches elements that satisfy their pattern constraints Fail ':valid' matches elements that satisfy their number constraints Pass ':invalid' matches elements that do not satisfy their simple text constraints Pass ':invalid' matches form elements that are the form owner of one or more elements that themselves are candidates for constraint validation but do not satisfy their constraints Pass ':invalid' matches fieldset elements that have of one or more descendant elements that themselves are candidates for constraint validation but do not satisfy their constraints -Fail ':invalid' matches elements that do not satisfy their pattern constraints +Pass ':invalid' matches elements that do not satisfy their pattern constraints Fail ':invalid' matches elements that do not satisfy their number constraints Pass ':valid' matches new elements that satisfy their constraints Pass ':invalid' doesn't match new elements that satisfy their constraints -Fail ':valid' doesn't match new elements that do not satisfy their constraints -Fail ':invalid' matches new elements that do not satisfy their constraints +Pass ':valid' doesn't match new elements that do not satisfy their constraints +Pass ':invalid' matches new elements that do not satisfy their constraints Pass :valid/:invalid styling for
Pass empty form correctly styled on page-load Pass valid form correctly styled on page-load diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-patternMismatch.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-patternMismatch.html new file mode 100644 index 00000000000..c0e8d8d6391 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-validity-patternMismatch.html @@ -0,0 +1,53 @@ + + +The constraint validation API Test: element.validity.patternMismatch + + + + + + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/input-pattern-dynamic-value.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/input-pattern-dynamic-value.html new file mode 100644 index 00000000000..82ebd5d1dd1 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/input-pattern-dynamic-value.html @@ -0,0 +1,17 @@ + + +Pattern dynamic value attribute change + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/pattern_attribute.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/pattern_attribute.html new file mode 100644 index 00000000000..f06c5091a32 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/the-input-element/pattern_attribute.html @@ -0,0 +1,55 @@ + + +pattern attribute + + + + + + + +

pattern attribute

+
+ + + + + + +
+
+