diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 3d81283d761..ebd935764f7 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -2526,8 +2526,7 @@ WebIDL::ExceptionOr HTMLInputElement::step_up_or_down(bool is_down, WebIDL // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-checkvalidity WebIDL::ExceptionOr HTMLInputElement::check_validity() { - dbgln("(STUBBED) HTMLInputElement::check_validity(). Called on: {}", debug_description()); - return true; + return check_validity_steps(); } // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-reportvalidity @@ -2874,6 +2873,8 @@ bool HTMLInputElement::is_focusable() const // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#suffering-from-being-missing bool HTMLInputElement::suffering_from_being_missing() const { + bool has_checkedness_false_for_all_elements_in_group = true; + bool has_required_element_in_group = false; switch (type_state()) { case TypeAttributeState::Checkbox: // https://html.spec.whatwg.org/multipage/input.html#checkbox-state-(type%3Dcheckbox)%3Asuffering-from-being-missing @@ -2883,14 +2884,25 @@ bool HTMLInputElement::suffering_from_being_missing() const break; case TypeAttributeState::RadioButton: // https://html.spec.whatwg.org/multipage/input.html#radio-button-state-(type%3Dradio)%3Asuffering-from-being-missing - // If an element in the radio button group is required, and all of the input elements in the radio button group have a checkedness that is false, then the element - // is suffering from being missing. - // FIXME: Implement this. + // If an element in the radio button group is required, and all of the input elements in the radio button group + // have a checkedness that is false, then the element is suffering from being missing. + root().for_each_in_inclusive_subtree_of_type([&](auto& element) { + if (is_in_same_radio_button_group(*this, element)) { + if (element.checked()) + has_checkedness_false_for_all_elements_in_group = false; + if (has_attribute(HTML::AttributeNames::required)) + has_required_element_in_group = true; + } + return TraversalDecision::Continue; + }); + if (has_checkedness_false_for_all_elements_in_group && has_required_element_in_group) + return true; break; case TypeAttributeState::FileUpload: // https://html.spec.whatwg.org/multipage/input.html#file-upload-state-(type%3Dfile)%3Asuffering-from-being-missing // If the element is required and the list of selected files is empty, then the element is suffering from being missing. - // FIXME: Implement this. + if (has_attribute(HTML::AttributeNames::required) && const_cast(*this).files()->length() == 0) + 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 new file mode 100644 index 00000000000..38fbf4acc68 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-checkValidity.txt @@ -0,0 +1,136 @@ +Harness status: OK + +Found 130 tests + +75 Pass +55 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 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 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 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 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) +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 +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) +Fail [INPUT in EMAIL status] suffering from a pattern mismatch +Fail [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 +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) +Fail [INPUT in DATETIME-LOCAL status] suffering from an overflow +Fail [INPUT in DATETIME-LOCAL status] suffering from an overflow (in a form) +Fail [INPUT in DATETIME-LOCAL status] suffering from an underflow +Fail [INPUT in DATETIME-LOCAL status] suffering from an underflow (in a form) +Fail [INPUT in DATETIME-LOCAL status] suffering from a step mismatch +Fail [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) +Fail [INPUT in DATE status] suffering from an overflow +Fail [INPUT in DATE status] suffering from an overflow (in a form) +Fail [INPUT in DATE status] suffering from an underflow +Fail [INPUT in DATE status] suffering from an underflow (in a form) +Fail [INPUT in DATE status] suffering from a step mismatch +Fail [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) +Fail [INPUT in MONTH status] suffering from an overflow +Fail [INPUT in MONTH status] suffering from an overflow (in a form) +Fail [INPUT in MONTH status] suffering from an underflow +Fail [INPUT in MONTH status] suffering from an underflow (in a form) +Fail [INPUT in MONTH status] suffering from a step mismatch +Fail [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) +Fail [INPUT in WEEK status] suffering from an overflow +Fail [INPUT in WEEK status] suffering from an overflow (in a form) +Fail [INPUT in WEEK status] suffering from an underflow +Fail [INPUT in WEEK status] suffering from an underflow (in a form) +Fail [INPUT in WEEK status] suffering from a step mismatch +Fail [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) +Fail [INPUT in TIME status] suffering from an overflow +Fail [INPUT in TIME status] suffering from an overflow (in a form) +Fail [INPUT in TIME status] suffering from an underflow +Fail [INPUT in TIME status] suffering from an underflow (in a form) +Fail [INPUT in TIME status] suffering from a step mismatch +Fail [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) +Fail [INPUT in NUMBER status] suffering from an overflow +Fail [INPUT in NUMBER status] suffering from an overflow (in a form) +Fail [INPUT in NUMBER status] suffering from an underflow +Fail [INPUT in NUMBER status] suffering from an underflow (in a form) +Fail [INPUT in NUMBER status] suffering from a step mismatch +Fail [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) +Fail [select] no constraint +Pass [select] no constraint (in a form) +Fail [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) +Fail [textarea] suffering from being missing +Pass [textarea] suffering from being missing (in a form) \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-valueMissing.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-valueMissing.txt index d0c79a4af5a..eb5bba22a84 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-valueMissing.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/constraints/form-validation-validity-valueMissing.txt @@ -2,8 +2,8 @@ Harness status: OK Found 78 tests -44 Pass -34 Fail +46 Pass +32 Fail Pass [INPUT in TEXT status] The required attribute is not set Pass [INPUT in TEXT status] The value is not empty and required is true Fail [INPUT in TEXT status] The value is empty and required is true @@ -71,10 +71,10 @@ Pass [INPUT in CHECKBOX status] The checked attribute is true Pass [INPUT in CHECKBOX status] The checked attribute is false Pass [INPUT in RADIO status] The required attribute is not set Pass [INPUT in RADIO status] The checked attribute is true -Fail [INPUT in RADIO status] The checked attribute is false +Pass [INPUT in RADIO status] The checked attribute is false Pass [INPUT in RADIO status] The checked attribute is false and the name attribute is empty Pass [INPUT in FILE status] The required attribute is not set -Fail [INPUT in FILE status] The Files attribute is null +Pass [INPUT in FILE status] The Files attribute is null Pass [select] The required attribute is not set Pass [select] Selected the option with value equals to 1 Pass [select] Selected the option with value equals to empty diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/radio.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/radio.txt index 0bbc41ea756..a1449345a92 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/radio.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/radio.txt @@ -2,8 +2,7 @@ Harness status: OK Found 12 tests -11 Pass -1 Fail +12 Pass Pass click on mutable radio fires click event, then input event, then change event Pass click on non-mutable radio doesn't fire the input event Pass click on non-mutable radio doesn't fire the change event @@ -12,7 +11,7 @@ Pass only one control of a radio button group can have its checkedness set to tr Pass radio inputs with non-ASCII name attributes belong to the same radio button group Pass changing the name of a radio input element and setting its checkedness to true makes all the other elements' checkedness in the same radio button group be set to false Pass moving radio input element out of or into a form should still work as expected -Fail Radio buttons in an orphan tree should make a group +Pass Radio buttons in an orphan tree should make a group Pass Radio buttons in different groups (because they have different form owners or no form owner) do not affect each other's checkedness Pass Radio buttons in different groups (because they are not in the same tree) do not affect each other's checkedness Pass Radio buttons in different groups (because they have different name attribute values, or no name attribute) do not affect each other's checkedness \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-checkValidity.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-checkValidity.html new file mode 100644 index 00000000000..b312614b094 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/forms/constraints/form-validation-checkValidity.html @@ -0,0 +1,145 @@ + + +The constraint validation API Test: element.checkValidity() + + + + + + +
+