View Transition: swap attributes of document's root element (#8206)

* swap attributes of the root element

* + changeset
This commit is contained in:
Martin Trapp 2023-08-24 15:09:22 +02:00 committed by GitHub
parent 85f2c2464c
commit 52606a3909
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 74 additions and 0 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
fix: View Transition: swap attributes of document's root element

View file

@ -136,6 +136,18 @@ const { fallback = 'animate' } = Astro.props as Props;
// Remove them before swapping.
doc.querySelectorAll('head noscript').forEach((el) => el.remove());
// swap attributes of the html element
// - delete all attributes from the current document
// - insert all attributes from doc
// - reinsert all original attributes that are named 'data-astro-*'
const html = document.documentElement;
const astro = [...html.attributes].filter(
({ name }) => (html.removeAttribute(name), name.startsWith('data-astro-'))
);
[...doc.documentElement.attributes, ...astro].forEach(({ name, value }) =>
html.setAttribute(name, value)
);
// Swap head
for (const el of Array.from(document.head.children)) {
const newEl = persistedHeadElement(el);

View file

@ -0,0 +1,17 @@
---
import { ViewTransitions } from 'astro:transitions';
import { HTMLAttributes } from 'astro/types';
interface Props extends HTMLAttributes<'html'> {}
---
<html {...Astro.props}>
<head>
<title>Testing</title>
<ViewTransitions />
</head>
<body>
<main transition:animate="slide">
<slot />
</main>
</body>
</html>

View file

@ -0,0 +1,11 @@
---
import AttributeLayout from '../components/AttributedLayout.astro';
---
<AttributeLayout
lang="es"
style="background-color: green"
data-other-name="value"
data-astro-fake="value"
data-astro-transition="downward">
<p id="heading">Page with other attributes</p>
</AttributeLayout>

View file

@ -0,0 +1,7 @@
---
import AttributedLayout from '../components/AttributedLayout.astro';
---
<AttributedLayout lang="en" class="ugly">
<p id="heading">Page with some attributes</p>
<a id="click-other-attributes" href="/other-attributes">Other attributes</a>
</AttributedLayout>

View file

@ -397,3 +397,25 @@ test.describe('View Transitions', () => {
).toEqual(1);
});
});
test('Navigation also swaps the attributes of the document root', async ({ page, astro }) => {
page.on('console', (msg) => console.log(msg.text()));
await page.goto(astro.resolveUrl('/some-attributes'));
let p = page.locator('#heading');
await expect(p, 'should have content').toHaveText('Page with some attributes');
let h = page.locator('html');
await expect(h, 'should have content').toHaveAttribute('lang', 'en');
await page.click('#click-other-attributes');
p = page.locator('#heading');
await expect(p, 'should have content').toHaveText('Page with other attributes');
h = page.locator('html');
await expect(h, 'should have content').toHaveAttribute('lang', 'es');
await expect(h, 'should have content').toHaveAttribute('style', 'background-color: green');
await expect(h, 'should have content').toHaveAttribute('data-other-name', 'value');
await expect(h, 'should have content').toHaveAttribute('data-astro-fake', 'value');
await expect(h, 'should have content').toHaveAttribute('data-astro-transition', 'forward');
await expect(h, 'should be absent').not.toHaveAttribute('class', /.*/);
});