@milkdown/plugin-emoji 5.3.0 → 5.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,15 +1,9 @@
1
1
  {
2
2
  "name": "@milkdown/plugin-emoji",
3
- "version": "5.3.0",
4
- "main": "./lib/index.cjs.js",
5
- "module": "./lib/index.es.js",
3
+ "version": "5.3.1",
4
+ "type": "module",
5
+ "main": "./lib/index.es.js",
6
6
  "types": "./lib/index.d.ts",
7
- "exports": {
8
- ".": {
9
- "import": "./lib/index.es.js",
10
- "require": "./lib/index.cjs.js"
11
- }
12
- },
13
7
  "sideEffects": false,
14
8
  "license": "MIT",
15
9
  "files": [
@@ -26,7 +20,7 @@
26
20
  "dependencies": {
27
21
  "@emotion/css": "^11.1.3",
28
22
  "@joeattardi/emoji-button": "^4.6.0",
29
- "@milkdown/utils": "5.3.0",
23
+ "@milkdown/utils": "5.3.1",
30
24
  "@types/node-emoji": "^1.8.1",
31
25
  "@types/twemoji": "^12.1.2",
32
26
  "emoji-regex": "^10.0.0",
@@ -37,14 +31,14 @@
37
31
  "unist-util-visit": "^4.0.0"
38
32
  },
39
33
  "devDependencies": {
40
- "@milkdown/core": "5.3.0",
41
- "@milkdown/prose": "5.3.0",
42
- "@milkdown/utils": "5.3.0"
34
+ "@milkdown/core": "5.3.1",
35
+ "@milkdown/prose": "5.3.1",
36
+ "@milkdown/utils": "5.3.1"
43
37
  },
44
38
  "scripts": {
45
39
  "start": "vite",
46
40
  "watch": "vite build --watch",
47
- "test": "jest",
41
+ "test": "vitest",
48
42
  "tsc": "tsc --noEmit",
49
43
  "build": "vite build && tsc --emitDeclarationOnly"
50
44
  },
package/lib/index.cjs.js DELETED
@@ -1,58 +0,0 @@
1
- "use strict";var S=Object.defineProperty,C=Object.defineProperties;var N=Object.getOwnPropertyDescriptors;var x=Object.getOwnPropertySymbols;var H=Object.prototype.hasOwnProperty,q=Object.prototype.propertyIsEnumerable;var $=(n,t,e)=>t in n?S(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,j=(n,t)=>{for(var e in t||(t={}))H.call(t,e)&&$(n,e,t[e]);if(x)for(var e of x(t))q.call(t,e)&&$(n,e,t[e]);return n},y=(n,t)=>C(n,N(t));Object.defineProperty(exports,"__esModule",{value:!0});exports[Symbol.toStringTag]="Module";var P=require("@milkdown/utils"),w=require("@emotion/css"),h=require("@milkdown/prose"),T=require("node-emoji"),A=require("remark-emoji"),B=require("twemoji"),F=require("@joeattardi/emoji-button"),O=require("emoji-regex");function k(n){return n&&typeof n=="object"&&"default"in n?n:{default:n}}var R=k(T),I=k(A),z=k(B),K=k(O);const W=/:\+1|:-1|:[\w-]+/,U=/:\+1:|:-1:|:[\w-]+:/,G=/(:([^:\s]+):)$/,v=n=>z.default.parse(n,{attributes:t=>({title:t})}),J=(n,t,e,i,s,c)=>{if(n.composing)return!1;const{state:a}=n,o=a.doc.resolve(t);if(o.parent.type.spec.code)return!1;const r=o.parent.textBetween(Math.max(0,o.parentOffset-10),o.parentOffset,void 0,"\uFFFC")+i;if(U.test(r))return!1;const d=W.exec(r);if(d&&r.endsWith(d[0])){const l=d[0];return s(t-(l.length-i.length),e),c(l),!0}return!1},Q=(n,t,e,i,s)=>{t.innerHTML="",n.forEach(({emoji:c,key:a},o)=>{const r=document.createElement("div");r.className="milkdown-emoji-filter_item";const d=document.createElement("span");d.innerHTML=v(c),d.className="milkdown-emoji-filter_item-emoji";const l=document.createElement("span");l.textContent=":"+a+":",l.className="milkdown-emoji-filter_item-key",r.appendChild(d),r.appendChild(l),t.appendChild(r),o===0&&(r.classList.add("active"),s(r)),r.addEventListener("mouseenter",u=>{e&&e.classList.remove("active");const{target:m}=u;m instanceof HTMLElement&&(m.classList.add("active"),s(m))}),r.addEventListener("mouseleave",u=>{const{target:m}=u;m instanceof HTMLElement&&m.classList.remove("active")}),r.addEventListener("mousedown",u=>{i(),u.preventDefault()})})},X=({size:n,mixin:t,palette:e,font:i})=>{var o,r;const s=(o=t.border)==null?void 0:o.call(t),c=(r=t.shadow)==null?void 0:r.call(t),a=w.css`
2
- position: absolute;
3
- &.hide {
4
- display: none;
5
- }
6
-
7
- border-radius: ${n.radius};
8
- background: ${e("surface")};
9
-
10
- .milkdown-emoji-filter_item {
11
- display: flex;
12
- gap: 0.5rem;
13
- height: 2.25rem;
14
- padding: 0 1rem;
15
- align-items: center;
16
- justify-content: flex-start;
17
- cursor: pointer;
18
- line-height: 2;
19
- font-family: ${i.typography};
20
- font-size: 0.875rem;
21
- &.active {
22
- background: ${e("secondary",.12)};
23
- color: ${e("primary")};
24
- }
25
- }
26
-
27
- .emoji {
28
- height: 1em;
29
- width: 1em;
30
- margin: 0 0.05em 0 0.1em;
31
- vertical-align: -0.1em;
32
- }
33
- `;return w.cx(s,c,a)},Y=n=>{let t=!1,e=0,i="",s=null;const c=()=>{t=!1,e=0,i="",s=null};return new h.Plugin({props:{handleKeyDown(a,o){return["Delete","Backspace"].includes(o.key)?(i=i.slice(0,-1),i.length<=1&&c(),!1):!(!t||!["ArrowUp","ArrowDown","Enter"].includes(o.key))},handleTextInput(a,o,r,d){return t=J(a,o,r,d,l=>{e=l},l=>{i=l}),t||c(),!1}},view:a=>{const{parentNode:o}=a.dom;if(!o)throw new Error;const r=document.createElement("div"),d=n.getStyle(X);d&&d.split(" ").forEach(u=>r.classList.add(u)),r.classList.add("milkdown-emoji-filter","hide");const l=()=>{var f;if(!s)return;const{tr:u}=a.state,m=a.state.schema.node("emoji",{html:(f=s.firstElementChild)==null?void 0:f.innerHTML});a.dispatch(u.delete(e,e+i.length).insert(e,m)),c(),r.classList.add("hide")};return o.appendChild(r),o.addEventListener("keydown",u=>{if(!t||!(u instanceof KeyboardEvent))return;const{key:m}=u;if(m==="Enter"){l();return}if(["ArrowDown","ArrowUp"].includes(m)){const f=m==="ArrowDown"?(s==null?void 0:s.nextElementSibling)||r.firstElementChild:(s==null?void 0:s.previousElementSibling)||r.lastElementChild;if(s&&s.classList.remove("active"),!f)return;f.classList.add("active"),s=f;return}}),o.addEventListener("mousedown",u=>{!t||(u.stopPropagation(),c(),r.classList.add("hide"))}),{update:u=>{if(!t)return r.classList.add("hide"),null;const m=T.search(i).slice(0,5),{node:f}=u.domAtPos(e);return m.length===0||!f?(r.classList.add("hide"),null):(r.classList.remove("hide"),Q(m,r,s,l,p=>{s=p}),h.calculateNodePosition(u,r,(p,g,E)=>{const _=u.coordsAtPos(e);let L=_.left-E.left,M=p.bottom-E.top+14;return L<0&&(L=0),window.innerHeight-_.bottom<g.height&&(M=p.top-E.top-g.height-14),[M,L]}),null)}}}})},b=":emoji:",Z=(n,t,e,i,s)=>{if(n.composing)return!1;const{state:c}=n,a=c.doc.resolve(t);return a.parent.type.spec.code?!1:a.parent.textBetween(a.parentOffset-b.length+1,a.parentOffset,void 0,"\uFFFC")+i===b?(s(t-b.length+1,e+1),!0):!1},V=n=>{let t=!1;const e=document.createElement("span");let i=0,s=0;const c=()=>{t=!1,i=0,s=0};return new h.Plugin({props:{handleKeyDown(){return c(),!1},handleClick(){return c(),!1},handleTextInput(o,r,d,l){return t=Z(o,r,d,l,(u,m)=>{i=u,s=m}),t||c(),!1},decorations(o){return t?h.DecorationSet.create(o.doc,[h.Decoration.widget(o.selection.to,e)]):null}},view:o=>{const{parentNode:r}=o.dom;if(!r)throw new Error;n.getStyle(({palette:l,font:u})=>{w.injectGlobal`
34
- .emoji-picker {
35
- --dark-search-background-color: ${l("surface")} !important;
36
- --dark-text-color: ${l("neutral",.87)} !important;
37
- --dark-background-color: ${l("background")} !important;
38
- --dark-border-color: ${l("shadow")} !important;
39
- --dark-hover-color: ${l("secondary",.12)} !important;
40
- --dark-blue-color: ${l("primary")} !important;
41
- --dark-search-icon-color: ${l("primary")} !important;
42
- --dark-category-button-color: ${l("secondary",.4)} !important;
43
- --font: ${u.typography} !important;
44
- --font-size: 1rem !important;
45
- }
46
- `});const d=new F.EmojiButton({rootElement:r,autoFocusSearch:!1,style:"twemoji",theme:"dark",zIndex:99});return d.on("emoji",l=>{const u=i,m=s;c();const f=v(l.emoji),p=o.state.schema.node("emoji",{html:f}),{tr:g}=o.state;o.dispatch(g.replaceRangeWith(u,m,p))}),{update:()=>t?(d.showPicker(e),null):(d.hidePicker(),null),destroy:()=>{d.destroyPicker()}}}})},ee=K.default(),te=n=>!!n.children,re=n=>!!n.value;function ne(n,t){return e(n,0,null)[0];function e(i,s,c){if(te(i)){const a=[];for(let o=0,r=i.children.length;o<r;o++){const d=e(i.children[o],o,i);if(d)for(let l=0,u=d.length;l<u;l++)a.push(d[l])}i.children=a}return t(i,s,c)}}const oe=()=>{function n(t){ne(t,e=>{if(!re(e))return[e];const i=e.value,s=[];let c,a=i;for(;c=ee.exec(a);){const{index:o}=c,r=c[0];o>0&&s.push(y(j({},e),{value:a.slice(0,o)})),s.push(y(j({},e),{value:v(r),type:"emoji"})),a=a.slice(o+r.length)}return a.length&&s.push(y(j({},e),{value:a})),s})}return n},D=P.createNode(n=>{const t=n.getStyle(()=>w.css`
47
- display: inline-flex;
48
- justify-content: center;
49
- align-items: center;
50
-
51
- .emoji {
52
- height: 1em;
53
- width: 1em;
54
- margin: 0 0.05em 0 0.1em;
55
- vertical-align: -0.1em;
56
- }
57
- `);return{id:"emoji",schema:()=>({group:"inline",inline:!0,selectable:!1,attrs:{html:{default:""}},parseDOM:[{tag:'span[data-type="emoji"]',getAttrs:e=>{if(!(e instanceof HTMLElement))throw new Error;return{html:e.innerHTML}}}],toDOM:e=>{const i=document.createElement("span");return i.dataset.type="emoji",t&&i.classList.add(t),i.classList.add("emoji-wrapper"),i.innerHTML=e.attrs.html,{dom:i}},parseMarkdown:{match:({type:e})=>e==="emoji",runner:(e,i,s)=>{e.addNode(s,{html:i.value})}},toMarkdown:{match:e=>e.type.name==="emoji",runner:(e,i)=>{const s=document.createElement("span");s.innerHTML=i.attrs.html;const c=s.querySelector("img"),a=c==null?void 0:c.title;s.remove(),e.addNode("text",void 0,a)}}}),inputRules:e=>[new h.InputRule(G,(i,s,c,a)=>{const o=s[0];if(!o)return null;const r=R.default.get(o);if(!r||o.includes(r))return null;const d=v(r);return i.tr.setMeta("emoji",!0).replaceRangeWith(c,a,e.create({html:d})).scrollIntoView()})],remarkPlugins:()=>[I.default,oe],prosePlugins:()=>[V(n),Y(n)]}}),se=P.AtomList.create([D()]);exports.emoji=se;exports.emojiNode=D;
58
- //# sourceMappingURL=index.cjs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/constant.ts","../src/parse.ts","../src/filter/helper.ts","../src/filter/style.ts","../src/filter/index.ts","../src/picker.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]+):)$/;\nexport const keyword = ':emoji:';\n","/* Copyright 2021, Milkdown by Mirone. */\nimport twemoji from 'twemoji';\n\nexport const parse = (emoji: string) => twemoji.parse(emoji, { attributes: (text) => ({ title: text }) });\n","/* Copyright 2021, Milkdown by Mirone. */\n\nimport { EditorView } from '@milkdown/prose';\nimport { 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 if (full.test(textBefore)) {\n return false;\n }\n const regex = part.exec(textBefore);\n if (regex && 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 dropDown.innerHTML = '';\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 container.addEventListener('mouseenter', (e) => {\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 container.addEventListener('mouseleave', (e) => {\n const { target } = e;\n if (!(target instanceof HTMLElement)) return;\n target.classList.remove('active');\n });\n container.addEventListener('mousedown', (e) => {\n onConfirm();\n e.preventDefault();\n });\n });\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { css, cx } from '@emotion/css';\nimport type { ThemeTool } from '@milkdown/core';\n\nexport const injectStyle = ({ size, mixin, palette, font }: ThemeTool) => {\n const border = mixin.border?.();\n const shadow = mixin.shadow?.();\n\n const style = css`\n position: absolute;\n &.hide {\n display: none;\n }\n\n border-radius: ${size.radius};\n background: ${palette('surface')};\n\n .milkdown-emoji-filter_item {\n display: flex;\n gap: 0.5rem;\n height: 2.25rem;\n padding: 0 1rem;\n align-items: center;\n justify-content: flex-start;\n cursor: pointer;\n line-height: 2;\n font-family: ${font.typography};\n font-size: 0.875rem;\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, Plugin } from '@milkdown/prose';\nimport { Utils } from '@milkdown/utils';\nimport { search } from 'node-emoji';\n\nimport { checkTrigger, renderDropdownList } from './helper';\nimport { injectStyle } from './style';\n\nexport const filter = (utils: Utils) => {\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 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 const style = utils.getStyle(injectStyle);\n\n if (style) {\n style.split(' ').forEach((x) => dropDown.classList.add(x));\n }\n\n dropDown.classList.add('milkdown-emoji-filter', 'hide');\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 parentNode.addEventListener('keydown', (e) => {\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 parentNode.addEventListener('mousedown', (e) => {\n if (!trigger) return;\n\n e.stopPropagation();\n off();\n dropDown.classList.add('hide');\n });\n\n return {\n update: (view) => {\n if (!trigger) {\n dropDown.classList.add('hide');\n return null;\n }\n const result = search(_search).slice(0, 5);\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 start = view.coordsAtPos(_from);\n let left = start.left - parent.left;\n let top = selected.bottom - parent.top + 14;\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;\n }\n return [top, left];\n });\n\n return null;\n },\n };\n },\n });\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { injectGlobal } from '@emotion/css';\nimport { EmojiButton } from '@joeattardi/emoji-button';\nimport { Decoration, DecorationSet, EditorView, Plugin } from '@milkdown/prose';\nimport { Utils } from '@milkdown/utils';\n\nimport { parse } from './parse';\n\nconst keyword = ':emoji:';\n\nconst checkTrigger = (\n view: EditorView,\n from: number,\n to: number,\n text: string,\n setRange: (from: number, to: number) => 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($from.parentOffset - keyword.length + 1, $from.parentOffset, undefined, '\\ufffc') +\n text;\n if (textBefore === keyword) {\n setRange(from - keyword.length + 1, to + 1);\n return true;\n }\n return false;\n};\n\nexport const picker = (utils: Utils) => {\n let trigger = false;\n const holder = document.createElement('span');\n let _from = 0;\n let _to = 0;\n const off = () => {\n trigger = false;\n _from = 0;\n _to = 0;\n };\n\n const plugin = new Plugin({\n props: {\n handleKeyDown() {\n off();\n return false;\n },\n handleClick() {\n off();\n return false;\n },\n handleTextInput(view, from, to, text) {\n trigger = checkTrigger(view, from, to, text, (from, to) => {\n _from = from;\n _to = to;\n });\n\n if (!trigger) {\n off();\n }\n return false;\n },\n decorations(state) {\n if (!trigger) return null;\n\n return DecorationSet.create(state.doc, [Decoration.widget(state.selection.to, holder)]);\n },\n },\n view: (editorView) => {\n const { parentNode } = editorView.dom;\n if (!parentNode) {\n throw new Error();\n }\n utils.getStyle(({ palette, font }) => {\n const css = injectGlobal;\n css`\n .emoji-picker {\n --dark-search-background-color: ${palette('surface')} !important;\n --dark-text-color: ${palette('neutral', 0.87)} !important;\n --dark-background-color: ${palette('background')} !important;\n --dark-border-color: ${palette('shadow')} !important;\n --dark-hover-color: ${palette('secondary', 0.12)} !important;\n --dark-blue-color: ${palette('primary')} !important;\n --dark-search-icon-color: ${palette('primary')} !important;\n --dark-category-button-color: ${palette('secondary', 0.4)} !important;\n --font: ${font.typography} !important;\n --font-size: 1rem !important;\n }\n `;\n });\n const emojiPicker = new EmojiButton({\n rootElement: parentNode as HTMLElement,\n autoFocusSearch: false,\n style: 'twemoji',\n theme: 'dark',\n zIndex: 99,\n });\n emojiPicker.on('emoji', (selection) => {\n const start = _from;\n const end = _to;\n off();\n const html = parse(selection.emoji);\n const node = editorView.state.schema.node('emoji', { html });\n const { tr } = editorView.state;\n\n editorView.dispatch(tr.replaceRangeWith(start, end, node));\n });\n return {\n update: () => {\n if (!trigger) {\n emojiPicker.hidePicker();\n return null;\n }\n emojiPicker.showPicker(holder);\n return null;\n },\n destroy: () => {\n emojiPicker.destroyPicker();\n },\n };\n },\n });\n\n return plugin;\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 xs = transform(node.children[i], i, node);\n if (xs) {\n for (let j = 0, m = xs.length; j < m; j++) {\n out.push(xs[j]);\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 (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 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 { css } from '@emotion/css';\nimport { RemarkPlugin } from '@milkdown/core';\nimport { InputRule } from '@milkdown/prose';\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 { picker } from './picker';\nimport { twemojiPlugin } from './remark-twemoji';\n\nexport const emojiNode = createNode((utils) => {\n const style = utils.getStyle(\n () => css`\n display: inline-flex;\n justify-content: center;\n align-items: center;\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 );\n return {\n id: 'emoji',\n schema: () => ({\n group: 'inline',\n inline: true,\n selectable: false,\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.dataset.type = 'emoji';\n if (style) {\n span.classList.add(style);\n }\n span.classList.add('emoji-wrapper');\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: () => [picker(utils), filter(utils)],\n };\n});\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { AtomList } from '@milkdown/utils';\n\nimport { emojiNode } from './node';\n\nexport const emoji = AtomList.create([emojiNode()]);\n\nexport { emojiNode } from './node';\n"],"names":["twemoji","checkTrigger","css","cx","Plugin","search","DecorationSet","Decoration","injectGlobal","EmojiButton","emojiRegex","createNode","InputRule","nodeEmoji","remarkEmoji","AtomList"],"mappings":"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"}