roosterjs-content-model-core 9.10.0 → 9.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/lib/corePlugin/copyPaste/CopyPastePlugin.js +3 -1
  2. package/lib/corePlugin/copyPaste/CopyPastePlugin.js.map +1 -1
  3. package/lib/corePlugin/copyPaste/utils/adjustImageSelectionOnSafari.d.ts +6 -0
  4. package/lib/corePlugin/copyPaste/utils/adjustImageSelectionOnSafari.js +21 -0
  5. package/lib/corePlugin/copyPaste/utils/adjustImageSelectionOnSafari.js.map +1 -0
  6. package/lib/corePlugin/copyPaste/utils/deleteEmptyList.js.map +1 -0
  7. package/lib/editor/core/DOMHelperImpl.js +6 -0
  8. package/lib/editor/core/DOMHelperImpl.js.map +1 -1
  9. package/lib-amd/corePlugin/copyPaste/CopyPastePlugin.js +2 -1
  10. package/lib-amd/corePlugin/copyPaste/CopyPastePlugin.js.map +1 -1
  11. package/lib-amd/corePlugin/copyPaste/utils/adjustImageSelectionOnSafari.d.ts +6 -0
  12. package/lib-amd/corePlugin/copyPaste/utils/adjustImageSelectionOnSafari.js +23 -0
  13. package/lib-amd/corePlugin/copyPaste/utils/adjustImageSelectionOnSafari.js.map +1 -0
  14. package/lib-amd/corePlugin/copyPaste/utils/deleteEmptyList.js.map +1 -0
  15. package/lib-amd/editor/core/DOMHelperImpl.js +6 -0
  16. package/lib-amd/editor/core/DOMHelperImpl.js.map +1 -1
  17. package/lib-mjs/corePlugin/copyPaste/CopyPastePlugin.js +3 -1
  18. package/lib-mjs/corePlugin/copyPaste/CopyPastePlugin.js.map +1 -1
  19. package/lib-mjs/corePlugin/copyPaste/utils/adjustImageSelectionOnSafari.d.ts +6 -0
  20. package/lib-mjs/corePlugin/copyPaste/utils/adjustImageSelectionOnSafari.js +17 -0
  21. package/lib-mjs/corePlugin/copyPaste/utils/adjustImageSelectionOnSafari.js.map +1 -0
  22. package/lib-mjs/corePlugin/copyPaste/utils/deleteEmptyList.js.map +1 -0
  23. package/lib-mjs/editor/core/DOMHelperImpl.js +6 -0
  24. package/lib-mjs/editor/core/DOMHelperImpl.js.map +1 -1
  25. package/package.json +3 -3
  26. package/lib/corePlugin/copyPaste/deleteEmptyList.js.map +0 -1
  27. package/lib-amd/corePlugin/copyPaste/deleteEmptyList.js.map +0 -1
  28. package/lib-mjs/corePlugin/copyPaste/deleteEmptyList.js.map +0 -1
  29. /package/lib/corePlugin/copyPaste/{deleteEmptyList.d.ts → utils/deleteEmptyList.d.ts} +0 -0
  30. /package/lib/corePlugin/copyPaste/{deleteEmptyList.js → utils/deleteEmptyList.js} +0 -0
  31. /package/lib-amd/corePlugin/copyPaste/{deleteEmptyList.d.ts → utils/deleteEmptyList.d.ts} +0 -0
  32. /package/lib-amd/corePlugin/copyPaste/{deleteEmptyList.js → utils/deleteEmptyList.js} +0 -0
  33. /package/lib-mjs/corePlugin/copyPaste/{deleteEmptyList.d.ts → utils/deleteEmptyList.d.ts} +0 -0
  34. /package/lib-mjs/corePlugin/copyPaste/{deleteEmptyList.js → utils/deleteEmptyList.js} +0 -0
@@ -3,7 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createCopyPastePlugin = exports.preprocessTable = exports.onNodeCreated = exports.adjustSelectionForCopyCut = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var addRangeToSelection_1 = require("../../coreApi/setDOMSelection/addRangeToSelection");
6
- var deleteEmptyList_1 = require("./deleteEmptyList");
6
+ var adjustImageSelectionOnSafari_1 = require("./utils/adjustImageSelectionOnSafari");
7
+ var deleteEmptyList_1 = require("./utils/deleteEmptyList");
7
8
  var pasteCopyBlockEntityParser_1 = require("../../override/pasteCopyBlockEntityParser");
8
9
  var paste_1 = require("../../command/paste/paste");
9
10
  var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
@@ -93,6 +94,7 @@ var CopyPastePlugin = /** @class */ (function () {
93
94
  }
94
95
  var doc = this.editor.getDocument();
95
96
  var selection = this.editor.getDOMSelection();
97
+ (0, adjustImageSelectionOnSafari_1.adjustImageSelectionOnSafari)(this.editor, selection);
96
98
  if (selection && (selection.type != 'range' || !selection.range.collapsed)) {
97
99
  var pasteModel = this.editor.getContentModelCopy('disconnected');
98
100
  if (selection.type === 'table') {
@@ -1 +1 @@
1
- {"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { addRangeToSelection } from '../../coreApi/setDOMSelection/addRangeToSelection';\nimport { deleteEmptyList } from './deleteEmptyList';\nimport { onCreateCopyEntityNode } from '../../override/pasteCopyBlockEntityParser';\nimport { paste } from '../../command/paste/paste';\n\nimport {\n ChangeSource,\n contentModelToDom,\n createModelToDomContext,\n deleteSelection,\n extractClipboardItems,\n getSelectedCells,\n isElementOfType,\n isNodeOfType,\n iterateSelections,\n moveChildNodes,\n normalizeContentModel,\n toArray,\n wrap,\n} from 'roosterjs-content-model-dom';\nimport type {\n ClipboardData,\n CopyPastePluginState,\n ContentModelTable,\n DOMSelection,\n IEditor,\n OnNodeCreated,\n EditorOptions,\n PluginWithState,\n ContentModelDocument,\n ContentModelParagraph,\n ContentModelSegment,\n ReadonlyTableSelectionContext,\n} from 'roosterjs-content-model-types';\n\n/**\n * Copy and paste plugin for handling onCopy and onPaste event\n */\nclass CopyPastePlugin implements PluginWithState<CopyPastePluginState> {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n private state: CopyPastePluginState;\n\n /**\n * Construct a new instance of CopyPastePlugin\n * @param option The editor option\n */\n constructor(option: EditorOptions) {\n this.state = {\n allowedCustomPasteType: option.allowedCustomPasteType || [],\n tempDiv: null,\n defaultPasteType: option.defaultPasteType,\n };\n }\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'CopyPaste';\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 this.disposer = this.editor.attachDomEvent({\n paste: {\n beforeDispatch: e => this.onPaste(e),\n },\n copy: {\n beforeDispatch: e => this.onCutCopy(e, false /*isCut*/),\n },\n cut: {\n beforeDispatch: e => this.onCutCopy(e, true /*isCut*/),\n },\n });\n }\n\n /**\n * Dispose this plugin\n */\n dispose() {\n if (this.state.tempDiv) {\n this.state.tempDiv.parentNode?.removeChild(this.state.tempDiv);\n this.state.tempDiv = null;\n }\n\n if (this.disposer) {\n this.disposer();\n }\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 onCutCopy(event: Event, isCut: boolean) {\n if (!this.editor) {\n return;\n }\n\n const doc = this.editor.getDocument();\n const selection = this.editor.getDOMSelection();\n\n if (selection && (selection.type != 'range' || !selection.range.collapsed)) {\n const pasteModel = this.editor.getContentModelCopy('disconnected');\n\n if (selection.type === 'table') {\n iterateSelections(pasteModel, (_, tableContext) => {\n if (tableContext?.table) {\n preprocessTable(tableContext.table);\n\n return true;\n }\n return false;\n });\n } else if (selection.type === 'range') {\n adjustSelectionForCopyCut(pasteModel);\n }\n\n const tempDiv = this.getTempDiv(this.editor.getDocument());\n const context = createModelToDomContext();\n\n context.onNodeCreated = onNodeCreated;\n\n const selectionForCopy = contentModelToDom(\n tempDiv.ownerDocument,\n tempDiv,\n pasteModel,\n context\n );\n\n let newRange: Range | null = selectionForCopy\n ? domSelectionToRange(doc, selectionForCopy)\n : null;\n\n if (newRange) {\n newRange = this.editor.triggerEvent('beforeCutCopy', {\n clonedRoot: tempDiv,\n range: newRange,\n rawEvent: event as ClipboardEvent,\n isCut,\n }).range;\n\n if (newRange) {\n addRangeToSelection(doc, newRange);\n }\n\n doc.defaultView?.requestAnimationFrame(() => {\n if (!this.editor) {\n return;\n }\n\n cleanUpAndRestoreSelection(tempDiv);\n this.editor.setDOMSelection(selection);\n this.editor.focus();\n\n if (isCut) {\n this.editor.formatContentModel(\n (model, context) => {\n if (\n deleteSelection(model, [deleteEmptyList], context)\n .deleteResult == 'range'\n ) {\n normalizeContentModel(model);\n }\n\n return true;\n },\n {\n apiName: 'cut',\n changeSource: ChangeSource.Cut,\n }\n );\n }\n });\n } else {\n cleanUpAndRestoreSelection(tempDiv);\n }\n }\n }\n\n private onPaste = (event: Event) => {\n if (this.editor && isClipboardEvent(event)) {\n const editor = this.editor;\n\n const dataTransfer = event.clipboardData;\n\n if (dataTransfer?.items) {\n event.preventDefault();\n extractClipboardItems(\n toArray(dataTransfer.items),\n this.state.allowedCustomPasteType\n ).then((clipboardData: ClipboardData) => {\n if (!editor.isDisposed()) {\n paste(editor, clipboardData, this.state.defaultPasteType);\n }\n });\n }\n }\n };\n\n private getTempDiv(doc: Document) {\n if (!this.state.tempDiv) {\n const tempDiv = doc.createElement('div');\n\n tempDiv.style.width = '600px';\n tempDiv.style.height = '1px';\n tempDiv.style.overflow = 'hidden';\n tempDiv.style.position = 'fixed';\n tempDiv.style.top = '0';\n tempDiv.style.left = '0';\n tempDiv.style.userSelect = 'text';\n tempDiv.contentEditable = 'true';\n\n doc.body.appendChild(tempDiv);\n\n this.state.tempDiv = tempDiv;\n }\n\n const div = this.state.tempDiv;\n\n div.style.backgroundColor = 'white';\n div.style.color = 'black';\n div.childNodes.forEach(node => div.removeChild(node));\n\n div.style.display = '';\n div.focus();\n\n return div;\n }\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function adjustSelectionForCopyCut(pasteModel: ContentModelDocument) {\n let selectionMarker: ContentModelSegment | undefined;\n let firstBlock: ContentModelParagraph | undefined;\n let tableContext: ReadonlyTableSelectionContext | undefined;\n\n iterateSelections(pasteModel, (_, tableCtxt, block, segments) => {\n if (selectionMarker) {\n if (tableCtxt != tableContext && firstBlock?.segments.includes(selectionMarker)) {\n firstBlock.segments.splice(firstBlock.segments.indexOf(selectionMarker), 1);\n }\n return true;\n }\n\n const marker = segments?.find(segment => segment.segmentType == 'SelectionMarker');\n if (!selectionMarker && marker) {\n tableContext = tableCtxt;\n firstBlock = block?.blockType == 'Paragraph' ? block : undefined;\n selectionMarker = marker;\n }\n\n return false;\n });\n}\n\nfunction cleanUpAndRestoreSelection(tempDiv: HTMLDivElement) {\n tempDiv.style.backgroundColor = '';\n tempDiv.style.color = '';\n tempDiv.style.display = 'none';\n moveChildNodes(tempDiv);\n}\n\nfunction isClipboardEvent(event: Event): event is ClipboardEvent {\n return !!(event as ClipboardEvent).clipboardData;\n}\n\nfunction domSelectionToRange(doc: Document, selection: DOMSelection): Range | null {\n let newRange: Range | null = null;\n\n if (selection.type === 'table') {\n const table = selection.table;\n const elementToSelect =\n table.parentElement?.childElementCount == 1 ? table.parentElement : table;\n\n newRange = doc.createRange();\n newRange.selectNode(elementToSelect);\n } else if (selection.type === 'image') {\n newRange = doc.createRange();\n newRange.selectNode(selection.image);\n } else {\n newRange = selection.range;\n }\n\n return newRange;\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport const onNodeCreated: OnNodeCreated = (modelElement, node): void => {\n if (isNodeOfType(node, 'ELEMENT_NODE') && isElementOfType(node, 'table')) {\n wrap(node.ownerDocument, node, 'div');\n }\n if (isNodeOfType(node, 'ELEMENT_NODE') && !node.isContentEditable) {\n node.removeAttribute('contenteditable');\n }\n onCreateCopyEntityNode(modelElement, node);\n};\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function preprocessTable(table: ContentModelTable) {\n const sel = getSelectedCells(table);\n table.rows = table.rows\n .map(row => {\n return {\n ...row,\n cells: row.cells.filter(cell => cell.isSelected),\n };\n })\n .filter(row => row.cells.length > 0);\n\n delete table.format.width;\n\n table.widths = sel\n ? table.widths.filter((_, index) => index >= sel?.firstColumn && index <= sel?.lastColumn)\n : [];\n}\n\n/**\n * @internal\n * Create a new instance of CopyPastePlugin\n * @param option The editor option\n */\nexport function createCopyPastePlugin(\n option: EditorOptions\n): PluginWithState<CopyPastePluginState> {\n return new CopyPastePlugin(option);\n}\n"]}
1
+ {"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { addRangeToSelection } from '../../coreApi/setDOMSelection/addRangeToSelection';\nimport { adjustImageSelectionOnSafari } from './utils/adjustImageSelectionOnSafari';\nimport { deleteEmptyList } from './utils/deleteEmptyList';\nimport { onCreateCopyEntityNode } from '../../override/pasteCopyBlockEntityParser';\nimport { paste } from '../../command/paste/paste';\nimport {\n ChangeSource,\n contentModelToDom,\n createModelToDomContext,\n deleteSelection,\n extractClipboardItems,\n getSelectedCells,\n isElementOfType,\n isNodeOfType,\n iterateSelections,\n moveChildNodes,\n normalizeContentModel,\n toArray,\n wrap,\n} from 'roosterjs-content-model-dom';\nimport type {\n ClipboardData,\n CopyPastePluginState,\n ContentModelTable,\n DOMSelection,\n IEditor,\n OnNodeCreated,\n EditorOptions,\n PluginWithState,\n ContentModelDocument,\n ContentModelParagraph,\n ContentModelSegment,\n ReadonlyTableSelectionContext,\n} from 'roosterjs-content-model-types';\n\n/**\n * Copy and paste plugin for handling onCopy and onPaste event\n */\nclass CopyPastePlugin implements PluginWithState<CopyPastePluginState> {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n private state: CopyPastePluginState;\n\n /**\n * Construct a new instance of CopyPastePlugin\n * @param option The editor option\n */\n constructor(option: EditorOptions) {\n this.state = {\n allowedCustomPasteType: option.allowedCustomPasteType || [],\n tempDiv: null,\n defaultPasteType: option.defaultPasteType,\n };\n }\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'CopyPaste';\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 this.disposer = this.editor.attachDomEvent({\n paste: {\n beforeDispatch: e => this.onPaste(e),\n },\n copy: {\n beforeDispatch: e => this.onCutCopy(e, false /*isCut*/),\n },\n cut: {\n beforeDispatch: e => this.onCutCopy(e, true /*isCut*/),\n },\n });\n }\n\n /**\n * Dispose this plugin\n */\n dispose() {\n if (this.state.tempDiv) {\n this.state.tempDiv.parentNode?.removeChild(this.state.tempDiv);\n this.state.tempDiv = null;\n }\n\n if (this.disposer) {\n this.disposer();\n }\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 onCutCopy(event: Event, isCut: boolean) {\n if (!this.editor) {\n return;\n }\n\n const doc = this.editor.getDocument();\n const selection = this.editor.getDOMSelection();\n\n adjustImageSelectionOnSafari(this.editor, selection);\n\n if (selection && (selection.type != 'range' || !selection.range.collapsed)) {\n const pasteModel = this.editor.getContentModelCopy('disconnected');\n\n if (selection.type === 'table') {\n iterateSelections(pasteModel, (_, tableContext) => {\n if (tableContext?.table) {\n preprocessTable(tableContext.table);\n\n return true;\n }\n return false;\n });\n } else if (selection.type === 'range') {\n adjustSelectionForCopyCut(pasteModel);\n }\n\n const tempDiv = this.getTempDiv(this.editor.getDocument());\n const context = createModelToDomContext();\n\n context.onNodeCreated = onNodeCreated;\n\n const selectionForCopy = contentModelToDom(\n tempDiv.ownerDocument,\n tempDiv,\n pasteModel,\n context\n );\n\n let newRange: Range | null = selectionForCopy\n ? domSelectionToRange(doc, selectionForCopy)\n : null;\n\n if (newRange) {\n newRange = this.editor.triggerEvent('beforeCutCopy', {\n clonedRoot: tempDiv,\n range: newRange,\n rawEvent: event as ClipboardEvent,\n isCut,\n }).range;\n\n if (newRange) {\n addRangeToSelection(doc, newRange);\n }\n\n doc.defaultView?.requestAnimationFrame(() => {\n if (!this.editor) {\n return;\n }\n\n cleanUpAndRestoreSelection(tempDiv);\n this.editor.setDOMSelection(selection);\n this.editor.focus();\n\n if (isCut) {\n this.editor.formatContentModel(\n (model, context) => {\n if (\n deleteSelection(model, [deleteEmptyList], context)\n .deleteResult == 'range'\n ) {\n normalizeContentModel(model);\n }\n\n return true;\n },\n {\n apiName: 'cut',\n changeSource: ChangeSource.Cut,\n }\n );\n }\n });\n } else {\n cleanUpAndRestoreSelection(tempDiv);\n }\n }\n }\n\n private onPaste = (event: Event) => {\n if (this.editor && isClipboardEvent(event)) {\n const editor = this.editor;\n\n const dataTransfer = event.clipboardData;\n\n if (dataTransfer?.items) {\n event.preventDefault();\n extractClipboardItems(\n toArray(dataTransfer.items),\n this.state.allowedCustomPasteType\n ).then((clipboardData: ClipboardData) => {\n if (!editor.isDisposed()) {\n paste(editor, clipboardData, this.state.defaultPasteType);\n }\n });\n }\n }\n };\n\n private getTempDiv(doc: Document) {\n if (!this.state.tempDiv) {\n const tempDiv = doc.createElement('div');\n\n tempDiv.style.width = '600px';\n tempDiv.style.height = '1px';\n tempDiv.style.overflow = 'hidden';\n tempDiv.style.position = 'fixed';\n tempDiv.style.top = '0';\n tempDiv.style.left = '0';\n tempDiv.style.userSelect = 'text';\n tempDiv.contentEditable = 'true';\n\n doc.body.appendChild(tempDiv);\n\n this.state.tempDiv = tempDiv;\n }\n\n const div = this.state.tempDiv;\n\n div.style.backgroundColor = 'white';\n div.style.color = 'black';\n div.childNodes.forEach(node => div.removeChild(node));\n\n div.style.display = '';\n div.focus();\n\n return div;\n }\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function adjustSelectionForCopyCut(pasteModel: ContentModelDocument) {\n let selectionMarker: ContentModelSegment | undefined;\n let firstBlock: ContentModelParagraph | undefined;\n let tableContext: ReadonlyTableSelectionContext | undefined;\n\n iterateSelections(pasteModel, (_, tableCtxt, block, segments) => {\n if (selectionMarker) {\n if (tableCtxt != tableContext && firstBlock?.segments.includes(selectionMarker)) {\n firstBlock.segments.splice(firstBlock.segments.indexOf(selectionMarker), 1);\n }\n return true;\n }\n\n const marker = segments?.find(segment => segment.segmentType == 'SelectionMarker');\n if (!selectionMarker && marker) {\n tableContext = tableCtxt;\n firstBlock = block?.blockType == 'Paragraph' ? block : undefined;\n selectionMarker = marker;\n }\n\n return false;\n });\n}\n\nfunction cleanUpAndRestoreSelection(tempDiv: HTMLDivElement) {\n tempDiv.style.backgroundColor = '';\n tempDiv.style.color = '';\n tempDiv.style.display = 'none';\n moveChildNodes(tempDiv);\n}\n\nfunction isClipboardEvent(event: Event): event is ClipboardEvent {\n return !!(event as ClipboardEvent).clipboardData;\n}\n\nfunction domSelectionToRange(doc: Document, selection: DOMSelection): Range | null {\n let newRange: Range | null = null;\n\n if (selection.type === 'table') {\n const table = selection.table;\n const elementToSelect =\n table.parentElement?.childElementCount == 1 ? table.parentElement : table;\n\n newRange = doc.createRange();\n newRange.selectNode(elementToSelect);\n } else if (selection.type === 'image') {\n newRange = doc.createRange();\n newRange.selectNode(selection.image);\n } else {\n newRange = selection.range;\n }\n\n return newRange;\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport const onNodeCreated: OnNodeCreated = (modelElement, node): void => {\n if (isNodeOfType(node, 'ELEMENT_NODE') && isElementOfType(node, 'table')) {\n wrap(node.ownerDocument, node, 'div');\n }\n if (isNodeOfType(node, 'ELEMENT_NODE') && !node.isContentEditable) {\n node.removeAttribute('contenteditable');\n }\n onCreateCopyEntityNode(modelElement, node);\n};\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function preprocessTable(table: ContentModelTable) {\n const sel = getSelectedCells(table);\n table.rows = table.rows\n .map(row => {\n return {\n ...row,\n cells: row.cells.filter(cell => cell.isSelected),\n };\n })\n .filter(row => row.cells.length > 0);\n\n delete table.format.width;\n\n table.widths = sel\n ? table.widths.filter((_, index) => index >= sel?.firstColumn && index <= sel?.lastColumn)\n : [];\n}\n\n/**\n * @internal\n * Create a new instance of CopyPastePlugin\n * @param option The editor option\n */\nexport function createCopyPastePlugin(\n option: EditorOptions\n): PluginWithState<CopyPastePluginState> {\n return new CopyPastePlugin(option);\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import type { IEditor, DOMSelection } from 'roosterjs-content-model-types';
2
+ /**
3
+ * @internal
4
+ * Adjust Image selection, so the copy by keyboard does not remove image selection.
5
+ */
6
+ export declare function adjustImageSelectionOnSafari(editor: IEditor, selection: DOMSelection | null): void;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.adjustImageSelectionOnSafari = void 0;
4
+ /**
5
+ * @internal
6
+ * Adjust Image selection, so the copy by keyboard does not remove image selection.
7
+ */
8
+ function adjustImageSelectionOnSafari(editor, selection) {
9
+ if (editor.getEnvironment().isSafari && (selection === null || selection === void 0 ? void 0 : selection.type) == 'image') {
10
+ var range = new Range();
11
+ range.setStartBefore(selection.image);
12
+ range.setEndAfter(selection.image);
13
+ editor.setDOMSelection({
14
+ range: range,
15
+ type: 'range',
16
+ isReverted: false,
17
+ });
18
+ }
19
+ }
20
+ exports.adjustImageSelectionOnSafari = adjustImageSelectionOnSafari;
21
+ //# sourceMappingURL=adjustImageSelectionOnSafari.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adjustImageSelectionOnSafari.js","sourceRoot":"","sources":["../../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/utils/adjustImageSelectionOnSafari.ts"],"names":[],"mappings":";;;AAEA;;;GAGG;AACH,SAAgB,4BAA4B,CAAC,MAAe,EAAE,SAA8B;IACxF,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC,QAAQ,IAAI,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,KAAI,OAAO,EAAE;QAChE,IAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QAC1B,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACtC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,CAAC,eAAe,CAAC;YACnB,KAAK,OAAA;YACL,IAAI,EAAE,OAAO;YACb,UAAU,EAAE,KAAK;SACpB,CAAC,CAAC;KACN;AACL,CAAC;AAXD,oEAWC","sourcesContent":["import type { IEditor, DOMSelection } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Adjust Image selection, so the copy by keyboard does not remove image selection.\n */\nexport function adjustImageSelectionOnSafari(editor: IEditor, selection: DOMSelection | null) {\n if (editor.getEnvironment().isSafari && selection?.type == 'image') {\n const range = new Range();\n range.setStartBefore(selection.image);\n range.setEndAfter(selection.image);\n editor.setDOMSelection({\n range,\n type: 'range',\n isReverted: false,\n });\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deleteEmptyList.js","sourceRoot":"","sources":["../../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/utils/deleteEmptyList.ts"],"names":[],"mappings":";;;AAAA,2EAKqC;AAOrC,SAAS,YAAY,CAAC,KAA4C;IAC9D,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,WAAW,EAAE;QACzC,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,CACvB,UAAA,OAAO,IAAI,OAAA,OAAO,CAAC,WAAW,KAAK,iBAAiB,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI,EAAxE,CAAwE,CACtF,CAAC;KACL;IAED,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,YAAY,EAAE;QAC1C,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;KAC3C;IAED,OAAO,CAAC,CAAC,KAAK,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACI,IAAM,eAAe,GAAwB,UAAC,OAA+B;IACxE,IAAA,WAAW,GAAmB,OAAO,YAA1B,EAAE,YAAY,GAAK,OAAO,aAAZ,CAAa;IAC9C,IAAI,YAAY,IAAI,OAAO,KAAI,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,IAAI,CAAA,EAAE;QAC9C,IAAM,KAAK,GAAG,IAAA,+DAAiC,EAC3C,WAAW,CAAC,IAAI,EAChB,CAAC,UAAU,CAAC,EACZ,CAAC,WAAW,CAAC,CAChB,CAAC;QACF,IAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,cAAc,IAAI,UAAU,EAAE;YACzD,IAAM,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACvE,IAAM,aAAa,GACf,aAAa,GAAG,CAAC,CAAC;gBACd,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;gBACvD,CAAC,CAAC,SAAS,CAAC;YACpB,IAAM,SAAS,GACX,aAAa,GAAG,CAAC,CAAC;gBACd,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;gBACvD,CAAC,CAAC,SAAS,CAAC;YACpB,IACI,IAAA,sDAAwB,EAAC,IAAI,CAAC;gBAC9B,CAAC,CAAC,aAAa,IAAI,IAAA,iDAAmB,EAAC,aAAa,CAAC,CAAC;gBACtD,SAAS;gBACT,YAAY,CAAC,SAAS,CAAC,EACzB;gBACE,IAAA,yCAAW,EAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC;aACjC;SACJ;KACJ;AACL,CAAC,CAAC;AA7BW,QAAA,eAAe,mBA6B1B","sourcesContent":["import {\n getClosestAncestorBlockGroupIndex,\n hasSelectionInBlock,\n hasSelectionInBlockGroup,\n mutateBlock,\n} from 'roosterjs-content-model-dom';\nimport type {\n DeleteSelectionContext,\n DeleteSelectionStep,\n ReadonlyContentModelBlock,\n} from 'roosterjs-content-model-types';\n\nfunction isEmptyBlock(block: ReadonlyContentModelBlock | undefined): boolean {\n if (block && block.blockType == 'Paragraph') {\n return block.segments.every(\n segment => segment.segmentType !== 'SelectionMarker' && segment.segmentType == 'Br'\n );\n }\n\n if (block && block.blockType == 'BlockGroup') {\n return block.blocks.every(isEmptyBlock);\n }\n\n return !!block;\n}\n\n/**\n * @internal\n * If the first item o the list is selected in a expanded selection, we need to remove the list item levels\n * @param context A context object provided by formatContentModel API\n */\nexport const deleteEmptyList: DeleteSelectionStep = (context: DeleteSelectionContext) => {\n const { insertPoint, deleteResult } = context;\n if (deleteResult == 'range' && insertPoint?.path) {\n const index = getClosestAncestorBlockGroupIndex(\n insertPoint.path,\n ['ListItem'],\n ['TableCell']\n );\n const item = insertPoint.path[index];\n if (index >= 0 && item && item.blockGroupType == 'ListItem') {\n const listItemIndex = insertPoint.path[index + 1].blocks.indexOf(item);\n const previousBlock =\n listItemIndex > -1\n ? insertPoint.path[index + 1].blocks[listItemIndex - 1]\n : undefined;\n const nextBlock =\n listItemIndex > -1\n ? insertPoint.path[index + 1].blocks[listItemIndex + 1]\n : undefined;\n if (\n hasSelectionInBlockGroup(item) &&\n (!previousBlock || hasSelectionInBlock(previousBlock)) &&\n nextBlock &&\n isEmptyBlock(nextBlock)\n ) {\n mutateBlock(item).levels = [];\n }\n }\n }\n};\n"]}
@@ -74,6 +74,12 @@ var DOMHelperImpl = /** @class */ (function () {
74
74
  var paddingRight = (0, roosterjs_content_model_dom_1.parseValueWithUnit)(style === null || style === void 0 ? void 0 : style.paddingRight);
75
75
  return this.contentDiv.clientWidth - (paddingLeft + paddingRight);
76
76
  };
77
+ /**
78
+ * Get a deep cloned root element
79
+ */
80
+ DOMHelperImpl.prototype.getClonedRoot = function () {
81
+ return this.contentDiv.cloneNode(true /*deep*/);
82
+ };
77
83
  return DOMHelperImpl;
78
84
  }());
79
85
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"DOMHelperImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/editor/core/DOMHelperImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import { isNodeOfType, parseValueWithUnit, toArray } from 'roosterjs-content-model-dom';\nimport type { DOMHelper } from 'roosterjs-content-model-types';\n\nclass DOMHelperImpl implements DOMHelper {\n constructor(private contentDiv: HTMLElement) {}\n\n queryElements(selector: string): HTMLElement[] {\n return toArray(this.contentDiv.querySelectorAll(selector)) as HTMLElement[];\n }\n\n getTextContent(): string {\n return this.contentDiv.textContent || '';\n }\n\n isNodeInEditor(node: Node, excludeRoot?: boolean): boolean {\n return excludeRoot && node == this.contentDiv ? false : this.contentDiv.contains(node);\n }\n\n calculateZoomScale(): number {\n const originalWidth = this.contentDiv.getBoundingClientRect()?.width || 0;\n const visualWidth = this.contentDiv.offsetWidth;\n\n return visualWidth > 0 && originalWidth > 0\n ? Math.round((originalWidth / visualWidth) * 100) / 100\n : 1;\n }\n\n setDomAttribute(name: string, value: string | null) {\n if (value === null) {\n this.contentDiv.removeAttribute(name);\n } else {\n this.contentDiv.setAttribute(name, value);\n }\n }\n\n getDomAttribute(name: string): string | null {\n return this.contentDiv.getAttribute(name);\n }\n\n getDomStyle<T extends keyof CSSStyleDeclaration>(style: T): CSSStyleDeclaration[T] {\n return this.contentDiv.style[style];\n }\n\n findClosestElementAncestor(startFrom: Node, selector?: string): HTMLElement | null {\n const startElement = isNodeOfType(startFrom, 'ELEMENT_NODE')\n ? startFrom\n : startFrom.parentElement;\n const closestElement = selector\n ? (startElement?.closest(selector) as HTMLElement | null)\n : startElement;\n\n return closestElement &&\n this.isNodeInEditor(closestElement) &&\n closestElement != this.contentDiv\n ? closestElement\n : null;\n }\n\n hasFocus(): boolean {\n const activeElement = this.contentDiv.ownerDocument.activeElement;\n return !!(activeElement && this.contentDiv.contains(activeElement));\n }\n\n /**\n * Check if the root element is in RTL mode\n */\n isRightToLeft(): boolean {\n const contentDiv = this.contentDiv;\n const style = contentDiv.ownerDocument.defaultView?.getComputedStyle(contentDiv);\n\n return style?.direction == 'rtl';\n }\n\n /**\n * Get the width of the editable area of the editor content div\n */\n getClientWidth(): number {\n const contentDiv = this.contentDiv;\n const style = contentDiv.ownerDocument.defaultView?.getComputedStyle(contentDiv);\n const paddingLeft = parseValueWithUnit(style?.paddingLeft);\n const paddingRight = parseValueWithUnit(style?.paddingRight);\n return this.contentDiv.clientWidth - (paddingLeft + paddingRight);\n }\n}\n\n/**\n * @internal Create new instance of DOMHelper\n */\nexport function createDOMHelper(contentDiv: HTMLElement): DOMHelper {\n return new DOMHelperImpl(contentDiv);\n}\n"]}
1
+ {"version":3,"file":"DOMHelperImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/editor/core/DOMHelperImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import { isNodeOfType, parseValueWithUnit, toArray } from 'roosterjs-content-model-dom';\nimport type { DOMHelper } from 'roosterjs-content-model-types';\n\nclass DOMHelperImpl implements DOMHelper {\n constructor(private contentDiv: HTMLElement) {}\n\n queryElements(selector: string): HTMLElement[] {\n return toArray(this.contentDiv.querySelectorAll(selector)) as HTMLElement[];\n }\n\n getTextContent(): string {\n return this.contentDiv.textContent || '';\n }\n\n isNodeInEditor(node: Node, excludeRoot?: boolean): boolean {\n return excludeRoot && node == this.contentDiv ? false : this.contentDiv.contains(node);\n }\n\n calculateZoomScale(): number {\n const originalWidth = this.contentDiv.getBoundingClientRect()?.width || 0;\n const visualWidth = this.contentDiv.offsetWidth;\n\n return visualWidth > 0 && originalWidth > 0\n ? Math.round((originalWidth / visualWidth) * 100) / 100\n : 1;\n }\n\n setDomAttribute(name: string, value: string | null) {\n if (value === null) {\n this.contentDiv.removeAttribute(name);\n } else {\n this.contentDiv.setAttribute(name, value);\n }\n }\n\n getDomAttribute(name: string): string | null {\n return this.contentDiv.getAttribute(name);\n }\n\n getDomStyle<T extends keyof CSSStyleDeclaration>(style: T): CSSStyleDeclaration[T] {\n return this.contentDiv.style[style];\n }\n\n findClosestElementAncestor(startFrom: Node, selector?: string): HTMLElement | null {\n const startElement = isNodeOfType(startFrom, 'ELEMENT_NODE')\n ? startFrom\n : startFrom.parentElement;\n const closestElement = selector\n ? (startElement?.closest(selector) as HTMLElement | null)\n : startElement;\n\n return closestElement &&\n this.isNodeInEditor(closestElement) &&\n closestElement != this.contentDiv\n ? closestElement\n : null;\n }\n\n hasFocus(): boolean {\n const activeElement = this.contentDiv.ownerDocument.activeElement;\n return !!(activeElement && this.contentDiv.contains(activeElement));\n }\n\n /**\n * Check if the root element is in RTL mode\n */\n isRightToLeft(): boolean {\n const contentDiv = this.contentDiv;\n const style = contentDiv.ownerDocument.defaultView?.getComputedStyle(contentDiv);\n\n return style?.direction == 'rtl';\n }\n\n /**\n * Get the width of the editable area of the editor content div\n */\n getClientWidth(): number {\n const contentDiv = this.contentDiv;\n const style = contentDiv.ownerDocument.defaultView?.getComputedStyle(contentDiv);\n const paddingLeft = parseValueWithUnit(style?.paddingLeft);\n const paddingRight = parseValueWithUnit(style?.paddingRight);\n return this.contentDiv.clientWidth - (paddingLeft + paddingRight);\n }\n\n /**\n * Get a deep cloned root element\n */\n getClonedRoot(): HTMLElement {\n return this.contentDiv.cloneNode(true /*deep*/) as HTMLElement;\n }\n}\n\n/**\n * @internal Create new instance of DOMHelper\n */\nexport function createDOMHelper(contentDiv: HTMLElement): DOMHelper {\n return new DOMHelperImpl(contentDiv);\n}\n"]}
@@ -1,4 +1,4 @@
1
- define(["require", "exports", "tslib", "../../coreApi/setDOMSelection/addRangeToSelection", "./deleteEmptyList", "../../override/pasteCopyBlockEntityParser", "../../command/paste/paste", "roosterjs-content-model-dom"], function (require, exports, tslib_1, addRangeToSelection_1, deleteEmptyList_1, pasteCopyBlockEntityParser_1, paste_1, roosterjs_content_model_dom_1) {
1
+ define(["require", "exports", "tslib", "../../coreApi/setDOMSelection/addRangeToSelection", "./utils/adjustImageSelectionOnSafari", "./utils/deleteEmptyList", "../../override/pasteCopyBlockEntityParser", "../../command/paste/paste", "roosterjs-content-model-dom"], function (require, exports, tslib_1, addRangeToSelection_1, adjustImageSelectionOnSafari_1, deleteEmptyList_1, pasteCopyBlockEntityParser_1, paste_1, roosterjs_content_model_dom_1) {
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.createCopyPastePlugin = exports.preprocessTable = exports.onNodeCreated = exports.adjustSelectionForCopyCut = void 0;
@@ -88,6 +88,7 @@ define(["require", "exports", "tslib", "../../coreApi/setDOMSelection/addRangeTo
88
88
  }
89
89
  var doc = this.editor.getDocument();
90
90
  var selection = this.editor.getDOMSelection();
91
+ (0, adjustImageSelectionOnSafari_1.adjustImageSelectionOnSafari)(this.editor, selection);
91
92
  if (selection && (selection.type != 'range' || !selection.range.collapsed)) {
92
93
  var pasteModel = this.editor.getContentModelCopy('disconnected');
93
94
  if (selection.type === 'table') {
@@ -1 +1 @@
1
- {"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { addRangeToSelection } from '../../coreApi/setDOMSelection/addRangeToSelection';\nimport { deleteEmptyList } from './deleteEmptyList';\nimport { onCreateCopyEntityNode } from '../../override/pasteCopyBlockEntityParser';\nimport { paste } from '../../command/paste/paste';\n\nimport {\n ChangeSource,\n contentModelToDom,\n createModelToDomContext,\n deleteSelection,\n extractClipboardItems,\n getSelectedCells,\n isElementOfType,\n isNodeOfType,\n iterateSelections,\n moveChildNodes,\n normalizeContentModel,\n toArray,\n wrap,\n} from 'roosterjs-content-model-dom';\nimport type {\n ClipboardData,\n CopyPastePluginState,\n ContentModelTable,\n DOMSelection,\n IEditor,\n OnNodeCreated,\n EditorOptions,\n PluginWithState,\n ContentModelDocument,\n ContentModelParagraph,\n ContentModelSegment,\n ReadonlyTableSelectionContext,\n} from 'roosterjs-content-model-types';\n\n/**\n * Copy and paste plugin for handling onCopy and onPaste event\n */\nclass CopyPastePlugin implements PluginWithState<CopyPastePluginState> {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n private state: CopyPastePluginState;\n\n /**\n * Construct a new instance of CopyPastePlugin\n * @param option The editor option\n */\n constructor(option: EditorOptions) {\n this.state = {\n allowedCustomPasteType: option.allowedCustomPasteType || [],\n tempDiv: null,\n defaultPasteType: option.defaultPasteType,\n };\n }\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'CopyPaste';\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 this.disposer = this.editor.attachDomEvent({\n paste: {\n beforeDispatch: e => this.onPaste(e),\n },\n copy: {\n beforeDispatch: e => this.onCutCopy(e, false /*isCut*/),\n },\n cut: {\n beforeDispatch: e => this.onCutCopy(e, true /*isCut*/),\n },\n });\n }\n\n /**\n * Dispose this plugin\n */\n dispose() {\n if (this.state.tempDiv) {\n this.state.tempDiv.parentNode?.removeChild(this.state.tempDiv);\n this.state.tempDiv = null;\n }\n\n if (this.disposer) {\n this.disposer();\n }\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 onCutCopy(event: Event, isCut: boolean) {\n if (!this.editor) {\n return;\n }\n\n const doc = this.editor.getDocument();\n const selection = this.editor.getDOMSelection();\n\n if (selection && (selection.type != 'range' || !selection.range.collapsed)) {\n const pasteModel = this.editor.getContentModelCopy('disconnected');\n\n if (selection.type === 'table') {\n iterateSelections(pasteModel, (_, tableContext) => {\n if (tableContext?.table) {\n preprocessTable(tableContext.table);\n\n return true;\n }\n return false;\n });\n } else if (selection.type === 'range') {\n adjustSelectionForCopyCut(pasteModel);\n }\n\n const tempDiv = this.getTempDiv(this.editor.getDocument());\n const context = createModelToDomContext();\n\n context.onNodeCreated = onNodeCreated;\n\n const selectionForCopy = contentModelToDom(\n tempDiv.ownerDocument,\n tempDiv,\n pasteModel,\n context\n );\n\n let newRange: Range | null = selectionForCopy\n ? domSelectionToRange(doc, selectionForCopy)\n : null;\n\n if (newRange) {\n newRange = this.editor.triggerEvent('beforeCutCopy', {\n clonedRoot: tempDiv,\n range: newRange,\n rawEvent: event as ClipboardEvent,\n isCut,\n }).range;\n\n if (newRange) {\n addRangeToSelection(doc, newRange);\n }\n\n doc.defaultView?.requestAnimationFrame(() => {\n if (!this.editor) {\n return;\n }\n\n cleanUpAndRestoreSelection(tempDiv);\n this.editor.setDOMSelection(selection);\n this.editor.focus();\n\n if (isCut) {\n this.editor.formatContentModel(\n (model, context) => {\n if (\n deleteSelection(model, [deleteEmptyList], context)\n .deleteResult == 'range'\n ) {\n normalizeContentModel(model);\n }\n\n return true;\n },\n {\n apiName: 'cut',\n changeSource: ChangeSource.Cut,\n }\n );\n }\n });\n } else {\n cleanUpAndRestoreSelection(tempDiv);\n }\n }\n }\n\n private onPaste = (event: Event) => {\n if (this.editor && isClipboardEvent(event)) {\n const editor = this.editor;\n\n const dataTransfer = event.clipboardData;\n\n if (dataTransfer?.items) {\n event.preventDefault();\n extractClipboardItems(\n toArray(dataTransfer.items),\n this.state.allowedCustomPasteType\n ).then((clipboardData: ClipboardData) => {\n if (!editor.isDisposed()) {\n paste(editor, clipboardData, this.state.defaultPasteType);\n }\n });\n }\n }\n };\n\n private getTempDiv(doc: Document) {\n if (!this.state.tempDiv) {\n const tempDiv = doc.createElement('div');\n\n tempDiv.style.width = '600px';\n tempDiv.style.height = '1px';\n tempDiv.style.overflow = 'hidden';\n tempDiv.style.position = 'fixed';\n tempDiv.style.top = '0';\n tempDiv.style.left = '0';\n tempDiv.style.userSelect = 'text';\n tempDiv.contentEditable = 'true';\n\n doc.body.appendChild(tempDiv);\n\n this.state.tempDiv = tempDiv;\n }\n\n const div = this.state.tempDiv;\n\n div.style.backgroundColor = 'white';\n div.style.color = 'black';\n div.childNodes.forEach(node => div.removeChild(node));\n\n div.style.display = '';\n div.focus();\n\n return div;\n }\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function adjustSelectionForCopyCut(pasteModel: ContentModelDocument) {\n let selectionMarker: ContentModelSegment | undefined;\n let firstBlock: ContentModelParagraph | undefined;\n let tableContext: ReadonlyTableSelectionContext | undefined;\n\n iterateSelections(pasteModel, (_, tableCtxt, block, segments) => {\n if (selectionMarker) {\n if (tableCtxt != tableContext && firstBlock?.segments.includes(selectionMarker)) {\n firstBlock.segments.splice(firstBlock.segments.indexOf(selectionMarker), 1);\n }\n return true;\n }\n\n const marker = segments?.find(segment => segment.segmentType == 'SelectionMarker');\n if (!selectionMarker && marker) {\n tableContext = tableCtxt;\n firstBlock = block?.blockType == 'Paragraph' ? block : undefined;\n selectionMarker = marker;\n }\n\n return false;\n });\n}\n\nfunction cleanUpAndRestoreSelection(tempDiv: HTMLDivElement) {\n tempDiv.style.backgroundColor = '';\n tempDiv.style.color = '';\n tempDiv.style.display = 'none';\n moveChildNodes(tempDiv);\n}\n\nfunction isClipboardEvent(event: Event): event is ClipboardEvent {\n return !!(event as ClipboardEvent).clipboardData;\n}\n\nfunction domSelectionToRange(doc: Document, selection: DOMSelection): Range | null {\n let newRange: Range | null = null;\n\n if (selection.type === 'table') {\n const table = selection.table;\n const elementToSelect =\n table.parentElement?.childElementCount == 1 ? table.parentElement : table;\n\n newRange = doc.createRange();\n newRange.selectNode(elementToSelect);\n } else if (selection.type === 'image') {\n newRange = doc.createRange();\n newRange.selectNode(selection.image);\n } else {\n newRange = selection.range;\n }\n\n return newRange;\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport const onNodeCreated: OnNodeCreated = (modelElement, node): void => {\n if (isNodeOfType(node, 'ELEMENT_NODE') && isElementOfType(node, 'table')) {\n wrap(node.ownerDocument, node, 'div');\n }\n if (isNodeOfType(node, 'ELEMENT_NODE') && !node.isContentEditable) {\n node.removeAttribute('contenteditable');\n }\n onCreateCopyEntityNode(modelElement, node);\n};\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function preprocessTable(table: ContentModelTable) {\n const sel = getSelectedCells(table);\n table.rows = table.rows\n .map(row => {\n return {\n ...row,\n cells: row.cells.filter(cell => cell.isSelected),\n };\n })\n .filter(row => row.cells.length > 0);\n\n delete table.format.width;\n\n table.widths = sel\n ? table.widths.filter((_, index) => index >= sel?.firstColumn && index <= sel?.lastColumn)\n : [];\n}\n\n/**\n * @internal\n * Create a new instance of CopyPastePlugin\n * @param option The editor option\n */\nexport function createCopyPastePlugin(\n option: EditorOptions\n): PluginWithState<CopyPastePluginState> {\n return new CopyPastePlugin(option);\n}\n"]}
1
+ {"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts"],"names":[],"mappings":";;;;IAmCA;;OAEG;IACH;QAKI;;;WAGG;QACH,yBAAY,MAAqB;YAAjC,iBAMC;YAdO,WAAM,GAAmB,IAAI,CAAC;YAC9B,aAAQ,GAAwB,IAAI,CAAC;YAwJrC,YAAO,GAAG,UAAC,KAAY;gBAC3B,IAAI,KAAI,CAAC,MAAM,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE;oBACxC,IAAM,QAAM,GAAG,KAAI,CAAC,MAAM,CAAC;oBAE3B,IAAM,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC;oBAEzC,IAAI,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK,EAAE;wBACrB,KAAK,CAAC,cAAc,EAAE,CAAC;wBACvB,IAAA,mDAAqB,EACjB,IAAA,qCAAO,EAAC,YAAY,CAAC,KAAK,CAAC,EAC3B,KAAI,CAAC,KAAK,CAAC,sBAAsB,CACpC,CAAC,IAAI,CAAC,UAAC,aAA4B;4BAChC,IAAI,CAAC,QAAM,CAAC,UAAU,EAAE,EAAE;gCACtB,IAAA,aAAK,EAAC,QAAM,EAAE,aAAa,EAAE,KAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;6BAC7D;wBACL,CAAC,CAAC,CAAC;qBACN;iBACJ;YACL,CAAC,CAAC;YAlKE,IAAI,CAAC,KAAK,GAAG;gBACT,sBAAsB,EAAE,MAAM,CAAC,sBAAsB,IAAI,EAAE;gBAC3D,OAAO,EAAE,IAAI;gBACb,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;aAC5C,CAAC;QACN,CAAC;QAED;;WAEG;QACH,iCAAO,GAAP;YACI,OAAO,WAAW,CAAC;QACvB,CAAC;QAED;;;WAGG;QACH,oCAAU,GAAV,UAAW,MAAe;YAA1B,iBAaC;YAZG,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YACrB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;gBACvC,KAAK,EAAE;oBACH,cAAc,EAAE,UAAA,CAAC,IAAI,OAAA,KAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAf,CAAe;iBACvC;gBACD,IAAI,EAAE;oBACF,cAAc,EAAE,UAAA,CAAC,IAAI,OAAA,KAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,EAAlC,CAAkC;iBAC1D;gBACD,GAAG,EAAE;oBACD,cAAc,EAAE,UAAA,CAAC,IAAI,OAAA,KAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAjC,CAAiC;iBACzD;aACJ,CAAC,CAAC;QACP,CAAC;QAED;;WAEG;QACH,iCAAO,GAAP;;YACI,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;gBACpB,MAAA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,0CAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAC/D,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;aAC7B;YAED,IAAI,IAAI,CAAC,QAAQ,EAAE;gBACf,IAAI,CAAC,QAAQ,EAAE,CAAC;aACnB;YACD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;YACrB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACvB,CAAC;QAED;;WAEG;QACH,kCAAQ,GAAR;YACI,OAAO,IAAI,CAAC,KAAK,CAAC;QACtB,CAAC;QAEO,mCAAS,GAAjB,UAAkB,KAAY,EAAE,KAAc;YAA9C,iBAsFC;;YArFG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;gBACd,OAAO;aACV;YAED,IAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YACtC,IAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YAEhD,IAAA,2DAA4B,EAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YAErD,IAAI,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE;gBACxE,IAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC;gBAEnE,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,EAAE;oBAC5B,IAAA,+CAAiB,EAAC,UAAU,EAAE,UAAC,CAAC,EAAE,YAAY;wBAC1C,IAAI,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK,EAAE;4BACrB,eAAe,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;4BAEpC,OAAO,IAAI,CAAC;yBACf;wBACD,OAAO,KAAK,CAAC;oBACjB,CAAC,CAAC,CAAC;iBACN;qBAAM,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,EAAE;oBACnC,yBAAyB,CAAC,UAAU,CAAC,CAAC;iBACzC;gBAED,IAAM,SAAO,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC3D,IAAM,OAAO,GAAG,IAAA,qDAAuB,GAAE,CAAC;gBAE1C,OAAO,CAAC,aAAa,GAAG,qBAAa,CAAC;gBAEtC,IAAM,gBAAgB,GAAG,IAAA,+CAAiB,EACtC,SAAO,CAAC,aAAa,EACrB,SAAO,EACP,UAAU,EACV,OAAO,CACV,CAAC;gBAEF,IAAI,QAAQ,GAAiB,gBAAgB;oBACzC,CAAC,CAAC,mBAAmB,CAAC,GAAG,EAAE,gBAAgB,CAAC;oBAC5C,CAAC,CAAC,IAAI,CAAC;gBAEX,IAAI,QAAQ,EAAE;oBACV,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE;wBACjD,UAAU,EAAE,SAAO;wBACnB,KAAK,EAAE,QAAQ;wBACf,QAAQ,EAAE,KAAuB;wBACjC,KAAK,OAAA;qBACR,CAAC,CAAC,KAAK,CAAC;oBAET,IAAI,QAAQ,EAAE;wBACV,IAAA,yCAAmB,EAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;qBACtC;oBAED,MAAA,GAAG,CAAC,WAAW,0CAAE,qBAAqB,CAAC;wBACnC,IAAI,CAAC,KAAI,CAAC,MAAM,EAAE;4BACd,OAAO;yBACV;wBAED,0BAA0B,CAAC,SAAO,CAAC,CAAC;wBACpC,KAAI,CAAC,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;wBACvC,KAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;wBAEpB,IAAI,KAAK,EAAE;4BACP,KAAI,CAAC,MAAM,CAAC,kBAAkB,CAC1B,UAAC,KAAK,EAAE,OAAO;gCACX,IACI,IAAA,6CAAe,EAAC,KAAK,EAAE,CAAC,iCAAe,CAAC,EAAE,OAAO,CAAC;qCAC7C,YAAY,IAAI,OAAO,EAC9B;oCACE,IAAA,mDAAqB,EAAC,KAAK,CAAC,CAAC;iCAChC;gCAED,OAAO,IAAI,CAAC;4BAChB,CAAC,EACD;gCACI,OAAO,EAAE,KAAK;gCACd,YAAY,EAAE,0CAAY,CAAC,GAAG;6BACjC,CACJ,CAAC;yBACL;oBACL,CAAC,CAAC,CAAC;iBACN;qBAAM;oBACH,0BAA0B,CAAC,SAAO,CAAC,CAAC;iBACvC;aACJ;QACL,CAAC;QAsBO,oCAAU,GAAlB,UAAmB,GAAa;YAC5B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;gBACrB,IAAM,OAAO,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;gBAEzC,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC;gBAC9B,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC;gBAC7B,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;gBAClC,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC;gBACjC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC;gBACxB,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC;gBACzB,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC;gBAClC,OAAO,CAAC,eAAe,GAAG,MAAM,CAAC;gBAEjC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;gBAE9B,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;aAChC;YAED,IAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;YAE/B,GAAG,CAAC,KAAK,CAAC,eAAe,GAAG,OAAO,CAAC;YACpC,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC;YAC1B,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,UAAA,IAAI,IAAI,OAAA,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,EAArB,CAAqB,CAAC,CAAC;YAEtD,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC;YACvB,GAAG,CAAC,KAAK,EAAE,CAAC;YAEZ,OAAO,GAAG,CAAC;QACf,CAAC;QACL,sBAAC;IAAD,CAAC,AA3MD,IA2MC;IAED;;;OAGG;IACH,SAAgB,yBAAyB,CAAC,UAAgC;QACtE,IAAI,eAAgD,CAAC;QACrD,IAAI,UAA6C,CAAC;QAClD,IAAI,YAAuD,CAAC;QAE5D,IAAA,+CAAiB,EAAC,UAAU,EAAE,UAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ;YACxD,IAAI,eAAe,EAAE;gBACjB,IAAI,SAAS,IAAI,YAAY,KAAI,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAA,EAAE;oBAC7E,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC;iBAC/E;gBACD,OAAO,IAAI,CAAC;aACf;YAED,IAAM,MAAM,GAAG,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,CAAC,UAAA,OAAO,IAAI,OAAA,OAAO,CAAC,WAAW,IAAI,iBAAiB,EAAxC,CAAwC,CAAC,CAAC;YACnF,IAAI,CAAC,eAAe,IAAI,MAAM,EAAE;gBAC5B,YAAY,GAAG,SAAS,CAAC;gBACzB,UAAU,GAAG,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,SAAS,KAAI,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;gBACjE,eAAe,GAAG,MAAM,CAAC;aAC5B;YAED,OAAO,KAAK,CAAC;QACjB,CAAC,CAAC,CAAC;IACP,CAAC;IAtBD,8DAsBC;IAED,SAAS,0BAA0B,CAAC,OAAuB;QACvD,OAAO,CAAC,KAAK,CAAC,eAAe,GAAG,EAAE,CAAC;QACnC,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;QAC/B,IAAA,4CAAc,EAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IAED,SAAS,gBAAgB,CAAC,KAAY;QAClC,OAAO,CAAC,CAAE,KAAwB,CAAC,aAAa,CAAC;IACrD,CAAC;IAED,SAAS,mBAAmB,CAAC,GAAa,EAAE,SAAuB;;QAC/D,IAAI,QAAQ,GAAiB,IAAI,CAAC;QAElC,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,EAAE;YAC5B,IAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;YAC9B,IAAM,eAAe,GACjB,CAAA,MAAA,KAAK,CAAC,aAAa,0CAAE,iBAAiB,KAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC;YAE9E,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;YAC7B,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;SACxC;aAAM,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,EAAE;YACnC,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;YAC7B,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;SACxC;aAAM;YACH,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC;SAC9B;QAED,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED;;;OAGG;IACI,IAAM,aAAa,GAAkB,UAAC,YAAY,EAAE,IAAI;QAC3D,IAAI,IAAA,0CAAY,EAAC,IAAI,EAAE,cAAc,CAAC,IAAI,IAAA,6CAAe,EAAC,IAAI,EAAE,OAAO,CAAC,EAAE;YACtE,IAAA,kCAAI,EAAC,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;SACzC;QACD,IAAI,IAAA,0CAAY,EAAC,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE;YAC/D,IAAI,CAAC,eAAe,CAAC,iBAAiB,CAAC,CAAC;SAC3C;QACD,IAAA,mDAAsB,EAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC,CAAC;IARW,QAAA,aAAa,iBAQxB;IAEF;;;OAGG;IACH,SAAgB,eAAe,CAAC,KAAwB;QACpD,IAAM,GAAG,GAAG,IAAA,8CAAgB,EAAC,KAAK,CAAC,CAAC;QACpC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;aAClB,GAAG,CAAC,UAAA,GAAG;YACJ,uDACO,GAAG,KACN,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,UAAA,IAAI,IAAI,OAAA,IAAI,CAAC,UAAU,EAAf,CAAe,CAAC,IAClD;QACN,CAAC,CAAC;aACD,MAAM,CAAC,UAAA,GAAG,IAAI,OAAA,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAApB,CAAoB,CAAC,CAAC;QAEzC,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;QAE1B,KAAK,CAAC,MAAM,GAAG,GAAG;YACd,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,UAAC,CAAC,EAAE,KAAK,IAAK,OAAA,KAAK,KAAI,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,WAAW,CAAA,IAAI,KAAK,KAAI,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,UAAU,CAAA,EAArD,CAAqD,CAAC;YAC1F,CAAC,CAAC,EAAE,CAAC;IACb,CAAC;IAhBD,0CAgBC;IAED;;;;OAIG;IACH,SAAgB,qBAAqB,CACjC,MAAqB;QAErB,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAJD,sDAIC","sourcesContent":["import { addRangeToSelection } from '../../coreApi/setDOMSelection/addRangeToSelection';\nimport { adjustImageSelectionOnSafari } from './utils/adjustImageSelectionOnSafari';\nimport { deleteEmptyList } from './utils/deleteEmptyList';\nimport { onCreateCopyEntityNode } from '../../override/pasteCopyBlockEntityParser';\nimport { paste } from '../../command/paste/paste';\nimport {\n ChangeSource,\n contentModelToDom,\n createModelToDomContext,\n deleteSelection,\n extractClipboardItems,\n getSelectedCells,\n isElementOfType,\n isNodeOfType,\n iterateSelections,\n moveChildNodes,\n normalizeContentModel,\n toArray,\n wrap,\n} from 'roosterjs-content-model-dom';\nimport type {\n ClipboardData,\n CopyPastePluginState,\n ContentModelTable,\n DOMSelection,\n IEditor,\n OnNodeCreated,\n EditorOptions,\n PluginWithState,\n ContentModelDocument,\n ContentModelParagraph,\n ContentModelSegment,\n ReadonlyTableSelectionContext,\n} from 'roosterjs-content-model-types';\n\n/**\n * Copy and paste plugin for handling onCopy and onPaste event\n */\nclass CopyPastePlugin implements PluginWithState<CopyPastePluginState> {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n private state: CopyPastePluginState;\n\n /**\n * Construct a new instance of CopyPastePlugin\n * @param option The editor option\n */\n constructor(option: EditorOptions) {\n this.state = {\n allowedCustomPasteType: option.allowedCustomPasteType || [],\n tempDiv: null,\n defaultPasteType: option.defaultPasteType,\n };\n }\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'CopyPaste';\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 this.disposer = this.editor.attachDomEvent({\n paste: {\n beforeDispatch: e => this.onPaste(e),\n },\n copy: {\n beforeDispatch: e => this.onCutCopy(e, false /*isCut*/),\n },\n cut: {\n beforeDispatch: e => this.onCutCopy(e, true /*isCut*/),\n },\n });\n }\n\n /**\n * Dispose this plugin\n */\n dispose() {\n if (this.state.tempDiv) {\n this.state.tempDiv.parentNode?.removeChild(this.state.tempDiv);\n this.state.tempDiv = null;\n }\n\n if (this.disposer) {\n this.disposer();\n }\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 onCutCopy(event: Event, isCut: boolean) {\n if (!this.editor) {\n return;\n }\n\n const doc = this.editor.getDocument();\n const selection = this.editor.getDOMSelection();\n\n adjustImageSelectionOnSafari(this.editor, selection);\n\n if (selection && (selection.type != 'range' || !selection.range.collapsed)) {\n const pasteModel = this.editor.getContentModelCopy('disconnected');\n\n if (selection.type === 'table') {\n iterateSelections(pasteModel, (_, tableContext) => {\n if (tableContext?.table) {\n preprocessTable(tableContext.table);\n\n return true;\n }\n return false;\n });\n } else if (selection.type === 'range') {\n adjustSelectionForCopyCut(pasteModel);\n }\n\n const tempDiv = this.getTempDiv(this.editor.getDocument());\n const context = createModelToDomContext();\n\n context.onNodeCreated = onNodeCreated;\n\n const selectionForCopy = contentModelToDom(\n tempDiv.ownerDocument,\n tempDiv,\n pasteModel,\n context\n );\n\n let newRange: Range | null = selectionForCopy\n ? domSelectionToRange(doc, selectionForCopy)\n : null;\n\n if (newRange) {\n newRange = this.editor.triggerEvent('beforeCutCopy', {\n clonedRoot: tempDiv,\n range: newRange,\n rawEvent: event as ClipboardEvent,\n isCut,\n }).range;\n\n if (newRange) {\n addRangeToSelection(doc, newRange);\n }\n\n doc.defaultView?.requestAnimationFrame(() => {\n if (!this.editor) {\n return;\n }\n\n cleanUpAndRestoreSelection(tempDiv);\n this.editor.setDOMSelection(selection);\n this.editor.focus();\n\n if (isCut) {\n this.editor.formatContentModel(\n (model, context) => {\n if (\n deleteSelection(model, [deleteEmptyList], context)\n .deleteResult == 'range'\n ) {\n normalizeContentModel(model);\n }\n\n return true;\n },\n {\n apiName: 'cut',\n changeSource: ChangeSource.Cut,\n }\n );\n }\n });\n } else {\n cleanUpAndRestoreSelection(tempDiv);\n }\n }\n }\n\n private onPaste = (event: Event) => {\n if (this.editor && isClipboardEvent(event)) {\n const editor = this.editor;\n\n const dataTransfer = event.clipboardData;\n\n if (dataTransfer?.items) {\n event.preventDefault();\n extractClipboardItems(\n toArray(dataTransfer.items),\n this.state.allowedCustomPasteType\n ).then((clipboardData: ClipboardData) => {\n if (!editor.isDisposed()) {\n paste(editor, clipboardData, this.state.defaultPasteType);\n }\n });\n }\n }\n };\n\n private getTempDiv(doc: Document) {\n if (!this.state.tempDiv) {\n const tempDiv = doc.createElement('div');\n\n tempDiv.style.width = '600px';\n tempDiv.style.height = '1px';\n tempDiv.style.overflow = 'hidden';\n tempDiv.style.position = 'fixed';\n tempDiv.style.top = '0';\n tempDiv.style.left = '0';\n tempDiv.style.userSelect = 'text';\n tempDiv.contentEditable = 'true';\n\n doc.body.appendChild(tempDiv);\n\n this.state.tempDiv = tempDiv;\n }\n\n const div = this.state.tempDiv;\n\n div.style.backgroundColor = 'white';\n div.style.color = 'black';\n div.childNodes.forEach(node => div.removeChild(node));\n\n div.style.display = '';\n div.focus();\n\n return div;\n }\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function adjustSelectionForCopyCut(pasteModel: ContentModelDocument) {\n let selectionMarker: ContentModelSegment | undefined;\n let firstBlock: ContentModelParagraph | undefined;\n let tableContext: ReadonlyTableSelectionContext | undefined;\n\n iterateSelections(pasteModel, (_, tableCtxt, block, segments) => {\n if (selectionMarker) {\n if (tableCtxt != tableContext && firstBlock?.segments.includes(selectionMarker)) {\n firstBlock.segments.splice(firstBlock.segments.indexOf(selectionMarker), 1);\n }\n return true;\n }\n\n const marker = segments?.find(segment => segment.segmentType == 'SelectionMarker');\n if (!selectionMarker && marker) {\n tableContext = tableCtxt;\n firstBlock = block?.blockType == 'Paragraph' ? block : undefined;\n selectionMarker = marker;\n }\n\n return false;\n });\n}\n\nfunction cleanUpAndRestoreSelection(tempDiv: HTMLDivElement) {\n tempDiv.style.backgroundColor = '';\n tempDiv.style.color = '';\n tempDiv.style.display = 'none';\n moveChildNodes(tempDiv);\n}\n\nfunction isClipboardEvent(event: Event): event is ClipboardEvent {\n return !!(event as ClipboardEvent).clipboardData;\n}\n\nfunction domSelectionToRange(doc: Document, selection: DOMSelection): Range | null {\n let newRange: Range | null = null;\n\n if (selection.type === 'table') {\n const table = selection.table;\n const elementToSelect =\n table.parentElement?.childElementCount == 1 ? table.parentElement : table;\n\n newRange = doc.createRange();\n newRange.selectNode(elementToSelect);\n } else if (selection.type === 'image') {\n newRange = doc.createRange();\n newRange.selectNode(selection.image);\n } else {\n newRange = selection.range;\n }\n\n return newRange;\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport const onNodeCreated: OnNodeCreated = (modelElement, node): void => {\n if (isNodeOfType(node, 'ELEMENT_NODE') && isElementOfType(node, 'table')) {\n wrap(node.ownerDocument, node, 'div');\n }\n if (isNodeOfType(node, 'ELEMENT_NODE') && !node.isContentEditable) {\n node.removeAttribute('contenteditable');\n }\n onCreateCopyEntityNode(modelElement, node);\n};\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function preprocessTable(table: ContentModelTable) {\n const sel = getSelectedCells(table);\n table.rows = table.rows\n .map(row => {\n return {\n ...row,\n cells: row.cells.filter(cell => cell.isSelected),\n };\n })\n .filter(row => row.cells.length > 0);\n\n delete table.format.width;\n\n table.widths = sel\n ? table.widths.filter((_, index) => index >= sel?.firstColumn && index <= sel?.lastColumn)\n : [];\n}\n\n/**\n * @internal\n * Create a new instance of CopyPastePlugin\n * @param option The editor option\n */\nexport function createCopyPastePlugin(\n option: EditorOptions\n): PluginWithState<CopyPastePluginState> {\n return new CopyPastePlugin(option);\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import type { IEditor, DOMSelection } from 'roosterjs-content-model-types';
2
+ /**
3
+ * @internal
4
+ * Adjust Image selection, so the copy by keyboard does not remove image selection.
5
+ */
6
+ export declare function adjustImageSelectionOnSafari(editor: IEditor, selection: DOMSelection | null): void;
@@ -0,0 +1,23 @@
1
+ define(["require", "exports"], function (require, exports) {
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.adjustImageSelectionOnSafari = void 0;
5
+ /**
6
+ * @internal
7
+ * Adjust Image selection, so the copy by keyboard does not remove image selection.
8
+ */
9
+ function adjustImageSelectionOnSafari(editor, selection) {
10
+ if (editor.getEnvironment().isSafari && (selection === null || selection === void 0 ? void 0 : selection.type) == 'image') {
11
+ var range = new Range();
12
+ range.setStartBefore(selection.image);
13
+ range.setEndAfter(selection.image);
14
+ editor.setDOMSelection({
15
+ range: range,
16
+ type: 'range',
17
+ isReverted: false,
18
+ });
19
+ }
20
+ }
21
+ exports.adjustImageSelectionOnSafari = adjustImageSelectionOnSafari;
22
+ });
23
+ //# sourceMappingURL=adjustImageSelectionOnSafari.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adjustImageSelectionOnSafari.js","sourceRoot":"","sources":["../../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/utils/adjustImageSelectionOnSafari.ts"],"names":[],"mappings":";;;;IAEA;;;OAGG;IACH,SAAgB,4BAA4B,CAAC,MAAe,EAAE,SAA8B;QACxF,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC,QAAQ,IAAI,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,KAAI,OAAO,EAAE;YAChE,IAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;YAC1B,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACtC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM,CAAC,eAAe,CAAC;gBACnB,KAAK,OAAA;gBACL,IAAI,EAAE,OAAO;gBACb,UAAU,EAAE,KAAK;aACpB,CAAC,CAAC;SACN;IACL,CAAC;IAXD,oEAWC","sourcesContent":["import type { IEditor, DOMSelection } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Adjust Image selection, so the copy by keyboard does not remove image selection.\n */\nexport function adjustImageSelectionOnSafari(editor: IEditor, selection: DOMSelection | null) {\n if (editor.getEnvironment().isSafari && selection?.type == 'image') {\n const range = new Range();\n range.setStartBefore(selection.image);\n range.setEndAfter(selection.image);\n editor.setDOMSelection({\n range,\n type: 'range',\n isReverted: false,\n });\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deleteEmptyList.js","sourceRoot":"","sources":["../../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/utils/deleteEmptyList.ts"],"names":[],"mappings":";;;;IAYA,SAAS,YAAY,CAAC,KAA4C;QAC9D,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,WAAW,EAAE;YACzC,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,CACvB,UAAA,OAAO,IAAI,OAAA,OAAO,CAAC,WAAW,KAAK,iBAAiB,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI,EAAxE,CAAwE,CACtF,CAAC;SACL;QAED,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,YAAY,EAAE;YAC1C,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;SAC3C;QAED,OAAO,CAAC,CAAC,KAAK,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACI,IAAM,eAAe,GAAwB,UAAC,OAA+B;QACxE,IAAA,WAAW,GAAmB,OAAO,YAA1B,EAAE,YAAY,GAAK,OAAO,aAAZ,CAAa;QAC9C,IAAI,YAAY,IAAI,OAAO,KAAI,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,IAAI,CAAA,EAAE;YAC9C,IAAM,KAAK,GAAG,IAAA,+DAAiC,EAC3C,WAAW,CAAC,IAAI,EAChB,CAAC,UAAU,CAAC,EACZ,CAAC,WAAW,CAAC,CAChB,CAAC;YACF,IAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,cAAc,IAAI,UAAU,EAAE;gBACzD,IAAM,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACvE,IAAM,aAAa,GACf,aAAa,GAAG,CAAC,CAAC;oBACd,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;oBACvD,CAAC,CAAC,SAAS,CAAC;gBACpB,IAAM,SAAS,GACX,aAAa,GAAG,CAAC,CAAC;oBACd,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;oBACvD,CAAC,CAAC,SAAS,CAAC;gBACpB,IACI,IAAA,sDAAwB,EAAC,IAAI,CAAC;oBAC9B,CAAC,CAAC,aAAa,IAAI,IAAA,iDAAmB,EAAC,aAAa,CAAC,CAAC;oBACtD,SAAS;oBACT,YAAY,CAAC,SAAS,CAAC,EACzB;oBACE,IAAA,yCAAW,EAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC;iBACjC;aACJ;SACJ;IACL,CAAC,CAAC;IA7BW,QAAA,eAAe,mBA6B1B","sourcesContent":["import {\n getClosestAncestorBlockGroupIndex,\n hasSelectionInBlock,\n hasSelectionInBlockGroup,\n mutateBlock,\n} from 'roosterjs-content-model-dom';\nimport type {\n DeleteSelectionContext,\n DeleteSelectionStep,\n ReadonlyContentModelBlock,\n} from 'roosterjs-content-model-types';\n\nfunction isEmptyBlock(block: ReadonlyContentModelBlock | undefined): boolean {\n if (block && block.blockType == 'Paragraph') {\n return block.segments.every(\n segment => segment.segmentType !== 'SelectionMarker' && segment.segmentType == 'Br'\n );\n }\n\n if (block && block.blockType == 'BlockGroup') {\n return block.blocks.every(isEmptyBlock);\n }\n\n return !!block;\n}\n\n/**\n * @internal\n * If the first item o the list is selected in a expanded selection, we need to remove the list item levels\n * @param context A context object provided by formatContentModel API\n */\nexport const deleteEmptyList: DeleteSelectionStep = (context: DeleteSelectionContext) => {\n const { insertPoint, deleteResult } = context;\n if (deleteResult == 'range' && insertPoint?.path) {\n const index = getClosestAncestorBlockGroupIndex(\n insertPoint.path,\n ['ListItem'],\n ['TableCell']\n );\n const item = insertPoint.path[index];\n if (index >= 0 && item && item.blockGroupType == 'ListItem') {\n const listItemIndex = insertPoint.path[index + 1].blocks.indexOf(item);\n const previousBlock =\n listItemIndex > -1\n ? insertPoint.path[index + 1].blocks[listItemIndex - 1]\n : undefined;\n const nextBlock =\n listItemIndex > -1\n ? insertPoint.path[index + 1].blocks[listItemIndex + 1]\n : undefined;\n if (\n hasSelectionInBlockGroup(item) &&\n (!previousBlock || hasSelectionInBlock(previousBlock)) &&\n nextBlock &&\n isEmptyBlock(nextBlock)\n ) {\n mutateBlock(item).levels = [];\n }\n }\n }\n};\n"]}
@@ -74,6 +74,12 @@ define(["require", "exports", "roosterjs-content-model-dom"], function (require,
74
74
  var paddingRight = (0, roosterjs_content_model_dom_1.parseValueWithUnit)(style === null || style === void 0 ? void 0 : style.paddingRight);
75
75
  return this.contentDiv.clientWidth - (paddingLeft + paddingRight);
76
76
  };
77
+ /**
78
+ * Get a deep cloned root element
79
+ */
80
+ DOMHelperImpl.prototype.getClonedRoot = function () {
81
+ return this.contentDiv.cloneNode(true /*deep*/);
82
+ };
77
83
  return DOMHelperImpl;
78
84
  }());
79
85
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"DOMHelperImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/editor/core/DOMHelperImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import { isNodeOfType, parseValueWithUnit, toArray } from 'roosterjs-content-model-dom';\nimport type { DOMHelper } from 'roosterjs-content-model-types';\n\nclass DOMHelperImpl implements DOMHelper {\n constructor(private contentDiv: HTMLElement) {}\n\n queryElements(selector: string): HTMLElement[] {\n return toArray(this.contentDiv.querySelectorAll(selector)) as HTMLElement[];\n }\n\n getTextContent(): string {\n return this.contentDiv.textContent || '';\n }\n\n isNodeInEditor(node: Node, excludeRoot?: boolean): boolean {\n return excludeRoot && node == this.contentDiv ? false : this.contentDiv.contains(node);\n }\n\n calculateZoomScale(): number {\n const originalWidth = this.contentDiv.getBoundingClientRect()?.width || 0;\n const visualWidth = this.contentDiv.offsetWidth;\n\n return visualWidth > 0 && originalWidth > 0\n ? Math.round((originalWidth / visualWidth) * 100) / 100\n : 1;\n }\n\n setDomAttribute(name: string, value: string | null) {\n if (value === null) {\n this.contentDiv.removeAttribute(name);\n } else {\n this.contentDiv.setAttribute(name, value);\n }\n }\n\n getDomAttribute(name: string): string | null {\n return this.contentDiv.getAttribute(name);\n }\n\n getDomStyle<T extends keyof CSSStyleDeclaration>(style: T): CSSStyleDeclaration[T] {\n return this.contentDiv.style[style];\n }\n\n findClosestElementAncestor(startFrom: Node, selector?: string): HTMLElement | null {\n const startElement = isNodeOfType(startFrom, 'ELEMENT_NODE')\n ? startFrom\n : startFrom.parentElement;\n const closestElement = selector\n ? (startElement?.closest(selector) as HTMLElement | null)\n : startElement;\n\n return closestElement &&\n this.isNodeInEditor(closestElement) &&\n closestElement != this.contentDiv\n ? closestElement\n : null;\n }\n\n hasFocus(): boolean {\n const activeElement = this.contentDiv.ownerDocument.activeElement;\n return !!(activeElement && this.contentDiv.contains(activeElement));\n }\n\n /**\n * Check if the root element is in RTL mode\n */\n isRightToLeft(): boolean {\n const contentDiv = this.contentDiv;\n const style = contentDiv.ownerDocument.defaultView?.getComputedStyle(contentDiv);\n\n return style?.direction == 'rtl';\n }\n\n /**\n * Get the width of the editable area of the editor content div\n */\n getClientWidth(): number {\n const contentDiv = this.contentDiv;\n const style = contentDiv.ownerDocument.defaultView?.getComputedStyle(contentDiv);\n const paddingLeft = parseValueWithUnit(style?.paddingLeft);\n const paddingRight = parseValueWithUnit(style?.paddingRight);\n return this.contentDiv.clientWidth - (paddingLeft + paddingRight);\n }\n}\n\n/**\n * @internal Create new instance of DOMHelper\n */\nexport function createDOMHelper(contentDiv: HTMLElement): DOMHelper {\n return new DOMHelperImpl(contentDiv);\n}\n"]}
1
+ {"version":3,"file":"DOMHelperImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/editor/core/DOMHelperImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import { isNodeOfType, parseValueWithUnit, toArray } from 'roosterjs-content-model-dom';\nimport type { DOMHelper } from 'roosterjs-content-model-types';\n\nclass DOMHelperImpl implements DOMHelper {\n constructor(private contentDiv: HTMLElement) {}\n\n queryElements(selector: string): HTMLElement[] {\n return toArray(this.contentDiv.querySelectorAll(selector)) as HTMLElement[];\n }\n\n getTextContent(): string {\n return this.contentDiv.textContent || '';\n }\n\n isNodeInEditor(node: Node, excludeRoot?: boolean): boolean {\n return excludeRoot && node == this.contentDiv ? false : this.contentDiv.contains(node);\n }\n\n calculateZoomScale(): number {\n const originalWidth = this.contentDiv.getBoundingClientRect()?.width || 0;\n const visualWidth = this.contentDiv.offsetWidth;\n\n return visualWidth > 0 && originalWidth > 0\n ? Math.round((originalWidth / visualWidth) * 100) / 100\n : 1;\n }\n\n setDomAttribute(name: string, value: string | null) {\n if (value === null) {\n this.contentDiv.removeAttribute(name);\n } else {\n this.contentDiv.setAttribute(name, value);\n }\n }\n\n getDomAttribute(name: string): string | null {\n return this.contentDiv.getAttribute(name);\n }\n\n getDomStyle<T extends keyof CSSStyleDeclaration>(style: T): CSSStyleDeclaration[T] {\n return this.contentDiv.style[style];\n }\n\n findClosestElementAncestor(startFrom: Node, selector?: string): HTMLElement | null {\n const startElement = isNodeOfType(startFrom, 'ELEMENT_NODE')\n ? startFrom\n : startFrom.parentElement;\n const closestElement = selector\n ? (startElement?.closest(selector) as HTMLElement | null)\n : startElement;\n\n return closestElement &&\n this.isNodeInEditor(closestElement) &&\n closestElement != this.contentDiv\n ? closestElement\n : null;\n }\n\n hasFocus(): boolean {\n const activeElement = this.contentDiv.ownerDocument.activeElement;\n return !!(activeElement && this.contentDiv.contains(activeElement));\n }\n\n /**\n * Check if the root element is in RTL mode\n */\n isRightToLeft(): boolean {\n const contentDiv = this.contentDiv;\n const style = contentDiv.ownerDocument.defaultView?.getComputedStyle(contentDiv);\n\n return style?.direction == 'rtl';\n }\n\n /**\n * Get the width of the editable area of the editor content div\n */\n getClientWidth(): number {\n const contentDiv = this.contentDiv;\n const style = contentDiv.ownerDocument.defaultView?.getComputedStyle(contentDiv);\n const paddingLeft = parseValueWithUnit(style?.paddingLeft);\n const paddingRight = parseValueWithUnit(style?.paddingRight);\n return this.contentDiv.clientWidth - (paddingLeft + paddingRight);\n }\n\n /**\n * Get a deep cloned root element\n */\n getClonedRoot(): HTMLElement {\n return this.contentDiv.cloneNode(true /*deep*/) as HTMLElement;\n }\n}\n\n/**\n * @internal Create new instance of DOMHelper\n */\nexport function createDOMHelper(contentDiv: HTMLElement): DOMHelper {\n return new DOMHelperImpl(contentDiv);\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import { __assign } from "tslib";
2
2
  import { addRangeToSelection } from '../../coreApi/setDOMSelection/addRangeToSelection';
3
- import { deleteEmptyList } from './deleteEmptyList';
3
+ import { adjustImageSelectionOnSafari } from './utils/adjustImageSelectionOnSafari';
4
+ import { deleteEmptyList } from './utils/deleteEmptyList';
4
5
  import { onCreateCopyEntityNode } from '../../override/pasteCopyBlockEntityParser';
5
6
  import { paste } from '../../command/paste/paste';
6
7
  import { ChangeSource, contentModelToDom, createModelToDomContext, deleteSelection, extractClipboardItems, getSelectedCells, isElementOfType, isNodeOfType, iterateSelections, moveChildNodes, normalizeContentModel, toArray, wrap, } from 'roosterjs-content-model-dom';
@@ -90,6 +91,7 @@ var CopyPastePlugin = /** @class */ (function () {
90
91
  }
91
92
  var doc = this.editor.getDocument();
92
93
  var selection = this.editor.getDOMSelection();
94
+ adjustImageSelectionOnSafari(this.editor, selection);
93
95
  if (selection && (selection.type != 'range' || !selection.range.collapsed)) {
94
96
  var pasteModel = this.editor.getContentModelCopy('disconnected');
95
97
  if (selection.type === 'table') {
@@ -1 +1 @@
1
- {"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mDAAmD,CAAC;AACxF,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AACnF,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAElD,OAAO,EACH,YAAY,EACZ,iBAAiB,EACjB,uBAAuB,EACvB,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,OAAO,EACP,IAAI,GACP,MAAM,6BAA6B,CAAC;AAgBrC;;GAEG;AACH;IAKI;;;OAGG;IACH,yBAAY,MAAqB;QAAjC,iBAMC;QAdO,WAAM,GAAmB,IAAI,CAAC;QAC9B,aAAQ,GAAwB,IAAI,CAAC;QAsJrC,YAAO,GAAG,UAAC,KAAY;YAC3B,IAAI,KAAI,CAAC,MAAM,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE;gBACxC,IAAM,QAAM,GAAG,KAAI,CAAC,MAAM,CAAC;gBAE3B,IAAM,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC;gBAEzC,IAAI,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK,EAAE;oBACrB,KAAK,CAAC,cAAc,EAAE,CAAC;oBACvB,qBAAqB,CACjB,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAC3B,KAAI,CAAC,KAAK,CAAC,sBAAsB,CACpC,CAAC,IAAI,CAAC,UAAC,aAA4B;wBAChC,IAAI,CAAC,QAAM,CAAC,UAAU,EAAE,EAAE;4BACtB,KAAK,CAAC,QAAM,EAAE,aAAa,EAAE,KAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;yBAC7D;oBACL,CAAC,CAAC,CAAC;iBACN;aACJ;QACL,CAAC,CAAC;QAhKE,IAAI,CAAC,KAAK,GAAG;YACT,sBAAsB,EAAE,MAAM,CAAC,sBAAsB,IAAI,EAAE;YAC3D,OAAO,EAAE,IAAI;YACb,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;SAC5C,CAAC;IACN,CAAC;IAED;;OAEG;IACH,iCAAO,GAAP;QACI,OAAO,WAAW,CAAC;IACvB,CAAC;IAED;;;OAGG;IACH,oCAAU,GAAV,UAAW,MAAe;QAA1B,iBAaC;QAZG,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;YACvC,KAAK,EAAE;gBACH,cAAc,EAAE,UAAA,CAAC,IAAI,OAAA,KAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAf,CAAe;aACvC;YACD,IAAI,EAAE;gBACF,cAAc,EAAE,UAAA,CAAC,IAAI,OAAA,KAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,EAAlC,CAAkC;aAC1D;YACD,GAAG,EAAE;gBACD,cAAc,EAAE,UAAA,CAAC,IAAI,OAAA,KAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAjC,CAAiC;aACzD;SACJ,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACH,iCAAO,GAAP;;QACI,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;YACpB,MAAA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,0CAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC/D,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;SAC7B;QAED,IAAI,IAAI,CAAC,QAAQ,EAAE;YACf,IAAI,CAAC,QAAQ,EAAE,CAAC;SACnB;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,kCAAQ,GAAR;QACI,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAEO,mCAAS,GAAjB,UAAkB,KAAY,EAAE,KAAc;QAA9C,iBAoFC;;QAnFG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YACd,OAAO;SACV;QAED,IAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QACtC,IAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;QAEhD,IAAI,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE;YACxE,IAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC;YAEnE,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,EAAE;gBAC5B,iBAAiB,CAAC,UAAU,EAAE,UAAC,CAAC,EAAE,YAAY;oBAC1C,IAAI,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK,EAAE;wBACrB,eAAe,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;wBAEpC,OAAO,IAAI,CAAC;qBACf;oBACD,OAAO,KAAK,CAAC;gBACjB,CAAC,CAAC,CAAC;aACN;iBAAM,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,EAAE;gBACnC,yBAAyB,CAAC,UAAU,CAAC,CAAC;aACzC;YAED,IAAM,SAAO,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;YAC3D,IAAM,OAAO,GAAG,uBAAuB,EAAE,CAAC;YAE1C,OAAO,CAAC,aAAa,GAAG,aAAa,CAAC;YAEtC,IAAM,gBAAgB,GAAG,iBAAiB,CACtC,SAAO,CAAC,aAAa,EACrB,SAAO,EACP,UAAU,EACV,OAAO,CACV,CAAC;YAEF,IAAI,QAAQ,GAAiB,gBAAgB;gBACzC,CAAC,CAAC,mBAAmB,CAAC,GAAG,EAAE,gBAAgB,CAAC;gBAC5C,CAAC,CAAC,IAAI,CAAC;YAEX,IAAI,QAAQ,EAAE;gBACV,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE;oBACjD,UAAU,EAAE,SAAO;oBACnB,KAAK,EAAE,QAAQ;oBACf,QAAQ,EAAE,KAAuB;oBACjC,KAAK,OAAA;iBACR,CAAC,CAAC,KAAK,CAAC;gBAET,IAAI,QAAQ,EAAE;oBACV,mBAAmB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;iBACtC;gBAED,MAAA,GAAG,CAAC,WAAW,0CAAE,qBAAqB,CAAC;oBACnC,IAAI,CAAC,KAAI,CAAC,MAAM,EAAE;wBACd,OAAO;qBACV;oBAED,0BAA0B,CAAC,SAAO,CAAC,CAAC;oBACpC,KAAI,CAAC,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;oBACvC,KAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;oBAEpB,IAAI,KAAK,EAAE;wBACP,KAAI,CAAC,MAAM,CAAC,kBAAkB,CAC1B,UAAC,KAAK,EAAE,OAAO;4BACX,IACI,eAAe,CAAC,KAAK,EAAE,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;iCAC7C,YAAY,IAAI,OAAO,EAC9B;gCACE,qBAAqB,CAAC,KAAK,CAAC,CAAC;6BAChC;4BAED,OAAO,IAAI,CAAC;wBAChB,CAAC,EACD;4BACI,OAAO,EAAE,KAAK;4BACd,YAAY,EAAE,YAAY,CAAC,GAAG;yBACjC,CACJ,CAAC;qBACL;gBACL,CAAC,CAAC,CAAC;aACN;iBAAM;gBACH,0BAA0B,CAAC,SAAO,CAAC,CAAC;aACvC;SACJ;IACL,CAAC;IAsBO,oCAAU,GAAlB,UAAmB,GAAa;QAC5B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;YACrB,IAAM,OAAO,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAEzC,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC;YAC9B,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC;YAC7B,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;YAClC,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC;YACjC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC;YACxB,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC;YAClC,OAAO,CAAC,eAAe,GAAG,MAAM,CAAC;YAEjC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YAE9B,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;SAChC;QAED,IAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;QAE/B,GAAG,CAAC,KAAK,CAAC,eAAe,GAAG,OAAO,CAAC;QACpC,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC;QAC1B,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,UAAA,IAAI,IAAI,OAAA,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,EAArB,CAAqB,CAAC,CAAC;QAEtD,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC;QACvB,GAAG,CAAC,KAAK,EAAE,CAAC;QAEZ,OAAO,GAAG,CAAC;IACf,CAAC;IACL,sBAAC;AAAD,CAAC,AAzMD,IAyMC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,UAAgC;IACtE,IAAI,eAAgD,CAAC;IACrD,IAAI,UAA6C,CAAC;IAClD,IAAI,YAAuD,CAAC;IAE5D,iBAAiB,CAAC,UAAU,EAAE,UAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ;QACxD,IAAI,eAAe,EAAE;YACjB,IAAI,SAAS,IAAI,YAAY,KAAI,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAA,EAAE;gBAC7E,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC;aAC/E;YACD,OAAO,IAAI,CAAC;SACf;QAED,IAAM,MAAM,GAAG,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,CAAC,UAAA,OAAO,IAAI,OAAA,OAAO,CAAC,WAAW,IAAI,iBAAiB,EAAxC,CAAwC,CAAC,CAAC;QACnF,IAAI,CAAC,eAAe,IAAI,MAAM,EAAE;YAC5B,YAAY,GAAG,SAAS,CAAC;YACzB,UAAU,GAAG,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,SAAS,KAAI,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;YACjE,eAAe,GAAG,MAAM,CAAC;SAC5B;QAED,OAAO,KAAK,CAAC;IACjB,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,0BAA0B,CAAC,OAAuB;IACvD,OAAO,CAAC,KAAK,CAAC,eAAe,GAAG,EAAE,CAAC;IACnC,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;IACzB,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;IAC/B,cAAc,CAAC,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAY;IAClC,OAAO,CAAC,CAAE,KAAwB,CAAC,aAAa,CAAC;AACrD,CAAC;AAED,SAAS,mBAAmB,CAAC,GAAa,EAAE,SAAuB;;IAC/D,IAAI,QAAQ,GAAiB,IAAI,CAAC;IAElC,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,EAAE;QAC5B,IAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;QAC9B,IAAM,eAAe,GACjB,CAAA,MAAA,KAAK,CAAC,aAAa,0CAAE,iBAAiB,KAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC;QAE9E,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAC7B,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;KACxC;SAAM,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,EAAE;QACnC,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAC7B,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;KACxC;SAAM;QACH,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC;KAC9B;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,IAAM,aAAa,GAAkB,UAAC,YAAY,EAAE,IAAI;IAC3D,IAAI,YAAY,CAAC,IAAI,EAAE,cAAc,CAAC,IAAI,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;QACtE,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;KACzC;IACD,IAAI,YAAY,CAAC,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE;QAC/D,IAAI,CAAC,eAAe,CAAC,iBAAiB,CAAC,CAAC;KAC3C;IACD,sBAAsB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;AAC/C,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,KAAwB;IACpD,IAAM,GAAG,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACpC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;SAClB,GAAG,CAAC,UAAA,GAAG;QACJ,6BACO,GAAG,KACN,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,UAAA,IAAI,IAAI,OAAA,IAAI,CAAC,UAAU,EAAf,CAAe,CAAC,IAClD;IACN,CAAC,CAAC;SACD,MAAM,CAAC,UAAA,GAAG,IAAI,OAAA,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAApB,CAAoB,CAAC,CAAC;IAEzC,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;IAE1B,KAAK,CAAC,MAAM,GAAG,GAAG;QACd,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,UAAC,CAAC,EAAE,KAAK,IAAK,OAAA,KAAK,KAAI,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,WAAW,CAAA,IAAI,KAAK,KAAI,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,UAAU,CAAA,EAArD,CAAqD,CAAC;QAC1F,CAAC,CAAC,EAAE,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CACjC,MAAqB;IAErB,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC","sourcesContent":["import { addRangeToSelection } from '../../coreApi/setDOMSelection/addRangeToSelection';\nimport { deleteEmptyList } from './deleteEmptyList';\nimport { onCreateCopyEntityNode } from '../../override/pasteCopyBlockEntityParser';\nimport { paste } from '../../command/paste/paste';\n\nimport {\n ChangeSource,\n contentModelToDom,\n createModelToDomContext,\n deleteSelection,\n extractClipboardItems,\n getSelectedCells,\n isElementOfType,\n isNodeOfType,\n iterateSelections,\n moveChildNodes,\n normalizeContentModel,\n toArray,\n wrap,\n} from 'roosterjs-content-model-dom';\nimport type {\n ClipboardData,\n CopyPastePluginState,\n ContentModelTable,\n DOMSelection,\n IEditor,\n OnNodeCreated,\n EditorOptions,\n PluginWithState,\n ContentModelDocument,\n ContentModelParagraph,\n ContentModelSegment,\n ReadonlyTableSelectionContext,\n} from 'roosterjs-content-model-types';\n\n/**\n * Copy and paste plugin for handling onCopy and onPaste event\n */\nclass CopyPastePlugin implements PluginWithState<CopyPastePluginState> {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n private state: CopyPastePluginState;\n\n /**\n * Construct a new instance of CopyPastePlugin\n * @param option The editor option\n */\n constructor(option: EditorOptions) {\n this.state = {\n allowedCustomPasteType: option.allowedCustomPasteType || [],\n tempDiv: null,\n defaultPasteType: option.defaultPasteType,\n };\n }\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'CopyPaste';\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 this.disposer = this.editor.attachDomEvent({\n paste: {\n beforeDispatch: e => this.onPaste(e),\n },\n copy: {\n beforeDispatch: e => this.onCutCopy(e, false /*isCut*/),\n },\n cut: {\n beforeDispatch: e => this.onCutCopy(e, true /*isCut*/),\n },\n });\n }\n\n /**\n * Dispose this plugin\n */\n dispose() {\n if (this.state.tempDiv) {\n this.state.tempDiv.parentNode?.removeChild(this.state.tempDiv);\n this.state.tempDiv = null;\n }\n\n if (this.disposer) {\n this.disposer();\n }\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 onCutCopy(event: Event, isCut: boolean) {\n if (!this.editor) {\n return;\n }\n\n const doc = this.editor.getDocument();\n const selection = this.editor.getDOMSelection();\n\n if (selection && (selection.type != 'range' || !selection.range.collapsed)) {\n const pasteModel = this.editor.getContentModelCopy('disconnected');\n\n if (selection.type === 'table') {\n iterateSelections(pasteModel, (_, tableContext) => {\n if (tableContext?.table) {\n preprocessTable(tableContext.table);\n\n return true;\n }\n return false;\n });\n } else if (selection.type === 'range') {\n adjustSelectionForCopyCut(pasteModel);\n }\n\n const tempDiv = this.getTempDiv(this.editor.getDocument());\n const context = createModelToDomContext();\n\n context.onNodeCreated = onNodeCreated;\n\n const selectionForCopy = contentModelToDom(\n tempDiv.ownerDocument,\n tempDiv,\n pasteModel,\n context\n );\n\n let newRange: Range | null = selectionForCopy\n ? domSelectionToRange(doc, selectionForCopy)\n : null;\n\n if (newRange) {\n newRange = this.editor.triggerEvent('beforeCutCopy', {\n clonedRoot: tempDiv,\n range: newRange,\n rawEvent: event as ClipboardEvent,\n isCut,\n }).range;\n\n if (newRange) {\n addRangeToSelection(doc, newRange);\n }\n\n doc.defaultView?.requestAnimationFrame(() => {\n if (!this.editor) {\n return;\n }\n\n cleanUpAndRestoreSelection(tempDiv);\n this.editor.setDOMSelection(selection);\n this.editor.focus();\n\n if (isCut) {\n this.editor.formatContentModel(\n (model, context) => {\n if (\n deleteSelection(model, [deleteEmptyList], context)\n .deleteResult == 'range'\n ) {\n normalizeContentModel(model);\n }\n\n return true;\n },\n {\n apiName: 'cut',\n changeSource: ChangeSource.Cut,\n }\n );\n }\n });\n } else {\n cleanUpAndRestoreSelection(tempDiv);\n }\n }\n }\n\n private onPaste = (event: Event) => {\n if (this.editor && isClipboardEvent(event)) {\n const editor = this.editor;\n\n const dataTransfer = event.clipboardData;\n\n if (dataTransfer?.items) {\n event.preventDefault();\n extractClipboardItems(\n toArray(dataTransfer.items),\n this.state.allowedCustomPasteType\n ).then((clipboardData: ClipboardData) => {\n if (!editor.isDisposed()) {\n paste(editor, clipboardData, this.state.defaultPasteType);\n }\n });\n }\n }\n };\n\n private getTempDiv(doc: Document) {\n if (!this.state.tempDiv) {\n const tempDiv = doc.createElement('div');\n\n tempDiv.style.width = '600px';\n tempDiv.style.height = '1px';\n tempDiv.style.overflow = 'hidden';\n tempDiv.style.position = 'fixed';\n tempDiv.style.top = '0';\n tempDiv.style.left = '0';\n tempDiv.style.userSelect = 'text';\n tempDiv.contentEditable = 'true';\n\n doc.body.appendChild(tempDiv);\n\n this.state.tempDiv = tempDiv;\n }\n\n const div = this.state.tempDiv;\n\n div.style.backgroundColor = 'white';\n div.style.color = 'black';\n div.childNodes.forEach(node => div.removeChild(node));\n\n div.style.display = '';\n div.focus();\n\n return div;\n }\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function adjustSelectionForCopyCut(pasteModel: ContentModelDocument) {\n let selectionMarker: ContentModelSegment | undefined;\n let firstBlock: ContentModelParagraph | undefined;\n let tableContext: ReadonlyTableSelectionContext | undefined;\n\n iterateSelections(pasteModel, (_, tableCtxt, block, segments) => {\n if (selectionMarker) {\n if (tableCtxt != tableContext && firstBlock?.segments.includes(selectionMarker)) {\n firstBlock.segments.splice(firstBlock.segments.indexOf(selectionMarker), 1);\n }\n return true;\n }\n\n const marker = segments?.find(segment => segment.segmentType == 'SelectionMarker');\n if (!selectionMarker && marker) {\n tableContext = tableCtxt;\n firstBlock = block?.blockType == 'Paragraph' ? block : undefined;\n selectionMarker = marker;\n }\n\n return false;\n });\n}\n\nfunction cleanUpAndRestoreSelection(tempDiv: HTMLDivElement) {\n tempDiv.style.backgroundColor = '';\n tempDiv.style.color = '';\n tempDiv.style.display = 'none';\n moveChildNodes(tempDiv);\n}\n\nfunction isClipboardEvent(event: Event): event is ClipboardEvent {\n return !!(event as ClipboardEvent).clipboardData;\n}\n\nfunction domSelectionToRange(doc: Document, selection: DOMSelection): Range | null {\n let newRange: Range | null = null;\n\n if (selection.type === 'table') {\n const table = selection.table;\n const elementToSelect =\n table.parentElement?.childElementCount == 1 ? table.parentElement : table;\n\n newRange = doc.createRange();\n newRange.selectNode(elementToSelect);\n } else if (selection.type === 'image') {\n newRange = doc.createRange();\n newRange.selectNode(selection.image);\n } else {\n newRange = selection.range;\n }\n\n return newRange;\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport const onNodeCreated: OnNodeCreated = (modelElement, node): void => {\n if (isNodeOfType(node, 'ELEMENT_NODE') && isElementOfType(node, 'table')) {\n wrap(node.ownerDocument, node, 'div');\n }\n if (isNodeOfType(node, 'ELEMENT_NODE') && !node.isContentEditable) {\n node.removeAttribute('contenteditable');\n }\n onCreateCopyEntityNode(modelElement, node);\n};\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function preprocessTable(table: ContentModelTable) {\n const sel = getSelectedCells(table);\n table.rows = table.rows\n .map(row => {\n return {\n ...row,\n cells: row.cells.filter(cell => cell.isSelected),\n };\n })\n .filter(row => row.cells.length > 0);\n\n delete table.format.width;\n\n table.widths = sel\n ? table.widths.filter((_, index) => index >= sel?.firstColumn && index <= sel?.lastColumn)\n : [];\n}\n\n/**\n * @internal\n * Create a new instance of CopyPastePlugin\n * @param option The editor option\n */\nexport function createCopyPastePlugin(\n option: EditorOptions\n): PluginWithState<CopyPastePluginState> {\n return new CopyPastePlugin(option);\n}\n"]}
1
+ {"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { addRangeToSelection } from '../../coreApi/setDOMSelection/addRangeToSelection';\nimport { adjustImageSelectionOnSafari } from './utils/adjustImageSelectionOnSafari';\nimport { deleteEmptyList } from './utils/deleteEmptyList';\nimport { onCreateCopyEntityNode } from '../../override/pasteCopyBlockEntityParser';\nimport { paste } from '../../command/paste/paste';\nimport {\n ChangeSource,\n contentModelToDom,\n createModelToDomContext,\n deleteSelection,\n extractClipboardItems,\n getSelectedCells,\n isElementOfType,\n isNodeOfType,\n iterateSelections,\n moveChildNodes,\n normalizeContentModel,\n toArray,\n wrap,\n} from 'roosterjs-content-model-dom';\nimport type {\n ClipboardData,\n CopyPastePluginState,\n ContentModelTable,\n DOMSelection,\n IEditor,\n OnNodeCreated,\n EditorOptions,\n PluginWithState,\n ContentModelDocument,\n ContentModelParagraph,\n ContentModelSegment,\n ReadonlyTableSelectionContext,\n} from 'roosterjs-content-model-types';\n\n/**\n * Copy and paste plugin for handling onCopy and onPaste event\n */\nclass CopyPastePlugin implements PluginWithState<CopyPastePluginState> {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n private state: CopyPastePluginState;\n\n /**\n * Construct a new instance of CopyPastePlugin\n * @param option The editor option\n */\n constructor(option: EditorOptions) {\n this.state = {\n allowedCustomPasteType: option.allowedCustomPasteType || [],\n tempDiv: null,\n defaultPasteType: option.defaultPasteType,\n };\n }\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'CopyPaste';\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 this.disposer = this.editor.attachDomEvent({\n paste: {\n beforeDispatch: e => this.onPaste(e),\n },\n copy: {\n beforeDispatch: e => this.onCutCopy(e, false /*isCut*/),\n },\n cut: {\n beforeDispatch: e => this.onCutCopy(e, true /*isCut*/),\n },\n });\n }\n\n /**\n * Dispose this plugin\n */\n dispose() {\n if (this.state.tempDiv) {\n this.state.tempDiv.parentNode?.removeChild(this.state.tempDiv);\n this.state.tempDiv = null;\n }\n\n if (this.disposer) {\n this.disposer();\n }\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 onCutCopy(event: Event, isCut: boolean) {\n if (!this.editor) {\n return;\n }\n\n const doc = this.editor.getDocument();\n const selection = this.editor.getDOMSelection();\n\n adjustImageSelectionOnSafari(this.editor, selection);\n\n if (selection && (selection.type != 'range' || !selection.range.collapsed)) {\n const pasteModel = this.editor.getContentModelCopy('disconnected');\n\n if (selection.type === 'table') {\n iterateSelections(pasteModel, (_, tableContext) => {\n if (tableContext?.table) {\n preprocessTable(tableContext.table);\n\n return true;\n }\n return false;\n });\n } else if (selection.type === 'range') {\n adjustSelectionForCopyCut(pasteModel);\n }\n\n const tempDiv = this.getTempDiv(this.editor.getDocument());\n const context = createModelToDomContext();\n\n context.onNodeCreated = onNodeCreated;\n\n const selectionForCopy = contentModelToDom(\n tempDiv.ownerDocument,\n tempDiv,\n pasteModel,\n context\n );\n\n let newRange: Range | null = selectionForCopy\n ? domSelectionToRange(doc, selectionForCopy)\n : null;\n\n if (newRange) {\n newRange = this.editor.triggerEvent('beforeCutCopy', {\n clonedRoot: tempDiv,\n range: newRange,\n rawEvent: event as ClipboardEvent,\n isCut,\n }).range;\n\n if (newRange) {\n addRangeToSelection(doc, newRange);\n }\n\n doc.defaultView?.requestAnimationFrame(() => {\n if (!this.editor) {\n return;\n }\n\n cleanUpAndRestoreSelection(tempDiv);\n this.editor.setDOMSelection(selection);\n this.editor.focus();\n\n if (isCut) {\n this.editor.formatContentModel(\n (model, context) => {\n if (\n deleteSelection(model, [deleteEmptyList], context)\n .deleteResult == 'range'\n ) {\n normalizeContentModel(model);\n }\n\n return true;\n },\n {\n apiName: 'cut',\n changeSource: ChangeSource.Cut,\n }\n );\n }\n });\n } else {\n cleanUpAndRestoreSelection(tempDiv);\n }\n }\n }\n\n private onPaste = (event: Event) => {\n if (this.editor && isClipboardEvent(event)) {\n const editor = this.editor;\n\n const dataTransfer = event.clipboardData;\n\n if (dataTransfer?.items) {\n event.preventDefault();\n extractClipboardItems(\n toArray(dataTransfer.items),\n this.state.allowedCustomPasteType\n ).then((clipboardData: ClipboardData) => {\n if (!editor.isDisposed()) {\n paste(editor, clipboardData, this.state.defaultPasteType);\n }\n });\n }\n }\n };\n\n private getTempDiv(doc: Document) {\n if (!this.state.tempDiv) {\n const tempDiv = doc.createElement('div');\n\n tempDiv.style.width = '600px';\n tempDiv.style.height = '1px';\n tempDiv.style.overflow = 'hidden';\n tempDiv.style.position = 'fixed';\n tempDiv.style.top = '0';\n tempDiv.style.left = '0';\n tempDiv.style.userSelect = 'text';\n tempDiv.contentEditable = 'true';\n\n doc.body.appendChild(tempDiv);\n\n this.state.tempDiv = tempDiv;\n }\n\n const div = this.state.tempDiv;\n\n div.style.backgroundColor = 'white';\n div.style.color = 'black';\n div.childNodes.forEach(node => div.removeChild(node));\n\n div.style.display = '';\n div.focus();\n\n return div;\n }\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function adjustSelectionForCopyCut(pasteModel: ContentModelDocument) {\n let selectionMarker: ContentModelSegment | undefined;\n let firstBlock: ContentModelParagraph | undefined;\n let tableContext: ReadonlyTableSelectionContext | undefined;\n\n iterateSelections(pasteModel, (_, tableCtxt, block, segments) => {\n if (selectionMarker) {\n if (tableCtxt != tableContext && firstBlock?.segments.includes(selectionMarker)) {\n firstBlock.segments.splice(firstBlock.segments.indexOf(selectionMarker), 1);\n }\n return true;\n }\n\n const marker = segments?.find(segment => segment.segmentType == 'SelectionMarker');\n if (!selectionMarker && marker) {\n tableContext = tableCtxt;\n firstBlock = block?.blockType == 'Paragraph' ? block : undefined;\n selectionMarker = marker;\n }\n\n return false;\n });\n}\n\nfunction cleanUpAndRestoreSelection(tempDiv: HTMLDivElement) {\n tempDiv.style.backgroundColor = '';\n tempDiv.style.color = '';\n tempDiv.style.display = 'none';\n moveChildNodes(tempDiv);\n}\n\nfunction isClipboardEvent(event: Event): event is ClipboardEvent {\n return !!(event as ClipboardEvent).clipboardData;\n}\n\nfunction domSelectionToRange(doc: Document, selection: DOMSelection): Range | null {\n let newRange: Range | null = null;\n\n if (selection.type === 'table') {\n const table = selection.table;\n const elementToSelect =\n table.parentElement?.childElementCount == 1 ? table.parentElement : table;\n\n newRange = doc.createRange();\n newRange.selectNode(elementToSelect);\n } else if (selection.type === 'image') {\n newRange = doc.createRange();\n newRange.selectNode(selection.image);\n } else {\n newRange = selection.range;\n }\n\n return newRange;\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport const onNodeCreated: OnNodeCreated = (modelElement, node): void => {\n if (isNodeOfType(node, 'ELEMENT_NODE') && isElementOfType(node, 'table')) {\n wrap(node.ownerDocument, node, 'div');\n }\n if (isNodeOfType(node, 'ELEMENT_NODE') && !node.isContentEditable) {\n node.removeAttribute('contenteditable');\n }\n onCreateCopyEntityNode(modelElement, node);\n};\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function preprocessTable(table: ContentModelTable) {\n const sel = getSelectedCells(table);\n table.rows = table.rows\n .map(row => {\n return {\n ...row,\n cells: row.cells.filter(cell => cell.isSelected),\n };\n })\n .filter(row => row.cells.length > 0);\n\n delete table.format.width;\n\n table.widths = sel\n ? table.widths.filter((_, index) => index >= sel?.firstColumn && index <= sel?.lastColumn)\n : [];\n}\n\n/**\n * @internal\n * Create a new instance of CopyPastePlugin\n * @param option The editor option\n */\nexport function createCopyPastePlugin(\n option: EditorOptions\n): PluginWithState<CopyPastePluginState> {\n return new CopyPastePlugin(option);\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import type { IEditor, DOMSelection } from 'roosterjs-content-model-types';
2
+ /**
3
+ * @internal
4
+ * Adjust Image selection, so the copy by keyboard does not remove image selection.
5
+ */
6
+ export declare function adjustImageSelectionOnSafari(editor: IEditor, selection: DOMSelection | null): void;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @internal
3
+ * Adjust Image selection, so the copy by keyboard does not remove image selection.
4
+ */
5
+ export function adjustImageSelectionOnSafari(editor, selection) {
6
+ if (editor.getEnvironment().isSafari && (selection === null || selection === void 0 ? void 0 : selection.type) == 'image') {
7
+ var range = new Range();
8
+ range.setStartBefore(selection.image);
9
+ range.setEndAfter(selection.image);
10
+ editor.setDOMSelection({
11
+ range: range,
12
+ type: 'range',
13
+ isReverted: false,
14
+ });
15
+ }
16
+ }
17
+ //# sourceMappingURL=adjustImageSelectionOnSafari.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adjustImageSelectionOnSafari.js","sourceRoot":"","sources":["../../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/utils/adjustImageSelectionOnSafari.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAAC,MAAe,EAAE,SAA8B;IACxF,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC,QAAQ,IAAI,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,KAAI,OAAO,EAAE;QAChE,IAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QAC1B,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACtC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,CAAC,eAAe,CAAC;YACnB,KAAK,OAAA;YACL,IAAI,EAAE,OAAO;YACb,UAAU,EAAE,KAAK;SACpB,CAAC,CAAC;KACN;AACL,CAAC","sourcesContent":["import type { IEditor, DOMSelection } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Adjust Image selection, so the copy by keyboard does not remove image selection.\n */\nexport function adjustImageSelectionOnSafari(editor: IEditor, selection: DOMSelection | null) {\n if (editor.getEnvironment().isSafari && selection?.type == 'image') {\n const range = new Range();\n range.setStartBefore(selection.image);\n range.setEndAfter(selection.image);\n editor.setDOMSelection({\n range,\n type: 'range',\n isReverted: false,\n });\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deleteEmptyList.js","sourceRoot":"","sources":["../../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/utils/deleteEmptyList.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,iCAAiC,EACjC,mBAAmB,EACnB,wBAAwB,EACxB,WAAW,GACd,MAAM,6BAA6B,CAAC;AAOrC,SAAS,YAAY,CAAC,KAA4C;IAC9D,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,WAAW,EAAE;QACzC,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,CACvB,UAAA,OAAO,IAAI,OAAA,OAAO,CAAC,WAAW,KAAK,iBAAiB,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI,EAAxE,CAAwE,CACtF,CAAC;KACL;IAED,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,YAAY,EAAE;QAC1C,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;KAC3C;IAED,OAAO,CAAC,CAAC,KAAK,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,IAAM,eAAe,GAAwB,UAAC,OAA+B;IACxE,IAAA,WAAW,GAAmB,OAAO,YAA1B,EAAE,YAAY,GAAK,OAAO,aAAZ,CAAa;IAC9C,IAAI,YAAY,IAAI,OAAO,KAAI,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,IAAI,CAAA,EAAE;QAC9C,IAAM,KAAK,GAAG,iCAAiC,CAC3C,WAAW,CAAC,IAAI,EAChB,CAAC,UAAU,CAAC,EACZ,CAAC,WAAW,CAAC,CAChB,CAAC;QACF,IAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,cAAc,IAAI,UAAU,EAAE;YACzD,IAAM,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACvE,IAAM,aAAa,GACf,aAAa,GAAG,CAAC,CAAC;gBACd,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;gBACvD,CAAC,CAAC,SAAS,CAAC;YACpB,IAAM,SAAS,GACX,aAAa,GAAG,CAAC,CAAC;gBACd,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;gBACvD,CAAC,CAAC,SAAS,CAAC;YACpB,IACI,wBAAwB,CAAC,IAAI,CAAC;gBAC9B,CAAC,CAAC,aAAa,IAAI,mBAAmB,CAAC,aAAa,CAAC,CAAC;gBACtD,SAAS;gBACT,YAAY,CAAC,SAAS,CAAC,EACzB;gBACE,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC;aACjC;SACJ;KACJ;AACL,CAAC,CAAC","sourcesContent":["import {\n getClosestAncestorBlockGroupIndex,\n hasSelectionInBlock,\n hasSelectionInBlockGroup,\n mutateBlock,\n} from 'roosterjs-content-model-dom';\nimport type {\n DeleteSelectionContext,\n DeleteSelectionStep,\n ReadonlyContentModelBlock,\n} from 'roosterjs-content-model-types';\n\nfunction isEmptyBlock(block: ReadonlyContentModelBlock | undefined): boolean {\n if (block && block.blockType == 'Paragraph') {\n return block.segments.every(\n segment => segment.segmentType !== 'SelectionMarker' && segment.segmentType == 'Br'\n );\n }\n\n if (block && block.blockType == 'BlockGroup') {\n return block.blocks.every(isEmptyBlock);\n }\n\n return !!block;\n}\n\n/**\n * @internal\n * If the first item o the list is selected in a expanded selection, we need to remove the list item levels\n * @param context A context object provided by formatContentModel API\n */\nexport const deleteEmptyList: DeleteSelectionStep = (context: DeleteSelectionContext) => {\n const { insertPoint, deleteResult } = context;\n if (deleteResult == 'range' && insertPoint?.path) {\n const index = getClosestAncestorBlockGroupIndex(\n insertPoint.path,\n ['ListItem'],\n ['TableCell']\n );\n const item = insertPoint.path[index];\n if (index >= 0 && item && item.blockGroupType == 'ListItem') {\n const listItemIndex = insertPoint.path[index + 1].blocks.indexOf(item);\n const previousBlock =\n listItemIndex > -1\n ? insertPoint.path[index + 1].blocks[listItemIndex - 1]\n : undefined;\n const nextBlock =\n listItemIndex > -1\n ? insertPoint.path[index + 1].blocks[listItemIndex + 1]\n : undefined;\n if (\n hasSelectionInBlockGroup(item) &&\n (!previousBlock || hasSelectionInBlock(previousBlock)) &&\n nextBlock &&\n isEmptyBlock(nextBlock)\n ) {\n mutateBlock(item).levels = [];\n }\n }\n }\n};\n"]}
@@ -71,6 +71,12 @@ var DOMHelperImpl = /** @class */ (function () {
71
71
  var paddingRight = parseValueWithUnit(style === null || style === void 0 ? void 0 : style.paddingRight);
72
72
  return this.contentDiv.clientWidth - (paddingLeft + paddingRight);
73
73
  };
74
+ /**
75
+ * Get a deep cloned root element
76
+ */
77
+ DOMHelperImpl.prototype.getClonedRoot = function () {
78
+ return this.contentDiv.cloneNode(true /*deep*/);
79
+ };
74
80
  return DOMHelperImpl;
75
81
  }());
76
82
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"DOMHelperImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/editor/core/DOMHelperImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import { isNodeOfType, parseValueWithUnit, toArray } from 'roosterjs-content-model-dom';\nimport type { DOMHelper } from 'roosterjs-content-model-types';\n\nclass DOMHelperImpl implements DOMHelper {\n constructor(private contentDiv: HTMLElement) {}\n\n queryElements(selector: string): HTMLElement[] {\n return toArray(this.contentDiv.querySelectorAll(selector)) as HTMLElement[];\n }\n\n getTextContent(): string {\n return this.contentDiv.textContent || '';\n }\n\n isNodeInEditor(node: Node, excludeRoot?: boolean): boolean {\n return excludeRoot && node == this.contentDiv ? false : this.contentDiv.contains(node);\n }\n\n calculateZoomScale(): number {\n const originalWidth = this.contentDiv.getBoundingClientRect()?.width || 0;\n const visualWidth = this.contentDiv.offsetWidth;\n\n return visualWidth > 0 && originalWidth > 0\n ? Math.round((originalWidth / visualWidth) * 100) / 100\n : 1;\n }\n\n setDomAttribute(name: string, value: string | null) {\n if (value === null) {\n this.contentDiv.removeAttribute(name);\n } else {\n this.contentDiv.setAttribute(name, value);\n }\n }\n\n getDomAttribute(name: string): string | null {\n return this.contentDiv.getAttribute(name);\n }\n\n getDomStyle<T extends keyof CSSStyleDeclaration>(style: T): CSSStyleDeclaration[T] {\n return this.contentDiv.style[style];\n }\n\n findClosestElementAncestor(startFrom: Node, selector?: string): HTMLElement | null {\n const startElement = isNodeOfType(startFrom, 'ELEMENT_NODE')\n ? startFrom\n : startFrom.parentElement;\n const closestElement = selector\n ? (startElement?.closest(selector) as HTMLElement | null)\n : startElement;\n\n return closestElement &&\n this.isNodeInEditor(closestElement) &&\n closestElement != this.contentDiv\n ? closestElement\n : null;\n }\n\n hasFocus(): boolean {\n const activeElement = this.contentDiv.ownerDocument.activeElement;\n return !!(activeElement && this.contentDiv.contains(activeElement));\n }\n\n /**\n * Check if the root element is in RTL mode\n */\n isRightToLeft(): boolean {\n const contentDiv = this.contentDiv;\n const style = contentDiv.ownerDocument.defaultView?.getComputedStyle(contentDiv);\n\n return style?.direction == 'rtl';\n }\n\n /**\n * Get the width of the editable area of the editor content div\n */\n getClientWidth(): number {\n const contentDiv = this.contentDiv;\n const style = contentDiv.ownerDocument.defaultView?.getComputedStyle(contentDiv);\n const paddingLeft = parseValueWithUnit(style?.paddingLeft);\n const paddingRight = parseValueWithUnit(style?.paddingRight);\n return this.contentDiv.clientWidth - (paddingLeft + paddingRight);\n }\n}\n\n/**\n * @internal Create new instance of DOMHelper\n */\nexport function createDOMHelper(contentDiv: HTMLElement): DOMHelper {\n return new DOMHelperImpl(contentDiv);\n}\n"]}
1
+ {"version":3,"file":"DOMHelperImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/editor/core/DOMHelperImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import { isNodeOfType, parseValueWithUnit, toArray } from 'roosterjs-content-model-dom';\nimport type { DOMHelper } from 'roosterjs-content-model-types';\n\nclass DOMHelperImpl implements DOMHelper {\n constructor(private contentDiv: HTMLElement) {}\n\n queryElements(selector: string): HTMLElement[] {\n return toArray(this.contentDiv.querySelectorAll(selector)) as HTMLElement[];\n }\n\n getTextContent(): string {\n return this.contentDiv.textContent || '';\n }\n\n isNodeInEditor(node: Node, excludeRoot?: boolean): boolean {\n return excludeRoot && node == this.contentDiv ? false : this.contentDiv.contains(node);\n }\n\n calculateZoomScale(): number {\n const originalWidth = this.contentDiv.getBoundingClientRect()?.width || 0;\n const visualWidth = this.contentDiv.offsetWidth;\n\n return visualWidth > 0 && originalWidth > 0\n ? Math.round((originalWidth / visualWidth) * 100) / 100\n : 1;\n }\n\n setDomAttribute(name: string, value: string | null) {\n if (value === null) {\n this.contentDiv.removeAttribute(name);\n } else {\n this.contentDiv.setAttribute(name, value);\n }\n }\n\n getDomAttribute(name: string): string | null {\n return this.contentDiv.getAttribute(name);\n }\n\n getDomStyle<T extends keyof CSSStyleDeclaration>(style: T): CSSStyleDeclaration[T] {\n return this.contentDiv.style[style];\n }\n\n findClosestElementAncestor(startFrom: Node, selector?: string): HTMLElement | null {\n const startElement = isNodeOfType(startFrom, 'ELEMENT_NODE')\n ? startFrom\n : startFrom.parentElement;\n const closestElement = selector\n ? (startElement?.closest(selector) as HTMLElement | null)\n : startElement;\n\n return closestElement &&\n this.isNodeInEditor(closestElement) &&\n closestElement != this.contentDiv\n ? closestElement\n : null;\n }\n\n hasFocus(): boolean {\n const activeElement = this.contentDiv.ownerDocument.activeElement;\n return !!(activeElement && this.contentDiv.contains(activeElement));\n }\n\n /**\n * Check if the root element is in RTL mode\n */\n isRightToLeft(): boolean {\n const contentDiv = this.contentDiv;\n const style = contentDiv.ownerDocument.defaultView?.getComputedStyle(contentDiv);\n\n return style?.direction == 'rtl';\n }\n\n /**\n * Get the width of the editable area of the editor content div\n */\n getClientWidth(): number {\n const contentDiv = this.contentDiv;\n const style = contentDiv.ownerDocument.defaultView?.getComputedStyle(contentDiv);\n const paddingLeft = parseValueWithUnit(style?.paddingLeft);\n const paddingRight = parseValueWithUnit(style?.paddingRight);\n return this.contentDiv.clientWidth - (paddingLeft + paddingRight);\n }\n\n /**\n * Get a deep cloned root element\n */\n getClonedRoot(): HTMLElement {\n return this.contentDiv.cloneNode(true /*deep*/) as HTMLElement;\n }\n}\n\n/**\n * @internal Create new instance of DOMHelper\n */\nexport function createDOMHelper(contentDiv: HTMLElement): DOMHelper {\n return new DOMHelperImpl(contentDiv);\n}\n"]}
package/package.json CHANGED
@@ -3,10 +3,10 @@
3
3
  "description": "Core editor for roosterjs",
4
4
  "dependencies": {
5
5
  "tslib": "^2.3.1",
6
- "roosterjs-content-model-dom": "^9.10.0",
7
- "roosterjs-content-model-types": "^9.10.0"
6
+ "roosterjs-content-model-dom": "^9.11.0",
7
+ "roosterjs-content-model-types": "^9.11.0"
8
8
  },
9
- "version": "9.10.0",
9
+ "version": "9.11.0",
10
10
  "main": "./lib/index.js",
11
11
  "typings": "./lib/index.d.ts",
12
12
  "module": "./lib-mjs/index.js",
@@ -1 +0,0 @@
1
- {"version":3,"file":"deleteEmptyList.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/deleteEmptyList.ts"],"names":[],"mappings":";;;AAAA,2EAKqC;AAOrC,SAAS,YAAY,CAAC,KAA4C;IAC9D,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,WAAW,EAAE;QACzC,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,CACvB,UAAA,OAAO,IAAI,OAAA,OAAO,CAAC,WAAW,KAAK,iBAAiB,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI,EAAxE,CAAwE,CACtF,CAAC;KACL;IAED,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,YAAY,EAAE;QAC1C,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;KAC3C;IAED,OAAO,CAAC,CAAC,KAAK,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACI,IAAM,eAAe,GAAwB,UAAC,OAA+B;IACxE,IAAA,WAAW,GAAmB,OAAO,YAA1B,EAAE,YAAY,GAAK,OAAO,aAAZ,CAAa;IAC9C,IAAI,YAAY,IAAI,OAAO,KAAI,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,IAAI,CAAA,EAAE;QAC9C,IAAM,KAAK,GAAG,IAAA,+DAAiC,EAC3C,WAAW,CAAC,IAAI,EAChB,CAAC,UAAU,CAAC,EACZ,CAAC,WAAW,CAAC,CAChB,CAAC;QACF,IAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,cAAc,IAAI,UAAU,EAAE;YACzD,IAAM,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACvE,IAAM,aAAa,GACf,aAAa,GAAG,CAAC,CAAC;gBACd,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;gBACvD,CAAC,CAAC,SAAS,CAAC;YACpB,IAAM,SAAS,GACX,aAAa,GAAG,CAAC,CAAC;gBACd,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;gBACvD,CAAC,CAAC,SAAS,CAAC;YACpB,IACI,IAAA,sDAAwB,EAAC,IAAI,CAAC;gBAC9B,CAAC,CAAC,aAAa,IAAI,IAAA,iDAAmB,EAAC,aAAa,CAAC,CAAC;gBACtD,SAAS;gBACT,YAAY,CAAC,SAAS,CAAC,EACzB;gBACE,IAAA,yCAAW,EAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC;aACjC;SACJ;KACJ;AACL,CAAC,CAAC;AA7BW,QAAA,eAAe,mBA6B1B","sourcesContent":["import {\n getClosestAncestorBlockGroupIndex,\n hasSelectionInBlock,\n hasSelectionInBlockGroup,\n mutateBlock,\n} from 'roosterjs-content-model-dom';\nimport type {\n DeleteSelectionContext,\n DeleteSelectionStep,\n ReadonlyContentModelBlock,\n} from 'roosterjs-content-model-types';\n\nfunction isEmptyBlock(block: ReadonlyContentModelBlock | undefined): boolean {\n if (block && block.blockType == 'Paragraph') {\n return block.segments.every(\n segment => segment.segmentType !== 'SelectionMarker' && segment.segmentType == 'Br'\n );\n }\n\n if (block && block.blockType == 'BlockGroup') {\n return block.blocks.every(isEmptyBlock);\n }\n\n return !!block;\n}\n\n/**\n * @internal\n * If the first item o the list is selected in a expanded selection, we need to remove the list item levels\n * @param context A context object provided by formatContentModel API\n */\nexport const deleteEmptyList: DeleteSelectionStep = (context: DeleteSelectionContext) => {\n const { insertPoint, deleteResult } = context;\n if (deleteResult == 'range' && insertPoint?.path) {\n const index = getClosestAncestorBlockGroupIndex(\n insertPoint.path,\n ['ListItem'],\n ['TableCell']\n );\n const item = insertPoint.path[index];\n if (index >= 0 && item && item.blockGroupType == 'ListItem') {\n const listItemIndex = insertPoint.path[index + 1].blocks.indexOf(item);\n const previousBlock =\n listItemIndex > -1\n ? insertPoint.path[index + 1].blocks[listItemIndex - 1]\n : undefined;\n const nextBlock =\n listItemIndex > -1\n ? insertPoint.path[index + 1].blocks[listItemIndex + 1]\n : undefined;\n if (\n hasSelectionInBlockGroup(item) &&\n (!previousBlock || hasSelectionInBlock(previousBlock)) &&\n nextBlock &&\n isEmptyBlock(nextBlock)\n ) {\n mutateBlock(item).levels = [];\n }\n }\n }\n};\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"deleteEmptyList.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/deleteEmptyList.ts"],"names":[],"mappings":";;;;IAYA,SAAS,YAAY,CAAC,KAA4C;QAC9D,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,WAAW,EAAE;YACzC,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,CACvB,UAAA,OAAO,IAAI,OAAA,OAAO,CAAC,WAAW,KAAK,iBAAiB,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI,EAAxE,CAAwE,CACtF,CAAC;SACL;QAED,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,YAAY,EAAE;YAC1C,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;SAC3C;QAED,OAAO,CAAC,CAAC,KAAK,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACI,IAAM,eAAe,GAAwB,UAAC,OAA+B;QACxE,IAAA,WAAW,GAAmB,OAAO,YAA1B,EAAE,YAAY,GAAK,OAAO,aAAZ,CAAa;QAC9C,IAAI,YAAY,IAAI,OAAO,KAAI,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,IAAI,CAAA,EAAE;YAC9C,IAAM,KAAK,GAAG,IAAA,+DAAiC,EAC3C,WAAW,CAAC,IAAI,EAChB,CAAC,UAAU,CAAC,EACZ,CAAC,WAAW,CAAC,CAChB,CAAC;YACF,IAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,cAAc,IAAI,UAAU,EAAE;gBACzD,IAAM,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACvE,IAAM,aAAa,GACf,aAAa,GAAG,CAAC,CAAC;oBACd,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;oBACvD,CAAC,CAAC,SAAS,CAAC;gBACpB,IAAM,SAAS,GACX,aAAa,GAAG,CAAC,CAAC;oBACd,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;oBACvD,CAAC,CAAC,SAAS,CAAC;gBACpB,IACI,IAAA,sDAAwB,EAAC,IAAI,CAAC;oBAC9B,CAAC,CAAC,aAAa,IAAI,IAAA,iDAAmB,EAAC,aAAa,CAAC,CAAC;oBACtD,SAAS;oBACT,YAAY,CAAC,SAAS,CAAC,EACzB;oBACE,IAAA,yCAAW,EAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC;iBACjC;aACJ;SACJ;IACL,CAAC,CAAC;IA7BW,QAAA,eAAe,mBA6B1B","sourcesContent":["import {\n getClosestAncestorBlockGroupIndex,\n hasSelectionInBlock,\n hasSelectionInBlockGroup,\n mutateBlock,\n} from 'roosterjs-content-model-dom';\nimport type {\n DeleteSelectionContext,\n DeleteSelectionStep,\n ReadonlyContentModelBlock,\n} from 'roosterjs-content-model-types';\n\nfunction isEmptyBlock(block: ReadonlyContentModelBlock | undefined): boolean {\n if (block && block.blockType == 'Paragraph') {\n return block.segments.every(\n segment => segment.segmentType !== 'SelectionMarker' && segment.segmentType == 'Br'\n );\n }\n\n if (block && block.blockType == 'BlockGroup') {\n return block.blocks.every(isEmptyBlock);\n }\n\n return !!block;\n}\n\n/**\n * @internal\n * If the first item o the list is selected in a expanded selection, we need to remove the list item levels\n * @param context A context object provided by formatContentModel API\n */\nexport const deleteEmptyList: DeleteSelectionStep = (context: DeleteSelectionContext) => {\n const { insertPoint, deleteResult } = context;\n if (deleteResult == 'range' && insertPoint?.path) {\n const index = getClosestAncestorBlockGroupIndex(\n insertPoint.path,\n ['ListItem'],\n ['TableCell']\n );\n const item = insertPoint.path[index];\n if (index >= 0 && item && item.blockGroupType == 'ListItem') {\n const listItemIndex = insertPoint.path[index + 1].blocks.indexOf(item);\n const previousBlock =\n listItemIndex > -1\n ? insertPoint.path[index + 1].blocks[listItemIndex - 1]\n : undefined;\n const nextBlock =\n listItemIndex > -1\n ? insertPoint.path[index + 1].blocks[listItemIndex + 1]\n : undefined;\n if (\n hasSelectionInBlockGroup(item) &&\n (!previousBlock || hasSelectionInBlock(previousBlock)) &&\n nextBlock &&\n isEmptyBlock(nextBlock)\n ) {\n mutateBlock(item).levels = [];\n }\n }\n }\n};\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"deleteEmptyList.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/deleteEmptyList.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,iCAAiC,EACjC,mBAAmB,EACnB,wBAAwB,EACxB,WAAW,GACd,MAAM,6BAA6B,CAAC;AAOrC,SAAS,YAAY,CAAC,KAA4C;IAC9D,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,WAAW,EAAE;QACzC,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,CACvB,UAAA,OAAO,IAAI,OAAA,OAAO,CAAC,WAAW,KAAK,iBAAiB,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI,EAAxE,CAAwE,CACtF,CAAC;KACL;IAED,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,YAAY,EAAE;QAC1C,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;KAC3C;IAED,OAAO,CAAC,CAAC,KAAK,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,IAAM,eAAe,GAAwB,UAAC,OAA+B;IACxE,IAAA,WAAW,GAAmB,OAAO,YAA1B,EAAE,YAAY,GAAK,OAAO,aAAZ,CAAa;IAC9C,IAAI,YAAY,IAAI,OAAO,KAAI,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,IAAI,CAAA,EAAE;QAC9C,IAAM,KAAK,GAAG,iCAAiC,CAC3C,WAAW,CAAC,IAAI,EAChB,CAAC,UAAU,CAAC,EACZ,CAAC,WAAW,CAAC,CAChB,CAAC;QACF,IAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,cAAc,IAAI,UAAU,EAAE;YACzD,IAAM,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACvE,IAAM,aAAa,GACf,aAAa,GAAG,CAAC,CAAC;gBACd,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;gBACvD,CAAC,CAAC,SAAS,CAAC;YACpB,IAAM,SAAS,GACX,aAAa,GAAG,CAAC,CAAC;gBACd,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;gBACvD,CAAC,CAAC,SAAS,CAAC;YACpB,IACI,wBAAwB,CAAC,IAAI,CAAC;gBAC9B,CAAC,CAAC,aAAa,IAAI,mBAAmB,CAAC,aAAa,CAAC,CAAC;gBACtD,SAAS;gBACT,YAAY,CAAC,SAAS,CAAC,EACzB;gBACE,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC;aACjC;SACJ;KACJ;AACL,CAAC,CAAC","sourcesContent":["import {\n getClosestAncestorBlockGroupIndex,\n hasSelectionInBlock,\n hasSelectionInBlockGroup,\n mutateBlock,\n} from 'roosterjs-content-model-dom';\nimport type {\n DeleteSelectionContext,\n DeleteSelectionStep,\n ReadonlyContentModelBlock,\n} from 'roosterjs-content-model-types';\n\nfunction isEmptyBlock(block: ReadonlyContentModelBlock | undefined): boolean {\n if (block && block.blockType == 'Paragraph') {\n return block.segments.every(\n segment => segment.segmentType !== 'SelectionMarker' && segment.segmentType == 'Br'\n );\n }\n\n if (block && block.blockType == 'BlockGroup') {\n return block.blocks.every(isEmptyBlock);\n }\n\n return !!block;\n}\n\n/**\n * @internal\n * If the first item o the list is selected in a expanded selection, we need to remove the list item levels\n * @param context A context object provided by formatContentModel API\n */\nexport const deleteEmptyList: DeleteSelectionStep = (context: DeleteSelectionContext) => {\n const { insertPoint, deleteResult } = context;\n if (deleteResult == 'range' && insertPoint?.path) {\n const index = getClosestAncestorBlockGroupIndex(\n insertPoint.path,\n ['ListItem'],\n ['TableCell']\n );\n const item = insertPoint.path[index];\n if (index >= 0 && item && item.blockGroupType == 'ListItem') {\n const listItemIndex = insertPoint.path[index + 1].blocks.indexOf(item);\n const previousBlock =\n listItemIndex > -1\n ? insertPoint.path[index + 1].blocks[listItemIndex - 1]\n : undefined;\n const nextBlock =\n listItemIndex > -1\n ? insertPoint.path[index + 1].blocks[listItemIndex + 1]\n : undefined;\n if (\n hasSelectionInBlockGroup(item) &&\n (!previousBlock || hasSelectionInBlock(previousBlock)) &&\n nextBlock &&\n isEmptyBlock(nextBlock)\n ) {\n mutateBlock(item).levels = [];\n }\n }\n }\n};\n"]}