mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 12:19:54 +00:00
LibWeb/HTML: Implement report_validity
Some checks are pending
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (arm64, macos-15, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (x86_64, ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Some checks are pending
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (arm64, macos-15, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (x86_64, ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
This implements the previously stubbed out `report_validity` method. The specification is not very clear on how to exactly report the validity. For now, we bring the first visible invalid control into view and focus it. In the future, however, it would make sense to support more complex scenarios and be more aligned with the other implementations.
This commit is contained in:
parent
296d9d74d8
commit
5c578b6057
Notes:
github-actions[bot]
2025-05-13 21:40:10 +00:00
Author: https://github.com/skyz1
Commit: 5c578b6057
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4578
Reviewed-by: https://github.com/Psychpsyo
Reviewed-by: https://github.com/shannonbooth ✅
11 changed files with 363 additions and 7 deletions
|
@ -13,6 +13,7 @@
|
||||||
#include <LibWeb/DOM/Event.h>
|
#include <LibWeb/DOM/Event.h>
|
||||||
#include <LibWeb/DOM/Position.h>
|
#include <LibWeb/DOM/Position.h>
|
||||||
#include <LibWeb/DOM/SelectionchangeEventDispatching.h>
|
#include <LibWeb/DOM/SelectionchangeEventDispatching.h>
|
||||||
|
#include <LibWeb/HTML/Focus.h>
|
||||||
#include <LibWeb/HTML/FormAssociatedElement.h>
|
#include <LibWeb/HTML/FormAssociatedElement.h>
|
||||||
#include <LibWeb/HTML/HTMLButtonElement.h>
|
#include <LibWeb/HTML/HTMLButtonElement.h>
|
||||||
#include <LibWeb/HTML/HTMLDataListElement.h>
|
#include <LibWeb/HTML/HTMLDataListElement.h>
|
||||||
|
@ -248,6 +249,36 @@ bool FormAssociatedElement::check_validity_steps()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#report-validity-steps
|
||||||
|
bool FormAssociatedElement::report_validity_steps()
|
||||||
|
{
|
||||||
|
// 1. If element is a candidate for constraint validation and does not satisfy its constraints, then:
|
||||||
|
if (is_candidate_for_constraint_validation() && !satisfies_its_constraints()) {
|
||||||
|
auto& element = form_associated_element_to_html_element();
|
||||||
|
// 1. Let report be the result of firing an event named invalid at element, with the cancelable attribute initialized to true.
|
||||||
|
auto report = element.dispatch_event(DOM::Event::create(element.realm(), EventNames::invalid, { .cancelable = true }));
|
||||||
|
|
||||||
|
// 2. If report is true, then report the problems with the constraints of this element to the user. When reporting the problem with the constraints to the user,
|
||||||
|
// the user agent may run the focusing steps for element, and may change the scrolling position of the document, or perform some other action that brings
|
||||||
|
// element to the user's attention. User agents may report more than one constraint violation, if element suffers from multiple problems at once.
|
||||||
|
// FIXME: Does this align with other browsers?
|
||||||
|
if (report && element.check_visibility({})) {
|
||||||
|
run_focusing_steps(&element);
|
||||||
|
DOM::ScrollIntoViewOptions scroll_options;
|
||||||
|
scroll_options.block = Bindings::ScrollLogicalPosition::Nearest;
|
||||||
|
scroll_options.inline_ = Bindings::ScrollLogicalPosition::Nearest;
|
||||||
|
scroll_options.behavior = Bindings::ScrollBehavior::Instant;
|
||||||
|
(void)element.scroll_into_view(scroll_options);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Return false.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Return true.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#candidate-for-constraint-validation
|
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#candidate-for-constraint-validation
|
||||||
bool FormAssociatedElement::is_candidate_for_constraint_validation() const
|
bool FormAssociatedElement::is_candidate_for_constraint_validation() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -101,6 +101,9 @@ public:
|
||||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#check-validity-steps
|
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#check-validity-steps
|
||||||
bool check_validity_steps();
|
bool check_validity_steps();
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#report-validity-steps
|
||||||
|
bool report_validity_steps();
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#candidate-for-constraint-validation
|
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#candidate-for-constraint-validation
|
||||||
bool is_candidate_for_constraint_validation() const;
|
bool is_candidate_for_constraint_validation() const;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <LibWeb/DOMURL/DOMURL.h>
|
#include <LibWeb/DOMURL/DOMURL.h>
|
||||||
#include <LibWeb/HTML/BrowsingContext.h>
|
#include <LibWeb/HTML/BrowsingContext.h>
|
||||||
#include <LibWeb/HTML/EventNames.h>
|
#include <LibWeb/HTML/EventNames.h>
|
||||||
|
#include <LibWeb/HTML/Focus.h>
|
||||||
#include <LibWeb/HTML/FormControlInfrastructure.h>
|
#include <LibWeb/HTML/FormControlInfrastructure.h>
|
||||||
#include <LibWeb/HTML/HTMLButtonElement.h>
|
#include <LibWeb/HTML/HTMLButtonElement.h>
|
||||||
#include <LibWeb/HTML/HTMLDialogElement.h>
|
#include <LibWeb/HTML/HTMLDialogElement.h>
|
||||||
|
@ -599,6 +600,41 @@ HTMLFormElement::StaticValidationResult HTMLFormElement::statically_validate_con
|
||||||
return { false, unhandled_invalid_controls };
|
return { false, unhandled_invalid_controls };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#interactively-validate-the-constraints
|
||||||
|
bool HTMLFormElement::interactively_validate_constraints()
|
||||||
|
{
|
||||||
|
// 1. Statically validate the constraints of form, and let unhandled invalid controls be the list of elements returned if the result was negative.
|
||||||
|
// 2. If the result was positive, then return that result.
|
||||||
|
auto static_validation_result = statically_validate_constraints();
|
||||||
|
if (static_validation_result.result)
|
||||||
|
return true;
|
||||||
|
auto unhandled_invalid_controls = static_validation_result.unhandled_invalid_controls;
|
||||||
|
|
||||||
|
// 3. Report the problems with the constraints of at least one of the elements given in unhandled invalid controls to the user.
|
||||||
|
// - User agents may focus one of those elements in the process, by running the focusing steps for that element, and may change the
|
||||||
|
// scrolling position of the document, or perform some other action that brings the element to the user's attention.
|
||||||
|
// For elements that are form-associated custom elements, user agents should use their validation anchor instead, for the purposes of these actions.
|
||||||
|
// - User agents may report more than one constraint violation.
|
||||||
|
// - User agents may coalesce related constraint violation reports if appropriate (e.g. if multiple radio buttons in a group are marked as required, only one error need be reported).
|
||||||
|
// - If one of the controls is not being rendered (e.g. it has the hidden attribute set) then user agents may report a script error.
|
||||||
|
// FIXME: Does this align with other browsers?
|
||||||
|
auto first_invalid_control = unhandled_invalid_controls.first_matching([](auto control) {
|
||||||
|
return control->check_visibility({});
|
||||||
|
});
|
||||||
|
if (first_invalid_control.has_value()) {
|
||||||
|
auto control = first_invalid_control.release_value();
|
||||||
|
run_focusing_steps(control);
|
||||||
|
DOM::ScrollIntoViewOptions scroll_options;
|
||||||
|
scroll_options.block = Bindings::ScrollLogicalPosition::Nearest;
|
||||||
|
scroll_options.inline_ = Bindings::ScrollLogicalPosition::Nearest;
|
||||||
|
scroll_options.behavior = Bindings::ScrollBehavior::Instant;
|
||||||
|
(void)control->scroll_into_view(scroll_options);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Return a negative result.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-form-checkvalidity
|
// https://html.spec.whatwg.org/multipage/forms.html#dom-form-checkvalidity
|
||||||
WebIDL::ExceptionOr<bool> HTMLFormElement::check_validity()
|
WebIDL::ExceptionOr<bool> HTMLFormElement::check_validity()
|
||||||
{
|
{
|
||||||
|
@ -608,8 +644,7 @@ WebIDL::ExceptionOr<bool> HTMLFormElement::check_validity()
|
||||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-form-reportvalidity
|
// https://html.spec.whatwg.org/multipage/forms.html#dom-form-reportvalidity
|
||||||
WebIDL::ExceptionOr<bool> HTMLFormElement::report_validity()
|
WebIDL::ExceptionOr<bool> HTMLFormElement::report_validity()
|
||||||
{
|
{
|
||||||
dbgln("(STUBBED) HTMLFormElement::report_validity(). Called on: {}", debug_description());
|
return interactively_validate_constraints();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/forms.html#category-submit
|
// https://html.spec.whatwg.org/multipage/forms.html#category-submit
|
||||||
|
|
|
@ -84,6 +84,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
StaticValidationResult statically_validate_constraints();
|
StaticValidationResult statically_validate_constraints();
|
||||||
|
bool interactively_validate_constraints();
|
||||||
WebIDL::ExceptionOr<bool> check_validity();
|
WebIDL::ExceptionOr<bool> check_validity();
|
||||||
WebIDL::ExceptionOr<bool> report_validity();
|
WebIDL::ExceptionOr<bool> report_validity();
|
||||||
|
|
||||||
|
|
|
@ -2785,8 +2785,7 @@ WebIDL::ExceptionOr<bool> HTMLInputElement::check_validity()
|
||||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-reportvalidity
|
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-reportvalidity
|
||||||
WebIDL::ExceptionOr<bool> HTMLInputElement::report_validity()
|
WebIDL::ExceptionOr<bool> HTMLInputElement::report_validity()
|
||||||
{
|
{
|
||||||
dbgln("(STUBBED) HTMLInputElement::report_validity(). Called on: {}", debug_description());
|
return report_validity_steps();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<ARIA::Role> HTMLInputElement::default_role() const
|
Optional<ARIA::Role> HTMLInputElement::default_role() const
|
||||||
|
|
|
@ -711,6 +711,12 @@ bool HTMLSelectElement::check_validity()
|
||||||
return check_validity_steps();
|
return check_validity_steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-reportvalidity
|
||||||
|
bool HTMLSelectElement::report_validity()
|
||||||
|
{
|
||||||
|
return report_validity_steps();
|
||||||
|
}
|
||||||
|
|
||||||
bool HTMLSelectElement::is_focusable() const
|
bool HTMLSelectElement::is_focusable() const
|
||||||
{
|
{
|
||||||
return enabled();
|
return enabled();
|
||||||
|
|
|
@ -63,6 +63,7 @@ public:
|
||||||
|
|
||||||
bool will_validate();
|
bool will_validate();
|
||||||
bool check_validity();
|
bool check_validity();
|
||||||
|
bool report_validity();
|
||||||
|
|
||||||
// ^EventTarget
|
// ^EventTarget
|
||||||
// https://html.spec.whatwg.org/multipage/interaction.html#the-tabindex-attribute:the-select-element
|
// https://html.spec.whatwg.org/multipage/interaction.html#the-tabindex-attribute:the-select-element
|
||||||
|
|
|
@ -35,7 +35,7 @@ interface HTMLSelectElement : HTMLElement {
|
||||||
readonly attribute ValidityState validity;
|
readonly attribute ValidityState validity;
|
||||||
[FIXME] readonly attribute DOMString validationMessage;
|
[FIXME] readonly attribute DOMString validationMessage;
|
||||||
boolean checkValidity();
|
boolean checkValidity();
|
||||||
[FIXME] boolean reportValidity();
|
boolean reportValidity();
|
||||||
undefined setCustomValidity(DOMString error);
|
undefined setCustomValidity(DOMString error);
|
||||||
|
|
||||||
undefined showPicker();
|
undefined showPicker();
|
||||||
|
|
|
@ -248,8 +248,7 @@ bool HTMLTextAreaElement::check_validity()
|
||||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-reportvalidity
|
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-reportvalidity
|
||||||
bool HTMLTextAreaElement::report_validity()
|
bool HTMLTextAreaElement::report_validity()
|
||||||
{
|
{
|
||||||
dbgln("(STUBBED) HTMLTextAreaElement::report_validity(). Called on: {}", debug_description());
|
return report_validity_steps();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-textarea-maxlength
|
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-textarea-maxlength
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 130 tests
|
||||||
|
|
||||||
|
130 Pass
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
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] not suffering from being too long
|
||||||
|
Pass [INPUT in URL status] not suffering from being too long (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)
|
||||||
|
Pass [INPUT in URL status] suffering from a type mismatch
|
||||||
|
Pass [INPUT in URL status] suffering from a type mismatch (in a form)
|
||||||
|
Pass [INPUT in URL status] suffering from being missing
|
||||||
|
Pass [INPUT in URL status] suffering from being missing (in a form)
|
||||||
|
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)
|
||||||
|
Pass [INPUT in EMAIL status] suffering from a pattern mismatch
|
||||||
|
Pass [INPUT in EMAIL status] suffering from a pattern 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
|
||||||
|
Pass [INPUT in DATETIME-LOCAL status] no constraint (in a form)
|
||||||
|
Pass [INPUT in DATETIME-LOCAL status] suffering from an overflow
|
||||||
|
Pass [INPUT in DATETIME-LOCAL status] suffering from an overflow (in a form)
|
||||||
|
Pass [INPUT in DATETIME-LOCAL status] suffering from an underflow
|
||||||
|
Pass [INPUT in DATETIME-LOCAL status] suffering from an underflow (in a form)
|
||||||
|
Pass [INPUT in DATETIME-LOCAL status] suffering from a step mismatch
|
||||||
|
Pass [INPUT in DATETIME-LOCAL status] suffering from a step mismatch (in a form)
|
||||||
|
Pass [INPUT in DATETIME-LOCAL status] suffering from being missing
|
||||||
|
Pass [INPUT in DATETIME-LOCAL status] suffering from being missing (in a form)
|
||||||
|
Pass [INPUT in DATE status] no constraint
|
||||||
|
Pass [INPUT in DATE status] no constraint (in a form)
|
||||||
|
Pass [INPUT in DATE status] suffering from an overflow
|
||||||
|
Pass [INPUT in DATE status] suffering from an overflow (in a form)
|
||||||
|
Pass [INPUT in DATE status] suffering from an underflow
|
||||||
|
Pass [INPUT in DATE status] suffering from an underflow (in a form)
|
||||||
|
Pass [INPUT in DATE status] suffering from a step mismatch
|
||||||
|
Pass [INPUT in DATE status] suffering from a step mismatch (in a form)
|
||||||
|
Pass [INPUT in DATE status] suffering from being missing
|
||||||
|
Pass [INPUT in DATE status] suffering from being missing (in a form)
|
||||||
|
Pass [INPUT in MONTH status] no constraint
|
||||||
|
Pass [INPUT in MONTH status] no constraint (in a form)
|
||||||
|
Pass [INPUT in MONTH status] suffering from an overflow
|
||||||
|
Pass [INPUT in MONTH status] suffering from an overflow (in a form)
|
||||||
|
Pass [INPUT in MONTH status] suffering from an underflow
|
||||||
|
Pass [INPUT in MONTH status] suffering from an underflow (in a form)
|
||||||
|
Pass [INPUT in MONTH status] suffering from a step mismatch
|
||||||
|
Pass [INPUT in MONTH status] suffering from a step mismatch (in a form)
|
||||||
|
Pass [INPUT in MONTH status] suffering from being missing
|
||||||
|
Pass [INPUT in MONTH status] suffering from being missing (in a form)
|
||||||
|
Pass [INPUT in WEEK status] no constraint
|
||||||
|
Pass [INPUT in WEEK status] no constraint (in a form)
|
||||||
|
Pass [INPUT in WEEK status] suffering from an overflow
|
||||||
|
Pass [INPUT in WEEK status] suffering from an overflow (in a form)
|
||||||
|
Pass [INPUT in WEEK status] suffering from an underflow
|
||||||
|
Pass [INPUT in WEEK status] suffering from an underflow (in a form)
|
||||||
|
Pass [INPUT in WEEK status] suffering from a step mismatch
|
||||||
|
Pass [INPUT in WEEK status] suffering from a step mismatch (in a form)
|
||||||
|
Pass [INPUT in WEEK status] suffering from being missing
|
||||||
|
Pass [INPUT in WEEK status] suffering from being missing (in a form)
|
||||||
|
Pass [INPUT in TIME status] no constraint
|
||||||
|
Pass [INPUT in TIME status] no constraint (in a form)
|
||||||
|
Pass [INPUT in TIME status] suffering from an overflow
|
||||||
|
Pass [INPUT in TIME status] suffering from an overflow (in a form)
|
||||||
|
Pass [INPUT in TIME status] suffering from an underflow
|
||||||
|
Pass [INPUT in TIME status] suffering from an underflow (in a form)
|
||||||
|
Pass [INPUT in TIME status] suffering from a step mismatch
|
||||||
|
Pass [INPUT in TIME status] suffering from a step mismatch (in a form)
|
||||||
|
Pass [INPUT in TIME status] suffering from being missing
|
||||||
|
Pass [INPUT in TIME status] suffering from being missing (in a form)
|
||||||
|
Pass [INPUT in NUMBER status] suffering from an overflow
|
||||||
|
Pass [INPUT in NUMBER status] suffering from an overflow (in a form)
|
||||||
|
Pass [INPUT in NUMBER status] suffering from an underflow
|
||||||
|
Pass [INPUT in NUMBER status] suffering from an underflow (in a form)
|
||||||
|
Pass [INPUT in NUMBER status] suffering from a step mismatch
|
||||||
|
Pass [INPUT in NUMBER status] suffering from a step mismatch (in a form)
|
||||||
|
Pass [INPUT in NUMBER status] suffering from being missing
|
||||||
|
Pass [INPUT in NUMBER status] suffering from being missing (in a form)
|
||||||
|
Pass [INPUT in CHECKBOX status] no constraint
|
||||||
|
Pass [INPUT in CHECKBOX status] no constraint (in a form)
|
||||||
|
Pass [INPUT in CHECKBOX status] suffering from being missing
|
||||||
|
Pass [INPUT in CHECKBOX status] suffering from being missing (in a form)
|
||||||
|
Pass [INPUT in RADIO status] no constraint
|
||||||
|
Pass [INPUT in RADIO status] no constraint (in a form)
|
||||||
|
Pass [INPUT in RADIO status] suffering from being missing
|
||||||
|
Pass [INPUT in RADIO status] suffering from being missing (in a form)
|
||||||
|
Pass [INPUT in FILE status] no constraint
|
||||||
|
Pass [INPUT in FILE status] no constraint (in a form)
|
||||||
|
Pass [INPUT in FILE status] suffering from being missing
|
||||||
|
Pass [INPUT in FILE status] suffering from being missing (in a form)
|
||||||
|
Pass [select] no constraint
|
||||||
|
Pass [select] no constraint (in a form)
|
||||||
|
Pass [select] suffering from being missing
|
||||||
|
Pass [select] suffering from being missing (in a form)
|
||||||
|
Pass [textarea] no constraint
|
||||||
|
Pass [textarea] no constraint (in a form)
|
||||||
|
Pass [textarea] suffering from being missing
|
||||||
|
Pass [textarea] suffering from being missing (in a form)
|
|
@ -0,0 +1,146 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="timeout" content="long">
|
||||||
|
<title>The constraint validation API Test: element.reportValidity()</title>
|
||||||
|
<link rel="author" title="Intel" href="http://www.intel.com/">
|
||||||
|
<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-cva-reportvalidity">
|
||||||
|
<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", "password"],
|
||||||
|
testData: [
|
||||||
|
{conditions: {}, expected: true, name: "[target] no constraint"},
|
||||||
|
{conditions: {maxLength: "4", value: "abcdef"}, expected: true, name: "[target] not suffering from being too long", dirty: true},
|
||||||
|
{conditions: {pattern: "[A-Z]", value: "abc"}, expected: false, name: "[target] suffering from a pattern mismatch"},
|
||||||
|
{conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: "input",
|
||||||
|
types: ["url"],
|
||||||
|
testData: [
|
||||||
|
{conditions: {}, expected: true, name: "[target] no constraint"},
|
||||||
|
{conditions: {maxLength: "20", value: "http://www.example.com"}, expected: true, name: "[target] not suffering from being too long", dirty: true},
|
||||||
|
{conditions: {pattern: "http://www.example.com", value: "http://www.example.net"}, expected: false, name: "[target] suffering from a pattern mismatch"},
|
||||||
|
{conditions: {value: "abc"}, expected: false, name: "[target] suffering from a type mismatch"},
|
||||||
|
{conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: "input",
|
||||||
|
types: ["email"],
|
||||||
|
testData: [
|
||||||
|
{conditions: {}, expected: true, name: "[target] no constraint"},
|
||||||
|
{conditions: {maxLength: "10", value: "test@example.com"}, expected: true, name: "[target] not suffering from being too long", dirty: true},
|
||||||
|
{conditions: {pattern: "test@example.com", value: "test@example.net"}, expected: false, name: "[target] suffering from a pattern mismatch"},
|
||||||
|
{conditions: {value: "abc"}, expected: false, name: "[target] suffering from a type mismatch"},
|
||||||
|
{conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: "input",
|
||||||
|
types: ["datetime-local"],
|
||||||
|
testData: [
|
||||||
|
{conditions: {}, expected: true, name: "[target] no constraint"},
|
||||||
|
{conditions: {max: "2000-01-01T12:00:00", value: "2001-01-01T12:00:00"}, expected: false, name: "[target] suffering from an overflow"},
|
||||||
|
{conditions: {min: "2001-01-01T12:00:00", value: "2000-01-01T12:00:00"}, expected: false, name: "[target] suffering from an underflow"},
|
||||||
|
{conditions: {step: 2 * 60 * 1000, value: "2001-01-01T12:03:00"}, expected: false, name: "[target] suffering from a step mismatch"},
|
||||||
|
{conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: "input",
|
||||||
|
types: ["date"],
|
||||||
|
testData: [
|
||||||
|
{conditions: {}, expected: true, name: "[target] no constraint"},
|
||||||
|
{conditions: {max: "2000-01-01", value: "2001-01-01"}, expected: false, name: "[target] suffering from an overflow"},
|
||||||
|
{conditions: {min: "2001-01-01", value: "2000-01-01"}, expected: false, name: "[target] suffering from an underflow"},
|
||||||
|
{conditions: {step: 2 * 1 * 86400000, value: "2001-01-03"}, expected: false, name: "[target] suffering from a step mismatch"},
|
||||||
|
{conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: "input",
|
||||||
|
types: ["month"],
|
||||||
|
testData: [
|
||||||
|
{conditions: {}, expected: true, name: "[target] no constraint"},
|
||||||
|
{conditions: {max: "2000-01", value: "2001-01"}, expected: false, name: "[target] suffering from an overflow"},
|
||||||
|
{conditions: {min: "2001-01", value: "2000-01"}, expected: false, name: "[target] suffering from an underflow"},
|
||||||
|
{conditions: {step: 3 * 1 * 1, value: "2001-03"}, expected: false, name: "[target] suffering from a step mismatch"},
|
||||||
|
{conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: "input",
|
||||||
|
types: ["week"],
|
||||||
|
testData: [
|
||||||
|
{conditions: {}, expected: true, name: "[target] no constraint"},
|
||||||
|
{conditions: {max: "2000-W01", value: "2001-W01"}, expected: false, name: "[target] suffering from an overflow"},
|
||||||
|
{conditions: {min: "2001-W01", value: "2000-W01"}, expected: false, name: "[target] suffering from an underflow"},
|
||||||
|
{conditions: {step: 2 * 1 * 604800000, value: "2001-W03"}, expected: false, name: "[target] suffering from a step mismatch"},
|
||||||
|
{conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: "input",
|
||||||
|
types: ["time"],
|
||||||
|
testData: [
|
||||||
|
{conditions: {}, expected: true, name: "[target] no constraint"},
|
||||||
|
{conditions: {max: "12:00:00", value: "13:00:00"}, expected: false, name: "[target] suffering from an overflow"},
|
||||||
|
{conditions: {min: "12:00:00", value: "11:00:00"}, expected: false, name: "[target] suffering from an underflow"},
|
||||||
|
{conditions: {step: 2 * 60 * 1000, value: "12:03:00"}, expected: false, name: "[target] suffering from a step mismatch"},
|
||||||
|
{conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: "input",
|
||||||
|
types: ["number"],
|
||||||
|
testData: [
|
||||||
|
{conditions: {max: "5", value: "6"}, expected: false, name: "[target] suffering from an overflow"},
|
||||||
|
{conditions: {min: "5", value: "4"}, expected: false, name: "[target] suffering from an underflow"},
|
||||||
|
{conditions: {step: 2 * 1 * 1, value: "3"}, expected: false, name: "[target] suffering from a step mismatch"},
|
||||||
|
{conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: "input",
|
||||||
|
types: ["checkbox", "radio"],
|
||||||
|
testData: [
|
||||||
|
{conditions: {}, expected: true, name: "[target] no constraint"},
|
||||||
|
{conditions: {required: true, checked: false, name: "test1"}, expected: false, name: "[target] suffering from being missing"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: "input",
|
||||||
|
types: ["file"],
|
||||||
|
testData: [
|
||||||
|
{conditions: {}, expected: true, name: "[target] no constraint"},
|
||||||
|
{conditions: {required: true, files: null}, expected: false, name: "[target] suffering from being missing"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: "select",
|
||||||
|
types: [],
|
||||||
|
testData: [
|
||||||
|
{conditions: {}, expected: true, name: "[target] no constraint"},
|
||||||
|
{conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag: "textarea",
|
||||||
|
types: [],
|
||||||
|
testData: [
|
||||||
|
{conditions: {}, expected: true, name: "[target] no constraint"},
|
||||||
|
{conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
validator.run_test(testElements, "reportValidity");
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue