Skip to content

Commit

Permalink
Specify breakoutable frames in requesting page
Browse files Browse the repository at this point in the history
Rather than use a meta tag in the response, we can put a central list of
"breakoutable" paths in a single meta tag, and include that on
requesting pages.

Assuming that an application will have a small number of these paths, it
might be simpler to centralise them in one place and include that in a
shared layout.
  • Loading branch information
kevinmcconnell committed Feb 2, 2023
1 parent 3cf225c commit 82748d5
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 8 deletions.
19 changes: 12 additions & 7 deletions src/core/frames/frame_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export class FrameController
try {
const html = await fetchResponse.responseHTML
if (html) {
const { body, head } = parseHTMLDocument(html)
const { body } = parseHTMLDocument(html)
const newFrameElement = await this.extractForeignFrameElement(body)

if (newFrameElement) {
Expand All @@ -182,7 +182,7 @@ export class FrameController
session.frameLoaded(this.element)
this.fetchResponseLoaded(fetchResponse)
} else if (this.willHandleFrameMissingFromResponse(fetchResponse)) {
this.handleFrameMissingFromResponse(fetchResponse, head)
this.handleFrameMissingFromResponse(fetchResponse)
}
}
} finally {
Expand Down Expand Up @@ -426,8 +426,8 @@ export class FrameController
return !event.defaultPrevented
}

private handleFrameMissingFromResponse(fetchResponse: FetchResponse, head: HTMLHeadElement) {
if (this.responsePermittedToBreakOutOfFrame(head)) {
private handleFrameMissingFromResponse(fetchResponse: FetchResponse) {
if (this.responsePermittedToBreakOutOfFrame(fetchResponse)) {
this.warnFrameMissingBreakout(fetchResponse)
this.visitResponse(fetchResponse.response)
} else {
Expand All @@ -436,8 +436,13 @@ export class FrameController
}
}

private responsePermittedToBreakOutOfFrame(head: HTMLHeadElement) {
return !!head.querySelector(`meta[name=turbo-frame-missing][content=visit]`)
private responsePermittedToBreakOutOfFrame(fetchResponse: FetchResponse) {
const allowedPathsTag = this.element.ownerDocument.querySelector<HTMLMetaElement>(
`meta[name=turbo-frame-breakout-paths]`
)
const allowedPaths = allowedPathsTag?.content?.split(/\s+/) || []

return allowedPaths.includes(fetchResponse.location.pathname)
}

private warnFrameMissingBreakout(fetchResponse: FetchResponse) {
Expand All @@ -452,7 +457,7 @@ export class FrameController
throw new TurboFrameMissingError(
this.frameMissingMessage(
fetchResponse,
"To transform the response into a full-page visit, include the turbo-frame-missing meta tag."
"To transform the response into a full-page visit, include its path in a turbo-frame-breakout-paths meta tag."
)
)
}
Expand Down
2 changes: 2 additions & 0 deletions src/tests/fixtures/frames.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
<head>
<meta charset="utf-8">
<title>Frame</title>
<meta name="turbo-frame-breakout-paths" content="/src/tests/fixtures/frames/breakout_frame.html /somewhere_else">

<script src="/dist/turbo.es2017-umd.js" data-turbo-track="reload"></script>
<script src="/src/tests/fixtures/test.js"></script>
<script>
Expand Down
1 change: 0 additions & 1 deletion src/tests/fixtures/frames/breakout_frame.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
<meta charset="utf-8">
<title>Breakout frame</title>
<script src="/dist/turbo.es2017-umd.js" data-turbo-track="reload"></script>
<meta name="turbo-frame-missing" content="visit">
</head>
<body>
<h1>Breakout frame</h1>
Expand Down

0 comments on commit 82748d5

Please sign in to comment.