@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.
@@ -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.addEventListener('keydown', handleKeyPress);
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.addEventListener('keydown', handleKeyPress);\n };\n }, [handleKeyPress]);\n\n return (\n <StyledEmojiPickerPopup>\n <Popup\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,QAAuB,yBAAyB;AAClF,OAAOC,KAAK,IAAQC,WAAW,EAAEC,SAAS,EAAEC,MAAM,QAAQ,OAAO;AACjE,OAAOC,WAAW,MAAM,6BAA6B;AACrD,SAASC,sBAAsB,QAAQ,2BAA2B;AAuBlE,MAAMC,gBAA2C,GAAGA,CAAC;EACjDC,WAAW;EACXC,uBAAuB;EACvBC,QAAQ;EACRC;AACJ,CAAC,KAAK;EACF,MAAMC,QAAQ,GAAGR,MAAM,CAAW,IAAI,CAAC;EAEvC,MAAMS,cAAc,GAAGX,WAAW,CAAEY,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;EAENf,SAAS,CAAC,MAAM;IACZgB,QAAQ,CAACC,gBAAgB,CAAC,SAAS,EAAEP,cAAc,CAAC;IAEpD,OAAO,MAAM;MACTM,QAAQ,CAACC,gBAAgB,CAAC,SAAS,EAAEP,cAAc,CAAC;IACxD,CAAC;EACL,CAAC,EAAE,CAACA,cAAc,CAAC,CAAC;EAEpB,oBACIZ,KAAA,CAAAoB,aAAA,CAACf,sBAAsB,qBACnBL,KAAA,CAAAoB,aAAA,CAACrB,KAAK;IACFsB,GAAG,EAAEV,QAAS;IACdW,MAAM,EAAEA,CAAA,KACJ,OAAOd,uBAAuB,KAAK,UAAU,GACvCA,uBAAuB,CAAC,KAAK,CAAC,GAC9Be,SACT;IACDC,MAAM,EAAEA,CAAA,KACJ,OAAOhB,uBAAuB,KAAK,UAAU,GACvCA,uBAAuB,CAAC,IAAI,CAAC,GAC7Be,SACT;IACDE,OAAO,eACHzB,KAAA,CAAAoB,aAAA,CAACvB,YAAY;MAAC6B,iBAAiB,EAAE;IAAM,gBACnC1B,KAAA,CAAAoB,aAAA,CAAChB,WAAW;MACRG,WAAW,EAAEA,WAAY;MACzBE,QAAQ,EAAEA,QAAS;MACnBC,QAAQ,EAAEA;IAAS,CACtB,CACS;EACjB,gBAEDV,KAAA,CAAAoB,aAAA,CAACtB,IAAI;IAAC6B,SAAS,EAAC,oBAAoB;IAACC,KAAK,EAAE,CAAC,cAAc,CAAE;IAACC,IAAI,EAAE;EAAG,CAAE,CACtE,CACa,CAAC;AAEjC,CAAC;AAEDvB,gBAAgB,CAACwB,WAAW,GAAG,kBAAkB;AAEjD,eAAexB,gBAAgB","ignoreList":[]}
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.className === 'no-emoji-convert') {
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 parentNode = span.parentNode;
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
- let cursorNodeOffset = cursorOffset;
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
- commonAncestorContainer = commonAncestorContainer.parentNode ?? commonAncestorContainer;
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.className === 'no-emoji-convert') {
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 nextSibling = span.nextSibling;
502
- const parentNode = span.parentNode;
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
- commonAncestorContainer = commonAncestorContainer.parentNode ?? commonAncestorContainer;
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":"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","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.8",
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": "e1aeb4ae0f155290fd5930dbd707ff6020aad0aa"
92
+ "gitHead": "ce93463945ac595b45885ca964c7b7eb41f98d37"
93
93
  }