@tiptap/vue-2 3.22.0 → 3.22.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tiptap/vue-2",
3
3
  "description": "Vue components for tiptap",
4
- "version": "3.22.0",
4
+ "version": "3.22.2",
5
5
  "homepage": "https://tiptap.dev",
6
6
  "keywords": [
7
7
  "tiptap",
@@ -43,17 +43,17 @@
43
43
  },
44
44
  "devDependencies": {
45
45
  "vue": "^2.7.16",
46
- "@tiptap/core": "^3.22.0",
47
- "@tiptap/pm": "^3.22.0"
46
+ "@tiptap/core": "^3.22.2",
47
+ "@tiptap/pm": "^3.22.2"
48
48
  },
49
49
  "optionalDependencies": {
50
- "@tiptap/extension-bubble-menu": "^3.22.0",
51
- "@tiptap/extension-floating-menu": "^3.22.0"
50
+ "@tiptap/extension-bubble-menu": "^3.22.2",
51
+ "@tiptap/extension-floating-menu": "^3.22.2"
52
52
  },
53
53
  "peerDependencies": {
54
54
  "vue": "^2.6.0",
55
- "@tiptap/core": "^3.22.0",
56
- "@tiptap/pm": "^3.22.0"
55
+ "@tiptap/core": "^3.22.2",
56
+ "@tiptap/pm": "^3.22.2"
57
57
  },
58
58
  "repository": {
59
59
  "type": "git",
@@ -1,5 +1,5 @@
1
1
  import type { DecorationWithType, NodeViewProps, NodeViewRenderer, NodeViewRendererOptions } from '@tiptap/core'
2
- import { NodeView } from '@tiptap/core'
2
+ import { cancelPositionCheck, NodeView, schedulePositionCheck } from '@tiptap/core'
3
3
  import type { Node as ProseMirrorNode } from '@tiptap/pm/model'
4
4
  import type { Decoration, DecorationSource, NodeView as ProseMirrorNodeView } from '@tiptap/pm/view'
5
5
  import type { VueConstructor } from 'vue'
@@ -37,6 +37,18 @@ export interface VueNodeViewRendererOptions extends NodeViewRendererOptions {
37
37
  class VueNodeView extends NodeView<Vue | VueConstructor, Editor, VueNodeViewRendererOptions> {
38
38
  renderer!: VueRenderer
39
39
 
40
+ /**
41
+ * The last known position of this node view, used to detect position-only
42
+ * changes that don't produce a new node object reference.
43
+ */
44
+ private currentPos: number | undefined
45
+
46
+ /**
47
+ * Callback registered with the per-editor position-update registry.
48
+ * Stored so it can be unregistered in destroy().
49
+ */
50
+ private positionCheckCallback: (() => void) | null = null
51
+
40
52
  decorationClasses!: {
41
53
  value: string
42
54
  }
@@ -77,6 +89,27 @@ class VueNodeView extends NodeView<Vue | VueConstructor, Editor, VueNodeViewRend
77
89
 
78
90
  this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this)
79
91
  this.editor.on('selectionUpdate', this.handleSelectionUpdate)
92
+ this.currentPos = this.getPos()
93
+
94
+ this.positionCheckCallback = () => {
95
+ // Guard against the callback firing before the renderer is fully initialized.
96
+ if (!this.renderer) {
97
+ return
98
+ }
99
+
100
+ const newPos = this.getPos()
101
+
102
+ if (typeof newPos !== 'number' || newPos === this.currentPos) {
103
+ return
104
+ }
105
+
106
+ this.currentPos = newPos
107
+
108
+ // Pass a fresh getPos reference so Vue's reactivity detects a prop change.
109
+ this.renderer.updateProps({ getPos: () => this.getPos() })
110
+ }
111
+
112
+ schedulePositionCheck(this.editor, this.positionCheckCallback)
80
113
 
81
114
  this.renderer = new VueRenderer(Component, {
82
115
  parent: this.editor.contentComponent,
@@ -153,6 +186,7 @@ class VueNodeView extends NodeView<Vue | VueConstructor, Editor, VueNodeViewRend
153
186
  this.node = node
154
187
  this.decorations = decorations
155
188
  this.innerDecorations = innerDecorations
189
+ this.currentPos = this.getPos()
156
190
 
157
191
  return this.options.update({
158
192
  oldNode,
@@ -169,13 +203,25 @@ class VueNodeView extends NodeView<Vue | VueConstructor, Editor, VueNodeViewRend
169
203
  return false
170
204
  }
171
205
 
206
+ const newPos = this.getPos()
207
+
172
208
  if (node === this.node && this.decorations === decorations && this.innerDecorations === innerDecorations) {
209
+ if (newPos === this.currentPos) {
210
+ return true
211
+ }
212
+
213
+ // Position changed without a content/decoration change — trigger re-render
214
+ // so the component receives an up-to-date value from getPos().
215
+ // Pass a fresh getPos reference so Vue's reactivity detects a prop change.
216
+ this.currentPos = newPos
217
+ rerenderComponent({ node, decorations, innerDecorations, getPos: () => this.getPos() })
173
218
  return true
174
219
  }
175
220
 
176
221
  this.node = node
177
222
  this.decorations = decorations
178
223
  this.innerDecorations = innerDecorations
224
+ this.currentPos = newPos
179
225
 
180
226
  rerenderComponent({ node, decorations, innerDecorations })
181
227
 
@@ -216,6 +262,11 @@ class VueNodeView extends NodeView<Vue | VueConstructor, Editor, VueNodeViewRend
216
262
  destroy() {
217
263
  this.renderer.destroy()
218
264
  this.editor.off('selectionUpdate', this.handleSelectionUpdate)
265
+
266
+ if (this.positionCheckCallback) {
267
+ cancelPositionCheck(this.editor, this.positionCheckCallback)
268
+ this.positionCheckCallback = null
269
+ }
219
270
  }
220
271
  }
221
272