Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- This WPT test may be referenced by the following Test IDs:
- /html/semantics/forms/form-submission-0/form-double-submit-requestsubmit.html - WPT Dashboard Interop Dashboard
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="help"
href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#form-submission-algorithm">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="./resources/targetted-form.js"></script>
<!-- The onclick requestSubmit() should get superseded by the default
action submit, which isn't preventDefaulted by onclick here.
This is per the Form Submission Algorithm [1], which
says that new planned navigations replace old planned navigations.
-->
<body>
<script>
function runTest({ submitterType, preventDefaultSubmitButton, preventDefaultRequestSubmit, passSubmitter, testName }) {
if (preventDefaultRequestSubmit && preventDefaultSubmitButton) {
// In this case, no submit action will take place.
return;
}
promise_test(async () => {
const form = populateForm(`<input name=n1 value=v1><${submitterType} type=submit name=n2 value=v2>${submitterType == 'button' ? '</button>' : ''}`);
const input = form.elements[0];
const submitter = form.elements[1];
submitter.addEventListener('click', e => {
form.addEventListener('submit', e => {
submitter.value = 'v3';
if (preventDefaultRequestSubmit) {
e.preventDefault();
}
}, { once: true });
form.requestSubmit(passSubmitter ? submitter : null);
input.value = 'v2';
form.addEventListener('submit', e => {
submitter.value = 'v4';
if (preventDefaultSubmitButton) {
e.preventDefault();
}
}, { once: true });
});
let formDataInEvent;
form.addEventListener('formdata', e => {
formDataInEvent = e.formData;
});
submitter.click();
assert_equals(formDataInEvent.get('n1'), preventDefaultSubmitButton ? 'v1' : 'v2');
if (preventDefaultSubmitButton && !passSubmitter) {
assert_false(formDataInEvent.has('n2'));
} else {
assert_equals(formDataInEvent.get('n2'),
preventDefaultSubmitButton && passSubmitter ? 'v3' : 'v4')
}
let iframe = form.previousSibling;
await loadPromise(iframe);
assert_equals(getParamValue(iframe, 'n1'), preventDefaultSubmitButton ? 'v1' : 'v2');
if (preventDefaultSubmitButton && !passSubmitter) {
assert_equals(getParamValue(iframe, 'n2'), null);
} else {
assert_equals(getParamValue(iframe, 'n2'),
preventDefaultSubmitButton && passSubmitter ? 'v3' : 'v4');
}
}, testName);
}
function runTest2({ submitterType, callRequestSubmit, callSubmit, preventDefault, passSubmitter, testName }) {
if (!callSubmit && preventDefault) {
// Without callSubmit, preventDefault will cause the form to not get
// submitted.
return;
}
promise_test(async () => {
const form = populateForm(`<input name=n1 value=v1><${submitterType} type=submit name=n2 value=v3>${submitterType == 'button' ? '</button>' : ''}`);
const input = form.elements[0];
const submitter = form.elements[1];
form.addEventListener('submit', e => {
if (callRequestSubmit) {
form.requestSubmit(passSubmitter ? submitter : null);
input.value = 'v2';
}
if (callSubmit) {
form.submit();
}
if (preventDefault) {
e.preventDefault();
}
});
form.requestSubmit(passSubmitter ? submitter : null);
let iframe = form.previousSibling;
await loadPromise(iframe);
assert_equals(getParamValue(iframe, 'n1'), callRequestSubmit ? 'v2' : 'v1');
if (callSubmit || !passSubmitter) {
assert_equals(getParamValue(iframe, 'n2'), null);
} else {
assert_equals(getParamValue(iframe, 'n2'), 'v3')
}
}, testName);
}
function callWithArgs(test, argsLeft, args) {
if (argsLeft.length == 0) {
args.testName = 'test ' + test.name + ' with ' + Object.entries(args).map(([key, value]) => `${key}: ${value}`).join(', ');
test(args);
return;
}
let [name, values] = argsLeft[0];
for (let value of values) {
callWithArgs(test, argsLeft.slice(1), { ...args, [name]: value })
}
}
let args = {
submitterType: ['input', 'button'],
preventDefaultRequestSubmit: [true, false],
preventDefaultSubmitButton: [true, false],
passSubmitter: [true, false],
};
callWithArgs(runTest, Object.entries(args), {});
args = {
submitterType: ['input', 'button'],
callRequestSubmit: [true, false],
callSubmit: [true, false],
preventDefault: [true, false],
passSubmitter: [true, false],
};
callWithArgs(runTest2, Object.entries(args), {});
</script>
</body>