Skip to content

Commit

Permalink
View Transition: swap attributes of document's root element (#8206)
Browse files Browse the repository at this point in the history
* swap attributes of the root element

* + changeset
  • Loading branch information
martrapp authored Aug 24, 2023
1 parent 85f2c24 commit 52606a3
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/lovely-ducks-move.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

fix: View Transition: swap attributes of document's root element
12 changes: 12 additions & 0 deletions packages/astro/components/ViewTransitions.astro
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -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>
22 changes: 22 additions & 0 deletions packages/astro/e2e/view-transitions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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', /.*/);
});

0 comments on commit 52606a3

Please sign in to comment.