@lobehub/editor 3.3.2 → 3.4.0

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.
Files changed (55) hide show
  1. package/es/editor-kernel/index.d.ts +1 -0
  2. package/es/editor-kernel/index.js +3 -1
  3. package/es/editor-kernel/kernel.js +1 -0
  4. package/es/editor-kernel/lexical/Lexical.dev.js +3052 -0
  5. package/es/editor-kernel/lexical/Lexical.dev.mjs +15365 -0
  6. package/es/editor-kernel/lexical/Lexical.js +7634 -0
  7. package/es/editor-kernel/lexical/Lexical.mjs +7258 -0
  8. package/es/editor-kernel/lexical/LexicalCommands.d.ts +175 -0
  9. package/es/editor-kernel/lexical/LexicalConstants.d.ts +54 -0
  10. package/es/editor-kernel/lexical/LexicalEditor.d.ts +672 -0
  11. package/es/editor-kernel/lexical/LexicalEditorState.d.ts +39 -0
  12. package/es/editor-kernel/lexical/LexicalEvents.d.ts +22 -0
  13. package/es/editor-kernel/lexical/LexicalGC.d.ts +23 -0
  14. package/es/editor-kernel/lexical/LexicalMutations.d.ts +12 -0
  15. package/es/editor-kernel/lexical/LexicalNode.d.ts +689 -0
  16. package/es/editor-kernel/lexical/LexicalNodeState.d.ts +569 -0
  17. package/es/editor-kernel/lexical/LexicalNormalization.d.ts +11 -0
  18. package/es/editor-kernel/lexical/LexicalReconciler.d.ts +28 -0
  19. package/es/editor-kernel/lexical/LexicalSelection.d.ts +368 -0
  20. package/es/editor-kernel/lexical/LexicalUpdateTags.d.ts +67 -0
  21. package/es/editor-kernel/lexical/LexicalUpdates.d.ts +72 -0
  22. package/es/editor-kernel/lexical/LexicalUtils.d.ts +492 -0
  23. package/es/editor-kernel/lexical/caret/LexicalCaret.d.ts +635 -0
  24. package/es/editor-kernel/lexical/caret/LexicalCaretUtils.d.ts +224 -0
  25. package/es/editor-kernel/lexical/extension-core/defineExtension.d.ts +126 -0
  26. package/es/editor-kernel/lexical/extension-core/index.d.ts +38 -0
  27. package/es/editor-kernel/lexical/extension-core/internal.d.ts +32 -0
  28. package/es/editor-kernel/lexical/extension-core/safeCast.d.ts +15 -0
  29. package/es/editor-kernel/lexical/extension-core/shallowMergeConfig.d.ts +20 -0
  30. package/es/editor-kernel/lexical/extension-core/types.d.ts +371 -0
  31. package/es/editor-kernel/lexical/index.d.ts +368 -0
  32. package/es/editor-kernel/lexical/nodes/ArtificialNode.d.ts +16 -0
  33. package/es/editor-kernel/lexical/nodes/LexicalDecoratorNode.d.ts +32 -0
  34. package/es/editor-kernel/lexical/nodes/LexicalElementNode.d.ts +235 -0
  35. package/es/editor-kernel/lexical/nodes/LexicalLineBreakNode.d.ts +30 -0
  36. package/es/editor-kernel/lexical/nodes/LexicalParagraphNode.d.ts +39 -0
  37. package/es/editor-kernel/lexical/nodes/LexicalRootNode.d.ts +35 -0
  38. package/es/editor-kernel/lexical/nodes/LexicalTabNode.d.ts +30 -0
  39. package/es/editor-kernel/lexical/nodes/LexicalTextNode.d.ts +311 -0
  40. package/es/plugins/common/data-source/json-data-source.js +29 -3
  41. package/es/plugins/common/react/ReactPlainText.js +9 -0
  42. package/es/plugins/common/utils/index.d.ts +2 -1
  43. package/es/plugins/common/utils/index.js +33 -0
  44. package/es/plugins/litexml/command/index.js +9 -1
  45. package/es/plugins/litexml/data-source/litexml-data-source.js +12 -2
  46. package/es/plugins/litexml/plugin/index.js +41 -3
  47. package/es/plugins/litexml/utils/index.d.ts +2 -1
  48. package/es/plugins/litexml/utils/index.js +7 -1
  49. package/es/plugins/markdown/data-source/markdown-data-source.js +6 -25
  50. package/es/plugins/markdown/data-source/markdown-writer-context.d.ts +5 -1
  51. package/es/plugins/markdown/data-source/markdown-writer-context.js +27 -2
  52. package/es/plugins/markdown/service/shortcut.d.ts +7 -0
  53. package/es/types/kernel.d.ts +4 -0
  54. package/package.json +8 -2
  55. package/scripts/patch-lexical.js +39 -0
@@ -0,0 +1,3052 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */'use strict';/**
8
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
9
+ *
10
+ * This source code is licensed under the MIT license found in the
11
+ * LICENSE file in the root directory of this source tree.
12
+ *
13
+ */ // Do not require this module directly! Use normal `invariant` calls.
14
+ var _Symbol$iterator,_Symbol$iterator2;function _get(){if(typeof Reflect!=="undefined"&&Reflect.get){_get=Reflect.get.bind();}else{_get=function _get(target,property,receiver){var base=_superPropBase(target,property);if(!base)return;var desc=Object.getOwnPropertyDescriptor(base,property);if(desc.get){return desc.get.call(arguments.length<3?target:receiver);}return desc.value;};}return _get.apply(this,arguments);}function _superPropBase(object,property){while(!Object.prototype.hasOwnProperty.call(object,property)){object=_getPrototypeOf(object);if(object===null)break;}return object;}function _toConsumableArray(arr){return _arrayWithoutHoles(arr)||_iterableToArray(arr)||_unsupportedIterableToArray(arr)||_nonIterableSpread();}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _iterableToArray(iter){if(typeof Symbol!=="undefined"&&iter[Symbol.iterator]!=null||iter["@@iterator"]!=null)return Array.from(iter);}function _arrayWithoutHoles(arr){if(Array.isArray(arr))return _arrayLikeToArray(arr);}function _inherits(subClass,superClass){if(typeof superClass!=="function"&&superClass!==null){throw new TypeError("Super expression must either be null or a function");}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,writable:true,configurable:true}});Object.defineProperty(subClass,"prototype",{writable:false});if(superClass)_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}function _createSuper(Derived){var hasNativeReflectConstruct=_isNativeReflectConstruct();return function _createSuperInternal(){var Super=_getPrototypeOf(Derived),result;if(hasNativeReflectConstruct){var NewTarget=_getPrototypeOf(this).constructor;result=Reflect.construct(Super,arguments,NewTarget);}else{result=Super.apply(this,arguments);}return _possibleConstructorReturn(this,result);};}function _possibleConstructorReturn(self,call){if(call&&(_typeof(call)==="object"||typeof call==="function")){return call;}else if(call!==void 0){throw new TypeError("Derived constructors may only return object or undefined");}return _assertThisInitialized(self);}function _assertThisInitialized(self){if(self===void 0){throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return self;}function _isNativeReflectConstruct(){if(typeof Reflect==="undefined"||!Reflect.construct)return false;if(Reflect.construct.sham)return false;if(typeof Proxy==="function")return true;try{Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}));return true;}catch(e){return false;}}function _getPrototypeOf(o){_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf.bind():function _getPrototypeOf(o){return o.__proto__||Object.getPrototypeOf(o);};return _getPrototypeOf(o);}function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o;}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o;},_typeof(o);}function ownKeys(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter(function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable;})),t.push.apply(t,o);}return t;}function _objectSpread(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?ownKeys(Object(t),!0).forEach(function(r){_defineProperty(e,r,t[r]);}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):ownKeys(Object(t)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r));});}return e;}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,_toPropertyKey(descriptor.key),descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}function _defineProperty(obj,key,value){key=_toPropertyKey(key);if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;}function _toPropertyKey(t){var i=_toPrimitive(t,"string");return"symbol"==_typeof(i)?i:String(i);}function _toPrimitive(t,r){if("object"!=_typeof(t)||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var i=e.call(t,r||"default");if("object"!=_typeof(i))return i;throw new TypeError("@@toPrimitive must return a primitive value.");}return("string"===r?String:Number)(t);}function _slicedToArray(arr,i){return _arrayWithHoles(arr)||_iterableToArrayLimit(arr,i)||_unsupportedIterableToArray(arr,i)||_nonIterableRest();}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _iterableToArrayLimit(r,l){var t=null==r?null:"undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(null!=t){var e,n,i,u,a=[],f=!0,o=!1;try{if(i=(t=t.call(r)).next,0===l){if(Object(t)!==t)return;f=!1;}else for(;!(f=(e=i.call(t)).done)&&(a.push(e.value),a.length!==l);f=!0);}catch(r){o=!0,n=r;}finally{try{if(!f&&null!=t.return&&(u=t.return(),Object(u)!==u))return;}finally{if(o)throw n;}}return a;}}function _arrayWithHoles(arr){if(Array.isArray(arr))return arr;}function _createForOfIteratorHelper(o,allowArrayLike){var it=typeof Symbol!=="undefined"&&o[Symbol.iterator]||o["@@iterator"];if(!it){if(Array.isArray(o)||(it=_unsupportedIterableToArray(o))||allowArrayLike&&o&&typeof o.length==="number"){if(it)o=it;var i=0;var F=function F(){};return{s:F,n:function n(){if(i>=o.length)return{done:true};return{done:false,value:o[i++]};},e:function e(_e2){throw _e2;},f:F};}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}var normalCompletion=true,didErr=false,err;return{s:function s(){it=it.call(o);},n:function n(){var step=it.next();normalCompletion=step.done;return step;},e:function e(_e3){didErr=true;err=_e3;},f:function f(){try{if(!normalCompletion&&it.return!=null)it.return();}finally{if(didErr)throw err;}}};}function _unsupportedIterableToArray(o,minLen){if(!o)return;if(typeof o==="string")return _arrayLikeToArray(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(o);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _arrayLikeToArray(o,minLen);}function _arrayLikeToArray(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++)arr2[i]=arr[i];return arr2;}function formatDevErrorMessage(message){throw new Error(message);}/**
15
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
16
+ *
17
+ * This source code is licensed under the MIT license found in the
18
+ * LICENSE file in the root directory of this source tree.
19
+ *
20
+ */var CAN_USE_DOM=typeof window!=='undefined'&&typeof window.document!=='undefined'&&typeof window.document.createElement!=='undefined';/**
21
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
22
+ *
23
+ * This source code is licensed under the MIT license found in the
24
+ * LICENSE file in the root directory of this source tree.
25
+ *
26
+ */var documentMode=CAN_USE_DOM&&'documentMode'in document?document.documentMode:null;var IS_APPLE=CAN_USE_DOM&&/Mac|iPod|iPhone|iPad/.test(navigator.platform);var IS_FIREFOX=CAN_USE_DOM&&/^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent);var CAN_USE_BEFORE_INPUT=CAN_USE_DOM&&'InputEvent'in window&&!documentMode?'getTargetRanges'in new window.InputEvent('input'):false;var IS_SAFARI=CAN_USE_DOM&&/Version\/[\d.]+.*Safari/.test(navigator.userAgent);var IS_IOS=CAN_USE_DOM&&/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream;var IS_ANDROID=CAN_USE_DOM&&/Android/.test(navigator.userAgent);// Keep these in case we need to use them in the future.
27
+ // export const IS_WINDOWS: boolean = CAN_USE_DOM && /Win/.test(navigator.platform);
28
+ var IS_CHROME=CAN_USE_DOM&&/^(?=.*Chrome).*/i.test(navigator.userAgent);// export const canUseTextInputEvent: boolean = CAN_USE_DOM && 'TextEvent' in window && !documentMode;
29
+ var IS_ANDROID_CHROME=CAN_USE_DOM&&IS_ANDROID&&IS_CHROME;var IS_APPLE_WEBKIT=CAN_USE_DOM&&/AppleWebKit\/[\d.]+/.test(navigator.userAgent)&&IS_APPLE&&!IS_CHROME;/**
30
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
31
+ *
32
+ * This source code is licensed under the MIT license found in the
33
+ * LICENSE file in the root directory of this source tree.
34
+ *
35
+ */function normalizeClassNames(){var rval=[];for(var _len=arguments.length,classNames=new Array(_len),_key=0;_key<_len;_key++){classNames[_key]=arguments[_key];}for(var _i=0,_classNames=classNames;_i<_classNames.length;_i++){var className=_classNames[_i];if(className&&typeof className==='string'){var _iterator=_createForOfIteratorHelper(className.matchAll(/\S+/g)),_step;try{for(_iterator.s();!(_step=_iterator.n()).done;){var _step$value=_slicedToArray(_step.value,1),s=_step$value[0];rval.push(s);}}catch(err){_iterator.e(err);}finally{_iterator.f();}}}return rval;}/**
36
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
37
+ *
38
+ * This source code is licensed under the MIT license found in the
39
+ * LICENSE file in the root directory of this source tree.
40
+ *
41
+ */ // DOM
42
+ var DOM_ELEMENT_TYPE=1;var DOM_TEXT_TYPE=3;var DOM_DOCUMENT_TYPE=9;var DOM_DOCUMENT_FRAGMENT_TYPE=11;// Reconciling
43
+ var NO_DIRTY_NODES=0;var HAS_DIRTY_NODES=1;var FULL_RECONCILE=2;// Text node modes
44
+ var IS_NORMAL=0;var IS_TOKEN=1;var IS_SEGMENTED=2;// IS_INERT = 3
45
+ // Text node formatting
46
+ var IS_BOLD=1;var IS_ITALIC=1<<1;var IS_STRIKETHROUGH=1<<2;var IS_UNDERLINE=1<<3;var IS_CODE=1<<4;var IS_SUBSCRIPT=1<<5;var IS_SUPERSCRIPT=1<<6;var IS_HIGHLIGHT=1<<7;var IS_LOWERCASE=1<<8;var IS_UPPERCASE=1<<9;var IS_CAPITALIZE=1<<10;var IS_ALL_FORMATTING=IS_BOLD|IS_ITALIC|IS_STRIKETHROUGH|IS_UNDERLINE|IS_CODE|IS_SUBSCRIPT|IS_SUPERSCRIPT|IS_HIGHLIGHT|IS_LOWERCASE|IS_UPPERCASE|IS_CAPITALIZE;// Text node details
47
+ var IS_DIRECTIONLESS=1;var IS_UNMERGEABLE=1<<1;// Element node formatting
48
+ var IS_ALIGN_LEFT=1;var IS_ALIGN_CENTER=2;var IS_ALIGN_RIGHT=3;var IS_ALIGN_JUSTIFY=4;var IS_ALIGN_START=5;var IS_ALIGN_END=6;// Reconciliation
49
+ var NON_BREAKING_SPACE="\xA0";var ZERO_WIDTH_SPACE="\u200B";// For iOS/Safari we use a non breaking space, otherwise the cursor appears
50
+ // overlapping the composed text.
51
+ var COMPOSITION_SUFFIX=IS_SAFARI||IS_IOS||IS_APPLE_WEBKIT?NON_BREAKING_SPACE:ZERO_WIDTH_SPACE;var DOUBLE_LINE_BREAK='\n\n';// For FF, we need to use a non-breaking space, or it gets composition
52
+ // in a stuck state.
53
+ var COMPOSITION_START_CHAR=IS_FIREFOX?NON_BREAKING_SPACE:COMPOSITION_SUFFIX;var RTL="\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC";var LTR="A-Za-z\xC0-\xD6\xD8-\xF6"+"\xF8-\u02B8\u0300-\u0590\u0800-\u1FFF\u200E\u2C00-\uFB1C"+"\uFE00-\uFE6F\uFEFD-\uFFFF";// eslint-disable-next-line no-misleading-character-class
54
+ var RTL_REGEX=new RegExp('^[^'+LTR+']*['+RTL+']');// eslint-disable-next-line no-misleading-character-class
55
+ var LTR_REGEX=new RegExp('^[^'+RTL+']*['+LTR+']');var TEXT_TYPE_TO_FORMAT={bold:IS_BOLD,capitalize:IS_CAPITALIZE,code:IS_CODE,highlight:IS_HIGHLIGHT,italic:IS_ITALIC,lowercase:IS_LOWERCASE,strikethrough:IS_STRIKETHROUGH,subscript:IS_SUBSCRIPT,superscript:IS_SUPERSCRIPT,underline:IS_UNDERLINE,uppercase:IS_UPPERCASE};var DETAIL_TYPE_TO_DETAIL={directionless:IS_DIRECTIONLESS,unmergeable:IS_UNMERGEABLE};var ELEMENT_TYPE_TO_FORMAT={center:IS_ALIGN_CENTER,end:IS_ALIGN_END,justify:IS_ALIGN_JUSTIFY,left:IS_ALIGN_LEFT,right:IS_ALIGN_RIGHT,start:IS_ALIGN_START};var ELEMENT_FORMAT_TO_TYPE=_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({},IS_ALIGN_CENTER,'center'),IS_ALIGN_END,'end'),IS_ALIGN_JUSTIFY,'justify'),IS_ALIGN_LEFT,'left'),IS_ALIGN_RIGHT,'right'),IS_ALIGN_START,'start');var TEXT_MODE_TO_TYPE={normal:IS_NORMAL,segmented:IS_SEGMENTED,token:IS_TOKEN};var TEXT_TYPE_TO_MODE=_defineProperty(_defineProperty(_defineProperty({},IS_NORMAL,'normal'),IS_SEGMENTED,'segmented'),IS_TOKEN,'token');var NODE_STATE_KEY='$';var PROTOTYPE_CONFIG_METHOD='$config';/**
56
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
57
+ *
58
+ * This source code is licensed under the MIT license found in the
59
+ * LICENSE file in the root directory of this source tree.
60
+ *
61
+ */function $garbageCollectDetachedDecorators(editor,pendingEditorState){var currentDecorators=editor._decorators;var pendingDecorators=editor._pendingDecorators;var decorators=pendingDecorators||currentDecorators;var nodeMap=pendingEditorState._nodeMap;var key;for(key in decorators){if(!nodeMap.has(key)){if(decorators===currentDecorators){decorators=cloneDecorators(editor);}delete decorators[key];}}}function $garbageCollectDetachedDeepChildNodes(node,parentKey,prevNodeMap,nodeMap,nodeMapDelete,dirtyNodes){var child=node.getFirstChild();while(child!==null){var childKey=child.__key;// TODO Revise condition below, redundant? LexicalNode already cleans up children when moving Nodes
62
+ if(child.__parent===parentKey){if($isElementNode(child)){$garbageCollectDetachedDeepChildNodes(child,childKey,prevNodeMap,nodeMap,nodeMapDelete,dirtyNodes);}// If we have created a node and it was dereferenced, then also
63
+ // remove it from out dirty nodes Set.
64
+ if(!prevNodeMap.has(childKey)){dirtyNodes.delete(childKey);}nodeMapDelete.push(childKey);}child=child.getNextSibling();}}function $garbageCollectDetachedNodes(prevEditorState,editorState,dirtyLeaves,dirtyElements){var prevNodeMap=prevEditorState._nodeMap;var nodeMap=editorState._nodeMap;// Store dirtyElements in a queue for later deletion; deleting dirty subtrees too early will
65
+ // hinder accessing .__next on child nodes
66
+ var nodeMapDelete=[];var _iterator2=_createForOfIteratorHelper(dirtyElements),_step2;try{for(_iterator2.s();!(_step2=_iterator2.n()).done;){var _step2$value=_slicedToArray(_step2.value,1),_nodeKey=_step2$value[0];var node=nodeMap.get(_nodeKey);if(node!==undefined){// Garbage collect node and its children if they exist
67
+ if(!node.isAttached()){if($isElementNode(node)){$garbageCollectDetachedDeepChildNodes(node,_nodeKey,prevNodeMap,nodeMap,nodeMapDelete,dirtyElements);}// If we have created a node and it was dereferenced, then also
68
+ // remove it from out dirty nodes Set.
69
+ if(!prevNodeMap.has(_nodeKey)){dirtyElements.delete(_nodeKey);}nodeMapDelete.push(_nodeKey);}}}}catch(err){_iterator2.e(err);}finally{_iterator2.f();}for(var _i2=0,_nodeMapDelete=nodeMapDelete;_i2<_nodeMapDelete.length;_i2++){var nodeKey=_nodeMapDelete[_i2];nodeMap.delete(nodeKey);}var _iterator3=_createForOfIteratorHelper(dirtyLeaves),_step3;try{for(_iterator3.s();!(_step3=_iterator3.n()).done;){var _nodeKey2=_step3.value;var _node2=nodeMap.get(_nodeKey2);if(_node2!==undefined&&!_node2.isAttached()){if(!prevNodeMap.has(_nodeKey2)){dirtyLeaves.delete(_nodeKey2);}nodeMap.delete(_nodeKey2);}}}catch(err){_iterator3.e(err);}finally{_iterator3.f();}}/**
70
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
71
+ *
72
+ * This source code is licensed under the MIT license found in the
73
+ * LICENSE file in the root directory of this source tree.
74
+ *
75
+ */ // The time between a text entry event and the mutation observer firing.
76
+ var TEXT_MUTATION_VARIANCE=100;var isProcessingMutations=false;var lastTextEntryTimeStamp=0;function getIsProcessingMutations(){return isProcessingMutations;}function updateTimeStamp(event){lastTextEntryTimeStamp=event.timeStamp;}function initTextEntryListener(editor){if(lastTextEntryTimeStamp===0){getWindow(editor).addEventListener('textInput',updateTimeStamp,true);}}function isManagedLineBreak(dom,target,editor){var isBR=dom.nodeName==='BR';var lexicalLineBreak=target.__lexicalLineBreak;return lexicalLineBreak&&(dom===lexicalLineBreak||isBR&&dom.previousSibling===lexicalLineBreak)||isBR&&getNodeKeyFromDOMNode(dom,editor)!==undefined;}function getLastSelection(editor){return editor.getEditorState().read(function(){var selection=$getSelection();return selection!==null?selection.clone():null;});}function $handleTextMutation(target,node,editor){var domSelection=getDOMSelection(getWindow(editor));var anchorOffset=null;var focusOffset=null;if(domSelection!==null&&domSelection.anchorNode===target){anchorOffset=domSelection.anchorOffset;focusOffset=domSelection.focusOffset;}var text=target.nodeValue;if(text!==null){$updateTextNodeFromDOMContent(node,text,anchorOffset,focusOffset,false);}}function shouldUpdateTextNodeFromMutation(selection,targetDOM,targetNode){if($isRangeSelection(selection)){var anchorNode=selection.anchor.getNode();if(anchorNode.is(targetNode)&&selection.format!==anchorNode.getFormat()){return false;}}return isDOMTextNode(targetDOM)&&targetNode.isAttached();}function $getNearestManagedNodePairFromDOMNode(startingDOM,editor,editorState,rootElement){for(var dom=startingDOM;dom&&!isDOMUnmanaged(dom);dom=getParentElement(dom)){var key=getNodeKeyFromDOMNode(dom,editor);if(key!==undefined){var node=$getNodeByKey(key,editorState);if(node){// All decorator nodes are unmanaged
77
+ return $isDecoratorNode(node)||!isHTMLElement(dom)?undefined:[dom,node];}}else if(dom===rootElement){return[rootElement,internalGetRoot(editorState)];}}}function flushMutations(editor,mutations,observer){isProcessingMutations=true;var shouldFlushTextMutations=performance.now()-lastTextEntryTimeStamp>TEXT_MUTATION_VARIANCE;try{updateEditorSync(editor,function(){var selection=$getSelection()||getLastSelection(editor);var badDOMTargets=new Map();var rootElement=editor.getRootElement();// We use the current editor state, as that reflects what is
78
+ // actually "on screen".
79
+ var currentEditorState=editor._editorState;var blockCursorElement=editor._blockCursorElement;var shouldRevertSelection=false;var possibleTextForFirefoxPaste='';for(var i=0;i<mutations.length;i++){var mutation=mutations[i];var type=mutation.type;var targetDOM=mutation.target;var pair=$getNearestManagedNodePairFromDOMNode(targetDOM,editor,currentEditorState,rootElement);if(!pair){continue;}var _pair=_slicedToArray(pair,2),nodeDOM=_pair[0],targetNode=_pair[1];if(type==='characterData'){// Text mutations are deferred and passed to mutation listeners to be
80
+ // processed outside of the Lexical engine.
81
+ if(// TODO there is an edge case here if a mutation happens too quickly
82
+ // after text input, it may never be handled since we do not
83
+ // track the ignored mutations in any way
84
+ shouldFlushTextMutations&&$isTextNode(targetNode)&&isDOMTextNode(targetDOM)&&shouldUpdateTextNodeFromMutation(selection,targetDOM,targetNode)){$handleTextMutation(targetDOM,targetNode,editor);}}else if(type==='childList'){shouldRevertSelection=true;// We attempt to "undo" any changes that have occurred outside
85
+ // of Lexical. We want Lexical's editor state to be source of truth.
86
+ // To the user, these will look like no-ops.
87
+ var addedDOMs=mutation.addedNodes;for(var s=0;s<addedDOMs.length;s++){var addedDOM=addedDOMs[s];var node=$getNodeFromDOMNode(addedDOM);var parentDOM=addedDOM.parentNode;if(parentDOM!=null&&addedDOM!==blockCursorElement&&node===null&&!isManagedLineBreak(addedDOM,parentDOM,editor)){if(IS_FIREFOX){var possibleText=(isHTMLElement(addedDOM)?addedDOM.innerText:null)||addedDOM.nodeValue;if(possibleText){possibleTextForFirefoxPaste+=possibleText;}}parentDOM.removeChild(addedDOM);}}var removedDOMs=mutation.removedNodes;var removedDOMsLength=removedDOMs.length;if(removedDOMsLength>0){var unremovedBRs=0;for(var _s=0;_s<removedDOMsLength;_s++){var removedDOM=removedDOMs[_s];if(isManagedLineBreak(removedDOM,targetDOM,editor)||blockCursorElement===removedDOM){targetDOM.appendChild(removedDOM);unremovedBRs++;}}if(removedDOMsLength!==unremovedBRs){badDOMTargets.set(nodeDOM,targetNode);}}}}// Now we process each of the unique target nodes, attempting
88
+ // to restore their contents back to the source of truth, which
89
+ // is Lexical's "current" editor state. This is basically like
90
+ // an internal revert on the DOM.
91
+ if(badDOMTargets.size>0){var _iterator4=_createForOfIteratorHelper(badDOMTargets),_step4;try{for(_iterator4.s();!(_step4=_iterator4.n()).done;){var _step4$value=_slicedToArray(_step4.value,2),_nodeDOM=_step4$value[0],_targetNode=_step4$value[1];_targetNode.reconcileObservedMutation(_nodeDOM,editor);}}catch(err){_iterator4.e(err);}finally{_iterator4.f();}}// Capture all the mutations made during this function. This
92
+ // also prevents us having to process them on the next cycle
93
+ // of onMutation, as these mutations were made by us.
94
+ var records=observer.takeRecords();// Check for any random auto-added <br> elements, and remove them.
95
+ // These get added by the browser when we undo the above mutations
96
+ // and this can lead to a broken UI.
97
+ if(records.length>0){for(var _i3=0;_i3<records.length;_i3++){var record=records[_i3];var addedNodes=record.addedNodes;var target=record.target;for(var _s2=0;_s2<addedNodes.length;_s2++){var _addedDOM=addedNodes[_s2];var _parentDOM=_addedDOM.parentNode;if(_parentDOM!=null&&_addedDOM.nodeName==='BR'&&!isManagedLineBreak(_addedDOM,target,editor)){_parentDOM.removeChild(_addedDOM);}}}// Clear any of those removal mutations
98
+ observer.takeRecords();}if(selection!==null){if(shouldRevertSelection){$setSelection(selection);}if(IS_FIREFOX&&isFirefoxClipboardEvents(editor)){selection.insertRawText(possibleTextForFirefoxPaste);}}});}finally{isProcessingMutations=false;}}function flushRootMutations(editor){var observer=editor._observer;if(observer!==null){var mutations=observer.takeRecords();flushMutations(editor,mutations,observer);}}function initMutationObserver(editor){initTextEntryListener(editor);editor._observer=new MutationObserver(function(mutations,observer){flushMutations(editor,mutations,observer);});}/**
99
+ * Get the value type (V) from a StateConfig
100
+ */ /**
101
+ * Get the key type (K) from a StateConfig
102
+ */ /**
103
+ * A value type, or an updater for that value type. For use with
104
+ * {@link $setState} or any user-defined wrappers around it.
105
+ */ /**
106
+ * A type alias to make it easier to define setter methods on your node class
107
+ *
108
+ * @example
109
+ * ```ts
110
+ * const fooState = createState("foo", { parse: ... });
111
+ * class MyClass extends TextNode {
112
+ * // ...
113
+ * setFoo(valueOrUpdater: StateValueOrUpdater<typeof fooState>): this {
114
+ * return $setState(this, fooState, valueOrUpdater);
115
+ * }
116
+ * }
117
+ * ```
118
+ */ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-enable @typescript-eslint/no-explicit-any */ /**
119
+ * The NodeState JSON produced by this LexicalNode
120
+ */ /**
121
+ * Configure a value to be used with StateConfig.
122
+ *
123
+ * The value type should be inferred from the definition of parse.
124
+ *
125
+ * If the value type is not JSON serializable, then unparse must also be provided.
126
+ *
127
+ * Values should be treated as immutable, much like React.useState. Mutating
128
+ * stored values directly will cause unpredictable behavior, is not supported,
129
+ * and may trigger errors in the future.
130
+ *
131
+ * @example
132
+ * ```ts
133
+ * const numberOrNullState = createState('numberOrNull', {parse: (v) => typeof v === 'number' ? v : null});
134
+ * // ^? State<'numberOrNull', StateValueConfig<number | null>>
135
+ * const numberState = createState('number', {parse: (v) => typeof v === 'number' ? v : 0});
136
+ * // ^? State<'number', StateValueConfig<number>>
137
+ * ```
138
+ *
139
+ * Only the parse option is required, it is generally not useful to
140
+ * override `unparse` or `isEqual`. However, if you are using
141
+ * non-primitive types such as Array, Object, Date, or something
142
+ * more exotic then you would want to override this. In these
143
+ * cases you might want to reach for third party libraries.
144
+ *
145
+ * @example
146
+ * ```ts
147
+ * const isoDateState = createState('isoDate', {
148
+ * parse: (v): null | Date => {
149
+ * const date = typeof v === 'string' ? new Date(v) : null;
150
+ * return date && !isNaN(date.valueOf()) ? date : null;
151
+ * }
152
+ * isEqual: (a, b) => a === b || (a && b && a.valueOf() === b.valueOf()),
153
+ * unparse: (v) => v && v.toString()
154
+ * });
155
+ * ```
156
+ *
157
+ * You may find it easier to write a parse function using libraries like
158
+ * zod, valibot, ajv, Effect, TypeBox, etc. perhaps with a wrapper function.
159
+ */ /**
160
+ * The return value of {@link createState}, for use with
161
+ * {@link $getState} and {@link $setState}.
162
+ */var StateConfig=/*#__PURE__*/_createClass(function StateConfig(key,stateValueConfig){_classCallCheck(this,StateConfig);/** The string key used when serializing this state to JSON */_defineProperty(this,"key",void 0);/** The parse function from the StateValueConfig passed to createState */_defineProperty(this,"parse",void 0);/**
163
+ * The unparse function from the StateValueConfig passed to createState,
164
+ * with a default that is simply a pass-through that assumes the value is
165
+ * JSON serializable.
166
+ */_defineProperty(this,"unparse",void 0);/**
167
+ * An equality function from the StateValueConfig, with a default of
168
+ * Object.is.
169
+ */_defineProperty(this,"isEqual",void 0);/**
170
+ * The result of `stateValueConfig.parse(undefined)`, which is computed only
171
+ * once and used as the default value. When the current value `isEqual` to
172
+ * the `defaultValue`, it will not be serialized to JSON.
173
+ */_defineProperty(this,"defaultValue",void 0);this.key=key;this.parse=stateValueConfig.parse.bind(stateValueConfig);this.unparse=(stateValueConfig.unparse||coerceToJSON).bind(stateValueConfig);this.isEqual=(stateValueConfig.isEqual||Object.is).bind(stateValueConfig);this.defaultValue=this.parse(undefined);});/**
174
+ * For advanced use cases, using this type is not recommended unless
175
+ * it is required (due to TypeScript's lack of features like
176
+ * higher-kinded types).
177
+ *
178
+ * A {@link StateConfig} type with any key and any value that can be
179
+ * used in situations where the key and value type can not be known,
180
+ * such as in a generic constraint when working with a collection of
181
+ * StateConfig.
182
+ *
183
+ * {@link StateConfigKey} and {@link StateConfigValue} will be
184
+ * useful when this is used as a generic constraint.
185
+ */ // eslint-disable-next-line @typescript-eslint/no-explicit-any
186
+ /**
187
+ * Create a StateConfig for the given string key and StateValueConfig.
188
+ *
189
+ * The key must be locally unique. In dev you will get a key collision error
190
+ * when you use two separate StateConfig on the same node with the same key.
191
+ *
192
+ * The returned StateConfig value should be used with {@link $getState} and
193
+ * {@link $setState}.
194
+ *
195
+ * @param key The key to use
196
+ * @param valueConfig Configuration for the value type
197
+ * @returns a StateConfig
198
+ *
199
+ * @__NO_SIDE_EFFECTS__
200
+ */function createState(key,valueConfig){return new StateConfig(key,valueConfig);}/**
201
+ * The accessor for working with node state. This will read the value for the
202
+ * state on the given node, and will return `stateConfig.defaultValue` if the
203
+ * state has never been set on this node.
204
+ *
205
+ * The `version` parameter is optional and should generally be `'latest'`,
206
+ * consistent with the behavior of other node methods and functions,
207
+ * but for certain use cases such as `updateDOM` you may have a need to
208
+ * use `'direct'` to read the state from a previous version of the node.
209
+ *
210
+ * For very advanced use cases, you can expect that 'direct' does not
211
+ * require an editor state, just like directly accessing other properties
212
+ * of a node without an accessor (e.g. `textNode.__text`).
213
+ *
214
+ * @param node Any LexicalNode
215
+ * @param stateConfig The configuration of the state to read
216
+ * @param version The default value 'latest' will read the latest version of the node state, 'direct' will read the version that is stored on this LexicalNode which not reflect the version used in the current editor state
217
+ * @returns The current value from the state, or the default value provided by the configuration.
218
+ */function $getState(node,stateConfig){var version=arguments.length>2&&arguments[2]!==undefined?arguments[2]:'latest';var latestOrDirectNode=version==='latest'?node.getLatest():node;var state=latestOrDirectNode.__state;if(state){$checkCollision(node,stateConfig,state);return state.getValue(stateConfig);}return stateConfig.defaultValue;}/**
219
+ * Given two versions of a node and a stateConfig, compare their state values
220
+ * using `$getState(nodeVersion, stateConfig, 'direct')`.
221
+ * If the values are equal according to `stateConfig.isEqual`, return `null`,
222
+ * otherwise return `[value, prevValue]`.
223
+ *
224
+ * This is useful for implementing updateDOM. Note that the `'direct'`
225
+ * version argument is used for both nodes.
226
+ *
227
+ * @param node Any LexicalNode
228
+ * @param prevNode A previous version of node
229
+ * @param stateConfig The configuration of the state to read
230
+ * @returns `[value, prevValue]` if changed, otherwise `null`
231
+ */function $getStateChange(node,prevNode,stateConfig){var value=$getState(node,stateConfig,'direct');var prevValue=$getState(prevNode,stateConfig,'direct');return stateConfig.isEqual(value,prevValue)?null:[value,prevValue];}/**
232
+ * Set the state defined by stateConfig on node. Like with `React.useState`
233
+ * you may directly specify the value or use an updater function that will
234
+ * be called with the previous value of the state on that node (which will
235
+ * be the `stateConfig.defaultValue` if not set).
236
+ *
237
+ * When an updater function is used, the node will only be marked dirty if
238
+ * `stateConfig.isEqual(prevValue, value)` is false.
239
+ *
240
+ * @example
241
+ * ```ts
242
+ * const toggle = createState('toggle', {parse: Boolean});
243
+ * // set it direction
244
+ * $setState(node, counterState, true);
245
+ * // use an updater
246
+ * $setState(node, counterState, (prev) => !prev);
247
+ * ```
248
+ *
249
+ * @param node The LexicalNode to set the state on
250
+ * @param stateConfig The configuration for this state
251
+ * @param valueOrUpdater The value or updater function
252
+ * @returns node
253
+ */function $setState(node,stateConfig,valueOrUpdater){errorOnReadOnly();var value;if(typeof valueOrUpdater==='function'){var latest=node.getLatest();var prevValue=$getState(latest,stateConfig);value=valueOrUpdater(prevValue);if(stateConfig.isEqual(prevValue,value)){return latest;}}else{value=valueOrUpdater;}var writable=node.getWritable();var state=$getWritableNodeState(writable);$checkCollision(node,stateConfig,state);state.updateFromKnown(stateConfig,value);return writable;}/**
254
+ * @internal
255
+ *
256
+ * Register the config to this node's sharedConfigMap and throw an exception in
257
+ * `true` when a collision is detected.
258
+ */function $checkCollision(node,stateConfig,state){{var collision=state.sharedNodeState.sharedConfigMap.get(stateConfig.key);if(collision!==undefined&&collision!==stateConfig){{formatDevErrorMessage("$setState: State key collision ".concat(JSON.stringify(stateConfig.key)," detected in ").concat(node.constructor.name," node with type ").concat(node.getType()," and key ").concat(node.getKey(),". Only one StateConfig with a given key should be used on a node."));}}}}/**
259
+ * @internal
260
+ *
261
+ * Opaque state to be stored on the editor's RegisterNode for use by NodeState
262
+ */ /**
263
+ * @internal
264
+ *
265
+ * Create the state to store on RegisteredNode
266
+ */function createSharedNodeState(nodeConfig){var sharedConfigMap=new Map();var flatKeys=new Set();for(var klass=typeof nodeConfig==='function'?nodeConfig:nodeConfig.replace;klass.prototype&&klass.prototype.getType!==undefined;klass=Object.getPrototypeOf(klass)){var _getStaticNodeConfig=getStaticNodeConfig(klass),ownNodeConfig=_getStaticNodeConfig.ownNodeConfig;if(ownNodeConfig&&ownNodeConfig.stateConfigs){var _iterator5=_createForOfIteratorHelper(ownNodeConfig.stateConfigs),_step5;try{for(_iterator5.s();!(_step5=_iterator5.n()).done;){var requiredStateConfig=_step5.value;var stateConfig=void 0;if('stateConfig'in requiredStateConfig){stateConfig=requiredStateConfig.stateConfig;if(requiredStateConfig.flat){flatKeys.add(stateConfig.key);}}else{stateConfig=requiredStateConfig;}sharedConfigMap.set(stateConfig.key,stateConfig);}}catch(err){_iterator5.e(err);}finally{_iterator5.f();}}}return{flatKeys:flatKeys,sharedConfigMap:sharedConfigMap};}/**
267
+ * @internal
268
+ *
269
+ * A Map of string keys to state configurations to be shared across nodes
270
+ * and/or node versions.
271
+ */ /**
272
+ * @internal
273
+ */var NodeState=/*#__PURE__*/function(){/**
274
+ * @internal
275
+ */function NodeState(node,sharedNodeState){var unknownState=arguments.length>2&&arguments[2]!==undefined?arguments[2]:undefined;var knownState=arguments.length>3&&arguments[3]!==undefined?arguments[3]:new Map();var size=arguments.length>4&&arguments[4]!==undefined?arguments[4]:undefined;_classCallCheck(this,NodeState);/**
276
+ * @internal
277
+ *
278
+ * Track the (versioned) node that this NodeState was created for, to
279
+ * facilitate copy-on-write for NodeState. When a LexicalNode is cloned,
280
+ * it will *reference* the NodeState from its prevNode. From the nextNode
281
+ * you can continue to read state without copying, but the first $setState
282
+ * will trigger a copy of the prevNode's NodeState with the node property
283
+ * updated.
284
+ */_defineProperty(this,"node",void 0);/**
285
+ * @internal
286
+ *
287
+ * State that has already been parsed in a get state, so it is safe. (can be returned with
288
+ * just a cast since the proof was given before).
289
+ *
290
+ * Note that it uses StateConfig, so in addition to (1) the CURRENT VALUE, it has access to
291
+ * (2) the State key (3) the DEFAULT VALUE and (4) the PARSE FUNCTION
292
+ */_defineProperty(this,"knownState",void 0);/**
293
+ * @internal
294
+ *
295
+ * A copy of serializedNode[NODE_STATE_KEY] that is made when JSON is
296
+ * imported but has not been parsed yet.
297
+ *
298
+ * It stays here until a get state requires us to parse it, and since we
299
+ * then know the value is safe we move it to knownState.
300
+ *
301
+ * Note that since only string keys are used here, we can only allow this
302
+ * state to pass-through on export or on the next version since there is
303
+ * no known value configuration. This pass-through is to support scenarios
304
+ * where multiple versions of the editor code are working in parallel so
305
+ * an old version of your code doesnt erase metadata that was
306
+ * set by a newer version of your code.
307
+ */_defineProperty(this,"unknownState",void 0);/**
308
+ * @internal
309
+ *
310
+ * This sharedNodeState is preserved across all instances of a given
311
+ * node type in an editor and remains writable. It is how keys are resolved
312
+ * to configuration.
313
+ */_defineProperty(this,"sharedNodeState",void 0);/**
314
+ * @internal
315
+ *
316
+ * The count of known or unknown keys in this state, ignoring the
317
+ * intersection between the two sets.
318
+ */_defineProperty(this,"size",void 0);this.node=node;this.sharedNodeState=sharedNodeState;this.unknownState=unknownState;this.knownState=knownState;var sharedConfigMap=this.sharedNodeState.sharedConfigMap;var computedSize=size!==undefined?size:computeSize(sharedConfigMap,unknownState,knownState);{if(!(size===undefined||computedSize===size)){formatDevErrorMessage("NodeState: size != computedSize (".concat(String(size)," != ").concat(String(computedSize),")"));}var _iterator6=_createForOfIteratorHelper(knownState.keys()),_step6;try{for(_iterator6.s();!(_step6=_iterator6.n()).done;){var stateConfig=_step6.value;if(!sharedConfigMap.has(stateConfig.key)){formatDevErrorMessage("NodeState: sharedConfigMap missing knownState key ".concat(stateConfig.key));}}}catch(err){_iterator6.e(err);}finally{_iterator6.f();}}this.size=computedSize;}/**
319
+ * @internal
320
+ *
321
+ * Get the value from knownState, or parse it from unknownState
322
+ * if it contains the given key.
323
+ *
324
+ * Updates the sharedConfigMap when no known state is found.
325
+ * Updates unknownState and knownState when an unknownState is parsed.
326
+ */_createClass(NodeState,[{key:"getValue",value:function getValue(stateConfig){var known=this.knownState.get(stateConfig);if(known!==undefined){return known;}this.sharedNodeState.sharedConfigMap.set(stateConfig.key,stateConfig);var parsed=stateConfig.defaultValue;if(this.unknownState&&stateConfig.key in this.unknownState){var jsonValue=this.unknownState[stateConfig.key];if(jsonValue!==undefined){parsed=stateConfig.parse(jsonValue);}// Only update if the key was unknown
327
+ this.updateFromKnown(stateConfig,parsed);}return parsed;}/**
328
+ * @internal
329
+ *
330
+ * Used only for advanced use cases, such as collab. The intent here is to
331
+ * allow you to diff states with a more stable interface than the properties
332
+ * of this class.
333
+ */},{key:"getInternalState",value:function getInternalState(){return[this.unknownState,this.knownState];}/**
334
+ * Encode this NodeState to JSON in the format that its node expects.
335
+ * This returns `{[NODE_STATE_KEY]?: UnknownStateRecord}` rather than
336
+ * `UnknownStateRecord | undefined` so that we can support flattening
337
+ * specific entries in the future when nodes can declare what
338
+ * their required StateConfigs are.
339
+ */},{key:"toJSON",value:function toJSON(){var state=_objectSpread({},this.unknownState);var flatState={};var _iterator7=_createForOfIteratorHelper(this.knownState),_step7;try{for(_iterator7.s();!(_step7=_iterator7.n()).done;){var _step7$value=_slicedToArray(_step7.value,2),stateConfig=_step7$value[0],v=_step7$value[1];if(stateConfig.isEqual(v,stateConfig.defaultValue)){delete state[stateConfig.key];}else{state[stateConfig.key]=stateConfig.unparse(v);}}}catch(err){_iterator7.e(err);}finally{_iterator7.f();}var _iterator8=_createForOfIteratorHelper(this.sharedNodeState.flatKeys),_step8;try{for(_iterator8.s();!(_step8=_iterator8.n()).done;){var key=_step8.value;if(key in state){flatState[key]=state[key];delete state[key];}}}catch(err){_iterator8.e(err);}finally{_iterator8.f();}if(undefinedIfEmpty(state)){flatState[NODE_STATE_KEY]=state;}return flatState;}/**
340
+ * @internal
341
+ *
342
+ * A NodeState is writable when the node to update matches
343
+ * the node associated with the NodeState. This basically
344
+ * mirrors how the EditorState NodeMap works, but in a
345
+ * bottom-up organization rather than a top-down organization.
346
+ *
347
+ * This allows us to implement the same "copy on write"
348
+ * pattern for state, without having the state version
349
+ * update every time the node version changes (e.g. when
350
+ * its parent or siblings change).
351
+ *
352
+ * @param node The node to associate with the state
353
+ * @returns The next writable state
354
+ */},{key:"getWritable",value:function getWritable(node){if(this.node===node){return this;}var sharedNodeState=this.sharedNodeState,unknownState=this.unknownState;var nextKnownState=new Map(this.knownState);return new NodeState(node,sharedNodeState,parseAndPruneNextUnknownState(sharedNodeState.sharedConfigMap,nextKnownState,unknownState),nextKnownState,this.size);}/** @internal */},{key:"updateFromKnown",value:function updateFromKnown(stateConfig,value){var key=stateConfig.key;this.sharedNodeState.sharedConfigMap.set(key,stateConfig);var knownState=this.knownState,unknownState=this.unknownState;if(!(knownState.has(stateConfig)||unknownState&&key in unknownState)){if(unknownState){delete unknownState[key];this.unknownState=undefinedIfEmpty(unknownState);}this.size++;}knownState.set(stateConfig,value);}/**
355
+ * @internal
356
+ *
357
+ * This is intended for advanced use cases only, such
358
+ * as collab or dev tools.
359
+ *
360
+ * Update a single key value pair from unknown state,
361
+ * parsing it if the key is known to this node. This is
362
+ * basically like updateFromJSON, but the effect is
363
+ * isolated to a single entry.
364
+ *
365
+ * @param k The string key from an UnknownStateRecord
366
+ * @param v The unknown value from an UnknownStateRecord
367
+ */},{key:"updateFromUnknown",value:function updateFromUnknown(k,v){var stateConfig=this.sharedNodeState.sharedConfigMap.get(k);if(stateConfig){this.updateFromKnown(stateConfig,stateConfig.parse(v));}else{this.unknownState=this.unknownState||{};if(!(k in this.unknownState)){this.size++;}this.unknownState[k]=v;}}/**
368
+ * @internal
369
+ *
370
+ * Reset all existing state to default or empty values,
371
+ * and perform any updates from the given unknownState.
372
+ *
373
+ * This is used when initializing a node's state from JSON,
374
+ * or when resetting a node's state from JSON.
375
+ *
376
+ * @param unknownState The new state in serialized form
377
+ */},{key:"updateFromJSON",value:function updateFromJSON(unknownState){var knownState=this.knownState;// Reset all known state to defaults
378
+ var _iterator9=_createForOfIteratorHelper(knownState.keys()),_step9;try{for(_iterator9.s();!(_step9=_iterator9.n()).done;){var stateConfig=_step9.value;knownState.set(stateConfig,stateConfig.defaultValue);}// Since we are resetting all state to this new record,
379
+ // the size starts at the number of known keys
380
+ // and will be updated as we traverse the new state
381
+ }catch(err){_iterator9.e(err);}finally{_iterator9.f();}this.size=knownState.size;this.unknownState=undefined;if(unknownState){for(var _i4=0,_Object$entries=Object.entries(unknownState);_i4<_Object$entries.length;_i4++){var _Object$entries$_i=_slicedToArray(_Object$entries[_i4],2),k=_Object$entries$_i[0],v=_Object$entries$_i[1];this.updateFromUnknown(k,v);}}}}]);return NodeState;}();/**
382
+ * @internal
383
+ *
384
+ * Only for direct use in very advanced integrations, such as lexical-yjs.
385
+ * Typically you would only use {@link createState}, {@link $getState}, and
386
+ * {@link $setState}. This is effectively the preamble for {@link $setState}.
387
+ */function $getWritableNodeState(node){var writable=node.getWritable();var state=writable.__state?writable.__state.getWritable(writable):new NodeState(writable,$getSharedNodeState(writable));writable.__state=state;return state;}/**
388
+ * @internal
389
+ *
390
+ * Get the SharedNodeState for a node on this editor
391
+ */function $getSharedNodeState(node){return node.__state?node.__state.sharedNodeState:getRegisteredNodeOrThrow($getEditor(),node.getType()).sharedNodeState;}/**
392
+ * @internal
393
+ *
394
+ * This is used to implement LexicalNode.updateFromJSON and is
395
+ * not intended to be exported from the package.
396
+ *
397
+ * @param node any LexicalNode
398
+ * @param unknownState undefined or a serialized State
399
+ * @returns A writable version of node, with the state set.
400
+ */function $updateStateFromJSON(node,serialized){var writable=node.getWritable();var unknownState=serialized[NODE_STATE_KEY];var parseState=unknownState;var _iterator10=_createForOfIteratorHelper($getSharedNodeState(writable).flatKeys),_step10;try{for(_iterator10.s();!(_step10=_iterator10.n()).done;){var k=_step10.value;if(k in serialized){if(parseState===undefined||parseState===unknownState){parseState=_objectSpread({},unknownState);}parseState[k]=serialized[k];}}}catch(err){_iterator10.e(err);}finally{_iterator10.f();}if(writable.__state||parseState){$getWritableNodeState(node).updateFromJSON(parseState);}return writable;}/**
401
+ * @internal
402
+ *
403
+ * Return true if the two nodes have equivalent NodeState, to be used
404
+ * to determine when TextNode are being merged, not a lot of use cases
405
+ * otherwise.
406
+ */function nodeStatesAreEquivalent(a,b){if(a===b){return true;}if(a&&b&&a.size!==b.size){return false;}var keys=new Set();return!(a&&hasUnequalMapEntry(keys,a,b)||b&&hasUnequalMapEntry(keys,b,a)||a&&hasUnequalRecordEntry(keys,a,b)||b&&hasUnequalRecordEntry(keys,b,a));}/**
407
+ * Compute the number of distinct keys that will be in a NodeState
408
+ */function computeSize(sharedConfigMap,unknownState,knownState){var size=knownState.size;if(unknownState){for(var k in unknownState){var sharedConfig=sharedConfigMap.get(k);if(!sharedConfig||!knownState.has(sharedConfig)){size++;}}}return size;}/**
409
+ * @internal
410
+ *
411
+ * Return obj if it is an object with at least one property, otherwise
412
+ * return undefined.
413
+ */function undefinedIfEmpty(obj){if(obj){for(var key in obj){return obj;}}return undefined;}/**
414
+ * @internal
415
+ *
416
+ * Cast the given v to unknown
417
+ */function coerceToJSON(v){return v;}/**
418
+ * @internal
419
+ *
420
+ * Parse all knowable values in an UnknownStateRecord into nextKnownState
421
+ * and return the unparsed values in a new UnknownStateRecord. Returns
422
+ * undefined if no unknown values remain.
423
+ */function parseAndPruneNextUnknownState(sharedConfigMap,nextKnownState,unknownState){var nextUnknownState=undefined;if(unknownState){for(var _i5=0,_Object$entries2=Object.entries(unknownState);_i5<_Object$entries2.length;_i5++){var _Object$entries2$_i=_slicedToArray(_Object$entries2[_i5],2),k=_Object$entries2$_i[0],v=_Object$entries2$_i[1];var stateConfig=sharedConfigMap.get(k);if(stateConfig){if(!nextKnownState.has(stateConfig)){nextKnownState.set(stateConfig,stateConfig.parse(v));}}else{nextUnknownState=nextUnknownState||{};nextUnknownState[k]=v;}}}return nextUnknownState;}/**
424
+ * @internal
425
+ *
426
+ * Compare each entry of sourceState.knownState that is not in keys to
427
+ * otherState (or the default value if otherState is undefined.
428
+ * Note that otherState will return the defaultValue as well if it
429
+ * has never been set. Any checked entry's key will be added to keys.
430
+ *
431
+ * @returns true if any difference is found, false otherwise
432
+ */function hasUnequalMapEntry(keys,sourceState,otherState){var _iterator11=_createForOfIteratorHelper(sourceState.knownState),_step11;try{for(_iterator11.s();!(_step11=_iterator11.n()).done;){var _step11$value=_slicedToArray(_step11.value,2),stateConfig=_step11$value[0],value=_step11$value[1];if(keys.has(stateConfig.key)){continue;}keys.add(stateConfig.key);var otherValue=otherState?otherState.getValue(stateConfig):stateConfig.defaultValue;if(otherValue!==value&&!stateConfig.isEqual(otherValue,value)){return true;}}}catch(err){_iterator11.e(err);}finally{_iterator11.f();}return false;}/**
433
+ * @internal
434
+ *
435
+ * Compare each entry of sourceState.unknownState that is not in keys to
436
+ * otherState.unknownState (or undefined if otherState is undefined).
437
+ * Any checked entry's key will be added to keys.
438
+ *
439
+ * Notably since we have already checked hasUnequalMapEntry on both sides,
440
+ * we do not do any parsing or checking of knownState.
441
+ *
442
+ * @returns true if any difference is found, false otherwise
443
+ */function hasUnequalRecordEntry(keys,sourceState,otherState){var unknownState=sourceState.unknownState;var otherUnknownState=otherState?otherState.unknownState:undefined;if(unknownState){for(var _i6=0,_Object$entries3=Object.entries(unknownState);_i6<_Object$entries3.length;_i6++){var _Object$entries3$_i=_slicedToArray(_Object$entries3[_i6],2),key=_Object$entries3$_i[0],value=_Object$entries3$_i[1];if(keys.has(key)){continue;}keys.add(key);var otherValue=otherUnknownState?otherUnknownState[key]:undefined;if(value!==otherValue){return true;}}}return false;}/**
444
+ * @internal
445
+ *
446
+ * Clones the NodeState for a given node. Handles aliasing if the state references the from node.
447
+ */function $cloneNodeState(from,to){var state=from.__state;return state&&state.node===from?state.getWritable(to):state;}/**
448
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
449
+ *
450
+ * This source code is licensed under the MIT license found in the
451
+ * LICENSE file in the root directory of this source tree.
452
+ *
453
+ */function $canSimpleTextNodesBeMerged(node1,node2){var node1Mode=node1.__mode;var node1Format=node1.__format;var node1Style=node1.__style;var node2Mode=node2.__mode;var node2Format=node2.__format;var node2Style=node2.__style;var node1State=node1.__state;var node2State=node2.__state;return(node1Mode===null||node1Mode===node2Mode)&&(node1Format===null||node1Format===node2Format)&&(node1Style===null||node1Style===node2Style)&&(node1.__state===null||node1State===node2State||nodeStatesAreEquivalent(node1State,node2State));}function $mergeTextNodes(node1,node2){var writableNode1=node1.mergeWithSibling(node2);var normalizedNodes=getActiveEditor()._normalizedNodes;normalizedNodes.add(node1.__key);normalizedNodes.add(node2.__key);return writableNode1;}function $normalizeTextNode(textNode){var node=textNode;if(node.__text===''&&node.isSimpleText()&&!node.isUnmergeable()){node.remove();return;}// Backward
454
+ var previousNode;while((previousNode=node.getPreviousSibling())!==null&&$isTextNode(previousNode)&&previousNode.isSimpleText()&&!previousNode.isUnmergeable()){if(previousNode.__text===''){previousNode.remove();}else if($canSimpleTextNodesBeMerged(previousNode,node)){node=$mergeTextNodes(previousNode,node);break;}else{break;}}// Forward
455
+ var nextNode;while((nextNode=node.getNextSibling())!==null&&$isTextNode(nextNode)&&nextNode.isSimpleText()&&!nextNode.isUnmergeable()){if(nextNode.__text===''){nextNode.remove();}else if($canSimpleTextNodesBeMerged(node,nextNode)){node=$mergeTextNodes(node,nextNode);break;}else{break;}}}function $normalizeSelection(selection){$normalizePoint(selection.anchor);$normalizePoint(selection.focus);return selection;}function $normalizePoint(point){while(point.type==='element'){var node=point.getNode();var offset=point.offset;var nextNode=void 0;var nextOffsetAtEnd=void 0;if(offset===node.getChildrenSize()){nextNode=node.getChildAtIndex(offset-1);nextOffsetAtEnd=true;}else{nextNode=node.getChildAtIndex(offset);nextOffsetAtEnd=false;}if($isTextNode(nextNode)){point.set(nextNode.__key,nextOffsetAtEnd?nextNode.getTextContentSize():0,'text',true);break;}else if(!$isElementNode(nextNode)){break;}point.set(nextNode.__key,nextOffsetAtEnd?nextNode.getChildrenSize():0,'element',true);}}var subTreeTextContent='';var subTreeTextFormat=null;var subTreeTextStyle=null;var editorTextContent='';var activeEditorConfig;var activeEditor$1;var activeEditorNodes;var treatAllNodesAsDirty=false;var activeEditorStateReadOnly=false;var activeMutationListeners;var activeDirtyElements;var activeDirtyLeaves;var activePrevNodeMap;var activeNextNodeMap;var activePrevKeyToDOMMap;var mutatedNodes;function destroyNode(key,parentDOM){var node=activePrevNodeMap.get(key);if(parentDOM!==null){var dom=getPrevElementByKeyOrThrow(key);if(dom.parentNode===parentDOM){parentDOM.removeChild(dom);}}// This logic is really important, otherwise we will leak DOM nodes
456
+ // when their corresponding LexicalNodes are removed from the editor state.
457
+ if(!activeNextNodeMap.has(key)){activeEditor$1._keyToDOMMap.delete(key);}if($isElementNode(node)){var children=createChildrenArray(node,activePrevNodeMap);destroyChildren(children,0,children.length-1,null);}if(node!==undefined){setMutatedNode(mutatedNodes,activeEditorNodes,activeMutationListeners,node,'destroyed');}}function destroyChildren(children,_startIndex,endIndex,dom){var startIndex=_startIndex;for(;startIndex<=endIndex;++startIndex){var child=children[startIndex];if(child!==undefined){destroyNode(child,dom);}}}function setTextAlign(domStyle,value){domStyle.setProperty('text-align',value);}var DEFAULT_INDENT_VALUE='40px';function setElementIndent(dom,indent){var indentClassName=activeEditorConfig.theme.indent;if(typeof indentClassName==='string'){var elementHasClassName=dom.classList.contains(indentClassName);if(indent>0&&!elementHasClassName){dom.classList.add(indentClassName);}else if(indent<1&&elementHasClassName){dom.classList.remove(indentClassName);}}var indentationBaseValue=getComputedStyle(dom).getPropertyValue('--lexical-indent-base-value')||DEFAULT_INDENT_VALUE;dom.style.setProperty('padding-inline-start',indent===0?'':"calc(".concat(indent," * ").concat(indentationBaseValue,")"));}function setElementFormat(dom,format){var domStyle=dom.style;if(format===0){setTextAlign(domStyle,'');}else if(format===IS_ALIGN_LEFT){setTextAlign(domStyle,'left');}else if(format===IS_ALIGN_CENTER){setTextAlign(domStyle,'center');}else if(format===IS_ALIGN_RIGHT){setTextAlign(domStyle,'right');}else if(format===IS_ALIGN_JUSTIFY){setTextAlign(domStyle,'justify');}else if(format===IS_ALIGN_START){setTextAlign(domStyle,'start');}else if(format===IS_ALIGN_END){setTextAlign(domStyle,'end');}}function $getReconciledDirection(node){var direction=node.__dir;if(direction!==null){return direction;}if($isRootNode(node)){return null;}var parent=node.getParentOrThrow();if(!$isRootNode(parent)||parent.__dir!==null){return null;}return'auto';}function $setElementDirection(dom,node){var direction=$getReconciledDirection(node);if(direction!==null){dom.dir=direction;}else{dom.removeAttribute('dir');}}function $createNode(key,slot){var node=activeNextNodeMap.get(key);if(node===undefined){{formatDevErrorMessage("createNode: node does not exist in nodeMap");}}var dom=node.createDOM(activeEditorConfig,activeEditor$1);storeDOMWithKey(key,dom,activeEditor$1);// This helps preserve the text, and stops spell check tools from
458
+ // merging or break the spans (which happens if they are missing
459
+ // this attribute).
460
+ if($isTextNode(node)){dom.setAttribute('data-lexical-text','true');}else if($isDecoratorNode(node)){dom.setAttribute('data-lexical-decorator','true');}if($isElementNode(node)){var indent=node.__indent;var childrenSize=node.__size;$setElementDirection(dom,node);if(indent!==0){setElementIndent(dom,indent);}if(childrenSize!==0){var endIndex=childrenSize-1;var children=createChildrenArray(node,activeNextNodeMap);$createChildren(children,node,0,endIndex,node.getDOMSlot(dom));}var format=node.__format;if(format!==0){setElementFormat(dom,format);}if(!node.isInline()){reconcileElementTerminatingLineBreak(null,node,dom);}if($textContentRequiresDoubleLinebreakAtEnd(node)){subTreeTextContent+=DOUBLE_LINE_BREAK;editorTextContent+=DOUBLE_LINE_BREAK;}}else{var text=node.getTextContent();if($isDecoratorNode(node)){var decorator=node.decorate(activeEditor$1,activeEditorConfig);if(decorator!==null){reconcileDecorator(key,decorator);}// Decorators are always non editable
461
+ dom.contentEditable='false';}subTreeTextContent+=text;editorTextContent+=text;}if(slot!==null){slot.insertChild(dom);}{// Freeze the node in DEV to prevent accidental mutations
462
+ Object.freeze(node);}setMutatedNode(mutatedNodes,activeEditorNodes,activeMutationListeners,node,'created');return dom;}function $createChildren(children,element,_startIndex,endIndex,slot){var previousSubTreeTextContent=subTreeTextContent;subTreeTextContent='';var startIndex=_startIndex;for(;startIndex<=endIndex;++startIndex){$createNode(children[startIndex],slot);var node=activeNextNodeMap.get(children[startIndex]);if(node!==null&&$isTextNode(node)){if(subTreeTextFormat===null){subTreeTextFormat=node.getFormat();subTreeTextStyle=node.getStyle();}}}if($textContentRequiresDoubleLinebreakAtEnd(element)){subTreeTextContent+=DOUBLE_LINE_BREAK;}var dom=slot.element;dom.__lexicalTextContent=subTreeTextContent;subTreeTextContent=previousSubTreeTextContent+subTreeTextContent;}function isLastChildLineBreakOrDecorator(element,nodeMap){if(element){var lastKey=element.__last;if(lastKey){var node=nodeMap.get(lastKey);if(node){return $isLineBreakNode(node)?'line-break':$isDecoratorNode(node)&&node.isInline()?'decorator':null;}}return'empty';}return null;}// If we end an element with a LineBreakNode, then we need to add an additional <br>
463
+ function reconcileElementTerminatingLineBreak(prevElement,nextElement,dom){var prevLineBreak=isLastChildLineBreakOrDecorator(prevElement,activePrevNodeMap);var nextLineBreak=isLastChildLineBreakOrDecorator(nextElement,activeNextNodeMap);if(prevLineBreak!==nextLineBreak){nextElement.getDOMSlot(dom).setManagedLineBreak(nextLineBreak);}}function reconcileTextFormat(element){if(subTreeTextFormat!=null&&subTreeTextFormat!==element.__textFormat&&!activeEditorStateReadOnly){element.setTextFormat(subTreeTextFormat);}}function reconcileTextStyle(element){if(subTreeTextStyle!=null&&subTreeTextStyle!==element.__textStyle&&!activeEditorStateReadOnly){element.setTextStyle(subTreeTextStyle);}}function $reconcileChildrenWithDirection(prevElement,nextElement,dom){subTreeTextFormat=null;subTreeTextStyle=null;$reconcileChildren(prevElement,nextElement,nextElement.getDOMSlot(dom));reconcileTextFormat(nextElement);reconcileTextStyle(nextElement);}function createChildrenArray(element,nodeMap){var children=[];var nodeKey=element.__first;while(nodeKey!==null){var node=nodeMap.get(nodeKey);if(node===undefined){{formatDevErrorMessage("createChildrenArray: node does not exist in nodeMap");}}children.push(nodeKey);nodeKey=node.__next;}return children;}function $reconcileChildren(prevElement,nextElement,slot){var previousSubTreeTextContent=subTreeTextContent;var prevChildrenSize=prevElement.__size;var nextChildrenSize=nextElement.__size;subTreeTextContent='';var dom=slot.element;if(prevChildrenSize===1&&nextChildrenSize===1){var prevFirstChildKey=prevElement.__first;var nextFirstChildKey=nextElement.__first;if(prevFirstChildKey===nextFirstChildKey){$reconcileNode(prevFirstChildKey,dom);}else{var lastDOM=getPrevElementByKeyOrThrow(prevFirstChildKey);var replacementDOM=$createNode(nextFirstChildKey,null);try{dom.replaceChild(replacementDOM,lastDOM);}catch(error){if(_typeof(error)==='object'&&error!=null){var msg="".concat(error.toString()," Parent: ").concat(dom.tagName,", new child: {tag: ").concat(replacementDOM.tagName," key: ").concat(nextFirstChildKey,"}, old child: {tag: ").concat(lastDOM.tagName,", key: ").concat(prevFirstChildKey,"}.");throw new Error(msg);}else{throw error;}}destroyNode(prevFirstChildKey,null);}var nextChildNode=activeNextNodeMap.get(nextFirstChildKey);if($isTextNode(nextChildNode)){if(subTreeTextFormat===null){subTreeTextFormat=nextChildNode.getFormat();subTreeTextStyle=nextChildNode.getStyle();}}}else{var prevChildren=createChildrenArray(prevElement,activePrevNodeMap);var nextChildren=createChildrenArray(nextElement,activeNextNodeMap);if(!(prevChildren.length===prevChildrenSize)){formatDevErrorMessage("$reconcileChildren: prevChildren.length !== prevChildrenSize");}if(!(nextChildren.length===nextChildrenSize)){formatDevErrorMessage("$reconcileChildren: nextChildren.length !== nextChildrenSize");}if(prevChildrenSize===0){if(nextChildrenSize!==0){$createChildren(nextChildren,nextElement,0,nextChildrenSize-1,slot);}}else if(nextChildrenSize===0){if(prevChildrenSize!==0){var canUseFastPath=slot.after==null&&slot.before==null&&slot.element.__lexicalLineBreak==null;destroyChildren(prevChildren,0,prevChildrenSize-1,canUseFastPath?null:dom);if(canUseFastPath){// Fast path for removing DOM nodes
464
+ dom.textContent='';}}}else{$reconcileNodeChildren(nextElement,prevChildren,nextChildren,prevChildrenSize,nextChildrenSize,slot);}}if($textContentRequiresDoubleLinebreakAtEnd(nextElement)){subTreeTextContent+=DOUBLE_LINE_BREAK;}dom.__lexicalTextContent=subTreeTextContent;subTreeTextContent=previousSubTreeTextContent+subTreeTextContent;}function $reconcileNode(key,parentDOM){var prevNode=activePrevNodeMap.get(key);var nextNode=activeNextNodeMap.get(key);if(prevNode===undefined||nextNode===undefined){{formatDevErrorMessage("reconcileNode: prevNode or nextNode does not exist in nodeMap");}}var isDirty=treatAllNodesAsDirty||activeDirtyLeaves.has(key)||activeDirtyElements.has(key);var dom=getElementByKeyOrThrow(activeEditor$1,key);// If the node key points to the same instance in both states
465
+ // and isn't dirty, we just update the text content cache
466
+ // and return the existing DOM Node.
467
+ if(prevNode===nextNode&&!isDirty){if($isElementNode(prevNode)){var previousSubTreeTextContent=dom.__lexicalTextContent;if(previousSubTreeTextContent!==undefined){subTreeTextContent+=previousSubTreeTextContent;editorTextContent+=previousSubTreeTextContent;}}else{var text=prevNode.getTextContent();editorTextContent+=text;subTreeTextContent+=text;}return dom;}// If the node key doesn't point to the same instance in both maps,
468
+ // it was cloned. If it's also dirty, we mark it as mutated.
469
+ if(prevNode!==nextNode&&isDirty){setMutatedNode(mutatedNodes,activeEditorNodes,activeMutationListeners,nextNode,'updated');}// Update node. If it returns true, we need to unmount and re-create the node
470
+ if(nextNode.updateDOM(prevNode,dom,activeEditorConfig)){var replacementDOM=$createNode(key,null);if(parentDOM===null){{formatDevErrorMessage("reconcileNode: parentDOM is null");}}parentDOM.replaceChild(replacementDOM,dom);destroyNode(key,null);return replacementDOM;}if($isElementNode(prevNode)&&$isElementNode(nextNode)){var nextIndent=nextNode.__indent;if(treatAllNodesAsDirty||nextIndent!==prevNode.__indent){setElementIndent(dom,nextIndent);}var nextFormat=nextNode.__format;if(treatAllNodesAsDirty||nextFormat!==prevNode.__format){setElementFormat(dom,nextFormat);}if(isDirty){$reconcileChildrenWithDirection(prevNode,nextNode,dom);if(!$isRootNode(nextNode)&&!nextNode.isInline()){reconcileElementTerminatingLineBreak(prevNode,nextNode,dom);}}if($textContentRequiresDoubleLinebreakAtEnd(nextNode)){subTreeTextContent+=DOUBLE_LINE_BREAK;editorTextContent+=DOUBLE_LINE_BREAK;}if(treatAllNodesAsDirty||nextNode.__dir!==prevNode.__dir){$setElementDirection(dom,nextNode);if(// Root node direction changing from set to unset (or vice versa)
471
+ // changes how children's direction is calculated.
472
+ $isRootNode(nextNode)&&// Can skip if all children already reconciled.
473
+ !treatAllNodesAsDirty){var _iterator12=_createForOfIteratorHelper(nextNode.getChildren()),_step12;try{for(_iterator12.s();!(_step12=_iterator12.n()).done;){var child=_step12.value;if($isElementNode(child)){var childDom=getElementByKeyOrThrow(activeEditor$1,child.getKey());$setElementDirection(childDom,child);}}}catch(err){_iterator12.e(err);}finally{_iterator12.f();}}}}else{var _text=nextNode.getTextContent();if($isDecoratorNode(nextNode)){var decorator=nextNode.decorate(activeEditor$1,activeEditorConfig);if(decorator!==null){reconcileDecorator(key,decorator);}}subTreeTextContent+=_text;editorTextContent+=_text;}if(!activeEditorStateReadOnly&&$isRootNode(nextNode)&&nextNode.__cachedText!==editorTextContent){// Cache the latest text content.
474
+ var nextRootNode=nextNode.getWritable();nextRootNode.__cachedText=editorTextContent;nextNode=nextRootNode;}{// Freeze the node in DEV to prevent accidental mutations
475
+ Object.freeze(nextNode);}return dom;}function reconcileDecorator(key,decorator){var pendingDecorators=activeEditor$1._pendingDecorators;var currentDecorators=activeEditor$1._decorators;if(pendingDecorators===null){if(currentDecorators[key]===decorator){return;}pendingDecorators=cloneDecorators(activeEditor$1);}pendingDecorators[key]=decorator;}function getNextSibling(element){var nextSibling=element.nextSibling;if(nextSibling!==null&&nextSibling===activeEditor$1._blockCursorElement){nextSibling=nextSibling.nextSibling;}return nextSibling;}function $reconcileNodeChildren(nextElement,prevChildren,nextChildren,prevChildrenLength,nextChildrenLength,slot){var prevEndIndex=prevChildrenLength-1;var nextEndIndex=nextChildrenLength-1;var prevChildrenSet;var nextChildrenSet;var siblingDOM=slot.getFirstChild();var prevIndex=0;var nextIndex=0;while(prevIndex<=prevEndIndex&&nextIndex<=nextEndIndex){var prevKey=prevChildren[prevIndex];var nextKey=nextChildren[nextIndex];if(prevKey===nextKey){siblingDOM=getNextSibling($reconcileNode(nextKey,slot.element));prevIndex++;nextIndex++;}else{if(prevChildrenSet===undefined){prevChildrenSet=new Set(prevChildren);}if(nextChildrenSet===undefined){nextChildrenSet=new Set(nextChildren);}var nextHasPrevKey=nextChildrenSet.has(prevKey);var prevHasNextKey=prevChildrenSet.has(nextKey);if(!nextHasPrevKey){// Remove prev
476
+ siblingDOM=getNextSibling(getPrevElementByKeyOrThrow(prevKey));destroyNode(prevKey,slot.element);prevIndex++;}else if(!prevHasNextKey){// Create next
477
+ $createNode(nextKey,slot.withBefore(siblingDOM));nextIndex++;}else{// Move next
478
+ var childDOM=getElementByKeyOrThrow(activeEditor$1,nextKey);if(childDOM===siblingDOM){siblingDOM=getNextSibling($reconcileNode(nextKey,slot.element));}else{slot.withBefore(siblingDOM).insertChild(childDOM);$reconcileNode(nextKey,slot.element);}prevIndex++;nextIndex++;}}var node=activeNextNodeMap.get(nextKey);if(node!==null&&$isTextNode(node)){if(subTreeTextFormat===null){subTreeTextFormat=node.getFormat();subTreeTextStyle=node.getStyle();}}}var appendNewChildren=prevIndex>prevEndIndex;var removeOldChildren=nextIndex>nextEndIndex;if(appendNewChildren&&!removeOldChildren){var previousNode=nextChildren[nextEndIndex+1];var insertDOM=previousNode===undefined?null:activeEditor$1.getElementByKey(previousNode);$createChildren(nextChildren,nextElement,nextIndex,nextEndIndex,slot.withBefore(insertDOM));}else if(removeOldChildren&&!appendNewChildren){destroyChildren(prevChildren,prevIndex,prevEndIndex,slot.element);}}function $reconcileRoot(prevEditorState,nextEditorState,editor,dirtyType,dirtyElements,dirtyLeaves){// We cache text content to make retrieval more efficient.
479
+ // The cache must be rebuilt during reconciliation to account for any changes.
480
+ subTreeTextContent='';editorTextContent='';// Rather than pass around a load of arguments through the stack recursively
481
+ // we instead set them as bindings within the scope of the module.
482
+ treatAllNodesAsDirty=dirtyType===FULL_RECONCILE;activeEditor$1=editor;activeEditorConfig=editor._config;activeEditorNodes=editor._nodes;activeMutationListeners=activeEditor$1._listeners.mutation;activeDirtyElements=dirtyElements;activeDirtyLeaves=dirtyLeaves;activePrevNodeMap=prevEditorState._nodeMap;activeNextNodeMap=nextEditorState._nodeMap;activeEditorStateReadOnly=nextEditorState._readOnly;activePrevKeyToDOMMap=new Map(editor._keyToDOMMap);// We keep track of mutated nodes so we can trigger mutation
483
+ // listeners later in the update cycle.
484
+ var currentMutatedNodes=new Map();mutatedNodes=currentMutatedNodes;$reconcileNode('root',null);// We don't want a bunch of void checks throughout the scope
485
+ // so instead we make it seem that these values are always set.
486
+ // We also want to make sure we clear them down, otherwise we
487
+ // can leak memory.
488
+ // @ts-ignore
489
+ activeEditor$1=undefined;// @ts-ignore
490
+ activeEditorNodes=undefined;// @ts-ignore
491
+ activeDirtyElements=undefined;// @ts-ignore
492
+ activeDirtyLeaves=undefined;// @ts-ignore
493
+ activePrevNodeMap=undefined;// @ts-ignore
494
+ activeNextNodeMap=undefined;// @ts-ignore
495
+ activeEditorConfig=undefined;// @ts-ignore
496
+ activePrevKeyToDOMMap=undefined;// @ts-ignore
497
+ mutatedNodes=undefined;return currentMutatedNodes;}function storeDOMWithKey(key,dom,editor){var keyToDOMMap=editor._keyToDOMMap;setNodeKeyOnDOMNode(dom,editor,key);keyToDOMMap.set(key,dom);}function getPrevElementByKeyOrThrow(key){var element=activePrevKeyToDOMMap.get(key);if(element===undefined){{formatDevErrorMessage("Reconciliation: could not find DOM element for node key ".concat(key));}}return element;}/**
498
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
499
+ *
500
+ * This source code is licensed under the MIT license found in the
501
+ * LICENSE file in the root directory of this source tree.
502
+ *
503
+ */ /*@__INLINE__*/function warnOnlyOnce(message){{var run=false;return function(){if(!run){console.warn(message);}run=true;};}}/**
504
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
505
+ *
506
+ * This source code is licensed under the MIT license found in the
507
+ * LICENSE file in the root directory of this source tree.
508
+ *
509
+ */ /**
510
+ * Crete a command that can be used with `editor.dispatchCommand` and
511
+ * `editor.registerCommand`. Commands are used by unique reference, not by
512
+ * name.
513
+ *
514
+ * @param type A string to identify the command, very helpful for debugging
515
+ * @returns A new LexicalCommand
516
+ *
517
+ * @__NO_SIDE_EFFECTS__
518
+ */function createCommand(type){return{type:type};}var SELECTION_CHANGE_COMMAND=createCommand('SELECTION_CHANGE_COMMAND');var SELECTION_INSERT_CLIPBOARD_NODES_COMMAND=createCommand('SELECTION_INSERT_CLIPBOARD_NODES_COMMAND');var CLICK_COMMAND=createCommand('CLICK_COMMAND');var BEFORE_INPUT_COMMAND=createCommand('BEFORE_INPUT_COMMAND');var INPUT_COMMAND=createCommand('INPUT_COMMAND');var COMPOSITION_START_COMMAND=createCommand('COMPOSITION_START_COMMAND');var COMPOSITION_END_COMMAND=createCommand('COMPOSITION_END_COMMAND');/**
519
+ * Dispatched to delete a character, the payload will be `true` if the deletion
520
+ * is backwards (backspace or delete on macOS) and `false` if forwards
521
+ * (delete or Fn+Delete on macOS).
522
+ */var DELETE_CHARACTER_COMMAND=createCommand('DELETE_CHARACTER_COMMAND');/**
523
+ * Dispatched to insert a line break. With a false payload the
524
+ * cursor moves to the new line (Shift+Enter), with a true payload the cursor
525
+ * does not move (Ctrl+O on macOS).
526
+ */var INSERT_LINE_BREAK_COMMAND=createCommand('INSERT_LINE_BREAK_COMMAND');var INSERT_PARAGRAPH_COMMAND=createCommand('INSERT_PARAGRAPH_COMMAND');var CONTROLLED_TEXT_INSERTION_COMMAND=createCommand('CONTROLLED_TEXT_INSERTION_COMMAND');var PASTE_COMMAND=createCommand('PASTE_COMMAND');var REMOVE_TEXT_COMMAND=createCommand('REMOVE_TEXT_COMMAND');/**
527
+ * Dispatched to delete a word, the payload will be `true` if the deletion is
528
+ * backwards (Ctrl+Backspace or Opt+Delete on macOS), and `false` if
529
+ * forwards (Ctrl+Delete or Fn+Opt+Delete on macOS).
530
+ */var DELETE_WORD_COMMAND=createCommand('DELETE_WORD_COMMAND');/**
531
+ * Dispatched to delete a line, the payload will be `true` if the deletion is
532
+ * backwards (Cmd+Delete on macOS), and `false` if forwards
533
+ * (Fn+Cmd+Delete on macOS).
534
+ */var DELETE_LINE_COMMAND=createCommand('DELETE_LINE_COMMAND');/**
535
+ * Dispatched to format the selected text.
536
+ */var FORMAT_TEXT_COMMAND=createCommand('FORMAT_TEXT_COMMAND');/**
537
+ * Dispatched on undo (Cmd+Z on macOS, Ctrl+Z elsewhere).
538
+ */var UNDO_COMMAND=createCommand('UNDO_COMMAND');/**
539
+ * Dispatched on redo (Shift+Cmd+Z on macOS, Shift+Ctrl+Z or Ctrl+Y elsewhere).
540
+ */var REDO_COMMAND=createCommand('REDO_COMMAND');/**
541
+ * Dispatched when any key is pressed.
542
+ */var KEY_DOWN_COMMAND=createCommand('KEYDOWN_COMMAND');/**
543
+ * Dispatched when the `'ArrowRight'` key is pressed.
544
+ * The shift modifier key may also be down.
545
+ */var KEY_ARROW_RIGHT_COMMAND=createCommand('KEY_ARROW_RIGHT_COMMAND');/**
546
+ * Dispatched when the move to end keyboard shortcut is pressed,
547
+ * (Cmd+Right on macOS; Ctrl+Right elsewhere).
548
+ */var MOVE_TO_END=createCommand('MOVE_TO_END');/**
549
+ * Dispatched when the `'ArrowLeft'` key is pressed.
550
+ * The shift modifier key may also be down.
551
+ */var KEY_ARROW_LEFT_COMMAND=createCommand('KEY_ARROW_LEFT_COMMAND');/**
552
+ * Dispatched when the move to start keyboard shortcut is pressed,
553
+ * (Cmd+Left on macOS; Ctrl+Left elsewhere).
554
+ */var MOVE_TO_START=createCommand('MOVE_TO_START');/**
555
+ * Dispatched when the `'ArrowUp'` key is pressed.
556
+ * The shift and/or alt (option) modifier keys may also be down.
557
+ */var KEY_ARROW_UP_COMMAND=createCommand('KEY_ARROW_UP_COMMAND');/**
558
+ * Dispatched when the `'ArrowDown'` key is pressed.
559
+ * The shift and/or alt (option) modifier keys may also be down.
560
+ */var KEY_ARROW_DOWN_COMMAND=createCommand('KEY_ARROW_DOWN_COMMAND');/**
561
+ * Dispatched when the enter key is pressed, may also be called with a null
562
+ * payload when the intent is to insert a newline. The shift modifier key
563
+ * must be down, any other modifier keys may also be down.
564
+ */var KEY_ENTER_COMMAND=createCommand('KEY_ENTER_COMMAND');/**
565
+ * Dispatched whenever the space (`' '`) key is pressed, any modifier
566
+ * keys may be down.
567
+ */var KEY_SPACE_COMMAND=createCommand('KEY_SPACE_COMMAND');/**
568
+ * Dispatched whenever the `'Backspace'` key is pressed, the shift
569
+ * modifier key may be down.
570
+ */var KEY_BACKSPACE_COMMAND=createCommand('KEY_BACKSPACE_COMMAND');/**
571
+ * Dispatched whenever the `'Escape'` key is pressed, any modifier
572
+ * keys may be down.
573
+ */var KEY_ESCAPE_COMMAND=createCommand('KEY_ESCAPE_COMMAND');/**
574
+ * Dispatched whenever the `'Delete'` key is pressed (Fn+Delete on macOS).
575
+ */var KEY_DELETE_COMMAND=createCommand('KEY_DELETE_COMMAND');/**
576
+ * Dispatched whenever the `'Tab'` key is pressed. The shift modifier key
577
+ * may be down.
578
+ */var KEY_TAB_COMMAND=createCommand('KEY_TAB_COMMAND');var INSERT_TAB_COMMAND=createCommand('INSERT_TAB_COMMAND');var INDENT_CONTENT_COMMAND=createCommand('INDENT_CONTENT_COMMAND');var OUTDENT_CONTENT_COMMAND=createCommand('OUTDENT_CONTENT_COMMAND');var DROP_COMMAND=createCommand('DROP_COMMAND');var FORMAT_ELEMENT_COMMAND=createCommand('FORMAT_ELEMENT_COMMAND');var DRAGSTART_COMMAND=createCommand('DRAGSTART_COMMAND');var DRAGOVER_COMMAND=createCommand('DRAGOVER_COMMAND');var DRAGEND_COMMAND=createCommand('DRAGEND_COMMAND');/**
579
+ * Dispatched on a copy event, either via the clipboard or a KeyboardEvent
580
+ * (Cmd+C on macOS, Ctrl+C elsewhere).
581
+ */var COPY_COMMAND=createCommand('COPY_COMMAND');/**
582
+ * Dispatched on a cut event, either via the clipboard or a KeyboardEvent
583
+ * (Cmd+X on macOS, Ctrl+X elsewhere).
584
+ */var CUT_COMMAND=createCommand('CUT_COMMAND');/**
585
+ * Dispatched on the select all keyboard shortcut
586
+ * (Cmd+A on macOS, Ctrl+A elsehwere).
587
+ */var SELECT_ALL_COMMAND=createCommand('SELECT_ALL_COMMAND');var CLEAR_EDITOR_COMMAND=createCommand('CLEAR_EDITOR_COMMAND');var CLEAR_HISTORY_COMMAND=createCommand('CLEAR_HISTORY_COMMAND');var CAN_REDO_COMMAND=createCommand('CAN_REDO_COMMAND');var CAN_UNDO_COMMAND=createCommand('CAN_UNDO_COMMAND');var FOCUS_COMMAND=createCommand('FOCUS_COMMAND');var BLUR_COMMAND=createCommand('BLUR_COMMAND');/**
588
+ * @deprecated in v0.31.0, use KEY_DOWN_COMMAND and check for modifiers
589
+ * directly.
590
+ *
591
+ * Dispatched after any KeyboardEvent when modifiers are pressed
592
+ */var KEY_MODIFIER_COMMAND=createCommand('KEY_MODIFIER_COMMAND');var PASS_THROUGH_COMMAND=Object.freeze({});var ANDROID_COMPOSITION_LATENCY=30;var rootElementEvents=[['keydown',onKeyDown],['pointerdown',onPointerDown],['compositionstart',onCompositionStart],['compositionend',onCompositionEnd],['input',onInput],['click',onClick],['cut',PASS_THROUGH_COMMAND],['copy',PASS_THROUGH_COMMAND],['dragstart',PASS_THROUGH_COMMAND],['dragover',PASS_THROUGH_COMMAND],['dragend',PASS_THROUGH_COMMAND],['paste',PASS_THROUGH_COMMAND],['focus',PASS_THROUGH_COMMAND],['blur',PASS_THROUGH_COMMAND],['drop',PASS_THROUGH_COMMAND]];if(CAN_USE_BEFORE_INPUT){rootElementEvents.push(['beforeinput',function(event,editor){return onBeforeInput(event,editor);}]);}var lastKeyDownTimeStamp=0;var lastKeyCode=null;var lastBeforeInputInsertTextTimeStamp=0;var unprocessedBeforeInputData=null;// Node can be moved between documents (for example using createPortal), so we
593
+ // need to track the document each root element was originally registered on.
594
+ var rootElementToDocument=new WeakMap();var rootElementsRegistered=new WeakMap();var isSelectionChangeFromDOMUpdate=false;var isSelectionChangeFromMouseDown=false;var isInsertLineBreak=false;var isFirefoxEndingComposition=false;var isSafariEndingComposition=false;var safariEndCompositionEventData='';var postDeleteSelectionToRestore=null;var collapsedSelectionFormat=[0,'',0,'root',0];// This function is used to determine if Lexical should attempt to override
595
+ // the default browser behavior for insertion of text and use its own internal
596
+ // heuristics. This is an extremely important function, and makes much of Lexical
597
+ // work as intended between different browsers and across word, line and character
598
+ // boundary/formats. It also is important for text replacement, node schemas and
599
+ // composition mechanics.
600
+ function $shouldPreventDefaultAndInsertText(selection,domTargetRange,text,timeStamp,isBeforeInput){var anchor=selection.anchor;var focus=selection.focus;var anchorNode=anchor.getNode();var editor=getActiveEditor();var domSelection=getDOMSelection(getWindow(editor));var domAnchorNode=domSelection!==null?domSelection.anchorNode:null;var anchorKey=anchor.key;var backingAnchorElement=editor.getElementByKey(anchorKey);var textLength=text.length;return anchorKey!==focus.key||// If we're working with a non-text node.
601
+ !$isTextNode(anchorNode)||// If we are replacing a range with a single character or grapheme, and not composing.
602
+ (!isBeforeInput&&(!CAN_USE_BEFORE_INPUT||// We check to see if there has been
603
+ // a recent beforeinput event for "textInput". If there has been one in the last
604
+ // 50ms then we proceed as normal. However, if there is not, then this is likely
605
+ // a dangling `input` event caused by execCommand('insertText').
606
+ lastBeforeInputInsertTextTimeStamp<timeStamp+50)||anchorNode.isDirty()&&textLength<2||// TODO consider if there are other scenarios when multiple code units
607
+ // should be addressed here
608
+ doesContainSurrogatePair(text))&&anchor.offset!==focus.offset&&!anchorNode.isComposing()||// Any non standard text node.
609
+ $isTokenOrSegmented(anchorNode)||// If the text length is more than a single character and we're either
610
+ // dealing with this in "beforeinput" or where the node has already recently
611
+ // been changed (thus is dirty).
612
+ anchorNode.isDirty()&&textLength>1||// If the DOM selection element is not the same as the backing node during beforeinput.
613
+ (isBeforeInput||!CAN_USE_BEFORE_INPUT)&&backingAnchorElement!==null&&!anchorNode.isComposing()&&domAnchorNode!==getDOMTextNode(backingAnchorElement)||// If TargetRange is not the same as the DOM selection; browser trying to edit random parts
614
+ // of the editor.
615
+ domSelection!==null&&domTargetRange!==null&&(!domTargetRange.collapsed||domTargetRange.startContainer!==domSelection.anchorNode||domTargetRange.startOffset!==domSelection.anchorOffset)||// Check if we're changing from bold to italics, or some other format.
616
+ anchorNode.getFormat()!==selection.format||anchorNode.getStyle()!==selection.style||// One last set of heuristics to check against.
617
+ $shouldInsertTextAfterOrBeforeTextNode(selection,anchorNode);}function shouldSkipSelectionChange(domNode,offset){return isDOMTextNode(domNode)&&domNode.nodeValue!==null&&offset!==0&&offset!==domNode.nodeValue.length;}function onSelectionChange(domSelection,editor,isActive){var anchorDOM=domSelection.anchorNode,anchorOffset=domSelection.anchorOffset,focusDOM=domSelection.focusNode,focusOffset=domSelection.focusOffset;if(isSelectionChangeFromDOMUpdate){isSelectionChangeFromDOMUpdate=false;// If native DOM selection is on a DOM element, then
618
+ // we should continue as usual, as Lexical's selection
619
+ // may have normalized to a better child. If the DOM
620
+ // element is a text node, we can safely apply this
621
+ // optimization and skip the selection change entirely.
622
+ // We also need to check if the offset is at the boundary,
623
+ // because in this case, we might need to normalize to a
624
+ // sibling instead.
625
+ if(shouldSkipSelectionChange(anchorDOM,anchorOffset)&&shouldSkipSelectionChange(focusDOM,focusOffset)&&!postDeleteSelectionToRestore){return;}}updateEditorSync(editor,function(){// Non-active editor don't need any extra logic for selection, it only needs update
626
+ // to reconcile selection (set it to null) to ensure that only one editor has non-null selection.
627
+ if(!isActive){$setSelection(null);return;}if(!isSelectionWithinEditor(editor,anchorDOM,focusDOM)){return;}var selection=$getSelection();// Restore selection in the event of incorrect rightward shift after deletion
628
+ if(postDeleteSelectionToRestore&&$isRangeSelection(selection)&&selection.isCollapsed()){var curAnchor=selection.anchor;var prevAnchor=postDeleteSelectionToRestore.anchor;if(// Rightward shift in same node
629
+ curAnchor.key===prevAnchor.key&&curAnchor.offset===prevAnchor.offset+1||// Or rightward shift into sibling node
630
+ curAnchor.offset===1&&prevAnchor.getNode().is(curAnchor.getNode().getPreviousSibling())){// Restore selection
631
+ selection=postDeleteSelectionToRestore.clone();$setSelection(selection);}}postDeleteSelectionToRestore=null;// Update the selection format
632
+ if($isRangeSelection(selection)){var anchor=selection.anchor;var anchorNode=anchor.getNode();if(selection.isCollapsed()){// Badly interpreted range selection when collapsed - #1482
633
+ if(domSelection.type==='Range'&&domSelection.anchorNode===domSelection.focusNode){selection.dirty=true;}// If we have marked a collapsed selection format, and we're
634
+ // within the given time range – then attempt to use that format
635
+ // instead of getting the format from the anchor node.
636
+ var windowEvent=getWindow(editor).event;var currentTimeStamp=windowEvent?windowEvent.timeStamp:performance.now();var _collapsedSelectionFo=collapsedSelectionFormat,_collapsedSelectionFo2=_slicedToArray(_collapsedSelectionFo,5),lastFormat=_collapsedSelectionFo2[0],lastStyle=_collapsedSelectionFo2[1],lastOffset=_collapsedSelectionFo2[2],lastKey=_collapsedSelectionFo2[3],timeStamp=_collapsedSelectionFo2[4];var root=$getRoot();var isRootTextContentEmpty=editor.isComposing()===false&&root.getTextContent()==='';if(currentTimeStamp<timeStamp+200&&anchor.offset===lastOffset&&anchor.key===lastKey){$updateSelectionFormatStyle(selection,lastFormat,lastStyle);}else{if(anchor.type==='text'){if(!$isTextNode(anchorNode)){formatDevErrorMessage("Point.getNode() must return TextNode when type is text");}$updateSelectionFormatStyleFromTextNode(selection,anchorNode);}else if(anchor.type==='element'&&!isRootTextContentEmpty){if(!$isElementNode(anchorNode)){formatDevErrorMessage("Point.getNode() must return ElementNode when type is element");}var lastNode=anchor.getNode();if(// This previously applied to all ParagraphNode
637
+ lastNode.isEmpty()){$updateSelectionFormatStyleFromElementNode(selection,lastNode);}else{$updateSelectionFormatStyle(selection,0,'');}}}}else{var anchorKey=anchor.key;var focus=selection.focus;var focusKey=focus.key;var nodes=selection.getNodes();var nodesLength=nodes.length;var isBackward=selection.isBackward();var startOffset=isBackward?focusOffset:anchorOffset;var endOffset=isBackward?anchorOffset:focusOffset;var startKey=isBackward?focusKey:anchorKey;var endKey=isBackward?anchorKey:focusKey;var combinedFormat=IS_ALL_FORMATTING;var hasTextNodes=false;for(var i=0;i<nodesLength;i++){var node=nodes[i];var textContentSize=node.getTextContentSize();if($isTextNode(node)&&textContentSize!==0&&// Exclude empty text nodes at boundaries resulting from user's selection
638
+ !(i===0&&node.__key===startKey&&startOffset===textContentSize||i===nodesLength-1&&node.__key===endKey&&endOffset===0)){// TODO: what about style?
639
+ hasTextNodes=true;combinedFormat&=node.getFormat();if(combinedFormat===0){break;}}}selection.format=hasTextNodes?combinedFormat:0;}}_dispatchCommand(editor,SELECTION_CHANGE_COMMAND,undefined);});}function $updateSelectionFormatStyle(selection,format,style){if(selection.format!==format||selection.style!==style){selection.format=format;selection.style=style;selection.dirty=true;}}function $updateSelectionFormatStyleFromTextNode(selection,node){var format=node.getFormat();var style=node.getStyle();$updateSelectionFormatStyle(selection,format,style);}function $updateSelectionFormatStyleFromElementNode(selection,node){var format=node.getTextFormat();var style=node.getTextStyle();$updateSelectionFormatStyle(selection,format,style);}// This is a work-around is mainly Chrome specific bug where if you select
640
+ // the contents of an empty block, you cannot easily unselect anything.
641
+ // This results in a tiny selection box that looks buggy/broken. This can
642
+ // also help other browsers when selection might "appear" lost, when it
643
+ // really isn't.
644
+ function onClick(event,editor){updateEditorSync(editor,function(){var selection=$getSelection();var domSelection=getDOMSelection(getWindow(editor));var lastSelection=$getPreviousSelection();if(domSelection){if($isRangeSelection(selection)){var anchor=selection.anchor;var anchorNode=anchor.getNode();if(anchor.type==='element'&&anchor.offset===0&&selection.isCollapsed()&&!$isRootNode(anchorNode)&&$getRoot().getChildrenSize()===1&&anchorNode.getTopLevelElementOrThrow().isEmpty()&&lastSelection!==null&&selection.is(lastSelection)){domSelection.removeAllRanges();selection.dirty=true;}else if(event.detail===3&&!selection.isCollapsed()){// Triple click causing selection to overflow into the nearest element. In that
645
+ // case visually it looks like a single element content is selected, focus node
646
+ // is actually at the beginning of the next element (if present) and any manipulations
647
+ // with selection (formatting) are affecting second element as well
648
+ var focus=selection.focus;var focusNode=focus.getNode();if(anchorNode!==focusNode){var parentNode=$findMatchingParent(anchorNode,function(node){return $isElementNode(node)&&!node.isInline();});if($isElementNode(parentNode)){parentNode.select(0);}}}}else if(event.pointerType==='touch'||event.pointerType==='pen'){// This is used to update the selection on touch devices (including Apple Pencil) when the user clicks on text after a
649
+ // node selection. See isSelectionChangeFromMouseDown for the inverse
650
+ var domAnchorNode=domSelection.anchorNode;// If the user is attempting to click selection back onto text, then
651
+ // we should attempt create a range selection.
652
+ // When we click on an empty paragraph node or the end of a paragraph that ends
653
+ // with an image/poll, the nodeType will be ELEMENT_NODE
654
+ if(isHTMLElement(domAnchorNode)||isDOMTextNode(domAnchorNode)){var newSelection=$internalCreateRangeSelection(lastSelection,domSelection,editor,event);$setSelection(newSelection);}}}_dispatchCommand(editor,CLICK_COMMAND,event);});}function onPointerDown(event,editor){// TODO implement text drag & drop
655
+ var target=event.target;var pointerType=event.pointerType;if(isDOMNode(target)&&pointerType!=='touch'&&pointerType!=='pen'&&event.button===0){updateEditorSync(editor,function(){// Drag & drop should not recompute selection until mouse up; otherwise the initially
656
+ // selected content is lost.
657
+ if(!$isSelectionCapturedInDecorator(target)){isSelectionChangeFromMouseDown=true;}});}}function getTargetRange(event){if(!event.getTargetRanges){return null;}var targetRanges=event.getTargetRanges();if(targetRanges.length===0){return null;}return targetRanges[0];}function $canRemoveText(anchorNode,focusNode){return anchorNode!==focusNode||$isElementNode(anchorNode)||$isElementNode(focusNode)||!$isTokenOrTab(anchorNode)||!$isTokenOrTab(focusNode);}function isPossiblyAndroidKeyPress(timeStamp){return lastKeyCode==='MediaLast'&&timeStamp<lastKeyDownTimeStamp+ANDROID_COMPOSITION_LATENCY;}function registerDefaultCommandHandlers(editor){editor.registerCommand(BEFORE_INPUT_COMMAND,$handleBeforeInput,COMMAND_PRIORITY_EDITOR);editor.registerCommand(INPUT_COMMAND,$handleInput,COMMAND_PRIORITY_EDITOR);editor.registerCommand(COMPOSITION_START_COMMAND,$handleCompositionStart,COMMAND_PRIORITY_EDITOR);editor.registerCommand(COMPOSITION_END_COMMAND,$handleCompositionEnd,COMMAND_PRIORITY_EDITOR);editor.registerCommand(KEY_DOWN_COMMAND,$handleKeyDown,COMMAND_PRIORITY_EDITOR);}function onBeforeInput(event,editor){var inputType=event.inputType;// We let the browser do its own thing for composition.
658
+ if(inputType==='deleteCompositionText'||// If we're pasting in FF, we shouldn't get this event
659
+ // as the `paste` event should have triggered, unless the
660
+ // user has dom.event.clipboardevents.enabled disabled in
661
+ // about:config. In that case, we need to process the
662
+ // pasted content in the DOM mutation phase.
663
+ IS_FIREFOX&&isFirefoxClipboardEvents(editor)){return;}else if(inputType==='insertCompositionText'){return;}_dispatchCommand(editor,BEFORE_INPUT_COMMAND,event);}function $handleBeforeInput(event){var inputType=event.inputType;var targetRange=getTargetRange(event);var editor=getActiveEditor();var selection=$getSelection();if(inputType==='deleteContentBackward'){if(selection===null){// Use previous selection
664
+ var prevSelection=$getPreviousSelection();if(!$isRangeSelection(prevSelection)){return true;}$setSelection(prevSelection.clone());}if($isRangeSelection(selection)){var isSelectionAnchorSameAsFocus=selection.anchor.key===selection.focus.key;if(isPossiblyAndroidKeyPress(event.timeStamp)&&editor.isComposing()&&isSelectionAnchorSameAsFocus){$setCompositionKey(null);lastKeyDownTimeStamp=0;// Fixes an Android bug where selection flickers when backspacing
665
+ setTimeout(function(){updateEditorSync(editor,function(){$setCompositionKey(null);});},ANDROID_COMPOSITION_LATENCY);if($isRangeSelection(selection)){var _anchorNode=selection.anchor.getNode();_anchorNode.markDirty();if(!$isTextNode(_anchorNode)){formatDevErrorMessage("Anchor node must be a TextNode");}$updateSelectionFormatStyleFromTextNode(selection,_anchorNode);}}else{$setCompositionKey(null);event.preventDefault();// Chromium Android at the moment seems to ignore the preventDefault
666
+ // on 'deleteContentBackward' and still deletes the content. Which leads
667
+ // to multiple deletions. So we let the browser handle the deletion in this case.
668
+ var selectedNode=selection.anchor.getNode();var selectedNodeText=selectedNode.getTextContent();// When the target node has `canInsertTextAfter` set to false, the first deletion
669
+ // doesn't have an effect, so we need to handle it with Lexical.
670
+ var selectedNodeCanInsertTextAfter=selectedNode.canInsertTextAfter();var hasSelectedAllTextInNode=selection.anchor.offset===0&&selection.focus.offset===selectedNodeText.length;var shouldLetBrowserHandleDelete=IS_ANDROID_CHROME&&isSelectionAnchorSameAsFocus&&!hasSelectedAllTextInNode&&selectedNodeCanInsertTextAfter;// Check if selection is collapsed and if the previous node is a decorator node
671
+ // If so, the browser will not be able to handle the deletion
672
+ if(shouldLetBrowserHandleDelete&&selection.isCollapsed()){shouldLetBrowserHandleDelete=!$isDecoratorNode($getAdjacentNode(selection.anchor,true));}if(!shouldLetBrowserHandleDelete){_dispatchCommand(editor,DELETE_CHARACTER_COMMAND,true);// When deleting across paragraphs, Chrome on Android incorrectly shifts the selection rightwards
673
+ // We save the correct selection to restore later during handling of selectionchange event
674
+ var selectionAfterDelete=$getSelection();if(IS_ANDROID_CHROME&&$isRangeSelection(selectionAfterDelete)&&selectionAfterDelete.isCollapsed()){postDeleteSelectionToRestore=selectionAfterDelete;// Cleanup in case selectionchange does not fire
675
+ setTimeout(function(){return postDeleteSelectionToRestore=null;});}}}return true;}}if(!$isRangeSelection(selection)){return true;}var data=event.data;// This represents the case when two beforeinput events are triggered at the same time (without a
676
+ // full event loop ending at input). This happens with MacOS with the default keyboard settings,
677
+ // a combination of autocorrection + autocapitalization.
678
+ // Having Lexical run everything in controlled mode would fix the issue without additional code
679
+ // but this would kill the massive performance win from the most common typing event.
680
+ // Alternatively, when this happens we can prematurely update our EditorState based on the DOM
681
+ // content, a job that would usually be the input event's responsibility.
682
+ if(unprocessedBeforeInputData!==null){$updateSelectedTextFromDOM(false,editor,unprocessedBeforeInputData);}if((!selection.dirty||unprocessedBeforeInputData!==null)&&selection.isCollapsed()&&!$isRootNode(selection.anchor.getNode())&&targetRange!==null){selection.applyDOMRange(targetRange);}unprocessedBeforeInputData=null;var anchor=selection.anchor;var focus=selection.focus;var anchorNode=anchor.getNode();var focusNode=focus.getNode();if(inputType==='insertText'||inputType==='insertTranspose'){if(data==='\n'){event.preventDefault();_dispatchCommand(editor,INSERT_LINE_BREAK_COMMAND,false);}else if(data===DOUBLE_LINE_BREAK){event.preventDefault();_dispatchCommand(editor,INSERT_PARAGRAPH_COMMAND,undefined);}else if(data==null&&event.dataTransfer){// Gets around a Safari text replacement bug.
683
+ var text=event.dataTransfer.getData('text/plain');event.preventDefault();selection.insertRawText(text);}else if(data!=null&&$shouldPreventDefaultAndInsertText(selection,targetRange,data,event.timeStamp,true)){event.preventDefault();_dispatchCommand(editor,CONTROLLED_TEXT_INSERTION_COMMAND,data);}else{unprocessedBeforeInputData=data;}lastBeforeInputInsertTextTimeStamp=event.timeStamp;return true;}// Prevent the browser from carrying out
684
+ // the input event, so we can control the
685
+ // output.
686
+ event.preventDefault();switch(inputType){case'insertFromYank':case'insertFromDrop':case'insertReplacementText':{_dispatchCommand(editor,CONTROLLED_TEXT_INSERTION_COMMAND,event);break;}case'insertFromComposition':{// This is the end of composition
687
+ $setCompositionKey(null);_dispatchCommand(editor,CONTROLLED_TEXT_INSERTION_COMMAND,event);break;}case'insertLineBreak':{// Used for Android
688
+ $setCompositionKey(null);_dispatchCommand(editor,INSERT_LINE_BREAK_COMMAND,false);break;}case'insertParagraph':{// Used for Android
689
+ $setCompositionKey(null);// Safari does not provide the type "insertLineBreak".
690
+ // So instead, we need to infer it from the keyboard event.
691
+ // We do not apply this logic to iOS to allow newline auto-capitalization
692
+ // work without creating linebreaks when pressing Enter
693
+ if(isInsertLineBreak&&!IS_IOS){isInsertLineBreak=false;_dispatchCommand(editor,INSERT_LINE_BREAK_COMMAND,false);}else{_dispatchCommand(editor,INSERT_PARAGRAPH_COMMAND,undefined);}break;}case'insertFromPaste':case'insertFromPasteAsQuotation':{_dispatchCommand(editor,PASTE_COMMAND,event);break;}case'deleteByComposition':{if($canRemoveText(anchorNode,focusNode)){_dispatchCommand(editor,REMOVE_TEXT_COMMAND,event);}break;}case'deleteByDrag':case'deleteByCut':{_dispatchCommand(editor,REMOVE_TEXT_COMMAND,event);break;}case'deleteContent':{_dispatchCommand(editor,DELETE_CHARACTER_COMMAND,false);break;}case'deleteWordBackward':{_dispatchCommand(editor,DELETE_WORD_COMMAND,true);break;}case'deleteWordForward':{_dispatchCommand(editor,DELETE_WORD_COMMAND,false);break;}case'deleteHardLineBackward':case'deleteSoftLineBackward':{_dispatchCommand(editor,DELETE_LINE_COMMAND,true);break;}case'deleteContentForward':case'deleteHardLineForward':case'deleteSoftLineForward':{_dispatchCommand(editor,DELETE_LINE_COMMAND,false);break;}case'formatStrikeThrough':{_dispatchCommand(editor,FORMAT_TEXT_COMMAND,'strikethrough');break;}case'formatBold':{_dispatchCommand(editor,FORMAT_TEXT_COMMAND,'bold');break;}case'formatItalic':{_dispatchCommand(editor,FORMAT_TEXT_COMMAND,'italic');break;}case'formatUnderline':{_dispatchCommand(editor,FORMAT_TEXT_COMMAND,'underline');break;}case'historyUndo':{_dispatchCommand(editor,UNDO_COMMAND,undefined);break;}case'historyRedo':{_dispatchCommand(editor,REDO_COMMAND,undefined);break;}// NO-OP
694
+ }return true;}function onInput(event,editor){// Note that the MutationObserver may or may not have already fired,
695
+ // but the the DOM and selection may have already changed.
696
+ // See also:
697
+ // - https://github.com/facebook/lexical/issues/7028
698
+ // - https://github.com/facebook/lexical/pull/794
699
+ // We don't want the onInput to bubble, in the case of nested editors.
700
+ event.stopPropagation();updateEditorSync(editor,function(){editor.dispatchCommand(INPUT_COMMAND,event);},{event:event});unprocessedBeforeInputData=null;}function $handleInput(event){if(isHTMLElement(event.target)&&$isSelectionCapturedInDecorator(event.target)){return true;}var editor=getActiveEditor();var selection=$getSelection();var data=event.data;var targetRange=getTargetRange(event);if(data!=null&&$isRangeSelection(selection)&&$shouldPreventDefaultAndInsertText(selection,targetRange,data,event.timeStamp,false)){// Given we're over-riding the default behavior, we will need
701
+ // to ensure to disable composition before dispatching the
702
+ // insertText command for when changing the sequence for FF.
703
+ if(isFirefoxEndingComposition){$onCompositionEndImpl(editor,data);isFirefoxEndingComposition=false;}var anchor=selection.anchor;var anchorNode=anchor.getNode();var domSelection=getDOMSelection(getWindow(editor));if(domSelection===null){return true;}var isBackward=selection.isBackward();var startOffset=isBackward?selection.anchor.offset:selection.focus.offset;var endOffset=isBackward?selection.focus.offset:selection.anchor.offset;// If the content is the same as inserted, then don't dispatch an insertion.
704
+ // Given onInput doesn't take the current selection (it uses the previous)
705
+ // we can compare that against what the DOM currently says.
706
+ if(!CAN_USE_BEFORE_INPUT||selection.isCollapsed()||!$isTextNode(anchorNode)||domSelection.anchorNode===null||anchorNode.getTextContent().slice(0,startOffset)+data+anchorNode.getTextContent().slice(startOffset+endOffset)!==getAnchorTextFromDOM(domSelection.anchorNode)){_dispatchCommand(editor,CONTROLLED_TEXT_INSERTION_COMMAND,data);}var textLength=data.length;// Another hack for FF, as it's possible that the IME is still
707
+ // open, even though compositionend has already fired (sigh).
708
+ if(IS_FIREFOX&&textLength>1&&event.inputType==='insertCompositionText'&&!editor.isComposing()){selection.anchor.offset-=textLength;}// This ensures consistency on Android.
709
+ if(!IS_SAFARI&&!IS_IOS&&!IS_APPLE_WEBKIT&&editor.isComposing()){lastKeyDownTimeStamp=0;$setCompositionKey(null);}}else{var characterData=data!==null?data:undefined;$updateSelectedTextFromDOM(false,editor,characterData);// onInput always fires after onCompositionEnd for FF.
710
+ if(isFirefoxEndingComposition){$onCompositionEndImpl(editor,data||undefined);isFirefoxEndingComposition=false;}}// Also flush any other mutations that might have occurred
711
+ // since the change.
712
+ $flushMutations();return true;}function onCompositionStart(event,editor){_dispatchCommand(editor,COMPOSITION_START_COMMAND,event);}function $handleCompositionStart(event){var editor=getActiveEditor();var selection=$getSelection();if($isRangeSelection(selection)&&!editor.isComposing()){var anchor=selection.anchor;var node=selection.anchor.getNode();$setCompositionKey(anchor.key);if(// If it has been 30ms since the last keydown, then we should
713
+ // apply the empty space heuristic. We can't do this for Safari,
714
+ // as the keydown fires after composition start.
715
+ event.timeStamp<lastKeyDownTimeStamp+ANDROID_COMPOSITION_LATENCY||// FF has issues around composing multibyte characters, so we also
716
+ // need to invoke the empty space heuristic below.
717
+ anchor.type==='element'||!selection.isCollapsed()||node.getFormat()!==selection.format||$isTextNode(node)&&node.getStyle()!==selection.style){// We insert a zero width character, ready for the composition
718
+ // to get inserted into the new node we create. If
719
+ // we don't do this, Safari will fail on us because
720
+ // there is no text node matching the selection.
721
+ _dispatchCommand(editor,CONTROLLED_TEXT_INSERTION_COMMAND,COMPOSITION_START_CHAR);}}return true;}function $handleCompositionEnd(event){var editor=getActiveEditor();$onCompositionEndImpl(editor,event.data);return true;}function $onCompositionEndImpl(editor,data){var compositionKey=editor._compositionKey;$setCompositionKey(null);// Handle termination of composition.
722
+ if(compositionKey!==null&&data!=null){// Composition can sometimes move to an adjacent DOM node when backspacing.
723
+ // So check for the empty case.
724
+ if(data===''){var node=$getNodeByKey(compositionKey);var textNode=getDOMTextNode(editor.getElementByKey(compositionKey));if(textNode!==null&&textNode.nodeValue!==null&&$isTextNode(node)){$updateTextNodeFromDOMContent(node,textNode.nodeValue,null,null,true);}return;}// Composition can sometimes be that of a new line. In which case, we need to
725
+ // handle that accordingly.
726
+ if(data[data.length-1]==='\n'){var selection=$getSelection();if($isRangeSelection(selection)){// If the last character is a line break, we also need to insert
727
+ // a line break.
728
+ var focus=selection.focus;selection.anchor.set(focus.key,focus.offset,focus.type);_dispatchCommand(editor,KEY_ENTER_COMMAND,null);return;}}}$updateSelectedTextFromDOM(true,editor,data);}function onCompositionEnd(event,editor){// Firefox fires onCompositionEnd before onInput, but Chrome/Webkit,
729
+ // fire onInput before onCompositionEnd. To ensure the sequence works
730
+ // like Chrome/Webkit we use the isFirefoxEndingComposition flag to
731
+ // defer handling of onCompositionEnd in Firefox till we have processed
732
+ // the logic in onInput.
733
+ if(IS_FIREFOX){isFirefoxEndingComposition=true;}else if(!IS_IOS&&(IS_SAFARI||IS_APPLE_WEBKIT)){// Fix:https://github.com/facebook/lexical/pull/7061
734
+ // In safari, onCompositionEnd triggers before keydown
735
+ // This will cause an extra character to be deleted when exiting the IME
736
+ // Therefore, a flag is used to mark that the keydown event is triggered after onCompositionEnd
737
+ // Ensure that an extra character is not deleted due to the backspace event being triggered in the keydown event.
738
+ isSafariEndingComposition=true;safariEndCompositionEventData=event.data;}else{_dispatchCommand(editor,COMPOSITION_END_COMMAND,event);}}function onKeyDown(event,editor){lastKeyDownTimeStamp=event.timeStamp;lastKeyCode=event.key;if(editor.isComposing()){return;}_dispatchCommand(editor,KEY_DOWN_COMMAND,event);}function $handleKeyDown(event){var editor=getActiveEditor();if(event.key==null){return true;}if(isSafariEndingComposition&&isBackspace(event)){updateEditorSync(editor,function(){$onCompositionEndImpl(editor,safariEndCompositionEventData);});isSafariEndingComposition=false;safariEndCompositionEventData='';return true;}if(isMoveForward(event)){_dispatchCommand(editor,KEY_ARROW_RIGHT_COMMAND,event);}else if(isMoveToEnd(event)){_dispatchCommand(editor,MOVE_TO_END,event);}else if(isMoveBackward(event)){_dispatchCommand(editor,KEY_ARROW_LEFT_COMMAND,event);}else if(isMoveToStart(event)){_dispatchCommand(editor,MOVE_TO_START,event);}else if(isMoveUp(event)){_dispatchCommand(editor,KEY_ARROW_UP_COMMAND,event);}else if(isMoveDown(event)){_dispatchCommand(editor,KEY_ARROW_DOWN_COMMAND,event);}else if(isLineBreak(event)){isInsertLineBreak=true;_dispatchCommand(editor,KEY_ENTER_COMMAND,event);}else if(isSpace(event)){_dispatchCommand(editor,KEY_SPACE_COMMAND,event);}else if(isOpenLineBreak(event)){event.preventDefault();isInsertLineBreak=true;_dispatchCommand(editor,INSERT_LINE_BREAK_COMMAND,true);}else if(isParagraph(event)){isInsertLineBreak=false;_dispatchCommand(editor,KEY_ENTER_COMMAND,event);}else if(isDeleteBackward(event)){if(isBackspace(event)){_dispatchCommand(editor,KEY_BACKSPACE_COMMAND,event);}else{event.preventDefault();_dispatchCommand(editor,DELETE_CHARACTER_COMMAND,true);}}else if(isEscape(event)){_dispatchCommand(editor,KEY_ESCAPE_COMMAND,event);}else if(isDeleteForward(event)){if(isDelete(event)){_dispatchCommand(editor,KEY_DELETE_COMMAND,event);}else{event.preventDefault();_dispatchCommand(editor,DELETE_CHARACTER_COMMAND,false);}}else if(isDeleteWordBackward(event)){event.preventDefault();_dispatchCommand(editor,DELETE_WORD_COMMAND,true);}else if(isDeleteWordForward(event)){event.preventDefault();_dispatchCommand(editor,DELETE_WORD_COMMAND,false);}else if(isDeleteLineBackward(event)){event.preventDefault();_dispatchCommand(editor,DELETE_LINE_COMMAND,true);}else if(isDeleteLineForward(event)){event.preventDefault();_dispatchCommand(editor,DELETE_LINE_COMMAND,false);}else if(isBold(event)){event.preventDefault();_dispatchCommand(editor,FORMAT_TEXT_COMMAND,'bold');}else if(isUnderline(event)){event.preventDefault();_dispatchCommand(editor,FORMAT_TEXT_COMMAND,'underline');}else if(isItalic(event)){event.preventDefault();_dispatchCommand(editor,FORMAT_TEXT_COMMAND,'italic');}else if(isTab(event)){_dispatchCommand(editor,KEY_TAB_COMMAND,event);}else if(isUndo(event)){event.preventDefault();_dispatchCommand(editor,UNDO_COMMAND,undefined);}else if(isRedo(event)){event.preventDefault();_dispatchCommand(editor,REDO_COMMAND,undefined);}else{var prevSelection=editor._editorState._selection;if(prevSelection!==null&&!$isRangeSelection(prevSelection)){// Only RangeSelection can use the native cut/copy/select all
739
+ if(isCopy(event)){event.preventDefault();_dispatchCommand(editor,COPY_COMMAND,event);}else if(isCut(event)){event.preventDefault();_dispatchCommand(editor,CUT_COMMAND,event);}else if(isSelectAll(event)){event.preventDefault();_dispatchCommand(editor,SELECT_ALL_COMMAND,event);}}else if(isSelectAll(event)){event.preventDefault();_dispatchCommand(editor,SELECT_ALL_COMMAND,event);}}if(isModifier(event)){editor.dispatchCommand(KEY_MODIFIER_COMMAND,event);}return true;}function getRootElementRemoveHandles(rootElement){// @ts-expect-error: internal field
740
+ var eventHandles=rootElement.__lexicalEventHandles;if(eventHandles===undefined){eventHandles=[];// @ts-expect-error: internal field
741
+ rootElement.__lexicalEventHandles=eventHandles;}return eventHandles;}// Mapping root editors to their active nested editors, contains nested editors
742
+ // mapping only, so if root editor is selected map will have no reference to free up memory
743
+ var activeNestedEditorsMap=new Map();function onDocumentSelectionChange(event){var domSelection=getDOMSelectionFromTarget(event.target);if(domSelection===null){return;}var nextActiveEditor=getNearestEditorFromDOMNode(domSelection.anchorNode);if(nextActiveEditor===null){return;}if(isSelectionChangeFromMouseDown){isSelectionChangeFromMouseDown=false;updateEditorSync(nextActiveEditor,function(){var lastSelection=$getPreviousSelection();var domAnchorNode=domSelection.anchorNode;if(isHTMLElement(domAnchorNode)||isDOMTextNode(domAnchorNode)){// If the user is attempting to click selection back onto text, then
744
+ // we should attempt create a range selection.
745
+ // When we click on an empty paragraph node or the end of a paragraph that ends
746
+ // with an image/poll, the nodeType will be ELEMENT_NODE
747
+ var newSelection=$internalCreateRangeSelection(lastSelection,domSelection,nextActiveEditor,event);$setSelection(newSelection);}});}// When editor receives selection change event, we're checking if
748
+ // it has any sibling editors (within same parent editor) that were active
749
+ // before, and trigger selection change on it to nullify selection.
750
+ var editors=getEditorsToPropagate(nextActiveEditor);var rootEditor=editors[editors.length-1];var rootEditorKey=rootEditor._key;var activeNestedEditor=activeNestedEditorsMap.get(rootEditorKey);var prevActiveEditor=activeNestedEditor||rootEditor;if(prevActiveEditor!==nextActiveEditor){onSelectionChange(domSelection,prevActiveEditor,false);}onSelectionChange(domSelection,nextActiveEditor,true);// If newly selected editor is nested, then add it to the map, clean map otherwise
751
+ if(nextActiveEditor!==rootEditor){activeNestedEditorsMap.set(rootEditorKey,nextActiveEditor);}else if(activeNestedEditor){activeNestedEditorsMap.delete(rootEditorKey);}}function stopLexicalPropagation(event){// We attach a special property to ensure the same event doesn't re-fire
752
+ // for parent editors.
753
+ // @ts-ignore
754
+ event._lexicalHandled=true;}function hasStoppedLexicalPropagation(event){// @ts-ignore
755
+ var stopped=event._lexicalHandled===true;return stopped;}function addRootElementEvents(rootElement,editor){var _rootElementsRegister;// We only want to have a single global selectionchange event handler, shared
756
+ // between all editor instances.
757
+ var doc=rootElement.ownerDocument;rootElementToDocument.set(rootElement,doc);var documentRootElementsCount=(_rootElementsRegister=rootElementsRegistered.get(doc))!==null&&_rootElementsRegister!==void 0?_rootElementsRegister:0;if(documentRootElementsCount<1){doc.addEventListener('selectionchange',onDocumentSelectionChange);}rootElementsRegistered.set(doc,documentRootElementsCount+1);// @ts-expect-error: internal field
758
+ rootElement.__lexicalEditor=editor;var removeHandles=getRootElementRemoveHandles(rootElement);var _loop=function _loop(){var _rootElementEvents$i=_slicedToArray(rootElementEvents[i],2),eventName=_rootElementEvents$i[0],onEvent=_rootElementEvents$i[1];var eventHandler=typeof onEvent==='function'?function(event){if(hasStoppedLexicalPropagation(event)){return;}stopLexicalPropagation(event);if(editor.isEditable()||eventName==='click'){onEvent(event,editor);}}:function(event){if(hasStoppedLexicalPropagation(event)){return;}stopLexicalPropagation(event);var isEditable=editor.isEditable();switch(eventName){case'cut':return isEditable&&_dispatchCommand(editor,CUT_COMMAND,event);case'copy':return _dispatchCommand(editor,COPY_COMMAND,event);case'paste':return isEditable&&_dispatchCommand(editor,PASTE_COMMAND,event);case'dragstart':return isEditable&&_dispatchCommand(editor,DRAGSTART_COMMAND,event);case'dragover':return isEditable&&_dispatchCommand(editor,DRAGOVER_COMMAND,event);case'dragend':return isEditable&&_dispatchCommand(editor,DRAGEND_COMMAND,event);case'focus':return isEditable&&_dispatchCommand(editor,FOCUS_COMMAND,event);case'blur':{return isEditable&&_dispatchCommand(editor,BLUR_COMMAND,event);}case'drop':return isEditable&&_dispatchCommand(editor,DROP_COMMAND,event);}};rootElement.addEventListener(eventName,eventHandler);removeHandles.push(function(){rootElement.removeEventListener(eventName,eventHandler);});};for(var i=0;i<rootElementEvents.length;i++){_loop();}}var rootElementNotRegisteredWarning=warnOnlyOnce('Root element not registered');function removeRootElementEvents(rootElement){var doc=rootElementToDocument.get(rootElement);if(doc===undefined){rootElementNotRegisteredWarning();return;}var documentRootElementsCount=rootElementsRegistered.get(doc);if(documentRootElementsCount===undefined){// This can happen if setRootElement() failed
759
+ rootElementNotRegisteredWarning();return;}// We only want to have a single global selectionchange event handler, shared
760
+ // between all editor instances.
761
+ var newCount=documentRootElementsCount-1;if(!(newCount>=0)){formatDevErrorMessage("Root element count less than 0");}rootElementToDocument.delete(rootElement);rootElementsRegistered.set(doc,newCount);if(newCount===0){doc.removeEventListener('selectionchange',onDocumentSelectionChange);}var editor=getEditorPropertyFromDOMNode(rootElement);if(isLexicalEditor(editor)){cleanActiveNestedEditorsMap(editor);// @ts-expect-error: internal field
762
+ rootElement.__lexicalEditor=null;}else if(editor){{formatDevErrorMessage("Attempted to remove event handlers from a node that does not belong to this build of Lexical");}}var removeHandles=getRootElementRemoveHandles(rootElement);for(var i=0;i<removeHandles.length;i++){removeHandles[i]();}// @ts-expect-error: internal field
763
+ rootElement.__lexicalEventHandles=[];}function cleanActiveNestedEditorsMap(editor){if(editor._parentEditor!==null){// For nested editor cleanup map if this editor was marked as active
764
+ var editors=getEditorsToPropagate(editor);var rootEditor=editors[editors.length-1];var rootEditorKey=rootEditor._key;if(activeNestedEditorsMap.get(rootEditorKey)===editor){activeNestedEditorsMap.delete(rootEditorKey);}}else{// For top-level editors cleanup map
765
+ activeNestedEditorsMap.delete(editor._key);}}function markSelectionChangeFromDOMUpdate(){isSelectionChangeFromDOMUpdate=true;}function markCollapsedSelectionFormat(format,style,offset,key,timeStamp){collapsedSelectionFormat=[format,style,offset,key,timeStamp];}/**
766
+ * The base type for all serialized nodes
767
+ */ /**
768
+ * EXPERIMENTAL
769
+ * The configuration of a node returned by LexicalNode.$config()
770
+ *
771
+ * @example
772
+ * ```ts
773
+ * class CustomText extends TextNode {
774
+ * $config() {
775
+ * return this.config('custom-text', {extends: TextNode}};
776
+ * }
777
+ * }
778
+ * ```
779
+ */ /**
780
+ * This is the type of LexicalNode.$config() that can be
781
+ * overridden by subclasses.
782
+ */ /**
783
+ * Used to extract the node and type from a StaticNodeConfigRecord
784
+ */ /**
785
+ * Any StaticNodeConfigValue (for generics and collections)
786
+ */ // eslint-disable-next-line @typescript-eslint/no-explicit-any
787
+ /**
788
+ * @internal
789
+ *
790
+ * This is the more specific type than BaseStaticNodeConfig that a subclass
791
+ * should return from $config()
792
+ */ /**
793
+ * Extract the type from a node based on its $config
794
+ *
795
+ * @example
796
+ * ```ts
797
+ * type TextNodeType = GetStaticNodeType<TextNode>;
798
+ * // ? 'text'
799
+ * ```
800
+ */ /**
801
+ * The most precise type we can infer for the JSON that will
802
+ * be produced by T.exportJSON().
803
+ *
804
+ * Do not use this for the return type of T.exportJSON()! It must be
805
+ * a more generic type to be compatible with subclassing.
806
+ */ /**
807
+ * Omit the children, type, and version properties from the given SerializedLexicalNode definition.
808
+ */ /** @internal */function $removeNode(nodeToRemove,restoreSelection,preserveEmptyParent){errorOnReadOnly();var key=nodeToRemove.__key;var parent=nodeToRemove.getParent();if(parent===null){return;}var selection=$maybeMoveChildrenSelectionToParent(nodeToRemove);var selectionMoved=false;if($isRangeSelection(selection)&&restoreSelection){var anchor=selection.anchor;var focus=selection.focus;if(anchor.key===key){moveSelectionPointToSibling(anchor,nodeToRemove,parent,nodeToRemove.getPreviousSibling(),nodeToRemove.getNextSibling());selectionMoved=true;}if(focus.key===key){moveSelectionPointToSibling(focus,nodeToRemove,parent,nodeToRemove.getPreviousSibling(),nodeToRemove.getNextSibling());selectionMoved=true;}}else if($isNodeSelection(selection)&&restoreSelection&&nodeToRemove.isSelected()){nodeToRemove.selectPrevious();}if($isRangeSelection(selection)&&restoreSelection&&!selectionMoved){// Doing this is O(n) so lets avoid it unless we need to do it
809
+ var index=nodeToRemove.getIndexWithinParent();removeFromParent(nodeToRemove);$updateElementSelectionOnCreateDeleteNode(selection,parent,index,-1);}else{removeFromParent(nodeToRemove);}if(!preserveEmptyParent&&!$isRootOrShadowRoot(parent)&&!parent.canBeEmpty()&&parent.isEmpty()){$removeNode(parent,restoreSelection);}if(restoreSelection&&selection&&$isRootNode(parent)&&parent.isEmpty()){parent.selectEnd();}}/**
810
+ * An identity function that will infer the type of DOM nodes
811
+ * based on tag names to make it easier to construct a
812
+ * DOMConversionMap.
813
+ */function buildImportMap(importMap){return importMap;}var EPHEMERAL=Symbol.for('ephemeral');/**
814
+ * @internal
815
+ * @param node any LexicalNode
816
+ * @returns true if the node was created with {@link $cloneWithPropertiesEphemeral}
817
+ */function $isEphemeral(node){return node[EPHEMERAL]||false;}/**
818
+ * @internal
819
+ * Mark this node as ephemeral, its instance always returns this
820
+ * for getLatest and getWritable. It must not be added to an EditorState.
821
+ */function $markEphemeral(node){node[EPHEMERAL]=true;return node;}var LexicalNode=/*#__PURE__*/function(){function LexicalNode(key){_classCallCheck(this,LexicalNode);/** @internal Allow us to look up the type including static props */ /** @internal */_defineProperty(this,"__type",void 0);/** @internal */ //@ts-ignore We set the key in the constructor.
822
+ _defineProperty(this,"__key",void 0);/** @internal */_defineProperty(this,"__parent",void 0);/** @internal */_defineProperty(this,"__prev",void 0);/** @internal */_defineProperty(this,"__next",void 0);/** @internal */_defineProperty(this,"__state",void 0);this.__type=this.constructor.getType();this.__parent=null;this.__prev=null;this.__next=null;Object.defineProperty(this,'__state',{configurable:true,enumerable:false,value:undefined,writable:true});$setNodeKey(this,key);{if(this.__type!=='root'){errorOnTypeKlassMismatch(this.__type,this.constructor);}}}// Getters and Traversers
823
+ /**
824
+ * Returns the string type of this node.
825
+ */_createClass(LexicalNode,[{key:"$config",value:/**
826
+ * Override this to implement the new static node configuration protocol,
827
+ * this method is called directly on the prototype and must not depend
828
+ * on anything initialized in the constructor. Generally it should be
829
+ * a trivial implementation.
830
+ *
831
+ * @example
832
+ * ```ts
833
+ * class MyNode extends TextNode {
834
+ * $config() {
835
+ * return this.config('my-node', {extends: TextNode});
836
+ * }
837
+ * }
838
+ * ```
839
+ */function $config(){return{};}/**
840
+ * This is a convenience method for $config that
841
+ * aids in type inference. See {@link LexicalNode.$config}
842
+ * for example usage.
843
+ */},{key:"config",value:function config(type,_config2){var parentKlass=_config2.extends||Object.getPrototypeOf(this.constructor);Object.assign(_config2,{extends:parentKlass,type:type});return _defineProperty({},type,_config2);}/**
844
+ * Perform any state updates on the clone of prevNode that are not already
845
+ * handled by the constructor call in the static clone method. If you have
846
+ * state to update in your clone that is not handled directly by the
847
+ * constructor, it is advisable to override this method but it is required
848
+ * to include a call to `super.afterCloneFrom(prevNode)` in your
849
+ * implementation. This is only intended to be called by
850
+ * {@link $cloneWithProperties} function or via a super call.
851
+ *
852
+ * @example
853
+ * ```ts
854
+ * class ClassesTextNode extends TextNode {
855
+ * // Not shown: static getType, static importJSON, exportJSON, createDOM, updateDOM
856
+ * __classes = new Set<string>();
857
+ * static clone(node: ClassesTextNode): ClassesTextNode {
858
+ * // The inherited TextNode constructor is used here, so
859
+ * // classes is not set by this method.
860
+ * return new ClassesTextNode(node.__text, node.__key);
861
+ * }
862
+ * afterCloneFrom(node: this): void {
863
+ * // This calls TextNode.afterCloneFrom and LexicalNode.afterCloneFrom
864
+ * // for necessary state updates
865
+ * super.afterCloneFrom(node);
866
+ * this.__addClasses(node.__classes);
867
+ * }
868
+ * // This method is a private implementation detail, it is not
869
+ * // suitable for the public API because it does not call getWritable
870
+ * __addClasses(classNames: Iterable<string>): this {
871
+ * for (const className of classNames) {
872
+ * this.__classes.add(className);
873
+ * }
874
+ * return this;
875
+ * }
876
+ * addClass(...classNames: string[]): this {
877
+ * return this.getWritable().__addClasses(classNames);
878
+ * }
879
+ * removeClass(...classNames: string[]): this {
880
+ * const node = this.getWritable();
881
+ * for (const className of classNames) {
882
+ * this.__classes.delete(className);
883
+ * }
884
+ * return this;
885
+ * }
886
+ * getClasses(): Set<string> {
887
+ * return this.getLatest().__classes;
888
+ * }
889
+ * }
890
+ * ```
891
+ *
892
+ */},{key:"afterCloneFrom",value:function afterCloneFrom(prevNode){if(this.__key===prevNode.__key){this.__parent=prevNode.__parent;this.__next=prevNode.__next;this.__prev=prevNode.__prev;this.__state=prevNode.__state;}else if(prevNode.__state){this.__state=prevNode.__state.getWritable(this);}}// eslint-disable-next-line @typescript-eslint/no-explicit-any
893
+ },{key:"getType",value:function getType(){return this.__type;}},{key:"isInline",value:function isInline(){{formatDevErrorMessage("LexicalNode: Node ".concat(this.constructor.name," does not implement .isInline()."));}}/**
894
+ * Returns true if there is a path between this node and the RootNode, false otherwise.
895
+ * This is a way of determining if the node is "attached" EditorState. Unattached nodes
896
+ * won't be reconciled and will ultimately be cleaned up by the Lexical GC.
897
+ */},{key:"isAttached",value:function isAttached(){var nodeKey=this.__key;while(nodeKey!==null){if(nodeKey==='root'){return true;}var node=$getNodeByKey(nodeKey);if(node===null){break;}nodeKey=node.__parent;}return false;}/**
898
+ * Returns true if this node is contained within the provided Selection., false otherwise.
899
+ * Relies on the algorithms implemented in {@link BaseSelection.getNodes} to determine
900
+ * what's included.
901
+ *
902
+ * @param selection - The selection that we want to determine if the node is in.
903
+ */},{key:"isSelected",value:function isSelected(selection){var _this=this;var targetSelection=selection||$getSelection();if(targetSelection==null){return false;}var isSelected=targetSelection.getNodes().some(function(n){return n.__key===_this.__key;});if($isTextNode(this)){return isSelected;}// For inline images inside of element nodes.
904
+ // Without this change the image will be selected if the cursor is before or after it.
905
+ var isElementRangeSelection=$isRangeSelection(targetSelection)&&targetSelection.anchor.type==='element'&&targetSelection.focus.type==='element';if(isElementRangeSelection){if(targetSelection.isCollapsed()){return false;}var parentNode=this.getParent();if($isDecoratorNode(this)&&this.isInline()&&parentNode){var firstPoint=targetSelection.isBackward()?targetSelection.focus:targetSelection.anchor;if(parentNode.is(firstPoint.getNode())&&firstPoint.offset===parentNode.getChildrenSize()&&this.is(parentNode.getLastChild())){return false;}}}return isSelected;}/**
906
+ * Returns this nodes key.
907
+ */},{key:"getKey",value:function getKey(){// Key is stable between copies
908
+ return this.__key;}/**
909
+ * Returns the zero-based index of this node within the parent.
910
+ */},{key:"getIndexWithinParent",value:function getIndexWithinParent(){var parent=this.getParent();if(parent===null){return-1;}var node=parent.getFirstChild();var index=0;while(node!==null){if(this.is(node)){return index;}index++;node=node.getNextSibling();}return-1;}/**
911
+ * Returns the parent of this node, or null if none is found.
912
+ */},{key:"getParent",value:function getParent(){var parent=this.getLatest().__parent;if(parent===null){return null;}return $getNodeByKey(parent);}/**
913
+ * Returns the parent of this node, or throws if none is found.
914
+ */},{key:"getParentOrThrow",value:function getParentOrThrow(){var parent=this.getParent();if(parent===null){{formatDevErrorMessage("Expected node ".concat(this.__key," to have a parent."));}}return parent;}/**
915
+ * Returns the highest (in the EditorState tree)
916
+ * non-root ancestor of this node, or null if none is found. See {@link lexical!$isRootOrShadowRoot}
917
+ * for more information on which Elements comprise "roots".
918
+ */},{key:"getTopLevelElement",value:function getTopLevelElement(){var node=this;while(node!==null){var parent=node.getParent();if($isRootOrShadowRoot(parent)){if(!($isElementNode(node)||node===this&&$isDecoratorNode(node))){formatDevErrorMessage("Children of root nodes must be elements or decorators");}return node;}node=parent;}return null;}/**
919
+ * Returns the highest (in the EditorState tree)
920
+ * non-root ancestor of this node, or throws if none is found. See {@link lexical!$isRootOrShadowRoot}
921
+ * for more information on which Elements comprise "roots".
922
+ */},{key:"getTopLevelElementOrThrow",value:function getTopLevelElementOrThrow(){var parent=this.getTopLevelElement();if(parent===null){{formatDevErrorMessage("Expected node ".concat(this.__key," to have a top parent element."));}}return parent;}/**
923
+ * Returns a list of the every ancestor of this node,
924
+ * all the way up to the RootNode.
925
+ *
926
+ */},{key:"getParents",value:function getParents(){var parents=[];var node=this.getParent();while(node!==null){parents.push(node);node=node.getParent();}return parents;}/**
927
+ * Returns a list of the keys of every ancestor of this node,
928
+ * all the way up to the RootNode.
929
+ *
930
+ */},{key:"getParentKeys",value:function getParentKeys(){var parents=[];var node=this.getParent();while(node!==null){parents.push(node.__key);node=node.getParent();}return parents;}/**
931
+ * Returns the "previous" siblings - that is, the node that comes
932
+ * before this one in the same parent.
933
+ *
934
+ */},{key:"getPreviousSibling",value:function getPreviousSibling(){var self=this.getLatest();var prevKey=self.__prev;return prevKey===null?null:$getNodeByKey(prevKey);}/**
935
+ * Returns the "previous" siblings - that is, the nodes that come between
936
+ * this one and the first child of it's parent, inclusive.
937
+ *
938
+ */},{key:"getPreviousSiblings",value:function getPreviousSiblings(){var siblings=[];var parent=this.getParent();if(parent===null){return siblings;}var node=parent.getFirstChild();while(node!==null){if(node.is(this)){break;}siblings.push(node);node=node.getNextSibling();}return siblings;}/**
939
+ * Returns the "next" siblings - that is, the node that comes
940
+ * after this one in the same parent
941
+ *
942
+ */},{key:"getNextSibling",value:function getNextSibling(){var self=this.getLatest();var nextKey=self.__next;return nextKey===null?null:$getNodeByKey(nextKey);}/**
943
+ * Returns all "next" siblings - that is, the nodes that come between this
944
+ * one and the last child of it's parent, inclusive.
945
+ *
946
+ */},{key:"getNextSiblings",value:function getNextSiblings(){var siblings=[];var node=this.getNextSibling();while(node!==null){siblings.push(node);node=node.getNextSibling();}return siblings;}/**
947
+ * @deprecated use {@link $getCommonAncestor}
948
+ *
949
+ * Returns the closest common ancestor of this node and the provided one or null
950
+ * if one cannot be found.
951
+ *
952
+ * @param node - the other node to find the common ancestor of.
953
+ */},{key:"getCommonAncestor",value:function getCommonAncestor(node){var a=$isElementNode(this)?this:this.getParent();var b=$isElementNode(node)?node:node.getParent();var result=a&&b?$getCommonAncestor(a,b):null;return result?result.commonAncestor/* TODO this type cast is a lie, but fixing it would break backwards compatibility */:null;}/**
954
+ * Returns true if the provided node is the exact same one as this node, from Lexical's perspective.
955
+ * Always use this instead of referential equality.
956
+ *
957
+ * @param object - the node to perform the equality comparison on.
958
+ */},{key:"is",value:function is(object){if(object==null){return false;}return this.__key===object.__key;}/**
959
+ * Returns true if this node logically precedes the target node in the
960
+ * editor state, false otherwise (including if there is no common ancestor).
961
+ *
962
+ * Note that this notion of isBefore is based on post-order; a descendant
963
+ * node is always before its ancestors. See also
964
+ * {@link $getCommonAncestor} and {@link $comparePointCaretNext} for
965
+ * more flexible ways to determine the relative positions of nodes.
966
+ *
967
+ * @param targetNode - the node we're testing to see if it's after this one.
968
+ */},{key:"isBefore",value:function isBefore(targetNode){var compare=$getCommonAncestor(this,targetNode);if(compare===null){return false;}if(compare.type==='descendant'){return true;}if(compare.type==='branch'){return $getCommonAncestorResultBranchOrder(compare)===-1;}if(!(compare.type==='same'||compare.type==='ancestor')){formatDevErrorMessage("LexicalNode.isBefore: exhaustiveness check");}return false;}/**
969
+ * Returns true if this node is an ancestor of and distinct from the target node, false otherwise.
970
+ *
971
+ * @param targetNode - the would-be child node.
972
+ */},{key:"isParentOf",value:function isParentOf(targetNode){var result=$getCommonAncestor(this,targetNode);return result!==null&&result.type==='ancestor';}// TO-DO: this function can be simplified a lot
973
+ /**
974
+ * Returns a list of nodes that are between this node and
975
+ * the target node in the EditorState.
976
+ *
977
+ * @param targetNode - the node that marks the other end of the range of nodes to be returned.
978
+ */},{key:"getNodesBetween",value:function getNodesBetween(targetNode){var isBefore=this.isBefore(targetNode);var nodes=[];var visited=new Set();var node=this;while(true){if(node===null){break;}var key=node.__key;if(!visited.has(key)){visited.add(key);nodes.push(node);}if(node===targetNode){break;}var child=$isElementNode(node)?isBefore?node.getFirstChild():node.getLastChild():null;if(child!==null){node=child;continue;}var nextSibling=isBefore?node.getNextSibling():node.getPreviousSibling();if(nextSibling!==null){node=nextSibling;continue;}var parent=node.getParentOrThrow();if(!visited.has(parent.__key)){nodes.push(parent);}if(parent===targetNode){break;}var parentSibling=null;var ancestor=parent;do{if(ancestor===null){{formatDevErrorMessage("getNodesBetween: ancestor is null");}}parentSibling=isBefore?ancestor.getNextSibling():ancestor.getPreviousSibling();ancestor=ancestor.getParent();if(ancestor!==null){if(parentSibling===null&&!visited.has(ancestor.__key)){nodes.push(ancestor);}}else{break;}}while(parentSibling===null);node=parentSibling;}if(!isBefore){nodes.reverse();}return nodes;}/**
979
+ * Returns true if this node has been marked dirty during this update cycle.
980
+ *
981
+ */},{key:"isDirty",value:function isDirty(){var editor=getActiveEditor();var dirtyLeaves=editor._dirtyLeaves;return dirtyLeaves!==null&&dirtyLeaves.has(this.__key);}/**
982
+ * Returns the latest version of the node from the active EditorState.
983
+ * This is used to avoid getting values from stale node references.
984
+ *
985
+ */},{key:"getLatest",value:function getLatest(){if($isEphemeral(this)){return this;}var latest=$getNodeByKey(this.__key);if(latest===null){{formatDevErrorMessage("Lexical node does not exist in active editor state. Avoid using the same node references between nested closures from editorState.read/editor.update.");}}return latest;}/**
986
+ * Returns a mutable version of the node using {@link $cloneWithProperties}
987
+ * if necessary. Will throw an error if called outside of a Lexical Editor
988
+ * {@link LexicalEditor.update} callback.
989
+ *
990
+ */},{key:"getWritable",value:function getWritable(){if($isEphemeral(this)){return this;}errorOnReadOnly();var editorState=getActiveEditorState();var editor=getActiveEditor();var nodeMap=editorState._nodeMap;var key=this.__key;// Ensure we get the latest node from pending state
991
+ var latestNode=this.getLatest();var cloneNotNeeded=editor._cloneNotNeeded;var selection=$getSelection();if(selection!==null){selection.setCachedNodes(null);}if(cloneNotNeeded.has(key)){// Transforms clear the dirty node set on each iteration to keep track on newly dirty nodes
992
+ internalMarkNodeAsDirty(latestNode);return latestNode;}var mutableNode=$cloneWithProperties(latestNode);cloneNotNeeded.add(key);internalMarkNodeAsDirty(mutableNode);// Update reference in node map
993
+ nodeMap.set(key,mutableNode);return mutableNode;}/**
994
+ * Returns the text content of the node. Override this for
995
+ * custom nodes that should have a representation in plain text
996
+ * format (for copy + paste, for example)
997
+ *
998
+ */},{key:"getTextContent",value:function getTextContent(){return'';}/**
999
+ * Returns the length of the string produced by calling getTextContent on this node.
1000
+ *
1001
+ */},{key:"getTextContentSize",value:function getTextContentSize(){return this.getTextContent().length;}// View
1002
+ /**
1003
+ * Called during the reconciliation process to determine which nodes
1004
+ * to insert into the DOM for this Lexical Node.
1005
+ *
1006
+ * This method must return exactly one HTMLElement. Nested elements are not supported.
1007
+ *
1008
+ * Do not attempt to update the Lexical EditorState during this phase of the update lifecycle.
1009
+ *
1010
+ * @param _config - allows access to things like the EditorTheme (to apply classes) during reconciliation.
1011
+ * @param _editor - allows access to the editor for context during reconciliation.
1012
+ *
1013
+ * */},{key:"createDOM",value:function createDOM(_config,_editor){{formatDevErrorMessage("createDOM: base method not extended");}}/**
1014
+ * Called when a node changes and should update the DOM
1015
+ * in whatever way is necessary to make it align with any changes that might
1016
+ * have happened during the update.
1017
+ *
1018
+ * Returning "true" here will cause lexical to unmount and recreate the DOM node
1019
+ * (by calling createDOM). You would need to do this if the element tag changes,
1020
+ * for instance.
1021
+ *
1022
+ * */},{key:"updateDOM",value:function updateDOM(_prevNode,_dom,_config){{formatDevErrorMessage("updateDOM: base method not extended");}}/**
1023
+ * Controls how the this node is serialized to HTML. This is important for
1024
+ * copy and paste between Lexical and non-Lexical editors, or Lexical editors with different namespaces,
1025
+ * in which case the primary transfer format is HTML. It's also important if you're serializing
1026
+ * to HTML for any other reason via {@link @lexical/html!$generateHtmlFromNodes}. You could
1027
+ * also use this method to build your own HTML renderer.
1028
+ *
1029
+ * */},{key:"exportDOM",value:function exportDOM(editor){var element=this.createDOM(editor._config,editor);return{element:element};}/**
1030
+ * Controls how the this node is serialized to JSON. This is important for
1031
+ * copy and paste between Lexical editors sharing the same namespace. It's also important
1032
+ * if you're serializing to JSON for persistent storage somewhere.
1033
+ * See [Serialization & Deserialization](https://lexical.dev/docs/concepts/serialization#lexical---html).
1034
+ *
1035
+ * */},{key:"exportJSON",value:function exportJSON(){// eslint-disable-next-line dot-notation
1036
+ var state=this.__state?this.__state.toJSON():undefined;return _objectSpread({type:this.__type,version:1},state);}/**
1037
+ * Controls how the this node is deserialized from JSON. This is usually boilerplate,
1038
+ * but provides an abstraction between the node implementation and serialized interface that can
1039
+ * be important if you ever make breaking changes to a node schema (by adding or removing properties).
1040
+ * See [Serialization & Deserialization](https://lexical.dev/docs/concepts/serialization#lexical---html).
1041
+ *
1042
+ * */},{key:"updateFromJSON",value:/**
1043
+ * Update this LexicalNode instance from serialized JSON. It's recommended
1044
+ * to implement as much logic as possible in this method instead of the
1045
+ * static importJSON method, so that the functionality can be inherited in subclasses.
1046
+ *
1047
+ * The LexicalUpdateJSON utility type should be used to ignore any type, version,
1048
+ * or children properties in the JSON so that the extended JSON from subclasses
1049
+ * are acceptable parameters for the super call.
1050
+ *
1051
+ * If overridden, this method must call super.
1052
+ *
1053
+ * @example
1054
+ * ```ts
1055
+ * class MyTextNode extends TextNode {
1056
+ * // ...
1057
+ * static importJSON(serializedNode: SerializedMyTextNode): MyTextNode {
1058
+ * return $createMyTextNode()
1059
+ * .updateFromJSON(serializedNode);
1060
+ * }
1061
+ * updateFromJSON(
1062
+ * serializedNode: LexicalUpdateJSON<SerializedMyTextNode>,
1063
+ * ): this {
1064
+ * return super.updateFromJSON(serializedNode)
1065
+ * .setMyProperty(serializedNode.myProperty);
1066
+ * }
1067
+ * }
1068
+ * ```
1069
+ **/function updateFromJSON(serializedNode){return $updateStateFromJSON(this,serializedNode);}/**
1070
+ * @experimental
1071
+ *
1072
+ * Registers the returned function as a transform on the node during
1073
+ * Editor initialization. Most such use cases should be addressed via
1074
+ * the {@link LexicalEditor.registerNodeTransform} API.
1075
+ *
1076
+ * Experimental - use at your own risk.
1077
+ */},{key:"remove",value:// Setters and mutators
1078
+ /**
1079
+ * Removes this LexicalNode from the EditorState. If the node isn't re-inserted
1080
+ * somewhere, the Lexical garbage collector will eventually clean it up.
1081
+ *
1082
+ * @param preserveEmptyParent - If falsy, the node's parent will be removed if
1083
+ * it's empty after the removal operation. This is the default behavior, subject to
1084
+ * other node heuristics such as {@link ElementNode#canBeEmpty}
1085
+ * */function remove(preserveEmptyParent){$removeNode(this,true,preserveEmptyParent);}/**
1086
+ * Replaces this LexicalNode with the provided node, optionally transferring the children
1087
+ * of the replaced node to the replacing node.
1088
+ *
1089
+ * @param replaceWith - The node to replace this one with.
1090
+ * @param includeChildren - Whether or not to transfer the children of this node to the replacing node.
1091
+ * */},{key:"replace",value:function replace(replaceWith,includeChildren){errorOnReadOnly();var selection=$getSelection();if(selection!==null){selection=selection.clone();}errorOnInsertTextNodeOnRoot(this,replaceWith);var self=this.getLatest();var toReplaceKey=this.__key;var key=replaceWith.__key;var writableReplaceWith=replaceWith.getWritable();var writableParent=this.getParentOrThrow().getWritable();var size=writableParent.__size;removeFromParent(writableReplaceWith);var prevSibling=self.getPreviousSibling();var nextSibling=self.getNextSibling();var prevKey=self.__prev;var nextKey=self.__next;var parentKey=self.__parent;$removeNode(self,false,true);if(prevSibling===null){writableParent.__first=key;}else{var writablePrevSibling=prevSibling.getWritable();writablePrevSibling.__next=key;}writableReplaceWith.__prev=prevKey;if(nextSibling===null){writableParent.__last=key;}else{var writableNextSibling=nextSibling.getWritable();writableNextSibling.__prev=key;}writableReplaceWith.__next=nextKey;writableReplaceWith.__parent=parentKey;writableParent.__size=size;if(includeChildren){if(!($isElementNode(this)&&$isElementNode(writableReplaceWith))){formatDevErrorMessage("includeChildren should only be true for ElementNodes");}this.getChildren().forEach(function(child){writableReplaceWith.append(child);});}if($isRangeSelection(selection)){$setSelection(selection);var anchor=selection.anchor;var focus=selection.focus;if(anchor.key===toReplaceKey){$moveSelectionPointToEnd(anchor,writableReplaceWith);}if(focus.key===toReplaceKey){$moveSelectionPointToEnd(focus,writableReplaceWith);}}if($getCompositionKey()===toReplaceKey){$setCompositionKey(key);}return writableReplaceWith;}/**
1092
+ * Inserts a node after this LexicalNode (as the next sibling).
1093
+ *
1094
+ * @param nodeToInsert - The node to insert after this one.
1095
+ * @param restoreSelection - Whether or not to attempt to resolve the
1096
+ * selection to the appropriate place after the operation is complete.
1097
+ * */},{key:"insertAfter",value:function insertAfter(nodeToInsert){var restoreSelection=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;errorOnReadOnly();errorOnInsertTextNodeOnRoot(this,nodeToInsert);var writableSelf=this.getWritable();var writableNodeToInsert=nodeToInsert.getWritable();var oldParent=writableNodeToInsert.getParent();var selection=$getSelection();var elementAnchorSelectionOnNode=false;var elementFocusSelectionOnNode=false;if(oldParent!==null){// TODO: this is O(n), can we improve?
1098
+ var oldIndex=nodeToInsert.getIndexWithinParent();removeFromParent(writableNodeToInsert);if($isRangeSelection(selection)){var oldParentKey=oldParent.__key;var anchor=selection.anchor;var focus=selection.focus;elementAnchorSelectionOnNode=anchor.type==='element'&&anchor.key===oldParentKey&&anchor.offset===oldIndex+1;elementFocusSelectionOnNode=focus.type==='element'&&focus.key===oldParentKey&&focus.offset===oldIndex+1;}}var nextSibling=this.getNextSibling();var writableParent=this.getParentOrThrow().getWritable();var insertKey=writableNodeToInsert.__key;var nextKey=writableSelf.__next;if(nextSibling===null){writableParent.__last=insertKey;}else{var writableNextSibling=nextSibling.getWritable();writableNextSibling.__prev=insertKey;}writableParent.__size++;writableSelf.__next=insertKey;writableNodeToInsert.__next=nextKey;writableNodeToInsert.__prev=writableSelf.__key;writableNodeToInsert.__parent=writableSelf.__parent;if(restoreSelection&&$isRangeSelection(selection)){var index=this.getIndexWithinParent();$updateElementSelectionOnCreateDeleteNode(selection,writableParent,index+1);var writableParentKey=writableParent.__key;if(elementAnchorSelectionOnNode){selection.anchor.set(writableParentKey,index+2,'element');}if(elementFocusSelectionOnNode){selection.focus.set(writableParentKey,index+2,'element');}}return nodeToInsert;}/**
1099
+ * Inserts a node before this LexicalNode (as the previous sibling).
1100
+ *
1101
+ * @param nodeToInsert - The node to insert before this one.
1102
+ * @param restoreSelection - Whether or not to attempt to resolve the
1103
+ * selection to the appropriate place after the operation is complete.
1104
+ * */},{key:"insertBefore",value:function insertBefore(nodeToInsert){var restoreSelection=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;errorOnReadOnly();errorOnInsertTextNodeOnRoot(this,nodeToInsert);var writableSelf=this.getWritable();var writableNodeToInsert=nodeToInsert.getWritable();var insertKey=writableNodeToInsert.__key;removeFromParent(writableNodeToInsert);var prevSibling=this.getPreviousSibling();var writableParent=this.getParentOrThrow().getWritable();var prevKey=writableSelf.__prev;// TODO: this is O(n), can we improve?
1105
+ var index=this.getIndexWithinParent();if(prevSibling===null){writableParent.__first=insertKey;}else{var writablePrevSibling=prevSibling.getWritable();writablePrevSibling.__next=insertKey;}writableParent.__size++;writableSelf.__prev=insertKey;writableNodeToInsert.__prev=prevKey;writableNodeToInsert.__next=writableSelf.__key;writableNodeToInsert.__parent=writableSelf.__parent;var selection=$getSelection();if(restoreSelection&&$isRangeSelection(selection)){var parent=this.getParentOrThrow();$updateElementSelectionOnCreateDeleteNode(selection,parent,index);}return nodeToInsert;}/**
1106
+ * Whether or not this node has a required parent. Used during copy + paste operations
1107
+ * to normalize nodes that would otherwise be orphaned. For example, ListItemNodes without
1108
+ * a ListNode parent or TextNodes with a ParagraphNode parent.
1109
+ *
1110
+ * */},{key:"isParentRequired",value:function isParentRequired(){return false;}/**
1111
+ * The creation logic for any required parent. Should be implemented if {@link isParentRequired} returns true.
1112
+ *
1113
+ * */},{key:"createParentElementNode",value:function createParentElementNode(){return $createParagraphNode();}},{key:"selectStart",value:function selectStart(){return this.selectPrevious();}},{key:"selectEnd",value:function selectEnd(){return this.selectNext(0,0);}/**
1114
+ * Moves selection to the previous sibling of this node, at the specified offsets.
1115
+ *
1116
+ * @param anchorOffset - The anchor offset for selection.
1117
+ * @param focusOffset - The focus offset for selection
1118
+ * */},{key:"selectPrevious",value:function selectPrevious(anchorOffset,focusOffset){errorOnReadOnly();var prevSibling=this.getPreviousSibling();var parent=this.getParentOrThrow();if(prevSibling===null){return parent.select(0,0);}if($isElementNode(prevSibling)){return prevSibling.select();}else if(!$isTextNode(prevSibling)){var index=prevSibling.getIndexWithinParent()+1;return parent.select(index,index);}return prevSibling.select(anchorOffset,focusOffset);}/**
1119
+ * Moves selection to the next sibling of this node, at the specified offsets.
1120
+ *
1121
+ * @param anchorOffset - The anchor offset for selection.
1122
+ * @param focusOffset - The focus offset for selection
1123
+ * */},{key:"selectNext",value:function selectNext(anchorOffset,focusOffset){errorOnReadOnly();var nextSibling=this.getNextSibling();var parent=this.getParentOrThrow();if(nextSibling===null){return parent.select();}if($isElementNode(nextSibling)){return nextSibling.select(0,0);}else if(!$isTextNode(nextSibling)){var index=nextSibling.getIndexWithinParent();return parent.select(index,index);}return nextSibling.select(anchorOffset,focusOffset);}/**
1124
+ * Marks a node dirty, triggering transforms and
1125
+ * forcing it to be reconciled during the update cycle.
1126
+ *
1127
+ * */},{key:"markDirty",value:function markDirty(){this.getWritable();}/**
1128
+ * @internal
1129
+ *
1130
+ * When the reconciler detects that a node was mutated, this method
1131
+ * may be called to restore the node to a known good state.
1132
+ */},{key:"reconcileObservedMutation",value:function reconcileObservedMutation(dom,editor){this.markDirty();}}],[{key:"getType",value:// Flow doesn't support abstract classes unfortunately, so we can't _force_
1133
+ // subclasses of Node to implement statics. All subclasses of Node should have
1134
+ // a static getType and clone method though. We define getType and clone here so we can call it
1135
+ // on any Node, and we throw this error by default since the subclass should provide
1136
+ // their own implementation.
1137
+ /**
1138
+ * Returns the string type of this node. Every node must
1139
+ * implement this and it MUST BE UNIQUE amongst nodes registered
1140
+ * on the editor.
1141
+ *
1142
+ */function getType(){var _getStaticNodeConfig2=getStaticNodeConfig(this),ownNodeType=_getStaticNodeConfig2.ownNodeType;if(!(ownNodeType!==undefined)){formatDevErrorMessage("LexicalNode: Node ".concat(this.name," does not implement .getType()."));}return ownNodeType;}/**
1143
+ * Clones this node, creating a new node with a different key
1144
+ * and adding it to the EditorState (but not attaching it anywhere!). All nodes must
1145
+ * implement this method.
1146
+ *
1147
+ */},{key:"clone",value:function clone(_data){{formatDevErrorMessage("LexicalNode: Node ".concat(this.name," does not implement .clone()."));}}},{key:"importJSON",value:function importJSON(_serializedNode){{formatDevErrorMessage("LexicalNode: Node ".concat(this.name," does not implement .importJSON()."));}}},{key:"transform",value:function transform(){return null;}}]);return LexicalNode;}();_defineProperty(LexicalNode,"importDOM",void 0);function errorOnTypeKlassMismatch(type,klass){var registeredNode=getRegisteredNode(getActiveEditor(),type);// Common error - split in its own invariant
1148
+ if(registeredNode===undefined){{formatDevErrorMessage("Create node: Attempted to create node ".concat(klass.name," that was not configured to be used on the editor."));}}var editorKlass=registeredNode.klass;if(editorKlass!==klass){{formatDevErrorMessage("Create node: Type ".concat(type," in node ").concat(klass.name," does not match registered node ").concat(editorKlass.name," with the same type"));}}}/**
1149
+ * Insert a series of nodes after this LexicalNode (as next siblings)
1150
+ *
1151
+ * @param firstToInsert - The first node to insert after this one.
1152
+ * @param lastToInsert - The last node to insert after this one. Must be a
1153
+ * later sibling of FirstNode. If not provided, it will be its last sibling.
1154
+ */function insertRangeAfter(node,firstToInsert,lastToInsert){var lastToInsert2=firstToInsert.getParentOrThrow().getLastChild();var current=firstToInsert;var nodesToInsert=[firstToInsert];while(current!==lastToInsert2){if(!current.getNextSibling()){{formatDevErrorMessage("insertRangeAfter: lastToInsert must be a later sibling of firstToInsert");}}current=current.getNextSibling();nodesToInsert.push(current);}var currentNode=node;for(var _i7=0,_nodesToInsert=nodesToInsert;_i7<_nodesToInsert.length;_i7++){var nodeToInsert=_nodesToInsert[_i7];currentNode=currentNode.insertAfter(nodeToInsert);}}/**
1155
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
1156
+ *
1157
+ * This source code is licensed under the MIT license found in the
1158
+ * LICENSE file in the root directory of this source tree.
1159
+ *
1160
+ */ /**
1161
+ * Common update tags used in Lexical. These tags can be used with editor.update() or $addUpdateTag()
1162
+ * to indicate the type/purpose of an update. Multiple tags can be used in a single update.
1163
+ */ /**
1164
+ * Indicates that the update is related to history operations (undo/redo)
1165
+ */var HISTORIC_TAG='historic';/**
1166
+ * Indicates that a new history entry should be pushed to the history stack
1167
+ */var HISTORY_PUSH_TAG='history-push';/**
1168
+ * Indicates that the current update should be merged with the previous history entry
1169
+ */var HISTORY_MERGE_TAG='history-merge';/**
1170
+ * Indicates that the update is related to a paste operation
1171
+ */var PASTE_TAG='paste';/**
1172
+ * Indicates that the update is related to collaborative editing
1173
+ */var COLLABORATION_TAG='collaboration';/**
1174
+ * Indicates that the update should skip collaborative sync
1175
+ */var SKIP_COLLAB_TAG='skip-collab';/**
1176
+ * Indicates that the update should skip scrolling the selection into view
1177
+ */var SKIP_SCROLL_INTO_VIEW_TAG='skip-scroll-into-view';/**
1178
+ * Indicates that the update should skip updating the DOM selection
1179
+ * This is useful when you want to make updates without changing the selection or focus
1180
+ */var SKIP_DOM_SELECTION_TAG='skip-dom-selection';/**
1181
+ * Indicates that after changing the selection, the editor should not focus itself
1182
+ * This tag is ignored if {@link SKIP_DOM_SELECTION_TAG} is used
1183
+ */var SKIP_SELECTION_FOCUS_TAG='skip-selection-focus';/**
1184
+ * The update was triggered by editor.focus()
1185
+ */var FOCUS_TAG='focus';/**
1186
+ * The set of known update tags to help with TypeScript suggestions.
1187
+ */ /**
1188
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
1189
+ *
1190
+ * This source code is licensed under the MIT license found in the
1191
+ * LICENSE file in the root directory of this source tree.
1192
+ *
1193
+ */ /** @noInheritDoc */var LineBreakNode=/*#__PURE__*/function(_LexicalNode){_inherits(LineBreakNode,_LexicalNode);var _super=_createSuper(LineBreakNode);function LineBreakNode(key){_classCallCheck(this,LineBreakNode);return _super.call(this,key);}_createClass(LineBreakNode,[{key:"getTextContent",value:function getTextContent(){return'\n';}},{key:"createDOM",value:function createDOM(){return document.createElement('br');}},{key:"updateDOM",value:function updateDOM(){return false;}},{key:"isInline",value:function isInline(){return true;}}],[{key:"getType",value:/** @internal */function getType(){return'linebreak';}},{key:"clone",value:function clone(node){return new LineBreakNode(node.__key);}},{key:"importDOM",value:function importDOM(){return{br:function br(node){if(isOnlyChildInBlockNode(node)||isLastChildInBlockNode(node)){return null;}return{conversion:$convertLineBreakElement,priority:0};}};}},{key:"importJSON",value:function importJSON(serializedLineBreakNode){return $createLineBreakNode().updateFromJSON(serializedLineBreakNode);}}]);return LineBreakNode;}(LexicalNode);function $convertLineBreakElement(node){return{node:$createLineBreakNode()};}function $createLineBreakNode(){return $applyNodeReplacement(new LineBreakNode());}function $isLineBreakNode(node){return node instanceof LineBreakNode;}function isOnlyChildInBlockNode(node){var parentElement=node.parentElement;if(parentElement!==null&&isBlockDomNode(parentElement)){var firstChild=parentElement.firstChild;if(firstChild===node||firstChild.nextSibling===node&&isWhitespaceDomTextNode(firstChild)){var lastChild=parentElement.lastChild;if(lastChild===node||lastChild.previousSibling===node&&isWhitespaceDomTextNode(lastChild)){return true;}}}return false;}function isLastChildInBlockNode(node){var parentElement=node.parentElement;if(parentElement!==null&&isBlockDomNode(parentElement)){// check if node is first child, because only child dont count
1194
+ var firstChild=parentElement.firstChild;if(firstChild===node||firstChild.nextSibling===node&&isWhitespaceDomTextNode(firstChild)){return false;}// check if its last child
1195
+ var lastChild=parentElement.lastChild;if(lastChild===node||lastChild.previousSibling===node&&isWhitespaceDomTextNode(lastChild)){return true;}}return false;}function isWhitespaceDomTextNode(node){return isDOMTextNode(node)&&/^( |\t|\r?\n)+$/.test(node.textContent||'');}function getElementOuterTag(node,format){if(format&IS_CODE){return'code';}if(format&IS_HIGHLIGHT){return'mark';}if(format&IS_SUBSCRIPT){return'sub';}if(format&IS_SUPERSCRIPT){return'sup';}return null;}function getElementInnerTag(node,format){if(format&IS_BOLD){return'strong';}if(format&IS_ITALIC){return'em';}return'span';}function setTextThemeClassNames(tag,prevFormat,nextFormat,dom,textClassNames){var domClassList=dom.classList;// Firstly we handle the base theme.
1196
+ var classNames=getCachedClassNameArray(textClassNames,'base');if(classNames!==undefined){domClassList.add.apply(domClassList,_toConsumableArray(classNames));}// Secondly we handle the special case: underline + strikethrough.
1197
+ // We have to do this as we need a way to compose the fact that
1198
+ // the same CSS property will need to be used: text-decoration.
1199
+ // In an ideal world we shouldn't have to do this, but there's no
1200
+ // easy workaround for many atomic CSS systems today.
1201
+ classNames=getCachedClassNameArray(textClassNames,'underlineStrikethrough');var hasUnderlineStrikethrough=false;var prevUnderlineStrikethrough=prevFormat&IS_UNDERLINE&&prevFormat&IS_STRIKETHROUGH;var nextUnderlineStrikethrough=nextFormat&IS_UNDERLINE&&nextFormat&IS_STRIKETHROUGH;if(classNames!==undefined){if(nextUnderlineStrikethrough){hasUnderlineStrikethrough=true;if(!prevUnderlineStrikethrough){domClassList.add.apply(domClassList,_toConsumableArray(classNames));}}else if(prevUnderlineStrikethrough){domClassList.remove.apply(domClassList,_toConsumableArray(classNames));}}for(var key in TEXT_TYPE_TO_FORMAT){var format=key;var flag=TEXT_TYPE_TO_FORMAT[format];classNames=getCachedClassNameArray(textClassNames,key);if(classNames!==undefined){if(nextFormat&flag){if(hasUnderlineStrikethrough&&(key==='underline'||key==='strikethrough')){if(prevFormat&flag){domClassList.remove.apply(domClassList,_toConsumableArray(classNames));}continue;}if((prevFormat&flag)===0||prevUnderlineStrikethrough&&key==='underline'||key==='strikethrough'){domClassList.add.apply(domClassList,_toConsumableArray(classNames));}}else if(prevFormat&flag){domClassList.remove.apply(domClassList,_toConsumableArray(classNames));}}}}function diffComposedText(a,b){var aLength=a.length;var bLength=b.length;var left=0;var right=0;while(left<aLength&&left<bLength&&a[left]===b[left]){left++;}while(right+left<aLength&&right+left<bLength&&a[aLength-right-1]===b[bLength-right-1]){right++;}return[left,aLength-left-right,b.slice(left,bLength-right)];}function setTextContent(nextText,dom,node){var firstChild=dom.firstChild;var isComposing=node.isComposing();// Always add a suffix if we're composing a node
1202
+ var suffix=isComposing?COMPOSITION_SUFFIX:'';var text=nextText+suffix;if(firstChild==null){dom.textContent=text;}else{var nodeValue=firstChild.nodeValue;if(nodeValue!==text){if(isComposing||IS_FIREFOX){// We also use the diff composed text for general text in FF to avoid
1203
+ // the spellcheck red line from flickering.
1204
+ var _diffComposedText=diffComposedText(nodeValue,text),_diffComposedText2=_slicedToArray(_diffComposedText,3),index=_diffComposedText2[0],remove=_diffComposedText2[1],insert=_diffComposedText2[2];if(remove!==0){// @ts-expect-error
1205
+ firstChild.deleteData(index,remove);}// @ts-expect-error
1206
+ firstChild.insertData(index,insert);}else{firstChild.nodeValue=text;}}}}function createTextInnerDOM(innerDOM,node,innerTag,format,text,config){setTextContent(text,innerDOM,node);var theme=config.theme;// Apply theme class names
1207
+ var textClassNames=theme.text;if(textClassNames!==undefined){setTextThemeClassNames(innerTag,0,format,innerDOM,textClassNames);}}function wrapElementWith(element,tag){var el=document.createElement(tag);el.appendChild(element);return el;}// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
1208
+ /** @noInheritDoc */ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
1209
+ var TextNode=/*#__PURE__*/function(_LexicalNode2){_inherits(TextNode,_LexicalNode2);var _super2=_createSuper(TextNode);function TextNode(){var _this2;var text=arguments.length>0&&arguments[0]!==undefined?arguments[0]:'';var key=arguments.length>1?arguments[1]:undefined;_classCallCheck(this,TextNode);_this2=_super2.call(this,key);/** @internal */_defineProperty(_assertThisInitialized(_this2),"__text",void 0);/** @internal */_defineProperty(_assertThisInitialized(_this2),"__format",void 0);/** @internal */_defineProperty(_assertThisInitialized(_this2),"__style",void 0);/** @internal */_defineProperty(_assertThisInitialized(_this2),"__mode",void 0);/** @internal */_defineProperty(_assertThisInitialized(_this2),"__detail",void 0);_this2.__text=text;_this2.__format=0;_this2.__style='';_this2.__mode=0;_this2.__detail=0;return _this2;}/**
1210
+ * Returns a 32-bit integer that represents the TextFormatTypes currently applied to the
1211
+ * TextNode. You probably don't want to use this method directly - consider using TextNode.hasFormat instead.
1212
+ *
1213
+ * @returns a number representing the format of the text node.
1214
+ */_createClass(TextNode,[{key:"afterCloneFrom",value:function afterCloneFrom(prevNode){_get(_getPrototypeOf(TextNode.prototype),"afterCloneFrom",this).call(this,prevNode);this.__text=prevNode.__text;this.__format=prevNode.__format;this.__style=prevNode.__style;this.__mode=prevNode.__mode;this.__detail=prevNode.__detail;}},{key:"getFormat",value:function getFormat(){var self=this.getLatest();return self.__format;}/**
1215
+ * Returns a 32-bit integer that represents the TextDetailTypes currently applied to the
1216
+ * TextNode. You probably don't want to use this method directly - consider using TextNode.isDirectionless
1217
+ * or TextNode.isUnmergeable instead.
1218
+ *
1219
+ * @returns a number representing the detail of the text node.
1220
+ */},{key:"getDetail",value:function getDetail(){var self=this.getLatest();return self.__detail;}/**
1221
+ * Returns the mode (TextModeType) of the TextNode, which may be "normal", "token", or "segmented"
1222
+ *
1223
+ * @returns TextModeType.
1224
+ */},{key:"getMode",value:function getMode(){var self=this.getLatest();return TEXT_TYPE_TO_MODE[self.__mode];}/**
1225
+ * Returns the styles currently applied to the node. This is analogous to CSSText in the DOM.
1226
+ *
1227
+ * @returns CSSText-like string of styles applied to the underlying DOM node.
1228
+ */},{key:"getStyle",value:function getStyle(){var self=this.getLatest();return self.__style;}/**
1229
+ * Returns whether or not the node is in "token" mode. TextNodes in token mode can be navigated through character-by-character
1230
+ * with a RangeSelection, but are deleted as a single entity (not individually by character).
1231
+ *
1232
+ * @returns true if the node is in token mode, false otherwise.
1233
+ */},{key:"isToken",value:function isToken(){var self=this.getLatest();return self.__mode===IS_TOKEN;}/**
1234
+ *
1235
+ * @returns true if Lexical detects that an IME or other 3rd-party script is attempting to
1236
+ * mutate the TextNode, false otherwise.
1237
+ */},{key:"isComposing",value:function isComposing(){return this.__key===$getCompositionKey();}/**
1238
+ * Returns whether or not the node is in "segmented" mode. TextNodes in segmented mode can be navigated through character-by-character
1239
+ * with a RangeSelection, but are deleted in space-delimited "segments".
1240
+ *
1241
+ * @returns true if the node is in segmented mode, false otherwise.
1242
+ */},{key:"isSegmented",value:function isSegmented(){var self=this.getLatest();return self.__mode===IS_SEGMENTED;}/**
1243
+ * Returns whether or not the node is "directionless". Directionless nodes don't respect changes between RTL and LTR modes.
1244
+ *
1245
+ * @returns true if the node is directionless, false otherwise.
1246
+ */},{key:"isDirectionless",value:function isDirectionless(){var self=this.getLatest();return(self.__detail&IS_DIRECTIONLESS)!==0;}/**
1247
+ * Returns whether or not the node is unmergeable. In some scenarios, Lexical tries to merge
1248
+ * adjacent TextNodes into a single TextNode. If a TextNode is unmergeable, this won't happen.
1249
+ *
1250
+ * @returns true if the node is unmergeable, false otherwise.
1251
+ */},{key:"isUnmergeable",value:function isUnmergeable(){var self=this.getLatest();return(self.__detail&IS_UNMERGEABLE)!==0;}/**
1252
+ * Returns whether or not the node has the provided format applied. Use this with the human-readable TextFormatType
1253
+ * string values to get the format of a TextNode.
1254
+ *
1255
+ * @param type - the TextFormatType to check for.
1256
+ *
1257
+ * @returns true if the node has the provided format, false otherwise.
1258
+ */},{key:"hasFormat",value:function hasFormat(type){var formatFlag=TEXT_TYPE_TO_FORMAT[type];return(this.getFormat()&formatFlag)!==0;}/**
1259
+ * Returns whether or not the node is simple text. Simple text is defined as a TextNode that has the string type "text"
1260
+ * (i.e., not a subclass) and has no mode applied to it (i.e., not segmented or token).
1261
+ *
1262
+ * @returns true if the node is simple text, false otherwise.
1263
+ */},{key:"isSimpleText",value:function isSimpleText(){return this.__type==='text'&&this.__mode===0;}/**
1264
+ * Returns the text content of the node as a string.
1265
+ *
1266
+ * @returns a string representing the text content of the node.
1267
+ */},{key:"getTextContent",value:function getTextContent(){var self=this.getLatest();return self.__text;}/**
1268
+ * Returns the format flags applied to the node as a 32-bit integer.
1269
+ *
1270
+ * @returns a number representing the TextFormatTypes applied to the node.
1271
+ */},{key:"getFormatFlags",value:function getFormatFlags(type,alignWithFormat){var self=this.getLatest();var format=self.__format;return toggleTextFormatType(format,type,alignWithFormat);}/**
1272
+ *
1273
+ * @returns true if the text node supports font styling, false otherwise.
1274
+ */},{key:"canHaveFormat",value:function canHaveFormat(){return true;}/**
1275
+ * @returns true if the text node is inline, false otherwise.
1276
+ */},{key:"isInline",value:function isInline(){return true;}// View
1277
+ },{key:"createDOM",value:function createDOM(config,editor){var format=this.__format;var outerTag=getElementOuterTag(this,format);var innerTag=getElementInnerTag(this,format);var tag=outerTag===null?innerTag:outerTag;var dom=document.createElement(tag);var innerDOM=dom;if(this.hasFormat('code')){dom.setAttribute('spellcheck','false');}if(outerTag!==null){innerDOM=document.createElement(innerTag);dom.appendChild(innerDOM);}var text=this.__text;createTextInnerDOM(innerDOM,this,innerTag,format,text,config);var style=this.__style;if(style!==''){dom.style.cssText=style;}return dom;}},{key:"updateDOM",value:function updateDOM(prevNode,dom,config){var nextText=this.__text;var prevFormat=prevNode.__format;var nextFormat=this.__format;var prevOuterTag=getElementOuterTag(this,prevFormat);var nextOuterTag=getElementOuterTag(this,nextFormat);var prevInnerTag=getElementInnerTag(this,prevFormat);var nextInnerTag=getElementInnerTag(this,nextFormat);var prevTag=prevOuterTag===null?prevInnerTag:prevOuterTag;var nextTag=nextOuterTag===null?nextInnerTag:nextOuterTag;if(prevTag!==nextTag){return true;}if(prevOuterTag===nextOuterTag&&prevInnerTag!==nextInnerTag){// should always be an element
1278
+ var prevInnerDOM=dom.firstChild;if(prevInnerDOM==null){{formatDevErrorMessage("updateDOM: prevInnerDOM is null or undefined");}}var nextInnerDOM=document.createElement(nextInnerTag);createTextInnerDOM(nextInnerDOM,this,nextInnerTag,nextFormat,nextText,config);dom.replaceChild(nextInnerDOM,prevInnerDOM);return false;}var innerDOM=dom;if(nextOuterTag!==null){if(prevOuterTag!==null){innerDOM=dom.firstChild;if(innerDOM==null){{formatDevErrorMessage("updateDOM: innerDOM is null or undefined");}}}}setTextContent(nextText,innerDOM,this);var theme=config.theme;// Apply theme class names
1279
+ var textClassNames=theme.text;if(textClassNames!==undefined&&prevFormat!==nextFormat){setTextThemeClassNames(nextInnerTag,prevFormat,nextFormat,innerDOM,textClassNames);}var prevStyle=prevNode.__style;var nextStyle=this.__style;if(prevStyle!==nextStyle){dom.style.cssText=nextStyle;}return false;}},{key:"updateFromJSON",value:function updateFromJSON(serializedNode){return _get(_getPrototypeOf(TextNode.prototype),"updateFromJSON",this).call(this,serializedNode).setTextContent(serializedNode.text).setFormat(serializedNode.format).setDetail(serializedNode.detail).setMode(serializedNode.mode).setStyle(serializedNode.style);}// This improves Lexical's basic text output in copy+paste plus
1280
+ // for headless mode where people might use Lexical to generate
1281
+ // HTML content and not have the ability to use CSS classes.
1282
+ },{key:"exportDOM",value:function exportDOM(editor){var _get$call=_get(_getPrototypeOf(TextNode.prototype),"exportDOM",this).call(this,editor),element=_get$call.element;if(!isHTMLElement(element)){formatDevErrorMessage("Expected TextNode createDOM to always return a HTMLElement");}element.style.whiteSpace='pre-wrap';// Add text-transform styles for capitalization formats
1283
+ if(this.hasFormat('lowercase')){element.style.textTransform='lowercase';}else if(this.hasFormat('uppercase')){element.style.textTransform='uppercase';}else if(this.hasFormat('capitalize')){element.style.textTransform='capitalize';}// This is the only way to properly add support for most clients,
1284
+ // even if it's semantically incorrect to have to resort to using
1285
+ // <b>, <u>, <s>, <i> elements.
1286
+ if(this.hasFormat('bold')){element=wrapElementWith(element,'b');}if(this.hasFormat('italic')){element=wrapElementWith(element,'i');}if(this.hasFormat('strikethrough')){element=wrapElementWith(element,'s');}if(this.hasFormat('underline')){element=wrapElementWith(element,'u');}return{element:element};}},{key:"exportJSON",value:function exportJSON(){return _objectSpread({detail:this.getDetail(),format:this.getFormat(),mode:this.getMode(),style:this.getStyle(),text:this.getTextContent()},_get(_getPrototypeOf(TextNode.prototype),"exportJSON",this).call(this));}// Mutators
1287
+ },{key:"selectionTransform",value:function selectionTransform(prevSelection,nextSelection){return;}/**
1288
+ * Sets the node format to the provided TextFormatType or 32-bit integer. Note that the TextFormatType
1289
+ * version of the argument can only specify one format and doing so will remove all other formats that
1290
+ * may be applied to the node. For toggling behavior, consider using {@link TextNode.toggleFormat}
1291
+ *
1292
+ * @param format - TextFormatType or 32-bit integer representing the node format.
1293
+ *
1294
+ * @returns this TextNode.
1295
+ * // TODO 0.12 This should just be a `string`.
1296
+ */},{key:"setFormat",value:function setFormat(format){var self=this.getWritable();self.__format=typeof format==='string'?TEXT_TYPE_TO_FORMAT[format]:format;return self;}/**
1297
+ * Sets the node detail to the provided TextDetailType or 32-bit integer. Note that the TextDetailType
1298
+ * version of the argument can only specify one detail value and doing so will remove all other detail values that
1299
+ * may be applied to the node. For toggling behavior, consider using {@link TextNode.toggleDirectionless}
1300
+ * or {@link TextNode.toggleUnmergeable}
1301
+ *
1302
+ * @param detail - TextDetailType or 32-bit integer representing the node detail.
1303
+ *
1304
+ * @returns this TextNode.
1305
+ * // TODO 0.12 This should just be a `string`.
1306
+ */},{key:"setDetail",value:function setDetail(detail){var self=this.getWritable();self.__detail=typeof detail==='string'?DETAIL_TYPE_TO_DETAIL[detail]:detail;return self;}/**
1307
+ * Sets the node style to the provided CSSText-like string. Set this property as you
1308
+ * would an HTMLElement style attribute to apply inline styles to the underlying DOM Element.
1309
+ *
1310
+ * @param style - CSSText to be applied to the underlying HTMLElement.
1311
+ *
1312
+ * @returns this TextNode.
1313
+ */},{key:"setStyle",value:function setStyle(style){var self=this.getWritable();self.__style=style;return self;}/**
1314
+ * Applies the provided format to this TextNode if it's not present. Removes it if it's present.
1315
+ * The subscript and superscript formats are mutually exclusive.
1316
+ * Prefer using this method to turn specific formats on and off.
1317
+ *
1318
+ * @param type - TextFormatType to toggle.
1319
+ *
1320
+ * @returns this TextNode.
1321
+ */},{key:"toggleFormat",value:function toggleFormat(type){var format=this.getFormat();var newFormat=toggleTextFormatType(format,type,null);return this.setFormat(newFormat);}/**
1322
+ * Toggles the directionless detail value of the node. Prefer using this method over setDetail.
1323
+ *
1324
+ * @returns this TextNode.
1325
+ */},{key:"toggleDirectionless",value:function toggleDirectionless(){var self=this.getWritable();self.__detail^=IS_DIRECTIONLESS;return self;}/**
1326
+ * Toggles the unmergeable detail value of the node. Prefer using this method over setDetail.
1327
+ *
1328
+ * @returns this TextNode.
1329
+ */},{key:"toggleUnmergeable",value:function toggleUnmergeable(){var self=this.getWritable();self.__detail^=IS_UNMERGEABLE;return self;}/**
1330
+ * Sets the mode of the node.
1331
+ *
1332
+ * @returns this TextNode.
1333
+ */},{key:"setMode",value:function setMode(type){var mode=TEXT_MODE_TO_TYPE[type];if(this.__mode===mode){return this;}var self=this.getWritable();self.__mode=mode;return self;}/**
1334
+ * Sets the text content of the node.
1335
+ *
1336
+ * @param text - the string to set as the text value of the node.
1337
+ *
1338
+ * @returns this TextNode.
1339
+ */},{key:"setTextContent",value:function setTextContent(text){if(this.__text===text){return this;}var self=this.getWritable();self.__text=text;return self;}/**
1340
+ * Sets the current Lexical selection to be a RangeSelection with anchor and focus on this TextNode at the provided offsets.
1341
+ *
1342
+ * @param _anchorOffset - the offset at which the Selection anchor will be placed.
1343
+ * @param _focusOffset - the offset at which the Selection focus will be placed.
1344
+ *
1345
+ * @returns the new RangeSelection.
1346
+ */},{key:"select",value:function select(_anchorOffset,_focusOffset){errorOnReadOnly();var anchorOffset=_anchorOffset;var focusOffset=_focusOffset;var selection=$getSelection();var text=this.getTextContent();var key=this.__key;if(typeof text==='string'){var lastOffset=text.length;if(anchorOffset===undefined){anchorOffset=lastOffset;}if(focusOffset===undefined){focusOffset=lastOffset;}}else{anchorOffset=0;focusOffset=0;}if(!$isRangeSelection(selection)){return $internalMakeRangeSelection(key,anchorOffset,key,focusOffset,'text','text');}else{var compositionKey=$getCompositionKey();if(compositionKey===selection.anchor.key||compositionKey===selection.focus.key){$setCompositionKey(key);}selection.setTextNodeRange(this,anchorOffset,this,focusOffset);}return selection;}},{key:"selectStart",value:function selectStart(){return this.select(0,0);}},{key:"selectEnd",value:function selectEnd(){var size=this.getTextContentSize();return this.select(size,size);}/**
1347
+ * Inserts the provided text into this TextNode at the provided offset, deleting the number of characters
1348
+ * specified. Can optionally calculate a new selection after the operation is complete.
1349
+ *
1350
+ * @param offset - the offset at which the splice operation should begin.
1351
+ * @param delCount - the number of characters to delete, starting from the offset.
1352
+ * @param newText - the text to insert into the TextNode at the offset.
1353
+ * @param moveSelection - optional, whether or not to move selection to the end of the inserted substring.
1354
+ *
1355
+ * @returns this TextNode.
1356
+ */},{key:"spliceText",value:function spliceText(offset,delCount,newText,moveSelection){var writableSelf=this.getWritable();var text=writableSelf.__text;var handledTextLength=newText.length;var index=offset;if(index<0){index=handledTextLength+index;if(index<0){index=0;}}var selection=$getSelection();if(moveSelection&&$isRangeSelection(selection)){var newOffset=offset+handledTextLength;selection.setTextNodeRange(writableSelf,newOffset,writableSelf,newOffset);}var updatedText=text.slice(0,index)+newText+text.slice(index+delCount);writableSelf.__text=updatedText;return writableSelf;}/**
1357
+ * This method is meant to be overridden by TextNode subclasses to control the behavior of those nodes
1358
+ * when a user event would cause text to be inserted before them in the editor. If true, Lexical will attempt
1359
+ * to insert text into this node. If false, it will insert the text in a new sibling node.
1360
+ *
1361
+ * @returns true if text can be inserted before the node, false otherwise.
1362
+ */},{key:"canInsertTextBefore",value:function canInsertTextBefore(){return true;}/**
1363
+ * This method is meant to be overridden by TextNode subclasses to control the behavior of those nodes
1364
+ * when a user event would cause text to be inserted after them in the editor. If true, Lexical will attempt
1365
+ * to insert text into this node. If false, it will insert the text in a new sibling node.
1366
+ *
1367
+ * @returns true if text can be inserted after the node, false otherwise.
1368
+ */},{key:"canInsertTextAfter",value:function canInsertTextAfter(){return true;}/**
1369
+ * Splits this TextNode at the provided character offsets, forming new TextNodes from the substrings
1370
+ * formed by the split, and inserting those new TextNodes into the editor, replacing the one that was split.
1371
+ *
1372
+ * @param splitOffsets - rest param of the text content character offsets at which this node should be split.
1373
+ *
1374
+ * @returns an Array containing the newly-created TextNodes.
1375
+ */},{key:"splitText",value:function splitText(){errorOnReadOnly();var self=this.getLatest();var textContent=self.getTextContent();if(textContent===''){return[];}var key=self.__key;var compositionKey=$getCompositionKey();var textLength=textContent.length;for(var _len2=arguments.length,splitOffsets=new Array(_len2),_key2=0;_key2<_len2;_key2++){splitOffsets[_key2]=arguments[_key2];}splitOffsets.sort(function(a,b){return a-b;});splitOffsets.push(textLength);var parts=[];var splitOffsetsLength=splitOffsets.length;for(var start=0,offsetIndex=0;start<textLength&&offsetIndex<=splitOffsetsLength;offsetIndex++){var end=splitOffsets[offsetIndex];if(end>start){parts.push(textContent.slice(start,end));start=end;}}var partsLength=parts.length;if(partsLength===1){return[self];}var firstPart=parts[0];var parent=self.getParent();var writableNode;var format=self.getFormat();var style=self.getStyle();var detail=self.__detail;var hasReplacedSelf=false;// Prepare to handle selection
1376
+ var startTextPoint=null;var endTextPoint=null;var selection=$getSelection();if($isRangeSelection(selection)){var _ref2=selection.isBackward()?[selection.focus,selection.anchor]:[selection.anchor,selection.focus],_ref3=_slicedToArray(_ref2,2),startPoint=_ref3[0],endPoint=_ref3[1];if(startPoint.type==='text'&&startPoint.key===key){startTextPoint=startPoint;}if(endPoint.type==='text'&&endPoint.key===key){endTextPoint=endPoint;}}if(self.isSegmented()){// Create a new TextNode
1377
+ writableNode=$createTextNode(firstPart);writableNode.__format=format;writableNode.__style=style;writableNode.__detail=detail;writableNode.__state=$cloneNodeState(self,writableNode);hasReplacedSelf=true;}else{// For the first part, update the existing node
1378
+ writableNode=self.setTextContent(firstPart);}// Then handle all other parts
1379
+ var splitNodes=[writableNode];for(var i=1;i<partsLength;i++){var part=parts[i];var sibling=$createTextNode(part);sibling.__format=format;sibling.__style=style;sibling.__detail=detail;sibling.__state=$cloneNodeState(self,sibling);var siblingKey=sibling.__key;if(compositionKey===key){$setCompositionKey(siblingKey);}splitNodes.push(sibling);}// Move the selection to the best location in the split string.
1380
+ // The end point is always left-biased, and the start point is
1381
+ // generally left biased unless the end point would land on a
1382
+ // later node in the split in which case it will prefer the start
1383
+ // of that node so they will tend to be on the same node.
1384
+ var originalStartOffset=startTextPoint?startTextPoint.offset:null;var originalEndOffset=endTextPoint?endTextPoint.offset:null;var startOffset=0;for(var _i8=0,_splitNodes=splitNodes;_i8<_splitNodes.length;_i8++){var node=_splitNodes[_i8];if(!(startTextPoint||endTextPoint)){break;}var endOffset=startOffset+node.getTextContentSize();if(startTextPoint!==null&&originalStartOffset!==null&&originalStartOffset<=endOffset&&originalStartOffset>=startOffset){// Set the start point to the first valid node
1385
+ startTextPoint.set(node.getKey(),originalStartOffset-startOffset,'text');if(originalStartOffset<endOffset){// The start isn't on a border so we can stop checking
1386
+ startTextPoint=null;}}if(endTextPoint!==null&&originalEndOffset!==null&&originalEndOffset<=endOffset&&originalEndOffset>=startOffset){endTextPoint.set(node.getKey(),originalEndOffset-startOffset,'text');break;}startOffset=endOffset;}// Insert the nodes into the parent's children
1387
+ if(parent!==null){internalMarkSiblingsAsDirty(this);var writableParent=parent.getWritable();var insertionIndex=this.getIndexWithinParent();if(hasReplacedSelf){writableParent.splice(insertionIndex,0,splitNodes);this.remove();}else{writableParent.splice(insertionIndex,1,splitNodes);}if($isRangeSelection(selection)){$updateElementSelectionOnCreateDeleteNode(selection,parent,insertionIndex,partsLength-1);}}return splitNodes;}/**
1388
+ * Merges the target TextNode into this TextNode, removing the target node.
1389
+ *
1390
+ * @param target - the TextNode to merge into this one.
1391
+ *
1392
+ * @returns this TextNode.
1393
+ */},{key:"mergeWithSibling",value:function mergeWithSibling(target){var isBefore=target===this.getPreviousSibling();if(!isBefore&&target!==this.getNextSibling()){{formatDevErrorMessage("mergeWithSibling: sibling must be a previous or next sibling");}}var key=this.__key;var targetKey=target.__key;var text=this.__text;var textLength=text.length;var compositionKey=$getCompositionKey();if(compositionKey===targetKey){$setCompositionKey(key);}var selection=$getSelection();if($isRangeSelection(selection)){var anchor=selection.anchor;var focus=selection.focus;if(anchor!==null&&anchor.key===targetKey){adjustPointOffsetForMergedSibling(anchor,isBefore,key,target,textLength);}if(focus!==null&&focus.key===targetKey){adjustPointOffsetForMergedSibling(focus,isBefore,key,target,textLength);}}var targetText=target.__text;var newText=isBefore?targetText+text:text+targetText;this.setTextContent(newText);var writableSelf=this.getWritable();target.remove();return writableSelf;}/**
1394
+ * This method is meant to be overridden by TextNode subclasses to control the behavior of those nodes
1395
+ * when used with the registerLexicalTextEntity function. If you're using registerLexicalTextEntity, the
1396
+ * node class that you create and replace matched text with should return true from this method.
1397
+ *
1398
+ * @returns true if the node is to be treated as a "text entity", false otherwise.
1399
+ */},{key:"isTextEntity",value:function isTextEntity(){return false;}}],[{key:"getType",value:function getType(){return'text';}},{key:"clone",value:function clone(node){return new TextNode(node.__text,node.__key);}},{key:"importDOM",value:function importDOM(){return{'#text':function text(){return{conversion:$convertTextDOMNode,priority:0};},'b':function b(){return{conversion:convertBringAttentionToElement,priority:0};},'code':function code(){return{conversion:convertTextFormatElement,priority:0};},'em':function em(){return{conversion:convertTextFormatElement,priority:0};},'i':function i(){return{conversion:convertTextFormatElement,priority:0};},'mark':function mark(){return{conversion:convertTextFormatElement,priority:0};},'s':function s(){return{conversion:convertTextFormatElement,priority:0};},'span':function span(){return{conversion:convertSpanElement,priority:0};},'strong':function strong(){return{conversion:convertTextFormatElement,priority:0};},'sub':function sub(){return{conversion:convertTextFormatElement,priority:0};},'sup':function sup(){return{conversion:convertTextFormatElement,priority:0};},'u':function u(){return{conversion:convertTextFormatElement,priority:0};}};}},{key:"importJSON",value:function importJSON(serializedNode){return $createTextNode().updateFromJSON(serializedNode);}}]);return TextNode;}(LexicalNode);function convertSpanElement(domNode){// domNode is a <span> since we matched it by nodeName
1400
+ var span=domNode;var style=span.style;return{forChild:applyTextFormatFromStyle(style),node:null};}function convertBringAttentionToElement(domNode){// domNode is a <b> since we matched it by nodeName
1401
+ var b=domNode;// Google Docs wraps all copied HTML in a <b> with font-weight normal
1402
+ var hasNormalFontWeight=b.style.fontWeight==='normal';return{forChild:applyTextFormatFromStyle(b.style,hasNormalFontWeight?undefined:'bold'),node:null};}var preParentCache=new WeakMap();function isNodePre(node){if(!isHTMLElement(node)){return false;}else if(node.nodeName==='PRE'){return true;}var whiteSpace=node.style.whiteSpace;return typeof whiteSpace==='string'&&whiteSpace.startsWith('pre');}function findParentPreDOMNode(node){var cached;var parent=node.parentNode;var visited=[node];while(parent!==null&&(cached=preParentCache.get(parent))===undefined&&!isNodePre(parent)){visited.push(parent);parent=parent.parentNode;}var resultNode=cached===undefined?parent:cached;for(var i=0;i<visited.length;i++){preParentCache.set(visited[i],resultNode);}return resultNode;}function $convertTextDOMNode(domNode){var domNode_=domNode;var parentDom=domNode.parentElement;if(!(parentDom!==null)){formatDevErrorMessage("Expected parentElement of Text not to be null");}var textContent=domNode_.textContent||'';// No collapse and preserve segment break for pre, pre-wrap and pre-line
1403
+ if(findParentPreDOMNode(domNode_)!==null){var parts=textContent.split(/(\r?\n|\t)/);var nodes=[];var length=parts.length;for(var i=0;i<length;i++){var part=parts[i];if(part==='\n'||part==='\r\n'){nodes.push($createLineBreakNode());}else if(part==='\t'){nodes.push($createTabNode());}else if(part!==''){nodes.push($createTextNode(part));}}return{node:nodes};}textContent=textContent.replace(/\r/g,'').replace(/[ \t\n]+/g,' ');if(textContent===''){return{node:null};}if(textContent[0]===' '){// Traverse backward while in the same line. If content contains new line or tab -> potential
1404
+ // delete, other elements can borrow from this one. Deletion depends on whether it's also the
1405
+ // last space (see next condition: textContent[textContent.length - 1] === ' '))
1406
+ var previousText=domNode_;var isStartOfLine=true;while(previousText!==null&&(previousText=findTextInLine(previousText,false))!==null){var previousTextContent=previousText.textContent||'';if(previousTextContent.length>0){if(/[ \t\n]$/.test(previousTextContent)){textContent=textContent.slice(1);}isStartOfLine=false;break;}}if(isStartOfLine){textContent=textContent.slice(1);}}if(textContent[textContent.length-1]===' '){// Traverse forward while in the same line, preserve if next inline will require a space
1407
+ var nextText=domNode_;var isEndOfLine=true;while(nextText!==null&&(nextText=findTextInLine(nextText,true))!==null){var nextTextContent=(nextText.textContent||'').replace(/^( |\t|\r?\n)+/,'');if(nextTextContent.length>0){isEndOfLine=false;break;}}if(isEndOfLine){textContent=textContent.slice(0,textContent.length-1);}}if(textContent===''){return{node:null};}return{node:$createTextNode(textContent)};}function findTextInLine(text,forward){var node=text;// eslint-disable-next-line no-constant-condition
1408
+ while(true){var sibling=void 0;while((sibling=forward?node.nextSibling:node.previousSibling)===null){var parentElement=node.parentElement;if(parentElement===null){return null;}node=parentElement;}node=sibling;if(isHTMLElement(node)){var display=node.style.display;if(display===''&&!isInlineDomNode(node)||display!==''&&!display.startsWith('inline')){return null;}}var descendant=node;while((descendant=forward?node.firstChild:node.lastChild)!==null){node=descendant;}if(isDOMTextNode(node)){return node;}else if(node.nodeName==='BR'){return null;}}}var nodeNameToTextFormat={code:'code',em:'italic',i:'italic',mark:'highlight',s:'strikethrough',strong:'bold',sub:'subscript',sup:'superscript',u:'underline'};function convertTextFormatElement(domNode){var format=nodeNameToTextFormat[domNode.nodeName.toLowerCase()];if(format===undefined){return{node:null};}return{forChild:applyTextFormatFromStyle(domNode.style,format),node:null};}function $createTextNode(){var text=arguments.length>0&&arguments[0]!==undefined?arguments[0]:'';return $applyNodeReplacement(new TextNode(text));}function $isTextNode(node){return node instanceof TextNode;}function applyTextFormatFromStyle(style,shouldApply){var fontWeight=style.fontWeight;var textDecoration=style.textDecoration.split(' ');// Google Docs uses span tags + font-weight for bold text
1409
+ var hasBoldFontWeight=fontWeight==='700'||fontWeight==='bold';// Google Docs uses span tags + text-decoration: line-through for strikethrough text
1410
+ var hasLinethroughTextDecoration=textDecoration.includes('line-through');// Google Docs uses span tags + font-style for italic text
1411
+ var hasItalicFontStyle=style.fontStyle==='italic';// Google Docs uses span tags + text-decoration: underline for underline text
1412
+ var hasUnderlineTextDecoration=textDecoration.includes('underline');// Google Docs uses span tags + vertical-align to specify subscript and superscript
1413
+ var verticalAlign=style.verticalAlign;return function(lexicalNode){if(!$isTextNode(lexicalNode)){return lexicalNode;}if(hasBoldFontWeight&&!lexicalNode.hasFormat('bold')){lexicalNode.toggleFormat('bold');}if(hasLinethroughTextDecoration&&!lexicalNode.hasFormat('strikethrough')){lexicalNode.toggleFormat('strikethrough');}if(hasItalicFontStyle&&!lexicalNode.hasFormat('italic')){lexicalNode.toggleFormat('italic');}if(hasUnderlineTextDecoration&&!lexicalNode.hasFormat('underline')){lexicalNode.toggleFormat('underline');}if(verticalAlign==='sub'&&!lexicalNode.hasFormat('subscript')){lexicalNode.toggleFormat('subscript');}if(verticalAlign==='super'&&!lexicalNode.hasFormat('superscript')){lexicalNode.toggleFormat('superscript');}if(shouldApply&&!lexicalNode.hasFormat(shouldApply)){lexicalNode.toggleFormat(shouldApply);}return lexicalNode;};}/** @noInheritDoc */var TabNode=/*#__PURE__*/function(_TextNode){_inherits(TabNode,_TextNode);var _super3=_createSuper(TabNode);function TabNode(key){var _this3;_classCallCheck(this,TabNode);_this3=_super3.call(this,'\t',key);_this3.__detail=IS_UNMERGEABLE;return _this3;}_createClass(TabNode,[{key:"createDOM",value:function createDOM(config){var dom=_get(_getPrototypeOf(TabNode.prototype),"createDOM",this).call(this,config);var classNames=getCachedClassNameArray(config.theme,'tab');if(classNames!==undefined){var domClassList=dom.classList;domClassList.add.apply(domClassList,_toConsumableArray(classNames));}return dom;}},{key:"setTextContent",value:function setTextContent(text){if(!(text==='\t'||text==='')){formatDevErrorMessage("TabNode does not support setTextContent");}return _get(_getPrototypeOf(TabNode.prototype),"setTextContent",this).call(this,'\t');}},{key:"spliceText",value:function spliceText(offset,delCount,newText,moveSelection){if(!(newText===''&&delCount===0||newText==='\t'&&delCount===1)){formatDevErrorMessage("TabNode does not support spliceText");}return this;}},{key:"setDetail",value:function setDetail(detail){if(!(detail===IS_UNMERGEABLE)){formatDevErrorMessage("TabNode does not support setDetail");}return this;}},{key:"setMode",value:function setMode(type){if(!(type==='normal')){formatDevErrorMessage("TabNode does not support setMode");}return this;}},{key:"canInsertTextBefore",value:function canInsertTextBefore(){return false;}},{key:"canInsertTextAfter",value:function canInsertTextAfter(){return false;}}],[{key:"getType",value:function getType(){return'tab';}},{key:"clone",value:function clone(node){return new TabNode(node.__key);}},{key:"importDOM",value:function importDOM(){return null;}},{key:"importJSON",value:function importJSON(serializedTabNode){return $createTabNode().updateFromJSON(serializedTabNode);}}]);return TabNode;}(TextNode);function $createTabNode(){return $applyNodeReplacement(new TabNode());}function $isTabNode(node){return node instanceof TabNode;}var Point=/*#__PURE__*/function(){function Point(key,offset,type){_classCallCheck(this,Point);_defineProperty(this,"key",void 0);_defineProperty(this,"offset",void 0);_defineProperty(this,"type",void 0);_defineProperty(this,"_selection",void 0);{// This prevents a circular reference error when serialized as JSON,
1414
+ // which happens on unit test failures
1415
+ Object.defineProperty(this,'_selection',{enumerable:false,writable:true});}this._selection=null;this.key=key;this.offset=offset;this.type=type;}_createClass(Point,[{key:"is",value:function is(point){return this.key===point.key&&this.offset===point.offset&&this.type===point.type;}},{key:"isBefore",value:function isBefore(b){if(this.key===b.key){return this.offset<b.offset;}var aCaret=$normalizeCaret($caretFromPoint(this,'next'));var bCaret=$normalizeCaret($caretFromPoint(b,'next'));return $comparePointCaretNext(aCaret,bCaret)<0;}},{key:"getNode",value:function getNode(){var key=this.key;var node=$getNodeByKey(key);if(node===null){{formatDevErrorMessage("Point.getNode: node not found");}}return node;}},{key:"set",value:function set(key,offset,type,onlyIfChanged){var selection=this._selection;var oldKey=this.key;if(onlyIfChanged&&this.key===key&&this.offset===offset&&this.type===type){return;}this.key=key;this.offset=offset;this.type=type;{var node=$getNodeByKey(key);if(!(type==='text'?$isTextNode(node):$isElementNode(node))){formatDevErrorMessage("PointType.set: node with key ".concat(key," is ").concat(node?node.__type:'[not found]'," and can not be used for a ").concat(type," point"));}}if(!isCurrentlyReadOnlyMode()){if($getCompositionKey()===oldKey){$setCompositionKey(key);}if(selection!==null){selection.setCachedNodes(null);selection.dirty=true;}}}}]);return Point;}();function $createPoint(key,offset,type){// @ts-expect-error: intentionally cast as we use a class for perf reasons
1416
+ return new Point(key,offset,type);}function selectPointOnNode(point,node){var key=node.__key;var offset=point.offset;var type='element';if($isTextNode(node)){type='text';var textContentLength=node.getTextContentSize();if(offset>textContentLength){offset=textContentLength;}}else if(!$isElementNode(node)){var nextSibling=node.getNextSibling();if($isTextNode(nextSibling)){key=nextSibling.__key;offset=0;type='text';}else{var parentNode=node.getParent();if(parentNode){key=parentNode.__key;offset=node.getIndexWithinParent()+1;}}}point.set(key,offset,type);}function $moveSelectionPointToEnd(point,node){if($isElementNode(node)){var lastNode=node.getLastDescendant();if($isElementNode(lastNode)||$isTextNode(lastNode)){selectPointOnNode(point,lastNode);}else{selectPointOnNode(point,node);}}else{selectPointOnNode(point,node);}}function $transferStartingElementPointToTextPoint(start,end,format,style){var element=start.getNode();var placementNode=element.getChildAtIndex(start.offset);var textNode=$createTextNode();textNode.setFormat(format);textNode.setStyle(style);if($isParagraphNode(placementNode)){placementNode.splice(0,0,[textNode]);}else{var target=$isRootNode(element)?$createParagraphNode().append(textNode):textNode;if(placementNode===null){element.append(target);}else{placementNode.insertBefore(target);}}// Transfer the element point to a text point.
1417
+ if(start.is(end)){end.set(textNode.__key,0,'text');}start.set(textNode.__key,0,'text');}var NodeSelection=/*#__PURE__*/function(){function NodeSelection(objects){_classCallCheck(this,NodeSelection);_defineProperty(this,"_nodes",void 0);_defineProperty(this,"_cachedNodes",void 0);_defineProperty(this,"dirty",void 0);this._cachedNodes=null;this._nodes=objects;this.dirty=false;}_createClass(NodeSelection,[{key:"getCachedNodes",value:function getCachedNodes(){return this._cachedNodes;}},{key:"setCachedNodes",value:function setCachedNodes(nodes){this._cachedNodes=nodes;}},{key:"is",value:function is(selection){if(!$isNodeSelection(selection)){return false;}var a=this._nodes;var b=selection._nodes;return a.size===b.size&&Array.from(a).every(function(key){return b.has(key);});}},{key:"isCollapsed",value:function isCollapsed(){return false;}},{key:"isBackward",value:function isBackward(){return false;}},{key:"getStartEndPoints",value:function getStartEndPoints(){return null;}},{key:"add",value:function add(key){this.dirty=true;this._nodes.add(key);this._cachedNodes=null;}},{key:"delete",value:function _delete(key){this.dirty=true;this._nodes.delete(key);this._cachedNodes=null;}},{key:"clear",value:function clear(){this.dirty=true;this._nodes.clear();this._cachedNodes=null;}},{key:"has",value:function has(key){return this._nodes.has(key);}},{key:"clone",value:function clone(){return new NodeSelection(new Set(this._nodes));}},{key:"extract",value:function extract(){return this.getNodes();}},{key:"insertRawText",value:function insertRawText(text){// Do nothing?
1418
+ }},{key:"insertText",value:function insertText(){// Do nothing?
1419
+ }},{key:"insertNodes",value:function insertNodes(nodes){var selectedNodes=this.getNodes();var selectedNodesLength=selectedNodes.length;var lastSelectedNode=selectedNodes[selectedNodesLength-1];var selectionAtEnd;// Insert nodes
1420
+ if($isTextNode(lastSelectedNode)){selectionAtEnd=lastSelectedNode.select();}else{var index=lastSelectedNode.getIndexWithinParent()+1;selectionAtEnd=lastSelectedNode.getParentOrThrow().select(index,index);}selectionAtEnd.insertNodes(nodes);// Remove selected nodes
1421
+ for(var i=0;i<selectedNodesLength;i++){selectedNodes[i].remove();}}},{key:"getNodes",value:function getNodes(){var cachedNodes=this._cachedNodes;if(cachedNodes!==null){return cachedNodes;}var objects=this._nodes;var nodes=[];var _iterator13=_createForOfIteratorHelper(objects),_step13;try{for(_iterator13.s();!(_step13=_iterator13.n()).done;){var object=_step13.value;var node=$getNodeByKey(object);if(node!==null){nodes.push(node);}}}catch(err){_iterator13.e(err);}finally{_iterator13.f();}if(!isCurrentlyReadOnlyMode()){this._cachedNodes=nodes;}return nodes;}},{key:"getTextContent",value:function getTextContent(){var nodes=this.getNodes();var textContent='';for(var i=0;i<nodes.length;i++){textContent+=nodes[i].getTextContent();}return textContent;}/**
1422
+ * Remove all nodes in the NodeSelection. If there were any nodes,
1423
+ * replace the selection with a new RangeSelection at the previous
1424
+ * location of the first node.
1425
+ */},{key:"deleteNodes",value:function deleteNodes(){var nodes=this.getNodes();if(($getSelection()||$getPreviousSelection())===this&&nodes[0]){var firstCaret=$getSiblingCaret(nodes[0],'next');$setSelectionFromCaretRange($getCaretRange(firstCaret,firstCaret));}var _iterator14=_createForOfIteratorHelper(nodes),_step14;try{for(_iterator14.s();!(_step14=_iterator14.n()).done;){var node=_step14.value;node.remove();}}catch(err){_iterator14.e(err);}finally{_iterator14.f();}}}]);return NodeSelection;}();function $isRangeSelection(x){return x instanceof RangeSelection;}var RangeSelection=/*#__PURE__*/function(){function RangeSelection(anchor,focus,format,style){_classCallCheck(this,RangeSelection);_defineProperty(this,"format",void 0);_defineProperty(this,"style",void 0);_defineProperty(this,"anchor",void 0);_defineProperty(this,"focus",void 0);_defineProperty(this,"_cachedNodes",void 0);_defineProperty(this,"dirty",void 0);this.anchor=anchor;this.focus=focus;anchor._selection=this;focus._selection=this;this._cachedNodes=null;this.format=format;this.style=style;this.dirty=false;}_createClass(RangeSelection,[{key:"getCachedNodes",value:function getCachedNodes(){return this._cachedNodes;}},{key:"setCachedNodes",value:function setCachedNodes(nodes){this._cachedNodes=nodes;}/**
1426
+ * Used to check if the provided selections is equal to this one by value,
1427
+ * including anchor, focus, format, and style properties.
1428
+ * @param selection - the Selection to compare this one to.
1429
+ * @returns true if the Selections are equal, false otherwise.
1430
+ */},{key:"is",value:function is(selection){if(!$isRangeSelection(selection)){return false;}return this.anchor.is(selection.anchor)&&this.focus.is(selection.focus)&&this.format===selection.format&&this.style===selection.style;}/**
1431
+ * Returns whether the Selection is "collapsed", meaning the anchor and focus are
1432
+ * the same node and have the same offset.
1433
+ *
1434
+ * @returns true if the Selection is collapsed, false otherwise.
1435
+ */},{key:"isCollapsed",value:function isCollapsed(){return this.anchor.is(this.focus);}/**
1436
+ * Gets all the nodes in the Selection. Uses caching to make it generally suitable
1437
+ * for use in hot paths.
1438
+ *
1439
+ * See also the {@link CaretRange} APIs (starting with
1440
+ * {@link $caretRangeFromSelection}), which are likely to provide a better
1441
+ * foundation for any operation where partial selection is relevant
1442
+ * (e.g. the anchor or focus are inside an ElementNode and TextNode)
1443
+ *
1444
+ * @returns an Array containing all the nodes in the Selection
1445
+ */},{key:"getNodes",value:function getNodes(){var cachedNodes=this._cachedNodes;if(cachedNodes!==null){return cachedNodes;}var range=$getCaretRangeInDirection($caretRangeFromSelection(this),'next');var nodes=$getNodesFromCaretRangeCompat(range);{if(this.isCollapsed()&&nodes.length>1){{formatDevErrorMessage("RangeSelection.getNodes() returned ".concat(String(nodes.length)," > 1 nodes in a collapsed selection"));}}}if(!isCurrentlyReadOnlyMode()){this._cachedNodes=nodes;}return nodes;}/**
1446
+ * Sets this Selection to be of type "text" at the provided anchor and focus values.
1447
+ *
1448
+ * @param anchorNode - the anchor node to set on the Selection
1449
+ * @param anchorOffset - the offset to set on the Selection
1450
+ * @param focusNode - the focus node to set on the Selection
1451
+ * @param focusOffset - the focus offset to set on the Selection
1452
+ */},{key:"setTextNodeRange",value:function setTextNodeRange(anchorNode,anchorOffset,focusNode,focusOffset){this.anchor.set(anchorNode.__key,anchorOffset,'text');this.focus.set(focusNode.__key,focusOffset,'text');}/**
1453
+ * Gets the (plain) text content of all the nodes in the selection.
1454
+ *
1455
+ * @returns a string representing the text content of all the nodes in the Selection
1456
+ */},{key:"getTextContent",value:function getTextContent(){var nodes=this.getNodes();if(nodes.length===0){return'';}var firstNode=nodes[0];var lastNode=nodes[nodes.length-1];var anchor=this.anchor;var focus=this.focus;var isBefore=anchor.isBefore(focus);var _$getCharacterOffsets=$getCharacterOffsets(this),_$getCharacterOffsets2=_slicedToArray(_$getCharacterOffsets,2),anchorOffset=_$getCharacterOffsets2[0],focusOffset=_$getCharacterOffsets2[1];var textContent='';var prevWasElement=true;for(var i=0;i<nodes.length;i++){var node=nodes[i];if($isElementNode(node)&&!node.isInline()){if(!prevWasElement){textContent+='\n';}if(node.isEmpty()){prevWasElement=false;}else{prevWasElement=true;}}else{prevWasElement=false;if($isTextNode(node)){var text=node.getTextContent();if(node===firstNode){if(node===lastNode){if(anchor.type!=='element'||focus.type!=='element'||focus.offset===anchor.offset){text=anchorOffset<focusOffset?text.slice(anchorOffset,focusOffset):text.slice(focusOffset,anchorOffset);}}else{text=isBefore?text.slice(anchorOffset):text.slice(focusOffset);}}else if(node===lastNode){text=isBefore?text.slice(0,focusOffset):text.slice(0,anchorOffset);}textContent+=text;}else if(($isDecoratorNode(node)||$isLineBreakNode(node))&&(node!==lastNode||!this.isCollapsed())){textContent+=node.getTextContent();}}}return textContent;}/**
1457
+ * Attempts to map a DOM selection range onto this Lexical Selection,
1458
+ * setting the anchor, focus, and type accordingly
1459
+ *
1460
+ * @param range a DOM Selection range conforming to the StaticRange interface.
1461
+ */},{key:"applyDOMRange",value:function applyDOMRange(range){var editor=getActiveEditor();var currentEditorState=editor.getEditorState();var lastSelection=currentEditorState._selection;var resolvedSelectionPoints=$internalResolveSelectionPoints(range.startContainer,range.startOffset,range.endContainer,range.endOffset,editor,lastSelection);if(resolvedSelectionPoints===null){return;}var _resolvedSelectionPoi=_slicedToArray(resolvedSelectionPoints,2),anchorPoint=_resolvedSelectionPoi[0],focusPoint=_resolvedSelectionPoi[1];this.anchor.set(anchorPoint.key,anchorPoint.offset,anchorPoint.type,true);this.focus.set(focusPoint.key,focusPoint.offset,focusPoint.type,true);// Firefox will use an element point rather than a text point in some cases,
1462
+ // so we normalize for that
1463
+ $normalizeSelection(this);}/**
1464
+ * Creates a new RangeSelection, copying over all the property values from this one.
1465
+ *
1466
+ * @returns a new RangeSelection with the same property values as this one.
1467
+ */},{key:"clone",value:function clone(){var anchor=this.anchor;var focus=this.focus;var selection=new RangeSelection($createPoint(anchor.key,anchor.offset,anchor.type),$createPoint(focus.key,focus.offset,focus.type),this.format,this.style);return selection;}/**
1468
+ * Toggles the provided format on all the TextNodes in the Selection.
1469
+ *
1470
+ * @param format a string TextFormatType to toggle on the TextNodes in the selection
1471
+ */},{key:"toggleFormat",value:function toggleFormat(format){this.format=toggleTextFormatType(this.format,format,null);this.dirty=true;}/**
1472
+ * Sets the value of the format property on the Selection
1473
+ *
1474
+ * @param format - the format to set at the value of the format property.
1475
+ */},{key:"setFormat",value:function setFormat(format){this.format=format;this.dirty=true;}/**
1476
+ * Sets the value of the style property on the Selection
1477
+ *
1478
+ * @param style - the style to set at the value of the style property.
1479
+ */},{key:"setStyle",value:function setStyle(style){this.style=style;this.dirty=true;}/**
1480
+ * Returns whether the provided TextFormatType is present on the Selection. This will be true if any node in the Selection
1481
+ * has the specified format.
1482
+ *
1483
+ * @param type the TextFormatType to check for.
1484
+ * @returns true if the provided format is currently toggled on on the Selection, false otherwise.
1485
+ */},{key:"hasFormat",value:function hasFormat(type){var formatFlag=TEXT_TYPE_TO_FORMAT[type];return(this.format&formatFlag)!==0;}/**
1486
+ * Attempts to insert the provided text into the EditorState at the current Selection.
1487
+ * converts tabs, newlines, and carriage returns into LexicalNodes.
1488
+ *
1489
+ * @param text the text to insert into the Selection
1490
+ */},{key:"insertRawText",value:function insertRawText(text){var parts=text.split(/(\r?\n|\t)/);var nodes=[];var length=parts.length;for(var i=0;i<length;i++){var part=parts[i];if(part==='\n'||part==='\r\n'){nodes.push($createLineBreakNode());}else if(part==='\t'){nodes.push($createTabNode());}else{nodes.push($createTextNode(part));}}this.insertNodes(nodes);}/**
1491
+ * Insert the provided text into the EditorState at the current Selection.
1492
+ *
1493
+ * @param text the text to insert into the Selection
1494
+ */},{key:"insertText",value:function insertText(text){// Now that "removeText" has been improved and does not depend on
1495
+ // insertText, insertText can be greatly simplified. The next
1496
+ // commented version is a WIP (about 5 tests fail).
1497
+ //
1498
+ // this.removeText();
1499
+ // if (text === '') {
1500
+ // return;
1501
+ // }
1502
+ // const anchorNode = this.anchor.getNode();
1503
+ // const textNode = $createTextNode(text);
1504
+ // textNode.setFormat(this.format);
1505
+ // textNode.setStyle(this.style);
1506
+ // if ($isTextNode(anchorNode)) {
1507
+ // const parent = anchorNode.getParentOrThrow();
1508
+ // if (this.anchor.offset === 0) {
1509
+ // if (parent.isInline() && !anchorNode.__prev) {
1510
+ // parent.insertBefore(textNode);
1511
+ // } else {
1512
+ // anchorNode.insertBefore(textNode);
1513
+ // }
1514
+ // } else if (this.anchor.offset === anchorNode.getTextContentSize()) {
1515
+ // if (parent.isInline() && !anchorNode.__next) {
1516
+ // parent.insertAfter(textNode);
1517
+ // } else {
1518
+ // anchorNode.insertAfter(textNode);
1519
+ // }
1520
+ // } else {
1521
+ // const [before] = anchorNode.splitText(this.anchor.offset);
1522
+ // before.insertAfter(textNode);
1523
+ // }
1524
+ // } else {
1525
+ // anchorNode.splice(this.anchor.offset, 0, [textNode]);
1526
+ // }
1527
+ // const nodeToSelect = textNode.isAttached() ? textNode : anchorNode;
1528
+ // nodeToSelect.selectEnd();
1529
+ // // When composing, we need to adjust the anchor offset so that
1530
+ // // we correctly replace that right range.
1531
+ // if (
1532
+ // textNode.isComposing() &&
1533
+ // this.anchor.type === 'text' &&
1534
+ // anchorNode.getTextContent() !== ''
1535
+ // ) {
1536
+ // this.anchor.offset -= text.length;
1537
+ // }
1538
+ var anchor=this.anchor;var focus=this.focus;var format=this.format;var style=this.style;var firstPoint=anchor;var endPoint=focus;if(!this.isCollapsed()&&focus.isBefore(anchor)){firstPoint=focus;endPoint=anchor;}if(firstPoint.type==='element'){$transferStartingElementPointToTextPoint(firstPoint,endPoint,format,style);}if(endPoint.type==='element'){$setPointFromCaret(endPoint,$normalizeCaret($caretFromPoint(endPoint,'next')));}var startOffset=firstPoint.offset;var endOffset=endPoint.offset;var selectedNodes=this.getNodes();var selectedNodesLength=selectedNodes.length;var firstNode=selectedNodes[0];if(!$isTextNode(firstNode)){{formatDevErrorMessage("insertText: first node is not a text node");}}var firstNodeText=firstNode.getTextContent();var firstNodeTextLength=firstNodeText.length;var firstNodeParent=firstNode.getParentOrThrow();var lastIndex=selectedNodesLength-1;var lastNode=selectedNodes[lastIndex];if(selectedNodesLength===1&&endPoint.type==='element'){endOffset=firstNodeTextLength;endPoint.set(firstPoint.key,endOffset,'text');}if(this.isCollapsed()&&startOffset===firstNodeTextLength&&($isTokenOrSegmented(firstNode)||!firstNode.canInsertTextAfter()||!firstNodeParent.canInsertTextAfter()&&firstNode.getNextSibling()===null)){var nextSibling=firstNode.getNextSibling();if(!$isTextNode(nextSibling)||!nextSibling.canInsertTextBefore()||$isTokenOrSegmented(nextSibling)){nextSibling=$createTextNode();nextSibling.setFormat(format);nextSibling.setStyle(style);if(!firstNodeParent.canInsertTextAfter()){firstNodeParent.insertAfter(nextSibling);}else{firstNode.insertAfter(nextSibling);}}nextSibling.select(0,0);firstNode=nextSibling;if(text!==''){this.insertText(text);return;}}else if(this.isCollapsed()&&startOffset===0&&($isTokenOrSegmented(firstNode)||!firstNode.canInsertTextBefore()||!firstNodeParent.canInsertTextBefore()&&firstNode.getPreviousSibling()===null)){var prevSibling=firstNode.getPreviousSibling();if(!$isTextNode(prevSibling)||$isTokenOrSegmented(prevSibling)){prevSibling=$createTextNode();prevSibling.setFormat(format);if(!firstNodeParent.canInsertTextBefore()){firstNodeParent.insertBefore(prevSibling);}else{firstNode.insertBefore(prevSibling);}}prevSibling.select();firstNode=prevSibling;if(text!==''){this.insertText(text);return;}}else if(firstNode.isSegmented()&&startOffset!==firstNodeTextLength){var textNode=$createTextNode(firstNode.getTextContent());textNode.setFormat(format);firstNode.replace(textNode);firstNode=textNode;}else if(!this.isCollapsed()&&text!==''){// When the firstNode or lastNode parents are elements that
1539
+ // do not allow text to be inserted before or after, we first
1540
+ // clear the content. Then we normalize selection, then insert
1541
+ // the new content.
1542
+ var lastNodeParent=lastNode.getParent();if(!firstNodeParent.canInsertTextBefore()||!firstNodeParent.canInsertTextAfter()||$isElementNode(lastNodeParent)&&(!lastNodeParent.canInsertTextBefore()||!lastNodeParent.canInsertTextAfter())){this.insertText('');$normalizeSelectionPointsForBoundaries(this.anchor,this.focus,null);this.insertText(text);return;}}if(selectedNodesLength===1){if($isTokenOrTab(firstNode)){var _textNode=$createTextNode(text);_textNode.select();firstNode.replace(_textNode);return;}var firstNodeFormat=firstNode.getFormat();var firstNodeStyle=firstNode.getStyle();if(startOffset===endOffset&&(firstNodeFormat!==format||firstNodeStyle!==style)){if(firstNode.getTextContent()===''){firstNode.setFormat(format);firstNode.setStyle(style);}else{var _textNode2=$createTextNode(text);_textNode2.setFormat(format);_textNode2.setStyle(style);_textNode2.select();if(startOffset===0){firstNode.insertBefore(_textNode2,false);}else{var _firstNode$splitText=firstNode.splitText(startOffset),_firstNode$splitText2=_slicedToArray(_firstNode$splitText,1),targetNode=_firstNode$splitText2[0];targetNode.insertAfter(_textNode2,false);}// When composing, we need to adjust the anchor offset so that
1543
+ // we correctly replace that right range.
1544
+ if(_textNode2.isComposing()&&this.anchor.type==='text'){this.anchor.offset-=text.length;}return;}}else if($isTabNode(firstNode)){// We don't need to check for delCount because there is only the entire selected node case
1545
+ // that can hit here for content size 1 and with canInsertTextBeforeAfter false
1546
+ var _textNode3=$createTextNode(text);_textNode3.setFormat(format);_textNode3.setStyle(style);_textNode3.select();firstNode.replace(_textNode3);return;}var delCount=endOffset-startOffset;firstNode=firstNode.spliceText(startOffset,delCount,text,true);if(firstNode.getTextContent()===''){firstNode.remove();}else if(this.anchor.type==='text'){if(firstNode.isComposing()){// When composing, we need to adjust the anchor offset so that
1547
+ // we correctly replace that right range.
1548
+ this.anchor.offset-=text.length;}else{this.format=firstNodeFormat;this.style=firstNodeStyle;}}}else{var markedNodeKeysForKeep=new Set([].concat(_toConsumableArray(firstNode.getParentKeys()),_toConsumableArray(lastNode.getParentKeys())));// We have to get the parent elements before the next section,
1549
+ // as in that section we might mutate the lastNode.
1550
+ var firstElement=$isElementNode(firstNode)?firstNode:firstNode.getParentOrThrow();var lastElement=$isElementNode(lastNode)?lastNode:lastNode.getParentOrThrow();var lastElementChild=lastNode;// If the last element is inline, we should instead look at getting
1551
+ // the nodes of its parent, rather than itself. This behavior will
1552
+ // then better match how text node insertions work. We will need to
1553
+ // also update the last element's child accordingly as we do this.
1554
+ if(!firstElement.is(lastElement)&&lastElement.isInline()){// Keep traversing till we have a non-inline element parent.
1555
+ do{lastElementChild=lastElement;lastElement=lastElement.getParentOrThrow();}while(lastElement.isInline());}// Handle mutations to the last node.
1556
+ if(endPoint.type==='text'&&(endOffset!==0||lastNode.getTextContent()==='')||endPoint.type==='element'&&lastNode.getIndexWithinParent()<endOffset){if($isTextNode(lastNode)&&!$isTokenOrTab(lastNode)&&endOffset!==lastNode.getTextContentSize()){if(lastNode.isSegmented()){var _textNode4=$createTextNode(lastNode.getTextContent());lastNode.replace(_textNode4);lastNode=_textNode4;}// root node selections only select whole nodes, so no text splice is necessary
1557
+ if(!$isRootNode(endPoint.getNode())&&endPoint.type==='text'){lastNode=lastNode.spliceText(0,endOffset,'');}markedNodeKeysForKeep.add(lastNode.__key);}else{var _lastNodeParent=lastNode.getParentOrThrow();if(!_lastNodeParent.canBeEmpty()&&_lastNodeParent.getChildrenSize()===1){_lastNodeParent.remove();}else{lastNode.remove();}}}else{markedNodeKeysForKeep.add(lastNode.__key);}// Either move the remaining nodes of the last parent to after
1558
+ // the first child, or remove them entirely. If the last parent
1559
+ // is the same as the first parent, this logic also works.
1560
+ var lastNodeChildren=lastElement.getChildren();var selectedNodesSet=new Set(selectedNodes);var firstAndLastElementsAreEqual=firstElement.is(lastElement);// We choose a target to insert all nodes after. In the case of having
1561
+ // and inline starting parent element with a starting node that has no
1562
+ // siblings, we should insert after the starting parent element, otherwise
1563
+ // we will incorrectly merge into the starting parent element.
1564
+ // TODO: should we keep on traversing parents if we're inside another
1565
+ // nested inline element?
1566
+ var insertionTarget=firstElement.isInline()&&firstNode.getNextSibling()===null?firstElement:firstNode;for(var i=lastNodeChildren.length-1;i>=0;i--){var lastNodeChild=lastNodeChildren[i];if(lastNodeChild.is(firstNode)||$isElementNode(lastNodeChild)&&lastNodeChild.isParentOf(firstNode)){break;}if(lastNodeChild.isAttached()){if(!selectedNodesSet.has(lastNodeChild)||lastNodeChild.is(lastElementChild)){if(!firstAndLastElementsAreEqual){insertionTarget.insertAfter(lastNodeChild,false);}}else{lastNodeChild.remove();}}}if(!firstAndLastElementsAreEqual){// Check if we have already moved out all the nodes of the
1567
+ // last parent, and if so, traverse the parent tree and mark
1568
+ // them all as being able to deleted too.
1569
+ var parent=lastElement;var lastRemovedParent=null;while(parent!==null){var children=parent.getChildren();var childrenLength=children.length;if(childrenLength===0||children[childrenLength-1].is(lastRemovedParent)){markedNodeKeysForKeep.delete(parent.__key);lastRemovedParent=parent;}parent=parent.getParent();}}// Ensure we do splicing after moving of nodes, as splicing
1570
+ // can have side-effects (in the case of hashtags).
1571
+ if(!$isTokenOrTab(firstNode)){firstNode=firstNode.spliceText(startOffset,firstNodeTextLength-startOffset,text,true);if(firstNode.getTextContent()===''){firstNode.remove();}else if(firstNode.isComposing()&&this.anchor.type==='text'){// When composing, we need to adjust the anchor offset so that
1572
+ // we correctly replace that right range.
1573
+ this.anchor.offset-=text.length;}}else if(startOffset===firstNodeTextLength){firstNode.select();}else{var _textNode5=$createTextNode(text);_textNode5.select();firstNode.replace(_textNode5);}// Remove all selected nodes that haven't already been removed.
1574
+ for(var _i9=1;_i9<selectedNodesLength;_i9++){var selectedNode=selectedNodes[_i9];var key=selectedNode.__key;if(!markedNodeKeysForKeep.has(key)){selectedNode.remove();}}}}/**
1575
+ * Removes the text in the Selection, adjusting the EditorState accordingly.
1576
+ */},{key:"removeText",value:function removeText(){var isCurrentSelection=$getSelection()===this;var newRange=$removeTextFromCaretRange($caretRangeFromSelection(this));$updateRangeSelectionFromCaretRange(this,newRange);if(isCurrentSelection&&$getSelection()!==this){$setSelection(this);}}// TO-DO: Migrate this method to the new utility function $forEachSelectedTextNode (share similar logic)
1577
+ /**
1578
+ * Applies the provided format to the TextNodes in the Selection, splitting or
1579
+ * merging nodes as necessary.
1580
+ *
1581
+ * @param formatType the format type to apply to the nodes in the Selection.
1582
+ * @param alignWithFormat a 32-bit integer representing formatting flags to align with.
1583
+ */},{key:"formatText",value:function formatText(formatType){var alignWithFormat=arguments.length>1&&arguments[1]!==undefined?arguments[1]:null;if(this.isCollapsed()){this.toggleFormat(formatType);// When changing format, we should stop composition
1584
+ $setCompositionKey(null);return;}var selectedNodes=this.getNodes();var selectedTextNodes=[];var _iterator15=_createForOfIteratorHelper(selectedNodes),_step15;try{for(_iterator15.s();!(_step15=_iterator15.n()).done;){var selectedNode=_step15.value;if($isTextNode(selectedNode)){selectedTextNodes.push(selectedNode);}}}catch(err){_iterator15.e(err);}finally{_iterator15.f();}var applyFormatToElements=function applyFormatToElements(alignWith){selectedNodes.forEach(function(node){if($isElementNode(node)){var newFormat=node.getFormatFlags(formatType,alignWith);node.setTextFormat(newFormat);}});};var selectedTextNodesLength=selectedTextNodes.length;if(selectedTextNodesLength===0){this.toggleFormat(formatType);// When changing format, we should stop composition
1585
+ $setCompositionKey(null);applyFormatToElements(alignWithFormat);return;}var anchor=this.anchor;var focus=this.focus;var isBackward=this.isBackward();var startPoint=isBackward?focus:anchor;var endPoint=isBackward?anchor:focus;var firstIndex=0;var firstNode=selectedTextNodes[0];var startOffset=startPoint.type==='element'?0:startPoint.offset;// In case selection started at the end of text node use next text node
1586
+ if(startPoint.type==='text'&&startOffset===firstNode.getTextContentSize()){firstIndex=1;firstNode=selectedTextNodes[1];startOffset=0;}if(firstNode==null){return;}var firstNextFormat=firstNode.getFormatFlags(formatType,alignWithFormat);applyFormatToElements(firstNextFormat);var lastIndex=selectedTextNodesLength-1;var lastNode=selectedTextNodes[lastIndex];var endOffset=endPoint.type==='text'?endPoint.offset:lastNode.getTextContentSize();// Single node selected
1587
+ if(firstNode.is(lastNode)){// No actual text is selected, so do nothing.
1588
+ if(startOffset===endOffset){return;}// The entire node is selected or it is token, so just format it
1589
+ if($isTokenOrSegmented(firstNode)||startOffset===0&&endOffset===firstNode.getTextContentSize()){firstNode.setFormat(firstNextFormat);}else{// Node is partially selected, so split it into two nodes
1590
+ // add style the selected one.
1591
+ var splitNodes=firstNode.splitText(startOffset,endOffset);var replacement=startOffset===0?splitNodes[0]:splitNodes[1];replacement.setFormat(firstNextFormat);// Update selection only if starts/ends on text node
1592
+ if(startPoint.type==='text'){startPoint.set(replacement.__key,0,'text');}if(endPoint.type==='text'){endPoint.set(replacement.__key,endOffset-startOffset,'text');}}this.format=firstNextFormat;return;}// Multiple nodes selected
1593
+ // The entire first node isn't selected, so split it
1594
+ if(startOffset!==0&&!$isTokenOrSegmented(firstNode)){var _firstNode$splitText3=firstNode.splitText(startOffset);var _firstNode$splitText4=_slicedToArray(_firstNode$splitText3,2);firstNode=_firstNode$splitText4[1];startOffset=0;}firstNode.setFormat(firstNextFormat);var lastNextFormat=lastNode.getFormatFlags(formatType,firstNextFormat);// If the offset is 0, it means no actual characters are selected,
1595
+ // so we skip formatting the last node altogether.
1596
+ if(endOffset>0){if(endOffset!==lastNode.getTextContentSize()&&!$isTokenOrSegmented(lastNode)){var _lastNode$splitText=lastNode.splitText(endOffset);var _lastNode$splitText2=_slicedToArray(_lastNode$splitText,1);lastNode=_lastNode$splitText2[0];}lastNode.setFormat(lastNextFormat);}// Process all text nodes in between
1597
+ for(var i=firstIndex+1;i<lastIndex;i++){var textNode=selectedTextNodes[i];var nextFormat=textNode.getFormatFlags(formatType,lastNextFormat);textNode.setFormat(nextFormat);}// Update selection only if starts/ends on text node
1598
+ if(startPoint.type==='text'){startPoint.set(firstNode.__key,startOffset,'text');}if(endPoint.type==='text'){endPoint.set(lastNode.__key,endOffset,'text');}this.format=firstNextFormat|lastNextFormat;}/**
1599
+ * Attempts to "intelligently" insert an arbitrary list of Lexical nodes into the EditorState at the
1600
+ * current Selection according to a set of heuristics that determine how surrounding nodes
1601
+ * should be changed, replaced, or moved to accommodate the incoming ones.
1602
+ *
1603
+ * @param nodes - the nodes to insert
1604
+ */},{key:"insertNodes",value:function insertNodes(nodes){if(nodes.length===0){return;}if(!this.isCollapsed()){this.removeText();}if(this.anchor.key==='root'){this.insertParagraph();var selection=$getSelection();if(!$isRangeSelection(selection)){formatDevErrorMessage("Expected RangeSelection after insertParagraph");}return selection.insertNodes(nodes);}var firstPoint=this.isBackward()?this.focus:this.anchor;var firstNode=firstPoint.getNode();var firstBlock=$findMatchingParent(firstNode,INTERNAL_$isBlock);var last=nodes[nodes.length-1];// CASE 1: insert inside a code block
1605
+ if($isElementNode(firstBlock)&&'__language'in firstBlock){if('__language'in nodes[0]){this.insertText(nodes[0].getTextContent());}else{var index=$removeTextAndSplitBlock(this);firstBlock.splice(index,0,nodes);last.selectEnd();}return;}// CASE 2: All elements of the array are inline
1606
+ var notInline=function notInline(node){return($isElementNode(node)||$isDecoratorNode(node))&&!node.isInline();};if(!nodes.some(notInline)){if(!$isElementNode(firstBlock)){formatDevErrorMessage("Expected node ".concat(firstNode.constructor.name," of type ").concat(firstNode.getType()," to have a block ElementNode ancestor"));}var _index=$removeTextAndSplitBlock(this);firstBlock.splice(_index,0,nodes);last.selectEnd();return;}// CASE 3: At least 1 element of the array is not inline
1607
+ var blocksParent=$wrapInlineNodes(nodes);var nodeToSelect=blocksParent.getLastDescendant();var blocks=blocksParent.getChildren();var isMergeable=function isMergeable(node){return $isElementNode(node)&&INTERNAL_$isBlock(node)&&!node.isEmpty()&&$isElementNode(firstBlock)&&(!firstBlock.isEmpty()||firstBlock.canMergeWhenEmpty());};var shouldInsert=!$isElementNode(firstBlock)||!firstBlock.isEmpty();var insertedParagraph=shouldInsert?this.insertParagraph():null;var lastToInsert=blocks[blocks.length-1];var firstToInsert=blocks[0];if(isMergeable(firstToInsert)){if(!$isElementNode(firstBlock)){formatDevErrorMessage("Expected node ".concat(firstNode.constructor.name," of type ").concat(firstNode.getType()," to have a block ElementNode ancestor"));}firstBlock.append.apply(firstBlock,_toConsumableArray(firstToInsert.getChildren()));firstToInsert=blocks[1];}if(firstToInsert){if(!(firstBlock!==null)){formatDevErrorMessage("Expected node ".concat(firstNode.constructor.name," of type ").concat(firstNode.getType()," to have a block ancestor"));}insertRangeAfter(firstBlock,firstToInsert);}var lastInsertedBlock=$findMatchingParent(nodeToSelect,INTERNAL_$isBlock);if(insertedParagraph&&$isElementNode(lastInsertedBlock)&&(insertedParagraph.canMergeWhenEmpty()||INTERNAL_$isBlock(lastToInsert))){lastInsertedBlock.append.apply(lastInsertedBlock,_toConsumableArray(insertedParagraph.getChildren()));insertedParagraph.remove();}if($isElementNode(firstBlock)&&firstBlock.isEmpty()){firstBlock.remove();}nodeToSelect.selectEnd();// To understand this take a look at the test "can wrap post-linebreak nodes into new element"
1608
+ var lastChild=$isElementNode(firstBlock)?firstBlock.getLastChild():null;if($isLineBreakNode(lastChild)&&lastInsertedBlock!==firstBlock){lastChild.remove();}}/**
1609
+ * Inserts a new ParagraphNode into the EditorState at the current Selection
1610
+ *
1611
+ * @returns the newly inserted node.
1612
+ */},{key:"insertParagraph",value:function insertParagraph(){if(this.anchor.key==='root'){var paragraph=$createParagraphNode();$getRoot().splice(this.anchor.offset,0,[paragraph]);paragraph.select();return paragraph;}var index=$removeTextAndSplitBlock(this);var block=$findMatchingParent(this.anchor.getNode(),INTERNAL_$isBlock);if(!$isElementNode(block)){formatDevErrorMessage("Expected ancestor to be a block ElementNode");}var firstToAppend=block.getChildAtIndex(index);var nodesToInsert=firstToAppend?[firstToAppend].concat(_toConsumableArray(firstToAppend.getNextSiblings())):[];var newBlock=block.insertNewAfter(this,false);if(newBlock){newBlock.append.apply(newBlock,_toConsumableArray(nodesToInsert));newBlock.selectStart();return newBlock;}// if newBlock is null, it means that block is of type CodeNode.
1613
+ return null;}/**
1614
+ * Inserts a logical linebreak, which may be a new LineBreakNode or a new ParagraphNode, into the EditorState at the
1615
+ * current Selection.
1616
+ */},{key:"insertLineBreak",value:function insertLineBreak(selectStart){var lineBreak=$createLineBreakNode();this.insertNodes([lineBreak]);// this is used in MacOS with the command 'ctrl-O' (openLineBreak)
1617
+ if(selectStart){var parent=lineBreak.getParentOrThrow();var index=lineBreak.getIndexWithinParent();parent.select(index,index);}}/**
1618
+ * Extracts the nodes in the Selection, splitting nodes where necessary
1619
+ * to get offset-level precision.
1620
+ *
1621
+ * @returns The nodes in the Selection
1622
+ */},{key:"extract",value:function extract(){var selectedNodes=_toConsumableArray(this.getNodes());var selectedNodesLength=selectedNodes.length;var firstNode=selectedNodes[0];var lastNode=selectedNodes[selectedNodesLength-1];var _$getCharacterOffsets3=$getCharacterOffsets(this),_$getCharacterOffsets4=_slicedToArray(_$getCharacterOffsets3,2),anchorOffset=_$getCharacterOffsets4[0],focusOffset=_$getCharacterOffsets4[1];var isBackward=this.isBackward();var _ref4=isBackward?[this.focus,this.anchor]:[this.anchor,this.focus],_ref5=_slicedToArray(_ref4,2),startPoint=_ref5[0],endPoint=_ref5[1];var _ref6=isBackward?[focusOffset,anchorOffset]:[anchorOffset,focusOffset],_ref7=_slicedToArray(_ref6,2),startOffset=_ref7[0],endOffset=_ref7[1];if(selectedNodesLength===0){return[];}else if(selectedNodesLength===1){if($isTextNode(firstNode)&&!this.isCollapsed()){var splitNodes=firstNode.splitText(startOffset,endOffset);var node=startOffset===0?splitNodes[0]:splitNodes[1];if(node){startPoint.set(node.getKey(),0,'text');endPoint.set(node.getKey(),node.getTextContentSize(),'text');return[node];}return[];}return[firstNode];}if($isTextNode(firstNode)){if(startOffset===firstNode.getTextContentSize()){selectedNodes.shift();}else if(startOffset!==0){var _firstNode$splitText5=firstNode.splitText(startOffset);var _firstNode$splitText6=_slicedToArray(_firstNode$splitText5,2);firstNode=_firstNode$splitText6[1];selectedNodes[0]=firstNode;startPoint.set(firstNode.getKey(),0,'text');}}if($isTextNode(lastNode)){var lastNodeText=lastNode.getTextContent();var lastNodeTextLength=lastNodeText.length;if(endOffset===0){selectedNodes.pop();}else if(endOffset!==lastNodeTextLength){var _lastNode$splitText3=lastNode.splitText(endOffset);var _lastNode$splitText4=_slicedToArray(_lastNode$splitText3,1);lastNode=_lastNode$splitText4[0];selectedNodes[selectedNodes.length-1]=lastNode;endPoint.set(lastNode.getKey(),lastNode.getTextContentSize(),'text');}}return selectedNodes;}/**
1623
+ * Modifies the Selection according to the parameters and a set of heuristics that account for
1624
+ * various node types. Can be used to safely move or extend selection by one logical "unit" without
1625
+ * dealing explicitly with all the possible node types.
1626
+ *
1627
+ * @param alter the type of modification to perform
1628
+ * @param isBackward whether or not selection is backwards
1629
+ * @param granularity the granularity at which to apply the modification
1630
+ */},{key:"modify",value:function modify(alter,isBackward,granularity){if($modifySelectionAroundDecoratorsAndBlocks(this,alter,isBackward,granularity)){return;}var collapse=alter==='move';var editor=getActiveEditor();var domSelection=getDOMSelection(getWindow(editor));if(!domSelection){return;}var blockCursorElement=editor._blockCursorElement;var rootElement=editor._rootElement;var focusNode=this.focus.getNode();// Remove the block cursor element if it exists. This will ensure selection
1631
+ // works as intended. If we leave it in the DOM all sorts of strange bugs
1632
+ // occur. :/
1633
+ if(rootElement!==null&&blockCursorElement!==null&&$isElementNode(focusNode)&&!focusNode.isInline()&&!focusNode.canBeEmpty()){removeDOMBlockCursorElement(blockCursorElement,editor,rootElement);}if(this.dirty){var nextAnchorDOM=getElementByKeyOrThrow(editor,this.anchor.key);var nextFocusDOM=getElementByKeyOrThrow(editor,this.focus.key);if(this.anchor.type==='text'){nextAnchorDOM=getDOMTextNode(nextAnchorDOM);}if(this.focus.type==='text'){nextFocusDOM=getDOMTextNode(nextFocusDOM);}if(nextAnchorDOM&&nextFocusDOM){setDOMSelectionBaseAndExtent(domSelection,nextAnchorDOM,this.anchor.offset,nextFocusDOM,this.focus.offset);}}// We use the DOM selection.modify API here to "tell" us what the selection
1634
+ // will be. We then use it to update the Lexical selection accordingly. This
1635
+ // is much more reliable than waiting for a beforeinput and using the ranges
1636
+ // from getTargetRanges(), and is also better than trying to do it ourselves
1637
+ // using Intl.Segmenter or other workarounds that struggle with word segments
1638
+ // and line segments (especially with word wrapping and non-Roman languages).
1639
+ moveNativeSelection(domSelection,alter,isBackward?'backward':'forward',granularity);// Guard against no ranges
1640
+ if(domSelection.rangeCount>0){var range=domSelection.getRangeAt(0);// Apply the DOM selection to our Lexical selection.
1641
+ var anchorNode=this.anchor.getNode();var root=$isRootNode(anchorNode)?anchorNode:$getNearestRootOrShadowRoot(anchorNode);this.applyDOMRange(range);this.dirty=true;if(!collapse){// Validate selection; make sure that the new extended selection respects shadow roots
1642
+ var nodes=this.getNodes();var validNodes=[];var shrinkSelection=false;for(var i=0;i<nodes.length;i++){var nextNode=nodes[i];if($hasAncestor(nextNode,root)){validNodes.push(nextNode);}else{shrinkSelection=true;}}if(shrinkSelection&&validNodes.length>0){// validNodes length check is a safeguard against an invalid selection; as getNodes()
1643
+ // will return an empty array in this case
1644
+ if(isBackward){var firstValidNode=validNodes[0];if($isElementNode(firstValidNode)){firstValidNode.selectStart();}else{firstValidNode.getParentOrThrow().selectStart();}}else{var lastValidNode=validNodes[validNodes.length-1];if($isElementNode(lastValidNode)){lastValidNode.selectEnd();}else{lastValidNode.getParentOrThrow().selectEnd();}}}// Because a range works on start and end, we might need to flip
1645
+ // the anchor and focus points to match what the DOM has, not what
1646
+ // the range has specifically.
1647
+ if(domSelection.anchorNode!==range.startContainer||domSelection.anchorOffset!==range.startOffset){$swapPoints(this);}}}if(granularity==='lineboundary'){$modifySelectionAroundDecoratorsAndBlocks(this,alter,isBackward,granularity,'decorators');}}/**
1648
+ * Helper for handling forward character and word deletion that prevents element nodes
1649
+ * like a table, columns layout being destroyed
1650
+ *
1651
+ * @param anchor the anchor
1652
+ * @param anchorNode the anchor node in the selection
1653
+ * @param isBackward whether or not selection is backwards
1654
+ */},{key:"forwardDeletion",value:function forwardDeletion(anchor,anchorNode,isBackward){if(!isBackward&&(// Delete forward handle case
1655
+ anchor.type==='element'&&$isElementNode(anchorNode)&&anchor.offset===anchorNode.getChildrenSize()||anchor.type==='text'&&anchor.offset===anchorNode.getTextContentSize())){var parent=anchorNode.getParent();var nextSibling=anchorNode.getNextSibling()||(parent===null?null:parent.getNextSibling());if($isElementNode(nextSibling)&&nextSibling.isShadowRoot()){return true;}}return false;}/**
1656
+ * Performs one logical character deletion operation on the EditorState based on the current Selection.
1657
+ * Handles different node types.
1658
+ *
1659
+ * @param isBackward whether or not the selection is backwards.
1660
+ */},{key:"deleteCharacter",value:function deleteCharacter(isBackward){var wasCollapsed=this.isCollapsed();if(this.isCollapsed()){var anchor=this.anchor;var anchorNode=anchor.getNode();if(this.forwardDeletion(anchor,anchorNode,isBackward)){return;}var direction=isBackward?'previous':'next';var initialCaret=$caretFromPoint(anchor,direction);var initialRange=$extendCaretToRange(initialCaret);if(initialRange.getTextSlices().every(function(slice){return slice===null||slice.distance===0;})){// There's no text in the direction of the deletion so we can explore our options
1661
+ var state={type:'initial'};var _iterator16=_createForOfIteratorHelper(initialRange.iterNodeCarets('shadowRoot')),_step16;try{for(_iterator16.s();!(_step16=_iterator16.n()).done;){var _caret=_step16.value;if($isChildCaret(_caret)){if(_caret.origin.isInline());else if(_caret.origin.isShadowRoot()){if(state.type==='merge-block'){break;}// Don't merge with a shadow root block
1662
+ if($isElementNode(initialRange.anchor.origin)&&initialRange.anchor.origin.isEmpty()){// delete an empty paragraph like the DecoratorNode case
1663
+ var normCaret=$normalizeCaret(_caret);$updateRangeSelectionFromCaretRange(this,$getCaretRange(normCaret,normCaret));initialRange.anchor.origin.remove();}return;}else if(state.type==='merge-next-block'||state.type==='merge-block'){// Keep descending ChildCaret to find which block to merge with
1664
+ state={block:state.block,caret:_caret,type:'merge-block'};}}else if(state.type==='merge-block'){break;}else if($isSiblingCaret(_caret)){if($isElementNode(_caret.origin)){if(!_caret.origin.isInline()){state={block:_caret.origin,type:'merge-next-block'};}else if(!_caret.origin.isParentOf(initialRange.anchor.origin)){break;}continue;}else if($isDecoratorNode(_caret.origin)){if(_caret.origin.isIsolated());else if(state.type==='merge-next-block'&&(_caret.origin.isKeyboardSelectable()||!_caret.origin.isInline())&&$isElementNode(initialRange.anchor.origin)&&initialRange.anchor.origin.isEmpty()){// If the anchor is an empty element that is adjacent to a
1665
+ // decorator then we remove the paragraph and select the
1666
+ // decorator
1667
+ initialRange.anchor.origin.remove();var nodeSelection=$createNodeSelection();nodeSelection.add(_caret.origin.getKey());$setSelection(nodeSelection);}else{// When the anchor is not an empty element then the
1668
+ // adjacent decorator is removed
1669
+ _caret.origin.remove();}// always stop when a decorator is encountered
1670
+ return;}break;}}}catch(err){_iterator16.e(err);}finally{_iterator16.f();}if(state.type==='merge-block'){var _state=state,caret=_state.caret,block=_state.block;$updateRangeSelectionFromCaretRange(this,$getCaretRange(!caret.origin.isEmpty()&&block.isEmpty()?$rewindSiblingCaret($getSiblingCaret(block,caret.direction)):initialRange.anchor,caret));return this.removeText();}}// Handle the deletion around decorators.
1671
+ var focus=this.focus;this.modify('extend',isBackward,'character');if(!this.isCollapsed()){var focusNode=focus.type==='text'?focus.getNode():null;anchorNode=anchor.type==='text'?anchor.getNode():null;if(focusNode!==null&&focusNode.isSegmented()){var offset=focus.offset;var textContentSize=focusNode.getTextContentSize();if(focusNode.is(anchorNode)||isBackward&&offset!==textContentSize||!isBackward&&offset!==0){$removeSegment(focusNode,isBackward,offset);return;}}else if(anchorNode!==null&&anchorNode.isSegmented()){var _offset=anchor.offset;var _textContentSize=anchorNode.getTextContentSize();if(anchorNode.is(focusNode)||isBackward&&_offset!==0||!isBackward&&_offset!==_textContentSize){$removeSegment(anchorNode,isBackward,_offset);return;}}$updateCaretSelectionForUnicodeCharacter(this,isBackward);}else if(isBackward&&anchor.offset===0){// Special handling around rich text nodes
1672
+ if($collapseAtStart(this,anchor.getNode())){return;}}}this.removeText();if(isBackward&&!wasCollapsed&&this.isCollapsed()&&this.anchor.type==='element'&&this.anchor.offset===0){var _anchorNode2=this.anchor.getNode();if(_anchorNode2.isEmpty()&&$isRootNode(_anchorNode2.getParent())&&_anchorNode2.getPreviousSibling()===null){$collapseAtStart(this,_anchorNode2);}}}/**
1673
+ * Performs one logical line deletion operation on the EditorState based on the current Selection.
1674
+ * Handles different node types.
1675
+ *
1676
+ * @param isBackward whether or not the selection is backwards.
1677
+ */},{key:"deleteLine",value:function deleteLine(isBackward){if(this.isCollapsed()){this.modify('extend',isBackward,'lineboundary');}if(this.isCollapsed()){// If the selection was already collapsed at the lineboundary,
1678
+ // use the deleteCharacter operation to handle all of the logic associated
1679
+ // with navigating through the parent element
1680
+ this.deleteCharacter(isBackward);}else{this.removeText();}}/**
1681
+ * Performs one logical word deletion operation on the EditorState based on the current Selection.
1682
+ * Handles different node types.
1683
+ *
1684
+ * @param isBackward whether or not the selection is backwards.
1685
+ */},{key:"deleteWord",value:function deleteWord(isBackward){if(this.isCollapsed()){var anchor=this.anchor;var anchorNode=anchor.getNode();if(this.forwardDeletion(anchor,anchorNode,isBackward)){return;}this.modify('extend',isBackward,'word');}this.removeText();}/**
1686
+ * Returns whether the Selection is "backwards", meaning the focus
1687
+ * logically precedes the anchor in the EditorState.
1688
+ * @returns true if the Selection is backwards, false otherwise.
1689
+ */},{key:"isBackward",value:function isBackward(){return this.focus.isBefore(this.anchor);}},{key:"getStartEndPoints",value:function getStartEndPoints(){return[this.anchor,this.focus];}}]);return RangeSelection;}();function $isNodeSelection(x){return x instanceof NodeSelection;}function getCharacterOffset(point){var offset=point.offset;if(point.type==='text'){return offset;}var parent=point.getNode();return offset===parent.getChildrenSize()?parent.getTextContent().length:0;}function $getCharacterOffsets(selection){var anchorAndFocus=selection.getStartEndPoints();if(anchorAndFocus===null){return[0,0];}var _anchorAndFocus=_slicedToArray(anchorAndFocus,2),anchor=_anchorAndFocus[0],focus=_anchorAndFocus[1];if(anchor.type==='element'&&focus.type==='element'&&anchor.key===focus.key&&anchor.offset===focus.offset){return[0,0];}return[getCharacterOffset(anchor),getCharacterOffset(focus)];}function $collapseAtStart(selection,startNode){for(var node=startNode;node;node=node.getParent()){if($isElementNode(node)){if(node.collapseAtStart(selection)){return true;}if($isRootOrShadowRoot(node)){break;}}if(node.getPreviousSibling()){break;}}return false;}function $swapPoints(selection){var focus=selection.focus;var anchor=selection.anchor;var anchorKey=anchor.key;var anchorOffset=anchor.offset;var anchorType=anchor.type;anchor.set(focus.key,focus.offset,focus.type,true);focus.set(anchorKey,anchorOffset,anchorType,true);}function moveNativeSelection(domSelection,alter,direction,granularity){// Selection.modify() method applies a change to the current selection or cursor position,
1690
+ // but is still non-standard in some browsers.
1691
+ domSelection.modify(alter,direction,granularity);}/**
1692
+ * Called by `RangeSelection.deleteCharacter` to determine if
1693
+ * `this.modify('extend', isBackward, 'character')` extended the selection
1694
+ * further than a user would expect for that operation.
1695
+ *
1696
+ * A short(?) JavaScript string vs. Unicode primer:
1697
+ *
1698
+ * Strings in JavaScript use an UTF-16 encoding, and the offsets into a
1699
+ * string are based on those UTF-16 *code units*. This is basically a
1700
+ * historical mistake (though logical at that time, decades ago), but
1701
+ * can never really be fixed for compatibility reasons.
1702
+ *
1703
+ * In Unicode, a *code point* is the combination of one or more *code units*.
1704
+ * and the range of a *code point* can fit into 21 bits.
1705
+ *
1706
+ * Every valid *code point* can be represented with one or two
1707
+ * *UTF-16 code units*. One unit is used when the code point is in the
1708
+ * Basic Multilingual Plane (BMP) and is `< 0xFFFF`. Anything outside
1709
+ * of that plane is encoded with a *surrogate pair* of *code units* and
1710
+ * `/[\uD800-\uDBFF][\uDC00-\uDFFF]/` is a regex that you could use to
1711
+ * find any valid *surrogate pair*. As far as Unicode is concerned, these
1712
+ * pairs represent a single *code point*, but in JavaScript, these pairs
1713
+ * have a length of 2 (`pair.charCodeAt(n)` is really returning a
1714
+ * UTF-16 *code unit*, not a unicode *code point*). It is possible to request
1715
+ * a *code point* with `pair.codePointAt(0)` and enumerate code points
1716
+ * in a string with `[...string]` but the offsets we work with, and
1717
+ * the string length, are based in *code units* so that functionality
1718
+ * is unfortunately not very useful here.
1719
+ *
1720
+ * This only gets us as far as *code points*. We now know that we must
1721
+ * consider that each *code point* can have a length of 1 or 2 in JavaScript
1722
+ * string distance. It gets even trickier because the visual representation
1723
+ * of a character is a *grapheme* (approximately what the user thinks of
1724
+ * as a character). A *grapheme* is one or more *code points*, and can
1725
+ * essentially be arbitrarily long, as there are many ways to combine
1726
+ * them.
1727
+ *
1728
+ * The `this.modify(…)` call has already extended our selection by one
1729
+ * *grapheme* in the direction we want to delete. Sounds great, it's done
1730
+ * a lot of awfully tricky work for us because this functionality has only
1731
+ * recently become available in JavaScript via `Intl.Segmenter`. The
1732
+ * problem is that in many cases the expected behavior of backspace or
1733
+ * delete is *not always to delete a whole grapheme*. In some languages
1734
+ * it's always expected that backspace ought to delete one code point, not the
1735
+ * whole grapheme. In other situations such as emoji that use variation
1736
+ * selectors you *do* want to delete the whole *grapheme*.
1737
+ *
1738
+ * In a few situations the behavior is even application dependent, such as
1739
+ * with latin languages where you have multiple ways to represent the same
1740
+ * character visually (e.g. a letter with an accent in one code point, or a
1741
+ * letter followed by a combining mark in a second code point); some apps will
1742
+ * delete the whole grapheme and others will delete only the combining mark,
1743
+ * probably based on whether they perform some sort of *normalization* on their
1744
+ * input to ensure that only one form is used when two sequences of code points
1745
+ * can represent the same visual character. Lexical currently chooses not
1746
+ * to perform any normalization so this type of combining marks will be
1747
+ * deleted as a *code point* without deleting the whole *grapheme*.
1748
+ *
1749
+ * See also:
1750
+ * https://www.unicode.org/versions/Unicode16.0.0/core-spec/chapter-2/#G25564
1751
+ * https://www.unicode.org/versions/Unicode16.0.0/core-spec/chapter-3/#G30602
1752
+ * https://www.unicode.org/versions/Unicode16.0.0/core-spec/chapter-3/#G49537
1753
+ * https://mathiasbynens.be/notes/javascript-unicode
1754
+ */function $updateCaretSelectionForUnicodeCharacter(selection,isBackward){var anchor=selection.anchor;var focus=selection.focus;var anchorNode=anchor.getNode();var focusNode=focus.getNode();if(anchorNode===focusNode&&anchor.type==='text'&&focus.type==='text'){// Handling of multibyte characters
1755
+ var anchorOffset=anchor.offset;var focusOffset=focus.offset;var isBefore=anchorOffset<focusOffset;var startOffset=isBefore?anchorOffset:focusOffset;var endOffset=isBefore?focusOffset:anchorOffset;var characterOffset=endOffset-1;if(startOffset!==characterOffset){var text=anchorNode.getTextContent().slice(startOffset,endOffset);if(shouldDeleteExactlyOneCodeUnit(text)){if(isBackward){focus.set(focus.key,characterOffset,focus.type);}else{anchor.set(anchor.key,characterOffset,anchor.type);}}}}}function shouldDeleteExactlyOneCodeUnit(text){{if(!(text.length>1)){formatDevErrorMessage("shouldDeleteExactlyOneCodeUnit: expecting to be called only with sequences of two or more code units");}}return!(doesContainSurrogatePair(text)||doesContainEmoji(text));}/**
1756
+ * Given the wall of text in $updateCaretSelectionForUnicodeCharacter, you'd
1757
+ * think that the solution might be complex, but the only currently known
1758
+ * cases given the above constraints where we want to delete a whole grapheme
1759
+ * are when emoji is involved. Since ES6 we can use unicode character classes
1760
+ * in regexp which makes this simple.
1761
+ *
1762
+ * It may make sense to add to this heuristic in the future if other
1763
+ * edge cases are discovered, which is why detailed notes remain.
1764
+ *
1765
+ * This is implemented with runtime feature detection and will always
1766
+ * return false on pre-2020 platforms that do not have unicode character
1767
+ * class support.
1768
+ */var doesContainEmoji=function(){try{var re=new RegExp('\\p{Emoji}','u');var test=re.test.bind(re);// Sanity check a few emoji to make sure the regexp was parsed
1769
+ // and works correctly. Any one of these should be sufficient,
1770
+ // but they're cheap and it only runs once.
1771
+ if(// Emoji in the BMP (heart) with variation selector
1772
+ test("\u2764\uFE0F")&&// Emoji in the BMP (#) with variation selector
1773
+ test("#\uFE0F\u20E3")&&// Emoji outside the BMP (thumbs up) that is encoded with a surrogate pair
1774
+ test("\uD83D\uDC4D")){return test;}}catch(_e){// SyntaxError
1775
+ }// fallback, surrogate pair already checked
1776
+ return function(){return false;};}();function $removeSegment(node,isBackward,offset){var textNode=node;var textContent=textNode.getTextContent();var split=textContent.split(/(?=\s)/g);var splitLength=split.length;var segmentOffset=0;var restoreOffset=0;for(var i=0;i<splitLength;i++){var text=split[i];var isLast=i===splitLength-1;restoreOffset=segmentOffset;segmentOffset+=text.length;if(isBackward&&segmentOffset===offset||segmentOffset>offset||isLast){split.splice(i,1);if(isLast){restoreOffset=undefined;}break;}}var nextTextContent=split.join('').trim();if(nextTextContent===''){textNode.remove();}else{textNode.setTextContent(nextTextContent);textNode.select(restoreOffset,restoreOffset);}}function shouldResolveAncestor(resolvedElement,resolvedOffset,lastPoint){var parent=resolvedElement.getParent();return lastPoint===null||parent===null||!parent.canBeEmpty()||parent!==lastPoint.getNode();}function $internalResolveSelectionPoint(dom,offset,lastPoint,editor){var resolvedOffset=offset;var resolvedNode;// If we have selection on an element, we will
1777
+ // need to figure out (using the offset) what text
1778
+ // node should be selected.
1779
+ if(isHTMLElement(dom)){// Resolve element to a ElementNode, or TextNode, or null
1780
+ var moveSelectionToEnd=false;// Given we're moving selection to another node, selection is
1781
+ // definitely dirty.
1782
+ // We use the anchor to find which child node to select
1783
+ var childNodes=dom.childNodes;var childNodesLength=childNodes.length;var blockCursorElement=editor._blockCursorElement;// If the anchor is the same as length, then this means we
1784
+ // need to select the very last text node.
1785
+ if(resolvedOffset===childNodesLength){moveSelectionToEnd=true;resolvedOffset=childNodesLength-1;}var childDOM=childNodes[resolvedOffset];var hasBlockCursor=false;if(childDOM===blockCursorElement){childDOM=childNodes[resolvedOffset+1];hasBlockCursor=true;}else if(blockCursorElement!==null){var blockCursorElementParent=blockCursorElement.parentNode;if(dom===blockCursorElementParent){var blockCursorOffset=Array.prototype.indexOf.call(blockCursorElementParent.children,blockCursorElement);if(offset>blockCursorOffset){resolvedOffset--;}}}resolvedNode=$getNodeFromDOM(childDOM);if($isTextNode(resolvedNode)){resolvedOffset=$getTextNodeOffset(resolvedNode,moveSelectionToEnd?'next':'previous');}else{var resolvedElement=$getNodeFromDOM(dom);// Ensure resolvedElement is actually a element.
1786
+ if(resolvedElement===null){return null;}if($isElementNode(resolvedElement)){var elementDOM=editor.getElementByKey(resolvedElement.getKey());if(!(elementDOM!==null)){formatDevErrorMessage("$internalResolveSelectionPoint: node in DOM but not keyToDOMMap");}var slot=resolvedElement.getDOMSlot(elementDOM);// This is just a typescript workaround, it is true but lost due to mutability
1787
+ var _slot$resolveChildInd=slot.resolveChildIndex(resolvedElement,elementDOM,dom,offset);var _slot$resolveChildInd2=_slicedToArray(_slot$resolveChildInd,2);resolvedElement=_slot$resolveChildInd2[0];resolvedOffset=_slot$resolveChildInd2[1];if(!$isElementNode(resolvedElement)){formatDevErrorMessage("$internalResolveSelectionPoint: resolvedElement is not an ElementNode");}if(moveSelectionToEnd&&resolvedOffset>=resolvedElement.getChildrenSize()){resolvedOffset=Math.max(0,resolvedElement.getChildrenSize()-1);}var child=resolvedElement.getChildAtIndex(resolvedOffset);if($isElementNode(child)&&shouldResolveAncestor(child,resolvedOffset,lastPoint)){var descendant=moveSelectionToEnd?child.getLastDescendant():child.getFirstDescendant();if(descendant===null){resolvedElement=child;}else{child=descendant;resolvedElement=$isElementNode(child)?child:child.getParentOrThrow();}resolvedOffset=0;}if($isTextNode(child)){resolvedNode=child;resolvedElement=null;resolvedOffset=$getTextNodeOffset(child,moveSelectionToEnd?'next':'previous');}else if(child!==resolvedElement&&moveSelectionToEnd&&!hasBlockCursor){if(!$isElementNode(resolvedElement)){formatDevErrorMessage("invariant");}resolvedOffset=Math.min(resolvedElement.getChildrenSize(),resolvedOffset+1);}}else{var index=resolvedElement.getIndexWithinParent();// When selecting decorators, there can be some selection issues when using resolvedOffset,
1788
+ // and instead we should be checking if we're using the offset
1789
+ if(offset===0&&$isDecoratorNode(resolvedElement)&&$getNodeFromDOM(dom)===resolvedElement){resolvedOffset=index;}else{resolvedOffset=index+1;}resolvedElement=resolvedElement.getParentOrThrow();}if($isElementNode(resolvedElement)){return $createPoint(resolvedElement.__key,resolvedOffset,'element');}}}else{// TextNode or null
1790
+ resolvedNode=$getNodeFromDOM(dom);}if(!$isTextNode(resolvedNode)){return null;}return $createPoint(resolvedNode.__key,$getTextNodeOffset(resolvedNode,resolvedOffset,'clamp'),'text');}function resolveSelectionPointOnBoundary(point,isBackward,isCollapsed){var offset=point.offset;var node=point.getNode();if(offset===0){var prevSibling=node.getPreviousSibling();var parent=node.getParent();if(!isBackward){if($isElementNode(prevSibling)&&!isCollapsed&&prevSibling.isInline()){point.set(prevSibling.__key,prevSibling.getChildrenSize(),'element');}else if($isTextNode(prevSibling)){point.set(prevSibling.__key,prevSibling.getTextContent().length,'text');}}else if((isCollapsed||!isBackward)&&prevSibling===null&&$isElementNode(parent)&&parent.isInline()){var parentSibling=parent.getPreviousSibling();if($isTextNode(parentSibling)){point.set(parentSibling.__key,parentSibling.getTextContent().length,'text');}}}else if(offset===node.getTextContent().length){var nextSibling=node.getNextSibling();var _parent=node.getParent();if(isBackward&&$isElementNode(nextSibling)&&nextSibling.isInline()){point.set(nextSibling.__key,0,'element');}else if((isCollapsed||isBackward)&&nextSibling===null&&$isElementNode(_parent)&&_parent.isInline()&&!_parent.canInsertTextAfter()){var _parentSibling=_parent.getNextSibling();if($isTextNode(_parentSibling)){point.set(_parentSibling.__key,0,'text');}}}}function $normalizeSelectionPointsForBoundaries(anchor,focus,lastSelection){if(anchor.type==='text'&&focus.type==='text'){var isBackward=anchor.isBefore(focus);var isCollapsed=anchor.is(focus);// Attempt to normalize the offset to the previous sibling if we're at the
1791
+ // start of a text node and the sibling is a text node or inline element.
1792
+ resolveSelectionPointOnBoundary(anchor,isBackward,isCollapsed);resolveSelectionPointOnBoundary(focus,!isBackward,isCollapsed);if(isCollapsed){focus.set(anchor.key,anchor.offset,anchor.type);}var editor=getActiveEditor();if(editor.isComposing()&&editor._compositionKey!==anchor.key&&$isRangeSelection(lastSelection)){var lastAnchor=lastSelection.anchor;var lastFocus=lastSelection.focus;anchor.set(lastAnchor.key,lastAnchor.offset,lastAnchor.type,true);focus.set(lastFocus.key,lastFocus.offset,lastFocus.type,true);}}}function $internalResolveSelectionPoints(anchorDOM,anchorOffset,focusDOM,focusOffset,editor,lastSelection){if(anchorDOM===null||focusDOM===null||!isSelectionWithinEditor(editor,anchorDOM,focusDOM)){return null;}var resolvedAnchorPoint=$internalResolveSelectionPoint(anchorDOM,anchorOffset,$isRangeSelection(lastSelection)?lastSelection.anchor:null,editor);if(resolvedAnchorPoint===null){return null;}var resolvedFocusPoint=$internalResolveSelectionPoint(focusDOM,focusOffset,$isRangeSelection(lastSelection)?lastSelection.focus:null,editor);if(resolvedFocusPoint===null){return null;}{$validatePoint('anchor',resolvedAnchorPoint);$validatePoint('focus',resolvedFocusPoint);}if(resolvedAnchorPoint.type==='element'&&resolvedFocusPoint.type==='element'){var anchorNode=$getNodeFromDOM(anchorDOM);var focusNode=$getNodeFromDOM(focusDOM);// Ensure if we're selecting the content of a decorator that we
1793
+ // return null for this point, as it's not in the controlled scope
1794
+ // of Lexical.
1795
+ if($isDecoratorNode(anchorNode)&&$isDecoratorNode(focusNode)){return null;}}// Handle normalization of selection when it is at the boundaries.
1796
+ $normalizeSelectionPointsForBoundaries(resolvedAnchorPoint,resolvedFocusPoint,lastSelection);return[resolvedAnchorPoint,resolvedFocusPoint];}function $isBlockElementNode(node){return $isElementNode(node)&&!node.isInline();}// This is used to make a selection when the existing
1797
+ // selection is null, i.e. forcing selection on the editor
1798
+ // when it current exists outside the editor.
1799
+ function $internalMakeRangeSelection(anchorKey,anchorOffset,focusKey,focusOffset,anchorType,focusType){var editorState=getActiveEditorState();var selection=new RangeSelection($createPoint(anchorKey,anchorOffset,anchorType),$createPoint(focusKey,focusOffset,focusType),0,'');selection.dirty=true;editorState._selection=selection;return selection;}function $createRangeSelection(){var anchor=$createPoint('root',0,'element');var focus=$createPoint('root',0,'element');return new RangeSelection(anchor,focus,0,'');}function $createNodeSelection(){return new NodeSelection(new Set());}function $internalCreateSelection(editor,event){var currentEditorState=editor.getEditorState();var lastSelection=currentEditorState._selection;var domSelection=getDOMSelection(getWindow(editor));if($isRangeSelection(lastSelection)||lastSelection==null){return $internalCreateRangeSelection(lastSelection,domSelection,editor,event);}return lastSelection.clone();}function $createRangeSelectionFromDom(domSelection,editor){return $internalCreateRangeSelection(null,domSelection,editor,null);}function $internalCreateRangeSelection(lastSelection,domSelection,editor,event){var windowObj=editor._window;if(windowObj===null){return null;}// When we create a selection, we try to use the previous
1800
+ // selection where possible, unless an actual user selection
1801
+ // change has occurred. When we do need to create a new selection
1802
+ // we validate we can have text nodes for both anchor and focus
1803
+ // nodes. If that holds true, we then return that selection
1804
+ // as a mutable object that we use for the editor state for this
1805
+ // update cycle. If a selection gets changed, and requires a
1806
+ // update to native DOM selection, it gets marked as "dirty".
1807
+ // If the selection changes, but matches with the existing
1808
+ // DOM selection, then we only need to sync it. Otherwise,
1809
+ // we generally bail out of doing an update to selection during
1810
+ // reconciliation unless there are dirty nodes that need
1811
+ // reconciling.
1812
+ var windowEvent=event||windowObj.event;var eventType=windowEvent?windowEvent.type:undefined;var isSelectionChange=eventType==='selectionchange';var useDOMSelection=!getIsProcessingMutations()&&(isSelectionChange||eventType==='beforeinput'||eventType==='compositionstart'||eventType==='compositionend'||eventType==='click'&&windowEvent&&windowEvent.detail===3||eventType==='drop'||eventType===undefined);var anchorDOM,focusDOM,anchorOffset,focusOffset;if(!$isRangeSelection(lastSelection)||useDOMSelection){if(domSelection===null){return null;}anchorDOM=domSelection.anchorNode;focusDOM=domSelection.focusNode;anchorOffset=domSelection.anchorOffset;focusOffset=domSelection.focusOffset;if((isSelectionChange||eventType===undefined)&&$isRangeSelection(lastSelection)&&!isSelectionWithinEditor(editor,anchorDOM,focusDOM)){return lastSelection.clone();}}else{return lastSelection.clone();}// Let's resolve the text nodes from the offsets and DOM nodes we have from
1813
+ // native selection.
1814
+ var resolvedSelectionPoints=$internalResolveSelectionPoints(anchorDOM,anchorOffset,focusDOM,focusOffset,editor,lastSelection);if(resolvedSelectionPoints===null){return null;}var _resolvedSelectionPoi2=_slicedToArray(resolvedSelectionPoints,2),resolvedAnchorPoint=_resolvedSelectionPoi2[0],resolvedFocusPoint=_resolvedSelectionPoi2[1];return new RangeSelection(resolvedAnchorPoint,resolvedFocusPoint,!$isRangeSelection(lastSelection)?0:lastSelection.format,!$isRangeSelection(lastSelection)?'':lastSelection.style);}function $validatePoint(name,point){var node=$getNodeByKey(point.key);if(!(node!==undefined)){formatDevErrorMessage("$validatePoint: ".concat(name," key ").concat(point.key," not found in current editorState"));}if(point.type==='text'){if(!$isTextNode(node)){formatDevErrorMessage("$validatePoint: ".concat(name," key ").concat(point.key," is not a TextNode"));}var size=node.getTextContentSize();if(!(point.offset<=size)){formatDevErrorMessage("$validatePoint: ".concat(name," point.offset > node.getTextContentSize() (").concat(String(point.offset)," > ").concat(String(size),")"));}}else{if(!$isElementNode(node)){formatDevErrorMessage("$validatePoint: ".concat(name," key ").concat(point.key," is not an ElementNode"));}var _size=node.getChildrenSize();if(!(point.offset<=_size)){formatDevErrorMessage("$validatePoint: ".concat(name," point.offset > node.getChildrenSize() (").concat(String(point.offset)," > ").concat(String(_size),")"));}}}function $getSelection(){var editorState=getActiveEditorState();return editorState._selection;}function $getPreviousSelection(){var editor=getActiveEditor();return editor._editorState._selection;}function $updateElementSelectionOnCreateDeleteNode(selection,parentNode,nodeOffset){var times=arguments.length>3&&arguments[3]!==undefined?arguments[3]:1;var anchor=selection.anchor;var focus=selection.focus;var anchorNode=anchor.getNode();var focusNode=focus.getNode();if(!parentNode.is(anchorNode)&&!parentNode.is(focusNode)){return;}var parentKey=parentNode.__key;// Single node. We shift selection but never redimension it
1815
+ if(selection.isCollapsed()){var selectionOffset=anchor.offset;if(nodeOffset<=selectionOffset&&times>0||nodeOffset<selectionOffset&&times<0){var newSelectionOffset=Math.max(0,selectionOffset+times);anchor.set(parentKey,newSelectionOffset,'element');focus.set(parentKey,newSelectionOffset,'element');// The new selection might point to text nodes, try to resolve them
1816
+ $updateSelectionResolveTextNodes(selection);}}else{// Multiple nodes selected. We shift or redimension selection
1817
+ var isBackward=selection.isBackward();var firstPoint=isBackward?focus:anchor;var firstPointNode=firstPoint.getNode();var lastPoint=isBackward?anchor:focus;var lastPointNode=lastPoint.getNode();if(parentNode.is(firstPointNode)){var firstPointOffset=firstPoint.offset;if(nodeOffset<=firstPointOffset&&times>0||nodeOffset<firstPointOffset&&times<0){firstPoint.set(parentKey,Math.max(0,firstPointOffset+times),'element');}}if(parentNode.is(lastPointNode)){var lastPointOffset=lastPoint.offset;if(nodeOffset<=lastPointOffset&&times>0||nodeOffset<lastPointOffset&&times<0){lastPoint.set(parentKey,Math.max(0,lastPointOffset+times),'element');}}}// The new selection might point to text nodes, try to resolve them
1818
+ $updateSelectionResolveTextNodes(selection);}function $updateSelectionResolveTextNodes(selection){var anchor=selection.anchor;var anchorOffset=anchor.offset;var focus=selection.focus;var focusOffset=focus.offset;var anchorNode=anchor.getNode();var focusNode=focus.getNode();if(selection.isCollapsed()){if(!$isElementNode(anchorNode)){return;}var childSize=anchorNode.getChildrenSize();var anchorOffsetAtEnd=anchorOffset>=childSize;var child=anchorOffsetAtEnd?anchorNode.getChildAtIndex(childSize-1):anchorNode.getChildAtIndex(anchorOffset);if($isTextNode(child)){var newOffset=0;if(anchorOffsetAtEnd){newOffset=child.getTextContentSize();}anchor.set(child.__key,newOffset,'text');focus.set(child.__key,newOffset,'text');}return;}if($isElementNode(anchorNode)){var _childSize=anchorNode.getChildrenSize();var _anchorOffsetAtEnd=anchorOffset>=_childSize;var _child=_anchorOffsetAtEnd?anchorNode.getChildAtIndex(_childSize-1):anchorNode.getChildAtIndex(anchorOffset);if($isTextNode(_child)){var _newOffset=0;if(_anchorOffsetAtEnd){_newOffset=_child.getTextContentSize();}anchor.set(_child.__key,_newOffset,'text');}}if($isElementNode(focusNode)){var _childSize2=focusNode.getChildrenSize();var focusOffsetAtEnd=focusOffset>=_childSize2;var _child2=focusOffsetAtEnd?focusNode.getChildAtIndex(_childSize2-1):focusNode.getChildAtIndex(focusOffset);if($isTextNode(_child2)){var _newOffset2=0;if(focusOffsetAtEnd){_newOffset2=_child2.getTextContentSize();}focus.set(_child2.__key,_newOffset2,'text');}}}function applySelectionTransforms(nextEditorState,editor){var prevEditorState=editor.getEditorState();var prevSelection=prevEditorState._selection;var nextSelection=nextEditorState._selection;if($isRangeSelection(nextSelection)){var anchor=nextSelection.anchor;var focus=nextSelection.focus;var anchorNode;if(anchor.type==='text'){anchorNode=anchor.getNode();anchorNode.selectionTransform(prevSelection,nextSelection);}if(focus.type==='text'){var focusNode=focus.getNode();if(anchorNode!==focusNode){focusNode.selectionTransform(prevSelection,nextSelection);}}}}function moveSelectionPointToSibling(point,node,parent,prevSibling,nextSibling){var siblingKey=null;var offset=0;var type=null;if(prevSibling!==null){siblingKey=prevSibling.__key;if($isTextNode(prevSibling)){offset=prevSibling.getTextContentSize();type='text';}else if($isElementNode(prevSibling)){offset=prevSibling.getChildrenSize();type='element';}}else{if(nextSibling!==null){siblingKey=nextSibling.__key;if($isTextNode(nextSibling)){type='text';}else if($isElementNode(nextSibling)){type='element';}}}if(siblingKey!==null&&type!==null){point.set(siblingKey,offset,type);}else{offset=node.getIndexWithinParent();if(offset===-1){// Move selection to end of parent
1819
+ offset=parent.getChildrenSize();}point.set(parent.__key,offset,'element');}}function adjustPointOffsetForMergedSibling(point,isBefore,key,target,textLength){if(point.type==='text'){point.set(key,point.offset+(isBefore?0:textLength),'text');}else if(point.offset>target.getIndexWithinParent()){point.set(point.key,point.offset-1,'element');}}function setDOMSelectionBaseAndExtent(domSelection,nextAnchorDOM,nextAnchorOffset,nextFocusDOM,nextFocusOffset){// Apply the updated selection to the DOM. Note: this will trigger
1820
+ // a "selectionchange" event, although it will be asynchronous.
1821
+ try{domSelection.setBaseAndExtent(nextAnchorDOM,nextAnchorOffset,nextFocusDOM,nextFocusOffset);}catch(error){// If we encounter an error, continue. This can sometimes
1822
+ // occur with FF and there's no good reason as to why it
1823
+ // should happen.
1824
+ {console.warn(error);}}}function updateDOMSelection(prevSelection,nextSelection,editor,domSelection,tags,rootElement,nodeCount){var anchorDOMNode=domSelection.anchorNode;var focusDOMNode=domSelection.focusNode;var anchorOffset=domSelection.anchorOffset;var focusOffset=domSelection.focusOffset;var activeElement=document.activeElement;// TODO: make this not hard-coded, and add another config option
1825
+ // that makes this configurable.
1826
+ if(tags.has(COLLABORATION_TAG)&&activeElement!==rootElement||activeElement!==null&&isSelectionCapturedInDecoratorInput(activeElement)){return;}if(!$isRangeSelection(nextSelection)){// We don't remove selection if the prevSelection is null because
1827
+ // of editor.setRootElement(). If this occurs on init when the
1828
+ // editor is already focused, then this can cause the editor to
1829
+ // lose focus.
1830
+ if(prevSelection!==null&&isSelectionWithinEditor(editor,anchorDOMNode,focusDOMNode)){domSelection.removeAllRanges();}return;}var anchor=nextSelection.anchor;var focus=nextSelection.focus;var anchorKey=anchor.key;var focusKey=focus.key;var anchorDOM=getElementByKeyOrThrow(editor,anchorKey);var focusDOM=getElementByKeyOrThrow(editor,focusKey);var nextAnchorOffset=anchor.offset;var nextFocusOffset=focus.offset;var nextFormat=nextSelection.format;var nextStyle=nextSelection.style;var isCollapsed=nextSelection.isCollapsed();var nextAnchorNode=anchorDOM;var nextFocusNode=focusDOM;var anchorFormatOrStyleChanged=false;if(anchor.type==='text'){nextAnchorNode=getDOMTextNode(anchorDOM);var anchorNode=anchor.getNode();anchorFormatOrStyleChanged=anchorNode.getFormat()!==nextFormat||anchorNode.getStyle()!==nextStyle;}else if($isRangeSelection(prevSelection)&&prevSelection.anchor.type==='text'){anchorFormatOrStyleChanged=true;}if(focus.type==='text'){nextFocusNode=getDOMTextNode(focusDOM);}// If we can't get an underlying text node for selection, then
1831
+ // we should avoid setting selection to something incorrect.
1832
+ if(nextAnchorNode===null||nextFocusNode===null){return;}if(isCollapsed&&(prevSelection===null||anchorFormatOrStyleChanged||$isRangeSelection(prevSelection)&&(prevSelection.format!==nextFormat||prevSelection.style!==nextStyle))){markCollapsedSelectionFormat(nextFormat,nextStyle,nextAnchorOffset,anchorKey,performance.now());}// Diff against the native DOM selection to ensure we don't do
1833
+ // an unnecessary selection update. We also skip this check if
1834
+ // we're moving selection to within an element, as this can
1835
+ // sometimes be problematic around scrolling.
1836
+ if(anchorOffset===nextAnchorOffset&&focusOffset===nextFocusOffset&&anchorDOMNode===nextAnchorNode&&focusDOMNode===nextFocusNode&&// Badly interpreted range selection when collapsed - #1482
1837
+ !(domSelection.type==='Range'&&isCollapsed)){// If the root element does not have focus, ensure it has focus
1838
+ if(activeElement===null||!rootElement.contains(activeElement)){if(!tags.has(SKIP_SELECTION_FOCUS_TAG)){rootElement.focus({preventScroll:true});}}if(anchor.type!=='element'){return;}}// Apply the updated selection to the DOM. Note: this will trigger
1839
+ // a "selectionchange" event, although it will be asynchronous.
1840
+ setDOMSelectionBaseAndExtent(domSelection,nextAnchorNode,nextAnchorOffset,nextFocusNode,nextFocusOffset);if(!tags.has(SKIP_SCROLL_INTO_VIEW_TAG)&&nextSelection.isCollapsed()&&rootElement!==null&&rootElement===document.activeElement){var selectionTarget=$isRangeSelection(nextSelection)&&nextSelection.anchor.type==='element'?nextAnchorNode.childNodes[nextAnchorOffset]||null:domSelection.rangeCount>0?domSelection.getRangeAt(0):null;if(selectionTarget!==null){var selectionRect;if(selectionTarget instanceof Text){var range=document.createRange();range.selectNode(selectionTarget);selectionRect=range.getBoundingClientRect();}else{selectionRect=selectionTarget.getBoundingClientRect();}scrollIntoViewIfNeeded(editor,selectionRect,rootElement);}}markSelectionChangeFromDOMUpdate();}function $insertNodes(nodes){var selection=$getSelection()||$getPreviousSelection();if(selection===null){selection=$getRoot().selectEnd();}selection.insertNodes(nodes);}function $getTextContent(){var selection=$getSelection();if(selection===null){return'';}return selection.getTextContent();}function $removeTextAndSplitBlock(selection){var selection_=selection;if(!selection.isCollapsed()){selection_.removeText();}// A new selection can originate as a result of node replacement, in which case is registered via
1841
+ // $setSelection
1842
+ var newSelection=$getSelection();if($isRangeSelection(newSelection)){selection_=newSelection;}if(!$isRangeSelection(selection_)){formatDevErrorMessage("Unexpected dirty selection to be null");}var anchor=selection_.anchor;var node=anchor.getNode();var offset=anchor.offset;while(!INTERNAL_$isBlock(node)){var prevNode=node;var _$splitNodeAtPoint=$splitNodeAtPoint(node,offset);var _$splitNodeAtPoint2=_slicedToArray(_$splitNodeAtPoint,2);node=_$splitNodeAtPoint2[0];offset=_$splitNodeAtPoint2[1];if(prevNode.is(node)){break;}}return offset;}function $splitNodeAtPoint(node,offset){var parent=node.getParent();if(!parent){var paragraph=$createParagraphNode();$getRoot().append(paragraph);paragraph.select();return[$getRoot(),0];}if($isTextNode(node)){var split=node.splitText(offset);if(split.length===0){return[parent,node.getIndexWithinParent()];}var x=offset===0?0:1;var index=split[0].getIndexWithinParent()+x;return[parent,index];}if(!$isElementNode(node)||offset===0){return[parent,node.getIndexWithinParent()];}var firstToAppend=node.getChildAtIndex(offset);if(firstToAppend){var insertPoint=new RangeSelection($createPoint(node.__key,offset,'element'),$createPoint(node.__key,offset,'element'),0,'');var newElement=node.insertNewAfter(insertPoint);if(newElement){newElement.append.apply(newElement,[firstToAppend].concat(_toConsumableArray(firstToAppend.getNextSiblings())));}}return[parent,node.getIndexWithinParent()+1];}function $wrapInlineNodes(nodes){// We temporarily insert the topLevelNodes into an arbitrary ElementNode,
1843
+ // since insertAfter does not work on nodes that have no parent (TO-DO: fix that).
1844
+ var virtualRoot=$createParagraphNode();var currentBlock=null;for(var i=0;i<nodes.length;i++){var node=nodes[i];var isLineBreakNode=$isLineBreakNode(node);if(isLineBreakNode||$isDecoratorNode(node)&&node.isInline()||$isElementNode(node)&&node.isInline()||$isTextNode(node)||node.isParentRequired()){if(currentBlock===null){currentBlock=node.createParentElementNode();virtualRoot.append(currentBlock);// In the case of LineBreakNode, we just need to
1845
+ // add an empty ParagraphNode to the topLevelBlocks.
1846
+ if(isLineBreakNode){continue;}}if(currentBlock!==null){currentBlock.append(node);}}else{virtualRoot.append(node);currentBlock=null;}}return virtualRoot;}/**
1847
+ * Get all nodes in a CaretRange in a way that complies with all of the
1848
+ * quirks of the original RangeSelection.getNodes().
1849
+ *
1850
+ * @param range The CaretRange
1851
+ */function $getNodesFromCaretRangeCompat(// getNodes returned nodes in document order
1852
+ range){var nodes=[];var _range$getTextSlices=range.getTextSlices(),_range$getTextSlices2=_slicedToArray(_range$getTextSlices,2),beforeSlice=_range$getTextSlices2[0],afterSlice=_range$getTextSlices2[1];if(beforeSlice){nodes.push(beforeSlice.caret.origin);}var seenAncestors=new Set();var seenElements=new Set();var _iterator17=_createForOfIteratorHelper(range),_step17;try{for(_iterator17.s();!(_step17=_iterator17.n()).done;){var caret=_step17.value;if($isChildCaret(caret)){// Emulate the leading under-selection behavior of getNodes by
1853
+ // ignoring the 'enter' of any ElementNode until we've seen a
1854
+ // SiblingCaret
1855
+ var origin=caret.origin;if(nodes.length===0){seenAncestors.add(origin);}else{seenElements.add(origin);nodes.push(origin);}}else{var _origin=caret.origin;if(!$isElementNode(_origin)||!seenElements.has(_origin)){nodes.push(_origin);}}}}catch(err){_iterator17.e(err);}finally{_iterator17.f();}if(afterSlice){nodes.push(afterSlice.caret.origin);}// Emulate the trailing underselection behavior when the last offset of
1856
+ // an element is selected
1857
+ if($isSiblingCaret(range.focus)&&$isElementNode(range.focus.origin)&&range.focus.getNodeAtCaret()===null){for(var reverseCaret=$getChildCaret(range.focus.origin,'previous');$isChildCaret(reverseCaret)&&seenAncestors.has(reverseCaret.origin)&&!reverseCaret.origin.isEmpty()&&reverseCaret.origin.is(nodes[nodes.length-1]);reverseCaret=$getAdjacentChildCaret(reverseCaret)){seenAncestors.delete(reverseCaret.origin);nodes.pop();}}while(nodes.length>1){var lastIncludedNode=nodes[nodes.length-1];if($isElementNode(lastIncludedNode)){if(seenElements.has(lastIncludedNode)||lastIncludedNode.isEmpty()||seenAncestors.has(lastIncludedNode));else{nodes.pop();continue;}}break;}if(nodes.length===0&&range.isCollapsed()){// Emulate the collapsed behavior of getNodes by returning the descendant
1858
+ var normCaret=$normalizeCaret(range.anchor);var flippedNormCaret=$normalizeCaret(range.anchor.getFlipped());var $getCandidate=function $getCandidate(caret){return $isTextPointCaret(caret)?caret.origin:caret.getNodeAtCaret();};var node=$getCandidate(normCaret)||$getCandidate(flippedNormCaret)||(range.anchor.getNodeAtCaret()?normCaret.origin:flippedNormCaret.origin);nodes.push(node);}return nodes;}/**
1859
+ * @internal
1860
+ *
1861
+ * Modify the focus of the focus around possible decorators and blocks and return true
1862
+ * if the movement is done.
1863
+ */function $modifySelectionAroundDecoratorsAndBlocks(selection,alter,isBackward,granularity){var mode=arguments.length>4&&arguments[4]!==undefined?arguments[4]:'decorators-and-blocks';if(alter==='move'&&granularity==='character'&&!selection.isCollapsed()){// moving left or right when the selection isn't collapsed will
1864
+ // just set the anchor to the focus or vice versa depending on
1865
+ // direction
1866
+ var _ref8=isBackward===selection.isBackward()?[selection.focus,selection.anchor]:[selection.anchor,selection.focus],_ref9=_slicedToArray(_ref8,2),src=_ref9[0],dst=_ref9[1];dst.set(src.key,src.offset,src.type);return true;}var initialFocus=$caretFromPoint(selection.focus,isBackward?'previous':'next');var isLineBoundary=granularity==='lineboundary';var collapse=alter==='move';var focus=initialFocus;var checkForBlock=mode==='decorators-and-blocks';if(!$isExtendableTextPointCaret(focus)){var _iterator18=_createForOfIteratorHelper(focus),_step18;try{for(_iterator18.s();!(_step18=_iterator18.n()).done;){var siblingCaret=_step18.value;checkForBlock=false;var origin=siblingCaret.origin;if($isDecoratorNode(origin)&&!origin.isIsolated()){focus=siblingCaret;if(isLineBoundary&&origin.isInline()){continue;}}break;}}catch(err){_iterator18.e(err);}finally{_iterator18.f();}if(checkForBlock){var _iterator19=_createForOfIteratorHelper($extendCaretToRange(initialFocus).iterNodeCarets(alter==='extend'?'shadowRoot':'root')),_step19;try{for(_iterator19.s();!(_step19=_iterator19.n()).done;){var nextCaret=_step19.value;if($isChildCaret(nextCaret)){if(!nextCaret.origin.isInline()){focus=nextCaret;}}else if($isElementNode(nextCaret.origin)){continue;}else if($isDecoratorNode(nextCaret.origin)&&!nextCaret.origin.isInline()){focus=nextCaret;}break;}}catch(err){_iterator19.e(err);}finally{_iterator19.f();}}}if(focus===initialFocus){return false;}// After this point checkForBlock is true if and only if we moved to a
1867
+ // different block, so we should stop regardless of the granularity
1868
+ if(collapse&&!isLineBoundary&&$isDecoratorNode(focus.origin)&&focus.origin.isKeyboardSelectable()){// Make it possible to move selection from range selection to
1869
+ // node selection on the node.
1870
+ var nodeSelection=$createNodeSelection();nodeSelection.add(focus.origin.getKey());$setSelection(nodeSelection);return true;}focus=$normalizeCaret(focus);if(collapse){$setPointFromCaret(selection.anchor,focus);}$setPointFromCaret(selection.focus,focus);return checkForBlock||!isLineBoundary;}var activeEditorState=null;var activeEditor=null;var isReadOnlyMode=false;var isAttemptingToRecoverFromReconcilerError=false;var infiniteTransformCount=0;var observerOptions={characterData:true,childList:true,subtree:true};function isCurrentlyReadOnlyMode(){return isReadOnlyMode||activeEditorState!==null&&activeEditorState._readOnly;}function errorOnReadOnly(){if(isReadOnlyMode){{formatDevErrorMessage("Cannot use method in read-only mode.");}}}function errorOnInfiniteTransforms(){if(infiniteTransformCount>99){{formatDevErrorMessage("One or more transforms are endlessly triggering additional transforms. May have encountered infinite recursion caused by transforms that have their preconditions too lose and/or conflict with each other.");}}}function getActiveEditorState(){if(activeEditorState===null){{formatDevErrorMessage("Unable to find an active editor state. State helpers or node methods can only be used synchronously during the callback of editor.update(), editor.read(), or editorState.read().".concat(collectBuildInformation()));}}return activeEditorState;}function getActiveEditor(){if(activeEditor===null){{formatDevErrorMessage("Unable to find an active editor. This method can only be used synchronously during the callback of editor.update() or editor.read().".concat(collectBuildInformation()));}}return activeEditor;}function collectBuildInformation(){var compatibleEditors=0;var incompatibleEditors=new Set();var thisVersion=LexicalEditor.version;if(typeof window!=='undefined'){var _iterator20=_createForOfIteratorHelper(document.querySelectorAll('[contenteditable]')),_step20;try{for(_iterator20.s();!(_step20=_iterator20.n()).done;){var node=_step20.value;var editor=getEditorPropertyFromDOMNode(node);if(isLexicalEditor(editor)){compatibleEditors++;}else if(editor){var version=String(editor.constructor.version||'<0.17.1');if(version===thisVersion){version+=' (separately built, likely a bundler configuration issue)';}incompatibleEditors.add(version);}}}catch(err){_iterator20.e(err);}finally{_iterator20.f();}}var output=" Detected on the page: ".concat(compatibleEditors," compatible editor(s) with version ").concat(thisVersion);if(incompatibleEditors.size){output+=" and incompatible editors with versions ".concat(Array.from(incompatibleEditors).join(', '));}return output;}function internalGetActiveEditor(){return activeEditor;}function internalGetActiveEditorState(){return activeEditorState;}function $applyTransforms(editor,node,transformsCache){var type=node.__type;var registeredNode=getRegisteredNodeOrThrow(editor,type);var transformsArr=transformsCache.get(type);if(transformsArr===undefined){transformsArr=Array.from(registeredNode.transforms);transformsCache.set(type,transformsArr);}var transformsArrLength=transformsArr.length;for(var i=0;i<transformsArrLength;i++){transformsArr[i](node);if(!node.isAttached()){break;}}}function $isNodeValidForTransform(node,compositionKey){return node!==undefined&&// We don't want to transform nodes being composed
1871
+ node.__key!==compositionKey&&node.isAttached();}function $normalizeAllDirtyTextNodes(editorState,editor){var dirtyLeaves=editor._dirtyLeaves;var nodeMap=editorState._nodeMap;var _iterator21=_createForOfIteratorHelper(dirtyLeaves),_step21;try{for(_iterator21.s();!(_step21=_iterator21.n()).done;){var nodeKey=_step21.value;var node=nodeMap.get(nodeKey);if($isTextNode(node)&&node.isAttached()&&node.isSimpleText()&&!node.isUnmergeable()){$normalizeTextNode(node);}}}catch(err){_iterator21.e(err);}finally{_iterator21.f();}}function addTags(editor,tags){if(!tags){return;}var updateTags=editor._updateTags;var tags_=tags;if(!Array.isArray(tags)){tags_=[tags];}var _iterator22=_createForOfIteratorHelper(tags_),_step22;try{for(_iterator22.s();!(_step22=_iterator22.n()).done;){var tag=_step22.value;updateTags.add(tag);}}catch(err){_iterator22.e(err);}finally{_iterator22.f();}}/**
1872
+ * Transform heuristic:
1873
+ * 1. We transform leaves first. If transforms generate additional dirty nodes we repeat step 1.
1874
+ * The reasoning behind this is that marking a leaf as dirty marks all its parent elements as dirty too.
1875
+ * 2. We transform elements. If element transforms generate additional dirty nodes we repeat step 1.
1876
+ * If element transforms only generate additional dirty elements we only repeat step 2.
1877
+ *
1878
+ * Note that to keep track of newly dirty nodes and subtrees we leverage the editor._dirtyNodes and
1879
+ * editor._subtrees which we reset in every loop.
1880
+ */function $applyAllTransforms(editorState,editor){var dirtyLeaves=editor._dirtyLeaves;var dirtyElements=editor._dirtyElements;var nodeMap=editorState._nodeMap;var compositionKey=$getCompositionKey();var transformsCache=new Map();var untransformedDirtyLeaves=dirtyLeaves;var untransformedDirtyLeavesLength=untransformedDirtyLeaves.size;var untransformedDirtyElements=dirtyElements;var untransformedDirtyElementsLength=untransformedDirtyElements.size;while(untransformedDirtyLeavesLength>0||untransformedDirtyElementsLength>0){if(untransformedDirtyLeavesLength>0){// We leverage editor._dirtyLeaves to track the new dirty leaves after the transforms
1881
+ editor._dirtyLeaves=new Set();var _iterator23=_createForOfIteratorHelper(untransformedDirtyLeaves),_step23;try{for(_iterator23.s();!(_step23=_iterator23.n()).done;){var nodeKey=_step23.value;var node=nodeMap.get(nodeKey);if($isTextNode(node)&&node.isAttached()&&node.isSimpleText()&&!node.isUnmergeable()){$normalizeTextNode(node);}if(node!==undefined&&$isNodeValidForTransform(node,compositionKey)){$applyTransforms(editor,node,transformsCache);}dirtyLeaves.add(nodeKey);}}catch(err){_iterator23.e(err);}finally{_iterator23.f();}untransformedDirtyLeaves=editor._dirtyLeaves;untransformedDirtyLeavesLength=untransformedDirtyLeaves.size;// We want to prioritize node transforms over element transforms
1882
+ if(untransformedDirtyLeavesLength>0){infiniteTransformCount++;continue;}}// All dirty leaves have been processed. Let's do elements!
1883
+ // We have previously processed dirty leaves, so let's restart the editor leaves Set to track
1884
+ // new ones caused by element transforms
1885
+ editor._dirtyLeaves=new Set();editor._dirtyElements=new Map();// The root is always considered intentionally dirty if any attached node
1886
+ // is dirty and by deleting and re-inserting we will apply its transforms
1887
+ // last (e.g. its transform can be used as a sort of "update finalizer")
1888
+ var rootDirty=untransformedDirtyElements.delete('root');if(rootDirty){untransformedDirtyElements.set('root',true);}var _iterator24=_createForOfIteratorHelper(untransformedDirtyElements),_step24;try{for(_iterator24.s();!(_step24=_iterator24.n()).done;){var currentUntransformedDirtyElement=_step24.value;var _nodeKey3=currentUntransformedDirtyElement[0];var intentionallyMarkedAsDirty=currentUntransformedDirtyElement[1];dirtyElements.set(_nodeKey3,intentionallyMarkedAsDirty);if(!intentionallyMarkedAsDirty){continue;}var _node3=nodeMap.get(_nodeKey3);if(_node3!==undefined&&$isNodeValidForTransform(_node3,compositionKey)){$applyTransforms(editor,_node3,transformsCache);}}}catch(err){_iterator24.e(err);}finally{_iterator24.f();}untransformedDirtyLeaves=editor._dirtyLeaves;untransformedDirtyLeavesLength=untransformedDirtyLeaves.size;untransformedDirtyElements=editor._dirtyElements;untransformedDirtyElementsLength=untransformedDirtyElements.size;infiniteTransformCount++;}editor._dirtyLeaves=dirtyLeaves;editor._dirtyElements=dirtyElements;}function $parseSerializedNode(serializedNode){var internalSerializedNode=serializedNode;return $parseSerializedNodeImpl(internalSerializedNode,getActiveEditor()._nodes);}function $parseSerializedNodeImpl(serializedNode,registeredNodes){var type=serializedNode.type;var registeredNode=registeredNodes.get(type);if(registeredNode===undefined){{formatDevErrorMessage("parseEditorState: type \"".concat(type,"\" + not found"));}}var nodeClass=registeredNode.klass;if(serializedNode.type!==nodeClass.getType()){{formatDevErrorMessage("LexicalNode: Node ".concat(nodeClass.name," does not implement .importJSON()."));}}var node=nodeClass.importJSON(serializedNode);var children=serializedNode.children;if($isElementNode(node)&&Array.isArray(children)){for(var i=0;i<children.length;i++){var serializedJSONChildNode=children[i];var childNode=$parseSerializedNodeImpl(serializedJSONChildNode,registeredNodes);node.append(childNode);}}return node;}function _parseEditorState(serializedEditorState,editor,updateFn){var editorState=createEmptyEditorState();var previousActiveEditorState=activeEditorState;var previousReadOnlyMode=isReadOnlyMode;var previousActiveEditor=activeEditor;var previousDirtyElements=editor._dirtyElements;var previousDirtyLeaves=editor._dirtyLeaves;var previousCloneNotNeeded=editor._cloneNotNeeded;var previousDirtyType=editor._dirtyType;editor._dirtyElements=new Map();editor._dirtyLeaves=new Set();editor._cloneNotNeeded=new Set();editor._dirtyType=0;activeEditorState=editorState;isReadOnlyMode=false;activeEditor=editor;setPendingNodeToClone(null);try{var registeredNodes=editor._nodes;var serializedNode=serializedEditorState.root;$parseSerializedNodeImpl(serializedNode,registeredNodes);if(updateFn){updateFn(editorState);}// Make the editorState immutable
1889
+ editorState._readOnly=true;{handleDEVOnlyPendingUpdateGuarantees(editorState);}}catch(error){if(error instanceof Error){editor._onError(error);}}finally{editor._dirtyElements=previousDirtyElements;editor._dirtyLeaves=previousDirtyLeaves;editor._cloneNotNeeded=previousCloneNotNeeded;editor._dirtyType=previousDirtyType;activeEditorState=previousActiveEditorState;isReadOnlyMode=previousReadOnlyMode;activeEditor=previousActiveEditor;}return editorState;}// This technically isn't an update but given we need
1890
+ // exposure to the module's active bindings, we have this
1891
+ // function here
1892
+ function readEditorState(editor,editorState,callbackFn){var previousActiveEditorState=activeEditorState;var previousReadOnlyMode=isReadOnlyMode;var previousActiveEditor=activeEditor;activeEditorState=editorState;isReadOnlyMode=true;activeEditor=editor;try{return callbackFn();}finally{activeEditorState=previousActiveEditorState;isReadOnlyMode=previousReadOnlyMode;activeEditor=previousActiveEditor;}}function handleDEVOnlyPendingUpdateGuarantees(pendingEditorState){// Given we can't Object.freeze the nodeMap as it's a Map,
1893
+ // we instead replace its set, clear and delete methods.
1894
+ var nodeMap=pendingEditorState._nodeMap;nodeMap.set=function(){throw new Error('Cannot call set() on a frozen Lexical node map');};nodeMap.clear=function(){throw new Error('Cannot call clear() on a frozen Lexical node map');};nodeMap.delete=function(){throw new Error('Cannot call delete() on a frozen Lexical node map');};}function $commitPendingUpdates(editor,recoveryEditorState){var pendingEditorState=editor._pendingEditorState;var rootElement=editor._rootElement;var shouldSkipDOM=editor._headless||rootElement===null;if(pendingEditorState===null){return;}// ======
1895
+ // Reconciliation has started.
1896
+ // ======
1897
+ var currentEditorState=editor._editorState;var currentSelection=currentEditorState._selection;var pendingSelection=pendingEditorState._selection;var needsUpdate=editor._dirtyType!==NO_DIRTY_NODES;var previousActiveEditorState=activeEditorState;var previousReadOnlyMode=isReadOnlyMode;var previousActiveEditor=activeEditor;var previouslyUpdating=editor._updating;var observer=editor._observer;var mutatedNodes=null;editor._pendingEditorState=null;editor._editorState=pendingEditorState;if(!shouldSkipDOM&&needsUpdate&&observer!==null){activeEditor=editor;activeEditorState=pendingEditorState;isReadOnlyMode=false;// We don't want updates to sync block the reconciliation.
1898
+ editor._updating=true;try{var dirtyType=editor._dirtyType;var _dirtyElements=editor._dirtyElements;var _dirtyLeaves=editor._dirtyLeaves;observer.disconnect();mutatedNodes=$reconcileRoot(currentEditorState,pendingEditorState,editor,dirtyType,_dirtyElements,_dirtyLeaves);}catch(error){// Report errors
1899
+ if(error instanceof Error){editor._onError(error);}// Reset editor and restore incoming editor state to the DOM
1900
+ if(!isAttemptingToRecoverFromReconcilerError){resetEditor(editor,null,rootElement,pendingEditorState);initMutationObserver(editor);editor._dirtyType=FULL_RECONCILE;isAttemptingToRecoverFromReconcilerError=true;$commitPendingUpdates(editor,currentEditorState);isAttemptingToRecoverFromReconcilerError=false;}else{// To avoid a possible situation of infinite loops, lets throw
1901
+ throw error;}return;}finally{observer.observe(rootElement,observerOptions);editor._updating=previouslyUpdating;activeEditorState=previousActiveEditorState;isReadOnlyMode=previousReadOnlyMode;activeEditor=previousActiveEditor;}}if(!pendingEditorState._readOnly){pendingEditorState._readOnly=true;{handleDEVOnlyPendingUpdateGuarantees(pendingEditorState);if($isRangeSelection(pendingSelection)){Object.freeze(pendingSelection.anchor);Object.freeze(pendingSelection.focus);}Object.freeze(pendingSelection);}}var dirtyLeaves=editor._dirtyLeaves;var dirtyElements=editor._dirtyElements;var normalizedNodes=editor._normalizedNodes;var tags=editor._updateTags;var deferred=editor._deferred;if(needsUpdate){editor._dirtyType=NO_DIRTY_NODES;editor._cloneNotNeeded.clear();editor._dirtyLeaves=new Set();editor._dirtyElements=new Map();editor._normalizedNodes=new Set();editor._updateTags=new Set();}$garbageCollectDetachedDecorators(editor,pendingEditorState);// ======
1902
+ // Reconciliation has finished. Now update selection and trigger listeners.
1903
+ // ======
1904
+ var domSelection=shouldSkipDOM?null:getDOMSelection(getWindow(editor));// Attempt to update the DOM selection, including focusing of the root element,
1905
+ // and scroll into view if needed.
1906
+ if(editor._editable&&// domSelection will be null in headless
1907
+ domSelection!==null&&(needsUpdate||pendingSelection===null||pendingSelection.dirty||!pendingSelection.is(currentSelection))&&rootElement!==null&&!tags.has(SKIP_DOM_SELECTION_TAG)){activeEditor=editor;activeEditorState=pendingEditorState;try{if(observer!==null){observer.disconnect();}if(needsUpdate||pendingSelection===null||pendingSelection.dirty){var blockCursorElement=editor._blockCursorElement;if(blockCursorElement!==null){removeDOMBlockCursorElement(blockCursorElement,editor,rootElement);}updateDOMSelection(currentSelection,pendingSelection,editor,domSelection,tags,rootElement);}updateDOMBlockCursorElement(editor,rootElement,pendingSelection);}finally{if(observer!==null){observer.observe(rootElement,observerOptions);}activeEditor=previousActiveEditor;activeEditorState=previousActiveEditorState;}}if(mutatedNodes!==null){triggerMutationListeners(editor,mutatedNodes,tags,dirtyLeaves,currentEditorState);}if(!$isRangeSelection(pendingSelection)&&pendingSelection!==null&&(currentSelection===null||!currentSelection.is(pendingSelection))){editor.dispatchCommand(SELECTION_CHANGE_COMMAND,undefined);}/**
1908
+ * Capture pendingDecorators after garbage collecting detached decorators
1909
+ */var pendingDecorators=editor._pendingDecorators;if(pendingDecorators!==null){editor._decorators=pendingDecorators;editor._pendingDecorators=null;triggerListeners('decorator',editor,true,pendingDecorators);}// If reconciler fails, we reset whole editor (so current editor state becomes empty)
1910
+ // and attempt to re-render pendingEditorState. If that goes through we trigger
1911
+ // listeners, but instead use recoverEditorState which is current editor state before reset
1912
+ // This specifically important for collab that relies on prevEditorState from update
1913
+ // listener to calculate delta of changed nodes/properties
1914
+ triggerTextContentListeners(editor,recoveryEditorState||currentEditorState,pendingEditorState);triggerListeners('update',editor,true,{dirtyElements:dirtyElements,dirtyLeaves:dirtyLeaves,editorState:pendingEditorState,mutatedNodes:mutatedNodes,normalizedNodes:normalizedNodes,prevEditorState:recoveryEditorState||currentEditorState,tags:tags});triggerDeferredUpdateCallbacks(editor,deferred);$triggerEnqueuedUpdates(editor);}function triggerTextContentListeners(editor,currentEditorState,pendingEditorState){var currentTextContent=getEditorStateTextContent(currentEditorState);var latestTextContent=getEditorStateTextContent(pendingEditorState);if(currentTextContent!==latestTextContent){triggerListeners('textcontent',editor,true,latestTextContent);}}function triggerMutationListeners(editor,mutatedNodes,updateTags,dirtyLeaves,prevEditorState){var listeners=Array.from(editor._listeners.mutation);var listenersLength=listeners.length;for(var i=0;i<listenersLength;i++){var _listeners$i=_slicedToArray(listeners[i],2),listener=_listeners$i[0],klassSet=_listeners$i[1];var _iterator25=_createForOfIteratorHelper(klassSet),_step25;try{for(_iterator25.s();!(_step25=_iterator25.n()).done;){var klass=_step25.value;var mutatedNodesByType=mutatedNodes.get(klass);if(mutatedNodesByType!==undefined){listener(mutatedNodesByType,{dirtyLeaves:dirtyLeaves,prevEditorState:prevEditorState,updateTags:updateTags});}}}catch(err){_iterator25.e(err);}finally{_iterator25.f();}}}function triggerListeners(type,editor,isCurrentlyEnqueuingUpdates){var previouslyUpdating=editor._updating;editor._updating=isCurrentlyEnqueuingUpdates;try{var listeners=Array.from(editor._listeners[type]);for(var _len3=arguments.length,payload=new Array(_len3>3?_len3-3:0),_key3=3;_key3<_len3;_key3++){payload[_key3-3]=arguments[_key3];}for(var i=0;i<listeners.length;i++){listeners[i].apply(null,payload);}}finally{editor._updating=previouslyUpdating;}}function triggerCommandListeners(editor,type,payload){var editors=getEditorsToPropagate(editor);for(var i=4;i>=0;i--){var _loop2=function _loop2(){var currentEditor=editors[e];var commandListeners=currentEditor._commands;var listenerInPriorityOrder=commandListeners.get(type);if(listenerInPriorityOrder!==undefined){var listenersSet=listenerInPriorityOrder[i];if(listenersSet!==undefined){var listeners=Array.from(listenersSet);var listenersLength=listeners.length;var returnVal=false;updateEditorSync(currentEditor,function(){for(var j=0;j<listenersLength;j++){if(listeners[j](payload,editor)){returnVal=true;return;}}});if(returnVal){return{v:returnVal};}}}},_ret;for(var e=0;e<editors.length;e++){_ret=_loop2();if(_ret)return _ret.v;}}return false;}function $triggerEnqueuedUpdates(editor){var queuedUpdates=editor._updates;if(queuedUpdates.length!==0){var queuedUpdate=queuedUpdates.shift();if(queuedUpdate){var _queuedUpdate=_slicedToArray(queuedUpdate,2),updateFn=_queuedUpdate[0],options=_queuedUpdate[1];$beginUpdate(editor,updateFn,options);}}}function triggerDeferredUpdateCallbacks(editor,deferred){editor._deferred=[];if(deferred.length!==0){var previouslyUpdating=editor._updating;editor._updating=true;try{for(var i=0;i<deferred.length;i++){deferred[i]();}}finally{editor._updating=previouslyUpdating;}}}function $processNestedUpdates(editor,initialSkipTransforms){var queuedUpdates=editor._updates;var skipTransforms=initialSkipTransforms||false;// Updates might grow as we process them, we so we'll need
1915
+ // to handle each update as we go until the updates array is
1916
+ // empty.
1917
+ while(queuedUpdates.length!==0){var queuedUpdate=queuedUpdates.shift();if(queuedUpdate){var _queuedUpdate2=_slicedToArray(queuedUpdate,2),nextUpdateFn=_queuedUpdate2[0],options=_queuedUpdate2[1];var pendingEditorState=editor._pendingEditorState;var onUpdate=void 0;if(options!==undefined){onUpdate=options.onUpdate;if(options.skipTransforms){skipTransforms=true;}if(options.discrete){if(!(pendingEditorState!==null)){formatDevErrorMessage("Unexpected empty pending editor state on discrete nested update");}pendingEditorState._flushSync=true;}if(onUpdate){editor._deferred.push(onUpdate);}addTags(editor,options.tag);}if(pendingEditorState==null){$beginUpdate(editor,nextUpdateFn,options);}else{nextUpdateFn();}}}return skipTransforms;}function $beginUpdate(editor,updateFn,options){var updateTags=editor._updateTags;var onUpdate;var skipTransforms=false;var discrete=false;if(options!==undefined){onUpdate=options.onUpdate;addTags(editor,options.tag);skipTransforms=options.skipTransforms||false;discrete=options.discrete||false;}if(onUpdate){editor._deferred.push(onUpdate);}var currentEditorState=editor._editorState;var pendingEditorState=editor._pendingEditorState;var editorStateWasCloned=false;if(pendingEditorState===null||pendingEditorState._readOnly){pendingEditorState=editor._pendingEditorState=cloneEditorState(pendingEditorState||currentEditorState);editorStateWasCloned=true;}pendingEditorState._flushSync=discrete;var previousActiveEditorState=activeEditorState;var previousReadOnlyMode=isReadOnlyMode;var previousActiveEditor=activeEditor;var previouslyUpdating=editor._updating;activeEditorState=pendingEditorState;isReadOnlyMode=false;editor._updating=true;activeEditor=editor;var headless=editor._headless||editor.getRootElement()===null;setPendingNodeToClone(null);try{if(editorStateWasCloned){if(headless){if(currentEditorState._selection!==null){pendingEditorState._selection=currentEditorState._selection.clone();}}else{pendingEditorState._selection=$internalCreateSelection(editor,options&&options.event||null);}}var startingCompositionKey=editor._compositionKey;updateFn();skipTransforms=$processNestedUpdates(editor,skipTransforms);applySelectionTransforms(pendingEditorState,editor);if(editor._dirtyType!==NO_DIRTY_NODES){if(skipTransforms){$normalizeAllDirtyTextNodes(pendingEditorState,editor);}else{$applyAllTransforms(pendingEditorState,editor);}$processNestedUpdates(editor);$garbageCollectDetachedNodes(currentEditorState,pendingEditorState,editor._dirtyLeaves,editor._dirtyElements);}var endingCompositionKey=editor._compositionKey;if(startingCompositionKey!==endingCompositionKey){pendingEditorState._flushSync=true;}var pendingSelection=pendingEditorState._selection;if($isRangeSelection(pendingSelection)){var pendingNodeMap=pendingEditorState._nodeMap;var anchorKey=pendingSelection.anchor.key;var focusKey=pendingSelection.focus.key;if(pendingNodeMap.get(anchorKey)===undefined||pendingNodeMap.get(focusKey)===undefined){{formatDevErrorMessage("updateEditor: selection has been lost because the previously selected nodes have been removed and selection wasn't moved to another node. Ensure selection changes after removing/replacing a selected node.");}}}else if($isNodeSelection(pendingSelection)){// TODO: we should also validate node selection?
1918
+ if(pendingSelection._nodes.size===0){pendingEditorState._selection=null;}}}catch(error){// Report errors
1919
+ if(error instanceof Error){editor._onError(error);}// Restore existing editor state to the DOM
1920
+ editor._pendingEditorState=currentEditorState;editor._dirtyType=FULL_RECONCILE;editor._cloneNotNeeded.clear();editor._dirtyLeaves=new Set();editor._dirtyElements.clear();$commitPendingUpdates(editor);return;}finally{activeEditorState=previousActiveEditorState;isReadOnlyMode=previousReadOnlyMode;activeEditor=previousActiveEditor;editor._updating=previouslyUpdating;infiniteTransformCount=0;}var shouldUpdate=editor._dirtyType!==NO_DIRTY_NODES||editor._deferred.length>0||editorStateHasDirtySelection(pendingEditorState,editor);if(shouldUpdate){if(pendingEditorState._flushSync){pendingEditorState._flushSync=false;$commitPendingUpdates(editor);}else if(editorStateWasCloned){scheduleMicroTask(function(){$commitPendingUpdates(editor);});}}else{pendingEditorState._flushSync=false;if(editorStateWasCloned){updateTags.clear();editor._deferred=[];editor._pendingEditorState=null;}}}/**
1921
+ * A variant of updateEditor that will not defer if it is nested in an update
1922
+ * to the same editor, much like if it was an editor.dispatchCommand issued
1923
+ * within an update
1924
+ */function updateEditorSync(editor,updateFn,options){if(activeEditor===editor&&options===undefined){updateFn();}else{$beginUpdate(editor,updateFn,options);}}function updateEditor(editor,updateFn,options){if(editor._updating){editor._updates.push([updateFn,options]);}else{$beginUpdate(editor,updateFn,options);}}// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
1925
+ /**
1926
+ * A utility class for managing the DOM children of an ElementNode
1927
+ */var ElementDOMSlot=/*#__PURE__*/function(){function ElementDOMSlot(element/** All managed children will be inserted before this node, if defined */,before/** All managed children will be inserted after this node, if defined */,after){_classCallCheck(this,ElementDOMSlot);_defineProperty(this,"element",void 0);_defineProperty(this,"before",void 0);_defineProperty(this,"after",void 0);this.element=element;this.before=before||null;this.after=after||null;}/**
1928
+ * Return a new ElementDOMSlot where all managed children will be inserted before this node
1929
+ */_createClass(ElementDOMSlot,[{key:"withBefore",value:function withBefore(before){return new ElementDOMSlot(this.element,before,this.after);}/**
1930
+ * Return a new ElementDOMSlot where all managed children will be inserted after this node
1931
+ */},{key:"withAfter",value:function withAfter(after){return new ElementDOMSlot(this.element,this.before,after);}/**
1932
+ * Return a new ElementDOMSlot with an updated root element
1933
+ */},{key:"withElement",value:function withElement(element){if(this.element===element){return this;}return new ElementDOMSlot(element,this.before,this.after);}/**
1934
+ * Insert the given child before this.before and any reconciler managed line break node,
1935
+ * or append it if this.before is not defined
1936
+ */},{key:"insertChild",value:function insertChild(dom){var before=this.before||this.getManagedLineBreak();if(!(before===null||before.parentElement===this.element)){formatDevErrorMessage("ElementDOMSlot.insertChild: before is not in element");}this.element.insertBefore(dom,before);return this;}/**
1937
+ * Remove the managed child from this container, will throw if it was not already there
1938
+ */},{key:"removeChild",value:function removeChild(dom){if(!(dom.parentElement===this.element)){formatDevErrorMessage("ElementDOMSlot.removeChild: dom is not in element");}this.element.removeChild(dom);return this;}/**
1939
+ * Replace managed child prevDom with dom. Will throw if prevDom is not a child
1940
+ *
1941
+ * @param dom The new node to replace prevDom
1942
+ * @param prevDom the node that will be replaced
1943
+ */},{key:"replaceChild",value:function replaceChild(dom,prevDom){if(!(prevDom.parentElement===this.element)){formatDevErrorMessage("ElementDOMSlot.replaceChild: prevDom is not in element");}this.element.replaceChild(dom,prevDom);return this;}/**
1944
+ * Returns the first managed child of this node,
1945
+ * which will either be this.after.nextSibling or this.element.firstChild,
1946
+ * and will never be this.before if it is defined.
1947
+ */},{key:"getFirstChild",value:function getFirstChild(){var firstChild=this.after?this.after.nextSibling:this.element.firstChild;return firstChild===this.before||firstChild===this.getManagedLineBreak()?null:firstChild;}/**
1948
+ * @internal
1949
+ */},{key:"getManagedLineBreak",value:function getManagedLineBreak(){var element=this.element;return element.__lexicalLineBreak||null;}/** @internal */},{key:"setManagedLineBreak",value:function setManagedLineBreak(lineBreakType){if(lineBreakType===null){this.removeManagedLineBreak();}else{var webkitHack=lineBreakType==='decorator'&&(IS_APPLE_WEBKIT||IS_IOS||IS_SAFARI);this.insertManagedLineBreak(webkitHack);}}/** @internal */},{key:"removeManagedLineBreak",value:function removeManagedLineBreak(){var br=this.getManagedLineBreak();if(br){var element=this.element;var sibling=br.nodeName==='IMG'?br.nextSibling:null;if(sibling){element.removeChild(sibling);}element.removeChild(br);element.__lexicalLineBreak=undefined;}}/** @internal */},{key:"insertManagedLineBreak",value:function insertManagedLineBreak(webkitHack){var prevBreak=this.getManagedLineBreak();if(prevBreak){if(webkitHack===(prevBreak.nodeName==='IMG')){return;}this.removeManagedLineBreak();}var element=this.element;var before=this.before;var br=document.createElement('br');element.insertBefore(br,before);if(webkitHack){var img=document.createElement('img');img.setAttribute('data-lexical-linebreak','true');img.style.cssText='display: inline !important; border: 0px !important; margin: 0px !important;';img.alt='';element.insertBefore(img,br);element.__lexicalLineBreak=img;}else{element.__lexicalLineBreak=br;}}/**
1950
+ * @internal
1951
+ *
1952
+ * Returns the offset of the first child
1953
+ */},{key:"getFirstChildOffset",value:function getFirstChildOffset(){var i=0;for(var node=this.after;node!==null;node=node.previousSibling){i++;}return i;}/**
1954
+ * @internal
1955
+ */},{key:"resolveChildIndex",value:function resolveChildIndex(element,elementDOM,initialDOM,initialOffset){if(initialDOM===this.element){var firstChildOffset=this.getFirstChildOffset();return[element,Math.min(firstChildOffset+element.getChildrenSize(),Math.max(firstChildOffset,initialOffset))];}// The resolved offset must be before or after the children
1956
+ var initialPath=indexPath(elementDOM,initialDOM);initialPath.push(initialOffset);var elementPath=indexPath(elementDOM,this.element);var offset=element.getIndexWithinParent();for(var i=0;i<elementPath.length;i++){var target=initialPath[i];var source=elementPath[i];if(target===undefined||target<source){break;}else if(target>source){offset+=1;break;}}return[element.getParentOrThrow(),offset];}}]);return ElementDOMSlot;}();function indexPath(root,child){var path=[];var node=child;for(;node!==root&&node!==null;node=node.parentNode){var i=0;for(var sibling=node.previousSibling;sibling!==null;sibling=sibling.previousSibling){i++;}path.push(i);}if(!(node===root)){formatDevErrorMessage("indexPath: root is not a parent of child");}return path.reverse();}/** @noInheritDoc */ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
1957
+ var ElementNode=/*#__PURE__*/function(_LexicalNode3){_inherits(ElementNode,_LexicalNode3);var _super4=_createSuper(ElementNode);function ElementNode(key){var _this4;_classCallCheck(this,ElementNode);_this4=_super4.call(this,key);/** @internal */ /** @internal */_defineProperty(_assertThisInitialized(_this4),"__first",void 0);/** @internal */_defineProperty(_assertThisInitialized(_this4),"__last",void 0);/** @internal */_defineProperty(_assertThisInitialized(_this4),"__size",void 0);/** @internal */_defineProperty(_assertThisInitialized(_this4),"__format",void 0);/** @internal */_defineProperty(_assertThisInitialized(_this4),"__style",void 0);/** @internal */_defineProperty(_assertThisInitialized(_this4),"__indent",void 0);/** @internal */_defineProperty(_assertThisInitialized(_this4),"__dir",void 0);/** @internal */_defineProperty(_assertThisInitialized(_this4),"__textFormat",void 0);/** @internal */_defineProperty(_assertThisInitialized(_this4),"__textStyle",void 0);_this4.__first=null;_this4.__last=null;_this4.__size=0;_this4.__format=0;_this4.__style='';_this4.__indent=0;_this4.__dir=null;_this4.__textFormat=0;_this4.__textStyle='';return _this4;}_createClass(ElementNode,[{key:"afterCloneFrom",value:function afterCloneFrom(prevNode){_get(_getPrototypeOf(ElementNode.prototype),"afterCloneFrom",this).call(this,prevNode);if(this.__key===prevNode.__key){this.__first=prevNode.__first;this.__last=prevNode.__last;this.__size=prevNode.__size;}this.__indent=prevNode.__indent;this.__format=prevNode.__format;this.__style=prevNode.__style;this.__dir=prevNode.__dir;this.__textFormat=prevNode.__textFormat;this.__textStyle=prevNode.__textStyle;}},{key:"getFormat",value:function getFormat(){var self=this.getLatest();return self.__format;}},{key:"getFormatType",value:function getFormatType(){var format=this.getFormat();return ELEMENT_FORMAT_TO_TYPE[format]||'';}},{key:"getStyle",value:function getStyle(){var self=this.getLatest();return self.__style;}},{key:"getIndent",value:function getIndent(){var self=this.getLatest();return self.__indent;}},{key:"getChildren",value:function getChildren(){var children=[];var child=this.getFirstChild();while(child!==null){children.push(child);child=child.getNextSibling();}return children;}},{key:"getChildrenKeys",value:function getChildrenKeys(){var children=[];var child=this.getFirstChild();while(child!==null){children.push(child.__key);child=child.getNextSibling();}return children;}},{key:"getChildrenSize",value:function getChildrenSize(){var self=this.getLatest();return self.__size;}},{key:"isEmpty",value:function isEmpty(){return this.getChildrenSize()===0;}},{key:"isDirty",value:function isDirty(){var editor=getActiveEditor();var dirtyElements=editor._dirtyElements;return dirtyElements!==null&&dirtyElements.has(this.__key);}},{key:"isLastChild",value:function isLastChild(){var self=this.getLatest();var parentLastChild=this.getParentOrThrow().getLastChild();return parentLastChild!==null&&parentLastChild.is(self);}},{key:"getAllTextNodes",value:function getAllTextNodes(){var textNodes=[];var child=this.getFirstChild();while(child!==null){if($isTextNode(child)){textNodes.push(child);}if($isElementNode(child)){var subChildrenNodes=child.getAllTextNodes();textNodes.push.apply(textNodes,_toConsumableArray(subChildrenNodes));}child=child.getNextSibling();}return textNodes;}},{key:"getFirstDescendant",value:function getFirstDescendant(){var node=this.getFirstChild();while($isElementNode(node)){var child=node.getFirstChild();if(child===null){break;}node=child;}return node;}},{key:"getLastDescendant",value:function getLastDescendant(){var node=this.getLastChild();while($isElementNode(node)){var child=node.getLastChild();if(child===null){break;}node=child;}return node;}},{key:"getDescendantByIndex",value:function getDescendantByIndex(index){var children=this.getChildren();var childrenLength=children.length;// For non-empty element nodes, we resolve its descendant
1958
+ // (either a leaf node or the bottom-most element)
1959
+ if(index>=childrenLength){var _resolvedNode=children[childrenLength-1];return $isElementNode(_resolvedNode)&&_resolvedNode.getLastDescendant()||_resolvedNode||null;}var resolvedNode=children[index];return $isElementNode(resolvedNode)&&resolvedNode.getFirstDescendant()||resolvedNode||null;}},{key:"getFirstChild",value:function getFirstChild(){var self=this.getLatest();var firstKey=self.__first;return firstKey===null?null:$getNodeByKey(firstKey);}},{key:"getFirstChildOrThrow",value:function getFirstChildOrThrow(){var firstChild=this.getFirstChild();if(firstChild===null){{formatDevErrorMessage("Expected node ".concat(this.__key," to have a first child."));}}return firstChild;}},{key:"getLastChild",value:function getLastChild(){var self=this.getLatest();var lastKey=self.__last;return lastKey===null?null:$getNodeByKey(lastKey);}},{key:"getLastChildOrThrow",value:function getLastChildOrThrow(){var lastChild=this.getLastChild();if(lastChild===null){{formatDevErrorMessage("Expected node ".concat(this.__key," to have a last child."));}}return lastChild;}},{key:"getChildAtIndex",value:function getChildAtIndex(index){var size=this.getChildrenSize();var node;var i;if(index<size/2){node=this.getFirstChild();i=0;while(node!==null&&i<=index){if(i===index){return node;}node=node.getNextSibling();i++;}return null;}node=this.getLastChild();i=size-1;while(node!==null&&i>=index){if(i===index){return node;}node=node.getPreviousSibling();i--;}return null;}},{key:"getTextContent",value:function getTextContent(){var textContent='';var children=this.getChildren();var childrenLength=children.length;for(var i=0;i<childrenLength;i++){var child=children[i];textContent+=child.getTextContent();if($isElementNode(child)&&i!==childrenLength-1&&!child.isInline()){textContent+=DOUBLE_LINE_BREAK;}}return textContent;}},{key:"getTextContentSize",value:function getTextContentSize(){var textContentSize=0;var children=this.getChildren();var childrenLength=children.length;for(var i=0;i<childrenLength;i++){var child=children[i];textContentSize+=child.getTextContentSize();if($isElementNode(child)&&i!==childrenLength-1&&!child.isInline()){textContentSize+=DOUBLE_LINE_BREAK.length;}}return textContentSize;}},{key:"getDirection",value:function getDirection(){var self=this.getLatest();return self.__dir;}},{key:"getTextFormat",value:function getTextFormat(){var self=this.getLatest();return self.__textFormat;}},{key:"hasFormat",value:function hasFormat(type){if(type!==''){var formatFlag=ELEMENT_TYPE_TO_FORMAT[type];return(this.getFormat()&formatFlag)!==0;}return false;}},{key:"hasTextFormat",value:function hasTextFormat(type){var formatFlag=TEXT_TYPE_TO_FORMAT[type];return(this.getTextFormat()&formatFlag)!==0;}/**
1960
+ * Returns the format flags applied to the node as a 32-bit integer.
1961
+ *
1962
+ * @returns a number representing the TextFormatTypes applied to the node.
1963
+ */},{key:"getFormatFlags",value:function getFormatFlags(type,alignWithFormat){var self=this.getLatest();var format=self.__textFormat;return toggleTextFormatType(format,type,alignWithFormat);}},{key:"getTextStyle",value:function getTextStyle(){var self=this.getLatest();return self.__textStyle;}// Mutators
1964
+ },{key:"select",value:function select(_anchorOffset,_focusOffset){errorOnReadOnly();var selection=$getSelection();var anchorOffset=_anchorOffset;var focusOffset=_focusOffset;var childrenCount=this.getChildrenSize();if(!this.canBeEmpty()){if(_anchorOffset===0&&_focusOffset===0){var firstChild=this.getFirstChild();if($isTextNode(firstChild)||$isElementNode(firstChild)){return firstChild.select(0,0);}}else if((_anchorOffset===undefined||_anchorOffset===childrenCount)&&(_focusOffset===undefined||_focusOffset===childrenCount)){var lastChild=this.getLastChild();if($isTextNode(lastChild)||$isElementNode(lastChild)){return lastChild.select();}}}if(anchorOffset===undefined){anchorOffset=childrenCount;}if(focusOffset===undefined){focusOffset=childrenCount;}var key=this.__key;if(!$isRangeSelection(selection)){return $internalMakeRangeSelection(key,anchorOffset,key,focusOffset,'element','element');}else{selection.anchor.set(key,anchorOffset,'element');selection.focus.set(key,focusOffset,'element');selection.dirty=true;}return selection;}},{key:"selectStart",value:function selectStart(){var firstNode=this.getFirstDescendant();return firstNode?firstNode.selectStart():this.select();}},{key:"selectEnd",value:function selectEnd(){var lastNode=this.getLastDescendant();return lastNode?lastNode.selectEnd():this.select();}},{key:"clear",value:function clear(){var writableSelf=this.getWritable();var children=this.getChildren();children.forEach(function(child){return child.remove();});return writableSelf;}},{key:"append",value:function append(){for(var _len4=arguments.length,nodesToAppend=new Array(_len4),_key4=0;_key4<_len4;_key4++){nodesToAppend[_key4]=arguments[_key4];}return this.splice(this.getChildrenSize(),0,nodesToAppend);}},{key:"setDirection",value:function setDirection(direction){var self=this.getWritable();self.__dir=direction;return self;}},{key:"setFormat",value:function setFormat(type){var self=this.getWritable();self.__format=type!==''?ELEMENT_TYPE_TO_FORMAT[type]:0;return this;}},{key:"setStyle",value:function setStyle(style){var self=this.getWritable();self.__style=style||'';return this;}},{key:"setTextFormat",value:function setTextFormat(type){var self=this.getWritable();self.__textFormat=type;return self;}},{key:"setTextStyle",value:function setTextStyle(style){var self=this.getWritable();self.__textStyle=style;return self;}},{key:"setIndent",value:function setIndent(indentLevel){var self=this.getWritable();self.__indent=indentLevel;return this;}},{key:"splice",value:function splice(start,deleteCount,nodesToInsert){if(!!$isEphemeral(this)){formatDevErrorMessage("ElementNode.splice: Ephemeral nodes can not mutate their children (key ".concat(this.__key," type ").concat(this.__type,")"));}var oldSize=this.getChildrenSize();var writableSelf=this.getWritable();if(!(start+deleteCount<=oldSize)){formatDevErrorMessage("ElementNode.splice: start + deleteCount > oldSize (".concat(String(start)," + ").concat(String(deleteCount)," > ").concat(String(oldSize),")"));}var writableSelfKey=writableSelf.__key;var nodesToInsertKeys=[];var nodesToRemoveKeys=[];var nodeAfterRange=this.getChildAtIndex(start+deleteCount);var nodeBeforeRange=null;var newSize=oldSize-deleteCount+nodesToInsert.length;if(start!==0){if(start===oldSize){nodeBeforeRange=this.getLastChild();}else{var node=this.getChildAtIndex(start);if(node!==null){nodeBeforeRange=node.getPreviousSibling();}}}if(deleteCount>0){var nodeToDelete=nodeBeforeRange===null?this.getFirstChild():nodeBeforeRange.getNextSibling();for(var i=0;i<deleteCount;i++){if(nodeToDelete===null){{formatDevErrorMessage("splice: sibling not found");}}var nextSibling=nodeToDelete.getNextSibling();var nodeKeyToDelete=nodeToDelete.__key;var writableNodeToDelete=nodeToDelete.getWritable();removeFromParent(writableNodeToDelete);nodesToRemoveKeys.push(nodeKeyToDelete);nodeToDelete=nextSibling;}}var prevNode=nodeBeforeRange;var _iterator26=_createForOfIteratorHelper(nodesToInsert),_step26;try{for(_iterator26.s();!(_step26=_iterator26.n()).done;){var nodeToInsert=_step26.value;if(prevNode!==null&&nodeToInsert.is(prevNode)){nodeBeforeRange=prevNode=prevNode.getPreviousSibling();}var writableNodeToInsert=nodeToInsert.getWritable();if(writableNodeToInsert.__parent===writableSelfKey){newSize--;}removeFromParent(writableNodeToInsert);var nodeKeyToInsert=nodeToInsert.__key;if(prevNode===null){writableSelf.__first=nodeKeyToInsert;writableNodeToInsert.__prev=null;}else{var _writablePrevNode2=prevNode.getWritable();_writablePrevNode2.__next=nodeKeyToInsert;writableNodeToInsert.__prev=_writablePrevNode2.__key;}if(nodeToInsert.__key===writableSelfKey){{formatDevErrorMessage("append: attempting to append self");}}// Set child parent to self
1965
+ writableNodeToInsert.__parent=writableSelfKey;nodesToInsertKeys.push(nodeKeyToInsert);prevNode=nodeToInsert;}}catch(err){_iterator26.e(err);}finally{_iterator26.f();}if(start+deleteCount===oldSize){if(prevNode!==null){var writablePrevNode=prevNode.getWritable();writablePrevNode.__next=null;writableSelf.__last=prevNode.__key;}}else if(nodeAfterRange!==null){var writableNodeAfterRange=nodeAfterRange.getWritable();if(prevNode!==null){var _writablePrevNode=prevNode.getWritable();writableNodeAfterRange.__prev=prevNode.__key;_writablePrevNode.__next=nodeAfterRange.__key;}else{writableNodeAfterRange.__prev=null;}}writableSelf.__size=newSize;// In case of deletion we need to adjust selection, unlink removed nodes
1966
+ // and clean up node itself if it becomes empty. None of these needed
1967
+ // for insertion-only cases
1968
+ if(nodesToRemoveKeys.length){// Adjusting selection, in case node that was anchor/focus will be deleted
1969
+ var selection=$getSelection();if($isRangeSelection(selection)){var nodesToRemoveKeySet=new Set(nodesToRemoveKeys);var nodesToInsertKeySet=new Set(nodesToInsertKeys);var anchor=selection.anchor,focus=selection.focus;if(isPointRemoved(anchor,nodesToRemoveKeySet,nodesToInsertKeySet)){moveSelectionPointToSibling(anchor,anchor.getNode(),this,nodeBeforeRange,nodeAfterRange);}if(isPointRemoved(focus,nodesToRemoveKeySet,nodesToInsertKeySet)){moveSelectionPointToSibling(focus,focus.getNode(),this,nodeBeforeRange,nodeAfterRange);}// Cleanup if node can't be empty
1970
+ if(newSize===0&&!this.canBeEmpty()&&!$isRootOrShadowRoot(this)){this.remove();}}}return writableSelf;}/**
1971
+ * @internal
1972
+ *
1973
+ * An experimental API that an ElementNode can override to control where its
1974
+ * children are inserted into the DOM, this is useful to add a wrapping node
1975
+ * or accessory nodes before or after the children. The root of the node returned
1976
+ * by createDOM must still be exactly one HTMLElement.
1977
+ */},{key:"getDOMSlot",value:function getDOMSlot(element){return new ElementDOMSlot(element);}},{key:"exportDOM",value:function exportDOM(editor){var _get$call2=_get(_getPrototypeOf(ElementNode.prototype),"exportDOM",this).call(this,editor),element=_get$call2.element;if(isHTMLElement(element)){var indent=this.getIndent();if(indent>0){// padding-inline-start is not widely supported in email HTML
1978
+ // (see https://www.caniemail.com/features/css-padding-inline-start-end/),
1979
+ // If you want to use HTML output for email, consider overriding the serialization
1980
+ // to use `padding-right` in RTL languages, `padding-left` in `LTR` languages, or
1981
+ // `text-indent` if you are ok with first-line indents.
1982
+ // We recommend keeping multiples of 40px to maintain consistency with list-items
1983
+ // (see https://github.com/facebook/lexical/pull/4025)
1984
+ element.style.paddingInlineStart="".concat(indent*40,"px");}var direction=this.getDirection();if(direction){element.dir=direction;}}return{element:element};}// JSON serialization
1985
+ },{key:"exportJSON",value:function exportJSON(){var json=_objectSpread({children:[],direction:this.getDirection(),format:this.getFormatType(),indent:this.getIndent()},_get(_getPrototypeOf(ElementNode.prototype),"exportJSON",this).call(this));var textFormat=this.getTextFormat();var textStyle=this.getTextStyle();// Only persist for cases when there are no TextNode children from which
1986
+ // these would be set on reconcile (#7968)
1987
+ if((textFormat!==0||textStyle!=='')&&!$isRootOrShadowRoot(this)&&!this.getChildren().some($isTextNode)){if(textFormat!==0){json.textFormat=textFormat;}if(textStyle!==''){json.textStyle=textStyle;}}return json;}},{key:"updateFromJSON",value:function updateFromJSON(serializedNode){return _get(_getPrototypeOf(ElementNode.prototype),"updateFromJSON",this).call(this,serializedNode).setFormat(serializedNode.format).setIndent(serializedNode.indent).setDirection(serializedNode.direction).setTextFormat(serializedNode.textFormat||0).setTextStyle(serializedNode.textStyle||'');}// These are intended to be extends for specific element heuristics.
1988
+ },{key:"insertNewAfter",value:function insertNewAfter(selection,restoreSelection){return null;}},{key:"canIndent",value:function canIndent(){return true;}/*
1989
+ * This method controls the behavior of the node during backwards
1990
+ * deletion (i.e., backspace) when selection is at the beginning of
1991
+ * the node (offset 0). You may use this to have the node replace
1992
+ * itself, change its state, or do nothing. When you do make such
1993
+ * a change, you should return true.
1994
+ *
1995
+ * When true is returned, the collapse phase will stop.
1996
+ * When false is returned, and isInline() is true, and getPreviousSibling() is null,
1997
+ * then this function will be called on its parent.
1998
+ */},{key:"collapseAtStart",value:function collapseAtStart(selection){return false;}},{key:"excludeFromCopy",value:function excludeFromCopy(destination){return false;}/** @deprecated @internal */},{key:"canReplaceWith",value:function canReplaceWith(replacement){return true;}/** @deprecated @internal */},{key:"canInsertAfter",value:function canInsertAfter(node){return true;}},{key:"canBeEmpty",value:function canBeEmpty(){return true;}},{key:"canInsertTextBefore",value:function canInsertTextBefore(){return true;}},{key:"canInsertTextAfter",value:function canInsertTextAfter(){return true;}},{key:"isInline",value:function isInline(){return false;}// A shadow root is a Node that behaves like RootNode. The shadow root (and RootNode) mark the
1999
+ // end of the hierarchy, most implementations should treat it as there's nothing (upwards)
2000
+ // beyond this point. For example, node.getTopLevelElement(), when performed inside a TableCellNode
2001
+ // will return the immediate first child underneath TableCellNode instead of RootNode.
2002
+ },{key:"isShadowRoot",value:function isShadowRoot(){return false;}/** @deprecated @internal */},{key:"canMergeWith",value:function canMergeWith(node){return false;}},{key:"extractWithChild",value:function extractWithChild(child,selection,destination){return false;}/**
2003
+ * Determines whether this node, when empty, can merge with a first block
2004
+ * of nodes being inserted.
2005
+ *
2006
+ * This method is specifically called in {@link RangeSelection.insertNodes}
2007
+ * to determine merging behavior during nodes insertion.
2008
+ *
2009
+ * @example
2010
+ * // In a ListItemNode or QuoteNode implementation:
2011
+ * canMergeWhenEmpty(): true {
2012
+ * return true;
2013
+ * }
2014
+ */},{key:"canMergeWhenEmpty",value:function canMergeWhenEmpty(){return false;}/** @internal */},{key:"reconcileObservedMutation",value:function reconcileObservedMutation(dom,editor){var slot=this.getDOMSlot(dom);var currentDOM=slot.getFirstChild();for(var currentNode=this.getFirstChild();currentNode;currentNode=currentNode.getNextSibling()){var correctDOM=editor.getElementByKey(currentNode.getKey());if(correctDOM===null){continue;}if(currentDOM==null){slot.insertChild(correctDOM);currentDOM=correctDOM;}else if(currentDOM!==correctDOM){slot.replaceChild(correctDOM,currentDOM);}currentDOM=currentDOM.nextSibling;}}}]);return ElementNode;}(LexicalNode);function $isElementNode(node){return node instanceof ElementNode;}function isPointRemoved(point,nodesToRemoveKeySet,nodesToInsertKeySet){var node=point.getNode();while(node){var nodeKey=node.__key;if(nodesToRemoveKeySet.has(nodeKey)&&!nodesToInsertKeySet.has(nodeKey)){return true;}node=node.getParent();}return false;}/**
2015
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
2016
+ *
2017
+ * This source code is licensed under the MIT license found in the
2018
+ * LICENSE file in the root directory of this source tree.
2019
+ *
2020
+ */ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2021
+ /** @noInheritDoc */ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
2022
+ var DecoratorNode=/*#__PURE__*/function(_LexicalNode4){_inherits(DecoratorNode,_LexicalNode4);var _super5=_createSuper(DecoratorNode);function DecoratorNode(){_classCallCheck(this,DecoratorNode);return _super5.apply(this,arguments);}_createClass(DecoratorNode,[{key:"decorate",value:/** @internal */ /**
2023
+ * The returned value is added to the LexicalEditor._decorators
2024
+ */function decorate(editor,config){return null;}},{key:"isIsolated",value:function isIsolated(){return false;}},{key:"isInline",value:function isInline(){return true;}},{key:"isKeyboardSelectable",value:function isKeyboardSelectable(){return true;}}]);return DecoratorNode;}(LexicalNode);function $isDecoratorNode(node){return node instanceof DecoratorNode;}/** @noInheritDoc */var RootNode=/*#__PURE__*/function(_ElementNode){_inherits(RootNode,_ElementNode);var _super6=_createSuper(RootNode);function RootNode(){var _this5;_classCallCheck(this,RootNode);_this5=_super6.call(this,'root');/** @internal */_defineProperty(_assertThisInitialized(_this5),"__cachedText",void 0);_this5.__cachedText=null;return _this5;}_createClass(RootNode,[{key:"getTopLevelElementOrThrow",value:function getTopLevelElementOrThrow(){{formatDevErrorMessage("getTopLevelElementOrThrow: root nodes are not top level elements");}}},{key:"getTextContent",value:function getTextContent(){var cachedText=this.__cachedText;if(isCurrentlyReadOnlyMode()||getActiveEditor()._dirtyType===NO_DIRTY_NODES){if(cachedText!==null){return cachedText;}}return _get(_getPrototypeOf(RootNode.prototype),"getTextContent",this).call(this);}},{key:"remove",value:function remove(){{formatDevErrorMessage("remove: cannot be called on root nodes");}}},{key:"replace",value:function replace(node){{formatDevErrorMessage("replace: cannot be called on root nodes");}}},{key:"insertBefore",value:function insertBefore(nodeToInsert){{formatDevErrorMessage("insertBefore: cannot be called on root nodes");}}},{key:"insertAfter",value:function insertAfter(nodeToInsert){{formatDevErrorMessage("insertAfter: cannot be called on root nodes");}}// View
2025
+ },{key:"updateDOM",value:function updateDOM(prevNode,dom){return false;}// Mutate
2026
+ },{key:"splice",value:function splice(start,deleteCount,nodesToInsert){var _iterator27=_createForOfIteratorHelper(nodesToInsert),_step27;try{for(_iterator27.s();!(_step27=_iterator27.n()).done;){var node=_step27.value;if(!($isElementNode(node)||$isDecoratorNode(node))){formatDevErrorMessage("rootNode.splice: Only element or decorator nodes can be inserted to the root node");}}}catch(err){_iterator27.e(err);}finally{_iterator27.f();}return _get(_getPrototypeOf(RootNode.prototype),"splice",this).call(this,start,deleteCount,nodesToInsert);}},{key:"collapseAtStart",value:function collapseAtStart(){return true;}}],[{key:"getType",value:function getType(){return'root';}},{key:"clone",value:function clone(){return new RootNode();}},{key:"importJSON",value:function importJSON(serializedNode){// We don't create a root, and instead use the existing root.
2027
+ return $getRoot().updateFromJSON(serializedNode);}}]);return RootNode;}(ElementNode);function $createRootNode(){return new RootNode();}function $isRootNode(node){return node instanceof RootNode;}function editorStateHasDirtySelection(editorState,editor){var currentSelection=editor.getEditorState()._selection;var pendingSelection=editorState._selection;// Check if we need to update because of changes in selection
2028
+ if(pendingSelection!==null){if(pendingSelection.dirty||!pendingSelection.is(currentSelection)){return true;}}else if(currentSelection!==null){return true;}return false;}function cloneEditorState(current){return new EditorState(new Map(current._nodeMap));}function createEmptyEditorState(){return new EditorState(new Map([['root',$createRootNode()]]));}function exportNodeToJSON(node){var serializedNode=node.exportJSON();var nodeClass=node.constructor;if(serializedNode.type!==nodeClass.getType()){{formatDevErrorMessage("LexicalNode: Node ".concat(nodeClass.name," does not match the serialized type. Check if .exportJSON() is implemented and it is returning the correct type."));}}if($isElementNode(node)){var serializedChildren=serializedNode.children;if(!Array.isArray(serializedChildren)){{formatDevErrorMessage("LexicalNode: Node ".concat(nodeClass.name," is an element but .exportJSON() does not have a children array."));}}var children=node.getChildren();for(var i=0;i<children.length;i++){var child=children[i];var serializedChildNode=exportNodeToJSON(child);serializedChildren.push(serializedChildNode);}}// @ts-expect-error
2029
+ return serializedNode;}/**
2030
+ * Type guard that returns true if the argument is an EditorState
2031
+ */function $isEditorState(x){return x instanceof EditorState;}var EditorState=/*#__PURE__*/function(){function EditorState(nodeMap,selection){_classCallCheck(this,EditorState);_defineProperty(this,"_nodeMap",void 0);_defineProperty(this,"_selection",void 0);_defineProperty(this,"_flushSync",void 0);_defineProperty(this,"_readOnly",void 0);this._nodeMap=nodeMap;this._selection=selection||null;this._flushSync=false;this._readOnly=false;}_createClass(EditorState,[{key:"isEmpty",value:function isEmpty(){return this._nodeMap.size===1&&this._selection===null;}},{key:"read",value:function read(callbackFn,options){return readEditorState(options&&options.editor||null,this,callbackFn);}},{key:"clone",value:function clone(selection){var editorState=new EditorState(this._nodeMap,selection===undefined?this._selection:selection);editorState._readOnly=true;return editorState;}},{key:"toJSON",value:function toJSON(){return readEditorState(null,this,function(){return{root:exportNodeToJSON($getRoot())};});}}]);return EditorState;}();/**
2032
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
2033
+ *
2034
+ * This source code is licensed under the MIT license found in the
2035
+ * LICENSE file in the root directory of this source tree.
2036
+ *
2037
+ */ // TODO: Cleanup ArtificialNode__DO_NOT_USE #5966
2038
+ /** @internal */var ArtificialNode__DO_NOT_USE=/*#__PURE__*/function(_ElementNode2){_inherits(ArtificialNode__DO_NOT_USE,_ElementNode2);var _super7=_createSuper(ArtificialNode__DO_NOT_USE);function ArtificialNode__DO_NOT_USE(){_classCallCheck(this,ArtificialNode__DO_NOT_USE);return _super7.apply(this,arguments);}_createClass(ArtificialNode__DO_NOT_USE,[{key:"createDOM",value:function createDOM(config){// this isnt supposed to be used and is not used anywhere but defining it to appease the API
2039
+ var dom=document.createElement('div');return dom;}}],[{key:"getType",value:function getType(){return'artificial';}}]);return ArtificialNode__DO_NOT_USE;}(ElementNode);/**
2040
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
2041
+ *
2042
+ * This source code is licensed under the MIT license found in the
2043
+ * LICENSE file in the root directory of this source tree.
2044
+ *
2045
+ */ /** @noInheritDoc */var ParagraphNode=/*#__PURE__*/function(_ElementNode3){_inherits(ParagraphNode,_ElementNode3);var _super8=_createSuper(ParagraphNode);function ParagraphNode(){_classCallCheck(this,ParagraphNode);return _super8.apply(this,arguments);}_createClass(ParagraphNode,[{key:"createDOM",value:// View
2046
+ function createDOM(config){var dom=document.createElement('p');var classNames=getCachedClassNameArray(config.theme,'paragraph');if(classNames!==undefined){var domClassList=dom.classList;domClassList.add.apply(domClassList,_toConsumableArray(classNames));}return dom;}},{key:"updateDOM",value:function updateDOM(prevNode,dom,config){return false;}},{key:"exportDOM",value:function exportDOM(editor){var _get$call3=_get(_getPrototypeOf(ParagraphNode.prototype),"exportDOM",this).call(this,editor),element=_get$call3.element;if(isHTMLElement(element)){if(this.isEmpty()){element.append(document.createElement('br'));}var formatType=this.getFormatType();if(formatType){element.style.textAlign=formatType;}}return{element:element};}},{key:"exportJSON",value:function exportJSON(){var json=_get(_getPrototypeOf(ParagraphNode.prototype),"exportJSON",this).call(this);// Provide backwards compatible values, see #7971
2047
+ if(json.textFormat===undefined||json.textStyle===undefined){// Compute the same value that the reconciler would
2048
+ var firstTextNode=this.getChildren().find($isTextNode);if(firstTextNode){json.textFormat=firstTextNode.getFormat();json.textStyle=firstTextNode.getStyle();}else{json.textFormat=this.getTextFormat();json.textStyle=this.getTextStyle();}}return json;}// Mutation
2049
+ },{key:"insertNewAfter",value:function insertNewAfter(rangeSelection,restoreSelection){var newElement=$createParagraphNode();newElement.setTextFormat(rangeSelection.format);newElement.setTextStyle(rangeSelection.style);var direction=this.getDirection();newElement.setDirection(direction);newElement.setFormat(this.getFormatType());newElement.setStyle(this.getStyle());this.insertAfter(newElement,restoreSelection);return newElement;}},{key:"collapseAtStart",value:function collapseAtStart(){var children=this.getChildren();// If we have an empty (trimmed) first paragraph and try and remove it,
2050
+ // delete the paragraph as long as we have another sibling to go to
2051
+ if(children.length===0||$isTextNode(children[0])&&children[0].getTextContent().trim()===''){var nextSibling=this.getNextSibling();if(nextSibling!==null){this.selectNext();this.remove();return true;}var prevSibling=this.getPreviousSibling();if(prevSibling!==null){this.selectPrevious();this.remove();return true;}}return false;}}],[{key:"getType",value:/** @internal */function getType(){return'paragraph';}},{key:"clone",value:function clone(node){return new ParagraphNode(node.__key);}},{key:"importDOM",value:function importDOM(){return{p:function p(node){return{conversion:$convertParagraphElement,priority:0};}};}},{key:"importJSON",value:function importJSON(serializedNode){return $createParagraphNode().updateFromJSON(serializedNode);}}]);return ParagraphNode;}(ElementNode);function $convertParagraphElement(element){var node=$createParagraphNode();if(element.style){node.setFormat(element.style.textAlign);setNodeIndentFromDOM(element,node);}return{node:node};}function $createParagraphNode(){return $applyNodeReplacement(new ParagraphNode());}function $isParagraphNode(node){return node instanceof ParagraphNode;}// https://github.com/microsoft/TypeScript/issues/3841
2052
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2053
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2054
+ /**
2055
+ * A LexicalNode class or LexicalNodeReplacement configuration
2056
+ */var DEFAULT_SKIP_INITIALIZATION=false;/**
2057
+ * The payload passed to an UpdateListener
2058
+ */ /**
2059
+ * A listener that gets called after the editor is updated
2060
+ */var COMMAND_PRIORITY_EDITOR=0;var COMMAND_PRIORITY_LOW=1;var COMMAND_PRIORITY_NORMAL=2;var COMMAND_PRIORITY_HIGH=3;var COMMAND_PRIORITY_CRITICAL=4;// eslint-disable-next-line @typescript-eslint/no-unused-vars
2061
+ /**
2062
+ * Type helper for extracting the payload type from a command.
2063
+ *
2064
+ * @example
2065
+ * ```ts
2066
+ * const MY_COMMAND = createCommand<SomeType>();
2067
+ *
2068
+ * // ...
2069
+ *
2070
+ * editor.registerCommand(MY_COMMAND, payload => {
2071
+ * // Type of `payload` is inferred here. But lets say we want to extract a function to delegate to
2072
+ * $handleMyCommand(editor, payload);
2073
+ * return true;
2074
+ * });
2075
+ *
2076
+ * function $handleMyCommand(editor: LexicalEditor, payload: CommandPayloadType<typeof MY_COMMAND>) {
2077
+ * // `payload` is of type `SomeType`, extracted from the command.
2078
+ * }
2079
+ * ```
2080
+ */function resetEditor(editor,prevRootElement,nextRootElement,pendingEditorState){var keyNodeMap=editor._keyToDOMMap;keyNodeMap.clear();editor._editorState=createEmptyEditorState();editor._pendingEditorState=pendingEditorState;editor._compositionKey=null;editor._dirtyType=NO_DIRTY_NODES;editor._cloneNotNeeded.clear();editor._dirtyLeaves=new Set();editor._dirtyElements.clear();editor._normalizedNodes=new Set();editor._updateTags=new Set();editor._updates=[];editor._blockCursorElement=null;var observer=editor._observer;if(observer!==null){observer.disconnect();editor._observer=null;}// Remove all the DOM nodes from the root element
2081
+ if(prevRootElement!==null){prevRootElement.textContent='';}if(nextRootElement!==null){nextRootElement.textContent='';keyNodeMap.set('root',nextRootElement);}}function initializeConversionCache(nodes,additionalConversions){var conversionCache=new Map();var handledConversions=new Set();var addConversionsToCache=function addConversionsToCache(map){Object.keys(map).forEach(function(key){var currentCache=conversionCache.get(key);if(currentCache===undefined){currentCache=[];conversionCache.set(key,currentCache);}currentCache.push(map[key]);});};nodes.forEach(function(node){var importDOM=node.klass.importDOM;if(importDOM==null||handledConversions.has(importDOM)){return;}handledConversions.add(importDOM);var map=importDOM.call(node.klass);if(map!==null){addConversionsToCache(map);}});if(additionalConversions){addConversionsToCache(additionalConversions);}return conversionCache;}/** @internal */function getTransformSetFromKlass(klass){var transforms=new Set();var staticTransforms=new Set();var currentKlass=klass;while(currentKlass){var _getStaticNodeConfig3=getStaticNodeConfig(currentKlass),ownNodeConfig=_getStaticNodeConfig3.ownNodeConfig;var staticTransform=currentKlass.transform;if(!staticTransforms.has(staticTransform)){staticTransforms.add(staticTransform);var transform=currentKlass.transform();if(transform){transforms.add(transform);}}if(ownNodeConfig){var $transform=ownNodeConfig.$transform;if($transform){transforms.add($transform);}currentKlass=ownNodeConfig.extends;}else{var parent=Object.getPrototypeOf(currentKlass);currentKlass=parent.prototype instanceof LexicalNode&&parent!==LexicalNode?parent:undefined;}}return transforms;}/**
2082
+ * Creates a new LexicalEditor attached to a single contentEditable (provided in the config). This is
2083
+ * the lowest-level initialization API for a LexicalEditor. If you're using React or another framework,
2084
+ * consider using the appropriate abstractions, such as LexicalComposer
2085
+ * @param editorConfig - the editor configuration.
2086
+ * @returns a LexicalEditor instance
2087
+ */function createEditor(editorConfig){var config=editorConfig||{};var activeEditor=internalGetActiveEditor();var theme=config.theme||{};var parentEditor=editorConfig===undefined?activeEditor:config.parentEditor||null;var disableEvents=config.disableEvents||false;var editorState=createEmptyEditorState();var namespace=config.namespace||(parentEditor!==null?parentEditor._config.namespace:createUID());var initialEditorState=config.editorState;var nodes=[RootNode,TextNode,LineBreakNode,TabNode,ParagraphNode,ArtificialNode__DO_NOT_USE].concat(_toConsumableArray(config.nodes||[]));var onError=config.onError,html=config.html;var isEditable=config.editable!==undefined?config.editable:true;var registeredNodes;if(editorConfig===undefined&&activeEditor!==null){registeredNodes=activeEditor._nodes;}else{registeredNodes=new Map();var _loop3=function _loop3(){var klass=nodes[i];var replace=null;var replaceWithKlass=null;if(typeof klass!=='function'){var options=klass;klass=options.replace;replace=options.with;replaceWithKlass=options.withKlass||null;}// For the side-effect of filling in the static methods
2088
+ void getStaticNodeConfig(klass);// Ensure custom nodes implement required methods and replaceWithKlass is instance of base klass.
2089
+ {// ArtificialNode__DO_NOT_USE can get renamed, so we use the type
2090
+ var name=klass.name;var nodeType=hasOwnStaticMethod(klass,'getType')&&klass.getType();if(replaceWithKlass){if(!(replaceWithKlass.prototype instanceof klass)){formatDevErrorMessage("".concat(replaceWithKlass.name," doesn't extend the ").concat(name));}}else if(replace){console.warn("Override for ".concat(name," specifies 'replace' without 'withKlass'. 'withKlass' will be required in a future version."));}if(name!=='RootNode'&&nodeType!=='root'&&nodeType!=='artificial'&&// This is mostly for the unit test suite which
2091
+ // uses LexicalNode in an otherwise incorrect way
2092
+ // by mocking its static getType
2093
+ klass!==LexicalNode){['getType','clone'].forEach(function(method){if(!hasOwnStaticMethod(klass,method)){console.warn("".concat(name," must implement static \"").concat(method,"\" method"));}});if(!hasOwnStaticMethod(klass,'importDOM')&&hasOwnExportDOM(klass)){console.warn("".concat(name," should implement \"importDOM\" if using a custom \"exportDOM\" method to ensure HTML serialization (important for copy & paste) works as expected"));}if(!hasOwnStaticMethod(klass,'importJSON')){console.warn("".concat(name," should implement \"importJSON\" method to ensure JSON and default HTML serialization works as expected"));}}}var type=klass.getType();var transforms=getTransformSetFromKlass(klass);registeredNodes.set(type,{exportDOM:html&&html.export?html.export.get(klass):undefined,klass:klass,replace:replace,replaceWithKlass:replaceWithKlass,sharedNodeState:createSharedNodeState(nodes[i]),transforms:transforms});};for(var i=0;i<nodes.length;i++){_loop3();}}var editor=new LexicalEditor(editorState,parentEditor,registeredNodes,{disableEvents:disableEvents,namespace:namespace,theme:theme},onError?onError:console.error,initializeConversionCache(registeredNodes,html?html.import:undefined),isEditable,editorConfig);if(initialEditorState!==undefined){editor._pendingEditorState=initialEditorState;editor._dirtyType=FULL_RECONCILE;}registerDefaultCommandHandlers(editor);return editor;}var LexicalEditor=/*#__PURE__*/function(){/** @internal */function LexicalEditor(editorState,parentEditor,nodes,config,onError,htmlConversions,editable,createEditorArgs){_classCallCheck(this,LexicalEditor);/** @internal */_defineProperty(this,"_headless",void 0);/** @internal */_defineProperty(this,"_parentEditor",void 0);/** @internal */_defineProperty(this,"_rootElement",void 0);/** @internal */_defineProperty(this,"_editorState",void 0);/** @internal */_defineProperty(this,"_pendingEditorState",void 0);/** @internal */_defineProperty(this,"_compositionKey",void 0);/** @internal */_defineProperty(this,"_deferred",void 0);/** @internal */_defineProperty(this,"_keyToDOMMap",void 0);/** @internal */_defineProperty(this,"_updates",void 0);/** @internal */_defineProperty(this,"_updating",void 0);/** @internal */_defineProperty(this,"_listeners",void 0);/** @internal */_defineProperty(this,"_commands",void 0);/** @internal */_defineProperty(this,"_nodes",void 0);/** @internal */_defineProperty(this,"_decorators",void 0);/** @internal */_defineProperty(this,"_pendingDecorators",void 0);/** @internal */_defineProperty(this,"_config",void 0);/** @internal */_defineProperty(this,"_dirtyType",void 0);/** @internal */_defineProperty(this,"_cloneNotNeeded",void 0);/** @internal */_defineProperty(this,"_dirtyLeaves",void 0);/** @internal */_defineProperty(this,"_dirtyElements",void 0);/** @internal */_defineProperty(this,"_normalizedNodes",void 0);/** @internal */_defineProperty(this,"_updateTags",void 0);/** @internal */_defineProperty(this,"_observer",void 0);/** @internal */_defineProperty(this,"_key",void 0);/** @internal */_defineProperty(this,"_onError",void 0);/** @internal */_defineProperty(this,"_htmlConversions",void 0);/** @internal */_defineProperty(this,"_window",void 0);/** @internal */_defineProperty(this,"_editable",void 0);/** @internal */_defineProperty(this,"_blockCursorElement",void 0);/** @internal */_defineProperty(this,"_createEditorArgs",void 0);this._createEditorArgs=createEditorArgs;this._parentEditor=parentEditor;// The root element associated with this editor
2094
+ this._rootElement=null;// The current editor state
2095
+ this._editorState=editorState;// Handling of drafts and updates
2096
+ this._pendingEditorState=null;// Used to help co-ordinate selection and events
2097
+ this._compositionKey=null;this._deferred=[];// Used during reconciliation
2098
+ this._keyToDOMMap=new Map();this._updates=[];this._updating=false;// Listeners
2099
+ this._listeners={decorator:new Set(),editable:new Set(),mutation:new Map(),root:new Set(),textcontent:new Set(),update:new Set()};// Commands
2100
+ this._commands=new Map();// Editor configuration for theme/context.
2101
+ this._config=config;// Mapping of types to their nodes
2102
+ this._nodes=nodes;// React node decorators for portals
2103
+ this._decorators={};this._pendingDecorators=null;// Used to optimize reconciliation
2104
+ this._dirtyType=NO_DIRTY_NODES;this._cloneNotNeeded=new Set();this._dirtyLeaves=new Set();this._dirtyElements=new Map();this._normalizedNodes=new Set();this._updateTags=new Set();// Handling of DOM mutations
2105
+ this._observer=null;// Used for identifying owning editors
2106
+ this._key=createUID();this._onError=onError;this._htmlConversions=htmlConversions;this._editable=editable;this._headless=parentEditor!==null&&parentEditor._headless;this._window=null;this._blockCursorElement=null;}/**
2107
+ *
2108
+ * @returns true if the editor is currently in "composition" mode due to receiving input
2109
+ * through an IME, or 3P extension, for example. Returns false otherwise.
2110
+ */_createClass(LexicalEditor,[{key:"isComposing",value:function isComposing(){return this._compositionKey!=null;}/**
2111
+ * Registers a listener for Editor update event. Will trigger the provided callback
2112
+ * each time the editor goes through an update (via {@link LexicalEditor.update}) until the
2113
+ * teardown function is called.
2114
+ *
2115
+ * @returns a teardown function that can be used to cleanup the listener.
2116
+ */},{key:"registerUpdateListener",value:function registerUpdateListener(listener){var listenerSetOrMap=this._listeners.update;listenerSetOrMap.add(listener);return function(){listenerSetOrMap.delete(listener);};}/**
2117
+ * Registers a listener for for when the editor changes between editable and non-editable states.
2118
+ * Will trigger the provided callback each time the editor transitions between these states until the
2119
+ * teardown function is called.
2120
+ *
2121
+ * @returns a teardown function that can be used to cleanup the listener.
2122
+ */},{key:"registerEditableListener",value:function registerEditableListener(listener){var listenerSetOrMap=this._listeners.editable;listenerSetOrMap.add(listener);return function(){listenerSetOrMap.delete(listener);};}/**
2123
+ * Registers a listener for when the editor's decorator object changes. The decorator object contains
2124
+ * all DecoratorNode keys -> their decorated value. This is primarily used with external UI frameworks.
2125
+ *
2126
+ * Will trigger the provided callback each time the editor transitions between these states until the
2127
+ * teardown function is called.
2128
+ *
2129
+ * @returns a teardown function that can be used to cleanup the listener.
2130
+ */},{key:"registerDecoratorListener",value:function registerDecoratorListener(listener){var listenerSetOrMap=this._listeners.decorator;listenerSetOrMap.add(listener);return function(){listenerSetOrMap.delete(listener);};}/**
2131
+ * Registers a listener for when Lexical commits an update to the DOM and the text content of
2132
+ * the editor changes from the previous state of the editor. If the text content is the
2133
+ * same between updates, no notifications to the listeners will happen.
2134
+ *
2135
+ * Will trigger the provided callback each time the editor transitions between these states until the
2136
+ * teardown function is called.
2137
+ *
2138
+ * @returns a teardown function that can be used to cleanup the listener.
2139
+ */},{key:"registerTextContentListener",value:function registerTextContentListener(listener){var listenerSetOrMap=this._listeners.textcontent;listenerSetOrMap.add(listener);return function(){listenerSetOrMap.delete(listener);};}/**
2140
+ * Registers a listener for when the editor's root DOM element (the content editable
2141
+ * Lexical attaches to) changes. This is primarily used to attach event listeners to the root
2142
+ * element. The root listener function is executed directly upon registration and then on
2143
+ * any subsequent update.
2144
+ *
2145
+ * Will trigger the provided callback each time the editor transitions between these states until the
2146
+ * teardown function is called.
2147
+ *
2148
+ * @returns a teardown function that can be used to cleanup the listener.
2149
+ */},{key:"registerRootListener",value:function registerRootListener(listener){var _this6=this;var listenerSetOrMap=this._listeners.root;listener(this._rootElement,null);listenerSetOrMap.add(listener);return function(){listener(null,_this6._rootElement);listenerSetOrMap.delete(listener);};}/**
2150
+ * Registers a listener that will trigger anytime the provided command
2151
+ * is dispatched with {@link LexicalEditor.dispatch}, subject to priority.
2152
+ * Listeners that run at a higher priority can "intercept" commands and
2153
+ * prevent them from propagating to other handlers by returning true.
2154
+ *
2155
+ * Listeners are always invoked in an {@link LexicalEditor.update} and can
2156
+ * call dollar functions.
2157
+ *
2158
+ * Listeners registered at the same priority level will run
2159
+ * deterministically in the order of registration.
2160
+ *
2161
+ * @param command - the command that will trigger the callback.
2162
+ * @param listener - the function that will execute when the command is dispatched.
2163
+ * @param priority - the relative priority of the listener. 0 | 1 | 2 | 3 | 4
2164
+ * (or {@link COMMAND_PRIORITY_EDITOR} |
2165
+ * {@link COMMAND_PRIORITY_LOW} |
2166
+ * {@link COMMAND_PRIORITY_NORMAL} |
2167
+ * {@link COMMAND_PRIORITY_HIGH} |
2168
+ * {@link COMMAND_PRIORITY_CRITICAL})
2169
+ * @returns a teardown function that can be used to cleanup the listener.
2170
+ */},{key:"registerCommand",value:function registerCommand(command,listener,priority){if(priority===undefined){{formatDevErrorMessage("Listener for type \"command\" requires a \"priority\".");}}var commandsMap=this._commands;if(!commandsMap.has(command)){commandsMap.set(command,[new Set(),new Set(),new Set(),new Set(),new Set()]);}var listenersInPriorityOrder=commandsMap.get(command);if(listenersInPriorityOrder===undefined){{formatDevErrorMessage("registerCommand: Command ".concat(String(command)," not found in command map"));}}var listeners=listenersInPriorityOrder[priority];listeners.add(listener);return function(){listeners.delete(listener);if(listenersInPriorityOrder.every(function(listenersSet){return listenersSet.size===0;})){commandsMap.delete(command);}};}/**
2171
+ * Registers a listener that will run when a Lexical node of the provided class is
2172
+ * mutated. The listener will receive a list of nodes along with the type of mutation
2173
+ * that was performed on each: created, destroyed, or updated.
2174
+ *
2175
+ * One common use case for this is to attach DOM event listeners to the underlying DOM nodes as Lexical nodes are created.
2176
+ * {@link LexicalEditor.getElementByKey} can be used for this.
2177
+ *
2178
+ * If any existing nodes are in the DOM, and skipInitialization is not true, the listener
2179
+ * will be called immediately with an updateTag of 'registerMutationListener' where all
2180
+ * nodes have the 'created' NodeMutation. This can be controlled with the skipInitialization option
2181
+ * (whose default was previously true for backwards compatibility with &lt;=0.16.1 but has been changed to false as of 0.21.0).
2182
+ *
2183
+ * @param klass - The class of the node that you want to listen to mutations on.
2184
+ * @param listener - The logic you want to run when the node is mutated.
2185
+ * @param options - see {@link MutationListenerOptions}
2186
+ * @returns a teardown function that can be used to cleanup the listener.
2187
+ */},{key:"registerMutationListener",value:function registerMutationListener(klass,listener,options){var klassToMutate=this.resolveRegisteredNodeAfterReplacements(this.getRegisteredNode(klass)).klass;var mutations=this._listeners.mutation;var klassSet=mutations.get(listener);if(klassSet===undefined){klassSet=new Set();mutations.set(listener,klassSet);}klassSet.add(klassToMutate);var skipInitialization=options&&options.skipInitialization;if(!(skipInitialization===undefined?DEFAULT_SKIP_INITIALIZATION:skipInitialization)){this.initializeMutationListener(listener,klassToMutate);}return function(){klassSet.delete(klassToMutate);if(klassSet.size===0){mutations.delete(listener);}};}/** @internal */},{key:"getRegisteredNode",value:function getRegisteredNode(klass){var registeredNode=this._nodes.get(klass.getType());if(registeredNode===undefined){{formatDevErrorMessage("Node ".concat(klass.name," has not been registered. Ensure node has been passed to createEditor."));}}return registeredNode;}/** @internal */},{key:"resolveRegisteredNodeAfterReplacements",value:function resolveRegisteredNodeAfterReplacements(registeredNode){while(registeredNode.replaceWithKlass){registeredNode=this.getRegisteredNode(registeredNode.replaceWithKlass);}return registeredNode;}/** @internal */},{key:"initializeMutationListener",value:function initializeMutationListener(listener,klass){var prevEditorState=this._editorState;var nodeMap=getCachedTypeToNodeMap(prevEditorState).get(klass.getType());if(!nodeMap){return;}var nodeMutationMap=new Map();var _iterator28=_createForOfIteratorHelper(nodeMap.keys()),_step28;try{for(_iterator28.s();!(_step28=_iterator28.n()).done;){var k=_step28.value;nodeMutationMap.set(k,'created');}}catch(err){_iterator28.e(err);}finally{_iterator28.f();}if(nodeMutationMap.size>0){listener(nodeMutationMap,{dirtyLeaves:new Set(),prevEditorState:prevEditorState,updateTags:new Set(['registerMutationListener'])});}}/** @internal */},{key:"registerNodeTransformToKlass",value:function registerNodeTransformToKlass(klass,listener){var registeredNode=this.getRegisteredNode(klass);registeredNode.transforms.add(listener);return registeredNode;}/**
2188
+ * Registers a listener that will run when a Lexical node of the provided class is
2189
+ * marked dirty during an update. The listener will continue to run as long as the node
2190
+ * is marked dirty. There are no guarantees around the order of transform execution!
2191
+ *
2192
+ * Watch out for infinite loops. See [Node Transforms](https://lexical.dev/docs/concepts/transforms)
2193
+ * @param klass - The class of the node that you want to run transforms on.
2194
+ * @param listener - The logic you want to run when the node is updated.
2195
+ * @returns a teardown function that can be used to cleanup the listener.
2196
+ */},{key:"registerNodeTransform",value:function registerNodeTransform(klass,listener){var registeredNode=this.registerNodeTransformToKlass(klass,listener);var registeredNodes=[registeredNode];var replaceWithKlass=registeredNode.replaceWithKlass;if(replaceWithKlass!=null){var registeredReplaceWithNode=this.registerNodeTransformToKlass(replaceWithKlass,listener);registeredNodes.push(registeredReplaceWithNode);}markNodesWithTypesAsDirty(this,registeredNodes.map(function(node){return node.klass.getType();}));return function(){registeredNodes.forEach(function(node){return node.transforms.delete(listener);});};}/**
2197
+ * Used to assert that a certain node is registered, usually by plugins to ensure nodes that they
2198
+ * depend on have been registered.
2199
+ * @returns True if the editor has registered the provided node type, false otherwise.
2200
+ */},{key:"hasNode",value:function hasNode(node){return this._nodes.has(node.getType());}/**
2201
+ * Used to assert that certain nodes are registered, usually by plugins to ensure nodes that they
2202
+ * depend on have been registered.
2203
+ * @returns True if the editor has registered all of the provided node types, false otherwise.
2204
+ */},{key:"hasNodes",value:function hasNodes(nodes){return nodes.every(this.hasNode.bind(this));}/**
2205
+ * Dispatches a command of the specified type with the specified payload.
2206
+ * This triggers all command listeners (set by {@link LexicalEditor.registerCommand})
2207
+ * for this type, passing them the provided payload. The command listeners
2208
+ * will be triggered in an implicit {@link LexicalEditor.update}, unless
2209
+ * this was invoked from inside an update in which case that update context
2210
+ * will be re-used (as if this was a dollar function itself).
2211
+ * @param type - the type of command listeners to trigger.
2212
+ * @param payload - the data to pass as an argument to the command listeners.
2213
+ */},{key:"dispatchCommand",value:function dispatchCommand(type,payload){return _dispatchCommand(this,type,payload);}/**
2214
+ * Gets a map of all decorators in the editor.
2215
+ * @returns A mapping of call decorator keys to their decorated content
2216
+ */},{key:"getDecorators",value:function getDecorators(){return this._decorators;}/**
2217
+ *
2218
+ * @returns the current root element of the editor. If you want to register
2219
+ * an event listener, do it via {@link LexicalEditor.registerRootListener}, since
2220
+ * this reference may not be stable.
2221
+ */},{key:"getRootElement",value:function getRootElement(){return this._rootElement;}/**
2222
+ * Gets the key of the editor
2223
+ * @returns The editor key
2224
+ */},{key:"getKey",value:function getKey(){return this._key;}/**
2225
+ * Imperatively set the root contenteditable element that Lexical listens
2226
+ * for events on.
2227
+ */},{key:"setRootElement",value:function setRootElement(nextRootElement){var prevRootElement=this._rootElement;if(nextRootElement!==prevRootElement){var classNames=getCachedClassNameArray(this._config.theme,'root');var pendingEditorState=this._pendingEditorState||this._editorState;this._rootElement=nextRootElement;resetEditor(this,prevRootElement,nextRootElement,pendingEditorState);if(prevRootElement!==null){// TODO: remove this flag once we no longer use UEv2 internally
2228
+ if(!this._config.disableEvents){removeRootElementEvents(prevRootElement);}if(classNames!=null){var _prevRootElement$clas;(_prevRootElement$clas=prevRootElement.classList).remove.apply(_prevRootElement$clas,_toConsumableArray(classNames));}}if(nextRootElement!==null){var windowObj=getDefaultView(nextRootElement);var style=nextRootElement.style;style.userSelect='text';style.whiteSpace='pre-wrap';style.wordBreak='break-word';nextRootElement.setAttribute('data-lexical-editor','true');this._window=windowObj;this._dirtyType=FULL_RECONCILE;initMutationObserver(this);this._updateTags.add(HISTORY_MERGE_TAG);$commitPendingUpdates(this);// TODO: remove this flag once we no longer use UEv2 internally
2229
+ if(!this._config.disableEvents){addRootElementEvents(nextRootElement,this);}if(classNames!=null){var _nextRootElement$clas;(_nextRootElement$clas=nextRootElement.classList).add.apply(_nextRootElement$clas,_toConsumableArray(classNames));}{var nextRootElementParent=nextRootElement.parentElement;if(nextRootElementParent!=null&&['flex','inline-flex'].includes(getComputedStyle(nextRootElementParent).display)){console.warn("When using \"display: flex\" or \"display: inline-flex\" on an element containing content editable, Chrome may have unwanted focusing behavior when clicking outside of it. Consider wrapping the content editable within a non-flex element.");}}}else{// When the content editable is unmounted we will still trigger a
2230
+ // reconciliation so that any pending updates are flushed,
2231
+ // to match the previous state change when
2232
+ // `_editorState = pendingEditorState` was used, but by
2233
+ // using a commit we preserve the readOnly invariant
2234
+ // for editor.getEditorState().
2235
+ this._window=null;this._updateTags.add(HISTORY_MERGE_TAG);$commitPendingUpdates(this);}triggerListeners('root',this,false,nextRootElement,prevRootElement);}}/**
2236
+ * Gets the underlying HTMLElement associated with the LexicalNode for the given key.
2237
+ * @returns the HTMLElement rendered by the LexicalNode associated with the key.
2238
+ * @param key - the key of the LexicalNode.
2239
+ */},{key:"getElementByKey",value:function getElementByKey(key){return this._keyToDOMMap.get(key)||null;}/**
2240
+ * Gets the active editor state.
2241
+ * @returns The editor state
2242
+ */},{key:"getEditorState",value:function getEditorState(){return this._editorState;}/**
2243
+ * Imperatively set the EditorState. Triggers reconciliation like an update.
2244
+ * @param editorState - the state to set the editor
2245
+ * @param options - options for the update.
2246
+ */},{key:"setEditorState",value:function setEditorState(editorState,options){if(editorState.isEmpty()){{formatDevErrorMessage("setEditorState: the editor state is empty. Ensure the editor state's root node never becomes empty.");}}// Ensure that we have a writable EditorState so that transforms can run
2247
+ // during a historic operation
2248
+ var writableEditorState=editorState;if(writableEditorState._readOnly){writableEditorState=cloneEditorState(editorState);writableEditorState._selection=editorState._selection?editorState._selection.clone():null;}flushRootMutations(this);var pendingEditorState=this._pendingEditorState;var tags=this._updateTags;var tag=options!==undefined?options.tag:null;if(pendingEditorState!==null&&!pendingEditorState.isEmpty()){if(tag!=null){tags.add(tag);}$commitPendingUpdates(this);}this._pendingEditorState=writableEditorState;this._dirtyType=FULL_RECONCILE;this._dirtyElements.set('root',false);this._compositionKey=null;if(tag!=null){tags.add(tag);}// Only commit pending updates if not already in an editor.update
2249
+ // (e.g. dispatchCommand) otherwise this will cause a second commit
2250
+ // with an already read-only state and selection
2251
+ if(!this._updating){$commitPendingUpdates(this);}}/**
2252
+ * Parses a SerializedEditorState (usually produced by {@link EditorState.toJSON}) and returns
2253
+ * and EditorState object that can be, for example, passed to {@link LexicalEditor.setEditorState}. Typically,
2254
+ * deserialization from JSON stored in a database uses this method.
2255
+ * @param maybeStringifiedEditorState
2256
+ * @param updateFn
2257
+ * @returns
2258
+ */},{key:"parseEditorState",value:function parseEditorState(maybeStringifiedEditorState,updateFn){var serializedEditorState=typeof maybeStringifiedEditorState==='string'?JSON.parse(maybeStringifiedEditorState):maybeStringifiedEditorState;return _parseEditorState(serializedEditorState,this,updateFn);}/**
2259
+ * Executes a read of the editor's state, with the
2260
+ * editor context available (useful for exporting and read-only DOM
2261
+ * operations). Much like update, but prevents any mutation of the
2262
+ * editor's state. Any pending updates will be flushed immediately before
2263
+ * the read.
2264
+ * @param callbackFn - A function that has access to read-only editor state.
2265
+ */},{key:"read",value:function read(callbackFn){$commitPendingUpdates(this);return this.getEditorState().read(callbackFn,{editor:this});}/**
2266
+ * Executes an update to the editor state. The updateFn callback is the ONLY place
2267
+ * where Lexical editor state can be safely mutated.
2268
+ * @param updateFn - A function that has access to writable editor state.
2269
+ * @param options - A bag of options to control the behavior of the update.
2270
+ */},{key:"update",value:function update(updateFn,options){updateEditor(this,updateFn,options);}/**
2271
+ * Focuses the editor by marking the existing selection as dirty, or by
2272
+ * creating a new selection at `defaultSelection` if one does not already
2273
+ * exist. If you want to force a specific selection, you should call
2274
+ * `root.selectStart()` or `root.selectEnd()` in an update.
2275
+ *
2276
+ * @param callbackFn - A function to run after the editor is focused.
2277
+ * @param options - A bag of options
2278
+ */},{key:"focus",value:function focus(callbackFn){var options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var rootElement=this._rootElement;if(rootElement!==null){// This ensures that iOS does not trigger caps lock upon focus
2279
+ rootElement.setAttribute('autocapitalize','off');updateEditorSync(this,function(){var selection=$getSelection();var root=$getRoot();if(selection!==null){// Marking the selection dirty will force the selection back to it
2280
+ if(!selection.dirty){$setSelection(selection.clone());}}else if(root.getChildrenSize()!==0){if(options.defaultSelection==='rootStart'){root.selectStart();}else{root.selectEnd();}}$addUpdateTag(FOCUS_TAG);$onUpdate(function(){rootElement.removeAttribute('autocapitalize');if(callbackFn){callbackFn();}});});// In the case where onUpdate doesn't fire (due to the focus update not
2281
+ // occurring).
2282
+ if(this._pendingEditorState===null){rootElement.removeAttribute('autocapitalize');}}}/**
2283
+ * Removes focus from the editor.
2284
+ */},{key:"blur",value:function blur(){var rootElement=this._rootElement;if(rootElement!==null){rootElement.blur();}var domSelection=getDOMSelection(this._window);if(domSelection!==null){domSelection.removeAllRanges();}}/**
2285
+ * Returns true if the editor is editable, false otherwise.
2286
+ * @returns True if the editor is editable, false otherwise.
2287
+ */},{key:"isEditable",value:function isEditable(){return this._editable;}/**
2288
+ * Sets the editable property of the editor. When false, the
2289
+ * editor will not listen for user events on the underling contenteditable.
2290
+ * @param editable - the value to set the editable mode to.
2291
+ */},{key:"setEditable",value:function setEditable(editable){if(this._editable!==editable){this._editable=editable;triggerListeners('editable',this,true,editable);}}/**
2292
+ * Returns a JSON-serializable javascript object NOT a JSON string.
2293
+ * You still must call JSON.stringify (or something else) to turn the
2294
+ * state into a string you can transfer over the wire and store in a database.
2295
+ *
2296
+ * See {@link LexicalNode.exportJSON}
2297
+ *
2298
+ * @returns A JSON-serializable javascript object
2299
+ */},{key:"toJSON",value:function toJSON(){return{editorState:this._editorState.toJSON()};}}]);return LexicalEditor;}();/** @internal */ /** The version with build identifiers for this editor (since 0.17.1) */_defineProperty(LexicalEditor,"version",void 0);LexicalEditor.version='0.39.0+dev.cjs';var pendingNodeToClone=null;function setPendingNodeToClone(pendingNode){pendingNodeToClone=pendingNode;}function getPendingNodeToClone(){var node=pendingNodeToClone;pendingNodeToClone=null;return node;}var keyCounter=1;function resetRandomKey(){keyCounter=1;}function generateRandomKey(){return''+keyCounter++;}/**
2300
+ * @internal
2301
+ */function getRegisteredNodeOrThrow(editor,nodeType){var registeredNode=getRegisteredNode(editor,nodeType);if(registeredNode===undefined){{formatDevErrorMessage("registeredNode: Type ".concat(nodeType," not found"));}}return registeredNode;}/**
2302
+ * @internal
2303
+ */function getRegisteredNode(editor,nodeType){return editor._nodes.get(nodeType);}/** @internal */var scheduleMicroTask=typeof queueMicrotask==='function'?queueMicrotask:function(fn){// No window prefix intended (#1400)
2304
+ Promise.resolve().then(fn);};function $isSelectionCapturedInDecorator(node){return $isDecoratorNode($getNearestNodeFromDOMNode(node));}function isSelectionCapturedInDecoratorInput(anchorDOM){var activeElement=document.activeElement;if(!isHTMLElement(activeElement)){return false;}var nodeName=activeElement.nodeName;return $isDecoratorNode($getNearestNodeFromDOMNode(anchorDOM))&&(nodeName==='INPUT'||nodeName==='TEXTAREA'||activeElement.contentEditable==='true'&&getEditorPropertyFromDOMNode(activeElement)==null);}function isSelectionWithinEditor(editor,anchorDOM,focusDOM){var rootElement=editor.getRootElement();try{return rootElement!==null&&rootElement.contains(anchorDOM)&&rootElement.contains(focusDOM)&&// Ignore if selection is within nested editor
2305
+ anchorDOM!==null&&!isSelectionCapturedInDecoratorInput(anchorDOM)&&getNearestEditorFromDOMNode(anchorDOM)===editor;}catch(_error){return false;}}/**
2306
+ * @returns true if the given argument is a LexicalEditor instance from this build of Lexical
2307
+ */function isLexicalEditor(editor){// Check instanceof to prevent issues with multiple embedded Lexical installations
2308
+ return editor instanceof LexicalEditor;}function getNearestEditorFromDOMNode(node){var currentNode=node;while(currentNode!=null){var editor=getEditorPropertyFromDOMNode(currentNode);if(isLexicalEditor(editor)){return editor;}currentNode=getParentElement(currentNode);}return null;}/** @internal */function getEditorPropertyFromDOMNode(node){// @ts-expect-error: internal field
2309
+ return node?node.__lexicalEditor:null;}function getTextDirection(text){if(RTL_REGEX.test(text)){return'rtl';}if(LTR_REGEX.test(text)){return'ltr';}return null;}/**
2310
+ * Return true if the TextNode is a TabNode or is in token mode.
2311
+ */function $isTokenOrTab(node){return $isTabNode(node)||node.isToken();}/**
2312
+ * Return true if the TextNode is a TabNode, or is in token or segmented mode.
2313
+ */function $isTokenOrSegmented(node){return $isTokenOrTab(node)||node.isSegmented();}/**
2314
+ * @param node - The element being tested
2315
+ * @returns Returns true if node is an DOM Text node, false otherwise.
2316
+ */function isDOMTextNode(node){return isDOMNode(node)&&node.nodeType===DOM_TEXT_TYPE;}/**
2317
+ * @param node - The element being tested
2318
+ * @returns Returns true if node is an DOM Document node, false otherwise.
2319
+ */function isDOMDocumentNode(node){return isDOMNode(node)&&node.nodeType===DOM_DOCUMENT_TYPE;}function getDOMTextNode(element){var node=element;while(node!=null){if(isDOMTextNode(node)){return node;}node=node.firstChild;}return null;}function toggleTextFormatType(format,type,alignWithFormat){var activeFormat=TEXT_TYPE_TO_FORMAT[type];if(alignWithFormat!==null&&(format&activeFormat)===(alignWithFormat&activeFormat)){return format;}var newFormat=format^activeFormat;if(type==='subscript'){newFormat&=~TEXT_TYPE_TO_FORMAT.superscript;}else if(type==='superscript'){newFormat&=~TEXT_TYPE_TO_FORMAT.subscript;}else if(type==='lowercase'){newFormat&=~TEXT_TYPE_TO_FORMAT.uppercase;newFormat&=~TEXT_TYPE_TO_FORMAT.capitalize;}else if(type==='uppercase'){newFormat&=~TEXT_TYPE_TO_FORMAT.lowercase;newFormat&=~TEXT_TYPE_TO_FORMAT.capitalize;}else if(type==='capitalize'){newFormat&=~TEXT_TYPE_TO_FORMAT.lowercase;newFormat&=~TEXT_TYPE_TO_FORMAT.uppercase;}return newFormat;}function $isLeafNode(node){return $isTextNode(node)||$isLineBreakNode(node)||$isDecoratorNode(node);}function $setNodeKey(node,existingKey){var pendingNode=getPendingNodeToClone();existingKey=existingKey||pendingNode&&pendingNode.__key;if(existingKey!=null){{errorOnNodeKeyConstructorMismatch(node,existingKey,pendingNode);}node.__key=existingKey;return;}errorOnReadOnly();errorOnInfiniteTransforms();var editor=getActiveEditor();var editorState=getActiveEditorState();var key=generateRandomKey();editorState._nodeMap.set(key,node);// TODO Split this function into leaf/element
2320
+ if($isElementNode(node)){editor._dirtyElements.set(key,true);}else{editor._dirtyLeaves.add(key);}editor._cloneNotNeeded.add(key);editor._dirtyType=HAS_DIRTY_NODES;node.__key=key;}function errorOnNodeKeyConstructorMismatch(node,existingKey,pendingNode){var editorState=internalGetActiveEditorState();if(!editorState){// tests expect to be able to do this kind of clone without an active editor state
2321
+ return;}var existingNode=editorState._nodeMap.get(existingKey);if(pendingNode){if(!(existingKey===pendingNode.__key)){formatDevErrorMessage("Lexical node with constructor ".concat(node.constructor.name," (type ").concat(node.getType(),") has an incorrect clone implementation, got ").concat(String(existingKey)," for nodeKey when expecting ").concat(pendingNode.__key));}}if(existingNode&&existingNode.constructor!==node.constructor){// Lifted condition to if statement because the inverted logic is a bit confusing
2322
+ if(node.constructor.name!==existingNode.constructor.name){{formatDevErrorMessage("Lexical node with constructor ".concat(node.constructor.name," attempted to re-use key from node in active editor state with constructor ").concat(existingNode.constructor.name,". Keys must not be re-used when the type is changed."));}}else{{formatDevErrorMessage("Lexical node with constructor ".concat(node.constructor.name," attempted to re-use key from node in active editor state with different constructor with the same name (possibly due to invalid Hot Module Replacement). Keys must not be re-used when the type is changed."));}}}}function internalMarkParentElementsAsDirty(parentKey,nodeMap,dirtyElements){var nextParentKey=parentKey;while(nextParentKey!==null){if(dirtyElements.has(nextParentKey)){return;}var node=nodeMap.get(nextParentKey);if(node===undefined){break;}dirtyElements.set(nextParentKey,false);nextParentKey=node.__parent;}}// TODO #6031 this function or their callers have to adjust selection (i.e. insertBefore)
2323
+ /**
2324
+ * Removes a node from its parent, updating all necessary pointers and links.
2325
+ * @internal
2326
+ *
2327
+ * This function is for internal use of the library.
2328
+ * Please do not use it as it may change in the future.
2329
+ */function removeFromParent(node){var oldParent=node.getParent();if(oldParent!==null){var writableNode=node.getWritable();var writableParent=oldParent.getWritable();var prevSibling=node.getPreviousSibling();var nextSibling=node.getNextSibling();// Store sibling keys
2330
+ var nextSiblingKey=nextSibling!==null?nextSibling.__key:null;var prevSiblingKey=prevSibling!==null?prevSibling.__key:null;// Get writable siblings once
2331
+ var writablePrevSibling=prevSibling!==null?prevSibling.getWritable():null;var writableNextSibling=nextSibling!==null?nextSibling.getWritable():null;// Update parent's first/last pointers
2332
+ if(prevSibling===null){writableParent.__first=nextSiblingKey;}if(nextSibling===null){writableParent.__last=prevSiblingKey;}// Update sibling links
2333
+ if(writablePrevSibling!==null){writablePrevSibling.__next=nextSiblingKey;}if(writableNextSibling!==null){writableNextSibling.__prev=prevSiblingKey;}// Clear node's links
2334
+ writableNode.__prev=null;writableNode.__next=null;writableNode.__parent=null;// Update parent size
2335
+ writableParent.__size--;}}// Never use this function directly! It will break
2336
+ // the cloning heuristic. Instead use node.getWritable().
2337
+ function internalMarkNodeAsDirty(node){errorOnInfiniteTransforms();if(!!$isEphemeral(node)){formatDevErrorMessage("internalMarkNodeAsDirty: Ephemeral nodes must not be marked as dirty (key ".concat(node.__key," type ").concat(node.__type,")"));}var latest=node.getLatest();var parent=latest.__parent;var editorState=getActiveEditorState();var editor=getActiveEditor();var nodeMap=editorState._nodeMap;var dirtyElements=editor._dirtyElements;if(parent!==null){internalMarkParentElementsAsDirty(parent,nodeMap,dirtyElements);}var key=latest.__key;editor._dirtyType=HAS_DIRTY_NODES;if($isElementNode(node)){dirtyElements.set(key,true);}else{editor._dirtyLeaves.add(key);}}function internalMarkSiblingsAsDirty(node){var previousNode=node.getPreviousSibling();var nextNode=node.getNextSibling();if(previousNode!==null){internalMarkNodeAsDirty(previousNode);}if(nextNode!==null){internalMarkNodeAsDirty(nextNode);}}function $setCompositionKey(compositionKey){errorOnReadOnly();var editor=getActiveEditor();var previousCompositionKey=editor._compositionKey;if(compositionKey!==previousCompositionKey){editor._compositionKey=compositionKey;if(previousCompositionKey!==null){var node=$getNodeByKey(previousCompositionKey);if(node!==null){node.getWritable();}}if(compositionKey!==null){var _node4=$getNodeByKey(compositionKey);if(_node4!==null){_node4.getWritable();}}}}function $getCompositionKey(){if(isCurrentlyReadOnlyMode()){return null;}var editor=getActiveEditor();return editor._compositionKey;}function $getNodeByKey(key,_editorState){var editorState=_editorState||getActiveEditorState();var node=editorState._nodeMap.get(key);if(node===undefined){return null;}return node;}function $getNodeFromDOMNode(dom,editorState){var editor=getActiveEditor();var key=getNodeKeyFromDOMNode(dom,editor);if(key!==undefined){return $getNodeByKey(key,editorState);}return null;}function setNodeKeyOnDOMNode(dom,editor,key){var prop="__lexicalKey_".concat(editor._key);dom[prop]=key;}function getNodeKeyFromDOMNode(dom,editor){var prop="__lexicalKey_".concat(editor._key);return dom[prop];}function $getNearestNodeFromDOMNode(startingDOM,editorState){var dom=startingDOM;while(dom!=null){var node=$getNodeFromDOMNode(dom,editorState);if(node!==null){return node;}dom=getParentElement(dom);}return null;}function cloneDecorators(editor){var currentDecorators=editor._decorators;var pendingDecorators=Object.assign({},currentDecorators);editor._pendingDecorators=pendingDecorators;return pendingDecorators;}function getEditorStateTextContent(editorState){return editorState.read(function(){return $getRoot().getTextContent();});}function markNodesWithTypesAsDirty(editor,types){// We only need to mark nodes dirty if they were in the previous state.
2338
+ // If they aren't, then they are by definition dirty already.
2339
+ var cachedMap=getCachedTypeToNodeMap(editor.getEditorState());var dirtyNodeMaps=[];var _iterator29=_createForOfIteratorHelper(types),_step29;try{for(_iterator29.s();!(_step29=_iterator29.n()).done;){var type=_step29.value;var nodeMap=cachedMap.get(type);if(nodeMap){// By construction these are non-empty
2340
+ dirtyNodeMaps.push(nodeMap);}}// Nothing to mark dirty, no update necessary
2341
+ }catch(err){_iterator29.e(err);}finally{_iterator29.f();}if(dirtyNodeMaps.length===0){return;}editor.update(function(){for(var _i10=0,_dirtyNodeMaps=dirtyNodeMaps;_i10<_dirtyNodeMaps.length;_i10++){var nodeMap=_dirtyNodeMaps[_i10];var _iterator30=_createForOfIteratorHelper(nodeMap.keys()),_step30;try{for(_iterator30.s();!(_step30=_iterator30.n()).done;){var nodeKey=_step30.value;// We are only concerned with nodes that are still in the latest NodeMap,
2342
+ // if they no longer exist then markDirty would raise an exception
2343
+ var latest=$getNodeByKey(nodeKey);if(latest){latest.markDirty();}}}catch(err){_iterator30.e(err);}finally{_iterator30.f();}}},editor._pendingEditorState===null?{tag:HISTORY_MERGE_TAG}:undefined);}function $getRoot(){return internalGetRoot(getActiveEditorState());}function internalGetRoot(editorState){return editorState._nodeMap.get('root');}function $setSelection(selection){errorOnReadOnly();var editorState=getActiveEditorState();if(selection!==null){{if(Object.isFrozen(selection)){{formatDevErrorMessage("$setSelection called on frozen selection object. Ensure selection is cloned before passing in.");}}}selection.dirty=true;selection.setCachedNodes(null);}editorState._selection=selection;}function $flushMutations(){errorOnReadOnly();var editor=getActiveEditor();flushRootMutations(editor);}function $getNodeFromDOM(dom){var editor=getActiveEditor();var nodeKey=getNodeKeyFromDOMTree(dom,editor);if(nodeKey===null){var rootElement=editor.getRootElement();if(dom===rootElement){return $getNodeByKey('root');}return null;}return $getNodeByKey(nodeKey);}function getNodeKeyFromDOMTree(// Note that node here refers to a DOM Node, not an Lexical Node
2344
+ dom,editor){var node=dom;while(node!=null){var key=getNodeKeyFromDOMNode(node,editor);if(key!==undefined){return key;}node=getParentElement(node);}return null;}/**
2345
+ * Return true if `str` contains any valid surrogate pair.
2346
+ *
2347
+ * See also $updateCaretSelectionForUnicodeCharacter for
2348
+ * a discussion on when and why this is useful.
2349
+ */function doesContainSurrogatePair(str){return /[\uD800-\uDBFF][\uDC00-\uDFFF]/g.test(str);}function getEditorsToPropagate(editor){var editorsToPropagate=[];var currentEditor=editor;while(currentEditor!==null){editorsToPropagate.push(currentEditor);currentEditor=currentEditor._parentEditor;}return editorsToPropagate;}function createUID(){return Math.random().toString(36).replace(/[^a-z]+/g,'').substring(0,5);}function getAnchorTextFromDOM(anchorNode){return isDOMTextNode(anchorNode)?anchorNode.nodeValue:null;}function $updateSelectedTextFromDOM(isCompositionEnd,editor,data){// Update the text content with the latest composition text
2350
+ var domSelection=getDOMSelection(getWindow(editor));if(domSelection===null){return;}var anchorNode=domSelection.anchorNode;var anchorOffset=domSelection.anchorOffset,focusOffset=domSelection.focusOffset;if(anchorNode!==null){var textContent=getAnchorTextFromDOM(anchorNode);var node=$getNearestNodeFromDOMNode(anchorNode);if(textContent!==null&&$isTextNode(node)){// Data is intentionally truthy, as we check for boolean, null and empty string.
2351
+ if(textContent===COMPOSITION_SUFFIX&&data){var offset=data.length;textContent=data;anchorOffset=offset;focusOffset=offset;}if(textContent!==null){$updateTextNodeFromDOMContent(node,textContent,anchorOffset,focusOffset,isCompositionEnd);}}}}function $updateTextNodeFromDOMContent(textNode,textContent,anchorOffset,focusOffset,compositionEnd){var node=textNode;if(node.isAttached()&&(compositionEnd||!node.isDirty())){var isComposing=node.isComposing();var normalizedTextContent=textContent;if((isComposing||compositionEnd)&&textContent[textContent.length-1]===COMPOSITION_SUFFIX){normalizedTextContent=textContent.slice(0,-1);}var prevTextContent=node.getTextContent();if(compositionEnd||normalizedTextContent!==prevTextContent){if(normalizedTextContent===''){$setCompositionKey(null);if(!IS_SAFARI&&!IS_IOS&&!IS_APPLE_WEBKIT){// For composition (mainly Android), we have to remove the node on a later update
2352
+ var editor=getActiveEditor();setTimeout(function(){editor.update(function(){if(node.isAttached()){node.remove();}});},20);}else{node.remove();}return;}var parent=node.getParent();var prevSelection=$getPreviousSelection();var prevTextContentSize=node.getTextContentSize();var compositionKey=$getCompositionKey();var nodeKey=node.getKey();if(node.isToken()||compositionKey!==null&&nodeKey===compositionKey&&!isComposing||// Check if character was added at the start or boundaries when not insertable, and we need
2353
+ // to clear this input from occurring as that action wasn't permitted.
2354
+ $isRangeSelection(prevSelection)&&(parent!==null&&!parent.canInsertTextBefore()&&prevSelection.anchor.offset===0||prevSelection.anchor.key===textNode.__key&&prevSelection.anchor.offset===0&&!node.canInsertTextBefore()&&!isComposing||prevSelection.focus.key===textNode.__key&&prevSelection.focus.offset===prevTextContentSize&&!node.canInsertTextAfter()&&!isComposing)){node.markDirty();return;}var selection=$getSelection();if(!$isRangeSelection(selection)||anchorOffset===null||focusOffset===null){$setTextContentWithSelection(node,normalizedTextContent,selection);return;}selection.setTextNodeRange(node,anchorOffset,node,focusOffset);if(node.isSegmented()){var originalTextContent=node.getTextContent();var replacement=$createTextNode(originalTextContent);node.replace(replacement);node=replacement;}$setTextContentWithSelection(node,normalizedTextContent,selection);}}}function $setTextContentWithSelection(node,textContent,selection){node.setTextContent(textContent);if($isRangeSelection(selection)){var key=node.getKey();for(var _i11=0,_arr=['anchor','focus'];_i11<_arr.length;_i11++){var k=_arr[_i11];var pt=selection[k];if(pt.type==='text'&&pt.key===key){pt.offset=$getTextNodeOffset(node,pt.offset,'clamp');}}}}function $previousSiblingDoesNotAcceptText(node){var previousSibling=node.getPreviousSibling();return($isTextNode(previousSibling)||$isElementNode(previousSibling)&&previousSibling.isInline())&&!previousSibling.canInsertTextAfter();}// This function is connected to $shouldPreventDefaultAndInsertText and determines whether the
2355
+ // TextNode boundaries are writable or we should use the previous/next sibling instead. For example,
2356
+ // in the case of a LinkNode, boundaries are not writable.
2357
+ function $shouldInsertTextAfterOrBeforeTextNode(selection,node){if(node.isSegmented()){return true;}if(!selection.isCollapsed()){return false;}var offset=selection.anchor.offset;var parent=node.getParentOrThrow();var isToken=$isTokenOrTab(node);if(offset===0){return!node.canInsertTextBefore()||!parent.canInsertTextBefore()&&!node.isComposing()||isToken||$previousSiblingDoesNotAcceptText(node);}else if(offset===node.getTextContentSize()){return!node.canInsertTextAfter()||!parent.canInsertTextAfter()&&!node.isComposing()||isToken;}else{return false;}}/**
2358
+ * A KeyboardEvent or structurally similar object with a string `key` as well
2359
+ * as `altKey`, `ctrlKey`, `metaKey`, and `shiftKey` boolean properties.
2360
+ */ /**
2361
+ * A record of keyboard modifiers that must be enabled.
2362
+ * If the value is `'any'` then the modifier key's state is ignored.
2363
+ * If the value is `true` then the modifier key must be pressed.
2364
+ * If the value is `false` or the property is omitted then the modifier key must
2365
+ * not be pressed.
2366
+ */function matchModifier(event,mask,prop){var expected=mask[prop]||false;return expected==='any'||expected===event[prop];}/**
2367
+ * Match a KeyboardEvent with its expected modifier state
2368
+ *
2369
+ * @param event A KeyboardEvent, or structurally similar object
2370
+ * @param mask An object specifying the expected state of the modifiers
2371
+ * @returns true if the event matches
2372
+ */function isModifierMatch(event,mask){return matchModifier(event,mask,'altKey')&&matchModifier(event,mask,'ctrlKey')&&matchModifier(event,mask,'shiftKey')&&matchModifier(event,mask,'metaKey');}/**
2373
+ * Match a KeyboardEvent with its expected state
2374
+ *
2375
+ * @param event A KeyboardEvent, or structurally similar object
2376
+ * @param expectedKey The string to compare with event.key (case insensitive)
2377
+ * @param mask An object specifying the expected state of the modifiers
2378
+ * @returns true if the event matches
2379
+ */function isExactShortcutMatch(event,expectedKey,mask){return isModifierMatch(event,mask)&&event.key.toLowerCase()===expectedKey.toLowerCase();}var CONTROL_OR_META={ctrlKey:!IS_APPLE,metaKey:IS_APPLE};var CONTROL_OR_ALT={altKey:IS_APPLE,ctrlKey:!IS_APPLE};function isTab(event){return isExactShortcutMatch(event,'Tab',{shiftKey:'any'});}function isBold(event){return isExactShortcutMatch(event,'b',CONTROL_OR_META);}function isItalic(event){return isExactShortcutMatch(event,'i',CONTROL_OR_META);}function isUnderline(event){return isExactShortcutMatch(event,'u',CONTROL_OR_META);}function isParagraph(event){return isExactShortcutMatch(event,'Enter',{altKey:'any',ctrlKey:'any',metaKey:'any'});}function isLineBreak(event){return isExactShortcutMatch(event,'Enter',{altKey:'any',ctrlKey:'any',metaKey:'any',shiftKey:true});}// Inserts a new line after the selection
2380
+ function isOpenLineBreak(event){// 79 = KeyO
2381
+ return IS_APPLE&&isExactShortcutMatch(event,'o',{ctrlKey:true});}function isDeleteWordBackward(event){return isExactShortcutMatch(event,'Backspace',CONTROL_OR_ALT);}function isDeleteWordForward(event){return isExactShortcutMatch(event,'Delete',CONTROL_OR_ALT);}function isDeleteLineBackward(event){return IS_APPLE&&isExactShortcutMatch(event,'Backspace',{metaKey:true});}function isDeleteLineForward(event){return IS_APPLE&&(isExactShortcutMatch(event,'Delete',{metaKey:true})||isExactShortcutMatch(event,'k',{ctrlKey:true}));}function isDeleteBackward(event){return isExactShortcutMatch(event,'Backspace',{shiftKey:'any'})||IS_APPLE&&isExactShortcutMatch(event,'h',{ctrlKey:true});}function isDeleteForward(event){return isExactShortcutMatch(event,'Delete',{})||IS_APPLE&&isExactShortcutMatch(event,'d',{ctrlKey:true});}function isUndo(event){return isExactShortcutMatch(event,'z',CONTROL_OR_META);}function isRedo(event){if(IS_APPLE){return isExactShortcutMatch(event,'z',{metaKey:true,shiftKey:true});}return isExactShortcutMatch(event,'y',{ctrlKey:true})||isExactShortcutMatch(event,'z',{ctrlKey:true,shiftKey:true});}function isCopy(event){return isExactShortcutMatch(event,'c',CONTROL_OR_META);}function isCut(event){return isExactShortcutMatch(event,'x',CONTROL_OR_META);}function isMoveBackward(event){return isExactShortcutMatch(event,'ArrowLeft',{shiftKey:'any'});}function isMoveToStart(event){return isExactShortcutMatch(event,'ArrowLeft',CONTROL_OR_META);}function isMoveForward(event){return isExactShortcutMatch(event,'ArrowRight',{shiftKey:'any'});}function isMoveToEnd(event){return isExactShortcutMatch(event,'ArrowRight',CONTROL_OR_META);}function isMoveUp(event){return isExactShortcutMatch(event,'ArrowUp',{altKey:'any',shiftKey:'any'});}function isMoveDown(event){return isExactShortcutMatch(event,'ArrowDown',{altKey:'any',shiftKey:'any'});}function isModifier(event){return event.ctrlKey||event.shiftKey||event.altKey||event.metaKey;}function isSpace(event){return event.key===' ';}function isBackspace(event){return event.key==='Backspace';}function isEscape(event){return event.key==='Escape';}function isDelete(event){return event.key==='Delete';}function isSelectAll(event){return isExactShortcutMatch(event,'a',CONTROL_OR_META);}function $selectAll(selection){var root=$getRoot();if($isRangeSelection(selection)){var anchor=selection.anchor;var focus=selection.focus;var anchorNode=anchor.getNode();var topParent=anchorNode.getTopLevelElementOrThrow();var rootNode=topParent.getParentOrThrow();anchor.set(rootNode.getKey(),0,'element');focus.set(rootNode.getKey(),rootNode.getChildrenSize(),'element');$normalizeSelection(selection);return selection;}else{// Create a new RangeSelection
2382
+ var newSelection=root.select(0,root.getChildrenSize());$setSelection($normalizeSelection(newSelection));return newSelection;}}function getCachedClassNameArray(classNamesTheme,classNameThemeType){if(classNamesTheme.__lexicalClassNameCache===undefined){classNamesTheme.__lexicalClassNameCache={};}var classNamesCache=classNamesTheme.__lexicalClassNameCache;var cachedClassNames=classNamesCache[classNameThemeType];if(cachedClassNames!==undefined){return cachedClassNames;}var classNames=classNamesTheme[classNameThemeType];// As we're using classList, we need
2383
+ // to handle className tokens that have spaces.
2384
+ // The easiest way to do this to convert the
2385
+ // className tokens to an array that can be
2386
+ // applied to classList.add()/remove().
2387
+ if(typeof classNames==='string'){var classNamesArr=normalizeClassNames(classNames);classNamesCache[classNameThemeType]=classNamesArr;return classNamesArr;}return classNames;}function setMutatedNode(mutatedNodes,registeredNodes,mutationListeners,node,mutation){if(mutationListeners.size===0){return;}var nodeType=node.__type;var nodeKey=node.__key;var registeredNode=registeredNodes.get(nodeType);if(registeredNode===undefined){{formatDevErrorMessage("Type ".concat(nodeType," not in registeredNodes"));}}var klass=registeredNode.klass;var mutatedNodesByType=mutatedNodes.get(klass);if(mutatedNodesByType===undefined){mutatedNodesByType=new Map();mutatedNodes.set(klass,mutatedNodesByType);}var prevMutation=mutatedNodesByType.get(nodeKey);// If the node has already been "destroyed", yet we are
2388
+ // re-making it, then this means a move likely happened.
2389
+ // We should change the mutation to be that of "updated"
2390
+ // instead.
2391
+ var isMove=prevMutation==='destroyed'&&mutation==='created';if(prevMutation===undefined||isMove){mutatedNodesByType.set(nodeKey,isMove?'updated':mutation);}}/**
2392
+ * @deprecated Use {@link LexicalEditor.registerMutationListener} with `skipInitialization: false` instead.
2393
+ */function $nodesOfType(klass){var klassType=klass.getType();var editorState=getActiveEditorState();if(editorState._readOnly){var _nodes=getCachedTypeToNodeMap(editorState).get(klassType);return _nodes?Array.from(_nodes.values()):[];}var nodes=editorState._nodeMap;var nodesOfType=[];var _iterator31=_createForOfIteratorHelper(nodes),_step31;try{for(_iterator31.s();!(_step31=_iterator31.n()).done;){var _step31$value=_slicedToArray(_step31.value,2),node=_step31$value[1];if(node instanceof klass&&node.__type===klassType&&node.isAttached()){nodesOfType.push(node);}}}catch(err){_iterator31.e(err);}finally{_iterator31.f();}return nodesOfType;}function resolveElement(element,isBackward,focusOffset){var parent=element.getParent();var offset=focusOffset;var block=element;if(parent!==null){if(isBackward&&focusOffset===0){offset=block.getIndexWithinParent();block=parent;}else if(!isBackward&&focusOffset===block.getChildrenSize()){offset=block.getIndexWithinParent()+1;block=parent;}}return block.getChildAtIndex(isBackward?offset-1:offset);}function $getAdjacentNode(focus,isBackward){var focusOffset=focus.offset;if(focus.type==='element'){var block=focus.getNode();return resolveElement(block,isBackward,focusOffset);}else{var focusNode=focus.getNode();if(isBackward&&focusOffset===0||!isBackward&&focusOffset===focusNode.getTextContentSize()){var possibleNode=isBackward?focusNode.getPreviousSibling():focusNode.getNextSibling();if(possibleNode===null){return resolveElement(focusNode.getParentOrThrow(),isBackward,focusNode.getIndexWithinParent()+(isBackward?0:1));}return possibleNode;}}return null;}function isFirefoxClipboardEvents(editor){var event=getWindow(editor).event;var inputType=event&&event.inputType;return inputType==='insertFromPaste'||inputType==='insertFromPasteAsQuotation';}function _dispatchCommand(editor,command,payload){return triggerCommandListeners(editor,command,payload);}function $textContentRequiresDoubleLinebreakAtEnd(node){return!$isRootNode(node)&&!node.isLastChild()&&!node.isInline();}function getElementByKeyOrThrow(editor,key){var element=editor._keyToDOMMap.get(key);if(element===undefined){{formatDevErrorMessage("Reconciliation: could not find DOM element for node key ".concat(key));}}return element;}function getParentElement(node){var parentElement=node.assignedSlot||node.parentElement;return isDocumentFragment(parentElement)?parentElement.host:parentElement;}function getDOMOwnerDocument(target){return isDOMDocumentNode(target)?target:isHTMLElement(target)?target.ownerDocument:null;}function scrollIntoViewIfNeeded(editor,selectionRect,rootElement){var doc=getDOMOwnerDocument(rootElement);var defaultView=getDefaultView(doc);if(doc===null||defaultView===null){return;}var currentTop=selectionRect.top,currentBottom=selectionRect.bottom;var targetTop=0;var targetBottom=0;var element=rootElement;while(element!==null){var isBodyElement=element===doc.body;if(isBodyElement){targetTop=0;targetBottom=getWindow(editor).innerHeight;}else{var targetRect=element.getBoundingClientRect();targetTop=targetRect.top;targetBottom=targetRect.bottom;}var diff=0;if(currentTop<targetTop){diff=-(targetTop-currentTop);}else if(currentBottom>targetBottom){diff=currentBottom-targetBottom;}if(diff!==0){if(isBodyElement){// Only handles scrolling of Y axis
2394
+ defaultView.scrollBy(0,diff);}else{var scrollTop=element.scrollTop;element.scrollTop+=diff;var yOffset=element.scrollTop-scrollTop;currentTop-=yOffset;currentBottom-=yOffset;}}if(isBodyElement){break;}element=getParentElement(element);}}function $hasUpdateTag(tag){var editor=getActiveEditor();return editor._updateTags.has(tag);}function $addUpdateTag(tag){errorOnReadOnly();var editor=getActiveEditor();editor._updateTags.add(tag);}/**
2395
+ * Add a function to run after the current update. This will run after any
2396
+ * `onUpdate` function already supplied to `editor.update()`, as well as any
2397
+ * functions added with previous calls to `$onUpdate`.
2398
+ *
2399
+ * @param updateFn The function to run after the current update.
2400
+ */function $onUpdate(updateFn){errorOnReadOnly();var editor=getActiveEditor();editor._deferred.push(updateFn);}function $maybeMoveChildrenSelectionToParent(parentNode){var selection=$getSelection();if(!$isRangeSelection(selection)||!$isElementNode(parentNode)){return selection;}var anchor=selection.anchor,focus=selection.focus;var anchorNode=anchor.getNode();var focusNode=focus.getNode();if($hasAncestor(anchorNode,parentNode)){anchor.set(parentNode.__key,0,'element');}if($hasAncestor(focusNode,parentNode)){focus.set(parentNode.__key,0,'element');}return selection;}function $hasAncestor(child,targetNode){var parent=child.getParent();while(parent!==null){if(parent.is(targetNode)){return true;}parent=parent.getParent();}return false;}function getDefaultView(domElem){var ownerDoc=getDOMOwnerDocument(domElem);return ownerDoc?ownerDoc.defaultView:null;}function getWindow(editor){var windowObj=editor._window;if(windowObj===null){{formatDevErrorMessage("window object not found");}}return windowObj;}function $isInlineElementOrDecoratorNode(node){return $isElementNode(node)&&node.isInline()||$isDecoratorNode(node)&&node.isInline();}function $getNearestRootOrShadowRoot(node){var parent=node.getParentOrThrow();while(parent!==null){if($isRootOrShadowRoot(parent)){return parent;}parent=parent.getParentOrThrow();}return parent;}function $isRootOrShadowRoot(node){return $isRootNode(node)||$isElementNode(node)&&node.isShadowRoot();}/**
2401
+ * Returns a shallow clone of node with a new key. All properties of the node
2402
+ * will be copied to the new node (by `clone` and then `afterCloneFrom`),
2403
+ * except those related to parent/sibling/child
2404
+ * relationships in the `EditorState`. This means that the copy must be
2405
+ * separately added to the document, and it will not have any children.
2406
+ *
2407
+ * @param node - The node to be copied.
2408
+ * @returns The copy of the node.
2409
+ */function $copyNode(node){var copy=node.constructor.clone(node);$setNodeKey(copy,null);copy.afterCloneFrom(node);return copy;}function $applyNodeReplacement(node){var editor=getActiveEditor();var nodeType=node.getType();var registeredNode=getRegisteredNode(editor,nodeType);if(!(registeredNode!==undefined)){formatDevErrorMessage("$applyNodeReplacement node ".concat(node.constructor.name," with type ").concat(nodeType," must be registered to the editor. You can do this by passing the node class via the \"nodes\" array in the editor config."));}var replace=registeredNode.replace,replaceWithKlass=registeredNode.replaceWithKlass;if(replace!==null){var replacementNode=replace(node);var replacementNodeKlass=replacementNode.constructor;if(replaceWithKlass!==null){if(!(replacementNode instanceof replaceWithKlass)){formatDevErrorMessage("$applyNodeReplacement failed. Expected replacement node to be an instance of ".concat(replaceWithKlass.name," with type ").concat(replaceWithKlass.getType()," but returned ").concat(replacementNodeKlass.name," with type ").concat(replacementNodeKlass.getType()," from original node ").concat(node.constructor.name," with type ").concat(nodeType));}}else{if(!(replacementNode instanceof node.constructor&&replacementNodeKlass!==node.constructor)){formatDevErrorMessage("$applyNodeReplacement failed. Ensure replacement node ".concat(replacementNodeKlass.name," with type ").concat(replacementNodeKlass.getType()," is a subclass of the original node ").concat(node.constructor.name," with type ").concat(nodeType,"."));}}if(!(replacementNode.__key!==node.__key)){formatDevErrorMessage("$applyNodeReplacement failed. Ensure that the key argument is *not* used in your replace function (from node ".concat(node.constructor.name," with type ").concat(nodeType," to node ").concat(replacementNodeKlass.name," with type ").concat(replacementNodeKlass.getType(),"), Node keys must never be re-used except by the static clone method."));}return replacementNode;}return node;}function errorOnInsertTextNodeOnRoot(node,insertNode){var parentNode=node.getParent();if($isRootNode(parentNode)&&!$isElementNode(insertNode)&&!$isDecoratorNode(insertNode)){{formatDevErrorMessage("Only element or decorator nodes can be inserted in to the root node");}}}function $getNodeByKeyOrThrow(key){var node=$getNodeByKey(key);if(node===null){{formatDevErrorMessage("Expected node with key ".concat(key," to exist but it's not in the nodeMap."));}}return node;}function createBlockCursorElement(editorConfig){var theme=editorConfig.theme;var element=document.createElement('div');element.contentEditable='false';element.setAttribute('data-lexical-cursor','true');var blockCursorTheme=theme.blockCursor;if(blockCursorTheme!==undefined){if(typeof blockCursorTheme==='string'){var classNamesArr=normalizeClassNames(blockCursorTheme);// @ts-expect-error: intentional
2410
+ blockCursorTheme=theme.blockCursor=classNamesArr;}if(blockCursorTheme!==undefined){var _element$classList;(_element$classList=element.classList).add.apply(_element$classList,_toConsumableArray(blockCursorTheme));}}return element;}function needsBlockCursor(node){return($isDecoratorNode(node)||$isElementNode(node)&&!node.canBeEmpty())&&!node.isInline();}function removeDOMBlockCursorElement(blockCursorElement,editor,rootElement){rootElement.style.removeProperty('caret-color');editor._blockCursorElement=null;var parentElement=blockCursorElement.parentElement;if(parentElement!==null){parentElement.removeChild(blockCursorElement);}}function updateDOMBlockCursorElement(editor,rootElement,nextSelection){var blockCursorElement=editor._blockCursorElement;if($isRangeSelection(nextSelection)&&nextSelection.isCollapsed()&&nextSelection.anchor.type==='element'&&rootElement.contains(document.activeElement)){var anchor=nextSelection.anchor;var elementNode=anchor.getNode();var offset=anchor.offset;var elementNodeSize=elementNode.getChildrenSize();var isBlockCursor=false;var insertBeforeElement=null;if(offset===elementNodeSize){var child=elementNode.getChildAtIndex(offset-1);if(needsBlockCursor(child)){isBlockCursor=true;}}else{var _child3=elementNode.getChildAtIndex(offset);if(_child3!==null&&needsBlockCursor(_child3)){var sibling=_child3.getPreviousSibling();if(sibling===null||needsBlockCursor(sibling)){isBlockCursor=true;insertBeforeElement=editor.getElementByKey(_child3.__key);}}}if(isBlockCursor){var elementDOM=editor.getElementByKey(elementNode.__key);if(blockCursorElement===null){editor._blockCursorElement=blockCursorElement=createBlockCursorElement(editor._config);}rootElement.style.caretColor='transparent';if(insertBeforeElement===null){elementDOM.appendChild(blockCursorElement);}else{elementDOM.insertBefore(blockCursorElement,insertBeforeElement);}return;}}// Remove cursor
2411
+ if(blockCursorElement!==null){removeDOMBlockCursorElement(blockCursorElement,editor,rootElement);}}/**
2412
+ * Returns the selection for the given window, or the global window if null.
2413
+ * Will return null if {@link CAN_USE_DOM} is false.
2414
+ *
2415
+ * @param targetWindow The window to get the selection from
2416
+ * @returns a Selection or null
2417
+ */function getDOMSelection(targetWindow){return!CAN_USE_DOM?null:(targetWindow||window).getSelection();}/**
2418
+ * Returns the selection for the defaultView of the ownerDocument of given EventTarget.
2419
+ *
2420
+ * @param eventTarget The node to get the selection from
2421
+ * @returns a Selection or null
2422
+ */function getDOMSelectionFromTarget(eventTarget){var defaultView=getDefaultView(eventTarget);return defaultView?defaultView.getSelection():null;}function $splitNode(node,offset){var startNode=node.getChildAtIndex(offset);if(startNode==null){startNode=node;}if(!!$isRootOrShadowRoot(node)){formatDevErrorMessage("Can not call $splitNode() on root element");}var recurse=function recurse(currentNode){var parent=currentNode.getParentOrThrow();var isParentRoot=$isRootOrShadowRoot(parent);// The node we start split from (leaf) is moved, but its recursive
2423
+ // parents are copied to create separate tree
2424
+ var nodeToMove=currentNode===startNode&&!isParentRoot?currentNode:$copyNode(currentNode);if(isParentRoot){if(!($isElementNode(currentNode)&&$isElementNode(nodeToMove))){formatDevErrorMessage("Children of a root must be ElementNode");}currentNode.insertAfter(nodeToMove);return[currentNode,nodeToMove,nodeToMove];}else{var _recurse=recurse(parent),_recurse2=_slicedToArray(_recurse,3),_leftTree=_recurse2[0],_rightTree=_recurse2[1],newParent=_recurse2[2];var nextSiblings=currentNode.getNextSiblings();newParent.append.apply(newParent,[nodeToMove].concat(_toConsumableArray(nextSiblings)));return[_leftTree,_rightTree,nodeToMove];}};var _recurse3=recurse(startNode),_recurse4=_slicedToArray(_recurse3,2),leftTree=_recurse4[0],rightTree=_recurse4[1];return[leftTree,rightTree];}/**
2425
+ * @param x - The element being tested
2426
+ * @returns Returns true if x is an HTML anchor tag, false otherwise
2427
+ */function isHTMLAnchorElement(x){return isHTMLElement(x)&&x.tagName==='A';}/**
2428
+ * @param x - The element being tested
2429
+ * @returns Returns true if x is an HTML element, false otherwise.
2430
+ */function isHTMLElement(x){return isDOMNode(x)&&x.nodeType===DOM_ELEMENT_TYPE;}/**
2431
+ * @param x - The element being tested
2432
+ * @returns Returns true if x is a DOM Node, false otherwise.
2433
+ */function isDOMNode(x){return _typeof(x)==='object'&&x!==null&&'nodeType'in x&&typeof x.nodeType==='number';}/**
2434
+ * @param x - The element being testing
2435
+ * @returns Returns true if x is a document fragment, false otherwise.
2436
+ */function isDocumentFragment(x){return isDOMNode(x)&&x.nodeType===DOM_DOCUMENT_FRAGMENT_TYPE;}/**
2437
+ *
2438
+ * @param node - the Dom Node to check
2439
+ * @returns if the Dom Node is an inline node
2440
+ */function isInlineDomNode(node){var inlineNodes=new RegExp(/^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|mark|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var|#text)$/,'i');return node.nodeName.match(inlineNodes)!==null;}/**
2441
+ *
2442
+ * @param node - the Dom Node to check
2443
+ * @returns if the Dom Node is a block node
2444
+ */function isBlockDomNode(node){var blockNodes=new RegExp(/^(address|article|aside|blockquote|canvas|dd|div|dl|dt|fieldset|figcaption|figure|footer|form|h1|h2|h3|h4|h5|h6|header|hr|li|main|nav|noscript|ol|p|pre|section|table|td|tfoot|ul|video)$/,'i');return node.nodeName.match(blockNodes)!==null;}/**
2445
+ * @internal
2446
+ *
2447
+ * This function is for internal use of the library.
2448
+ * Please do not use it as it may change in the future.
2449
+ *
2450
+ * This function returns true for a DecoratorNode that is not inline OR
2451
+ * an ElementNode that is:
2452
+ * - not a root or shadow root
2453
+ * - not inline
2454
+ * - can't be empty
2455
+ * - has no children or an inline first child
2456
+ */function INTERNAL_$isBlock(node){if($isDecoratorNode(node)&&!node.isInline()){return true;}if(!$isElementNode(node)||$isRootOrShadowRoot(node)){return false;}var firstChild=node.getFirstChild();var isLeafElement=firstChild===null||$isLineBreakNode(firstChild)||$isTextNode(firstChild)||firstChild.isInline();return!node.isInline()&&node.canBeEmpty()!==false&&isLeafElement;}/**
2457
+ * Utility function for accessing current active editor instance.
2458
+ * @returns Current active editor
2459
+ */function $getEditor(){return getActiveEditor();}/** @internal */ /**
2460
+ * @internal
2461
+ * Compute a cached Map of node type to nodes for a frozen EditorState
2462
+ */var cachedNodeMaps=new WeakMap();var EMPTY_TYPE_TO_NODE_MAP=new Map();function getCachedTypeToNodeMap(editorState){// If this is a new Editor it may have a writable this._editorState
2463
+ // with only a 'root' entry.
2464
+ if(!editorState._readOnly&&editorState.isEmpty()){return EMPTY_TYPE_TO_NODE_MAP;}if(!editorState._readOnly){formatDevErrorMessage("getCachedTypeToNodeMap called with a writable EditorState");}var typeToNodeMap=cachedNodeMaps.get(editorState);if(!typeToNodeMap){typeToNodeMap=computeTypeToNodeMap(editorState);cachedNodeMaps.set(editorState,typeToNodeMap);}return typeToNodeMap;}/**
2465
+ * @internal
2466
+ * Compute a Map of node type to nodes for an EditorState
2467
+ */function computeTypeToNodeMap(editorState){var typeToNodeMap=new Map();var _iterator32=_createForOfIteratorHelper(editorState._nodeMap),_step32;try{for(_iterator32.s();!(_step32=_iterator32.n()).done;){var _step32$value=_slicedToArray(_step32.value,2),nodeKey=_step32$value[0],node=_step32$value[1];var nodeType=node.__type;var nodeMap=typeToNodeMap.get(nodeType);if(!nodeMap){nodeMap=new Map();typeToNodeMap.set(nodeType,nodeMap);}nodeMap.set(nodeKey,node);}}catch(err){_iterator32.e(err);}finally{_iterator32.f();}return typeToNodeMap;}/**
2468
+ * Returns a clone of a node using `node.constructor.clone()` followed by
2469
+ * `clone.afterCloneFrom(node)`. The resulting clone must have the same key,
2470
+ * parent/next/prev pointers, and other properties that are not set by
2471
+ * `node.constructor.clone` (format, style, etc.). This is primarily used by
2472
+ * {@link LexicalNode.getWritable} to create a writable version of an
2473
+ * existing node. The clone is the same logical node as the original node,
2474
+ * do not try and use this function to duplicate or copy an existing node.
2475
+ *
2476
+ * Does not mutate the EditorState.
2477
+ * @param latestNode - The node to be cloned.
2478
+ * @returns The clone of the node.
2479
+ */function $cloneWithProperties(latestNode){var constructor=latestNode.constructor;var mutableNode=constructor.clone(latestNode);mutableNode.afterCloneFrom(latestNode);{if(!(mutableNode.__key===latestNode.__key)){formatDevErrorMessage("$cloneWithProperties: ".concat(constructor.name,".clone(node) (with type '").concat(constructor.getType(),"') did not return a node with the same key, make sure to specify node.__key as the last argument to the constructor"));}if(!(mutableNode.__parent===latestNode.__parent&&mutableNode.__next===latestNode.__next&&mutableNode.__prev===latestNode.__prev)){formatDevErrorMessage("$cloneWithProperties: ".concat(constructor.name,".clone(node) (with type '").concat(constructor.getType(),"') overrode afterCloneFrom but did not call super.afterCloneFrom(prevNode)"));}}return mutableNode;}/**
2480
+ * Returns a clone with {@link $cloneWithProperties} and then "detaches"
2481
+ * it from the state by overriding its getLatest and getWritable to always
2482
+ * return this. This node can not be added to an EditorState or become the
2483
+ * parent, child, or sibling of another node. It is primarily only useful
2484
+ * for making in-place temporary modifications to a TextNode when
2485
+ * serializing a partial slice.
2486
+ *
2487
+ * Does not mutate the EditorState.
2488
+ * @param latestNode - The node to be cloned.
2489
+ * @returns The clone of the node.
2490
+ */function $cloneWithPropertiesEphemeral(latestNode){return $markEphemeral($cloneWithProperties(latestNode));}function setNodeIndentFromDOM(elementDom,elementNode){var indentSize=parseInt(elementDom.style.paddingInlineStart,10)||0;var indent=Math.round(indentSize/40);elementNode.setIndent(indent);}/**
2491
+ * @internal
2492
+ *
2493
+ * Mark this node as unmanaged by lexical's mutation observer like
2494
+ * decorator nodes
2495
+ */function setDOMUnmanaged(elementDom){var el=elementDom;el.__lexicalUnmanaged=true;}/**
2496
+ * @internal
2497
+ *
2498
+ * True if this DOM node was marked with {@link setDOMUnmanaged}
2499
+ */function isDOMUnmanaged(elementDom){var el=elementDom;return el.__lexicalUnmanaged===true;}/**
2500
+ * @internal
2501
+ *
2502
+ * Object.hasOwn ponyfill
2503
+ */function hasOwn(o,k){return Object.prototype.hasOwnProperty.call(o,k);}/**
2504
+ * @internal
2505
+ */function hasOwnStaticMethod(klass,k){return hasOwn(klass,k)&&klass[k]!==LexicalNode[k];}/**
2506
+ * @internal
2507
+ */function hasOwnExportDOM(klass){return hasOwn(klass.prototype,'exportDOM');}/** @internal */function isAbstractNodeClass(klass){if(!(klass===LexicalNode||klass.prototype instanceof LexicalNode)){var ownNodeType='<unknown>';var version='<unknown>';try{ownNodeType=klass.getType();}catch(_err){// ignore
2508
+ }try{if(LexicalEditor.version){version=JSON.parse(LexicalEditor.version);}}catch(_err){// ignore
2509
+ }{formatDevErrorMessage("".concat(klass.name," (type ").concat(ownNodeType,") does not subclass LexicalNode from the lexical package used by this editor (version ").concat(version,"). All lexical and @lexical/* packages used by an editor must have identical versions. If you suspect the version does match, then the problem may be caused by multiple copies of the same lexical module (e.g. both esm and cjs, or included directly in multiple entrypoints)."));}}return klass===DecoratorNode||klass===ElementNode||klass===LexicalNode;}/** @internal */function getStaticNodeConfig(klass){var nodeConfigRecord=PROTOTYPE_CONFIG_METHOD in klass.prototype?klass.prototype[PROTOTYPE_CONFIG_METHOD]():undefined;var isAbstract=isAbstractNodeClass(klass);var nodeType=!isAbstract&&hasOwnStaticMethod(klass,'getType')?klass.getType():undefined;var ownNodeConfig;var ownNodeType=nodeType;if(nodeConfigRecord){if(nodeType){ownNodeConfig=nodeConfigRecord[nodeType];}else{for(var _i12=0,_Object$entries4=Object.entries(nodeConfigRecord);_i12<_Object$entries4.length;_i12++){var _Object$entries4$_i=_slicedToArray(_Object$entries4[_i12],2),k=_Object$entries4$_i[0],v=_Object$entries4$_i[1];ownNodeType=k;ownNodeConfig=v;}}}if(!isAbstract&&ownNodeType){if(!hasOwnStaticMethod(klass,'getType')){klass.getType=function(){return ownNodeType;};}if(!hasOwnStaticMethod(klass,'clone')){// TextNode.length > 0 will only be true if the compiler output
2510
+ // is not ES6 compliant, in which case we can not provide this
2511
+ // warning
2512
+ if(TextNode.length===0){if(!(klass.length===0)){formatDevErrorMessage("".concat(klass.name," (type ").concat(ownNodeType,") must implement a static clone method since its constructor has ").concat(String(klass.length)," required arguments (expecting 0). Use an explicit default in the first argument of your constructor(prop: T=X, nodeKey?: NodeKey)."));}}klass.clone=function(prevNode){setPendingNodeToClone(prevNode);return new klass();};}if(!hasOwnStaticMethod(klass,'importJSON')){if(TextNode.length===0){if(!(klass.length===0)){formatDevErrorMessage("".concat(klass.name," (type ").concat(ownNodeType,") must implement a static importJSON method since its constructor has ").concat(String(klass.length)," required arguments (expecting 0). Use an explicit default in the first argument of your constructor(prop: T=X, nodeKey?: NodeKey)."));}}klass.importJSON=ownNodeConfig&&ownNodeConfig.$importJSON||function(serializedNode){return new klass().updateFromJSON(serializedNode);};}if(!hasOwnStaticMethod(klass,'importDOM')&&ownNodeConfig){var _ownNodeConfig=ownNodeConfig,importDOM=_ownNodeConfig.importDOM;if(importDOM){klass.importDOM=function(){return importDOM;};}}}return{ownNodeConfig:ownNodeConfig,ownNodeType:ownNodeType};}/**
2513
+ * Create an node from its class.
2514
+ *
2515
+ * Note that this will directly construct the final `withKlass` node type,
2516
+ * and will ignore the deprecated `with` functions. This allows `$create` to
2517
+ * skip any intermediate steps where the replaced node would be created and
2518
+ * then immediately discarded (once per configured replacement of that node).
2519
+ *
2520
+ * This does not support any arguments to the constructor.
2521
+ * Setters can be used to initialize your node, and they can
2522
+ * be chained. You can of course write your own mutliple-argument functions
2523
+ * to wrap that.
2524
+ *
2525
+ * @example
2526
+ * ```ts
2527
+ * function $createTokenText(text: string): TextNode {
2528
+ * return $create(TextNode).setTextContent(text).setMode('token');
2529
+ * }
2530
+ * ```
2531
+ */function $create(klass){var editor=$getEditor();errorOnReadOnly();var registeredNode=editor.resolveRegisteredNodeAfterReplacements(editor.getRegisteredNode(klass));return new registeredNode.klass();}/**
2532
+ * Starts with a node and moves up the tree (toward the root node) to find a matching node based on
2533
+ * the search parameters of the findFn. (Consider JavaScripts' .find() function where a testing function must be
2534
+ * passed as an argument. eg. if( (node) => node.__type === 'div') ) return true; otherwise return false
2535
+ * @param startingNode - The node where the search starts.
2536
+ * @param findFn - A testing function that returns true if the current node satisfies the testing parameters.
2537
+ * @returns `startingNode` or one of its ancestors that matches the `findFn` predicate and is not the `RootNode`, or `null` if no match was found.
2538
+ */var $findMatchingParent=function $findMatchingParent(startingNode,findFn){var curr=startingNode;while(curr!=null&&!$isRootNode(curr)){if(findFn(curr)){return curr;}curr=curr.getParent();}return null;};/**
2539
+ * The direction of a caret, 'next' points towards the end of the document
2540
+ * and 'previous' points towards the beginning
2541
+ */ /**
2542
+ * A type utility to flip next and previous
2543
+ */ /**
2544
+ * A sibling caret type points from a LexicalNode origin to its next or previous sibling,
2545
+ * and a child caret type points from an ElementNode origin to its first or last child.
2546
+ */ /**
2547
+ * The RootMode is specified in all caret traversals where the traversal can go up
2548
+ * towards the root. 'root' means that it will stop at the document root,
2549
+ * and 'shadowRoot' will stop at the document root or any shadow root
2550
+ * (per {@link $isRootOrShadowRoot}).
2551
+ */var FLIP_DIRECTION={next:'previous',previous:'next'};/** @noInheritDoc */ /**
2552
+ * A RangeSelection expressed as a pair of Carets
2553
+ */ /**
2554
+ * A NodeCaret is the combination of an origin node and a direction
2555
+ * that points towards where a connected node will be fetched, inserted,
2556
+ * or replaced. A SiblingCaret points from a node to its next or previous
2557
+ * sibling, and a ChildCaret points to its first or last child
2558
+ * (using next or previous as direction, for symmetry with SiblingCaret).
2559
+ *
2560
+ * The differences between NodeCaret and PointType are:
2561
+ * - NodeCaret can only be used to refer to an entire node (PointCaret is used when a full analog is needed). A PointType of text type can be used to refer to a specific location inside of a TextNode.
2562
+ * - NodeCaret stores an origin node, type (sibling or child), and direction (next or previous). A PointType stores a type (text or element), the key of a node, and a text or child offset within that node.
2563
+ * - NodeCaret is directional and always refers to a very specific node, eliminating all ambiguity. PointType can refer to the location before or at a node depending on context.
2564
+ * - NodeCaret is more robust to nearby mutations, as it relies only on a node's direct connections. An element Any change to the count of previous siblings in an element PointType will invalidate it.
2565
+ * - NodeCaret is designed to work more directly with the internal representation of the document tree, making it suitable for use in traversals without performing any redundant work.
2566
+ *
2567
+ * The caret does *not* update in response to any mutations, you should
2568
+ * not persist it across editor updates, and using a caret after its origin
2569
+ * node has been removed or replaced may result in runtime errors.
2570
+ */ /**
2571
+ * A PointCaret is a NodeCaret that also includes a
2572
+ * TextPointCaret type which refers to a specific offset of a TextNode.
2573
+ * This type is separate because it is not relevant to general node traversal
2574
+ * so it doesn't make sense to have it show up except when defining
2575
+ * a CaretRange and in those cases there will be at most two of them only
2576
+ * at the boundaries.
2577
+ *
2578
+ * The addition of TextPointCaret allows this type to represent any location
2579
+ * that is representable by PointType, as the TextPointCaret refers to a
2580
+ * specific offset within a TextNode.
2581
+ */ /**
2582
+ * A SiblingCaret points from an origin LexicalNode towards its next or previous sibling.
2583
+ */ /**
2584
+ * A ChildCaret points from an origin ElementNode towards its first or last child.
2585
+ */ /**
2586
+ * A TextPointCaret is a special case of a SiblingCaret that also carries
2587
+ * an offset used for representing partially selected TextNode at the edges
2588
+ * of a CaretRange.
2589
+ *
2590
+ * The direction determines which part of the text is adjacent to the caret,
2591
+ * if next it's all of the text after offset. If previous, it's all of the
2592
+ * text before offset.
2593
+ *
2594
+ * While this can be used in place of any SiblingCaret of a TextNode,
2595
+ * the offset into the text will be ignored except in contexts that
2596
+ * specifically use the TextPointCaret or PointCaret types.
2597
+ */ /**
2598
+ * A TextPointCaretSlice is a wrapper for a TextPointCaret that carries a signed
2599
+ * distance representing the direction and amount of text selected from the given
2600
+ * caret. A negative distance means that text before offset is selected, a
2601
+ * positive distance means that text after offset is selected. The offset+distance
2602
+ * pair is not affected in any way by the direction of the caret.
2603
+ */ /**
2604
+ * A utility type to specify that a CaretRange may have zero,
2605
+ * one, or two associated TextPointCaretSlice. If the anchor
2606
+ * and focus are on the same node, the anchorSlice will contain
2607
+ * the slice and focusSlie will be null.
2608
+ */_Symbol$iterator=Symbol.iterator;var AbstractCaret=/*#__PURE__*/function(){function AbstractCaret(origin){_classCallCheck(this,AbstractCaret);_defineProperty(this,"origin",void 0);this.origin=origin;}_createClass(AbstractCaret,[{key:_Symbol$iterator,value:function value(){return makeStepwiseIterator({hasNext:$isSiblingCaret,initial:this.getAdjacentCaret(),map:function map(caret){return caret;},step:function step(caret){return caret.getAdjacentCaret();}});}},{key:"getAdjacentCaret",value:function getAdjacentCaret(){return $getSiblingCaret(this.getNodeAtCaret(),this.direction);}},{key:"getSiblingCaret",value:function getSiblingCaret(){return $getSiblingCaret(this.origin,this.direction);}},{key:"remove",value:function remove(){var node=this.getNodeAtCaret();if(node){node.remove();}return this;}},{key:"replaceOrInsert",value:function replaceOrInsert(node,includeChildren){var target=this.getNodeAtCaret();if(node.is(this.origin)||node.is(target));else if(target===null){this.insert(node);}else{target.replace(node,includeChildren);}return this;}},{key:"splice",value:function splice(deleteCount,nodes){var nodesDirection=arguments.length>2&&arguments[2]!==undefined?arguments[2]:'next';var nodeIter=nodesDirection===this.direction?nodes:Array.from(nodes).reverse();var caret=this;var parent=this.getParentAtCaret();var nodesToRemove=new Map();// Find all of the nodes we expect to remove first, so
2609
+ // we don't have to worry about the cases where there is
2610
+ // overlap between the nodes to insert and the nodes to
2611
+ // remove
2612
+ for(var removeCaret=caret.getAdjacentCaret();removeCaret!==null&&nodesToRemove.size<deleteCount;removeCaret=removeCaret.getAdjacentCaret()){var writableNode=removeCaret.origin.getWritable();nodesToRemove.set(writableNode.getKey(),writableNode);}// TODO: Optimize this to work directly with node internals
2613
+ var _iterator33=_createForOfIteratorHelper(nodeIter),_step33;try{for(_iterator33.s();!(_step33=_iterator33.n()).done;){var node=_step33.value;if(nodesToRemove.size>0){// For some reason `pnpm run tsc-extension` needs this annotation?
2614
+ var target=caret.getNodeAtCaret();if(target){nodesToRemove.delete(target.getKey());nodesToRemove.delete(node.getKey());if(target.is(node)||caret.origin.is(node));else{var nodeParent=node.getParent();if(nodeParent&&nodeParent.is(parent)){// It's a sibling somewhere else in this node, so unparent it first
2615
+ node.remove();}target.replace(node);}}else{if(!(target!==null)){formatDevErrorMessage("NodeCaret.splice: Underflow of expected nodesToRemove during splice (keys: ".concat(Array.from(nodesToRemove).join(' '),")"));}}}else{caret.insert(node);}caret=$getSiblingCaret(node,this.direction);}}catch(err){_iterator33.e(err);}finally{_iterator33.f();}var _iterator34=_createForOfIteratorHelper(nodesToRemove.values()),_step34;try{for(_iterator34.s();!(_step34=_iterator34.n()).done;){var _node5=_step34.value;_node5.remove();}}catch(err){_iterator34.e(err);}finally{_iterator34.f();}return this;}}]);return AbstractCaret;}();var AbstractChildCaret=/*#__PURE__*/function(_AbstractCaret){_inherits(AbstractChildCaret,_AbstractCaret);var _super9=_createSuper(AbstractChildCaret);function AbstractChildCaret(){var _this7;_classCallCheck(this,AbstractChildCaret);for(var _len5=arguments.length,args=new Array(_len5),_key5=0;_key5<_len5;_key5++){args[_key5]=arguments[_key5];}_this7=_super9.call.apply(_super9,[this].concat(args));_defineProperty(_assertThisInitialized(_this7),"type",'child');return _this7;}_createClass(AbstractChildCaret,[{key:"getLatest",value:function getLatest(){var origin=this.origin.getLatest();return origin===this.origin?this:$getChildCaret(origin,this.direction);}/**
2616
+ * Get the SiblingCaret from this origin in the same direction.
2617
+ *
2618
+ * @param mode 'root' to return null at the root, 'shadowRoot' to return null at the root or any shadow root
2619
+ * @returns A SiblingCaret with this origin, or null if origin is a root according to mode.
2620
+ */},{key:"getParentCaret",value:function getParentCaret(){var mode=arguments.length>0&&arguments[0]!==undefined?arguments[0]:'root';return $getSiblingCaret($filterByMode(this.getParentAtCaret(),mode),this.direction);}},{key:"getFlipped",value:function getFlipped(){var dir=flipDirection(this.direction);return $getSiblingCaret(this.getNodeAtCaret(),dir)||$getChildCaret(this.origin,dir);}},{key:"getParentAtCaret",value:function getParentAtCaret(){return this.origin;}},{key:"getChildCaret",value:function getChildCaret(){return this;}},{key:"isSameNodeCaret",value:function isSameNodeCaret(other){return other instanceof AbstractChildCaret&&this.direction===other.direction&&this.origin.is(other.origin);}},{key:"isSamePointCaret",value:function isSamePointCaret(other){return this.isSameNodeCaret(other);}}]);return AbstractChildCaret;}(AbstractCaret);var ChildCaretFirst=/*#__PURE__*/function(_AbstractChildCaret){_inherits(ChildCaretFirst,_AbstractChildCaret);var _super10=_createSuper(ChildCaretFirst);function ChildCaretFirst(){var _this8;_classCallCheck(this,ChildCaretFirst);for(var _len6=arguments.length,args=new Array(_len6),_key6=0;_key6<_len6;_key6++){args[_key6]=arguments[_key6];}_this8=_super10.call.apply(_super10,[this].concat(args));_defineProperty(_assertThisInitialized(_this8),"direction",'next');return _this8;}_createClass(ChildCaretFirst,[{key:"getNodeAtCaret",value:function getNodeAtCaret(){return this.origin.getFirstChild();}},{key:"insert",value:function insert(node){this.origin.splice(0,0,[node]);return this;}}]);return ChildCaretFirst;}(AbstractChildCaret);var ChildCaretLast=/*#__PURE__*/function(_AbstractChildCaret2){_inherits(ChildCaretLast,_AbstractChildCaret2);var _super11=_createSuper(ChildCaretLast);function ChildCaretLast(){var _this9;_classCallCheck(this,ChildCaretLast);for(var _len7=arguments.length,args=new Array(_len7),_key7=0;_key7<_len7;_key7++){args[_key7]=arguments[_key7];}_this9=_super11.call.apply(_super11,[this].concat(args));_defineProperty(_assertThisInitialized(_this9),"direction",'previous');return _this9;}_createClass(ChildCaretLast,[{key:"getNodeAtCaret",value:function getNodeAtCaret(){return this.origin.getLastChild();}},{key:"insert",value:function insert(node){this.origin.splice(this.origin.getChildrenSize(),0,[node]);return this;}}]);return ChildCaretLast;}(AbstractChildCaret);var MODE_PREDICATE={root:$isRootNode,shadowRoot:$isRootOrShadowRoot};/**
2621
+ * Flip a direction ('next' -> 'previous'; 'previous' -> 'next').
2622
+ *
2623
+ * Note that TypeScript can't prove that FlipDirection is its own
2624
+ * inverse (but if you have a concrete 'next' or 'previous' it will
2625
+ * simplify accordingly).
2626
+ *
2627
+ * @param direction A direction
2628
+ * @returns The opposite direction
2629
+ */function flipDirection(direction){return FLIP_DIRECTION[direction];}function $filterByMode(node){var mode=arguments.length>1&&arguments[1]!==undefined?arguments[1]:'root';return MODE_PREDICATE[mode](node)?null:node;}var AbstractSiblingCaret=/*#__PURE__*/function(_AbstractCaret2){_inherits(AbstractSiblingCaret,_AbstractCaret2);var _super12=_createSuper(AbstractSiblingCaret);function AbstractSiblingCaret(){var _this10;_classCallCheck(this,AbstractSiblingCaret);for(var _len8=arguments.length,args=new Array(_len8),_key8=0;_key8<_len8;_key8++){args[_key8]=arguments[_key8];}_this10=_super12.call.apply(_super12,[this].concat(args));_defineProperty(_assertThisInitialized(_this10),"type",'sibling');return _this10;}_createClass(AbstractSiblingCaret,[{key:"getLatest",value:function getLatest(){var origin=this.origin.getLatest();return origin===this.origin?this:$getSiblingCaret(origin,this.direction);}},{key:"getSiblingCaret",value:function getSiblingCaret(){return this;}},{key:"getParentAtCaret",value:function getParentAtCaret(){return this.origin.getParent();}},{key:"getChildCaret",value:function getChildCaret(){return $isElementNode(this.origin)?$getChildCaret(this.origin,this.direction):null;}},{key:"getParentCaret",value:function getParentCaret(){var mode=arguments.length>0&&arguments[0]!==undefined?arguments[0]:'root';return $getSiblingCaret($filterByMode(this.getParentAtCaret(),mode),this.direction);}},{key:"getFlipped",value:function getFlipped(){var dir=flipDirection(this.direction);return $getSiblingCaret(this.getNodeAtCaret(),dir)||$getChildCaret(this.origin.getParentOrThrow(),dir);}},{key:"isSamePointCaret",value:function isSamePointCaret(other){return other instanceof AbstractSiblingCaret&&this.direction===other.direction&&this.origin.is(other.origin);}},{key:"isSameNodeCaret",value:function isSameNodeCaret(other){return(other instanceof AbstractSiblingCaret||other instanceof AbstractTextPointCaret)&&this.direction===other.direction&&this.origin.is(other.origin);}}]);return AbstractSiblingCaret;}(AbstractCaret);var AbstractTextPointCaret=/*#__PURE__*/function(_AbstractCaret3){_inherits(AbstractTextPointCaret,_AbstractCaret3);var _super13=_createSuper(AbstractTextPointCaret);function AbstractTextPointCaret(origin,offset){var _this11;_classCallCheck(this,AbstractTextPointCaret);_this11=_super13.call(this,origin);_defineProperty(_assertThisInitialized(_this11),"type",'text');_defineProperty(_assertThisInitialized(_this11),"offset",void 0);_this11.offset=offset;return _this11;}_createClass(AbstractTextPointCaret,[{key:"getLatest",value:function getLatest(){var origin=this.origin.getLatest();return origin===this.origin?this:$getTextPointCaret(origin,this.direction,this.offset);}},{key:"getParentAtCaret",value:function getParentAtCaret(){return this.origin.getParent();}},{key:"getChildCaret",value:function getChildCaret(){return null;}},{key:"getParentCaret",value:function getParentCaret(){var mode=arguments.length>0&&arguments[0]!==undefined?arguments[0]:'root';return $getSiblingCaret($filterByMode(this.getParentAtCaret(),mode),this.direction);}},{key:"getFlipped",value:function getFlipped(){return $getTextPointCaret(this.origin,flipDirection(this.direction),this.offset);}},{key:"isSamePointCaret",value:function isSamePointCaret(other){return other instanceof AbstractTextPointCaret&&this.direction===other.direction&&this.origin.is(other.origin)&&this.offset===other.offset;}},{key:"isSameNodeCaret",value:function isSameNodeCaret(other){return(other instanceof AbstractSiblingCaret||other instanceof AbstractTextPointCaret)&&this.direction===other.direction&&this.origin.is(other.origin);}},{key:"getSiblingCaret",value:function getSiblingCaret(){return $getSiblingCaret(this.origin,this.direction);}}]);return AbstractTextPointCaret;}(AbstractCaret);/**
2630
+ * Guard to check if the given caret is specifically a TextPointCaret
2631
+ *
2632
+ * @param caret Any caret
2633
+ * @returns true if it is a TextPointCaret
2634
+ */function $isTextPointCaret(caret){return caret instanceof AbstractTextPointCaret;}/**
2635
+ * Guard to check if the given argument is any type of caret
2636
+ *
2637
+ * @param caret
2638
+ * @returns true if caret is any type of caret
2639
+ */function $isNodeCaret(caret){return caret instanceof AbstractCaret;}/**
2640
+ * Guard to check if the given argument is specifically a SiblingCaret (or TextPointCaret)
2641
+ *
2642
+ * @param caret
2643
+ * @returns true if caret is a SiblingCaret
2644
+ */function $isSiblingCaret(caret){return caret instanceof AbstractSiblingCaret;}/**
2645
+ * Guard to check if the given argument is specifically a ChildCaret
2646
+
2647
+ * @param caret
2648
+ * @returns true if caret is a ChildCaret
2649
+ */function $isChildCaret(caret){return caret instanceof AbstractChildCaret;}var SiblingCaretNext=/*#__PURE__*/function(_AbstractSiblingCaret){_inherits(SiblingCaretNext,_AbstractSiblingCaret);var _super14=_createSuper(SiblingCaretNext);function SiblingCaretNext(){var _this12;_classCallCheck(this,SiblingCaretNext);for(var _len9=arguments.length,args=new Array(_len9),_key9=0;_key9<_len9;_key9++){args[_key9]=arguments[_key9];}_this12=_super14.call.apply(_super14,[this].concat(args));_defineProperty(_assertThisInitialized(_this12),"direction",'next');return _this12;}_createClass(SiblingCaretNext,[{key:"getNodeAtCaret",value:function getNodeAtCaret(){return this.origin.getNextSibling();}},{key:"insert",value:function insert(node){this.origin.insertAfter(node);return this;}}]);return SiblingCaretNext;}(AbstractSiblingCaret);var SiblingCaretPrevious=/*#__PURE__*/function(_AbstractSiblingCaret2){_inherits(SiblingCaretPrevious,_AbstractSiblingCaret2);var _super15=_createSuper(SiblingCaretPrevious);function SiblingCaretPrevious(){var _this13;_classCallCheck(this,SiblingCaretPrevious);for(var _len10=arguments.length,args=new Array(_len10),_key10=0;_key10<_len10;_key10++){args[_key10]=arguments[_key10];}_this13=_super15.call.apply(_super15,[this].concat(args));_defineProperty(_assertThisInitialized(_this13),"direction",'previous');return _this13;}_createClass(SiblingCaretPrevious,[{key:"getNodeAtCaret",value:function getNodeAtCaret(){return this.origin.getPreviousSibling();}},{key:"insert",value:function insert(node){this.origin.insertBefore(node);return this;}}]);return SiblingCaretPrevious;}(AbstractSiblingCaret);var TextPointCaretNext=/*#__PURE__*/function(_AbstractTextPointCar){_inherits(TextPointCaretNext,_AbstractTextPointCar);var _super16=_createSuper(TextPointCaretNext);function TextPointCaretNext(){var _this14;_classCallCheck(this,TextPointCaretNext);for(var _len11=arguments.length,args=new Array(_len11),_key11=0;_key11<_len11;_key11++){args[_key11]=arguments[_key11];}_this14=_super16.call.apply(_super16,[this].concat(args));_defineProperty(_assertThisInitialized(_this14),"direction",'next');return _this14;}_createClass(TextPointCaretNext,[{key:"getNodeAtCaret",value:function getNodeAtCaret(){return this.origin.getNextSibling();}},{key:"insert",value:function insert(node){this.origin.insertAfter(node);return this;}}]);return TextPointCaretNext;}(AbstractTextPointCaret);var TextPointCaretPrevious=/*#__PURE__*/function(_AbstractTextPointCar2){_inherits(TextPointCaretPrevious,_AbstractTextPointCar2);var _super17=_createSuper(TextPointCaretPrevious);function TextPointCaretPrevious(){var _this15;_classCallCheck(this,TextPointCaretPrevious);for(var _len12=arguments.length,args=new Array(_len12),_key12=0;_key12<_len12;_key12++){args[_key12]=arguments[_key12];}_this15=_super17.call.apply(_super17,[this].concat(args));_defineProperty(_assertThisInitialized(_this15),"direction",'previous');return _this15;}_createClass(TextPointCaretPrevious,[{key:"getNodeAtCaret",value:function getNodeAtCaret(){return this.origin.getPreviousSibling();}},{key:"insert",value:function insert(node){this.origin.insertBefore(node);return this;}}]);return TextPointCaretPrevious;}(AbstractTextPointCaret);var TEXT_CTOR={next:TextPointCaretNext,previous:TextPointCaretPrevious};var SIBLING_CTOR={next:SiblingCaretNext,previous:SiblingCaretPrevious};var CHILD_CTOR={next:ChildCaretFirst,previous:ChildCaretLast};/**
2650
+ * Get a caret that points at the next or previous sibling of the given origin node.
2651
+ *
2652
+ * @param origin The origin node
2653
+ * @param direction 'next' or 'previous'
2654
+ * @returns null if origin is null, otherwise a SiblingCaret for this origin and direction
2655
+ */function $getSiblingCaret(origin,direction){return origin?new SIBLING_CTOR[direction](origin):null;}/**
2656
+ * Construct a TextPointCaret
2657
+ *
2658
+ * @param origin The TextNode
2659
+ * @param direction The direction (next points to the end of the text, previous points to the beginning)
2660
+ * @param offset The offset into the text in absolute positive string coordinates (0 is the start)
2661
+ * @returns a TextPointCaret
2662
+ */function $getTextPointCaret(origin,direction,offset){return origin?new TEXT_CTOR[direction](origin,$getTextNodeOffset(origin,offset)):null;}/**
2663
+ * Get a normalized offset into a TextNode given a numeric offset or a
2664
+ * direction for which end of the string to use. Throws in dev if the offset
2665
+ * is not in the bounds of the text content size.
2666
+ *
2667
+ * @param origin a TextNode
2668
+ * @param offset An absolute offset into the TextNode string, or a direction for which end to use as the offset
2669
+ * @param mode If 'error' (the default) out of bounds offsets will be an error in dev. Otherwise it will clamp to a valid offset.
2670
+ * @returns An absolute offset into the TextNode string
2671
+ */function $getTextNodeOffset(origin,offset){var mode=arguments.length>2&&arguments[2]!==undefined?arguments[2]:'error';var size=origin.getTextContentSize();var numericOffset=offset==='next'?size:offset==='previous'?0:offset;if(numericOffset<0||numericOffset>size){if(!(mode==='clamp')){formatDevErrorMessage("$getTextNodeOffset: invalid offset ".concat(String(offset)," for size ").concat(String(size)," at key ").concat(origin.getKey()));}// Clamp invalid offsets in prod
2672
+ numericOffset=numericOffset<0?0:size;}return numericOffset;}/**
2673
+ * Construct a TextPointCaretSlice given a TextPointCaret and a signed distance. The
2674
+ * distance should be negative to slice text before the caret's offset, and positive
2675
+ * to slice text after the offset. The direction of the caret itself is not
2676
+ * relevant to the string coordinates when working with a TextPointCaretSlice
2677
+ * but mutation operations will preserve the direction.
2678
+ *
2679
+ * @param caret
2680
+ * @param distance
2681
+ * @returns TextPointCaretSlice
2682
+ */function $getTextPointCaretSlice(caret,distance){return new TextPointCaretSliceImpl(caret,distance);}/**
2683
+ * Get a caret that points at the first or last child of the given origin node,
2684
+ * which must be an ElementNode.
2685
+ *
2686
+ * @param origin The origin ElementNode
2687
+ * @param direction 'next' for first child or 'previous' for last child
2688
+ * @returns null if origin is null or not an ElementNode, otherwise a ChildCaret for this origin and direction
2689
+ */function $getChildCaret(origin,direction){return $isElementNode(origin)?new CHILD_CTOR[direction](origin):null;}/**
2690
+ * Gets the ChildCaret if one is possible at this caret origin, otherwise return the caret
2691
+ */function $getChildCaretOrSelf(caret){return caret&&caret.getChildCaret()||caret;}/**
2692
+ * Gets the adjacent caret, if not-null and if the origin of the adjacent caret is an ElementNode, then return
2693
+ * the ChildCaret. This can be used along with the getParentAdjacentCaret method to perform a full DFS
2694
+ * style traversal of the tree.
2695
+ *
2696
+ * @param caret The caret to start at
2697
+ */function $getAdjacentChildCaret(caret){return caret&&$getChildCaretOrSelf(caret.getAdjacentCaret());}_Symbol$iterator2=Symbol.iterator;var CaretRangeImpl=/*#__PURE__*/function(){function CaretRangeImpl(anchor,focus,direction){_classCallCheck(this,CaretRangeImpl);_defineProperty(this,"type",'node-caret-range');_defineProperty(this,"direction",void 0);_defineProperty(this,"anchor",void 0);_defineProperty(this,"focus",void 0);this.anchor=anchor;this.focus=focus;this.direction=direction;}_createClass(CaretRangeImpl,[{key:"getLatest",value:function getLatest(){var anchor=this.anchor.getLatest();var focus=this.focus.getLatest();return anchor===this.anchor&&focus===this.focus?this:new CaretRangeImpl(anchor,focus,this.direction);}},{key:"isCollapsed",value:function isCollapsed(){return this.anchor.isSamePointCaret(this.focus);}},{key:"getTextSlices",value:function getTextSlices(){var _this16=this;var getSlice=function getSlice(k){var caret=_this16[k].getLatest();return $isTextPointCaret(caret)?$getSliceFromTextPointCaret(caret,k):null;};var anchorSlice=getSlice('anchor');var focusSlice=getSlice('focus');if(anchorSlice&&focusSlice){var anchorCaret=anchorSlice.caret;var focusCaret=focusSlice.caret;if(anchorCaret.isSameNodeCaret(focusCaret)){return[$getTextPointCaretSlice(anchorCaret,focusCaret.offset-anchorCaret.offset),null];}}return[anchorSlice,focusSlice];}},{key:"iterNodeCarets",value:function iterNodeCarets(){var rootMode=arguments.length>0&&arguments[0]!==undefined?arguments[0]:'root';var anchor=$isTextPointCaret(this.anchor)?this.anchor.getSiblingCaret():this.anchor.getLatest();var focus=this.focus.getLatest();var isTextFocus=$isTextPointCaret(focus);var step=function step(state){return state.isSameNodeCaret(focus)?null:$getAdjacentChildCaret(state)||state.getParentCaret(rootMode);};return makeStepwiseIterator({hasNext:function hasNext(state){return state!==null&&!(isTextFocus&&focus.isSameNodeCaret(state));},initial:anchor.isSameNodeCaret(focus)?null:step(anchor),map:function map(state){return state;},step:step});}},{key:_Symbol$iterator2,value:function value(){return this.iterNodeCarets('root');}}]);return CaretRangeImpl;}();var TextPointCaretSliceImpl=/*#__PURE__*/function(){function TextPointCaretSliceImpl(caret,distance){_classCallCheck(this,TextPointCaretSliceImpl);_defineProperty(this,"type",'slice');_defineProperty(this,"caret",void 0);_defineProperty(this,"distance",void 0);this.caret=caret;this.distance=distance;}_createClass(TextPointCaretSliceImpl,[{key:"getSliceIndices",value:function getSliceIndices(){var distance=this.distance,offset=this.caret.offset;var offsetB=offset+distance;return offsetB<offset?[offsetB,offset]:[offset,offsetB];}},{key:"getTextContent",value:function getTextContent(){var _this$getSliceIndices=this.getSliceIndices(),_this$getSliceIndices2=_slicedToArray(_this$getSliceIndices,2),startIndex=_this$getSliceIndices2[0],endIndex=_this$getSliceIndices2[1];return this.caret.origin.getTextContent().slice(startIndex,endIndex);}},{key:"getTextContentSize",value:function getTextContentSize(){return Math.abs(this.distance);}},{key:"removeTextSlice",value:function removeTextSlice(){var _this$caret=this.caret,origin=_this$caret.origin,direction=_this$caret.direction;var _this$getSliceIndices3=this.getSliceIndices(),_this$getSliceIndices4=_slicedToArray(_this$getSliceIndices3,2),indexStart=_this$getSliceIndices4[0],indexEnd=_this$getSliceIndices4[1];var text=origin.getTextContent();return $getTextPointCaret(origin.setTextContent(text.slice(0,indexStart)+text.slice(indexEnd)),direction,indexStart);}}]);return TextPointCaretSliceImpl;}();function $getSliceFromTextPointCaret(caret,anchorOrFocus){var direction=caret.direction,origin=caret.origin;var offsetB=$getTextNodeOffset(origin,anchorOrFocus==='focus'?flipDirection(direction):direction);return $getTextPointCaretSlice(caret,offsetB-caret.offset);}/**
2698
+ * Guard to check for a TextPointCaretSlice
2699
+ *
2700
+ * @param caretOrSlice A caret or slice
2701
+ * @returns true if caretOrSlice is a TextPointCaretSlice
2702
+ */function $isTextPointCaretSlice(caretOrSlice){return caretOrSlice instanceof TextPointCaretSliceImpl;}/**
2703
+ * Construct a CaretRange that starts at anchor and goes to the end of the
2704
+ * document in the anchor caret's direction.
2705
+ */function $extendCaretToRange(anchor){return $getCaretRange(anchor,$getSiblingCaret($getRoot(),anchor.direction));}/**
2706
+ * Construct a collapsed CaretRange that starts and ends at anchor.
2707
+ */function $getCollapsedCaretRange(anchor){return $getCaretRange(anchor,anchor);}/**
2708
+ * Construct a CaretRange from anchor and focus carets pointing in the
2709
+ * same direction. In order to get the expected behavior,
2710
+ * the anchor must point towards the focus or be the same point.
2711
+ *
2712
+ * In the 'next' direction the anchor should be at or before the
2713
+ * focus in the document. In the 'previous' direction the anchor
2714
+ * should be at or after the focus in the document
2715
+ * (similar to a backwards RangeSelection).
2716
+ *
2717
+ * @param anchor
2718
+ * @param focus
2719
+ * @returns a CaretRange
2720
+ */function $getCaretRange(anchor,focus){if(!(anchor.direction===focus.direction)){formatDevErrorMessage("$getCaretRange: anchor and focus must be in the same direction");}return new CaretRangeImpl(anchor,focus,anchor.direction);}/**
2721
+ * A generalized utility for creating a stepwise iterator
2722
+ * based on:
2723
+ *
2724
+ * - an initial state
2725
+ * - a stop guard that returns true if the iteration is over, this
2726
+ * is typically used to detect a sentinel value such as null or
2727
+ * undefined from the state but may return true for other conditions
2728
+ * as well
2729
+ * - a step function that advances the state (this will be called
2730
+ * after map each time next() is called to prepare the next state)
2731
+ * - a map function that will be called that may transform the state
2732
+ * before returning it. It will only be called once for each next()
2733
+ * call when stop(state) === false
2734
+ *
2735
+ * @param config
2736
+ * @returns An IterableIterator
2737
+ */function makeStepwiseIterator(config){var initial=config.initial,hasNext=config.hasNext,step=config.step,map=config.map;var state=initial;return _defineProperty(_defineProperty({},Symbol.iterator,function(){return this;}),"next",function next(){if(!hasNext(state)){return{done:true,value:undefined};}var rval={done:false,value:map(state)};state=step(state);return rval;});}function compareNumber(a,b){return Math.sign(a-b);}/**
2738
+ * A total ordering for `PointCaret<'next'>`, based on
2739
+ * the same order that a {@link CaretRange} would iterate
2740
+ * them.
2741
+ *
2742
+ * For a given origin node:
2743
+ * - ChildCaret comes before SiblingCaret
2744
+ * - TextPointCaret comes before SiblingCaret
2745
+ *
2746
+ * An exception is thrown when a and b do not have any
2747
+ * common ancestor.
2748
+ *
2749
+ * This ordering is a sort of mix of pre-order and post-order
2750
+ * because each ElementNode will show up as a ChildCaret
2751
+ * on 'enter' (pre-order) and a SiblingCaret on 'leave' (post-order).
2752
+ *
2753
+ * @param a
2754
+ * @param b
2755
+ * @returns -1 if a comes before b, 0 if a and b are the same, or 1 if a comes after b
2756
+ */function $comparePointCaretNext(a,b){var compare=$getCommonAncestor(a.origin,b.origin);if(!(compare!==null)){formatDevErrorMessage("$comparePointCaretNext: a (key ".concat(a.origin.getKey(),") and b (key ").concat(b.origin.getKey(),") do not have a common ancestor"));}switch(compare.type){case'same':{var aIsText=a.type==='text';var bIsText=b.type==='text';return aIsText&&bIsText?compareNumber(a.offset,b.offset):a.type===b.type?0:aIsText?-1:bIsText?1:a.type==='child'?-1:1;}case'ancestor':{return a.type==='child'?-1:1;}case'descendant':{return b.type==='child'?1:-1;}case'branch':{return $getCommonAncestorResultBranchOrder(compare);}}}/**
2757
+ * Return the ordering of siblings in a {@link CommonAncestorResultBranch}
2758
+ * @param compare Returns -1 if a precedes b, 1 otherwise
2759
+ */function $getCommonAncestorResultBranchOrder(compare){var a=compare.a,b=compare.b;var aKey=a.__key;var bKey=b.__key;var na=a;var nb=b;for(;na&&nb;na=na.getNextSibling(),nb=nb.getNextSibling()){if(na.__key===bKey){return-1;}else if(nb.__key===aKey){return 1;}}return na===null?1:-1;}/**
2760
+ * The two compared nodes are the same
2761
+ */ /**
2762
+ * Node a was a descendant of node b, and not the same node
2763
+ */ /**
2764
+ * Node a is an ancestor of node b, and not the same node
2765
+ */ /**
2766
+ * Node a and node b have a common ancestor but are on different branches,
2767
+ * the `a` and `b` properties of this result are the ancestors of a and b
2768
+ * that are children of the commonAncestor. Since they are siblings, their
2769
+ * positions are comparable to determine order in the document.
2770
+ */ /**
2771
+ * The result of comparing two nodes that share some common ancestor
2772
+ */function $isSameNode(reference,other){return other.is(reference);}function $initialElementTuple(node){return $isElementNode(node)?[node.getLatest(),null]:[node.getParent(),node.getLatest()];}/**
2773
+ * Find a common ancestor of a and b and return a detailed result object,
2774
+ * or null if there is no common ancestor between the two nodes.
2775
+ *
2776
+ * The result object will have a commonAncestor property, and the other
2777
+ * properties can be used to quickly compare these positions in the tree.
2778
+ *
2779
+ * @param a A LexicalNode
2780
+ * @param b A LexicalNode
2781
+ * @returns A comparison result between the two nodes or null if they have no common ancestor
2782
+ */function $getCommonAncestor(a,b){if(a.is(b)){return{commonAncestor:a,type:'same'};}// Map of parent -> child entries based on a and its ancestors
2783
+ var aMap=new Map();for(var _$initialElementTuple=$initialElementTuple(a),_$initialElementTuple2=_slicedToArray(_$initialElementTuple,2),parent=_$initialElementTuple2[0],child=_$initialElementTuple2[1];parent;child=parent,parent=parent.getParent()){aMap.set(parent,child);}for(var _$initialElementTuple3=$initialElementTuple(b),_$initialElementTuple4=_slicedToArray(_$initialElementTuple3,2),_parent2=_$initialElementTuple4[0],_child4=_$initialElementTuple4[1];_parent2;_child4=_parent2,_parent2=_parent2.getParent()){var aChild=aMap.get(_parent2);if(aChild===undefined);else if(aChild===null){// a is the ancestor
2784
+ if(!$isSameNode(a,_parent2)){formatDevErrorMessage("$originComparison: ancestor logic error");}return{commonAncestor:_parent2,type:'ancestor'};}else if(_child4===null){// b is the ancestor
2785
+ if(!$isSameNode(b,_parent2)){formatDevErrorMessage("$originComparison: descendant logic error");}return{commonAncestor:_parent2,type:'descendant'};}else{if(!(($isElementNode(aChild)||$isSameNode(a,aChild))&&($isElementNode(_child4)||$isSameNode(b,_child4))&&_parent2.is(aChild.getParent())&&_parent2.is(_child4.getParent()))){formatDevErrorMessage("$originComparison: branch logic error");}return{a:aChild,b:_child4,commonAncestor:_parent2,type:'branch'};}}return null;}/**
2786
+ * @param point
2787
+ * @returns a PointCaret for the point
2788
+ */function $caretFromPoint(point,direction){var type=point.type,key=point.key,offset=point.offset;var node=$getNodeByKeyOrThrow(point.key);if(type==='text'){if(!$isTextNode(node)){formatDevErrorMessage("$caretFromPoint: Node with type ".concat(node.getType()," and key ").concat(key," that does not inherit from TextNode encountered for text point"));}return $getTextPointCaret(node,direction,offset);}if(!$isElementNode(node)){formatDevErrorMessage("$caretFromPoint: Node with type ".concat(node.getType()," and key ").concat(key," that does not inherit from ElementNode encountered for element point"));}return $getChildCaretAtIndex(node,point.offset,direction);}/**
2789
+ * Update the given point in-place from the PointCaret
2790
+ *
2791
+ * @param point the point to set
2792
+ * @param caret the caret to set the point from
2793
+ */function $setPointFromCaret(point,caret){var origin=caret.origin,direction=caret.direction;var isNext=direction==='next';if($isTextPointCaret(caret)){point.set(origin.getKey(),caret.offset,'text');}else if($isSiblingCaret(caret)){if($isTextNode(origin)){point.set(origin.getKey(),$getTextNodeOffset(origin,direction),'text');}else{point.set(origin.getParentOrThrow().getKey(),origin.getIndexWithinParent()+(isNext?1:0),'element');}}else{if(!($isChildCaret(caret)&&$isElementNode(origin))){formatDevErrorMessage("$setPointFromCaret: exhaustiveness check");}point.set(origin.getKey(),isNext?0:origin.getChildrenSize(),'element');}}/**
2794
+ * Set a RangeSelection on the editor from the given CaretRange
2795
+ *
2796
+ * @returns The new RangeSelection
2797
+ */function $setSelectionFromCaretRange(caretRange){var currentSelection=$getSelection();var selection=$isRangeSelection(currentSelection)?currentSelection:$createRangeSelection();$updateRangeSelectionFromCaretRange(selection,caretRange);$setSelection(selection);return selection;}/**
2798
+ * Update the points of a RangeSelection based on the given PointCaret.
2799
+ */function $updateRangeSelectionFromCaretRange(selection,caretRange){$setPointFromCaret(selection.anchor,caretRange.anchor);$setPointFromCaret(selection.focus,caretRange.focus);}/**
2800
+ * Get a pair of carets for a RangeSelection.
2801
+ *
2802
+ * If the focus is before the anchor, then the direction will be
2803
+ * 'previous', otherwise the direction will be 'next'.
2804
+ */function $caretRangeFromSelection(selection){var anchor=selection.anchor,focus=selection.focus;var anchorCaret=$caretFromPoint(anchor,'next');var focusCaret=$caretFromPoint(focus,'next');var direction=$comparePointCaretNext(anchorCaret,focusCaret)<=0?'next':'previous';return $getCaretRange($getCaretInDirection(anchorCaret,direction),$getCaretInDirection(focusCaret,direction));}/**
2805
+ * Given a SiblingCaret we can always compute a caret that points to the
2806
+ * origin of that caret in the same direction. The adjacent caret of the
2807
+ * returned caret will be equivalent to the given caret.
2808
+ *
2809
+ * @example
2810
+ * ```ts
2811
+ * siblingCaret.is($rewindSiblingCaret(siblingCaret).getAdjacentCaret())
2812
+ * ```
2813
+ *
2814
+ * @param caret The caret to "rewind"
2815
+ * @returns A new caret (ChildCaret or SiblingCaret) with the same direction
2816
+ */function $rewindSiblingCaret(caret){var direction=caret.direction,origin=caret.origin;// Rotate the direction around the origin and get the adjacent node
2817
+ var rewindOrigin=$getSiblingCaret(origin,flipDirection(direction)).getNodeAtCaret();return rewindOrigin?$getSiblingCaret(rewindOrigin,direction):$getChildCaret(origin.getParentOrThrow(),direction);}function $getAnchorCandidates(anchor){var rootMode=arguments.length>1&&arguments[1]!==undefined?arguments[1]:'root';// These candidates will be the anchor itself, the pointer to the anchor (if different), and then any parents of that
2818
+ var carets=[anchor];for(var parent=$isChildCaret(anchor)?anchor.getParentCaret(rootMode):anchor.getSiblingCaret();parent!==null;parent=parent.getParentCaret(rootMode)){carets.push($rewindSiblingCaret(parent));}return carets;}function $isCaretAttached(caret){return!!caret&&caret.origin.isAttached();}/**
2819
+ * Remove all text and nodes in the given range. If the range spans multiple
2820
+ * blocks then the remaining contents of the later block will be merged with
2821
+ * the earlier block.
2822
+ *
2823
+ * @param initialRange The range to remove text and nodes from
2824
+ * @param sliceMode If 'preserveEmptyTextPointCaret' it will leave an empty TextPointCaret at the anchor for insert if one exists, otherwise empty slices will be removed
2825
+ * @returns The new collapsed range (biased towards the earlier node)
2826
+ */function $removeTextFromCaretRange(initialRange){var sliceMode=arguments.length>1&&arguments[1]!==undefined?arguments[1]:'removeEmptySlices';if(initialRange.isCollapsed()){return initialRange;}// Always process removals in document order
2827
+ var rootMode='root';var nextDirection='next';var sliceState=sliceMode;var range=$getCaretRangeInDirection(initialRange,nextDirection);var anchorCandidates=$getAnchorCandidates(range.anchor,rootMode);var focusCandidates=$getAnchorCandidates(range.focus.getFlipped(),rootMode);// Mark the start of each ElementNode
2828
+ var seenStart=new Set();// Queue removals since removing the only child can cascade to having
2829
+ // a parent remove itself which will affect iteration
2830
+ var removedNodes=[];var _iterator35=_createForOfIteratorHelper(range.iterNodeCarets(rootMode)),_step35;try{for(_iterator35.s();!(_step35=_iterator35.n()).done;){var caret=_step35.value;if($isChildCaret(caret)){seenStart.add(caret.origin.getKey());}else if($isSiblingCaret(caret)){var origin=caret.origin;if(!$isElementNode(origin)||seenStart.has(origin.getKey())){removedNodes.push(origin);}}}}catch(err){_iterator35.e(err);}finally{_iterator35.f();}for(var _i13=0,_removedNodes=removedNodes;_i13<_removedNodes.length;_i13++){var node=_removedNodes[_i13];node.remove();}// Splice text at the anchor and/or origin.
2831
+ // If the text is entirely selected then it is removed (unless it is the first slice and sliceMode is preserveEmptyTextSliceCaret).
2832
+ // If it's a token with a non-empty selection then it is removed.
2833
+ // Segmented nodes will be copied to a plain text node with the same format
2834
+ // and style and set to normal mode.
2835
+ var _iterator36=_createForOfIteratorHelper(range.getTextSlices()),_step36;try{for(_iterator36.s();!(_step36=_iterator36.n()).done;){var slice=_step36.value;if(!slice){continue;}var _origin2=slice.caret.origin;var contentSize=_origin2.getTextContentSize();var caretBefore=$rewindSiblingCaret($getSiblingCaret(_origin2,nextDirection));var mode=_origin2.getMode();if(Math.abs(slice.distance)===contentSize&&sliceState==='removeEmptySlices'||mode==='token'&&slice.distance!==0){// anchorCandidates[1] should still be valid, it is caretBefore
2836
+ caretBefore.remove();}else if(slice.distance!==0){sliceState='removeEmptySlices';var nextCaret=slice.removeTextSlice();var sliceOrigin=slice.caret.origin;if(mode==='segmented'){var src=nextCaret.origin;var plainTextNode=$createTextNode(src.getTextContent()).setStyle(src.getStyle()).setFormat(src.getFormat());caretBefore.replaceOrInsert(plainTextNode);nextCaret=$getTextPointCaret(plainTextNode,nextDirection,nextCaret.offset);}if(sliceOrigin.is(anchorCandidates[0].origin)){anchorCandidates[0]=nextCaret;}if(sliceOrigin.is(focusCandidates[0].origin)){focusCandidates[0]=nextCaret.getFlipped();}}}// Find the deepest anchor and focus candidates that are
2837
+ // still attached
2838
+ }catch(err){_iterator36.e(err);}finally{_iterator36.f();}var anchorCandidate;var focusCandidate;var _iterator37=_createForOfIteratorHelper(anchorCandidates),_step37;try{for(_iterator37.s();!(_step37=_iterator37.n()).done;){var candidate=_step37.value;if($isCaretAttached(candidate)){anchorCandidate=$normalizeCaret(candidate);break;}}}catch(err){_iterator37.e(err);}finally{_iterator37.f();}var _iterator38=_createForOfIteratorHelper(focusCandidates),_step38;try{for(_iterator38.s();!(_step38=_iterator38.n()).done;){var _candidate=_step38.value;if($isCaretAttached(_candidate)){focusCandidate=$normalizeCaret(_candidate);break;}}// Merge blocks if necessary
2839
+ }catch(err){_iterator38.e(err);}finally{_iterator38.f();}var mergeTargets=$getBlockMergeTargets(anchorCandidate,focusCandidate,seenStart);if(mergeTargets){var _mergeTargets=_slicedToArray(mergeTargets,2),anchorBlock=_mergeTargets[0],focusBlock=_mergeTargets[1];// always merge blocks later in the document with
2840
+ // blocks earlier in the document
2841
+ $getChildCaret(anchorBlock,'previous').splice(0,focusBlock.getChildren());focusBlock.remove();}// note this caret can be in either direction
2842
+ var bestCandidate=[anchorCandidate,focusCandidate].concat(_toConsumableArray(anchorCandidates),_toConsumableArray(focusCandidates)).find($isCaretAttached);if(bestCandidate){var anchor=$getCaretInDirection($normalizeCaret(bestCandidate),initialRange.direction);return $getCollapsedCaretRange(anchor);}{formatDevErrorMessage("$removeTextFromCaretRange: selection was lost, could not find a new anchor given candidates with keys: ".concat(JSON.stringify(anchorCandidates.map(function(n){return n.origin.__key;}))));}}/**
2843
+ * Determine if the two caret origins are in distinct blocks that
2844
+ * should be merged.
2845
+ *
2846
+ * The returned block pair will be the closest blocks to their
2847
+ * common ancestor, and must be no shadow roots between
2848
+ * the blocks and their respective carets. If two distinct
2849
+ * blocks matching this criteria are not found, this will return
2850
+ * null.
2851
+ */function $getBlockMergeTargets(anchor,focus,seenStart){if(!anchor||!focus){return null;}var anchorParent=anchor.getParentAtCaret();var focusParent=focus.getParentAtCaret();if(!anchorParent||!focusParent){return null;}// TODO refactor when we have a better primitive for common ancestor
2852
+ var anchorElements=anchorParent.getParents().reverse();anchorElements.push(anchorParent);var focusElements=focusParent.getParents().reverse();focusElements.push(focusParent);var maxLen=Math.min(anchorElements.length,focusElements.length);var commonAncestorCount;for(commonAncestorCount=0;commonAncestorCount<maxLen&&anchorElements[commonAncestorCount]===focusElements[commonAncestorCount];commonAncestorCount++){// just traverse the ancestors
2853
+ }var $getBlock=function $getBlock(arr,predicate){var block;for(var i=commonAncestorCount;i<arr.length;i++){var ancestor=arr[i];if($isRootOrShadowRoot(ancestor)){return;}else if(!block&&predicate(ancestor)){block=ancestor;}}return block;};var anchorBlock=$getBlock(anchorElements,INTERNAL_$isBlock);var focusBlock=anchorBlock&&$getBlock(focusElements,function(node){return seenStart.has(node.getKey())&&INTERNAL_$isBlock(node);});return anchorBlock&&focusBlock?[anchorBlock,focusBlock]:null;}/**
2854
+ * Return the deepest ChildCaret that has initialCaret's origin
2855
+ * as an ancestor, or initialCaret if the origin is not an ElementNode
2856
+ * or is already the deepest ChildCaret.
2857
+ *
2858
+ * This is generally used when normalizing because there is
2859
+ * "zero distance" between these locations.
2860
+ *
2861
+ * @param initialCaret
2862
+ * @returns Either a deeper ChildCaret or the given initialCaret
2863
+ */function $getDeepestChildOrSelf(initialCaret){var caret=initialCaret;while($isChildCaret(caret)){var adjacent=$getAdjacentChildCaret(caret);if(!$isChildCaret(adjacent)){break;}caret=adjacent;}return caret;}/**
2864
+ * Normalize a caret to the deepest equivalent PointCaret.
2865
+ * This will return a TextPointCaret with the offset set according
2866
+ * to the direction if given a caret with a TextNode origin
2867
+ * or a caret with an ElementNode origin with the deepest ChildCaret
2868
+ * having an adjacent TextNode.
2869
+ *
2870
+ * If given a TextPointCaret, it will be returned, as no normalization
2871
+ * is required when an offset is already present.
2872
+ *
2873
+ * @param initialCaret
2874
+ * @returns The normalized PointCaret
2875
+ */function $normalizeCaret(initialCaret){var caret=$getDeepestChildOrSelf(initialCaret.getLatest());var direction=caret.direction;if($isTextNode(caret.origin)){return $isTextPointCaret(caret)?caret:$getTextPointCaret(caret.origin,direction,direction);}var adj=caret.getAdjacentCaret();return $isSiblingCaret(adj)&&$isTextNode(adj.origin)?$getTextPointCaret(adj.origin,direction,flipDirection(direction)):caret;}/**
2876
+ * Determine whether the TextPointCaret's offset can be extended further without leaving the TextNode.
2877
+ * Returns false if the given caret is not a TextPointCaret or the offset can not be moved further in
2878
+ * direction.
2879
+ *
2880
+ * @param caret A PointCaret
2881
+ * @returns true if caret is a TextPointCaret with an offset that is not at the end of the text given the direction.
2882
+ */function $isExtendableTextPointCaret(caret){return $isTextPointCaret(caret)&&caret.offset!==$getTextNodeOffset(caret.origin,caret.direction);}/**
2883
+ * Return the caret if it's in the given direction, otherwise return
2884
+ * caret.getFlipped().
2885
+ *
2886
+ * @param caret Any PointCaret
2887
+ * @param direction The desired direction
2888
+ * @returns A PointCaret in direction
2889
+ */function $getCaretInDirection(caret,direction){return caret.direction===direction?caret:caret.getFlipped();}/**
2890
+ * Return the range if it's in the given direction, otherwise
2891
+ * construct a new range using a flipped focus as the anchor
2892
+ * and a flipped anchor as the focus. This transformation
2893
+ * preserves the section of the document that it's working
2894
+ * with, but reverses the order of iteration.
2895
+ *
2896
+ * @param range Any CaretRange
2897
+ * @param direction The desired direction
2898
+ * @returns A CaretRange in direction
2899
+ */function $getCaretRangeInDirection(range,direction){if(range.direction===direction){return range;}return $getCaretRange(// focus and anchor get flipped here
2900
+ $getCaretInDirection(range.focus,direction),$getCaretInDirection(range.anchor,direction));}/**
2901
+ * Get a caret pointing at the child at the given index, or the last
2902
+ * caret in that node if out of bounds.
2903
+ *
2904
+ * @param parent An ElementNode
2905
+ * @param index The index of the origin for the caret
2906
+ * @returns A caret pointing towards the node at that index
2907
+ */function $getChildCaretAtIndex(parent,index,direction){var caret=$getChildCaret(parent,'next');for(var i=0;i<index;i++){var nextCaret=caret.getAdjacentCaret();if(nextCaret===null){break;}caret=nextCaret;}return $getCaretInDirection(caret,direction);}/**
2908
+ * Returns the Node sibling when this exists, otherwise the closest parent sibling. For example
2909
+ * R -> P -> T1, T2
2910
+ * -> P2
2911
+ * returns T2 for node T1, P2 for node T2, and null for node P2.
2912
+ * @param startCaret The initial caret
2913
+ * @param rootMode The root mode, 'root' (default) or 'shadowRoot'
2914
+ * @returns An array (tuple) containing the found caret and the depth difference, or null, if this node doesn't exist.
2915
+ */function $getAdjacentSiblingOrParentSiblingCaret(startCaret){var rootMode=arguments.length>1&&arguments[1]!==undefined?arguments[1]:'root';var depthDiff=0;var caret=startCaret;var nextCaret=$getAdjacentChildCaret(caret);while(nextCaret===null){depthDiff--;nextCaret=caret.getParentCaret(rootMode);if(!nextCaret){return null;}caret=nextCaret;nextCaret=$getAdjacentChildCaret(caret);}return nextCaret&&[nextCaret,depthDiff];}/**
2916
+ * Get the adjacent nodes to initialCaret in the given direction.
2917
+ *
2918
+ * @example
2919
+ * ```ts
2920
+ * expect($getAdjacentNodes($getChildCaret(parent, 'next'))).toEqual(parent.getChildren());
2921
+ * expect($getAdjacentNodes($getChildCaret(parent, 'previous'))).toEqual(parent.getChildren().reverse());
2922
+ * expect($getAdjacentNodes($getSiblingCaret(node, 'next'))).toEqual(node.getNextSiblings());
2923
+ * expect($getAdjacentNodes($getSiblingCaret(node, 'previous'))).toEqual(node.getPreviousSiblings().reverse());
2924
+ * ```
2925
+ *
2926
+ * @param initialCaret The caret to start at (the origin will not be included)
2927
+ * @returns An array of siblings.
2928
+ */function $getAdjacentNodes(initialCaret){var siblings=[];for(var caret=initialCaret.getAdjacentCaret();caret;caret=caret.getAdjacentCaret()){siblings.push(caret.origin);}return siblings;}function $splitTextPointCaret(textPointCaret){var origin=textPointCaret.origin,offset=textPointCaret.offset,direction=textPointCaret.direction;if(offset===$getTextNodeOffset(origin,direction)){return textPointCaret.getSiblingCaret();}else if(offset===$getTextNodeOffset(origin,flipDirection(direction))){return $rewindSiblingCaret(textPointCaret.getSiblingCaret());}var _origin$splitText=origin.splitText(offset),_origin$splitText2=_slicedToArray(_origin$splitText,1),textNode=_origin$splitText2[0];if(!$isTextNode(textNode)){formatDevErrorMessage("$splitTextPointCaret: splitText must return at least one TextNode");}return $getCaretInDirection($getSiblingCaret(textNode,'next'),direction);}function $alwaysSplit(_node,_edge){return true;}/**
2929
+ * Split a node at a PointCaret and return a NodeCaret at that point, or null if the
2930
+ * node can't be split. This is non-recursive and will only perform at most one split.
2931
+ *
2932
+ * @returns The NodeCaret pointing to the location of the split (or null if a split is not possible)
2933
+ */function $splitAtPointCaretNext(pointCaret){var _ref11=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{},_ref11$$copyElementNo=_ref11.$copyElementNode,$copyElementNode=_ref11$$copyElementNo===void 0?$copyNode:_ref11$$copyElementNo,_ref11$$splitTextPoin=_ref11.$splitTextPointCaretNext,$splitTextPointCaretNext=_ref11$$splitTextPoin===void 0?$splitTextPointCaret:_ref11$$splitTextPoin,_ref11$rootMode=_ref11.rootMode,rootMode=_ref11$rootMode===void 0?'shadowRoot':_ref11$rootMode,_ref11$$shouldSplit=_ref11.$shouldSplit,$shouldSplit=_ref11$$shouldSplit===void 0?$alwaysSplit:_ref11$$shouldSplit;if($isTextPointCaret(pointCaret)){return $splitTextPointCaretNext(pointCaret);}var parentCaret=pointCaret.getParentCaret(rootMode);if(parentCaret){var origin=parentCaret.origin;if($isChildCaret(pointCaret)&&!(origin.canBeEmpty()&&$shouldSplit(origin,'first'))){// No split necessary, the left side would be empty
2934
+ return $rewindSiblingCaret(parentCaret);}var siblings=$getAdjacentNodes(pointCaret);if(siblings.length>0||origin.canBeEmpty()&&$shouldSplit(origin,'last')){// Split and insert the siblings into the new tree
2935
+ parentCaret.insert($copyElementNode(origin).splice(0,0,siblings));}}return parentCaret;}/**
2936
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
2937
+ *
2938
+ * This source code is licensed under the MIT license found in the
2939
+ * LICENSE file in the root directory of this source tree.
2940
+ *
2941
+ */ /**
2942
+ * @experimental
2943
+ * Define a LexicalExtension from the given object literal. TypeScript will
2944
+ * infer Config and Name in most cases, but you may want to use
2945
+ * {@link safeCast} for config if there are default fields or varying types.
2946
+ *
2947
+ * @param extension - The LexicalExtension
2948
+ * @returns The unmodified extension argument (this is only an inference helper)
2949
+ *
2950
+ * @example
2951
+ * Basic example
2952
+ * ```ts
2953
+ * export const MyExtension = defineExtension({
2954
+ * // Extension names must be unique in an editor
2955
+ * name: "my",
2956
+ * nodes: [MyNode],
2957
+ * });
2958
+ * ```
2959
+ *
2960
+ * @example
2961
+ * Extension with optional configuration
2962
+ * ```ts
2963
+ * export interface ConfigurableConfig {
2964
+ * optional?: string;
2965
+ * required: number;
2966
+ * }
2967
+ * export const ConfigurableExtension = defineExtension({
2968
+ * name: "configurable",
2969
+ * // The Extension's config must satisfy the full config type,
2970
+ * // but using the Extension as a dependency never requires
2971
+ * // configuration and any partial of the config can be specified
2972
+ * config: safeCast<ConfigurableConfig>({ required: 1 }),
2973
+ * });
2974
+ * ```
2975
+ *
2976
+ * @__NO_SIDE_EFFECTS__
2977
+ */function defineExtension(extension){return extension;}/**
2978
+ * @experimental
2979
+ * Override a partial of the configuration of an Extension, to be used
2980
+ * in the dependencies array of another extension, or as
2981
+ * an argument to {@link buildEditorFromExtensions}.
2982
+ *
2983
+ * Before building the editor, configurations will be merged using
2984
+ * `extension.mergeConfig(extension, config)` or {@link shallowMergeConfig} if
2985
+ * this is not directly implemented by the Extension.
2986
+ *
2987
+ * @param args - An extension followed by one or more config partials for that extension
2988
+ * @returns `[extension, config, ...configs]`
2989
+ *
2990
+ * @example
2991
+ * ```ts
2992
+ * export const ReactDecoratorExtension = defineExtension({
2993
+ * name: "react-decorator",
2994
+ * dependencies: [
2995
+ * configExtension(ReactExtension, {
2996
+ * decorators: [<ReactDecorator />]
2997
+ * }),
2998
+ * ],
2999
+ * });
3000
+ * ```
3001
+ *
3002
+ * @__NO_SIDE_EFFECTS__
3003
+ */function configExtension(){for(var _len13=arguments.length,args=new Array(_len13),_key13=0;_key13<_len13;_key13++){args[_key13]=arguments[_key13];}return args;}/**
3004
+ * @experimental
3005
+ * Used to declare a peer dependency of an extension in a type-safe way,
3006
+ * requires the type parameter. The most common use case for peer dependencies
3007
+ * is to avoid a direct import dependency, so you would want to use a
3008
+ * type import or the import type (shown in below examples).
3009
+ *
3010
+ * @param name - The extension's name
3011
+ * @param config - An optional config override
3012
+ * @returns NormalizedPeerDependency
3013
+ *
3014
+ * @example
3015
+ * ```ts
3016
+ * import type {FooExtension} from "foo";
3017
+ *
3018
+ * export const PeerExtension = defineExtension({
3019
+ * name: 'PeerExtension',
3020
+ * peerDependencies: [
3021
+ * declarePeerDependency<FooExtension>("foo"),
3022
+ * declarePeerDependency<typeof import("bar").BarExtension>("bar", {config: "bar"}),
3023
+ * ],
3024
+ * });
3025
+ * ```
3026
+ *
3027
+ * @__NO_SIDE_EFFECTS__
3028
+ */function declarePeerDependency(name,config){return[name,config];}/**
3029
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3030
+ *
3031
+ * This source code is licensed under the MIT license found in the
3032
+ * LICENSE file in the root directory of this source tree.
3033
+ *
3034
+ */ /**
3035
+ * Explicitly and safely cast a value to a specific type when inference or
3036
+ * satisfies isn't going to work as expected (often useful for the config
3037
+ * property with {@link defineExtension})
3038
+ *
3039
+ * @__NO_SIDE_EFFECTS__
3040
+ */function safeCast(value){return value;}/**
3041
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3042
+ *
3043
+ * This source code is licensed under the MIT license found in the
3044
+ * LICENSE file in the root directory of this source tree.
3045
+ *
3046
+ */ /**
3047
+ * The default merge strategy for extension configuration is a shallow merge.
3048
+ *
3049
+ * @param config - A full config
3050
+ * @param overrides - A partial config of overrides
3051
+ * @returns config if there are no overrides, otherwise `{...config, ...overrides}`
3052
+ */function shallowMergeConfig(config,overrides){if(!overrides||config===overrides){return config;}for(var k in overrides){if(config[k]!==overrides[k]){return _objectSpread(_objectSpread({},config),overrides);}}return config;}exports.$addUpdateTag=$addUpdateTag;exports.$applyNodeReplacement=$applyNodeReplacement;exports.$caretFromPoint=$caretFromPoint;exports.$caretRangeFromSelection=$caretRangeFromSelection;exports.$cloneWithProperties=$cloneWithProperties;exports.$cloneWithPropertiesEphemeral=$cloneWithPropertiesEphemeral;exports.$comparePointCaretNext=$comparePointCaretNext;exports.$copyNode=$copyNode;exports.$create=$create;exports.$createLineBreakNode=$createLineBreakNode;exports.$createNodeSelection=$createNodeSelection;exports.$createParagraphNode=$createParagraphNode;exports.$createPoint=$createPoint;exports.$createRangeSelection=$createRangeSelection;exports.$createRangeSelectionFromDom=$createRangeSelectionFromDom;exports.$createTabNode=$createTabNode;exports.$createTextNode=$createTextNode;exports.$extendCaretToRange=$extendCaretToRange;exports.$findMatchingParent=$findMatchingParent;exports.$getAdjacentChildCaret=$getAdjacentChildCaret;exports.$getAdjacentNode=$getAdjacentNode;exports.$getAdjacentSiblingOrParentSiblingCaret=$getAdjacentSiblingOrParentSiblingCaret;exports.$getCaretInDirection=$getCaretInDirection;exports.$getCaretRange=$getCaretRange;exports.$getCaretRangeInDirection=$getCaretRangeInDirection;exports.$getCharacterOffsets=$getCharacterOffsets;exports.$getChildCaret=$getChildCaret;exports.$getChildCaretAtIndex=$getChildCaretAtIndex;exports.$getChildCaretOrSelf=$getChildCaretOrSelf;exports.$getCollapsedCaretRange=$getCollapsedCaretRange;exports.$getCommonAncestor=$getCommonAncestor;exports.$getCommonAncestorResultBranchOrder=$getCommonAncestorResultBranchOrder;exports.$getEditor=$getEditor;exports.$getNearestNodeFromDOMNode=$getNearestNodeFromDOMNode;exports.$getNearestRootOrShadowRoot=$getNearestRootOrShadowRoot;exports.$getNodeByKey=$getNodeByKey;exports.$getNodeByKeyOrThrow=$getNodeByKeyOrThrow;exports.$getNodeFromDOMNode=$getNodeFromDOMNode;exports.$getPreviousSelection=$getPreviousSelection;exports.$getRoot=$getRoot;exports.$getSelection=$getSelection;exports.$getSiblingCaret=$getSiblingCaret;exports.$getState=$getState;exports.$getStateChange=$getStateChange;exports.$getTextContent=$getTextContent;exports.$getTextNodeOffset=$getTextNodeOffset;exports.$getTextPointCaret=$getTextPointCaret;exports.$getTextPointCaretSlice=$getTextPointCaretSlice;exports.$getWritableNodeState=$getWritableNodeState;exports.$hasAncestor=$hasAncestor;exports.$hasUpdateTag=$hasUpdateTag;exports.$insertNodes=$insertNodes;exports.$isBlockElementNode=$isBlockElementNode;exports.$isChildCaret=$isChildCaret;exports.$isDecoratorNode=$isDecoratorNode;exports.$isEditorState=$isEditorState;exports.$isElementNode=$isElementNode;exports.$isExtendableTextPointCaret=$isExtendableTextPointCaret;exports.$isInlineElementOrDecoratorNode=$isInlineElementOrDecoratorNode;exports.$isLeafNode=$isLeafNode;exports.$isLineBreakNode=$isLineBreakNode;exports.$isNodeCaret=$isNodeCaret;exports.$isNodeSelection=$isNodeSelection;exports.$isParagraphNode=$isParagraphNode;exports.$isRangeSelection=$isRangeSelection;exports.$isRootNode=$isRootNode;exports.$isRootOrShadowRoot=$isRootOrShadowRoot;exports.$isSiblingCaret=$isSiblingCaret;exports.$isTabNode=$isTabNode;exports.$isTextNode=$isTextNode;exports.$isTextPointCaret=$isTextPointCaret;exports.$isTextPointCaretSlice=$isTextPointCaretSlice;exports.$isTokenOrSegmented=$isTokenOrSegmented;exports.$isTokenOrTab=$isTokenOrTab;exports.$nodesOfType=$nodesOfType;exports.$normalizeCaret=$normalizeCaret;exports.$normalizeSelection__EXPERIMENTAL=$normalizeSelection;exports.$onUpdate=$onUpdate;exports.$parseSerializedNode=$parseSerializedNode;exports.$removeTextFromCaretRange=$removeTextFromCaretRange;exports.$rewindSiblingCaret=$rewindSiblingCaret;exports.$selectAll=$selectAll;exports.$setCompositionKey=$setCompositionKey;exports.$setPointFromCaret=$setPointFromCaret;exports.$setSelection=$setSelection;exports.$setSelectionFromCaretRange=$setSelectionFromCaretRange;exports.$setState=$setState;exports.$splitAtPointCaretNext=$splitAtPointCaretNext;exports.$splitNode=$splitNode;exports.$updateRangeSelectionFromCaretRange=$updateRangeSelectionFromCaretRange;exports.ArtificialNode__DO_NOT_USE=ArtificialNode__DO_NOT_USE;exports.BEFORE_INPUT_COMMAND=BEFORE_INPUT_COMMAND;exports.BLUR_COMMAND=BLUR_COMMAND;exports.CAN_REDO_COMMAND=CAN_REDO_COMMAND;exports.CAN_UNDO_COMMAND=CAN_UNDO_COMMAND;exports.CLEAR_EDITOR_COMMAND=CLEAR_EDITOR_COMMAND;exports.CLEAR_HISTORY_COMMAND=CLEAR_HISTORY_COMMAND;exports.CLICK_COMMAND=CLICK_COMMAND;exports.COLLABORATION_TAG=COLLABORATION_TAG;exports.COMMAND_PRIORITY_CRITICAL=COMMAND_PRIORITY_CRITICAL;exports.COMMAND_PRIORITY_EDITOR=COMMAND_PRIORITY_EDITOR;exports.COMMAND_PRIORITY_HIGH=COMMAND_PRIORITY_HIGH;exports.COMMAND_PRIORITY_LOW=COMMAND_PRIORITY_LOW;exports.COMMAND_PRIORITY_NORMAL=COMMAND_PRIORITY_NORMAL;exports.COMPOSITION_END_COMMAND=COMPOSITION_END_COMMAND;exports.COMPOSITION_START_COMMAND=COMPOSITION_START_COMMAND;exports.CONTROLLED_TEXT_INSERTION_COMMAND=CONTROLLED_TEXT_INSERTION_COMMAND;exports.COPY_COMMAND=COPY_COMMAND;exports.CUT_COMMAND=CUT_COMMAND;exports.DELETE_CHARACTER_COMMAND=DELETE_CHARACTER_COMMAND;exports.DELETE_LINE_COMMAND=DELETE_LINE_COMMAND;exports.DELETE_WORD_COMMAND=DELETE_WORD_COMMAND;exports.DRAGEND_COMMAND=DRAGEND_COMMAND;exports.DRAGOVER_COMMAND=DRAGOVER_COMMAND;exports.DRAGSTART_COMMAND=DRAGSTART_COMMAND;exports.DROP_COMMAND=DROP_COMMAND;exports.DecoratorNode=DecoratorNode;exports.ElementNode=ElementNode;exports.FOCUS_COMMAND=FOCUS_COMMAND;exports.FORMAT_ELEMENT_COMMAND=FORMAT_ELEMENT_COMMAND;exports.FORMAT_TEXT_COMMAND=FORMAT_TEXT_COMMAND;exports.HISTORIC_TAG=HISTORIC_TAG;exports.HISTORY_MERGE_TAG=HISTORY_MERGE_TAG;exports.HISTORY_PUSH_TAG=HISTORY_PUSH_TAG;exports.INDENT_CONTENT_COMMAND=INDENT_CONTENT_COMMAND;exports.INPUT_COMMAND=INPUT_COMMAND;exports.INSERT_LINE_BREAK_COMMAND=INSERT_LINE_BREAK_COMMAND;exports.INSERT_PARAGRAPH_COMMAND=INSERT_PARAGRAPH_COMMAND;exports.INSERT_TAB_COMMAND=INSERT_TAB_COMMAND;exports.INTERNAL_$isBlock=INTERNAL_$isBlock;exports.IS_ALL_FORMATTING=IS_ALL_FORMATTING;exports.IS_BOLD=IS_BOLD;exports.IS_CODE=IS_CODE;exports.IS_HIGHLIGHT=IS_HIGHLIGHT;exports.IS_ITALIC=IS_ITALIC;exports.IS_STRIKETHROUGH=IS_STRIKETHROUGH;exports.IS_SUBSCRIPT=IS_SUBSCRIPT;exports.IS_SUPERSCRIPT=IS_SUPERSCRIPT;exports.IS_UNDERLINE=IS_UNDERLINE;exports.KEY_ARROW_DOWN_COMMAND=KEY_ARROW_DOWN_COMMAND;exports.KEY_ARROW_LEFT_COMMAND=KEY_ARROW_LEFT_COMMAND;exports.KEY_ARROW_RIGHT_COMMAND=KEY_ARROW_RIGHT_COMMAND;exports.KEY_ARROW_UP_COMMAND=KEY_ARROW_UP_COMMAND;exports.KEY_BACKSPACE_COMMAND=KEY_BACKSPACE_COMMAND;exports.KEY_DELETE_COMMAND=KEY_DELETE_COMMAND;exports.KEY_DOWN_COMMAND=KEY_DOWN_COMMAND;exports.KEY_ENTER_COMMAND=KEY_ENTER_COMMAND;exports.KEY_ESCAPE_COMMAND=KEY_ESCAPE_COMMAND;exports.KEY_MODIFIER_COMMAND=KEY_MODIFIER_COMMAND;exports.KEY_SPACE_COMMAND=KEY_SPACE_COMMAND;exports.KEY_TAB_COMMAND=KEY_TAB_COMMAND;exports.LineBreakNode=LineBreakNode;exports.MOVE_TO_END=MOVE_TO_END;exports.MOVE_TO_START=MOVE_TO_START;exports.NODE_STATE_KEY=NODE_STATE_KEY;exports.OUTDENT_CONTENT_COMMAND=OUTDENT_CONTENT_COMMAND;exports.PASTE_COMMAND=PASTE_COMMAND;exports.PASTE_TAG=PASTE_TAG;exports.ParagraphNode=ParagraphNode;exports.REDO_COMMAND=REDO_COMMAND;exports.REMOVE_TEXT_COMMAND=REMOVE_TEXT_COMMAND;exports.RootNode=RootNode;exports.SELECTION_CHANGE_COMMAND=SELECTION_CHANGE_COMMAND;exports.SELECTION_INSERT_CLIPBOARD_NODES_COMMAND=SELECTION_INSERT_CLIPBOARD_NODES_COMMAND;exports.SELECT_ALL_COMMAND=SELECT_ALL_COMMAND;exports.SKIP_COLLAB_TAG=SKIP_COLLAB_TAG;exports.SKIP_DOM_SELECTION_TAG=SKIP_DOM_SELECTION_TAG;exports.SKIP_SCROLL_INTO_VIEW_TAG=SKIP_SCROLL_INTO_VIEW_TAG;exports.SKIP_SELECTION_FOCUS_TAG=SKIP_SELECTION_FOCUS_TAG;exports.TEXT_TYPE_TO_FORMAT=TEXT_TYPE_TO_FORMAT;exports.TabNode=TabNode;exports.TextNode=TextNode;exports.UNDO_COMMAND=UNDO_COMMAND;exports.buildImportMap=buildImportMap;exports.configExtension=configExtension;exports.createCommand=createCommand;exports.createEditor=createEditor;exports.createSharedNodeState=createSharedNodeState;exports.createState=createState;exports.declarePeerDependency=declarePeerDependency;exports.defineExtension=defineExtension;exports.flipDirection=flipDirection;exports.getDOMOwnerDocument=getDOMOwnerDocument;exports.getDOMSelection=getDOMSelection;exports.getDOMSelectionFromTarget=getDOMSelectionFromTarget;exports.getDOMTextNode=getDOMTextNode;exports.getEditorPropertyFromDOMNode=getEditorPropertyFromDOMNode;exports.getNearestEditorFromDOMNode=getNearestEditorFromDOMNode;exports.getRegisteredNode=getRegisteredNode;exports.getRegisteredNodeOrThrow=getRegisteredNodeOrThrow;exports.getStaticNodeConfig=getStaticNodeConfig;exports.getTextDirection=getTextDirection;exports.getTransformSetFromKlass=getTransformSetFromKlass;exports.isBlockDomNode=isBlockDomNode;exports.isCurrentlyReadOnlyMode=isCurrentlyReadOnlyMode;exports.isDOMDocumentNode=isDOMDocumentNode;exports.isDOMNode=isDOMNode;exports.isDOMTextNode=isDOMTextNode;exports.isDOMUnmanaged=isDOMUnmanaged;exports.isDocumentFragment=isDocumentFragment;exports.isExactShortcutMatch=isExactShortcutMatch;exports.isHTMLAnchorElement=isHTMLAnchorElement;exports.isHTMLElement=isHTMLElement;exports.isInlineDomNode=isInlineDomNode;exports.isLexicalEditor=isLexicalEditor;exports.isModifierMatch=isModifierMatch;exports.isSelectionCapturedInDecoratorInput=isSelectionCapturedInDecoratorInput;exports.isSelectionWithinEditor=isSelectionWithinEditor;exports.makeStepwiseIterator=makeStepwiseIterator;exports.removeFromParent=removeFromParent;exports.resetRandomKey=resetRandomKey;exports.safeCast=safeCast;exports.setDOMUnmanaged=setDOMUnmanaged;exports.setNodeIndentFromDOM=setNodeIndentFromDOM;exports.shallowMergeConfig=shallowMergeConfig;