@chayns-components/emoji-input 5.4.8 → 5.4.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/components/emoji-input/EmojiInput.js +15 -5
- package/lib/cjs/components/emoji-input/EmojiInput.js.map +1 -1
- package/lib/cjs/components/emoji-picker-popup/EmojiPickerPopup.js +3 -1
- package/lib/cjs/components/emoji-picker-popup/EmojiPickerPopup.js.map +1 -1
- package/lib/cjs/utils/selection.js +24 -8
- package/lib/cjs/utils/selection.js.map +1 -1
- package/lib/esm/components/emoji-input/EmojiInput.js +15 -5
- package/lib/esm/components/emoji-input/EmojiInput.js.map +1 -1
- package/lib/esm/components/emoji-picker-popup/EmojiPickerPopup.js +3 -1
- package/lib/esm/components/emoji-picker-popup/EmojiPickerPopup.js.map +1 -1
- package/lib/esm/utils/selection.js +24 -8
- package/lib/esm/utils/selection.js.map +1 -1
- package/lib/types/components/emoji-input/EmojiInput.d.ts +8 -0
- package/lib/types/components/emoji-picker-popup/EmojiPickerPopup.d.ts +4 -0
- package/package.json +2 -2
|
@@ -4,6 +4,7 @@ import EmojiPicker from '../emoji-picker/EmojiPicker';
|
|
|
4
4
|
import { StyledEmojiPickerPopup } from './EmojiPickerPopup.styles';
|
|
5
5
|
const EmojiPickerPopup = ({
|
|
6
6
|
accessToken,
|
|
7
|
+
container,
|
|
7
8
|
onPopupVisibilityChange,
|
|
8
9
|
onSelect,
|
|
9
10
|
personId
|
|
@@ -17,10 +18,11 @@ const EmojiPickerPopup = ({
|
|
|
17
18
|
useEffect(() => {
|
|
18
19
|
document.addEventListener('keydown', handleKeyPress);
|
|
19
20
|
return () => {
|
|
20
|
-
document.
|
|
21
|
+
document.removeEventListener('keydown', handleKeyPress);
|
|
21
22
|
};
|
|
22
23
|
}, [handleKeyPress]);
|
|
23
24
|
return /*#__PURE__*/React.createElement(StyledEmojiPickerPopup, null, /*#__PURE__*/React.createElement(Popup, {
|
|
25
|
+
container: container,
|
|
24
26
|
ref: popupRef,
|
|
25
27
|
onHide: () => typeof onPopupVisibilityChange === 'function' ? onPopupVisibilityChange(false) : undefined,
|
|
26
28
|
onShow: () => typeof onPopupVisibilityChange === 'function' ? onPopupVisibilityChange(true) : undefined,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmojiPickerPopup.js","names":["AreaProvider","Icon","Popup","React","useCallback","useEffect","useRef","EmojiPicker","StyledEmojiPickerPopup","EmojiPickerPopup","accessToken","onPopupVisibilityChange","onSelect","personId","popupRef","handleKeyPress","event","key","shiftKey","current","hide","document","addEventListener","createElement","ref","onHide","undefined","onShow","content","shouldChangeColor","className","icons","size","displayName"],"sources":["../../../../src/components/emoji-picker-popup/EmojiPickerPopup.tsx"],"sourcesContent":["import { AreaProvider, Icon, Popup, type PopupRef } from '@chayns-components/core';\nimport React, { FC, useCallback, useEffect, useRef } from 'react';\nimport EmojiPicker from '../emoji-picker/EmojiPicker';\nimport { StyledEmojiPickerPopup } from './EmojiPickerPopup.styles';\n\nexport type EmojiPickerPopupProps = {\n /**\n * Access token of the logged-in user. Is needed to load and save the history of the emojis.\n */\n accessToken?: string;\n /**\n * Function that is executed when the visibility of the popup changes.\n * @param {boolean} isVisible - Whether the popup is visible or not\n */\n onPopupVisibilityChange?: (isVisible: boolean) => void;\n /**\n * Person id of the logged-in user. Is needed to load and save the history of the emojis.\n */\n personId?: string;\n /**\n * Function executed when an emoji is selected in the popup\n * @param {string} emoji - Emoji that was selected\n */\n onSelect: (emoji: string) => void;\n};\n\nconst EmojiPickerPopup: FC<EmojiPickerPopupProps> = ({\n accessToken,\n onPopupVisibilityChange,\n onSelect,\n personId,\n}) => {\n const popupRef = useRef<PopupRef>(null);\n\n const handleKeyPress = useCallback((event: KeyboardEvent) => {\n if (event.key === 'Escape' && !event.shiftKey) {\n popupRef.current?.hide();\n }\n }, []);\n\n useEffect(() => {\n document.addEventListener('keydown', handleKeyPress);\n\n return () => {\n document.
|
|
1
|
+
{"version":3,"file":"EmojiPickerPopup.js","names":["AreaProvider","Icon","Popup","React","useCallback","useEffect","useRef","EmojiPicker","StyledEmojiPickerPopup","EmojiPickerPopup","accessToken","container","onPopupVisibilityChange","onSelect","personId","popupRef","handleKeyPress","event","key","shiftKey","current","hide","document","addEventListener","removeEventListener","createElement","ref","onHide","undefined","onShow","content","shouldChangeColor","className","icons","size","displayName"],"sources":["../../../../src/components/emoji-picker-popup/EmojiPickerPopup.tsx"],"sourcesContent":["import { AreaProvider, Icon, Popup, PopupAlignment, type PopupRef } from '@chayns-components/core';\nimport React, { FC, useCallback, useEffect, useRef } from 'react';\nimport EmojiPicker from '../emoji-picker/EmojiPicker';\nimport { StyledEmojiPickerPopup } from './EmojiPickerPopup.styles';\n\nexport type EmojiPickerPopupProps = {\n /**\n * Access token of the logged-in user. Is needed to load and save the history of the emojis.\n */\n accessToken?: string;\n /**\n * The DOM element that should receive the popup portal.\n */\n container?: Element;\n /**\n * Function that is executed when the visibility of the popup changes.\n * @param {boolean} isVisible - Whether the popup is visible or not\n */\n onPopupVisibilityChange?: (isVisible: boolean) => void;\n /**\n * Person id of the logged-in user. Is needed to load and save the history of the emojis.\n */\n personId?: string;\n /**\n * Function executed when an emoji is selected in the popup\n * @param {string} emoji - Emoji that was selected\n */\n onSelect: (emoji: string) => void;\n};\n\nconst EmojiPickerPopup: FC<EmojiPickerPopupProps> = ({\n accessToken,\n container,\n onPopupVisibilityChange,\n onSelect,\n personId,\n}) => {\n const popupRef = useRef<PopupRef>(null);\n\n const handleKeyPress = useCallback((event: KeyboardEvent) => {\n if (event.key === 'Escape' && !event.shiftKey) {\n popupRef.current?.hide();\n }\n }, []);\n\n useEffect(() => {\n document.addEventListener('keydown', handleKeyPress);\n\n return () => {\n document.removeEventListener('keydown', handleKeyPress);\n };\n }, [handleKeyPress]);\n\n return (\n <StyledEmojiPickerPopup>\n <Popup\n container={container}\n ref={popupRef}\n onHide={() =>\n typeof onPopupVisibilityChange === 'function'\n ? onPopupVisibilityChange(false)\n : undefined\n }\n onShow={() =>\n typeof onPopupVisibilityChange === 'function'\n ? onPopupVisibilityChange(true)\n : undefined\n }\n content={\n <AreaProvider shouldChangeColor={false}>\n <EmojiPicker\n accessToken={accessToken}\n onSelect={onSelect}\n personId={personId}\n />\n </AreaProvider>\n }\n >\n <Icon className=\"prevent-lose-focus\" icons={['far fa-smile']} size={18} />\n </Popup>\n </StyledEmojiPickerPopup>\n );\n};\n\nEmojiPickerPopup.displayName = 'EmojiPickerPopup';\n\nexport default EmojiPickerPopup;\n"],"mappings":"AAAA,SAASA,YAAY,EAAEC,IAAI,EAAEC,KAAK,QAAuC,yBAAyB;AAClG,OAAOC,KAAK,IAAQC,WAAW,EAAEC,SAAS,EAAEC,MAAM,QAAQ,OAAO;AACjE,OAAOC,WAAW,MAAM,6BAA6B;AACrD,SAASC,sBAAsB,QAAQ,2BAA2B;AA2BlE,MAAMC,gBAA2C,GAAGA,CAAC;EACjDC,WAAW;EACXC,SAAS;EACTC,uBAAuB;EACvBC,QAAQ;EACRC;AACJ,CAAC,KAAK;EACF,MAAMC,QAAQ,GAAGT,MAAM,CAAW,IAAI,CAAC;EAEvC,MAAMU,cAAc,GAAGZ,WAAW,CAAEa,KAAoB,IAAK;IACzD,IAAIA,KAAK,CAACC,GAAG,KAAK,QAAQ,IAAI,CAACD,KAAK,CAACE,QAAQ,EAAE;MAC3CJ,QAAQ,CAACK,OAAO,EAAEC,IAAI,CAAC,CAAC;IAC5B;EACJ,CAAC,EAAE,EAAE,CAAC;EAENhB,SAAS,CAAC,MAAM;IACZiB,QAAQ,CAACC,gBAAgB,CAAC,SAAS,EAAEP,cAAc,CAAC;IAEpD,OAAO,MAAM;MACTM,QAAQ,CAACE,mBAAmB,CAAC,SAAS,EAAER,cAAc,CAAC;IAC3D,CAAC;EACL,CAAC,EAAE,CAACA,cAAc,CAAC,CAAC;EAEpB,oBACIb,KAAA,CAAAsB,aAAA,CAACjB,sBAAsB,qBACnBL,KAAA,CAAAsB,aAAA,CAACvB,KAAK;IACFS,SAAS,EAAEA,SAAU;IACrBe,GAAG,EAAEX,QAAS;IACdY,MAAM,EAAEA,CAAA,KACJ,OAAOf,uBAAuB,KAAK,UAAU,GACvCA,uBAAuB,CAAC,KAAK,CAAC,GAC9BgB,SACT;IACDC,MAAM,EAAEA,CAAA,KACJ,OAAOjB,uBAAuB,KAAK,UAAU,GACvCA,uBAAuB,CAAC,IAAI,CAAC,GAC7BgB,SACT;IACDE,OAAO,eACH3B,KAAA,CAAAsB,aAAA,CAACzB,YAAY;MAAC+B,iBAAiB,EAAE;IAAM,gBACnC5B,KAAA,CAAAsB,aAAA,CAAClB,WAAW;MACRG,WAAW,EAAEA,WAAY;MACzBG,QAAQ,EAAEA,QAAS;MACnBC,QAAQ,EAAEA;IAAS,CACtB,CACS;EACjB,gBAEDX,KAAA,CAAAsB,aAAA,CAACxB,IAAI;IAAC+B,SAAS,EAAC,oBAAoB;IAACC,KAAK,EAAE,CAAC,cAAc,CAAE;IAACC,IAAI,EAAE;EAAG,CAAE,CACtE,CACa,CAAC;AAEjC,CAAC;AAEDzB,gBAAgB,CAAC0B,WAAW,GAAG,kBAAkB;AAEjD,eAAe1B,gBAAgB","ignoreList":[]}
|
|
@@ -431,20 +431,25 @@ export const unwrapIgnoreEmojiSpanAtCursor = editorElement => {
|
|
|
431
431
|
commonAncestorContainer
|
|
432
432
|
} = range;
|
|
433
433
|
const cursorOffset = range.startOffset;
|
|
434
|
+
if (!editorElement.contains(commonAncestorContainer)) {
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
434
437
|
|
|
435
438
|
// Walk up the DOM tree to find if we're inside a no-emoji-convert span
|
|
436
439
|
while (commonAncestorContainer && commonAncestorContainer !== editorElement) {
|
|
437
|
-
if (commonAncestorContainer.nodeType === Node.ELEMENT_NODE && commonAncestorContainer.
|
|
440
|
+
if (commonAncestorContainer.nodeType === Node.ELEMENT_NODE && commonAncestorContainer.classList.contains('no-emoji-convert')) {
|
|
438
441
|
// We're inside a no-emoji-convert span, unwrap it
|
|
439
442
|
const span = commonAncestorContainer;
|
|
440
|
-
const
|
|
443
|
+
const {
|
|
444
|
+
parentNode
|
|
445
|
+
} = span;
|
|
441
446
|
if (!parentNode) {
|
|
442
447
|
return;
|
|
443
448
|
}
|
|
444
449
|
|
|
445
450
|
// Find which text node contains the cursor
|
|
446
451
|
let cursorNode = null;
|
|
447
|
-
|
|
452
|
+
const cursorNodeOffset = cursorOffset;
|
|
448
453
|
|
|
449
454
|
// Get all child nodes of the span
|
|
450
455
|
const childNodes = Array.from(span.childNodes);
|
|
@@ -472,7 +477,9 @@ export const unwrapIgnoreEmojiSpanAtCursor = editorElement => {
|
|
|
472
477
|
}
|
|
473
478
|
break;
|
|
474
479
|
}
|
|
475
|
-
|
|
480
|
+
|
|
481
|
+
// @ts-expect-error - is needed
|
|
482
|
+
commonAncestorContainer = commonAncestorContainer.parentNode;
|
|
476
483
|
}
|
|
477
484
|
};
|
|
478
485
|
|
|
@@ -492,14 +499,21 @@ export const moveCursorOutOfIgnoreEmojiSpan = editorElement => {
|
|
|
492
499
|
let {
|
|
493
500
|
commonAncestorContainer
|
|
494
501
|
} = range;
|
|
502
|
+
if (!editorElement.contains(commonAncestorContainer)) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
495
505
|
|
|
496
506
|
// Walk up the DOM tree to find if we're inside a no-emoji-convert span
|
|
497
507
|
while (commonAncestorContainer && commonAncestorContainer !== editorElement) {
|
|
498
|
-
if (commonAncestorContainer.nodeType === Node.ELEMENT_NODE && commonAncestorContainer.
|
|
508
|
+
if (commonAncestorContainer.nodeType === Node.ELEMENT_NODE && commonAncestorContainer.classList.contains('no-emoji-convert')) {
|
|
499
509
|
// We're inside a no-emoji-convert span, move cursor to after it
|
|
500
510
|
const span = commonAncestorContainer;
|
|
501
|
-
const
|
|
502
|
-
|
|
511
|
+
const {
|
|
512
|
+
nextSibling
|
|
513
|
+
} = span;
|
|
514
|
+
const {
|
|
515
|
+
parentNode
|
|
516
|
+
} = span;
|
|
503
517
|
if (!parentNode) {
|
|
504
518
|
return;
|
|
505
519
|
}
|
|
@@ -533,7 +547,9 @@ export const moveCursorOutOfIgnoreEmojiSpan = editorElement => {
|
|
|
533
547
|
selection.addRange(range);
|
|
534
548
|
break;
|
|
535
549
|
}
|
|
536
|
-
|
|
550
|
+
|
|
551
|
+
// @ts-expect-error - is needed
|
|
552
|
+
commonAncestorContainer = commonAncestorContainer.parentNode;
|
|
537
553
|
}
|
|
538
554
|
};
|
|
539
555
|
//# sourceMappingURL=selection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.js","names":["clamp","convertHTMLToText","getElementTextLength","childIndex","endOffset","startOffset","saveSelection","element","shouldIgnoreEmptyTextNodes","selection","window","getSelection","anchorNode","range","getRangeAt","childNodesArray","Array","from","childNodes","filter","nodeType","nodeValue","Node","TEXT_NODE","indexOf","restoreSelection","hasFoundNoJoiner","forEach","node","noJoinerIndex","replace","childNode","elementTextLength","nextSibling","charCodeAt","textNode","document","createTextNode","parentNode","insertBefore","length","createRange","setStart","setEnd","error","removeAllRanges","addRange","collapse","insertInvisibleCursorMarker","rangeCount","startContainer","offset","execCommand","span","createElement","style","display","width","height","className","parent","textContent","beforeText","slice","afterText","afterTextNode","setTimeout","newRange","setStartAfter","setEndAfter","remove","insertPseudoMarker","marker","id","insertNode","insertCursorAtMarker","ref","current","querySelector","moveSelectionOffset","distance","setChildIndex","index","getCharCodeThatWillBeDeleted","event","key","previousSibling","endContainer","findAndSelectText","editorElement","searchText","options","shouldReplaceNearCursor","includes","cursorPos","getCurrentCursorPosition","matches","absCounter","searchNodesForText","push","absIndex","nodeName","match","reduce","prev","curr","Math","abs","sel","contains","commonAncestorContainer","pre","selectNodeContents","container","appendChild","cloneContents","bbCodeUntilCursor","innerHTML","preserveSpaces","shouldSerializeNoEmojiToBBCode","getCursorTargetByAbsIndex","position","clampedPosition","searchNodes","nodeText","nextAbsCounter","child","found","rootNode","lastTextNode","lastChild","appendedTextNode","setCursorPositionByAbsIndex","target","unwrapIgnoreEmojiSpanAtCursor","cursorOffset","ELEMENT_NODE","cursorNode","cursorNodeOffset","clonedChild","cloneNode","removeChild","moveCursorOutOfIgnoreEmojiSpan","targetNode","walker","createTreeWalker","NodeFilter","SHOW_TEXT","firstTextNode","nextNode"],"sources":["../../../src/utils/selection.ts"],"sourcesContent":["import type { KeyboardEvent, RefObject } from 'react';\nimport { clamp } from './number';\nimport { convertHTMLToText, getElementTextLength } from './text';\n\nlet childIndex = -1;\nlet endOffset = -1;\nlet startOffset = -1;\n\ninterface SaveSelectionOptions {\n shouldIgnoreEmptyTextNodes?: boolean;\n}\n\nexport const saveSelection = (\n element: HTMLDivElement,\n { shouldIgnoreEmptyTextNodes }: SaveSelectionOptions = {},\n) => {\n const selection = window.getSelection();\n\n if (!selection) {\n return;\n }\n\n const { anchorNode } = selection;\n\n if (!anchorNode) {\n return;\n }\n\n const range = selection.getRangeAt(0);\n\n let childNodesArray = Array.from(element.childNodes);\n\n if (shouldIgnoreEmptyTextNodes) {\n childNodesArray = childNodesArray.filter(\n ({ nodeType, nodeValue }) =>\n nodeType !== Node.TEXT_NODE || (nodeValue !== '' && nodeValue !== '\\u200B'),\n );\n }\n\n childIndex = childNodesArray.indexOf(anchorNode as ChildNode);\n\n endOffset = range.endOffset;\n startOffset = range.startOffset;\n};\n\nexport const restoreSelection = (element: HTMLDivElement) => {\n // Search for \\u200C in child nodes. If found, set the childIndex, startOffset, and endOffset to the\n // position of the \\u200C character. Also remove the \\u200C character from the child node. If not found,\n // the childIndex, startOffset, and endOffset will be like before.\n const childNodesArray = Array.from(element.childNodes);\n\n let hasFoundNoJoiner = false;\n\n childNodesArray.forEach((node) => {\n if (\n !hasFoundNoJoiner &&\n node.nodeType === Node.TEXT_NODE &&\n typeof node.nodeValue === 'string'\n ) {\n const noJoinerIndex = node.nodeValue.indexOf('\\u200C');\n\n if (noJoinerIndex !== -1) {\n hasFoundNoJoiner = true;\n\n childIndex = childNodesArray.indexOf(node);\n startOffset = noJoinerIndex;\n endOffset = noJoinerIndex;\n }\n }\n });\n\n // Remove all no joiner characters from the child nodes if no joiner was found\n if (hasFoundNoJoiner) {\n childNodesArray.forEach((node) => {\n if (node.nodeType === Node.TEXT_NODE && typeof node.nodeValue === 'string') {\n // eslint-disable-next-line no-param-reassign\n node.nodeValue = node.nodeValue.replace(/\\u200C/g, '');\n }\n });\n }\n\n let childNode = element.childNodes[childIndex];\n\n const selection = window.getSelection();\n\n if (!childNode || !element || !selection) {\n return;\n }\n\n // noinspection SuspiciousTypeOfGuard\n if (typeof childNode.nodeValue !== 'string') {\n const elementTextLength = getElementTextLength(childNode as Element);\n\n if (childNode.nextSibling) {\n childNode = childNode.nextSibling;\n\n if (childNode.nodeType === Node.TEXT_NODE && childNode.nodeValue) {\n endOffset -= elementTextLength;\n startOffset -= elementTextLength;\n\n if (childNode.nodeValue.charCodeAt(endOffset) === 8203) {\n endOffset += 1;\n startOffset += 1;\n }\n } else {\n const textNode = document.createTextNode('\\u200B');\n\n childNode.parentNode?.insertBefore(textNode, childNode.nextSibling);\n\n childNode = textNode;\n\n endOffset = textNode.length;\n startOffset = textNode.length;\n }\n } else {\n const textNode = document.createTextNode('\\u200B');\n\n childNode.parentNode?.insertBefore(textNode, childNode.nextSibling);\n\n childNode = textNode;\n\n endOffset = textNode.length;\n startOffset = textNode.length;\n }\n } else if (childNode.nodeValue && endOffset > childNode.nodeValue.length) {\n if (childNode.nextSibling?.nodeValue) {\n let elementTextLength = childNode.nodeValue.length;\n\n childNode = childNode.nextSibling;\n\n // noinspection SuspiciousTypeOfGuard\n if (typeof childNode.nodeValue !== 'string') {\n elementTextLength += getElementTextLength(childNode as Element);\n\n if (childNode.nextSibling?.nodeValue) {\n childNode = childNode.nextSibling;\n\n if (childNode.nodeType === Node.TEXT_NODE && childNode.nodeValue) {\n endOffset -= elementTextLength;\n startOffset -= elementTextLength;\n\n if (childNode.nodeValue.charCodeAt(endOffset) === 8203) {\n endOffset += 1;\n startOffset += 1;\n }\n } else {\n const textNode = document.createTextNode('\\u200B');\n\n childNode.parentNode?.insertBefore(textNode, childNode.nextSibling);\n\n childNode = textNode;\n\n endOffset = textNode.length;\n startOffset = textNode.length;\n }\n } else {\n const textNode = document.createTextNode('\\u200B');\n\n childNode.parentNode?.insertBefore(textNode, childNode.nextSibling);\n\n childNode = textNode;\n\n endOffset = textNode.length;\n startOffset = textNode.length;\n }\n }\n } else {\n endOffset = childNode.nodeValue.length;\n startOffset = childNode.nodeValue.length;\n }\n }\n\n const range = document.createRange();\n\n // noinspection SuspiciousTypeOfGuard\n if (typeof childNode.nodeValue === 'string') {\n startOffset = clamp(startOffset, 0, childNode.nodeValue.length);\n endOffset = clamp(endOffset, 0, childNode.nodeValue.length);\n }\n\n try {\n range.setStart(childNode, startOffset);\n range.setEnd(childNode, endOffset);\n } catch (error) {\n // Do nothing\n }\n\n selection.removeAllRanges();\n selection.addRange(range);\n\n range.collapse(true);\n};\n\nexport const insertInvisibleCursorMarker = (): void => {\n const selection = window.getSelection();\n\n if (!selection || selection.rangeCount === 0) {\n return;\n }\n\n const range = selection.getRangeAt(0);\n const textNode = range.startContainer;\n const offset = range.startOffset;\n\n // noinspection JSDeprecatedSymbols\n document.execCommand('delete', false);\n\n const span = document.createElement('span');\n span.style.display = 'inline-block';\n span.style.width = '0';\n span.style.height = '0';\n span.className = 'invisible-cursor-marker';\n\n const parent = textNode.parentNode;\n\n if (parent) {\n if (textNode.nodeType === Node.TEXT_NODE) {\n const textContent = textNode.textContent || '';\n const beforeText = textContent.slice(0, offset);\n const afterText = textContent.slice(offset);\n\n textNode.textContent = beforeText;\n\n parent.insertBefore(span, textNode.nextSibling);\n const afterTextNode = document.createTextNode(afterText);\n parent.insertBefore(afterTextNode, span.nextSibling);\n\n setTimeout(() => {\n // Set cursor to cursor element\n const newRange = document.createRange();\n newRange.setStartAfter(span);\n newRange.setEndAfter(span);\n selection.removeAllRanges();\n selection.addRange(newRange);\n\n // Remove cursor element\n span.remove();\n }, 10);\n }\n }\n};\n\nexport const insertPseudoMarker = () => {\n const selection = window.getSelection();\n\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n const marker = document.createElement('span');\n marker.id = 'cursor-marker';\n marker.style.display = 'inline-block';\n marker.style.width = '0';\n marker.style.height = '0';\n range.insertNode(marker);\n }\n};\n\nexport const insertCursorAtMarker = (ref: RefObject<HTMLDivElement>) => {\n const marker = ref.current?.querySelector('#cursor-marker');\n\n if (marker) {\n const selection = window.getSelection();\n const range = document.createRange();\n range.setStartAfter(marker);\n range.setEndAfter(marker);\n selection?.removeAllRanges();\n selection?.addRange(range);\n marker.remove();\n }\n};\n\nexport const moveSelectionOffset = (distance: number) => {\n endOffset += distance;\n startOffset += distance;\n};\n\nexport const setChildIndex = (index: number) => {\n childIndex = index;\n};\n\n/**\n * This function returns the code of the character that will be removed by the KeyDown event in the\n * next step, if the \"Backspace\" or \"Delete\" key was pressed and there is no selection of multiple\n * characters.\n *\n * @param event - Keyboard event from \"onKeyDown\"\n */\nexport const getCharCodeThatWillBeDeleted = (event: KeyboardEvent<HTMLDivElement>) => {\n const range = window.getSelection()?.getRangeAt(0);\n\n /**\n * At this point the function is aborted if there is no selection range, several characters have\n * been selected and therefore no single letter is removed or neither the \"Backspace\" nor the\n * \"Delete\" key has been pressed.\n */\n if (\n !range ||\n range.endOffset !== range.startOffset ||\n (event.key !== 'Backspace' && event.key !== 'Delete' && event.key !== 'Unidentified')\n ) {\n return null;\n }\n\n if (event.key === 'Backspace' || event.key === 'Unidentified') {\n const { nodeValue, previousSibling } = range.startContainer;\n\n if (range.startOffset > 0) {\n return nodeValue?.charCodeAt(range.startOffset - 1);\n }\n\n return previousSibling?.nodeValue?.charCodeAt(previousSibling.nodeValue.length - 1);\n }\n\n const { nextSibling, nodeValue } = range.endContainer;\n\n if (range.endOffset < (nodeValue?.length ?? 0)) {\n return nodeValue?.charCodeAt(range.endOffset);\n }\n\n return nextSibling?.nodeValue?.charCodeAt(0);\n};\n\nexport type ReplaceTextOptions = { shouldReplaceNearCursor?: boolean };\n\ninterface FindAndSelectTextOptions {\n editorElement: HTMLDivElement;\n searchText: string;\n options?: ReplaceTextOptions;\n}\n\nexport interface SetCursorPositionByAbsIndexOptions {\n editorElement: HTMLDivElement;\n position: number;\n}\n\ntype Match = { node: Node; offset: number; absIndex: number };\n\nexport const findAndSelectText = ({\n editorElement,\n searchText,\n options = { shouldReplaceNearCursor: true },\n}: FindAndSelectTextOptions): Range | null => {\n if (!editorElement.textContent?.includes(searchText)) {\n return null;\n }\n\n const range = document.createRange();\n\n const cursorPos = getCurrentCursorPosition(editorElement);\n\n const matches: Match[] = [];\n let absCounter = 0;\n\n const searchNodesForText = (node: Node) => {\n if (node.nodeType === Node.TEXT_NODE && node.textContent) {\n let index = node.textContent.indexOf(searchText);\n while (index !== -1) {\n matches.push({\n node,\n offset: index,\n absIndex: absCounter + index,\n });\n index = node.textContent.indexOf(searchText, index + 1);\n }\n absCounter += node.textContent.length;\n } else if (node.nodeName !== 'LC_MENTION') {\n Array.from(node.childNodes).forEach(searchNodesForText);\n }\n };\n\n searchNodesForText(editorElement);\n\n if (matches.length === 0) {\n return null;\n }\n\n let match = matches[0];\n\n if (options?.shouldReplaceNearCursor && cursorPos !== null) {\n match = matches.reduce((prev, curr) =>\n Math.abs(curr.absIndex - cursorPos) < Math.abs(prev.absIndex - cursorPos) ? curr : prev,\n );\n }\n\n if (!match) {\n return null;\n }\n\n range.setStart(match.node, match.offset);\n range.setEnd(match.node, match.offset + searchText.length);\n\n return range;\n};\n\nexport const getCurrentCursorPosition = (editorElement: HTMLDivElement | null): number | null => {\n if (!editorElement) {\n return null;\n }\n\n const sel = window.getSelection?.();\n if (!sel || sel.rangeCount === 0) {\n return null;\n }\n\n const range = sel.getRangeAt(0);\n\n if (!editorElement.contains(range.commonAncestorContainer)) {\n return null;\n }\n\n const pre = document.createRange();\n pre.selectNodeContents(editorElement);\n\n try {\n pre.setEnd(range.startContainer, range.startOffset);\n\n const container = document.createElement('div');\n container.appendChild(pre.cloneContents());\n\n const bbCodeUntilCursor = convertHTMLToText(container.innerHTML, {\n preserveSpaces: true,\n shouldSerializeNoEmojiToBBCode: false,\n });\n\n return bbCodeUntilCursor.length;\n } catch {\n return convertHTMLToText(editorElement.innerHTML, {\n shouldSerializeNoEmojiToBBCode: false,\n }).length;\n }\n};\n\ntype CursorTarget = { node: Text; offset: number };\n\nconst getCursorTargetByAbsIndex = ({\n editorElement,\n position,\n}: SetCursorPositionByAbsIndexOptions): CursorTarget | null => {\n const childNodes = Array.from(editorElement.childNodes);\n\n if (childNodes.length === 0) {\n const textNode = document.createTextNode('');\n editorElement.appendChild(textNode);\n\n return { node: textNode, offset: 0 };\n }\n\n const clampedPosition = clamp(\n position,\n 0,\n convertHTMLToText(editorElement.innerHTML, {\n shouldSerializeNoEmojiToBBCode: false,\n }).length,\n );\n\n let absCounter = 0;\n\n const searchNodes = (node: Node): CursorTarget | null => {\n if (node.nodeType === Node.TEXT_NODE) {\n const textNode = node as Text;\n const nodeText = textNode.nodeValue ?? '';\n const nextAbsCounter = absCounter + nodeText.length;\n\n if (clampedPosition <= nextAbsCounter) {\n return {\n node: textNode,\n offset: clamp(clampedPosition - absCounter, 0, nodeText.length),\n };\n }\n\n absCounter = nextAbsCounter;\n\n return null;\n }\n\n if (node.nodeName === 'LC_MENTION') {\n return null;\n }\n\n for (const child of Array.from(node.childNodes)) {\n const found = searchNodes(child);\n if (found) {\n return found;\n }\n }\n\n return null;\n };\n\n for (const rootNode of childNodes) {\n const found = searchNodes(rootNode);\n if (found) {\n return found;\n }\n }\n\n const lastTextNode = editorElement.lastChild;\n if (lastTextNode?.nodeType === Node.TEXT_NODE) {\n const textNode = lastTextNode as Text;\n return { node: textNode, offset: textNode.length };\n }\n\n const appendedTextNode = document.createTextNode('\\u200B');\n editorElement.appendChild(appendedTextNode);\n\n return { node: appendedTextNode, offset: appendedTextNode.length };\n};\n\nexport const setCursorPositionByAbsIndex = ({\n editorElement,\n position,\n}: SetCursorPositionByAbsIndexOptions): void => {\n const selection = window.getSelection?.();\n\n if (!selection) {\n return;\n }\n\n const target = getCursorTargetByAbsIndex({ editorElement, position });\n\n if (!target) {\n return;\n }\n\n const range = document.createRange();\n\n try {\n range.setStart(target.node, target.offset);\n range.setEnd(target.node, target.offset);\n } catch {\n return;\n }\n\n selection.removeAllRanges();\n selection.addRange(range);\n\n range.collapse(true);\n};\n\n/**\n * Unwraps any no-emoji-convert span that contains the cursor.\n * This removes the span element but keeps its text content, preventing the cursor from getting stuck.\n */\nexport const unwrapIgnoreEmojiSpanAtCursor = (editorElement: HTMLDivElement | null) => {\n if (!editorElement) {\n return;\n }\n\n const selection = window.getSelection();\n\n if (!selection || !selection.rangeCount) {\n return;\n }\n\n const range = selection.getRangeAt(0);\n let { commonAncestorContainer } = range;\n const cursorOffset = range.startOffset;\n\n // Walk up the DOM tree to find if we're inside a no-emoji-convert span\n while (commonAncestorContainer && commonAncestorContainer !== editorElement) {\n if (\n commonAncestorContainer.nodeType === Node.ELEMENT_NODE &&\n (commonAncestorContainer as Element).className === 'no-emoji-convert'\n ) {\n // We're inside a no-emoji-convert span, unwrap it\n const span = commonAncestorContainer as Element;\n const parentNode = span.parentNode;\n\n if (!parentNode) {\n return;\n }\n\n // Find which text node contains the cursor\n let cursorNode: Node | null = null;\n let cursorNodeOffset = cursorOffset;\n\n // Get all child nodes of the span\n const childNodes = Array.from(span.childNodes);\n\n // Insert all children before the span and find the cursor node\n childNodes.forEach((child) => {\n const clonedChild = child.cloneNode(true);\n parentNode.insertBefore(clonedChild, span);\n\n // If this is the node that contains the cursor, track it\n if (child === range.startContainer) {\n cursorNode = clonedChild;\n }\n });\n\n // Remove the span\n parentNode.removeChild(span);\n\n // Restore cursor position in the unwrapped content\n if (cursorNode) {\n range.setStart(cursorNode, cursorNodeOffset);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n\n break;\n }\n\n commonAncestorContainer = commonAncestorContainer.parentNode ?? commonAncestorContainer;\n }\n};\n\n/**\n * Moves the cursor outside of any no-emoji-convert span if it's currently inside one.\n * This prevents the cursor from getting \"stuck\" inside the protection span when typing.\n */\nexport const moveCursorOutOfIgnoreEmojiSpan = (editorElement: HTMLDivElement | null) => {\n if (!editorElement) {\n return;\n }\n\n const selection = window.getSelection();\n\n if (!selection || !selection.rangeCount) {\n return;\n }\n\n const range = selection.getRangeAt(0);\n let { commonAncestorContainer } = range;\n\n // Walk up the DOM tree to find if we're inside a no-emoji-convert span\n while (commonAncestorContainer && commonAncestorContainer !== editorElement) {\n if (\n commonAncestorContainer.nodeType === Node.ELEMENT_NODE &&\n (commonAncestorContainer as Element).className === 'no-emoji-convert'\n ) {\n // We're inside a no-emoji-convert span, move cursor to after it\n const span = commonAncestorContainer as Element;\n const nextSibling = span.nextSibling;\n const parentNode = span.parentNode;\n\n if (!parentNode) {\n return;\n }\n\n // Always ensure there's a text node AFTER the span\n let targetNode: Text;\n\n if (nextSibling && nextSibling.nodeType === Node.TEXT_NODE) {\n // Next sibling is already a text node, use it\n targetNode = nextSibling as Text;\n } else if (nextSibling && nextSibling.nodeType === Node.ELEMENT_NODE) {\n // Next sibling is an element, find first text node in it\n const walker = document.createTreeWalker(nextSibling, NodeFilter.SHOW_TEXT);\n const firstTextNode = walker.nextNode() as Text;\n if (firstTextNode) {\n targetNode = firstTextNode;\n } else {\n // No text node found, create one\n targetNode = document.createTextNode('\\u200B');\n parentNode.insertBefore(targetNode, nextSibling);\n }\n } else {\n // No next sibling or it's not a text/element node, create a new text node\n targetNode = document.createTextNode('\\u200B');\n parentNode.insertBefore(targetNode, nextSibling);\n }\n\n // Place cursor at the start of the target node\n range.setStart(targetNode, 0);\n range.collapse(true);\n\n selection.removeAllRanges();\n selection.addRange(range);\n break;\n }\n\n commonAncestorContainer = commonAncestorContainer.parentNode ?? commonAncestorContainer;\n }\n};\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"selection.js","names":["clamp","convertHTMLToText","getElementTextLength","childIndex","endOffset","startOffset","saveSelection","element","shouldIgnoreEmptyTextNodes","selection","window","getSelection","anchorNode","range","getRangeAt","childNodesArray","Array","from","childNodes","filter","nodeType","nodeValue","Node","TEXT_NODE","indexOf","restoreSelection","hasFoundNoJoiner","forEach","node","noJoinerIndex","replace","childNode","elementTextLength","nextSibling","charCodeAt","textNode","document","createTextNode","parentNode","insertBefore","length","createRange","setStart","setEnd","error","removeAllRanges","addRange","collapse","insertInvisibleCursorMarker","rangeCount","startContainer","offset","execCommand","span","createElement","style","display","width","height","className","parent","textContent","beforeText","slice","afterText","afterTextNode","setTimeout","newRange","setStartAfter","setEndAfter","remove","insertPseudoMarker","marker","id","insertNode","insertCursorAtMarker","ref","current","querySelector","moveSelectionOffset","distance","setChildIndex","index","getCharCodeThatWillBeDeleted","event","key","previousSibling","endContainer","findAndSelectText","editorElement","searchText","options","shouldReplaceNearCursor","includes","cursorPos","getCurrentCursorPosition","matches","absCounter","searchNodesForText","push","absIndex","nodeName","match","reduce","prev","curr","Math","abs","sel","contains","commonAncestorContainer","pre","selectNodeContents","container","appendChild","cloneContents","bbCodeUntilCursor","innerHTML","preserveSpaces","shouldSerializeNoEmojiToBBCode","getCursorTargetByAbsIndex","position","clampedPosition","searchNodes","nodeText","nextAbsCounter","child","found","rootNode","lastTextNode","lastChild","appendedTextNode","setCursorPositionByAbsIndex","target","unwrapIgnoreEmojiSpanAtCursor","cursorOffset","ELEMENT_NODE","classList","cursorNode","cursorNodeOffset","clonedChild","cloneNode","removeChild","moveCursorOutOfIgnoreEmojiSpan","targetNode","walker","createTreeWalker","NodeFilter","SHOW_TEXT","firstTextNode","nextNode"],"sources":["../../../src/utils/selection.ts"],"sourcesContent":["import type { KeyboardEvent, RefObject } from 'react';\nimport { clamp } from './number';\nimport { convertHTMLToText, getElementTextLength } from './text';\n\nlet childIndex = -1;\nlet endOffset = -1;\nlet startOffset = -1;\n\ninterface SaveSelectionOptions {\n shouldIgnoreEmptyTextNodes?: boolean;\n}\n\nexport const saveSelection = (\n element: HTMLDivElement,\n { shouldIgnoreEmptyTextNodes }: SaveSelectionOptions = {},\n) => {\n const selection = window.getSelection();\n\n if (!selection) {\n return;\n }\n\n const { anchorNode } = selection;\n\n if (!anchorNode) {\n return;\n }\n\n const range = selection.getRangeAt(0);\n\n let childNodesArray = Array.from(element.childNodes);\n\n if (shouldIgnoreEmptyTextNodes) {\n childNodesArray = childNodesArray.filter(\n ({ nodeType, nodeValue }) =>\n nodeType !== Node.TEXT_NODE || (nodeValue !== '' && nodeValue !== '\\u200B'),\n );\n }\n\n childIndex = childNodesArray.indexOf(anchorNode as ChildNode);\n\n endOffset = range.endOffset;\n startOffset = range.startOffset;\n};\n\nexport const restoreSelection = (element: HTMLDivElement) => {\n // Search for \\u200C in child nodes. If found, set the childIndex, startOffset, and endOffset to the\n // position of the \\u200C character. Also remove the \\u200C character from the child node. If not found,\n // the childIndex, startOffset, and endOffset will be like before.\n const childNodesArray = Array.from(element.childNodes);\n\n let hasFoundNoJoiner = false;\n\n childNodesArray.forEach((node) => {\n if (\n !hasFoundNoJoiner &&\n node.nodeType === Node.TEXT_NODE &&\n typeof node.nodeValue === 'string'\n ) {\n const noJoinerIndex = node.nodeValue.indexOf('\\u200C');\n\n if (noJoinerIndex !== -1) {\n hasFoundNoJoiner = true;\n\n childIndex = childNodesArray.indexOf(node);\n startOffset = noJoinerIndex;\n endOffset = noJoinerIndex;\n }\n }\n });\n\n // Remove all no joiner characters from the child nodes if no joiner was found\n if (hasFoundNoJoiner) {\n childNodesArray.forEach((node) => {\n if (node.nodeType === Node.TEXT_NODE && typeof node.nodeValue === 'string') {\n // eslint-disable-next-line no-param-reassign\n node.nodeValue = node.nodeValue.replace(/\\u200C/g, '');\n }\n });\n }\n\n let childNode = element.childNodes[childIndex];\n\n const selection = window.getSelection();\n\n if (!childNode || !element || !selection) {\n return;\n }\n\n // noinspection SuspiciousTypeOfGuard\n if (typeof childNode.nodeValue !== 'string') {\n const elementTextLength = getElementTextLength(childNode as Element);\n\n if (childNode.nextSibling) {\n childNode = childNode.nextSibling;\n\n if (childNode.nodeType === Node.TEXT_NODE && childNode.nodeValue) {\n endOffset -= elementTextLength;\n startOffset -= elementTextLength;\n\n if (childNode.nodeValue.charCodeAt(endOffset) === 8203) {\n endOffset += 1;\n startOffset += 1;\n }\n } else {\n const textNode = document.createTextNode('\\u200B');\n\n childNode.parentNode?.insertBefore(textNode, childNode.nextSibling);\n\n childNode = textNode;\n\n endOffset = textNode.length;\n startOffset = textNode.length;\n }\n } else {\n const textNode = document.createTextNode('\\u200B');\n\n childNode.parentNode?.insertBefore(textNode, childNode.nextSibling);\n\n childNode = textNode;\n\n endOffset = textNode.length;\n startOffset = textNode.length;\n }\n } else if (childNode.nodeValue && endOffset > childNode.nodeValue.length) {\n if (childNode.nextSibling?.nodeValue) {\n let elementTextLength = childNode.nodeValue.length;\n\n childNode = childNode.nextSibling;\n\n // noinspection SuspiciousTypeOfGuard\n if (typeof childNode.nodeValue !== 'string') {\n elementTextLength += getElementTextLength(childNode as Element);\n\n if (childNode.nextSibling?.nodeValue) {\n childNode = childNode.nextSibling;\n\n if (childNode.nodeType === Node.TEXT_NODE && childNode.nodeValue) {\n endOffset -= elementTextLength;\n startOffset -= elementTextLength;\n\n if (childNode.nodeValue.charCodeAt(endOffset) === 8203) {\n endOffset += 1;\n startOffset += 1;\n }\n } else {\n const textNode = document.createTextNode('\\u200B');\n\n childNode.parentNode?.insertBefore(textNode, childNode.nextSibling);\n\n childNode = textNode;\n\n endOffset = textNode.length;\n startOffset = textNode.length;\n }\n } else {\n const textNode = document.createTextNode('\\u200B');\n\n childNode.parentNode?.insertBefore(textNode, childNode.nextSibling);\n\n childNode = textNode;\n\n endOffset = textNode.length;\n startOffset = textNode.length;\n }\n }\n } else {\n endOffset = childNode.nodeValue.length;\n startOffset = childNode.nodeValue.length;\n }\n }\n\n const range = document.createRange();\n\n // noinspection SuspiciousTypeOfGuard\n if (typeof childNode.nodeValue === 'string') {\n startOffset = clamp(startOffset, 0, childNode.nodeValue.length);\n endOffset = clamp(endOffset, 0, childNode.nodeValue.length);\n }\n\n try {\n range.setStart(childNode, startOffset);\n range.setEnd(childNode, endOffset);\n } catch (error) {\n // Do nothing\n }\n\n selection.removeAllRanges();\n selection.addRange(range);\n\n range.collapse(true);\n};\n\nexport const insertInvisibleCursorMarker = (): void => {\n const selection = window.getSelection();\n\n if (!selection || selection.rangeCount === 0) {\n return;\n }\n\n const range = selection.getRangeAt(0);\n const textNode = range.startContainer;\n const offset = range.startOffset;\n\n // noinspection JSDeprecatedSymbols\n document.execCommand('delete', false);\n\n const span = document.createElement('span');\n span.style.display = 'inline-block';\n span.style.width = '0';\n span.style.height = '0';\n span.className = 'invisible-cursor-marker';\n\n const parent = textNode.parentNode;\n\n if (parent) {\n if (textNode.nodeType === Node.TEXT_NODE) {\n const textContent = textNode.textContent || '';\n const beforeText = textContent.slice(0, offset);\n const afterText = textContent.slice(offset);\n\n textNode.textContent = beforeText;\n\n parent.insertBefore(span, textNode.nextSibling);\n const afterTextNode = document.createTextNode(afterText);\n parent.insertBefore(afterTextNode, span.nextSibling);\n\n setTimeout(() => {\n // Set cursor to cursor element\n const newRange = document.createRange();\n newRange.setStartAfter(span);\n newRange.setEndAfter(span);\n selection.removeAllRanges();\n selection.addRange(newRange);\n\n // Remove cursor element\n span.remove();\n }, 10);\n }\n }\n};\n\nexport const insertPseudoMarker = () => {\n const selection = window.getSelection();\n\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n const marker = document.createElement('span');\n marker.id = 'cursor-marker';\n marker.style.display = 'inline-block';\n marker.style.width = '0';\n marker.style.height = '0';\n range.insertNode(marker);\n }\n};\n\nexport const insertCursorAtMarker = (ref: RefObject<HTMLDivElement>) => {\n const marker = ref.current?.querySelector('#cursor-marker');\n\n if (marker) {\n const selection = window.getSelection();\n const range = document.createRange();\n range.setStartAfter(marker);\n range.setEndAfter(marker);\n selection?.removeAllRanges();\n selection?.addRange(range);\n marker.remove();\n }\n};\n\nexport const moveSelectionOffset = (distance: number) => {\n endOffset += distance;\n startOffset += distance;\n};\n\nexport const setChildIndex = (index: number) => {\n childIndex = index;\n};\n\n/**\n * This function returns the code of the character that will be removed by the KeyDown event in the\n * next step, if the \"Backspace\" or \"Delete\" key was pressed and there is no selection of multiple\n * characters.\n *\n * @param event - Keyboard event from \"onKeyDown\"\n */\nexport const getCharCodeThatWillBeDeleted = (event: KeyboardEvent<HTMLDivElement>) => {\n const range = window.getSelection()?.getRangeAt(0);\n\n /**\n * At this point the function is aborted if there is no selection range, several characters have\n * been selected and therefore no single letter is removed or neither the \"Backspace\" nor the\n * \"Delete\" key has been pressed.\n */\n if (\n !range ||\n range.endOffset !== range.startOffset ||\n (event.key !== 'Backspace' && event.key !== 'Delete' && event.key !== 'Unidentified')\n ) {\n return null;\n }\n\n if (event.key === 'Backspace' || event.key === 'Unidentified') {\n const { nodeValue, previousSibling } = range.startContainer;\n\n if (range.startOffset > 0) {\n return nodeValue?.charCodeAt(range.startOffset - 1);\n }\n\n return previousSibling?.nodeValue?.charCodeAt(previousSibling.nodeValue.length - 1);\n }\n\n const { nextSibling, nodeValue } = range.endContainer;\n\n if (range.endOffset < (nodeValue?.length ?? 0)) {\n return nodeValue?.charCodeAt(range.endOffset);\n }\n\n return nextSibling?.nodeValue?.charCodeAt(0);\n};\n\nexport type ReplaceTextOptions = { shouldReplaceNearCursor?: boolean };\n\ninterface FindAndSelectTextOptions {\n editorElement: HTMLDivElement;\n searchText: string;\n options?: ReplaceTextOptions;\n}\n\nexport interface SetCursorPositionByAbsIndexOptions {\n editorElement: HTMLDivElement;\n position: number;\n}\n\ntype Match = { node: Node; offset: number; absIndex: number };\n\nexport const findAndSelectText = ({\n editorElement,\n searchText,\n options = { shouldReplaceNearCursor: true },\n}: FindAndSelectTextOptions): Range | null => {\n if (!editorElement.textContent?.includes(searchText)) {\n return null;\n }\n\n const range = document.createRange();\n\n const cursorPos = getCurrentCursorPosition(editorElement);\n\n const matches: Match[] = [];\n let absCounter = 0;\n\n const searchNodesForText = (node: Node) => {\n if (node.nodeType === Node.TEXT_NODE && node.textContent) {\n let index = node.textContent.indexOf(searchText);\n while (index !== -1) {\n matches.push({\n node,\n offset: index,\n absIndex: absCounter + index,\n });\n index = node.textContent.indexOf(searchText, index + 1);\n }\n absCounter += node.textContent.length;\n } else if (node.nodeName !== 'LC_MENTION') {\n Array.from(node.childNodes).forEach(searchNodesForText);\n }\n };\n\n searchNodesForText(editorElement);\n\n if (matches.length === 0) {\n return null;\n }\n\n let match = matches[0];\n\n if (options?.shouldReplaceNearCursor && cursorPos !== null) {\n match = matches.reduce((prev, curr) =>\n Math.abs(curr.absIndex - cursorPos) < Math.abs(prev.absIndex - cursorPos) ? curr : prev,\n );\n }\n\n if (!match) {\n return null;\n }\n\n range.setStart(match.node, match.offset);\n range.setEnd(match.node, match.offset + searchText.length);\n\n return range;\n};\n\nexport const getCurrentCursorPosition = (editorElement: HTMLDivElement | null): number | null => {\n if (!editorElement) {\n return null;\n }\n\n const sel = window.getSelection?.();\n if (!sel || sel.rangeCount === 0) {\n return null;\n }\n\n const range = sel.getRangeAt(0);\n\n if (!editorElement.contains(range.commonAncestorContainer)) {\n return null;\n }\n\n const pre = document.createRange();\n pre.selectNodeContents(editorElement);\n\n try {\n pre.setEnd(range.startContainer, range.startOffset);\n\n const container = document.createElement('div');\n container.appendChild(pre.cloneContents());\n\n const bbCodeUntilCursor = convertHTMLToText(container.innerHTML, {\n preserveSpaces: true,\n shouldSerializeNoEmojiToBBCode: false,\n });\n\n return bbCodeUntilCursor.length;\n } catch {\n return convertHTMLToText(editorElement.innerHTML, {\n shouldSerializeNoEmojiToBBCode: false,\n }).length;\n }\n};\n\ntype CursorTarget = { node: Text; offset: number };\n\nconst getCursorTargetByAbsIndex = ({\n editorElement,\n position,\n}: SetCursorPositionByAbsIndexOptions): CursorTarget | null => {\n const childNodes = Array.from(editorElement.childNodes);\n\n if (childNodes.length === 0) {\n const textNode = document.createTextNode('');\n editorElement.appendChild(textNode);\n\n return { node: textNode, offset: 0 };\n }\n\n const clampedPosition = clamp(\n position,\n 0,\n convertHTMLToText(editorElement.innerHTML, {\n shouldSerializeNoEmojiToBBCode: false,\n }).length,\n );\n\n let absCounter = 0;\n\n const searchNodes = (node: Node): CursorTarget | null => {\n if (node.nodeType === Node.TEXT_NODE) {\n const textNode = node as Text;\n const nodeText = textNode.nodeValue ?? '';\n const nextAbsCounter = absCounter + nodeText.length;\n\n if (clampedPosition <= nextAbsCounter) {\n return {\n node: textNode,\n offset: clamp(clampedPosition - absCounter, 0, nodeText.length),\n };\n }\n\n absCounter = nextAbsCounter;\n\n return null;\n }\n\n if (node.nodeName === 'LC_MENTION') {\n return null;\n }\n\n for (const child of Array.from(node.childNodes)) {\n const found = searchNodes(child);\n if (found) {\n return found;\n }\n }\n\n return null;\n };\n\n for (const rootNode of childNodes) {\n const found = searchNodes(rootNode);\n if (found) {\n return found;\n }\n }\n\n const lastTextNode = editorElement.lastChild;\n if (lastTextNode?.nodeType === Node.TEXT_NODE) {\n const textNode = lastTextNode as Text;\n return { node: textNode, offset: textNode.length };\n }\n\n const appendedTextNode = document.createTextNode('\\u200B');\n editorElement.appendChild(appendedTextNode);\n\n return { node: appendedTextNode, offset: appendedTextNode.length };\n};\n\nexport const setCursorPositionByAbsIndex = ({\n editorElement,\n position,\n}: SetCursorPositionByAbsIndexOptions): void => {\n const selection = window.getSelection?.();\n\n if (!selection) {\n return;\n }\n\n const target = getCursorTargetByAbsIndex({ editorElement, position });\n\n if (!target) {\n return;\n }\n\n const range = document.createRange();\n\n try {\n range.setStart(target.node, target.offset);\n range.setEnd(target.node, target.offset);\n } catch {\n return;\n }\n\n selection.removeAllRanges();\n selection.addRange(range);\n\n range.collapse(true);\n};\n\n/**\n * Unwraps any no-emoji-convert span that contains the cursor.\n * This removes the span element but keeps its text content, preventing the cursor from getting stuck.\n */\nexport const unwrapIgnoreEmojiSpanAtCursor = (editorElement: HTMLDivElement | null) => {\n if (!editorElement) {\n return;\n }\n\n const selection = window.getSelection();\n\n if (!selection || !selection.rangeCount) {\n return;\n }\n\n const range = selection.getRangeAt(0);\n let { commonAncestorContainer } = range;\n const cursorOffset = range.startOffset;\n\n if (!editorElement.contains(commonAncestorContainer)) {\n return;\n }\n\n // Walk up the DOM tree to find if we're inside a no-emoji-convert span\n while (commonAncestorContainer && commonAncestorContainer !== editorElement) {\n if (\n commonAncestorContainer.nodeType === Node.ELEMENT_NODE &&\n (commonAncestorContainer as Element).classList.contains('no-emoji-convert')\n ) {\n // We're inside a no-emoji-convert span, unwrap it\n const span = commonAncestorContainer as Element;\n const { parentNode } = span;\n\n if (!parentNode) {\n return;\n }\n\n // Find which text node contains the cursor\n let cursorNode: Node | null = null;\n const cursorNodeOffset = cursorOffset;\n\n // Get all child nodes of the span\n const childNodes = Array.from(span.childNodes);\n\n // Insert all children before the span and find the cursor node\n childNodes.forEach((child) => {\n const clonedChild = child.cloneNode(true);\n parentNode.insertBefore(clonedChild, span);\n\n // If this is the node that contains the cursor, track it\n if (child === range.startContainer) {\n cursorNode = clonedChild;\n }\n });\n\n // Remove the span\n parentNode.removeChild(span);\n\n // Restore cursor position in the unwrapped content\n if (cursorNode) {\n range.setStart(cursorNode, cursorNodeOffset);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n\n break;\n }\n\n // @ts-expect-error - is needed\n commonAncestorContainer = commonAncestorContainer.parentNode;\n }\n};\n\n/**\n * Moves the cursor outside of any no-emoji-convert span if it's currently inside one.\n * This prevents the cursor from getting \"stuck\" inside the protection span when typing.\n */\nexport const moveCursorOutOfIgnoreEmojiSpan = (editorElement: HTMLDivElement | null) => {\n if (!editorElement) {\n return;\n }\n\n const selection = window.getSelection();\n\n if (!selection || !selection.rangeCount) {\n return;\n }\n\n const range = selection.getRangeAt(0);\n let { commonAncestorContainer } = range;\n\n if (!editorElement.contains(commonAncestorContainer)) {\n return;\n }\n\n // Walk up the DOM tree to find if we're inside a no-emoji-convert span\n while (commonAncestorContainer && commonAncestorContainer !== editorElement) {\n if (\n commonAncestorContainer.nodeType === Node.ELEMENT_NODE &&\n (commonAncestorContainer as Element).classList.contains('no-emoji-convert')\n ) {\n // We're inside a no-emoji-convert span, move cursor to after it\n const span = commonAncestorContainer as Element;\n const { nextSibling } = span;\n const { parentNode } = span;\n\n if (!parentNode) {\n return;\n }\n\n // Always ensure there's a text node AFTER the span\n let targetNode: Text;\n\n if (nextSibling && nextSibling.nodeType === Node.TEXT_NODE) {\n // Next sibling is already a text node, use it\n targetNode = nextSibling as Text;\n } else if (nextSibling && nextSibling.nodeType === Node.ELEMENT_NODE) {\n // Next sibling is an element, find first text node in it\n const walker = document.createTreeWalker(nextSibling, NodeFilter.SHOW_TEXT);\n const firstTextNode = walker.nextNode() as Text;\n if (firstTextNode) {\n targetNode = firstTextNode;\n } else {\n // No text node found, create one\n targetNode = document.createTextNode('\\u200B');\n parentNode.insertBefore(targetNode, nextSibling);\n }\n } else {\n // No next sibling or it's not a text/element node, create a new text node\n targetNode = document.createTextNode('\\u200B');\n parentNode.insertBefore(targetNode, nextSibling);\n }\n\n // Place cursor at the start of the target node\n range.setStart(targetNode, 0);\n range.collapse(true);\n\n selection.removeAllRanges();\n selection.addRange(range);\n break;\n }\n\n // @ts-expect-error - is needed\n commonAncestorContainer = commonAncestorContainer.parentNode;\n }\n};\n"],"mappings":"AACA,SAASA,KAAK,QAAQ,UAAU;AAChC,SAASC,iBAAiB,EAAEC,oBAAoB,QAAQ,QAAQ;AAEhE,IAAIC,UAAU,GAAG,CAAC,CAAC;AACnB,IAAIC,SAAS,GAAG,CAAC,CAAC;AAClB,IAAIC,WAAW,GAAG,CAAC,CAAC;AAMpB,OAAO,MAAMC,aAAa,GAAGA,CACzBC,OAAuB,EACvB;EAAEC;AAAiD,CAAC,GAAG,CAAC,CAAC,KACxD;EACD,MAAMC,SAAS,GAAGC,MAAM,CAACC,YAAY,CAAC,CAAC;EAEvC,IAAI,CAACF,SAAS,EAAE;IACZ;EACJ;EAEA,MAAM;IAAEG;EAAW,CAAC,GAAGH,SAAS;EAEhC,IAAI,CAACG,UAAU,EAAE;IACb;EACJ;EAEA,MAAMC,KAAK,GAAGJ,SAAS,CAACK,UAAU,CAAC,CAAC,CAAC;EAErC,IAAIC,eAAe,GAAGC,KAAK,CAACC,IAAI,CAACV,OAAO,CAACW,UAAU,CAAC;EAEpD,IAAIV,0BAA0B,EAAE;IAC5BO,eAAe,GAAGA,eAAe,CAACI,MAAM,CACpC,CAAC;MAAEC,QAAQ;MAAEC;IAAU,CAAC,KACpBD,QAAQ,KAAKE,IAAI,CAACC,SAAS,IAAKF,SAAS,KAAK,EAAE,IAAIA,SAAS,KAAK,QAC1E,CAAC;EACL;EAEAlB,UAAU,GAAGY,eAAe,CAACS,OAAO,CAACZ,UAAuB,CAAC;EAE7DR,SAAS,GAAGS,KAAK,CAACT,SAAS;EAC3BC,WAAW,GAAGQ,KAAK,CAACR,WAAW;AACnC,CAAC;AAED,OAAO,MAAMoB,gBAAgB,GAAIlB,OAAuB,IAAK;EACzD;EACA;EACA;EACA,MAAMQ,eAAe,GAAGC,KAAK,CAACC,IAAI,CAACV,OAAO,CAACW,UAAU,CAAC;EAEtD,IAAIQ,gBAAgB,GAAG,KAAK;EAE5BX,eAAe,CAACY,OAAO,CAAEC,IAAI,IAAK;IAC9B,IACI,CAACF,gBAAgB,IACjBE,IAAI,CAACR,QAAQ,KAAKE,IAAI,CAACC,SAAS,IAChC,OAAOK,IAAI,CAACP,SAAS,KAAK,QAAQ,EACpC;MACE,MAAMQ,aAAa,GAAGD,IAAI,CAACP,SAAS,CAACG,OAAO,CAAC,QAAQ,CAAC;MAEtD,IAAIK,aAAa,KAAK,CAAC,CAAC,EAAE;QACtBH,gBAAgB,GAAG,IAAI;QAEvBvB,UAAU,GAAGY,eAAe,CAACS,OAAO,CAACI,IAAI,CAAC;QAC1CvB,WAAW,GAAGwB,aAAa;QAC3BzB,SAAS,GAAGyB,aAAa;MAC7B;IACJ;EACJ,CAAC,CAAC;;EAEF;EACA,IAAIH,gBAAgB,EAAE;IAClBX,eAAe,CAACY,OAAO,CAAEC,IAAI,IAAK;MAC9B,IAAIA,IAAI,CAACR,QAAQ,KAAKE,IAAI,CAACC,SAAS,IAAI,OAAOK,IAAI,CAACP,SAAS,KAAK,QAAQ,EAAE;QACxE;QACAO,IAAI,CAACP,SAAS,GAAGO,IAAI,CAACP,SAAS,CAACS,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;MAC1D;IACJ,CAAC,CAAC;EACN;EAEA,IAAIC,SAAS,GAAGxB,OAAO,CAACW,UAAU,CAACf,UAAU,CAAC;EAE9C,MAAMM,SAAS,GAAGC,MAAM,CAACC,YAAY,CAAC,CAAC;EAEvC,IAAI,CAACoB,SAAS,IAAI,CAACxB,OAAO,IAAI,CAACE,SAAS,EAAE;IACtC;EACJ;;EAEA;EACA,IAAI,OAAOsB,SAAS,CAACV,SAAS,KAAK,QAAQ,EAAE;IACzC,MAAMW,iBAAiB,GAAG9B,oBAAoB,CAAC6B,SAAoB,CAAC;IAEpE,IAAIA,SAAS,CAACE,WAAW,EAAE;MACvBF,SAAS,GAAGA,SAAS,CAACE,WAAW;MAEjC,IAAIF,SAAS,CAACX,QAAQ,KAAKE,IAAI,CAACC,SAAS,IAAIQ,SAAS,CAACV,SAAS,EAAE;QAC9DjB,SAAS,IAAI4B,iBAAiB;QAC9B3B,WAAW,IAAI2B,iBAAiB;QAEhC,IAAID,SAAS,CAACV,SAAS,CAACa,UAAU,CAAC9B,SAAS,CAAC,KAAK,IAAI,EAAE;UACpDA,SAAS,IAAI,CAAC;UACdC,WAAW,IAAI,CAAC;QACpB;MACJ,CAAC,MAAM;QACH,MAAM8B,QAAQ,GAAGC,QAAQ,CAACC,cAAc,CAAC,QAAQ,CAAC;QAElDN,SAAS,CAACO,UAAU,EAAEC,YAAY,CAACJ,QAAQ,EAAEJ,SAAS,CAACE,WAAW,CAAC;QAEnEF,SAAS,GAAGI,QAAQ;QAEpB/B,SAAS,GAAG+B,QAAQ,CAACK,MAAM;QAC3BnC,WAAW,GAAG8B,QAAQ,CAACK,MAAM;MACjC;IACJ,CAAC,MAAM;MACH,MAAML,QAAQ,GAAGC,QAAQ,CAACC,cAAc,CAAC,QAAQ,CAAC;MAElDN,SAAS,CAACO,UAAU,EAAEC,YAAY,CAACJ,QAAQ,EAAEJ,SAAS,CAACE,WAAW,CAAC;MAEnEF,SAAS,GAAGI,QAAQ;MAEpB/B,SAAS,GAAG+B,QAAQ,CAACK,MAAM;MAC3BnC,WAAW,GAAG8B,QAAQ,CAACK,MAAM;IACjC;EACJ,CAAC,MAAM,IAAIT,SAAS,CAACV,SAAS,IAAIjB,SAAS,GAAG2B,SAAS,CAACV,SAAS,CAACmB,MAAM,EAAE;IACtE,IAAIT,SAAS,CAACE,WAAW,EAAEZ,SAAS,EAAE;MAClC,IAAIW,iBAAiB,GAAGD,SAAS,CAACV,SAAS,CAACmB,MAAM;MAElDT,SAAS,GAAGA,SAAS,CAACE,WAAW;;MAEjC;MACA,IAAI,OAAOF,SAAS,CAACV,SAAS,KAAK,QAAQ,EAAE;QACzCW,iBAAiB,IAAI9B,oBAAoB,CAAC6B,SAAoB,CAAC;QAE/D,IAAIA,SAAS,CAACE,WAAW,EAAEZ,SAAS,EAAE;UAClCU,SAAS,GAAGA,SAAS,CAACE,WAAW;UAEjC,IAAIF,SAAS,CAACX,QAAQ,KAAKE,IAAI,CAACC,SAAS,IAAIQ,SAAS,CAACV,SAAS,EAAE;YAC9DjB,SAAS,IAAI4B,iBAAiB;YAC9B3B,WAAW,IAAI2B,iBAAiB;YAEhC,IAAID,SAAS,CAACV,SAAS,CAACa,UAAU,CAAC9B,SAAS,CAAC,KAAK,IAAI,EAAE;cACpDA,SAAS,IAAI,CAAC;cACdC,WAAW,IAAI,CAAC;YACpB;UACJ,CAAC,MAAM;YACH,MAAM8B,QAAQ,GAAGC,QAAQ,CAACC,cAAc,CAAC,QAAQ,CAAC;YAElDN,SAAS,CAACO,UAAU,EAAEC,YAAY,CAACJ,QAAQ,EAAEJ,SAAS,CAACE,WAAW,CAAC;YAEnEF,SAAS,GAAGI,QAAQ;YAEpB/B,SAAS,GAAG+B,QAAQ,CAACK,MAAM;YAC3BnC,WAAW,GAAG8B,QAAQ,CAACK,MAAM;UACjC;QACJ,CAAC,MAAM;UACH,MAAML,QAAQ,GAAGC,QAAQ,CAACC,cAAc,CAAC,QAAQ,CAAC;UAElDN,SAAS,CAACO,UAAU,EAAEC,YAAY,CAACJ,QAAQ,EAAEJ,SAAS,CAACE,WAAW,CAAC;UAEnEF,SAAS,GAAGI,QAAQ;UAEpB/B,SAAS,GAAG+B,QAAQ,CAACK,MAAM;UAC3BnC,WAAW,GAAG8B,QAAQ,CAACK,MAAM;QACjC;MACJ;IACJ,CAAC,MAAM;MACHpC,SAAS,GAAG2B,SAAS,CAACV,SAAS,CAACmB,MAAM;MACtCnC,WAAW,GAAG0B,SAAS,CAACV,SAAS,CAACmB,MAAM;IAC5C;EACJ;EAEA,MAAM3B,KAAK,GAAGuB,QAAQ,CAACK,WAAW,CAAC,CAAC;;EAEpC;EACA,IAAI,OAAOV,SAAS,CAACV,SAAS,KAAK,QAAQ,EAAE;IACzChB,WAAW,GAAGL,KAAK,CAACK,WAAW,EAAE,CAAC,EAAE0B,SAAS,CAACV,SAAS,CAACmB,MAAM,CAAC;IAC/DpC,SAAS,GAAGJ,KAAK,CAACI,SAAS,EAAE,CAAC,EAAE2B,SAAS,CAACV,SAAS,CAACmB,MAAM,CAAC;EAC/D;EAEA,IAAI;IACA3B,KAAK,CAAC6B,QAAQ,CAACX,SAAS,EAAE1B,WAAW,CAAC;IACtCQ,KAAK,CAAC8B,MAAM,CAACZ,SAAS,EAAE3B,SAAS,CAAC;EACtC,CAAC,CAAC,OAAOwC,KAAK,EAAE;IACZ;EAAA;EAGJnC,SAAS,CAACoC,eAAe,CAAC,CAAC;EAC3BpC,SAAS,CAACqC,QAAQ,CAACjC,KAAK,CAAC;EAEzBA,KAAK,CAACkC,QAAQ,CAAC,IAAI,CAAC;AACxB,CAAC;AAED,OAAO,MAAMC,2BAA2B,GAAGA,CAAA,KAAY;EACnD,MAAMvC,SAAS,GAAGC,MAAM,CAACC,YAAY,CAAC,CAAC;EAEvC,IAAI,CAACF,SAAS,IAAIA,SAAS,CAACwC,UAAU,KAAK,CAAC,EAAE;IAC1C;EACJ;EAEA,MAAMpC,KAAK,GAAGJ,SAAS,CAACK,UAAU,CAAC,CAAC,CAAC;EACrC,MAAMqB,QAAQ,GAAGtB,KAAK,CAACqC,cAAc;EACrC,MAAMC,MAAM,GAAGtC,KAAK,CAACR,WAAW;;EAEhC;EACA+B,QAAQ,CAACgB,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC;EAErC,MAAMC,IAAI,GAAGjB,QAAQ,CAACkB,aAAa,CAAC,MAAM,CAAC;EAC3CD,IAAI,CAACE,KAAK,CAACC,OAAO,GAAG,cAAc;EACnCH,IAAI,CAACE,KAAK,CAACE,KAAK,GAAG,GAAG;EACtBJ,IAAI,CAACE,KAAK,CAACG,MAAM,GAAG,GAAG;EACvBL,IAAI,CAACM,SAAS,GAAG,yBAAyB;EAE1C,MAAMC,MAAM,GAAGzB,QAAQ,CAACG,UAAU;EAElC,IAAIsB,MAAM,EAAE;IACR,IAAIzB,QAAQ,CAACf,QAAQ,KAAKE,IAAI,CAACC,SAAS,EAAE;MACtC,MAAMsC,WAAW,GAAG1B,QAAQ,CAAC0B,WAAW,IAAI,EAAE;MAC9C,MAAMC,UAAU,GAAGD,WAAW,CAACE,KAAK,CAAC,CAAC,EAAEZ,MAAM,CAAC;MAC/C,MAAMa,SAAS,GAAGH,WAAW,CAACE,KAAK,CAACZ,MAAM,CAAC;MAE3ChB,QAAQ,CAAC0B,WAAW,GAAGC,UAAU;MAEjCF,MAAM,CAACrB,YAAY,CAACc,IAAI,EAAElB,QAAQ,CAACF,WAAW,CAAC;MAC/C,MAAMgC,aAAa,GAAG7B,QAAQ,CAACC,cAAc,CAAC2B,SAAS,CAAC;MACxDJ,MAAM,CAACrB,YAAY,CAAC0B,aAAa,EAAEZ,IAAI,CAACpB,WAAW,CAAC;MAEpDiC,UAAU,CAAC,MAAM;QACb;QACA,MAAMC,QAAQ,GAAG/B,QAAQ,CAACK,WAAW,CAAC,CAAC;QACvC0B,QAAQ,CAACC,aAAa,CAACf,IAAI,CAAC;QAC5Bc,QAAQ,CAACE,WAAW,CAAChB,IAAI,CAAC;QAC1B5C,SAAS,CAACoC,eAAe,CAAC,CAAC;QAC3BpC,SAAS,CAACqC,QAAQ,CAACqB,QAAQ,CAAC;;QAE5B;QACAd,IAAI,CAACiB,MAAM,CAAC,CAAC;MACjB,CAAC,EAAE,EAAE,CAAC;IACV;EACJ;AACJ,CAAC;AAED,OAAO,MAAMC,kBAAkB,GAAGA,CAAA,KAAM;EACpC,MAAM9D,SAAS,GAAGC,MAAM,CAACC,YAAY,CAAC,CAAC;EAEvC,IAAIF,SAAS,IAAIA,SAAS,CAACwC,UAAU,GAAG,CAAC,EAAE;IACvC,MAAMpC,KAAK,GAAGJ,SAAS,CAACK,UAAU,CAAC,CAAC,CAAC;IACrC,MAAM0D,MAAM,GAAGpC,QAAQ,CAACkB,aAAa,CAAC,MAAM,CAAC;IAC7CkB,MAAM,CAACC,EAAE,GAAG,eAAe;IAC3BD,MAAM,CAACjB,KAAK,CAACC,OAAO,GAAG,cAAc;IACrCgB,MAAM,CAACjB,KAAK,CAACE,KAAK,GAAG,GAAG;IACxBe,MAAM,CAACjB,KAAK,CAACG,MAAM,GAAG,GAAG;IACzB7C,KAAK,CAAC6D,UAAU,CAACF,MAAM,CAAC;EAC5B;AACJ,CAAC;AAED,OAAO,MAAMG,oBAAoB,GAAIC,GAA8B,IAAK;EACpE,MAAMJ,MAAM,GAAGI,GAAG,CAACC,OAAO,EAAEC,aAAa,CAAC,gBAAgB,CAAC;EAE3D,IAAIN,MAAM,EAAE;IACR,MAAM/D,SAAS,GAAGC,MAAM,CAACC,YAAY,CAAC,CAAC;IACvC,MAAME,KAAK,GAAGuB,QAAQ,CAACK,WAAW,CAAC,CAAC;IACpC5B,KAAK,CAACuD,aAAa,CAACI,MAAM,CAAC;IAC3B3D,KAAK,CAACwD,WAAW,CAACG,MAAM,CAAC;IACzB/D,SAAS,EAAEoC,eAAe,CAAC,CAAC;IAC5BpC,SAAS,EAAEqC,QAAQ,CAACjC,KAAK,CAAC;IAC1B2D,MAAM,CAACF,MAAM,CAAC,CAAC;EACnB;AACJ,CAAC;AAED,OAAO,MAAMS,mBAAmB,GAAIC,QAAgB,IAAK;EACrD5E,SAAS,IAAI4E,QAAQ;EACrB3E,WAAW,IAAI2E,QAAQ;AAC3B,CAAC;AAED,OAAO,MAAMC,aAAa,GAAIC,KAAa,IAAK;EAC5C/E,UAAU,GAAG+E,KAAK;AACtB,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,4BAA4B,GAAIC,KAAoC,IAAK;EAClF,MAAMvE,KAAK,GAAGH,MAAM,CAACC,YAAY,CAAC,CAAC,EAAEG,UAAU,CAAC,CAAC,CAAC;;EAElD;AACJ;AACA;AACA;AACA;EACI,IACI,CAACD,KAAK,IACNA,KAAK,CAACT,SAAS,KAAKS,KAAK,CAACR,WAAW,IACpC+E,KAAK,CAACC,GAAG,KAAK,WAAW,IAAID,KAAK,CAACC,GAAG,KAAK,QAAQ,IAAID,KAAK,CAACC,GAAG,KAAK,cAAe,EACvF;IACE,OAAO,IAAI;EACf;EAEA,IAAID,KAAK,CAACC,GAAG,KAAK,WAAW,IAAID,KAAK,CAACC,GAAG,KAAK,cAAc,EAAE;IAC3D,MAAM;MAAEhE,SAAS;MAAEiE;IAAgB,CAAC,GAAGzE,KAAK,CAACqC,cAAc;IAE3D,IAAIrC,KAAK,CAACR,WAAW,GAAG,CAAC,EAAE;MACvB,OAAOgB,SAAS,EAAEa,UAAU,CAACrB,KAAK,CAACR,WAAW,GAAG,CAAC,CAAC;IACvD;IAEA,OAAOiF,eAAe,EAAEjE,SAAS,EAAEa,UAAU,CAACoD,eAAe,CAACjE,SAAS,CAACmB,MAAM,GAAG,CAAC,CAAC;EACvF;EAEA,MAAM;IAAEP,WAAW;IAAEZ;EAAU,CAAC,GAAGR,KAAK,CAAC0E,YAAY;EAErD,IAAI1E,KAAK,CAACT,SAAS,IAAIiB,SAAS,EAAEmB,MAAM,IAAI,CAAC,CAAC,EAAE;IAC5C,OAAOnB,SAAS,EAAEa,UAAU,CAACrB,KAAK,CAACT,SAAS,CAAC;EACjD;EAEA,OAAO6B,WAAW,EAAEZ,SAAS,EAAEa,UAAU,CAAC,CAAC,CAAC;AAChD,CAAC;AAiBD,OAAO,MAAMsD,iBAAiB,GAAGA,CAAC;EAC9BC,aAAa;EACbC,UAAU;EACVC,OAAO,GAAG;IAAEC,uBAAuB,EAAE;EAAK;AACpB,CAAC,KAAmB;EAC1C,IAAI,CAACH,aAAa,CAAC5B,WAAW,EAAEgC,QAAQ,CAACH,UAAU,CAAC,EAAE;IAClD,OAAO,IAAI;EACf;EAEA,MAAM7E,KAAK,GAAGuB,QAAQ,CAACK,WAAW,CAAC,CAAC;EAEpC,MAAMqD,SAAS,GAAGC,wBAAwB,CAACN,aAAa,CAAC;EAEzD,MAAMO,OAAgB,GAAG,EAAE;EAC3B,IAAIC,UAAU,GAAG,CAAC;EAElB,MAAMC,kBAAkB,GAAItE,IAAU,IAAK;IACvC,IAAIA,IAAI,CAACR,QAAQ,KAAKE,IAAI,CAACC,SAAS,IAAIK,IAAI,CAACiC,WAAW,EAAE;MACtD,IAAIqB,KAAK,GAAGtD,IAAI,CAACiC,WAAW,CAACrC,OAAO,CAACkE,UAAU,CAAC;MAChD,OAAOR,KAAK,KAAK,CAAC,CAAC,EAAE;QACjBc,OAAO,CAACG,IAAI,CAAC;UACTvE,IAAI;UACJuB,MAAM,EAAE+B,KAAK;UACbkB,QAAQ,EAAEH,UAAU,GAAGf;QAC3B,CAAC,CAAC;QACFA,KAAK,GAAGtD,IAAI,CAACiC,WAAW,CAACrC,OAAO,CAACkE,UAAU,EAAER,KAAK,GAAG,CAAC,CAAC;MAC3D;MACAe,UAAU,IAAIrE,IAAI,CAACiC,WAAW,CAACrB,MAAM;IACzC,CAAC,MAAM,IAAIZ,IAAI,CAACyE,QAAQ,KAAK,YAAY,EAAE;MACvCrF,KAAK,CAACC,IAAI,CAACW,IAAI,CAACV,UAAU,CAAC,CAACS,OAAO,CAACuE,kBAAkB,CAAC;IAC3D;EACJ,CAAC;EAEDA,kBAAkB,CAACT,aAAa,CAAC;EAEjC,IAAIO,OAAO,CAACxD,MAAM,KAAK,CAAC,EAAE;IACtB,OAAO,IAAI;EACf;EAEA,IAAI8D,KAAK,GAAGN,OAAO,CAAC,CAAC,CAAC;EAEtB,IAAIL,OAAO,EAAEC,uBAAuB,IAAIE,SAAS,KAAK,IAAI,EAAE;IACxDQ,KAAK,GAAGN,OAAO,CAACO,MAAM,CAAC,CAACC,IAAI,EAAEC,IAAI,KAC9BC,IAAI,CAACC,GAAG,CAACF,IAAI,CAACL,QAAQ,GAAGN,SAAS,CAAC,GAAGY,IAAI,CAACC,GAAG,CAACH,IAAI,CAACJ,QAAQ,GAAGN,SAAS,CAAC,GAAGW,IAAI,GAAGD,IACvF,CAAC;EACL;EAEA,IAAI,CAACF,KAAK,EAAE;IACR,OAAO,IAAI;EACf;EAEAzF,KAAK,CAAC6B,QAAQ,CAAC4D,KAAK,CAAC1E,IAAI,EAAE0E,KAAK,CAACnD,MAAM,CAAC;EACxCtC,KAAK,CAAC8B,MAAM,CAAC2D,KAAK,CAAC1E,IAAI,EAAE0E,KAAK,CAACnD,MAAM,GAAGuC,UAAU,CAAClD,MAAM,CAAC;EAE1D,OAAO3B,KAAK;AAChB,CAAC;AAED,OAAO,MAAMkF,wBAAwB,GAAIN,aAAoC,IAAoB;EAC7F,IAAI,CAACA,aAAa,EAAE;IAChB,OAAO,IAAI;EACf;EAEA,MAAMmB,GAAG,GAAGlG,MAAM,CAACC,YAAY,GAAG,CAAC;EACnC,IAAI,CAACiG,GAAG,IAAIA,GAAG,CAAC3D,UAAU,KAAK,CAAC,EAAE;IAC9B,OAAO,IAAI;EACf;EAEA,MAAMpC,KAAK,GAAG+F,GAAG,CAAC9F,UAAU,CAAC,CAAC,CAAC;EAE/B,IAAI,CAAC2E,aAAa,CAACoB,QAAQ,CAAChG,KAAK,CAACiG,uBAAuB,CAAC,EAAE;IACxD,OAAO,IAAI;EACf;EAEA,MAAMC,GAAG,GAAG3E,QAAQ,CAACK,WAAW,CAAC,CAAC;EAClCsE,GAAG,CAACC,kBAAkB,CAACvB,aAAa,CAAC;EAErC,IAAI;IACAsB,GAAG,CAACpE,MAAM,CAAC9B,KAAK,CAACqC,cAAc,EAAErC,KAAK,CAACR,WAAW,CAAC;IAEnD,MAAM4G,SAAS,GAAG7E,QAAQ,CAACkB,aAAa,CAAC,KAAK,CAAC;IAC/C2D,SAAS,CAACC,WAAW,CAACH,GAAG,CAACI,aAAa,CAAC,CAAC,CAAC;IAE1C,MAAMC,iBAAiB,GAAGnH,iBAAiB,CAACgH,SAAS,CAACI,SAAS,EAAE;MAC7DC,cAAc,EAAE,IAAI;MACpBC,8BAA8B,EAAE;IACpC,CAAC,CAAC;IAEF,OAAOH,iBAAiB,CAAC5E,MAAM;EACnC,CAAC,CAAC,MAAM;IACJ,OAAOvC,iBAAiB,CAACwF,aAAa,CAAC4B,SAAS,EAAE;MAC9CE,8BAA8B,EAAE;IACpC,CAAC,CAAC,CAAC/E,MAAM;EACb;AACJ,CAAC;AAID,MAAMgF,yBAAyB,GAAGA,CAAC;EAC/B/B,aAAa;EACbgC;AACgC,CAAC,KAA0B;EAC3D,MAAMvG,UAAU,GAAGF,KAAK,CAACC,IAAI,CAACwE,aAAa,CAACvE,UAAU,CAAC;EAEvD,IAAIA,UAAU,CAACsB,MAAM,KAAK,CAAC,EAAE;IACzB,MAAML,QAAQ,GAAGC,QAAQ,CAACC,cAAc,CAAC,EAAE,CAAC;IAC5CoD,aAAa,CAACyB,WAAW,CAAC/E,QAAQ,CAAC;IAEnC,OAAO;MAAEP,IAAI,EAAEO,QAAQ;MAAEgB,MAAM,EAAE;IAAE,CAAC;EACxC;EAEA,MAAMuE,eAAe,GAAG1H,KAAK,CACzByH,QAAQ,EACR,CAAC,EACDxH,iBAAiB,CAACwF,aAAa,CAAC4B,SAAS,EAAE;IACvCE,8BAA8B,EAAE;EACpC,CAAC,CAAC,CAAC/E,MACP,CAAC;EAED,IAAIyD,UAAU,GAAG,CAAC;EAElB,MAAM0B,WAAW,GAAI/F,IAAU,IAA0B;IACrD,IAAIA,IAAI,CAACR,QAAQ,KAAKE,IAAI,CAACC,SAAS,EAAE;MAClC,MAAMY,QAAQ,GAAGP,IAAY;MAC7B,MAAMgG,QAAQ,GAAGzF,QAAQ,CAACd,SAAS,IAAI,EAAE;MACzC,MAAMwG,cAAc,GAAG5B,UAAU,GAAG2B,QAAQ,CAACpF,MAAM;MAEnD,IAAIkF,eAAe,IAAIG,cAAc,EAAE;QACnC,OAAO;UACHjG,IAAI,EAAEO,QAAQ;UACdgB,MAAM,EAAEnD,KAAK,CAAC0H,eAAe,GAAGzB,UAAU,EAAE,CAAC,EAAE2B,QAAQ,CAACpF,MAAM;QAClE,CAAC;MACL;MAEAyD,UAAU,GAAG4B,cAAc;MAE3B,OAAO,IAAI;IACf;IAEA,IAAIjG,IAAI,CAACyE,QAAQ,KAAK,YAAY,EAAE;MAChC,OAAO,IAAI;IACf;IAEA,KAAK,MAAMyB,KAAK,IAAI9G,KAAK,CAACC,IAAI,CAACW,IAAI,CAACV,UAAU,CAAC,EAAE;MAC7C,MAAM6G,KAAK,GAAGJ,WAAW,CAACG,KAAK,CAAC;MAChC,IAAIC,KAAK,EAAE;QACP,OAAOA,KAAK;MAChB;IACJ;IAEA,OAAO,IAAI;EACf,CAAC;EAED,KAAK,MAAMC,QAAQ,IAAI9G,UAAU,EAAE;IAC/B,MAAM6G,KAAK,GAAGJ,WAAW,CAACK,QAAQ,CAAC;IACnC,IAAID,KAAK,EAAE;MACP,OAAOA,KAAK;IAChB;EACJ;EAEA,MAAME,YAAY,GAAGxC,aAAa,CAACyC,SAAS;EAC5C,IAAID,YAAY,EAAE7G,QAAQ,KAAKE,IAAI,CAACC,SAAS,EAAE;IAC3C,MAAMY,QAAQ,GAAG8F,YAAoB;IACrC,OAAO;MAAErG,IAAI,EAAEO,QAAQ;MAAEgB,MAAM,EAAEhB,QAAQ,CAACK;IAAO,CAAC;EACtD;EAEA,MAAM2F,gBAAgB,GAAG/F,QAAQ,CAACC,cAAc,CAAC,QAAQ,CAAC;EAC1DoD,aAAa,CAACyB,WAAW,CAACiB,gBAAgB,CAAC;EAE3C,OAAO;IAAEvG,IAAI,EAAEuG,gBAAgB;IAAEhF,MAAM,EAAEgF,gBAAgB,CAAC3F;EAAO,CAAC;AACtE,CAAC;AAED,OAAO,MAAM4F,2BAA2B,GAAGA,CAAC;EACxC3C,aAAa;EACbgC;AACgC,CAAC,KAAW;EAC5C,MAAMhH,SAAS,GAAGC,MAAM,CAACC,YAAY,GAAG,CAAC;EAEzC,IAAI,CAACF,SAAS,EAAE;IACZ;EACJ;EAEA,MAAM4H,MAAM,GAAGb,yBAAyB,CAAC;IAAE/B,aAAa;IAAEgC;EAAS,CAAC,CAAC;EAErE,IAAI,CAACY,MAAM,EAAE;IACT;EACJ;EAEA,MAAMxH,KAAK,GAAGuB,QAAQ,CAACK,WAAW,CAAC,CAAC;EAEpC,IAAI;IACA5B,KAAK,CAAC6B,QAAQ,CAAC2F,MAAM,CAACzG,IAAI,EAAEyG,MAAM,CAAClF,MAAM,CAAC;IAC1CtC,KAAK,CAAC8B,MAAM,CAAC0F,MAAM,CAACzG,IAAI,EAAEyG,MAAM,CAAClF,MAAM,CAAC;EAC5C,CAAC,CAAC,MAAM;IACJ;EACJ;EAEA1C,SAAS,CAACoC,eAAe,CAAC,CAAC;EAC3BpC,SAAS,CAACqC,QAAQ,CAACjC,KAAK,CAAC;EAEzBA,KAAK,CAACkC,QAAQ,CAAC,IAAI,CAAC;AACxB,CAAC;;AAED;AACA;AACA;AACA;AACA,OAAO,MAAMuF,6BAA6B,GAAI7C,aAAoC,IAAK;EACnF,IAAI,CAACA,aAAa,EAAE;IAChB;EACJ;EAEA,MAAMhF,SAAS,GAAGC,MAAM,CAACC,YAAY,CAAC,CAAC;EAEvC,IAAI,CAACF,SAAS,IAAI,CAACA,SAAS,CAACwC,UAAU,EAAE;IACrC;EACJ;EAEA,MAAMpC,KAAK,GAAGJ,SAAS,CAACK,UAAU,CAAC,CAAC,CAAC;EACrC,IAAI;IAAEgG;EAAwB,CAAC,GAAGjG,KAAK;EACvC,MAAM0H,YAAY,GAAG1H,KAAK,CAACR,WAAW;EAEtC,IAAI,CAACoF,aAAa,CAACoB,QAAQ,CAACC,uBAAuB,CAAC,EAAE;IAClD;EACJ;;EAEA;EACA,OAAOA,uBAAuB,IAAIA,uBAAuB,KAAKrB,aAAa,EAAE;IACzE,IACIqB,uBAAuB,CAAC1F,QAAQ,KAAKE,IAAI,CAACkH,YAAY,IACrD1B,uBAAuB,CAAa2B,SAAS,CAAC5B,QAAQ,CAAC,kBAAkB,CAAC,EAC7E;MACE;MACA,MAAMxD,IAAI,GAAGyD,uBAAkC;MAC/C,MAAM;QAAExE;MAAW,CAAC,GAAGe,IAAI;MAE3B,IAAI,CAACf,UAAU,EAAE;QACb;MACJ;;MAEA;MACA,IAAIoG,UAAuB,GAAG,IAAI;MAClC,MAAMC,gBAAgB,GAAGJ,YAAY;;MAErC;MACA,MAAMrH,UAAU,GAAGF,KAAK,CAACC,IAAI,CAACoC,IAAI,CAACnC,UAAU,CAAC;;MAE9C;MACAA,UAAU,CAACS,OAAO,CAAEmG,KAAK,IAAK;QAC1B,MAAMc,WAAW,GAAGd,KAAK,CAACe,SAAS,CAAC,IAAI,CAAC;QACzCvG,UAAU,CAACC,YAAY,CAACqG,WAAW,EAAEvF,IAAI,CAAC;;QAE1C;QACA,IAAIyE,KAAK,KAAKjH,KAAK,CAACqC,cAAc,EAAE;UAChCwF,UAAU,GAAGE,WAAW;QAC5B;MACJ,CAAC,CAAC;;MAEF;MACAtG,UAAU,CAACwG,WAAW,CAACzF,IAAI,CAAC;;MAE5B;MACA,IAAIqF,UAAU,EAAE;QACZ7H,KAAK,CAAC6B,QAAQ,CAACgG,UAAU,EAAEC,gBAAgB,CAAC;QAC5C9H,KAAK,CAACkC,QAAQ,CAAC,IAAI,CAAC;QACpBtC,SAAS,CAACoC,eAAe,CAAC,CAAC;QAC3BpC,SAAS,CAACqC,QAAQ,CAACjC,KAAK,CAAC;MAC7B;MAEA;IACJ;;IAEA;IACAiG,uBAAuB,GAAGA,uBAAuB,CAACxE,UAAU;EAChE;AACJ,CAAC;;AAED;AACA;AACA;AACA;AACA,OAAO,MAAMyG,8BAA8B,GAAItD,aAAoC,IAAK;EACpF,IAAI,CAACA,aAAa,EAAE;IAChB;EACJ;EAEA,MAAMhF,SAAS,GAAGC,MAAM,CAACC,YAAY,CAAC,CAAC;EAEvC,IAAI,CAACF,SAAS,IAAI,CAACA,SAAS,CAACwC,UAAU,EAAE;IACrC;EACJ;EAEA,MAAMpC,KAAK,GAAGJ,SAAS,CAACK,UAAU,CAAC,CAAC,CAAC;EACrC,IAAI;IAAEgG;EAAwB,CAAC,GAAGjG,KAAK;EAEvC,IAAI,CAAC4E,aAAa,CAACoB,QAAQ,CAACC,uBAAuB,CAAC,EAAE;IAClD;EACJ;;EAEA;EACA,OAAOA,uBAAuB,IAAIA,uBAAuB,KAAKrB,aAAa,EAAE;IACzE,IACIqB,uBAAuB,CAAC1F,QAAQ,KAAKE,IAAI,CAACkH,YAAY,IACrD1B,uBAAuB,CAAa2B,SAAS,CAAC5B,QAAQ,CAAC,kBAAkB,CAAC,EAC7E;MACE;MACA,MAAMxD,IAAI,GAAGyD,uBAAkC;MAC/C,MAAM;QAAE7E;MAAY,CAAC,GAAGoB,IAAI;MAC5B,MAAM;QAAEf;MAAW,CAAC,GAAGe,IAAI;MAE3B,IAAI,CAACf,UAAU,EAAE;QACb;MACJ;;MAEA;MACA,IAAI0G,UAAgB;MAEpB,IAAI/G,WAAW,IAAIA,WAAW,CAACb,QAAQ,KAAKE,IAAI,CAACC,SAAS,EAAE;QACxD;QACAyH,UAAU,GAAG/G,WAAmB;MACpC,CAAC,MAAM,IAAIA,WAAW,IAAIA,WAAW,CAACb,QAAQ,KAAKE,IAAI,CAACkH,YAAY,EAAE;QAClE;QACA,MAAMS,MAAM,GAAG7G,QAAQ,CAAC8G,gBAAgB,CAACjH,WAAW,EAAEkH,UAAU,CAACC,SAAS,CAAC;QAC3E,MAAMC,aAAa,GAAGJ,MAAM,CAACK,QAAQ,CAAC,CAAS;QAC/C,IAAID,aAAa,EAAE;UACfL,UAAU,GAAGK,aAAa;QAC9B,CAAC,MAAM;UACH;UACAL,UAAU,GAAG5G,QAAQ,CAACC,cAAc,CAAC,QAAQ,CAAC;UAC9CC,UAAU,CAACC,YAAY,CAACyG,UAAU,EAAE/G,WAAW,CAAC;QACpD;MACJ,CAAC,MAAM;QACH;QACA+G,UAAU,GAAG5G,QAAQ,CAACC,cAAc,CAAC,QAAQ,CAAC;QAC9CC,UAAU,CAACC,YAAY,CAACyG,UAAU,EAAE/G,WAAW,CAAC;MACpD;;MAEA;MACApB,KAAK,CAAC6B,QAAQ,CAACsG,UAAU,EAAE,CAAC,CAAC;MAC7BnI,KAAK,CAACkC,QAAQ,CAAC,IAAI,CAAC;MAEpBtC,SAAS,CAACoC,eAAe,CAAC,CAAC;MAC3BpC,SAAS,CAACqC,QAAQ,CAACjC,KAAK,CAAC;MACzB;IACJ;;IAEA;IACAiG,uBAAuB,GAAGA,uBAAuB,CAACxE,UAAU;EAChE;AACJ,CAAC","ignoreList":[]}
|
|
@@ -6,6 +6,10 @@ export type EmojiInputProps = {
|
|
|
6
6
|
* Access token of the logged-in user. Is needed to load and save the history of the emojis.
|
|
7
7
|
*/
|
|
8
8
|
accessToken?: string;
|
|
9
|
+
/**
|
|
10
|
+
* The DOM element that should receive the emoji picker popup portal.
|
|
11
|
+
*/
|
|
12
|
+
container?: Element;
|
|
9
13
|
/**
|
|
10
14
|
* Sets the height of the input field to a fixed value. If this value is not set, the component will use the needed height until the maximum height is reached.
|
|
11
15
|
*/
|
|
@@ -79,6 +83,10 @@ export type EmojiInputProps = {
|
|
|
79
83
|
* Whether the placeholder should be shown after the input has focus.
|
|
80
84
|
*/
|
|
81
85
|
shouldHidePlaceholderOnFocus?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Allows the most recently auto-converted ASCII smiley to be reverted with Backspace.
|
|
88
|
+
*/
|
|
89
|
+
shouldRevertAsciiSmileyConversionOnBackspace?: boolean;
|
|
82
90
|
/**
|
|
83
91
|
* Prevents the EmojiPickerPopup icon from being displayed
|
|
84
92
|
*/
|
|
@@ -4,6 +4,10 @@ export type EmojiPickerPopupProps = {
|
|
|
4
4
|
* Access token of the logged-in user. Is needed to load and save the history of the emojis.
|
|
5
5
|
*/
|
|
6
6
|
accessToken?: string;
|
|
7
|
+
/**
|
|
8
|
+
* The DOM element that should receive the popup portal.
|
|
9
|
+
*/
|
|
10
|
+
container?: Element;
|
|
7
11
|
/**
|
|
8
12
|
* Function that is executed when the visibility of the popup changes.
|
|
9
13
|
* @param {boolean} isVisible - Whether the popup is visible or not
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chayns-components/emoji-input",
|
|
3
|
-
"version": "5.4.
|
|
3
|
+
"version": "5.4.11",
|
|
4
4
|
"description": "Input field that supports HTML elements and emojis",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"browserslist": [
|
|
@@ -89,5 +89,5 @@
|
|
|
89
89
|
"publishConfig": {
|
|
90
90
|
"access": "public"
|
|
91
91
|
},
|
|
92
|
-
"gitHead": "
|
|
92
|
+
"gitHead": "ce93463945ac595b45885ca964c7b7eb41f98d37"
|
|
93
93
|
}
|