Skip to content

Commit

Permalink
Programmatic form submission should also affect :user-invalid/valid s…
Browse files Browse the repository at this point in the history
…tate

https://bugs.webkit.org/show_bug.cgi?id=260813
rdar://114580382

Reviewed by Aditya Keerthi.

We should not check for an user gesture when setting the user-interacted flag on submission.
This also matches the HTML spec that landed.

* LayoutTests/imported/w3c/web-platform-tests/css/selectors/user-invalid.html:
* LayoutTests/imported/w3c/web-platform-tests/css/selectors/user-valid.html:
* Source/WebCore/html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::submitIfPossible):

Canonical link: https://commits.webkit.org/267384@main
  • Loading branch information
nt1m committed Aug 29, 2023
1 parent af0be1f commit f4bbd99
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<title>Support for the :user-invalid pseudo-class</title>
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="help" href="https://drafts.csswg.org/selectors/#user-pseudos">
<link rel="help" href="https://html.spec.whatwg.org/#selector-user-invalid">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
Expand Down Expand Up @@ -79,21 +80,30 @@
assert_false(requiredTextarea.matches(":user-valid"), "Initially does not match :user-valid");
assert_false(requiredTextarea.matches(":user-invalid"), "Initially does not match :user-invalid");

await test_driver.click(submitButton);
submitButton.click();

assert_true(requiredInput.matches(":user-invalid"), "Submitted the form, input is validated");
assert_false(requiredInput.matches(":user-valid"), "Submitted the form, input is validated");

assert_true(requiredTextarea.matches(":user-invalid"), "Submitted the form, textarea is validated");
assert_false(requiredTextarea.matches(":user-valid"), "Submitted the form, textarea is validated");

await test_driver.click(resetButton);
resetButton.click();

assert_false(requiredInput.matches(":user-valid"), "Reset the form, user-interacted flag is reset");
assert_false(requiredInput.matches(":user-invalid"), "Reset the form, user-interacted flag is reset");

assert_false(requiredTextarea.matches(":user-valid"), "Reset the form, user-interacted flag is reset");
assert_false(requiredTextarea.matches(":user-invalid"), "Reset the form, user-interacted flag is reset");

// Test programmatic form submission with constraint validation.
form.requestSubmit();

assert_true(requiredInput.matches(":user-invalid"), "Called form.requestSubmit(), input is validated");
assert_false(requiredInput.matches(":user-valid"), "Called form.requestSubmit(), input is validated");

assert_true(requiredTextarea.matches(":user-invalid"), "Called form.requestSubmit(), textarea is validated");
assert_false(requiredTextarea.matches(":user-valid"), "Called form.requestSubmit(), textarea is validated");
}, ":user-invalid selector properly interacts with submit & reset buttons");

// historical: https://github.com/w3c/csswg-drafts/issues/1329
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<title>Support for the :user-valid pseudo-class</title>
<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
<link rel="help" href="https://drafts.csswg.org/selectors/#user-pseudos">
<link rel="help" href="https://html.spec.whatwg.org/#selector-user-valid">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
Expand Down Expand Up @@ -76,20 +77,29 @@
assert_false(optionalTextarea.matches(":user-valid"), "Initially does not match :user-valid");
assert_false(optionalTextarea.matches(":user-invalid"), "Initially does not match :user-invalid");

await test_driver.click(submitButton);
submitButton.click();

assert_true(optionalInput.matches(":user-valid"), "Submitted the form, input is validated");
assert_false(optionalInput.matches(":user-invalid"), "Submitted the form, input is validated");

assert_true(optionalTextarea.matches(":user-valid"), "Submitted the form, textarea is validated");
assert_false(optionalTextarea.matches(":user-invalid"), "Submitted the form, textarea is validated");

await test_driver.click(resetButton);
resetButton.click();

assert_false(optionalInput.matches(":user-valid"), "Reset the form, user-interacted flag is reset");
assert_false(optionalInput.matches(":user-invalid"), "Reset the form, user-interacted flag is reset");

assert_false(optionalTextarea.matches(":user-valid"), "Reset the form, user-interacted flag is reset");
assert_false(optionalTextarea.matches(":user-invalid"), "Reset the form, user-interacted flag is reset");

// Test programmatic form submission with constraint validation.
form.requestSubmit();

assert_true(optionalInput.matches(":user-valid"), "Called form.requestSubmit(), input is validated");
assert_false(optionalInput.matches(":user-invalid"), "Called form.requestSubmit(), input is validated");

assert_true(optionalTextarea.matches(":user-valid"), "Called form.requestSubmit(), textarea is validated");
assert_false(optionalTextarea.matches(":user-invalid"), "Called form.requestSubmit(), textarea is validated");
}, ":user-valid selector properly interacts with submit & reset buttons");
</script>
8 changes: 3 additions & 5 deletions Source/WebCore/html/HTMLFormElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,11 +260,9 @@ void HTMLFormElement::submitIfPossible(Event* event, HTMLFormControlElement* sub
m_isSubmittingOrPreparingForSubmission = true;
m_shouldSubmit = false;

if (UserGestureIndicator::processingUserGesture()) {
for (auto& element : m_listedElements) {
if (auto* formControlElement = dynamicDowncast<HTMLFormControlElement>(*element))
formControlElement->setInteractedWithSinceLastFormSubmitEvent(true);
}
for (auto& element : m_listedElements) {
if (auto* formControlElement = dynamicDowncast<HTMLFormControlElement>(*element))
formControlElement->setInteractedWithSinceLastFormSubmitEvent(true);
}

bool shouldValidate = document().page() && document().page()->settings().interactiveFormValidationEnabled() && !noValidate();
Expand Down

0 comments on commit f4bbd99

Please sign in to comment.