@rico.trevisan
thanks again for your work!
just something that I am not sure whether it is a bug or not. when I upload an image and then resize it to make it smaller, when I refresh the page the new smaller size is not saved but the old size is still in place. not sure whether this is something related to how tiptap works or the plugin itself. thanks
Thanks.
I’ll take a look!
v4.6.1
Bug Fix — Image resize not persisting
Fixed a bug where resizing an image would not persist after page refresh. The resized image would revert to its original size when the page was reloaded.
Root cause: The tiptap-extension-resizable extension was directly mutating the ProseMirror node’s attrs.width property instead of dispatching a proper transaction. ProseMirror uses immutable data structures, so direct mutations are not recorded in the document state and editor.getHTML() would not include the resized width.
Fix: The extension now uses editor.chain().updateAttributes('image', { width }) on mouseup to properly persist the width change via a ProseMirror transaction.
@rico.trevisan a small bug with collaboration that I can reproduce this way: when the editor is loaded and you start the editing by selecting a text (rather than just puttin the cursor somewhere and starrt writing) the name of the collaborator shows as “User: 2342345” to other collaborators rather than the value you set in the “user_name” field.
EDIT: this happens occasionally even in other cases
thanks and appreciate the work with this plugin
@rico.trevisan any chance you could check this in the future? thanks in advance
I’ll take a look this weekend. Thanks for the report.
Hey @rico.trevisan — first off, thanks for an excellent plugin, we’re using it heavily in production.
I think I’ve tracked down a reproducible bug where characters get silently dropped while typing when auto-binding is enabled (collab off) and delay set to 0. Wanted to share the diagnosis in case it’s useful.
Symptom: while typing in a focused editor, a chunk of recently-typed characters occasionally disappears. It’s racey and intermittent, but easy to trigger by typing quickly for a couple of seconds.
Root cause: a feedback loop between onUpdate and the autobind branch of update(). Walking through it:
-
User types →
onUpdatefires →instance.data.updateContent(contentHTML)writes to the bound field and setsisDebouncingDone = false. -
Debounce completes,
isDebouncingDone = true, Bubble re-runsupdate()with the newproperties.autobinding. -
But by the time
update()runs, the user has already typed more keystrokes, soproperties.autobindingis stale relative toeditor.getHTML(). -
The guard
properties.autobinding !== editor.getHTML()is thereforetrue, and this branch runs:
editor.commands.setContent(properties.autobinding, false);
editor.commands.setTextSelection({ from: newFrom, to: newTo });
…which clobbers the in-flight keystrokes with the older saved HTML. Confirmed via a view.updateState trace: one transaction goes from 137 → 107 chars, stack traces straight to setContent from the plugin’s update function.
Suggested fix: ignore echoes of our own writes, and don’t yank content while the editor is focused. Roughly:
// in onUpdate, remember what we just published
instance.data._lastPublishedHTML = contentHTML;
// in update(), tighten the autobind branch
if (
instance.data.editor_is_ready &&
properties.bubble.auto_binding() &&
!properties.collab_active &&
instance.data.isDebouncingDone &&
properties.autobinding !== editor.getHTML() &&
properties.autobinding !== instance.data._lastPublishedHTML && // ignore self-echo
!editor.isFocused // don't overwrite live typing
) {
editor.commands.setContent(properties.autobinding, false);
...
}
Happy to share a fuller repro or test a patched build if helpful. Thanks again for the great work!
@rico.trevisan Another one:
Closely related: when switching between pages quickly (single-page-app navigation, each page rendering a Tiptap editor bound to a different record), the content of the previous page sometimes overwrites the new page’s content. The new editor briefly mounts with the correct initialContent, then a delayed update() from the previous page’s autobind round-trip lands and calls setContent(staleHTML) on the wrong record. The result is page B showing page A’s text — and worse, if autobind then fires, page B’s record gets silently corrupted with page A’s content.
Previously I worked around this with a “Reset Tiptap” action that I’d call on page change, which forced a clean teardown. That action no longer appears to exist in the current version, so the workaround is gone. Could it be reinstated, or alternatively could update() short-circuit when the element is being torn down / when initialContent’s underlying record id has changed since the debounce started?