@milkdown/vue 6.1.5 → 6.2.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/Editor.d.ts +8 -23
- package/lib/Editor.d.ts.map +1 -1
- package/lib/EditorComponent.d.ts +14 -0
- package/lib/EditorComponent.d.ts.map +1 -0
- package/lib/VueNode.d.ts +8 -6
- package/lib/VueNode.d.ts.map +1 -1
- package/lib/VueNodeView.d.ts +11 -14
- package/lib/VueNodeView.d.ts.map +1 -1
- package/lib/index.d.ts +3 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.es.js +118 -53
- package/lib/index.es.js.map +1 -1
- package/lib/types.d.ts +26 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/useEditor.d.ts +3 -0
- package/lib/useEditor.d.ts.map +1 -0
- package/lib/useGetEditor.d.ts +7 -0
- package/lib/useGetEditor.d.ts.map +1 -0
- package/package.json +5 -5
- package/src/Editor.tsx +57 -69
- package/src/EditorComponent.tsx +25 -0
- package/src/VueNode.tsx +8 -5
- package/src/VueNodeView.tsx +22 -11
- package/src/index.ts +3 -1
- package/src/types.ts +50 -0
- package/src/useEditor.ts +25 -0
- package/src/useGetEditor.ts +50 -0
package/lib/Editor.d.ts
CHANGED
|
@@ -1,28 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { AnyVueComponent } from './utils';
|
|
5
|
-
import { RenderOptions } from './VueNodeView';
|
|
6
|
-
export declare type RenderVue = (Component: AnyVueComponent, options?: RenderOptions) => (ctx: Ctx) => ViewFactory;
|
|
7
|
-
export declare type GetEditor = (container: HTMLDivElement, renderVue: RenderVue) => Editor;
|
|
8
|
-
export declare const EditorComponent: DefineComponent<{
|
|
9
|
-
editor: GetEditor;
|
|
10
|
-
editorRef?: Ref<EditorRef> | undefined;
|
|
11
|
-
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
|
|
12
|
-
editor: GetEditor;
|
|
13
|
-
editorRef?: Ref<EditorRef> | undefined;
|
|
14
|
-
}>, {}>;
|
|
15
|
-
export declare type EditorRef = {
|
|
16
|
-
get: () => Editor | undefined;
|
|
17
|
-
dom: () => HTMLDivElement | null;
|
|
18
|
-
};
|
|
1
|
+
import { ComponentInternalInstance, DefineComponent, InjectionKey } from 'vue';
|
|
2
|
+
import { EditorRef } from './EditorComponent';
|
|
3
|
+
import { EditorInfo, EditorInfoCtx } from './types';
|
|
19
4
|
export declare const getRootInstance: () => ComponentInternalInstance | null;
|
|
5
|
+
export declare const editorInfoCtxKey: InjectionKey<EditorInfoCtx>;
|
|
20
6
|
export declare const VueEditor: DefineComponent<{
|
|
21
|
-
editor:
|
|
22
|
-
editorRef?:
|
|
7
|
+
editor: EditorInfo;
|
|
8
|
+
editorRef?: EditorRef | undefined;
|
|
23
9
|
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
|
|
24
|
-
editor:
|
|
25
|
-
editorRef?:
|
|
10
|
+
editor: EditorInfo;
|
|
11
|
+
editorRef?: EditorRef | undefined;
|
|
26
12
|
}>, {}>;
|
|
27
|
-
export declare const useEditor: (getEditor: GetEditor) => (container: HTMLDivElement, renderVue: RenderVue) => Editor;
|
|
28
13
|
//# 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,
|
|
1
|
+
{"version":3,"file":"Editor.d.ts","sourceRoot":"","sources":["../src/Editor.tsx"],"names":[],"mappings":"AACA,OAAO,EACH,yBAAyB,EACzB,eAAe,EAKf,YAAY,EAMf,MAAM,KAAK,CAAC;AAEb,OAAO,EAAmB,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AASpD,eAAO,MAAM,eAAe,wCAE3B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,YAAY,CAAC,aAAa,CAAY,CAAC;AA4BtE,eAAO,MAAM,SAAS;YAA6B,UAAU;;;YAAV,UAAU;;OA0D3D,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Editor } from '@milkdown/core';
|
|
2
|
+
import { GetEditor } from './types';
|
|
3
|
+
export declare const EditorComponent: import("vue").DefineComponent<{
|
|
4
|
+
editor: GetEditor;
|
|
5
|
+
editorRef?: EditorRef | undefined;
|
|
6
|
+
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
|
|
7
|
+
editor: GetEditor;
|
|
8
|
+
editorRef?: EditorRef | undefined;
|
|
9
|
+
}>, {}>;
|
|
10
|
+
export declare type EditorRef = {
|
|
11
|
+
get: () => Editor | undefined;
|
|
12
|
+
dom: () => HTMLDivElement | null;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=EditorComponent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditorComponent.d.ts","sourceRoot":"","sources":["../src/EditorComponent.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAIxC,OAAO,EAAiB,SAAS,EAAE,MAAM,SAAS,CAAC;AAGnD,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"}
|
package/lib/VueNode.d.ts
CHANGED
|
@@ -2,17 +2,19 @@ import { Ctx } from '@milkdown/core';
|
|
|
2
2
|
import { Mark, Node } from '@milkdown/prose/model';
|
|
3
3
|
import { Decoration, EditorView } from '@milkdown/prose/view';
|
|
4
4
|
import { InjectionKey } from 'vue';
|
|
5
|
-
export declare type NodeContext = {
|
|
5
|
+
export declare type NodeContext<T extends Node | Mark = Node | Mark> = {
|
|
6
6
|
ctx: Ctx;
|
|
7
|
-
node:
|
|
7
|
+
node: T;
|
|
8
8
|
view: EditorView;
|
|
9
|
-
getPos: boolean | (() => number);
|
|
10
|
-
decorations: Decoration[];
|
|
9
|
+
getPos: T extends Mark ? boolean : T extends Node ? () => number : boolean | (() => number);
|
|
10
|
+
decorations: readonly Decoration[];
|
|
11
11
|
};
|
|
12
12
|
export declare const nodeMetadata: InjectionKey<NodeContext>;
|
|
13
|
-
export declare
|
|
13
|
+
export declare type UseNodeCtx = <T extends Node | Mark = Node | Mark>() => NodeContext<T>;
|
|
14
|
+
export declare const useNodeCtx: UseNodeCtx;
|
|
15
|
+
export declare const VueNodeContainer: import("vue").DefineComponent<NodeContext<Mark | Node> & {
|
|
14
16
|
as: string;
|
|
15
|
-
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<NodeContext & {
|
|
17
|
+
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<NodeContext<Mark | Node> & {
|
|
16
18
|
as: string;
|
|
17
19
|
}>, {}>;
|
|
18
20
|
export declare const Content: import("vue").DefineComponent<{
|
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,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC9D,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,IAAI,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAA8B,YAAY,EAAW,MAAM,KAAK,CAAC;AAExE,oBAAY,WAAW,CAAC,CAAC,SAAS,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,IAAI;IAC3D,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,CAAC,CAAC;IACR,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,CAAC,SAAS,IAAI,GAAG,OAAO,GAAG,CAAC,SAAS,IAAI,GAAG,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IAC5F,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;CACtC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,YAAY,CAAC,WAAW,CAAY,CAAC;AAEhE,oBAAY,UAAU,GAAG,CAAC,CAAC,SAAS,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC;AACnF,eAAO,MAAM,UAAU,EAAE,UAA6D,CAAC;AAEvF,eAAO,MAAM,gBAAgB;QAAuC,MAAM;;QAAN,MAAM;OAYxE,CAAC;AAGH,eAAO,MAAM,OAAO;;;;OAKlB,CAAC"}
|
package/lib/VueNodeView.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Ctx } from '@milkdown/core';
|
|
2
|
-
import type { ViewFactory } from '@milkdown/prose';
|
|
3
2
|
import { Mark, Node } from '@milkdown/prose/model';
|
|
4
|
-
import type { Decoration,
|
|
3
|
+
import type { Decoration, DecorationSource, EditorView, MarkViewConstructor, NodeView, NodeViewConstructor } from '@milkdown/prose/view';
|
|
5
4
|
import { DefineComponent } from 'vue';
|
|
6
5
|
export declare type RenderOptions = Partial<{
|
|
7
6
|
as: string;
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
update?: (node: Node, decorations: readonly Decoration[], innerDecorations: DecorationSource) => boolean;
|
|
8
|
+
} & Pick<NodeView, 'ignoreMutation' | 'deselectNode' | 'selectNode' | 'destroy'>>;
|
|
9
|
+
export declare const createVueView: (addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) => (component: DefineComponent, options?: RenderOptions) => (ctx: Ctx) => NodeViewConstructor | MarkViewConstructor;
|
|
10
10
|
export declare class VueNodeView implements NodeView {
|
|
11
11
|
private ctx;
|
|
12
12
|
private component;
|
|
@@ -20,17 +20,14 @@ export declare class VueNodeView implements NodeView {
|
|
|
20
20
|
teleportDOM: HTMLElement;
|
|
21
21
|
key: string;
|
|
22
22
|
get isInlineOrMark(): boolean;
|
|
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[]);
|
|
24
|
-
get dom():
|
|
25
|
-
get contentDOM():
|
|
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: readonly Decoration[]);
|
|
24
|
+
get dom(): HTMLElement;
|
|
25
|
+
get contentDOM(): HTMLElement | undefined;
|
|
26
26
|
renderPortal(): void;
|
|
27
27
|
destroy(): void;
|
|
28
|
-
ignoreMutation(mutation: MutationRecord
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
update(node: Node, decorations: Decoration[], innerDecorations: DecorationSet): boolean;
|
|
33
|
-
selectNode: (() => void) | null | undefined;
|
|
34
|
-
deselectNode: (() => void) | null | undefined;
|
|
28
|
+
ignoreMutation(mutation: MutationRecord): boolean;
|
|
29
|
+
update(node: Node, decorations: readonly Decoration[], innerDecorations: DecorationSource): boolean;
|
|
30
|
+
selectNode: (() => void) | undefined;
|
|
31
|
+
deselectNode: (() => void) | undefined;
|
|
35
32
|
}
|
|
36
33
|
//# 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,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,
|
|
1
|
+
{"version":3,"file":"VueNodeView.d.ts","sourceRoot":"","sources":["../src/VueNodeView.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,EACR,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,QAAQ,EACR,mBAAmB,EACtB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,eAAe,EAAyC,MAAM,KAAK,CAAC;AAO7E,oBAAY,aAAa,GAAG,OAAO,CAC/B;IACI,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,UAAU,EAAE,EAAE,gBAAgB,EAAE,gBAAgB,KAAK,OAAO,CAAC;CAC5G,GAAG,IAAI,CAAC,QAAQ,EAAE,gBAAgB,GAAG,cAAc,GAAG,YAAY,GAAG,SAAS,CAAC,CACnF,CAAC;AAEF,eAAO,MAAM,aAAa,uBACD,eAAe,OAAO,MAAM,KAAK,IAAI,2BAA2B,MAAM,KAAK,IAAI,iBAErF,eAAe,YACjB,aAAa,WAChB,GAAG,KAAK,mBAAmB,GAAG,mBAGmE,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,SAAS,UAAU,EAAE;IAQ9C,IAAI,GAAG,gBAEN;IAED,IAAI,UAAU,4BAMb;IAED,YAAY;IAiCZ,OAAO;IAMP,cAAc,CAAC,QAAQ,EAAE,cAAc;IA6BvC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,UAAU,EAAE,EAAE,gBAAgB,EAAE,gBAAgB;IAoBzF,UAAU,2BAA4B;IAEtC,YAAY,2BAA8B;CAC7C"}
|
package/lib/index.d.ts
CHANGED
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,UAAU,CAAC;AACzB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC"}
|
package/lib/index.es.js
CHANGED
|
@@ -5,11 +5,65 @@ var __publicField = (obj, key, value) => {
|
|
|
5
5
|
return value;
|
|
6
6
|
};
|
|
7
7
|
var _a, _b;
|
|
8
|
-
import { defineComponent, provide, h,
|
|
8
|
+
import { inject, ref, onMounted, onUnmounted, defineComponent, createVNode, provide, h, Teleport, markRaw, shallowReactive, getCurrentInstance, onBeforeMount, effect, isVNode } from "vue";
|
|
9
9
|
import { editorViewCtx, rootCtx } from "@milkdown/core";
|
|
10
10
|
import { Mark, Node } from "@milkdown/prose/model";
|
|
11
11
|
import { customAlphabet } from "nanoid";
|
|
12
|
+
const rendererKey = Symbol();
|
|
13
|
+
const useGetEditor = (getEditor) => {
|
|
14
|
+
const renderVue = inject(rendererKey, () => {
|
|
15
|
+
throw new Error();
|
|
16
|
+
});
|
|
17
|
+
const { dom, loading, editor: editorRef } = inject(editorInfoCtxKey, {});
|
|
18
|
+
const lock = ref(false);
|
|
19
|
+
onMounted(() => {
|
|
20
|
+
if (!dom.value)
|
|
21
|
+
return;
|
|
22
|
+
const editor = getEditor(dom.value, renderVue);
|
|
23
|
+
if (!editor)
|
|
24
|
+
return;
|
|
25
|
+
if (lock.value)
|
|
26
|
+
return;
|
|
27
|
+
loading.value = true;
|
|
28
|
+
lock.value = true;
|
|
29
|
+
editor.create().then((editor2) => {
|
|
30
|
+
editorRef.value = editor2;
|
|
31
|
+
return;
|
|
32
|
+
}).finally(() => {
|
|
33
|
+
loading.value = false;
|
|
34
|
+
lock.value = false;
|
|
35
|
+
}).catch((e) => console.error(e));
|
|
36
|
+
});
|
|
37
|
+
onUnmounted(() => {
|
|
38
|
+
var _a2, _b2, _c;
|
|
39
|
+
const view = (_a2 = editorRef.value) == null ? void 0 : _a2.action((ctx) => ctx.get(editorViewCtx));
|
|
40
|
+
const root = (_b2 = editorRef.value) == null ? void 0 : _b2.action((ctx) => ctx.get(rootCtx));
|
|
41
|
+
(_c = root == null ? void 0 : root.firstChild) == null ? void 0 : _c.remove();
|
|
42
|
+
view == null ? void 0 : view.destroy();
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
const EditorComponent = defineComponent({
|
|
46
|
+
name: "milkdown-dom-root",
|
|
47
|
+
setup: (props, {
|
|
48
|
+
slots
|
|
49
|
+
}) => {
|
|
50
|
+
useGetEditor(props.editor);
|
|
51
|
+
const ctx = inject(editorInfoCtxKey, {});
|
|
52
|
+
if (props.editorRef) {
|
|
53
|
+
props.editorRef.get = () => ctx.editor.value;
|
|
54
|
+
props.editorRef.dom = () => ctx.dom.value;
|
|
55
|
+
}
|
|
56
|
+
return () => {
|
|
57
|
+
var _a2;
|
|
58
|
+
return createVNode("div", {
|
|
59
|
+
"ref": ctx.dom
|
|
60
|
+
}, [(_a2 = slots["default"]) == null ? void 0 : _a2.call(slots)]);
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
EditorComponent["props"] = ["editor", "editorRef"];
|
|
12
65
|
const nodeMetadata = Symbol();
|
|
66
|
+
const useNodeCtx = () => inject(nodeMetadata);
|
|
13
67
|
const VueNodeContainer = defineComponent({
|
|
14
68
|
name: "milkdown-node-container",
|
|
15
69
|
setup: ({
|
|
@@ -77,7 +131,7 @@ class VueNodeView {
|
|
|
77
131
|
}
|
|
78
132
|
get contentDOM() {
|
|
79
133
|
if (this.node instanceof Node && this.node.isLeaf) {
|
|
80
|
-
return
|
|
134
|
+
return void 0;
|
|
81
135
|
}
|
|
82
136
|
return this.teleportDOM.querySelector("[data-view-content]") || this.dom;
|
|
83
137
|
}
|
|
@@ -119,6 +173,7 @@ class VueNodeView {
|
|
|
119
173
|
destroy() {
|
|
120
174
|
var _a2, _b2;
|
|
121
175
|
(_b2 = (_a2 = this.options).destroy) == null ? void 0 : _b2.call(_a2);
|
|
176
|
+
this.teleportDOM.remove();
|
|
122
177
|
this.removePortalByKey(this.key);
|
|
123
178
|
}
|
|
124
179
|
ignoreMutation(mutation) {
|
|
@@ -166,60 +221,36 @@ class VueNodeView {
|
|
|
166
221
|
function _isSlot(s) {
|
|
167
222
|
return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
|
|
168
223
|
}
|
|
169
|
-
const rendererKey = Symbol();
|
|
170
|
-
const useGetEditor = (getEditor) => {
|
|
171
|
-
const divRef = ref(null);
|
|
172
|
-
const renderVue = inject(rendererKey, () => {
|
|
173
|
-
throw new Error();
|
|
174
|
-
});
|
|
175
|
-
const editorRef = markRaw({});
|
|
176
|
-
onMounted(() => {
|
|
177
|
-
if (!divRef.value)
|
|
178
|
-
return;
|
|
179
|
-
getEditor(divRef.value, renderVue).create().then((editor) => {
|
|
180
|
-
editorRef.editor = editor;
|
|
181
|
-
return;
|
|
182
|
-
}).catch((e) => console.error(e));
|
|
183
|
-
});
|
|
184
|
-
onUnmounted(() => {
|
|
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));
|
|
188
|
-
(_c = root == null ? void 0 : root.firstChild) == null ? void 0 : _c.remove();
|
|
189
|
-
view == null ? void 0 : view.destroy();
|
|
190
|
-
});
|
|
191
|
-
return {
|
|
192
|
-
divRef,
|
|
193
|
-
editorRef
|
|
194
|
-
};
|
|
195
|
-
};
|
|
196
|
-
const EditorComponent = defineComponent({
|
|
197
|
-
name: "milkdown-dom-root",
|
|
198
|
-
setup: (props, {
|
|
199
|
-
slots
|
|
200
|
-
}) => {
|
|
201
|
-
const refs = useGetEditor(props.editor);
|
|
202
|
-
if (props.editorRef) {
|
|
203
|
-
props.editorRef.value = {
|
|
204
|
-
get: () => refs.editorRef.editor,
|
|
205
|
-
dom: () => refs.divRef.value
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
return () => {
|
|
209
|
-
var _a2;
|
|
210
|
-
return createVNode("div", {
|
|
211
|
-
"ref": refs.divRef
|
|
212
|
-
}, [(_a2 = slots["default"]) == null ? void 0 : _a2.call(slots)]);
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
EditorComponent["props"] = ["editor", "editorRef"];
|
|
217
224
|
const rootInstance = {
|
|
218
225
|
instance: null
|
|
219
226
|
};
|
|
220
227
|
const getRootInstance = () => {
|
|
221
228
|
return rootInstance.instance;
|
|
222
229
|
};
|
|
230
|
+
const editorInfoCtxKey = Symbol();
|
|
231
|
+
const refDeprecatedInfo = `
|
|
232
|
+
@milkdown/vue:
|
|
233
|
+
Passing ref to VueEditor will soon be deprecated, please use:
|
|
234
|
+
|
|
235
|
+
const { editor, getInstance, getDom, loading } = useEditor(/* creator */);
|
|
236
|
+
|
|
237
|
+
effect(() => {
|
|
238
|
+
if (!loading) {
|
|
239
|
+
const editor = getInstance();
|
|
240
|
+
const rootDOM = getDom();
|
|
241
|
+
}
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
<VueEditor editor={editor} />
|
|
245
|
+
`;
|
|
246
|
+
const compositionDeprecatedInfo = `
|
|
247
|
+
@milkdown/vue:
|
|
248
|
+
Passing editor directly to VueEditor will soon be deprecated, please use:
|
|
249
|
+
|
|
250
|
+
const { editor } = useEditor(/* creator */);
|
|
251
|
+
|
|
252
|
+
<VueEditor editor={editor} />
|
|
253
|
+
`;
|
|
223
254
|
const VueEditor = defineComponent({
|
|
224
255
|
name: "milkdown-vue-root",
|
|
225
256
|
setup: (props) => {
|
|
@@ -240,13 +271,33 @@ const VueEditor = defineComponent({
|
|
|
240
271
|
});
|
|
241
272
|
const renderVue = createVueView(addPortal, removePortalByKey);
|
|
242
273
|
provide(rendererKey, renderVue);
|
|
274
|
+
const usingDeprecatedCompositionAPI = Object.hasOwnProperty.call(props.editor, "getInstance");
|
|
275
|
+
const {
|
|
276
|
+
getEditorCallback,
|
|
277
|
+
dom,
|
|
278
|
+
editor,
|
|
279
|
+
loading
|
|
280
|
+
} = usingDeprecatedCompositionAPI ? props.editor.editor : props.editor;
|
|
281
|
+
effect(() => {
|
|
282
|
+
if (usingDeprecatedCompositionAPI) {
|
|
283
|
+
console.warn(compositionDeprecatedInfo);
|
|
284
|
+
}
|
|
285
|
+
if (props.editorRef) {
|
|
286
|
+
console.warn(refDeprecatedInfo);
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
provide(editorInfoCtxKey, {
|
|
290
|
+
dom,
|
|
291
|
+
editor,
|
|
292
|
+
loading
|
|
293
|
+
});
|
|
243
294
|
return () => {
|
|
244
295
|
const portalElements = portals.map(([id, P]) => createVNode(P, {
|
|
245
296
|
"key": id
|
|
246
297
|
}, null));
|
|
247
298
|
return createVNode(EditorComponent, {
|
|
248
299
|
"editorRef": props.editorRef,
|
|
249
|
-
"editor":
|
|
300
|
+
"editor": getEditorCallback.value
|
|
250
301
|
}, _isSlot(portalElements) ? portalElements : {
|
|
251
302
|
default: () => [portalElements]
|
|
252
303
|
});
|
|
@@ -255,7 +306,21 @@ const VueEditor = defineComponent({
|
|
|
255
306
|
});
|
|
256
307
|
VueEditor["props"] = ["editor", "editorRef"];
|
|
257
308
|
const useEditor = (getEditor) => {
|
|
258
|
-
|
|
309
|
+
const dom = ref(null);
|
|
310
|
+
const editor = ref();
|
|
311
|
+
const loading = ref(true);
|
|
312
|
+
const getEditorCallback = ref((...args) => getEditor(...args));
|
|
313
|
+
return {
|
|
314
|
+
loading,
|
|
315
|
+
getInstance: () => editor.value,
|
|
316
|
+
getDom: () => dom.value,
|
|
317
|
+
editor: {
|
|
318
|
+
getEditorCallback,
|
|
319
|
+
dom,
|
|
320
|
+
editor,
|
|
321
|
+
loading
|
|
322
|
+
}
|
|
323
|
+
};
|
|
259
324
|
};
|
|
260
|
-
export {
|
|
325
|
+
export { Content, VueEditor, VueNodeContainer, editorInfoCtxKey, getRootInstance, nodeMetadata, useEditor, useNodeCtx };
|
|
261
326
|
//# sourceMappingURL=index.es.js.map
|
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 { Mark, Node } from '@milkdown/prose/model';\nimport { Decoration, EditorView } from '@milkdown/prose/view';\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 { ViewFactory } from '@milkdown/prose';\nimport { Mark, Node } from '@milkdown/prose/model';\nimport type { Decoration, DecorationSet, EditorView, NodeView } from '@milkdown/prose/view';\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\nexport type RenderVue = (Component: AnyVueComponent, options?: RenderOptions) => (ctx: Ctx) => ViewFactory;\nexport type GetEditor = (container: HTMLDivElement, renderVue: RenderVue) => 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","_createVNode","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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"}
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../src/useGetEditor.ts","../src/EditorComponent.tsx","../src/VueNode.tsx","../src/VueNodeView.tsx","../src/Editor.tsx","../src/useEditor.ts"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx, editorViewCtx, rootCtx } from '@milkdown/core';\nimport { MarkViewConstructor, NodeViewConstructor } from '@milkdown/prose/view';\nimport { DefineComponent, inject, InjectionKey, onMounted, onUnmounted, ref } from 'vue';\n\nimport { editorInfoCtxKey } from '.';\nimport { EditorInfoCtx, GetEditor, RenderOptions, RenderVue } from './types';\n\nexport const rendererKey: InjectionKey<\n (component: DefineComponent, options?: RenderOptions) => (ctx: Ctx) => NodeViewConstructor | MarkViewConstructor\n> = Symbol();\n\nexport const useGetEditor = (getEditor: GetEditor) => {\n const renderVue = inject<RenderVue>(rendererKey, () => {\n throw new Error();\n });\n const { dom, loading, editor: editorRef } = inject(editorInfoCtxKey, {} as EditorInfoCtx);\n const lock = ref(false);\n\n onMounted(() => {\n if (!dom.value) return;\n\n const editor = getEditor(dom.value, renderVue);\n if (!editor) return;\n\n if (lock.value) return;\n\n loading.value = true;\n lock.value = true;\n\n editor\n .create()\n .then((editor) => {\n editorRef.value = editor;\n return;\n })\n .finally(() => {\n loading.value = false;\n lock.value = false;\n })\n .catch((e) => console.error(e));\n });\n onUnmounted(() => {\n const view = editorRef.value?.action((ctx) => ctx.get(editorViewCtx));\n const root = editorRef.value?.action((ctx) => ctx.get(rootCtx)) as HTMLElement;\n\n root?.firstChild?.remove();\n view?.destroy();\n });\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Editor } from '@milkdown/core';\nimport { defineComponent, h, inject } from 'vue';\n\nimport { editorInfoCtxKey } from './Editor';\nimport { EditorInfoCtx, GetEditor } from './types';\nimport { useGetEditor } from './useGetEditor';\n\nexport const EditorComponent = defineComponent<{ editor: GetEditor; editorRef?: EditorRef }>({\n name: 'milkdown-dom-root',\n setup: (props, { slots }) => {\n useGetEditor(props.editor);\n const ctx = inject(editorInfoCtxKey, {} as EditorInfoCtx);\n\n if (props.editorRef) {\n props.editorRef.get = () => ctx.editor.value;\n props.editorRef.dom = () => ctx.dom.value;\n }\n\n return () => <div ref={ctx.dom}>{slots['default']?.()}</div>;\n },\n});\nEditorComponent['props'] = ['editor', 'editorRef'];\n\nexport type EditorRef = { get: () => Editor | undefined; dom: () => HTMLDivElement | null };\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx } from '@milkdown/core';\nimport { Mark, Node } from '@milkdown/prose/model';\nimport { Decoration, EditorView } from '@milkdown/prose/view';\nimport { defineComponent, h, inject, InjectionKey, provide } from 'vue';\n\nexport type NodeContext<T extends Node | Mark = Node | Mark> = {\n ctx: Ctx;\n node: T;\n view: EditorView;\n getPos: T extends Mark ? boolean : T extends Node ? () => number : boolean | (() => number);\n decorations: readonly Decoration[];\n};\n\nexport const nodeMetadata: InjectionKey<NodeContext> = Symbol();\n\nexport type UseNodeCtx = <T extends Node | Mark = Node | Mark>() => NodeContext<T>;\nexport const useNodeCtx: UseNodeCtx = () => inject(nodeMetadata) as NodeContext<never>;\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 { Mark, Node } from '@milkdown/prose/model';\nimport type {\n Decoration,\n DecorationSource,\n EditorView,\n MarkViewConstructor,\n NodeView,\n NodeViewConstructor,\n} from '@milkdown/prose/view';\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 update?: (node: Node, decorations: readonly Decoration[], innerDecorations: DecorationSource) => boolean;\n } & Pick<NodeView, 'ignoreMutation' | 'deselectNode' | 'selectNode' | 'destroy'>\n>;\n\nexport const createVueView =\n (addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) =>\n (\n component: DefineComponent,\n options: RenderOptions = {},\n ): ((ctx: Ctx) => NodeViewConstructor | MarkViewConstructor) =>\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: readonly 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) as HTMLElement;\n }\n\n get contentDOM() {\n if (this.node instanceof Node && this.node.isLeaf) {\n return undefined;\n }\n\n return this.teleportDOM.querySelector<HTMLElement>('[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.teleportDOM.remove();\n this.removePortalByKey(this.key);\n }\n\n ignoreMutation(mutation: MutationRecord) {\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 as unknown as { type: string }).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: readonly Decoration[], innerDecorations: DecorationSource) {\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 {\n ComponentInternalInstance,\n DefineComponent,\n defineComponent,\n effect,\n getCurrentInstance,\n h,\n InjectionKey,\n markRaw,\n onBeforeMount,\n onUnmounted,\n provide,\n shallowReactive,\n} from 'vue';\n\nimport { EditorComponent, EditorRef } from './EditorComponent';\nimport { EditorInfo, EditorInfoCtx } from './types';\nimport { rendererKey } from './useGetEditor';\nimport { createVueView } from './VueNodeView';\n\nconst rootInstance: {\n instance: null | ComponentInternalInstance;\n} = {\n instance: null,\n};\nexport const getRootInstance = () => {\n return rootInstance.instance;\n};\n\nexport const editorInfoCtxKey: InjectionKey<EditorInfoCtx> = Symbol();\n\nconst refDeprecatedInfo = `\n@milkdown/vue:\nPassing ref to VueEditor will soon be deprecated, please use:\n\nconst { editor, getInstance, getDom, loading } = useEditor(/* creator */);\n\neffect(() => {\n if (!loading) {\n const editor = getInstance();\n const rootDOM = getDom();\n }\n})\n\n<VueEditor editor={editor} />\n`;\n\nconst compositionDeprecatedInfo = `\n@milkdown/vue:\nPassing editor directly to VueEditor will soon be deprecated, please use:\n\nconst { editor } = useEditor(/* creator */);\n\n<VueEditor editor={editor} />\n`;\n\ntype PortalPair = [key: string, component: DefineComponent];\nexport const VueEditor = defineComponent<{ editor: EditorInfo; editorRef?: 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\n provide(rendererKey, renderVue);\n\n const usingDeprecatedCompositionAPI = Object.hasOwnProperty.call(props.editor, 'getInstance');\n\n const { getEditorCallback, dom, editor, loading } = usingDeprecatedCompositionAPI\n ? // @ts-expect-error deprecated old composition API\n (props.editor.editor as EditorInfo)\n : props.editor;\n\n effect(() => {\n if (usingDeprecatedCompositionAPI) {\n console.warn(compositionDeprecatedInfo);\n }\n if (props.editorRef) {\n console.warn(refDeprecatedInfo);\n }\n });\n\n provide(editorInfoCtxKey, {\n dom,\n editor,\n loading,\n });\n\n return () => {\n const portalElements = portals.map(([id, P]) => <P key={id} />);\n return (\n <EditorComponent editorRef={props.editorRef} editor={getEditorCallback.value}>\n {portalElements}\n </EditorComponent>\n );\n };\n },\n});\nVueEditor['props'] = ['editor', 'editorRef'];\n","/* Copyright 2021, Milkdown by Mirone. */\n\nimport { Editor } from '@milkdown/core';\nimport { ref } from 'vue';\n\nimport { GetEditor, UseEditorReturn } from './types';\n\nexport const useEditor = (getEditor: GetEditor): UseEditorReturn => {\n const dom = ref<HTMLDivElement | null>(null);\n const editor = ref<Editor>();\n const loading = ref(true);\n const getEditorCallback = ref<GetEditor>((...args) => getEditor(...args));\n\n return {\n loading,\n getInstance: () => editor.value,\n getDom: () => dom.value,\n editor: {\n getEditorCallback,\n dom,\n editor,\n loading,\n },\n };\n};\n"],"names":["EditorComponent","defineComponent","name","setup","props","slots","useGetEditor","editor","ctx","inject","editorInfoCtxKey","editorRef","get","value","dom","_createVNode","nodeMetadata","Symbol","useNodeCtx","VueNodeContainer","node","view","getPos","decorations","as","context","provide","h","Content","isInline","nanoid","customAlphabet","createVueView","addPortal","removePortalByKey","component","options","VueNodeView","constructor","selectNode","deselectNode","key","elementName","isInlineOrMark","teleportDOM","document","createElement","renderPortal","Mark","firstElementChild","contentDOM","Node","isLeaf","undefined","querySelector","CustomComponent","Portal","markRaw","instance","getRootInstance","update","destroy","remove","ignoreMutation","mutation","isAtom","type","contains","target","innerDecorations","result","rootInstance","refDeprecatedInfo","compositionDeprecatedInfo","VueEditor","portals","shallowReactive","getCurrentInstance","onBeforeMount","_","onUnmounted","push","index","findIndex","p","splice","renderVue","rendererKey","usingDeprecatedCompositionAPI","Object","hasOwnProperty","call","getEditorCallback","loading","effect","console","warn","portalElements","map","id","P"],"mappings":"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"}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Ctx, Editor } from '@milkdown/core';
|
|
2
|
+
import type { Mark, Node } from '@milkdown/prose/model';
|
|
3
|
+
import { Decoration, DecorationSource, MarkViewConstructor, NodeView, NodeViewConstructor } from '@milkdown/prose/view';
|
|
4
|
+
import { Ref } from 'vue';
|
|
5
|
+
import { AnyVueComponent } from './utils';
|
|
6
|
+
export declare type RenderOptions = Partial<{
|
|
7
|
+
as: string;
|
|
8
|
+
update?: (node: Node, decorations: readonly Decoration[], innerDecorations: DecorationSource) => boolean;
|
|
9
|
+
} & Pick<NodeView, 'ignoreMutation' | 'deselectNode' | 'selectNode' | 'destroy'>>;
|
|
10
|
+
export declare type RenderVue<U = never> = <T extends Node | Mark = Node | Mark>(Component: AnyVueComponent, options?: RenderOptions) => (ctx: Ctx) => U extends never ? T extends Node ? NodeViewConstructor : T extends Mark ? MarkViewConstructor : NodeViewConstructor & MarkViewConstructor : U extends Node ? NodeViewConstructor : U extends Mark ? MarkViewConstructor : NodeViewConstructor & MarkViewConstructor;
|
|
11
|
+
export declare type GetEditor = (container: HTMLDivElement, renderVue: RenderVue) => Editor;
|
|
12
|
+
export declare type EditorInfoCtx = {
|
|
13
|
+
dom: Ref<HTMLDivElement | null>;
|
|
14
|
+
editor: Ref<Editor | undefined>;
|
|
15
|
+
loading: Ref<boolean>;
|
|
16
|
+
};
|
|
17
|
+
export declare type EditorInfo = {
|
|
18
|
+
getEditorCallback: Ref<GetEditor>;
|
|
19
|
+
} & EditorInfoCtx;
|
|
20
|
+
export declare type UseEditorReturn = {
|
|
21
|
+
loading: Ref<boolean>;
|
|
22
|
+
getInstance: () => Editor | undefined;
|
|
23
|
+
getDom: () => HTMLDivElement | null;
|
|
24
|
+
editor: EditorInfo;
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACxH,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,oBAAY,aAAa,GAAG,OAAO,CAC/B;IACI,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,UAAU,EAAE,EAAE,gBAAgB,EAAE,gBAAgB,KAAK,OAAO,CAAC;CAC5G,GAAG,IAAI,CAAC,QAAQ,EAAE,gBAAgB,GAAG,cAAc,GAAG,YAAY,GAAG,SAAS,CAAC,CACnF,CAAC;AAEF,oBAAY,SAAS,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,SAAS,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EACnE,SAAS,EAAE,eAAe,EAC1B,OAAO,CAAC,EAAE,aAAa,KACtB,CACD,GAAG,EAAE,GAAG,KACP,CAAC,SAAS,KAAK,GACd,CAAC,SAAS,IAAI,GACV,mBAAmB,GACnB,CAAC,SAAS,IAAI,GACd,mBAAmB,GACnB,mBAAmB,GAAG,mBAAmB,GAC7C,CAAC,SAAS,IAAI,GACd,mBAAmB,GACnB,CAAC,SAAS,IAAI,GACd,mBAAmB,GACnB,mBAAmB,GAAG,mBAAmB,CAAC;AAEhD,oBAAY,SAAS,GAAG,CAAC,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,KAAK,MAAM,CAAC;AAEpF,oBAAY,aAAa,GAAG;IACxB,GAAG,EAAE,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAChC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;CACzB,CAAC;AAEF,oBAAY,UAAU,GAAG;IACrB,iBAAiB,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;CACrC,GAAG,aAAa,CAAC;AAElB,oBAAY,eAAe,GAAG;IAC1B,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACtB,WAAW,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACtC,MAAM,EAAE,MAAM,cAAc,GAAG,IAAI,CAAC;IACpC,MAAM,EAAE,UAAU,CAAC;CACtB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useEditor.d.ts","sourceRoot":"","sources":["../src/useEditor.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAErD,eAAO,MAAM,SAAS,cAAe,SAAS,KAAG,eAiBhD,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Ctx } from '@milkdown/core';
|
|
2
|
+
import { MarkViewConstructor, NodeViewConstructor } from '@milkdown/prose/view';
|
|
3
|
+
import { DefineComponent, InjectionKey } from 'vue';
|
|
4
|
+
import { GetEditor, RenderOptions } from './types';
|
|
5
|
+
export declare const rendererKey: InjectionKey<(component: DefineComponent, options?: RenderOptions) => (ctx: Ctx) => NodeViewConstructor | MarkViewConstructor>;
|
|
6
|
+
export declare const useGetEditor: (getEditor: GetEditor) => void;
|
|
7
|
+
//# sourceMappingURL=useGetEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useGetEditor.d.ts","sourceRoot":"","sources":["../src/useGetEditor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAA0B,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,eAAe,EAAU,YAAY,EAA+B,MAAM,KAAK,CAAC;AAGzF,OAAO,EAAiB,SAAS,EAAE,aAAa,EAAa,MAAM,SAAS,CAAC;AAE7E,eAAO,MAAM,WAAW,EAAE,YAAY,CAClC,CAAC,SAAS,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,aAAa,KAAK,CAAC,GAAG,EAAE,GAAG,KAAK,mBAAmB,GAAG,mBAAmB,CACxG,CAAC;AAEb,eAAO,MAAM,YAAY,cAAe,SAAS,SAqChD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milkdown/vue",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./lib/index.es.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"vue"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@milkdown/utils": "6.
|
|
20
|
-
"nanoid": "^
|
|
19
|
+
"@milkdown/utils": "6.2.0",
|
|
20
|
+
"nanoid": "^4.0.0",
|
|
21
21
|
"tslib": "^2.3.1"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"vue": "^3.0.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@milkdown/core": "6.
|
|
30
|
-
"@milkdown/prose": "6.
|
|
29
|
+
"@milkdown/core": "6.2.0",
|
|
30
|
+
"@milkdown/prose": "6.2.0",
|
|
31
31
|
"vue": "^3.0.0"
|
|
32
32
|
},
|
|
33
33
|
"nx": {
|
package/src/Editor.tsx
CHANGED
|
@@ -1,81 +1,23 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { Ctx, Editor, editorViewCtx, rootCtx } from '@milkdown/core';
|
|
3
|
-
import { ViewFactory } from '@milkdown/prose';
|
|
4
2
|
import {
|
|
5
3
|
ComponentInternalInstance,
|
|
6
4
|
DefineComponent,
|
|
7
5
|
defineComponent,
|
|
6
|
+
effect,
|
|
8
7
|
getCurrentInstance,
|
|
9
8
|
h,
|
|
10
|
-
inject,
|
|
11
9
|
InjectionKey,
|
|
12
10
|
markRaw,
|
|
13
11
|
onBeforeMount,
|
|
14
|
-
onMounted,
|
|
15
12
|
onUnmounted,
|
|
16
13
|
provide,
|
|
17
|
-
Ref,
|
|
18
|
-
ref,
|
|
19
14
|
shallowReactive,
|
|
20
15
|
} from 'vue';
|
|
21
16
|
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Symbol();
|
|
27
|
-
|
|
28
|
-
export type RenderVue = (Component: AnyVueComponent, options?: RenderOptions) => (ctx: Ctx) => ViewFactory;
|
|
29
|
-
export type GetEditor = (container: HTMLDivElement, renderVue: RenderVue) => Editor;
|
|
30
|
-
|
|
31
|
-
const useGetEditor = (getEditor: GetEditor) => {
|
|
32
|
-
const divRef = ref<HTMLDivElement | null>(null);
|
|
33
|
-
const renderVue = inject<(Component: DefineComponent, options?: RenderOptions) => (ctx: Ctx) => ViewFactory>(
|
|
34
|
-
rendererKey,
|
|
35
|
-
() => {
|
|
36
|
-
throw new Error();
|
|
37
|
-
},
|
|
38
|
-
);
|
|
39
|
-
const editorRef = markRaw<{ editor?: Editor }>({});
|
|
40
|
-
onMounted(() => {
|
|
41
|
-
if (!divRef.value) return;
|
|
42
|
-
|
|
43
|
-
getEditor(divRef.value, renderVue)
|
|
44
|
-
.create()
|
|
45
|
-
.then((editor) => {
|
|
46
|
-
editorRef.editor = editor;
|
|
47
|
-
return;
|
|
48
|
-
})
|
|
49
|
-
.catch((e) => console.error(e));
|
|
50
|
-
});
|
|
51
|
-
onUnmounted(() => {
|
|
52
|
-
const view = editorRef.editor?.action((ctx) => ctx.get(editorViewCtx));
|
|
53
|
-
const root = editorRef.editor?.action((ctx) => ctx.get(rootCtx)) as HTMLElement;
|
|
54
|
-
|
|
55
|
-
root?.firstChild?.remove();
|
|
56
|
-
view?.destroy();
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
return { divRef, editorRef };
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export const EditorComponent = defineComponent<{ editor: GetEditor; editorRef?: Ref<EditorRef> }>({
|
|
63
|
-
name: 'milkdown-dom-root',
|
|
64
|
-
setup: (props, { slots }) => {
|
|
65
|
-
const refs = useGetEditor(props.editor);
|
|
66
|
-
if (props.editorRef) {
|
|
67
|
-
props.editorRef.value = {
|
|
68
|
-
get: () => refs.editorRef.editor,
|
|
69
|
-
dom: () => refs.divRef.value,
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return () => <div ref={refs.divRef}>{slots['default']?.()}</div>;
|
|
74
|
-
},
|
|
75
|
-
});
|
|
76
|
-
EditorComponent['props'] = ['editor', 'editorRef'];
|
|
77
|
-
|
|
78
|
-
export type EditorRef = { get: () => Editor | undefined; dom: () => HTMLDivElement | null };
|
|
17
|
+
import { EditorComponent, EditorRef } from './EditorComponent';
|
|
18
|
+
import { EditorInfo, EditorInfoCtx } from './types';
|
|
19
|
+
import { rendererKey } from './useGetEditor';
|
|
20
|
+
import { createVueView } from './VueNodeView';
|
|
79
21
|
|
|
80
22
|
const rootInstance: {
|
|
81
23
|
instance: null | ComponentInternalInstance;
|
|
@@ -86,8 +28,35 @@ export const getRootInstance = () => {
|
|
|
86
28
|
return rootInstance.instance;
|
|
87
29
|
};
|
|
88
30
|
|
|
31
|
+
export const editorInfoCtxKey: InjectionKey<EditorInfoCtx> = Symbol();
|
|
32
|
+
|
|
33
|
+
const refDeprecatedInfo = `
|
|
34
|
+
@milkdown/vue:
|
|
35
|
+
Passing ref to VueEditor will soon be deprecated, please use:
|
|
36
|
+
|
|
37
|
+
const { editor, getInstance, getDom, loading } = useEditor(/* creator */);
|
|
38
|
+
|
|
39
|
+
effect(() => {
|
|
40
|
+
if (!loading) {
|
|
41
|
+
const editor = getInstance();
|
|
42
|
+
const rootDOM = getDom();
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
<VueEditor editor={editor} />
|
|
47
|
+
`;
|
|
48
|
+
|
|
49
|
+
const compositionDeprecatedInfo = `
|
|
50
|
+
@milkdown/vue:
|
|
51
|
+
Passing editor directly to VueEditor will soon be deprecated, please use:
|
|
52
|
+
|
|
53
|
+
const { editor } = useEditor(/* creator */);
|
|
54
|
+
|
|
55
|
+
<VueEditor editor={editor} />
|
|
56
|
+
`;
|
|
57
|
+
|
|
89
58
|
type PortalPair = [key: string, component: DefineComponent];
|
|
90
|
-
export const VueEditor = defineComponent<{ editor:
|
|
59
|
+
export const VueEditor = defineComponent<{ editor: EditorInfo; editorRef?: EditorRef }>({
|
|
91
60
|
name: 'milkdown-vue-root',
|
|
92
61
|
setup: (props) => {
|
|
93
62
|
const portals = shallowReactive<PortalPair[]>([]);
|
|
@@ -111,12 +80,35 @@ export const VueEditor = defineComponent<{ editor: GetEditor; editorRef?: Ref<Ed
|
|
|
111
80
|
portals.splice(index, 1);
|
|
112
81
|
});
|
|
113
82
|
const renderVue = createVueView(addPortal, removePortalByKey);
|
|
83
|
+
|
|
114
84
|
provide(rendererKey, renderVue);
|
|
115
85
|
|
|
86
|
+
const usingDeprecatedCompositionAPI = Object.hasOwnProperty.call(props.editor, 'getInstance');
|
|
87
|
+
|
|
88
|
+
const { getEditorCallback, dom, editor, loading } = usingDeprecatedCompositionAPI
|
|
89
|
+
? // @ts-expect-error deprecated old composition API
|
|
90
|
+
(props.editor.editor as EditorInfo)
|
|
91
|
+
: props.editor;
|
|
92
|
+
|
|
93
|
+
effect(() => {
|
|
94
|
+
if (usingDeprecatedCompositionAPI) {
|
|
95
|
+
console.warn(compositionDeprecatedInfo);
|
|
96
|
+
}
|
|
97
|
+
if (props.editorRef) {
|
|
98
|
+
console.warn(refDeprecatedInfo);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
provide(editorInfoCtxKey, {
|
|
103
|
+
dom,
|
|
104
|
+
editor,
|
|
105
|
+
loading,
|
|
106
|
+
});
|
|
107
|
+
|
|
116
108
|
return () => {
|
|
117
109
|
const portalElements = portals.map(([id, P]) => <P key={id} />);
|
|
118
110
|
return (
|
|
119
|
-
<EditorComponent editorRef={props.editorRef} editor={
|
|
111
|
+
<EditorComponent editorRef={props.editorRef} editor={getEditorCallback.value}>
|
|
120
112
|
{portalElements}
|
|
121
113
|
</EditorComponent>
|
|
122
114
|
);
|
|
@@ -124,7 +116,3 @@ export const VueEditor = defineComponent<{ editor: GetEditor; editorRef?: Ref<Ed
|
|
|
124
116
|
},
|
|
125
117
|
});
|
|
126
118
|
VueEditor['props'] = ['editor', 'editorRef'];
|
|
127
|
-
|
|
128
|
-
export const useEditor = (getEditor: GetEditor) => {
|
|
129
|
-
return (...args: Parameters<GetEditor>) => getEditor(...args);
|
|
130
|
-
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
+
import { Editor } from '@milkdown/core';
|
|
3
|
+
import { defineComponent, h, inject } from 'vue';
|
|
4
|
+
|
|
5
|
+
import { editorInfoCtxKey } from './Editor';
|
|
6
|
+
import { EditorInfoCtx, GetEditor } from './types';
|
|
7
|
+
import { useGetEditor } from './useGetEditor';
|
|
8
|
+
|
|
9
|
+
export const EditorComponent = defineComponent<{ editor: GetEditor; editorRef?: EditorRef }>({
|
|
10
|
+
name: 'milkdown-dom-root',
|
|
11
|
+
setup: (props, { slots }) => {
|
|
12
|
+
useGetEditor(props.editor);
|
|
13
|
+
const ctx = inject(editorInfoCtxKey, {} as EditorInfoCtx);
|
|
14
|
+
|
|
15
|
+
if (props.editorRef) {
|
|
16
|
+
props.editorRef.get = () => ctx.editor.value;
|
|
17
|
+
props.editorRef.dom = () => ctx.dom.value;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return () => <div ref={ctx.dom}>{slots['default']?.()}</div>;
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
EditorComponent['props'] = ['editor', 'editorRef'];
|
|
24
|
+
|
|
25
|
+
export type EditorRef = { get: () => Editor | undefined; dom: () => HTMLDivElement | null };
|
package/src/VueNode.tsx
CHANGED
|
@@ -2,18 +2,21 @@
|
|
|
2
2
|
import { Ctx } from '@milkdown/core';
|
|
3
3
|
import { Mark, Node } from '@milkdown/prose/model';
|
|
4
4
|
import { Decoration, EditorView } from '@milkdown/prose/view';
|
|
5
|
-
import { defineComponent, h, InjectionKey, provide } from 'vue';
|
|
5
|
+
import { defineComponent, h, inject, InjectionKey, provide } from 'vue';
|
|
6
6
|
|
|
7
|
-
export type NodeContext = {
|
|
7
|
+
export type NodeContext<T extends Node | Mark = Node | Mark> = {
|
|
8
8
|
ctx: Ctx;
|
|
9
|
-
node:
|
|
9
|
+
node: T;
|
|
10
10
|
view: EditorView;
|
|
11
|
-
getPos: boolean | (() => number);
|
|
12
|
-
decorations: Decoration[];
|
|
11
|
+
getPos: T extends Mark ? boolean : T extends Node ? () => number : boolean | (() => number);
|
|
12
|
+
decorations: readonly Decoration[];
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
export const nodeMetadata: InjectionKey<NodeContext> = Symbol();
|
|
16
16
|
|
|
17
|
+
export type UseNodeCtx = <T extends Node | Mark = Node | Mark>() => NodeContext<T>;
|
|
18
|
+
export const useNodeCtx: UseNodeCtx = () => inject(nodeMetadata) as NodeContext<never>;
|
|
19
|
+
|
|
17
20
|
export const VueNodeContainer = defineComponent<NodeContext & { as: string }>({
|
|
18
21
|
name: 'milkdown-node-container',
|
|
19
22
|
setup: ({ node, view, getPos, decorations, ctx, as }, context) => {
|
package/src/VueNodeView.tsx
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
2
|
import { Ctx } from '@milkdown/core';
|
|
3
|
-
import type { ViewFactory } from '@milkdown/prose';
|
|
4
3
|
import { Mark, Node } from '@milkdown/prose/model';
|
|
5
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
Decoration,
|
|
6
|
+
DecorationSource,
|
|
7
|
+
EditorView,
|
|
8
|
+
MarkViewConstructor,
|
|
9
|
+
NodeView,
|
|
10
|
+
NodeViewConstructor,
|
|
11
|
+
} from '@milkdown/prose/view';
|
|
6
12
|
import { customAlphabet } from 'nanoid';
|
|
7
13
|
import { DefineComponent, defineComponent, h, markRaw, Teleport } from 'vue';
|
|
8
14
|
|
|
@@ -14,12 +20,16 @@ const nanoid = customAlphabet('abcedfghicklmn', 10);
|
|
|
14
20
|
export type RenderOptions = Partial<
|
|
15
21
|
{
|
|
16
22
|
as: string;
|
|
17
|
-
|
|
23
|
+
update?: (node: Node, decorations: readonly Decoration[], innerDecorations: DecorationSource) => boolean;
|
|
24
|
+
} & Pick<NodeView, 'ignoreMutation' | 'deselectNode' | 'selectNode' | 'destroy'>
|
|
18
25
|
>;
|
|
19
26
|
|
|
20
27
|
export const createVueView =
|
|
21
28
|
(addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) =>
|
|
22
|
-
(
|
|
29
|
+
(
|
|
30
|
+
component: DefineComponent,
|
|
31
|
+
options: RenderOptions = {},
|
|
32
|
+
): ((ctx: Ctx) => NodeViewConstructor | MarkViewConstructor) =>
|
|
23
33
|
(ctx) =>
|
|
24
34
|
(node, view, getPos, decorations) =>
|
|
25
35
|
new VueNodeView(ctx, component, addPortal, removePortalByKey, options, node, view, getPos, decorations);
|
|
@@ -41,7 +51,7 @@ export class VueNodeView implements NodeView {
|
|
|
41
51
|
private node: Node | Mark,
|
|
42
52
|
private view: EditorView,
|
|
43
53
|
private getPos: boolean | (() => number),
|
|
44
|
-
private decorations: Decoration[],
|
|
54
|
+
private decorations: readonly Decoration[],
|
|
45
55
|
) {
|
|
46
56
|
this.key = nanoid();
|
|
47
57
|
const elementName = options.as ? options.as : this.isInlineOrMark ? 'span' : 'div';
|
|
@@ -50,15 +60,15 @@ export class VueNodeView implements NodeView {
|
|
|
50
60
|
}
|
|
51
61
|
|
|
52
62
|
get dom() {
|
|
53
|
-
return this.teleportDOM.firstElementChild || this.teleportDOM;
|
|
63
|
+
return (this.teleportDOM.firstElementChild || this.teleportDOM) as HTMLElement;
|
|
54
64
|
}
|
|
55
65
|
|
|
56
66
|
get contentDOM() {
|
|
57
67
|
if (this.node instanceof Node && this.node.isLeaf) {
|
|
58
|
-
return
|
|
68
|
+
return undefined;
|
|
59
69
|
}
|
|
60
70
|
|
|
61
|
-
return this.teleportDOM.querySelector('[data-view-content]') || this.dom;
|
|
71
|
+
return this.teleportDOM.querySelector<HTMLElement>('[data-view-content]') || this.dom;
|
|
62
72
|
}
|
|
63
73
|
|
|
64
74
|
renderPortal() {
|
|
@@ -96,10 +106,11 @@ export class VueNodeView implements NodeView {
|
|
|
96
106
|
|
|
97
107
|
destroy() {
|
|
98
108
|
this.options.destroy?.();
|
|
109
|
+
this.teleportDOM.remove();
|
|
99
110
|
this.removePortalByKey(this.key);
|
|
100
111
|
}
|
|
101
112
|
|
|
102
|
-
ignoreMutation(mutation: MutationRecord
|
|
113
|
+
ignoreMutation(mutation: MutationRecord) {
|
|
103
114
|
if (this.options.ignoreMutation) {
|
|
104
115
|
return this.options.ignoreMutation(mutation);
|
|
105
116
|
}
|
|
@@ -113,7 +124,7 @@ export class VueNodeView implements NodeView {
|
|
|
113
124
|
}
|
|
114
125
|
}
|
|
115
126
|
|
|
116
|
-
if (mutation.type === 'selection') {
|
|
127
|
+
if ((mutation as unknown as { type: string }).type === 'selection') {
|
|
117
128
|
return false;
|
|
118
129
|
}
|
|
119
130
|
|
|
@@ -128,7 +139,7 @@ export class VueNodeView implements NodeView {
|
|
|
128
139
|
return true;
|
|
129
140
|
}
|
|
130
141
|
|
|
131
|
-
update(node: Node, decorations: Decoration[], innerDecorations:
|
|
142
|
+
update(node: Node, decorations: readonly Decoration[], innerDecorations: DecorationSource) {
|
|
132
143
|
if (this.options.update) {
|
|
133
144
|
const result = this.options.update?.(node, decorations, innerDecorations);
|
|
134
145
|
if (result != null) {
|
package/src/index.ts
CHANGED
package/src/types.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
+
import { Ctx, Editor } from '@milkdown/core';
|
|
3
|
+
import type { Mark, Node } from '@milkdown/prose/model';
|
|
4
|
+
import { Decoration, DecorationSource, MarkViewConstructor, NodeView, NodeViewConstructor } from '@milkdown/prose/view';
|
|
5
|
+
import { Ref } from 'vue';
|
|
6
|
+
|
|
7
|
+
import { AnyVueComponent } from './utils';
|
|
8
|
+
|
|
9
|
+
export type RenderOptions = Partial<
|
|
10
|
+
{
|
|
11
|
+
as: string;
|
|
12
|
+
update?: (node: Node, decorations: readonly Decoration[], innerDecorations: DecorationSource) => boolean;
|
|
13
|
+
} & Pick<NodeView, 'ignoreMutation' | 'deselectNode' | 'selectNode' | 'destroy'>
|
|
14
|
+
>;
|
|
15
|
+
|
|
16
|
+
export type RenderVue<U = never> = <T extends Node | Mark = Node | Mark>(
|
|
17
|
+
Component: AnyVueComponent,
|
|
18
|
+
options?: RenderOptions,
|
|
19
|
+
) => (
|
|
20
|
+
ctx: Ctx,
|
|
21
|
+
) => U extends never
|
|
22
|
+
? T extends Node
|
|
23
|
+
? NodeViewConstructor
|
|
24
|
+
: T extends Mark
|
|
25
|
+
? MarkViewConstructor
|
|
26
|
+
: NodeViewConstructor & MarkViewConstructor
|
|
27
|
+
: U extends Node
|
|
28
|
+
? NodeViewConstructor
|
|
29
|
+
: U extends Mark
|
|
30
|
+
? MarkViewConstructor
|
|
31
|
+
: NodeViewConstructor & MarkViewConstructor;
|
|
32
|
+
|
|
33
|
+
export type GetEditor = (container: HTMLDivElement, renderVue: RenderVue) => Editor;
|
|
34
|
+
|
|
35
|
+
export type EditorInfoCtx = {
|
|
36
|
+
dom: Ref<HTMLDivElement | null>;
|
|
37
|
+
editor: Ref<Editor | undefined>;
|
|
38
|
+
loading: Ref<boolean>;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type EditorInfo = {
|
|
42
|
+
getEditorCallback: Ref<GetEditor>;
|
|
43
|
+
} & EditorInfoCtx;
|
|
44
|
+
|
|
45
|
+
export type UseEditorReturn = {
|
|
46
|
+
loading: Ref<boolean>;
|
|
47
|
+
getInstance: () => Editor | undefined;
|
|
48
|
+
getDom: () => HTMLDivElement | null;
|
|
49
|
+
editor: EditorInfo;
|
|
50
|
+
};
|
package/src/useEditor.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
+
|
|
3
|
+
import { Editor } from '@milkdown/core';
|
|
4
|
+
import { ref } from 'vue';
|
|
5
|
+
|
|
6
|
+
import { GetEditor, UseEditorReturn } from './types';
|
|
7
|
+
|
|
8
|
+
export const useEditor = (getEditor: GetEditor): UseEditorReturn => {
|
|
9
|
+
const dom = ref<HTMLDivElement | null>(null);
|
|
10
|
+
const editor = ref<Editor>();
|
|
11
|
+
const loading = ref(true);
|
|
12
|
+
const getEditorCallback = ref<GetEditor>((...args) => getEditor(...args));
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
loading,
|
|
16
|
+
getInstance: () => editor.value,
|
|
17
|
+
getDom: () => dom.value,
|
|
18
|
+
editor: {
|
|
19
|
+
getEditorCallback,
|
|
20
|
+
dom,
|
|
21
|
+
editor,
|
|
22
|
+
loading,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
+
import { Ctx, editorViewCtx, rootCtx } from '@milkdown/core';
|
|
3
|
+
import { MarkViewConstructor, NodeViewConstructor } from '@milkdown/prose/view';
|
|
4
|
+
import { DefineComponent, inject, InjectionKey, onMounted, onUnmounted, ref } from 'vue';
|
|
5
|
+
|
|
6
|
+
import { editorInfoCtxKey } from '.';
|
|
7
|
+
import { EditorInfoCtx, GetEditor, RenderOptions, RenderVue } from './types';
|
|
8
|
+
|
|
9
|
+
export const rendererKey: InjectionKey<
|
|
10
|
+
(component: DefineComponent, options?: RenderOptions) => (ctx: Ctx) => NodeViewConstructor | MarkViewConstructor
|
|
11
|
+
> = Symbol();
|
|
12
|
+
|
|
13
|
+
export const useGetEditor = (getEditor: GetEditor) => {
|
|
14
|
+
const renderVue = inject<RenderVue>(rendererKey, () => {
|
|
15
|
+
throw new Error();
|
|
16
|
+
});
|
|
17
|
+
const { dom, loading, editor: editorRef } = inject(editorInfoCtxKey, {} as EditorInfoCtx);
|
|
18
|
+
const lock = ref(false);
|
|
19
|
+
|
|
20
|
+
onMounted(() => {
|
|
21
|
+
if (!dom.value) return;
|
|
22
|
+
|
|
23
|
+
const editor = getEditor(dom.value, renderVue);
|
|
24
|
+
if (!editor) return;
|
|
25
|
+
|
|
26
|
+
if (lock.value) return;
|
|
27
|
+
|
|
28
|
+
loading.value = true;
|
|
29
|
+
lock.value = true;
|
|
30
|
+
|
|
31
|
+
editor
|
|
32
|
+
.create()
|
|
33
|
+
.then((editor) => {
|
|
34
|
+
editorRef.value = editor;
|
|
35
|
+
return;
|
|
36
|
+
})
|
|
37
|
+
.finally(() => {
|
|
38
|
+
loading.value = false;
|
|
39
|
+
lock.value = false;
|
|
40
|
+
})
|
|
41
|
+
.catch((e) => console.error(e));
|
|
42
|
+
});
|
|
43
|
+
onUnmounted(() => {
|
|
44
|
+
const view = editorRef.value?.action((ctx) => ctx.get(editorViewCtx));
|
|
45
|
+
const root = editorRef.value?.action((ctx) => ctx.get(rootCtx)) as HTMLElement;
|
|
46
|
+
|
|
47
|
+
root?.firstChild?.remove();
|
|
48
|
+
view?.destroy();
|
|
49
|
+
});
|
|
50
|
+
};
|