diff --git a/src/core/frames/frame_controller.ts b/src/core/frames/frame_controller.ts index 6815bc349..7727f6491 100644 --- a/src/core/frames/frame_controller.ts +++ b/src/core/frames/frame_controller.ts @@ -21,6 +21,7 @@ export class FrameController implements AppearanceObserverDelegate, FetchRequest readonly formInterceptor: FormInterceptor currentURL?: string | null formSubmission?: FormSubmission + private currentFetchRequest: FetchRequest | null = null private resolveVisitPromise = () => {} private connected = false private hasBeenLoaded = false @@ -233,11 +234,15 @@ export class FrameController implements AppearanceObserverDelegate, FetchRequest // Private private async visit(url: Locatable) { - const request = new FetchRequest(this, FetchMethod.get, expandURL(url), undefined, this.element) + const request = new FetchRequest(this, FetchMethod.get, expandURL(url), new URLSearchParams, this.element) + + this.currentFetchRequest?.cancel() + this.currentFetchRequest = request return new Promise(resolve => { this.resolveVisitPromise = () => { this.resolveVisitPromise = () => {} + this.currentFetchRequest = null resolve() } request.perform() diff --git a/src/tests/fixtures/frames.html b/src/tests/fixtures/frames.html index 87a17dbf7..ed786a2a9 100644 --- a/src/tests/fixtures/frames.html +++ b/src/tests/fixtures/frames.html @@ -12,6 +12,7 @@

Frames

Frames: #frame

+ Navigate #frame to /frames/form.html

Frames: #hello

diff --git a/src/tests/functional/frame_tests.ts b/src/tests/functional/frame_tests.ts index 2a617ae79..61f008622 100644 --- a/src/tests/functional/frame_tests.ts +++ b/src/tests/functional/frame_tests.ts @@ -46,6 +46,15 @@ export class FrameTests extends TurboDriveTestCase { this.assert.equal(await frameText.getVisibleText(), "Frame: Loaded") } + async "test following a link in rapid succession cancels the previous request"() { + await this.clickSelector("#outside-frame-form") + await this.clickSelector("#outer-frame-link") + await this.nextBeat + + const frameText = await this.querySelector("#frame h2") + this.assert.equal(await frameText.getVisibleText(), "Frame: Loaded") + } + async "test following a link within a descendant frame whose ancestor declares a target set navigates the descendant frame"() { const link = await this.querySelector("#nested-root[target=frame] #nested-child a:not([data-turbo-frame])") const href = await link.getProperty("href")