-
Notifications
You must be signed in to change notification settings - Fork 331
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
Trix editor is disabled and the toolbar disappears on page "update" using turbo 8 beta #533
Comments
I did a test also with a Trix editor and had similar issue. This relates to this more general issue hotwired/turbo#1083. What worked for me was to put the Trix editor in a |
Thanks @adrienpoly for linking the more general issue.
Yeah, I've done the same thing to temporarily fix the problem! |
I wonder if the right place to fix this is Trix itself or Action Text. Is it correct that Trix knows about these cases? Or should it be bulletproof and reset itself every time trix-editor element is changed. I had initially thought of marking trix-toolbar as data-turbo-permanent but if you say that the editor is disabled I don't think that will be enough. |
Follow-up to [9944490][] Related to [hotwired#1083] Related to [@hotwired/turbo-railshotwired#533][] The problem --- Some client-side plugins are losing their state when elements are morphed. Without resorting to `MutationObserver` instances to determine when a node is morphed, uses of those plugins don't have the ability to prevent (without `[data-turbo-permanent]`) or respond to the morphing. The proposal --- This commit introduces a `turbo:before-morph` event that'll dispatch as part of the Idiomorph `beforeNodeMorphed` callback. It'll give interested parties access to the nodes before and after a morph. If that event is cancelled via `event.preventDefault()`, it'll skip the morph as if the element were marked with `[data-turbo-permanent]`. Similarly, this commit re-purposes the new `turbo:morph` event to be dispatched for every morphed node (via Idiomorph's `afterNodeMorphed` callback). The original implementation dispatched the event for the `<body>` element as part of `MorphRenderer`'s lifecycle. That event will still be dispatched, since `<body>` is the first element the callback will fire for. In addition to that event, each individual morphed node will dispatch one. This commit re-introduced test coverage for a Stimulus controller to demonstrate how an interested party might respond. It isn't immediately clear with that code should live, but once we iron out the details, it could be part of a `@hotwired/turbo/stimulus` package, or a `@hotwired/stimulus/turbo` package that users (or `@hotwired/turbo-rails`) could opt-into. [9944490]: hotwired@9944490 [hotwired#1083]: hotwired#1083 [@hotwired/turbo-railshotwired#533]: hotwired/turbo-rails#533
With |
After further investigation, I believe there are two issues at-play:
There are, of course, some other issues. For example, Trix will respond to an omitted As an initial step, I propose that Action Text make two corresponding changes:
|
Follow-up to [9944490][] Related to [hotwired#1083] Related to [@hotwired/turbo-railshotwired#533][] The problem --- Some client-side plugins are losing their state when elements are morphed. Without resorting to `MutationObserver` instances to determine when a node is morphed, uses of those plugins don't have the ability to prevent (without `[data-turbo-permanent]`) or respond to the morphing. The proposal --- This commit introduces a `turbo:before-morph` event that'll dispatch as part of the Idiomorph `beforeNodeMorphed` callback. It'll give interested parties access to the nodes before and after a morph. If that event is cancelled via `event.preventDefault()`, it'll skip the morph as if the element were marked with `[data-turbo-permanent]`. Similarly, this commit re-purposes the new `turbo:morph` event to be dispatched for every morphed node (via Idiomorph's `afterNodeMorphed` callback). The original implementation dispatched the event for the `<body>` element as part of `MorphRenderer`'s lifecycle. That event will still be dispatched, since `<body>` is the first element the callback will fire for. In addition to that event, each individual morphed node will dispatch one. This commit re-introduced test coverage for a Stimulus controller to demonstrate how an interested party might respond. It isn't immediately clear with that code should live, but once we iron out the details, it could be part of a `@hotwired/turbo/stimulus` package, or a `@hotwired/stimulus/turbo` package that users (or `@hotwired/turbo-rails`) could opt-into. [9944490]: hotwired@9944490 [hotwired#1083]: hotwired#1083 [@hotwired/turbo-railshotwired#533]: hotwired/turbo-rails#533
Strange. I can't reproduce this issue. |
Follow-up to [9944490][] Related to [hotwired#1083] Related to [@hotwired/turbo-railshotwired#533][] The problem --- Some client-side plugins are losing their state when elements are morphed. Without resorting to `MutationObserver` instances to determine when a node is morphed, uses of those plugins don't have the ability to prevent (without `[data-turbo-permanent]`) or respond to the morphing. The proposal --- This commit introduces a `turbo:before-morph` event that'll dispatch as part of the Idiomorph `beforeNodeMorphed` callback. It'll give interested parties access to the nodes before and after a morph. If that event is cancelled via `event.preventDefault()`, it'll skip the morph as if the element were marked with `[data-turbo-permanent]`. Along with `turbo:before-morph`, this commit also introduces a `turbo:before-morph-attribute` to correspond to the `beforeAttributeUpdated` callback that Idiomorph provides. When listeners (like an `HTMLDetailsElement`, an `HTMLDialogElement`, or a Stimulus controller) want to preserve the state of an attribute, they can cancel the `turbo:before-morph-attribute` event that corresponds with the attribute name (through `event.detail.attributeName`). Similarly, this commit re-purposes the new `turbo:morph` event to be dispatched for every morphed node (via Idiomorph's `afterNodeMorphed` callback). The original implementation dispatched the event for the `<body>` element as part of `MorphRenderer`'s lifecycle. That event will still be dispatched, since `<body>` is the first element the callback will fire for. In addition to that event, each individual morphed node will dispatch one. This commit re-introduced test coverage for a Stimulus controller to demonstrate how an interested party might respond. It isn't immediately clear with that code should live, but once we iron out the details, it could be part of a `@hotwired/turbo/stimulus` package, or a `@hotwired/stimulus/turbo` package that users (or `@hotwired/turbo-rails`) could opt-into. [9944490]: hotwired@9944490 [hotwired#1083]: hotwired#1083 [@hotwired/turbo-railshotwired#533]: hotwired/turbo-rails#533
Follow-up to [9944490][] Related to [hotwired#1083] Related to [@hotwired/turbo-railshotwired#533][] The problem --- Some client-side plugins are losing their state when elements are morphed. Without resorting to `MutationObserver` instances to determine when a node is morphed, uses of those plugins don't have the ability to prevent (without `[data-turbo-permanent]`) or respond to the morphing. The proposal --- This commit introduces a `turbo:before-morph-element` event that'll dispatch as part of the Idiomorph `beforeNodeMorphed` callback. It'll give interested parties access to the nodes before and after a morph. If that event is cancelled via `event.preventDefault()`, it'll skip the morph as if the element were marked with `[data-turbo-permanent]`. Along with `turbo:before-morph-element`, this commit also introduces a `turbo:before-morph-attribute` to correspond to the `beforeAttributeUpdated` callback that Idiomorph provides. When listeners (like an `HTMLDetailsElement`, an `HTMLDialogElement`, or a Stimulus controller) want to preserve the state of an attribute, they can cancel the `turbo:before-morph-attribute` event that corresponds with the attribute name (through `event.detail.attributeName`). Similarly, this commit adds a new `turbo:morph-element` event to be dispatched for every morphed node (via Idiomorph's `afterNodeMorphed` callback). The original implementation dispatched the event for the `<body>` element as part of `MorphRenderer`'s lifecycle. That event will still be dispatched, since `<body>` is the first element the callback will fire for. In addition to that event, each individual morphed node will dispatch one. This commit re-introduced test coverage for a Stimulus controller to demonstrate how an interested party might respond. It isn't immediately clear with that code should live, but once we iron out the details, it could be part of a `@hotwired/turbo/stimulus` package, or a `@hotwired/stimulus/turbo` package that users (or `@hotwired/turbo-rails`) could opt-into. [9944490]: hotwired@9944490 [hotwired#1083]: hotwired#1083 [@hotwired/turbo-railshotwired#533]: hotwired/turbo-rails#533
Is just stumbled across this. now that there the hooks available, is there a solution for the trix editor? |
I think I got it working like this: addEventListener("turbo:before-morph-attribute", (event) => {
const { target } = event;
if (target.tagName == "TRIX-EDITOR") {
// save new value as default so that `reset()` doesn't reset to old content
target.defaultValue = target.value;
}
});
addEventListener("turbo:morph-element", (event) => {
const { target } = event;
if (target.tagName == "TRIX-EDITOR") {
// after morphing `value` is `null`, so set value to default which was saved before
target.reset();
// disconnect because we call `connectedCallback()` below
target.disconnectedCallback();
// remove old `editorController`, otherwise `connectedCallback` will skip some initialization
target.editorController = null;
// connect it
target.connectedCallback();
}
}); I haven't tested it extensively though yet, and not with stuff like attachments and images inside it. What do you think? |
I just noticed my solution has a serious performance drawback. On one page I have 188 Anyway it looks like I got a solution that is easier: Simply prevent morphing for the editor and toolbar. addEventListener("turbo:before-morph-attribute", (event) => {
const { target } = event;
if (target.tagName == "TRIX-EDITOR" || target.tagName == "TRIX-TOOLBAR") {
event.preventDefault();
}
});
addEventListener("turbo:before-morph-element", (event) => {
const { target } = event;
if (target.tagName == "TRIX-EDITOR" || target.tagName == "TRIX-TOOLBAR") {
event.preventDefault();
}
}); A drawback is though that if the request actually changed the editor (e.g. different content got returned) it will not be reflected. I think there is nothing to do about it for now. |
@jorgemanrubia sorry to tag you out of the blue, but I'd love your thoughts on this one. I'm sure the Hey calendar uses Trix somewhere, so I imagine this is something you guys would have come up against already? |
Follow-up to [9944490][] Related to [hotwired#1083] Related to [@hotwired/turbo-railshotwired#533][] The problem --- Some client-side plugins are losing their state when elements are morphed. Without resorting to `MutationObserver` instances to determine when a node is morphed, uses of those plugins don't have the ability to prevent (without `[data-turbo-permanent]`) or respond to the morphing. The proposal --- This commit introduces a `turbo:before-morph-element` event that'll dispatch as part of the Idiomorph `beforeNodeMorphed` callback. It'll give interested parties access to the nodes before and after a morph. If that event is cancelled via `event.preventDefault()`, it'll skip the morph as if the element were marked with `[data-turbo-permanent]`. Along with `turbo:before-morph-element`, this commit also introduces a `turbo:before-morph-attribute` to correspond to the `beforeAttributeUpdated` callback that Idiomorph provides. When listeners (like an `HTMLDetailsElement`, an `HTMLDialogElement`, or a Stimulus controller) want to preserve the state of an attribute, they can cancel the `turbo:before-morph-attribute` event that corresponds with the attribute name (through `event.detail.attributeName`). Similarly, this commit adds a new `turbo:morph-element` event to be dispatched for every morphed node (via Idiomorph's `afterNodeMorphed` callback). The original implementation dispatched the event for the `<body>` element as part of `MorphRenderer`'s lifecycle. That event will still be dispatched, since `<body>` is the first element the callback will fire for. In addition to that event, each individual morphed node will dispatch one. This commit re-introduced test coverage for a Stimulus controller to demonstrate how an interested party might respond. It isn't immediately clear with that code should live, but once we iron out the details, it could be part of a `@hotwired/turbo/stimulus` package, or a `@hotwired/stimulus/turbo` package that users (or `@hotwired/turbo-rails`) could opt-into. [9944490]: hotwired@9944490 [hotwired#1083]: hotwired#1083 [@hotwired/turbo-railshotwired#533]: hotwired/turbo-rails#533
Problems with the Trix editor blocked this before. I didn't identify problems with any other components. The issue seems to be cases where a component adds elements and the morph removes them but does not reinitialize the component so it can fix things up. See: hotwired/turbo-rails#533 See: hotwired/turbo#1083
I have a task page where the user can comment using a trix editor. When I create a comment, it goes on the comments list above correctly, without reloading the page but the trix editor is disabled and the toolbar isn't there anymore.
Preview
Initial status:

Let's create a comment

This is the situation after clicking the

post
buttonSome code
application.html.erb
contains those lines just before the</head>
:The
comment
model hasbelongs_to :commentable, polymorphic: true, touch: true
where commentable is thetask
where I've commented in this case.The
task
model hasbroadcasts_refreshes
I think the problem is that trix is not being re-initialized after the form submission.
The text was updated successfully, but these errors were encountered: