Skip to content

Commit

Permalink
Introduce Turbo.config object
Browse files Browse the repository at this point in the history
The initial implementation aims to replace the ad hoc configurations
spread across `window.Turbo` and `Turbo.session`. Those objects
shouldn't be considered part of the public interface, especially for
extension.

This commit exports a single object from `src/core/config` to serve as a
centralized, user-facing repository for configuration values.

The main `src/core/config` object is composed of two constituent parts:

* `src/core/config/drive`
* `src/core/config/forms`

In the future, the directory structure can be expanded upon to suit the
needs of the project.

Any user-facing configuration outside of `Turbo.config` is deprecated.
  • Loading branch information
seanpdoyle committed Mar 3, 2024
1 parent 00527e5 commit 49055e3
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 14 deletions.
4 changes: 4 additions & 0 deletions src/core/config/drive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const drive = {
enabled: true,
progressBarDelay: 500
}
3 changes: 3 additions & 0 deletions src/core/config/forms.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const forms = {
mode: "on"
}
7 changes: 7 additions & 0 deletions src/core/config/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { drive } from "./drive"
import { forms } from "./forms"

export const config = {
drive,
forms
}
9 changes: 7 additions & 2 deletions src/core/drive/form_submission.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { expandURL } from "../url"
import { clearBusyState, dispatch, getAttribute, getMetaContent, hasAttribute, markAsBusy } from "../../util"
import { StreamMessage } from "../streams/stream_message"
import { prefetchCache } from "./prefetch_cache"
import { config } from "../config"

export const FormSubmissionState = {
initialized: "initialized",
Expand All @@ -22,7 +23,7 @@ export const FormEnctype = {
export class FormSubmission {
state = FormSubmissionState.initialized

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

Expand Down Expand Up @@ -78,7 +79,11 @@ 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 confirmMethod = typeof config.forms.confirm === "function" ?
config.forms.confirm :
FormSubmission.confirmMethod

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

const session = new Session(recentRequests)
const { cache, navigator } = session
export { navigator, session, cache, PageRenderer, PageSnapshot, FrameRenderer, fetch }
export { navigator, session, cache, PageRenderer, PageSnapshot, FrameRenderer, fetch, config }

/**
* Starts the main session.
Expand Down Expand Up @@ -97,13 +97,22 @@ export function clearCache() {
* @param delay Time to delay in milliseconds
*/
export function setProgressBarDelay(delay) {
session.setProgressBarDelay(delay)
console.warn(
"Please replace `Turbo.setProgressBarDelay(delay)` with `Turbo.config.drive.progressBarDelay = delay`. The top-level function is deprecated and will be removed in a future version of Turbo.`"
)
config.drive.progressBarDelay = delay
}

export function setConfirmMethod(confirmMethod) {
FormSubmission.confirmMethod = confirmMethod
console.warn(
"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
}

export function setFormMode(mode) {
session.setFormMode(mode)
console.warn(
"Please replace `Turbo.setFormMode(mode)` with `Turbo.config.forms.mode = mode`. The top-level function is deprecated and will be removed in a future version of Turbo.`"
)
config.forms.mode = mode
}
42 changes: 35 additions & 7 deletions 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 { config } from "./config"

export class Session {
navigator = new Navigator(this)
Expand All @@ -37,11 +38,8 @@ export class Session {
streamMessageRenderer = new StreamMessageRenderer()
cache = new Cache(this)

drive = true
enabled = true
progressBarDelay = 500
started = false
formMode = "on"
#pageRefreshDebouncePeriod = 150

constructor(recentRequests) {
Expand Down Expand Up @@ -135,7 +133,10 @@ export class Session {
}

setFormMode(mode) {
this.formMode = mode
console.warn(
"Please replace `Turbo.session.formMode = mode` with `Turbo.config.forms.mode = mode`. The `Turbo.session.formMode` property is deprecated and will be removed in a future version of Turbo.`"
)
config.forms.mode = mode
}

get location() {
Expand Down Expand Up @@ -425,12 +426,12 @@ export class Session {
// Helpers

submissionIsNavigatable(form, submitter) {
if (this.formMode == "off") {
if (config.forms.mode == "off") {
return false
} else {
const submitterIsNavigatable = submitter ? this.elementIsNavigatable(submitter) : true

if (this.formMode == "optin") {
if (config.forms.mode == "optin") {
return submitterIsNavigatable && form.closest('[data-turbo="true"]') != null
} else {
return submitterIsNavigatable && this.elementIsNavigatable(form)
Expand All @@ -443,7 +444,7 @@ export class Session {
const withinFrame = findClosestRecursively(element, "turbo-frame")

// Check if Drive is enabled on the session or we're within a Frame.
if (this.drive || withinFrame) {
if (config.drive.enabled || withinFrame) {
// Element is navigatable by default, unless `data-turbo="false"`.
if (container) {
return container.getAttribute("data-turbo") != "false"
Expand All @@ -460,6 +461,33 @@ export class Session {
}
}

get drive() {
return config.drive.enabled
}

set drive(value) {
console.warn(
"Please replace `Turbo.session.drive = value` with `Turbo.config.drive = value`. The `Turbo.session.drive` property is deprecated and will be removed in a future version of Turbo.`"
)
config.drive.enabled = value
}

get progressBarDelay() {
return config.drive.progressBarDelay
}

set progressBarDelay(value) {
config.drive.progressBarDelay = value
}

get formMode() {
return config.forms.mode
}

set formMode(value) {
config.forms.mode = value
}

// Private

getActionForLink(link) {
Expand Down
1 change: 1 addition & 0 deletions src/tests/unit/export_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ test("Turbo interface", () => {
assert.equal(typeof Turbo.setConfirmMethod, "function")
assert.equal(typeof Turbo.setFormMode, "function")
assert.equal(typeof Turbo.cache, "object")
assert.equal(typeof Turbo.config, "object")
assert.equal(typeof Turbo.cache.clear, "function")
assert.equal(typeof Turbo.navigator, "object")
assert.equal(typeof Turbo.session, "object")
Expand Down

0 comments on commit 49055e3

Please sign in to comment.