@milkdown/vue 5.5.0 → 6.0.0-next.0
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/lib/{src/Editor.d.ts → Editor.d.ts} +5 -2
- package/lib/Editor.d.ts.map +1 -0
- package/lib/{src/VueNode.d.ts → VueNode.d.ts} +6 -1
- package/lib/VueNode.d.ts.map +1 -0
- package/lib/{src/VueNodeView.d.ts → VueNodeView.d.ts} +11 -4
- package/lib/VueNodeView.d.ts.map +1 -0
- package/lib/index.d.ts +3 -1
- package/lib/index.d.ts.map +1 -0
- package/lib/index.es.js +45 -19
- package/lib/index.es.js.map +1 -1
- package/lib/{src/utils.d.ts → utils.d.ts} +0 -0
- package/lib/utils.d.ts.map +1 -0
- package/package.json +32 -8
- package/src/Editor.tsx +10 -6
- package/src/VueNode.tsx +5 -5
- package/src/VueNodeView.tsx +29 -5
- package/lib/src/Editor.d.ts.map +0 -1
- package/lib/src/VueNode.d.ts.map +0 -1
- package/lib/src/VueNodeView.d.ts.map +0 -1
- package/lib/src/index.d.ts +0 -3
- package/lib/src/index.d.ts.map +0 -1
- package/lib/src/utils.d.ts.map +0 -1
|
@@ -2,7 +2,8 @@ import { Ctx, Editor } from '@milkdown/core';
|
|
|
2
2
|
import { ViewFactory } from '@milkdown/prose';
|
|
3
3
|
import { ComponentInternalInstance, DefineComponent, Ref } from 'vue';
|
|
4
4
|
import { AnyVueComponent } from './utils';
|
|
5
|
-
|
|
5
|
+
import { RenderOptions } from './VueNodeView';
|
|
6
|
+
declare type GetEditor = (container: HTMLDivElement, renderVue: (Component: AnyVueComponent, options?: RenderOptions) => (ctx: Ctx) => ViewFactory) => Editor;
|
|
6
7
|
export declare const EditorComponent: DefineComponent<{
|
|
7
8
|
editor: GetEditor;
|
|
8
9
|
editorRef?: Ref<EditorRef> | undefined;
|
|
@@ -22,6 +23,8 @@ export declare const VueEditor: DefineComponent<{
|
|
|
22
23
|
editor: GetEditor;
|
|
23
24
|
editorRef?: Ref<EditorRef> | undefined;
|
|
24
25
|
}>, {}>;
|
|
25
|
-
export declare const useEditor: (getEditor: GetEditor) => (container: HTMLDivElement, renderVue: (Component: AnyVueComponent
|
|
26
|
+
export declare const useEditor: (getEditor: GetEditor) => (container: HTMLDivElement, renderVue: (Component: AnyVueComponent, options?: Partial<{
|
|
27
|
+
as: string;
|
|
28
|
+
} & Pick<import("prosemirror-view").NodeView<any>, "update" | "selectNode" | "deselectNode" | "ignoreMutation" | "destroy">> | undefined) => (ctx: Ctx) => ViewFactory) => Editor;
|
|
26
29
|
export {};
|
|
27
30
|
//# sourceMappingURL=Editor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Editor.d.ts","sourceRoot":"","sources":["../src/Editor.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,EAA0B,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EACH,yBAAyB,EACzB,eAAe,EAWf,GAAG,EAGN,MAAM,KAAK,CAAC;AAEb,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAiB,aAAa,EAAE,MAAM,eAAe,CAAC;AAK7D,aAAK,SAAS,GAAG,CACb,SAAS,EAAE,cAAc,EACzB,SAAS,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,aAAa,KAAK,CAAC,GAAG,EAAE,GAAG,KAAK,WAAW,KAC5F,MAAM,CAAC;AAiCZ,eAAO,MAAM,eAAe;YAA6B,SAAS;;;YAAT,SAAS;;OAahE,CAAC;AAGH,oBAAY,SAAS,GAAG;IAAE,GAAG,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,cAAc,GAAG,IAAI,CAAA;CAAE,CAAC;AAO5F,eAAO,MAAM,eAAe,wCAE3B,CAAC;AAGF,eAAO,MAAM,SAAS;YAA6B,SAAS;;;YAAT,SAAS;;OAmC1D,CAAC;AAGH,eAAO,MAAM,SAAS,cAAe,SAAS,wDApGnB,eAAe;;mJAAoC,GAAG,KAAK,WAAW,WAsGhG,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="prosemirror-model" />
|
|
1
2
|
import { Ctx } from '@milkdown/core';
|
|
2
3
|
import { Decoration, EditorView, Mark, Node } from '@milkdown/prose';
|
|
3
4
|
import { InjectionKey } from 'vue';
|
|
@@ -9,7 +10,11 @@ export declare type NodeContext = {
|
|
|
9
10
|
decorations: Decoration[];
|
|
10
11
|
};
|
|
11
12
|
export declare const nodeMetadata: InjectionKey<NodeContext>;
|
|
12
|
-
export declare const VueNodeContainer: import("vue").DefineComponent<NodeContext
|
|
13
|
+
export declare const VueNodeContainer: import("vue").DefineComponent<NodeContext & {
|
|
14
|
+
as: string;
|
|
15
|
+
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<NodeContext & {
|
|
16
|
+
as: string;
|
|
17
|
+
}>, {}>;
|
|
13
18
|
export declare const Content: import("vue").DefineComponent<{
|
|
14
19
|
isInline?: boolean | undefined;
|
|
15
20
|
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VueNode.d.ts","sourceRoot":"","sources":["../src/VueNode.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAsB,YAAY,EAAW,MAAM,KAAK,CAAC;AAEhE,oBAAY,WAAW,GAAG;IACtB,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IACjC,WAAW,EAAE,UAAU,EAAE,CAAC;CAC7B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,YAAY,CAAC,WAAW,CAAY,CAAC;AAEhE,eAAO,MAAM,gBAAgB;QAAuC,MAAM;;QAAN,MAAM;OAYxE,CAAC;AAGH,eAAO,MAAM,OAAO;;;;OAKlB,CAAC"}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
+
/// <reference types="prosemirror-model" />
|
|
1
2
|
import { Ctx } from '@milkdown/core';
|
|
2
|
-
import type { Decoration, EditorView, NodeView, ViewFactory } from '@milkdown/prose';
|
|
3
|
+
import type { Decoration, DecorationSet, EditorView, NodeView, ViewFactory } from '@milkdown/prose';
|
|
3
4
|
import { Mark, Node } from '@milkdown/prose';
|
|
4
5
|
import { DefineComponent } from 'vue';
|
|
5
|
-
export declare
|
|
6
|
+
export declare type RenderOptions = Partial<{
|
|
7
|
+
as: string;
|
|
8
|
+
} & Pick<NodeView, 'ignoreMutation' | 'deselectNode' | 'selectNode' | 'destroy' | 'update'>>;
|
|
9
|
+
export declare const createVueView: (addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) => (component: DefineComponent, options?: RenderOptions) => (ctx: Ctx) => ViewFactory;
|
|
6
10
|
export declare class VueNodeView implements NodeView {
|
|
7
11
|
private ctx;
|
|
8
12
|
private component;
|
|
9
13
|
private addPortal;
|
|
10
14
|
private removePortalByKey;
|
|
15
|
+
private options;
|
|
11
16
|
private node;
|
|
12
17
|
private view;
|
|
13
18
|
private getPos;
|
|
@@ -15,7 +20,7 @@ export declare class VueNodeView implements NodeView {
|
|
|
15
20
|
teleportDOM: HTMLElement;
|
|
16
21
|
key: string;
|
|
17
22
|
get isInlineOrMark(): boolean;
|
|
18
|
-
constructor(ctx: Ctx, component: DefineComponent, addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void, node: Node | Mark, view: EditorView, getPos: boolean | (() => number), decorations: Decoration[]);
|
|
23
|
+
constructor(ctx: Ctx, component: DefineComponent, addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void, options: RenderOptions, node: Node | Mark, view: EditorView, getPos: boolean | (() => number), decorations: Decoration[]);
|
|
19
24
|
get dom(): Element;
|
|
20
25
|
get contentDOM(): Element | null;
|
|
21
26
|
renderPortal(): void;
|
|
@@ -24,6 +29,8 @@ export declare class VueNodeView implements NodeView {
|
|
|
24
29
|
type: 'selection';
|
|
25
30
|
target: Element;
|
|
26
31
|
}): boolean;
|
|
27
|
-
update(node: Node
|
|
32
|
+
update(node: Node, decorations: Decoration[], innerDecorations: DecorationSet): boolean;
|
|
33
|
+
selectNode: (() => void) | null | undefined;
|
|
34
|
+
deselectNode: (() => void) | null | undefined;
|
|
28
35
|
}
|
|
29
36
|
//# sourceMappingURL=VueNodeView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VueNodeView.d.ts","sourceRoot":"","sources":["../src/VueNodeView.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACpG,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,eAAe,EAAyC,MAAM,KAAK,CAAC;AAO7E,oBAAY,aAAa,GAAG,OAAO,CAC/B;IACI,EAAE,EAAE,MAAM,CAAC;CACd,GAAG,IAAI,CAAC,QAAQ,EAAE,gBAAgB,GAAG,cAAc,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC,CAC9F,CAAC;AAEF,eAAO,MAAM,aAAa,uBACD,eAAe,OAAO,MAAM,KAAK,IAAI,2BAA2B,MAAM,KAAK,IAAI,iBACxF,eAAe,YAAW,aAAa,WAAe,GAAG,KAAK,WAGiC,CAAC;AAEhH,qBAAa,WAAY,YAAW,QAAQ;IASpC,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IAhBvB,WAAW,EAAE,WAAW,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IAEZ,IAAI,cAAc,YAEjB;gBAGW,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,eAAe,EAC1B,SAAS,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,EACzD,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,EACxC,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,IAAI,GAAG,IAAI,EACjB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,EAChC,WAAW,EAAE,UAAU,EAAE;IAQrC,IAAI,GAAG,YAEN;IAED,IAAI,UAAU,mBAMb;IAED,YAAY;IAiCZ,OAAO;IAKP,cAAc,CAAC,QAAQ,EAAE,cAAc,GAAG;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE;IA6BhF,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,gBAAgB,EAAE,aAAa;IAoB7E,UAAU,kCAA4B;IAEtC,YAAY,kCAA8B;CAC7C"}
|
package/lib/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|
package/lib/index.es.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => {
|
|
4
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
|
+
return value;
|
|
6
|
+
};
|
|
7
|
+
var _a, _b;
|
|
8
|
+
import { defineComponent, provide, h, createVNode, Teleport, markRaw, shallowReactive, getCurrentInstance, onBeforeMount, onUnmounted, isVNode, ref, inject, onMounted } from "vue";
|
|
2
9
|
import { editorViewCtx, rootCtx } from "@milkdown/core";
|
|
3
10
|
import { Mark, Node } from "@milkdown/prose";
|
|
4
11
|
import { customAlphabet } from "nanoid";
|
|
@@ -10,7 +17,8 @@ const VueNodeContainer = defineComponent({
|
|
|
10
17
|
view,
|
|
11
18
|
getPos,
|
|
12
19
|
decorations,
|
|
13
|
-
ctx
|
|
20
|
+
ctx,
|
|
21
|
+
as
|
|
14
22
|
}, context) => {
|
|
15
23
|
provide(nodeMetadata, {
|
|
16
24
|
ctx,
|
|
@@ -20,14 +28,14 @@ const VueNodeContainer = defineComponent({
|
|
|
20
28
|
decorations
|
|
21
29
|
});
|
|
22
30
|
return () => {
|
|
23
|
-
var
|
|
24
|
-
return
|
|
31
|
+
var _a2, _b2;
|
|
32
|
+
return h(as, {
|
|
25
33
|
"data-view-container": true
|
|
26
|
-
},
|
|
34
|
+
}, (_b2 = (_a2 = context.slots)["default"]) == null ? void 0 : _b2.call(_a2));
|
|
27
35
|
};
|
|
28
36
|
}
|
|
29
37
|
});
|
|
30
|
-
VueNodeContainer["props"] = ["ctx", "editor", "node", "view", "getPos", "decorations"];
|
|
38
|
+
VueNodeContainer["props"] = ["ctx", "editor", "node", "view", "getPos", "decorations", "as"];
|
|
31
39
|
const Content = defineComponent({
|
|
32
40
|
name: "milkdown-content",
|
|
33
41
|
setup: ({
|
|
@@ -40,26 +48,30 @@ const Content = defineComponent({
|
|
|
40
48
|
}, null);
|
|
41
49
|
}
|
|
42
50
|
});
|
|
43
|
-
Content["props"] = ["
|
|
51
|
+
Content["props"] = ["isInline"];
|
|
44
52
|
const nanoid = customAlphabet("abcedfghicklmn", 10);
|
|
45
|
-
const createVueView = (addPortal, removePortalByKey) => (component) => (ctx) => (node, view, getPos, decorations) => new VueNodeView(ctx, component, addPortal, removePortalByKey, node, view, getPos, decorations);
|
|
53
|
+
const createVueView = (addPortal, removePortalByKey) => (component, options = {}) => (ctx) => (node, view, getPos, decorations) => new VueNodeView(ctx, component, addPortal, removePortalByKey, options, node, view, getPos, decorations);
|
|
46
54
|
class VueNodeView {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
constructor(ctx, component, addPortal, removePortalByKey, node, view, getPos, decorations) {
|
|
55
|
+
constructor(ctx, component, addPortal, removePortalByKey, options, node, view, getPos, decorations) {
|
|
56
|
+
__publicField(this, "selectNode", (_a = this.options) == null ? void 0 : _a.selectNode);
|
|
57
|
+
__publicField(this, "deselectNode", (_b = this.options) == null ? void 0 : _b.deselectNode);
|
|
51
58
|
this.ctx = ctx;
|
|
52
59
|
this.component = component;
|
|
53
60
|
this.addPortal = addPortal;
|
|
54
61
|
this.removePortalByKey = removePortalByKey;
|
|
62
|
+
this.options = options;
|
|
55
63
|
this.node = node;
|
|
56
64
|
this.view = view;
|
|
57
65
|
this.getPos = getPos;
|
|
58
66
|
this.decorations = decorations;
|
|
59
67
|
this.key = nanoid();
|
|
60
|
-
|
|
68
|
+
const elementName = options.as ? options.as : this.isInlineOrMark ? "span" : "div";
|
|
69
|
+
this.teleportDOM = document.createElement(elementName);
|
|
61
70
|
this.renderPortal();
|
|
62
71
|
}
|
|
72
|
+
get isInlineOrMark() {
|
|
73
|
+
return this.node instanceof Mark || this.node.isInline;
|
|
74
|
+
}
|
|
63
75
|
get dom() {
|
|
64
76
|
return this.teleportDOM.firstElementChild || this.teleportDOM;
|
|
65
77
|
}
|
|
@@ -73,6 +85,7 @@ class VueNodeView {
|
|
|
73
85
|
if (!this.teleportDOM)
|
|
74
86
|
return;
|
|
75
87
|
const CustomComponent = this.component;
|
|
88
|
+
const elementName = this.options.as ? this.options.as : this.isInlineOrMark ? "span" : "div";
|
|
76
89
|
const Portal = defineComponent({
|
|
77
90
|
name: "milkdown-portal",
|
|
78
91
|
setup: () => {
|
|
@@ -81,6 +94,7 @@ class VueNodeView {
|
|
|
81
94
|
"to": this.teleportDOM
|
|
82
95
|
}, {
|
|
83
96
|
default: () => [createVNode(VueNodeContainer, {
|
|
97
|
+
"as": elementName,
|
|
84
98
|
"ctx": this.ctx,
|
|
85
99
|
"node": this.node,
|
|
86
100
|
"view": this.view,
|
|
@@ -103,9 +117,14 @@ class VueNodeView {
|
|
|
103
117
|
}
|
|
104
118
|
}
|
|
105
119
|
destroy() {
|
|
120
|
+
var _a2, _b2;
|
|
121
|
+
(_b2 = (_a2 = this.options).destroy) == null ? void 0 : _b2.call(_a2);
|
|
106
122
|
this.removePortalByKey(this.key);
|
|
107
123
|
}
|
|
108
124
|
ignoreMutation(mutation) {
|
|
125
|
+
if (this.options.ignoreMutation) {
|
|
126
|
+
return this.options.ignoreMutation(mutation);
|
|
127
|
+
}
|
|
109
128
|
if (!this.dom || !this.contentDOM) {
|
|
110
129
|
return true;
|
|
111
130
|
}
|
|
@@ -125,7 +144,14 @@ class VueNodeView {
|
|
|
125
144
|
}
|
|
126
145
|
return true;
|
|
127
146
|
}
|
|
128
|
-
update(node, decorations) {
|
|
147
|
+
update(node, decorations, innerDecorations) {
|
|
148
|
+
var _a2, _b2;
|
|
149
|
+
if (this.options.update) {
|
|
150
|
+
const result = (_b2 = (_a2 = this.options).update) == null ? void 0 : _b2.call(_a2, node, decorations, innerDecorations);
|
|
151
|
+
if (result != null) {
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
129
155
|
if (this.node.type !== node.type) {
|
|
130
156
|
return false;
|
|
131
157
|
}
|
|
@@ -156,9 +182,9 @@ const useGetEditor = (getEditor) => {
|
|
|
156
182
|
}).catch((e) => console.error(e));
|
|
157
183
|
});
|
|
158
184
|
onUnmounted(() => {
|
|
159
|
-
var
|
|
160
|
-
const view = (
|
|
161
|
-
const root = (
|
|
185
|
+
var _a2, _b2, _c;
|
|
186
|
+
const view = (_a2 = editorRef.editor) == null ? void 0 : _a2.action((ctx) => ctx.get(editorViewCtx));
|
|
187
|
+
const root = (_b2 = editorRef.editor) == null ? void 0 : _b2.action((ctx) => ctx.get(rootCtx));
|
|
162
188
|
(_c = root == null ? void 0 : root.firstChild) == null ? void 0 : _c.remove();
|
|
163
189
|
view == null ? void 0 : view.destroy();
|
|
164
190
|
});
|
|
@@ -180,10 +206,10 @@ const EditorComponent = defineComponent({
|
|
|
180
206
|
};
|
|
181
207
|
}
|
|
182
208
|
return () => {
|
|
183
|
-
var
|
|
209
|
+
var _a2;
|
|
184
210
|
return createVNode("div", {
|
|
185
211
|
"ref": refs.divRef
|
|
186
|
-
}, [(
|
|
212
|
+
}, [(_a2 = slots["default"]) == null ? void 0 : _a2.call(slots)]);
|
|
187
213
|
};
|
|
188
214
|
}
|
|
189
215
|
});
|
package/lib/index.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es.js","sources":["../src/VueNode.tsx","../src/VueNodeView.tsx","../src/Editor.tsx"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx } from '@milkdown/core';\nimport { Decoration, EditorView, Mark, Node } from '@milkdown/prose';\nimport { defineComponent, h, InjectionKey, provide } from 'vue';\n\nexport type NodeContext = {\n ctx: Ctx;\n node: Node | Mark;\n view: EditorView;\n getPos: boolean | (() => number);\n decorations: Decoration[];\n};\n\nexport const nodeMetadata: InjectionKey<NodeContext> = Symbol();\n\nexport const VueNodeContainer = defineComponent<NodeContext>({\n name: 'milkdown-node-container',\n setup: ({ node, view, getPos, decorations, ctx }, context) => {\n provide(nodeMetadata, {\n ctx,\n node,\n view,\n getPos,\n decorations,\n });\n return () => <div data-view-container>{context.slots['default']?.()}</div>;\n },\n});\nVueNodeContainer['props'] = ['ctx', 'editor', 'node', 'view', 'getPos', 'decorations'];\n\nexport const Content = defineComponent<{ isInline?: boolean }>({\n name: 'milkdown-content',\n setup: ({ isInline }) => {\n return () => (isInline ? <span data-view-content /> : <div data-view-content />);\n },\n});\nContent['props'] = ['isMark'];\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx } from '@milkdown/core';\nimport type { Decoration, EditorView, NodeView, ViewFactory } from '@milkdown/prose';\nimport { Mark, Node } from '@milkdown/prose';\nimport { customAlphabet } from 'nanoid';\nimport { DefineComponent, defineComponent, h, markRaw, Teleport } from 'vue';\n\nimport { getRootInstance } from '.';\nimport { Content, VueNodeContainer } from './VueNode';\n\nconst nanoid = customAlphabet('abcedfghicklmn', 10);\n\nexport const createVueView =\n (addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) =>\n (component: DefineComponent): ((ctx: Ctx) => ViewFactory) =>\n (ctx) =>\n (node, view, getPos, decorations) =>\n new VueNodeView(ctx, component, addPortal, removePortalByKey, node, view, getPos, decorations);\n\nexport class VueNodeView implements NodeView {\n teleportDOM: HTMLElement;\n key: string;\n\n get isInlineOrMark() {\n return this.node instanceof Mark || this.node.isInline;\n }\n\n constructor(\n private ctx: Ctx,\n private component: DefineComponent,\n private addPortal: (portal: DefineComponent, key: string) => void,\n private removePortalByKey: (key: string) => void,\n private node: Node | Mark,\n private view: EditorView,\n private getPos: boolean | (() => number),\n private decorations: Decoration[],\n ) {\n this.key = nanoid();\n this.teleportDOM = document.createElement(this.isInlineOrMark ? 'span' : 'div');\n this.renderPortal();\n }\n\n get dom() {\n return this.teleportDOM.firstElementChild || this.teleportDOM;\n }\n\n get contentDOM() {\n if (this.node instanceof Node && this.node.isLeaf) {\n return null;\n }\n\n return this.teleportDOM.querySelector('[data-view-content]') || this.dom;\n }\n\n renderPortal() {\n if (!this.teleportDOM) return;\n\n const CustomComponent = this.component;\n const Portal = defineComponent({\n name: 'milkdown-portal',\n setup: () => {\n return () => (\n <Teleport key={this.key} to={this.teleportDOM}>\n <VueNodeContainer\n ctx={this.ctx}\n node={this.node}\n view={this.view}\n getPos={this.getPos}\n decorations={this.decorations}\n >\n <CustomComponent>\n <Content isInline={this.isInlineOrMark} />\n </CustomComponent>\n </VueNodeContainer>\n </Teleport>\n );\n },\n });\n this.addPortal(markRaw(Portal) as DefineComponent, this.key);\n const instance = getRootInstance();\n if (instance) {\n instance.update();\n }\n }\n\n destroy() {\n this.removePortalByKey(this.key);\n }\n\n ignoreMutation(mutation: MutationRecord | { type: 'selection'; target: Element }) {\n if (!this.dom || !this.contentDOM) {\n return true;\n }\n\n if (this.node instanceof Node) {\n if (this.node.isLeaf || this.node.isAtom) {\n return true;\n }\n }\n\n if (mutation.type === 'selection') {\n return false;\n }\n\n if (this.contentDOM === this.dom) {\n return false;\n }\n\n if (this.contentDOM.contains(mutation.target)) {\n return false;\n }\n\n return true;\n }\n\n update(node: Node | Mark, decorations: Decoration[]) {\n if (this.node.type !== node.type) {\n return false;\n }\n\n if (node === this.node && this.decorations === decorations) {\n return true;\n }\n\n this.node = node;\n this.decorations = decorations;\n return true;\n }\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx, Editor, editorViewCtx, rootCtx } from '@milkdown/core';\nimport { ViewFactory } from '@milkdown/prose';\nimport {\n ComponentInternalInstance,\n DefineComponent,\n defineComponent,\n getCurrentInstance,\n h,\n inject,\n InjectionKey,\n markRaw,\n onBeforeMount,\n onMounted,\n onUnmounted,\n provide,\n Ref,\n ref,\n shallowReactive,\n} from 'vue';\n\nimport { AnyVueComponent } from './utils';\nimport { createVueView } from './VueNodeView';\n\nconst rendererKey: InjectionKey<(component: DefineComponent) => (ctx: Ctx) => ViewFactory> = Symbol();\n\ntype GetEditor = (\n container: HTMLDivElement,\n renderVue: (Component: AnyVueComponent) => (ctx: Ctx) => ViewFactory,\n) => Editor;\n\nconst useGetEditor = (getEditor: GetEditor) => {\n const divRef = ref<HTMLDivElement | null>(null);\n const renderVue = inject<(Component: DefineComponent) => (ctx: Ctx) => ViewFactory>(rendererKey, () => {\n throw new Error();\n });\n const editorRef = markRaw<{ editor?: Editor }>({});\n onMounted(() => {\n if (!divRef.value) return;\n\n getEditor(divRef.value, renderVue)\n .create()\n .then((editor) => {\n editorRef.editor = editor;\n return;\n })\n .catch((e) => console.error(e));\n });\n onUnmounted(() => {\n const view = editorRef.editor?.action((ctx) => ctx.get(editorViewCtx));\n const root = editorRef.editor?.action((ctx) => ctx.get(rootCtx)) as HTMLElement;\n\n root?.firstChild?.remove();\n view?.destroy();\n });\n\n return { divRef, editorRef };\n};\n\nexport const EditorComponent = defineComponent<{ editor: GetEditor; editorRef?: Ref<EditorRef> }>({\n name: 'milkdown-dom-root',\n setup: (props, { slots }) => {\n const refs = useGetEditor(props.editor);\n if (props.editorRef) {\n props.editorRef.value = {\n get: () => refs.editorRef.editor,\n dom: () => refs.divRef.value,\n };\n }\n\n return () => <div ref={refs.divRef}>{slots['default']?.()}</div>;\n },\n});\nEditorComponent['props'] = ['editor', 'editorRef'];\n\nexport type EditorRef = { get: () => Editor | undefined; dom: () => HTMLDivElement | null };\n\nconst rootInstance: {\n instance: null | ComponentInternalInstance;\n} = {\n instance: null,\n};\nexport const getRootInstance = () => {\n return rootInstance.instance;\n};\n\ntype PortalPair = [key: string, component: DefineComponent];\nexport const VueEditor = defineComponent<{ editor: GetEditor; editorRef?: Ref<EditorRef> }>({\n name: 'milkdown-vue-root',\n setup: (props) => {\n const portals = shallowReactive<PortalPair[]>([]);\n\n const instance = getCurrentInstance();\n\n onBeforeMount(() => {\n rootInstance.instance = (instance as ComponentInternalInstance & { ctx: { _: ComponentInternalInstance } })\n .ctx._ as ComponentInternalInstance;\n });\n\n onUnmounted(() => {\n rootInstance.instance = null;\n });\n\n const addPortal = markRaw((component: DefineComponent, key: string) => {\n portals.push([key, component]);\n });\n const removePortalByKey = markRaw((key: string) => {\n const index = portals.findIndex((p) => p[0] === key);\n portals.splice(index, 1);\n });\n const renderVue = createVueView(addPortal, removePortalByKey);\n provide(rendererKey, renderVue);\n\n return () => {\n const portalElements = portals.map(([id, P]) => <P key={id} />);\n return (\n <EditorComponent editorRef={props.editorRef} editor={props.editor}>\n {portalElements}\n </EditorComponent>\n );\n };\n },\n});\nVueEditor['props'] = ['editor', 'editorRef'];\n\nexport const useEditor = (getEditor: GetEditor) => {\n return (...args: Parameters<GetEditor>) => getEditor(...args);\n};\n"],"names":["nodeMetadata","Symbol","VueNodeContainer","defineComponent","name","setup","node","view","getPos","decorations","ctx","context","provide","slots","Content","isInline","nanoid","customAlphabet","createVueView","addPortal","removePortalByKey","component","VueNodeView","isInlineOrMark","Mark","constructor","key","teleportDOM","document","createElement","renderPortal","dom","firstElementChild","contentDOM","Node","isLeaf","querySelector","CustomComponent","Portal","markRaw","instance","getRootInstance","update","destroy","ignoreMutation","mutation","isAtom","type","contains","target","rendererKey","useGetEditor","getEditor","divRef","ref","renderVue","inject","Error","editorRef","onMounted","value","create","then","editor","catch","e","console","error","onUnmounted","action","get","editorViewCtx","root","rootCtx","firstChild","remove","EditorComponent","props","refs","rootInstance","VueEditor","portals","shallowReactive","getCurrentInstance","onBeforeMount","_","push","index","findIndex","p","splice","portalElements","map","id","P","useEditor","args"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../src/VueNode.tsx","../src/VueNodeView.tsx","../src/Editor.tsx"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx } from '@milkdown/core';\nimport { Decoration, EditorView, Mark, Node } from '@milkdown/prose';\nimport { defineComponent, h, InjectionKey, provide } from 'vue';\n\nexport type NodeContext = {\n ctx: Ctx;\n node: Node | Mark;\n view: EditorView;\n getPos: boolean | (() => number);\n decorations: Decoration[];\n};\n\nexport const nodeMetadata: InjectionKey<NodeContext> = Symbol();\n\nexport const VueNodeContainer = defineComponent<NodeContext & { as: string }>({\n name: 'milkdown-node-container',\n setup: ({ node, view, getPos, decorations, ctx, as }, context) => {\n provide(nodeMetadata, {\n ctx,\n node,\n view,\n getPos,\n decorations,\n });\n return () => h(as, { 'data-view-container': true }, context.slots['default']?.());\n },\n});\nVueNodeContainer['props'] = ['ctx', 'editor', 'node', 'view', 'getPos', 'decorations', 'as'];\n\nexport const Content = defineComponent<{ isInline?: boolean }>({\n name: 'milkdown-content',\n setup: ({ isInline }) => {\n return () => (isInline ? <span data-view-content /> : <div data-view-content />);\n },\n});\nContent['props'] = ['isInline'];\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx } from '@milkdown/core';\nimport type { Decoration, DecorationSet, EditorView, NodeView, ViewFactory } from '@milkdown/prose';\nimport { Mark, Node } from '@milkdown/prose';\nimport { customAlphabet } from 'nanoid';\nimport { DefineComponent, defineComponent, h, markRaw, Teleport } from 'vue';\n\nimport { getRootInstance } from '.';\nimport { Content, VueNodeContainer } from './VueNode';\n\nconst nanoid = customAlphabet('abcedfghicklmn', 10);\n\nexport type RenderOptions = Partial<\n {\n as: string;\n } & Pick<NodeView, 'ignoreMutation' | 'deselectNode' | 'selectNode' | 'destroy' | 'update'>\n>;\n\nexport const createVueView =\n (addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) =>\n (component: DefineComponent, options: RenderOptions = {}): ((ctx: Ctx) => ViewFactory) =>\n (ctx) =>\n (node, view, getPos, decorations) =>\n new VueNodeView(ctx, component, addPortal, removePortalByKey, options, node, view, getPos, decorations);\n\nexport class VueNodeView implements NodeView {\n teleportDOM: HTMLElement;\n key: string;\n\n get isInlineOrMark() {\n return this.node instanceof Mark || this.node.isInline;\n }\n\n constructor(\n private ctx: Ctx,\n private component: DefineComponent,\n private addPortal: (portal: DefineComponent, key: string) => void,\n private removePortalByKey: (key: string) => void,\n private options: RenderOptions,\n private node: Node | Mark,\n private view: EditorView,\n private getPos: boolean | (() => number),\n private decorations: Decoration[],\n ) {\n this.key = nanoid();\n const elementName = options.as ? options.as : this.isInlineOrMark ? 'span' : 'div';\n this.teleportDOM = document.createElement(elementName);\n this.renderPortal();\n }\n\n get dom() {\n return this.teleportDOM.firstElementChild || this.teleportDOM;\n }\n\n get contentDOM() {\n if (this.node instanceof Node && this.node.isLeaf) {\n return null;\n }\n\n return this.teleportDOM.querySelector('[data-view-content]') || this.dom;\n }\n\n renderPortal() {\n if (!this.teleportDOM) return;\n\n const CustomComponent = this.component;\n const elementName = this.options.as ? this.options.as : this.isInlineOrMark ? 'span' : 'div';\n const Portal = defineComponent({\n name: 'milkdown-portal',\n setup: () => {\n return () => (\n <Teleport key={this.key} to={this.teleportDOM}>\n <VueNodeContainer\n as={elementName}\n ctx={this.ctx}\n node={this.node}\n view={this.view}\n getPos={this.getPos}\n decorations={this.decorations}\n >\n <CustomComponent>\n <Content isInline={this.isInlineOrMark} />\n </CustomComponent>\n </VueNodeContainer>\n </Teleport>\n );\n },\n });\n this.addPortal(markRaw(Portal) as DefineComponent, this.key);\n const instance = getRootInstance();\n if (instance) {\n instance.update();\n }\n }\n\n destroy() {\n this.options.destroy?.();\n this.removePortalByKey(this.key);\n }\n\n ignoreMutation(mutation: MutationRecord | { type: 'selection'; target: Element }) {\n if (this.options.ignoreMutation) {\n return this.options.ignoreMutation(mutation);\n }\n if (!this.dom || !this.contentDOM) {\n return true;\n }\n\n if (this.node instanceof Node) {\n if (this.node.isLeaf || this.node.isAtom) {\n return true;\n }\n }\n\n if (mutation.type === 'selection') {\n return false;\n }\n\n if (this.contentDOM === this.dom) {\n return false;\n }\n\n if (this.contentDOM.contains(mutation.target)) {\n return false;\n }\n\n return true;\n }\n\n update(node: Node, decorations: Decoration[], innerDecorations: DecorationSet) {\n if (this.options.update) {\n const result = this.options.update?.(node, decorations, innerDecorations);\n if (result != null) {\n return result;\n }\n }\n if (this.node.type !== node.type) {\n return false;\n }\n\n if (node === this.node && this.decorations === decorations) {\n return true;\n }\n\n this.node = node;\n this.decorations = decorations;\n return true;\n }\n\n selectNode = this.options?.selectNode;\n\n deselectNode = this.options?.deselectNode;\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx, Editor, editorViewCtx, rootCtx } from '@milkdown/core';\nimport { ViewFactory } from '@milkdown/prose';\nimport {\n ComponentInternalInstance,\n DefineComponent,\n defineComponent,\n getCurrentInstance,\n h,\n inject,\n InjectionKey,\n markRaw,\n onBeforeMount,\n onMounted,\n onUnmounted,\n provide,\n Ref,\n ref,\n shallowReactive,\n} from 'vue';\n\nimport { AnyVueComponent } from './utils';\nimport { createVueView, RenderOptions } from './VueNodeView';\n\nconst rendererKey: InjectionKey<(component: DefineComponent, options?: RenderOptions) => (ctx: Ctx) => ViewFactory> =\n Symbol();\n\ntype GetEditor = (\n container: HTMLDivElement,\n renderVue: (Component: AnyVueComponent, options?: RenderOptions) => (ctx: Ctx) => ViewFactory,\n) => Editor;\n\nconst useGetEditor = (getEditor: GetEditor) => {\n const divRef = ref<HTMLDivElement | null>(null);\n const renderVue = inject<(Component: DefineComponent, options?: RenderOptions) => (ctx: Ctx) => ViewFactory>(\n rendererKey,\n () => {\n throw new Error();\n },\n );\n const editorRef = markRaw<{ editor?: Editor }>({});\n onMounted(() => {\n if (!divRef.value) return;\n\n getEditor(divRef.value, renderVue)\n .create()\n .then((editor) => {\n editorRef.editor = editor;\n return;\n })\n .catch((e) => console.error(e));\n });\n onUnmounted(() => {\n const view = editorRef.editor?.action((ctx) => ctx.get(editorViewCtx));\n const root = editorRef.editor?.action((ctx) => ctx.get(rootCtx)) as HTMLElement;\n\n root?.firstChild?.remove();\n view?.destroy();\n });\n\n return { divRef, editorRef };\n};\n\nexport const EditorComponent = defineComponent<{ editor: GetEditor; editorRef?: Ref<EditorRef> }>({\n name: 'milkdown-dom-root',\n setup: (props, { slots }) => {\n const refs = useGetEditor(props.editor);\n if (props.editorRef) {\n props.editorRef.value = {\n get: () => refs.editorRef.editor,\n dom: () => refs.divRef.value,\n };\n }\n\n return () => <div ref={refs.divRef}>{slots['default']?.()}</div>;\n },\n});\nEditorComponent['props'] = ['editor', 'editorRef'];\n\nexport type EditorRef = { get: () => Editor | undefined; dom: () => HTMLDivElement | null };\n\nconst rootInstance: {\n instance: null | ComponentInternalInstance;\n} = {\n instance: null,\n};\nexport const getRootInstance = () => {\n return rootInstance.instance;\n};\n\ntype PortalPair = [key: string, component: DefineComponent];\nexport const VueEditor = defineComponent<{ editor: GetEditor; editorRef?: Ref<EditorRef> }>({\n name: 'milkdown-vue-root',\n setup: (props) => {\n const portals = shallowReactive<PortalPair[]>([]);\n\n const instance = getCurrentInstance();\n\n onBeforeMount(() => {\n rootInstance.instance = (instance as ComponentInternalInstance & { ctx: { _: ComponentInternalInstance } })\n .ctx._ as ComponentInternalInstance;\n });\n\n onUnmounted(() => {\n rootInstance.instance = null;\n });\n\n const addPortal = markRaw((component: DefineComponent, key: string) => {\n portals.push([key, component]);\n });\n const removePortalByKey = markRaw((key: string) => {\n const index = portals.findIndex((p) => p[0] === key);\n portals.splice(index, 1);\n });\n const renderVue = createVueView(addPortal, removePortalByKey);\n provide(rendererKey, renderVue);\n\n return () => {\n const portalElements = portals.map(([id, P]) => <P key={id} />);\n return (\n <EditorComponent editorRef={props.editorRef} editor={props.editor}>\n {portalElements}\n </EditorComponent>\n );\n };\n },\n});\nVueEditor['props'] = ['editor', 'editorRef'];\n\nexport const useEditor = (getEditor: GetEditor) => {\n return (...args: Parameters<GetEditor>) => getEditor(...args);\n};\n"],"names":["nodeMetadata","Symbol","VueNodeContainer","defineComponent","name","setup","node","view","getPos","decorations","ctx","as","context","provide","h","slots","Content","isInline","nanoid","customAlphabet","createVueView","addPortal","removePortalByKey","component","options","VueNodeView","constructor","selectNode","deselectNode","key","elementName","isInlineOrMark","teleportDOM","document","createElement","renderPortal","Mark","dom","firstElementChild","contentDOM","Node","isLeaf","querySelector","CustomComponent","Portal","markRaw","instance","getRootInstance","update","destroy","ignoreMutation","mutation","isAtom","type","contains","target","innerDecorations","result","rendererKey","useGetEditor","getEditor","divRef","ref","renderVue","inject","Error","editorRef","onMounted","value","create","then","editor","catch","e","console","error","onUnmounted","action","get","editorViewCtx","root","rootCtx","firstChild","remove","EditorComponent","props","refs","rootInstance","VueEditor","portals","shallowReactive","getCurrentInstance","onBeforeMount","_","push","index","findIndex","p","splice","portalElements","map","id","P","useEditor","args"],"mappings":"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"}
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,KAAK,CAAC;AAEtC,aAAK,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;AACjD,aAAK,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,WAAW,EAAE,IAAI;KACpE,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CACtG,CAAC,MAAM,CAAC,CAAC,CAAC;AACX,oBAAY,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAGnE,oBAAY,eAAe,GAAG,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milkdown/vue",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0-next.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./lib/index.es.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -16,25 +16,49 @@
|
|
|
16
16
|
"vue"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@milkdown/utils": "
|
|
19
|
+
"@milkdown/utils": "6.0.0-next.0",
|
|
20
20
|
"nanoid": "^3.1.25",
|
|
21
21
|
"tslib": "^2.3.1"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
|
-
"@milkdown/core": "^
|
|
25
|
-
"@milkdown/prose": "^
|
|
24
|
+
"@milkdown/core": "^6.0.0-next.0",
|
|
25
|
+
"@milkdown/prose": "^6.0.0-next.0",
|
|
26
26
|
"vue": "^3.0.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@milkdown/core": "
|
|
30
|
-
"@milkdown/prose": "
|
|
29
|
+
"@milkdown/core": "6.0.0-next.0",
|
|
30
|
+
"@milkdown/prose": "6.0.0-next.0",
|
|
31
31
|
"vue": "^3.0.0"
|
|
32
32
|
},
|
|
33
|
+
"nx": {
|
|
34
|
+
"targets": {
|
|
35
|
+
"build": {
|
|
36
|
+
"outputs": [
|
|
37
|
+
"packages/vue/lib"
|
|
38
|
+
],
|
|
39
|
+
"dependsOn": [
|
|
40
|
+
{
|
|
41
|
+
"target": "build",
|
|
42
|
+
"projects": "dependencies"
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
"tsc": {
|
|
47
|
+
"outputs": [],
|
|
48
|
+
"dependsOn": [
|
|
49
|
+
{
|
|
50
|
+
"target": "build",
|
|
51
|
+
"projects": "dependencies"
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
},
|
|
33
57
|
"scripts": {
|
|
34
|
-
"start": "vite build --watch",
|
|
58
|
+
"start": "concurrently -n es,dts \"vite build --watch\" \"tsc --emitDeclarationOnly --watch\"",
|
|
35
59
|
"test": "vitest",
|
|
36
60
|
"tsc": "tsc --noEmit",
|
|
37
|
-
"build": "vite build"
|
|
61
|
+
"build": "vite build && tsc --emitDeclarationOnly"
|
|
38
62
|
},
|
|
39
63
|
"readme": "# @milkdown/vue\n\nVue integration for [milkdown](https://saul-mirone.github.io/milkdown/).\n\n# Example Usage\n\n```typescript\nimport { defineComponent } from 'vue';\nimport { Editor, rootCtx } from '@milkdown/core';\nimport { VueEditor, useEditor } from '@milkdown/vue';\nimport { commonmark } from '@milkdown/preset-commonmark';\nimport { nord } from '@milkdown/theme-nord';\n\nexport const MilkdownEditor = defineComponent(() => {\n const editor = useEditor((root) =>\n Editor.make()\n .config((ctx) => {\n ctx.set(rootCtx, root);\n })\n .use(nord)\n .use(commonmark),\n );\n\n return () => <VueEditor editor={editor} />;\n});\n```\n\n# License\n\nMilkdown is open sourced software licensed under [MIT license](https://github.com/Saul-Mirone/milkdown/blob/main/LICENSE).\n"
|
|
40
64
|
}
|
package/src/Editor.tsx
CHANGED
|
@@ -20,20 +20,24 @@ import {
|
|
|
20
20
|
} from 'vue';
|
|
21
21
|
|
|
22
22
|
import { AnyVueComponent } from './utils';
|
|
23
|
-
import { createVueView } from './VueNodeView';
|
|
23
|
+
import { createVueView, RenderOptions } from './VueNodeView';
|
|
24
24
|
|
|
25
|
-
const rendererKey: InjectionKey<(component: DefineComponent) => (ctx: Ctx) => ViewFactory> =
|
|
25
|
+
const rendererKey: InjectionKey<(component: DefineComponent, options?: RenderOptions) => (ctx: Ctx) => ViewFactory> =
|
|
26
|
+
Symbol();
|
|
26
27
|
|
|
27
28
|
type GetEditor = (
|
|
28
29
|
container: HTMLDivElement,
|
|
29
|
-
renderVue: (Component: AnyVueComponent) => (ctx: Ctx) => ViewFactory,
|
|
30
|
+
renderVue: (Component: AnyVueComponent, options?: RenderOptions) => (ctx: Ctx) => ViewFactory,
|
|
30
31
|
) => Editor;
|
|
31
32
|
|
|
32
33
|
const useGetEditor = (getEditor: GetEditor) => {
|
|
33
34
|
const divRef = ref<HTMLDivElement | null>(null);
|
|
34
|
-
const renderVue = inject<(Component: DefineComponent) => (ctx: Ctx) => ViewFactory>(
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
const renderVue = inject<(Component: DefineComponent, options?: RenderOptions) => (ctx: Ctx) => ViewFactory>(
|
|
36
|
+
rendererKey,
|
|
37
|
+
() => {
|
|
38
|
+
throw new Error();
|
|
39
|
+
},
|
|
40
|
+
);
|
|
37
41
|
const editorRef = markRaw<{ editor?: Editor }>({});
|
|
38
42
|
onMounted(() => {
|
|
39
43
|
if (!divRef.value) return;
|
package/src/VueNode.tsx
CHANGED
|
@@ -13,9 +13,9 @@ export type NodeContext = {
|
|
|
13
13
|
|
|
14
14
|
export const nodeMetadata: InjectionKey<NodeContext> = Symbol();
|
|
15
15
|
|
|
16
|
-
export const VueNodeContainer = defineComponent<NodeContext>({
|
|
16
|
+
export const VueNodeContainer = defineComponent<NodeContext & { as: string }>({
|
|
17
17
|
name: 'milkdown-node-container',
|
|
18
|
-
setup: ({ node, view, getPos, decorations, ctx }, context) => {
|
|
18
|
+
setup: ({ node, view, getPos, decorations, ctx, as }, context) => {
|
|
19
19
|
provide(nodeMetadata, {
|
|
20
20
|
ctx,
|
|
21
21
|
node,
|
|
@@ -23,10 +23,10 @@ export const VueNodeContainer = defineComponent<NodeContext>({
|
|
|
23
23
|
getPos,
|
|
24
24
|
decorations,
|
|
25
25
|
});
|
|
26
|
-
return () =>
|
|
26
|
+
return () => h(as, { 'data-view-container': true }, context.slots['default']?.());
|
|
27
27
|
},
|
|
28
28
|
});
|
|
29
|
-
VueNodeContainer['props'] = ['ctx', 'editor', 'node', 'view', 'getPos', 'decorations'];
|
|
29
|
+
VueNodeContainer['props'] = ['ctx', 'editor', 'node', 'view', 'getPos', 'decorations', 'as'];
|
|
30
30
|
|
|
31
31
|
export const Content = defineComponent<{ isInline?: boolean }>({
|
|
32
32
|
name: 'milkdown-content',
|
|
@@ -34,4 +34,4 @@ export const Content = defineComponent<{ isInline?: boolean }>({
|
|
|
34
34
|
return () => (isInline ? <span data-view-content /> : <div data-view-content />);
|
|
35
35
|
},
|
|
36
36
|
});
|
|
37
|
-
Content['props'] = ['
|
|
37
|
+
Content['props'] = ['isInline'];
|
package/src/VueNodeView.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
2
|
import { Ctx } from '@milkdown/core';
|
|
3
|
-
import type { Decoration, EditorView, NodeView, ViewFactory } from '@milkdown/prose';
|
|
3
|
+
import type { Decoration, DecorationSet, EditorView, NodeView, ViewFactory } from '@milkdown/prose';
|
|
4
4
|
import { Mark, Node } from '@milkdown/prose';
|
|
5
5
|
import { customAlphabet } from 'nanoid';
|
|
6
6
|
import { DefineComponent, defineComponent, h, markRaw, Teleport } from 'vue';
|
|
@@ -10,12 +10,18 @@ import { Content, VueNodeContainer } from './VueNode';
|
|
|
10
10
|
|
|
11
11
|
const nanoid = customAlphabet('abcedfghicklmn', 10);
|
|
12
12
|
|
|
13
|
+
export type RenderOptions = Partial<
|
|
14
|
+
{
|
|
15
|
+
as: string;
|
|
16
|
+
} & Pick<NodeView, 'ignoreMutation' | 'deselectNode' | 'selectNode' | 'destroy' | 'update'>
|
|
17
|
+
>;
|
|
18
|
+
|
|
13
19
|
export const createVueView =
|
|
14
20
|
(addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) =>
|
|
15
|
-
(component: DefineComponent): ((ctx: Ctx) => ViewFactory) =>
|
|
21
|
+
(component: DefineComponent, options: RenderOptions = {}): ((ctx: Ctx) => ViewFactory) =>
|
|
16
22
|
(ctx) =>
|
|
17
23
|
(node, view, getPos, decorations) =>
|
|
18
|
-
new VueNodeView(ctx, component, addPortal, removePortalByKey, node, view, getPos, decorations);
|
|
24
|
+
new VueNodeView(ctx, component, addPortal, removePortalByKey, options, node, view, getPos, decorations);
|
|
19
25
|
|
|
20
26
|
export class VueNodeView implements NodeView {
|
|
21
27
|
teleportDOM: HTMLElement;
|
|
@@ -30,13 +36,15 @@ export class VueNodeView implements NodeView {
|
|
|
30
36
|
private component: DefineComponent,
|
|
31
37
|
private addPortal: (portal: DefineComponent, key: string) => void,
|
|
32
38
|
private removePortalByKey: (key: string) => void,
|
|
39
|
+
private options: RenderOptions,
|
|
33
40
|
private node: Node | Mark,
|
|
34
41
|
private view: EditorView,
|
|
35
42
|
private getPos: boolean | (() => number),
|
|
36
43
|
private decorations: Decoration[],
|
|
37
44
|
) {
|
|
38
45
|
this.key = nanoid();
|
|
39
|
-
|
|
46
|
+
const elementName = options.as ? options.as : this.isInlineOrMark ? 'span' : 'div';
|
|
47
|
+
this.teleportDOM = document.createElement(elementName);
|
|
40
48
|
this.renderPortal();
|
|
41
49
|
}
|
|
42
50
|
|
|
@@ -56,12 +64,14 @@ export class VueNodeView implements NodeView {
|
|
|
56
64
|
if (!this.teleportDOM) return;
|
|
57
65
|
|
|
58
66
|
const CustomComponent = this.component;
|
|
67
|
+
const elementName = this.options.as ? this.options.as : this.isInlineOrMark ? 'span' : 'div';
|
|
59
68
|
const Portal = defineComponent({
|
|
60
69
|
name: 'milkdown-portal',
|
|
61
70
|
setup: () => {
|
|
62
71
|
return () => (
|
|
63
72
|
<Teleport key={this.key} to={this.teleportDOM}>
|
|
64
73
|
<VueNodeContainer
|
|
74
|
+
as={elementName}
|
|
65
75
|
ctx={this.ctx}
|
|
66
76
|
node={this.node}
|
|
67
77
|
view={this.view}
|
|
@@ -84,10 +94,14 @@ export class VueNodeView implements NodeView {
|
|
|
84
94
|
}
|
|
85
95
|
|
|
86
96
|
destroy() {
|
|
97
|
+
this.options.destroy?.();
|
|
87
98
|
this.removePortalByKey(this.key);
|
|
88
99
|
}
|
|
89
100
|
|
|
90
101
|
ignoreMutation(mutation: MutationRecord | { type: 'selection'; target: Element }) {
|
|
102
|
+
if (this.options.ignoreMutation) {
|
|
103
|
+
return this.options.ignoreMutation(mutation);
|
|
104
|
+
}
|
|
91
105
|
if (!this.dom || !this.contentDOM) {
|
|
92
106
|
return true;
|
|
93
107
|
}
|
|
@@ -113,7 +127,13 @@ export class VueNodeView implements NodeView {
|
|
|
113
127
|
return true;
|
|
114
128
|
}
|
|
115
129
|
|
|
116
|
-
update(node: Node
|
|
130
|
+
update(node: Node, decorations: Decoration[], innerDecorations: DecorationSet) {
|
|
131
|
+
if (this.options.update) {
|
|
132
|
+
const result = this.options.update?.(node, decorations, innerDecorations);
|
|
133
|
+
if (result != null) {
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
117
137
|
if (this.node.type !== node.type) {
|
|
118
138
|
return false;
|
|
119
139
|
}
|
|
@@ -126,4 +146,8 @@ export class VueNodeView implements NodeView {
|
|
|
126
146
|
this.decorations = decorations;
|
|
127
147
|
return true;
|
|
128
148
|
}
|
|
149
|
+
|
|
150
|
+
selectNode = this.options?.selectNode;
|
|
151
|
+
|
|
152
|
+
deselectNode = this.options?.deselectNode;
|
|
129
153
|
}
|
package/lib/src/Editor.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Editor.d.ts","sourceRoot":"","sources":["Editor.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,EAA0B,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EACH,yBAAyB,EACzB,eAAe,EAWf,GAAG,EAGN,MAAM,KAAK,CAAC;AAEb,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAK1C,aAAK,SAAS,GAAG,CACb,SAAS,EAAE,cAAc,EACzB,SAAS,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,CAAC,GAAG,EAAE,GAAG,KAAK,WAAW,KACnE,MAAM,CAAC;AA8BZ,eAAO,MAAM,eAAe;YAA6B,SAAS;;;YAAT,SAAS;;OAahE,CAAC;AAGH,oBAAY,SAAS,GAAG;IAAE,GAAG,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,cAAc,GAAG,IAAI,CAAA;CAAE,CAAC;AAO5F,eAAO,MAAM,eAAe,wCAE3B,CAAC;AAGF,eAAO,MAAM,SAAS;YAA6B,SAAS;;;YAAT,SAAS;;OAmC1D,CAAC;AAGH,eAAO,MAAM,SAAS,cAAe,SAAS,wDAjGnB,eAAe,WAAW,GAAG,KAAK,WAAW,WAmGvE,CAAC"}
|
package/lib/src/VueNode.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VueNode.d.ts","sourceRoot":"","sources":["VueNode.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAsB,YAAY,EAAW,MAAM,KAAK,CAAC;AAEhE,oBAAY,WAAW,GAAG;IACtB,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IACjC,WAAW,EAAE,UAAU,EAAE,CAAC;CAC7B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,YAAY,CAAC,WAAW,CAAY,CAAC;AAEhE,eAAO,MAAM,gBAAgB,0SAY3B,CAAC;AAGH,eAAO,MAAM,OAAO;;;;OAKlB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VueNodeView.d.ts","sourceRoot":"","sources":["VueNodeView.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,eAAe,EAAyC,MAAM,KAAK,CAAC;AAO7E,eAAO,MAAM,aAAa,uBACD,eAAe,OAAO,MAAM,KAAK,IAAI,2BAA2B,MAAM,KAAK,IAAI,iBACxF,eAAe,WAAU,GAAG,KAAK,WAGqD,CAAC;AAEvG,qBAAa,WAAY,YAAW,QAAQ;IASpC,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IAfvB,WAAW,EAAE,WAAW,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IAEZ,IAAI,cAAc,YAEjB;gBAGW,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,eAAe,EAC1B,SAAS,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,EACzD,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,EACxC,IAAI,EAAE,IAAI,GAAG,IAAI,EACjB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,EAChC,WAAW,EAAE,UAAU,EAAE;IAOrC,IAAI,GAAG,YAEN;IAED,IAAI,UAAU,mBAMb;IAED,YAAY;IA+BZ,OAAO;IAIP,cAAc,CAAC,QAAQ,EAAE,cAAc,GAAG;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE;IA0BhF,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE;CAatD"}
|
package/lib/src/index.d.ts
DELETED
package/lib/src/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AACA,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|
package/lib/src/utils.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,KAAK,CAAC;AAEtC,aAAK,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;AACjD,aAAK,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,WAAW,EAAE,IAAI;KACpE,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CACtG,CAAC,MAAM,CAAC,CAAC,CAAC;AACX,oBAAY,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAGnE,oBAAY,eAAe,GAAG,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC"}
|