@milkdown/plugin-emoji 6.5.0 → 6.5.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.
@@ -1,5 +1,5 @@
1
1
  import { EditorView } from '@milkdown/prose/view';
2
2
  import type { Emoji } from 'node-emoji';
3
3
  export declare const checkTrigger: (view: EditorView, from: number, to: number, text: string, setRange: (from: number, to: number) => void, setSearch: (words: string) => void) => boolean;
4
- export declare const renderDropdownList: (list: Emoji[], dropDown: HTMLElement, $active: HTMLElement | null, onConfirm: () => void, setActive: (active: HTMLElement | null) => void) => void;
4
+ export declare const renderDropdownList: (list: Emoji[], dropDown: HTMLElement, $active: HTMLElement | null, onConfirm: () => void, setActive: (active: HTMLElement | null) => void, twemojiOptions?: TwemojiOptions) => void;
5
5
  //# sourceMappingURL=helper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../src/filter/helper.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAKxC,eAAO,MAAM,YAAY,SACf,UAAU,QACV,MAAM,MACR,MAAM,QACJ,MAAM,mBACK,MAAM,MAAM,MAAM,KAAK,IAAI,qBACzB,MAAM,KAAK,IAAI,YAoBrC,CAAC;AAEF,eAAO,MAAM,kBAAkB,SACrB,KAAK,EAAE,YACH,WAAW,WACZ,WAAW,GAAG,IAAI,aAChB,MAAM,IAAI,sBACD,WAAW,GAAG,IAAI,KAAK,IAAI,SAmDlD,CAAC"}
1
+ {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../src/filter/helper.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAKxC,eAAO,MAAM,YAAY,SACf,UAAU,QACV,MAAM,MACR,MAAM,QACJ,MAAM,mBACK,MAAM,MAAM,MAAM,KAAK,IAAI,qBACzB,MAAM,KAAK,IAAI,YAoBrC,CAAC;AAEF,eAAO,MAAM,kBAAkB,SACrB,KAAK,EAAE,YACH,WAAW,WACZ,WAAW,GAAG,IAAI,aAChB,MAAM,IAAI,sBACD,WAAW,GAAG,IAAI,KAAK,IAAI,mBAC9B,cAAc,SAmDlC,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { Plugin, PluginKey } from '@milkdown/prose/state';
2
2
  import { ThemeUtils } from '@milkdown/utils';
3
3
  export declare const key: PluginKey<any>;
4
- export declare const filter: (utils: ThemeUtils, maxListSize: number) => Plugin<any>;
4
+ export declare const filter: (utils: ThemeUtils, maxListSize: number, twemojiOptions?: TwemojiOptions) => Plugin<any>;
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/filter/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAM7C,eAAO,MAAM,GAAG,gBAAyC,CAAC;AAE1D,eAAO,MAAM,MAAM,UAAW,UAAU,eAAe,MAAM,gBAuK5D,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/filter/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAM7C,eAAO,MAAM,GAAG,gBAAyC,CAAC;AAE1D,eAAO,MAAM,MAAM,UAAW,UAAU,eAAe,MAAM,mBAAmB,cAAc,gBA6M7F,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../src/filter/style.ts"],"names":[],"mappings":"AACA,OAAO,EAEH,OAAO,EAIP,YAAY,EAGf,MAAM,gBAAgB,CAAC;AAExB,eAAO,MAAM,WAAW,iBAAkB,YAAY,eAAe,OAAO,WAyC3E,CAAC"}
1
+ {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../src/filter/style.ts"],"names":[],"mappings":"AACA,OAAO,EAEH,OAAO,EAIP,YAAY,EAIf,MAAM,gBAAgB,CAAC;AAExB,eAAO,MAAM,WAAW,iBAAkB,YAAY,eAAe,OAAO,WA6C3E,CAAC"}
package/lib/index.es.js CHANGED
@@ -1,60 +1,63 @@
1
- import { createNode as M, AtomList as N } from "@milkdown/utils";
2
- import { missingRootElement as k, expectDomTypeError as S } from "@milkdown/exception";
3
- import { InputRule as b } from "@milkdown/prose/inputrules";
4
- import T from "node-emoji";
5
- import D from "remark-emoji";
6
- import { calculateNodePosition as P } from "@milkdown/prose";
7
- import { PluginKey as A, Plugin as H } from "@milkdown/prose/state";
8
- import _ from "twemoji";
9
- import { ThemeBorder as F, ThemeShadow as I, ThemeSize as O, ThemeFont as R, ThemeColor as K } from "@milkdown/core";
10
- import B from "emoji-regex";
11
- const $ = /:\+1|:-1|:[\w-]+/, z = /:\+1:|:-1:|:[\w-]+:/, W = /(:([^:\s]+):)$/, U = (i) => ({ title: i }), v = (i) => _.parse(i, { attributes: U }), q = (i, d, a, e, o, t) => {
12
- if (i.composing)
1
+ import { createNode as A, AtomList as H } from "@milkdown/utils";
2
+ import { missingRootElement as N, expectDomTypeError as O } from "@milkdown/exception";
3
+ import { InputRule as F } from "@milkdown/prose/inputrules";
4
+ import D from "node-emoji";
5
+ import I from "remark-emoji";
6
+ import { calculateNodePosition as R } from "@milkdown/prose";
7
+ import { PluginKey as B, Plugin as K } from "@milkdown/prose/state";
8
+ import W from "twemoji";
9
+ import { ThemeBorder as $, ThemeShadow as z, ThemeScrollbar as U, ThemeSize as q, ThemeFont as J, ThemeColor as G } from "@milkdown/core";
10
+ import Q from "emoji-regex";
11
+ const X = /:\+1|:-1|:[\w-]+/, Y = /:\+1:|:-1:|:[\w-]+:/, Z = /(:([^:\s]+):)$/, V = (r) => ({ title: r }), b = (r, a) => W.parse(r, { attributes: V, ...a }), ee = (r, a, f, e, i, s) => {
12
+ if (r.composing)
13
13
  return !1;
14
- const { state: l } = i, s = l.doc.resolve(d);
15
- if (s.parent.type.spec.code)
14
+ const { state: o } = r, l = o.doc.resolve(a);
15
+ if (l.parent.type.spec.code)
16
16
  return !1;
17
- const n = (s.parent.textBetween(Math.max(0, s.parentOffset - 10), s.parentOffset, void 0, "\uFFFC") + e).toLowerCase();
18
- if (z.test(n))
17
+ const c = (l.parent.textBetween(Math.max(0, l.parentOffset - 10), l.parentOffset, void 0, "\uFFFC") + e).toLowerCase();
18
+ if (Y.test(c))
19
19
  return !1;
20
- const r = $.exec(n);
21
- if (r && r[0] && n.endsWith(r[0])) {
22
- const m = r[0];
23
- return o(d - (m.length - e.length), a), t(m), !0;
20
+ const t = X.exec(c);
21
+ if (t && t[0] && c.endsWith(t[0])) {
22
+ const n = t[0];
23
+ return i(a - (n.length - e.length), f), s(n), !0;
24
24
  }
25
25
  return !1;
26
- }, J = (i, d, a, e, o) => {
27
- for (; d.firstChild; )
28
- d.firstChild.remove();
29
- i.forEach(({ emoji: t, key: l }, s) => {
30
- const n = document.createElement("div");
31
- n.className = "milkdown-emoji-filter_item";
32
- const r = document.createElement("span");
33
- r.innerHTML = v(t), r.className = "milkdown-emoji-filter_item-emoji";
34
- const m = document.createElement("span");
35
- m.textContent = ":" + l + ":", m.className = "milkdown-emoji-filter_item-key", n.appendChild(r), n.appendChild(m), d.appendChild(n), s === 0 && (n.classList.add("active"), o(n));
36
- const p = (f) => {
37
- a && a.classList.remove("active");
38
- const { target: c } = f;
39
- c instanceof HTMLElement && (c.classList.add("active"), o(c));
40
- }, h = (f) => {
41
- const { target: c } = f;
42
- c instanceof HTMLElement && c.classList.remove("active");
43
- }, u = (f) => {
44
- f.preventDefault(), e();
26
+ }, te = (r, a, f, e, i, s) => {
27
+ for (; a.firstChild; )
28
+ a.firstChild.remove();
29
+ r.forEach(({ emoji: o, key: l }, c) => {
30
+ const t = document.createElement("div");
31
+ t.className = "milkdown-emoji-filter_item";
32
+ const n = document.createElement("span");
33
+ n.innerHTML = b(o, s), n.className = "milkdown-emoji-filter_item-emoji";
34
+ const h = document.createElement("span");
35
+ h.textContent = ":" + l + ":", h.className = "milkdown-emoji-filter_item-key", t.appendChild(n), t.appendChild(h), a.appendChild(t), c === 0 && (t.classList.add("active"), i(t));
36
+ const g = (d) => {
37
+ f && f.classList.remove("active");
38
+ const { target: m } = d;
39
+ m instanceof HTMLElement && (m.classList.add("active"), i(m));
40
+ }, w = (d) => {
41
+ const { target: m } = d;
42
+ m instanceof HTMLElement && m.classList.remove("active");
43
+ }, u = (d) => {
44
+ d.preventDefault(), e();
45
45
  };
46
- n.addEventListener("mouseenter", p), n.addEventListener("mouseleave", h), n.addEventListener("mousedown", u);
46
+ t.addEventListener("mouseenter", g), t.addEventListener("mouseleave", w), t.addEventListener("mousedown", u);
47
47
  });
48
- }, G = (i, { css: d, cx: a }) => {
49
- const e = i.get(F, void 0), o = i.get(I, void 0), t = i.get(O, "radius"), l = i.get(R, "typography"), s = (r, m = 1) => i.get(K, [r, m]), n = d`
48
+ }, ne = (r, { css: a, cx: f }) => {
49
+ const e = r.get($, void 0), i = r.get(z, void 0), s = r.get(U, void 0), o = r.get(q, "radius"), l = r.get(J, "typography"), c = (n, h = 1) => r.get(G, [n, h]), t = a`
50
+ min-height: 36px;
51
+ max-height: 320px;
52
+ overflow-y: auto;
53
+ border-radius: ${o};
50
54
  position: absolute;
55
+ background: ${c("surface")};
56
+
51
57
  &.hide {
52
58
  display: none;
53
59
  }
54
60
 
55
- border-radius: ${t};
56
- background: ${s("surface")};
57
-
58
61
  .milkdown-emoji-filter_item {
59
62
  display: flex;
60
63
  gap: 8px;
@@ -67,8 +70,8 @@ const $ = /:\+1|:-1|:[\w-]+/, z = /:\+1:|:-1:|:[\w-]+:/, W = /(:([^:\s]+):)$/, U
67
70
  font-family: ${l};
68
71
  font-size: 14px;
69
72
  &.active {
70
- background: ${s("secondary", 0.12)};
71
- color: ${s("primary")};
73
+ background: ${c("secondary", 0.12)};
74
+ color: ${c("primary")};
72
75
  }
73
76
  }
74
77
 
@@ -79,132 +82,155 @@ const $ = /:\+1|:-1|:[\w-]+/, z = /:\+1:|:-1:|:[\w-]+:/, W = /(:([^:\s]+):)$/, U
79
82
  vertical-align: -1.5px;
80
83
  }
81
84
  `;
82
- return a(e, o, n);
83
- }, Q = new A("MILKDOWN_EMOJI_FILTER"), X = (i, d) => {
84
- let a = !1, e = 0, o = "", t = null;
85
+ return f(e, i, s, t);
86
+ }, oe = new B("MILKDOWN_EMOJI_FILTER"), re = (r, a, f) => {
87
+ let e = !1, i = 0, s = "", o = null;
85
88
  const l = () => {
86
- a = !1, e = 0, o = "", t = null;
89
+ e = !1, i = 0, s = "", o = null;
87
90
  };
88
- return new H({
89
- key: Q,
91
+ return new K({
92
+ key: oe,
90
93
  props: {
91
- handleKeyDown(s, n) {
92
- return ["Delete", "Backspace"].includes(n.key) ? (o = o.slice(0, -1), o.length <= 1 && l(), !1) : !(!a || !["ArrowUp", "ArrowDown", "Enter"].includes(n.key));
94
+ handleKeyDown(c, t) {
95
+ return ["Delete", "Backspace"].includes(t.key) ? (s = s.slice(0, -1), s.length <= 1 && l(), !1) : !(!e || !["ArrowUp", "ArrowDown", "Enter"].includes(t.key));
93
96
  },
94
- handleTextInput(s, n, r, m) {
95
- return a = q(s, n, r, m, (p) => {
96
- e = p;
97
- }, (p) => {
98
- o = p;
99
- }), a || l(), !1;
97
+ handleTextInput(c, t, n, h) {
98
+ return e = ee(
99
+ c,
100
+ t,
101
+ n,
102
+ h,
103
+ (g) => {
104
+ i = g;
105
+ },
106
+ (g) => {
107
+ s = g;
108
+ }
109
+ ), e || l(), !1;
100
110
  }
101
111
  },
102
- view: (s) => {
103
- const { parentNode: n } = s.dom;
104
- if (!n)
105
- throw k();
106
- const r = document.createElement("div");
107
- r.classList.add("milkdown-emoji-filter", "hide"), i.themeManager.onFlush(() => {
108
- const u = r.className.split(" ").filter((c) => ["hide", "milkdown-emoji-filter"].includes(c));
109
- r.className = u.join(" ");
110
- const f = i.getStyle((c) => G(i.themeManager, c));
111
- f && f.split(" ").forEach((c) => r.classList.add(c));
112
+ view: (c) => {
113
+ const { parentNode: t } = c.dom;
114
+ if (!t)
115
+ throw N();
116
+ const n = document.createElement("div");
117
+ n.classList.add("milkdown-emoji-filter", "hide"), r.themeManager.onFlush(() => {
118
+ const u = n.className.split(" ").filter((m) => ["hide", "milkdown-emoji-filter"].includes(m));
119
+ n.className = u.join(" ");
120
+ const d = r.getStyle((m) => ne(r.themeManager, m));
121
+ d && d.split(" ").forEach((m) => n.classList.add(m));
112
122
  });
113
- const m = () => {
114
- var c;
115
- if (!t)
123
+ const h = () => {
124
+ var m;
125
+ if (!o)
116
126
  return;
117
- const { tr: u } = s.state, f = s.state.schema.node("emoji", { html: (c = t.firstElementChild) == null ? void 0 : c.innerHTML });
118
- s.dispatch(u.delete(e, e + o.length).insert(e, f)), l(), r.classList.add("hide");
127
+ const { tr: u } = c.state, d = c.state.schema.node("emoji", { html: (m = o.firstElementChild) == null ? void 0 : m.innerHTML });
128
+ c.dispatch(u.delete(i, i + s.length).insert(i, d)), l(), n.classList.add("hide");
119
129
  };
120
- n.appendChild(r);
121
- const p = (u) => {
122
- if (!a || !(u instanceof KeyboardEvent))
130
+ t.appendChild(n);
131
+ const g = (u) => {
132
+ if (!e || !(u instanceof KeyboardEvent))
123
133
  return;
124
- const { key: f } = u;
125
- if (f === "Enter") {
126
- m();
134
+ const { key: d } = u;
135
+ if (d === "Enter") {
136
+ h();
127
137
  return;
128
138
  }
129
- if (["ArrowDown", "ArrowUp"].includes(f)) {
130
- const c = f === "ArrowDown" ? (t == null ? void 0 : t.nextElementSibling) || r.firstElementChild : (t == null ? void 0 : t.previousElementSibling) || r.lastElementChild;
131
- if (t && t.classList.remove("active"), !c)
139
+ if (["ArrowDown", "ArrowUp"].includes(d)) {
140
+ const m = d === "ArrowDown" ? (o == null ? void 0 : o.nextElementSibling) || n.firstElementChild : (o == null ? void 0 : o.previousElementSibling) || n.lastElementChild;
141
+ if (o && o.classList.remove("active"), !m)
132
142
  return;
133
- c.classList.add("active"), t = c;
143
+ m.classList.add("active"), o = m;
134
144
  return;
135
145
  }
136
- }, h = (u) => {
137
- !a || (u.stopPropagation(), l(), r.classList.add("hide"));
146
+ }, w = (u) => {
147
+ !e || (u.stopPropagation(), l(), n.classList.add("hide"));
138
148
  };
139
- return n.addEventListener("keydown", p), n.addEventListener("mousedown", h), {
149
+ return t.addEventListener("keydown", g), t.addEventListener("mousedown", w), {
140
150
  update: (u) => {
141
- const { selection: f } = u.state;
142
- if (f.from - f.to !== 0 || !a)
143
- return l(), r.classList.add("hide"), null;
144
- const c = T.search(o).slice(0, d), { node: C } = u.domAtPos(e);
145
- return c.length === 0 || !C ? (r.classList.add("hide"), null) : (r.classList.remove("hide"), J(c, r, t, m, (g) => {
146
- t = g;
147
- }), P(u, r, (g, E, w) => {
148
- const y = r.parentElement;
149
- if (!y)
150
- throw k();
151
- const j = u.coordsAtPos(e);
152
- let L = j.left - w.left, x = g.bottom - w.top + 14 + y.scrollTop;
153
- return L < 0 && (L = 0), window.innerHeight - j.bottom < E.height && (x = g.top - w.top - E.height - 14 + y.scrollTop), [x, L];
151
+ const { selection: d } = u.state;
152
+ if (d.from - d.to !== 0 || !e)
153
+ return l(), n.classList.add("hide"), null;
154
+ const m = D.search(s).slice(0, a), { node: P } = u.domAtPos(i);
155
+ return m.length === 0 || !P ? (n.classList.add("hide"), null) : (n.style.maxHeight = "", n.classList.remove("hide"), te(
156
+ m,
157
+ n,
158
+ o,
159
+ h,
160
+ (C) => {
161
+ o = C;
162
+ },
163
+ f
164
+ ), R(u, n, (C, j, y) => {
165
+ const E = n.parentElement;
166
+ if (!E)
167
+ throw N();
168
+ const v = u.coordsAtPos(i);
169
+ let L = v.left - y.left;
170
+ L < 0 && (L = 0);
171
+ let x, p;
172
+ const k = v.top - y.top, T = y.height + y.top - v.bottom;
173
+ T >= j.height + 28 ? x = "bottom" : k >= j.height + 28 ? x = "top" : T >= k ? (x = "bottom", p = T - 28) : (x = "top", p = k - 28), (k < 0 || T < 0) && (p = y.height - (v.bottom - v.top) - 28, p > j.height && (p = void 0));
174
+ const _ = x === "top" ? v.top - y.top - (p != null ? p : j.height) - 14 + E.scrollTop : v.bottom - y.top + 14 + E.scrollTop;
175
+ n.style.maxHeight = p !== void 0 && p > 0 ? `${p}px` : "";
176
+ const M = E.clientWidth - (n.offsetWidth + 4);
177
+ return L > M && (L = M), [_, L];
154
178
  }), null);
155
179
  },
156
180
  destroy: () => {
157
- n.removeEventListener("keydown", p), n.removeEventListener("mousedown", h), r.remove();
181
+ t.removeEventListener("keydown", g), t.removeEventListener("mousedown", w), n.remove();
158
182
  }
159
183
  };
160
184
  }
161
185
  });
162
- }, Y = B(), Z = (i) => !!i.children, V = (i) => !!i.value;
163
- function ee(i, d) {
164
- return a(i, 0, null)[0];
165
- function a(e, o, t) {
166
- if (Z(e)) {
167
- const l = [];
168
- for (let s = 0, n = e.children.length; s < n; s++) {
169
- const r = e.children[s];
170
- if (r) {
171
- const m = a(r, s, e);
172
- if (m)
173
- for (let p = 0, h = m.length; p < h; p++) {
174
- const u = m[p];
175
- u && l.push(u);
186
+ }, S = Q(), se = (r) => !!r.children, ie = (r) => !!r.value;
187
+ function le(r, a) {
188
+ return f(r, 0, null)[0];
189
+ function f(e, i, s) {
190
+ if (se(e)) {
191
+ const o = [];
192
+ for (let l = 0, c = e.children.length; l < c; l++) {
193
+ const t = e.children[l];
194
+ if (t) {
195
+ const n = f(t, l, e);
196
+ if (n)
197
+ for (let h = 0, g = n.length; h < g; h++) {
198
+ const w = n[h];
199
+ w && o.push(w);
176
200
  }
177
201
  }
178
202
  }
179
- e.children = l;
203
+ e.children = o;
180
204
  }
181
- return d(e, o, t);
205
+ return a(e, i, s);
182
206
  }
183
207
  }
184
- const te = () => {
185
- function i(d) {
186
- ee(d, (a) => {
187
- if (!V(a))
188
- return [a];
189
- const e = a.value, o = [];
190
- let t, l = e;
191
- for (; t = Y.exec(l); ) {
192
- const { index: s } = t, n = t[0];
193
- n && (s > 0 && o.push({ ...a, value: l.slice(0, s) }), o.push({ ...a, value: v(n), type: "emoji" }), l = l.slice(s + n.length));
208
+ const ae = (r) => () => {
209
+ function a(f) {
210
+ le(f, (e) => {
211
+ if (!ie(e))
212
+ return [e];
213
+ const i = e.value, s = [];
214
+ let o, l = i;
215
+ for (; o = S.exec(l); ) {
216
+ const { index: c } = o, t = o[0];
217
+ t && (c > 0 && s.push({ ...e, value: l.slice(0, c) }), s.push({ ...e, value: b(t, r), type: "emoji" }), l = l.slice(c + t.length)), S.lastIndex = 0;
194
218
  }
195
- return l.length && o.push({ ...a, value: l }), o;
219
+ return l.length && s.push({ ...e, value: l }), s;
196
220
  });
197
221
  }
198
- return i;
199
- }, ne = M((i, d) => {
200
- const a = () => i.getStyle(({ css: e }) => e`
222
+ return a;
223
+ }, ce = A((r, a) => {
224
+ const f = () => r.getStyle(
225
+ ({ css: e }) => e`
201
226
  .emoji {
202
227
  height: 1em;
203
228
  width: 1em;
204
229
  margin: 0 1px 0 1.5px;
205
230
  vertical-align: -1.5px;
206
231
  }
207
- `);
232
+ `
233
+ );
208
234
  return {
209
235
  id: "emoji",
210
236
  schema: () => ({
@@ -221,55 +247,55 @@ const te = () => {
221
247
  tag: 'span[data-type="emoji"]',
222
248
  getAttrs: (e) => {
223
249
  if (!(e instanceof HTMLElement))
224
- throw S(e);
250
+ throw O(e);
225
251
  return { html: e.innerHTML };
226
252
  }
227
253
  }
228
254
  ],
229
255
  toDOM: (e) => {
230
- const o = document.createElement("span");
231
- return o.classList.add("emoji-wrapper"), o.dataset.type = "emoji", i.themeManager.onFlush(() => {
232
- const t = a();
233
- t && o.classList.add(t);
234
- }), o.innerHTML = e.attrs.html, { dom: o };
256
+ const i = document.createElement("span");
257
+ return i.classList.add("emoji-wrapper"), i.dataset.type = "emoji", r.themeManager.onFlush(() => {
258
+ const s = f();
259
+ s && i.classList.add(s);
260
+ }), i.innerHTML = e.attrs.html, { dom: i };
235
261
  },
236
262
  parseMarkdown: {
237
263
  match: ({ type: e }) => e === "emoji",
238
- runner: (e, o, t) => {
239
- e.addNode(t, { html: o.value });
264
+ runner: (e, i, s) => {
265
+ e.addNode(s, { html: i.value });
240
266
  }
241
267
  },
242
268
  toMarkdown: {
243
269
  match: (e) => e.type.name === "emoji",
244
- runner: (e, o) => {
245
- const t = document.createElement("span");
246
- t.innerHTML = o.attrs.html;
247
- const l = t.querySelector("img"), s = l == null ? void 0 : l.title;
248
- t.remove(), e.addNode("text", void 0, s);
270
+ runner: (e, i) => {
271
+ const s = document.createElement("span");
272
+ s.innerHTML = i.attrs.html;
273
+ const o = s.querySelector("img"), l = o == null ? void 0 : o.title;
274
+ s.remove(), e.addNode("text", void 0, l);
249
275
  }
250
276
  }
251
277
  }),
252
278
  inputRules: (e) => [
253
- new b(W, (o, t, l, s) => {
254
- const n = t[0];
255
- if (!n)
279
+ new F(Z, (i, s, o, l) => {
280
+ const c = s[0];
281
+ if (!c)
256
282
  return null;
257
- const r = T.get(n);
258
- if (!r || n.includes(r))
283
+ const t = D.get(c);
284
+ if (!t || c.includes(t))
259
285
  return null;
260
- const m = v(r);
261
- return o.tr.setMeta("emoji", !0).replaceRangeWith(l, s, e.create({ html: m })).scrollIntoView();
286
+ const n = b(t, a == null ? void 0 : a.twemojiOptions);
287
+ return i.tr.setMeta("emoji", !0).replaceRangeWith(o, l, e.create({ html: n })).scrollIntoView();
262
288
  })
263
289
  ],
264
- remarkPlugins: () => [D, te],
290
+ remarkPlugins: () => [I, ae(a == null ? void 0 : a.twemojiOptions)],
265
291
  prosePlugins: () => {
266
292
  var e;
267
- return [X(i, (e = d == null ? void 0 : d.maxListSize) != null ? e : 6)];
293
+ return [re(r, (e = a == null ? void 0 : a.maxListSize) != null ? e : 6, a == null ? void 0 : a.twemojiOptions)];
268
294
  }
269
295
  };
270
- }), fe = N.create([ne()]);
296
+ }), Le = H.create([ce()]);
271
297
  export {
272
- fe as emoji,
273
- ne as emojiNode
298
+ Le as emoji,
299
+ ce as emojiNode
274
300
  };
275
301
  //# sourceMappingURL=index.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/constant.ts","../src/parse.ts","../src/filter/helper.ts","../src/filter/style.ts","../src/filter/index.ts","../src/remark-twemoji.ts","../src/node.ts","../src/index.ts"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nexport const part = /:\\+1|:-1|:[\\w-]+/;\nexport const full = /:\\+1:|:-1:|:[\\w-]+:/;\nexport const input = /(:([^:\\s]+):)$/;\n","/* Copyright 2021, Milkdown by Mirone. */\nimport twemoji from 'twemoji';\n\nconst setAttr = (text: string) => ({ title: text });\n\nexport const parse = (emoji: string): string => twemoji.parse(emoji, { attributes: setAttr }) as unknown as string;\n","/* Copyright 2021, Milkdown by Mirone. */\n\nimport { EditorView } from '@milkdown/prose/view';\nimport type { Emoji } from 'node-emoji';\n\nimport { full, part } from '../constant';\nimport { parse } from '../parse';\n\nexport const checkTrigger = (\n view: EditorView,\n from: number,\n to: number,\n text: string,\n setRange: (from: number, to: number) => void,\n setSearch: (words: string) => void,\n) => {\n if (view.composing) return false;\n const { state } = view;\n const $from = state.doc.resolve(from);\n if ($from.parent.type.spec.code) return false;\n const textBefore = (\n $from.parent.textBetween(Math.max(0, $from.parentOffset - 10), $from.parentOffset, undefined, '\\ufffc') + text\n ).toLowerCase();\n if (full.test(textBefore)) {\n return false;\n }\n const regex = part.exec(textBefore);\n if (regex && regex[0] && textBefore.endsWith(regex[0])) {\n const match = regex[0];\n setRange(from - (match.length - text.length), to);\n setSearch(match);\n return true;\n }\n return false;\n};\n\nexport const renderDropdownList = (\n list: Emoji[],\n dropDown: HTMLElement,\n $active: HTMLElement | null,\n onConfirm: () => void,\n setActive: (active: HTMLElement | null) => void,\n) => {\n while (dropDown.firstChild) {\n dropDown.firstChild.remove();\n }\n list.forEach(({ emoji, key }, i) => {\n const container = document.createElement('div');\n container.className = 'milkdown-emoji-filter_item';\n\n const emojiSpan = document.createElement('span');\n emojiSpan.innerHTML = parse(emoji);\n\n emojiSpan.className = 'milkdown-emoji-filter_item-emoji';\n const keySpan = document.createElement('span');\n keySpan.textContent = ':' + key + ':';\n keySpan.className = 'milkdown-emoji-filter_item-key';\n\n container.appendChild(emojiSpan);\n container.appendChild(keySpan);\n dropDown.appendChild(container);\n\n if (i === 0) {\n container.classList.add('active');\n setActive(container);\n }\n\n const onEnter = (e: MouseEvent) => {\n if ($active) {\n $active.classList.remove('active');\n }\n const { target } = e;\n if (!(target instanceof HTMLElement)) return;\n target.classList.add('active');\n setActive(target);\n };\n\n const onLeave = (e: MouseEvent) => {\n const { target } = e;\n if (!(target instanceof HTMLElement)) return;\n target.classList.remove('active');\n };\n\n const onClick = (e: MouseEvent) => {\n e.preventDefault();\n onConfirm();\n };\n\n container.addEventListener('mouseenter', onEnter);\n container.addEventListener('mouseleave', onLeave);\n container.addEventListener('mousedown', onClick);\n });\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport {\n Color,\n Emotion,\n ThemeBorder,\n ThemeColor,\n ThemeFont,\n ThemeManager,\n ThemeShadow,\n ThemeSize,\n} from '@milkdown/core';\n\nexport const injectStyle = (themeManager: ThemeManager, { css, cx }: Emotion) => {\n const border = themeManager.get(ThemeBorder, undefined);\n const shadow = themeManager.get(ThemeShadow, undefined);\n const radius = themeManager.get(ThemeSize, 'radius');\n const typography = themeManager.get(ThemeFont, 'typography');\n const palette = (color: Color, opacity = 1) => themeManager.get(ThemeColor, [color, opacity]);\n\n const style = css`\n position: absolute;\n &.hide {\n display: none;\n }\n\n border-radius: ${radius};\n background: ${palette('surface')};\n\n .milkdown-emoji-filter_item {\n display: flex;\n gap: 8px;\n height: 36px;\n padding: 0 14px;\n align-items: center;\n justify-content: flex-start;\n cursor: pointer;\n line-height: 2;\n font-family: ${typography};\n font-size: 14px;\n &.active {\n background: ${palette('secondary', 0.12)};\n color: ${palette('primary')};\n }\n }\n\n .emoji {\n height: 14px;\n width: 14px;\n margin: 0 1px 0 1.5px;\n vertical-align: -1.5px;\n }\n `;\n return cx(border, shadow, style);\n};\n","/* Copyright 2021, Milkdown by Mirone. */\n\nimport { missingRootElement } from '@milkdown/exception';\nimport { calculateNodePosition } from '@milkdown/prose';\nimport { Plugin, PluginKey } from '@milkdown/prose/state';\nimport { ThemeUtils } from '@milkdown/utils';\nimport nodeEmoji from 'node-emoji';\n\nimport { checkTrigger, renderDropdownList } from './helper';\nimport { injectStyle } from './style';\n\nexport const key = new PluginKey('MILKDOWN_EMOJI_FILTER');\n\nexport const filter = (utils: ThemeUtils, maxListSize: number) => {\n let trigger = false;\n let _from = 0;\n let _search = '';\n let $active: null | HTMLElement = null;\n\n const off = () => {\n trigger = false;\n _from = 0;\n _search = '';\n $active = null;\n };\n\n return new Plugin({\n key,\n props: {\n handleKeyDown(_, event) {\n if (['Delete', 'Backspace'].includes(event.key)) {\n _search = _search.slice(0, -1);\n if (_search.length <= 1) {\n off();\n }\n return false;\n }\n if (!trigger) return false;\n if (!['ArrowUp', 'ArrowDown', 'Enter'].includes(event.key)) {\n return false;\n }\n return true;\n },\n handleTextInput(view, from, to, text) {\n trigger = checkTrigger(\n view,\n from,\n to,\n text,\n (from) => {\n _from = from;\n },\n (search) => {\n _search = search;\n },\n );\n if (!trigger) {\n off();\n }\n return false;\n },\n },\n view: (editorView) => {\n const { parentNode } = editorView.dom;\n if (!parentNode) {\n throw missingRootElement();\n }\n\n const dropDown = document.createElement('div');\n\n dropDown.classList.add('milkdown-emoji-filter', 'hide');\n\n utils.themeManager.onFlush(() => {\n const className = dropDown.className\n .split(' ')\n .filter((x) => ['hide', 'milkdown-emoji-filter'].includes(x));\n dropDown.className = className.join(' ');\n const style = utils.getStyle((emotion) => injectStyle(utils.themeManager, emotion));\n if (style) {\n style.split(' ').forEach((x) => dropDown.classList.add(x));\n }\n });\n\n const replace = () => {\n if (!$active) return;\n\n const { tr } = editorView.state;\n const node = editorView.state.schema.node('emoji', { html: $active.firstElementChild?.innerHTML });\n\n editorView.dispatch(tr.delete(_from, _from + _search.length).insert(_from, node));\n off();\n dropDown.classList.add('hide');\n };\n\n parentNode.appendChild(dropDown);\n const onKeydown = (e: Event) => {\n if (!trigger || !(e instanceof KeyboardEvent)) return;\n\n const { key } = e;\n\n if (key === 'Enter') {\n replace();\n return;\n }\n\n if (['ArrowDown', 'ArrowUp'].includes(key)) {\n const next =\n key === 'ArrowDown'\n ? $active?.nextElementSibling || dropDown.firstElementChild\n : $active?.previousElementSibling || dropDown.lastElementChild;\n if ($active) {\n $active.classList.remove('active');\n }\n if (!next) return;\n next.classList.add('active');\n $active = next as HTMLElement;\n\n return;\n }\n };\n const onClick = (e: Event) => {\n if (!trigger) return;\n\n e.stopPropagation();\n off();\n dropDown.classList.add('hide');\n };\n parentNode.addEventListener('keydown', onKeydown);\n parentNode.addEventListener('mousedown', onClick);\n\n return {\n update: (view) => {\n const { selection } = view.state;\n\n if (selection.from - selection.to !== 0 || !trigger) {\n off();\n dropDown.classList.add('hide');\n return null;\n }\n const result = nodeEmoji.search(_search).slice(0, maxListSize);\n const { node } = view.domAtPos(_from);\n if (result.length === 0 || !node) {\n dropDown.classList.add('hide');\n return null;\n }\n\n dropDown.classList.remove('hide');\n renderDropdownList(result, dropDown, $active, replace, (a) => {\n $active = a;\n });\n calculateNodePosition(view, dropDown, (selected, target, parent) => {\n const $editor = dropDown.parentElement;\n if (!$editor) {\n throw missingRootElement();\n }\n const start = view.coordsAtPos(_from);\n let left = start.left - parent.left;\n let top = selected.bottom - parent.top + 14 + $editor.scrollTop;\n\n if (left < 0) {\n left = 0;\n }\n\n if (window.innerHeight - start.bottom < target.height) {\n top = selected.top - parent.top - target.height - 14 + $editor.scrollTop;\n }\n return [top, left];\n });\n\n return null;\n },\n\n destroy: () => {\n parentNode.removeEventListener('keydown', onKeydown);\n parentNode.removeEventListener('mousedown', onClick);\n dropDown.remove();\n },\n };\n },\n });\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport emojiRegex from 'emoji-regex';\nimport { Literal, Node, Parent } from 'unist';\n\nimport { parse } from './parse';\n\nconst regex = emojiRegex();\n\nconst isParent = (node: Node): node is Parent => !!(node as Parent).children;\nconst isLiteral = (node: Node): node is Literal => !!(node as Literal).value;\n\nfunction flatMap(ast: Node, fn: (node: Node, index: number, parent: Node | null) => Node[]) {\n return transform(ast, 0, null)[0];\n\n function transform(node: Node, index: number, parent: Node | null) {\n if (isParent(node)) {\n const out = [];\n for (let i = 0, n = node.children.length; i < n; i++) {\n const nthChild = node.children[i];\n if (nthChild) {\n const xs = transform(nthChild, i, node);\n if (xs) {\n for (let j = 0, m = xs.length; j < m; j++) {\n const item = xs[j];\n if (item) {\n out.push(item);\n }\n }\n }\n }\n }\n node.children = out;\n }\n\n return fn(node, index, parent);\n }\n}\n\nexport const twemojiPlugin = () => {\n function transformer(tree: Node) {\n flatMap(tree, (node) => {\n if (!isLiteral(node)) {\n return [node];\n }\n const value = node.value as string;\n const output: Literal<string>[] = [];\n let match;\n let str = value;\n while ((match = regex.exec(str))) {\n const { index } = match;\n const emoji = match[0];\n if (emoji) {\n if (index > 0) {\n output.push({ ...node, value: str.slice(0, index) });\n }\n output.push({ ...node, value: parse(emoji), type: 'emoji' });\n str = str.slice(index + emoji.length);\n }\n }\n if (str.length) {\n output.push({ ...node, value: str });\n }\n return output;\n });\n }\n return transformer;\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { RemarkPlugin } from '@milkdown/core';\nimport { expectDomTypeError } from '@milkdown/exception';\nimport { InputRule } from '@milkdown/prose/inputrules';\nimport { createNode } from '@milkdown/utils';\nimport nodeEmoji from 'node-emoji';\nimport remarkEmoji from 'remark-emoji';\n\nimport { input } from './constant';\nimport { filter } from './filter';\nimport { parse } from './parse';\nimport { twemojiPlugin } from './remark-twemoji';\n\nexport type EmojiOptions = {\n maxListSize: number;\n};\n\nexport const emojiNode = createNode<string, EmojiOptions>((utils, options) => {\n const getStyle = () =>\n utils.getStyle(\n ({ css }) => css`\n .emoji {\n height: 1em;\n width: 1em;\n margin: 0 1px 0 1.5px;\n vertical-align: -1.5px;\n }\n `,\n );\n return {\n id: 'emoji',\n schema: () => ({\n group: 'inline',\n inline: true,\n atom: true,\n attrs: {\n html: {\n default: '',\n },\n },\n parseDOM: [\n {\n tag: 'span[data-type=\"emoji\"]',\n getAttrs: (dom) => {\n if (!(dom instanceof HTMLElement)) {\n throw expectDomTypeError(dom);\n }\n return { html: dom.innerHTML };\n },\n },\n ],\n toDOM: (node) => {\n const span = document.createElement('span');\n span.classList.add('emoji-wrapper');\n span.dataset['type'] = 'emoji';\n utils.themeManager.onFlush(() => {\n const style = getStyle();\n if (style) {\n span.classList.add(style);\n }\n });\n span.innerHTML = node.attrs['html'];\n return { dom: span };\n },\n parseMarkdown: {\n match: ({ type }) => type === 'emoji',\n runner: (state, node, type) => {\n state.addNode(type, { html: node['value'] as string });\n },\n },\n toMarkdown: {\n match: (node) => node.type.name === 'emoji',\n runner: (state, node) => {\n const span = document.createElement('span');\n span.innerHTML = node.attrs['html'];\n const img = span.querySelector('img');\n const title = img?.title;\n span.remove();\n state.addNode('text', undefined, title);\n },\n },\n }),\n inputRules: (nodeType) => [\n new InputRule(input, (state, match, start, end) => {\n const content = match[0];\n if (!content) return null;\n const got = nodeEmoji.get(content);\n if (!got || content.includes(got)) return null;\n\n const html = parse(got);\n\n return state.tr\n .setMeta('emoji', true)\n .replaceRangeWith(start, end, nodeType.create({ html }))\n .scrollIntoView();\n }),\n ],\n remarkPlugins: () => [remarkEmoji as RemarkPlugin, twemojiPlugin],\n prosePlugins: () => [filter(utils, options?.maxListSize ?? 6)],\n };\n});\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { AtomList } from '@milkdown/utils';\n\nimport { emojiNode } from './node';\nexport * from './node';\n\nexport const emoji = AtomList.create([emojiNode()]);\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/constant.ts","../src/parse.ts","../src/filter/helper.ts","../src/filter/style.ts","../src/filter/index.ts","../src/remark-twemoji.ts","../src/node.ts","../src/index.ts"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nexport const part = /:\\+1|:-1|:[\\w-]+/;\nexport const full = /:\\+1:|:-1:|:[\\w-]+:/;\nexport const input = /(:([^:\\s]+):)$/;\n","/* Copyright 2021, Milkdown by Mirone. */\nimport twemoji from 'twemoji';\n\nconst setAttr = (text: string) => ({ title: text });\n\nexport const parse = (emoji: string, twemojiOptions?: TwemojiOptions): string =>\n twemoji.parse(emoji, { attributes: setAttr, ...twemojiOptions }) as unknown as string;\n","/* Copyright 2021, Milkdown by Mirone. */\n\nimport { EditorView } from '@milkdown/prose/view';\nimport type { Emoji } from 'node-emoji';\n\nimport { full, part } from '../constant';\nimport { parse } from '../parse';\n\nexport const checkTrigger = (\n view: EditorView,\n from: number,\n to: number,\n text: string,\n setRange: (from: number, to: number) => void,\n setSearch: (words: string) => void,\n) => {\n if (view.composing) return false;\n const { state } = view;\n const $from = state.doc.resolve(from);\n if ($from.parent.type.spec.code) return false;\n const textBefore = (\n $from.parent.textBetween(Math.max(0, $from.parentOffset - 10), $from.parentOffset, undefined, '\\ufffc') + text\n ).toLowerCase();\n if (full.test(textBefore)) {\n return false;\n }\n const regex = part.exec(textBefore);\n if (regex && regex[0] && textBefore.endsWith(regex[0])) {\n const match = regex[0];\n setRange(from - (match.length - text.length), to);\n setSearch(match);\n return true;\n }\n return false;\n};\n\nexport const renderDropdownList = (\n list: Emoji[],\n dropDown: HTMLElement,\n $active: HTMLElement | null,\n onConfirm: () => void,\n setActive: (active: HTMLElement | null) => void,\n twemojiOptions?: TwemojiOptions,\n) => {\n while (dropDown.firstChild) {\n dropDown.firstChild.remove();\n }\n list.forEach(({ emoji, key }, i) => {\n const container = document.createElement('div');\n container.className = 'milkdown-emoji-filter_item';\n\n const emojiSpan = document.createElement('span');\n emojiSpan.innerHTML = parse(emoji, twemojiOptions);\n\n emojiSpan.className = 'milkdown-emoji-filter_item-emoji';\n const keySpan = document.createElement('span');\n keySpan.textContent = ':' + key + ':';\n keySpan.className = 'milkdown-emoji-filter_item-key';\n\n container.appendChild(emojiSpan);\n container.appendChild(keySpan);\n dropDown.appendChild(container);\n\n if (i === 0) {\n container.classList.add('active');\n setActive(container);\n }\n\n const onEnter = (e: MouseEvent) => {\n if ($active) {\n $active.classList.remove('active');\n }\n const { target } = e;\n if (!(target instanceof HTMLElement)) return;\n target.classList.add('active');\n setActive(target);\n };\n\n const onLeave = (e: MouseEvent) => {\n const { target } = e;\n if (!(target instanceof HTMLElement)) return;\n target.classList.remove('active');\n };\n\n const onClick = (e: MouseEvent) => {\n e.preventDefault();\n onConfirm();\n };\n\n container.addEventListener('mouseenter', onEnter);\n container.addEventListener('mouseleave', onLeave);\n container.addEventListener('mousedown', onClick);\n });\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport {\n Color,\n Emotion,\n ThemeBorder,\n ThemeColor,\n ThemeFont,\n ThemeManager,\n ThemeScrollbar,\n ThemeShadow,\n ThemeSize,\n} from '@milkdown/core';\n\nexport const injectStyle = (themeManager: ThemeManager, { css, cx }: Emotion) => {\n const border = themeManager.get(ThemeBorder, undefined);\n const shadow = themeManager.get(ThemeShadow, undefined);\n const scrollbar = themeManager.get(ThemeScrollbar, undefined);\n const radius = themeManager.get(ThemeSize, 'radius');\n const typography = themeManager.get(ThemeFont, 'typography');\n const palette = (color: Color, opacity = 1) => themeManager.get(ThemeColor, [color, opacity]);\n\n const style = css`\n min-height: 36px;\n max-height: 320px;\n overflow-y: auto;\n border-radius: ${radius};\n position: absolute;\n background: ${palette('surface')};\n\n &.hide {\n display: none;\n }\n\n .milkdown-emoji-filter_item {\n display: flex;\n gap: 8px;\n height: 36px;\n padding: 0 14px;\n align-items: center;\n justify-content: flex-start;\n cursor: pointer;\n line-height: 2;\n font-family: ${typography};\n font-size: 14px;\n &.active {\n background: ${palette('secondary', 0.12)};\n color: ${palette('primary')};\n }\n }\n\n .emoji {\n height: 14px;\n width: 14px;\n margin: 0 1px 0 1.5px;\n vertical-align: -1.5px;\n }\n `;\n return cx(border, shadow, scrollbar, style);\n};\n","/* Copyright 2021, Milkdown by Mirone. */\n\nimport { missingRootElement } from '@milkdown/exception';\nimport { calculateNodePosition } from '@milkdown/prose';\nimport { Plugin, PluginKey } from '@milkdown/prose/state';\nimport { ThemeUtils } from '@milkdown/utils';\nimport nodeEmoji from 'node-emoji';\n\nimport { checkTrigger, renderDropdownList } from './helper';\nimport { injectStyle } from './style';\n\nexport const key = new PluginKey('MILKDOWN_EMOJI_FILTER');\n\nexport const filter = (utils: ThemeUtils, maxListSize: number, twemojiOptions?: TwemojiOptions) => {\n let trigger = false;\n let _from = 0;\n let _search = '';\n let $active: null | HTMLElement = null;\n\n const off = () => {\n trigger = false;\n _from = 0;\n _search = '';\n $active = null;\n };\n\n return new Plugin({\n key,\n props: {\n handleKeyDown(_, event) {\n if (['Delete', 'Backspace'].includes(event.key)) {\n _search = _search.slice(0, -1);\n if (_search.length <= 1) {\n off();\n }\n return false;\n }\n if (!trigger) return false;\n if (!['ArrowUp', 'ArrowDown', 'Enter'].includes(event.key)) {\n return false;\n }\n return true;\n },\n handleTextInput(view, from, to, text) {\n trigger = checkTrigger(\n view,\n from,\n to,\n text,\n (from) => {\n _from = from;\n },\n (search) => {\n _search = search;\n },\n );\n if (!trigger) {\n off();\n }\n return false;\n },\n },\n view: (editorView) => {\n const { parentNode } = editorView.dom;\n if (!parentNode) {\n throw missingRootElement();\n }\n\n const dropDown = document.createElement('div');\n\n dropDown.classList.add('milkdown-emoji-filter', 'hide');\n\n utils.themeManager.onFlush(() => {\n const className = dropDown.className\n .split(' ')\n .filter((x) => ['hide', 'milkdown-emoji-filter'].includes(x));\n dropDown.className = className.join(' ');\n const style = utils.getStyle((emotion) => injectStyle(utils.themeManager, emotion));\n if (style) {\n style.split(' ').forEach((x) => dropDown.classList.add(x));\n }\n });\n\n const replace = () => {\n if (!$active) return;\n\n const { tr } = editorView.state;\n const node = editorView.state.schema.node('emoji', { html: $active.firstElementChild?.innerHTML });\n\n editorView.dispatch(tr.delete(_from, _from + _search.length).insert(_from, node));\n off();\n dropDown.classList.add('hide');\n };\n\n parentNode.appendChild(dropDown);\n const onKeydown = (e: Event) => {\n if (!trigger || !(e instanceof KeyboardEvent)) return;\n\n const { key } = e;\n\n if (key === 'Enter') {\n replace();\n return;\n }\n\n if (['ArrowDown', 'ArrowUp'].includes(key)) {\n const next =\n key === 'ArrowDown'\n ? $active?.nextElementSibling || dropDown.firstElementChild\n : $active?.previousElementSibling || dropDown.lastElementChild;\n if ($active) {\n $active.classList.remove('active');\n }\n if (!next) return;\n next.classList.add('active');\n $active = next as HTMLElement;\n\n return;\n }\n };\n const onClick = (e: Event) => {\n if (!trigger) return;\n\n e.stopPropagation();\n off();\n dropDown.classList.add('hide');\n };\n parentNode.addEventListener('keydown', onKeydown);\n parentNode.addEventListener('mousedown', onClick);\n\n return {\n update: (view) => {\n const { selection } = view.state;\n\n if (selection.from - selection.to !== 0 || !trigger) {\n off();\n dropDown.classList.add('hide');\n return null;\n }\n const result = nodeEmoji.search(_search).slice(0, maxListSize);\n const { node } = view.domAtPos(_from);\n if (result.length === 0 || !node) {\n dropDown.classList.add('hide');\n return null;\n }\n\n dropDown.style.maxHeight = '';\n dropDown.classList.remove('hide');\n renderDropdownList(\n result,\n dropDown,\n $active,\n replace,\n (a) => {\n $active = a;\n },\n twemojiOptions,\n );\n calculateNodePosition(view, dropDown, (_selected, target, parent) => {\n const $editor = dropDown.parentElement;\n if (!$editor) {\n throw missingRootElement();\n }\n const start = view.coordsAtPos(_from);\n let left = start.left - parent.left;\n\n if (left < 0) {\n left = 0;\n }\n\n let direction: 'top' | 'bottom';\n let maxHeight: number | undefined;\n const startToTop = start.top - parent.top;\n const startToBottom = parent.height + parent.top - start.bottom;\n if (startToBottom >= target.height + 28) {\n direction = 'bottom';\n } else if (startToTop >= target.height + 28) {\n direction = 'top';\n } else if (startToBottom >= startToTop) {\n direction = 'bottom';\n maxHeight = startToBottom - 28;\n } else {\n direction = 'top';\n maxHeight = startToTop - 28;\n }\n if (startToTop < 0 || startToBottom < 0) {\n maxHeight = parent.height - (start.bottom - start.top) - 28;\n if (maxHeight > target.height) {\n maxHeight = undefined;\n }\n }\n\n const top =\n direction === 'top'\n ? start.top - parent.top - (maxHeight ?? target.height) - 14 + $editor.scrollTop\n : start.bottom - parent.top + 14 + $editor.scrollTop;\n\n dropDown.style.maxHeight = maxHeight !== undefined && maxHeight > 0 ? `${maxHeight}px` : '';\n\n const maxLeft = $editor.clientWidth - (dropDown.offsetWidth + 4);\n if (left > maxLeft) {\n left = maxLeft;\n }\n\n return [top, left];\n });\n\n return null;\n },\n\n destroy: () => {\n parentNode.removeEventListener('keydown', onKeydown);\n parentNode.removeEventListener('mousedown', onClick);\n dropDown.remove();\n },\n };\n },\n });\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { RemarkPlugin } from '@milkdown/core';\nimport emojiRegex from 'emoji-regex';\nimport { Literal, Node, Parent } from 'unist';\n\nimport { parse } from './parse';\n\nconst regex = emojiRegex();\n\nconst isParent = (node: Node): node is Parent => !!(node as Parent).children;\nconst isLiteral = (node: Node): node is Literal => !!(node as Literal).value;\n\nfunction flatMap(ast: Node, fn: (node: Node, index: number, parent: Node | null) => Node[]) {\n return transform(ast, 0, null)[0];\n\n function transform(node: Node, index: number, parent: Node | null) {\n if (isParent(node)) {\n const out = [];\n for (let i = 0, n = node.children.length; i < n; i++) {\n const nthChild = node.children[i];\n if (nthChild) {\n const xs = transform(nthChild, i, node);\n if (xs) {\n for (let j = 0, m = xs.length; j < m; j++) {\n const item = xs[j];\n if (item) {\n out.push(item);\n }\n }\n }\n }\n }\n node.children = out;\n }\n\n return fn(node, index, parent);\n }\n}\n\nexport const twemojiPlugin: (twemojiOptions?: TwemojiOptions) => RemarkPlugin = (twemojiOptions) => () => {\n function transformer(tree: Node) {\n flatMap(tree, (node) => {\n if (!isLiteral(node)) {\n return [node];\n }\n const value = node.value as string;\n const output: Literal<string>[] = [];\n let match;\n let str = value;\n while ((match = regex.exec(str))) {\n const { index } = match;\n const emoji = match[0];\n if (emoji) {\n if (index > 0) {\n output.push({ ...node, value: str.slice(0, index) });\n }\n output.push({ ...node, value: parse(emoji, twemojiOptions), type: 'emoji' });\n str = str.slice(index + emoji.length);\n }\n regex.lastIndex = 0;\n }\n if (str.length) {\n output.push({ ...node, value: str });\n }\n return output;\n });\n }\n return transformer;\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { RemarkPlugin } from '@milkdown/core';\nimport { expectDomTypeError } from '@milkdown/exception';\nimport { InputRule } from '@milkdown/prose/inputrules';\nimport { createNode } from '@milkdown/utils';\nimport nodeEmoji from 'node-emoji';\nimport remarkEmoji from 'remark-emoji';\n\nimport { input } from './constant';\nimport { filter } from './filter';\nimport { parse } from './parse';\nimport { twemojiPlugin } from './remark-twemoji';\n\nexport type EmojiOptions = {\n maxListSize: number;\n twemojiOptions: TwemojiOptions;\n};\n\nexport const emojiNode = createNode<string, EmojiOptions>((utils, options) => {\n const getStyle = () =>\n utils.getStyle(\n ({ css }) => css`\n .emoji {\n height: 1em;\n width: 1em;\n margin: 0 1px 0 1.5px;\n vertical-align: -1.5px;\n }\n `,\n );\n return {\n id: 'emoji',\n schema: () => ({\n group: 'inline',\n inline: true,\n atom: true,\n attrs: {\n html: {\n default: '',\n },\n },\n parseDOM: [\n {\n tag: 'span[data-type=\"emoji\"]',\n getAttrs: (dom) => {\n if (!(dom instanceof HTMLElement)) {\n throw expectDomTypeError(dom);\n }\n return { html: dom.innerHTML };\n },\n },\n ],\n toDOM: (node) => {\n const span = document.createElement('span');\n span.classList.add('emoji-wrapper');\n span.dataset['type'] = 'emoji';\n utils.themeManager.onFlush(() => {\n const style = getStyle();\n if (style) {\n span.classList.add(style);\n }\n });\n span.innerHTML = node.attrs['html'];\n return { dom: span };\n },\n parseMarkdown: {\n match: ({ type }) => type === 'emoji',\n runner: (state, node, type) => {\n state.addNode(type, { html: node['value'] as string });\n },\n },\n toMarkdown: {\n match: (node) => node.type.name === 'emoji',\n runner: (state, node) => {\n const span = document.createElement('span');\n span.innerHTML = node.attrs['html'];\n const img = span.querySelector('img');\n const title = img?.title;\n span.remove();\n state.addNode('text', undefined, title);\n },\n },\n }),\n inputRules: (nodeType) => [\n new InputRule(input, (state, match, start, end) => {\n const content = match[0];\n if (!content) return null;\n const got = nodeEmoji.get(content);\n if (!got || content.includes(got)) return null;\n\n const html = parse(got, options?.twemojiOptions);\n\n return state.tr\n .setMeta('emoji', true)\n .replaceRangeWith(start, end, nodeType.create({ html }))\n .scrollIntoView();\n }),\n ],\n remarkPlugins: () => [remarkEmoji as RemarkPlugin, twemojiPlugin(options?.twemojiOptions)],\n prosePlugins: () => [filter(utils, options?.maxListSize ?? 6, options?.twemojiOptions)],\n };\n});\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { AtomList } from '@milkdown/utils';\n\nimport { emojiNode } from './node';\nexport * from './node';\n\nexport const emoji = AtomList.create([emojiNode()]);\n"],"names":["part","full","input","setAttr","text","parse","emoji","twemojiOptions","twemoji","checkTrigger","view","from","to","setRange","setSearch","state","$from","textBefore","regex","match","renderDropdownList","list","dropDown","$active","onConfirm","setActive","key","i","container","emojiSpan","keySpan","onEnter","e","target","onLeave","onClick","injectStyle","themeManager","css","cx","border","ThemeBorder","shadow","ThemeShadow","scrollbar","ThemeScrollbar","radius","ThemeSize","typography","ThemeFont","palette","color","opacity","ThemeColor","style","PluginKey","filter","utils","maxListSize","trigger","_from","_search","off","Plugin","_","event","search","editorView","parentNode","missingRootElement","className","x","emotion","replace","tr","node","_a","onKeydown","next","selection","result","nodeEmoji","a","calculateNodePosition","_selected","parent","$editor","start","left","direction","maxHeight","startToTop","startToBottom","top","maxLeft","emojiRegex","isParent","isLiteral","flatMap","ast","fn","transform","index","out","n","nthChild","xs","j","m","item","twemojiPlugin","transformer","tree","value","output","str","emojiNode","createNode","options","getStyle","dom","expectDomTypeError","span","type","img","title","nodeType","InputRule","end","content","got","html","remarkEmoji","AtomList"],"mappings":"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"}
package/lib/node.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export declare type EmojiOptions = {
2
2
  maxListSize: number;
3
+ twemojiOptions: TwemojiOptions;
3
4
  };
4
5
  export declare const emojiNode: import("@milkdown/utils").NodeCreator<string, EmojiOptions>;
5
6
  //# sourceMappingURL=node.d.ts.map
package/lib/node.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAaA,oBAAY,YAAY,GAAG;IACvB,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,SAAS,6DAmFpB,CAAC"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAaA,oBAAY,YAAY,GAAG;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,cAAc,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,SAAS,6DAmFpB,CAAC"}
package/lib/parse.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const parse: (emoji: string) => string;
1
+ export declare const parse: (emoji: string, twemojiOptions?: TwemojiOptions) => string;
2
2
  //# sourceMappingURL=parse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,KAAK,UAAW,MAAM,KAAG,MAA4E,CAAC"}
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,KAAK,UAAW,MAAM,mBAAmB,cAAc,KAAG,MACkB,CAAC"}
@@ -1,3 +1,3 @@
1
- import { Node } from 'unist';
2
- export declare const twemojiPlugin: () => (tree: Node) => void;
1
+ import { RemarkPlugin } from '@milkdown/core';
2
+ export declare const twemojiPlugin: (twemojiOptions?: TwemojiOptions) => RemarkPlugin;
3
3
  //# sourceMappingURL=remark-twemoji.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"remark-twemoji.d.ts","sourceRoot":"","sources":["../src/remark-twemoji.ts"],"names":[],"mappings":"AAEA,OAAO,EAAW,IAAI,EAAU,MAAM,OAAO,CAAC;AAoC9C,eAAO,MAAM,aAAa,eACK,IAAI,SA2BlC,CAAC"}
1
+ {"version":3,"file":"remark-twemoji.d.ts","sourceRoot":"","sources":["../src/remark-twemoji.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAsC9C,eAAO,MAAM,aAAa,EAAE,CAAC,cAAc,CAAC,EAAE,cAAc,KAAK,YA6BhE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milkdown/plugin-emoji",
3
- "version": "6.5.0",
3
+ "version": "6.5.2",
4
4
  "type": "module",
5
5
  "main": "./lib/index.es.js",
6
6
  "types": "./lib/index.d.ts",
@@ -15,8 +15,8 @@
15
15
  "milkdown plugin"
16
16
  ],
17
17
  "devDependencies": {
18
- "@milkdown/core": "6.5.0",
19
- "@milkdown/prose": "6.5.0",
18
+ "@milkdown/core": "6.5.2",
19
+ "@milkdown/prose": "6.5.2",
20
20
  "@types/unist": "^2.0.6"
21
21
  },
22
22
  "peerDependencies": {
@@ -24,8 +24,8 @@
24
24
  "@milkdown/prose": "^6.0.1"
25
25
  },
26
26
  "dependencies": {
27
- "@milkdown/exception": "6.5.0",
28
- "@milkdown/utils": "6.5.0",
27
+ "@milkdown/exception": "6.5.2",
28
+ "@milkdown/utils": "6.5.2",
29
29
  "@types/node-emoji": "^1.8.1",
30
30
  "emoji-regex": "^10.0.0",
31
31
  "node-emoji": "^1.10.0",
@@ -40,6 +40,7 @@ export const renderDropdownList = (
40
40
  $active: HTMLElement | null,
41
41
  onConfirm: () => void,
42
42
  setActive: (active: HTMLElement | null) => void,
43
+ twemojiOptions?: TwemojiOptions,
43
44
  ) => {
44
45
  while (dropDown.firstChild) {
45
46
  dropDown.firstChild.remove();
@@ -49,7 +50,7 @@ export const renderDropdownList = (
49
50
  container.className = 'milkdown-emoji-filter_item';
50
51
 
51
52
  const emojiSpan = document.createElement('span');
52
- emojiSpan.innerHTML = parse(emoji);
53
+ emojiSpan.innerHTML = parse(emoji, twemojiOptions);
53
54
 
54
55
  emojiSpan.className = 'milkdown-emoji-filter_item-emoji';
55
56
  const keySpan = document.createElement('span');
@@ -11,7 +11,7 @@ import { injectStyle } from './style';
11
11
 
12
12
  export const key = new PluginKey('MILKDOWN_EMOJI_FILTER');
13
13
 
14
- export const filter = (utils: ThemeUtils, maxListSize: number) => {
14
+ export const filter = (utils: ThemeUtils, maxListSize: number, twemojiOptions?: TwemojiOptions) => {
15
15
  let trigger = false;
16
16
  let _from = 0;
17
17
  let _search = '';
@@ -144,26 +144,64 @@ export const filter = (utils: ThemeUtils, maxListSize: number) => {
144
144
  return null;
145
145
  }
146
146
 
147
+ dropDown.style.maxHeight = '';
147
148
  dropDown.classList.remove('hide');
148
- renderDropdownList(result, dropDown, $active, replace, (a) => {
149
- $active = a;
150
- });
151
- calculateNodePosition(view, dropDown, (selected, target, parent) => {
149
+ renderDropdownList(
150
+ result,
151
+ dropDown,
152
+ $active,
153
+ replace,
154
+ (a) => {
155
+ $active = a;
156
+ },
157
+ twemojiOptions,
158
+ );
159
+ calculateNodePosition(view, dropDown, (_selected, target, parent) => {
152
160
  const $editor = dropDown.parentElement;
153
161
  if (!$editor) {
154
162
  throw missingRootElement();
155
163
  }
156
164
  const start = view.coordsAtPos(_from);
157
165
  let left = start.left - parent.left;
158
- let top = selected.bottom - parent.top + 14 + $editor.scrollTop;
159
166
 
160
167
  if (left < 0) {
161
168
  left = 0;
162
169
  }
163
170
 
164
- if (window.innerHeight - start.bottom < target.height) {
165
- top = selected.top - parent.top - target.height - 14 + $editor.scrollTop;
171
+ let direction: 'top' | 'bottom';
172
+ let maxHeight: number | undefined;
173
+ const startToTop = start.top - parent.top;
174
+ const startToBottom = parent.height + parent.top - start.bottom;
175
+ if (startToBottom >= target.height + 28) {
176
+ direction = 'bottom';
177
+ } else if (startToTop >= target.height + 28) {
178
+ direction = 'top';
179
+ } else if (startToBottom >= startToTop) {
180
+ direction = 'bottom';
181
+ maxHeight = startToBottom - 28;
182
+ } else {
183
+ direction = 'top';
184
+ maxHeight = startToTop - 28;
185
+ }
186
+ if (startToTop < 0 || startToBottom < 0) {
187
+ maxHeight = parent.height - (start.bottom - start.top) - 28;
188
+ if (maxHeight > target.height) {
189
+ maxHeight = undefined;
190
+ }
166
191
  }
192
+
193
+ const top =
194
+ direction === 'top'
195
+ ? start.top - parent.top - (maxHeight ?? target.height) - 14 + $editor.scrollTop
196
+ : start.bottom - parent.top + 14 + $editor.scrollTop;
197
+
198
+ dropDown.style.maxHeight = maxHeight !== undefined && maxHeight > 0 ? `${maxHeight}px` : '';
199
+
200
+ const maxLeft = $editor.clientWidth - (dropDown.offsetWidth + 4);
201
+ if (left > maxLeft) {
202
+ left = maxLeft;
203
+ }
204
+
167
205
  return [top, left];
168
206
  });
169
207
 
@@ -6,6 +6,7 @@ import {
6
6
  ThemeColor,
7
7
  ThemeFont,
8
8
  ThemeManager,
9
+ ThemeScrollbar,
9
10
  ThemeShadow,
10
11
  ThemeSize,
11
12
  } from '@milkdown/core';
@@ -13,19 +14,23 @@ import {
13
14
  export const injectStyle = (themeManager: ThemeManager, { css, cx }: Emotion) => {
14
15
  const border = themeManager.get(ThemeBorder, undefined);
15
16
  const shadow = themeManager.get(ThemeShadow, undefined);
17
+ const scrollbar = themeManager.get(ThemeScrollbar, undefined);
16
18
  const radius = themeManager.get(ThemeSize, 'radius');
17
19
  const typography = themeManager.get(ThemeFont, 'typography');
18
20
  const palette = (color: Color, opacity = 1) => themeManager.get(ThemeColor, [color, opacity]);
19
21
 
20
22
  const style = css`
23
+ min-height: 36px;
24
+ max-height: 320px;
25
+ overflow-y: auto;
26
+ border-radius: ${radius};
21
27
  position: absolute;
28
+ background: ${palette('surface')};
29
+
22
30
  &.hide {
23
31
  display: none;
24
32
  }
25
33
 
26
- border-radius: ${radius};
27
- background: ${palette('surface')};
28
-
29
34
  .milkdown-emoji-filter_item {
30
35
  display: flex;
31
36
  gap: 8px;
@@ -50,5 +55,5 @@ export const injectStyle = (themeManager: ThemeManager, { css, cx }: Emotion) =>
50
55
  vertical-align: -1.5px;
51
56
  }
52
57
  `;
53
- return cx(border, shadow, style);
58
+ return cx(border, shadow, scrollbar, style);
54
59
  };
package/src/node.ts CHANGED
@@ -13,6 +13,7 @@ import { twemojiPlugin } from './remark-twemoji';
13
13
 
14
14
  export type EmojiOptions = {
15
15
  maxListSize: number;
16
+ twemojiOptions: TwemojiOptions;
16
17
  };
17
18
 
18
19
  export const emojiNode = createNode<string, EmojiOptions>((utils, options) => {
@@ -87,7 +88,7 @@ export const emojiNode = createNode<string, EmojiOptions>((utils, options) => {
87
88
  const got = nodeEmoji.get(content);
88
89
  if (!got || content.includes(got)) return null;
89
90
 
90
- const html = parse(got);
91
+ const html = parse(got, options?.twemojiOptions);
91
92
 
92
93
  return state.tr
93
94
  .setMeta('emoji', true)
@@ -95,7 +96,7 @@ export const emojiNode = createNode<string, EmojiOptions>((utils, options) => {
95
96
  .scrollIntoView();
96
97
  }),
97
98
  ],
98
- remarkPlugins: () => [remarkEmoji as RemarkPlugin, twemojiPlugin],
99
- prosePlugins: () => [filter(utils, options?.maxListSize ?? 6)],
99
+ remarkPlugins: () => [remarkEmoji as RemarkPlugin, twemojiPlugin(options?.twemojiOptions)],
100
+ prosePlugins: () => [filter(utils, options?.maxListSize ?? 6, options?.twemojiOptions)],
100
101
  };
101
102
  });
package/src/parse.ts CHANGED
@@ -3,4 +3,5 @@ import twemoji from 'twemoji';
3
3
 
4
4
  const setAttr = (text: string) => ({ title: text });
5
5
 
6
- export const parse = (emoji: string): string => twemoji.parse(emoji, { attributes: setAttr }) as unknown as string;
6
+ export const parse = (emoji: string, twemojiOptions?: TwemojiOptions): string =>
7
+ twemoji.parse(emoji, { attributes: setAttr, ...twemojiOptions }) as unknown as string;
@@ -1,4 +1,5 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
+ import { RemarkPlugin } from '@milkdown/core';
2
3
  import emojiRegex from 'emoji-regex';
3
4
  import { Literal, Node, Parent } from 'unist';
4
5
 
@@ -36,7 +37,7 @@ function flatMap(ast: Node, fn: (node: Node, index: number, parent: Node | null)
36
37
  }
37
38
  }
38
39
 
39
- export const twemojiPlugin = () => {
40
+ export const twemojiPlugin: (twemojiOptions?: TwemojiOptions) => RemarkPlugin = (twemojiOptions) => () => {
40
41
  function transformer(tree: Node) {
41
42
  flatMap(tree, (node) => {
42
43
  if (!isLiteral(node)) {
@@ -53,9 +54,10 @@ export const twemojiPlugin = () => {
53
54
  if (index > 0) {
54
55
  output.push({ ...node, value: str.slice(0, index) });
55
56
  }
56
- output.push({ ...node, value: parse(emoji), type: 'emoji' });
57
+ output.push({ ...node, value: parse(emoji, twemojiOptions), type: 'emoji' });
57
58
  str = str.slice(index + emoji.length);
58
59
  }
60
+ regex.lastIndex = 0;
59
61
  }
60
62
  if (str.length) {
61
63
  output.push({ ...node, value: str });