@milkdown/plugin-slash 7.0.0-next.0 → 7.0.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.es.js +55 -56
- package/lib/index.es.js.map +1 -1
- package/lib/slash-plugin.d.ts +0 -1
- package/lib/slash-plugin.d.ts.map +1 -1
- package/lib/slash-provider.d.ts +1 -0
- package/lib/slash-provider.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/slash-plugin.ts +3 -2
- package/src/slash-provider.ts +33 -14
package/lib/index.es.js
CHANGED
|
@@ -1,87 +1,86 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
if (!t.has(
|
|
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
|
|
8
|
-
if (t.has(
|
|
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(
|
|
11
|
-
},
|
|
12
|
-
var
|
|
13
|
-
import { Plugin as
|
|
14
|
-
import { $ctx as
|
|
15
|
-
import { posToDOMRect as
|
|
16
|
-
import
|
|
17
|
-
import
|
|
18
|
-
const
|
|
19
|
-
const t =
|
|
20
|
-
const a =
|
|
21
|
-
return new
|
|
22
|
-
key: new
|
|
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
|
-
}),
|
|
26
|
-
return
|
|
27
|
-
}
|
|
28
|
-
var
|
|
29
|
-
class
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const { state:
|
|
39
|
-
if (
|
|
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
|
-
...
|
|
44
|
-
content:
|
|
45
|
-
})), !(
|
|
46
|
-
if (!
|
|
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
|
-
|
|
51
|
-
getReferenceClientRect: () =>
|
|
50
|
+
s(this, r).setProps({
|
|
51
|
+
getReferenceClientRect: () => M(t, y, C)
|
|
52
52
|
}), this.show();
|
|
53
53
|
}
|
|
54
54
|
});
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
c(this, "update", (t, e) => {
|
|
56
|
+
O(s(this, f), s(this, m))(t, e);
|
|
57
57
|
});
|
|
58
|
-
|
|
59
|
-
const { selection: e } = t.state, { empty:
|
|
60
|
-
return
|
|
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
|
-
|
|
62
|
+
c(this, "destroy", () => {
|
|
63
63
|
var t;
|
|
64
|
-
(t =
|
|
64
|
+
(t = s(this, r)) == null || t.destroy();
|
|
65
65
|
});
|
|
66
|
-
|
|
66
|
+
c(this, "show", () => {
|
|
67
67
|
var t;
|
|
68
|
-
(t =
|
|
68
|
+
(t = s(this, r)) == null || t.show();
|
|
69
69
|
});
|
|
70
|
-
|
|
70
|
+
c(this, "hide", () => {
|
|
71
71
|
var t;
|
|
72
|
-
(t =
|
|
72
|
+
(t = s(this, r)) == null || t.hide();
|
|
73
73
|
});
|
|
74
|
-
|
|
75
|
-
|
|
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
|
-
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
q as slashFactory
|
|
83
|
+
j as SlashProvider,
|
|
84
|
+
U as slashFactory
|
|
86
85
|
};
|
|
87
86
|
//# sourceMappingURL=index.es.js.map
|
package/lib/index.es.js.map
CHANGED
|
@@ -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
|
|
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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"}
|
package/lib/slash-plugin.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/lib/slash-provider.d.ts
CHANGED
|
@@ -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;
|
|
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,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milkdown/plugin-slash",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "7.0.0-next.
|
|
4
|
+
"version": "7.0.0-next.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -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.
|
|
34
|
-
"@milkdown/utils": "7.0.0-next.
|
|
33
|
+
"@milkdown/exception": "7.0.0-next.1",
|
|
34
|
+
"@milkdown/utils": "7.0.0-next.1"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@milkdown/core": "7.0.0-next.
|
|
38
|
-
"@milkdown/ctx": "7.0.0-next.
|
|
39
|
-
"@milkdown/prose": "7.0.0-next.
|
|
37
|
+
"@milkdown/core": "7.0.0-next.1",
|
|
38
|
+
"@milkdown/ctx": "7.0.0-next.1",
|
|
39
|
+
"@milkdown/prose": "7.0.0-next.1"
|
|
40
40
|
},
|
|
41
41
|
"nx": {
|
|
42
42
|
"targets": {
|
package/src/slash-plugin.ts
CHANGED
|
@@ -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')
|
package/src/slash-provider.ts
CHANGED
|
@@ -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
|
-
|
|
24
|
+
/// The root element of the slash.
|
|
25
|
+
element: HTMLElement
|
|
19
26
|
|
|
20
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
}
|