@milkdown/plugin-tooltip 6.5.0 → 6.5.3
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/button-manager/calc-button-pos.d.ts +1 -1
- package/lib/button-manager/calc-button-pos.d.ts.map +1 -1
- package/lib/button-manager/create-tooltip.d.ts +2 -2
- package/lib/button-manager/create-tooltip.d.ts.map +1 -1
- package/lib/button-manager/filter-button.d.ts +2 -2
- package/lib/button-manager/filter-button.d.ts.map +1 -1
- package/lib/button-manager/index.d.ts.map +1 -1
- package/lib/button-manager/no-active.d.ts +2 -2
- package/lib/button-manager/no-active.d.ts.map +1 -1
- package/lib/button-manager/style.d.ts +1 -1
- package/lib/button-manager/style.d.ts.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.es.js +40 -38
- package/lib/index.es.js.map +1 -1
- package/lib/item.d.ts +13 -13
- package/lib/item.d.ts.map +1 -1
- package/lib/selection-marks-tooltip.d.ts +2 -2
- package/lib/selection-marks-tooltip.d.ts.map +1 -1
- package/lib/utility/element.d.ts.map +1 -1
- package/lib/utility/index.d.ts.map +1 -1
- package/lib/utility/prosemirror.d.ts +4 -4
- package/lib/utility/prosemirror.d.ts.map +1 -1
- package/package.json +15 -15
- package/src/button-manager/calc-button-pos.ts +24 -19
- package/src/button-manager/create-tooltip.ts +25 -26
- package/src/button-manager/filter-button.ts +21 -21
- package/src/button-manager/index.ts +40 -39
- package/src/button-manager/no-active.ts +6 -6
- package/src/button-manager/style.ts +7 -6
- package/src/index.ts +38 -37
- package/src/item.ts +53 -52
- package/src/selection-marks-tooltip.ts +46 -45
- package/src/utility/element.ts +1 -1
- package/src/utility/index.ts +2 -2
- package/src/utility/prosemirror.ts +27 -25
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calc-button-pos.d.ts","sourceRoot":"","sources":["../../src/button-manager/calc-button-pos.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"calc-button-pos.d.ts","sourceRoot":"","sources":["../../src/button-manager/calc-button-pos.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEtD,eAAO,MAAM,aAAa,YAAa,WAAW,QAAQ,UAAU,YAAY,OAAO,SAuBtF,CAAA"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { EditorView } from '@milkdown/prose/view';
|
|
2
2
|
import type { ThemeUtils } from '@milkdown/utils';
|
|
3
3
|
import type { ButtonList } from '../item';
|
|
4
|
-
|
|
4
|
+
interface Tooltip {
|
|
5
5
|
dom: HTMLDivElement;
|
|
6
6
|
render: (editorView: EditorView) => void;
|
|
7
|
-
}
|
|
7
|
+
}
|
|
8
8
|
export declare const createTooltip: (buttonMap: ButtonList, utils: ThemeUtils, className: string) => Tooltip;
|
|
9
9
|
export {};
|
|
10
10
|
//# sourceMappingURL=create-tooltip.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-tooltip.d.ts","sourceRoot":"","sources":["../../src/button-manager/create-tooltip.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"create-tooltip.d.ts","sourceRoot":"","sources":["../../src/button-manager/create-tooltip.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAGzC,UAAU,OAAO;IACf,GAAG,EAAE,cAAc,CAAA;IACnB,MAAM,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAA;CACzC;AAED,eAAO,MAAM,aAAa,iCAAkC,UAAU,aAAa,MAAM,KAAG,OAoB3F,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EditorView } from '@milkdown/prose/view';
|
|
2
|
-
import { ButtonList } from '../item';
|
|
1
|
+
import type { EditorView } from '@milkdown/prose/view';
|
|
2
|
+
import type { ButtonList } from '../item';
|
|
3
3
|
export declare const filterButton: (buttons: ButtonList, view: EditorView) => boolean;
|
|
4
4
|
//# sourceMappingURL=filter-button.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-button.d.ts","sourceRoot":"","sources":["../../src/button-manager/filter-button.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"filter-button.d.ts","sourceRoot":"","sources":["../../src/button-manager/filter-button.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAGzC,eAAO,MAAM,YAAY,8BAA+B,UAAU,YAqBjE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/button-manager/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/button-manager/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAKzC,eAAO,MAAM,mBAAmB,+BAEvB,UAAU,UACT,OAAO,sBACK,MAAM;;;yBA0BH,UAAU;;CAUlC,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EditorView } from '@milkdown/prose/view';
|
|
2
|
-
import { ButtonList } from '../item';
|
|
1
|
+
import type { EditorView } from '@milkdown/prose/view';
|
|
2
|
+
import type { ButtonList } from '../item';
|
|
3
3
|
export declare const noActive: (buttonMap: ButtonList, view: EditorView) => boolean;
|
|
4
4
|
//# sourceMappingURL=no-active.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-active.d.ts","sourceRoot":"","sources":["../../src/button-manager/no-active.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"no-active.d.ts","sourceRoot":"","sources":["../../src/button-manager/no-active.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEzC,eAAO,MAAM,QAAQ,gCAAiC,UAAU,YAI/D,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../src/button-manager/style.ts"],"names":[],"mappings":"AACA,OAAO,EAAS,OAAO,
|
|
1
|
+
{"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../src/button-manager/style.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAS,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAGlE,eAAO,MAAM,WAAW,iBAAkB,YAAY,WAAW,OAAO,WA8CvE,CAAA"}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PluginKey } from '@milkdown/prose/state';
|
|
2
2
|
import { AtomList } from '@milkdown/utils';
|
|
3
|
-
import { TooltipOptions } from './item';
|
|
3
|
+
import type { TooltipOptions } from './item';
|
|
4
4
|
export declare const key: PluginKey<any>;
|
|
5
5
|
export * from './item';
|
|
6
6
|
export declare const tooltipPlugin: import("@milkdown/utils").WithExtend<string, TooltipOptions, import("@milkdown/utils").TypeMapping<string, string>, import("@milkdown/utils").PluginRest<string, string>>;
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,SAAS,EAAE,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAE,QAAQ,EAA0B,MAAM,iBAAiB,CAAA;AAElE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAI5C,eAAO,MAAM,GAAG,gBAAoC,CAAA;AACpD,cAAc,QAAQ,CAAA;AAEtB,eAAO,MAAM,aAAa,2KA+BxB,CAAA;AAEF,eAAO,MAAM,OAAO,qJAAqC,CAAA"}
|
package/lib/index.es.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { TextSelection as
|
|
2
|
-
import { createPlugin as
|
|
3
|
-
import { schemaCtx as
|
|
4
|
-
import { findParentNode as
|
|
5
|
-
import { missingRootElement as
|
|
6
|
-
const
|
|
1
|
+
import { TextSelection as p, PluginKey as T, Plugin as v } from "@milkdown/prose/state";
|
|
2
|
+
import { createPlugin as $, AtomList as y } from "@milkdown/utils";
|
|
3
|
+
import { schemaCtx as b, themeManagerCtx as L, ThemeIcon as k, commandsCtx as P, ThemeSize as h, ThemeBorder as E, ThemeShadow as x, ThemeColor as B } from "@milkdown/core";
|
|
4
|
+
import { findParentNode as C, calculateTextPosition as M } from "@milkdown/prose";
|
|
5
|
+
import { missingRootElement as A } from "@milkdown/exception";
|
|
6
|
+
const m = (e, t) => {
|
|
7
7
|
if (!t)
|
|
8
8
|
return !1;
|
|
9
9
|
const { from: o, to: s } = e.selection;
|
|
10
10
|
return e.doc.rangeHasMark(o, o === s ? s + 1 : s, t);
|
|
11
|
-
},
|
|
11
|
+
}, H = (e) => {
|
|
12
12
|
const { selection: t } = e;
|
|
13
|
-
return t instanceof
|
|
14
|
-
},
|
|
13
|
+
return t instanceof p ? !!e.doc.textBetween(t.from, t.to) : !1;
|
|
14
|
+
}, I = (e) => Boolean(C((t) => !!t.type.spec.code)(e.selection)), O = (e, t) => !H(e) || I(e) || m(e, t), u = (e, t, o, s) => ({
|
|
15
15
|
icon: e,
|
|
16
16
|
onClick: t,
|
|
17
|
-
isHidden: () => (n) =>
|
|
18
|
-
isActive: () => (n) =>
|
|
17
|
+
isHidden: () => (n) => O(n.state, s),
|
|
18
|
+
isActive: () => (n) => m(n.state, o),
|
|
19
19
|
canAddToDOM: () => (n) => !!o && !!n.state.schema.marks[o.name]
|
|
20
|
-
}),
|
|
21
|
-
const t = e.get(
|
|
20
|
+
}), w = (e) => {
|
|
21
|
+
const t = e.get(b).marks;
|
|
22
22
|
return [
|
|
23
23
|
u("bold", "ToggleBold", t.strong),
|
|
24
24
|
u("italic", "ToggleItalic", t.em),
|
|
@@ -26,39 +26,41 @@ const h = (e, t) => {
|
|
|
26
26
|
u("code", "ToggleInlineCode", t.code_inline),
|
|
27
27
|
u("link", "ToggleLink", t.link)
|
|
28
28
|
];
|
|
29
|
-
}, D = (e, t =
|
|
29
|
+
}, D = (e, t = w) => {
|
|
30
30
|
const o = ({ icon: s, onClick: n, isHidden: l, isActive: i, canAddToDOM: c }) => {
|
|
31
31
|
var r;
|
|
32
32
|
return {
|
|
33
|
-
$: typeof s == "function" ? s(e) : (r = e.get(
|
|
34
|
-
command: typeof n == "string" ? () => e.get(
|
|
33
|
+
$: typeof s == "function" ? s(e) : (r = e.get(L).get(k, s)) == null ? void 0 : r.dom,
|
|
34
|
+
command: typeof n == "string" ? () => e.get(P).call(n) : n(e),
|
|
35
35
|
disable: l(e),
|
|
36
36
|
active: i(e),
|
|
37
37
|
enable: c(e)
|
|
38
38
|
};
|
|
39
39
|
};
|
|
40
40
|
return t(e).map(o);
|
|
41
|
-
},
|
|
42
|
-
e.classList.remove("hide"),
|
|
41
|
+
}, W = (e, t, o) => {
|
|
42
|
+
e.classList.remove("hide"), M(t, e, (s, n, l, i) => {
|
|
43
43
|
const c = e.parentElement;
|
|
44
44
|
if (!c)
|
|
45
|
-
throw
|
|
45
|
+
throw A();
|
|
46
46
|
const r = n.left - s.left;
|
|
47
47
|
let a = s.left - i.left - (l.width - r) / 2, d = s.top - i.top - l.height - 14 + c.scrollTop;
|
|
48
|
-
|
|
48
|
+
a < 0 && (a = 0);
|
|
49
|
+
const f = c.clientWidth - (l.width + 4);
|
|
50
|
+
return a > f && (a = f), (d < c.scrollTop || o && i.bottom - s.bottom > l.height) && (d = s.bottom - i.top + 14 + c.scrollTop), [d, a];
|
|
49
51
|
});
|
|
50
|
-
},
|
|
51
|
-
const o = (n, l = 1) => e.get(
|
|
52
|
+
}, q = (e, { css: t }) => {
|
|
53
|
+
const o = (n, l = 1) => e.get(B, [n, l]), s = e.get(h, "lineWidth");
|
|
52
54
|
return t`
|
|
53
55
|
display: inline-flex;
|
|
54
56
|
cursor: pointer;
|
|
55
57
|
justify-content: space-evenly;
|
|
56
58
|
position: absolute;
|
|
57
|
-
border-radius: ${e.get(
|
|
59
|
+
border-radius: ${e.get(h, "radius")};
|
|
58
60
|
z-index: 2;
|
|
59
61
|
|
|
60
|
-
${e.get(P, void 0)}
|
|
61
62
|
${e.get(E, void 0)}
|
|
63
|
+
${e.get(x, void 0)}
|
|
62
64
|
|
|
63
65
|
overflow: hidden;
|
|
64
66
|
background: ${o("surface")};
|
|
@@ -95,7 +97,7 @@ const h = (e, t) => {
|
|
|
95
97
|
}, N = (e, t, o) => {
|
|
96
98
|
const s = document.createElement("div");
|
|
97
99
|
return t.themeManager.onFlush(() => {
|
|
98
|
-
const n = t.getStyle((l) =>
|
|
100
|
+
const n = t.getStyle((l) => q(t.themeManager, l)) || "";
|
|
99
101
|
n && s.classList.add(n);
|
|
100
102
|
}), s.classList.add(t.getClassName({}, o)), {
|
|
101
103
|
dom: s,
|
|
@@ -104,7 +106,7 @@ const h = (e, t) => {
|
|
|
104
106
|
e.filter((i) => i.enable(n) && i.$ != null).forEach(({ $: i }) => s.appendChild(i)), (l = n.dom.parentNode) == null || l.appendChild(s);
|
|
105
107
|
}
|
|
106
108
|
};
|
|
107
|
-
},
|
|
109
|
+
}, _ = (e, t) => Object.values(e).filter((o) => o.enable(t) && o.$ != null).every(({ $: o }) => o.classList.contains("hide")), j = (e, t) => (e.filter((o) => o.enable(t) && o.$ != null).forEach((o) => {
|
|
108
110
|
var l;
|
|
109
111
|
if ((l = o.disable) == null ? void 0 : l.call(o, t)) {
|
|
110
112
|
o.$.classList.add("hide");
|
|
@@ -115,7 +117,7 @@ const h = (e, t) => {
|
|
|
115
117
|
return;
|
|
116
118
|
}
|
|
117
119
|
o.$.classList.remove("active");
|
|
118
|
-
}),
|
|
120
|
+
}), _(e, t)), g = (e, t, o, s) => {
|
|
119
121
|
const { dom: n, render: l } = N(e, t, s), i = (r) => {
|
|
120
122
|
const a = e.find(({ $: d }) => r.target instanceof Element && d.contains(r.target));
|
|
121
123
|
!a || (r.stopPropagation(), r.preventDefault(), a.command());
|
|
@@ -128,15 +130,15 @@ const h = (e, t) => {
|
|
|
128
130
|
},
|
|
129
131
|
hide: c,
|
|
130
132
|
update: (r) => {
|
|
131
|
-
if (
|
|
133
|
+
if (j(e, r)) {
|
|
132
134
|
c();
|
|
133
135
|
return;
|
|
134
136
|
}
|
|
135
|
-
|
|
137
|
+
W(n, r, o);
|
|
136
138
|
},
|
|
137
139
|
render: l
|
|
138
140
|
};
|
|
139
|
-
},
|
|
141
|
+
}, z = (e, t, o, s) => {
|
|
140
142
|
let n = g(e, t, o, s), l = !1;
|
|
141
143
|
const i = () => {
|
|
142
144
|
n.hide();
|
|
@@ -163,13 +165,13 @@ const h = (e, t) => {
|
|
|
163
165
|
l = r;
|
|
164
166
|
}
|
|
165
167
|
};
|
|
166
|
-
},
|
|
168
|
+
}, F = new T("MILKDOWN_TOOLTIP"), K = $((e, t) => ({
|
|
167
169
|
id: "tooltip",
|
|
168
170
|
prosePlugins: (o, s) => {
|
|
169
171
|
var i;
|
|
170
|
-
const n =
|
|
171
|
-
return [new
|
|
172
|
-
key:
|
|
172
|
+
const n = z(D(s, t == null ? void 0 : t.items), e, (i = t == null ? void 0 : t.bottom) != null ? i : !1, "tooltip");
|
|
173
|
+
return [new v({
|
|
174
|
+
key: F,
|
|
173
175
|
props: {
|
|
174
176
|
handleClick: (c) => (n.setHide(!1), n.update(c), !1),
|
|
175
177
|
handleDOMEvents: {
|
|
@@ -182,13 +184,13 @@ const h = (e, t) => {
|
|
|
182
184
|
})
|
|
183
185
|
})];
|
|
184
186
|
}
|
|
185
|
-
})), U =
|
|
187
|
+
})), U = y.create([K()]);
|
|
186
188
|
export {
|
|
187
189
|
D as buttonMap,
|
|
188
190
|
u as createToggleIcon,
|
|
189
|
-
|
|
190
|
-
|
|
191
|
+
w as defaultButtons,
|
|
192
|
+
F as key,
|
|
191
193
|
U as tooltip,
|
|
192
|
-
|
|
194
|
+
K as tooltipPlugin
|
|
193
195
|
};
|
|
194
196
|
//# sourceMappingURL=index.es.js.map
|
package/lib/index.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es.js","sources":["../src/utility/prosemirror.ts","../src/item.ts","../src/button-manager/calc-button-pos.ts","../src/button-manager/style.ts","../src/button-manager/create-tooltip.ts","../src/button-manager/no-active.ts","../src/button-manager/filter-button.ts","../src/button-manager/index.ts","../src/selection-marks-tooltip.ts","../src/index.ts"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nimport { findParentNode } from '@milkdown/prose';\nimport { MarkType, Node, NodeType } from '@milkdown/prose/model';\nimport { EditorState, TextSelection } from '@milkdown/prose/state';\n\nexport type Position = {\n start: number;\n end: number;\n};\n\nexport const hasMark = (editorState: EditorState, type?: MarkType): boolean => {\n if (!type) {\n return false;\n }\n const { from, to } = editorState.selection;\n\n return editorState.doc.rangeHasMark(from, from === to ? to + 1 : to, type);\n};\n\nexport const isTextSelection = (editorState: EditorState): boolean => {\n const { selection } = editorState;\n if (selection instanceof TextSelection) {\n const text = editorState.doc.textBetween(selection.from, selection.to);\n\n if (!text) return false;\n\n return true;\n }\n return false;\n};\n\nexport const isInCodeFence = (editorState: EditorState): boolean =>\n Boolean(findParentNode((node) => !!node.type.spec.code)(editorState.selection));\n\nexport const isTextAndNotHasMark = (editorState: EditorState, mark?: MarkType): boolean =>\n !isTextSelection(editorState) || isInCodeFence(editorState) || hasMark(editorState, mark);\n\nexport const equalNodeType = (nodeType: NodeType, node: Node) => {\n return (Array.isArray(nodeType) && nodeType.indexOf(node.type) > -1) || node.type === nodeType;\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { commandsCtx, Ctx, schemaCtx, ThemeIcon, themeManagerCtx } from '@milkdown/core';\nimport type { Icon } from '@milkdown/design-system';\nimport type { MarkType } from '@milkdown/prose/model';\nimport { EditorView } from '@milkdown/prose/view';\n\nimport { hasMark, isTextAndNotHasMark } from './utility';\n\nexport type Pred = (view: EditorView) => boolean;\nexport type Updater = (view: EditorView, $: HTMLElement) => void;\nexport type Event2Command = (e: Event) => void;\n\nexport type OnClick = (ctx: Ctx) => void;\n\nexport type Item = {\n icon: Icon | ((ctx: Ctx) => HTMLElement);\n onClick: string | ((ctx: Ctx) => () => void);\n isHidden: (ctx: Ctx) => Pred;\n isActive: (ctx: Ctx) => Pred;\n canAddToDOM: (ctx: Ctx) => Pred;\n};\n\nexport type ButtonItem = {\n $: HTMLElement;\n command: () => void;\n active: Pred;\n disable?: Pred;\n enable: Pred;\n};\n\nexport const createToggleIcon = (icon: Icon, onClick: string, mark?: MarkType, disableForMark?: MarkType): Item => ({\n icon,\n onClick,\n isHidden: () => (view: EditorView) => isTextAndNotHasMark(view.state, disableForMark),\n isActive: () => (view: EditorView) => hasMark(view.state, mark),\n canAddToDOM: () => (view: EditorView) => !!mark && !!view.state.schema.marks[mark.name],\n});\n\nexport const defaultButtons = (ctx: Ctx) => {\n const marks = ctx.get(schemaCtx).marks;\n return [\n createToggleIcon('bold', 'ToggleBold', marks['strong']),\n createToggleIcon('italic', 'ToggleItalic', marks['em']),\n createToggleIcon('strikeThrough', 'ToggleStrikeThrough', marks['strike_through']),\n createToggleIcon('code', 'ToggleInlineCode', marks['code_inline']),\n createToggleIcon('link', 'ToggleLink', marks['link']),\n ];\n};\n\nexport type ButtonList = ButtonItem[];\n\nexport type TooltipOptions = {\n bottom: boolean;\n items: (ctx: Ctx) => Array<Item>;\n};\n\nexport const buttonMap = (ctx: Ctx, items: (ctx: Ctx) => Array<Item> = defaultButtons): ButtonList => {\n const toButton = ({ icon, onClick, isHidden, isActive, canAddToDOM }: Item): ButtonItem => ({\n $: typeof icon === 'function' ? icon(ctx) : (ctx.get(themeManagerCtx).get(ThemeIcon, icon)?.dom as HTMLElement),\n command: typeof onClick === 'string' ? () => ctx.get(commandsCtx).call(onClick) : onClick(ctx),\n disable: isHidden(ctx),\n active: isActive(ctx),\n enable: canAddToDOM(ctx),\n });\n return items(ctx).map(toButton);\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { missingRootElement } from '@milkdown/exception';\nimport { calculateTextPosition } from '@milkdown/prose';\nimport { EditorView } from '@milkdown/prose/view';\n\nexport const calcButtonPos = (buttons: HTMLElement, view: EditorView, isBottom: boolean) => {\n buttons.classList.remove('hide');\n calculateTextPosition(view, buttons, (start, end, target, parent) => {\n const $editor = buttons.parentElement;\n if (!$editor) {\n throw missingRootElement();\n }\n const selectionWidth = end.left - start.left;\n let left = start.left - parent.left - (target.width - selectionWidth) / 2;\n let top = start.top - parent.top - target.height - 14 + $editor.scrollTop;\n\n if (left < 0) left = 0;\n\n if (start.top - parent.top < target.height || (isBottom && parent.bottom - start.bottom > target.height)) {\n top = start.bottom - parent.top + 14 + $editor.scrollTop;\n }\n return [top, left];\n });\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Color, Emotion, ThemeBorder, ThemeColor, ThemeManager, ThemeShadow, ThemeSize } from '@milkdown/core';\n\nexport const injectStyle = (themeManager: ThemeManager, { css }: Emotion) => {\n const palette = (color: Color, opacity = 1) => themeManager.get(ThemeColor, [color, opacity]);\n const lineWidth = themeManager.get(ThemeSize, 'lineWidth');\n return css`\n display: inline-flex;\n cursor: pointer;\n justify-content: space-evenly;\n position: absolute;\n border-radius: ${themeManager.get(ThemeSize, 'radius')};\n z-index: 2;\n\n ${themeManager.get(ThemeBorder, undefined)}\n ${themeManager.get(ThemeShadow, undefined)}\n\n overflow: hidden;\n background: ${palette('surface')};\n\n .icon {\n position: relative;\n color: ${palette('solid', 0.87)};\n\n width: 48px;\n line-height: 48px;\n text-align: center;\n transition: all 0.4s ease-in-out;\n &:hover {\n background-color: ${palette('secondary', 0.12)};\n }\n &.active {\n color: ${palette('primary')};\n }\n &:not(:last-child)::after {\n content: '';\n position: absolute;\n top: 0;\n right: calc(-0.5 * ${lineWidth});\n width: ${lineWidth};\n bottom: 0;\n background: ${palette('line')};\n }\n }\n &.hide,\n .hide {\n display: none;\n }\n `;\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorView } from '@milkdown/prose/view';\nimport type { ThemeUtils } from '@milkdown/utils';\n\nimport type { ButtonList } from '../item';\nimport { injectStyle } from './style';\n\ntype Tooltip = {\n dom: HTMLDivElement;\n render: (editorView: EditorView) => void;\n};\n\nexport const createTooltip = (buttonMap: ButtonList, utils: ThemeUtils, className: string): Tooltip => {\n const div = document.createElement('div');\n utils.themeManager.onFlush(() => {\n const style = utils.getStyle((emotion) => injectStyle(utils.themeManager, emotion)) || '';\n if (style) {\n div.classList.add(style);\n }\n });\n\n div.classList.add(utils.getClassName({}, className));\n\n return {\n dom: div,\n render: (editorView: EditorView) => {\n buttonMap\n .filter((item) => item.enable(editorView) && item.$ != null)\n .forEach(({ $ }) => div.appendChild($));\n\n editorView.dom.parentNode?.appendChild(div);\n },\n };\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { EditorView } from '@milkdown/prose/view';\n\nimport { ButtonList } from '../item';\n\nexport const noActive = (buttonMap: ButtonList, view: EditorView) => {\n return Object.values(buttonMap)\n .filter((item) => item.enable(view) && item.$ != null)\n .every(({ $ }) => $.classList.contains('hide'));\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { EditorView } from '@milkdown/prose/view';\n\nimport { ButtonList } from '../item';\nimport { noActive } from './no-active';\n\nexport const filterButton = (buttons: ButtonList, view: EditorView) => {\n buttons\n .filter((item) => item.enable(view) && item.$ != null)\n .forEach((item) => {\n const disable = item.disable?.(view);\n if (disable) {\n item.$.classList.add('hide');\n return;\n }\n\n item.$.classList.remove('hide');\n\n const active = item.active(view);\n if (active) {\n item.$.classList.add('active');\n return;\n }\n item.$.classList.remove('active');\n });\n\n return noActive(buttons, view);\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorView } from '@milkdown/prose/view';\nimport type { ThemeUtils } from '@milkdown/utils';\n\nimport type { ButtonList } from '../item';\nimport { calcButtonPos } from './calc-button-pos';\nimport { createTooltip } from './create-tooltip';\nimport { filterButton } from './filter-button';\n\nexport const createButtonManager = (\n buttons: ButtonList,\n utils: ThemeUtils,\n bottom: boolean,\n containerClassName: string,\n) => {\n const { dom: buttonDOM, render } = createTooltip(buttons, utils, containerClassName);\n\n const onClick = (e: Event) => {\n const target = buttons.find(({ $ }) => e.target instanceof Element && $.contains(e.target));\n if (!target) return;\n\n e.stopPropagation();\n e.preventDefault();\n target.command();\n };\n\n const hide = () => {\n buttonDOM.classList.add('hide');\n };\n\n buttonDOM.addEventListener('mousedown', onClick);\n\n return {\n destroy: () => {\n buttonDOM.removeEventListener('mousedown', onClick);\n buttonDOM.remove();\n },\n hide,\n update: (editorView: EditorView) => {\n const noActive = filterButton(buttons, editorView);\n if (noActive) {\n hide();\n return;\n }\n calcButtonPos(buttonDOM, editorView, bottom);\n },\n render,\n };\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { EditorState } from '@milkdown/prose/state';\nimport type { EditorView } from '@milkdown/prose/view';\nimport { ThemeUtils } from '@milkdown/utils';\n\nimport { createButtonManager } from './button-manager';\nimport type { ButtonList } from './item';\n\nexport const createPlugin = (buttonMap: ButtonList, utils: ThemeUtils, bottom: boolean, containerClassName: string) => {\n let buttonManager = createButtonManager(buttonMap, utils, bottom, containerClassName);\n let shouldHide = false;\n\n const hide = () => {\n buttonManager.hide();\n };\n\n const update = (view: EditorView, prevState?: EditorState) => {\n const { state } = view;\n\n if (!view.editable || shouldHide) {\n hide();\n return;\n }\n\n const isEqualSelection = prevState?.doc.eq(state.doc) && prevState.selection.eq(state.selection);\n if (isEqualSelection) return;\n\n buttonManager.update(view);\n };\n\n return {\n recreate: (editorView: EditorView) => {\n buttonManager = createButtonManager(buttonMap, utils, bottom, containerClassName);\n buttonManager.render(editorView);\n update(editorView);\n },\n update,\n destroy: () => {\n buttonManager.destroy();\n },\n render: (editorView: EditorView) => {\n buttonManager.render(editorView);\n update(editorView);\n },\n setHide: (isTyping: boolean) => {\n shouldHide = isTyping;\n },\n };\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Plugin, PluginKey } from '@milkdown/prose/state';\nimport { AtomList, createPlugin as create } from '@milkdown/utils';\n\nimport { buttonMap, TooltipOptions } from './item';\nimport { createPlugin } from './selection-marks-tooltip';\n\nexport const key = new PluginKey('MILKDOWN_TOOLTIP');\nexport * from './item';\n\nexport const tooltipPlugin = create<string, TooltipOptions>((utils, options) => {\n return {\n id: 'tooltip',\n prosePlugins: (_, ctx) => {\n const manager = createPlugin(buttonMap(ctx, options?.items), utils, options?.bottom ?? false, 'tooltip');\n const plugin = new Plugin({\n key,\n props: {\n handleClick: (view) => {\n manager.setHide(false);\n manager.update(view);\n return false;\n },\n handleDOMEvents: {\n mousedown: () => {\n manager.setHide(false);\n return false;\n },\n },\n },\n view: (editorView) => {\n manager.recreate(editorView);\n return {\n update: manager.update,\n destroy: manager.destroy,\n };\n },\n });\n return [plugin];\n },\n };\n});\n\nexport const tooltip = AtomList.create([tooltipPlugin()]);\n"],"names":["create"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../src/utility/prosemirror.ts","../src/item.ts","../src/button-manager/calc-button-pos.ts","../src/button-manager/style.ts","../src/button-manager/create-tooltip.ts","../src/button-manager/no-active.ts","../src/button-manager/filter-button.ts","../src/button-manager/index.ts","../src/selection-marks-tooltip.ts","../src/index.ts"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nimport { findParentNode } from '@milkdown/prose'\nimport type { MarkType, Node, NodeType } from '@milkdown/prose/model'\nimport type { EditorState } from '@milkdown/prose/state'\nimport { TextSelection } from '@milkdown/prose/state'\n\nexport interface Position {\n start: number\n end: number\n}\n\nexport const hasMark = (editorState: EditorState, type?: MarkType): boolean => {\n if (!type)\n return false\n\n const { from, to } = editorState.selection\n\n return editorState.doc.rangeHasMark(from, from === to ? to + 1 : to, type)\n}\n\nexport const isTextSelection = (editorState: EditorState): boolean => {\n const { selection } = editorState\n if (selection instanceof TextSelection) {\n const text = editorState.doc.textBetween(selection.from, selection.to)\n\n if (!text)\n return false\n\n return true\n }\n return false\n}\n\nexport const isInCodeFence = (editorState: EditorState): boolean =>\n Boolean(findParentNode(node => !!node.type.spec.code)(editorState.selection))\n\nexport const isTextAndNotHasMark = (editorState: EditorState, mark?: MarkType): boolean =>\n !isTextSelection(editorState) || isInCodeFence(editorState) || hasMark(editorState, mark)\n\nexport const equalNodeType = (nodeType: NodeType, node: Node) => {\n return (Array.isArray(nodeType) && nodeType.includes(node.type)) || node.type === nodeType\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { Ctx } from '@milkdown/core'\nimport { ThemeIcon, commandsCtx, schemaCtx, themeManagerCtx } from '@milkdown/core'\nimport type { Icon } from '@milkdown/design-system'\nimport type { MarkType } from '@milkdown/prose/model'\nimport type { EditorView } from '@milkdown/prose/view'\n\nimport { hasMark, isTextAndNotHasMark } from './utility'\n\nexport type Pred = (view: EditorView) => boolean\nexport type Updater = (view: EditorView, $: HTMLElement) => void\nexport type Event2Command = (e: Event) => void\n\nexport type OnClick = (ctx: Ctx) => void\n\nexport interface Item {\n icon: Icon | ((ctx: Ctx) => HTMLElement)\n onClick: string | ((ctx: Ctx) => () => void)\n isHidden: (ctx: Ctx) => Pred\n isActive: (ctx: Ctx) => Pred\n canAddToDOM: (ctx: Ctx) => Pred\n}\n\nexport interface ButtonItem {\n $: HTMLElement\n command: () => void\n active: Pred\n disable?: Pred\n enable: Pred\n}\n\nexport const createToggleIcon = (icon: Icon, onClick: string, mark?: MarkType, disableForMark?: MarkType): Item => ({\n icon,\n onClick,\n isHidden: () => (view: EditorView) => isTextAndNotHasMark(view.state, disableForMark),\n isActive: () => (view: EditorView) => hasMark(view.state, mark),\n canAddToDOM: () => (view: EditorView) => !!mark && !!view.state.schema.marks[mark.name],\n})\n\nexport const defaultButtons = (ctx: Ctx) => {\n const marks = ctx.get(schemaCtx).marks\n return [\n createToggleIcon('bold', 'ToggleBold', marks.strong),\n createToggleIcon('italic', 'ToggleItalic', marks.em),\n createToggleIcon('strikeThrough', 'ToggleStrikeThrough', marks.strike_through),\n createToggleIcon('code', 'ToggleInlineCode', marks.code_inline),\n createToggleIcon('link', 'ToggleLink', marks.link),\n ]\n}\n\nexport type ButtonList = ButtonItem[]\n\nexport interface TooltipOptions {\n bottom: boolean\n items: (ctx: Ctx) => Array<Item>\n}\n\nexport const buttonMap = (ctx: Ctx, items: (ctx: Ctx) => Array<Item> = defaultButtons): ButtonList => {\n const toButton = ({ icon, onClick, isHidden, isActive, canAddToDOM }: Item): ButtonItem => ({\n $: typeof icon === 'function' ? icon(ctx) : (ctx.get(themeManagerCtx).get(ThemeIcon, icon)?.dom as HTMLElement),\n command: typeof onClick === 'string' ? () => ctx.get(commandsCtx).call(onClick) : onClick(ctx),\n disable: isHidden(ctx),\n active: isActive(ctx),\n enable: canAddToDOM(ctx),\n })\n return items(ctx).map(toButton)\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { missingRootElement } from '@milkdown/exception'\nimport { calculateTextPosition } from '@milkdown/prose'\nimport type { EditorView } from '@milkdown/prose/view'\n\nexport const calcButtonPos = (buttons: HTMLElement, view: EditorView, isBottom: boolean) => {\n buttons.classList.remove('hide')\n calculateTextPosition(view, buttons, (start, end, target, parent) => {\n const $editor = buttons.parentElement\n if (!$editor)\n throw missingRootElement()\n\n const selectionWidth = end.left - start.left\n let left = start.left - parent.left - (target.width - selectionWidth) / 2\n let top = start.top - parent.top - target.height - 14 + $editor.scrollTop\n\n if (left < 0)\n left = 0\n\n const maxLeft = $editor.clientWidth - (target.width + 4)\n if (left > maxLeft)\n left = maxLeft\n\n if (top < $editor.scrollTop || (isBottom && parent.bottom - start.bottom > target.height))\n top = start.bottom - parent.top + 14 + $editor.scrollTop\n\n return [top, left]\n })\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { Color, Emotion, ThemeManager } from '@milkdown/core'\nimport { ThemeBorder, ThemeColor, ThemeShadow, ThemeSize } from '@milkdown/core'\n\nexport const injectStyle = (themeManager: ThemeManager, { css }: Emotion) => {\n const palette = (color: Color, opacity = 1) => themeManager.get(ThemeColor, [color, opacity])\n const lineWidth = themeManager.get(ThemeSize, 'lineWidth')\n return css`\n display: inline-flex;\n cursor: pointer;\n justify-content: space-evenly;\n position: absolute;\n border-radius: ${themeManager.get(ThemeSize, 'radius')};\n z-index: 2;\n\n ${themeManager.get(ThemeBorder, undefined)}\n ${themeManager.get(ThemeShadow, undefined)}\n\n overflow: hidden;\n background: ${palette('surface')};\n\n .icon {\n position: relative;\n color: ${palette('solid', 0.87)};\n\n width: 48px;\n line-height: 48px;\n text-align: center;\n transition: all 0.4s ease-in-out;\n &:hover {\n background-color: ${palette('secondary', 0.12)};\n }\n &.active {\n color: ${palette('primary')};\n }\n &:not(:last-child)::after {\n content: '';\n position: absolute;\n top: 0;\n right: calc(-0.5 * ${lineWidth});\n width: ${lineWidth};\n bottom: 0;\n background: ${palette('line')};\n }\n }\n &.hide,\n .hide {\n display: none;\n }\n `\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorView } from '@milkdown/prose/view'\nimport type { ThemeUtils } from '@milkdown/utils'\n\nimport type { ButtonList } from '../item'\nimport { injectStyle } from './style'\n\ninterface Tooltip {\n dom: HTMLDivElement\n render: (editorView: EditorView) => void\n}\n\nexport const createTooltip = (buttonMap: ButtonList, utils: ThemeUtils, className: string): Tooltip => {\n const div = document.createElement('div')\n utils.themeManager.onFlush(() => {\n const style = utils.getStyle(emotion => injectStyle(utils.themeManager, emotion)) || ''\n if (style)\n div.classList.add(style)\n })\n\n div.classList.add(utils.getClassName({}, className))\n\n return {\n dom: div,\n render: (editorView: EditorView) => {\n buttonMap\n .filter(item => item.enable(editorView) && item.$ != null)\n .forEach(({ $ }) => div.appendChild($))\n\n editorView.dom.parentNode?.appendChild(div)\n },\n }\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorView } from '@milkdown/prose/view'\n\nimport type { ButtonList } from '../item'\n\nexport const noActive = (buttonMap: ButtonList, view: EditorView) => {\n return Object.values(buttonMap)\n .filter(item => item.enable(view) && item.$ != null)\n .every(({ $ }) => $.classList.contains('hide'))\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorView } from '@milkdown/prose/view'\n\nimport type { ButtonList } from '../item'\nimport { noActive } from './no-active'\n\nexport const filterButton = (buttons: ButtonList, view: EditorView) => {\n buttons\n .filter(item => item.enable(view) && item.$ != null)\n .forEach((item) => {\n const disable = item.disable?.(view)\n if (disable) {\n item.$.classList.add('hide')\n return\n }\n\n item.$.classList.remove('hide')\n\n const active = item.active(view)\n if (active) {\n item.$.classList.add('active')\n return\n }\n item.$.classList.remove('active')\n })\n\n return noActive(buttons, view)\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorView } from '@milkdown/prose/view'\nimport type { ThemeUtils } from '@milkdown/utils'\n\nimport type { ButtonList } from '../item'\nimport { calcButtonPos } from './calc-button-pos'\nimport { createTooltip } from './create-tooltip'\nimport { filterButton } from './filter-button'\n\nexport const createButtonManager = (\n buttons: ButtonList,\n utils: ThemeUtils,\n bottom: boolean,\n containerClassName: string,\n) => {\n const { dom: buttonDOM, render } = createTooltip(buttons, utils, containerClassName)\n\n const onClick = (e: Event) => {\n const target = buttons.find(({ $ }) => e.target instanceof Element && $.contains(e.target))\n if (!target)\n return\n\n e.stopPropagation()\n e.preventDefault()\n target.command()\n }\n\n const hide = () => {\n buttonDOM.classList.add('hide')\n }\n\n buttonDOM.addEventListener('mousedown', onClick)\n\n return {\n destroy: () => {\n buttonDOM.removeEventListener('mousedown', onClick)\n buttonDOM.remove()\n },\n hide,\n update: (editorView: EditorView) => {\n const noActive = filterButton(buttons, editorView)\n if (noActive) {\n hide()\n return\n }\n calcButtonPos(buttonDOM, editorView, bottom)\n },\n render,\n }\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorState } from '@milkdown/prose/state'\nimport type { EditorView } from '@milkdown/prose/view'\nimport type { ThemeUtils } from '@milkdown/utils'\n\nimport { createButtonManager } from './button-manager'\nimport type { ButtonList } from './item'\n\nexport const createPlugin = (buttonMap: ButtonList, utils: ThemeUtils, bottom: boolean, containerClassName: string) => {\n let buttonManager = createButtonManager(buttonMap, utils, bottom, containerClassName)\n let shouldHide = false\n\n const hide = () => {\n buttonManager.hide()\n }\n\n const update = (view: EditorView, prevState?: EditorState) => {\n const { state } = view\n\n if (!view.editable || shouldHide) {\n hide()\n return\n }\n\n const isEqualSelection = prevState?.doc.eq(state.doc) && prevState.selection.eq(state.selection)\n if (isEqualSelection)\n return\n\n buttonManager.update(view)\n }\n\n return {\n recreate: (editorView: EditorView) => {\n buttonManager = createButtonManager(buttonMap, utils, bottom, containerClassName)\n buttonManager.render(editorView)\n update(editorView)\n },\n update,\n destroy: () => {\n buttonManager.destroy()\n },\n render: (editorView: EditorView) => {\n buttonManager.render(editorView)\n update(editorView)\n },\n setHide: (isTyping: boolean) => {\n shouldHide = isTyping\n },\n }\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Plugin, PluginKey } from '@milkdown/prose/state'\nimport { AtomList, createPlugin as create } from '@milkdown/utils'\n\nimport type { TooltipOptions } from './item'\nimport { buttonMap } from './item'\nimport { createPlugin } from './selection-marks-tooltip'\n\nexport const key = new PluginKey('MILKDOWN_TOOLTIP')\nexport * from './item'\n\nexport const tooltipPlugin = create<string, TooltipOptions>((utils, options) => {\n return {\n id: 'tooltip',\n prosePlugins: (_, ctx) => {\n const manager = createPlugin(buttonMap(ctx, options?.items), utils, options?.bottom ?? false, 'tooltip')\n const plugin = new Plugin({\n key,\n props: {\n handleClick: (view) => {\n manager.setHide(false)\n manager.update(view)\n return false\n },\n handleDOMEvents: {\n mousedown: () => {\n manager.setHide(false)\n return false\n },\n },\n },\n view: (editorView) => {\n manager.recreate(editorView)\n return {\n update: manager.update,\n destroy: manager.destroy,\n }\n },\n })\n return [plugin]\n },\n }\n})\n\nexport const tooltip = AtomList.create([tooltipPlugin()])\n"],"names":["hasMark","editorState","type","from","to","isTextSelection","selection","TextSelection","isInCodeFence","findParentNode","node","isTextAndNotHasMark","mark","createToggleIcon","icon","onClick","disableForMark","view","defaultButtons","ctx","marks","schemaCtx","buttonMap","items","toButton","isHidden","isActive","canAddToDOM","_a","themeManagerCtx","ThemeIcon","commandsCtx","calcButtonPos","buttons","isBottom","calculateTextPosition","start","end","target","parent","$editor","missingRootElement","selectionWidth","left","top","maxLeft","injectStyle","themeManager","css","palette","color","opacity","ThemeColor","lineWidth","ThemeSize","ThemeBorder","ThemeShadow","createTooltip","utils","className","div","style","emotion","editorView","item","$","noActive","filterButton","createButtonManager","bottom","containerClassName","buttonDOM","render","e","hide","createPlugin","buttonManager","shouldHide","update","prevState","state","isTyping","key","PluginKey","tooltipPlugin","create","options","_","manager","Plugin","tooltip","AtomList"],"mappings":"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"}
|
package/lib/item.d.ts
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
import { Ctx } from '@milkdown/core';
|
|
1
|
+
import type { Ctx } from '@milkdown/core';
|
|
2
2
|
import type { Icon } from '@milkdown/design-system';
|
|
3
3
|
import type { MarkType } from '@milkdown/prose/model';
|
|
4
|
-
import { EditorView } from '@milkdown/prose/view';
|
|
5
|
-
export
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
export
|
|
9
|
-
export
|
|
4
|
+
import type { EditorView } from '@milkdown/prose/view';
|
|
5
|
+
export type Pred = (view: EditorView) => boolean;
|
|
6
|
+
export type Updater = (view: EditorView, $: HTMLElement) => void;
|
|
7
|
+
export type Event2Command = (e: Event) => void;
|
|
8
|
+
export type OnClick = (ctx: Ctx) => void;
|
|
9
|
+
export interface Item {
|
|
10
10
|
icon: Icon | ((ctx: Ctx) => HTMLElement);
|
|
11
11
|
onClick: string | ((ctx: Ctx) => () => void);
|
|
12
12
|
isHidden: (ctx: Ctx) => Pred;
|
|
13
13
|
isActive: (ctx: Ctx) => Pred;
|
|
14
14
|
canAddToDOM: (ctx: Ctx) => Pred;
|
|
15
|
-
}
|
|
16
|
-
export
|
|
15
|
+
}
|
|
16
|
+
export interface ButtonItem {
|
|
17
17
|
$: HTMLElement;
|
|
18
18
|
command: () => void;
|
|
19
19
|
active: Pred;
|
|
20
20
|
disable?: Pred;
|
|
21
21
|
enable: Pred;
|
|
22
|
-
}
|
|
22
|
+
}
|
|
23
23
|
export declare const createToggleIcon: (icon: Icon, onClick: string, mark?: MarkType, disableForMark?: MarkType) => Item;
|
|
24
24
|
export declare const defaultButtons: (ctx: Ctx) => Item[];
|
|
25
|
-
export
|
|
26
|
-
export
|
|
25
|
+
export type ButtonList = ButtonItem[];
|
|
26
|
+
export interface TooltipOptions {
|
|
27
27
|
bottom: boolean;
|
|
28
28
|
items: (ctx: Ctx) => Array<Item>;
|
|
29
|
-
}
|
|
29
|
+
}
|
|
30
30
|
export declare const buttonMap: (ctx: Ctx, items?: (ctx: Ctx) => Array<Item>) => ButtonList;
|
|
31
31
|
//# sourceMappingURL=item.d.ts.map
|
package/lib/item.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item.d.ts","sourceRoot":"","sources":["../src/item.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"item.d.ts","sourceRoot":"","sources":["../src/item.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAA;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAItD,MAAM,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAA;AAChD,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;AAChE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAA;AAE9C,MAAM,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAA;AAExC,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,WAAW,CAAC,CAAA;IACxC,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,IAAI,CAAC,CAAA;IAC5C,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAA;IAC5B,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAA;IAC5B,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAA;CAChC;AAED,MAAM,WAAW,UAAU;IACzB,CAAC,EAAE,WAAW,CAAA;IACd,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,MAAM,EAAE,IAAI,CAAA;IACZ,OAAO,CAAC,EAAE,IAAI,CAAA;IACd,MAAM,EAAE,IAAI,CAAA;CACb;AAED,eAAO,MAAM,gBAAgB,SAAU,IAAI,WAAW,MAAM,SAAS,QAAQ,mBAAmB,QAAQ,KAAG,IAMzG,CAAA;AAEF,eAAO,MAAM,cAAc,QAAS,GAAG,WAStC,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,EAAE,CAAA;AAErC,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAA;IACf,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,CAAA;CACjC;AAED,eAAO,MAAM,SAAS,QAAS,GAAG,gBAAe,GAAG,KAAK,MAAM,IAAI,CAAC,eASnE,CAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { EditorState } from '@milkdown/prose/state';
|
|
1
|
+
import type { EditorState } from '@milkdown/prose/state';
|
|
2
2
|
import type { EditorView } from '@milkdown/prose/view';
|
|
3
|
-
import { ThemeUtils } from '@milkdown/utils';
|
|
3
|
+
import type { ThemeUtils } from '@milkdown/utils';
|
|
4
4
|
import type { ButtonList } from './item';
|
|
5
5
|
export declare const createPlugin: (buttonMap: ButtonList, utils: ThemeUtils, bottom: boolean, containerClassName: string) => {
|
|
6
6
|
recreate: (editorView: EditorView) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection-marks-tooltip.d.ts","sourceRoot":"","sources":["../src/selection-marks-tooltip.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"selection-marks-tooltip.d.ts","sourceRoot":"","sources":["../src/selection-marks-tooltip.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAGjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AAExC,eAAO,MAAM,YAAY,iCAAkC,UAAU,UAAU,OAAO,sBAAsB,MAAM;2BAwBvF,UAAU;mBAhBb,UAAU,cAAc,WAAW;;yBAyBlC,UAAU;wBAIX,OAAO;CAI9B,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../../src/utility/element.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,YAAY,YAAa,WAAW,WAAW,MAAM,KAAG,
|
|
1
|
+
{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../../src/utility/element.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,YAAY,YAAa,WAAW,WAAW,MAAM,KAAG,OAC1B,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utility/index.ts"],"names":[],"mappings":"AACA,cAAc,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utility/index.ts"],"names":[],"mappings":"AACA,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { MarkType, Node, NodeType } from '@milkdown/prose/model';
|
|
2
|
-
import { EditorState } from '@milkdown/prose/state';
|
|
3
|
-
export
|
|
1
|
+
import type { MarkType, Node, NodeType } from '@milkdown/prose/model';
|
|
2
|
+
import type { EditorState } from '@milkdown/prose/state';
|
|
3
|
+
export interface Position {
|
|
4
4
|
start: number;
|
|
5
5
|
end: number;
|
|
6
|
-
}
|
|
6
|
+
}
|
|
7
7
|
export declare const hasMark: (editorState: EditorState, type?: MarkType) => boolean;
|
|
8
8
|
export declare const isTextSelection: (editorState: EditorState) => boolean;
|
|
9
9
|
export declare const isInCodeFence: (editorState: EditorState) => boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prosemirror.d.ts","sourceRoot":"","sources":["../../src/utility/prosemirror.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"prosemirror.d.ts","sourceRoot":"","sources":["../../src/utility/prosemirror.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAGxD,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,eAAO,MAAM,OAAO,gBAAiB,WAAW,SAAS,QAAQ,KAAG,OAOnE,CAAA;AAED,eAAO,MAAM,eAAe,gBAAiB,WAAW,KAAG,OAW1D,CAAA;AAED,eAAO,MAAM,aAAa,gBAAiB,WAAW,KAAG,OACsB,CAAA;AAE/E,eAAO,MAAM,mBAAmB,gBAAiB,WAAW,SAAS,QAAQ,KAAG,OACW,CAAA;AAE3F,eAAO,MAAM,aAAa,aAAc,QAAQ,QAAQ,IAAI,YAE3D,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milkdown/plugin-tooltip",
|
|
3
|
-
"version": "6.5.0",
|
|
4
3
|
"type": "module",
|
|
4
|
+
"version": "6.5.3",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"milkdown",
|
|
8
|
+
"milkdown plugin"
|
|
9
|
+
],
|
|
10
|
+
"sideEffects": false,
|
|
5
11
|
"main": "./lib/index.es.js",
|
|
6
12
|
"types": "./lib/index.d.ts",
|
|
7
|
-
"sideEffects": false,
|
|
8
|
-
"license": "MIT",
|
|
9
13
|
"files": [
|
|
10
14
|
"lib",
|
|
11
15
|
"src"
|
|
12
16
|
],
|
|
13
|
-
"keywords": [
|
|
14
|
-
"milkdown",
|
|
15
|
-
"milkdown plugin"
|
|
16
|
-
],
|
|
17
|
-
"devDependencies": {
|
|
18
|
-
"@milkdown/core": "6.5.0",
|
|
19
|
-
"@milkdown/prose": "6.5.0",
|
|
20
|
-
"@milkdown/design-system": "6.5.0"
|
|
21
|
-
},
|
|
22
17
|
"peerDependencies": {
|
|
23
18
|
"@milkdown/core": "^6.0.1",
|
|
24
19
|
"@milkdown/prose": "^6.0.1"
|
|
25
20
|
},
|
|
26
21
|
"dependencies": {
|
|
27
|
-
"
|
|
28
|
-
"@milkdown/exception": "6.5.
|
|
29
|
-
"
|
|
22
|
+
"tslib": "^2.4.0",
|
|
23
|
+
"@milkdown/exception": "6.5.3",
|
|
24
|
+
"@milkdown/utils": "6.5.3"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@milkdown/core": "6.5.3",
|
|
28
|
+
"@milkdown/design-system": "6.5.3",
|
|
29
|
+
"@milkdown/prose": "6.5.3"
|
|
30
30
|
},
|
|
31
31
|
"nx": {
|
|
32
32
|
"targets": {
|
|
@@ -1,24 +1,29 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { missingRootElement } from '@milkdown/exception'
|
|
3
|
-
import { calculateTextPosition } from '@milkdown/prose'
|
|
4
|
-
import { EditorView } from '@milkdown/prose/view'
|
|
2
|
+
import { missingRootElement } from '@milkdown/exception'
|
|
3
|
+
import { calculateTextPosition } from '@milkdown/prose'
|
|
4
|
+
import type { EditorView } from '@milkdown/prose/view'
|
|
5
5
|
|
|
6
6
|
export const calcButtonPos = (buttons: HTMLElement, view: EditorView, isBottom: boolean) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
const selectionWidth = end.left - start.left;
|
|
14
|
-
let left = start.left - parent.left - (target.width - selectionWidth) / 2;
|
|
15
|
-
let top = start.top - parent.top - target.height - 14 + $editor.scrollTop;
|
|
7
|
+
buttons.classList.remove('hide')
|
|
8
|
+
calculateTextPosition(view, buttons, (start, end, target, parent) => {
|
|
9
|
+
const $editor = buttons.parentElement
|
|
10
|
+
if (!$editor)
|
|
11
|
+
throw missingRootElement()
|
|
16
12
|
|
|
17
|
-
|
|
13
|
+
const selectionWidth = end.left - start.left
|
|
14
|
+
let left = start.left - parent.left - (target.width - selectionWidth) / 2
|
|
15
|
+
let top = start.top - parent.top - target.height - 14 + $editor.scrollTop
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
if (left < 0)
|
|
18
|
+
left = 0
|
|
19
|
+
|
|
20
|
+
const maxLeft = $editor.clientWidth - (target.width + 4)
|
|
21
|
+
if (left > maxLeft)
|
|
22
|
+
left = maxLeft
|
|
23
|
+
|
|
24
|
+
if (top < $editor.scrollTop || (isBottom && parent.bottom - start.bottom > target.height))
|
|
25
|
+
top = start.bottom - parent.top + 14 + $editor.scrollTop
|
|
26
|
+
|
|
27
|
+
return [top, left]
|
|
28
|
+
})
|
|
29
|
+
}
|
|
@@ -1,34 +1,33 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import type { EditorView } from '@milkdown/prose/view'
|
|
3
|
-
import type { ThemeUtils } from '@milkdown/utils'
|
|
2
|
+
import type { EditorView } from '@milkdown/prose/view'
|
|
3
|
+
import type { ThemeUtils } from '@milkdown/utils'
|
|
4
4
|
|
|
5
|
-
import type { ButtonList } from '../item'
|
|
6
|
-
import { injectStyle } from './style'
|
|
5
|
+
import type { ButtonList } from '../item'
|
|
6
|
+
import { injectStyle } from './style'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
8
|
+
interface Tooltip {
|
|
9
|
+
dom: HTMLDivElement
|
|
10
|
+
render: (editorView: EditorView) => void
|
|
11
|
+
}
|
|
12
12
|
|
|
13
13
|
export const createTooltip = (buttonMap: ButtonList, utils: ThemeUtils, className: string): Tooltip => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
});
|
|
14
|
+
const div = document.createElement('div')
|
|
15
|
+
utils.themeManager.onFlush(() => {
|
|
16
|
+
const style = utils.getStyle(emotion => injectStyle(utils.themeManager, emotion)) || ''
|
|
17
|
+
if (style)
|
|
18
|
+
div.classList.add(style)
|
|
19
|
+
})
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
div.classList.add(utils.getClassName({}, className))
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
return {
|
|
24
|
+
dom: div,
|
|
25
|
+
render: (editorView: EditorView) => {
|
|
26
|
+
buttonMap
|
|
27
|
+
.filter(item => item.enable(editorView) && item.$ != null)
|
|
28
|
+
.forEach(({ $ }) => div.appendChild($))
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
30
|
+
editorView.dom.parentNode?.appendChild(div)
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { EditorView } from '@milkdown/prose/view'
|
|
2
|
+
import type { EditorView } from '@milkdown/prose/view'
|
|
3
3
|
|
|
4
|
-
import { ButtonList } from '../item'
|
|
5
|
-
import { noActive } from './no-active'
|
|
4
|
+
import type { ButtonList } from '../item'
|
|
5
|
+
import { noActive } from './no-active'
|
|
6
6
|
|
|
7
7
|
export const filterButton = (buttons: ButtonList, view: EditorView) => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
buttons
|
|
9
|
+
.filter(item => item.enable(view) && item.$ != null)
|
|
10
|
+
.forEach((item) => {
|
|
11
|
+
const disable = item.disable?.(view)
|
|
12
|
+
if (disable) {
|
|
13
|
+
item.$.classList.add('hide')
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
item.$.classList.remove('hide')
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
const active = item.active(view)
|
|
20
|
+
if (active) {
|
|
21
|
+
item.$.classList.add('active')
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
item.$.classList.remove('active')
|
|
25
|
+
})
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
}
|
|
27
|
+
return noActive(buttons, view)
|
|
28
|
+
}
|
|
@@ -1,49 +1,50 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import type { EditorView } from '@milkdown/prose/view'
|
|
3
|
-
import type { ThemeUtils } from '@milkdown/utils'
|
|
2
|
+
import type { EditorView } from '@milkdown/prose/view'
|
|
3
|
+
import type { ThemeUtils } from '@milkdown/utils'
|
|
4
4
|
|
|
5
|
-
import type { ButtonList } from '../item'
|
|
6
|
-
import { calcButtonPos } from './calc-button-pos'
|
|
7
|
-
import { createTooltip } from './create-tooltip'
|
|
8
|
-
import { filterButton } from './filter-button'
|
|
5
|
+
import type { ButtonList } from '../item'
|
|
6
|
+
import { calcButtonPos } from './calc-button-pos'
|
|
7
|
+
import { createTooltip } from './create-tooltip'
|
|
8
|
+
import { filterButton } from './filter-button'
|
|
9
9
|
|
|
10
10
|
export const createButtonManager = (
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
buttons: ButtonList,
|
|
12
|
+
utils: ThemeUtils,
|
|
13
|
+
bottom: boolean,
|
|
14
|
+
containerClassName: string,
|
|
15
15
|
) => {
|
|
16
|
-
|
|
16
|
+
const { dom: buttonDOM, render } = createTooltip(buttons, utils, containerClassName)
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
const onClick = (e: Event) => {
|
|
19
|
+
const target = buttons.find(({ $ }) => e.target instanceof Element && $.contains(e.target))
|
|
20
|
+
if (!target)
|
|
21
|
+
return
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
e.stopPropagation()
|
|
24
|
+
e.preventDefault()
|
|
25
|
+
target.command()
|
|
26
|
+
}
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
const hide = () => {
|
|
29
|
+
buttonDOM.classList.add('hide')
|
|
30
|
+
}
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
buttonDOM.addEventListener('mousedown', onClick)
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
34
|
+
return {
|
|
35
|
+
destroy: () => {
|
|
36
|
+
buttonDOM.removeEventListener('mousedown', onClick)
|
|
37
|
+
buttonDOM.remove()
|
|
38
|
+
},
|
|
39
|
+
hide,
|
|
40
|
+
update: (editorView: EditorView) => {
|
|
41
|
+
const noActive = filterButton(buttons, editorView)
|
|
42
|
+
if (noActive) {
|
|
43
|
+
hide()
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
calcButtonPos(buttonDOM, editorView, bottom)
|
|
47
|
+
},
|
|
48
|
+
render,
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { EditorView } from '@milkdown/prose/view'
|
|
2
|
+
import type { EditorView } from '@milkdown/prose/view'
|
|
3
3
|
|
|
4
|
-
import { ButtonList } from '../item'
|
|
4
|
+
import type { ButtonList } from '../item'
|
|
5
5
|
|
|
6
6
|
export const noActive = (buttonMap: ButtonList, view: EditorView) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
7
|
+
return Object.values(buttonMap)
|
|
8
|
+
.filter(item => item.enable(view) && item.$ != null)
|
|
9
|
+
.every(({ $ }) => $.classList.contains('hide'))
|
|
10
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { Color, Emotion,
|
|
2
|
+
import type { Color, Emotion, ThemeManager } from '@milkdown/core'
|
|
3
|
+
import { ThemeBorder, ThemeColor, ThemeShadow, ThemeSize } from '@milkdown/core'
|
|
3
4
|
|
|
4
5
|
export const injectStyle = (themeManager: ThemeManager, { css }: Emotion) => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
const palette = (color: Color, opacity = 1) => themeManager.get(ThemeColor, [color, opacity])
|
|
7
|
+
const lineWidth = themeManager.get(ThemeSize, 'lineWidth')
|
|
8
|
+
return css`
|
|
8
9
|
display: inline-flex;
|
|
9
10
|
cursor: pointer;
|
|
10
11
|
justify-content: space-evenly;
|
|
@@ -46,5 +47,5 @@ export const injectStyle = (themeManager: ThemeManager, { css }: Emotion) => {
|
|
|
46
47
|
.hide {
|
|
47
48
|
display: none;
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
-
}
|
|
50
|
+
`
|
|
51
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,44 +1,45 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { Plugin, PluginKey } from '@milkdown/prose/state'
|
|
3
|
-
import { AtomList, createPlugin as create } from '@milkdown/utils'
|
|
2
|
+
import { Plugin, PluginKey } from '@milkdown/prose/state'
|
|
3
|
+
import { AtomList, createPlugin as create } from '@milkdown/utils'
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import type { TooltipOptions } from './item'
|
|
6
|
+
import { buttonMap } from './item'
|
|
7
|
+
import { createPlugin } from './selection-marks-tooltip'
|
|
7
8
|
|
|
8
|
-
export const key = new PluginKey('MILKDOWN_TOOLTIP')
|
|
9
|
-
export * from './item'
|
|
9
|
+
export const key = new PluginKey('MILKDOWN_TOOLTIP')
|
|
10
|
+
export * from './item'
|
|
10
11
|
|
|
11
12
|
export const tooltipPlugin = create<string, TooltipOptions>((utils, options) => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
},
|
|
31
|
-
view: (editorView) => {
|
|
32
|
-
manager.recreate(editorView);
|
|
33
|
-
return {
|
|
34
|
-
update: manager.update,
|
|
35
|
-
destroy: manager.destroy,
|
|
36
|
-
};
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
return [plugin];
|
|
13
|
+
return {
|
|
14
|
+
id: 'tooltip',
|
|
15
|
+
prosePlugins: (_, ctx) => {
|
|
16
|
+
const manager = createPlugin(buttonMap(ctx, options?.items), utils, options?.bottom ?? false, 'tooltip')
|
|
17
|
+
const plugin = new Plugin({
|
|
18
|
+
key,
|
|
19
|
+
props: {
|
|
20
|
+
handleClick: (view) => {
|
|
21
|
+
manager.setHide(false)
|
|
22
|
+
manager.update(view)
|
|
23
|
+
return false
|
|
24
|
+
},
|
|
25
|
+
handleDOMEvents: {
|
|
26
|
+
mousedown: () => {
|
|
27
|
+
manager.setHide(false)
|
|
28
|
+
return false
|
|
29
|
+
},
|
|
30
|
+
},
|
|
40
31
|
},
|
|
41
|
-
|
|
42
|
-
|
|
32
|
+
view: (editorView) => {
|
|
33
|
+
manager.recreate(editorView)
|
|
34
|
+
return {
|
|
35
|
+
update: manager.update,
|
|
36
|
+
destroy: manager.destroy,
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
})
|
|
40
|
+
return [plugin]
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
})
|
|
43
44
|
|
|
44
|
-
export const tooltip = AtomList.create([tooltipPlugin()])
|
|
45
|
+
export const tooltip = AtomList.create([tooltipPlugin()])
|
package/src/item.ts
CHANGED
|
@@ -1,66 +1,67 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import type {
|
|
5
|
-
import {
|
|
2
|
+
import type { Ctx } from '@milkdown/core'
|
|
3
|
+
import { ThemeIcon, commandsCtx, schemaCtx, themeManagerCtx } from '@milkdown/core'
|
|
4
|
+
import type { Icon } from '@milkdown/design-system'
|
|
5
|
+
import type { MarkType } from '@milkdown/prose/model'
|
|
6
|
+
import type { EditorView } from '@milkdown/prose/view'
|
|
6
7
|
|
|
7
|
-
import { hasMark, isTextAndNotHasMark } from './utility'
|
|
8
|
+
import { hasMark, isTextAndNotHasMark } from './utility'
|
|
8
9
|
|
|
9
|
-
export type Pred = (view: EditorView) => boolean
|
|
10
|
-
export type Updater = (view: EditorView, $: HTMLElement) => void
|
|
11
|
-
export type Event2Command = (e: Event) => void
|
|
10
|
+
export type Pred = (view: EditorView) => boolean
|
|
11
|
+
export type Updater = (view: EditorView, $: HTMLElement) => void
|
|
12
|
+
export type Event2Command = (e: Event) => void
|
|
12
13
|
|
|
13
|
-
export type OnClick = (ctx: Ctx) => void
|
|
14
|
+
export type OnClick = (ctx: Ctx) => void
|
|
14
15
|
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
16
|
+
export interface Item {
|
|
17
|
+
icon: Icon | ((ctx: Ctx) => HTMLElement)
|
|
18
|
+
onClick: string | ((ctx: Ctx) => () => void)
|
|
19
|
+
isHidden: (ctx: Ctx) => Pred
|
|
20
|
+
isActive: (ctx: Ctx) => Pred
|
|
21
|
+
canAddToDOM: (ctx: Ctx) => Pred
|
|
22
|
+
}
|
|
22
23
|
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
24
|
+
export interface ButtonItem {
|
|
25
|
+
$: HTMLElement
|
|
26
|
+
command: () => void
|
|
27
|
+
active: Pred
|
|
28
|
+
disable?: Pred
|
|
29
|
+
enable: Pred
|
|
30
|
+
}
|
|
30
31
|
|
|
31
32
|
export const createToggleIcon = (icon: Icon, onClick: string, mark?: MarkType, disableForMark?: MarkType): Item => ({
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
})
|
|
33
|
+
icon,
|
|
34
|
+
onClick,
|
|
35
|
+
isHidden: () => (view: EditorView) => isTextAndNotHasMark(view.state, disableForMark),
|
|
36
|
+
isActive: () => (view: EditorView) => hasMark(view.state, mark),
|
|
37
|
+
canAddToDOM: () => (view: EditorView) => !!mark && !!view.state.schema.marks[mark.name],
|
|
38
|
+
})
|
|
38
39
|
|
|
39
40
|
export const defaultButtons = (ctx: Ctx) => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
41
|
+
const marks = ctx.get(schemaCtx).marks
|
|
42
|
+
return [
|
|
43
|
+
createToggleIcon('bold', 'ToggleBold', marks.strong),
|
|
44
|
+
createToggleIcon('italic', 'ToggleItalic', marks.em),
|
|
45
|
+
createToggleIcon('strikeThrough', 'ToggleStrikeThrough', marks.strike_through),
|
|
46
|
+
createToggleIcon('code', 'ToggleInlineCode', marks.code_inline),
|
|
47
|
+
createToggleIcon('link', 'ToggleLink', marks.link),
|
|
48
|
+
]
|
|
49
|
+
}
|
|
49
50
|
|
|
50
|
-
export type ButtonList = ButtonItem[]
|
|
51
|
+
export type ButtonList = ButtonItem[]
|
|
51
52
|
|
|
52
|
-
export
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
53
|
+
export interface TooltipOptions {
|
|
54
|
+
bottom: boolean
|
|
55
|
+
items: (ctx: Ctx) => Array<Item>
|
|
56
|
+
}
|
|
56
57
|
|
|
57
58
|
export const buttonMap = (ctx: Ctx, items: (ctx: Ctx) => Array<Item> = defaultButtons): ButtonList => {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
59
|
+
const toButton = ({ icon, onClick, isHidden, isActive, canAddToDOM }: Item): ButtonItem => ({
|
|
60
|
+
$: typeof icon === 'function' ? icon(ctx) : (ctx.get(themeManagerCtx).get(ThemeIcon, icon)?.dom as HTMLElement),
|
|
61
|
+
command: typeof onClick === 'string' ? () => ctx.get(commandsCtx).call(onClick) : onClick(ctx),
|
|
62
|
+
disable: isHidden(ctx),
|
|
63
|
+
active: isActive(ctx),
|
|
64
|
+
enable: canAddToDOM(ctx),
|
|
65
|
+
})
|
|
66
|
+
return items(ctx).map(toButton)
|
|
67
|
+
}
|
|
@@ -1,49 +1,50 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { EditorState } from '@milkdown/prose/state'
|
|
3
|
-
import type { EditorView } from '@milkdown/prose/view'
|
|
4
|
-
import { ThemeUtils } from '@milkdown/utils'
|
|
2
|
+
import type { EditorState } from '@milkdown/prose/state'
|
|
3
|
+
import type { EditorView } from '@milkdown/prose/view'
|
|
4
|
+
import type { ThemeUtils } from '@milkdown/utils'
|
|
5
5
|
|
|
6
|
-
import { createButtonManager } from './button-manager'
|
|
7
|
-
import type { ButtonList } from './item'
|
|
6
|
+
import { createButtonManager } from './button-manager'
|
|
7
|
+
import type { ButtonList } from './item'
|
|
8
8
|
|
|
9
9
|
export const createPlugin = (buttonMap: ButtonList, utils: ThemeUtils, bottom: boolean, containerClassName: string) => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
}
|
|
10
|
+
let buttonManager = createButtonManager(buttonMap, utils, bottom, containerClassName)
|
|
11
|
+
let shouldHide = false
|
|
12
|
+
|
|
13
|
+
const hide = () => {
|
|
14
|
+
buttonManager.hide()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const update = (view: EditorView, prevState?: EditorState) => {
|
|
18
|
+
const { state } = view
|
|
19
|
+
|
|
20
|
+
if (!view.editable || shouldHide) {
|
|
21
|
+
hide()
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const isEqualSelection = prevState?.doc.eq(state.doc) && prevState.selection.eq(state.selection)
|
|
26
|
+
if (isEqualSelection)
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
buttonManager.update(view)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
recreate: (editorView: EditorView) => {
|
|
34
|
+
buttonManager = createButtonManager(buttonMap, utils, bottom, containerClassName)
|
|
35
|
+
buttonManager.render(editorView)
|
|
36
|
+
update(editorView)
|
|
37
|
+
},
|
|
38
|
+
update,
|
|
39
|
+
destroy: () => {
|
|
40
|
+
buttonManager.destroy()
|
|
41
|
+
},
|
|
42
|
+
render: (editorView: EditorView) => {
|
|
43
|
+
buttonManager.render(editorView)
|
|
44
|
+
update(editorView)
|
|
45
|
+
},
|
|
46
|
+
setHide: (isTyping: boolean) => {
|
|
47
|
+
shouldHide = isTyping
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
}
|
package/src/utility/element.ts
CHANGED
package/src/utility/index.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
export * from './element'
|
|
3
|
-
export * from './prosemirror'
|
|
2
|
+
export * from './element'
|
|
3
|
+
export * from './prosemirror'
|
|
@@ -1,40 +1,42 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { findParentNode } from '@milkdown/prose'
|
|
3
|
-
import { MarkType, Node, NodeType } from '@milkdown/prose/model'
|
|
4
|
-
import { EditorState
|
|
2
|
+
import { findParentNode } from '@milkdown/prose'
|
|
3
|
+
import type { MarkType, Node, NodeType } from '@milkdown/prose/model'
|
|
4
|
+
import type { EditorState } from '@milkdown/prose/state'
|
|
5
|
+
import { TextSelection } from '@milkdown/prose/state'
|
|
5
6
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
7
|
+
export interface Position {
|
|
8
|
+
start: number
|
|
9
|
+
end: number
|
|
10
|
+
}
|
|
10
11
|
|
|
11
12
|
export const hasMark = (editorState: EditorState, type?: MarkType): boolean => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
const { from, to } = editorState.selection;
|
|
13
|
+
if (!type)
|
|
14
|
+
return false
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
const { from, to } = editorState.selection
|
|
17
|
+
|
|
18
|
+
return editorState.doc.rangeHasMark(from, from === to ? to + 1 : to, type)
|
|
19
|
+
}
|
|
19
20
|
|
|
20
21
|
export const isTextSelection = (editorState: EditorState): boolean => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
const { selection } = editorState
|
|
23
|
+
if (selection instanceof TextSelection) {
|
|
24
|
+
const text = editorState.doc.textBetween(selection.from, selection.to)
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
if (!text)
|
|
27
|
+
return false
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
29
|
+
return true
|
|
30
|
+
}
|
|
31
|
+
return false
|
|
32
|
+
}
|
|
31
33
|
|
|
32
34
|
export const isInCodeFence = (editorState: EditorState): boolean =>
|
|
33
|
-
|
|
35
|
+
Boolean(findParentNode(node => !!node.type.spec.code)(editorState.selection))
|
|
34
36
|
|
|
35
37
|
export const isTextAndNotHasMark = (editorState: EditorState, mark?: MarkType): boolean =>
|
|
36
|
-
|
|
38
|
+
!isTextSelection(editorState) || isInCodeFence(editorState) || hasMark(editorState, mark)
|
|
37
39
|
|
|
38
40
|
export const equalNodeType = (nodeType: NodeType, node: Node) => {
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
+
return (Array.isArray(nodeType) && nodeType.includes(node.type)) || node.type === nodeType
|
|
42
|
+
}
|