Respect the download attribute in links when using view transitions (#8339)

* Respect the download attribute in links when using view transitions

* cleanup
This commit is contained in:
Martin Trapp 2023-08-31 23:51:03 +02:00 committed by GitHub
parent a4780e97f6
commit f21599671a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 70 additions and 35 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Respect the download attribute in links when using view transitions

View file

@ -300,6 +300,7 @@ const { fallback = 'animate' } = Astro.props as Props;
!link || !link ||
!(link instanceof HTMLAnchorElement) || !(link instanceof HTMLAnchorElement) ||
link.dataset.astroReload !== undefined || link.dataset.astroReload !== undefined ||
link.hasAttribute('download') ||
!link.href || !link.href ||
(link.target && link.target !== '_self') || (link.target && link.target !== '_self') ||
link.origin !== location.origin || link.origin !== location.origin ||

View file

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" width="363" height="102" viewBox="0 0 363 102" fill="none" aria-hidden="true" class="astro-2W66RQV5">
<style>
.text {
fill: white;
}
.hover {
fill: white;
}
</style>
<path class="text astro-2W66RQV5" fill-rule="evenodd" d="M55.07 14.216l16.81 54.865a72.6 72.6 0 00-20.765-6.984L39.808 24.135a1.475 1.475 0 00-2.827.005L25.81 62.078a72.598 72.598 0 00-20.859 6.995L21.847 14.2c.998-3.243 1.497-4.865 2.47-6.066a8 8 0 013.239-2.392c1.434-.576 3.13-.576 6.524-.576h8.751c3.398 0 5.097 0 6.532.577a8 8 0 013.241 2.397c.972 1.203 1.47 2.827 2.465 6.076z" clip-rule="evenodd"></path>
<path fill="#FF5D01" fill-rule="evenodd" d="M54.618 71.779c-2.863 2.432-8.578 4.091-15.161 4.091-8.08 0-14.852-2.499-16.649-5.86-.642 1.926-.786 4.13-.786 5.539 0 0-.423 6.915 4.418 11.725 0-2.498 2.037-4.522 4.551-4.522 4.309 0 4.304 3.734 4.3 6.764v.27c0 4.6 2.829 8.541 6.852 10.203a9.22 9.22 0 01-.938-4.064c0-4.386 2.592-6.02 5.604-7.917 2.396-1.51 5.06-3.188 6.894-6.554a12.297 12.297 0 001.502-5.905c0-1.314-.206-2.581-.587-3.77z" clip-rule="evenodd" class="astro-2W66RQV5"></path>
<path class="text astro-2W66RQV5" d="M126.554 69c13.115 0 21.047-3.14 25.68-9.654 0 2.904.157 5.651.55 8.163h7.774c-.706-4.082-.863-6.75-.863-14.128V43.334c0-10.831-8.403-16.56-24.424-16.56-15.47 0-25.522 5.964-26.779 14.598h8.246c1.256-5.808 7.774-8.87 18.533-8.87 10.602 0 16.885 3.69 16.885 9.969v.785l-24.502 1.413c-9.974.549-13.665 1.962-16.492 4.003-2.67 1.962-4.162 5.023-4.162 8.555C107 64.683 114.696 69 126.554 69zm2.513-5.573c-9.109 0-14.135-2.119-14.135-6.357 0-4.553 3.141-6.593 14.214-7.3l23.01-1.412v1.805c0 8.241-9.66 13.264-23.089 13.264zM196.086 69c16.256 0 22.775-5.337 22.775-13.108 0-6.436-4.006-9.732-14.215-10.596l-19.083-1.49c-5.183-.393-8.088-1.884-8.088-5.102 0-4.082 4.476-6.201 14.135-6.201 10.995 0 16.727 2.198 20.497 7.064l6.361-3.061c-3.927-6.122-12.644-9.733-26.151-9.733-13.9 0-22.224 4.631-22.224 12.244 0 6.829 4.947 10.125 14.292 10.91l18.926 1.492c6.204.47 8.089 1.726 8.089 4.944 0 4.631-4.79 6.829-14.293 6.829-11.544 0-18.847-3.14-22.381-8.87l-6.204 3.376C173.312 64.918 181.715 69 196.086 69zM234.929 34.151v18.916c0 7.77 2.67 15.54 17.198 15.54 3.691 0 8.167-.706 10.131-1.57V60.68c-2.749.628-6.047 1.1-9.267 1.1-6.832 0-10.523-2.67-10.523-9.42V34.151h19.633v-5.887h-19.633V15l-7.539 3.061v10.204h-12.33v5.886h12.33zM280.823 28.265h-6.911v39.244h7.461V52.83c0-5.65 1.099-10.439 4.24-13.735 2.749-3.061 6.283-4.788 12.487-4.788 2.12 0 3.455.157 5.262.471v-7.22c-1.65-.393-3.063-.472-5.184-.472-8.402 0-15.078 4.945-17.355 12.558v-11.38zM334.807 69C351.534 69 363 60.523 363 47.887c0-12.637-11.466-21.114-28.193-21.114-16.727 0-28.193 8.477-28.193 21.114C306.614 60.523 318.08 69 334.807 69zm0-6.2c-12.329 0-20.261-5.809-20.261-14.913 0-9.105 7.932-14.913 20.261-14.913 12.251 0 20.261 5.808 20.261 14.913 0 9.104-8.01 14.912-20.261 14.912z"></path>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -10,4 +10,5 @@ import Layout from '../components/Layout.astro';
</div> </div>
</a> </a>
<a id="click-two" href="/two" data-astro-reload>load page / no navigation</a> <a id="click-two" href="/two" data-astro-reload>load page / no navigation</a>
<a id="click-logo" href="/logo.svg" download>load page / no navigation</a>
</Layout> </Layout>

View file

@ -443,47 +443,62 @@ test.describe('View Transitions', () => {
'There should be only 1 page load. No additional loads for going back on same page' 'There should be only 1 page load. No additional loads for going back on same page'
).toEqual(1); ).toEqual(1);
}); });
});
test('Navigation also swaps the attributes of the document root', async ({ page, astro }) => { test('Navigation also swaps the attributes of the document root', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/some-attributes')); await page.goto(astro.resolveUrl('/some-attributes'));
let p = page.locator('#heading'); let p = page.locator('#heading');
await expect(p, 'should have content').toHaveText('Page with some attributes'); await expect(p, 'should have content').toHaveText('Page with some attributes');
let h = page.locator('html'); let h = page.locator('html');
await expect(h, 'should have content').toHaveAttribute('lang', 'en'); await expect(h, 'should have content').toHaveAttribute('lang', 'en');
await page.click('#click-other-attributes'); await page.click('#click-other-attributes');
p = page.locator('#heading'); p = page.locator('#heading');
await expect(p, 'should have content').toHaveText('Page with other attributes'); await expect(p, 'should have content').toHaveText('Page with other attributes');
h = page.locator('html'); h = page.locator('html');
await expect(h, 'should have content').toHaveAttribute('lang', 'es'); 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('style', 'background-color: green');
await expect(h, 'should have content').toHaveAttribute('data-other-name', 'value'); 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-fake', 'value');
await expect(h, 'should have content').toHaveAttribute('data-astro-transition', 'forward'); await expect(h, 'should have content').toHaveAttribute('data-astro-transition', 'forward');
await expect(h, 'should be absent').not.toHaveAttribute('class', /.*/); await expect(h, 'should be absent').not.toHaveAttribute('class', /.*/);
});
test('Link with data-astro-reload attribute should trigger page load, no tranistion', async ({
page,
astro,
}) => {
const loads = [];
page.addListener('load', (p) => {
loads.push(p.title());
}); });
// Go to page 4 test('Link with data-astro-reload attribute should trigger page load, no tranistion', async ({
await page.goto(astro.resolveUrl('/four')); page,
let p = page.locator('#four'); astro,
await expect(p, 'should have content').toHaveText('Page 4'); }) => {
const loads = [];
page.addListener('load', (p) => {
loads.push(p.title());
});
// go to page 2 // Go to page 4
await page.click('#click-two'); await page.goto(astro.resolveUrl('/four'));
p = page.locator('#two'); let p = page.locator('#four');
await expect(p, 'should have content').toHaveText('Page 2'); await expect(p, 'should have content').toHaveText('Page 4');
expect(loads.length, 'There should be 2 page load').toEqual(2); // go to page 2
await page.click('#click-two');
p = page.locator('#two');
await expect(p, 'should have content').toHaveText('Page 2');
expect(loads.length, 'There should be 2 page load').toEqual(2);
});
test('Link with download attribute should trigger download, no transition', async ({
page,
astro,
}) => {
// Go to page 4
await page.goto(astro.resolveUrl('/four'));
let p = page.locator('#four');
await expect(p, 'should have content').toHaveText('Page 4');
// Start waiting for download before clicking. Note no await.
const downloadPromise = page.waitForEvent('download', { timeout: 4000 });
await page.click('#click-logo');
await downloadPromise;
});
}); });