script: implement missing steps for form submission (#43700)

Implement missing history handling steps for form submission 
Test: ./mach test-wpt
tests/wpt/tests/html/semantics/forms/form-submission-0
Fixes: #43670

---------

Signed-off-by: Kelechi Ebiri <ebiritg@gmail.com>
This commit is contained in:
Kelechi Ebiri
2026-04-10 19:13:46 +01:00
committed by GitHub
parent 34337273a3
commit a670c7a52b
12 changed files with 53 additions and 27 deletions

View File

@@ -877,16 +877,20 @@ impl HTMLFormElement {
// Step 23. If targetNavigable is null, then return.
return;
};
// Step 24. Let historyHandling be "auto".
// TODO
// Step 25. If form document equals targetNavigable's active document, and form document has not yet completely loaded,
// then set historyHandling to "replace".
// TODO
let target_document = match chosen.document() {
Some(doc) => doc,
None => return,
};
// Step 24. Let historyHandling be "auto".
// Step 25. If form document equals targetNavigable's active document, and form document has not yet completely loaded,
// then set historyHandling to "replace".
let history_handling = if doc == target_document && !doc.completely_loaded() {
NavigationHistoryBehavior::Replace
} else {
NavigationHistoryBehavior::Auto
};
let target_window = target_document.window();
let mut load_data = LoadData::new(
LoadOrigin::Script(doc.origin().snapshot()),
@@ -914,7 +918,13 @@ impl HTMLFormElement {
load_data
.headers
.typed_insert(ContentType::from(mime::APPLICATION_WWW_FORM_URLENCODED));
self.mutate_action_url(&mut form_data, load_data, encoding, target_window);
self.mutate_action_url(
&mut form_data,
load_data,
encoding,
target_window,
history_handling,
);
},
// https://html.spec.whatwg.org/multipage/#submit-body
("http", FormMethod::Post) | ("https", FormMethod::Post) => {
@@ -925,6 +935,7 @@ impl HTMLFormElement {
enctype,
encoding,
target_window,
history_handling,
can_gc,
);
},
@@ -934,7 +945,7 @@ impl HTMLFormElement {
("data", FormMethod::Post) |
("ftp", _) |
("javascript", _) => {
self.plan_to_navigate(load_data, target_window);
self.plan_to_navigate(load_data, target_window, history_handling);
},
("mailto", FormMethod::Post) => {
// TODO: Mail as body
@@ -955,6 +966,7 @@ impl HTMLFormElement {
mut load_data: LoadData,
encoding: &'static Encoding,
target: &Window,
history_handling: NavigationHistoryBehavior,
) {
let charset = encoding.name();
@@ -965,10 +977,11 @@ impl HTMLFormElement {
.map(|field| (field.name.str(), field.replace_value(charset))),
);
self.plan_to_navigate(load_data, target);
self.plan_to_navigate(load_data, target, history_handling);
}
/// <https://html.spec.whatwg.org/multipage/#submit-body>
#[allow(clippy::too_many_arguments)]
fn submit_entity_body(
&self,
form_data: &mut [FormDatum],
@@ -976,6 +989,7 @@ impl HTMLFormElement {
enctype: FormEncType,
encoding: &'static Encoding,
target: &Window,
history_handling: NavigationHistoryBehavior,
can_gc: CanGc,
) {
let boundary = generate_boundary();
@@ -1020,7 +1034,7 @@ impl HTMLFormElement {
.0;
load_data.data = Some(request_body);
self.plan_to_navigate(load_data, target);
self.plan_to_navigate(load_data, target, history_handling);
}
fn set_url_query_pairs<T>(
@@ -1039,7 +1053,12 @@ impl HTMLFormElement {
}
/// [Planned navigation](https://html.spec.whatwg.org/multipage/#planned-navigation)
fn plan_to_navigate(&self, mut load_data: LoadData, target: &Window) {
fn plan_to_navigate(
&self,
mut load_data: LoadData,
target: &Window,
history_handling: NavigationHistoryBehavior,
) {
// 1. Let referrerPolicy be the empty string.
// 2. If the form element's link types include the noreferrer keyword,
// then set referrerPolicy to "no-referrer".
@@ -1113,10 +1132,10 @@ impl HTMLFormElement {
navigate(
cx,
&window.root(),
NavigationHistoryBehavior::Push,
history_handling,
false,
load_data,
);
)
});
// 5. Set the form's planned navigation to the just-queued task.

View File

@@ -0,0 +1,3 @@
[a-click.html]
[aElement.click() before the load event must NOT replace]
expected: FAIL

View File

@@ -1,3 +1,4 @@
[form-requestsubmit-during-load.html]
expected: TIMEOUT
[Replace during the load event, triggered by formElement.submit()]
expected: FAIL
expected: TIMEOUT

View File

@@ -1,3 +1,4 @@
[form-requestsubmit-during-pageshow.html]
expected: TIMEOUT
[Replace during the pageshow event, triggered by formElement.submit()]
expected: FAIL
expected: TIMEOUT

View File

@@ -1,3 +1,4 @@
[form-requestsubmit.html]
expected: TIMEOUT
[Replace before load, triggered by formElement.requestSubmit()]
expected: FAIL
expected: TIMEOUT

View File

@@ -1,3 +1,4 @@
[form-submit-button-click-during-load.html]
expected: TIMEOUT
[Replace during load, triggered by submitButton.click()]
expected: FAIL
expected: TIMEOUT

View File

@@ -1,3 +1,4 @@
[form-submit-button-click-during-pageshow.html]
expected: TIMEOUT
[Replace during pageshow, triggered by submitButton.click()]
expected: FAIL
expected: TIMEOUT

View File

@@ -1,3 +1,4 @@
[form-submit-button-click.html]
expected: TIMEOUT
[Replace before load, triggered by submitButton.click()]
expected: FAIL
expected: TIMEOUT

View File

@@ -1,3 +1,4 @@
[form-submit-during-load.html]
expected: TIMEOUT
[Replace during the load event, triggered by formElement.submit()]
expected: FAIL
expected: TIMEOUT

View File

@@ -1,3 +1,4 @@
[form-submit-during-pageshow.html]
expected: TIMEOUT
[Replace during the pageshow event, triggered by formElement.submit()]
expected: FAIL
expected: TIMEOUT

View File

@@ -1,6 +1,5 @@
[form-submit.html]
[Replace before load, triggered by formElement.submit()]
expected: FAIL
expected: TIMEOUT
[Replace before load, triggered by same-document formElement.submit()]
expected: FAIL
expected: [FAIL, TIMEOUT]

View File

@@ -1,3 +0,0 @@
[navigation-in-onload.html]
[Navigation in onload handler]
expected: FAIL