mirror of
https://github.com/withastro/astro.git
synced 2024-12-16 21:46:22 -05:00
Respect forms with enctype set for view transitions
This commit is contained in:
parent
429be8cc3e
commit
6d3e04a959
4 changed files with 22 additions and 11 deletions
|
@ -117,7 +117,18 @@ const { fallback = 'animate' } = Astro.props;
|
|||
url.search = params.toString();
|
||||
action = url.toString();
|
||||
} else {
|
||||
options.formData = formData;
|
||||
// Form elements without enctype explicitly set default to application/x-www-form-urlencoded.
|
||||
// In order to maintain compatibility with Astro 4.x, we need to check the value of enctype
|
||||
// on the attributes property rather than accessing .enctype directly. Astro 5.x may
|
||||
// introduce defaulting to application/x-www-form-urlencoded as a breaking change, and then
|
||||
// we can access .enctype directly.
|
||||
//
|
||||
// Note: getNamedItem can return null in real life, even if TypeScript doesn't think so.
|
||||
const enctype = form.attributes.getNamedItem('enctype')?.value;
|
||||
options.body =
|
||||
enctype === 'application/x-www-form-urlencoded'
|
||||
? new URLSearchParams(formData as any)
|
||||
: formData;
|
||||
}
|
||||
|
||||
ev.preventDefault();
|
||||
|
|
|
@ -66,7 +66,7 @@ export const isTransitionBeforePreparationEvent = (
|
|||
value: any
|
||||
): value is TransitionBeforePreparationEvent => value.type === TRANSITION_BEFORE_PREPARATION;
|
||||
export class TransitionBeforePreparationEvent extends BeforeEvent {
|
||||
formData: FormData | undefined;
|
||||
body: FormData | URLSearchParams | undefined;
|
||||
loader: () => Promise<void>;
|
||||
constructor(
|
||||
from: URL,
|
||||
|
@ -76,7 +76,7 @@ export class TransitionBeforePreparationEvent extends BeforeEvent {
|
|||
sourceElement: Element | undefined,
|
||||
info: any,
|
||||
newDocument: Document,
|
||||
formData: FormData | undefined,
|
||||
body: FormData | URLSearchParams | undefined,
|
||||
loader: (event: TransitionBeforePreparationEvent) => Promise<void>
|
||||
) {
|
||||
super(
|
||||
|
@ -90,7 +90,7 @@ export class TransitionBeforePreparationEvent extends BeforeEvent {
|
|||
info,
|
||||
newDocument
|
||||
);
|
||||
this.formData = formData;
|
||||
this.body = body;
|
||||
this.loader = loader.bind(this, this);
|
||||
Object.defineProperties(this, {
|
||||
formData: { enumerable: true },
|
||||
|
@ -145,7 +145,7 @@ export async function doPreparation(
|
|||
navigationType: NavigationTypeString,
|
||||
sourceElement: Element | undefined,
|
||||
info: any,
|
||||
formData: FormData | undefined,
|
||||
body: FormData | URLSearchParams | undefined,
|
||||
defaultLoader: (event: TransitionBeforePreparationEvent) => Promise<void>
|
||||
) {
|
||||
const event = new TransitionBeforePreparationEvent(
|
||||
|
@ -156,7 +156,7 @@ export async function doPreparation(
|
|||
sourceElement,
|
||||
info,
|
||||
window.document,
|
||||
formData,
|
||||
body,
|
||||
defaultLoader
|
||||
);
|
||||
if (document.dispatchEvent(event)) {
|
||||
|
|
|
@ -449,7 +449,7 @@ async function transition(
|
|||
navigationType,
|
||||
options.sourceElement,
|
||||
options.info,
|
||||
options.formData,
|
||||
options.body,
|
||||
defaultLoader
|
||||
);
|
||||
if (prepEvent.defaultPrevented) {
|
||||
|
@ -460,9 +460,9 @@ async function transition(
|
|||
async function defaultLoader(preparationEvent: TransitionBeforePreparationEvent) {
|
||||
const href = preparationEvent.to.href;
|
||||
const init: RequestInit = {};
|
||||
if (preparationEvent.formData) {
|
||||
if (preparationEvent.body) {
|
||||
init.method = 'POST';
|
||||
init.body = preparationEvent.formData;
|
||||
init.body = preparationEvent.body;
|
||||
}
|
||||
const response = await fetchHTML(href, init);
|
||||
// If there is a problem fetching the new page, just do an MPA navigation to it.
|
||||
|
@ -488,7 +488,7 @@ async function transition(
|
|||
// Unless this was a form submission, in which case we do not want to trigger another mutation.
|
||||
if (
|
||||
!preparationEvent.newDocument.querySelector('[name="astro-view-transitions-enabled"]') &&
|
||||
!preparationEvent.formData
|
||||
!preparationEvent.body
|
||||
) {
|
||||
preparationEvent.preventDefault();
|
||||
return;
|
||||
|
|
|
@ -5,6 +5,6 @@ export type Options = {
|
|||
history?: 'auto' | 'push' | 'replace';
|
||||
info?: any;
|
||||
state?: any;
|
||||
formData?: FormData;
|
||||
body?: FormData | URLSearchParams;
|
||||
sourceElement?: Element; // more than HTMLElement, e.g. SVGAElement
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue