roosterjs-content-model-core 9.36.0 → 9.36.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. package/lib/coreApi/restoreUndoSnapshot/restoreSnapshotLogicalRoot.js +0 -3
  2. package/lib/coreApi/restoreUndoSnapshot/restoreSnapshotLogicalRoot.js.map +1 -1
  3. package/lib/coreApi/restoreUndoSnapshot/restoreUndoSnapshot.js +4 -0
  4. package/lib/coreApi/restoreUndoSnapshot/restoreUndoSnapshot.js.map +1 -1
  5. package/lib/corePlugin/domEvent/DOMEventPlugin.js.map +1 -1
  6. package/lib/corePlugin/selection/SelectionPlugin.js +27 -13
  7. package/lib/corePlugin/selection/SelectionPlugin.js.map +1 -1
  8. package/lib-amd/coreApi/restoreUndoSnapshot/restoreSnapshotLogicalRoot.js +0 -3
  9. package/lib-amd/coreApi/restoreUndoSnapshot/restoreSnapshotLogicalRoot.js.map +1 -1
  10. package/lib-amd/coreApi/restoreUndoSnapshot/restoreUndoSnapshot.js +4 -0
  11. package/lib-amd/coreApi/restoreUndoSnapshot/restoreUndoSnapshot.js.map +1 -1
  12. package/lib-amd/corePlugin/domEvent/DOMEventPlugin.js.map +1 -1
  13. package/lib-amd/corePlugin/selection/SelectionPlugin.js +27 -13
  14. package/lib-amd/corePlugin/selection/SelectionPlugin.js.map +1 -1
  15. package/lib-mjs/coreApi/restoreUndoSnapshot/restoreSnapshotLogicalRoot.js +0 -3
  16. package/lib-mjs/coreApi/restoreUndoSnapshot/restoreSnapshotLogicalRoot.js.map +1 -1
  17. package/lib-mjs/coreApi/restoreUndoSnapshot/restoreUndoSnapshot.js +4 -0
  18. package/lib-mjs/coreApi/restoreUndoSnapshot/restoreUndoSnapshot.js.map +1 -1
  19. package/lib-mjs/corePlugin/domEvent/DOMEventPlugin.js.map +1 -1
  20. package/lib-mjs/corePlugin/selection/SelectionPlugin.js +27 -13
  21. package/lib-mjs/corePlugin/selection/SelectionPlugin.js.map +1 -1
  22. package/package.json +3 -3
@@ -13,9 +13,6 @@ function restoreSnapshotLogicalRoot(core, snapshot) {
13
13
  core.api.setLogicalRoot(core, restoredLogicalRoot);
14
14
  }
15
15
  }
16
- else {
17
- core.api.setLogicalRoot(core, null);
18
- }
19
16
  }
20
17
  exports.restoreSnapshotLogicalRoot = restoreSnapshotLogicalRoot;
21
18
  //# sourceMappingURL=restoreSnapshotLogicalRoot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"restoreSnapshotLogicalRoot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreSnapshotLogicalRoot.ts"],"names":[],"mappings":";;;AACA,6DAA4D;AAE5D;;GAEG;AACH,SAAgB,0BAA0B,CAAC,IAAgB,EAAE,QAAkB;IAC3E,IAAI,QAAQ,CAAC,eAAe,IAAI,QAAQ,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE;QACjE,IAAM,mBAAmB,GAAG,IAAA,yCAAmB,EAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,eAAe,CAAC;aACvF,IAAsB,CAAC;QAC5B,IAAI,mBAAmB,KAAK,IAAI,CAAC,WAAW,EAAE;YAC1C,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;SACtD;KACJ;SAAM;QACH,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;KACvC;AACL,CAAC;AAVD,gEAUC","sourcesContent":["import type { EditorCore, Snapshot } from 'roosterjs-content-model-types';\nimport { getPositionFromPath } from './getPositionFromPath';\n\n/**\n * @internal\n */\nexport function restoreSnapshotLogicalRoot(core: EditorCore, snapshot: Snapshot) {\n if (snapshot.logicalRootPath && snapshot.logicalRootPath.length > 0) {\n const restoredLogicalRoot = getPositionFromPath(core.physicalRoot, snapshot.logicalRootPath)\n .node as HTMLDivElement;\n if (restoredLogicalRoot !== core.logicalRoot) {\n core.api.setLogicalRoot(core, restoredLogicalRoot);\n }\n } else {\n core.api.setLogicalRoot(core, null);\n }\n}\n"]}
1
+ {"version":3,"file":"restoreSnapshotLogicalRoot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreSnapshotLogicalRoot.ts"],"names":[],"mappings":";;;AACA,6DAA4D;AAE5D;;GAEG;AACH,SAAgB,0BAA0B,CAAC,IAAgB,EAAE,QAAkB;IAC3E,IAAI,QAAQ,CAAC,eAAe,IAAI,QAAQ,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE;QACjE,IAAM,mBAAmB,GAAG,IAAA,yCAAmB,EAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,eAAe,CAAC;aACvF,IAAsB,CAAC;QAC5B,IAAI,mBAAmB,KAAK,IAAI,CAAC,WAAW,EAAE;YAC1C,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;SACtD;KACJ;AACL,CAAC;AARD,gEAQC","sourcesContent":["import type { EditorCore, Snapshot } from 'roosterjs-content-model-types';\nimport { getPositionFromPath } from './getPositionFromPath';\n\n/**\n * @internal\n */\nexport function restoreSnapshotLogicalRoot(core: EditorCore, snapshot: Snapshot) {\n if (snapshot.logicalRootPath && snapshot.logicalRootPath.length > 0) {\n const restoredLogicalRoot = getPositionFromPath(core.physicalRoot, snapshot.logicalRootPath)\n .node as HTMLDivElement;\n if (restoredLogicalRoot !== core.logicalRoot) {\n core.api.setLogicalRoot(core, restoredLogicalRoot);\n }\n }\n}\n"]}
@@ -19,6 +19,10 @@ var restoreUndoSnapshot = function (core, snapshot) {
19
19
  }, true /*broadcast*/);
20
20
  try {
21
21
  core.undo.isRestoring = true;
22
+ // Force clear logical root before restoring snapshot, so the whole editor is editable.
23
+ // Without changing logical root, browser may want to maintain the scroll position of current logical root,
24
+ // which may cause the editor to scroll to a wrong position after content is changed.
25
+ core.api.setLogicalRoot(core, null /* logicalRoot */);
22
26
  (0, restoreSnapshotHTML_1.restoreSnapshotHTML)(core, snapshot);
23
27
  (0, restoreSnapshotLogicalRoot_1.restoreSnapshotLogicalRoot)(core, snapshot);
24
28
  (0, restoreSnapshotSelection_1.restoreSnapshotSelection)(core, snapshot);
@@ -1 +1 @@
1
- {"version":3,"file":"restoreUndoSnapshot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreUndoSnapshot.ts"],"names":[],"mappings":";;;AAAA,2EAA2D;AAC3D,iEAAgE;AAChE,6DAA4D;AAC5D,2EAA0E;AAC1E,uEAAsE;AAGtE;;;;;GAKG;AACI,IAAM,mBAAmB,GAAwB,UAAC,IAAI,EAAE,QAAQ;IACnE,IAAI,CAAC,GAAG,CAAC,YAAY,CACjB,IAAI,EACJ;QACI,SAAS,EAAE,kBAAkB;QAC7B,UAAU,EAAE,QAAQ,CAAC,IAAI;KAC5B,EACD,IAAI,CAAC,aAAa,CACrB,CAAC;IAEF,IAAI;QACA,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAE7B,IAAA,yCAAmB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACpC,IAAA,uDAA0B,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC3C,IAAA,mDAAwB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACzC,IAAA,6CAAqB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAEtC,IAAM,OAAK,GAAwB;YAC/B,SAAS,EAAE,gBAAgB;YAC3B,eAAe,EAAE,QAAQ,CAAC,eAAe;YACzC,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,MAAM,EAAE,0CAAY,CAAC,UAAU;SAClC,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAK,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;KAC3D;YAAS;QACN,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;KACjC;AACL,CAAC,CAAC;AA7BW,QAAA,mBAAmB,uBA6B9B","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { restoreSnapshotColors } from './restoreSnapshotColors';\nimport { restoreSnapshotHTML } from './restoreSnapshotHTML';\nimport { restoreSnapshotLogicalRoot } from './restoreSnapshotLogicalRoot';\nimport { restoreSnapshotSelection } from './restoreSnapshotSelection';\nimport type { ContentChangedEvent, RestoreUndoSnapshot } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Restore an undo snapshot into editor\n * @param core The editor core object\n * @param step Steps to move, can be 0, positive or negative\n */\nexport const restoreUndoSnapshot: RestoreUndoSnapshot = (core, snapshot) => {\n core.api.triggerEvent(\n core,\n {\n eventType: 'beforeSetContent',\n newContent: snapshot.html,\n },\n true /*broadcast*/\n );\n\n try {\n core.undo.isRestoring = true;\n\n restoreSnapshotHTML(core, snapshot);\n restoreSnapshotLogicalRoot(core, snapshot);\n restoreSnapshotSelection(core, snapshot);\n restoreSnapshotColors(core, snapshot);\n\n const event: ContentChangedEvent = {\n eventType: 'contentChanged',\n additionalState: snapshot.additionalState,\n entityStates: snapshot.entityStates,\n source: ChangeSource.SetContent,\n };\n\n core.api.triggerEvent(core, event, false /*broadcast*/);\n } finally {\n core.undo.isRestoring = false;\n }\n};\n"]}
1
+ {"version":3,"file":"restoreUndoSnapshot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreUndoSnapshot.ts"],"names":[],"mappings":";;;AAAA,2EAA2D;AAC3D,iEAAgE;AAChE,6DAA4D;AAC5D,2EAA0E;AAC1E,uEAAsE;AAGtE;;;;;GAKG;AACI,IAAM,mBAAmB,GAAwB,UAAC,IAAI,EAAE,QAAQ;IACnE,IAAI,CAAC,GAAG,CAAC,YAAY,CACjB,IAAI,EACJ;QACI,SAAS,EAAE,kBAAkB;QAC7B,UAAU,EAAE,QAAQ,CAAC,IAAI;KAC5B,EACD,IAAI,CAAC,aAAa,CACrB,CAAC;IAEF,IAAI;QACA,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAE7B,uFAAuF;QACvF,2GAA2G;QAC3G,qFAAqF;QACrF,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAEtD,IAAA,yCAAmB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACpC,IAAA,uDAA0B,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC3C,IAAA,mDAAwB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACzC,IAAA,6CAAqB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAEtC,IAAM,OAAK,GAAwB;YAC/B,SAAS,EAAE,gBAAgB;YAC3B,eAAe,EAAE,QAAQ,CAAC,eAAe;YACzC,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,MAAM,EAAE,0CAAY,CAAC,UAAU;SAClC,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAK,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;KAC3D;YAAS;QACN,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;KACjC;AACL,CAAC,CAAC;AAlCW,QAAA,mBAAmB,uBAkC9B","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { restoreSnapshotColors } from './restoreSnapshotColors';\nimport { restoreSnapshotHTML } from './restoreSnapshotHTML';\nimport { restoreSnapshotLogicalRoot } from './restoreSnapshotLogicalRoot';\nimport { restoreSnapshotSelection } from './restoreSnapshotSelection';\nimport type { ContentChangedEvent, RestoreUndoSnapshot } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Restore an undo snapshot into editor\n * @param core The editor core object\n * @param step Steps to move, can be 0, positive or negative\n */\nexport const restoreUndoSnapshot: RestoreUndoSnapshot = (core, snapshot) => {\n core.api.triggerEvent(\n core,\n {\n eventType: 'beforeSetContent',\n newContent: snapshot.html,\n },\n true /*broadcast*/\n );\n\n try {\n core.undo.isRestoring = true;\n\n // Force clear logical root before restoring snapshot, so the whole editor is editable.\n // Without changing logical root, browser may want to maintain the scroll position of current logical root,\n // which may cause the editor to scroll to a wrong position after content is changed.\n core.api.setLogicalRoot(core, null /* logicalRoot */);\n\n restoreSnapshotHTML(core, snapshot);\n restoreSnapshotLogicalRoot(core, snapshot);\n restoreSnapshotSelection(core, snapshot);\n restoreSnapshotColors(core, snapshot);\n\n const event: ContentChangedEvent = {\n eventType: 'contentChanged',\n additionalState: snapshot.additionalState,\n entityStates: snapshot.entityStates,\n source: ChangeSource.SetContent,\n };\n\n core.api.triggerEvent(core, event, false /*broadcast*/);\n } finally {\n core.undo.isRestoring = false;\n }\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"DOMEventPlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/domEvent/DOMEventPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ChangeSource,\n isCharacterValue,\n isCursorMovingKey,\n isNodeOfType,\n} from 'roosterjs-content-model-dom';\nimport type {\n DOMEventPluginState,\n IEditor,\n DOMEventRecord,\n EditorOptions,\n PluginWithState,\n} from 'roosterjs-content-model-types';\n\nconst EventTypeMap: Record<string, 'keyDown' | 'keyUp' | 'keyPress'> = {\n keydown: 'keyDown',\n keyup: 'keyUp',\n keypress: 'keyPress',\n};\n\n/**\n * DOMEventPlugin handles customized DOM events, including:\n * 1. Keyboard event\n * 2. Mouse event\n * 3. IME state\n * 4. Drop event\n * 5. Focus and blur event\n * 6. Input event\n * 7. Scroll event\n * It contains special handling for Safari since Safari cannot get correct selection when onBlur event is triggered in editor.\n */\nclass DOMEventPlugin implements PluginWithState<DOMEventPluginState> {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n private state: DOMEventPluginState;\n\n /**\n * Construct a new instance of DOMEventPlugin\n * @param options The editor options\n * @param contentDiv The editor content DIV\n */\n constructor(options: EditorOptions, contentDiv: HTMLDivElement) {\n this.state = {\n isInIME: false,\n scrollContainer: options.scrollContainer || contentDiv,\n mouseDownX: null,\n mouseDownY: null,\n mouseUpEventListerAdded: false,\n };\n }\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'DOMEvent';\n }\n\n /**\n * Initialize this plugin. This should only be called from Editor\n * @param editor Editor instance\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n\n const document = this.editor.getDocument();\n const eventHandlers: Partial<\n { [P in keyof HTMLElementEventMap]: DOMEventRecord<HTMLElementEventMap[P]> }\n > = {\n // 1. Keyboard event\n keypress: this.keyboardEventHandler,\n keydown: this.keyboardEventHandler,\n keyup: this.keyboardEventHandler,\n input: this.inputEventHandler,\n\n // 2. Mouse event\n mousedown: { beforeDispatch: this.onMouseDown },\n\n // 3. IME state management\n compositionstart: { beforeDispatch: this.onCompositionStart },\n compositionend: { beforeDispatch: this.onCompositionEnd },\n\n // 4. Drag and Drop event\n dragstart: { beforeDispatch: this.onDragStart },\n drop: { beforeDispatch: this.onDrop },\n };\n\n this.disposer = this.editor.attachDomEvent(<Record<string, DOMEventRecord>>eventHandlers);\n\n // 7. Scroll event\n this.state.scrollContainer.addEventListener('scroll', this.onScroll);\n document.defaultView?.addEventListener('scroll', this.onScroll);\n document.defaultView?.addEventListener('resize', this.onScroll);\n }\n\n /**\n * Dispose this plugin\n */\n dispose() {\n this.removeMouseUpEventListener();\n\n const document = this.editor?.getDocument();\n\n document?.defaultView?.removeEventListener('resize', this.onScroll);\n document?.defaultView?.removeEventListener('scroll', this.onScroll);\n this.state.scrollContainer.removeEventListener('scroll', this.onScroll);\n this.disposer?.();\n this.disposer = null;\n this.editor = null;\n }\n\n /**\n * Get plugin state object\n */\n getState() {\n return this.state;\n }\n\n private onDragStart = (e: Event) => {\n const dragEvent = e as DragEvent;\n const node = dragEvent.target as Node;\n const element = isNodeOfType(node, 'ELEMENT_NODE') ? node : node.parentElement;\n\n if (element && !element.isContentEditable) {\n dragEvent.preventDefault();\n }\n };\n\n private onDrop = () => {\n const doc = this.editor?.getDocument();\n\n doc?.defaultView?.requestAnimationFrame(() => {\n if (this.editor) {\n this.editor.takeSnapshot();\n this.editor.triggerEvent('contentChanged', {\n source: ChangeSource.Drop,\n });\n }\n });\n };\n\n private onScroll = (e: Event) => {\n this.editor?.triggerEvent('scroll', {\n rawEvent: e,\n scrollContainer: this.state.scrollContainer,\n });\n };\n\n private keyboardEventHandler: DOMEventRecord<KeyboardEvent> = {\n beforeDispatch: event => {\n const eventType = EventTypeMap[event.type];\n\n if (isCharacterValue(event) || isCursorMovingKey(event)) {\n // Stop propagation for Character keys and Up/Down/Left/Right/Home/End/PageUp/PageDown\n // since editor already handles these keys and no need to propagate to parents\n event.stopPropagation();\n }\n\n const isAndroid = this.editor?.getEnvironment()?.isAndroid ?? false;\n const isComposing = !isAndroid && (event.isComposing || this.state.isInIME);\n\n if (this.editor && eventType && !isComposing) {\n this.editor.triggerEvent(eventType, {\n rawEvent: event,\n });\n }\n },\n };\n\n private inputEventHandler: DOMEventRecord<Event> = {\n beforeDispatch: event => {\n event.stopPropagation();\n\n const isAndroid = this.editor?.getEnvironment()?.isAndroid ?? false;\n const isComposing = !isAndroid && ((event as InputEvent).isComposing || this.state.isInIME);\n\n if (this.editor && !isComposing) {\n this.editor.triggerEvent('input', {\n rawEvent: event as InputEvent,\n });\n }\n },\n };\n\n private onMouseDown = (event: MouseEvent) => {\n if (this.editor) {\n if (!this.state.mouseUpEventListerAdded) {\n this.editor\n .getDocument()\n .addEventListener('mouseup', this.onMouseUp, true /*setCapture*/);\n this.state.mouseUpEventListerAdded = true;\n this.state.mouseDownX = event.pageX;\n this.state.mouseDownY = event.pageY;\n }\n\n this.editor.triggerEvent('mouseDown', {\n rawEvent: event,\n });\n }\n };\n\n private onMouseUp = (rawEvent: MouseEvent) => {\n if (this.editor) {\n this.removeMouseUpEventListener();\n this.editor.triggerEvent('mouseUp', {\n rawEvent,\n isClicking:\n this.state.mouseDownX == rawEvent.pageX &&\n this.state.mouseDownY == rawEvent.pageY,\n });\n }\n };\n\n private onCompositionStart = () => {\n this.state.isInIME = true;\n };\n\n private onCompositionEnd = (rawEvent: CompositionEvent) => {\n this.state.isInIME = false;\n this.editor?.triggerEvent('compositionEnd', {\n rawEvent,\n });\n };\n\n private removeMouseUpEventListener() {\n if (this.editor && this.state.mouseUpEventListerAdded) {\n this.state.mouseUpEventListerAdded = false;\n this.editor.getDocument().removeEventListener('mouseup', this.onMouseUp, true);\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of DOMEventPlugin.\n * @param option The editor option\n * @param contentDiv The editor content DIV element\n */\nexport function createDOMEventPlugin(\n option: EditorOptions,\n contentDiv: HTMLDivElement\n): PluginWithState<DOMEventPluginState> {\n return new DOMEventPlugin(option, contentDiv);\n}\n"]}
1
+ {"version":3,"file":"DOMEventPlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/domEvent/DOMEventPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ChangeSource,\n isCharacterValue,\n isCursorMovingKey,\n isNodeOfType,\n} from 'roosterjs-content-model-dom';\nimport type {\n DOMEventPluginState,\n IEditor,\n DOMEventRecord,\n EditorOptions,\n PluginWithState,\n} from 'roosterjs-content-model-types';\n\nconst EventTypeMap: Record<string, 'keyDown' | 'keyUp' | 'keyPress'> = {\n keydown: 'keyDown',\n keyup: 'keyUp',\n keypress: 'keyPress',\n};\n\n/**\n * DOMEventPlugin handles customized DOM events, including:\n * 1. Keyboard event\n * 2. Mouse event\n * 3. IME state\n * 4. Drop event\n * 5. Focus and blur event\n * 6. Input event\n * 7. Scroll event\n * It contains special handling for Safari since Safari cannot get correct selection when onBlur event is triggered in editor.\n */\nclass DOMEventPlugin implements PluginWithState<DOMEventPluginState> {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n private state: DOMEventPluginState;\n\n /**\n * Construct a new instance of DOMEventPlugin\n * @param options The editor options\n * @param contentDiv The editor content DIV\n */\n constructor(options: EditorOptions, contentDiv: HTMLDivElement) {\n this.state = {\n isInIME: false,\n scrollContainer: options.scrollContainer || contentDiv,\n mouseDownX: null,\n mouseDownY: null,\n mouseUpEventListerAdded: false,\n };\n }\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'DOMEvent';\n }\n\n /**\n * Initialize this plugin. This should only be called from Editor\n * @param editor Editor instance\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n\n const document = this.editor.getDocument();\n const eventHandlers: Partial<\n { [P in keyof HTMLElementEventMap]: DOMEventRecord<HTMLElementEventMap[P]> }\n > = {\n // 1. Keyboard event\n keypress: this.keyboardEventHandler,\n keydown: this.keyboardEventHandler,\n keyup: this.keyboardEventHandler,\n input: this.inputEventHandler,\n\n // 2. Mouse event\n mousedown: { beforeDispatch: this.onMouseDown },\n\n // 3. IME state management\n compositionstart: { beforeDispatch: this.onCompositionStart },\n compositionend: { beforeDispatch: this.onCompositionEnd },\n\n // 4. Drag and Drop event\n dragstart: { beforeDispatch: this.onDragStart },\n drop: { beforeDispatch: this.onDrop },\n };\n\n this.disposer = this.editor.attachDomEvent(<Record<string, DOMEventRecord>>eventHandlers);\n\n // 7. Scroll event\n this.state.scrollContainer.addEventListener('scroll', this.onScroll);\n document.defaultView?.addEventListener('scroll', this.onScroll);\n document.defaultView?.addEventListener('resize', this.onScroll);\n }\n\n /**\n * Dispose this plugin\n */\n dispose() {\n this.removeMouseUpEventListener();\n\n const document = this.editor?.getDocument();\n\n document?.defaultView?.removeEventListener('resize', this.onScroll);\n document?.defaultView?.removeEventListener('scroll', this.onScroll);\n this.state.scrollContainer.removeEventListener('scroll', this.onScroll);\n this.disposer?.();\n this.disposer = null;\n this.editor = null;\n }\n\n /**\n * Get plugin state object\n */\n getState() {\n return this.state;\n }\n\n private onDragStart = (e: Event) => {\n const dragEvent = e as DragEvent;\n const node = dragEvent.target as Node;\n const element = isNodeOfType(node, 'ELEMENT_NODE') ? node : node.parentElement;\n\n if (element && !element.isContentEditable) {\n dragEvent.preventDefault();\n }\n };\n\n private onDrop = () => {\n const doc = this.editor?.getDocument();\n\n doc?.defaultView?.requestAnimationFrame(() => {\n if (this.editor) {\n this.editor.takeSnapshot();\n this.editor.triggerEvent('contentChanged', {\n source: ChangeSource.Drop,\n });\n }\n });\n };\n\n private onScroll = (e: Event) => {\n this.editor?.triggerEvent('scroll', {\n rawEvent: e,\n scrollContainer: this.state.scrollContainer,\n });\n };\n\n private keyboardEventHandler: DOMEventRecord<KeyboardEvent> = {\n beforeDispatch: event => {\n const eventType = EventTypeMap[event.type];\n\n if (isCharacterValue(event) || isCursorMovingKey(event)) {\n // Stop propagation for Character keys and Up/Down/Left/Right/Home/End/PageUp/PageDown\n // since editor already handles these keys and no need to propagate to parents\n event.stopPropagation();\n }\n\n const isAndroid = this.editor?.getEnvironment()?.isAndroid ?? false;\n const isComposing = !isAndroid && (event.isComposing || this.state.isInIME);\n\n if (this.editor && eventType && !isComposing) {\n this.editor.triggerEvent(eventType, {\n rawEvent: event,\n });\n }\n },\n };\n\n private inputEventHandler: DOMEventRecord<Event> = {\n beforeDispatch: event => {\n event.stopPropagation();\n\n const isAndroid = this.editor?.getEnvironment()?.isAndroid ?? false;\n const isComposing =\n !isAndroid && ((event as InputEvent).isComposing || this.state.isInIME);\n\n if (this.editor && !isComposing) {\n this.editor.triggerEvent('input', {\n rawEvent: event as InputEvent,\n });\n }\n },\n };\n\n private onMouseDown = (event: MouseEvent) => {\n if (this.editor) {\n if (!this.state.mouseUpEventListerAdded) {\n this.editor\n .getDocument()\n .addEventListener('mouseup', this.onMouseUp, true /*setCapture*/);\n this.state.mouseUpEventListerAdded = true;\n this.state.mouseDownX = event.pageX;\n this.state.mouseDownY = event.pageY;\n }\n\n this.editor.triggerEvent('mouseDown', {\n rawEvent: event,\n });\n }\n };\n\n private onMouseUp = (rawEvent: MouseEvent) => {\n if (this.editor) {\n this.removeMouseUpEventListener();\n this.editor.triggerEvent('mouseUp', {\n rawEvent,\n isClicking:\n this.state.mouseDownX == rawEvent.pageX &&\n this.state.mouseDownY == rawEvent.pageY,\n });\n }\n };\n\n private onCompositionStart = () => {\n this.state.isInIME = true;\n };\n\n private onCompositionEnd = (rawEvent: CompositionEvent) => {\n this.state.isInIME = false;\n this.editor?.triggerEvent('compositionEnd', {\n rawEvent,\n });\n };\n\n private removeMouseUpEventListener() {\n if (this.editor && this.state.mouseUpEventListerAdded) {\n this.state.mouseUpEventListerAdded = false;\n this.editor.getDocument().removeEventListener('mouseup', this.onMouseUp, true);\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of DOMEventPlugin.\n * @param option The editor option\n * @param contentDiv The editor content DIV element\n */\nexport function createDOMEventPlugin(\n option: EditorOptions,\n contentDiv: HTMLDivElement\n): PluginWithState<DOMEventPluginState> {\n return new DOMEventPlugin(option, contentDiv);\n}\n"]}
@@ -31,6 +31,7 @@ var SelectionPlugin = /** @class */ (function () {
31
31
  this.isSafari = false;
32
32
  this.isMac = false;
33
33
  this.scrollTopCache = 0;
34
+ this.pointerEvent = null;
34
35
  this.onMouseMove = function (event) {
35
36
  var _a, _b, _c;
36
37
  if (_this.editor && _this.state.tableSelection) {
@@ -78,6 +79,11 @@ var SelectionPlugin = /** @class */ (function () {
78
79
  this.onDrop = function () {
79
80
  _this.detachMouseEvent();
80
81
  };
82
+ this.onPointerDown = function (e) {
83
+ if (e.pointerType === 'touch' || e.pointerType === 'pen') {
84
+ _this.pointerEvent = e;
85
+ }
86
+ };
81
87
  // MacOS will not create a mouseUp event if contextMenu event is not prevent defaulted.
82
88
  // Make sure we capture image target even if image is wrapped
83
89
  this.getContainedTargetImage = function (event, previousSelection) {
@@ -166,6 +172,7 @@ var SelectionPlugin = /** @class */ (function () {
166
172
  return 'Selection';
167
173
  };
168
174
  SelectionPlugin.prototype.initialize = function (editor) {
175
+ var _this = this;
169
176
  this.editor = editor;
170
177
  if (!this.state.imageSelectionBorderColorDark && this.state.imageSelectionBorderColor) {
171
178
  this.state.imageSelectionBorderColorDark = editor
@@ -183,19 +190,13 @@ var SelectionPlugin = /** @class */ (function () {
183
190
  this.isSafari = !!env.isSafari;
184
191
  this.isMac = !!env.isMac;
185
192
  document.addEventListener('selectionchange', this.onSelectionChange);
186
- if (this.isSafari) {
187
- this.disposer = this.editor.attachDomEvent({
188
- focus: { beforeDispatch: this.onFocus },
189
- drop: { beforeDispatch: this.onDrop },
190
- });
191
- }
192
- else {
193
- this.disposer = this.editor.attachDomEvent({
194
- focus: { beforeDispatch: this.onFocus },
195
- blur: { beforeDispatch: this.onBlur },
196
- drop: { beforeDispatch: this.onDrop },
197
- });
198
- }
193
+ var eventHandlers = {
194
+ focus: { beforeDispatch: this.onFocus },
195
+ drop: { beforeDispatch: this.onDrop },
196
+ blur: this.isSafari ? undefined : { beforeDispatch: this.onBlur },
197
+ pointerdown: { beforeDispatch: function (event) { return _this.onPointerDown(event); } },
198
+ };
199
+ this.disposer = this.editor.attachDomEvent(eventHandlers);
199
200
  };
200
201
  SelectionPlugin.prototype.dispose = function () {
201
202
  var _a, _b;
@@ -300,9 +301,22 @@ var SelectionPlugin = /** @class */ (function () {
300
301
  },
301
302
  });
302
303
  }
304
+ if (rawEvent.defaultPrevented) {
305
+ this.pointerEvent = null;
306
+ }
303
307
  };
304
308
  SelectionPlugin.prototype.onMouseUp = function () {
309
+ var _this = this;
305
310
  this.detachMouseEvent();
311
+ if (this.pointerEvent && this.pointerEvent.pointerType === 'touch') {
312
+ requestAnimationFrame(function () {
313
+ if (_this.editor && _this.pointerEvent) {
314
+ // Handle touch selection here since the cursor position is updated
315
+ // Work-in-progress
316
+ }
317
+ _this.pointerEvent = null;
318
+ });
319
+ }
306
320
  };
307
321
  SelectionPlugin.prototype.onKeyDown = function (editor, rawEvent) {
308
322
  var _this = this;
@@ -1 +1 @@
1
- {"version":3,"file":"SelectionPlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/selection/SelectionPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { findCoordinate } from './findCoordinate';\nimport { findTableCellElement } from '../../coreApi/setDOMSelection/findTableCellElement';\nimport { isSingleImageInSelection } from './isSingleImageInSelection';\nimport { normalizePos } from './normalizePos';\nimport {\n isCharacterValue,\n isElementOfType,\n isModifierKey,\n isNodeOfType,\n parseTableCells,\n toArray,\n} from 'roosterjs-content-model-dom';\nimport type {\n DOMSelection,\n IEditor,\n PluginEvent,\n PluginWithState,\n SelectionPluginState,\n EditorOptions,\n DOMHelper,\n ParsedTable,\n TableSelectionInfo,\n TableCellCoordinate,\n} from 'roosterjs-content-model-types';\n\nconst MouseLeftButton = 0;\nconst MouseRightButton = 2;\nconst Up = 'ArrowUp';\nconst Down = 'ArrowDown';\nconst Left = 'ArrowLeft';\nconst Right = 'ArrowRight';\nconst Tab = 'Tab';\n\n/**\n * @internal\n */\nexport const DEFAULT_SELECTION_BORDER_COLOR = '#DB626C';\n/**\n * @internal\n */\nexport const DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR = '#C6C6C6';\n\nclass SelectionPlugin implements PluginWithState<SelectionPluginState> {\n private editor: IEditor | null = null;\n private state: SelectionPluginState;\n private disposer: (() => void) | null = null;\n private logicalRootDisposer: (() => void) | null = null;\n private isSafari = false;\n private isMac = false;\n private scrollTopCache: number = 0;\n\n constructor(options: EditorOptions) {\n this.state = {\n selection: null,\n tableSelection: null,\n imageSelectionBorderColor:\n options.imageSelectionBorderColor ?? DEFAULT_SELECTION_BORDER_COLOR,\n imageSelectionBorderColorDark: options.imageSelectionBorderColor\n ? undefined\n : DEFAULT_SELECTION_BORDER_COLOR,\n tableCellSelectionBackgroundColor:\n options.tableCellSelectionBackgroundColor ??\n DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR,\n tableCellSelectionBackgroundColorDark: options.tableCellSelectionBackgroundColor\n ? undefined\n : DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR,\n };\n }\n\n getName() {\n return 'Selection';\n }\n\n initialize(editor: IEditor) {\n this.editor = editor;\n\n if (!this.state.imageSelectionBorderColorDark && this.state.imageSelectionBorderColor) {\n this.state.imageSelectionBorderColorDark = editor\n .getColorManager()\n .getDarkColor(this.state.imageSelectionBorderColor, undefined, 'border');\n }\n\n if (\n !this.state.tableCellSelectionBackgroundColorDark &&\n this.state.tableCellSelectionBackgroundColor\n ) {\n this.state.tableCellSelectionBackgroundColorDark = editor\n .getColorManager()\n .getDarkColor(\n this.state.tableCellSelectionBackgroundColor,\n undefined,\n 'background'\n );\n }\n\n const env = this.editor.getEnvironment();\n const document = this.editor.getDocument();\n\n this.isSafari = !!env.isSafari;\n this.isMac = !!env.isMac;\n document.addEventListener('selectionchange', this.onSelectionChange);\n if (this.isSafari) {\n this.disposer = this.editor.attachDomEvent({\n focus: { beforeDispatch: this.onFocus },\n drop: { beforeDispatch: this.onDrop },\n });\n } else {\n this.disposer = this.editor.attachDomEvent({\n focus: { beforeDispatch: this.onFocus },\n blur: { beforeDispatch: this.onBlur },\n drop: { beforeDispatch: this.onDrop },\n });\n }\n }\n\n dispose() {\n this.editor?.getDocument().removeEventListener('selectionchange', this.onSelectionChange);\n\n if (this.disposer) {\n this.disposer();\n this.disposer = null;\n }\n\n this.logicalRootDisposer?.();\n this.logicalRootDisposer = null;\n\n this.detachMouseEvent();\n this.editor = null;\n }\n\n getState(): SelectionPluginState {\n return this.state;\n }\n\n onPluginEvent(event: PluginEvent) {\n if (!this.editor) {\n return;\n }\n\n switch (event.eventType) {\n case 'mouseDown':\n this.onMouseDown(this.editor, event.rawEvent);\n break;\n\n case 'mouseUp':\n this.onMouseUp();\n break;\n\n case 'keyDown':\n this.onKeyDown(this.editor, event.rawEvent);\n break;\n\n case 'contentChanged':\n this.state.tableSelection = null;\n break;\n\n case 'scroll':\n if (!this.editor.hasFocus()) {\n this.scrollTopCache = event.scrollContainer.scrollTop;\n }\n break;\n\n case 'logicalRootChanged':\n this.logicalRootDisposer?.();\n if (this.isSafari) {\n this.logicalRootDisposer = this.editor.attachDomEvent({\n focus: { beforeDispatch: this.onFocus },\n drop: { beforeDispatch: this.onDrop },\n });\n } else {\n this.logicalRootDisposer = this.editor.attachDomEvent({\n focus: { beforeDispatch: this.onFocus },\n blur: { beforeDispatch: this.onBlur },\n drop: { beforeDispatch: this.onDrop },\n });\n }\n break;\n }\n }\n\n private onMouseDown(editor: IEditor, rawEvent: MouseEvent) {\n const selection = editor.getDOMSelection();\n let image: HTMLImageElement | null;\n\n // Image selection\n if (\n selection?.type == 'image' &&\n (rawEvent.button == MouseLeftButton ||\n (rawEvent.button == MouseRightButton &&\n !this.getClickingImage(rawEvent) &&\n !this.getContainedTargetImage(rawEvent, selection)))\n ) {\n this.setDOMSelection(null /*domSelection*/, null /*tableSelection*/);\n }\n\n if (\n (image =\n this.getClickingImage(rawEvent) ??\n this.getContainedTargetImage(rawEvent, selection)) &&\n image.isContentEditable\n ) {\n this.setDOMSelection(\n {\n type: 'image',\n image: image,\n },\n null\n );\n return;\n }\n\n // Table selection\n if (selection?.type == 'table' && rawEvent.button == MouseLeftButton) {\n this.setDOMSelection(null /*domSelection*/, null /*tableSelection*/);\n }\n\n let tableSelection: TableSelectionInfo | null;\n const target = rawEvent.target as Node;\n\n if (\n target &&\n rawEvent.button == MouseLeftButton &&\n (tableSelection = this.parseTableSelection(target, target, editor.getDOMHelper()))\n ) {\n this.state.tableSelection = tableSelection;\n\n if (rawEvent.detail >= 3) {\n const lastCo = findCoordinate(\n tableSelection.parsedTable,\n rawEvent.target as Node,\n editor.getDOMHelper()\n );\n\n if (lastCo) {\n // Triple click, select the current cell\n tableSelection.lastCo = lastCo;\n this.updateTableSelection(lastCo);\n rawEvent.preventDefault();\n }\n }\n\n this.state.mouseDisposer?.();\n this.state.mouseDisposer = editor.attachDomEvent({\n mousemove: {\n beforeDispatch: this.onMouseMove,\n },\n });\n }\n }\n\n private onMouseMove = (event: Event) => {\n if (this.editor && this.state.tableSelection) {\n const hasTableSelection = !!this.state.tableSelection.lastCo;\n const currentNode = event.target as Node;\n const domHelper = this.editor.getDOMHelper();\n\n const range = this.editor.getDocument().createRange();\n const startNode = this.state.tableSelection.startNode;\n const isReverted =\n currentNode.compareDocumentPosition(startNode) == Node.DOCUMENT_POSITION_FOLLOWING;\n\n if (isReverted) {\n range.setStart(currentNode, 0);\n range.setEnd(\n startNode,\n isNodeOfType(startNode, 'TEXT_NODE')\n ? startNode.nodeValue?.length ?? 0\n : startNode.childNodes.length\n );\n } else {\n range.setStart(startNode, 0);\n range.setEnd(currentNode, 0);\n }\n\n // Use common container of the range to search a common table that covers both start and end node\n const tableStart = range.commonAncestorContainer;\n const newTableSelection = this.parseTableSelection(tableStart, startNode, domHelper);\n\n if (newTableSelection) {\n const lastCo = findCoordinate(\n newTableSelection.parsedTable,\n currentNode,\n domHelper\n );\n\n if (newTableSelection.table != this.state.tableSelection.table) {\n // Move mouse into another table (nest table scenario)\n this.state.tableSelection = newTableSelection;\n this.state.tableSelection.lastCo = lastCo ?? undefined;\n }\n\n const updated = lastCo && this.updateTableSelection(lastCo);\n\n if (hasTableSelection || updated) {\n event.preventDefault();\n }\n } else if (this.editor.getDOMSelection()?.type == 'table') {\n // Move mouse out of table\n this.setDOMSelection(\n {\n type: 'range',\n range,\n isReverted,\n },\n this.state.tableSelection\n );\n }\n }\n };\n\n private onMouseUp() {\n this.detachMouseEvent();\n }\n\n private onDrop = () => {\n this.detachMouseEvent();\n };\n\n private onKeyDown(editor: IEditor, rawEvent: KeyboardEvent) {\n const key = rawEvent.key;\n const selection = editor.getDOMSelection();\n const win = editor.getDocument().defaultView;\n\n switch (selection?.type) {\n case 'image':\n if (!isModifierKey(rawEvent) && !rawEvent.shiftKey && selection.image.parentNode) {\n if (key === 'Escape') {\n this.selectBeforeOrAfterElement(editor, selection.image);\n rawEvent.stopPropagation();\n } else if (key !== 'Delete' && key !== 'Backspace') {\n this.selectBeforeOrAfterElement(editor, selection.image);\n }\n }\n\n if (\n (isModifierKey(rawEvent) || rawEvent.shiftKey) &&\n selection.image &&\n !this.isSafari\n ) {\n const range = selection.image.ownerDocument.createRange();\n range.selectNode(selection.image);\n this.setDOMSelection(\n {\n type: 'range',\n range,\n isReverted: false,\n },\n null /* tableSelection */\n );\n }\n break;\n\n case 'range':\n if (key == Up || key == Down || key == Left || key == Right || key == Tab) {\n const start = selection.range.startContainer;\n this.state.tableSelection = this.parseTableSelection(\n start,\n start,\n editor.getDOMHelper()\n );\n\n if (this.state.tableSelection && !rawEvent.defaultPrevented) {\n if (key == Tab) {\n this.handleSelectionInTable(this.getTabKey(rawEvent));\n rawEvent.preventDefault();\n } else {\n win?.requestAnimationFrame(() => this.handleSelectionInTable(key));\n }\n }\n }\n break;\n\n case 'table':\n // After a content change event is handled tableSelection state is reset to null\n // Since we have table selection from DOMSelection, we can use it to re-create the tableSelection state\n if (this.state.tableSelection == null) {\n const { table, firstRow, firstColumn, lastRow, lastColumn } = selection;\n\n const parsedTable = parseTableCells(table);\n if (parsedTable) {\n const firstCo = { row: firstRow, col: firstColumn };\n const lastCo = { row: lastRow, col: lastColumn };\n\n // Create the tableSelection with current table info\n this.state.tableSelection = {\n table,\n parsedTable,\n firstCo,\n lastCo,\n startNode: findTableCellElement(parsedTable, firstCo)?.cell || table,\n };\n }\n }\n if (this.state.tableSelection?.lastCo) {\n const { shiftKey, key } = rawEvent;\n\n if (shiftKey && (key == Left || key == Right)) {\n const isRtl =\n win?.getComputedStyle(this.state.tableSelection.table).direction ==\n 'rtl';\n\n this.updateTableSelectionFromKeyboard(\n 0,\n (key == Left ? -1 : 1) * (isRtl ? -1 : 1)\n );\n rawEvent.preventDefault();\n } else if (shiftKey && (key == Up || key == Down)) {\n this.updateTableSelectionFromKeyboard(key == Up ? -1 : 1, 0);\n rawEvent.preventDefault();\n } else if (key != 'Shift' && !isCharacterValue(rawEvent)) {\n if (key == Up || key == Down || key == Left || key == Right) {\n this.setDOMSelection(null /*domSelection*/, this.state.tableSelection);\n win?.requestAnimationFrame(() => this.handleSelectionInTable(key));\n }\n }\n }\n break;\n }\n }\n\n private getTabKey(rawEvent: KeyboardEvent) {\n return rawEvent.shiftKey ? 'TabLeft' : 'TabRight';\n }\n\n private handleSelectionInTable(\n key: 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight' | 'TabLeft' | 'TabRight'\n ) {\n if (!this.editor || !this.state.tableSelection) {\n return;\n }\n\n const selection = this.editor.getDOMSelection();\n const domHelper = this.editor.getDOMHelper();\n\n if (selection?.type == 'range') {\n const {\n range: { collapsed, startContainer, endContainer, commonAncestorContainer },\n isReverted,\n } = selection;\n const start = isReverted ? endContainer : startContainer;\n const end: Node | null = isReverted ? startContainer : endContainer;\n const tableSel = this.parseTableSelection(commonAncestorContainer, start, domHelper);\n\n if (!tableSel) {\n return;\n }\n\n let lastCo = findCoordinate(tableSel?.parsedTable, end, domHelper);\n let tabMove = false;\n const { parsedTable, firstCo: oldCo, table } = this.state.tableSelection;\n\n if (lastCo && tableSel.table == table) {\n if (lastCo.col != oldCo.col && (key == Up || key == Down)) {\n const change = key == Up ? -1 : 1;\n const originalTd = findTableCellElement(parsedTable, oldCo)?.cell;\n let td: HTMLTableCellElement | null = null;\n\n lastCo = { row: oldCo.row + change, col: oldCo.col };\n\n while (lastCo.row >= 0 && lastCo.row < parsedTable.length) {\n td = findTableCellElement(parsedTable, lastCo)?.cell || null;\n\n if (td == originalTd) {\n lastCo.row += change;\n } else {\n break;\n }\n }\n\n if (collapsed && td) {\n this.setRangeSelectionInTable(\n td,\n key == Up ? td.childNodes.length : 0,\n this.editor\n );\n } else if (!td && (lastCo.row == -1 || lastCo.row <= parsedTable.length)) {\n this.selectBeforeOrAfterElement(\n this.editor,\n table,\n change == 1 /* after */,\n change != 1 /* setSelectionInNextSiblingElement */\n );\n }\n } else if (key == 'TabLeft' || key == 'TabRight') {\n const reverse = key == 'TabLeft';\n for (\n let step = reverse ? -1 : 1,\n row = lastCo.row ?? 0,\n col = (lastCo.col ?? 0) + step;\n ;\n col += step\n ) {\n if (col < 0 || col >= parsedTable[row].length) {\n row += step;\n if (row < 0) {\n this.selectBeforeOrAfterElement(this.editor, tableSel.table);\n break;\n } else if (row >= parsedTable.length) {\n this.selectBeforeOrAfterElement(\n this.editor,\n tableSel.table,\n true /*after*/\n );\n break;\n }\n col = reverse ? parsedTable[row].length - 1 : 0;\n }\n const cell = parsedTable[row][col];\n\n if (typeof cell != 'string') {\n tabMove = true;\n this.setRangeSelectionInTable(\n cell,\n 0,\n this.editor,\n true /* selectAll */\n );\n lastCo.row = row;\n lastCo.col = col;\n break;\n }\n }\n } else {\n this.state.tableSelection = null;\n }\n\n if (\n collapsed &&\n (lastCo.col != oldCo.col || lastCo.row != oldCo.row) &&\n lastCo.row >= 0 &&\n lastCo.row == parsedTable.length - 1 &&\n lastCo.col == parsedTable[lastCo.row]?.length - 1\n ) {\n this.editor?.announce({ defaultStrings: 'announceOnFocusLastCell' });\n }\n }\n\n if (!collapsed && lastCo && !tabMove) {\n this.state.tableSelection = tableSel;\n this.updateTableSelection(lastCo);\n }\n }\n }\n\n private setRangeSelectionInTable(\n cell: Node,\n nodeOffset: number,\n editor: IEditor,\n selectAll?: boolean\n ) {\n const range = editor.getDocument().createRange();\n if (selectAll && cell.firstChild && cell.lastChild) {\n const cellStart = cell.firstChild;\n const cellEnd = cell.lastChild;\n // Get first deepest editable position in the cell\n const posStart = normalizePos(cellStart, 0);\n // Get last deepest editable position in the cell\n const posEnd = normalizePos(cellEnd, cellEnd.childNodes.length);\n\n range.setStart(posStart.node, posStart.offset);\n range.setEnd(posEnd.node, posEnd.offset);\n } else {\n // Get deepest editable position in the cell\n const { node, offset } = normalizePos(cell, nodeOffset);\n\n range.setStart(node, offset);\n range.collapse(true /* toStart */);\n }\n\n this.setDOMSelection(\n {\n type: 'range',\n range,\n isReverted: false,\n },\n null /*tableSelection*/\n );\n }\n\n private updateTableSelectionFromKeyboard(rowChange: number, colChange: number) {\n if (this.state.tableSelection?.lastCo && this.editor) {\n const { lastCo, parsedTable } = this.state.tableSelection;\n const row = lastCo.row + rowChange;\n const col = lastCo.col + colChange;\n\n if (row >= 0 && row < parsedTable.length && col >= 0 && col < parsedTable[row].length) {\n this.updateTableSelection({ row, col });\n }\n }\n }\n\n private selectBeforeOrAfterElement(\n editor: IEditor,\n element: HTMLElement,\n after?: boolean,\n setSelectionInNextSiblingElement?: boolean\n ) {\n const doc = editor.getDocument();\n const parent = element.parentNode;\n const index = parent && toArray(parent.childNodes).indexOf(element);\n let sibling: Element | undefined | null;\n\n if (parent && index !== null && index >= 0) {\n const range = doc.createRange();\n if (\n setSelectionInNextSiblingElement &&\n (sibling = after ? element.nextElementSibling : element.previousElementSibling) &&\n isNodeOfType(sibling, 'ELEMENT_NODE')\n ) {\n range.selectNodeContents(sibling);\n range.collapse(false /* toStart */);\n } else {\n range.setStart(parent, index + (after ? 1 : 0));\n range.collapse();\n }\n\n this.setDOMSelection(\n {\n type: 'range',\n range: range,\n isReverted: false,\n },\n null /*tableSelection*/\n );\n }\n }\n\n private getClickingImage(event: UIEvent): HTMLImageElement | null {\n const target = event.target as Node;\n\n return isNodeOfType(target, 'ELEMENT_NODE') && isElementOfType(target, 'img')\n ? target\n : null;\n }\n\n // MacOS will not create a mouseUp event if contextMenu event is not prevent defaulted.\n // Make sure we capture image target even if image is wrapped\n private getContainedTargetImage = (\n event: MouseEvent,\n previousSelection: DOMSelection | null\n ): HTMLImageElement | null => {\n if (!this.isMac || !previousSelection || previousSelection.type !== 'image') {\n return null;\n }\n\n const target = event.target as Node;\n if (\n isNodeOfType(target, 'ELEMENT_NODE') &&\n isElementOfType(target, 'span') &&\n target.firstChild === previousSelection.image\n ) {\n return previousSelection.image;\n }\n return null;\n };\n\n private onFocus = () => {\n if (!this.state.skipReselectOnFocus && this.state.selection) {\n this.setDOMSelection(this.state.selection, this.state.tableSelection);\n }\n\n if (this.state.selection?.type == 'range' && !this.isSafari) {\n // Editor is focused, now we can get live selection. So no need to keep a selection if the selection type is range.\n this.state.selection = null;\n }\n\n if (this.scrollTopCache && this.editor) {\n const sc = this.editor.getScrollContainer();\n sc.scrollTop = this.scrollTopCache;\n this.scrollTopCache = 0;\n }\n };\n\n private onBlur = () => {\n if (this.editor) {\n if (!this.state.selection) {\n this.state.selection = this.editor.getDOMSelection();\n }\n const sc = this.editor.getScrollContainer();\n this.scrollTopCache = sc.scrollTop;\n }\n };\n\n private onSelectionChange = () => {\n if (this.editor?.hasFocus() && !this.editor.isInShadowEdit()) {\n const newSelection = this.editor.getDOMSelection();\n\n //If am image selection changed to a wider range due a keyboard event, we should update the selection\n const selection = this.editor.getDocument().getSelection();\n if (selection && selection.focusNode) {\n const image = isSingleImageInSelection(selection);\n if (newSelection?.type == 'image' && !image) {\n const range = selection.getRangeAt(0);\n this.editor.setDOMSelection({\n type: 'range',\n range,\n isReverted:\n selection.focusNode != range.endContainer ||\n selection.focusOffset != range.endOffset,\n });\n } else if (newSelection?.type !== 'image' && image) {\n this.editor.setDOMSelection({\n type: 'image',\n image,\n });\n }\n }\n\n // Safari has problem to handle onBlur event. When blur, we cannot get the original selection from editor.\n // So we always save a selection whenever editor has focus. Then after blur, we can still use this cached selection.\n if (newSelection?.type == 'range') {\n if (this.isSafari) {\n this.state.selection = newSelection;\n }\n }\n }\n };\n\n private parseTableSelection(\n tableStart: Node,\n tdStart: Node,\n domHelper: DOMHelper\n ): TableSelectionInfo | null {\n let table: HTMLTableElement | null;\n let parsedTable: ParsedTable | null;\n let firstCo: TableCellCoordinate | null;\n\n if (\n (table = domHelper.findClosestElementAncestor(tableStart, 'table')) &&\n table.isContentEditable &&\n (parsedTable = parseTableCells(table)) &&\n (firstCo = findCoordinate(parsedTable, tdStart, domHelper))\n ) {\n return { table, parsedTable, firstCo, startNode: tdStart };\n } else {\n return null;\n }\n }\n\n private updateTableSelection(lastCo: TableCellCoordinate) {\n if (this.state.tableSelection && this.editor) {\n const {\n table,\n firstCo,\n parsedTable,\n startNode,\n lastCo: oldCo,\n } = this.state.tableSelection;\n\n if (oldCo || firstCo.row != lastCo.row || firstCo.col != lastCo.col) {\n this.state.tableSelection.lastCo = lastCo;\n\n this.setDOMSelection(\n {\n type: 'table',\n table,\n firstRow: firstCo.row,\n firstColumn: firstCo.col,\n lastRow: lastCo.row,\n lastColumn: lastCo.col,\n },\n { table, firstCo, lastCo, parsedTable, startNode }\n );\n\n return true;\n }\n }\n\n return false;\n }\n\n private setDOMSelection(\n selection: DOMSelection | null,\n tableSelection: TableSelectionInfo | null\n ) {\n this.editor?.setDOMSelection(selection);\n this.state.tableSelection = tableSelection;\n }\n\n private detachMouseEvent() {\n if (this.state.mouseDisposer) {\n this.state.mouseDisposer();\n this.state.mouseDisposer = undefined;\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of SelectionPlugin.\n * @param option The editor option\n */\nexport function createSelectionPlugin(\n options: EditorOptions\n): PluginWithState<SelectionPluginState> {\n return new SelectionPlugin(options);\n}\n"]}
1
+ {"version":3,"file":"SelectionPlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/selection/SelectionPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { findCoordinate } from './findCoordinate';\nimport { findTableCellElement } from '../../coreApi/setDOMSelection/findTableCellElement';\nimport { isSingleImageInSelection } from './isSingleImageInSelection';\nimport { normalizePos } from './normalizePos';\nimport {\n isCharacterValue,\n isElementOfType,\n isModifierKey,\n isNodeOfType,\n parseTableCells,\n toArray,\n} from 'roosterjs-content-model-dom';\nimport type {\n DOMSelection,\n IEditor,\n PluginEvent,\n PluginWithState,\n SelectionPluginState,\n EditorOptions,\n DOMHelper,\n ParsedTable,\n TableSelectionInfo,\n TableCellCoordinate,\n DOMEventRecord,\n} from 'roosterjs-content-model-types';\n\nconst MouseLeftButton = 0;\nconst MouseRightButton = 2;\nconst Up = 'ArrowUp';\nconst Down = 'ArrowDown';\nconst Left = 'ArrowLeft';\nconst Right = 'ArrowRight';\nconst Tab = 'Tab';\n\n/**\n * @internal\n */\nexport const DEFAULT_SELECTION_BORDER_COLOR = '#DB626C';\n/**\n * @internal\n */\nexport const DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR = '#C6C6C6';\n\nclass SelectionPlugin implements PluginWithState<SelectionPluginState> {\n private editor: IEditor | null = null;\n private state: SelectionPluginState;\n private disposer: (() => void) | null = null;\n private logicalRootDisposer: (() => void) | null = null;\n private isSafari = false;\n private isMac = false;\n private scrollTopCache: number = 0;\n private pointerEvent: PointerEvent | null = null;\n\n constructor(options: EditorOptions) {\n this.state = {\n selection: null,\n tableSelection: null,\n imageSelectionBorderColor:\n options.imageSelectionBorderColor ?? DEFAULT_SELECTION_BORDER_COLOR,\n imageSelectionBorderColorDark: options.imageSelectionBorderColor\n ? undefined\n : DEFAULT_SELECTION_BORDER_COLOR,\n tableCellSelectionBackgroundColor:\n options.tableCellSelectionBackgroundColor ??\n DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR,\n tableCellSelectionBackgroundColorDark: options.tableCellSelectionBackgroundColor\n ? undefined\n : DEFAULT_TABLE_CELL_SELECTION_BACKGROUND_COLOR,\n };\n }\n\n getName() {\n return 'Selection';\n }\n\n initialize(editor: IEditor) {\n this.editor = editor;\n\n if (!this.state.imageSelectionBorderColorDark && this.state.imageSelectionBorderColor) {\n this.state.imageSelectionBorderColorDark = editor\n .getColorManager()\n .getDarkColor(this.state.imageSelectionBorderColor, undefined, 'border');\n }\n\n if (\n !this.state.tableCellSelectionBackgroundColorDark &&\n this.state.tableCellSelectionBackgroundColor\n ) {\n this.state.tableCellSelectionBackgroundColorDark = editor\n .getColorManager()\n .getDarkColor(\n this.state.tableCellSelectionBackgroundColor,\n undefined,\n 'background'\n );\n }\n\n const env = this.editor.getEnvironment();\n const document = this.editor.getDocument();\n\n this.isSafari = !!env.isSafari;\n this.isMac = !!env.isMac;\n document.addEventListener('selectionchange', this.onSelectionChange);\n const eventHandlers: Partial<\n { [P in keyof HTMLElementEventMap]: DOMEventRecord<HTMLElementEventMap[P]> }\n > = {\n focus: { beforeDispatch: this.onFocus },\n drop: { beforeDispatch: this.onDrop },\n blur: this.isSafari ? undefined : { beforeDispatch: this.onBlur },\n pointerdown: { beforeDispatch: (event: PointerEvent) => this.onPointerDown(event) },\n };\n this.disposer = this.editor.attachDomEvent(<Record<string, DOMEventRecord>>eventHandlers);\n }\n\n dispose() {\n this.editor?.getDocument().removeEventListener('selectionchange', this.onSelectionChange);\n\n if (this.disposer) {\n this.disposer();\n this.disposer = null;\n }\n\n this.logicalRootDisposer?.();\n this.logicalRootDisposer = null;\n\n this.detachMouseEvent();\n this.editor = null;\n }\n\n getState(): SelectionPluginState {\n return this.state;\n }\n\n onPluginEvent(event: PluginEvent) {\n if (!this.editor) {\n return;\n }\n\n switch (event.eventType) {\n case 'mouseDown':\n this.onMouseDown(this.editor, event.rawEvent);\n break;\n\n case 'mouseUp':\n this.onMouseUp();\n break;\n\n case 'keyDown':\n this.onKeyDown(this.editor, event.rawEvent);\n break;\n\n case 'contentChanged':\n this.state.tableSelection = null;\n break;\n\n case 'scroll':\n if (!this.editor.hasFocus()) {\n this.scrollTopCache = event.scrollContainer.scrollTop;\n }\n break;\n\n case 'logicalRootChanged':\n this.logicalRootDisposer?.();\n if (this.isSafari) {\n this.logicalRootDisposer = this.editor.attachDomEvent({\n focus: { beforeDispatch: this.onFocus },\n drop: { beforeDispatch: this.onDrop },\n });\n } else {\n this.logicalRootDisposer = this.editor.attachDomEvent({\n focus: { beforeDispatch: this.onFocus },\n blur: { beforeDispatch: this.onBlur },\n drop: { beforeDispatch: this.onDrop },\n });\n }\n break;\n }\n }\n\n private onMouseDown(editor: IEditor, rawEvent: MouseEvent) {\n const selection = editor.getDOMSelection();\n let image: HTMLImageElement | null;\n\n // Image selection\n if (\n selection?.type == 'image' &&\n (rawEvent.button == MouseLeftButton ||\n (rawEvent.button == MouseRightButton &&\n !this.getClickingImage(rawEvent) &&\n !this.getContainedTargetImage(rawEvent, selection)))\n ) {\n this.setDOMSelection(null /*domSelection*/, null /*tableSelection*/);\n }\n\n if (\n (image =\n this.getClickingImage(rawEvent) ??\n this.getContainedTargetImage(rawEvent, selection)) &&\n image.isContentEditable\n ) {\n this.setDOMSelection(\n {\n type: 'image',\n image: image,\n },\n null\n );\n return;\n }\n\n // Table selection\n if (selection?.type == 'table' && rawEvent.button == MouseLeftButton) {\n this.setDOMSelection(null /*domSelection*/, null /*tableSelection*/);\n }\n\n let tableSelection: TableSelectionInfo | null;\n const target = rawEvent.target as Node;\n\n if (\n target &&\n rawEvent.button == MouseLeftButton &&\n (tableSelection = this.parseTableSelection(target, target, editor.getDOMHelper()))\n ) {\n this.state.tableSelection = tableSelection;\n\n if (rawEvent.detail >= 3) {\n const lastCo = findCoordinate(\n tableSelection.parsedTable,\n rawEvent.target as Node,\n editor.getDOMHelper()\n );\n\n if (lastCo) {\n // Triple click, select the current cell\n tableSelection.lastCo = lastCo;\n this.updateTableSelection(lastCo);\n rawEvent.preventDefault();\n }\n }\n\n this.state.mouseDisposer?.();\n this.state.mouseDisposer = editor.attachDomEvent({\n mousemove: {\n beforeDispatch: this.onMouseMove,\n },\n });\n }\n\n if (rawEvent.defaultPrevented) {\n this.pointerEvent = null;\n }\n }\n\n private onMouseMove = (event: Event) => {\n if (this.editor && this.state.tableSelection) {\n const hasTableSelection = !!this.state.tableSelection.lastCo;\n const currentNode = event.target as Node;\n const domHelper = this.editor.getDOMHelper();\n\n const range = this.editor.getDocument().createRange();\n const startNode = this.state.tableSelection.startNode;\n const isReverted =\n currentNode.compareDocumentPosition(startNode) == Node.DOCUMENT_POSITION_FOLLOWING;\n\n if (isReverted) {\n range.setStart(currentNode, 0);\n range.setEnd(\n startNode,\n isNodeOfType(startNode, 'TEXT_NODE')\n ? startNode.nodeValue?.length ?? 0\n : startNode.childNodes.length\n );\n } else {\n range.setStart(startNode, 0);\n range.setEnd(currentNode, 0);\n }\n\n // Use common container of the range to search a common table that covers both start and end node\n const tableStart = range.commonAncestorContainer;\n const newTableSelection = this.parseTableSelection(tableStart, startNode, domHelper);\n\n if (newTableSelection) {\n const lastCo = findCoordinate(\n newTableSelection.parsedTable,\n currentNode,\n domHelper\n );\n\n if (newTableSelection.table != this.state.tableSelection.table) {\n // Move mouse into another table (nest table scenario)\n this.state.tableSelection = newTableSelection;\n this.state.tableSelection.lastCo = lastCo ?? undefined;\n }\n\n const updated = lastCo && this.updateTableSelection(lastCo);\n\n if (hasTableSelection || updated) {\n event.preventDefault();\n }\n } else if (this.editor.getDOMSelection()?.type == 'table') {\n // Move mouse out of table\n this.setDOMSelection(\n {\n type: 'range',\n range,\n isReverted,\n },\n this.state.tableSelection\n );\n }\n }\n };\n\n private onMouseUp() {\n this.detachMouseEvent();\n if (this.pointerEvent && this.pointerEvent.pointerType === 'touch') {\n requestAnimationFrame(() => {\n if (this.editor && this.pointerEvent) {\n // Handle touch selection here since the cursor position is updated\n // Work-in-progress\n }\n this.pointerEvent = null;\n });\n }\n }\n\n private onDrop = () => {\n this.detachMouseEvent();\n };\n\n private onPointerDown = (e: PointerEvent) => {\n if (e.pointerType === 'touch' || e.pointerType === 'pen') {\n this.pointerEvent = e;\n }\n };\n\n private onKeyDown(editor: IEditor, rawEvent: KeyboardEvent) {\n const key = rawEvent.key;\n const selection = editor.getDOMSelection();\n const win = editor.getDocument().defaultView;\n\n switch (selection?.type) {\n case 'image':\n if (!isModifierKey(rawEvent) && !rawEvent.shiftKey && selection.image.parentNode) {\n if (key === 'Escape') {\n this.selectBeforeOrAfterElement(editor, selection.image);\n rawEvent.stopPropagation();\n } else if (key !== 'Delete' && key !== 'Backspace') {\n this.selectBeforeOrAfterElement(editor, selection.image);\n }\n }\n\n if (\n (isModifierKey(rawEvent) || rawEvent.shiftKey) &&\n selection.image &&\n !this.isSafari\n ) {\n const range = selection.image.ownerDocument.createRange();\n range.selectNode(selection.image);\n this.setDOMSelection(\n {\n type: 'range',\n range,\n isReverted: false,\n },\n null /* tableSelection */\n );\n }\n break;\n\n case 'range':\n if (key == Up || key == Down || key == Left || key == Right || key == Tab) {\n const start = selection.range.startContainer;\n this.state.tableSelection = this.parseTableSelection(\n start,\n start,\n editor.getDOMHelper()\n );\n\n if (this.state.tableSelection && !rawEvent.defaultPrevented) {\n if (key == Tab) {\n this.handleSelectionInTable(this.getTabKey(rawEvent));\n rawEvent.preventDefault();\n } else {\n win?.requestAnimationFrame(() => this.handleSelectionInTable(key));\n }\n }\n }\n break;\n\n case 'table':\n // After a content change event is handled tableSelection state is reset to null\n // Since we have table selection from DOMSelection, we can use it to re-create the tableSelection state\n if (this.state.tableSelection == null) {\n const { table, firstRow, firstColumn, lastRow, lastColumn } = selection;\n\n const parsedTable = parseTableCells(table);\n if (parsedTable) {\n const firstCo = { row: firstRow, col: firstColumn };\n const lastCo = { row: lastRow, col: lastColumn };\n\n // Create the tableSelection with current table info\n this.state.tableSelection = {\n table,\n parsedTable,\n firstCo,\n lastCo,\n startNode: findTableCellElement(parsedTable, firstCo)?.cell || table,\n };\n }\n }\n if (this.state.tableSelection?.lastCo) {\n const { shiftKey, key } = rawEvent;\n\n if (shiftKey && (key == Left || key == Right)) {\n const isRtl =\n win?.getComputedStyle(this.state.tableSelection.table).direction ==\n 'rtl';\n\n this.updateTableSelectionFromKeyboard(\n 0,\n (key == Left ? -1 : 1) * (isRtl ? -1 : 1)\n );\n rawEvent.preventDefault();\n } else if (shiftKey && (key == Up || key == Down)) {\n this.updateTableSelectionFromKeyboard(key == Up ? -1 : 1, 0);\n rawEvent.preventDefault();\n } else if (key != 'Shift' && !isCharacterValue(rawEvent)) {\n if (key == Up || key == Down || key == Left || key == Right) {\n this.setDOMSelection(null /*domSelection*/, this.state.tableSelection);\n win?.requestAnimationFrame(() => this.handleSelectionInTable(key));\n }\n }\n }\n break;\n }\n }\n\n private getTabKey(rawEvent: KeyboardEvent) {\n return rawEvent.shiftKey ? 'TabLeft' : 'TabRight';\n }\n\n private handleSelectionInTable(\n key: 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight' | 'TabLeft' | 'TabRight'\n ) {\n if (!this.editor || !this.state.tableSelection) {\n return;\n }\n\n const selection = this.editor.getDOMSelection();\n const domHelper = this.editor.getDOMHelper();\n\n if (selection?.type == 'range') {\n const {\n range: { collapsed, startContainer, endContainer, commonAncestorContainer },\n isReverted,\n } = selection;\n const start = isReverted ? endContainer : startContainer;\n const end: Node | null = isReverted ? startContainer : endContainer;\n const tableSel = this.parseTableSelection(commonAncestorContainer, start, domHelper);\n\n if (!tableSel) {\n return;\n }\n\n let lastCo = findCoordinate(tableSel?.parsedTable, end, domHelper);\n let tabMove = false;\n const { parsedTable, firstCo: oldCo, table } = this.state.tableSelection;\n\n if (lastCo && tableSel.table == table) {\n if (lastCo.col != oldCo.col && (key == Up || key == Down)) {\n const change = key == Up ? -1 : 1;\n const originalTd = findTableCellElement(parsedTable, oldCo)?.cell;\n let td: HTMLTableCellElement | null = null;\n\n lastCo = { row: oldCo.row + change, col: oldCo.col };\n\n while (lastCo.row >= 0 && lastCo.row < parsedTable.length) {\n td = findTableCellElement(parsedTable, lastCo)?.cell || null;\n\n if (td == originalTd) {\n lastCo.row += change;\n } else {\n break;\n }\n }\n\n if (collapsed && td) {\n this.setRangeSelectionInTable(\n td,\n key == Up ? td.childNodes.length : 0,\n this.editor\n );\n } else if (!td && (lastCo.row == -1 || lastCo.row <= parsedTable.length)) {\n this.selectBeforeOrAfterElement(\n this.editor,\n table,\n change == 1 /* after */,\n change != 1 /* setSelectionInNextSiblingElement */\n );\n }\n } else if (key == 'TabLeft' || key == 'TabRight') {\n const reverse = key == 'TabLeft';\n for (\n let step = reverse ? -1 : 1,\n row = lastCo.row ?? 0,\n col = (lastCo.col ?? 0) + step;\n ;\n col += step\n ) {\n if (col < 0 || col >= parsedTable[row].length) {\n row += step;\n if (row < 0) {\n this.selectBeforeOrAfterElement(this.editor, tableSel.table);\n break;\n } else if (row >= parsedTable.length) {\n this.selectBeforeOrAfterElement(\n this.editor,\n tableSel.table,\n true /*after*/\n );\n break;\n }\n col = reverse ? parsedTable[row].length - 1 : 0;\n }\n const cell = parsedTable[row][col];\n\n if (typeof cell != 'string') {\n tabMove = true;\n this.setRangeSelectionInTable(\n cell,\n 0,\n this.editor,\n true /* selectAll */\n );\n lastCo.row = row;\n lastCo.col = col;\n break;\n }\n }\n } else {\n this.state.tableSelection = null;\n }\n\n if (\n collapsed &&\n (lastCo.col != oldCo.col || lastCo.row != oldCo.row) &&\n lastCo.row >= 0 &&\n lastCo.row == parsedTable.length - 1 &&\n lastCo.col == parsedTable[lastCo.row]?.length - 1\n ) {\n this.editor?.announce({ defaultStrings: 'announceOnFocusLastCell' });\n }\n }\n\n if (!collapsed && lastCo && !tabMove) {\n this.state.tableSelection = tableSel;\n this.updateTableSelection(lastCo);\n }\n }\n }\n\n private setRangeSelectionInTable(\n cell: Node,\n nodeOffset: number,\n editor: IEditor,\n selectAll?: boolean\n ) {\n const range = editor.getDocument().createRange();\n if (selectAll && cell.firstChild && cell.lastChild) {\n const cellStart = cell.firstChild;\n const cellEnd = cell.lastChild;\n // Get first deepest editable position in the cell\n const posStart = normalizePos(cellStart, 0);\n // Get last deepest editable position in the cell\n const posEnd = normalizePos(cellEnd, cellEnd.childNodes.length);\n\n range.setStart(posStart.node, posStart.offset);\n range.setEnd(posEnd.node, posEnd.offset);\n } else {\n // Get deepest editable position in the cell\n const { node, offset } = normalizePos(cell, nodeOffset);\n\n range.setStart(node, offset);\n range.collapse(true /* toStart */);\n }\n\n this.setDOMSelection(\n {\n type: 'range',\n range,\n isReverted: false,\n },\n null /*tableSelection*/\n );\n }\n\n private updateTableSelectionFromKeyboard(rowChange: number, colChange: number) {\n if (this.state.tableSelection?.lastCo && this.editor) {\n const { lastCo, parsedTable } = this.state.tableSelection;\n const row = lastCo.row + rowChange;\n const col = lastCo.col + colChange;\n\n if (row >= 0 && row < parsedTable.length && col >= 0 && col < parsedTable[row].length) {\n this.updateTableSelection({ row, col });\n }\n }\n }\n\n private selectBeforeOrAfterElement(\n editor: IEditor,\n element: HTMLElement,\n after?: boolean,\n setSelectionInNextSiblingElement?: boolean\n ) {\n const doc = editor.getDocument();\n const parent = element.parentNode;\n const index = parent && toArray(parent.childNodes).indexOf(element);\n let sibling: Element | undefined | null;\n\n if (parent && index !== null && index >= 0) {\n const range = doc.createRange();\n if (\n setSelectionInNextSiblingElement &&\n (sibling = after ? element.nextElementSibling : element.previousElementSibling) &&\n isNodeOfType(sibling, 'ELEMENT_NODE')\n ) {\n range.selectNodeContents(sibling);\n range.collapse(false /* toStart */);\n } else {\n range.setStart(parent, index + (after ? 1 : 0));\n range.collapse();\n }\n\n this.setDOMSelection(\n {\n type: 'range',\n range: range,\n isReverted: false,\n },\n null /*tableSelection*/\n );\n }\n }\n\n private getClickingImage(event: UIEvent): HTMLImageElement | null {\n const target = event.target as Node;\n\n return isNodeOfType(target, 'ELEMENT_NODE') && isElementOfType(target, 'img')\n ? target\n : null;\n }\n\n // MacOS will not create a mouseUp event if contextMenu event is not prevent defaulted.\n // Make sure we capture image target even if image is wrapped\n private getContainedTargetImage = (\n event: MouseEvent,\n previousSelection: DOMSelection | null\n ): HTMLImageElement | null => {\n if (!this.isMac || !previousSelection || previousSelection.type !== 'image') {\n return null;\n }\n\n const target = event.target as Node;\n if (\n isNodeOfType(target, 'ELEMENT_NODE') &&\n isElementOfType(target, 'span') &&\n target.firstChild === previousSelection.image\n ) {\n return previousSelection.image;\n }\n return null;\n };\n\n private onFocus = () => {\n if (!this.state.skipReselectOnFocus && this.state.selection) {\n this.setDOMSelection(this.state.selection, this.state.tableSelection);\n }\n\n if (this.state.selection?.type == 'range' && !this.isSafari) {\n // Editor is focused, now we can get live selection. So no need to keep a selection if the selection type is range.\n this.state.selection = null;\n }\n\n if (this.scrollTopCache && this.editor) {\n const sc = this.editor.getScrollContainer();\n sc.scrollTop = this.scrollTopCache;\n this.scrollTopCache = 0;\n }\n };\n\n private onBlur = () => {\n if (this.editor) {\n if (!this.state.selection) {\n this.state.selection = this.editor.getDOMSelection();\n }\n const sc = this.editor.getScrollContainer();\n this.scrollTopCache = sc.scrollTop;\n }\n };\n\n private onSelectionChange = () => {\n if (this.editor?.hasFocus() && !this.editor.isInShadowEdit()) {\n const newSelection = this.editor.getDOMSelection();\n\n //If am image selection changed to a wider range due a keyboard event, we should update the selection\n const selection = this.editor.getDocument().getSelection();\n if (selection && selection.focusNode) {\n const image = isSingleImageInSelection(selection);\n if (newSelection?.type == 'image' && !image) {\n const range = selection.getRangeAt(0);\n this.editor.setDOMSelection({\n type: 'range',\n range,\n isReverted:\n selection.focusNode != range.endContainer ||\n selection.focusOffset != range.endOffset,\n });\n } else if (newSelection?.type !== 'image' && image) {\n this.editor.setDOMSelection({\n type: 'image',\n image,\n });\n }\n }\n\n // Safari has problem to handle onBlur event. When blur, we cannot get the original selection from editor.\n // So we always save a selection whenever editor has focus. Then after blur, we can still use this cached selection.\n if (newSelection?.type == 'range') {\n if (this.isSafari) {\n this.state.selection = newSelection;\n }\n }\n }\n };\n\n private parseTableSelection(\n tableStart: Node,\n tdStart: Node,\n domHelper: DOMHelper\n ): TableSelectionInfo | null {\n let table: HTMLTableElement | null;\n let parsedTable: ParsedTable | null;\n let firstCo: TableCellCoordinate | null;\n\n if (\n (table = domHelper.findClosestElementAncestor(tableStart, 'table')) &&\n table.isContentEditable &&\n (parsedTable = parseTableCells(table)) &&\n (firstCo = findCoordinate(parsedTable, tdStart, domHelper))\n ) {\n return { table, parsedTable, firstCo, startNode: tdStart };\n } else {\n return null;\n }\n }\n\n private updateTableSelection(lastCo: TableCellCoordinate) {\n if (this.state.tableSelection && this.editor) {\n const {\n table,\n firstCo,\n parsedTable,\n startNode,\n lastCo: oldCo,\n } = this.state.tableSelection;\n\n if (oldCo || firstCo.row != lastCo.row || firstCo.col != lastCo.col) {\n this.state.tableSelection.lastCo = lastCo;\n\n this.setDOMSelection(\n {\n type: 'table',\n table,\n firstRow: firstCo.row,\n firstColumn: firstCo.col,\n lastRow: lastCo.row,\n lastColumn: lastCo.col,\n },\n { table, firstCo, lastCo, parsedTable, startNode }\n );\n\n return true;\n }\n }\n\n return false;\n }\n\n private setDOMSelection(\n selection: DOMSelection | null,\n tableSelection: TableSelectionInfo | null\n ) {\n this.editor?.setDOMSelection(selection);\n this.state.tableSelection = tableSelection;\n }\n\n private detachMouseEvent() {\n if (this.state.mouseDisposer) {\n this.state.mouseDisposer();\n this.state.mouseDisposer = undefined;\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of SelectionPlugin.\n * @param option The editor option\n */\nexport function createSelectionPlugin(\n options: EditorOptions\n): PluginWithState<SelectionPluginState> {\n return new SelectionPlugin(options);\n}\n"]}
@@ -13,9 +13,6 @@ define(["require", "exports", "./getPositionFromPath"], function (require, expor
13
13
  core.api.setLogicalRoot(core, restoredLogicalRoot);
14
14
  }
15
15
  }
16
- else {
17
- core.api.setLogicalRoot(core, null);
18
- }
19
16
  }
20
17
  exports.restoreSnapshotLogicalRoot = restoreSnapshotLogicalRoot;
21
18
  });
@@ -1 +1 @@
1
- {"version":3,"file":"restoreSnapshotLogicalRoot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreSnapshotLogicalRoot.ts"],"names":[],"mappings":";;;;IAGA;;OAEG;IACH,SAAgB,0BAA0B,CAAC,IAAgB,EAAE,QAAkB;QAC3E,IAAI,QAAQ,CAAC,eAAe,IAAI,QAAQ,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE;YACjE,IAAM,mBAAmB,GAAG,IAAA,yCAAmB,EAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,eAAe,CAAC;iBACvF,IAAsB,CAAC;YAC5B,IAAI,mBAAmB,KAAK,IAAI,CAAC,WAAW,EAAE;gBAC1C,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;aACtD;SACJ;aAAM;YACH,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;SACvC;IACL,CAAC;IAVD,gEAUC","sourcesContent":["import type { EditorCore, Snapshot } from 'roosterjs-content-model-types';\nimport { getPositionFromPath } from './getPositionFromPath';\n\n/**\n * @internal\n */\nexport function restoreSnapshotLogicalRoot(core: EditorCore, snapshot: Snapshot) {\n if (snapshot.logicalRootPath && snapshot.logicalRootPath.length > 0) {\n const restoredLogicalRoot = getPositionFromPath(core.physicalRoot, snapshot.logicalRootPath)\n .node as HTMLDivElement;\n if (restoredLogicalRoot !== core.logicalRoot) {\n core.api.setLogicalRoot(core, restoredLogicalRoot);\n }\n } else {\n core.api.setLogicalRoot(core, null);\n }\n}\n"]}
1
+ {"version":3,"file":"restoreSnapshotLogicalRoot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreSnapshotLogicalRoot.ts"],"names":[],"mappings":";;;;IAGA;;OAEG;IACH,SAAgB,0BAA0B,CAAC,IAAgB,EAAE,QAAkB;QAC3E,IAAI,QAAQ,CAAC,eAAe,IAAI,QAAQ,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE;YACjE,IAAM,mBAAmB,GAAG,IAAA,yCAAmB,EAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,eAAe,CAAC;iBACvF,IAAsB,CAAC;YAC5B,IAAI,mBAAmB,KAAK,IAAI,CAAC,WAAW,EAAE;gBAC1C,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;aACtD;SACJ;IACL,CAAC;IARD,gEAQC","sourcesContent":["import type { EditorCore, Snapshot } from 'roosterjs-content-model-types';\nimport { getPositionFromPath } from './getPositionFromPath';\n\n/**\n * @internal\n */\nexport function restoreSnapshotLogicalRoot(core: EditorCore, snapshot: Snapshot) {\n if (snapshot.logicalRootPath && snapshot.logicalRootPath.length > 0) {\n const restoredLogicalRoot = getPositionFromPath(core.physicalRoot, snapshot.logicalRootPath)\n .node as HTMLDivElement;\n if (restoredLogicalRoot !== core.logicalRoot) {\n core.api.setLogicalRoot(core, restoredLogicalRoot);\n }\n }\n}\n"]}
@@ -15,6 +15,10 @@ define(["require", "exports", "roosterjs-content-model-dom", "./restoreSnapshotC
15
15
  }, true /*broadcast*/);
16
16
  try {
17
17
  core.undo.isRestoring = true;
18
+ // Force clear logical root before restoring snapshot, so the whole editor is editable.
19
+ // Without changing logical root, browser may want to maintain the scroll position of current logical root,
20
+ // which may cause the editor to scroll to a wrong position after content is changed.
21
+ core.api.setLogicalRoot(core, null /* logicalRoot */);
18
22
  (0, restoreSnapshotHTML_1.restoreSnapshotHTML)(core, snapshot);
19
23
  (0, restoreSnapshotLogicalRoot_1.restoreSnapshotLogicalRoot)(core, snapshot);
20
24
  (0, restoreSnapshotSelection_1.restoreSnapshotSelection)(core, snapshot);
@@ -1 +1 @@
1
- {"version":3,"file":"restoreUndoSnapshot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreUndoSnapshot.ts"],"names":[],"mappings":";;;;IAOA;;;;;OAKG;IACI,IAAM,mBAAmB,GAAwB,UAAC,IAAI,EAAE,QAAQ;QACnE,IAAI,CAAC,GAAG,CAAC,YAAY,CACjB,IAAI,EACJ;YACI,SAAS,EAAE,kBAAkB;YAC7B,UAAU,EAAE,QAAQ,CAAC,IAAI;SAC5B,EACD,IAAI,CAAC,aAAa,CACrB,CAAC;QAEF,IAAI;YACA,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YAE7B,IAAA,yCAAmB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACpC,IAAA,uDAA0B,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC3C,IAAA,mDAAwB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACzC,IAAA,6CAAqB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAEtC,IAAM,OAAK,GAAwB;gBAC/B,SAAS,EAAE,gBAAgB;gBAC3B,eAAe,EAAE,QAAQ,CAAC,eAAe;gBACzC,YAAY,EAAE,QAAQ,CAAC,YAAY;gBACnC,MAAM,EAAE,0CAAY,CAAC,UAAU;aAClC,CAAC;YAEF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAK,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;SAC3D;gBAAS;YACN,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;SACjC;IACL,CAAC,CAAC;IA7BW,QAAA,mBAAmB,uBA6B9B","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { restoreSnapshotColors } from './restoreSnapshotColors';\nimport { restoreSnapshotHTML } from './restoreSnapshotHTML';\nimport { restoreSnapshotLogicalRoot } from './restoreSnapshotLogicalRoot';\nimport { restoreSnapshotSelection } from './restoreSnapshotSelection';\nimport type { ContentChangedEvent, RestoreUndoSnapshot } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Restore an undo snapshot into editor\n * @param core The editor core object\n * @param step Steps to move, can be 0, positive or negative\n */\nexport const restoreUndoSnapshot: RestoreUndoSnapshot = (core, snapshot) => {\n core.api.triggerEvent(\n core,\n {\n eventType: 'beforeSetContent',\n newContent: snapshot.html,\n },\n true /*broadcast*/\n );\n\n try {\n core.undo.isRestoring = true;\n\n restoreSnapshotHTML(core, snapshot);\n restoreSnapshotLogicalRoot(core, snapshot);\n restoreSnapshotSelection(core, snapshot);\n restoreSnapshotColors(core, snapshot);\n\n const event: ContentChangedEvent = {\n eventType: 'contentChanged',\n additionalState: snapshot.additionalState,\n entityStates: snapshot.entityStates,\n source: ChangeSource.SetContent,\n };\n\n core.api.triggerEvent(core, event, false /*broadcast*/);\n } finally {\n core.undo.isRestoring = false;\n }\n};\n"]}
1
+ {"version":3,"file":"restoreUndoSnapshot.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/restoreUndoSnapshot/restoreUndoSnapshot.ts"],"names":[],"mappings":";;;;IAOA;;;;;OAKG;IACI,IAAM,mBAAmB,GAAwB,UAAC,IAAI,EAAE,QAAQ;QACnE,IAAI,CAAC,GAAG,CAAC,YAAY,CACjB,IAAI,EACJ;YACI,SAAS,EAAE,kBAAkB;YAC7B,UAAU,EAAE,QAAQ,CAAC,IAAI;SAC5B,EACD,IAAI,CAAC,aAAa,CACrB,CAAC;QAEF,IAAI;YACA,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YAE7B,uFAAuF;YACvF,2GAA2G;YAC3G,qFAAqF;YACrF,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAEtD,IAAA,yCAAmB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACpC,IAAA,uDAA0B,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC3C,IAAA,mDAAwB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACzC,IAAA,6CAAqB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAEtC,IAAM,OAAK,GAAwB;gBAC/B,SAAS,EAAE,gBAAgB;gBAC3B,eAAe,EAAE,QAAQ,CAAC,eAAe;gBACzC,YAAY,EAAE,QAAQ,CAAC,YAAY;gBACnC,MAAM,EAAE,0CAAY,CAAC,UAAU;aAClC,CAAC;YAEF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAK,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;SAC3D;gBAAS;YACN,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;SACjC;IACL,CAAC,CAAC;IAlCW,QAAA,mBAAmB,uBAkC9B","sourcesContent":["import { ChangeSource } from 'roosterjs-content-model-dom';\nimport { restoreSnapshotColors } from './restoreSnapshotColors';\nimport { restoreSnapshotHTML } from './restoreSnapshotHTML';\nimport { restoreSnapshotLogicalRoot } from './restoreSnapshotLogicalRoot';\nimport { restoreSnapshotSelection } from './restoreSnapshotSelection';\nimport type { ContentChangedEvent, RestoreUndoSnapshot } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Restore an undo snapshot into editor\n * @param core The editor core object\n * @param step Steps to move, can be 0, positive or negative\n */\nexport const restoreUndoSnapshot: RestoreUndoSnapshot = (core, snapshot) => {\n core.api.triggerEvent(\n core,\n {\n eventType: 'beforeSetContent',\n newContent: snapshot.html,\n },\n true /*broadcast*/\n );\n\n try {\n core.undo.isRestoring = true;\n\n // Force clear logical root before restoring snapshot, so the whole editor is editable.\n // Without changing logical root, browser may want to maintain the scroll position of current logical root,\n // which may cause the editor to scroll to a wrong position after content is changed.\n core.api.setLogicalRoot(core, null /* logicalRoot */);\n\n restoreSnapshotHTML(core, snapshot);\n restoreSnapshotLogicalRoot(core, snapshot);\n restoreSnapshotSelection(core, snapshot);\n restoreSnapshotColors(core, snapshot);\n\n const event: ContentChangedEvent = {\n eventType: 'contentChanged',\n additionalState: snapshot.additionalState,\n entityStates: snapshot.entityStates,\n source: ChangeSource.SetContent,\n };\n\n core.api.triggerEvent(core, event, false /*broadcast*/);\n } finally {\n core.undo.isRestoring = false;\n }\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"DOMEventPlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/domEvent/DOMEventPlugin.ts"],"names":[],"mappings":";;;;IAcA,IAAM,YAAY,GAAqD;QACnE,OAAO,EAAE,SAAS;QAClB,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,UAAU;KACvB,CAAC;IAEF;;;;;;;;;;OAUG;IACH;QAKI;;;;WAIG;QACH,wBAAY,OAAsB,EAAE,UAA0B;YAA9D,iBAQC;YAjBO,WAAM,GAAmB,IAAI,CAAC;YAC9B,aAAQ,GAAwB,IAAI,CAAC;YAqFrC,gBAAW,GAAG,UAAC,CAAQ;gBAC3B,IAAM,SAAS,GAAG,CAAc,CAAC;gBACjC,IAAM,IAAI,GAAG,SAAS,CAAC,MAAc,CAAC;gBACtC,IAAM,OAAO,GAAG,IAAA,0CAAY,EAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;gBAE/E,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE;oBACvC,SAAS,CAAC,cAAc,EAAE,CAAC;iBAC9B;YACL,CAAC,CAAC;YAEM,WAAM,GAAG;;gBACb,IAAM,GAAG,GAAG,MAAA,KAAI,CAAC,MAAM,0CAAE,WAAW,EAAE,CAAC;gBAEvC,MAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,WAAW,0CAAE,qBAAqB,CAAC;oBACpC,IAAI,KAAI,CAAC,MAAM,EAAE;wBACb,KAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;wBAC3B,KAAI,CAAC,MAAM,CAAC,YAAY,CAAC,gBAAgB,EAAE;4BACvC,MAAM,EAAE,0CAAY,CAAC,IAAI;yBAC5B,CAAC,CAAC;qBACN;gBACL,CAAC,CAAC,CAAC;YACP,CAAC,CAAC;YAEM,aAAQ,GAAG,UAAC,CAAQ;;gBACxB,MAAA,KAAI,CAAC,MAAM,0CAAE,YAAY,CAAC,QAAQ,EAAE;oBAChC,QAAQ,EAAE,CAAC;oBACX,eAAe,EAAE,KAAI,CAAC,KAAK,CAAC,eAAe;iBAC9C,CAAC,CAAC;YACP,CAAC,CAAC;YAEM,yBAAoB,GAAkC;gBAC1D,cAAc,EAAE,UAAA,KAAK;;oBACjB,IAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAE3C,IAAI,IAAA,8CAAgB,EAAC,KAAK,CAAC,IAAI,IAAA,+CAAiB,EAAC,KAAK,CAAC,EAAE;wBACrD,sFAAsF;wBACtF,8EAA8E;wBAC9E,KAAK,CAAC,eAAe,EAAE,CAAC;qBAC3B;oBAED,IAAM,SAAS,GAAG,MAAA,MAAA,MAAA,KAAI,CAAC,MAAM,0CAAE,cAAc,EAAE,0CAAE,SAAS,mCAAI,KAAK,CAAC;oBACpE,IAAM,WAAW,GAAG,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,KAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;oBAE5E,IAAI,KAAI,CAAC,MAAM,IAAI,SAAS,IAAI,CAAC,WAAW,EAAE;wBAC1C,KAAI,CAAC,MAAM,CAAC,YAAY,CAAC,SAAS,EAAE;4BAChC,QAAQ,EAAE,KAAK;yBAClB,CAAC,CAAC;qBACN;gBACL,CAAC;aACJ,CAAC;YAEM,sBAAiB,GAA0B;gBAC/C,cAAc,EAAE,UAAA,KAAK;;oBACjB,KAAK,CAAC,eAAe,EAAE,CAAC;oBAExB,IAAM,SAAS,GAAG,MAAA,MAAA,MAAA,KAAI,CAAC,MAAM,0CAAE,cAAc,EAAE,0CAAE,SAAS,mCAAI,KAAK,CAAC;oBACpE,IAAM,WAAW,GAAG,CAAC,SAAS,IAAI,CAAE,KAAoB,CAAC,WAAW,IAAI,KAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;oBAE5F,IAAI,KAAI,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE;wBAC7B,KAAI,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE;4BAC9B,QAAQ,EAAE,KAAmB;yBAChC,CAAC,CAAC;qBACN;gBACL,CAAC;aACJ,CAAC;YAEM,gBAAW,GAAG,UAAC,KAAiB;gBACpC,IAAI,KAAI,CAAC,MAAM,EAAE;oBACb,IAAI,CAAC,KAAI,CAAC,KAAK,CAAC,uBAAuB,EAAE;wBACrC,KAAI,CAAC,MAAM;6BACN,WAAW,EAAE;6BACb,gBAAgB,CAAC,SAAS,EAAE,KAAI,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;wBACtE,KAAI,CAAC,KAAK,CAAC,uBAAuB,GAAG,IAAI,CAAC;wBAC1C,KAAI,CAAC,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC;wBACpC,KAAI,CAAC,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC;qBACvC;oBAED,KAAI,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,EAAE;wBAClC,QAAQ,EAAE,KAAK;qBAClB,CAAC,CAAC;iBACN;YACL,CAAC,CAAC;YAEM,cAAS,GAAG,UAAC,QAAoB;gBACrC,IAAI,KAAI,CAAC,MAAM,EAAE;oBACb,KAAI,CAAC,0BAA0B,EAAE,CAAC;oBAClC,KAAI,CAAC,MAAM,CAAC,YAAY,CAAC,SAAS,EAAE;wBAChC,QAAQ,UAAA;wBACR,UAAU,EACN,KAAI,CAAC,KAAK,CAAC,UAAU,IAAI,QAAQ,CAAC,KAAK;4BACvC,KAAI,CAAC,KAAK,CAAC,UAAU,IAAI,QAAQ,CAAC,KAAK;qBAC9C,CAAC,CAAC;iBACN;YACL,CAAC,CAAC;YAEM,uBAAkB,GAAG;gBACzB,KAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;YAC9B,CAAC,CAAC;YAEM,qBAAgB,GAAG,UAAC,QAA0B;;gBAClD,KAAI,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;gBAC3B,MAAA,KAAI,CAAC,MAAM,0CAAE,YAAY,CAAC,gBAAgB,EAAE;oBACxC,QAAQ,UAAA;iBACX,CAAC,CAAC;YACP,CAAC,CAAC;YApLE,IAAI,CAAC,KAAK,GAAG;gBACT,OAAO,EAAE,KAAK;gBACd,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,UAAU;gBACtD,UAAU,EAAE,IAAI;gBAChB,UAAU,EAAE,IAAI;gBAChB,uBAAuB,EAAE,KAAK;aACjC,CAAC;QACN,CAAC;QAED;;WAEG;QACH,gCAAO,GAAP;YACI,OAAO,UAAU,CAAC;QACtB,CAAC;QAED;;;WAGG;QACH,mCAAU,GAAV,UAAW,MAAe;;YACtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YAErB,IAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAC3C,IAAM,aAAa,GAEf;gBACA,oBAAoB;gBACpB,QAAQ,EAAE,IAAI,CAAC,oBAAoB;gBACnC,OAAO,EAAE,IAAI,CAAC,oBAAoB;gBAClC,KAAK,EAAE,IAAI,CAAC,oBAAoB;gBAChC,KAAK,EAAE,IAAI,CAAC,iBAAiB;gBAE7B,iBAAiB;gBACjB,SAAS,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,WAAW,EAAE;gBAE/C,0BAA0B;gBAC1B,gBAAgB,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,kBAAkB,EAAE;gBAC7D,cAAc,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,gBAAgB,EAAE;gBAEzD,yBAAyB;gBACzB,SAAS,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,WAAW,EAAE;gBAC/C,IAAI,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,MAAM,EAAE;aACxC,CAAC;YAEF,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,CAAiC,aAAa,CAAC,CAAC;YAE1F,kBAAkB;YAClB,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrE,MAAA,QAAQ,CAAC,WAAW,0CAAE,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAChE,MAAA,QAAQ,CAAC,WAAW,0CAAE,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpE,CAAC;QAED;;WAEG;QACH,gCAAO,GAAP;;YACI,IAAI,CAAC,0BAA0B,EAAE,CAAC;YAElC,IAAM,QAAQ,GAAG,MAAA,IAAI,CAAC,MAAM,0CAAE,WAAW,EAAE,CAAC;YAE5C,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,WAAW,0CAAE,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YACpE,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,WAAW,0CAAE,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YACpE,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YACxE,MAAA,IAAI,CAAC,QAAQ,+CAAb,IAAI,CAAa,CAAC;YAClB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;YACrB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACvB,CAAC;QAED;;WAEG;QACH,iCAAQ,GAAR;YACI,OAAO,IAAI,CAAC,KAAK,CAAC;QACtB,CAAC;QA4GO,mDAA0B,GAAlC;YACI,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,uBAAuB,EAAE;gBACnD,IAAI,CAAC,KAAK,CAAC,uBAAuB,GAAG,KAAK,CAAC;gBAC3C,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;aAClF;QACL,CAAC;QACL,qBAAC;IAAD,CAAC,AAvMD,IAuMC;IAED;;;;;OAKG;IACH,SAAgB,oBAAoB,CAChC,MAAqB,EACrB,UAA0B;QAE1B,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAClD,CAAC;IALD,oDAKC","sourcesContent":["import {\n ChangeSource,\n isCharacterValue,\n isCursorMovingKey,\n isNodeOfType,\n} from 'roosterjs-content-model-dom';\nimport type {\n DOMEventPluginState,\n IEditor,\n DOMEventRecord,\n EditorOptions,\n PluginWithState,\n} from 'roosterjs-content-model-types';\n\nconst EventTypeMap: Record<string, 'keyDown' | 'keyUp' | 'keyPress'> = {\n keydown: 'keyDown',\n keyup: 'keyUp',\n keypress: 'keyPress',\n};\n\n/**\n * DOMEventPlugin handles customized DOM events, including:\n * 1. Keyboard event\n * 2. Mouse event\n * 3. IME state\n * 4. Drop event\n * 5. Focus and blur event\n * 6. Input event\n * 7. Scroll event\n * It contains special handling for Safari since Safari cannot get correct selection when onBlur event is triggered in editor.\n */\nclass DOMEventPlugin implements PluginWithState<DOMEventPluginState> {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n private state: DOMEventPluginState;\n\n /**\n * Construct a new instance of DOMEventPlugin\n * @param options The editor options\n * @param contentDiv The editor content DIV\n */\n constructor(options: EditorOptions, contentDiv: HTMLDivElement) {\n this.state = {\n isInIME: false,\n scrollContainer: options.scrollContainer || contentDiv,\n mouseDownX: null,\n mouseDownY: null,\n mouseUpEventListerAdded: false,\n };\n }\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'DOMEvent';\n }\n\n /**\n * Initialize this plugin. This should only be called from Editor\n * @param editor Editor instance\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n\n const document = this.editor.getDocument();\n const eventHandlers: Partial<\n { [P in keyof HTMLElementEventMap]: DOMEventRecord<HTMLElementEventMap[P]> }\n > = {\n // 1. Keyboard event\n keypress: this.keyboardEventHandler,\n keydown: this.keyboardEventHandler,\n keyup: this.keyboardEventHandler,\n input: this.inputEventHandler,\n\n // 2. Mouse event\n mousedown: { beforeDispatch: this.onMouseDown },\n\n // 3. IME state management\n compositionstart: { beforeDispatch: this.onCompositionStart },\n compositionend: { beforeDispatch: this.onCompositionEnd },\n\n // 4. Drag and Drop event\n dragstart: { beforeDispatch: this.onDragStart },\n drop: { beforeDispatch: this.onDrop },\n };\n\n this.disposer = this.editor.attachDomEvent(<Record<string, DOMEventRecord>>eventHandlers);\n\n // 7. Scroll event\n this.state.scrollContainer.addEventListener('scroll', this.onScroll);\n document.defaultView?.addEventListener('scroll', this.onScroll);\n document.defaultView?.addEventListener('resize', this.onScroll);\n }\n\n /**\n * Dispose this plugin\n */\n dispose() {\n this.removeMouseUpEventListener();\n\n const document = this.editor?.getDocument();\n\n document?.defaultView?.removeEventListener('resize', this.onScroll);\n document?.defaultView?.removeEventListener('scroll', this.onScroll);\n this.state.scrollContainer.removeEventListener('scroll', this.onScroll);\n this.disposer?.();\n this.disposer = null;\n this.editor = null;\n }\n\n /**\n * Get plugin state object\n */\n getState() {\n return this.state;\n }\n\n private onDragStart = (e: Event) => {\n const dragEvent = e as DragEvent;\n const node = dragEvent.target as Node;\n const element = isNodeOfType(node, 'ELEMENT_NODE') ? node : node.parentElement;\n\n if (element && !element.isContentEditable) {\n dragEvent.preventDefault();\n }\n };\n\n private onDrop = () => {\n const doc = this.editor?.getDocument();\n\n doc?.defaultView?.requestAnimationFrame(() => {\n if (this.editor) {\n this.editor.takeSnapshot();\n this.editor.triggerEvent('contentChanged', {\n source: ChangeSource.Drop,\n });\n }\n });\n };\n\n private onScroll = (e: Event) => {\n this.editor?.triggerEvent('scroll', {\n rawEvent: e,\n scrollContainer: this.state.scrollContainer,\n });\n };\n\n private keyboardEventHandler: DOMEventRecord<KeyboardEvent> = {\n beforeDispatch: event => {\n const eventType = EventTypeMap[event.type];\n\n if (isCharacterValue(event) || isCursorMovingKey(event)) {\n // Stop propagation for Character keys and Up/Down/Left/Right/Home/End/PageUp/PageDown\n // since editor already handles these keys and no need to propagate to parents\n event.stopPropagation();\n }\n\n const isAndroid = this.editor?.getEnvironment()?.isAndroid ?? false;\n const isComposing = !isAndroid && (event.isComposing || this.state.isInIME);\n\n if (this.editor && eventType && !isComposing) {\n this.editor.triggerEvent(eventType, {\n rawEvent: event,\n });\n }\n },\n };\n\n private inputEventHandler: DOMEventRecord<Event> = {\n beforeDispatch: event => {\n event.stopPropagation();\n\n const isAndroid = this.editor?.getEnvironment()?.isAndroid ?? false;\n const isComposing = !isAndroid && ((event as InputEvent).isComposing || this.state.isInIME);\n\n if (this.editor && !isComposing) {\n this.editor.triggerEvent('input', {\n rawEvent: event as InputEvent,\n });\n }\n },\n };\n\n private onMouseDown = (event: MouseEvent) => {\n if (this.editor) {\n if (!this.state.mouseUpEventListerAdded) {\n this.editor\n .getDocument()\n .addEventListener('mouseup', this.onMouseUp, true /*setCapture*/);\n this.state.mouseUpEventListerAdded = true;\n this.state.mouseDownX = event.pageX;\n this.state.mouseDownY = event.pageY;\n }\n\n this.editor.triggerEvent('mouseDown', {\n rawEvent: event,\n });\n }\n };\n\n private onMouseUp = (rawEvent: MouseEvent) => {\n if (this.editor) {\n this.removeMouseUpEventListener();\n this.editor.triggerEvent('mouseUp', {\n rawEvent,\n isClicking:\n this.state.mouseDownX == rawEvent.pageX &&\n this.state.mouseDownY == rawEvent.pageY,\n });\n }\n };\n\n private onCompositionStart = () => {\n this.state.isInIME = true;\n };\n\n private onCompositionEnd = (rawEvent: CompositionEvent) => {\n this.state.isInIME = false;\n this.editor?.triggerEvent('compositionEnd', {\n rawEvent,\n });\n };\n\n private removeMouseUpEventListener() {\n if (this.editor && this.state.mouseUpEventListerAdded) {\n this.state.mouseUpEventListerAdded = false;\n this.editor.getDocument().removeEventListener('mouseup', this.onMouseUp, true);\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of DOMEventPlugin.\n * @param option The editor option\n * @param contentDiv The editor content DIV element\n */\nexport function createDOMEventPlugin(\n option: EditorOptions,\n contentDiv: HTMLDivElement\n): PluginWithState<DOMEventPluginState> {\n return new DOMEventPlugin(option, contentDiv);\n}\n"]}
1
+ {"version":3,"file":"DOMEventPlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/domEvent/DOMEventPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ChangeSource,\n isCharacterValue,\n isCursorMovingKey,\n isNodeOfType,\n} from 'roosterjs-content-model-dom';\nimport type {\n DOMEventPluginState,\n IEditor,\n DOMEventRecord,\n EditorOptions,\n PluginWithState,\n} from 'roosterjs-content-model-types';\n\nconst EventTypeMap: Record<string, 'keyDown' | 'keyUp' | 'keyPress'> = {\n keydown: 'keyDown',\n keyup: 'keyUp',\n keypress: 'keyPress',\n};\n\n/**\n * DOMEventPlugin handles customized DOM events, including:\n * 1. Keyboard event\n * 2. Mouse event\n * 3. IME state\n * 4. Drop event\n * 5. Focus and blur event\n * 6. Input event\n * 7. Scroll event\n * It contains special handling for Safari since Safari cannot get correct selection when onBlur event is triggered in editor.\n */\nclass DOMEventPlugin implements PluginWithState<DOMEventPluginState> {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n private state: DOMEventPluginState;\n\n /**\n * Construct a new instance of DOMEventPlugin\n * @param options The editor options\n * @param contentDiv The editor content DIV\n */\n constructor(options: EditorOptions, contentDiv: HTMLDivElement) {\n this.state = {\n isInIME: false,\n scrollContainer: options.scrollContainer || contentDiv,\n mouseDownX: null,\n mouseDownY: null,\n mouseUpEventListerAdded: false,\n };\n }\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'DOMEvent';\n }\n\n /**\n * Initialize this plugin. This should only be called from Editor\n * @param editor Editor instance\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n\n const document = this.editor.getDocument();\n const eventHandlers: Partial<\n { [P in keyof HTMLElementEventMap]: DOMEventRecord<HTMLElementEventMap[P]> }\n > = {\n // 1. Keyboard event\n keypress: this.keyboardEventHandler,\n keydown: this.keyboardEventHandler,\n keyup: this.keyboardEventHandler,\n input: this.inputEventHandler,\n\n // 2. Mouse event\n mousedown: { beforeDispatch: this.onMouseDown },\n\n // 3. IME state management\n compositionstart: { beforeDispatch: this.onCompositionStart },\n compositionend: { beforeDispatch: this.onCompositionEnd },\n\n // 4. Drag and Drop event\n dragstart: { beforeDispatch: this.onDragStart },\n drop: { beforeDispatch: this.onDrop },\n };\n\n this.disposer = this.editor.attachDomEvent(<Record<string, DOMEventRecord>>eventHandlers);\n\n // 7. Scroll event\n this.state.scrollContainer.addEventListener('scroll', this.onScroll);\n document.defaultView?.addEventListener('scroll', this.onScroll);\n document.defaultView?.addEventListener('resize', this.onScroll);\n }\n\n /**\n * Dispose this plugin\n */\n dispose() {\n this.removeMouseUpEventListener();\n\n const document = this.editor?.getDocument();\n\n document?.defaultView?.removeEventListener('resize', this.onScroll);\n document?.defaultView?.removeEventListener('scroll', this.onScroll);\n this.state.scrollContainer.removeEventListener('scroll', this.onScroll);\n this.disposer?.();\n this.disposer = null;\n this.editor = null;\n }\n\n /**\n * Get plugin state object\n */\n getState() {\n return this.state;\n }\n\n private onDragStart = (e: Event) => {\n const dragEvent = e as DragEvent;\n const node = dragEvent.target as Node;\n const element = isNodeOfType(node, 'ELEMENT_NODE') ? node : node.parentElement;\n\n if (element && !element.isContentEditable) {\n dragEvent.preventDefault();\n }\n };\n\n private onDrop = () => {\n const doc = this.editor?.getDocument();\n\n doc?.defaultView?.requestAnimationFrame(() => {\n if (this.editor) {\n this.editor.takeSnapshot();\n this.editor.triggerEvent('contentChanged', {\n source: ChangeSource.Drop,\n });\n }\n });\n };\n\n private onScroll = (e: Event) => {\n this.editor?.triggerEvent('scroll', {\n rawEvent: e,\n scrollContainer: this.state.scrollContainer,\n });\n };\n\n private keyboardEventHandler: DOMEventRecord<KeyboardEvent> = {\n beforeDispatch: event => {\n const eventType = EventTypeMap[event.type];\n\n if (isCharacterValue(event) || isCursorMovingKey(event)) {\n // Stop propagation for Character keys and Up/Down/Left/Right/Home/End/PageUp/PageDown\n // since editor already handles these keys and no need to propagate to parents\n event.stopPropagation();\n }\n\n const isAndroid = this.editor?.getEnvironment()?.isAndroid ?? false;\n const isComposing = !isAndroid && (event.isComposing || this.state.isInIME);\n\n if (this.editor && eventType && !isComposing) {\n this.editor.triggerEvent(eventType, {\n rawEvent: event,\n });\n }\n },\n };\n\n private inputEventHandler: DOMEventRecord<Event> = {\n beforeDispatch: event => {\n event.stopPropagation();\n\n const isAndroid = this.editor?.getEnvironment()?.isAndroid ?? false;\n const isComposing =\n !isAndroid && ((event as InputEvent).isComposing || this.state.isInIME);\n\n if (this.editor && !isComposing) {\n this.editor.triggerEvent('input', {\n rawEvent: event as InputEvent,\n });\n }\n },\n };\n\n private onMouseDown = (event: MouseEvent) => {\n if (this.editor) {\n if (!this.state.mouseUpEventListerAdded) {\n this.editor\n .getDocument()\n .addEventListener('mouseup', this.onMouseUp, true /*setCapture*/);\n this.state.mouseUpEventListerAdded = true;\n this.state.mouseDownX = event.pageX;\n this.state.mouseDownY = event.pageY;\n }\n\n this.editor.triggerEvent('mouseDown', {\n rawEvent: event,\n });\n }\n };\n\n private onMouseUp = (rawEvent: MouseEvent) => {\n if (this.editor) {\n this.removeMouseUpEventListener();\n this.editor.triggerEvent('mouseUp', {\n rawEvent,\n isClicking:\n this.state.mouseDownX == rawEvent.pageX &&\n this.state.mouseDownY == rawEvent.pageY,\n });\n }\n };\n\n private onCompositionStart = () => {\n this.state.isInIME = true;\n };\n\n private onCompositionEnd = (rawEvent: CompositionEvent) => {\n this.state.isInIME = false;\n this.editor?.triggerEvent('compositionEnd', {\n rawEvent,\n });\n };\n\n private removeMouseUpEventListener() {\n if (this.editor && this.state.mouseUpEventListerAdded) {\n this.state.mouseUpEventListerAdded = false;\n this.editor.getDocument().removeEventListener('mouseup', this.onMouseUp, true);\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of DOMEventPlugin.\n * @param option The editor option\n * @param contentDiv The editor content DIV element\n */\nexport function createDOMEventPlugin(\n option: EditorOptions,\n contentDiv: HTMLDivElement\n): PluginWithState<DOMEventPluginState> {\n return new DOMEventPlugin(option, contentDiv);\n}\n"]}