@milkdown/vue 5.1.1 → 5.3.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,11 +1,12 @@
1
- import { Editor } from '@milkdown/core';
1
+ import { Ctx, Editor } from '@milkdown/core';
2
2
  import { ViewFactory } from '@milkdown/prose';
3
- import { DefineComponent, Ref } from 'vue';
4
- declare type GetEditor = (container: HTMLDivElement, renderVue: (Component: DefineComponent) => ViewFactory) => Editor;
3
+ import { ComponentInternalInstance, DefineComponent, Ref } from 'vue';
4
+ import { AnyVueComponent } from './utils';
5
+ declare type GetEditor = (container: HTMLDivElement, renderVue: (Component: AnyVueComponent) => (ctx: Ctx) => ViewFactory) => Editor;
5
6
  export declare const EditorComponent: DefineComponent<{
6
7
  editor: GetEditor;
7
8
  editorRef?: Ref<EditorRef> | undefined;
8
- }, () => JSX.Element, {}, import("vue").ComputedOptions, import("vue").MethodOptions, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
9
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
9
10
  editor: GetEditor;
10
11
  editorRef?: Ref<EditorRef> | undefined;
11
12
  }>, {}>;
@@ -13,13 +14,14 @@ export declare type EditorRef = {
13
14
  get: () => Editor | undefined;
14
15
  dom: () => HTMLDivElement | null;
15
16
  };
17
+ export declare const getRootInstance: () => ComponentInternalInstance | null;
16
18
  export declare const VueEditor: DefineComponent<{
17
19
  editor: GetEditor;
18
20
  editorRef?: Ref<EditorRef> | undefined;
19
- }, () => JSX.Element, {}, import("vue").ComputedOptions, import("vue").MethodOptions, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
21
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
20
22
  editor: GetEditor;
21
23
  editorRef?: Ref<EditorRef> | undefined;
22
24
  }>, {}>;
23
- export declare const useEditor: (getEditor: GetEditor) => (container: HTMLDivElement, renderVue: (Component: DefineComponent) => ViewFactory) => Editor;
25
+ export declare const useEditor: (getEditor: GetEditor) => (container: HTMLDivElement, renderVue: (Component: AnyVueComponent) => (ctx: Ctx) => ViewFactory) => Editor;
24
26
  export {};
25
27
  //# sourceMappingURL=Editor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Editor.d.ts","sourceRoot":"","sources":["../src/Editor.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAiB,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EACH,eAAe,EAUf,GAAG,EAGN,MAAM,KAAK,CAAC;AAOb,aAAK,SAAS,GAAG,CAAC,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,WAAW,KAAK,MAAM,CAAC;AA8B/G,eAAO,MAAM,eAAe;YAAqC,SAAS;;;YAAT,SAAS;;OAUxE,CAAC;AAGH,oBAAY,SAAS,GAAG;IAAE,GAAG,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,cAAc,GAAG,IAAI,CAAA;CAAE,CAAC;AAE5F,eAAO,MAAM,SAAS;YAAqC,SAAS;;;YAAT,SAAS;;OAkBlE,CAAC;AAGH,eAAO,MAAM,SAAS,cAAe,SAAS,wDAlEsB,eAAe,KAAK,WAAW,WAoElG,CAAC"}
1
+ {"version":3,"file":"Editor.d.ts","sourceRoot":"","sources":["../src/Editor.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,EAA0B,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EACH,yBAAyB,EACzB,eAAe,EAWf,GAAG,EAGN,MAAM,KAAK,CAAC;AAEb,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAK1C,aAAK,SAAS,GAAG,CACb,SAAS,EAAE,cAAc,EACzB,SAAS,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,CAAC,GAAG,EAAE,GAAG,KAAK,WAAW,KACnE,MAAM,CAAC;AA8BZ,eAAO,MAAM,eAAe;YAA6B,SAAS;;;YAAT,SAAS;;OAahE,CAAC;AAGH,oBAAY,SAAS,GAAG;IAAE,GAAG,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,cAAc,GAAG,IAAI,CAAA;CAAE,CAAC;AAO5F,eAAO,MAAM,eAAe,wCAE3B,CAAC;AAGF,eAAO,MAAM,SAAS;YAA6B,SAAS;;;YAAT,SAAS;;OAmC1D,CAAC;AAGH,eAAO,MAAM,SAAS,cAAe,SAAS,wDAjGnB,eAAe,WAAW,GAAG,KAAK,WAAW,WAmGvE,CAAC"}
package/lib/VueNode.d.ts CHANGED
@@ -1,27 +1,19 @@
1
1
  /// <reference types="prosemirror-model" />
2
+ import { Ctx } from '@milkdown/core';
2
3
  import { Decoration, EditorView, Mark, Node } from '@milkdown/prose';
3
4
  import { InjectionKey } from 'vue';
4
5
  export declare type NodeContext = {
6
+ ctx: Ctx;
5
7
  node: Node | Mark;
6
8
  view: EditorView;
7
9
  getPos: boolean | (() => number);
8
10
  decorations: Decoration[];
9
11
  };
10
12
  export declare const nodeMetadata: InjectionKey<NodeContext>;
11
- export declare const VueNodeContainer: import("vue").DefineComponent<{
12
- node: Node | Mark;
13
- view: EditorView;
14
- getPos: boolean | (() => number);
15
- decorations: Decoration[];
16
- }, () => JSX.Element, {}, import("vue").ComputedOptions, import("vue").MethodOptions, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
17
- node: Node | Mark;
18
- view: EditorView;
19
- getPos: boolean | (() => number);
20
- decorations: Decoration[];
21
- }>, {}>;
13
+ export declare const VueNodeContainer: import("vue").DefineComponent<NodeContext, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<NodeContext>, {}>;
22
14
  export declare const Content: import("vue").DefineComponent<{
23
- dom?: HTMLElement | undefined;
24
- }, () => JSX.Element, {}, import("vue").ComputedOptions, import("vue").MethodOptions, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
25
- dom?: HTMLElement | undefined;
15
+ isMark?: boolean | undefined;
16
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
17
+ isMark?: boolean | undefined;
26
18
  }>, {}>;
27
19
  //# sourceMappingURL=VueNode.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"VueNode.d.ts","sourceRoot":"","sources":["../src/VueNode.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAgC,YAAY,EAA6B,MAAM,KAAK,CAAC;AAE5F,oBAAY,WAAW,GAAG;IACtB,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;UARnB,IAAI,GAAG,IAAI;UACX,UAAU;YACR,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC;iBACnB,UAAU,EAAE;;UAHnB,IAAI,GAAG,IAAI;UACX,UAAU;YACR,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC;iBACnB,UAAU,EAAE;OAa3B,CAAC;AAGH,eAAO,MAAM,OAAO;;;;OAOlB,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,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAsB,YAAY,EAAW,MAAM,KAAK,CAAC;AAEhE,oBAAY,WAAW,GAAG;IACtB,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IACjC,WAAW,EAAE,UAAU,EAAE,CAAC;CAC7B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,YAAY,CAAC,WAAW,CAAY,CAAC;AAEhE,eAAO,MAAM,gBAAgB,0SAY3B,CAAC;AAGH,eAAO,MAAM,OAAO;;;;OAKlB,CAAC"}
@@ -1,9 +1,11 @@
1
1
  /// <reference types="prosemirror-model" />
2
+ import { Ctx } from '@milkdown/core';
2
3
  import type { Decoration, EditorView, NodeView, ViewFactory } from '@milkdown/prose';
3
4
  import { Mark, Node } from '@milkdown/prose';
4
5
  import { DefineComponent } from 'vue';
5
- export declare const createVueView: (addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) => (component: DefineComponent) => ViewFactory;
6
+ export declare const createVueView: (addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) => (component: DefineComponent) => (ctx: Ctx) => ViewFactory;
6
7
  export declare class VueNodeView implements NodeView {
8
+ private ctx;
7
9
  private component;
8
10
  private addPortal;
9
11
  private removePortalByKey;
@@ -11,15 +13,17 @@ export declare class VueNodeView implements NodeView {
11
13
  private view;
12
14
  private getPos;
13
15
  private decorations;
14
- dom: HTMLElement | undefined;
15
- contentDOM: HTMLElement | undefined;
16
+ teleportDOM: HTMLElement;
16
17
  key: string;
17
- constructor(component: DefineComponent, addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void, node: Node | Mark, view: EditorView, getPos: boolean | (() => number), decorations: Decoration[]);
18
+ constructor(ctx: Ctx, component: DefineComponent, addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void, node: Node | Mark, view: EditorView, getPos: boolean | (() => number), decorations: Decoration[]);
19
+ get dom(): Element;
20
+ get contentDOM(): Element | null;
18
21
  renderPortal(): void;
19
22
  destroy(): void;
20
23
  ignoreMutation(mutation: MutationRecord | {
21
24
  type: 'selection';
22
25
  target: Element;
23
26
  }): boolean;
27
+ update(node: Node | Mark, decorations: Decoration[]): boolean;
24
28
  }
25
29
  //# sourceMappingURL=VueNodeView.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"VueNodeView.d.ts","sourceRoot":"","sources":["../src/VueNodeView.tsx"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,eAAe,EAAgC,MAAM,KAAK,CAAC;AAMpE,eAAO,MAAM,aAAa,uBACD,eAAe,OAAO,MAAM,KAAK,IAAI,2BAA2B,MAAM,KAAK,IAAI,iBACxF,eAAe,KAAG,WAE+D,CAAC;AAElG,qBAAa,WAAY,YAAW,QAAQ;IAMpC,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IAXvB,GAAG,EAAE,WAAW,GAAG,SAAS,CAAC;IAC7B,UAAU,EAAE,WAAW,GAAG,SAAS,CAAC;IACpC,GAAG,EAAE,MAAM,CAAC;gBAGA,SAAS,EAAE,eAAe,EAC1B,SAAS,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,EACzD,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,EACxC,IAAI,EAAE,IAAI,GAAG,IAAI,EACjB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,EAChC,WAAW,EAAE,UAAU,EAAE;IAmBrC,YAAY;IAwBZ,OAAO;IAMP,cAAc,CAAC,QAAQ,EAAE,cAAc,GAAG;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE;CAMnF"}
1
+ {"version":3,"file":"VueNodeView.d.ts","sourceRoot":"","sources":["../src/VueNodeView.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,eAAe,EAAyC,MAAM,KAAK,CAAC;AAO7E,eAAO,MAAM,aAAa,uBACD,eAAe,OAAO,MAAM,KAAK,IAAI,2BAA2B,MAAM,KAAK,IAAI,iBACxF,eAAe,WAAU,GAAG,KAAK,WAGqD,CAAC;AAEvG,qBAAa,WAAY,YAAW,QAAQ;IAKpC,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IAXvB,WAAW,EAAE,WAAW,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;gBAGA,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,eAAe,EAC1B,SAAS,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,EACzD,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,EACxC,IAAI,EAAE,IAAI,GAAG,IAAI,EACjB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,EAChC,WAAW,EAAE,UAAU,EAAE;IAOrC,IAAI,GAAG,YAEN;IAED,IAAI,UAAU,mBAMb;IAED,YAAY;IA+BZ,OAAO;IAIP,cAAc,CAAC,QAAQ,EAAE,cAAc,GAAG;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE;IA0BhF,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE;CAatD"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});exports[Symbol.toStringTag]="Module";var e=require("vue"),m=require("@milkdown/core"),u=require("@milkdown/prose"),V=require("nanoid");const p=Symbol(),v=e.defineComponent({name:"milkdown-node-container",setup:({node:o,view:t,getPos:n,decorations:r,ctx:s},a)=>(e.provide(p,{ctx:s,node:o,view:t,getPos:n,decorations:r}),()=>{var i,d;return e.createVNode("div",{"data-view-container":!0},[(d=(i=a.slots).default)==null?void 0:d.call(i)])})});v.props=["ctx","editor","node","view","getPos","decorations"];const w=e.defineComponent({name:"milkdown-content",setup:({isMark:o})=>()=>o?e.createVNode("span",{"data-view-content":!0},null):e.createVNode("div",{"data-view-content":!0},null)});w.props=["isMark"];const g=V.customAlphabet("abcedfghicklmn",10),R=(o,t)=>n=>r=>(s,a,i,d)=>new C(r,n,o,t,s,a,i,d);class C{constructor(t,n,r,s,a,i,d,c){this.ctx=t,this.component=n,this.addPortal=r,this.removePortalByKey=s,this.node=a,this.view=i,this.getPos=d,this.decorations=c,this.key=g(),this.teleportDOM=document.createElement(a instanceof u.Mark?"span":"div"),this.renderPortal()}get dom(){return this.teleportDOM.firstElementChild||this.teleportDOM}get contentDOM(){return this.node instanceof u.Node&&this.node.isLeaf?null:this.teleportDOM.querySelector("[data-view-content]")||this.dom}renderPortal(){if(!this.teleportDOM)return;const t=this.component,n=e.defineComponent({name:"milkdown-portal",setup:()=>()=>e.createVNode(e.Teleport,{key:this.key,to:this.teleportDOM},{default:()=>[e.createVNode(v,{ctx:this.ctx,node:this.node,view:this.view,getPos:this.getPos,decorations:this.decorations},{default:()=>[e.createVNode(t,null,{default:()=>[e.createVNode(w,{isMark:this.node instanceof u.Mark},null)]})]})]})});this.addPortal(e.markRaw(n),this.key);const r=k();r&&r.update()}destroy(){this.removePortalByKey(this.key)}ignoreMutation(t){return!this.dom||!this.contentDOM||this.node instanceof u.Node&&(this.node.isLeaf||this.node.isAtom)?!0:!(t.type==="selection"||this.contentDOM===this.dom||this.contentDOM.contains(t.target))}update(t,n){return this.node.type!==t.type?!1:(t===this.node&&this.decorations===n||(this.node=t,this.decorations=n),!0)}}function N(o){return typeof o=="function"||Object.prototype.toString.call(o)==="[object Object]"&&!e.isVNode(o)}const y=Symbol(),P=o=>{const t=e.ref(null),n=e.inject(y,()=>{throw new Error}),r=e.markRaw({});return e.onMounted(()=>{!t.value||o(t.value,n).create().then(s=>{r.editor=s}).catch(s=>console.error(s))}),e.onUnmounted(()=>{var i,d,c;const s=(i=r.editor)==null?void 0:i.action(l=>l.get(m.editorViewCtx)),a=(d=r.editor)==null?void 0:d.action(l=>l.get(m.rootCtx));(c=a==null?void 0:a.firstChild)==null||c.remove(),s==null||s.destroy()}),{divRef:t,editorRef:r}},f=e.defineComponent({name:"milkdown-dom-root",setup:(o,{slots:t})=>{const n=P(o.editor);return o.editorRef&&(o.editorRef.value={get:()=>n.editorRef.editor,dom:()=>n.divRef.value}),()=>{var r;return e.createVNode("div",{ref:n.divRef},[(r=t.default)==null?void 0:r.call(t)])}}});f.props=["editor","editorRef"];const h={instance:null},k=()=>h.instance,M=e.defineComponent({name:"milkdown-vue-root",setup:o=>{const t=e.shallowReactive([]),n=e.getCurrentInstance();e.onBeforeMount(()=>{h.instance=n.ctx._}),e.onUnmounted(()=>{h.instance=null});const r=e.markRaw((i,d)=>{t.push([d,i])}),s=e.markRaw(i=>{const d=t.findIndex(c=>c[0]===i);t.splice(d,1)}),a=R(r,s);return e.provide(y,a),()=>{const i=t.map(([d,c])=>e.createVNode(c,{key:d},null));return e.createVNode(f,{editorRef:o.editorRef,editor:o.editor},N(i)?i:{default:()=>[i]})}}});M.props=["editor","editorRef"];const O=o=>(...t)=>o(...t);exports.EditorComponent=f;exports.VueEditor=M;exports.getRootInstance=k;exports.nodeMetadata=p;exports.useEditor=O;
2
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/VueNode.tsx","../src/VueNodeView.tsx","../src/Editor.tsx"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx } from '@milkdown/core';\nimport { Decoration, EditorView, Mark, Node } from '@milkdown/prose';\nimport { defineComponent, h, InjectionKey, provide } from 'vue';\n\nexport type NodeContext = {\n ctx: Ctx;\n node: Node | Mark;\n view: EditorView;\n getPos: boolean | (() => number);\n decorations: Decoration[];\n};\n\nexport const nodeMetadata: InjectionKey<NodeContext> = Symbol();\n\nexport const VueNodeContainer = defineComponent<NodeContext>({\n name: 'milkdown-node-container',\n setup: ({ node, view, getPos, decorations, ctx }, context) => {\n provide(nodeMetadata, {\n ctx,\n node,\n view,\n getPos,\n decorations,\n });\n return () => <div data-view-container>{context.slots.default?.()}</div>;\n },\n});\nVueNodeContainer.props = ['ctx', 'editor', 'node', 'view', 'getPos', 'decorations'];\n\nexport const Content = defineComponent<{ isMark?: boolean }>({\n name: 'milkdown-content',\n setup: ({ isMark }) => {\n return () => (isMark ? <span data-view-content /> : <div data-view-content />);\n },\n});\nContent.props = ['isMark'];\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx } from '@milkdown/core';\nimport type { Decoration, EditorView, NodeView, ViewFactory } from '@milkdown/prose';\nimport { Mark, Node } from '@milkdown/prose';\nimport { customAlphabet } from 'nanoid';\nimport { DefineComponent, defineComponent, h, markRaw, Teleport } from 'vue';\n\nimport { getRootInstance } from '.';\nimport { Content, VueNodeContainer } from './VueNode';\n\nconst nanoid = customAlphabet('abcedfghicklmn', 10);\n\nexport const createVueView =\n (addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) =>\n (component: DefineComponent): ((ctx: Ctx) => ViewFactory) =>\n (ctx) =>\n (node, view, getPos, decorations) =>\n new VueNodeView(ctx, component, addPortal, removePortalByKey, node, view, getPos, decorations);\n\nexport class VueNodeView implements NodeView {\n teleportDOM: HTMLElement;\n key: string;\n\n constructor(\n private ctx: Ctx,\n private component: DefineComponent,\n private addPortal: (portal: DefineComponent, key: string) => void,\n private removePortalByKey: (key: string) => void,\n private node: Node | Mark,\n private view: EditorView,\n private getPos: boolean | (() => number),\n private decorations: Decoration[],\n ) {\n this.key = nanoid();\n this.teleportDOM = document.createElement(node instanceof Mark ? 'span' : 'div');\n this.renderPortal();\n }\n\n get dom() {\n return this.teleportDOM.firstElementChild || this.teleportDOM;\n }\n\n get contentDOM() {\n if (this.node instanceof Node && this.node.isLeaf) {\n return null;\n }\n\n return this.teleportDOM.querySelector('[data-view-content]') || this.dom;\n }\n\n renderPortal() {\n if (!this.teleportDOM) return;\n\n const CustomComponent = this.component;\n const Portal = defineComponent({\n name: 'milkdown-portal',\n setup: () => {\n return () => (\n <Teleport key={this.key} to={this.teleportDOM}>\n <VueNodeContainer\n ctx={this.ctx}\n node={this.node}\n view={this.view}\n getPos={this.getPos}\n decorations={this.decorations}\n >\n <CustomComponent>\n <Content isMark={this.node instanceof Mark} />\n </CustomComponent>\n </VueNodeContainer>\n </Teleport>\n );\n },\n });\n this.addPortal(markRaw(Portal) as DefineComponent, this.key);\n const instance = getRootInstance();\n if (instance) {\n instance.update();\n }\n }\n\n destroy() {\n this.removePortalByKey(this.key);\n }\n\n ignoreMutation(mutation: MutationRecord | { type: 'selection'; target: Element }) {\n if (!this.dom || !this.contentDOM) {\n return true;\n }\n\n if (this.node instanceof Node) {\n if (this.node.isLeaf || this.node.isAtom) {\n return true;\n }\n }\n\n if (mutation.type === 'selection') {\n return false;\n }\n\n if (this.contentDOM === this.dom) {\n return false;\n }\n\n if (this.contentDOM.contains(mutation.target)) {\n return false;\n }\n\n return true;\n }\n\n update(node: Node | Mark, decorations: Decoration[]) {\n if (this.node.type !== node.type) {\n return false;\n }\n\n if (node === this.node && this.decorations === decorations) {\n return true;\n }\n\n this.node = node;\n this.decorations = decorations;\n return true;\n }\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx, Editor, editorViewCtx, rootCtx } from '@milkdown/core';\nimport { ViewFactory } from '@milkdown/prose';\nimport {\n ComponentInternalInstance,\n DefineComponent,\n defineComponent,\n getCurrentInstance,\n h,\n inject,\n InjectionKey,\n markRaw,\n onBeforeMount,\n onMounted,\n onUnmounted,\n provide,\n Ref,\n ref,\n shallowReactive,\n} from 'vue';\n\nimport { AnyVueComponent } from './utils';\nimport { createVueView } from './VueNodeView';\n\nconst rendererKey: InjectionKey<(component: DefineComponent) => (ctx: Ctx) => ViewFactory> = Symbol();\n\ntype GetEditor = (\n container: HTMLDivElement,\n renderVue: (Component: AnyVueComponent) => (ctx: Ctx) => ViewFactory,\n) => Editor;\n\nconst useGetEditor = (getEditor: GetEditor) => {\n const divRef = ref<HTMLDivElement | null>(null);\n const renderVue = inject<(Component: DefineComponent) => (ctx: Ctx) => ViewFactory>(rendererKey, () => {\n throw new Error();\n });\n const editorRef = markRaw<{ editor?: Editor }>({});\n onMounted(() => {\n if (!divRef.value) return;\n\n getEditor(divRef.value, renderVue)\n .create()\n .then((editor) => {\n editorRef.editor = editor;\n return;\n })\n .catch((e) => console.error(e));\n });\n onUnmounted(() => {\n const view = editorRef.editor?.action((ctx) => ctx.get(editorViewCtx));\n const root = editorRef.editor?.action((ctx) => ctx.get(rootCtx)) as HTMLElement;\n\n root?.firstChild?.remove();\n view?.destroy();\n });\n\n return { divRef, editorRef };\n};\n\nexport const EditorComponent = defineComponent<{ editor: GetEditor; editorRef?: Ref<EditorRef> }>({\n name: 'milkdown-dom-root',\n setup: (props, { slots }) => {\n const refs = useGetEditor(props.editor);\n if (props.editorRef) {\n props.editorRef.value = {\n get: () => refs.editorRef.editor,\n dom: () => refs.divRef.value,\n };\n }\n\n return () => <div ref={refs.divRef}>{slots.default?.()}</div>;\n },\n});\nEditorComponent.props = ['editor', 'editorRef'];\n\nexport type EditorRef = { get: () => Editor | undefined; dom: () => HTMLDivElement | null };\n\nconst rootInstance: {\n instance: null | ComponentInternalInstance;\n} = {\n instance: null,\n};\nexport const getRootInstance = () => {\n return rootInstance.instance;\n};\n\ntype PortalPair = [key: string, component: DefineComponent];\nexport const VueEditor = defineComponent<{ editor: GetEditor; editorRef?: Ref<EditorRef> }>({\n name: 'milkdown-vue-root',\n setup: (props) => {\n const portals = shallowReactive<PortalPair[]>([]);\n\n const instance = getCurrentInstance();\n\n onBeforeMount(() => {\n rootInstance.instance = (instance as ComponentInternalInstance & { ctx: { _: ComponentInternalInstance } })\n .ctx._ as ComponentInternalInstance;\n });\n\n onUnmounted(() => {\n rootInstance.instance = null;\n });\n\n const addPortal = markRaw((component: DefineComponent, key: string) => {\n portals.push([key, component]);\n });\n const removePortalByKey = markRaw((key: string) => {\n const index = portals.findIndex((p) => p[0] === key);\n portals.splice(index, 1);\n });\n const renderVue = createVueView(addPortal, removePortalByKey);\n provide(rendererKey, renderVue);\n\n return () => {\n const portalElements = portals.map(([id, P]) => <P key={id} />);\n return (\n <EditorComponent editorRef={props.editorRef} editor={props.editor}>\n {portalElements}\n </EditorComponent>\n );\n };\n },\n});\nVueEditor.props = ['editor', 'editorRef'];\n\nexport const useEditor = (getEditor: GetEditor) => {\n return (...args: Parameters<GetEditor>) => getEditor(...args);\n};\n"],"names":["nodeMetadata","Symbol","VueNodeContainer","defineComponent","name","setup","node","view","getPos","decorations","ctx","context","provide","slots","default","props","Content","isMark","nanoid","customAlphabet","createVueView","addPortal","removePortalByKey","component","VueNodeView","constructor","key","teleportDOM","document","createElement","Mark","renderPortal","dom","firstElementChild","contentDOM","Node","isLeaf","querySelector","CustomComponent","Portal","markRaw","instance","getRootInstance","update","destroy","ignoreMutation","mutation","isAtom","type","contains","target","rendererKey","useGetEditor","getEditor","divRef","ref","renderVue","inject","Error","editorRef","onMounted","value","create","then","editor","catch","e","console","error","onUnmounted","action","get","editorViewCtx","root","rootCtx","firstChild","remove","EditorComponent","refs","rootInstance","VueEditor","portals","shallowReactive","getCurrentInstance","onBeforeMount","_","push","index","findIndex","p","splice","portalElements","map","id","P","useEditor","args"],"mappings":"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"}
@@ -0,0 +1,232 @@
1
+ import { defineComponent, provide, createVNode, Teleport, markRaw, shallowReactive, getCurrentInstance, onBeforeMount, onUnmounted, isVNode, ref, inject, onMounted } from "vue";
2
+ import { editorViewCtx, rootCtx } from "@milkdown/core";
3
+ import { Mark, Node } from "@milkdown/prose";
4
+ import { customAlphabet } from "nanoid";
5
+ const nodeMetadata = Symbol();
6
+ const VueNodeContainer = defineComponent({
7
+ name: "milkdown-node-container",
8
+ setup: ({
9
+ node,
10
+ view,
11
+ getPos,
12
+ decorations,
13
+ ctx
14
+ }, context) => {
15
+ provide(nodeMetadata, {
16
+ ctx,
17
+ node,
18
+ view,
19
+ getPos,
20
+ decorations
21
+ });
22
+ return () => {
23
+ var _a, _b;
24
+ return createVNode("div", {
25
+ "data-view-container": true
26
+ }, [(_b = (_a = context.slots).default) == null ? void 0 : _b.call(_a)]);
27
+ };
28
+ }
29
+ });
30
+ VueNodeContainer.props = ["ctx", "editor", "node", "view", "getPos", "decorations"];
31
+ const Content = defineComponent({
32
+ name: "milkdown-content",
33
+ setup: ({
34
+ isMark
35
+ }) => {
36
+ return () => isMark ? createVNode("span", {
37
+ "data-view-content": true
38
+ }, null) : createVNode("div", {
39
+ "data-view-content": true
40
+ }, null);
41
+ }
42
+ });
43
+ Content.props = ["isMark"];
44
+ const nanoid = customAlphabet("abcedfghicklmn", 10);
45
+ const createVueView = (addPortal, removePortalByKey) => (component) => (ctx) => (node, view, getPos, decorations) => new VueNodeView(ctx, component, addPortal, removePortalByKey, node, view, getPos, decorations);
46
+ class VueNodeView {
47
+ constructor(ctx, component, addPortal, removePortalByKey, node, view, getPos, decorations) {
48
+ this.ctx = ctx;
49
+ this.component = component;
50
+ this.addPortal = addPortal;
51
+ this.removePortalByKey = removePortalByKey;
52
+ this.node = node;
53
+ this.view = view;
54
+ this.getPos = getPos;
55
+ this.decorations = decorations;
56
+ this.key = nanoid();
57
+ this.teleportDOM = document.createElement(node instanceof Mark ? "span" : "div");
58
+ this.renderPortal();
59
+ }
60
+ get dom() {
61
+ return this.teleportDOM.firstElementChild || this.teleportDOM;
62
+ }
63
+ get contentDOM() {
64
+ if (this.node instanceof Node && this.node.isLeaf) {
65
+ return null;
66
+ }
67
+ return this.teleportDOM.querySelector("[data-view-content]") || this.dom;
68
+ }
69
+ renderPortal() {
70
+ if (!this.teleportDOM)
71
+ return;
72
+ const CustomComponent = this.component;
73
+ const Portal = defineComponent({
74
+ name: "milkdown-portal",
75
+ setup: () => {
76
+ return () => createVNode(Teleport, {
77
+ "key": this.key,
78
+ "to": this.teleportDOM
79
+ }, {
80
+ default: () => [createVNode(VueNodeContainer, {
81
+ "ctx": this.ctx,
82
+ "node": this.node,
83
+ "view": this.view,
84
+ "getPos": this.getPos,
85
+ "decorations": this.decorations
86
+ }, {
87
+ default: () => [createVNode(CustomComponent, null, {
88
+ default: () => [createVNode(Content, {
89
+ "isMark": this.node instanceof Mark
90
+ }, null)]
91
+ })]
92
+ })]
93
+ });
94
+ }
95
+ });
96
+ this.addPortal(markRaw(Portal), this.key);
97
+ const instance = getRootInstance();
98
+ if (instance) {
99
+ instance.update();
100
+ }
101
+ }
102
+ destroy() {
103
+ this.removePortalByKey(this.key);
104
+ }
105
+ ignoreMutation(mutation) {
106
+ if (!this.dom || !this.contentDOM) {
107
+ return true;
108
+ }
109
+ if (this.node instanceof Node) {
110
+ if (this.node.isLeaf || this.node.isAtom) {
111
+ return true;
112
+ }
113
+ }
114
+ if (mutation.type === "selection") {
115
+ return false;
116
+ }
117
+ if (this.contentDOM === this.dom) {
118
+ return false;
119
+ }
120
+ if (this.contentDOM.contains(mutation.target)) {
121
+ return false;
122
+ }
123
+ return true;
124
+ }
125
+ update(node, decorations) {
126
+ if (this.node.type !== node.type) {
127
+ return false;
128
+ }
129
+ if (node === this.node && this.decorations === decorations) {
130
+ return true;
131
+ }
132
+ this.node = node;
133
+ this.decorations = decorations;
134
+ return true;
135
+ }
136
+ }
137
+ function _isSlot(s) {
138
+ return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
139
+ }
140
+ const rendererKey = Symbol();
141
+ const useGetEditor = (getEditor) => {
142
+ const divRef = ref(null);
143
+ const renderVue = inject(rendererKey, () => {
144
+ throw new Error();
145
+ });
146
+ const editorRef = markRaw({});
147
+ onMounted(() => {
148
+ if (!divRef.value)
149
+ return;
150
+ getEditor(divRef.value, renderVue).create().then((editor) => {
151
+ editorRef.editor = editor;
152
+ return;
153
+ }).catch((e) => console.error(e));
154
+ });
155
+ onUnmounted(() => {
156
+ var _a, _b, _c;
157
+ const view = (_a = editorRef.editor) == null ? void 0 : _a.action((ctx) => ctx.get(editorViewCtx));
158
+ const root = (_b = editorRef.editor) == null ? void 0 : _b.action((ctx) => ctx.get(rootCtx));
159
+ (_c = root == null ? void 0 : root.firstChild) == null ? void 0 : _c.remove();
160
+ view == null ? void 0 : view.destroy();
161
+ });
162
+ return {
163
+ divRef,
164
+ editorRef
165
+ };
166
+ };
167
+ const EditorComponent = defineComponent({
168
+ name: "milkdown-dom-root",
169
+ setup: (props, {
170
+ slots
171
+ }) => {
172
+ const refs = useGetEditor(props.editor);
173
+ if (props.editorRef) {
174
+ props.editorRef.value = {
175
+ get: () => refs.editorRef.editor,
176
+ dom: () => refs.divRef.value
177
+ };
178
+ }
179
+ return () => {
180
+ var _a;
181
+ return createVNode("div", {
182
+ "ref": refs.divRef
183
+ }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]);
184
+ };
185
+ }
186
+ });
187
+ EditorComponent.props = ["editor", "editorRef"];
188
+ const rootInstance = {
189
+ instance: null
190
+ };
191
+ const getRootInstance = () => {
192
+ return rootInstance.instance;
193
+ };
194
+ const VueEditor = defineComponent({
195
+ name: "milkdown-vue-root",
196
+ setup: (props) => {
197
+ const portals = shallowReactive([]);
198
+ const instance = getCurrentInstance();
199
+ onBeforeMount(() => {
200
+ rootInstance.instance = instance.ctx._;
201
+ });
202
+ onUnmounted(() => {
203
+ rootInstance.instance = null;
204
+ });
205
+ const addPortal = markRaw((component, key) => {
206
+ portals.push([key, component]);
207
+ });
208
+ const removePortalByKey = markRaw((key) => {
209
+ const index = portals.findIndex((p) => p[0] === key);
210
+ portals.splice(index, 1);
211
+ });
212
+ const renderVue = createVueView(addPortal, removePortalByKey);
213
+ provide(rendererKey, renderVue);
214
+ return () => {
215
+ const portalElements = portals.map(([id, P]) => createVNode(P, {
216
+ "key": id
217
+ }, null));
218
+ return createVNode(EditorComponent, {
219
+ "editorRef": props.editorRef,
220
+ "editor": props.editor
221
+ }, _isSlot(portalElements) ? portalElements : {
222
+ default: () => [portalElements]
223
+ });
224
+ };
225
+ }
226
+ });
227
+ VueEditor.props = ["editor", "editorRef"];
228
+ const useEditor = (getEditor) => {
229
+ return (...args) => getEditor(...args);
230
+ };
231
+ export { EditorComponent, VueEditor, getRootInstance, nodeMetadata, useEditor };
232
+ //# sourceMappingURL=index.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.es.js","sources":["../src/VueNode.tsx","../src/VueNodeView.tsx","../src/Editor.tsx"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx } from '@milkdown/core';\nimport { Decoration, EditorView, Mark, Node } from '@milkdown/prose';\nimport { defineComponent, h, InjectionKey, provide } from 'vue';\n\nexport type NodeContext = {\n ctx: Ctx;\n node: Node | Mark;\n view: EditorView;\n getPos: boolean | (() => number);\n decorations: Decoration[];\n};\n\nexport const nodeMetadata: InjectionKey<NodeContext> = Symbol();\n\nexport const VueNodeContainer = defineComponent<NodeContext>({\n name: 'milkdown-node-container',\n setup: ({ node, view, getPos, decorations, ctx }, context) => {\n provide(nodeMetadata, {\n ctx,\n node,\n view,\n getPos,\n decorations,\n });\n return () => <div data-view-container>{context.slots.default?.()}</div>;\n },\n});\nVueNodeContainer.props = ['ctx', 'editor', 'node', 'view', 'getPos', 'decorations'];\n\nexport const Content = defineComponent<{ isMark?: boolean }>({\n name: 'milkdown-content',\n setup: ({ isMark }) => {\n return () => (isMark ? <span data-view-content /> : <div data-view-content />);\n },\n});\nContent.props = ['isMark'];\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx } from '@milkdown/core';\nimport type { Decoration, EditorView, NodeView, ViewFactory } from '@milkdown/prose';\nimport { Mark, Node } from '@milkdown/prose';\nimport { customAlphabet } from 'nanoid';\nimport { DefineComponent, defineComponent, h, markRaw, Teleport } from 'vue';\n\nimport { getRootInstance } from '.';\nimport { Content, VueNodeContainer } from './VueNode';\n\nconst nanoid = customAlphabet('abcedfghicklmn', 10);\n\nexport const createVueView =\n (addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) =>\n (component: DefineComponent): ((ctx: Ctx) => ViewFactory) =>\n (ctx) =>\n (node, view, getPos, decorations) =>\n new VueNodeView(ctx, component, addPortal, removePortalByKey, node, view, getPos, decorations);\n\nexport class VueNodeView implements NodeView {\n teleportDOM: HTMLElement;\n key: string;\n\n constructor(\n private ctx: Ctx,\n private component: DefineComponent,\n private addPortal: (portal: DefineComponent, key: string) => void,\n private removePortalByKey: (key: string) => void,\n private node: Node | Mark,\n private view: EditorView,\n private getPos: boolean | (() => number),\n private decorations: Decoration[],\n ) {\n this.key = nanoid();\n this.teleportDOM = document.createElement(node instanceof Mark ? 'span' : 'div');\n this.renderPortal();\n }\n\n get dom() {\n return this.teleportDOM.firstElementChild || this.teleportDOM;\n }\n\n get contentDOM() {\n if (this.node instanceof Node && this.node.isLeaf) {\n return null;\n }\n\n return this.teleportDOM.querySelector('[data-view-content]') || this.dom;\n }\n\n renderPortal() {\n if (!this.teleportDOM) return;\n\n const CustomComponent = this.component;\n const Portal = defineComponent({\n name: 'milkdown-portal',\n setup: () => {\n return () => (\n <Teleport key={this.key} to={this.teleportDOM}>\n <VueNodeContainer\n ctx={this.ctx}\n node={this.node}\n view={this.view}\n getPos={this.getPos}\n decorations={this.decorations}\n >\n <CustomComponent>\n <Content isMark={this.node instanceof Mark} />\n </CustomComponent>\n </VueNodeContainer>\n </Teleport>\n );\n },\n });\n this.addPortal(markRaw(Portal) as DefineComponent, this.key);\n const instance = getRootInstance();\n if (instance) {\n instance.update();\n }\n }\n\n destroy() {\n this.removePortalByKey(this.key);\n }\n\n ignoreMutation(mutation: MutationRecord | { type: 'selection'; target: Element }) {\n if (!this.dom || !this.contentDOM) {\n return true;\n }\n\n if (this.node instanceof Node) {\n if (this.node.isLeaf || this.node.isAtom) {\n return true;\n }\n }\n\n if (mutation.type === 'selection') {\n return false;\n }\n\n if (this.contentDOM === this.dom) {\n return false;\n }\n\n if (this.contentDOM.contains(mutation.target)) {\n return false;\n }\n\n return true;\n }\n\n update(node: Node | Mark, decorations: Decoration[]) {\n if (this.node.type !== node.type) {\n return false;\n }\n\n if (node === this.node && this.decorations === decorations) {\n return true;\n }\n\n this.node = node;\n this.decorations = decorations;\n return true;\n }\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx, Editor, editorViewCtx, rootCtx } from '@milkdown/core';\nimport { ViewFactory } from '@milkdown/prose';\nimport {\n ComponentInternalInstance,\n DefineComponent,\n defineComponent,\n getCurrentInstance,\n h,\n inject,\n InjectionKey,\n markRaw,\n onBeforeMount,\n onMounted,\n onUnmounted,\n provide,\n Ref,\n ref,\n shallowReactive,\n} from 'vue';\n\nimport { AnyVueComponent } from './utils';\nimport { createVueView } from './VueNodeView';\n\nconst rendererKey: InjectionKey<(component: DefineComponent) => (ctx: Ctx) => ViewFactory> = Symbol();\n\ntype GetEditor = (\n container: HTMLDivElement,\n renderVue: (Component: AnyVueComponent) => (ctx: Ctx) => ViewFactory,\n) => Editor;\n\nconst useGetEditor = (getEditor: GetEditor) => {\n const divRef = ref<HTMLDivElement | null>(null);\n const renderVue = inject<(Component: DefineComponent) => (ctx: Ctx) => ViewFactory>(rendererKey, () => {\n throw new Error();\n });\n const editorRef = markRaw<{ editor?: Editor }>({});\n onMounted(() => {\n if (!divRef.value) return;\n\n getEditor(divRef.value, renderVue)\n .create()\n .then((editor) => {\n editorRef.editor = editor;\n return;\n })\n .catch((e) => console.error(e));\n });\n onUnmounted(() => {\n const view = editorRef.editor?.action((ctx) => ctx.get(editorViewCtx));\n const root = editorRef.editor?.action((ctx) => ctx.get(rootCtx)) as HTMLElement;\n\n root?.firstChild?.remove();\n view?.destroy();\n });\n\n return { divRef, editorRef };\n};\n\nexport const EditorComponent = defineComponent<{ editor: GetEditor; editorRef?: Ref<EditorRef> }>({\n name: 'milkdown-dom-root',\n setup: (props, { slots }) => {\n const refs = useGetEditor(props.editor);\n if (props.editorRef) {\n props.editorRef.value = {\n get: () => refs.editorRef.editor,\n dom: () => refs.divRef.value,\n };\n }\n\n return () => <div ref={refs.divRef}>{slots.default?.()}</div>;\n },\n});\nEditorComponent.props = ['editor', 'editorRef'];\n\nexport type EditorRef = { get: () => Editor | undefined; dom: () => HTMLDivElement | null };\n\nconst rootInstance: {\n instance: null | ComponentInternalInstance;\n} = {\n instance: null,\n};\nexport const getRootInstance = () => {\n return rootInstance.instance;\n};\n\ntype PortalPair = [key: string, component: DefineComponent];\nexport const VueEditor = defineComponent<{ editor: GetEditor; editorRef?: Ref<EditorRef> }>({\n name: 'milkdown-vue-root',\n setup: (props) => {\n const portals = shallowReactive<PortalPair[]>([]);\n\n const instance = getCurrentInstance();\n\n onBeforeMount(() => {\n rootInstance.instance = (instance as ComponentInternalInstance & { ctx: { _: ComponentInternalInstance } })\n .ctx._ as ComponentInternalInstance;\n });\n\n onUnmounted(() => {\n rootInstance.instance = null;\n });\n\n const addPortal = markRaw((component: DefineComponent, key: string) => {\n portals.push([key, component]);\n });\n const removePortalByKey = markRaw((key: string) => {\n const index = portals.findIndex((p) => p[0] === key);\n portals.splice(index, 1);\n });\n const renderVue = createVueView(addPortal, removePortalByKey);\n provide(rendererKey, renderVue);\n\n return () => {\n const portalElements = portals.map(([id, P]) => <P key={id} />);\n return (\n <EditorComponent editorRef={props.editorRef} editor={props.editor}>\n {portalElements}\n </EditorComponent>\n );\n };\n },\n});\nVueEditor.props = ['editor', 'editorRef'];\n\nexport const useEditor = (getEditor: GetEditor) => {\n return (...args: Parameters<GetEditor>) => getEditor(...args);\n};\n"],"names":["nodeMetadata","Symbol","VueNodeContainer","defineComponent","name","setup","node","view","getPos","decorations","ctx","context","provide","slots","default","props","Content","isMark","nanoid","customAlphabet","createVueView","addPortal","removePortalByKey","component","VueNodeView","constructor","key","teleportDOM","document","createElement","Mark","renderPortal","dom","firstElementChild","contentDOM","Node","isLeaf","querySelector","CustomComponent","Portal","markRaw","instance","getRootInstance","update","destroy","ignoreMutation","mutation","isAtom","type","contains","target","rendererKey","useGetEditor","getEditor","divRef","ref","renderVue","inject","Error","editorRef","onMounted","value","create","then","editor","catch","e","console","error","onUnmounted","action","get","editorViewCtx","root","rootCtx","firstChild","remove","EditorComponent","refs","rootInstance","VueEditor","portals","shallowReactive","getCurrentInstance","onBeforeMount","_","push","index","findIndex","p","splice","portalElements","map","id","P","useEditor","args"],"mappings":"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"}
package/lib/utils.d.ts CHANGED
@@ -1,7 +1,9 @@
1
+ import { DefineComponent } from 'vue';
1
2
  declare type Prepend<T, U extends unknown[]> = [T, ...U];
2
3
  declare type Keys_<T extends Record<string, unknown>, U extends PropertyKey[]> = {
3
4
  [P in keyof T]: Record<string, unknown> extends Omit<T, P> ? [P] : Prepend<P, Keys_<Omit<T, P>, U>>;
4
5
  }[keyof T];
5
6
  export declare type Keys<T extends Record<string, unknown>> = Keys_<T, []>;
7
+ export declare type AnyVueComponent = DefineComponent<any, any, any, any, any, any, any, any, any, any, any, any>;
6
8
  export {};
7
9
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,aAAK,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;AACjD,aAAK,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,WAAW,EAAE,IAAI;KACpE,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CACtG,CAAC,MAAM,CAAC,CAAC,CAAC;AACX,oBAAY,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,KAAK,CAAC;AAEtC,aAAK,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;AACjD,aAAK,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,WAAW,EAAE,IAAI;KACpE,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CACtG,CAAC,MAAM,CAAC,CAAC,CAAC;AACX,oBAAY,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAGnE,oBAAY,eAAe,GAAG,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,9 +1,15 @@
1
1
  {
2
2
  "name": "@milkdown/vue",
3
- "version": "5.1.1",
4
- "main": "lib/index.js",
5
- "module": "lib/index.js",
6
- "types": "lib/index.d.ts",
3
+ "version": "5.3.0",
4
+ "main": "./lib/index.cjs.js",
5
+ "module": "./lib/index.es.js",
6
+ "types": "./lib/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./lib/index.es.js",
10
+ "require": "./lib/index.cjs.js"
11
+ }
12
+ },
7
13
  "sideEffects": false,
8
14
  "license": "MIT",
9
15
  "files": [
@@ -16,7 +22,7 @@
16
22
  "vue"
17
23
  ],
18
24
  "dependencies": {
19
- "@milkdown/utils": "5.1.1",
25
+ "@milkdown/utils": "5.3.0",
20
26
  "nanoid": "^3.1.25",
21
27
  "tslib": "^2.3.1"
22
28
  },
@@ -25,13 +31,19 @@
25
31
  "vue": "^3.0.0"
26
32
  },
27
33
  "devDependencies": {
34
+ "@milkdown/core": "5.3.0",
35
+ "@milkdown/prose": "5.3.0",
36
+ "@milkdown/preset-commonmark": "5.3.0",
37
+ "@milkdown/plugin-slash": "5.3.0",
38
+ "@milkdown/theme-nord": "5.3.0",
28
39
  "vue": "^3.0.0"
29
40
  },
30
41
  "scripts": {
31
42
  "start": "vite",
32
- "watch": "tsc -w",
43
+ "watch": "vite build --watch",
33
44
  "test": "jest",
34
45
  "tsc": "tsc --noEmit",
35
- "build": "tsc"
36
- }
46
+ "build": "vite build && tsc --emitDeclarationOnly"
47
+ },
48
+ "readme": "# @milkdown/vue\n\nVue integration for [milkdown](https://saul-mirone.github.io/milkdown/).\n\n# Example Usage\n\n```typescript\nimport { defineComponent } from 'vue';\nimport { Editor, rootCtx } from '@milkdown/core';\nimport { VueEditor, useEditor } from '@milkdown/vue';\nimport { commonmark } from '@milkdown/preset-commonmark';\nimport { nord } from '@milkdown/theme-nord';\n\nexport const MilkdownEditor = defineComponent(() => {\n const editor = useEditor((root) =>\n Editor.make()\n .config((ctx) => {\n ctx.set(rootCtx, root);\n })\n .use(nord)\n .use(commonmark),\n );\n\n return () => <VueEditor editor={editor} />;\n});\n```\n\n# License\n\nMilkdown is open sourced software licensed under [MIT license](https://github.com/Saul-Mirone/milkdown/blob/main/LICENSE).\n"
37
49
  }
package/src/Editor.tsx CHANGED
@@ -1,14 +1,16 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import { Editor, editorViewCtx } from '@milkdown/core';
2
+ import { Ctx, Editor, editorViewCtx, rootCtx } from '@milkdown/core';
3
3
  import { ViewFactory } from '@milkdown/prose';
4
4
  import {
5
+ ComponentInternalInstance,
5
6
  DefineComponent,
6
7
  defineComponent,
7
- Fragment,
8
+ getCurrentInstance,
8
9
  h,
9
10
  inject,
10
11
  InjectionKey,
11
12
  markRaw,
13
+ onBeforeMount,
12
14
  onMounted,
13
15
  onUnmounted,
14
16
  provide,
@@ -17,16 +19,19 @@ import {
17
19
  shallowReactive,
18
20
  } from 'vue';
19
21
 
20
- import { PortalPair, Portals } from './Portals';
22
+ import { AnyVueComponent } from './utils';
21
23
  import { createVueView } from './VueNodeView';
22
24
 
23
- const rendererKey: InjectionKey<(component: DefineComponent) => ViewFactory> = Symbol();
25
+ const rendererKey: InjectionKey<(component: DefineComponent) => (ctx: Ctx) => ViewFactory> = Symbol();
24
26
 
25
- type GetEditor = (container: HTMLDivElement, renderVue: (Component: DefineComponent) => ViewFactory) => Editor;
27
+ type GetEditor = (
28
+ container: HTMLDivElement,
29
+ renderVue: (Component: AnyVueComponent) => (ctx: Ctx) => ViewFactory,
30
+ ) => Editor;
26
31
 
27
32
  const useGetEditor = (getEditor: GetEditor) => {
28
33
  const divRef = ref<HTMLDivElement | null>(null);
29
- const renderVue = inject<(Component: DefineComponent) => ViewFactory>(rendererKey, () => {
34
+ const renderVue = inject<(Component: DefineComponent) => (ctx: Ctx) => ViewFactory>(rendererKey, () => {
30
35
  throw new Error();
31
36
  });
32
37
  const editorRef = markRaw<{ editor?: Editor }>({});
@@ -43,48 +48,78 @@ const useGetEditor = (getEditor: GetEditor) => {
43
48
  });
44
49
  onUnmounted(() => {
45
50
  const view = editorRef.editor?.action((ctx) => ctx.get(editorViewCtx));
46
- if (!view) return;
51
+ const root = editorRef.editor?.action((ctx) => ctx.get(rootCtx)) as HTMLElement;
47
52
 
48
- view.dom.parentElement?.remove();
49
- view.destroy();
53
+ root?.firstChild?.remove();
54
+ view?.destroy();
50
55
  });
51
56
 
52
57
  return { divRef, editorRef };
53
58
  };
54
59
 
55
- export const EditorComponent = defineComponent((props: { editor: GetEditor; editorRef?: Ref<EditorRef> }) => {
56
- const refs = useGetEditor(props.editor);
57
- if (props.editorRef) {
58
- props.editorRef.value = {
59
- get: () => refs.editorRef.editor,
60
- dom: () => refs.divRef.value,
61
- };
62
- }
60
+ export const EditorComponent = defineComponent<{ editor: GetEditor; editorRef?: Ref<EditorRef> }>({
61
+ name: 'milkdown-dom-root',
62
+ setup: (props, { slots }) => {
63
+ const refs = useGetEditor(props.editor);
64
+ if (props.editorRef) {
65
+ props.editorRef.value = {
66
+ get: () => refs.editorRef.editor,
67
+ dom: () => refs.divRef.value,
68
+ };
69
+ }
63
70
 
64
- return () => <div ref={refs.divRef} />;
71
+ return () => <div ref={refs.divRef}>{slots.default?.()}</div>;
72
+ },
65
73
  });
66
74
  EditorComponent.props = ['editor', 'editorRef'];
67
75
 
68
76
  export type EditorRef = { get: () => Editor | undefined; dom: () => HTMLDivElement | null };
69
77
 
70
- export const VueEditor = defineComponent((props: { editor: GetEditor; editorRef?: Ref<EditorRef> }) => {
71
- const portals = shallowReactive<PortalPair[]>([]);
72
- const addPortal = markRaw((component: DefineComponent, key: string) => {
73
- portals.push([key, component]);
74
- });
75
- const removePortalByKey = markRaw((key: string) => {
76
- const index = portals.findIndex((p) => p[0] === key);
77
- portals.splice(index, 1);
78
- });
79
- const renderVue = createVueView(addPortal, removePortalByKey);
80
- provide(rendererKey, renderVue);
81
-
82
- return () => (
83
- <>
84
- <Portals portals={portals} />
85
- <EditorComponent editorRef={props.editorRef} editor={props.editor} />
86
- </>
87
- );
78
+ const rootInstance: {
79
+ instance: null | ComponentInternalInstance;
80
+ } = {
81
+ instance: null,
82
+ };
83
+ export const getRootInstance = () => {
84
+ return rootInstance.instance;
85
+ };
86
+
87
+ type PortalPair = [key: string, component: DefineComponent];
88
+ export const VueEditor = defineComponent<{ editor: GetEditor; editorRef?: Ref<EditorRef> }>({
89
+ name: 'milkdown-vue-root',
90
+ setup: (props) => {
91
+ const portals = shallowReactive<PortalPair[]>([]);
92
+
93
+ const instance = getCurrentInstance();
94
+
95
+ onBeforeMount(() => {
96
+ rootInstance.instance = (instance as ComponentInternalInstance & { ctx: { _: ComponentInternalInstance } })
97
+ .ctx._ as ComponentInternalInstance;
98
+ });
99
+
100
+ onUnmounted(() => {
101
+ rootInstance.instance = null;
102
+ });
103
+
104
+ const addPortal = markRaw((component: DefineComponent, key: string) => {
105
+ portals.push([key, component]);
106
+ });
107
+ const removePortalByKey = markRaw((key: string) => {
108
+ const index = portals.findIndex((p) => p[0] === key);
109
+ portals.splice(index, 1);
110
+ });
111
+ const renderVue = createVueView(addPortal, removePortalByKey);
112
+ provide(rendererKey, renderVue);
113
+
114
+ return () => {
115
+ const portalElements = portals.map(([id, P]) => <P key={id} />);
116
+ return (
117
+ <EditorComponent editorRef={props.editorRef} editor={props.editor}>
118
+ {portalElements}
119
+ </EditorComponent>
120
+ );
121
+ };
122
+ },
88
123
  });
89
124
  VueEditor.props = ['editor', 'editorRef'];
90
125
 
package/src/VueNode.tsx CHANGED
@@ -1,8 +1,10 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
+ import { Ctx } from '@milkdown/core';
2
3
  import { Decoration, EditorView, Mark, Node } from '@milkdown/prose';
3
- import { defineComponent, Fragment, h, InjectionKey, provide, ref, watchEffect } from 'vue';
4
+ import { defineComponent, h, InjectionKey, provide } from 'vue';
4
5
 
5
6
  export type NodeContext = {
7
+ ctx: Ctx;
6
8
  node: Node | Mark;
7
9
  view: EditorView;
8
10
  getPos: boolean | (() => number);
@@ -11,23 +13,25 @@ export type NodeContext = {
11
13
 
12
14
  export const nodeMetadata: InjectionKey<NodeContext> = Symbol();
13
15
 
14
- export const VueNodeContainer = defineComponent(({ node, view, getPos, decorations }: NodeContext, context) => {
15
- provide(nodeMetadata, {
16
- node,
17
- view,
18
- getPos,
19
- decorations,
20
- });
21
- return () => <>{context.slots.default?.() ?? []}</>;
16
+ export const VueNodeContainer = defineComponent<NodeContext>({
17
+ name: 'milkdown-node-container',
18
+ setup: ({ node, view, getPos, decorations, ctx }, context) => {
19
+ provide(nodeMetadata, {
20
+ ctx,
21
+ node,
22
+ view,
23
+ getPos,
24
+ decorations,
25
+ });
26
+ return () => <div data-view-container>{context.slots.default?.()}</div>;
27
+ },
22
28
  });
23
- VueNodeContainer.props = ['editor', 'node', 'view', 'getPos', 'decorations'];
29
+ VueNodeContainer.props = ['ctx', 'editor', 'node', 'view', 'getPos', 'decorations'];
24
30
 
25
- export const Content = defineComponent((props: { dom?: HTMLElement }) => {
26
- const containerRef = ref<HTMLDivElement | null>(null);
27
- watchEffect(() => {
28
- if (!props.dom || !containerRef.value) return;
29
- containerRef.value.appendChild(props.dom);
30
- });
31
- return () => <div ref={containerRef} />;
31
+ export const Content = defineComponent<{ isMark?: boolean }>({
32
+ name: 'milkdown-content',
33
+ setup: ({ isMark }) => {
34
+ return () => (isMark ? <span data-view-content /> : <div data-view-content />);
35
+ },
32
36
  });
33
- Content.props = ['dom'];
37
+ Content.props = ['isMark'];
@@ -1,25 +1,28 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
+ import { Ctx } from '@milkdown/core';
2
3
  import type { Decoration, EditorView, NodeView, ViewFactory } from '@milkdown/prose';
3
4
  import { Mark, Node } from '@milkdown/prose';
4
5
  import { customAlphabet } from 'nanoid';
5
- import { DefineComponent, defineComponent, h, Teleport } from 'vue';
6
+ import { DefineComponent, defineComponent, h, markRaw, Teleport } from 'vue';
6
7
 
8
+ import { getRootInstance } from '.';
7
9
  import { Content, VueNodeContainer } from './VueNode';
8
10
 
9
11
  const nanoid = customAlphabet('abcedfghicklmn', 10);
10
12
 
11
13
  export const createVueView =
12
14
  (addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) =>
13
- (component: DefineComponent): ViewFactory =>
15
+ (component: DefineComponent): ((ctx: Ctx) => ViewFactory) =>
16
+ (ctx) =>
14
17
  (node, view, getPos, decorations) =>
15
- new VueNodeView(component, addPortal, removePortalByKey, node, view, getPos, decorations);
18
+ new VueNodeView(ctx, component, addPortal, removePortalByKey, node, view, getPos, decorations);
16
19
 
17
20
  export class VueNodeView implements NodeView {
18
- dom: HTMLElement | undefined;
19
- contentDOM: HTMLElement | undefined;
21
+ teleportDOM: HTMLElement;
20
22
  key: string;
21
23
 
22
24
  constructor(
25
+ private ctx: Ctx,
23
26
  private component: DefineComponent,
24
27
  private addPortal: (portal: DefineComponent, key: string) => void,
25
28
  private removePortalByKey: (key: string) => void,
@@ -29,56 +32,94 @@ export class VueNodeView implements NodeView {
29
32
  private decorations: Decoration[],
30
33
  ) {
31
34
  this.key = nanoid();
32
- const dom = document.createElement(node instanceof Mark ? 'span' : 'div');
33
- dom.classList.add('dom-wrapper');
34
-
35
- const contentDOM =
36
- node instanceof Node && node.isLeaf
37
- ? undefined
38
- : document.createElement(node instanceof Mark ? 'span' : 'div');
39
- if (contentDOM) {
40
- contentDOM.classList.add('content-dom');
41
- dom.appendChild(contentDOM);
42
- }
43
- this.dom = dom;
44
- this.contentDOM = contentDOM;
35
+ this.teleportDOM = document.createElement(node instanceof Mark ? 'span' : 'div');
45
36
  this.renderPortal();
46
37
  }
47
38
 
39
+ get dom() {
40
+ return this.teleportDOM.firstElementChild || this.teleportDOM;
41
+ }
42
+
43
+ get contentDOM() {
44
+ if (this.node instanceof Node && this.node.isLeaf) {
45
+ return null;
46
+ }
47
+
48
+ return this.teleportDOM.querySelector('[data-view-content]') || this.dom;
49
+ }
50
+
48
51
  renderPortal() {
49
- if (!this.dom) return;
52
+ if (!this.teleportDOM) return;
50
53
 
51
54
  const CustomComponent = this.component;
52
- const Portal = defineComponent(() => {
53
- return () => (
54
- <Teleport to={this.dom}>
55
- <VueNodeContainer
56
- key={this.key}
57
- node={this.node}
58
- view={this.view}
59
- getPos={this.getPos}
60
- decorations={this.decorations}
61
- >
62
- <CustomComponent>
63
- <Content dom={this.contentDOM} />
64
- </CustomComponent>
65
- </VueNodeContainer>
66
- </Teleport>
67
- );
55
+ const Portal = defineComponent({
56
+ name: 'milkdown-portal',
57
+ setup: () => {
58
+ return () => (
59
+ <Teleport key={this.key} to={this.teleportDOM}>
60
+ <VueNodeContainer
61
+ ctx={this.ctx}
62
+ node={this.node}
63
+ view={this.view}
64
+ getPos={this.getPos}
65
+ decorations={this.decorations}
66
+ >
67
+ <CustomComponent>
68
+ <Content isMark={this.node instanceof Mark} />
69
+ </CustomComponent>
70
+ </VueNodeContainer>
71
+ </Teleport>
72
+ );
73
+ },
68
74
  });
69
- this.addPortal(Portal, this.key);
75
+ this.addPortal(markRaw(Portal) as DefineComponent, this.key);
76
+ const instance = getRootInstance();
77
+ if (instance) {
78
+ instance.update();
79
+ }
70
80
  }
71
81
 
72
82
  destroy() {
73
- this.dom = undefined;
74
- this.contentDOM = undefined;
75
83
  this.removePortalByKey(this.key);
76
84
  }
77
85
 
78
86
  ignoreMutation(mutation: MutationRecord | { type: 'selection'; target: Element }) {
79
- if (!this.contentDOM) {
87
+ if (!this.dom || !this.contentDOM) {
88
+ return true;
89
+ }
90
+
91
+ if (this.node instanceof Node) {
92
+ if (this.node.isLeaf || this.node.isAtom) {
93
+ return true;
94
+ }
95
+ }
96
+
97
+ if (mutation.type === 'selection') {
98
+ return false;
99
+ }
100
+
101
+ if (this.contentDOM === this.dom) {
102
+ return false;
103
+ }
104
+
105
+ if (this.contentDOM.contains(mutation.target)) {
106
+ return false;
107
+ }
108
+
109
+ return true;
110
+ }
111
+
112
+ update(node: Node | Mark, decorations: Decoration[]) {
113
+ if (this.node.type !== node.type) {
114
+ return false;
115
+ }
116
+
117
+ if (node === this.node && this.decorations === decorations) {
80
118
  return true;
81
119
  }
82
- return !this.contentDOM.contains(mutation.target);
120
+
121
+ this.node = node;
122
+ this.decorations = decorations;
123
+ return true;
83
124
  }
84
125
  }
package/src/utils.ts CHANGED
@@ -1,7 +1,12 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
2
 
3
+ import { DefineComponent } from 'vue';
4
+
3
5
  type Prepend<T, U extends unknown[]> = [T, ...U];
4
6
  type Keys_<T extends Record<string, unknown>, U extends PropertyKey[]> = {
5
7
  [P in keyof T]: Record<string, unknown> extends Omit<T, P> ? [P] : Prepend<P, Keys_<Omit<T, P>, U>>;
6
8
  }[keyof T];
7
9
  export type Keys<T extends Record<string, unknown>> = Keys_<T, []>;
10
+
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
+ export type AnyVueComponent = DefineComponent<any, any, any, any, any, any, any, any, any, any, any, any>;
package/lib/Editor.js DELETED
@@ -1,64 +0,0 @@
1
- /* Copyright 2021, Milkdown by Mirone. */
2
- import { editorViewCtx } from '@milkdown/core';
3
- import { defineComponent, Fragment, h, inject, markRaw, onMounted, onUnmounted, provide, ref, shallowReactive, } from 'vue';
4
- import { Portals } from './Portals';
5
- import { createVueView } from './VueNodeView';
6
- const rendererKey = Symbol();
7
- const useGetEditor = (getEditor) => {
8
- const divRef = ref(null);
9
- const renderVue = inject(rendererKey, () => {
10
- throw new Error();
11
- });
12
- const editorRef = markRaw({});
13
- onMounted(() => {
14
- if (!divRef.value)
15
- return;
16
- getEditor(divRef.value, renderVue)
17
- .create()
18
- .then((editor) => {
19
- editorRef.editor = editor;
20
- return;
21
- })
22
- .catch((e) => console.error(e));
23
- });
24
- onUnmounted(() => {
25
- var _a, _b;
26
- const view = (_a = editorRef.editor) === null || _a === void 0 ? void 0 : _a.action((ctx) => ctx.get(editorViewCtx));
27
- if (!view)
28
- return;
29
- (_b = view.dom.parentElement) === null || _b === void 0 ? void 0 : _b.remove();
30
- view.destroy();
31
- });
32
- return { divRef, editorRef };
33
- };
34
- export const EditorComponent = defineComponent((props) => {
35
- const refs = useGetEditor(props.editor);
36
- if (props.editorRef) {
37
- props.editorRef.value = {
38
- get: () => refs.editorRef.editor,
39
- dom: () => refs.divRef.value,
40
- };
41
- }
42
- return () => h("div", { ref: refs.divRef });
43
- });
44
- EditorComponent.props = ['editor', 'editorRef'];
45
- export const VueEditor = defineComponent((props) => {
46
- const portals = shallowReactive([]);
47
- const addPortal = markRaw((component, key) => {
48
- portals.push([key, component]);
49
- });
50
- const removePortalByKey = markRaw((key) => {
51
- const index = portals.findIndex((p) => p[0] === key);
52
- portals.splice(index, 1);
53
- });
54
- const renderVue = createVueView(addPortal, removePortalByKey);
55
- provide(rendererKey, renderVue);
56
- return () => (h(Fragment, null,
57
- h(Portals, { portals: portals }),
58
- h(EditorComponent, { editorRef: props.editorRef, editor: props.editor })));
59
- });
60
- VueEditor.props = ['editor', 'editorRef'];
61
- export const useEditor = (getEditor) => {
62
- return (...args) => getEditor(...args);
63
- };
64
- //# sourceMappingURL=Editor.js.map
package/lib/Editor.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"Editor.js","sourceRoot":"","sources":["../src/Editor.tsx"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,OAAO,EAAU,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAEH,eAAe,EACf,QAAQ,EACR,CAAC,EACD,MAAM,EAEN,OAAO,EACP,SAAS,EACT,WAAW,EACX,OAAO,EAEP,GAAG,EACH,eAAe,GAClB,MAAM,KAAK,CAAC;AAEb,OAAO,EAAc,OAAO,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,WAAW,GAA8D,MAAM,EAAE,CAAC;AAIxF,MAAM,YAAY,GAAG,CAAC,SAAoB,EAAE,EAAE;IAC1C,MAAM,MAAM,GAAG,GAAG,CAAwB,IAAI,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,MAAM,CAA8C,WAAW,EAAE,GAAG,EAAE;QACpF,MAAM,IAAI,KAAK,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,OAAO,CAAsB,EAAE,CAAC,CAAC;IACnD,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,CAAC,MAAM,CAAC,KAAK;YAAE,OAAO;QAE1B,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC;aAC7B,MAAM,EAAE;aACR,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;YACb,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC;YAC1B,OAAO;QACX,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IACH,WAAW,CAAC,GAAG,EAAE;;QACb,MAAM,IAAI,GAAG,MAAA,SAAS,CAAC,MAAM,0CAAE,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;QACvE,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,MAAA,IAAI,CAAC,GAAG,CAAC,aAAa,0CAAE,MAAM,EAAE,CAAC;QACjC,IAAI,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,eAAe,CAAC,CAAC,KAAwD,EAAE,EAAE;IACxG,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,KAAK,CAAC,SAAS,EAAE;QACjB,KAAK,CAAC,SAAS,CAAC,KAAK,GAAG;YACpB,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM;YAChC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK;SAC/B,CAAC;KACL;IAED,OAAO,GAAG,EAAE,CAAC,WAAK,GAAG,EAAE,IAAI,CAAC,MAAM,GAAI,CAAC;AAC3C,CAAC,CAAC,CAAC;AACH,eAAe,CAAC,KAAK,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AAIhD,MAAM,CAAC,MAAM,SAAS,GAAG,eAAe,CAAC,CAAC,KAAwD,EAAE,EAAE;IAClG,MAAM,OAAO,GAAG,eAAe,CAAe,EAAE,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,SAA0B,EAAE,GAAW,EAAE,EAAE;QAClE,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IACH,MAAM,iBAAiB,GAAG,OAAO,CAAC,CAAC,GAAW,EAAE,EAAE;QAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;QACrD,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,aAAa,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;IAC9D,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAEhC,OAAO,GAAG,EAAE,CAAC,CACT;QACI,EAAC,OAAO,IAAC,OAAO,EAAE,OAAO,GAAI;QAC7B,EAAC,eAAe,IAAC,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,GAAI,CACtE,CACN,CAAC;AACN,CAAC,CAAC,CAAC;AACH,SAAS,CAAC,KAAK,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AAE1C,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,SAAoB,EAAE,EAAE;IAC9C,OAAO,CAAC,GAAG,IAA2B,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;AAClE,CAAC,CAAC"}
package/lib/Portals.d.ts DELETED
@@ -1,8 +0,0 @@
1
- import { DefineComponent } from 'vue';
2
- export declare type PortalPair = [key: string, component: DefineComponent];
3
- export declare const Portals: DefineComponent<{
4
- portals: PortalPair[];
5
- }, () => JSX.Element, {}, import("vue").ComputedOptions, import("vue").MethodOptions, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
6
- portals: PortalPair[];
7
- }>, {}>;
8
- //# sourceMappingURL=Portals.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Portals.d.ts","sourceRoot":"","sources":["../src/Portals.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAkE,MAAM,KAAK,CAAC;AACtG,oBAAY,UAAU,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;AAInE,eAAO,MAAM,OAAO;aAAsC,UAAU,EAAE;;aAAZ,UAAU,EAAE;OAuBpE,CAAC"}
package/lib/Portals.js DELETED
@@ -1,23 +0,0 @@
1
- /* Copyright 2021, Milkdown by Mirone. */
2
- import { defineComponent, Fragment, h, nextTick, ref, shallowRef, watch } from 'vue';
3
- const getId = (pairs) => pairs.map((p) => p[0]).join('\n');
4
- export const Portals = defineComponent((props) => {
5
- const portalComponents = shallowRef([]);
6
- const prev = ref('');
7
- const renderList = shallowRef(() => []);
8
- watch(() => getId(props.portals), (ids) => {
9
- if (ids !== prev.value) {
10
- prev.value = ids;
11
- const next = props.portals.map((p) => p[1]);
12
- portalComponents.value = next;
13
- }
14
- });
15
- nextTick(() => {
16
- renderList.value = () => portalComponents.value.map((P) => h(P, null));
17
- });
18
- return () => {
19
- return h(Fragment, null, renderList.value());
20
- };
21
- });
22
- Portals.props = ['portals'];
23
- //# sourceMappingURL=Portals.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Portals.js","sourceRoot":"","sources":["../src/Portals.tsx"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,OAAO,EAAmB,eAAe,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC;AAGtG,MAAM,KAAK,GAAG,CAAC,KAAmB,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEzE,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAC,CAAC,KAAgC,EAAE,EAAE;IACxE,MAAM,gBAAgB,GAAG,UAAU,CAAyB,EAAE,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,GAAG,CAAS,EAAE,CAAC,CAAC;IAC7B,MAAM,UAAU,GAAG,UAAU,CAAsB,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAE7D,KAAK,CACD,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAC1B,CAAC,GAAG,EAAE,EAAE;QACJ,IAAI,GAAG,KAAK,IAAI,CAAC,KAAK,EAAE;YACpB,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC;YACjB,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5C,gBAAgB,CAAC,KAAK,GAAG,IAAI,CAAC;SACjC;IACL,CAAC,CACJ,CAAC;IAEF,QAAQ,CAAC,GAAG,EAAE;QACV,UAAU,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAC,CAAC,OAAG,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,EAAE;QACR,OAAO,kBAAG,UAAU,CAAC,KAAK,EAAE,CAAI,CAAC;IACrC,CAAC,CAAC;AACN,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,KAAK,GAAG,CAAC,SAAS,CAAC,CAAC"}
package/lib/VueNode.js DELETED
@@ -1,23 +0,0 @@
1
- import { defineComponent, Fragment, h, provide, ref, watchEffect } from 'vue';
2
- export const nodeMetadata = Symbol();
3
- export const VueNodeContainer = defineComponent(({ node, view, getPos, decorations }, context) => {
4
- provide(nodeMetadata, {
5
- node,
6
- view,
7
- getPos,
8
- decorations,
9
- });
10
- return () => { var _a, _b, _c; return h(Fragment, null, (_c = (_b = (_a = context.slots).default) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : []); };
11
- });
12
- VueNodeContainer.props = ['editor', 'node', 'view', 'getPos', 'decorations'];
13
- export const Content = defineComponent((props) => {
14
- const containerRef = ref(null);
15
- watchEffect(() => {
16
- if (!props.dom || !containerRef.value)
17
- return;
18
- containerRef.value.appendChild(props.dom);
19
- });
20
- return () => h("div", { ref: containerRef });
21
- });
22
- Content.props = ['dom'];
23
- //# sourceMappingURL=VueNode.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"VueNode.js","sourceRoot":"","sources":["../src/VueNode.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC,EAAgB,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,KAAK,CAAC;AAS5F,MAAM,CAAC,MAAM,YAAY,GAA8B,MAAM,EAAE,CAAC;AAEhE,MAAM,CAAC,MAAM,gBAAgB,GAAG,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAe,EAAE,OAAO,EAAE,EAAE;IAC1G,OAAO,CAAC,YAAY,EAAE;QAClB,IAAI;QACJ,IAAI;QACJ,MAAM;QACN,WAAW;KACd,CAAC,CAAC;IACH,OAAO,GAAG,EAAE,mBAAC,OAAA,kBAAG,MAAA,MAAA,MAAA,OAAO,CAAC,KAAK,EAAC,OAAO,kDAAI,mCAAI,EAAE,CAAI,CAAA,EAAA,CAAC;AACxD,CAAC,CAAC,CAAC;AACH,gBAAgB,CAAC,KAAK,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;AAE7E,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAC,CAAC,KAA4B,EAAE,EAAE;IACpE,MAAM,YAAY,GAAG,GAAG,CAAwB,IAAI,CAAC,CAAC;IACtD,WAAW,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK;YAAE,OAAO;QAC9C,YAAY,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,EAAE,CAAC,WAAK,GAAG,EAAE,YAAY,GAAI,CAAC;AAC5C,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC"}
@@ -1,54 +0,0 @@
1
- import { Mark, Node } from '@milkdown/prose';
2
- import { customAlphabet } from 'nanoid';
3
- import { defineComponent, h, Teleport } from 'vue';
4
- import { Content, VueNodeContainer } from './VueNode';
5
- const nanoid = customAlphabet('abcedfghicklmn', 10);
6
- export const createVueView = (addPortal, removePortalByKey) => (component) => (node, view, getPos, decorations) => new VueNodeView(component, addPortal, removePortalByKey, node, view, getPos, decorations);
7
- export class VueNodeView {
8
- constructor(component, addPortal, removePortalByKey, node, view, getPos, decorations) {
9
- this.component = component;
10
- this.addPortal = addPortal;
11
- this.removePortalByKey = removePortalByKey;
12
- this.node = node;
13
- this.view = view;
14
- this.getPos = getPos;
15
- this.decorations = decorations;
16
- this.key = nanoid();
17
- const dom = document.createElement(node instanceof Mark ? 'span' : 'div');
18
- dom.classList.add('dom-wrapper');
19
- const contentDOM = node instanceof Node && node.isLeaf
20
- ? undefined
21
- : document.createElement(node instanceof Mark ? 'span' : 'div');
22
- if (contentDOM) {
23
- contentDOM.classList.add('content-dom');
24
- dom.appendChild(contentDOM);
25
- }
26
- this.dom = dom;
27
- this.contentDOM = contentDOM;
28
- this.renderPortal();
29
- }
30
- renderPortal() {
31
- if (!this.dom)
32
- return;
33
- const CustomComponent = this.component;
34
- const Portal = defineComponent(() => {
35
- return () => (h(Teleport, { to: this.dom },
36
- h(VueNodeContainer, { key: this.key, node: this.node, view: this.view, getPos: this.getPos, decorations: this.decorations },
37
- h(CustomComponent, null,
38
- h(Content, { dom: this.contentDOM })))));
39
- });
40
- this.addPortal(Portal, this.key);
41
- }
42
- destroy() {
43
- this.dom = undefined;
44
- this.contentDOM = undefined;
45
- this.removePortalByKey(this.key);
46
- }
47
- ignoreMutation(mutation) {
48
- if (!this.contentDOM) {
49
- return true;
50
- }
51
- return !this.contentDOM.contains(mutation.target);
52
- }
53
- }
54
- //# sourceMappingURL=VueNodeView.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"VueNodeView.js","sourceRoot":"","sources":["../src/VueNodeView.tsx"],"names":[],"mappings":"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"}
package/lib/index.js DELETED
@@ -1,4 +0,0 @@
1
- /* Copyright 2021, Milkdown by Mirone. */
2
- export * from './Editor';
3
- export { nodeMetadata } from './VueNode';
4
- //# sourceMappingURL=index.js.map
package/lib/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
package/lib/utils.js DELETED
@@ -1,3 +0,0 @@
1
- /* Copyright 2021, Milkdown by Mirone. */
2
- export {};
3
- //# sourceMappingURL=utils.js.map
package/lib/utils.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,yCAAyC"}
package/src/Portals.tsx DELETED
@@ -1,31 +0,0 @@
1
- /* Copyright 2021, Milkdown by Mirone. */
2
- import { DefineComponent, defineComponent, Fragment, h, nextTick, ref, shallowRef, watch } from 'vue';
3
- export type PortalPair = [key: string, component: DefineComponent];
4
-
5
- const getId = (pairs: PortalPair[]) => pairs.map((p) => p[0]).join('\n');
6
-
7
- export const Portals = defineComponent((props: { portals: PortalPair[] }) => {
8
- const portalComponents = shallowRef<Array<DefineComponent>>([]);
9
- const prev = ref<string>('');
10
- const renderList = shallowRef<() => JSX.Element[]>(() => []);
11
-
12
- watch(
13
- () => getId(props.portals),
14
- (ids) => {
15
- if (ids !== prev.value) {
16
- prev.value = ids;
17
- const next = props.portals.map((p) => p[1]);
18
- portalComponents.value = next;
19
- }
20
- },
21
- );
22
-
23
- nextTick(() => {
24
- renderList.value = () => portalComponents.value.map((P) => <P />);
25
- });
26
-
27
- return () => {
28
- return <>{renderList.value()}</>;
29
- };
30
- });
31
- Portals.props = ['portals'];