@tiptap/vue-2 3.30.1 → 3.30.3

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/dist/index.cjs CHANGED
@@ -1,516 +1,430 @@
1
- "use strict";
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0rolldown/runtime.js
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
7
  var __getProtoOf = Object.getPrototypeOf;
7
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
9
  var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
19
18
  };
20
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
21
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
- // If the importer is in node compatibility mode or this is not an ESM
23
- // file that has been converted to a CommonJS file using a Babel-
24
- // compatible transform (i.e. "__esModule" has not been set), then set
25
- // "default" to the CommonJS "module.exports" for node compatibility.
26
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
- mod
28
- ));
29
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
-
31
- // src/index.ts
32
- var index_exports = {};
33
- __export(index_exports, {
34
- Editor: () => Editor,
35
- EditorContent: () => EditorContent,
36
- NodeViewContent: () => NodeViewContent,
37
- NodeViewWrapper: () => NodeViewWrapper,
38
- VueNodeViewRenderer: () => VueNodeViewRenderer,
39
- VueRenderer: () => VueRenderer,
40
- VueWidgetRenderer: () => VueWidgetRenderer,
41
- nodeViewProps: () => nodeViewProps
42
- });
43
- module.exports = __toCommonJS(index_exports);
44
-
45
- // src/Editor.ts
46
- var import_core = require("@tiptap/core");
47
- var Editor = class extends import_core.Editor {
48
- constructor() {
49
- super(...arguments);
50
- this.contentComponent = null;
51
- }
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+ //#endregion
24
+ let _tiptap_core = require("@tiptap/core");
25
+ let vue_ts_types = require("vue-ts-types");
26
+ let vue = require("vue");
27
+ vue = __toESM(vue, 1);
28
+ //#region src/Editor.ts
29
+ var Editor = class extends _tiptap_core.Editor {
30
+ constructor(..._args) {
31
+ super(..._args);
32
+ this.contentComponent = null;
33
+ }
52
34
  };
53
-
54
- // src/EditorContent.ts
55
- var EditorContent = {
56
- name: "EditorContent",
57
- props: {
58
- editor: {
59
- default: null,
60
- type: Object
61
- }
62
- },
63
- watch: {
64
- editor: {
65
- immediate: true,
66
- handler(editor) {
67
- if (editor && editor.options.element) {
68
- this.$nextTick(() => {
69
- var _a;
70
- const element = this.$el;
71
- if (!element || !((_a = editor.view.dom) == null ? void 0 : _a.parentNode)) {
72
- return;
73
- }
74
- element.append(...editor.view.dom.parentNode.childNodes);
75
- editor.contentComponent = this;
76
- editor.setOptions({
77
- element
78
- });
79
- editor.createNodeViews();
80
- });
81
- }
82
- }
83
- }
84
- },
85
- render(createElement) {
86
- return createElement("div");
87
- },
88
- beforeDestroy() {
89
- var _a;
90
- const { editor } = this;
91
- if (!editor) {
92
- return;
93
- }
94
- if (!editor.isDestroyed) {
95
- editor.view.setProps({
96
- nodeViews: {}
97
- });
98
- }
99
- editor.contentComponent = null;
100
- if (!((_a = editor.view.dom) == null ? void 0 : _a.parentNode)) {
101
- return;
102
- }
103
- const newElement = document.createElement("div");
104
- newElement.append(...editor.view.dom.parentNode.childNodes);
105
- editor.setOptions({
106
- element: newElement
107
- });
108
- }
35
+ //#endregion
36
+ //#region src/EditorContent.ts
37
+ const EditorContent = {
38
+ name: "EditorContent",
39
+ props: { editor: {
40
+ default: null,
41
+ type: Object
42
+ } },
43
+ watch: { editor: {
44
+ immediate: true,
45
+ handler(editor) {
46
+ if (editor && editor.options.element) this.$nextTick(() => {
47
+ var _editor$view$dom;
48
+ const element = this.$el;
49
+ if (!element || !((_editor$view$dom = editor.view.dom) === null || _editor$view$dom === void 0 ? void 0 : _editor$view$dom.parentNode)) return;
50
+ element.append(...editor.view.dom.parentNode.childNodes);
51
+ editor.contentComponent = this;
52
+ editor.setOptions({ element });
53
+ editor.createNodeViews();
54
+ });
55
+ }
56
+ } },
57
+ render(createElement) {
58
+ return createElement("div");
59
+ },
60
+ beforeDestroy() {
61
+ var _editor$view$dom2;
62
+ const { editor } = this;
63
+ if (!editor) return;
64
+ if (!editor.isDestroyed) editor.view.setProps({ nodeViews: {} });
65
+ editor.contentComponent = null;
66
+ if (!((_editor$view$dom2 = editor.view.dom) === null || _editor$view$dom2 === void 0 ? void 0 : _editor$view$dom2.parentNode)) return;
67
+ const newElement = document.createElement("div");
68
+ newElement.append(...editor.view.dom.parentNode.childNodes);
69
+ editor.setOptions({ element: newElement });
70
+ }
109
71
  };
110
-
111
- // src/NodeViewContent.ts
112
- var NodeViewContent = {
113
- props: {
114
- as: {
115
- type: String,
116
- default: "div"
117
- }
118
- },
119
- inject: {
120
- nodeViewContentRef: { default: void 0 }
121
- },
122
- mounted() {
123
- if (this.nodeViewContentRef && this.$el) {
124
- this.nodeViewContentRef(this.$el);
125
- }
126
- },
127
- beforeDestroy() {
128
- if (this.nodeViewContentRef) {
129
- this.nodeViewContentRef(null);
130
- }
131
- },
132
- render(createElement) {
133
- return createElement(this.as, {
134
- style: {
135
- whiteSpace: "pre-wrap"
136
- },
137
- attrs: {
138
- "data-node-view-content": ""
139
- }
140
- });
141
- }
72
+ //#endregion
73
+ //#region src/NodeViewContent.ts
74
+ const NodeViewContent = {
75
+ props: { as: {
76
+ type: String,
77
+ default: "div"
78
+ } },
79
+ inject: { nodeViewContentRef: { default: void 0 } },
80
+ mounted() {
81
+ if (this.nodeViewContentRef && this.$el) this.nodeViewContentRef(this.$el);
82
+ },
83
+ beforeDestroy() {
84
+ if (this.nodeViewContentRef) this.nodeViewContentRef(null);
85
+ },
86
+ render(createElement) {
87
+ return createElement(this.as, {
88
+ style: { whiteSpace: "pre-wrap" },
89
+ attrs: { "data-node-view-content": "" }
90
+ });
91
+ }
142
92
  };
143
-
144
- // src/NodeViewWrapper.ts
145
- var NodeViewWrapper = {
146
- props: {
147
- as: {
148
- type: String,
149
- default: "div"
150
- }
151
- },
152
- inject: ["onDragStart", "decorationClasses"],
153
- render(createElement) {
154
- return createElement(
155
- this.as,
156
- {
157
- class: this.decorationClasses.value,
158
- style: {
159
- whiteSpace: "normal"
160
- },
161
- attrs: {
162
- "data-node-view-wrapper": ""
163
- },
164
- on: {
165
- dragstart: this.onDragStart
166
- }
167
- },
168
- this.$slots.default
169
- );
170
- }
93
+ //#endregion
94
+ //#region src/NodeViewWrapper.ts
95
+ const NodeViewWrapper = {
96
+ props: { as: {
97
+ type: String,
98
+ default: "div"
99
+ } },
100
+ inject: ["onDragStart", "decorationClasses"],
101
+ render(createElement) {
102
+ return createElement(this.as, {
103
+ class: this.decorationClasses.value,
104
+ style: { whiteSpace: "normal" },
105
+ attrs: { "data-node-view-wrapper": "" },
106
+ on: { dragstart: this.onDragStart }
107
+ }, this.$slots.default);
108
+ }
171
109
  };
172
-
173
- // src/VueNodeViewRenderer.ts
174
- var import_core2 = require("@tiptap/core");
175
- var import_vue_ts_types = require("vue-ts-types");
176
-
177
- // src/Vue.ts
178
- var import_vue = __toESM(require("vue"), 1);
179
- var Vue = import_vue.default;
180
-
181
- // src/VueRenderer.ts
110
+ //#endregion
111
+ //#region src/Vue.ts
112
+ const Vue = vue.default;
113
+ //#endregion
114
+ //#region src/VueRenderer.ts
115
+ /**
116
+ * The VueRenderer class is responsible for rendering a Vue component as a ProseMirror node view.
117
+ */
182
118
  var VueRenderer = class {
183
- constructor(component, props) {
184
- const Component = typeof component === "function" ? component : Vue.extend(component);
185
- this.ref = new Component(props).$mount();
186
- }
187
- get element() {
188
- return this.ref.$el;
189
- }
190
- updateProps(props = {}) {
191
- var _a, _b, _c;
192
- if (!this.ref.$props) {
193
- return;
194
- }
195
- const currentVueConstructor = (_c = (_b = (_a = this.ref.$props.editor) == null ? void 0 : _a.contentComponent) == null ? void 0 : _b.$options._base) != null ? _c : Vue;
196
- const originalSilent = currentVueConstructor.config.silent;
197
- currentVueConstructor.config.silent = true;
198
- Object.entries(props).forEach(([key, value]) => {
199
- this.ref.$props[key] = value;
200
- });
201
- currentVueConstructor.config.silent = originalSilent;
202
- }
203
- destroy() {
204
- this.ref.$destroy();
205
- }
119
+ constructor(component, props) {
120
+ const Component = typeof component === "function" ? component : Vue.extend(component);
121
+ this.ref = new Component(props).$mount();
122
+ }
123
+ get element() {
124
+ return this.ref.$el;
125
+ }
126
+ updateProps(props = {}) {
127
+ var _this$ref$$props$edit, _this$ref$$props$edit2;
128
+ if (!this.ref.$props) return;
129
+ const currentVueConstructor = (_this$ref$$props$edit = (_this$ref$$props$edit2 = this.ref.$props.editor) === null || _this$ref$$props$edit2 === void 0 || (_this$ref$$props$edit2 = _this$ref$$props$edit2.contentComponent) === null || _this$ref$$props$edit2 === void 0 ? void 0 : _this$ref$$props$edit2.$options._base) !== null && _this$ref$$props$edit !== void 0 ? _this$ref$$props$edit : Vue;
130
+ const originalSilent = currentVueConstructor.config.silent;
131
+ currentVueConstructor.config.silent = true;
132
+ Object.entries(props).forEach(([key, value]) => {
133
+ this.ref.$props[key] = value;
134
+ });
135
+ currentVueConstructor.config.silent = originalSilent;
136
+ }
137
+ destroy() {
138
+ this.ref.$destroy();
139
+ }
206
140
  };
207
-
208
- // src/VueNodeViewRenderer.ts
209
- var nodeViewProps = {
210
- editor: (0, import_vue_ts_types.objectProp)().required,
211
- node: (0, import_vue_ts_types.objectProp)().required,
212
- decorations: (0, import_vue_ts_types.objectProp)().required,
213
- selected: (0, import_vue_ts_types.booleanProp)().required,
214
- extension: (0, import_vue_ts_types.objectProp)().required,
215
- getPos: (0, import_vue_ts_types.functionProp)().required,
216
- updateAttributes: (0, import_vue_ts_types.functionProp)().required,
217
- deleteNode: (0, import_vue_ts_types.functionProp)().required
141
+ //#endregion
142
+ //#region src/VueNodeViewRenderer.ts
143
+ const nodeViewProps = {
144
+ editor: (0, vue_ts_types.objectProp)().required,
145
+ node: (0, vue_ts_types.objectProp)().required,
146
+ decorations: (0, vue_ts_types.objectProp)().required,
147
+ selected: (0, vue_ts_types.booleanProp)().required,
148
+ extension: (0, vue_ts_types.objectProp)().required,
149
+ getPos: (0, vue_ts_types.functionProp)().required,
150
+ updateAttributes: (0, vue_ts_types.functionProp)().required,
151
+ deleteNode: (0, vue_ts_types.functionProp)().required
218
152
  };
219
- var VueNodeView = class extends import_core2.NodeView {
220
- constructor(component, props, options) {
221
- super(component, props, options);
222
- this.handlePositionUpdate = () => {
223
- const newPos = this.getPos();
224
- if (typeof newPos !== "number" || newPos === this.currentPos) {
225
- return;
226
- }
227
- this.currentPos = newPos;
228
- this.renderer.updateProps({ getPos: () => this.getPos() });
229
- };
230
- if (this.options.trackNodeViewPosition) {
231
- this.editor.on("update", this.handlePositionUpdate);
232
- }
233
- }
234
- /**
235
- * Called when the node view is mounted.
236
- */
237
- mount() {
238
- var _a, _b;
239
- const props = {
240
- editor: this.editor,
241
- node: this.node,
242
- decorations: this.decorations,
243
- innerDecorations: this.innerDecorations,
244
- view: this.view,
245
- selected: false,
246
- extension: this.extension,
247
- HTMLAttributes: this.HTMLAttributes,
248
- getPos: () => this.getPos(),
249
- updateAttributes: (attributes = {}) => this.updateAttributes(attributes),
250
- deleteNode: () => this.deleteNode()
251
- };
252
- const mountProps = props;
253
- const onDragStart = this.onDragStart.bind(this);
254
- this.decorationClasses = Vue.observable({
255
- value: this.getDecorationClasses()
256
- });
257
- const vue = (_b = (_a = this.editor.contentComponent) == null ? void 0 : _a.$options._base) != null ? _b : Vue;
258
- const Component = vue.extend(this.component).extend({
259
- props: Object.keys(props),
260
- provide: () => {
261
- return {
262
- onDragStart,
263
- decorationClasses: this.decorationClasses,
264
- nodeViewContentRef: (el) => {
265
- if (!this.contentDOMElement) return;
266
- if (el && el.firstChild !== this.contentDOMElement) {
267
- el.appendChild(this.contentDOMElement);
268
- }
269
- }
270
- };
271
- }
272
- });
273
- this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this);
274
- this.editor.on("selectionUpdate", this.handleSelectionUpdate);
275
- this.currentPos = this.getPos();
276
- if (!this.node.isLeaf) {
277
- if (this.options.contentDOMElementTag) {
278
- this.contentDOMElement = document.createElement(this.options.contentDOMElementTag);
279
- } else {
280
- this.contentDOMElement = document.createElement(this.node.isInline ? "span" : "div");
281
- }
282
- this.contentDOMElement.style.whiteSpace = "inherit";
283
- this.contentDOMElement.dataset.nodeViewContentVue = "";
284
- }
285
- this.renderer = new VueRenderer(Component, {
286
- parent: this.editor.contentComponent,
287
- propsData: mountProps
288
- });
289
- }
290
- /**
291
- * Return the DOM element.
292
- * This is the element that will be used to display the node view.
293
- */
294
- get dom() {
295
- if (!this.renderer.element.hasAttribute("data-node-view-wrapper")) {
296
- throw Error("Please use the NodeViewWrapper component for your node view.");
297
- }
298
- return this.renderer.element;
299
- }
300
- /**
301
- * Return the content DOM element.
302
- * This is the element that will be used to display the rich-text content of the node.
303
- */
304
- get contentDOM() {
305
- if (this.node.isLeaf) {
306
- return null;
307
- }
308
- return this.contentDOMElement;
309
- }
310
- /**
311
- * On editor selection update, check if the node is selected.
312
- * If it is, call `selectNode`, otherwise call `deselectNode`.
313
- */
314
- handleSelectionUpdate() {
315
- const pos = this.getPos();
316
- if (typeof pos !== "number") {
317
- return;
318
- }
319
- const isSelected = (0, import_core2.isNodeViewSelected)({
320
- selection: this.editor.state.selection,
321
- pos,
322
- nodeSize: this.node.nodeSize,
323
- selectedOnTextSelection: this.options.selectedOnTextSelection
324
- });
325
- if (isSelected) {
326
- if (this.renderer.ref.$props.selected) {
327
- return;
328
- }
329
- this.selectNode();
330
- } else {
331
- if (!this.renderer.ref.$props.selected) {
332
- return;
333
- }
334
- this.deselectNode();
335
- }
336
- }
337
- /**
338
- * On update, update the React component.
339
- * To prevent unnecessary updates, the `update` option can be used.
340
- */
341
- update(node, decorations, innerDecorations) {
342
- const rerenderComponent = (props) => {
343
- this.decorationClasses.value = this.getDecorationClasses();
344
- this.renderer.updateProps(props);
345
- };
346
- if (typeof this.options.update === "function") {
347
- const oldNode = this.node;
348
- const oldDecorations = this.decorations;
349
- const oldInnerDecorations = this.innerDecorations;
350
- this.node = node;
351
- this.decorations = decorations;
352
- this.innerDecorations = innerDecorations;
353
- return this.options.update({
354
- oldNode,
355
- oldDecorations,
356
- newNode: node,
357
- newDecorations: decorations,
358
- oldInnerDecorations,
359
- innerDecorations,
360
- updateProps: () => rerenderComponent({ node, decorations, innerDecorations })
361
- });
362
- }
363
- if (node.type !== this.node.type) {
364
- return false;
365
- }
366
- const nodeChanged = node !== this.node;
367
- if (!nodeChanged) {
368
- this.node = node;
369
- this.decorations = decorations;
370
- this.innerDecorations = innerDecorations;
371
- this.decorationClasses.value = this.getDecorationClasses();
372
- return true;
373
- }
374
- this.node = node;
375
- this.decorations = decorations;
376
- this.innerDecorations = innerDecorations;
377
- this.currentPos = this.getPos();
378
- const extraProps = {
379
- node,
380
- decorations,
381
- innerDecorations
382
- };
383
- if (this.options.trackNodeViewPosition) {
384
- extraProps.getPos = () => this.getPos();
385
- }
386
- rerenderComponent(extraProps);
387
- return true;
388
- }
389
- /**
390
- * Select the node.
391
- * Add the `selected` prop and the `ProseMirror-selectednode` class.
392
- */
393
- selectNode() {
394
- this.renderer.updateProps({
395
- selected: true
396
- });
397
- this.renderer.element.classList.add("ProseMirror-selectednode");
398
- }
399
- /**
400
- * Deselect the node.
401
- * Remove the `selected` prop and the `ProseMirror-selectednode` class.
402
- */
403
- deselectNode() {
404
- this.renderer.updateProps({
405
- selected: false
406
- });
407
- this.renderer.element.classList.remove("ProseMirror-selectednode");
408
- }
409
- getDecorationClasses() {
410
- return this.decorations.flatMap((item) => item.type.attrs.class).join(" ");
411
- }
412
- destroy() {
413
- this.renderer.destroy();
414
- this.editor.off("selectionUpdate", this.handleSelectionUpdate);
415
- if (this.options.trackNodeViewPosition) {
416
- this.editor.off("update", this.handlePositionUpdate);
417
- }
418
- this.contentDOMElement = null;
419
- }
153
+ var VueNodeView = class extends _tiptap_core.NodeView {
154
+ constructor(component, props, options) {
155
+ super(component, props, options);
156
+ this.handlePositionUpdate = () => {
157
+ const newPos = this.getPos();
158
+ if (typeof newPos !== "number" || newPos === this.currentPos) return;
159
+ this.currentPos = newPos;
160
+ this.renderer.updateProps({ getPos: () => this.getPos() });
161
+ };
162
+ if (this.options.trackNodeViewPosition) this.editor.on("update", this.handlePositionUpdate);
163
+ }
164
+ /**
165
+ * Called when the node view is mounted.
166
+ */
167
+ mount() {
168
+ var _this$editor$contentC, _this$editor$contentC2;
169
+ const props = {
170
+ editor: this.editor,
171
+ node: this.node,
172
+ decorations: this.decorations,
173
+ innerDecorations: this.innerDecorations,
174
+ view: this.view,
175
+ selected: false,
176
+ extension: this.extension,
177
+ HTMLAttributes: this.HTMLAttributes,
178
+ getPos: () => this.getPos(),
179
+ updateAttributes: (attributes = {}) => this.updateAttributes(attributes),
180
+ deleteNode: () => this.deleteNode()
181
+ };
182
+ const mountProps = props;
183
+ const onDragStart = this.onDragStart.bind(this);
184
+ this.decorationClasses = Vue.observable({ value: this.getDecorationClasses() });
185
+ const Component = ((_this$editor$contentC = (_this$editor$contentC2 = this.editor.contentComponent) === null || _this$editor$contentC2 === void 0 ? void 0 : _this$editor$contentC2.$options._base) !== null && _this$editor$contentC !== void 0 ? _this$editor$contentC : Vue).extend(this.component).extend({
186
+ props: Object.keys(props),
187
+ provide: () => {
188
+ return {
189
+ onDragStart,
190
+ decorationClasses: this.decorationClasses,
191
+ nodeViewContentRef: (el) => {
192
+ if (!this.contentDOMElement) return;
193
+ if (el && el.firstChild !== this.contentDOMElement) el.appendChild(this.contentDOMElement);
194
+ }
195
+ };
196
+ }
197
+ });
198
+ this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this);
199
+ this.editor.on("selectionUpdate", this.handleSelectionUpdate);
200
+ this.currentPos = this.getPos();
201
+ if (!this.node.isLeaf) {
202
+ if (this.options.contentDOMElementTag) this.contentDOMElement = document.createElement(this.options.contentDOMElementTag);
203
+ else this.contentDOMElement = document.createElement(this.node.isInline ? "span" : "div");
204
+ this.contentDOMElement.style.whiteSpace = "inherit";
205
+ this.contentDOMElement.dataset.nodeViewContentVue = "";
206
+ }
207
+ this.renderer = new VueRenderer(Component, {
208
+ parent: this.editor.contentComponent,
209
+ propsData: mountProps
210
+ });
211
+ }
212
+ /**
213
+ * Return the DOM element.
214
+ * This is the element that will be used to display the node view.
215
+ */
216
+ get dom() {
217
+ if (!this.renderer.element.hasAttribute("data-node-view-wrapper")) throw Error("Please use the NodeViewWrapper component for your node view.");
218
+ return this.renderer.element;
219
+ }
220
+ /**
221
+ * Return the content DOM element.
222
+ * This is the element that will be used to display the rich-text content of the node.
223
+ */
224
+ get contentDOM() {
225
+ if (this.node.isLeaf) return null;
226
+ return this.contentDOMElement;
227
+ }
228
+ /**
229
+ * On editor selection update, check if the node is selected.
230
+ * If it is, call `selectNode`, otherwise call `deselectNode`.
231
+ */
232
+ handleSelectionUpdate() {
233
+ const pos = this.getPos();
234
+ if (typeof pos !== "number") return;
235
+ if ((0, _tiptap_core.isNodeViewSelected)({
236
+ selection: this.editor.state.selection,
237
+ pos,
238
+ nodeSize: this.node.nodeSize,
239
+ selectedOnTextSelection: this.options.selectedOnTextSelection
240
+ })) {
241
+ if (this.renderer.ref.$props.selected) return;
242
+ this.selectNode();
243
+ } else {
244
+ if (!this.renderer.ref.$props.selected) return;
245
+ this.deselectNode();
246
+ }
247
+ }
248
+ /**
249
+ * On update, update the React component.
250
+ * To prevent unnecessary updates, the `update` option can be used.
251
+ */
252
+ update(node, decorations, innerDecorations) {
253
+ const rerenderComponent = (props) => {
254
+ this.decorationClasses.value = this.getDecorationClasses();
255
+ this.renderer.updateProps(props);
256
+ };
257
+ if (typeof this.options.update === "function") {
258
+ const oldNode = this.node;
259
+ const oldDecorations = this.decorations;
260
+ const oldInnerDecorations = this.innerDecorations;
261
+ this.node = node;
262
+ this.decorations = decorations;
263
+ this.innerDecorations = innerDecorations;
264
+ return this.options.update({
265
+ oldNode,
266
+ oldDecorations,
267
+ newNode: node,
268
+ newDecorations: decorations,
269
+ oldInnerDecorations,
270
+ innerDecorations,
271
+ updateProps: () => rerenderComponent({
272
+ node,
273
+ decorations,
274
+ innerDecorations
275
+ })
276
+ });
277
+ }
278
+ if (node.type !== this.node.type) return false;
279
+ if (!(node !== this.node)) {
280
+ this.node = node;
281
+ this.decorations = decorations;
282
+ this.innerDecorations = innerDecorations;
283
+ this.decorationClasses.value = this.getDecorationClasses();
284
+ return true;
285
+ }
286
+ this.node = node;
287
+ this.decorations = decorations;
288
+ this.innerDecorations = innerDecorations;
289
+ this.currentPos = this.getPos();
290
+ const extraProps = {
291
+ node,
292
+ decorations,
293
+ innerDecorations
294
+ };
295
+ if (this.options.trackNodeViewPosition) extraProps.getPos = () => this.getPos();
296
+ rerenderComponent(extraProps);
297
+ return true;
298
+ }
299
+ /**
300
+ * Select the node.
301
+ * Add the `selected` prop and the `ProseMirror-selectednode` class.
302
+ */
303
+ selectNode() {
304
+ this.renderer.updateProps({ selected: true });
305
+ this.renderer.element.classList.add("ProseMirror-selectednode");
306
+ }
307
+ /**
308
+ * Deselect the node.
309
+ * Remove the `selected` prop and the `ProseMirror-selectednode` class.
310
+ */
311
+ deselectNode() {
312
+ this.renderer.updateProps({ selected: false });
313
+ this.renderer.element.classList.remove("ProseMirror-selectednode");
314
+ }
315
+ getDecorationClasses() {
316
+ return this.decorations.flatMap((item) => item.type.attrs.class).join(" ");
317
+ }
318
+ destroy() {
319
+ this.renderer.destroy();
320
+ this.editor.off("selectionUpdate", this.handleSelectionUpdate);
321
+ if (this.options.trackNodeViewPosition) this.editor.off("update", this.handlePositionUpdate);
322
+ this.contentDOMElement = null;
323
+ }
420
324
  };
421
325
  function VueNodeViewRenderer(component, options) {
422
- return (props) => {
423
- if (!props.editor.contentComponent) {
424
- return {};
425
- }
426
- return new VueNodeView(component, props, options);
427
- };
326
+ return (props) => {
327
+ if (!props.editor.contentComponent) return {};
328
+ return new VueNodeView(component, props, options);
329
+ };
428
330
  }
429
-
430
- // src/VueWidgetRenderer.ts
431
- var import_core3 = require("@tiptap/core");
432
-
433
- // src/utils/createWidgetConstructor.ts
331
+ //#endregion
332
+ //#region src/utils/createWidgetConstructor.ts
333
+ /**
334
+ * Builds the Vue 2 constructor for a widget component.
335
+ *
336
+ * Extends the editor's own Vue constructor so the widget shares its context,
337
+ * then auto-declares every passed prop the component does not declare itself.
338
+ * Vue 2 fixes the prop list at construction, so undeclared keys would be
339
+ * dropped. Existing declarations keep their type, default and validator.
340
+ *
341
+ * @param base The editor's Vue constructor, or undefined to fall back to `Vue`.
342
+ * @param component The widget component.
343
+ * @param props The props the widget is mounted with.
344
+ * @returns A constructor that accepts every key in `props`.
345
+ * @example
346
+ * createWidgetConstructor(undefined, MyWidget, { editor, getPos, label: 'a' })
347
+ */
434
348
  function createWidgetConstructor(base, component, props) {
435
- const VueBase = base != null ? base : Vue;
436
- const Extended = VueBase.extend(component);
437
- const declaredProps = {
438
- ...Extended.options.props
439
- };
440
- for (const name of Object.keys(props)) {
441
- if (!Object.prototype.hasOwnProperty.call(declaredProps, name)) {
442
- declaredProps[name] = null;
443
- }
444
- }
445
- return Extended.extend({ props: declaredProps });
349
+ const Extended = (base !== null && base !== void 0 ? base : Vue).extend(component);
350
+ const declaredProps = { ...Extended.options.props };
351
+ for (const name of Object.keys(props)) if (!Object.prototype.hasOwnProperty.call(declaredProps, name)) declaredProps[name] = null;
352
+ return Extended.extend({ props: declaredProps });
446
353
  }
447
-
448
- // src/VueWidgetRenderer.ts
449
- var WIDGET_CACHE = /* @__PURE__ */ Symbol("tiptapVue2WidgetCache");
450
- var isDev = process.env.NODE_ENV !== "production";
354
+ //#endregion
355
+ //#region src/VueWidgetRenderer.ts
356
+ const WIDGET_CACHE = Symbol("tiptapVue2WidgetCache");
357
+ const isDev = process.env.NODE_ENV !== "production";
451
358
  function warnUndeclaredProps(renderer, props, key) {
452
- var _a;
453
- if (!isDev) {
454
- return;
455
- }
456
- const declared = (_a = renderer.ref.$props) != null ? _a : {};
457
- for (const name of Object.keys(props)) {
458
- if (!(name in declared)) {
459
- console.warn(
460
- `[tiptap warn]: VueWidgetRenderer prop "${name}" was not passed on first mount for widget "${key}".`,
461
- "Vue 2 cannot declare new props after mount, so this value is ignored."
462
- );
463
- }
464
- }
359
+ var _renderer$ref$$props;
360
+ if (!isDev) return;
361
+ const declared = (_renderer$ref$$props = renderer.ref.$props) !== null && _renderer$ref$$props !== void 0 ? _renderer$ref$$props : {};
362
+ for (const name of Object.keys(props)) if (!(name in declared)) console.warn(`[tiptap warn]: VueWidgetRenderer prop "${name}" was not passed on first mount for widget "${key}".`, "Vue 2 cannot declare new props after mount, so this value is ignored.");
465
363
  }
466
364
  function withPropWarnings(renderer, key) {
467
- return {
468
- renderer,
469
- updateProps: (props) => {
470
- warnUndeclaredProps(renderer, props, key);
471
- renderer.updateProps(props);
472
- },
473
- destroy: () => renderer.destroy()
474
- };
365
+ return {
366
+ renderer,
367
+ updateProps: (props) => {
368
+ warnUndeclaredProps(renderer, props, key);
369
+ renderer.updateProps(props);
370
+ },
371
+ destroy: () => renderer.destroy()
372
+ };
475
373
  }
374
+ /**
375
+ * Renders a Vue 2 component into a ProseMirror widget decoration.
376
+ * Reuses Tiptap's `VueRenderer` so the component is mounted under the editor's
377
+ * content component (inject/provide works as usual). Use a stable `key` for
378
+ * stateful widgets. The component must render a single root element.
379
+ * @example
380
+ * addDecorations() {
381
+ * return {
382
+ * create: ({ editor, state }) =>
383
+ * findMatches(state.doc).map(match =>
384
+ * VueWidgetRenderer(MyWidget, {
385
+ * editor, pos: match.pos, key: `match-${match.id}`,
386
+ * props: { label: match.label },
387
+ * }),
388
+ * ),
389
+ * }
390
+ * }
391
+ */
476
392
  function VueWidgetRenderer(component, options) {
477
- const { editor, key, props = {} } = options;
478
- return (0, import_core3.createWidgetDecoration)({
479
- // Forwards editor, pos, key and the ProseMirror widget options unchanged.
480
- ...options,
481
- props,
482
- cacheKey: WIDGET_CACHE,
483
- // `view` is not passed on purpose: Vue 2 deeply observes props and
484
- // observing a ProseMirror view corrupts its internals.
485
- context: (getPos) => ({ editor, getPos }),
486
- create: (renderProps) => {
487
- var _a, _b;
488
- const base = (_b = (_a = editor.contentComponent) == null ? void 0 : _a.$options) == null ? void 0 : _b._base;
489
- const Constructor = createWidgetConstructor(base, component, renderProps);
490
- return withPropWarnings(
491
- new VueRenderer(Constructor, {
492
- parent: editor.contentComponent,
493
- propsData: renderProps
494
- }),
495
- key
496
- );
497
- },
498
- materialize: (entry) => entry.renderer.element
499
- });
393
+ const { editor, key, props = {} } = options;
394
+ return (0, _tiptap_core.createWidgetDecoration)({
395
+ ...options,
396
+ props,
397
+ cacheKey: WIDGET_CACHE,
398
+ context: (getPos) => ({
399
+ editor,
400
+ getPos
401
+ }),
402
+ create: (renderProps) => {
403
+ var _editor$contentCompon;
404
+ return withPropWarnings(new VueRenderer(createWidgetConstructor((_editor$contentCompon = editor.contentComponent) === null || _editor$contentCompon === void 0 || (_editor$contentCompon = _editor$contentCompon.$options) === null || _editor$contentCompon === void 0 ? void 0 : _editor$contentCompon._base, component, renderProps), {
405
+ parent: editor.contentComponent,
406
+ propsData: renderProps
407
+ }), key);
408
+ },
409
+ materialize: (entry) => entry.renderer.element
410
+ });
500
411
  }
501
-
502
- // src/index.ts
503
- __reExport(index_exports, require("@tiptap/core"), module.exports);
504
- // Annotate the CommonJS export names for ESM import in node:
505
- 0 && (module.exports = {
506
- Editor,
507
- EditorContent,
508
- NodeViewContent,
509
- NodeViewWrapper,
510
- VueNodeViewRenderer,
511
- VueRenderer,
512
- VueWidgetRenderer,
513
- nodeViewProps,
514
- ...require("@tiptap/core")
412
+ //#endregion
413
+ exports.Editor = Editor;
414
+ exports.EditorContent = EditorContent;
415
+ exports.NodeViewContent = NodeViewContent;
416
+ exports.NodeViewWrapper = NodeViewWrapper;
417
+ exports.VueNodeViewRenderer = VueNodeViewRenderer;
418
+ exports.VueRenderer = VueRenderer;
419
+ exports.VueWidgetRenderer = VueWidgetRenderer;
420
+ exports.nodeViewProps = nodeViewProps;
421
+ Object.keys(_tiptap_core).forEach(function(k) {
422
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
423
+ enumerable: true,
424
+ get: function() {
425
+ return _tiptap_core[k];
426
+ }
427
+ });
515
428
  });
429
+
516
430
  //# sourceMappingURL=index.cjs.map