View Transition: swap attributes of document's root element (#8206)
* swap attributes of the root element * + changeset
This commit is contained in:
parent
85f2c2464c
commit
52606a3909
6 changed files with 74 additions and 0 deletions
5
.changeset/lovely-ducks-move.md
Normal file
5
.changeset/lovely-ducks-move.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
fix: View Transition: swap attributes of document's root element
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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', /.*/);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue