0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-16 21:46:22 -05:00

Prevent client-side navigation for method="dialog" (#9327)

Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com>
This commit is contained in:
Ted Klingenberg 2023-12-05 19:42:53 -05:00 committed by GitHub
parent dd24379f49
commit 3878a91be4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 0 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fixes an edge case for `<form method="dialog">` when using View Transitions. Forms with `method="dialog"` no longer require an additional `data-astro-reload` attribute.

View file

@ -104,6 +104,12 @@ const { fallback = 'animate' } = Astro.props;
let action = submitter?.getAttribute('formaction') ?? form.action ?? location.pathname;
const method = submitter?.getAttribute('formmethod') ?? form.method;
// the "dialog" method is a special keyword used within <dialog> elements
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fs-method
if (method === "dialog") {
return
}
const options: Options = { sourceElement: submitter ?? form };
if (method === 'get') {
const params = new URLSearchParams(formData as any);
@ -113,6 +119,7 @@ const { fallback = 'animate' } = Astro.props;
} else {
options.formData = formData;
}
ev.preventDefault();
navigate(action, options);
});

View file

@ -0,0 +1,16 @@
---
import { ViewTransitions } from "astro:transitions";
---
<html>
<head>
<ViewTransitions />
</head>
<body>
<button id="open" onclick="modal.showModal()">Open Modal</button>
<dialog id="modal">
<form method="dialog">
<button id="close">Close</button>
</form>
</dialog>
</body>
</html>

View file

@ -1074,4 +1074,18 @@ test.describe('View Transitions', () => {
await page.click('#three');
await expect(page).toHaveURL(expected);
});
test('Dialog using form with method of "dialog" should not trigger navigation', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/dialog'));
let requests = [];
page.on('request', request => requests.push(`${request.method()} ${request.url()}`));
await page.click('#open');
await expect(page.locator("dialog")).toHaveAttribute("open")
await page.click('#close');
await expect(page.locator("dialog")).not.toHaveAttribute("open")
expect(requests).toHaveLength(0)
});
});