forked from hotwired/turbo
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Guard
[data-turbo-preload]
with conditionals
Prior to this change, _any_ `<a>` element with `[data-turbo-preload]` would be preloaded. With that behavior comes some risk: * if an element is nested within a `[data-turbo="false"]` element, the preloading would occur unnecessarily * if an element has `[data-turbo-stream]`, the preloaded request won't be the same as the ensuing request due to differences in the `Accept:` header * if an element has `[data-turbo-method]`, the preloaded request won't be the same as the ensuing request due to differences in the method * if an element is within a `<turbo-frame>` or driving a frame via `[data-turbo-frame]`, the preloaded request won't be the same as the ensuing request due to differences in the `Turbo-Frame:` header This commit extends the `Preloader` delegate interface to include a `shouldPreloadLink(link: HTMLAnchorElement)` predicate method to give delegates an opportunity to opt-out of preloading. The `Session` implementation of the delegate class adds rejects `<a>` elements that match any of those cases. Co-authored-by: Julian Rubisch <julian@julianrubisch.at>
- Loading branch information
1 parent
db310ef
commit 05ed1b7
Showing
7 changed files
with
121 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,88 @@ | ||
import { test } from "@playwright/test" | ||
import { assert } from "chai" | ||
import { nextBeat } from "../helpers/page" | ||
import { nextEventOnTarget } from "../helpers/page" | ||
|
||
test("preloads snapshot on initial load", async ({ page }) => { | ||
// contains `a[rel="preload"][href="http://localhost:9000/src/tests/fixtures/preloaded.html"]` | ||
await page.goto("/src/tests/fixtures/preloading.html") | ||
await nextBeat() | ||
|
||
assert.ok( | ||
await page.evaluate(() => { | ||
const preloadedUrl = "http://localhost:9000/src/tests/fixtures/preloaded.html" | ||
const cache = window.Turbo.session.preloader.snapshotCache.snapshots | ||
const preloadLink = await page.locator("#preload_anchor") | ||
const href = await preloadLink.evaluate((link) => link.href) | ||
|
||
return preloadedUrl in cache | ||
}) | ||
) | ||
assert.ok(await urlInSnapshotCache(page, href)) | ||
}) | ||
|
||
test("preloads snapshot on page visit", async ({ page }) => { | ||
// contains `a[rel="preload"][href="http://localhost:9000/src/tests/fixtures/preloading.html"]` | ||
await page.goto("/src/tests/fixtures/hot_preloading.html") | ||
|
||
// contains `a[rel="preload"][href="http://localhost:9000/src/tests/fixtures/preloaded.html"]` | ||
await page.click("#hot_preload_anchor") | ||
await page.waitForSelector("#preload_anchor") | ||
await nextBeat() | ||
|
||
assert.ok( | ||
await page.evaluate(() => { | ||
const preloadedUrl = "http://localhost:9000/src/tests/fixtures/preloaded.html" | ||
const cache = window.Turbo.session.preloader.snapshotCache.snapshots | ||
const preloadLink = await page.locator("#preload_anchor") | ||
const href = await preloadLink.evaluate((link) => link.href) | ||
|
||
return preloadedUrl in cache | ||
}) | ||
) | ||
assert.ok(await urlInSnapshotCache(page, href)) | ||
}) | ||
|
||
test("navigates to preloaded snapshot from frame", async ({ page }) => { | ||
// contains `a[rel="preload"][href="http://localhost:9000/src/tests/fixtures/preloaded.html"]` | ||
test("preloads anchor from frame that will drive the page", async ({ page }) => { | ||
await page.goto("/src/tests/fixtures/frame_preloading.html") | ||
await nextEventOnTarget(page, "menu", "turbo:frame-load") | ||
|
||
const preloadLink = await page.locator("#menu a[data-turbo-frame=_top]") | ||
const href = await preloadLink.evaluate((link) => link.href) | ||
|
||
assert.ok(await urlInSnapshotCache(page, href)) | ||
}) | ||
|
||
test("does not preload anchor off-site", async ({ page }) => { | ||
await page.goto("/src/tests/fixtures/preloading.html") | ||
|
||
const link = await page.locator("a[href*=https]") | ||
const href = await link.evaluate((link) => link.href) | ||
|
||
assert.notOk(await urlInSnapshotCache(page, href)) | ||
}) | ||
|
||
test("does not preload anchor that will drive an ancestor frame", async ({ page }) => { | ||
await page.goto("/src/tests/fixtures/frame_preloading.html") | ||
|
||
const preloadLink = await page.locator("#hello a[data-turbo-preload]") | ||
const href = await preloadLink.evaluate((link) => link.href) | ||
|
||
assert.notOk(await urlInSnapshotCache(page, href)) | ||
}) | ||
|
||
test("does not preload anchor that will drive a target frame", async ({ page }) => { | ||
await page.goto("/src/tests/fixtures/frame_preloading.html") | ||
await page.waitForSelector("#frame_preload_anchor") | ||
await nextBeat() | ||
|
||
assert.ok( | ||
await page.evaluate(() => { | ||
const preloadedUrl = "http://localhost:9000/src/tests/fixtures/preloaded.html" | ||
const cache = window.Turbo.session.preloader.snapshotCache.snapshots | ||
const link = await page.locator("a[data-turbo-frame=hello]") | ||
const href = await link.evaluate((link) => link.href) | ||
|
||
assert.notOk(await urlInSnapshotCache(page, href)) | ||
}) | ||
|
||
test("does not preload a link with [data-turbo=false]", async ({ page }) => { | ||
await page.goto("/src/tests/fixtures/preloading.html") | ||
|
||
const link = await page.locator("[data-turbo=false] a") | ||
const href = await link.evaluate((link) => link.href) | ||
|
||
return preloadedUrl in cache | ||
}) | ||
) | ||
assert.notOk(await urlInSnapshotCache(page, href)) | ||
}) | ||
|
||
test("does not preload a link with [data-turbo-method]", async ({ page }) => { | ||
await page.goto("/src/tests/fixtures/preloading.html") | ||
|
||
const preloadLink = await page.locator("a[data-turbo-method]") | ||
const href = await preloadLink.evaluate((link) => link.href) | ||
|
||
assert.notOk(await urlInSnapshotCache(page, href)) | ||
}) | ||
|
||
function urlInSnapshotCache(page, href) { | ||
return page.evaluate((href) => { | ||
const preloadedUrl = new URL(href) | ||
const cache = window.Turbo.session.preloader.snapshotCache | ||
|
||
return cache.has(preloadedUrl) | ||
}, href) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters