From 2d4029463986073a876d813bf32b815321798315 Mon Sep 17 00:00:00 2001 From: Sean Doyle Date: Sun, 8 Oct 2023 17:37:18 -0400 Subject: [PATCH] Delegate `StreamActions.refresh` to `Session` The bulk of the `StreamActions.refresh` implementation was reaching through the global `window.Turbo` property, which itself was reaching through either global variables or the `Session`. This commit moves the implementation out of the `StreamActions` and into a new `Session.refresh(url, requestId)` method. With that change, all property access is encapsulated within the `Session`. To support that change, this commit also introduces the `StreamElement.requestId` property to read the `[request-id]` attribute. --- src/core/index.js | 4 +--- src/core/session.js | 10 ++++++++++ src/core/streams/stream_actions.js | 9 +++------ src/elements/stream_element.js | 7 +++++++ src/http/recent_fetch_requests.js | 2 +- .../functional/page_refresh_stream_action_tests.js | 2 +- src/tests/unit/stream_element_tests.js | 2 +- 7 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/core/index.js b/src/core/index.js index d326aaa89..99350cba4 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -3,12 +3,10 @@ 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 { LimitedSet } from "./drive/limited_set" const session = new Session() -const recentRequests = new LimitedSet(20) const { cache, navigator } = session -export { navigator, session, cache, recentRequests, PageRenderer, PageSnapshot, FrameRenderer } +export { navigator, session, cache, PageRenderer, PageSnapshot, FrameRenderer } /** * Starts the main session. diff --git a/src/core/session.js b/src/core/session.js index 38460d17d..928e03aae 100644 --- a/src/core/session.js +++ b/src/core/session.js @@ -16,6 +16,7 @@ import { clearBusyState, dispatch, findClosestRecursively, getVisitAction, markA import { PageView } from "./drive/page_view" import { FrameElement } from "../elements/frame_element" import { Preloader } from "./drive/preloader" +import { LimitedSet } from "./drive/limited_set" import { Cache } from "./cache" export class Session { @@ -35,6 +36,7 @@ export class Session { frameRedirector = new FrameRedirector(this, document.documentElement) streamMessageRenderer = new StreamMessageRenderer() cache = new Cache(this) + recentRequests = new LimitedSet(20) drive = true enabled = true @@ -93,6 +95,14 @@ export class Session { } } + refresh(url, requestId) { + const isRecentRequest = requestId && this.recentRequests.has(requestId) + if (!isRecentRequest) { + this.cache.exemptPageFromPreview() + this.visit(url, { action: "replace" }) + } + } + connectStreamSource(source) { this.streamObserver.connectStreamSource(source) } diff --git a/src/core/streams/stream_actions.js b/src/core/streams/stream_actions.js index 62801fd69..064e94ca4 100644 --- a/src/core/streams/stream_actions.js +++ b/src/core/streams/stream_actions.js @@ -1,3 +1,5 @@ +import { session } from "../" + export const StreamActions = { after() { this.targetElements.forEach((e) => e.parentElement?.insertBefore(this.templateContent, e.nextSibling)) @@ -33,11 +35,6 @@ export const StreamActions = { }, refresh() { - const requestId = this.getAttribute("request-id") - const isRecentRequest = requestId && window.Turbo.recentRequests.has(requestId) - if (!isRecentRequest) { - window.Turbo.cache.exemptPageFromPreview() - window.Turbo.visit(window.location.href, { action: "replace" }) - } + session.refresh(this.baseURI, this.requestId) } } diff --git a/src/elements/stream_element.js b/src/elements/stream_element.js index 38f463fb3..cd6dd3321 100644 --- a/src/elements/stream_element.js +++ b/src/elements/stream_element.js @@ -143,6 +143,13 @@ export class StreamElement extends HTMLElement { return this.getAttribute("targets") } + /** + * Reads the request-id attribute + */ + get requestId() { + return this.getAttribute("request-id") + } + #raise(message) { throw new Error(`${this.description}: ${message}`) } diff --git a/src/http/recent_fetch_requests.js b/src/http/recent_fetch_requests.js index 620afd0a5..36f878ea8 100644 --- a/src/http/recent_fetch_requests.js +++ b/src/http/recent_fetch_requests.js @@ -5,7 +5,7 @@ const originalFetch = window.fetch window.fetch = async function(url, options = {}) { const modifiedHeaders = new Headers(options.headers || {}) const requestUID = uuid() - window.Turbo.recentRequests.add(requestUID) + window.Turbo.session.recentRequests.add(requestUID) modifiedHeaders.append("X-Turbo-Request-Id", requestUID) return originalFetch(url, { diff --git a/src/tests/functional/page_refresh_stream_action_tests.js b/src/tests/functional/page_refresh_stream_action_tests.js index 22cf17e8d..c3c5b869c 100644 --- a/src/tests/functional/page_refresh_stream_action_tests.js +++ b/src/tests/functional/page_refresh_stream_action_tests.js @@ -22,7 +22,7 @@ test("don't refresh the page on self-originated request ids", async ({ page }) = assert.match(await textContent(page), /Hello/) await page.locator("#content").evaluate((content)=>content.innerHTML = "") - page.evaluate(()=> { window.Turbo.recentRequests.add("123") }) + page.evaluate(()=> { window.Turbo.session.recentRequests.add("123") }) await page.locator("#request-id").evaluate((input)=>input.value = "123") await page.click("#refresh button") diff --git a/src/tests/unit/stream_element_tests.js b/src/tests/unit/stream_element_tests.js index bd62c8aa5..2ae2ad9a4 100644 --- a/src/tests/unit/stream_element_tests.js +++ b/src/tests/unit/stream_element_tests.js @@ -183,7 +183,7 @@ test("test action=refresh", async () => { }) test("test action=refresh discarded when matching request id", async () => { - Turbo.recentRequests.add("123") + Turbo.session.recentRequests.add("123") document.body.setAttribute("data-modified", "") assert.ok(document.body.hasAttribute("data-modified"))