Skip to content

Commit

Permalink
Support FrameElement.reload() without an initial [src] attribute
Browse files Browse the repository at this point in the history
The problem
---

If a `<turbo-frame>` element is rendered without a `[src]` attribute,
calls to `.reload()` will have no effect. If a `<turbo-frame>` is to be
its own browsing context, it should be able to apply its current
location (that is, it's owning document's current location) to its
browsing context.

The solution
---

When `FrameElement.reload()` is invoked, it delegates to its delegate
instance's `sourceURLReloaded()` method. In all cases,
`FrameElement.delegate` is an instance of `FrameController`.

This commit extends the `FrameController.sourceURLReloaded()`
implementation to set the element's `[src]` attribute to the element's
[baseURI][] value, which sets off the usual attribute change listeners
and `<turbo-frame>` navigation logic.

[baseURI]: https://developer.mozilla.org/en-US/docs/Web/API/Node/baseURI
  • Loading branch information
seanpdoyle committed Sep 14, 2023
1 parent 32cadc0 commit daacfc0
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/core/frames/frame_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export class FrameController {
this.element.removeAttribute("complete")
})
this.element.src = null
this.element.src = src
this.element.src = src || this.element.baseURI
return this.element.loaded
}

Expand Down
34 changes: 32 additions & 2 deletions src/tests/functional/frame_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -515,15 +515,45 @@ test("test navigating a frame targeting _top from an outer link fires events", a
assert.equal(otherEvents.length, 0, "no more events")
})

test("test invoking .reload() re-fetches the frame's content", async ({ page }) => {
test("test invoking .reload() re-fetches the content of a <turbo-frame> element with a [src] attribute", async ({ page }) => {
await page.click("#link-frame")
await nextEventOnTarget(page, "frame", "turbo:frame-load")
await page.evaluate(() => document.getElementById("frame").reload())

const dispatchedEvents = await readEventLogs(page)

assert.deepEqual(
dispatchedEvents.map(([name, _, id]) => [id, name]),
dispatchedEvents
.map(([name, _, id]) => [id, name])
.filter(([id]) => id === "frame"),
[
["frame", "turbo:before-fetch-request"],
["frame", "turbo:before-fetch-response"],
["frame", "turbo:before-frame-render"],
["frame", "turbo:frame-render"],
["frame", "turbo:frame-load"]
]
)
})

test("test invoking .reload() re-fetches the content of a <turbo-frame> element without a [src] attribute", async ({ page }) => {
const frame = await page.locator("turbo-frame#frame")
const heading = await frame.locator("h2")

assert.match(await heading.textContent(), /Frames: #frame/)

await heading.evaluate((element) => element.textContent = "Not yet refreshed")

assert.match(await heading.textContent(), /Not yet refreshed/)

await frame.evaluate((element) => element.reload())

const dispatchedEvents = await readEventLogs(page)

assert.deepEqual(
dispatchedEvents
.map(([name, _, id]) => [id, name])
.filter(([id]) => id === "frame"),
[
["frame", "turbo:before-fetch-request"],
["frame", "turbo:before-fetch-response"],
Expand Down

0 comments on commit daacfc0

Please sign in to comment.