@milkdown/vue 5.1.2 → 5.3.1
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/Editor.d.ts +8 -6
- package/lib/Editor.d.ts.map +1 -1
- package/lib/VueNode.d.ts +6 -14
- package/lib/VueNode.d.ts.map +1 -1
- package/lib/VueNodeView.d.ts +8 -4
- package/lib/VueNodeView.d.ts.map +1 -1
- package/lib/index.es.js +232 -0
- package/lib/index.es.js.map +1 -0
- package/lib/utils.d.ts +2 -0
- package/lib/utils.d.ts.map +1 -1
- package/package.json +15 -9
- package/src/Editor.tsx +71 -36
- package/src/VueNode.tsx +22 -18
- package/src/VueNodeView.tsx +81 -40
- package/src/utils.ts +5 -0
- package/lib/Editor.js +0 -64
- package/lib/Editor.js.map +0 -1
- package/lib/Portals.d.ts +0 -8
- package/lib/Portals.d.ts.map +0 -1
- package/lib/Portals.js +0 -23
- package/lib/Portals.js.map +0 -1
- package/lib/VueNode.js +0 -23
- package/lib/VueNode.js.map +0 -1
- package/lib/VueNodeView.js +0 -54
- package/lib/VueNodeView.js.map +0 -1
- package/lib/index.js +0 -4
- package/lib/index.js.map +0 -1
- package/lib/utils.js +0 -3
- package/lib/utils.js.map +0 -1
- package/src/Portals.tsx +0 -31
package/lib/Editor.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { Editor } from '@milkdown/core';
|
|
1
|
+
import { Ctx, Editor } from '@milkdown/core';
|
|
2
2
|
import { ViewFactory } from '@milkdown/prose';
|
|
3
|
-
import { DefineComponent, Ref } from 'vue';
|
|
4
|
-
|
|
3
|
+
import { ComponentInternalInstance, DefineComponent, Ref } from 'vue';
|
|
4
|
+
import { AnyVueComponent } from './utils';
|
|
5
|
+
declare type GetEditor = (container: HTMLDivElement, renderVue: (Component: AnyVueComponent) => (ctx: Ctx) => ViewFactory) => Editor;
|
|
5
6
|
export declare const EditorComponent: DefineComponent<{
|
|
6
7
|
editor: GetEditor;
|
|
7
8
|
editorRef?: Ref<EditorRef> | undefined;
|
|
8
|
-
},
|
|
9
|
+
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
|
|
9
10
|
editor: GetEditor;
|
|
10
11
|
editorRef?: Ref<EditorRef> | undefined;
|
|
11
12
|
}>, {}>;
|
|
@@ -13,13 +14,14 @@ export declare type EditorRef = {
|
|
|
13
14
|
get: () => Editor | undefined;
|
|
14
15
|
dom: () => HTMLDivElement | null;
|
|
15
16
|
};
|
|
17
|
+
export declare const getRootInstance: () => ComponentInternalInstance | null;
|
|
16
18
|
export declare const VueEditor: DefineComponent<{
|
|
17
19
|
editor: GetEditor;
|
|
18
20
|
editorRef?: Ref<EditorRef> | undefined;
|
|
19
|
-
},
|
|
21
|
+
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
|
|
20
22
|
editor: GetEditor;
|
|
21
23
|
editorRef?: Ref<EditorRef> | undefined;
|
|
22
24
|
}>, {}>;
|
|
23
|
-
export declare const useEditor: (getEditor: GetEditor) => (container: HTMLDivElement, renderVue: (Component:
|
|
25
|
+
export declare const useEditor: (getEditor: GetEditor) => (container: HTMLDivElement, renderVue: (Component: AnyVueComponent) => (ctx: Ctx) => ViewFactory) => Editor;
|
|
24
26
|
export {};
|
|
25
27
|
//# sourceMappingURL=Editor.d.ts.map
|
package/lib/Editor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Editor.d.ts","sourceRoot":"","sources":["../src/Editor.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,
|
|
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;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/VueNode.d.ts
CHANGED
|
@@ -1,27 +1,19 @@
|
|
|
1
1
|
/// <reference types="prosemirror-model" />
|
|
2
|
+
import { Ctx } from '@milkdown/core';
|
|
2
3
|
import { Decoration, EditorView, Mark, Node } from '@milkdown/prose';
|
|
3
4
|
import { InjectionKey } from 'vue';
|
|
4
5
|
export declare type NodeContext = {
|
|
6
|
+
ctx: Ctx;
|
|
5
7
|
node: Node | Mark;
|
|
6
8
|
view: EditorView;
|
|
7
9
|
getPos: boolean | (() => number);
|
|
8
10
|
decorations: Decoration[];
|
|
9
11
|
};
|
|
10
12
|
export declare const nodeMetadata: InjectionKey<NodeContext>;
|
|
11
|
-
export declare const VueNodeContainer: import("vue").DefineComponent<{
|
|
12
|
-
node: Node | Mark;
|
|
13
|
-
view: EditorView;
|
|
14
|
-
getPos: boolean | (() => number);
|
|
15
|
-
decorations: Decoration[];
|
|
16
|
-
}, () => JSX.Element, {}, import("vue").ComputedOptions, import("vue").MethodOptions, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
|
|
17
|
-
node: Node | Mark;
|
|
18
|
-
view: EditorView;
|
|
19
|
-
getPos: boolean | (() => number);
|
|
20
|
-
decorations: Decoration[];
|
|
21
|
-
}>, {}>;
|
|
13
|
+
export declare const VueNodeContainer: import("vue").DefineComponent<NodeContext, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<NodeContext>, {}>;
|
|
22
14
|
export declare const Content: import("vue").DefineComponent<{
|
|
23
|
-
|
|
24
|
-
},
|
|
25
|
-
|
|
15
|
+
isMark?: boolean | undefined;
|
|
16
|
+
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
|
|
17
|
+
isMark?: boolean | undefined;
|
|
26
18
|
}>, {}>;
|
|
27
19
|
//# sourceMappingURL=VueNode.d.ts.map
|
package/lib/VueNode.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VueNode.d.ts","sourceRoot":"","sources":["../src/VueNode.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,
|
|
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,0SAY3B,CAAC;AAGH,eAAO,MAAM,OAAO;;;;OAKlB,CAAC"}
|
package/lib/VueNodeView.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/// <reference types="prosemirror-model" />
|
|
2
|
+
import { Ctx } from '@milkdown/core';
|
|
2
3
|
import type { Decoration, EditorView, NodeView, ViewFactory } from '@milkdown/prose';
|
|
3
4
|
import { Mark, Node } from '@milkdown/prose';
|
|
4
5
|
import { DefineComponent } from 'vue';
|
|
5
|
-
export declare const createVueView: (addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) => (component: DefineComponent) => ViewFactory;
|
|
6
|
+
export declare const createVueView: (addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) => (component: DefineComponent) => (ctx: Ctx) => ViewFactory;
|
|
6
7
|
export declare class VueNodeView implements NodeView {
|
|
8
|
+
private ctx;
|
|
7
9
|
private component;
|
|
8
10
|
private addPortal;
|
|
9
11
|
private removePortalByKey;
|
|
@@ -11,15 +13,17 @@ export declare class VueNodeView implements NodeView {
|
|
|
11
13
|
private view;
|
|
12
14
|
private getPos;
|
|
13
15
|
private decorations;
|
|
14
|
-
|
|
15
|
-
contentDOM: HTMLElement | undefined;
|
|
16
|
+
teleportDOM: HTMLElement;
|
|
16
17
|
key: string;
|
|
17
|
-
constructor(component: DefineComponent, addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void, node: Node | Mark, view: EditorView, getPos: boolean | (() => number), decorations: Decoration[]);
|
|
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[]);
|
|
19
|
+
get dom(): Element;
|
|
20
|
+
get contentDOM(): Element | null;
|
|
18
21
|
renderPortal(): void;
|
|
19
22
|
destroy(): void;
|
|
20
23
|
ignoreMutation(mutation: MutationRecord | {
|
|
21
24
|
type: 'selection';
|
|
22
25
|
target: Element;
|
|
23
26
|
}): boolean;
|
|
27
|
+
update(node: Node | Mark, decorations: Decoration[]): boolean;
|
|
24
28
|
}
|
|
25
29
|
//# sourceMappingURL=VueNodeView.d.ts.map
|
package/lib/VueNodeView.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VueNodeView.d.ts","sourceRoot":"","sources":["../src/VueNodeView.tsx"],"names":[],"mappings":";AACA,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,
|
|
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,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;IAKpC,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;IAXvB,WAAW,EAAE,WAAW,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;gBAGA,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/index.es.js
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { defineComponent, provide, createVNode, Teleport, markRaw, shallowReactive, getCurrentInstance, onBeforeMount, onUnmounted, isVNode, ref, inject, onMounted } from "vue";
|
|
2
|
+
import { editorViewCtx, rootCtx } from "@milkdown/core";
|
|
3
|
+
import { Mark, Node } from "@milkdown/prose";
|
|
4
|
+
import { customAlphabet } from "nanoid";
|
|
5
|
+
const nodeMetadata = Symbol();
|
|
6
|
+
const VueNodeContainer = defineComponent({
|
|
7
|
+
name: "milkdown-node-container",
|
|
8
|
+
setup: ({
|
|
9
|
+
node,
|
|
10
|
+
view,
|
|
11
|
+
getPos,
|
|
12
|
+
decorations,
|
|
13
|
+
ctx
|
|
14
|
+
}, context) => {
|
|
15
|
+
provide(nodeMetadata, {
|
|
16
|
+
ctx,
|
|
17
|
+
node,
|
|
18
|
+
view,
|
|
19
|
+
getPos,
|
|
20
|
+
decorations
|
|
21
|
+
});
|
|
22
|
+
return () => {
|
|
23
|
+
var _a, _b;
|
|
24
|
+
return createVNode("div", {
|
|
25
|
+
"data-view-container": true
|
|
26
|
+
}, [(_b = (_a = context.slots).default) == null ? void 0 : _b.call(_a)]);
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
VueNodeContainer.props = ["ctx", "editor", "node", "view", "getPos", "decorations"];
|
|
31
|
+
const Content = defineComponent({
|
|
32
|
+
name: "milkdown-content",
|
|
33
|
+
setup: ({
|
|
34
|
+
isMark
|
|
35
|
+
}) => {
|
|
36
|
+
return () => isMark ? createVNode("span", {
|
|
37
|
+
"data-view-content": true
|
|
38
|
+
}, null) : createVNode("div", {
|
|
39
|
+
"data-view-content": true
|
|
40
|
+
}, null);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
Content.props = ["isMark"];
|
|
44
|
+
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);
|
|
46
|
+
class VueNodeView {
|
|
47
|
+
constructor(ctx, component, addPortal, removePortalByKey, node, view, getPos, decorations) {
|
|
48
|
+
this.ctx = ctx;
|
|
49
|
+
this.component = component;
|
|
50
|
+
this.addPortal = addPortal;
|
|
51
|
+
this.removePortalByKey = removePortalByKey;
|
|
52
|
+
this.node = node;
|
|
53
|
+
this.view = view;
|
|
54
|
+
this.getPos = getPos;
|
|
55
|
+
this.decorations = decorations;
|
|
56
|
+
this.key = nanoid();
|
|
57
|
+
this.teleportDOM = document.createElement(node instanceof Mark ? "span" : "div");
|
|
58
|
+
this.renderPortal();
|
|
59
|
+
}
|
|
60
|
+
get dom() {
|
|
61
|
+
return this.teleportDOM.firstElementChild || this.teleportDOM;
|
|
62
|
+
}
|
|
63
|
+
get contentDOM() {
|
|
64
|
+
if (this.node instanceof Node && this.node.isLeaf) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
return this.teleportDOM.querySelector("[data-view-content]") || this.dom;
|
|
68
|
+
}
|
|
69
|
+
renderPortal() {
|
|
70
|
+
if (!this.teleportDOM)
|
|
71
|
+
return;
|
|
72
|
+
const CustomComponent = this.component;
|
|
73
|
+
const Portal = defineComponent({
|
|
74
|
+
name: "milkdown-portal",
|
|
75
|
+
setup: () => {
|
|
76
|
+
return () => createVNode(Teleport, {
|
|
77
|
+
"key": this.key,
|
|
78
|
+
"to": this.teleportDOM
|
|
79
|
+
}, {
|
|
80
|
+
default: () => [createVNode(VueNodeContainer, {
|
|
81
|
+
"ctx": this.ctx,
|
|
82
|
+
"node": this.node,
|
|
83
|
+
"view": this.view,
|
|
84
|
+
"getPos": this.getPos,
|
|
85
|
+
"decorations": this.decorations
|
|
86
|
+
}, {
|
|
87
|
+
default: () => [createVNode(CustomComponent, null, {
|
|
88
|
+
default: () => [createVNode(Content, {
|
|
89
|
+
"isMark": this.node instanceof Mark
|
|
90
|
+
}, null)]
|
|
91
|
+
})]
|
|
92
|
+
})]
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
this.addPortal(markRaw(Portal), this.key);
|
|
97
|
+
const instance = getRootInstance();
|
|
98
|
+
if (instance) {
|
|
99
|
+
instance.update();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
destroy() {
|
|
103
|
+
this.removePortalByKey(this.key);
|
|
104
|
+
}
|
|
105
|
+
ignoreMutation(mutation) {
|
|
106
|
+
if (!this.dom || !this.contentDOM) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
if (this.node instanceof Node) {
|
|
110
|
+
if (this.node.isLeaf || this.node.isAtom) {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (mutation.type === "selection") {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
if (this.contentDOM === this.dom) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
if (this.contentDOM.contains(mutation.target)) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
update(node, decorations) {
|
|
126
|
+
if (this.node.type !== node.type) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
if (node === this.node && this.decorations === decorations) {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
this.node = node;
|
|
133
|
+
this.decorations = decorations;
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function _isSlot(s) {
|
|
138
|
+
return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
|
|
139
|
+
}
|
|
140
|
+
const rendererKey = Symbol();
|
|
141
|
+
const useGetEditor = (getEditor) => {
|
|
142
|
+
const divRef = ref(null);
|
|
143
|
+
const renderVue = inject(rendererKey, () => {
|
|
144
|
+
throw new Error();
|
|
145
|
+
});
|
|
146
|
+
const editorRef = markRaw({});
|
|
147
|
+
onMounted(() => {
|
|
148
|
+
if (!divRef.value)
|
|
149
|
+
return;
|
|
150
|
+
getEditor(divRef.value, renderVue).create().then((editor) => {
|
|
151
|
+
editorRef.editor = editor;
|
|
152
|
+
return;
|
|
153
|
+
}).catch((e) => console.error(e));
|
|
154
|
+
});
|
|
155
|
+
onUnmounted(() => {
|
|
156
|
+
var _a, _b, _c;
|
|
157
|
+
const view = (_a = editorRef.editor) == null ? void 0 : _a.action((ctx) => ctx.get(editorViewCtx));
|
|
158
|
+
const root = (_b = editorRef.editor) == null ? void 0 : _b.action((ctx) => ctx.get(rootCtx));
|
|
159
|
+
(_c = root == null ? void 0 : root.firstChild) == null ? void 0 : _c.remove();
|
|
160
|
+
view == null ? void 0 : view.destroy();
|
|
161
|
+
});
|
|
162
|
+
return {
|
|
163
|
+
divRef,
|
|
164
|
+
editorRef
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
const EditorComponent = defineComponent({
|
|
168
|
+
name: "milkdown-dom-root",
|
|
169
|
+
setup: (props, {
|
|
170
|
+
slots
|
|
171
|
+
}) => {
|
|
172
|
+
const refs = useGetEditor(props.editor);
|
|
173
|
+
if (props.editorRef) {
|
|
174
|
+
props.editorRef.value = {
|
|
175
|
+
get: () => refs.editorRef.editor,
|
|
176
|
+
dom: () => refs.divRef.value
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
return () => {
|
|
180
|
+
var _a;
|
|
181
|
+
return createVNode("div", {
|
|
182
|
+
"ref": refs.divRef
|
|
183
|
+
}, [(_a = slots.default) == null ? void 0 : _a.call(slots)]);
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
EditorComponent.props = ["editor", "editorRef"];
|
|
188
|
+
const rootInstance = {
|
|
189
|
+
instance: null
|
|
190
|
+
};
|
|
191
|
+
const getRootInstance = () => {
|
|
192
|
+
return rootInstance.instance;
|
|
193
|
+
};
|
|
194
|
+
const VueEditor = defineComponent({
|
|
195
|
+
name: "milkdown-vue-root",
|
|
196
|
+
setup: (props) => {
|
|
197
|
+
const portals = shallowReactive([]);
|
|
198
|
+
const instance = getCurrentInstance();
|
|
199
|
+
onBeforeMount(() => {
|
|
200
|
+
rootInstance.instance = instance.ctx._;
|
|
201
|
+
});
|
|
202
|
+
onUnmounted(() => {
|
|
203
|
+
rootInstance.instance = null;
|
|
204
|
+
});
|
|
205
|
+
const addPortal = markRaw((component, key) => {
|
|
206
|
+
portals.push([key, component]);
|
|
207
|
+
});
|
|
208
|
+
const removePortalByKey = markRaw((key) => {
|
|
209
|
+
const index = portals.findIndex((p) => p[0] === key);
|
|
210
|
+
portals.splice(index, 1);
|
|
211
|
+
});
|
|
212
|
+
const renderVue = createVueView(addPortal, removePortalByKey);
|
|
213
|
+
provide(rendererKey, renderVue);
|
|
214
|
+
return () => {
|
|
215
|
+
const portalElements = portals.map(([id, P]) => createVNode(P, {
|
|
216
|
+
"key": id
|
|
217
|
+
}, null));
|
|
218
|
+
return createVNode(EditorComponent, {
|
|
219
|
+
"editorRef": props.editorRef,
|
|
220
|
+
"editor": props.editor
|
|
221
|
+
}, _isSlot(portalElements) ? portalElements : {
|
|
222
|
+
default: () => [portalElements]
|
|
223
|
+
});
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
VueEditor.props = ["editor", "editorRef"];
|
|
228
|
+
const useEditor = (getEditor) => {
|
|
229
|
+
return (...args) => getEditor(...args);
|
|
230
|
+
};
|
|
231
|
+
export { EditorComponent, VueEditor, getRootInstance, nodeMetadata, useEditor };
|
|
232
|
+
//# sourceMappingURL=index.es.js.map
|
|
@@ -0,0 +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<{ isMark?: boolean }>({\n name: 'milkdown-content',\n setup: ({ isMark }) => {\n return () => (isMark ? <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 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(node instanceof Mark ? '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 isMark={this.node instanceof Mark} />\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","default","props","Content","isMark","nanoid","customAlphabet","createVueView","addPortal","removePortalByKey","component","VueNodeView","constructor","key","teleportDOM","document","createElement","Mark","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","refs","rootInstance","VueEditor","portals","shallowReactive","getCurrentInstance","onBeforeMount","_","push","index","findIndex","p","splice","portalElements","map","id","P","useEditor","args"],"mappings":"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"}
|
package/lib/utils.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { DefineComponent } from 'vue';
|
|
1
2
|
declare type Prepend<T, U extends unknown[]> = [T, ...U];
|
|
2
3
|
declare type Keys_<T extends Record<string, unknown>, U extends PropertyKey[]> = {
|
|
3
4
|
[P in keyof T]: Record<string, unknown> extends Omit<T, P> ? [P] : Prepend<P, Keys_<Omit<T, P>, U>>;
|
|
4
5
|
}[keyof T];
|
|
5
6
|
export declare type Keys<T extends Record<string, unknown>> = Keys_<T, []>;
|
|
7
|
+
export declare type AnyVueComponent = DefineComponent<any, any, any, any, any, any, any, any, any, any, any, any>;
|
|
6
8
|
export {};
|
|
7
9
|
//# sourceMappingURL=utils.d.ts.map
|
package/lib/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,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"}
|
|
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,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milkdown/vue",
|
|
3
|
-
"version": "5.1
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"types": "lib/index.d.ts",
|
|
3
|
+
"version": "5.3.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./lib/index.es.js",
|
|
6
|
+
"types": "./lib/index.d.ts",
|
|
7
7
|
"sideEffects": false,
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"files": [
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"vue"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@milkdown/utils": "5.1
|
|
19
|
+
"@milkdown/utils": "5.3.1",
|
|
20
20
|
"nanoid": "^3.1.25",
|
|
21
21
|
"tslib": "^2.3.1"
|
|
22
22
|
},
|
|
@@ -25,13 +25,19 @@
|
|
|
25
25
|
"vue": "^3.0.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
+
"@milkdown/core": "5.3.1",
|
|
29
|
+
"@milkdown/prose": "5.3.1",
|
|
30
|
+
"@milkdown/preset-commonmark": "5.3.1",
|
|
31
|
+
"@milkdown/plugin-slash": "5.3.1",
|
|
32
|
+
"@milkdown/theme-nord": "5.3.1",
|
|
28
33
|
"vue": "^3.0.0"
|
|
29
34
|
},
|
|
30
35
|
"scripts": {
|
|
31
36
|
"start": "vite",
|
|
32
|
-
"watch": "
|
|
33
|
-
"test": "
|
|
37
|
+
"watch": "vite build --watch",
|
|
38
|
+
"test": "vitest",
|
|
34
39
|
"tsc": "tsc --noEmit",
|
|
35
|
-
"build": "tsc"
|
|
36
|
-
}
|
|
40
|
+
"build": "vite build && tsc --emitDeclarationOnly"
|
|
41
|
+
},
|
|
42
|
+
"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"
|
|
37
43
|
}
|
package/src/Editor.tsx
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { Editor, editorViewCtx } from '@milkdown/core';
|
|
2
|
+
import { Ctx, Editor, editorViewCtx, rootCtx } from '@milkdown/core';
|
|
3
3
|
import { ViewFactory } from '@milkdown/prose';
|
|
4
4
|
import {
|
|
5
|
+
ComponentInternalInstance,
|
|
5
6
|
DefineComponent,
|
|
6
7
|
defineComponent,
|
|
7
|
-
|
|
8
|
+
getCurrentInstance,
|
|
8
9
|
h,
|
|
9
10
|
inject,
|
|
10
11
|
InjectionKey,
|
|
11
12
|
markRaw,
|
|
13
|
+
onBeforeMount,
|
|
12
14
|
onMounted,
|
|
13
15
|
onUnmounted,
|
|
14
16
|
provide,
|
|
@@ -17,16 +19,19 @@ import {
|
|
|
17
19
|
shallowReactive,
|
|
18
20
|
} from 'vue';
|
|
19
21
|
|
|
20
|
-
import {
|
|
22
|
+
import { AnyVueComponent } from './utils';
|
|
21
23
|
import { createVueView } from './VueNodeView';
|
|
22
24
|
|
|
23
|
-
const rendererKey: InjectionKey<(component: DefineComponent) => ViewFactory> = Symbol();
|
|
25
|
+
const rendererKey: InjectionKey<(component: DefineComponent) => (ctx: Ctx) => ViewFactory> = Symbol();
|
|
24
26
|
|
|
25
|
-
type GetEditor = (
|
|
27
|
+
type GetEditor = (
|
|
28
|
+
container: HTMLDivElement,
|
|
29
|
+
renderVue: (Component: AnyVueComponent) => (ctx: Ctx) => ViewFactory,
|
|
30
|
+
) => Editor;
|
|
26
31
|
|
|
27
32
|
const useGetEditor = (getEditor: GetEditor) => {
|
|
28
33
|
const divRef = ref<HTMLDivElement | null>(null);
|
|
29
|
-
const renderVue = inject<(Component: DefineComponent) => ViewFactory>(rendererKey, () => {
|
|
34
|
+
const renderVue = inject<(Component: DefineComponent) => (ctx: Ctx) => ViewFactory>(rendererKey, () => {
|
|
30
35
|
throw new Error();
|
|
31
36
|
});
|
|
32
37
|
const editorRef = markRaw<{ editor?: Editor }>({});
|
|
@@ -43,48 +48,78 @@ const useGetEditor = (getEditor: GetEditor) => {
|
|
|
43
48
|
});
|
|
44
49
|
onUnmounted(() => {
|
|
45
50
|
const view = editorRef.editor?.action((ctx) => ctx.get(editorViewCtx));
|
|
46
|
-
|
|
51
|
+
const root = editorRef.editor?.action((ctx) => ctx.get(rootCtx)) as HTMLElement;
|
|
47
52
|
|
|
48
|
-
|
|
49
|
-
view
|
|
53
|
+
root?.firstChild?.remove();
|
|
54
|
+
view?.destroy();
|
|
50
55
|
});
|
|
51
56
|
|
|
52
57
|
return { divRef, editorRef };
|
|
53
58
|
};
|
|
54
59
|
|
|
55
|
-
export const EditorComponent = defineComponent
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
export const EditorComponent = defineComponent<{ editor: GetEditor; editorRef?: Ref<EditorRef> }>({
|
|
61
|
+
name: 'milkdown-dom-root',
|
|
62
|
+
setup: (props, { slots }) => {
|
|
63
|
+
const refs = useGetEditor(props.editor);
|
|
64
|
+
if (props.editorRef) {
|
|
65
|
+
props.editorRef.value = {
|
|
66
|
+
get: () => refs.editorRef.editor,
|
|
67
|
+
dom: () => refs.divRef.value,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
63
70
|
|
|
64
|
-
|
|
71
|
+
return () => <div ref={refs.divRef}>{slots.default?.()}</div>;
|
|
72
|
+
},
|
|
65
73
|
});
|
|
66
74
|
EditorComponent.props = ['editor', 'editorRef'];
|
|
67
75
|
|
|
68
76
|
export type EditorRef = { get: () => Editor | undefined; dom: () => HTMLDivElement | null };
|
|
69
77
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
78
|
+
const rootInstance: {
|
|
79
|
+
instance: null | ComponentInternalInstance;
|
|
80
|
+
} = {
|
|
81
|
+
instance: null,
|
|
82
|
+
};
|
|
83
|
+
export const getRootInstance = () => {
|
|
84
|
+
return rootInstance.instance;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
type PortalPair = [key: string, component: DefineComponent];
|
|
88
|
+
export const VueEditor = defineComponent<{ editor: GetEditor; editorRef?: Ref<EditorRef> }>({
|
|
89
|
+
name: 'milkdown-vue-root',
|
|
90
|
+
setup: (props) => {
|
|
91
|
+
const portals = shallowReactive<PortalPair[]>([]);
|
|
92
|
+
|
|
93
|
+
const instance = getCurrentInstance();
|
|
94
|
+
|
|
95
|
+
onBeforeMount(() => {
|
|
96
|
+
rootInstance.instance = (instance as ComponentInternalInstance & { ctx: { _: ComponentInternalInstance } })
|
|
97
|
+
.ctx._ as ComponentInternalInstance;
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
onUnmounted(() => {
|
|
101
|
+
rootInstance.instance = null;
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const addPortal = markRaw((component: DefineComponent, key: string) => {
|
|
105
|
+
portals.push([key, component]);
|
|
106
|
+
});
|
|
107
|
+
const removePortalByKey = markRaw((key: string) => {
|
|
108
|
+
const index = portals.findIndex((p) => p[0] === key);
|
|
109
|
+
portals.splice(index, 1);
|
|
110
|
+
});
|
|
111
|
+
const renderVue = createVueView(addPortal, removePortalByKey);
|
|
112
|
+
provide(rendererKey, renderVue);
|
|
113
|
+
|
|
114
|
+
return () => {
|
|
115
|
+
const portalElements = portals.map(([id, P]) => <P key={id} />);
|
|
116
|
+
return (
|
|
117
|
+
<EditorComponent editorRef={props.editorRef} editor={props.editor}>
|
|
118
|
+
{portalElements}
|
|
119
|
+
</EditorComponent>
|
|
120
|
+
);
|
|
121
|
+
};
|
|
122
|
+
},
|
|
88
123
|
});
|
|
89
124
|
VueEditor.props = ['editor', 'editorRef'];
|
|
90
125
|
|
package/src/VueNode.tsx
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
+
import { Ctx } from '@milkdown/core';
|
|
2
3
|
import { Decoration, EditorView, Mark, Node } from '@milkdown/prose';
|
|
3
|
-
import { defineComponent,
|
|
4
|
+
import { defineComponent, h, InjectionKey, provide } from 'vue';
|
|
4
5
|
|
|
5
6
|
export type NodeContext = {
|
|
7
|
+
ctx: Ctx;
|
|
6
8
|
node: Node | Mark;
|
|
7
9
|
view: EditorView;
|
|
8
10
|
getPos: boolean | (() => number);
|
|
@@ -11,23 +13,25 @@ export type NodeContext = {
|
|
|
11
13
|
|
|
12
14
|
export const nodeMetadata: InjectionKey<NodeContext> = Symbol();
|
|
13
15
|
|
|
14
|
-
export const VueNodeContainer = defineComponent(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
export const VueNodeContainer = defineComponent<NodeContext>({
|
|
17
|
+
name: 'milkdown-node-container',
|
|
18
|
+
setup: ({ node, view, getPos, decorations, ctx }, context) => {
|
|
19
|
+
provide(nodeMetadata, {
|
|
20
|
+
ctx,
|
|
21
|
+
node,
|
|
22
|
+
view,
|
|
23
|
+
getPos,
|
|
24
|
+
decorations,
|
|
25
|
+
});
|
|
26
|
+
return () => <div data-view-container>{context.slots.default?.()}</div>;
|
|
27
|
+
},
|
|
22
28
|
});
|
|
23
|
-
VueNodeContainer.props = ['editor', 'node', 'view', 'getPos', 'decorations'];
|
|
29
|
+
VueNodeContainer.props = ['ctx', 'editor', 'node', 'view', 'getPos', 'decorations'];
|
|
24
30
|
|
|
25
|
-
export const Content = defineComponent
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
});
|
|
31
|
-
return () => <div ref={containerRef} />;
|
|
31
|
+
export const Content = defineComponent<{ isMark?: boolean }>({
|
|
32
|
+
name: 'milkdown-content',
|
|
33
|
+
setup: ({ isMark }) => {
|
|
34
|
+
return () => (isMark ? <span data-view-content /> : <div data-view-content />);
|
|
35
|
+
},
|
|
32
36
|
});
|
|
33
|
-
Content.props = ['
|
|
37
|
+
Content.props = ['isMark'];
|
package/src/VueNodeView.tsx
CHANGED
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
+
import { Ctx } from '@milkdown/core';
|
|
2
3
|
import type { Decoration, EditorView, NodeView, ViewFactory } from '@milkdown/prose';
|
|
3
4
|
import { Mark, Node } from '@milkdown/prose';
|
|
4
5
|
import { customAlphabet } from 'nanoid';
|
|
5
|
-
import { DefineComponent, defineComponent, h, Teleport } from 'vue';
|
|
6
|
+
import { DefineComponent, defineComponent, h, markRaw, Teleport } from 'vue';
|
|
6
7
|
|
|
8
|
+
import { getRootInstance } from '.';
|
|
7
9
|
import { Content, VueNodeContainer } from './VueNode';
|
|
8
10
|
|
|
9
11
|
const nanoid = customAlphabet('abcedfghicklmn', 10);
|
|
10
12
|
|
|
11
13
|
export const createVueView =
|
|
12
14
|
(addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) =>
|
|
13
|
-
(component: DefineComponent): ViewFactory =>
|
|
15
|
+
(component: DefineComponent): ((ctx: Ctx) => ViewFactory) =>
|
|
16
|
+
(ctx) =>
|
|
14
17
|
(node, view, getPos, decorations) =>
|
|
15
|
-
new VueNodeView(component, addPortal, removePortalByKey, node, view, getPos, decorations);
|
|
18
|
+
new VueNodeView(ctx, component, addPortal, removePortalByKey, node, view, getPos, decorations);
|
|
16
19
|
|
|
17
20
|
export class VueNodeView implements NodeView {
|
|
18
|
-
|
|
19
|
-
contentDOM: HTMLElement | undefined;
|
|
21
|
+
teleportDOM: HTMLElement;
|
|
20
22
|
key: string;
|
|
21
23
|
|
|
22
24
|
constructor(
|
|
25
|
+
private ctx: Ctx,
|
|
23
26
|
private component: DefineComponent,
|
|
24
27
|
private addPortal: (portal: DefineComponent, key: string) => void,
|
|
25
28
|
private removePortalByKey: (key: string) => void,
|
|
@@ -29,56 +32,94 @@ export class VueNodeView implements NodeView {
|
|
|
29
32
|
private decorations: Decoration[],
|
|
30
33
|
) {
|
|
31
34
|
this.key = nanoid();
|
|
32
|
-
|
|
33
|
-
dom.classList.add('dom-wrapper');
|
|
34
|
-
|
|
35
|
-
const contentDOM =
|
|
36
|
-
node instanceof Node && node.isLeaf
|
|
37
|
-
? undefined
|
|
38
|
-
: document.createElement(node instanceof Mark ? 'span' : 'div');
|
|
39
|
-
if (contentDOM) {
|
|
40
|
-
contentDOM.classList.add('content-dom');
|
|
41
|
-
dom.appendChild(contentDOM);
|
|
42
|
-
}
|
|
43
|
-
this.dom = dom;
|
|
44
|
-
this.contentDOM = contentDOM;
|
|
35
|
+
this.teleportDOM = document.createElement(node instanceof Mark ? 'span' : 'div');
|
|
45
36
|
this.renderPortal();
|
|
46
37
|
}
|
|
47
38
|
|
|
39
|
+
get dom() {
|
|
40
|
+
return this.teleportDOM.firstElementChild || this.teleportDOM;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
get contentDOM() {
|
|
44
|
+
if (this.node instanceof Node && this.node.isLeaf) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return this.teleportDOM.querySelector('[data-view-content]') || this.dom;
|
|
49
|
+
}
|
|
50
|
+
|
|
48
51
|
renderPortal() {
|
|
49
|
-
if (!this.
|
|
52
|
+
if (!this.teleportDOM) return;
|
|
50
53
|
|
|
51
54
|
const CustomComponent = this.component;
|
|
52
|
-
const Portal = defineComponent(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
55
|
+
const Portal = defineComponent({
|
|
56
|
+
name: 'milkdown-portal',
|
|
57
|
+
setup: () => {
|
|
58
|
+
return () => (
|
|
59
|
+
<Teleport key={this.key} to={this.teleportDOM}>
|
|
60
|
+
<VueNodeContainer
|
|
61
|
+
ctx={this.ctx}
|
|
62
|
+
node={this.node}
|
|
63
|
+
view={this.view}
|
|
64
|
+
getPos={this.getPos}
|
|
65
|
+
decorations={this.decorations}
|
|
66
|
+
>
|
|
67
|
+
<CustomComponent>
|
|
68
|
+
<Content isMark={this.node instanceof Mark} />
|
|
69
|
+
</CustomComponent>
|
|
70
|
+
</VueNodeContainer>
|
|
71
|
+
</Teleport>
|
|
72
|
+
);
|
|
73
|
+
},
|
|
68
74
|
});
|
|
69
|
-
this.addPortal(Portal, this.key);
|
|
75
|
+
this.addPortal(markRaw(Portal) as DefineComponent, this.key);
|
|
76
|
+
const instance = getRootInstance();
|
|
77
|
+
if (instance) {
|
|
78
|
+
instance.update();
|
|
79
|
+
}
|
|
70
80
|
}
|
|
71
81
|
|
|
72
82
|
destroy() {
|
|
73
|
-
this.dom = undefined;
|
|
74
|
-
this.contentDOM = undefined;
|
|
75
83
|
this.removePortalByKey(this.key);
|
|
76
84
|
}
|
|
77
85
|
|
|
78
86
|
ignoreMutation(mutation: MutationRecord | { type: 'selection'; target: Element }) {
|
|
79
|
-
if (!this.contentDOM) {
|
|
87
|
+
if (!this.dom || !this.contentDOM) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (this.node instanceof Node) {
|
|
92
|
+
if (this.node.isLeaf || this.node.isAtom) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (mutation.type === 'selection') {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (this.contentDOM === this.dom) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (this.contentDOM.contains(mutation.target)) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
update(node: Node | Mark, decorations: Decoration[]) {
|
|
113
|
+
if (this.node.type !== node.type) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (node === this.node && this.decorations === decorations) {
|
|
80
118
|
return true;
|
|
81
119
|
}
|
|
82
|
-
|
|
120
|
+
|
|
121
|
+
this.node = node;
|
|
122
|
+
this.decorations = decorations;
|
|
123
|
+
return true;
|
|
83
124
|
}
|
|
84
125
|
}
|
package/src/utils.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
2
|
|
|
3
|
+
import { DefineComponent } from 'vue';
|
|
4
|
+
|
|
3
5
|
type Prepend<T, U extends unknown[]> = [T, ...U];
|
|
4
6
|
type Keys_<T extends Record<string, unknown>, U extends PropertyKey[]> = {
|
|
5
7
|
[P in keyof T]: Record<string, unknown> extends Omit<T, P> ? [P] : Prepend<P, Keys_<Omit<T, P>, U>>;
|
|
6
8
|
}[keyof T];
|
|
7
9
|
export type Keys<T extends Record<string, unknown>> = Keys_<T, []>;
|
|
10
|
+
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12
|
+
export type AnyVueComponent = DefineComponent<any, any, any, any, any, any, any, any, any, any, any, any>;
|
package/lib/Editor.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { editorViewCtx } from '@milkdown/core';
|
|
3
|
-
import { defineComponent, Fragment, h, inject, markRaw, onMounted, onUnmounted, provide, ref, shallowReactive, } from 'vue';
|
|
4
|
-
import { Portals } from './Portals';
|
|
5
|
-
import { createVueView } from './VueNodeView';
|
|
6
|
-
const rendererKey = Symbol();
|
|
7
|
-
const useGetEditor = (getEditor) => {
|
|
8
|
-
const divRef = ref(null);
|
|
9
|
-
const renderVue = inject(rendererKey, () => {
|
|
10
|
-
throw new Error();
|
|
11
|
-
});
|
|
12
|
-
const editorRef = markRaw({});
|
|
13
|
-
onMounted(() => {
|
|
14
|
-
if (!divRef.value)
|
|
15
|
-
return;
|
|
16
|
-
getEditor(divRef.value, renderVue)
|
|
17
|
-
.create()
|
|
18
|
-
.then((editor) => {
|
|
19
|
-
editorRef.editor = editor;
|
|
20
|
-
return;
|
|
21
|
-
})
|
|
22
|
-
.catch((e) => console.error(e));
|
|
23
|
-
});
|
|
24
|
-
onUnmounted(() => {
|
|
25
|
-
var _a, _b;
|
|
26
|
-
const view = (_a = editorRef.editor) === null || _a === void 0 ? void 0 : _a.action((ctx) => ctx.get(editorViewCtx));
|
|
27
|
-
if (!view)
|
|
28
|
-
return;
|
|
29
|
-
(_b = view.dom.parentElement) === null || _b === void 0 ? void 0 : _b.remove();
|
|
30
|
-
view.destroy();
|
|
31
|
-
});
|
|
32
|
-
return { divRef, editorRef };
|
|
33
|
-
};
|
|
34
|
-
export const EditorComponent = defineComponent((props) => {
|
|
35
|
-
const refs = useGetEditor(props.editor);
|
|
36
|
-
if (props.editorRef) {
|
|
37
|
-
props.editorRef.value = {
|
|
38
|
-
get: () => refs.editorRef.editor,
|
|
39
|
-
dom: () => refs.divRef.value,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
return () => h("div", { ref: refs.divRef });
|
|
43
|
-
});
|
|
44
|
-
EditorComponent.props = ['editor', 'editorRef'];
|
|
45
|
-
export const VueEditor = defineComponent((props) => {
|
|
46
|
-
const portals = shallowReactive([]);
|
|
47
|
-
const addPortal = markRaw((component, key) => {
|
|
48
|
-
portals.push([key, component]);
|
|
49
|
-
});
|
|
50
|
-
const removePortalByKey = markRaw((key) => {
|
|
51
|
-
const index = portals.findIndex((p) => p[0] === key);
|
|
52
|
-
portals.splice(index, 1);
|
|
53
|
-
});
|
|
54
|
-
const renderVue = createVueView(addPortal, removePortalByKey);
|
|
55
|
-
provide(rendererKey, renderVue);
|
|
56
|
-
return () => (h(Fragment, null,
|
|
57
|
-
h(Portals, { portals: portals }),
|
|
58
|
-
h(EditorComponent, { editorRef: props.editorRef, editor: props.editor })));
|
|
59
|
-
});
|
|
60
|
-
VueEditor.props = ['editor', 'editorRef'];
|
|
61
|
-
export const useEditor = (getEditor) => {
|
|
62
|
-
return (...args) => getEditor(...args);
|
|
63
|
-
};
|
|
64
|
-
//# sourceMappingURL=Editor.js.map
|
package/lib/Editor.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Editor.js","sourceRoot":"","sources":["../src/Editor.tsx"],"names":[],"mappings":"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"}
|
package/lib/Portals.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { DefineComponent } from 'vue';
|
|
2
|
-
export declare type PortalPair = [key: string, component: DefineComponent];
|
|
3
|
-
export declare const Portals: DefineComponent<{
|
|
4
|
-
portals: PortalPair[];
|
|
5
|
-
}, () => JSX.Element, {}, import("vue").ComputedOptions, import("vue").MethodOptions, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
|
|
6
|
-
portals: PortalPair[];
|
|
7
|
-
}>, {}>;
|
|
8
|
-
//# sourceMappingURL=Portals.d.ts.map
|
package/lib/Portals.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Portals.d.ts","sourceRoot":"","sources":["../src/Portals.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAkE,MAAM,KAAK,CAAC;AACtG,oBAAY,UAAU,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;AAInE,eAAO,MAAM,OAAO;aAAsC,UAAU,EAAE;;aAAZ,UAAU,EAAE;OAuBpE,CAAC"}
|
package/lib/Portals.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { defineComponent, Fragment, h, nextTick, ref, shallowRef, watch } from 'vue';
|
|
3
|
-
const getId = (pairs) => pairs.map((p) => p[0]).join('\n');
|
|
4
|
-
export const Portals = defineComponent((props) => {
|
|
5
|
-
const portalComponents = shallowRef([]);
|
|
6
|
-
const prev = ref('');
|
|
7
|
-
const renderList = shallowRef(() => []);
|
|
8
|
-
watch(() => getId(props.portals), (ids) => {
|
|
9
|
-
if (ids !== prev.value) {
|
|
10
|
-
prev.value = ids;
|
|
11
|
-
const next = props.portals.map((p) => p[1]);
|
|
12
|
-
portalComponents.value = next;
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
nextTick(() => {
|
|
16
|
-
renderList.value = () => portalComponents.value.map((P) => h(P, null));
|
|
17
|
-
});
|
|
18
|
-
return () => {
|
|
19
|
-
return h(Fragment, null, renderList.value());
|
|
20
|
-
};
|
|
21
|
-
});
|
|
22
|
-
Portals.props = ['portals'];
|
|
23
|
-
//# sourceMappingURL=Portals.js.map
|
package/lib/Portals.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Portals.js","sourceRoot":"","sources":["../src/Portals.tsx"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,OAAO,EAAmB,eAAe,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC;AAGtG,MAAM,KAAK,GAAG,CAAC,KAAmB,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEzE,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAC,CAAC,KAAgC,EAAE,EAAE;IACxE,MAAM,gBAAgB,GAAG,UAAU,CAAyB,EAAE,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,GAAG,CAAS,EAAE,CAAC,CAAC;IAC7B,MAAM,UAAU,GAAG,UAAU,CAAsB,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAE7D,KAAK,CACD,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAC1B,CAAC,GAAG,EAAE,EAAE;QACJ,IAAI,GAAG,KAAK,IAAI,CAAC,KAAK,EAAE;YACpB,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC;YACjB,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5C,gBAAgB,CAAC,KAAK,GAAG,IAAI,CAAC;SACjC;IACL,CAAC,CACJ,CAAC;IAEF,QAAQ,CAAC,GAAG,EAAE;QACV,UAAU,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAC,CAAC,OAAG,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,EAAE;QACR,OAAO,kBAAG,UAAU,CAAC,KAAK,EAAE,CAAI,CAAC;IACrC,CAAC,CAAC;AACN,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,KAAK,GAAG,CAAC,SAAS,CAAC,CAAC"}
|
package/lib/VueNode.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { defineComponent, Fragment, h, provide, ref, watchEffect } from 'vue';
|
|
2
|
-
export const nodeMetadata = Symbol();
|
|
3
|
-
export const VueNodeContainer = defineComponent(({ node, view, getPos, decorations }, context) => {
|
|
4
|
-
provide(nodeMetadata, {
|
|
5
|
-
node,
|
|
6
|
-
view,
|
|
7
|
-
getPos,
|
|
8
|
-
decorations,
|
|
9
|
-
});
|
|
10
|
-
return () => { var _a, _b, _c; return h(Fragment, null, (_c = (_b = (_a = context.slots).default) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : []); };
|
|
11
|
-
});
|
|
12
|
-
VueNodeContainer.props = ['editor', 'node', 'view', 'getPos', 'decorations'];
|
|
13
|
-
export const Content = defineComponent((props) => {
|
|
14
|
-
const containerRef = ref(null);
|
|
15
|
-
watchEffect(() => {
|
|
16
|
-
if (!props.dom || !containerRef.value)
|
|
17
|
-
return;
|
|
18
|
-
containerRef.value.appendChild(props.dom);
|
|
19
|
-
});
|
|
20
|
-
return () => h("div", { ref: containerRef });
|
|
21
|
-
});
|
|
22
|
-
Content.props = ['dom'];
|
|
23
|
-
//# sourceMappingURL=VueNode.js.map
|
package/lib/VueNode.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VueNode.js","sourceRoot":"","sources":["../src/VueNode.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC,EAAgB,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,KAAK,CAAC;AAS5F,MAAM,CAAC,MAAM,YAAY,GAA8B,MAAM,EAAE,CAAC;AAEhE,MAAM,CAAC,MAAM,gBAAgB,GAAG,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAe,EAAE,OAAO,EAAE,EAAE;IAC1G,OAAO,CAAC,YAAY,EAAE;QAClB,IAAI;QACJ,IAAI;QACJ,MAAM;QACN,WAAW;KACd,CAAC,CAAC;IACH,OAAO,GAAG,EAAE,mBAAC,OAAA,kBAAG,MAAA,MAAA,MAAA,OAAO,CAAC,KAAK,EAAC,OAAO,kDAAI,mCAAI,EAAE,CAAI,CAAA,EAAA,CAAC;AACxD,CAAC,CAAC,CAAC;AACH,gBAAgB,CAAC,KAAK,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;AAE7E,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAC,CAAC,KAA4B,EAAE,EAAE;IACpE,MAAM,YAAY,GAAG,GAAG,CAAwB,IAAI,CAAC,CAAC;IACtD,WAAW,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK;YAAE,OAAO;QAC9C,YAAY,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,EAAE,CAAC,WAAK,GAAG,EAAE,YAAY,GAAI,CAAC;AAC5C,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC"}
|
package/lib/VueNodeView.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { Mark, Node } from '@milkdown/prose';
|
|
2
|
-
import { customAlphabet } from 'nanoid';
|
|
3
|
-
import { defineComponent, h, Teleport } from 'vue';
|
|
4
|
-
import { Content, VueNodeContainer } from './VueNode';
|
|
5
|
-
const nanoid = customAlphabet('abcedfghicklmn', 10);
|
|
6
|
-
export const createVueView = (addPortal, removePortalByKey) => (component) => (node, view, getPos, decorations) => new VueNodeView(component, addPortal, removePortalByKey, node, view, getPos, decorations);
|
|
7
|
-
export class VueNodeView {
|
|
8
|
-
constructor(component, addPortal, removePortalByKey, node, view, getPos, decorations) {
|
|
9
|
-
this.component = component;
|
|
10
|
-
this.addPortal = addPortal;
|
|
11
|
-
this.removePortalByKey = removePortalByKey;
|
|
12
|
-
this.node = node;
|
|
13
|
-
this.view = view;
|
|
14
|
-
this.getPos = getPos;
|
|
15
|
-
this.decorations = decorations;
|
|
16
|
-
this.key = nanoid();
|
|
17
|
-
const dom = document.createElement(node instanceof Mark ? 'span' : 'div');
|
|
18
|
-
dom.classList.add('dom-wrapper');
|
|
19
|
-
const contentDOM = node instanceof Node && node.isLeaf
|
|
20
|
-
? undefined
|
|
21
|
-
: document.createElement(node instanceof Mark ? 'span' : 'div');
|
|
22
|
-
if (contentDOM) {
|
|
23
|
-
contentDOM.classList.add('content-dom');
|
|
24
|
-
dom.appendChild(contentDOM);
|
|
25
|
-
}
|
|
26
|
-
this.dom = dom;
|
|
27
|
-
this.contentDOM = contentDOM;
|
|
28
|
-
this.renderPortal();
|
|
29
|
-
}
|
|
30
|
-
renderPortal() {
|
|
31
|
-
if (!this.dom)
|
|
32
|
-
return;
|
|
33
|
-
const CustomComponent = this.component;
|
|
34
|
-
const Portal = defineComponent(() => {
|
|
35
|
-
return () => (h(Teleport, { to: this.dom },
|
|
36
|
-
h(VueNodeContainer, { key: this.key, node: this.node, view: this.view, getPos: this.getPos, decorations: this.decorations },
|
|
37
|
-
h(CustomComponent, null,
|
|
38
|
-
h(Content, { dom: this.contentDOM })))));
|
|
39
|
-
});
|
|
40
|
-
this.addPortal(Portal, this.key);
|
|
41
|
-
}
|
|
42
|
-
destroy() {
|
|
43
|
-
this.dom = undefined;
|
|
44
|
-
this.contentDOM = undefined;
|
|
45
|
-
this.removePortalByKey(this.key);
|
|
46
|
-
}
|
|
47
|
-
ignoreMutation(mutation) {
|
|
48
|
-
if (!this.contentDOM) {
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
return !this.contentDOM.contains(mutation.target);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
//# sourceMappingURL=VueNodeView.js.map
|
package/lib/VueNodeView.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VueNodeView.js","sourceRoot":"","sources":["../src/VueNodeView.tsx"],"names":[],"mappings":"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"}
|
package/lib/index.js
DELETED
package/lib/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|
package/lib/utils.js
DELETED
package/lib/utils.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,yCAAyC"}
|
package/src/Portals.tsx
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { DefineComponent, defineComponent, Fragment, h, nextTick, ref, shallowRef, watch } from 'vue';
|
|
3
|
-
export type PortalPair = [key: string, component: DefineComponent];
|
|
4
|
-
|
|
5
|
-
const getId = (pairs: PortalPair[]) => pairs.map((p) => p[0]).join('\n');
|
|
6
|
-
|
|
7
|
-
export const Portals = defineComponent((props: { portals: PortalPair[] }) => {
|
|
8
|
-
const portalComponents = shallowRef<Array<DefineComponent>>([]);
|
|
9
|
-
const prev = ref<string>('');
|
|
10
|
-
const renderList = shallowRef<() => JSX.Element[]>(() => []);
|
|
11
|
-
|
|
12
|
-
watch(
|
|
13
|
-
() => getId(props.portals),
|
|
14
|
-
(ids) => {
|
|
15
|
-
if (ids !== prev.value) {
|
|
16
|
-
prev.value = ids;
|
|
17
|
-
const next = props.portals.map((p) => p[1]);
|
|
18
|
-
portalComponents.value = next;
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
nextTick(() => {
|
|
24
|
-
renderList.value = () => portalComponents.value.map((P) => <P />);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
return () => {
|
|
28
|
-
return <>{renderList.value()}</>;
|
|
29
|
-
};
|
|
30
|
-
});
|
|
31
|
-
Portals.props = ['portals'];
|