@@ -37,6 +37,7 @@ const { fallback = 'animate' } = Astro.props;
3737 import { init } from 'astro/virtual-modules/prefetch.js';
3838
3939 type Fallback = 'none' | 'animate' | 'swap';
40+ let lastClickedElementLeavingWindow: EventTarget | null = null;
4041
4142 function getFallback(): Fallback {
4243 const el = document.querySelector('[name="astro-view-transitions-fallback"]');
@@ -50,6 +51,13 @@ const { fallback = 'animate' } = Astro.props;
5051 return el.dataset.astroReload !== undefined;
5152 }
5253
54+ const leavesWindow = (ev: MouseEvent) =>
55+ (ev.button && ev.button !== 0) || // left clicks only
56+ ev.metaKey || // new tab (mac)
57+ ev.ctrlKey || // new tab (windows)
58+ ev.altKey || // download
59+ ev.shiftKey; // new window
60+
5361 if (supportsViewTransitions || getFallback() !== 'none') {
5462 if (import.meta.env.DEV && window.matchMedia('(prefers-reduced-motion)').matches) {
5563 console.warn(
@@ -58,6 +66,9 @@ const { fallback = 'animate' } = Astro.props;
5866 }
5967 document.addEventListener('click', (ev) => {
6068 let link = ev.target;
69+
70+ lastClickedElementLeavingWindow = leavesWindow(ev) ? link : null;
71+
6172 if (ev.composed) {
6273 link = ev.composedPath()[0];
6374 }
@@ -82,11 +93,7 @@ const { fallback = 'animate' } = Astro.props;
8293 !link.href ||
8394 (linkTarget && linkTarget !== '_self') ||
8495 origin !== location.origin ||
85- ev.button !== 0 || // left clicks only
86- ev.metaKey || // new tab (mac)
87- ev.ctrlKey || // new tab (windows)
88- ev.altKey || // download
89- ev.shiftKey || // new window
96+ lastClickedElementLeavingWindow ||
9097 ev.defaultPrevented
9198 ) {
9299 // No page transitions in these cases,
@@ -102,11 +109,15 @@ const { fallback = 'animate' } = Astro.props;
102109
103110 document.addEventListener('submit', (ev) => {
104111 let el = ev.target as HTMLElement;
105- if (el.tagName !== 'FORM' || ev.defaultPrevented || isReloadEl(el)) {
112+ const submitter = ev.submitter;
113+
114+ const clickedWithKeys = submitter && submitter === lastClickedElementLeavingWindow;
115+ lastClickedElementLeavingWindow = null;
116+
117+ if (el.tagName !== 'FORM' || ev.defaultPrevented || isReloadEl(el) || clickedWithKeys) {
106118 return;
107119 }
108120 const form = el as HTMLFormElement;
109- const submitter = ev.submitter;
110121 const formData = new FormData(form, submitter);
111122 // form.action and form.method can point to an <input name="action"> or <input name="method">
112123 // in which case should fallback to the form attribute
0 commit comments