Skip to content

Commit

Permalink
Fix data-turbo-confirm on <a> without data-turbo-method
Browse files Browse the repository at this point in the history
  • Loading branch information
marcoroth committed Feb 16, 2023
1 parent 89be8e4 commit f3682bd
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 8 deletions.
5 changes: 5 additions & 0 deletions src/core/confirmation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export class Confirmation {
static confirmMethod(message, _element, _submitter) {
return Promise.resolve(confirm(message))
}
}
7 changes: 2 additions & 5 deletions src/core/drive/form_submission.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Confirmation } from "../confirmation"
import { FetchRequest, FetchMethod, fetchMethodFromString, fetchEnctypeFromString, isSafe } from "../../http/fetch_request"
import { expandURL } from "../url"
import { clearBusyState, dispatch, getAttribute, getMetaContent, hasAttribute, markAsBusy } from "../../util"
Expand All @@ -22,10 +23,6 @@ export const FormEnctype = {
export class FormSubmission {
state = FormSubmissionState.initialized

static confirmMethod(message, _element, _submitter) {
return Promise.resolve(confirm(message))
}

constructor(delegate, formElement, submitter, mustRedirect = false) {
const method = getMethod(formElement, submitter)
const action = getAction(getFormAction(formElement, submitter), method)
Expand Down Expand Up @@ -78,7 +75,7 @@ export class FormSubmission {
const confirmationMessage = getAttribute("data-turbo-confirm", this.submitter, this.formElement)

if (typeof confirmationMessage === "string") {
const answer = await FormSubmission.confirmMethod(confirmationMessage, this.formElement, this.submitter)
const answer = await Confirmation.confirmMethod(confirmationMessage, this.formElement, this.submitter)
if (!answer) {
return
}
Expand Down
4 changes: 2 additions & 2 deletions src/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Session } from "./session"
import { PageRenderer } from "./drive/page_renderer"
import { PageSnapshot } from "./drive/page_snapshot"
import { FrameRenderer } from "./frames/frame_renderer"
import { FormSubmission } from "./drive/form_submission"
import { Confirmation } from "./confirmation"
import { fetch, recentRequests } from "../http/fetch"

const session = new Session(recentRequests)
Expand Down Expand Up @@ -101,7 +101,7 @@ export function setProgressBarDelay(delay) {
}

export function setConfirmMethod(confirmMethod) {
FormSubmission.confirmMethod = confirmMethod
Confirmation.confirmMethod = confirmMethod
}

export function setFormMode(mode) {
Expand Down
11 changes: 10 additions & 1 deletion src/core/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { PageView } from "./drive/page_view"
import { FrameElement } from "../elements/frame_element"
import { Preloader } from "./drive/preloader"
import { Cache } from "./cache"
import { Confirmation } from "./confirmation"

export class Session {
navigator = new Navigator(this)
Expand Down Expand Up @@ -223,9 +224,17 @@ export class Session {
)
}

followedLinkToLocation(link, location) {
async followedLinkToLocation(link, location) {
const action = this.getActionForLink(link)
const acceptsStreamResponse = link.hasAttribute("data-turbo-stream")
const confirmationMessage = link.getAttribute("data-turbo-confirm")

if (typeof confirmationMessage === "string") {
const answer = await Confirmation.confirmMethod(confirmationMessage, link, link)
if (!answer) {
return
}
}

this.visit(location.href, { action, acceptsStreamResponse })
}
Expand Down
25 changes: 25 additions & 0 deletions src/tests/functional/visit_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,31 @@ test("Turbo history state after a reload", async ({ page }) => {
)
})

test("test data-turbo-confirm on anchor element without data-turbo-method", async ({ page }) => {
let confirmed = false

page.on("dialog", (alert) => {
assert.equal(alert.message(), "Are you sure?")
alert.accept()
confirmed = true
})

await page.evaluate(() => {
const link = document.querySelector("#same-origin-link")

if (link) link.dataset.turboConfirm = "Are you sure?"
})

assert.equal(await page.locator("#same-origin-link[data-turbo-confirm]:not([data-turbo-method])").count(), 1)
assert.equal(pathname(page.url()), "/src/tests/fixtures/visit.html")

await page.click("#same-origin-link")
await nextEventNamed(page, "turbo:load")

assert.isTrue(confirmed)
assert.equal(pathname(page.url()), "/src/tests/fixtures/one.html")
})

async function visitLocation(page, location) {
return page.evaluate((location) => window.Turbo.visit(location), location)
}
Expand Down

0 comments on commit f3682bd

Please sign in to comment.