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 Aug 18, 2024
1 parent 6646957 commit bbd65cc
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 6 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
Expand Up @@ -2,6 +2,7 @@ import { FetchRequest, FetchMethod, fetchMethodFromString, fetchEnctypeFromStrin
import { expandURL } from "../url"
import { clearBusyState, dispatch, getAttribute, getMetaContent, hasAttribute, markAsBusy } from "../../util"
import { StreamMessage } from "../streams/stream_message"
import { Confirmation } from "../confirmation"
import { prefetchCache } from "./prefetch_cache"
import { config } from "../config"

Expand All @@ -23,10 +24,6 @@ export const FormEnctype = {
export class FormSubmission {
state = FormSubmissionState.initialized

static confirmMethod(message) {
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 @@ -81,7 +78,7 @@ export class FormSubmission {
if (typeof confirmationMessage === "string") {
const confirmMethod = typeof config.forms.confirm === "function" ?
config.forms.confirm :
FormSubmission.confirmMethod
Confirmation.confirmMethod

const answer = await confirmMethod(confirmationMessage, this.formElement, this.submitter)
if (!answer) {
Expand Down
2 changes: 2 additions & 0 deletions src/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +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 { Confirmation } from "./confirmation"
import { fetch, recentRequests } from "../http/fetch"
import { config } from "./config"

Expand Down Expand Up @@ -108,6 +109,7 @@ export function setConfirmMethod(confirmMethod) {
"Please replace `Turbo.setConfirmMethod(confirmMethod)` with `Turbo.config.forms.confirm = confirmMethod`. The top-level function is deprecated and will be removed in a future version of Turbo.`"
)
config.forms.confirm = 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"
import { config } from "./config"

export class Session {
Expand Down Expand Up @@ -229,9 +230,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 bbd65cc

Please sign in to comment.