Skip to content

Commit e81d363

Browse files
committed
Add support to replace the turbo_frame contents
1 parent 73cb728 commit e81d363

File tree

21 files changed

+468
-13
lines changed

21 files changed

+468
-13
lines changed

.github/workflows/prettier.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ jobs:
2525
run: 'npm install --legacy-peer-deps'
2626

2727
- name: Run Prettier
28-
run: 'npx prettier --check --fail-on-errors .'
28+
run: 'npx prettier --check .'
2929

app/assets/builds/@turbo-boost/commands.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/assets/builds/@turbo-boost/commands.js.map

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/javascript/invoker.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ const parseError = error => {
99
dispatch(lifecycle.events.clientError, document, { detail: { message, error } }, true)
1010
}
1111

12-
const parseAndRenderResponse = response => {
12+
const parseAndRenderResponse = frameId => response => {
1313
const { strategy } = headers.tokenize(response.headers.get(headers.RESPONSE_HEADER))
14-
response.text().then(content => render(strategy, content))
14+
response.text().then(content => render(strategy, content, frameId))
1515
}
1616

1717
const invoke = (payload = {}) => {
@@ -21,7 +21,7 @@ const invoke = (payload = {}) => {
2121
headers: headers.prepare({}),
2222
body: JSON.stringify(payload)
2323
})
24-
.then(parseAndRenderResponse)
24+
.then(parseAndRenderResponse(payload.frameId))
2525
.catch(parseError)
2626
} catch (error) {
2727
parseError(error)

app/javascript/renderer.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
import elements from './elements'
2+
3+
const getElementByIdFromHTMLString = (htmlString, id) => {
4+
var parser = new DOMParser()
5+
var doc = parser.parseFromString(htmlString, 'text/html')
6+
var element = doc.getElementById(id)
7+
return element.outerHTML
8+
}
9+
10+
const frameReplace = (content, frameId) => {
11+
const newFrame = getElementByIdFromHTMLString(content, frameId)
12+
const frame = document.querySelector(`#${frameId}`)
13+
if (frame && newFrame) TurboBoost?.Streams?.morph?.method(frame, newFrame)
14+
}
15+
116
const append = content => {
217
document.body.insertAdjacentHTML('beforeend', content)
318
}
@@ -14,10 +29,11 @@ const replace = content => {
1429
}
1530

1631
// TODO: dispatch events after append/replace so we can apply page state
17-
export const render = (strategy, content) => {
32+
export const render = (strategy, content, frameId) => {
1833
if (strategy && content) {
1934
if (strategy.match(/^Append$/i)) return append(content)
2035
if (strategy.match(/^Replace$/i)) return replace(content)
36+
if (strategy.match(/^FrameReplace$/i)) return frameReplace(content, frameId)
2137
}
2238
}
2339

lib/turbo_boost/commands/runner.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ def turbo_stream_template_exists?
235235
# Commands support the following redering strategies on the client.
236236
# 1. Replace: The entire page (head, body) is replaced with the new content via morph
237237
# 2. Append: The new content is appended to the body
238+
# 3. FrameReplace: Replace the turbo frame specified in the command with the frame in the content. The content can contain more( e.g. whole content)
238239
def client_render_strategy
239240
# Use the replace strategy if the follow things are true:
240241
#
@@ -244,6 +245,9 @@ def client_render_strategy
244245
if command_params[:driver] == "window" && controller_action_allowed?
245246
return "Replace" unless turbo_stream_template_exists?
246247
end
248+
if command_params[:driver] == "frame" && controller_action_allowed?
249+
return "FrameReplace" unless turbo_stream_template_exists?
250+
end
247251

248252
"Append"
249253
end

test/dummy/app/assets/builds/tailwind.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/dummy/app/commands/decrement_count_command.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
class DecrementCountCommand < ApplicationCommand
44
def perform
55
Current.user.decrement! :count
6+
controller.instance_variable_set(:@extra_data, "decremented")
67
end
78
end

test/dummy/app/commands/increment_count_command.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
class IncrementCountCommand < ApplicationCommand
44
def perform
55
Current.user.increment! :count
6+
controller.instance_variable_set(:@extra_data, "incremented")
67
end
78
end
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# frozen_string_literal: true
2+
3+
class TurboFrameReplacesController < ApplicationController
4+
# GET /turbo_frame_replace
5+
def show
6+
@extra_data ||= "Unchanged"
7+
end
8+
end

0 commit comments

Comments
 (0)