LibWeb: Implement the HTMLInputElement pattern attribute

This commit is contained in:
Tim Ledbetter 2025-02-27 10:13:52 +00:00 committed by Andreas Kling
parent 5651701f31
commit 3fd1538191
Notes: github-actions[bot] 2025-02-27 20:47:10 +00:00
11 changed files with 332 additions and 23 deletions

View file

@ -14,6 +14,7 @@
#include <LibCore/DateTime.h>
#include <LibJS/Runtime/Date.h>
#include <LibJS/Runtime/NativeFunction.h>
#include <LibJS/Runtime/RegExpObject.h>
#include <LibWeb/Bindings/HTMLInputElementPrototype.h>
#include <LibWeb/Bindings/PrincipalHostDefined.h>
#include <LibWeb/CSS/ComputedProperties.h>
@ -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<Regex<ECMA262>> 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<ECMA262> 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<ECMA262>(anchored_pattern, JS::RegExpObject::default_flags | ECMAScriptFlags::UnicodeSets);
}
// https://html.spec.whatwg.org/multipage/input.html#dom-input-files
GC::Ptr<FileAPI::FileList> 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

View file

@ -9,6 +9,7 @@
#pragma once
#include <LibRegex/Regex.h>
#include <LibWeb/DOM/DocumentLoadEventDelayer.h>
#include <LibWeb/DOM/Text.h>
#include <LibWeb/FileAPI/FileList.h>
@ -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<SharedResourceRequest> m_resource_request;
SelectedCoordinate m_selected_coordinate;
Optional<Regex<ECMA262>> compiled_pattern_regular_expression() const;
Optional<DOM::DocumentLoadEventDelayer> m_load_event_delayer;
// https://html.spec.whatwg.org/multipage/input.html#dom-input-indeterminate

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,6 @@
Harness status: OK
Found 1 tests
1 Pass
Pass input validation is updated after pattern attribute change

View file

@ -0,0 +1,10 @@
Harness status: OK
Found 4 tests
3 Pass
1 Fail
Pass basic <input pattern> support
Fail <input pattern> is Unicode code point-aware
Pass <input pattern> supports Unicode property escape syntax
Pass <input pattern> supports Unicode property escape syntax for properties of strings

View file

@ -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 <form>
Pass empty form correctly styled on page-load
Pass valid form correctly styled on page-load

View file

@ -0,0 +1,53 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>The constraint validation API Test: element.validity.patternMismatch</title>
<link rel="author" title="Intel" href="http://www.intel.com/">
<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-validitystate-patternmismatch">
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<script src="support/validator.js"></script>
<div id="log"></div>
<script>
var testElements = [
{
tag: "input",
types: ["text", "search", "tel", "url", "email", "password"],
testData: [
{conditions: {pattern: null, value: "abc"}, expected: false, name: "[target] The pattern attribute is not set"},
{conditions: {pattern: "[A-Z]+", value: ""}, expected: false, name: "[target] The value attibute is empty string"},
{conditions: {pattern: "[A-Z]{1}", value: "A"}, expected: false, name: "[target] The value attribute matches the pattern attribute"},
{conditions: {pattern: "[A-Z]+", value: "\x41\x42\x43"}, expected: false, name: "[target] The value(ABC) in unicode attribute matches the pattern attribute"},
{conditions: {pattern: "[a-z]{3,}", value: "ABCD"}, expected: true, name: "[target] The value attribute mismatches the pattern attribute"},
{conditions: {pattern: "[A-Z]+", value: "ABC123"}, expected: true, name: "[target] The value attribute mismatches the pattern attribute even when a subset matches"},
{conditions: {pattern: "(abc", value: "de"}, expected: false, name: "[target] Invalid regular expression gets ignored"},
{conditions: {pattern: "[(]", value: "x"}, expected: false, name: "[target] Invalid `v` regular expression gets ignored"},
{conditions: {pattern: "a)(b", value: "de"}, expected: false, name: "[target] The pattern attribute tries to escape a group"},
{conditions: {pattern: "a\\u{10FFFF}", value: "a\u{10FFFF}"}, expected: false, name: "[target] The pattern attribute uses Unicode features"},
{conditions: {pattern: "\\u1234\\cx[5-\\[]{2}", value: "\u1234\x18[6"}, expected: false, name: "[target] The value attribute matches JavaScript-specific regular expression"},
{conditions: {pattern: "\\u1234\\cx[5-\\[]{2}", value: "\u1234\x18[4"}, expected: true, name: "[target] The value attribute mismatches JavaScript-specific regular expression"},
]
},
{
tag: "input",
types: ["email"],
testData: [
{conditions: {multiple: true, pattern: null, value: "abc,abc"}, expected: false, name: "[target] The pattern attribute is not set, if multiple is present"},
{conditions: {multiple: true, pattern: "[A-Z]+", value: ""}, expected: false, name: "[target] The value attibute is empty string, if multiple is present"},
{conditions: {multiple: true, pattern: "[A-Z]{1}", value: "A,A"}, expected: false, name: "[target] The value attribute matches the pattern attribute, if multiple is present"},
{conditions: {multiple: true, pattern: "[A-Z]+", value: "\x41\x42\x43,\x41\x42\x43"}, expected: false, name: "[target] The value(ABC) in unicode attribute matches the pattern attribute, if multiple is present"},
{conditions: {multiple: true, pattern: "[a-z]{3,}", value: "abcd,ABCD"}, expected: true, name: "[target] The value attribute mismatches the pattern attribute, if multiple is present"},
{conditions: {multiple: true, pattern: "[A-Z]+", value: "ABCD,ABC123"}, expected: true, name: "[target] The value attribute mismatches the pattern attribute even when a subset matches, if multiple is present"},
{conditions: {multiple: true, pattern: "(abc", value: "de,de"}, expected: false, name: "[target] Invalid regular expression gets ignored, if multiple is present"},
{conditions: {multiple: true, pattern: "[(]", value: "x"}, expected: false, name: "[target] Invalid `v` regular expression gets ignored, if multiple is present"},
{conditions: {multiple: true, pattern: "a)(b", value: "de,de"}, expected: false, name: "[target] The pattern attribute tries to escape a group, if multiple is present"},
{conditions: {multiple: true, pattern: "a\\u{10FFFF}", value: "a\u{10FFFF},a\u{10FFFF}"}, expected: false, name: "[target] The pattern attribute uses Unicode features, if multiple is present"},
{conditions: {multiple: true, pattern: "\\u1234\\cx[5-\\[]{2}", value: "\u1234\x18[6,\u1234\x18[Z"}, expected: false, name: "[target] The value attribute matches JavaScript-specific regular expression, if multiple is present"},
{conditions: {multiple: true, pattern: "\\u1234\\cx[5-\\[]{2}", value: "\u1234\x18[4,\u1234\x18[6"}, expected: true, name: "[target] The value attribute mismatches JavaScript-specific regular expression, if multiple is present"},
{conditions: {multiple: true, pattern: "a,", value: "a,"}, expected: true, name: "[target] Commas should be stripped from regex input, if multiple is present"},
]
}
];
validator.run_test (testElements, "patternMismatch");
</script>

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Pattern dynamic value attribute change</title>
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1636495">
<input pattern="a" value="a">
<script>
test(function() {
let i = document.querySelector("input");
assert_false(i.matches(":invalid"));
i.pattern = "b";
assert_true(i.matches(":invalid"));
i.pattern = "(";
assert_false(i.matches(":invalid"));
}, "input validation is updated after pattern attribute change");
</script>

View file

@ -0,0 +1,55 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>pattern attribute</title>
<meta name=viewport content="width=device-width">
<link rel="author" title="Fabrice Clari" href="mailto:f.clari@inno-group.com">
<link rel="author" title="Dimitri Bocquet" href="mailto:Dimitri.Bocquet@mosquito-fp7.eu">
<link rel="author" title="Mathias Bynens" href="https://mathiasbynens.be/">
<link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-input-pattern">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<h1><code>pattern</code> attribute</h1>
<div style="display: none">
<input pattern="[a-z]{3}" value="abcd" id="basic">
<input pattern="a.b" value="a&#x1D306;b" id="unicode-code-points">
<input pattern="\p{ASCII_Hex_Digit}+" value="c0ff33" id="unicode-property">
<input pattern="\p{RGI_Emoji}+" value="&#x1F618;&#x1F48B;" id="unicode-property-of-strings">
</div>
<div id="log"></div>
<script>
test(() => {
const input = document.querySelector("#basic");
assert_idl_attribute(input, "pattern");
assert_equals(input.pattern, "[a-z]{3}");
assert_inherits(input, "validity");
assert_false(input.validity.valid);
assert_true(input.validity.patternMismatch);
assert_true(input.matches(":invalid"));
}, "basic <input pattern> support");
test(() => {
const input = document.querySelector("#unicode-code-points");
assert_true(input.validity.valid);
assert_true(input.matches(":valid"));
assert_false(input.validity.patternMismatch);
}, "<input pattern> is Unicode code point-aware");
test(() => {
const input = document.querySelector("#unicode-property");
assert_true(input.validity.valid);
assert_true(input.matches(":valid"));
assert_false(input.validity.patternMismatch);
}, "<input pattern> supports Unicode property escape syntax");
test(() => {
const input = document.querySelector("#unicode-property-of-strings");
assert_true(input.validity.valid);
assert_true(input.matches(":valid"));
assert_false(input.validity.patternMismatch);
}, "<input pattern> supports Unicode property escape syntax for properties of strings");
</script>