Skip to content

Commit

Permalink
passing tests
Browse files Browse the repository at this point in the history
  • Loading branch information
seanpdoyle committed Sep 15, 2021
1 parent 28240de commit 6931b98
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 13 deletions.
4 changes: 2 additions & 2 deletions src/core/frames/frame_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ export class FrameController implements AppearanceObserverDelegate, FetchRequest

formSubmissionSucceededWithResponse(formSubmission: FormSubmission, response: FetchResponse) {
const frame = this.findFrameElement(formSubmission.formElement, formSubmission.submitter)
const target = formSubmission.formElement.getAttribute("data-turbo-frame")
|| formSubmission.submitter?.getAttribute("data-turbo-frame")
const target = formSubmission.submitter?.getAttribute("data-turbo-frame")
|| formSubmission.formElement.getAttribute("data-turbo-frame")
|| frame.getAttribute("target")

if (response.redirected && target == "_top") {
Expand Down
20 changes: 14 additions & 6 deletions src/core/frames/frame_redirector.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { FormInterceptor, FormInterceptorDelegate } from "./form_interceptor"
import { FrameElement } from "../../elements/frame_element"
import { LinkInterceptor, LinkInterceptorDelegate } from "./link_interceptor"
import { FetchMethod, fetchMethodFromString } from "../../http/fetch_request"

export class FrameRedirector implements LinkInterceptorDelegate, FormInterceptorDelegate {
readonly element: Element
Expand Down Expand Up @@ -51,15 +52,20 @@ export class FrameRedirector implements LinkInterceptorDelegate, FormInterceptor
const frame = this.findFrameElement(element, submitter)

if (frame) {
const target = frame.getAttribute("target")

if (frame == element.closest("turbo-frame")) {
if (element instanceof HTMLFormElement) {
const frameTarget = element.getAttribute("data-turbo-frame")
const target = submitter?.getAttribute("data-turbo-frame")
|| element.getAttribute("data-turbo-frame")
|| frame.getAttribute("target")
const method = submitter?.getAttribute("formmethod") || element.getAttribute("method") || ""

return target == "_top" || frameTarget == "_top"
if (fetchMethodFromString(method) == FetchMethod.get) {
return false
} else {
return target == "_top"
}
} else {
return target == "_top"
return frame.getAttribute("target") == "_top"
}
} else {
return true
Expand All @@ -73,13 +79,15 @@ export class FrameRedirector implements LinkInterceptorDelegate, FormInterceptor
const id = element.getAttribute("data-turbo-frame") || submitter?.getAttribute("data-turbo-frame")

if (id == "_top") {
return element.closest<FrameElement>(`turbo-frame:not([disabled])`)
return element.closest<FrameElement>("turbo-frame:not([disabled])")
} else if (id) {
const frame = this.element.querySelector(`#${id}:not([disabled])`)

if (frame instanceof FrameElement) {
return frame
}
} else {
return element.closest<FrameElement>("turbo-frame:not([disabled])")
}
}
}
12 changes: 10 additions & 2 deletions src/tests/fixtures/form.html
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,19 @@ <h2>Frame: Form</h2>
</div>
<form action="/__turbo/redirect" method="post" class="redirect" data-turbo-frame="_top">
<input type="hidden" name="path" value="/src/tests/fixtures/one.html">
<button>303 and redirect _top</button>
<button>303 data-turbo-frame="_top"</button>
</form>
<form class="unprocessable_entity" action="/__turbo/reject" method="post" data-turbo-frame="_top">
<input type="hidden" name="status" value="422">
<button>422</button>
<button>422 form[data-turbo-frame="_top"]</button>
</form>
<form class="unprocessable_entity" action="/__turbo/reject" method="post">
<input type="hidden" name="status" value="422">
<button data-turbo-frame="_top">422 button[data-turbo-frame="_top"]</button>
</form>
<form class="unprocessable_entity" action="/__turbo/reject" method="post">
<input type="hidden" name="status" value="422">
<button>422 turbo-frame[target="_top"]</button>
</form>
</turbo-frame>
<a href="/__turbo/messages?content=Link!&type=stream" data-turbo-method="post" id="link-method-outside-frame">Stream link outside frame</a>
Expand Down
30 changes: 27 additions & 3 deletions src/tests/functional/form_submission_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export class FormSubmissionTests extends TurboDriveTestCase {
}

async "test frame form GET submission from submitter with data-turbo-frame=_top"() {
await this.clickSelector("#frame form[method=get] [type=submit][data-turbo-frame=_top]")
await this.clickSelector("#frame form[method=get] button[data-turbo-frame=_top]")
await this.nextBody

const title = await this.querySelector("h1")
Expand Down Expand Up @@ -311,7 +311,7 @@ export class FormSubmissionTests extends TurboDriveTestCase {
this.assert.equal(await this.nextAttributeMutationNamed("frame", "busy"), null, "removes [busy] from the #frame")
}

async "test frame form submission with [data-turbo-frame=_top]"() {
async "test frame form submission with form[data-turbo-frame=_top]"() {
await this.clickSelector("#frame form.redirect[data-turbo-frame=_top] button")
await this.nextBody

Expand Down Expand Up @@ -367,7 +367,7 @@ export class FormSubmissionTests extends TurboDriveTestCase {
this.assert.equal(await title.getVisibleText(), "Frame: Internal Server Error")
}

async "test invalid frame form submission in turbo-frame[data-turbo-frame=_top]"() {
async "test invalid frame form submission submitted by form[data-turbo-frame=_top]"() {
await this.clickSelector("#frame form.unprocessable_entity[data-turbo-frame=_top] button")
await this.nextBeat

Expand All @@ -377,6 +377,30 @@ export class FormSubmissionTests extends TurboDriveTestCase {
this.assert.equal(await frameTitle.getVisibleText(), "Frame: Unprocessable Entity", "renders the response HTML inside the frame")
}

async "test invalid frame form submission submitted by button[data-turbo-frame=_top]"() {
await this.clickSelector("#frame form.unprocessable_entity button[data-turbo-frame=_top]")
await this.nextBeat

const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")
this.assert.equal(await title.getVisibleText(), "Form", "does not replace entire page")
this.assert.equal(await frameTitle.getVisibleText(), "Frame: Unprocessable Entity", "renders the response HTML inside the frame")
}

async "test invalid frame form submission submitted in turbo-frame[target=_top]"() {
await this.remote.execute(() => {
addEventListener("turbo:load", () => document.getElementById("frame")?.setAttribute("target", "_top"), { once: true })
})

await this.clickSelector("#frame form.unprocessable_entity button")
await this.nextBeat

const title = await this.querySelector("h1")
const frameTitle = await this.querySelector("#frame h2")
this.assert.equal(await title.getVisibleText(), "Form", "does not replace entire page")
this.assert.equal(await frameTitle.getVisibleText(), "Frame: Unprocessable Entity", "renders the response HTML inside the frame")
}

async "test frame form submission with stream response"() {
const button = await this.querySelector("#frame form.stream input[type=submit]")
await button.click()
Expand Down

0 comments on commit 6931b98

Please sign in to comment.