diff --git a/src/core/drive/preloader.js b/src/core/drive/preloader.js index b971cea19..ab7bc2efa 100644 --- a/src/core/drive/preloader.js +++ b/src/core/drive/preloader.js @@ -3,27 +3,28 @@ import { PageSnapshot } from "./page_snapshot" export class Preloader { selector = "a[data-turbo-preload]" - constructor(delegate) { + constructor(delegate, snapshotCache) { this.delegate = delegate - } - - get snapshotCache() { - return this.delegate.navigator.view.snapshotCache + this.snapshotCache = snapshotCache } start() { if (document.readyState === "loading") { - return document.addEventListener("DOMContentLoaded", () => { - this.preloadOnLoadLinksForView(document.body) - }) + document.addEventListener("DOMContentLoaded", this.#preloadAll) } else { this.preloadOnLoadLinksForView(document.body) } } + stop() { + document.removeEventListener("DOMContentLoaded", this.#preloadAll) + } + preloadOnLoadLinksForView(element) { for (const link of element.querySelectorAll(this.selector)) { - this.preloadURL(link) + if (this.delegate.shouldPreloadLink(link)) { + this.preloadURL(link) + } } } @@ -42,4 +43,8 @@ export class Preloader { // If we cannot preload that is ok! } } + + #preloadAll = () => { + this.preloadOnLoadLinksForView(document.body) + } } diff --git a/src/core/session.js b/src/core/session.js index 44edc7856..6aa5c1276 100644 --- a/src/core/session.js +++ b/src/core/session.js @@ -20,7 +20,6 @@ import { Preloader } from "./drive/preloader" export class Session { navigator = new Navigator(this) history = new History(this) - preloader = new Preloader(this) view = new PageView(this, document.documentElement) adapter = new BrowserAdapter(this) @@ -40,6 +39,10 @@ export class Session { started = false formMode = "on" + constructor() { + this.preloader = new Preloader(this, this.view.snapshotCache) + } + start() { if (!this.started) { this.pageObserver.start() @@ -72,6 +75,7 @@ export class Session { this.streamObserver.stop() this.frameRedirector.stop() this.history.stop() + this.preloader.stop() this.started = false } } @@ -123,6 +127,21 @@ export class Session { return this.history.restorationIdentifier } + // Preloader delegate + + shouldPreloadLink(element) { + const isUnsafe = element.hasAttribute("data-turbo-method") + const isStream = element.hasAttribute("data-turbo-stream") + const closestFrame = findClosestRecursively(element, "turbo-frame:not([disabled])") + const targetFrame = document.getElementById(element.getAttribute("data-turbo-frame")) + + if (isUnsafe || isStream || closestFrame instanceof FrameElement || targetFrame instanceof FrameElement) { + return false + } else { + return this.elementIsNavigatable(element) && locationIsVisitable(location, this.snapshot.rootLocation) + } + } + // History delegate historyPoppedToLocationWithRestorationIdentifier(location, restorationIdentifier) { diff --git a/src/tests/fixtures/frame_preloading.html b/src/tests/fixtures/frame_preloading.html index 9fb02266f..3d779da1a 100644 --- a/src/tests/fixtures/frame_preloading.html +++ b/src/tests/fixtures/frame_preloading.html @@ -8,5 +8,9 @@