@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 CHANGED
@@ -1,28 +1,13 @@
1
- import { Ctx, Editor } from '@milkdown/core';
2
- import { ViewFactory } from '@milkdown/prose';
3
- import { ComponentInternalInstance, DefineComponent, Ref } from 'vue';
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: GetEditor;
22
- editorRef?: Ref<EditorRef> | undefined;
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: GetEditor;
25
- editorRef?: Ref<EditorRef> | undefined;
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
@@ -1 +1 @@
1
- {"version":3,"file":"Editor.d.ts","sourceRoot":"","sources":["../src/Editor.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,EAA0B,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EACH,yBAAyB,EACzB,eAAe,EAWf,GAAG,EAGN,MAAM,KAAK,CAAC;AAEb,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAiB,aAAa,EAAE,MAAM,eAAe,CAAC;AAK7D,oBAAY,SAAS,GAAG,CAAC,SAAS,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,aAAa,KAAK,CAAC,GAAG,EAAE,GAAG,KAAK,WAAW,CAAC;AAC3G,oBAAY,SAAS,GAAG,CAAC,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,KAAK,MAAM,CAAC;AAiCpF,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,gEAE7C,CAAC"}
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: Node | Mark;
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 const VueNodeContainer: import("vue").DefineComponent<NodeContext & {
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<{
@@ -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,EAAsB,YAAY,EAAW,MAAM,KAAK,CAAC;AAEhE,oBAAY,WAAW,GAAG;IACtB,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IACjC,WAAW,EAAE,UAAU,EAAE,CAAC;CAC7B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,YAAY,CAAC,WAAW,CAAY,CAAC;AAEhE,eAAO,MAAM,gBAAgB;QAAuC,MAAM;;QAAN,MAAM;OAYxE,CAAC;AAGH,eAAO,MAAM,OAAO;;;;OAKlB,CAAC"}
1
+ {"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"}
@@ -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, DecorationSet, EditorView, NodeView } from '@milkdown/prose/view';
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
- } & Pick<NodeView, 'ignoreMutation' | 'deselectNode' | 'selectNode' | 'destroy' | 'update'>>;
9
- export declare const createVueView: (addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) => (component: DefineComponent, options?: RenderOptions) => (ctx: Ctx) => ViewFactory;
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(): Element;
25
- get contentDOM(): Element | null;
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
- type: 'selection';
30
- target: Element;
31
- }): boolean;
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
@@ -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,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE5F,OAAO,EAAE,eAAe,EAAyC,MAAM,KAAK,CAAC;AAO7E,oBAAY,aAAa,GAAG,OAAO,CAC/B;IACI,EAAE,EAAE,MAAM,CAAC;CACd,GAAG,IAAI,CAAC,QAAQ,EAAE,gBAAgB,GAAG,cAAc,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC,CAC9F,CAAC;AAEF,eAAO,MAAM,aAAa,uBACD,eAAe,OAAO,MAAM,KAAK,IAAI,2BAA2B,MAAM,KAAK,IAAI,iBACxF,eAAe,YAAW,aAAa,WAAe,GAAG,KAAK,WAGiC,CAAC;AAEhH,qBAAa,WAAY,YAAW,QAAQ;IASpC,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IAhBvB,WAAW,EAAE,WAAW,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IAEZ,IAAI,cAAc,YAEjB;gBAGW,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,eAAe,EAC1B,SAAS,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,EACzD,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,EACxC,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,IAAI,GAAG,IAAI,EACjB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,EAChC,WAAW,EAAE,UAAU,EAAE;IAQrC,IAAI,GAAG,YAEN;IAED,IAAI,UAAU,mBAMb;IAED,YAAY;IAiCZ,OAAO;IAKP,cAAc,CAAC,QAAQ,EAAE,cAAc,GAAG;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE;IA6BhF,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,gBAAgB,EAAE,aAAa;IAoB7E,UAAU,kCAA4B;IAEtC,YAAY,kCAA8B;CAC7C"}
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
@@ -1,3 +1,5 @@
1
1
  export * from './Editor';
2
- export { nodeMetadata } from './VueNode';
2
+ export * from './types';
3
+ export * from './useEditor';
4
+ export * from './VueNode';
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
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, createVNode, Teleport, markRaw, shallowReactive, getCurrentInstance, onBeforeMount, onUnmounted, isVNode, ref, inject, onMounted } from "vue";
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 null;
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": props.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
- return (...args) => getEditor(...args);
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 { EditorComponent, VueEditor, getRootInstance, nodeMetadata, useEditor };
325
+ export { Content, VueEditor, VueNodeContainer, editorInfoCtxKey, getRootInstance, nodeMetadata, useEditor, useNodeCtx };
261
326
  //# sourceMappingURL=index.es.js.map
@@ -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,3 @@
1
+ import { GetEditor, UseEditorReturn } from './types';
2
+ export declare const useEditor: (getEditor: GetEditor) => UseEditorReturn;
3
+ //# sourceMappingURL=useEditor.d.ts.map
@@ -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.1.5",
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.1.5",
20
- "nanoid": "^3.1.25",
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.1.5",
30
- "@milkdown/prose": "6.1.5",
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 { AnyVueComponent } from './utils';
23
- import { createVueView, RenderOptions } from './VueNodeView';
24
-
25
- const rendererKey: InjectionKey<(component: DefineComponent, options?: RenderOptions) => (ctx: Ctx) => ViewFactory> =
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: GetEditor; editorRef?: Ref<EditorRef> }>({
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={props.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: Node | Mark;
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) => {
@@ -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 { Decoration, DecorationSet, EditorView, NodeView } from '@milkdown/prose/view';
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
- } & Pick<NodeView, 'ignoreMutation' | 'deselectNode' | 'selectNode' | 'destroy' | 'update'>
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
- (component: DefineComponent, options: RenderOptions = {}): ((ctx: Ctx) => ViewFactory) =>
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 null;
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 | { type: 'selection'; target: Element }) {
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: DecorationSet) {
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
@@ -1,3 +1,5 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
2
  export * from './Editor';
3
- export { nodeMetadata } from './VueNode';
3
+ export * from './types';
4
+ export * from './useEditor';
5
+ export * from './VueNode';
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
+ };
@@ -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
+ };