diff --git a/src/core/drive/preloader.js b/src/core/drive/preloader.js index b93d9b7ee..7deca1857 100644 --- a/src/core/drive/preloader.js +++ b/src/core/drive/preloader.js @@ -1,5 +1,5 @@ import { PageSnapshot } from "./page_snapshot" -import { fetch } from "../../http/fetch" +import { FetchMethod, FetchRequest } from "../../http/fetch_request" export class Preloader { selector = "a[data-turbo-preload]" @@ -36,17 +36,37 @@ export class Preloader { return } + const fetchRequest = new FetchRequest(this, FetchMethod.get, location, new URLSearchParams(), link) + await fetchRequest.perform() + } + + // Fetch request delegate + + prepareRequest(fetchRequest) { + fetchRequest.headers["Sec-Purpose"] = "prefetch" + } + + async requestSucceededWithResponse(fetchRequest, fetchResponse) { try { - const response = await fetch(location.toString(), { headers: { "Sec-Purpose": "prefetch", Accept: "text/html" } }) - const responseText = await response.text() - const snapshot = PageSnapshot.fromHTMLString(responseText) + const responseHTML = await fetchResponse.responseHTML + const snapshot = PageSnapshot.fromHTMLString(responseHTML) - this.snapshotCache.put(location, snapshot) + this.snapshotCache.put(fetchRequest.url, snapshot) } catch (_) { // If we cannot preload that is ok! } } + requestStarted(fetchRequest) {} + + requestErrored(fetchRequest) {} + + requestFinished(fetchRequest) {} + + requestPreventedHandlingResponse(fetchRequest, fetchResponse) {} + + requestFailedWithResponse(fetchRequest, fetchResponse) {} + #preloadAll = () => { this.preloadOnLoadLinksForView(document.body) } diff --git a/src/tests/fixtures/hot_preloading.html b/src/tests/fixtures/hot_preloading.html index 0a9d511c5..029fdda8e 100644 --- a/src/tests/fixtures/hot_preloading.html +++ b/src/tests/fixtures/hot_preloading.html @@ -5,6 +5,7 @@ Page That Links to Preloading Page + diff --git a/src/tests/fixtures/preloaded.html b/src/tests/fixtures/preloaded.html index 9b34768fb..99de99152 100644 --- a/src/tests/fixtures/preloaded.html +++ b/src/tests/fixtures/preloaded.html @@ -5,6 +5,7 @@ Preloaded Page + diff --git a/src/tests/fixtures/preloading.html b/src/tests/fixtures/preloading.html index 9bdacc1aa..db1a57534 100644 --- a/src/tests/fixtures/preloading.html +++ b/src/tests/fixtures/preloading.html @@ -5,6 +5,7 @@ Preloading Page + diff --git a/src/tests/functional/preloader_tests.js b/src/tests/functional/preloader_tests.js index d4c750b93..f90250014 100644 --- a/src/tests/functional/preloader_tests.js +++ b/src/tests/functional/preloader_tests.js @@ -1,6 +1,6 @@ import { test } from "@playwright/test" import { assert } from "chai" -import { nextEventOnTarget } from "../helpers/page" +import { nextEventNamed, nextEventOnTarget } from "../helpers/page" test("preloads snapshot on initial load", async ({ page }) => { // contains `a[rel="preload"][href="http://localhost:9000/src/tests/fixtures/preloaded.html"]` @@ -12,6 +12,20 @@ test("preloads snapshot on initial load", async ({ page }) => { assert.ok(await urlInSnapshotCache(page, href)) }) +test("preloading dispatch turbo:before-fetch-{request,response} events", async ({ page }) => { + await page.goto("/src/tests/fixtures/preloading.html") + + const link = await page.locator("#preload_anchor") + const href = await link.evaluate((link) => link.href) + + const { url, fetchOptions } = await nextEventNamed(page, "turbo:before-fetch-request") + const { fetchResponse } = await nextEventNamed(page, "turbo:before-fetch-response") + + assert.equal(href, url, "dispatches request during preloading") + assert.equal(fetchOptions.headers.Accept, "text/html, application/xhtml+xml") + assert.equal(fetchResponse.response.url, href) +}) + test("preloads snapshot on page visit", async ({ page }) => { // contains `a[rel="preload"][href="http://localhost:9000/src/tests/fixtures/preloading.html"]` await page.goto("/src/tests/fixtures/hot_preloading.html")