-
Notifications
You must be signed in to change notification settings - Fork 429
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Prevent double requests from within
turbo-frame
Closes #743 The change in behavior can be traced back to [#412][]. When the overlap between the `LinkInterceptor` and the `LinkClickObserver` were unified, the technique used by the `LinkInterceptor` to prevent duplicate event handlers from responding to the same `click` event was changed in a subtle way. In its place, this commit changes the `LinkClickObserver` and `FormSubmitObserver` to ignore `<a>` clicks and `<form>` submissions if they're annotated with `[data-remote="true"]`. To exercise these edge cases, this commit also adds a `ujs.html` fixture file along with a `ujs_tests.ts` module to cover situations when `@rails/ujs` and `@hotwired/turbo` co-exist. [#412]: #412
- Loading branch information
1 parent
732db00
commit 5871173
Showing
4 changed files
with
75 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>Frame</title> | ||
<script src="/src/tests/fixtures/test.js"></script> | ||
<script type="module"> | ||
import Rails from "https://ga.jspm.io/npm:@rails/ujs@7.0.1/lib/assets/compiled/rails-ujs.js" | ||
|
||
Rails.start() | ||
</script> | ||
<script src="/dist/turbo.es2017-umd.js" data-turbo-track="reload"></script> | ||
</head> | ||
<body> | ||
<turbo-frame id="frame"> | ||
<h2>Frames: #frame</h2> | ||
|
||
<a data-remote="true" href="/src/tests/fixtures/frames/frame.html">navigate #frame to /src/tests/fixtures/frames/frame.html</a> | ||
<form data-remote="true" action="/src/tests/fixtures/frames/frame.html"> | ||
<button>navigate #frame to /src/tests/fixtures/frames/frame.html</button> | ||
</form> | ||
</turbo-frame> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { Page, test } from "@playwright/test" | ||
import { assert } from "chai" | ||
import { noNextEventOnTarget } from "../helpers/page" | ||
|
||
test.beforeEach(async ({ page }) => { | ||
await page.goto("/src/tests/fixtures/ujs.html") | ||
}) | ||
|
||
test("test clicking a [data-remote=true] anchor within a turbo-frame", async ({ page }) => { | ||
await assertRequestLimit(page, 1, async () => { | ||
await page.click("#frame a[data-remote=true]") | ||
await noNextEventOnTarget(page, "frame", "turbo:frame-load") | ||
|
||
assert.equal(await page.textContent("#frame h2"), "Frames: #frame", "does not navigate the target frame") | ||
}) | ||
}) | ||
|
||
test("test submitting a [data-remote=true] form within a turbo-frame", async ({ page }) => { | ||
await assertRequestLimit(page, 1, async () => { | ||
await page.click("#frame form[data-remote=true] button") | ||
await noNextEventOnTarget(page, "frame", "turbo:frame-load") | ||
|
||
assert.equal(await page.textContent("#frame h2"), "Frames: #frame", "does not navigate the target frame") | ||
}) | ||
}) | ||
|
||
async function assertRequestLimit(page: Page, count: number, callback: () => Promise<void>) { | ||
let requestsStarted = 0 | ||
await page.on("request", () => requestsStarted++) | ||
await callback() | ||
|
||
assert.equal(requestsStarted, count, `only submits ${count} requests`) | ||
} |