@milkdown/plugin-slash 7.0.0-next.0 → 7.0.0-next.2

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/README.md CHANGED
@@ -8,4 +8,4 @@ Documentation can be found on the [Milkdown website](https://milkdown.dev/plugin
8
8
 
9
9
  # License
10
10
 
11
- Milkdown is open sourced software licensed under [MIT license](https://github.com/Saul-Mirone/milkdown/blob/main/LICENSE).
11
+ Milkdown is open sourced software licensed under [MIT license](https://github.com/Milkdown/milkdown/blob/main/LICENSE).
package/lib/index.es.js CHANGED
@@ -1,87 +1,86 @@
1
- var B = Object.defineProperty;
2
- var I = (s, t, e) => t in s ? B(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e;
3
- var i = (s, t, e) => (I(s, typeof t != "symbol" ? t + "" : t, e), e), C = (s, t, e) => {
4
- if (!t.has(s))
1
+ var b = Object.defineProperty;
2
+ var B = (n, t, e) => t in n ? b(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
3
+ var c = (n, t, e) => (B(n, typeof t != "symbol" ? t + "" : t, e), e), x = (n, t, e) => {
4
+ if (!t.has(n))
5
5
  throw TypeError("Cannot " + e);
6
6
  };
7
- var o = (s, t, e) => (C(s, t, "read from private field"), e ? e.call(s) : t.get(s)), r = (s, t, e) => {
8
- if (t.has(s))
7
+ var s = (n, t, e) => (x(n, t, "read from private field"), e ? e.call(n) : t.get(n)), i = (n, t, e) => {
8
+ if (t.has(n))
9
9
  throw TypeError("Cannot add the same private member more than once");
10
- t instanceof WeakSet ? t.add(s) : t.set(s, e);
11
- }, h = (s, t, e, n) => (C(s, t, "write to private field"), n ? n.call(s, e) : t.set(s, e), e);
12
- var $ = (s, t, e) => (C(s, t, "access private method"), e);
13
- import { Plugin as M, PluginKey as N, TextSelection as O } from "@milkdown/prose/state";
14
- import { $ctx as R, $prose as _ } from "@milkdown/utils";
15
- import { posToDOMRect as F, findParentNode as H } from "@milkdown/prose";
16
- import K from "lodash.debounce";
17
- import L from "tippy.js";
18
- const q = (s) => {
19
- const t = R({}, `${s}_SLASH_SPEC`), e = _((p) => {
20
- const a = p.get(t.key);
21
- return new M({
22
- key: new N(`${s}_SLASH`),
10
+ t instanceof WeakSet ? t.add(n) : t.set(n, e);
11
+ }, p = (n, t, e, o) => (x(n, t, "write to private field"), o ? o.call(n, e) : t.set(n, e), e);
12
+ var T = (n, t, e) => (x(n, t, "access private method"), e);
13
+ import { Plugin as R, PluginKey as _, TextSelection as F } from "@milkdown/prose/state";
14
+ import { $ctx as H, $prose as I } from "@milkdown/utils";
15
+ import { posToDOMRect as M, findParentNode as N } from "@milkdown/prose";
16
+ import O from "lodash.debounce";
17
+ import q from "tippy.js";
18
+ const U = (n) => {
19
+ const t = H({}, `${n}_SLASH_SPEC`), e = I((h) => {
20
+ const a = h.get(t.key);
21
+ return new R({
22
+ key: new _(`${n}_SLASH`),
23
23
  ...a
24
24
  });
25
- }), n = [t, e];
26
- return n.key = t.key, n.pluginKey = e.key, n;
27
- }, j = q("MILKDOWN");
28
- var c, l, m, d, g, S, k, b;
29
- class z {
25
+ }), o = [t, e];
26
+ return o.key = t.key, o.pluginKey = e.key, o;
27
+ };
28
+ var r, u, m, d, f, S, $;
29
+ class j {
30
30
  constructor(t) {
31
- r(this, k);
32
- r(this, c, void 0);
33
- r(this, l, void 0);
34
- r(this, m, void 0);
35
- r(this, d, void 0);
36
- r(this, g, void 0);
37
- r(this, S, (t, e) => {
38
- const { state: n, composing: p } = t, { selection: a, doc: x } = n, { ranges: y } = a, f = Math.min(...y.map((u) => u.$from.pos)), P = Math.max(...y.map((u) => u.$to.pos)), T = e && e.doc.eq(x) && e.selection.eq(a);
39
- if (o(this, c) ?? h(this, c, L(t.dom, {
31
+ i(this, S);
32
+ c(this, "element");
33
+ i(this, r, void 0);
34
+ i(this, u, void 0);
35
+ i(this, m, void 0);
36
+ i(this, d, void 0);
37
+ i(this, f, (t, e) => {
38
+ const { state: o, composing: h } = t, { selection: a, doc: k } = o, { ranges: g } = a, y = Math.min(...g.map((l) => l.$from.pos)), C = Math.max(...g.map((l) => l.$to.pos)), P = e && e.doc.eq(k) && e.selection.eq(a);
39
+ if (s(this, r) ?? p(this, r, q(t.dom, {
40
40
  trigger: "manual",
41
41
  placement: "bottom-start",
42
42
  interactive: !0,
43
- ...o(this, m),
44
- content: o(this, l)
45
- })), !(p || T)) {
46
- if (!o(this, g).call(this, t, e)) {
43
+ ...s(this, u),
44
+ content: this.element
45
+ })), !(h || P)) {
46
+ if (!s(this, d).call(this, t, e)) {
47
47
  this.hide();
48
48
  return;
49
49
  }
50
- o(this, c).setProps({
51
- getReferenceClientRect: () => F(t, f, P)
50
+ s(this, r).setProps({
51
+ getReferenceClientRect: () => M(t, y, C)
52
52
  }), this.show();
53
53
  }
54
54
  });
55
- i(this, "update", (t, e) => {
56
- K(o(this, S), o(this, d))(t, e);
55
+ c(this, "update", (t, e) => {
56
+ O(s(this, f), s(this, m))(t, e);
57
57
  });
58
- i(this, "getContent", (t) => {
59
- const { selection: e } = t.state, { empty: n } = e, p = t.state.selection instanceof O, a = o(this, l).contains(document.activeElement), x = !t.hasFocus() && !a, y = !t.editable, f = H(({ type: u }) => u.name === "paragraph")(t.state.selection);
60
- return x || y || !n || !p || !f ? void 0 : f.node.textContent;
58
+ c(this, "getContent", (t) => {
59
+ const { selection: e } = t.state, { empty: o } = e, h = t.state.selection instanceof F, a = this.element.contains(document.activeElement), k = !t.hasFocus() && !a, g = !t.editable, y = N(({ type: l }) => l.name === "paragraph")(t.state.selection);
60
+ return k || g || !o || !h || !y ? void 0 : y.node.textContent;
61
61
  });
62
- i(this, "destroy", () => {
62
+ c(this, "destroy", () => {
63
63
  var t;
64
- (t = o(this, c)) == null || t.destroy();
64
+ (t = s(this, r)) == null || t.destroy();
65
65
  });
66
- i(this, "show", () => {
66
+ c(this, "show", () => {
67
67
  var t;
68
- (t = o(this, c)) == null || t.show();
68
+ (t = s(this, r)) == null || t.show();
69
69
  });
70
- i(this, "hide", () => {
70
+ c(this, "hide", () => {
71
71
  var t;
72
- (t = o(this, c)) == null || t.hide();
72
+ (t = s(this, r)) == null || t.hide();
73
73
  });
74
- i(this, "getInstance", () => o(this, c));
75
- h(this, l, t.content), h(this, m, t.tippyOptions ?? {}), h(this, d, t.debounce ?? 200), h(this, g, t.shouldShow ?? $(this, k, b));
74
+ c(this, "getInstance", () => s(this, r));
75
+ this.element = t.content, p(this, u, t.tippyOptions ?? {}), p(this, m, t.debounce ?? 200), p(this, d, t.shouldShow ?? T(this, S, $));
76
76
  }
77
77
  }
78
- c = new WeakMap(), l = new WeakMap(), m = new WeakMap(), d = new WeakMap(), g = new WeakMap(), S = new WeakMap(), k = new WeakSet(), b = function(t) {
78
+ r = new WeakMap(), u = new WeakMap(), m = new WeakMap(), d = new WeakMap(), f = new WeakMap(), S = new WeakSet(), $ = function(t) {
79
79
  const e = this.getContent(t);
80
80
  return e ? e.at(-1) === "/" : !1;
81
81
  };
82
82
  export {
83
- z as SlashProvider,
84
- j as slash,
85
- q as slashFactory
83
+ j as SlashProvider,
84
+ U as slashFactory
86
85
  };
87
86
  //# sourceMappingURL=index.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/slash-plugin.ts","../src/slash-provider.ts"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nimport type { SliceType } from '@milkdown/ctx'\nimport type { PluginSpec } from '@milkdown/prose/state'\nimport { Plugin, PluginKey } from '@milkdown/prose/state'\nimport type { $Ctx, $Prose } from '@milkdown/utils'\nimport { $ctx, $prose } from '@milkdown/utils'\n\nexport type SlashPluginSpecId<Id extends string> = `${Id}_SLASH_SPEC`\n\nexport type SlashPlugin<Id extends string, State = any> = [$Ctx<PluginSpec<State>, SlashPluginSpecId<Id>>, $Prose] & {\n key: SliceType<PluginSpec<State>, SlashPluginSpecId<Id>>\n pluginKey: $Prose['key']\n}\n\nexport const slashFactory = <Id extends string, State = any>(id: Id) => {\n const slashSpec = $ctx<PluginSpec<State>, SlashPluginSpecId<Id>>({}, `${id}_SLASH_SPEC`)\n const slashPlugin = $prose((ctx) => {\n const spec = ctx.get(slashSpec.key)\n return new Plugin({\n key: new PluginKey(`${id}_SLASH`),\n ...spec,\n })\n })\n const result = [slashSpec, slashPlugin] as SlashPlugin<Id>\n result.key = slashSpec.key\n result.pluginKey = slashPlugin.key\n\n return result\n}\n\nexport const slash = slashFactory('MILKDOWN')\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { findParentNode, posToDOMRect } from '@milkdown/prose'\nimport type { EditorState } from '@milkdown/prose/state'\nimport { TextSelection } from '@milkdown/prose/state'\nimport type { EditorView } from '@milkdown/prose/view'\nimport debounce from 'lodash.debounce'\nimport type { Instance, Props } from 'tippy.js'\nimport tippy from 'tippy.js'\n\nexport type SlashProviderOptions = {\n content: HTMLElement\n tippyOptions?: Partial<Props>\n debounce?: number\n shouldShow?: (view: EditorView, prevState?: EditorState) => boolean\n}\n\nexport class SlashProvider {\n #tippy: Instance | undefined\n\n #element: HTMLElement\n\n #tippyOptions: Partial<Props>\n\n #debounce: number\n\n #shouldShow: (view: EditorView, prevState?: EditorState) => boolean\n\n constructor(options: SlashProviderOptions) {\n this.#element = options.content\n this.#tippyOptions = options.tippyOptions ?? {}\n this.#debounce = options.debounce ?? 200\n this.#shouldShow = options.shouldShow ?? this.#_shouldShow\n }\n\n #onUpdate = (view: EditorView, prevState?: EditorState): void => {\n const { state, composing } = view\n const { selection, doc } = state\n const { ranges } = selection\n const from = Math.min(...ranges.map(range => range.$from.pos))\n const to = Math.max(...ranges.map(range => range.$to.pos))\n const isSame = prevState && prevState.doc.eq(doc) && prevState.selection.eq(selection)\n\n this.#tippy ??= tippy(view.dom, {\n trigger: 'manual',\n placement: 'bottom-start',\n interactive: true,\n ...this.#tippyOptions,\n content: this.#element,\n })\n\n if (composing || isSame)\n return\n\n if (!this.#shouldShow(view, prevState)) {\n this.hide()\n return\n }\n\n this.#tippy.setProps({\n getReferenceClientRect: () => posToDOMRect(view, from, to),\n })\n\n this.show()\n }\n\n update = (view: EditorView, prevState?: EditorState): void => {\n const updater = debounce(this.#onUpdate, this.#debounce)\n\n updater(view, prevState)\n }\n\n getContent = (view: EditorView): string | undefined => {\n const { selection } = view.state\n const { empty } = selection\n const isTextBlock = view.state.selection instanceof TextSelection\n\n const isSlashChildren = this.#element.contains(document.activeElement)\n\n const notHasFocus = !view.hasFocus() && !isSlashChildren\n\n const isReadonly = !view.editable\n\n const paragraph = findParentNode(({ type }) => type.name === 'paragraph')(view.state.selection)\n\n const isNotInParagraph = !paragraph\n\n if (notHasFocus || isReadonly || !empty || !isTextBlock || isNotInParagraph)\n return\n\n const currentTextBlockContent = paragraph.node.textContent\n\n return currentTextBlockContent\n }\n\n #_shouldShow(view: EditorView): boolean {\n const currentTextBlockContent = this.getContent(view)\n\n if (!currentTextBlockContent)\n return false\n\n return currentTextBlockContent.at(-1) === '/'\n }\n\n destroy = () => {\n this.#tippy?.destroy()\n }\n\n show = () => {\n this.#tippy?.show()\n }\n\n hide = () => {\n this.#tippy?.hide()\n }\n\n getInstance = () => {\n return this.#tippy\n }\n}\n"],"names":["slashFactory","id","slashSpec","$ctx","slashPlugin","$prose","ctx","spec","Plugin","PluginKey","result","slash","SlashProvider","options","__privateAdd","__shouldShow","_tippy","_element","_tippyOptions","_debounce","_shouldShow","_onUpdate","view","prevState","state","composing","selection","doc","ranges","from","range","to","isSame","__privateGet","__privateSet","tippy","posToDOMRect","__publicField","debounce","empty","isTextBlock","TextSelection","isSlashChildren","notHasFocus","isReadonly","paragraph","findParentNode","type","_a","__privateMethod","_shouldShow_fn","currentTextBlockContent"],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/slash-plugin.ts","../src/slash-provider.ts"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nimport type { SliceType } from '@milkdown/ctx'\nimport type { PluginSpec } from '@milkdown/prose/state'\nimport { Plugin, PluginKey } from '@milkdown/prose/state'\nimport type { $Ctx, $Prose } from '@milkdown/utils'\nimport { $ctx, $prose } from '@milkdown/utils'\n\n/// @internal\nexport type SlashPluginSpecId<Id extends string> = `${Id}_SLASH_SPEC`\n\n/// @internal\nexport type SlashPlugin<Id extends string, State = any> = [$Ctx<PluginSpec<State>, SlashPluginSpecId<Id>>, $Prose] & {\n key: SliceType<PluginSpec<State>, SlashPluginSpecId<Id>>\n pluginKey: $Prose['key']\n}\n\n/// Create a slash plugin with a unique id.\nexport const slashFactory = <Id extends string, State = any>(id: Id) => {\n const slashSpec = $ctx<PluginSpec<State>, SlashPluginSpecId<Id>>({}, `${id}_SLASH_SPEC`)\n const slashPlugin = $prose((ctx) => {\n const spec = ctx.get(slashSpec.key)\n return new Plugin({\n key: new PluginKey(`${id}_SLASH`),\n ...spec,\n })\n })\n const result = [slashSpec, slashPlugin] as SlashPlugin<Id>\n result.key = slashSpec.key\n result.pluginKey = slashPlugin.key\n\n return result\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { findParentNode, posToDOMRect } from '@milkdown/prose'\nimport type { EditorState } from '@milkdown/prose/state'\nimport { TextSelection } from '@milkdown/prose/state'\nimport type { EditorView } from '@milkdown/prose/view'\nimport debounce from 'lodash.debounce'\nimport type { Instance, Props } from 'tippy.js'\nimport tippy from 'tippy.js'\n\n/// Options for slash provider.\nexport type SlashProviderOptions = {\n /// The slash content.\n content: HTMLElement\n /// The options for creating [tippy.js](https://atomiks.github.io/tippyjs/) instance.\n tippyOptions?: Partial<Props>\n /// The debounce time for updating slash, 200ms by default.\n debounce?: number\n /// The function to determine whether the tooltip should be shown.\n shouldShow?: (view: EditorView, prevState?: EditorState) => boolean\n}\n\n/// A provider for creating slash.\nexport class SlashProvider {\n /// The root element of the slash.\n element: HTMLElement\n\n /// @internal\n #tippy: Instance | undefined\n\n /// @internal\n #tippyOptions: Partial<Props>\n\n /// @internal\n #debounce: number\n\n /// @internal\n #shouldShow: (view: EditorView, prevState?: EditorState) => boolean\n\n constructor(options: SlashProviderOptions) {\n this.element = options.content\n this.#tippyOptions = options.tippyOptions ?? {}\n this.#debounce = options.debounce ?? 200\n this.#shouldShow = options.shouldShow ?? this.#_shouldShow\n }\n\n /// @internal\n #onUpdate = (view: EditorView, prevState?: EditorState): void => {\n const { state, composing } = view\n const { selection, doc } = state\n const { ranges } = selection\n const from = Math.min(...ranges.map(range => range.$from.pos))\n const to = Math.max(...ranges.map(range => range.$to.pos))\n const isSame = prevState && prevState.doc.eq(doc) && prevState.selection.eq(selection)\n\n this.#tippy ??= tippy(view.dom, {\n trigger: 'manual',\n placement: 'bottom-start',\n interactive: true,\n ...this.#tippyOptions,\n content: this.element,\n })\n\n if (composing || isSame)\n return\n\n if (!this.#shouldShow(view, prevState)) {\n this.hide()\n return\n }\n\n this.#tippy.setProps({\n getReferenceClientRect: () => posToDOMRect(view, from, to),\n })\n\n this.show()\n }\n\n /// @internal\n #_shouldShow(view: EditorView): boolean {\n const currentTextBlockContent = this.getContent(view)\n\n if (!currentTextBlockContent)\n return false\n\n return currentTextBlockContent.at(-1) === '/'\n }\n\n /// Update provider state by editor view.\n update = (view: EditorView, prevState?: EditorState): void => {\n const updater = debounce(this.#onUpdate, this.#debounce)\n\n updater(view, prevState)\n }\n\n /// Get the content of the current text block.\n getContent = (view: EditorView): string | undefined => {\n const { selection } = view.state\n const { empty } = selection\n const isTextBlock = view.state.selection instanceof TextSelection\n\n const isSlashChildren = this.element.contains(document.activeElement)\n\n const notHasFocus = !view.hasFocus() && !isSlashChildren\n\n const isReadonly = !view.editable\n\n const paragraph = findParentNode(({ type }) => type.name === 'paragraph')(view.state.selection)\n\n const isNotInParagraph = !paragraph\n\n if (notHasFocus || isReadonly || !empty || !isTextBlock || isNotInParagraph)\n return\n\n const currentTextBlockContent = paragraph.node.textContent\n\n return currentTextBlockContent\n }\n\n /// Destroy the slash.\n destroy = () => {\n this.#tippy?.destroy()\n }\n\n /// Show the slash.\n show = () => {\n this.#tippy?.show()\n }\n\n /// Hide the slash.\n hide = () => {\n this.#tippy?.hide()\n }\n\n /// Get the [tippy.js](https://atomiks.github.io/tippyjs/) instance.\n getInstance = () => {\n return this.#tippy\n }\n}\n"],"names":["slashFactory","id","slashSpec","$ctx","slashPlugin","$prose","ctx","spec","Plugin","PluginKey","result","SlashProvider","options","__privateAdd","__shouldShow","__publicField","_tippy","_tippyOptions","_debounce","_shouldShow","_onUpdate","view","prevState","state","composing","selection","doc","ranges","from","range","to","isSame","__privateGet","__privateSet","tippy","posToDOMRect","debounce","empty","isTextBlock","TextSelection","isSlashChildren","notHasFocus","isReadonly","paragraph","findParentNode","type","_a","__privateMethod","_shouldShow_fn","currentTextBlockContent"],"mappings":"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"}
@@ -7,5 +7,4 @@ export type SlashPlugin<Id extends string, State = any> = [$Ctx<PluginSpec<State
7
7
  pluginKey: $Prose['key'];
8
8
  };
9
9
  export declare const slashFactory: <Id extends string, State = any>(id: Id) => SlashPlugin<Id, any>;
10
- export declare const slash: SlashPlugin<"MILKDOWN", any>;
11
10
  //# sourceMappingURL=slash-plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"slash-plugin.d.ts","sourceRoot":"","sources":["../src/slash-plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAEvD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAGnD,MAAM,MAAM,iBAAiB,CAAC,EAAE,SAAS,MAAM,IAAI,GAAG,EAAE,aAAa,CAAA;AAErE,MAAM,MAAM,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,KAAK,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG;IACnH,GAAG,EAAE,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAA;IACxD,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;CACzB,CAAA;AAED,eAAO,MAAM,YAAY,kEAcxB,CAAA;AAED,eAAO,MAAM,KAAK,8BAA2B,CAAA"}
1
+ {"version":3,"file":"slash-plugin.d.ts","sourceRoot":"","sources":["../src/slash-plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAEvD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAInD,MAAM,MAAM,iBAAiB,CAAC,EAAE,SAAS,MAAM,IAAI,GAAG,EAAE,aAAa,CAAA;AAGrE,MAAM,MAAM,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,KAAK,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG;IACnH,GAAG,EAAE,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAA;IACxD,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;CACzB,CAAA;AAGD,eAAO,MAAM,YAAY,kEAcxB,CAAA"}
@@ -9,6 +9,7 @@ export type SlashProviderOptions = {
9
9
  };
10
10
  export declare class SlashProvider {
11
11
  #private;
12
+ element: HTMLElement;
12
13
  constructor(options: SlashProviderOptions);
13
14
  update: (view: EditorView, prevState?: EditorState) => void;
14
15
  getContent: (view: EditorView) => string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"slash-provider.d.ts","sourceRoot":"","sources":["../src/slash-provider.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAG/C,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,WAAW,CAAA;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,WAAW,KAAK,OAAO,CAAA;CACpE,CAAA;AAED,qBAAa,aAAa;;gBAWZ,OAAO,EAAE,oBAAoB;IAsCzC,MAAM,SAAU,UAAU,cAAc,WAAW,KAAG,IAAI,CAIzD;IAED,UAAU,SAAU,UAAU,KAAG,MAAM,GAAG,SAAS,CAqBlD;IAWD,OAAO,aAEN;IAED,IAAI,aAEH;IAED,IAAI,aAEH;IAED,WAAW,oCAEV;CACF"}
1
+ {"version":3,"file":"slash-provider.d.ts","sourceRoot":"","sources":["../src/slash-provider.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAI/C,MAAM,MAAM,oBAAoB,GAAG;IAEjC,OAAO,EAAE,WAAW,CAAA;IAEpB,YAAY,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;IAE7B,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,WAAW,KAAK,OAAO,CAAA;CACpE,CAAA;AAGD,qBAAa,aAAa;;IAExB,OAAO,EAAE,WAAW,CAAA;gBAcR,OAAO,EAAE,oBAAoB;IAkDzC,MAAM,SAAU,UAAU,cAAc,WAAW,KAAG,IAAI,CAIzD;IAGD,UAAU,SAAU,UAAU,KAAG,MAAM,GAAG,SAAS,CAqBlD;IAGD,OAAO,aAEN;IAGD,IAAI,aAEH;IAGD,IAAI,aAEH;IAGD,WAAW,oCAEV;CACF"}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@milkdown/plugin-slash",
3
3
  "type": "module",
4
- "version": "7.0.0-next.0",
4
+ "version": "7.0.0-next.2",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "git+https://github.com/Saul-Mirone/milkdown.git",
8
+ "url": "git+https://github.com/Milkdown/milkdown.git",
9
9
  "directory": "packages/plugin-slash"
10
10
  },
11
11
  "keywords": [
@@ -30,13 +30,13 @@
30
30
  "smooth-scroll-into-view-if-needed": "^1.1.32",
31
31
  "tippy.js": "^6.3.7",
32
32
  "tslib": "^2.4.0",
33
- "@milkdown/exception": "7.0.0-next.0",
34
- "@milkdown/utils": "7.0.0-next.0"
33
+ "@milkdown/exception": "7.0.0-next.2",
34
+ "@milkdown/utils": "7.0.0-next.2"
35
35
  },
36
36
  "devDependencies": {
37
- "@milkdown/core": "7.0.0-next.0",
38
- "@milkdown/ctx": "7.0.0-next.0",
39
- "@milkdown/prose": "7.0.0-next.0"
37
+ "@milkdown/core": "7.0.0-next.2",
38
+ "@milkdown/ctx": "7.0.0-next.2",
39
+ "@milkdown/prose": "7.0.0-next.2"
40
40
  },
41
41
  "nx": {
42
42
  "targets": {
@@ -5,13 +5,16 @@ import { Plugin, PluginKey } from '@milkdown/prose/state'
5
5
  import type { $Ctx, $Prose } from '@milkdown/utils'
6
6
  import { $ctx, $prose } from '@milkdown/utils'
7
7
 
8
+ /// @internal
8
9
  export type SlashPluginSpecId<Id extends string> = `${Id}_SLASH_SPEC`
9
10
 
11
+ /// @internal
10
12
  export type SlashPlugin<Id extends string, State = any> = [$Ctx<PluginSpec<State>, SlashPluginSpecId<Id>>, $Prose] & {
11
13
  key: SliceType<PluginSpec<State>, SlashPluginSpecId<Id>>
12
14
  pluginKey: $Prose['key']
13
15
  }
14
16
 
17
+ /// Create a slash plugin with a unique id.
15
18
  export const slashFactory = <Id extends string, State = any>(id: Id) => {
16
19
  const slashSpec = $ctx<PluginSpec<State>, SlashPluginSpecId<Id>>({}, `${id}_SLASH_SPEC`)
17
20
  const slashPlugin = $prose((ctx) => {
@@ -27,5 +30,3 @@ export const slashFactory = <Id extends string, State = any>(id: Id) => {
27
30
 
28
31
  return result
29
32
  }
30
-
31
- export const slash = slashFactory('MILKDOWN')
@@ -7,31 +7,43 @@ import debounce from 'lodash.debounce'
7
7
  import type { Instance, Props } from 'tippy.js'
8
8
  import tippy from 'tippy.js'
9
9
 
10
+ /// Options for slash provider.
10
11
  export type SlashProviderOptions = {
12
+ /// The slash content.
11
13
  content: HTMLElement
14
+ /// The options for creating [tippy.js](https://atomiks.github.io/tippyjs/) instance.
12
15
  tippyOptions?: Partial<Props>
16
+ /// The debounce time for updating slash, 200ms by default.
13
17
  debounce?: number
18
+ /// The function to determine whether the tooltip should be shown.
14
19
  shouldShow?: (view: EditorView, prevState?: EditorState) => boolean
15
20
  }
16
21
 
22
+ /// A provider for creating slash.
17
23
  export class SlashProvider {
18
- #tippy: Instance | undefined
24
+ /// The root element of the slash.
25
+ element: HTMLElement
19
26
 
20
- #element: HTMLElement
27
+ /// @internal
28
+ #tippy: Instance | undefined
21
29
 
30
+ /// @internal
22
31
  #tippyOptions: Partial<Props>
23
32
 
33
+ /// @internal
24
34
  #debounce: number
25
35
 
36
+ /// @internal
26
37
  #shouldShow: (view: EditorView, prevState?: EditorState) => boolean
27
38
 
28
39
  constructor(options: SlashProviderOptions) {
29
- this.#element = options.content
40
+ this.element = options.content
30
41
  this.#tippyOptions = options.tippyOptions ?? {}
31
42
  this.#debounce = options.debounce ?? 200
32
43
  this.#shouldShow = options.shouldShow ?? this.#_shouldShow
33
44
  }
34
45
 
46
+ /// @internal
35
47
  #onUpdate = (view: EditorView, prevState?: EditorState): void => {
36
48
  const { state, composing } = view
37
49
  const { selection, doc } = state
@@ -45,7 +57,7 @@ export class SlashProvider {
45
57
  placement: 'bottom-start',
46
58
  interactive: true,
47
59
  ...this.#tippyOptions,
48
- content: this.#element,
60
+ content: this.element,
49
61
  })
50
62
 
51
63
  if (composing || isSame)
@@ -63,18 +75,30 @@ export class SlashProvider {
63
75
  this.show()
64
76
  }
65
77
 
78
+ /// @internal
79
+ #_shouldShow(view: EditorView): boolean {
80
+ const currentTextBlockContent = this.getContent(view)
81
+
82
+ if (!currentTextBlockContent)
83
+ return false
84
+
85
+ return currentTextBlockContent.at(-1) === '/'
86
+ }
87
+
88
+ /// Update provider state by editor view.
66
89
  update = (view: EditorView, prevState?: EditorState): void => {
67
90
  const updater = debounce(this.#onUpdate, this.#debounce)
68
91
 
69
92
  updater(view, prevState)
70
93
  }
71
94
 
95
+ /// Get the content of the current text block.
72
96
  getContent = (view: EditorView): string | undefined => {
73
97
  const { selection } = view.state
74
98
  const { empty } = selection
75
99
  const isTextBlock = view.state.selection instanceof TextSelection
76
100
 
77
- const isSlashChildren = this.#element.contains(document.activeElement)
101
+ const isSlashChildren = this.element.contains(document.activeElement)
78
102
 
79
103
  const notHasFocus = !view.hasFocus() && !isSlashChildren
80
104
 
@@ -92,27 +116,22 @@ export class SlashProvider {
92
116
  return currentTextBlockContent
93
117
  }
94
118
 
95
- #_shouldShow(view: EditorView): boolean {
96
- const currentTextBlockContent = this.getContent(view)
97
-
98
- if (!currentTextBlockContent)
99
- return false
100
-
101
- return currentTextBlockContent.at(-1) === '/'
102
- }
103
-
119
+ /// Destroy the slash.
104
120
  destroy = () => {
105
121
  this.#tippy?.destroy()
106
122
  }
107
123
 
124
+ /// Show the slash.
108
125
  show = () => {
109
126
  this.#tippy?.show()
110
127
  }
111
128
 
129
+ /// Hide the slash.
112
130
  hide = () => {
113
131
  this.#tippy?.hide()
114
132
  }
115
133
 
134
+ /// Get the [tippy.js](https://atomiks.github.io/tippyjs/) instance.
116
135
  getInstance = () => {
117
136
  return this.#tippy
118
137
  }