summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Matthew Phillips <matthew@skypack.dev> 2023-08-11 08:56:12 -0400
committerGravatar GitHub <noreply@github.com> 2023-08-11 08:56:12 -0400
commit405913cdf20b26407aa351c090f0a0859a4e6f54 (patch)
tree050570c2273e55f7827ba98de322fe2e83402cfb
parent87d4b18437c7565c48cad4bea81831c2a244ebb8 (diff)
downloadastro-405913cdf20b26407aa351c090f0a0859a4e6f54.tar.gz
astro-405913cdf20b26407aa351c090f0a0859a4e6f54.tar.zst
astro-405913cdf20b26407aa351c090f0a0859a4e6f54.zip
Prevent script re-execution on page evaluation (#8033)
-rw-r--r--.changeset/lovely-impalas-pretend.md5
-rw-r--r--packages/astro/components/ViewTransitions.astro23
-rw-r--r--packages/astro/e2e/fixtures/view-transitions/src/components/Layout.astro10
-rw-r--r--packages/astro/e2e/view-transitions.test.js15
4 files changed, 53 insertions, 0 deletions
diff --git a/.changeset/lovely-impalas-pretend.md b/.changeset/lovely-impalas-pretend.md
new file mode 100644
index 000000000..fc11a88e1
--- /dev/null
+++ b/.changeset/lovely-impalas-pretend.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Prevent script re-evaluation on page transition
diff --git a/packages/astro/components/ViewTransitions.astro b/packages/astro/components/ViewTransitions.astro
index d8d5bd1d7..215cb5b38 100644
--- a/packages/astro/components/ViewTransitions.astro
+++ b/packages/astro/components/ViewTransitions.astro
@@ -63,9 +63,16 @@ const { fallback = 'animate' } = Astro.props as Props;
return 'animate';
}
+ function markScriptsExec() {
+ for (const script of document.scripts) {
+ script.dataset.astroExec = '';
+ }
+ }
+
function runScripts() {
let wait = Promise.resolve();
for (const script of Array.from(document.scripts)) {
+ if(script.dataset.astroExec === '') continue;
const s = document.createElement('script');
s.innerHTML = script.innerHTML;
for (const attr of script.attributes) {
@@ -77,6 +84,7 @@ const { fallback = 'animate' } = Astro.props as Props;
}
s.setAttribute(attr.name, attr.value);
}
+ s.dataset.astroExec = '';
script.replaceWith(s);
}
return wait;
@@ -100,6 +108,18 @@ const { fallback = 'animate' } = Astro.props as Props;
const href = el.getAttribute('href');
return doc.head.querySelector(`link[rel=stylesheet][href="${href}"]`);
}
+ if(el.tagName === 'SCRIPT') {
+ let s1 = el as HTMLScriptElement;
+ for(const s2 of doc.scripts) {
+ if(
+ // Inline
+ (s1.textContent && s1.textContent === s2.textContent) ||
+ // External
+ (s1.type === s2.type && s1.src === s2.src)) {
+ return s2;
+ }
+ }
+ }
return null;
};
@@ -207,6 +227,7 @@ const { fallback = 'animate' } = Astro.props as Props;
} finally {
document.documentElement.removeAttribute('data-astro-transition');
await runScripts();
+ markScriptsExec();
onload();
}
}
@@ -225,6 +246,8 @@ const { fallback = 'animate' } = Astro.props as Props;
}
if (supportsViewTransitions || getFallback() !== 'none') {
+ markScriptsExec();
+
document.addEventListener('click', (ev) => {
let link = ev.target;
if (link instanceof Element && link.tagName !== 'A') {
diff --git a/packages/astro/e2e/fixtures/view-transitions/src/components/Layout.astro b/packages/astro/e2e/fixtures/view-transitions/src/components/Layout.astro
index 7016a1bf7..1c0f9bbdf 100644
--- a/packages/astro/e2e/fixtures/view-transitions/src/components/Layout.astro
+++ b/packages/astro/e2e/fixtures/view-transitions/src/components/Layout.astro
@@ -20,6 +20,16 @@ const { link } = Astro.props as Props;
</style>
<ViewTransitions />
<DarkMode />
+ <meta name="script-executions" content="0">
+ <script is:inline defer>
+ {
+ // Increment a global to see if this is running more than once
+ globalThis.scriptExecutions = globalThis.scriptExecutions == null ? -1 : globalThis.scriptExecutions;
+ globalThis.scriptExecutions++;
+ const el = document.querySelector('[name="script-executions"]');
+ el.setAttribute('content', globalThis.scriptExecutions);
+ }
+ </script>
</head>
<body>
<header transition:animate="morph">
diff --git a/packages/astro/e2e/view-transitions.test.js b/packages/astro/e2e/view-transitions.test.js
index f30cd9902..0a3235b90 100644
--- a/packages/astro/e2e/view-transitions.test.js
+++ b/packages/astro/e2e/view-transitions.test.js
@@ -279,4 +279,19 @@ test.describe('View Transitions', () => {
// Count should remain
await expect(cnt).toHaveText('6');
});
+
+ test('Scripts are only executed once', async ({ page, astro }) => {
+ // Go to page 1
+ await page.goto(astro.resolveUrl('/one'));
+ const p = page.locator('#one');
+ await expect(p, 'should have content').toHaveText('Page 1');
+
+ // go to page 2
+ await page.click('#click-two');
+ const article = page.locator('#twoarticle');
+ await expect(article, 'should have script content').toHaveText('works');
+
+ const meta = page.locator('[name="script-executions"]');
+ await expect(meta).toHaveAttribute('content', '0');
+ });
});