Fix global attributes not syncing on resizable image updates#7568
Fix global attributes not syncing on resizable image updates#7568
Conversation
|
✅ Deploy Preview for tiptap-embed ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
This PR fixes a gap in the resizable image NodeView where global/rendered attributes (e.g. data-* from extensions like UniqueID) weren’t being kept in sync on node updates, by recomputing rendered attributes and applying them to the underlying <img>.
Changes:
- Use
getRenderedAttributes()duringResizableNodeView.onUpdateto include global attributes when syncing the<img>element. - Implement attribute diffing to add/update attributes and remove attributes that are no longer rendered.
- Add a Vitest suite validating initial render, updates, preservation, and removals of attributes on resizable images.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/extension-image/src/image.ts | Updates resizable image NodeView onUpdate to sync rendered/global attributes onto the <img> element. |
| packages/extension-image/tests/image.spec.ts | Adds unit tests covering resizable image attribute rendering and update/removal behavior. |
@tiptap/extension-character-count
@tiptap/extension-dropcursor
@tiptap/extension-focus
@tiptap/extension-history
@tiptap/extension-gapcursor
@tiptap/extension-list-item
@tiptap/extension-list-keymap
@tiptap/extension-table-cell
@tiptap/extension-table-header
@tiptap/extension-task-item
@tiptap/extension-table-row
@tiptap/extension-task-list
@tiptap/extension-placeholder
@tiptap/core
@tiptap/extension-audio
@tiptap/extension-blockquote
@tiptap/extension-bold
@tiptap/extension-bubble-menu
@tiptap/extension-bullet-list
@tiptap/extension-code
@tiptap/extension-code-block
@tiptap/extension-collaboration
@tiptap/extension-code-block-lowlight
@tiptap/extension-collaboration-caret
@tiptap/extension-color
@tiptap/extension-details
@tiptap/extension-document
@tiptap/extension-drag-handle-react
@tiptap/extension-drag-handle
@tiptap/extension-drag-handle-vue-2
@tiptap/extension-drag-handle-vue-3
@tiptap/extension-emoji
@tiptap/extension-file-handler
@tiptap/extension-floating-menu
@tiptap/extension-font-family
@tiptap/extension-heading
@tiptap/extension-highlight
@tiptap/extension-hard-break
@tiptap/extension-horizontal-rule
@tiptap/extension-image
@tiptap/extension-invisible-characters
@tiptap/extension-italic
@tiptap/extension-link
@tiptap/extension-list
@tiptap/extension-mention
@tiptap/extension-mathematics
@tiptap/extension-node-range
@tiptap/extension-ordered-list
@tiptap/extension-paragraph
@tiptap/extension-strike
@tiptap/extension-subscript
@tiptap/extension-superscript
@tiptap/extension-text
@tiptap/extension-table
@tiptap/extension-table-of-contents
@tiptap/extension-text-align
@tiptap/extension-text-style
@tiptap/extension-twitch
@tiptap/extension-typography
@tiptap/extension-unique-id
@tiptap/extension-underline
@tiptap/extensions
@tiptap/extension-youtube
@tiptap/html
@tiptap/markdown
@tiptap/pm
@tiptap/react
@tiptap/starter-kit
@tiptap/static-renderer
@tiptap/vue-2
@tiptap/suggestion
@tiptap/vue-3
commit: |
When the image extension has resize enabled, it uses a custom NodeView. The HTMLAttributes (including data-id from UniqueID extension) were only applied once during node view creation. On subsequent node updates, the onUpdate callback did not re-render attributes, causing extensions like UniqueID to fail to add their attributes to resizable images. Now the onUpdate callback re-computes rendered HTML attributes from the updated node and applies them to the img element. Fixes #7542 https://claude.ai/code/session_01T9FxnSEVbWimV5xdC9ftaw
- Replace `any` type on onUpdate with proper type derived from ResizableNodeViewOptions and getRenderedAttributes - Track previous HTML attributes to detect and remove attributes that are no longer rendered (e.g., when a global attribute is set to null) - Add unit tests covering global attribute rendering, updates, preservation across unrelated changes, src updates, and attribute removal on resizable images https://claude.ai/code/session_01T9FxnSEVbWimV5xdC9ftaw
88c8409 to
ce907db
Compare
Changes Overview
Fixed an issue where global attributes (added via extensions like custom ID attributes) were not being properly synced to the resizable image element when node attributes changed. The image extension now correctly renders and updates all global attributes on the
<img>element within the resize container.Implementation Approach
Modified the
onUpdatecallback in the resizable node view to:getRenderedAttributes()to compute all rendered attributes (including global attributes from extensions) for the updated nodewidth/height(managed by resize logic) andsrc(requires direct property assignment)This ensures that any attributes added by extensions are properly maintained when the node is updated, while preserving the existing resize functionality.
Testing Done
Added comprehensive test suite (
packages/extension-image/__tests__/image.spec.ts) with 5 test cases covering:srcattribute on the resizable imageAll tests pass and verify that global attributes are correctly synced to the DOM element.
Verification Steps
npm test -- packages/extension-image<img>elementupdateAttributes()and verify global attributes persist and update correctlyAdditional Notes
The fix uses the existing
getRenderedAttributes()utility from@tiptap/coreto ensure consistency with how attributes are rendered elsewhere in the library. The implementation is careful to preserve the existing resize container behavior while adding proper attribute synchronization.Checklist
Related Issues
Fixes #7542