Skip to content

Commit

Permalink
Respect forms with enctype set for view transitions
Browse files Browse the repository at this point in the history
  • Loading branch information
knpwrs committed Dec 19, 2023
1 parent 429be8c commit 6d3e04a
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 11 deletions.
13 changes: 12 additions & 1 deletion packages/astro/components/ViewTransitions.astro
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
10 changes: 5 additions & 5 deletions packages/astro/src/transitions/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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(
Expand All @@ -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 },
Expand Down Expand Up @@ -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(
Expand All @@ -156,7 +156,7 @@ export async function doPreparation(
sourceElement,
info,
window.document,
formData,
body,
defaultLoader
);
if (document.dispatchEvent(event)) {
Expand Down
8 changes: 4 additions & 4 deletions packages/astro/src/transitions/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ async function transition(
navigationType,
options.sourceElement,
options.info,
options.formData,
options.body,
defaultLoader
);
if (prepEvent.defaultPrevented) {
Expand All @@ -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.
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/transitions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

0 comments on commit 6d3e04a

Please sign in to comment.