Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure that the turbo-frame header is not sent when the turbo-frame has a target of _top #1138

Merged
merged 2 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions src/observers/link_prefetch_observer.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,11 @@ export class LinkPrefetchObserver {

request.headers["Sec-Purpose"] = "prefetch"

if (link.dataset.turboFrame && link.dataset.turboFrame !== "_top") {
request.headers["Turbo-Frame"] = link.dataset.turboFrame
} else if (link.dataset.turboFrame !== "_top") {
const turboFrame = link.closest("turbo-frame")
const turboFrame = link.closest("turbo-frame")
afcapel marked this conversation as resolved.
Show resolved Hide resolved
const turboFrameTarget = link.dataset.turboFrame || turboFrame?.getAttribute("target") || turboFrame?.id
afcapel marked this conversation as resolved.
Show resolved Hide resolved

if (turboFrame) {
request.headers["Turbo-Frame"] = turboFrame.id
}
if (turboFrameTarget && turboFrameTarget !== "_top") {
request.headers["Turbo-Frame"] = turboFrameTarget
}

if (link.hasAttribute("data-turbo-stream")) {
Expand Down
8 changes: 8 additions & 0 deletions src/tests/fixtures/hover_to_prefetch.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,13 @@
<a href="/src/tests/fixtures/prefetched.html" data-turbo-method="post" id="anchor_with_post_method"
>Won't prefetch when hovering me</a>
<iframe src="/src/tests/fixtures/hover_to_prefetch_iframe.html" name="prefetch_iframe"> </iframe>

<turbo-frame id="frame_for_prefetch">
<a href="/src/tests/fixtures/prefetched.html" id="anchor_for_prefetch_in_frame">Hover to prefetch me</a>
</turbo-frame>

<turbo-frame id="frame_for_prefetch_top" target="_top">
<a href="/src/tests/fixtures/prefetched.html" id="anchor_for_prefetch_in_frame_target_top">Hover to prefetch me</a>
</turbo-frame>
</body>
</html>
28 changes: 25 additions & 3 deletions src/tests/functional/link_prefetch_observer_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,25 @@ test("it prefetches links with inner elements", async ({ page }) => {
await assertPrefetchedOnHover({ page, selector: "#anchor_with_inner_elements" })
})

test("it prefetches links inside a turbo frame", async ({ page }) => {
await goTo({ page, path: "/hover_to_prefetch.html" })

await assertPrefetchedOnHover({ page, selector: "#anchor_for_prefetch_in_frame", callback: (request) => {
const turboFrameHeader = request.headers()["turbo-frame"]
assert.equal(turboFrameHeader, "frame_for_prefetch")
}})
})


test("doesn't include a turbo-frame header when the link is inside a turbo frame with a target=_top", async ({ page}) => {
await goTo({ page, path: "/hover_to_prefetch.html" })

await assertPrefetchedOnHover({ page, selector: "#anchor_for_prefetch_in_frame_target_top", callback: (request) => {
const turboFrameHeader = request.headers()["turbo-frame"]
assert.equal(undefined, turboFrameHeader)
}})
})

test("it prefetches links with a delay", async ({ page }) => {
await goTo({ page, path: "/hover_to_prefetch.html" })

Expand Down Expand Up @@ -253,15 +272,18 @@ const assertPrefetchedOnHover = async ({ page, selector, callback }) => {
let requestMade = false

page.on("request", (request) => {
callback && callback(request)
requestMade = true
requestMade = request
})

await hoverSelector({ page, selector })

await sleep(100)

assertRequestMade(requestMade)
if (callback) {
await callback(requestMade)
}

assertRequestMade(!!requestMade)
}

const assertNotPrefetchedOnHover = async ({ page, selector, callback }) => {
Expand Down