@milkdown/plugin-emoji 6.2.0 → 6.3.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":"AAGA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAMxC,eAAO,MAAM,GAAG,gBAAyC,CAAC;AAE1D,eAAO,MAAM,MAAM,UAAW,KAAK,eAAe,MAAM,gBAuKvD,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,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAMxC,eAAO,MAAM,GAAG,gBAAyC,CAAC;AAE1D,eAAO,MAAM,MAAM,UAAW,KAAK,eAAe,MAAM,gBAuKvD,CAAC"}
package/lib/index.es.js CHANGED
@@ -1,355 +1,216 @@
1
- var __defProp = Object.defineProperty;
2
- var __defProps = Object.defineProperties;
3
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
- var __defNormalProp = (obj, key2, value) => key2 in obj ? __defProp(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value;
8
- var __spreadValues = (a, b) => {
9
- for (var prop in b || (b = {}))
10
- if (__hasOwnProp.call(b, prop))
11
- __defNormalProp(a, prop, b[prop]);
12
- if (__getOwnPropSymbols)
13
- for (var prop of __getOwnPropSymbols(b)) {
14
- if (__propIsEnum.call(b, prop))
15
- __defNormalProp(a, prop, b[prop]);
16
- }
17
- return a;
18
- };
19
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
- import { createNode, AtomList } from "@milkdown/utils";
21
- import { InputRule } from "@milkdown/prose/inputrules";
22
- import nodeEmoji from "node-emoji";
23
- import remarkEmoji from "remark-emoji";
24
- import { calculateNodePosition } from "@milkdown/prose";
25
- import { PluginKey, Plugin } from "@milkdown/prose/state";
26
- import twemoji from "twemoji";
27
- import { ThemeBorder, ThemeShadow, ThemeSize, ThemeFont, ThemeColor } from "@milkdown/core";
28
- import emojiRegex from "emoji-regex";
29
- const part = /:\+1|:-1|:[\w-]+/;
30
- const full = /:\+1:|:-1:|:[\w-]+:/;
31
- const input = /(:([^:\s]+):)$/;
32
- const setAttr = (text) => ({ title: text });
33
- const parse = (emoji2) => twemoji.parse(emoji2, { attributes: setAttr });
34
- const checkTrigger = (view, from, to, text, setRange, setSearch) => {
35
- if (view.composing)
36
- return false;
37
- const { state } = view;
38
- const $from = state.doc.resolve(from);
39
- if ($from.parent.type.spec.code)
40
- return false;
41
- const textBefore = ($from.parent.textBetween(Math.max(0, $from.parentOffset - 10), $from.parentOffset, void 0, "\uFFFC") + text).toLowerCase();
42
- if (full.test(textBefore)) {
43
- return false;
44
- }
45
- const regex2 = part.exec(textBefore);
46
- if (regex2 && regex2[0] && textBefore.endsWith(regex2[0])) {
47
- const match = regex2[0];
48
- setRange(from - (match.length - text.length), to);
49
- setSearch(match);
50
- return true;
51
- }
52
- return false;
53
- };
54
- const renderDropdownList = (list, dropDown, $active, onConfirm, setActive) => {
55
- while (dropDown.firstChild) {
56
- dropDown.firstChild.remove();
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)
13
+ return !1;
14
+ const { state: l } = i, s = l.doc.resolve(d);
15
+ if (s.parent.type.spec.code)
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))
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;
57
24
  }
58
- list.forEach(({ emoji: emoji2, key: key2 }, i) => {
59
- const container = document.createElement("div");
60
- container.className = "milkdown-emoji-filter_item";
61
- const emojiSpan = document.createElement("span");
62
- emojiSpan.innerHTML = parse(emoji2);
63
- emojiSpan.className = "milkdown-emoji-filter_item-emoji";
64
- const keySpan = document.createElement("span");
65
- keySpan.textContent = ":" + key2 + ":";
66
- keySpan.className = "milkdown-emoji-filter_item-key";
67
- container.appendChild(emojiSpan);
68
- container.appendChild(keySpan);
69
- dropDown.appendChild(container);
70
- if (i === 0) {
71
- container.classList.add("active");
72
- setActive(container);
73
- }
74
- const onEnter = (e) => {
75
- if ($active) {
76
- $active.classList.remove("active");
77
- }
78
- const { target } = e;
79
- if (!(target instanceof HTMLElement))
80
- return;
81
- target.classList.add("active");
82
- setActive(target);
83
- };
84
- const onLeave = (e) => {
85
- const { target } = e;
86
- if (!(target instanceof HTMLElement))
87
- return;
88
- target.classList.remove("active");
89
- };
90
- const onClick = (e) => {
91
- e.preventDefault();
92
- onConfirm();
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();
93
45
  };
94
- container.addEventListener("mouseenter", onEnter);
95
- container.addEventListener("mouseleave", onLeave);
96
- container.addEventListener("mousedown", onClick);
46
+ n.addEventListener("mouseenter", p), n.addEventListener("mouseleave", h), n.addEventListener("mousedown", u);
97
47
  });
98
- };
99
- const injectStyle = (themeManager, { css, cx }) => {
100
- const border = themeManager.get(ThemeBorder, void 0);
101
- const shadow = themeManager.get(ThemeShadow, void 0);
102
- const radius = themeManager.get(ThemeSize, "radius");
103
- const typography = themeManager.get(ThemeFont, "typography");
104
- const palette = (color, opacity = 1) => themeManager.get(ThemeColor, [color, opacity]);
105
- const style = css`
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`
106
50
  position: absolute;
107
51
  &.hide {
108
52
  display: none;
109
53
  }
110
54
 
111
- border-radius: ${radius};
112
- background: ${palette("surface")};
55
+ border-radius: ${t};
56
+ background: ${s("surface")};
113
57
 
114
58
  .milkdown-emoji-filter_item {
115
59
  display: flex;
116
- gap: 0.5em;
117
- height: 2.57143em;
118
- padding: 0 1em;
60
+ gap: 8px;
61
+ height: 36px;
62
+ padding: 0 14px;
119
63
  align-items: center;
120
64
  justify-content: flex-start;
121
65
  cursor: pointer;
122
66
  line-height: 2;
123
- font-family: ${typography};
124
- font-size: 0.875em;
67
+ font-family: ${l};
68
+ font-size: 14px;
125
69
  &.active {
126
- background: ${palette("secondary", 0.12)};
127
- color: ${palette("primary")};
70
+ background: ${s("secondary", 0.12)};
71
+ color: ${s("primary")};
128
72
  }
129
73
  }
130
74
 
131
75
  .emoji {
132
- height: 1em;
133
- width: 1em;
134
- margin: 0 0.05em 0 0.1em;
135
- vertical-align: -0.1em;
76
+ height: 14px;
77
+ width: 14px;
78
+ margin: 0 1px 0 1.5px;
79
+ vertical-align: -1.5px;
136
80
  }
137
81
  `;
138
- return cx(border, shadow, style);
139
- };
140
- const key = new PluginKey("MILKDOWN_EMOJI_FILTER");
141
- const filter = (utils, maxListSize) => {
142
- let trigger = false;
143
- let _from = 0;
144
- let _search = "";
145
- let $active = null;
146
- const off = () => {
147
- trigger = false;
148
- _from = 0;
149
- _search = "";
150
- $active = null;
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
+ const l = () => {
86
+ a = !1, e = 0, o = "", t = null;
151
87
  };
152
- return new Plugin({
153
- key,
88
+ return new H({
89
+ key: Q,
154
90
  props: {
155
- handleKeyDown(_, event) {
156
- if (["Delete", "Backspace"].includes(event.key)) {
157
- _search = _search.slice(0, -1);
158
- if (_search.length <= 1) {
159
- off();
160
- }
161
- return false;
162
- }
163
- if (!trigger)
164
- return false;
165
- if (!["ArrowUp", "ArrowDown", "Enter"].includes(event.key)) {
166
- return false;
167
- }
168
- return true;
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));
169
93
  },
170
- handleTextInput(view, from, to, text) {
171
- trigger = checkTrigger(view, from, to, text, (from2) => {
172
- _from = from2;
173
- }, (search) => {
174
- _search = search;
175
- });
176
- if (!trigger) {
177
- off();
178
- }
179
- return false;
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;
180
100
  }
181
101
  },
182
- view: (editorView) => {
183
- const { parentNode } = editorView.dom;
184
- if (!parentNode) {
185
- throw new Error();
186
- }
187
- const dropDown = document.createElement("div");
188
- dropDown.classList.add("milkdown-emoji-filter", "hide");
189
- utils.themeManager.onFlush(() => {
190
- const className = dropDown.className.split(" ").filter((x) => ["hide", "milkdown-emoji-filter"].includes(x));
191
- dropDown.className = className.join(" ");
192
- const style = utils.getStyle((emotion) => injectStyle(utils.themeManager, emotion));
193
- if (style) {
194
- style.split(" ").forEach((x) => dropDown.classList.add(x));
195
- }
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));
196
112
  });
197
- const replace = () => {
198
- var _a;
199
- if (!$active)
113
+ const m = () => {
114
+ var c;
115
+ if (!t)
200
116
  return;
201
- const { tr } = editorView.state;
202
- const node = editorView.state.schema.node("emoji", { html: (_a = $active.firstElementChild) == null ? void 0 : _a.innerHTML });
203
- editorView.dispatch(tr.delete(_from, _from + _search.length).insert(_from, node));
204
- off();
205
- dropDown.classList.add("hide");
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");
206
119
  };
207
- parentNode.appendChild(dropDown);
208
- const onKeydown = (e) => {
209
- if (!trigger || !(e instanceof KeyboardEvent))
120
+ n.appendChild(r);
121
+ const p = (u) => {
122
+ if (!a || !(u instanceof KeyboardEvent))
210
123
  return;
211
- const { key: key2 } = e;
212
- if (key2 === "Enter") {
213
- replace();
124
+ const { key: f } = u;
125
+ if (f === "Enter") {
126
+ m();
214
127
  return;
215
128
  }
216
- if (["ArrowDown", "ArrowUp"].includes(key2)) {
217
- const next = key2 === "ArrowDown" ? ($active == null ? void 0 : $active.nextElementSibling) || dropDown.firstElementChild : ($active == null ? void 0 : $active.previousElementSibling) || dropDown.lastElementChild;
218
- if ($active) {
219
- $active.classList.remove("active");
220
- }
221
- if (!next)
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)
222
132
  return;
223
- next.classList.add("active");
224
- $active = next;
133
+ c.classList.add("active"), t = c;
225
134
  return;
226
135
  }
136
+ }, h = (u) => {
137
+ !a || (u.stopPropagation(), l(), r.classList.add("hide"));
227
138
  };
228
- const onClick = (e) => {
229
- if (!trigger)
230
- return;
231
- e.stopPropagation();
232
- off();
233
- dropDown.classList.add("hide");
234
- };
235
- parentNode.addEventListener("keydown", onKeydown);
236
- parentNode.addEventListener("mousedown", onClick);
237
- return {
238
- update: (view) => {
239
- const { selection } = view.state;
240
- if (selection.from - selection.to !== 0 || !trigger) {
241
- off();
242
- dropDown.classList.add("hide");
243
- return null;
244
- }
245
- const result = nodeEmoji.search(_search).slice(0, maxListSize);
246
- const { node } = view.domAtPos(_from);
247
- if (result.length === 0 || !node) {
248
- dropDown.classList.add("hide");
249
- return null;
250
- }
251
- dropDown.classList.remove("hide");
252
- renderDropdownList(result, dropDown, $active, replace, (a) => {
253
- $active = a;
254
- });
255
- calculateNodePosition(view, dropDown, (selected, target, parent) => {
256
- const $editor = dropDown.parentElement;
257
- if (!$editor) {
258
- throw new Error();
259
- }
260
- const start = view.coordsAtPos(_from);
261
- let left = start.left - parent.left;
262
- let top = selected.bottom - parent.top + 14 + $editor.scrollTop;
263
- if (left < 0) {
264
- left = 0;
265
- }
266
- if (window.innerHeight - start.bottom < target.height) {
267
- top = selected.top - parent.top - target.height - 14 + $editor.scrollTop;
268
- }
269
- return [top, left];
270
- });
271
- return null;
139
+ return n.addEventListener("keydown", p), n.addEventListener("mousedown", h), {
140
+ 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];
154
+ }), null);
272
155
  },
273
156
  destroy: () => {
274
- parentNode.removeEventListener("keydown", onKeydown);
275
- parentNode.removeEventListener("mousedown", onClick);
276
- dropDown.remove();
157
+ n.removeEventListener("keydown", p), n.removeEventListener("mousedown", h), r.remove();
277
158
  }
278
159
  };
279
160
  }
280
161
  });
281
- };
282
- const regex = emojiRegex();
283
- const isParent = (node) => !!node.children;
284
- const isLiteral = (node) => !!node.value;
285
- function flatMap(ast, fn) {
286
- return transform(ast, 0, null)[0];
287
- function transform(node, index, parent) {
288
- if (isParent(node)) {
289
- const out = [];
290
- for (let i = 0, n = node.children.length; i < n; i++) {
291
- const nthChild = node.children[i];
292
- if (nthChild) {
293
- const xs = transform(nthChild, i, node);
294
- if (xs) {
295
- for (let j = 0, m = xs.length; j < m; j++) {
296
- const item = xs[j];
297
- if (item) {
298
- out.push(item);
299
- }
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);
300
176
  }
301
- }
302
177
  }
303
178
  }
304
- node.children = out;
179
+ e.children = l;
305
180
  }
306
- return fn(node, index, parent);
181
+ return d(e, o, t);
307
182
  }
308
183
  }
309
- const twemojiPlugin = () => {
310
- function transformer(tree) {
311
- flatMap(tree, (node) => {
312
- if (!isLiteral(node)) {
313
- return [node];
314
- }
315
- const value = node.value;
316
- const output = [];
317
- let match;
318
- let str = value;
319
- while (match = regex.exec(str)) {
320
- const { index } = match;
321
- const emoji2 = match[0];
322
- if (emoji2) {
323
- if (index > 0) {
324
- output.push(__spreadProps(__spreadValues({}, node), { value: str.slice(0, index) }));
325
- }
326
- output.push(__spreadProps(__spreadValues({}, node), { value: parse(emoji2), type: "emoji" }));
327
- str = str.slice(index + emoji2.length);
328
- }
329
- }
330
- if (str.length) {
331
- output.push(__spreadProps(__spreadValues({}, node), { value: str }));
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));
332
194
  }
333
- return output;
195
+ return l.length && o.push({ ...a, value: l }), o;
334
196
  });
335
197
  }
336
- return transformer;
337
- };
338
- const emojiNode = createNode((utils, options) => {
339
- const getStyle = () => utils.getStyle(({ css }) => css`
198
+ return i;
199
+ }, ne = M((i, d) => {
200
+ const a = () => i.getStyle(({ css: e }) => e`
340
201
  .emoji {
341
202
  height: 1em;
342
203
  width: 1em;
343
- margin: 0 0.05em 0 0.1em;
344
- vertical-align: -0.1em;
204
+ margin: 0 1px 0 1.5px;
205
+ vertical-align: -1.5px;
345
206
  }
346
207
  `);
347
208
  return {
348
209
  id: "emoji",
349
210
  schema: () => ({
350
211
  group: "inline",
351
- inline: true,
352
- atom: true,
212
+ inline: !0,
213
+ atom: !0,
353
214
  attrs: {
354
215
  html: {
355
216
  default: ""
@@ -358,64 +219,57 @@ const emojiNode = createNode((utils, options) => {
358
219
  parseDOM: [
359
220
  {
360
221
  tag: 'span[data-type="emoji"]',
361
- getAttrs: (dom) => {
362
- if (!(dom instanceof HTMLElement)) {
363
- throw new Error();
364
- }
365
- return { html: dom.innerHTML };
222
+ getAttrs: (e) => {
223
+ if (!(e instanceof HTMLElement))
224
+ throw S(e);
225
+ return { html: e.innerHTML };
366
226
  }
367
227
  }
368
228
  ],
369
- toDOM: (node) => {
370
- const span = document.createElement("span");
371
- span.classList.add("emoji-wrapper");
372
- span.dataset["type"] = "emoji";
373
- utils.themeManager.onFlush(() => {
374
- const style = getStyle();
375
- if (style) {
376
- span.classList.add(style);
377
- }
378
- });
379
- span.innerHTML = node.attrs["html"];
380
- return { dom: span };
229
+ 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 };
381
235
  },
382
236
  parseMarkdown: {
383
- match: ({ type }) => type === "emoji",
384
- runner: (state, node, type) => {
385
- state.addNode(type, { html: node["value"] });
237
+ match: ({ type: e }) => e === "emoji",
238
+ runner: (e, o, t) => {
239
+ e.addNode(t, { html: o.value });
386
240
  }
387
241
  },
388
242
  toMarkdown: {
389
- match: (node) => node.type.name === "emoji",
390
- runner: (state, node) => {
391
- const span = document.createElement("span");
392
- span.innerHTML = node.attrs["html"];
393
- const img = span.querySelector("img");
394
- const title = img == null ? void 0 : img.title;
395
- span.remove();
396
- state.addNode("text", void 0, title);
243
+ 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);
397
249
  }
398
250
  }
399
251
  }),
400
- inputRules: (nodeType) => [
401
- new InputRule(input, (state, match, start, end) => {
402
- const content = match[0];
403
- if (!content)
252
+ inputRules: (e) => [
253
+ new b(W, (o, t, l, s) => {
254
+ const n = t[0];
255
+ if (!n)
404
256
  return null;
405
- const got = nodeEmoji.get(content);
406
- if (!got || content.includes(got))
257
+ const r = T.get(n);
258
+ if (!r || n.includes(r))
407
259
  return null;
408
- const html = parse(got);
409
- return state.tr.setMeta("emoji", true).replaceRangeWith(start, end, nodeType.create({ html })).scrollIntoView();
260
+ const m = v(r);
261
+ return o.tr.setMeta("emoji", !0).replaceRangeWith(l, s, e.create({ html: m })).scrollIntoView();
410
262
  })
411
263
  ],
412
- remarkPlugins: () => [remarkEmoji, twemojiPlugin],
264
+ remarkPlugins: () => [D, te],
413
265
  prosePlugins: () => {
414
- var _a;
415
- return [filter(utils, (_a = options == null ? void 0 : options.maxListSize) != null ? _a : 6)];
266
+ var e;
267
+ return [X(i, (e = d == null ? void 0 : d.maxListSize) != null ? e : 6)];
416
268
  }
417
269
  };
418
- });
419
- const emoji = AtomList.create([emojiNode()]);
420
- export { emoji, emojiNode };
270
+ }), fe = N.create([ne()]);
271
+ export {
272
+ fe as emoji,
273
+ ne as emojiNode
274
+ };
421
275
  //# 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: 0.5em;\n height: 2.57143em;\n padding: 0 1em;\n align-items: center;\n justify-content: flex-start;\n cursor: pointer;\n line-height: 2;\n font-family: ${typography};\n font-size: 0.875em;\n &.active {\n background: ${palette('secondary', 0.12)};\n color: ${palette('primary')};\n }\n }\n\n .emoji {\n height: 1em;\n width: 1em;\n margin: 0 0.05em 0 0.1em;\n vertical-align: -0.1em;\n }\n `;\n return cx(border, shadow, style);\n};\n","/* Copyright 2021, Milkdown by Mirone. */\n\nimport { calculateNodePosition } from '@milkdown/prose';\nimport { Plugin, PluginKey } from '@milkdown/prose/state';\nimport { Utils } 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: Utils, 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 new Error();\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 new Error();\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 { 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 0.05em 0 0.1em;\n vertical-align: -0.1em;\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 new Error();\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): 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 { Utils } 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: Utils, 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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"}
package/lib/node.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAYA,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;CACvB,CAAC;AAEF,eAAO,MAAM,SAAS,6DAmFpB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milkdown/plugin-emoji",
3
- "version": "6.2.0",
3
+ "version": "6.3.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.2.0",
19
- "@milkdown/prose": "6.2.0",
18
+ "@milkdown/core": "6.3.2",
19
+ "@milkdown/prose": "6.3.2",
20
20
  "@types/unist": "^2.0.6"
21
21
  },
22
22
  "peerDependencies": {
@@ -24,12 +24,13 @@
24
24
  "@milkdown/prose": "^6.0.1"
25
25
  },
26
26
  "dependencies": {
27
- "@milkdown/utils": "6.2.0",
27
+ "@milkdown/exception": "6.3.2",
28
+ "@milkdown/utils": "6.3.2",
28
29
  "@types/node-emoji": "^1.8.1",
29
30
  "emoji-regex": "^10.0.0",
30
31
  "node-emoji": "^1.10.0",
31
32
  "remark-emoji": "^3.0.1",
32
- "tslib": "^2.3.1",
33
+ "tslib": "^2.4.0",
33
34
  "twemoji": "^14.0.1",
34
35
  "unist-util-visit": "^4.0.0"
35
36
  },
@@ -1,5 +1,6 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
2
 
3
+ import { missingRootElement } from '@milkdown/exception';
3
4
  import { calculateNodePosition } from '@milkdown/prose';
4
5
  import { Plugin, PluginKey } from '@milkdown/prose/state';
5
6
  import { Utils } from '@milkdown/utils';
@@ -62,7 +63,7 @@ export const filter = (utils: Utils, maxListSize: number) => {
62
63
  view: (editorView) => {
63
64
  const { parentNode } = editorView.dom;
64
65
  if (!parentNode) {
65
- throw new Error();
66
+ throw missingRootElement();
66
67
  }
67
68
 
68
69
  const dropDown = document.createElement('div');
@@ -150,7 +151,7 @@ export const filter = (utils: Utils, maxListSize: number) => {
150
151
  calculateNodePosition(view, dropDown, (selected, target, parent) => {
151
152
  const $editor = dropDown.parentElement;
152
153
  if (!$editor) {
153
- throw new Error();
154
+ throw missingRootElement();
154
155
  }
155
156
  const start = view.coordsAtPos(_from);
156
157
  let left = start.left - parent.left;
@@ -28,15 +28,15 @@ export const injectStyle = (themeManager: ThemeManager, { css, cx }: Emotion) =>
28
28
 
29
29
  .milkdown-emoji-filter_item {
30
30
  display: flex;
31
- gap: 0.5em;
32
- height: 2.57143em;
33
- padding: 0 1em;
31
+ gap: 8px;
32
+ height: 36px;
33
+ padding: 0 14px;
34
34
  align-items: center;
35
35
  justify-content: flex-start;
36
36
  cursor: pointer;
37
37
  line-height: 2;
38
38
  font-family: ${typography};
39
- font-size: 0.875em;
39
+ font-size: 14px;
40
40
  &.active {
41
41
  background: ${palette('secondary', 0.12)};
42
42
  color: ${palette('primary')};
@@ -44,10 +44,10 @@ export const injectStyle = (themeManager: ThemeManager, { css, cx }: Emotion) =>
44
44
  }
45
45
 
46
46
  .emoji {
47
- height: 1em;
48
- width: 1em;
49
- margin: 0 0.05em 0 0.1em;
50
- vertical-align: -0.1em;
47
+ height: 14px;
48
+ width: 14px;
49
+ margin: 0 1px 0 1.5px;
50
+ vertical-align: -1.5px;
51
51
  }
52
52
  `;
53
53
  return cx(border, shadow, style);
package/src/node.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
2
  import { RemarkPlugin } from '@milkdown/core';
3
+ import { expectDomTypeError } from '@milkdown/exception';
3
4
  import { InputRule } from '@milkdown/prose/inputrules';
4
5
  import { createNode } from '@milkdown/utils';
5
6
  import nodeEmoji from 'node-emoji';
@@ -21,8 +22,8 @@ export const emojiNode = createNode<string, EmojiOptions>((utils, options) => {
21
22
  .emoji {
22
23
  height: 1em;
23
24
  width: 1em;
24
- margin: 0 0.05em 0 0.1em;
25
- vertical-align: -0.1em;
25
+ margin: 0 1px 0 1.5px;
26
+ vertical-align: -1.5px;
26
27
  }
27
28
  `,
28
29
  );
@@ -42,7 +43,7 @@ export const emojiNode = createNode<string, EmojiOptions>((utils, options) => {
42
43
  tag: 'span[data-type="emoji"]',
43
44
  getAttrs: (dom) => {
44
45
  if (!(dom instanceof HTMLElement)) {
45
- throw new Error();
46
+ throw expectDomTypeError(dom);
46
47
  }
47
48
  return { html: dom.innerHTML };
48
49
  },