@milkdown/plugin-emoji 6.5.1 → 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 +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,mBAAmB,cAAc,gBA8K7F,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 S, AtomList as b } from "@milkdown/utils";
2
- import { missingRootElement as T, expectDomTypeError as D } from "@milkdown/exception";
3
- import { InputRule as P } from "@milkdown/prose/inputrules";
4
- import M from "node-emoji";
5
- import A from "remark-emoji";
6
- import { calculateNodePosition as H } from "@milkdown/prose";
7
- import { PluginKey as O, Plugin as _ } from "@milkdown/prose/state";
8
- import F from "twemoji";
9
- import { ThemeBorder as I, ThemeShadow as R, ThemeSize as K, ThemeFont as B, ThemeColor as $ } from "@milkdown/core";
10
- import z from "emoji-regex";
11
- const W = /:\+1|:-1|:[\w-]+/, U = /:\+1:|:-1:|:[\w-]+:/, q = /(:([^:\s]+):)$/, J = (i) => ({ title: i }), j = (i, a) => F.parse(i, { attributes: J, ...a }), G = (i, a, u, e, l, o) => {
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: n } = i, s = n.doc.resolve(a);
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 c = (s.parent.textBetween(Math.max(0, s.parentOffset - 10), s.parentOffset, void 0, "\uFFFC") + e).toLowerCase();
18
- if (U.test(c))
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 t = W.exec(c);
20
+ const t = X.exec(c);
21
21
  if (t && t[0] && c.endsWith(t[0])) {
22
- const r = t[0];
23
- return l(a - (r.length - e.length), u), o(r), !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
- }, Q = (i, a, u, e, l, o) => {
26
+ }, te = (r, a, f, e, i, s) => {
27
27
  for (; a.firstChild; )
28
28
  a.firstChild.remove();
29
- i.forEach(({ emoji: n, key: s }, c) => {
29
+ r.forEach(({ emoji: o, key: l }, c) => {
30
30
  const t = document.createElement("div");
31
31
  t.className = "milkdown-emoji-filter_item";
32
- const r = document.createElement("span");
33
- r.innerHTML = j(n, o), r.className = "milkdown-emoji-filter_item-emoji";
32
+ const n = document.createElement("span");
33
+ n.innerHTML = b(o, s), n.className = "milkdown-emoji-filter_item-emoji";
34
34
  const h = document.createElement("span");
35
- h.textContent = ":" + s + ":", h.className = "milkdown-emoji-filter_item-key", t.appendChild(r), t.appendChild(h), a.appendChild(t), c === 0 && (t.classList.add("active"), l(t));
36
- const p = (d) => {
37
- u && u.classList.remove("active");
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
38
  const { target: m } = d;
39
- m instanceof HTMLElement && (m.classList.add("active"), l(m));
40
- }, g = (d) => {
39
+ m instanceof HTMLElement && (m.classList.add("active"), i(m));
40
+ }, w = (d) => {
41
41
  const { target: m } = d;
42
42
  m instanceof HTMLElement && m.classList.remove("active");
43
- }, f = (d) => {
43
+ }, u = (d) => {
44
44
  d.preventDefault(), e();
45
45
  };
46
- t.addEventListener("mouseenter", p), t.addEventListener("mouseleave", g), t.addEventListener("mousedown", f);
46
+ t.addEventListener("mouseenter", g), t.addEventListener("mouseleave", w), t.addEventListener("mousedown", u);
47
47
  });
48
- }, X = (i, { css: a, cx: u }) => {
49
- const e = i.get(I, void 0), l = i.get(R, void 0), o = i.get(K, "radius"), n = i.get(B, "typography"), s = (t, r = 1) => i.get($, [t, r]), c = a`
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: ${o};
56
- background: ${s("surface")};
57
-
58
61
  .milkdown-emoji-filter_item {
59
62
  display: flex;
60
63
  gap: 8px;
@@ -64,11 +67,11 @@ const W = /:\+1|:-1|:[\w-]+/, U = /:\+1:|:-1:|:[\w-]+:/, q = /(:([^:\s]+):)$/, J
64
67
  justify-content: flex-start;
65
68
  cursor: pointer;
66
69
  line-height: 2;
67
- font-family: ${n};
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 W = /:\+1|:-1|:[\w-]+/, U = /:\+1:|:-1:|:[\w-]+:/, q = /(:([^:\s]+):)$/, J
79
82
  vertical-align: -1.5px;
80
83
  }
81
84
  `;
82
- return u(e, l, c);
83
- }, Y = new O("MILKDOWN_EMOJI_FILTER"), Z = (i, a, u) => {
84
- let e = !1, l = 0, o = "", n = null;
85
- const s = () => {
86
- e = !1, l = 0, o = "", n = 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;
88
+ const l = () => {
89
+ e = !1, i = 0, s = "", o = null;
87
90
  };
88
- return new _({
89
- key: Y,
91
+ return new K({
92
+ key: oe,
90
93
  props: {
91
94
  handleKeyDown(c, t) {
92
- return ["Delete", "Backspace"].includes(t.key) ? (o = o.slice(0, -1), o.length <= 1 && s(), !1) : !(!e || !["ArrowUp", "ArrowDown", "Enter"].includes(t.key));
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(c, t, r, h) {
95
- return e = G(c, t, r, h, (p) => {
96
- l = p;
97
- }, (p) => {
98
- o = p;
99
- }), e || s(), !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
112
  view: (c) => {
103
113
  const { parentNode: t } = c.dom;
104
114
  if (!t)
105
- throw T();
106
- const r = document.createElement("div");
107
- r.classList.add("milkdown-emoji-filter", "hide"), i.themeManager.onFlush(() => {
108
- const f = r.className.split(" ").filter((m) => ["hide", "milkdown-emoji-filter"].includes(m));
109
- r.className = f.join(" ");
110
- const d = i.getStyle((m) => X(i.themeManager, m));
111
- d && d.split(" ").forEach((m) => r.classList.add(m));
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
123
  const h = () => {
114
124
  var m;
115
- if (!n)
125
+ if (!o)
116
126
  return;
117
- const { tr: f } = c.state, d = c.state.schema.node("emoji", { html: (m = n.firstElementChild) == null ? void 0 : m.innerHTML });
118
- c.dispatch(f.delete(l, l + o.length).insert(l, d)), s(), 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
- t.appendChild(r);
121
- const p = (f) => {
122
- if (!e || !(f instanceof KeyboardEvent))
130
+ t.appendChild(n);
131
+ const g = (u) => {
132
+ if (!e || !(u instanceof KeyboardEvent))
123
133
  return;
124
- const { key: d } = f;
134
+ const { key: d } = u;
125
135
  if (d === "Enter") {
126
136
  h();
127
137
  return;
128
138
  }
129
139
  if (["ArrowDown", "ArrowUp"].includes(d)) {
130
- const m = d === "ArrowDown" ? (n == null ? void 0 : n.nextElementSibling) || r.firstElementChild : (n == null ? void 0 : n.previousElementSibling) || r.lastElementChild;
131
- if (n && n.classList.remove("active"), !m)
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
- m.classList.add("active"), n = m;
143
+ m.classList.add("active"), o = m;
134
144
  return;
135
145
  }
136
- }, g = (f) => {
137
- !e || (f.stopPropagation(), s(), r.classList.add("hide"));
146
+ }, w = (u) => {
147
+ !e || (u.stopPropagation(), l(), n.classList.add("hide"));
138
148
  };
139
- return t.addEventListener("keydown", p), t.addEventListener("mousedown", g), {
140
- update: (f) => {
141
- const { selection: d } = f.state;
149
+ return t.addEventListener("keydown", g), t.addEventListener("mousedown", w), {
150
+ update: (u) => {
151
+ const { selection: d } = u.state;
142
152
  if (d.from - d.to !== 0 || !e)
143
- return s(), r.classList.add("hide"), null;
144
- const m = M.search(o).slice(0, a), { node: N } = f.domAtPos(l);
145
- return m.length === 0 || !N ? (r.classList.add("hide"), null) : (r.classList.remove("hide"), Q(m, r, n, h, (w) => {
146
- n = w;
147
- }, u), H(f, r, (w, E, y) => {
148
- const L = r.parentElement;
149
- if (!L)
150
- throw T();
151
- const x = f.coordsAtPos(l);
152
- let v = x.left - y.left, k = w.bottom - y.top + 14 + L.scrollTop;
153
- return v < 0 && (v = 0), window.innerHeight - x.bottom < E.height && (k = w.top - y.top - E.height - 14 + L.scrollTop), [k, v];
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
- t.removeEventListener("keydown", p), t.removeEventListener("mousedown", g), r.remove();
181
+ t.removeEventListener("keydown", g), t.removeEventListener("mousedown", w), n.remove();
158
182
  }
159
183
  };
160
184
  }
161
185
  });
162
- }, C = z(), V = (i) => !!i.children, ee = (i) => !!i.value;
163
- function te(i, a) {
164
- return u(i, 0, null)[0];
165
- function u(e, l, o) {
166
- if (V(e)) {
167
- const n = [];
168
- for (let s = 0, c = e.children.length; s < c; s++) {
169
- const t = e.children[s];
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];
170
194
  if (t) {
171
- const r = u(t, s, e);
172
- if (r)
173
- for (let h = 0, p = r.length; h < p; h++) {
174
- const g = r[h];
175
- g && n.push(g);
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 = n;
203
+ e.children = o;
180
204
  }
181
- return a(e, l, o);
205
+ return a(e, i, s);
182
206
  }
183
207
  }
184
- const ne = (i) => () => {
185
- function a(u) {
186
- te(u, (e) => {
187
- if (!ee(e))
208
+ const ae = (r) => () => {
209
+ function a(f) {
210
+ le(f, (e) => {
211
+ if (!ie(e))
188
212
  return [e];
189
- const l = e.value, o = [];
190
- let n, s = l;
191
- for (; n = C.exec(s); ) {
192
- const { index: c } = n, t = n[0];
193
- t && (c > 0 && o.push({ ...e, value: s.slice(0, c) }), o.push({ ...e, value: j(t, i), type: "emoji" }), s = s.slice(c + t.length)), C.lastIndex = 0;
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 s.length && o.push({ ...e, value: s }), o;
219
+ return l.length && s.push({ ...e, value: l }), s;
196
220
  });
197
221
  }
198
222
  return a;
199
- }, re = S((i, a) => {
200
- const u = () => i.getStyle(({ css: e }) => e`
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 ne = (i) => () => {
221
247
  tag: 'span[data-type="emoji"]',
222
248
  getAttrs: (e) => {
223
249
  if (!(e instanceof HTMLElement))
224
- throw D(e);
250
+ throw O(e);
225
251
  return { html: e.innerHTML };
226
252
  }
227
253
  }
228
254
  ],
229
255
  toDOM: (e) => {
230
- const l = document.createElement("span");
231
- return l.classList.add("emoji-wrapper"), l.dataset.type = "emoji", i.themeManager.onFlush(() => {
232
- const o = u();
233
- o && l.classList.add(o);
234
- }), l.innerHTML = e.attrs.html, { dom: l };
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, l, o) => {
239
- e.addNode(o, { html: l.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, l) => {
245
- const o = document.createElement("span");
246
- o.innerHTML = l.attrs.html;
247
- const n = o.querySelector("img"), s = n == null ? void 0 : n.title;
248
- o.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 P(q, (l, o, n, s) => {
254
- const c = o[0];
279
+ new F(Z, (i, s, o, l) => {
280
+ const c = s[0];
255
281
  if (!c)
256
282
  return null;
257
- const t = M.get(c);
283
+ const t = D.get(c);
258
284
  if (!t || c.includes(t))
259
285
  return null;
260
- const r = j(t, a == null ? void 0 : a.twemojiOptions);
261
- return l.tr.setMeta("emoji", !0).replaceRangeWith(n, s, e.create({ html: r })).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: () => [A, ne(a == null ? void 0 : a.twemojiOptions)],
290
+ remarkPlugins: () => [I, ae(a == null ? void 0 : a.twemojiOptions)],
265
291
  prosePlugins: () => {
266
292
  var e;
267
- return [Z(i, (e = a == null ? void 0 : a.maxListSize) != null ? e : 6, a == null ? void 0 : a.twemojiOptions)];
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
- }), he = b.create([re()]);
296
+ }), Le = H.create([ce()]);
271
297
  export {
272
- he as emoji,
273
- re 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, 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 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, 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.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 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 { 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":[],"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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milkdown/plugin-emoji",
3
- "version": "6.5.1",
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",
@@ -144,6 +144,7 @@ export const filter = (utils: ThemeUtils, maxListSize: number, twemojiOptions?:
144
144
  return null;
145
145
  }
146
146
 
147
+ dropDown.style.maxHeight = '';
147
148
  dropDown.classList.remove('hide');
148
149
  renderDropdownList(
149
150
  result,
@@ -155,22 +156,52 @@ export const filter = (utils: ThemeUtils, maxListSize: number, twemojiOptions?:
155
156
  },
156
157
  twemojiOptions,
157
158
  );
158
- calculateNodePosition(view, dropDown, (selected, target, parent) => {
159
+ calculateNodePosition(view, dropDown, (_selected, target, parent) => {
159
160
  const $editor = dropDown.parentElement;
160
161
  if (!$editor) {
161
162
  throw missingRootElement();
162
163
  }
163
164
  const start = view.coordsAtPos(_from);
164
165
  let left = start.left - parent.left;
165
- let top = selected.bottom - parent.top + 14 + $editor.scrollTop;
166
166
 
167
167
  if (left < 0) {
168
168
  left = 0;
169
169
  }
170
170
 
171
- if (window.innerHeight - start.bottom < target.height) {
172
- 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;
173
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
+ }
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
+
174
205
  return [top, left];
175
206
  });
176
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
  };