-
Notifications
You must be signed in to change notification settings - Fork 433
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extract Morph
class, then use it in FrameRenderer
#1029
Extract Morph
class, then use it in FrameRenderer
#1029
Conversation
This commit introduces the concept of page refresh. A page refresh happens when Turbo renders the current page again. We will offer two new options to control behavior when a page refresh happens: - The method used to update the page: with a new option to use morphing (Turbo currently replaces the body). - The scroll strategy: with a new option to keep it (Turbo currently resets scroll to the top-left). The combination of morphing and scroll-keeping results in smoother updates that keep the screen state. For example, this will keep both horizontal and vertical scroll, the focus, the text selection, CSS transition states, etc. We will also introduce a new turbo stream action that, when broadcasted, will request a page refresh. This will offer a simplified alternative to fine-grained broadcasted turbo-stream actions. Co-Authored-By: Jorge Manrubia <[email protected]>
642c3ef
to
fae93de
Compare
fae93de
to
5196762
Compare
assert.equal(await input.count(), 1) | ||
assert.equal(await frame.count("#permanent-form-in-frame"), 1) | ||
assert.equal(await frame.count("#permanent-descendant-input-in-frame"), 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something is off, I can't figure out a way to pass these. When the morph occurs, it duplicates the [data-turbo-permanent]
elements.
Declaring all `Idiomorph`-related logic in the `MorphRenderer` limits its accessibility to other parts of the system. For example, `<turbo-frame refresh="morph">` elements are unable to morph their renders when driven by `<a>` navigations or `<form>` submissions. This commit extracts the bulk of the morphing logic into a new `Morph` class. The `Morph` encapsulates the call to `Idiomorph`, along with the remote `<turbo-frame>` reloading and `[data-turbo-permanent]` checking. With this extraction, the `MorphRenderer` is implemented in terms of delegating to the static `Morph.render` method. With that extraction in place, the `FrameRenderer.renderElement` method can incorporate the `element.src && element.refresh === "morph"` check, calling `FrameRenderer.morph` when true, then falling back to the default `FrameRenderer.replace` when false. For the sake of consistency, declare all `Renderer` subclasses' `renderElement` methods in terms of `static replace` and `static morph` methods to be explicit about which styles they support. This commit includes test coverage for morphing `<turbo-frame refresh="morph">` elements driven by typical navigation. The potential for `<turbo-stream action="morph">` --- With the `Morph.render` function existing separately from `MorphRenderer`, there's the potential to add a new `StreamAction.morph`. The implementation would look something like: ```js morph() { this.targetElements.forEach((targetElement) => { Morph.render(targetElement, this.templateContent) }) } ``` I've omitted that from this commit because I'm not sure if that's an interface we're interested in introducing, but I did want to highlight the possibility here. It'd be an Idiomorph-powered version of the [turbo-morph][] package. [turbo-morph]: https://github.com/marcoroth/turbo-morph
5196762
to
2fd95cf
Compare
|
||
render(morphStyle = "outerHTML") { | ||
window.Idiomorph.morph(this.currentElement, this.newElement, { | ||
ignoreActiveValue: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ignoreActiveValue: option was introduced in 0.0.9
, and feels important enough to include as a default for the sake of focus preservation and to minimize disruptions to the element with focus.
Progressing this branch forward hinges on bigskysoftware/idiomorph#12 being merged. Without it, the package needs to depend on window.Idiomorph
.
9125652
to
00b3015
Compare
c75d4bc
to
25b9db0
Compare
25b9db0
to
9944490
Compare
Declaring all
Idiomorph
-related logic in theMorphRenderer
limitsits accessibility to other parts of the system. For example,
<turbo-frame refresh="morph">
elements are unable to morph theirrenders when driven by
<a>
navigations or<form>
submissions.This commit extracts the bulk of the morphing logic into a new
Morph
class. The
Morph
encapsulates the call toIdiomorph
, along with theremote
<turbo-frame>
reloading and[data-turbo-permanent]
checking.With this extraction, the
MorphRenderer
is implemented in terms ofdelegating to the static
Morph.render
method.With that extraction in place, the
FrameRenderer.renderElement
methodcan incorporate the
element.src && element.refresh === "morph"
check,calling
FrameRenderer.morph
when true, then falling back to thedefault
FrameRenderer.replace
when false.For the sake of consistency, declare all
Renderer
subclasses'renderElement
methods in terms ofstatic replace
andstatic morph
methods to be explicit about which styles they support.
This commit includes test coverage for morphing
<turbo-frame refresh="morph">
elements driven by typical navigation.The potential for
<turbo-stream action="morph">
With the
Morph.render
function existing separately fromMorphRenderer
, there's the potential to add a newStreamAction.morph
.The implementation would look something like:
I've omitted that from this commit because I'm not sure if that's an
interface we're interested in introducing, but I did want to highlight
the possibility here. It'd be an Idiomorph-powered version of the
turbo-morph package.