roosterjs-content-model-core 9.39.0 → 9.41.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 (113) hide show
  1. package/lib/command/cutCopy/adjustImageSelectionOnSafari.js.map +1 -0
  2. package/lib/command/cutCopy/adjustSelectionForCopyCut.d.ts +5 -0
  3. package/lib/command/cutCopy/adjustSelectionForCopyCut.js +29 -0
  4. package/lib/command/cutCopy/adjustSelectionForCopyCut.js.map +1 -0
  5. package/lib/command/cutCopy/getContentForCopy.d.ts +14 -0
  6. package/lib/command/cutCopy/getContentForCopy.js +89 -0
  7. package/lib/command/cutCopy/getContentForCopy.js.map +1 -0
  8. package/lib/command/cutCopy/preprocessTable.d.ts +5 -0
  9. package/lib/command/cutCopy/preprocessTable.js +22 -0
  10. package/lib/command/cutCopy/preprocessTable.js.map +1 -0
  11. package/lib/command/cutCopy/pruneUnselectedModel.js.map +1 -0
  12. package/lib/coreApi/formatContentModel/scrollCaretIntoView.js +1 -8
  13. package/lib/coreApi/formatContentModel/scrollCaretIntoView.js.map +1 -1
  14. package/lib/coreApi/setDOMSelection/setDOMSelection.js +1 -0
  15. package/lib/coreApi/setDOMSelection/setDOMSelection.js.map +1 -1
  16. package/lib/corePlugin/cache/CachePlugin.js +0 -1
  17. package/lib/corePlugin/cache/CachePlugin.js.map +1 -1
  18. package/lib/corePlugin/cache/domIndexerImpl.d.ts +1 -2
  19. package/lib/corePlugin/cache/domIndexerImpl.js +1 -8
  20. package/lib/corePlugin/cache/domIndexerImpl.js.map +1 -1
  21. package/lib/corePlugin/contextMenu/ContextMenuPlugin.js +5 -5
  22. package/lib/corePlugin/contextMenu/ContextMenuPlugin.js.map +1 -1
  23. package/lib/corePlugin/copyPaste/CopyPastePlugin.d.ts +1 -16
  24. package/lib/corePlugin/copyPaste/CopyPastePlugin.js +19 -179
  25. package/lib/corePlugin/copyPaste/CopyPastePlugin.js.map +1 -1
  26. package/lib/corePlugin/selection/SelectionPlugin.js +1 -0
  27. package/lib/corePlugin/selection/SelectionPlugin.js.map +1 -1
  28. package/lib/editor/core/DOMHelperImpl.js +26 -0
  29. package/lib/editor/core/DOMHelperImpl.js.map +1 -1
  30. package/lib/index.d.ts +1 -0
  31. package/lib/index.js +4 -1
  32. package/lib/index.js.map +1 -1
  33. package/{lib-mjs/corePlugin/copyPaste/utils → lib-amd/command/cutCopy}/adjustImageSelectionOnSafari.js.map +1 -1
  34. package/lib-amd/command/cutCopy/adjustSelectionForCopyCut.d.ts +5 -0
  35. package/lib-amd/command/cutCopy/adjustSelectionForCopyCut.js +30 -0
  36. package/lib-amd/command/cutCopy/adjustSelectionForCopyCut.js.map +1 -0
  37. package/lib-amd/command/cutCopy/getContentForCopy.d.ts +14 -0
  38. package/lib-amd/command/cutCopy/getContentForCopy.js +85 -0
  39. package/lib-amd/command/cutCopy/getContentForCopy.js.map +1 -0
  40. package/lib-amd/command/cutCopy/preprocessTable.d.ts +5 -0
  41. package/lib-amd/command/cutCopy/preprocessTable.js +22 -0
  42. package/lib-amd/command/cutCopy/preprocessTable.js.map +1 -0
  43. package/{lib/corePlugin/copyPaste/utils → lib-amd/command/cutCopy}/pruneUnselectedModel.js.map +1 -1
  44. package/lib-amd/coreApi/formatContentModel/scrollCaretIntoView.js +1 -8
  45. package/lib-amd/coreApi/formatContentModel/scrollCaretIntoView.js.map +1 -1
  46. package/lib-amd/coreApi/setDOMSelection/setDOMSelection.js +1 -0
  47. package/lib-amd/coreApi/setDOMSelection/setDOMSelection.js.map +1 -1
  48. package/lib-amd/corePlugin/cache/CachePlugin.js +0 -1
  49. package/lib-amd/corePlugin/cache/CachePlugin.js.map +1 -1
  50. package/lib-amd/corePlugin/cache/domIndexerImpl.d.ts +1 -2
  51. package/lib-amd/corePlugin/cache/domIndexerImpl.js +1 -8
  52. package/lib-amd/corePlugin/cache/domIndexerImpl.js.map +1 -1
  53. package/lib-amd/corePlugin/contextMenu/ContextMenuPlugin.js +5 -5
  54. package/lib-amd/corePlugin/contextMenu/ContextMenuPlugin.js.map +1 -1
  55. package/lib-amd/corePlugin/copyPaste/CopyPastePlugin.d.ts +1 -16
  56. package/lib-amd/corePlugin/copyPaste/CopyPastePlugin.js +19 -175
  57. package/lib-amd/corePlugin/copyPaste/CopyPastePlugin.js.map +1 -1
  58. package/lib-amd/corePlugin/selection/SelectionPlugin.js +1 -0
  59. package/lib-amd/corePlugin/selection/SelectionPlugin.js.map +1 -1
  60. package/lib-amd/editor/core/DOMHelperImpl.js +26 -0
  61. package/lib-amd/editor/core/DOMHelperImpl.js.map +1 -1
  62. package/lib-amd/index.d.ts +1 -0
  63. package/lib-amd/index.js +3 -2
  64. package/lib-amd/index.js.map +1 -1
  65. package/lib-mjs/command/cutCopy/adjustImageSelectionOnSafari.js.map +1 -0
  66. package/lib-mjs/command/cutCopy/adjustSelectionForCopyCut.d.ts +5 -0
  67. package/lib-mjs/command/cutCopy/adjustSelectionForCopyCut.js +25 -0
  68. package/lib-mjs/command/cutCopy/adjustSelectionForCopyCut.js.map +1 -0
  69. package/lib-mjs/command/cutCopy/getContentForCopy.d.ts +14 -0
  70. package/lib-mjs/command/cutCopy/getContentForCopy.js +84 -0
  71. package/lib-mjs/command/cutCopy/getContentForCopy.js.map +1 -0
  72. package/lib-mjs/command/cutCopy/preprocessTable.d.ts +5 -0
  73. package/lib-mjs/command/cutCopy/preprocessTable.js +18 -0
  74. package/lib-mjs/command/cutCopy/preprocessTable.js.map +1 -0
  75. package/lib-mjs/command/cutCopy/pruneUnselectedModel.js.map +1 -0
  76. package/lib-mjs/coreApi/formatContentModel/scrollCaretIntoView.js +2 -9
  77. package/lib-mjs/coreApi/formatContentModel/scrollCaretIntoView.js.map +1 -1
  78. package/lib-mjs/coreApi/setDOMSelection/setDOMSelection.js +1 -0
  79. package/lib-mjs/coreApi/setDOMSelection/setDOMSelection.js.map +1 -1
  80. package/lib-mjs/corePlugin/cache/CachePlugin.js +0 -1
  81. package/lib-mjs/corePlugin/cache/CachePlugin.js.map +1 -1
  82. package/lib-mjs/corePlugin/cache/domIndexerImpl.d.ts +1 -2
  83. package/lib-mjs/corePlugin/cache/domIndexerImpl.js +1 -8
  84. package/lib-mjs/corePlugin/cache/domIndexerImpl.js.map +1 -1
  85. package/lib-mjs/corePlugin/contextMenu/ContextMenuPlugin.js +5 -5
  86. package/lib-mjs/corePlugin/contextMenu/ContextMenuPlugin.js.map +1 -1
  87. package/lib-mjs/corePlugin/copyPaste/CopyPastePlugin.d.ts +1 -16
  88. package/lib-mjs/corePlugin/copyPaste/CopyPastePlugin.js +19 -176
  89. package/lib-mjs/corePlugin/copyPaste/CopyPastePlugin.js.map +1 -1
  90. package/lib-mjs/corePlugin/selection/SelectionPlugin.js +1 -0
  91. package/lib-mjs/corePlugin/selection/SelectionPlugin.js.map +1 -1
  92. package/lib-mjs/editor/core/DOMHelperImpl.js +27 -1
  93. package/lib-mjs/editor/core/DOMHelperImpl.js.map +1 -1
  94. package/lib-mjs/index.d.ts +1 -0
  95. package/lib-mjs/index.js +2 -0
  96. package/lib-mjs/index.js.map +1 -1
  97. package/package.json +3 -3
  98. package/lib/corePlugin/copyPaste/utils/adjustImageSelectionOnSafari.js.map +0 -1
  99. package/lib-amd/corePlugin/copyPaste/utils/adjustImageSelectionOnSafari.js.map +0 -1
  100. package/lib-amd/corePlugin/copyPaste/utils/pruneUnselectedModel.js.map +0 -1
  101. package/lib-mjs/corePlugin/copyPaste/utils/pruneUnselectedModel.js.map +0 -1
  102. /package/lib/{corePlugin/copyPaste/utils → command/cutCopy}/adjustImageSelectionOnSafari.d.ts +0 -0
  103. /package/lib/{corePlugin/copyPaste/utils → command/cutCopy}/adjustImageSelectionOnSafari.js +0 -0
  104. /package/lib/{corePlugin/copyPaste/utils → command/cutCopy}/pruneUnselectedModel.d.ts +0 -0
  105. /package/lib/{corePlugin/copyPaste/utils → command/cutCopy}/pruneUnselectedModel.js +0 -0
  106. /package/lib-amd/{corePlugin/copyPaste/utils → command/cutCopy}/adjustImageSelectionOnSafari.d.ts +0 -0
  107. /package/lib-amd/{corePlugin/copyPaste/utils → command/cutCopy}/adjustImageSelectionOnSafari.js +0 -0
  108. /package/lib-amd/{corePlugin/copyPaste/utils → command/cutCopy}/pruneUnselectedModel.d.ts +0 -0
  109. /package/lib-amd/{corePlugin/copyPaste/utils → command/cutCopy}/pruneUnselectedModel.js +0 -0
  110. /package/lib-mjs/{corePlugin/copyPaste/utils → command/cutCopy}/adjustImageSelectionOnSafari.d.ts +0 -0
  111. /package/lib-mjs/{corePlugin/copyPaste/utils → command/cutCopy}/adjustImageSelectionOnSafari.js +0 -0
  112. /package/lib-mjs/{corePlugin/copyPaste/utils → command/cutCopy}/pruneUnselectedModel.d.ts +0 -0
  113. /package/lib-mjs/{corePlugin/copyPaste/utils → command/cutCopy}/pruneUnselectedModel.js +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adjustImageSelectionOnSafari.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/cutCopy/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,5 @@
1
+ import type { ContentModelDocument } from 'roosterjs-content-model-types';
2
+ /**
3
+ * @internal
4
+ */
5
+ export declare function adjustSelectionForCopyCut(pasteModel: ContentModelDocument): void;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.adjustSelectionForCopyCut = void 0;
4
+ var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
5
+ /**
6
+ * @internal
7
+ */
8
+ function adjustSelectionForCopyCut(pasteModel) {
9
+ var selectionMarker;
10
+ var firstBlock;
11
+ var tableContext;
12
+ (0, roosterjs_content_model_dom_1.iterateSelections)(pasteModel, function (_, tableCtxt, block, segments) {
13
+ if (selectionMarker) {
14
+ if (tableCtxt != tableContext && (firstBlock === null || firstBlock === void 0 ? void 0 : firstBlock.segments.includes(selectionMarker))) {
15
+ firstBlock.segments.splice(firstBlock.segments.indexOf(selectionMarker), 1);
16
+ }
17
+ return true;
18
+ }
19
+ var marker = segments === null || segments === void 0 ? void 0 : segments.find(function (segment) { return segment.segmentType == 'SelectionMarker'; });
20
+ if (!selectionMarker && marker) {
21
+ tableContext = tableCtxt;
22
+ firstBlock = (block === null || block === void 0 ? void 0 : block.blockType) == 'Paragraph' ? block : undefined;
23
+ selectionMarker = marker;
24
+ }
25
+ return false;
26
+ });
27
+ }
28
+ exports.adjustSelectionForCopyCut = adjustSelectionForCopyCut;
29
+ //# sourceMappingURL=adjustSelectionForCopyCut.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adjustSelectionForCopyCut.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/cutCopy/adjustSelectionForCopyCut.ts"],"names":[],"mappings":";;;AAAA,2EAAgE;AAQhE;;GAEG;AACH,SAAgB,yBAAyB,CAAC,UAAgC;IACtE,IAAI,eAAgD,CAAC;IACrD,IAAI,UAA6C,CAAC;IAClD,IAAI,YAAuD,CAAC;IAE5D,IAAA,+CAAiB,EAAC,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;AAtBD,8DAsBC","sourcesContent":["import { iterateSelections } from 'roosterjs-content-model-dom';\nimport type {\n ContentModelDocument,\n ContentModelParagraph,\n ContentModelSegment,\n ReadonlyTableSelectionContext,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\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"]}
@@ -0,0 +1,14 @@
1
+ import type { IEditor, OnNodeCreated, TextAndHtmlContentForCopy } from 'roosterjs-content-model-types';
2
+ /**
3
+ * @internal
4
+ * Exported only for unit testing
5
+ */
6
+ export declare const onNodeCreated: OnNodeCreated;
7
+ /**
8
+ * Get the content for the copy event
9
+ * @param editor The editor object
10
+ * @param isCut if the event cut the content.
11
+ * @param event the clipboard event that triggered the copy/cut
12
+ * @returns
13
+ */
14
+ export declare function getContentForCopy(editor: IEditor, isCut: boolean, event: ClipboardEvent): TextAndHtmlContentForCopy | null;
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getContentForCopy = exports.onNodeCreated = void 0;
4
+ var adjustImageSelectionOnSafari_1 = require("./adjustImageSelectionOnSafari");
5
+ var adjustSelectionForCopyCut_1 = require("./adjustSelectionForCopyCut");
6
+ var pasteCopyBlockEntityParser_1 = require("../../override/pasteCopyBlockEntityParser");
7
+ var preprocessTable_1 = require("./preprocessTable");
8
+ var pruneUnselectedModel_1 = require("./pruneUnselectedModel");
9
+ var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
10
+ /**
11
+ * @internal
12
+ * Exported only for unit testing
13
+ */
14
+ var onNodeCreated = function (modelElement, node) {
15
+ if ((0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'ELEMENT_NODE') && (0, roosterjs_content_model_dom_1.isElementOfType)(node, 'table')) {
16
+ (0, roosterjs_content_model_dom_1.wrap)(node.ownerDocument, node, 'div');
17
+ }
18
+ if ((0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'ELEMENT_NODE') && !node.isContentEditable) {
19
+ node.removeAttribute('contenteditable');
20
+ }
21
+ (0, pasteCopyBlockEntityParser_1.onCreateCopyEntityNode)(modelElement, node);
22
+ };
23
+ exports.onNodeCreated = onNodeCreated;
24
+ /**
25
+ * Get the content for the copy event
26
+ * @param editor The editor object
27
+ * @param isCut if the event cut the content.
28
+ * @param event the clipboard event that triggered the copy/cut
29
+ * @returns
30
+ */
31
+ function getContentForCopy(editor, isCut, event) {
32
+ var selection = editor.getDOMSelection();
33
+ (0, adjustImageSelectionOnSafari_1.adjustImageSelectionOnSafari)(editor, selection);
34
+ if (selection && (selection.type != 'range' || !selection.range.collapsed)) {
35
+ var pasteModel = editor.getContentModelCopy('disconnected');
36
+ (0, pruneUnselectedModel_1.pruneUnselectedModel)(pasteModel);
37
+ if (selection.type === 'table') {
38
+ (0, roosterjs_content_model_dom_1.iterateSelections)(pasteModel, function (_, tableContext) {
39
+ if (tableContext === null || tableContext === void 0 ? void 0 : tableContext.table) {
40
+ (0, preprocessTable_1.preprocessTable)(tableContext.table);
41
+ return true;
42
+ }
43
+ return false;
44
+ });
45
+ }
46
+ else if (selection.type === 'range') {
47
+ (0, adjustSelectionForCopyCut_1.adjustSelectionForCopyCut)(pasteModel);
48
+ }
49
+ var context = (0, roosterjs_content_model_dom_1.createModelToDomContext)();
50
+ context.onNodeCreated = exports.onNodeCreated;
51
+ var doc = editor.getDocument();
52
+ var tempDiv = doc.createElement('div');
53
+ var selectionForCopy = (0, roosterjs_content_model_dom_1.contentModelToDom)(doc, tempDiv, pasteModel, context);
54
+ var newRange = selectionForCopy ? domSelectionToRange(doc, selectionForCopy) : null;
55
+ if (newRange) {
56
+ var clonedRoot = editor.triggerEvent('beforeCutCopy', {
57
+ clonedRoot: tempDiv,
58
+ range: newRange,
59
+ rawEvent: event,
60
+ isCut: isCut,
61
+ }).clonedRoot;
62
+ return {
63
+ htmlContent: clonedRoot,
64
+ textContent: (0, roosterjs_content_model_dom_1.contentModelToText)(pasteModel),
65
+ };
66
+ }
67
+ }
68
+ return null;
69
+ }
70
+ exports.getContentForCopy = getContentForCopy;
71
+ function domSelectionToRange(doc, selection) {
72
+ var _a;
73
+ var newRange = null;
74
+ if (selection.type === 'table') {
75
+ var table = selection.table;
76
+ var elementToSelect = ((_a = table.parentElement) === null || _a === void 0 ? void 0 : _a.childElementCount) == 1 ? table.parentElement : table;
77
+ newRange = doc.createRange();
78
+ newRange.selectNode(elementToSelect);
79
+ }
80
+ else if (selection.type === 'image') {
81
+ newRange = doc.createRange();
82
+ newRange.selectNode(selection.image);
83
+ }
84
+ else {
85
+ newRange = selection.range;
86
+ }
87
+ return newRange;
88
+ }
89
+ //# sourceMappingURL=getContentForCopy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getContentForCopy.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/cutCopy/getContentForCopy.ts"],"names":[],"mappings":"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","sourcesContent":["import { adjustImageSelectionOnSafari } from './adjustImageSelectionOnSafari';\nimport { adjustSelectionForCopyCut } from './adjustSelectionForCopyCut';\nimport { onCreateCopyEntityNode } from '../../override/pasteCopyBlockEntityParser';\nimport { preprocessTable } from './preprocessTable';\nimport { pruneUnselectedModel } from './pruneUnselectedModel';\nimport type {\n DOMSelection,\n IEditor,\n OnNodeCreated,\n TextAndHtmlContentForCopy,\n} from 'roosterjs-content-model-types';\nimport {\n contentModelToDom,\n contentModelToText,\n createModelToDomContext,\n isElementOfType,\n isNodeOfType,\n iterateSelections,\n wrap,\n} from 'roosterjs-content-model-dom';\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 * Get the content for the copy event\n * @param editor The editor object\n * @param isCut if the event cut the content.\n * @param event the clipboard event that triggered the copy/cut\n * @returns\n */\nexport function getContentForCopy(\n editor: IEditor,\n isCut: boolean,\n event: ClipboardEvent\n): TextAndHtmlContentForCopy | null {\n const selection = editor.getDOMSelection();\n adjustImageSelectionOnSafari(editor, selection);\n if (selection && (selection.type != 'range' || !selection.range.collapsed)) {\n const pasteModel = editor.getContentModelCopy('disconnected');\n pruneUnselectedModel(pasteModel);\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 const context = createModelToDomContext();\n\n context.onNodeCreated = onNodeCreated;\n const doc = editor.getDocument();\n const tempDiv = doc.createElement('div');\n\n const selectionForCopy = contentModelToDom(doc, tempDiv, pasteModel, context);\n const newRange = selectionForCopy ? domSelectionToRange(doc, selectionForCopy) : null;\n if (newRange) {\n const { clonedRoot } = editor.triggerEvent('beforeCutCopy', {\n clonedRoot: tempDiv,\n range: newRange,\n rawEvent: event,\n isCut,\n });\n\n return {\n htmlContent: clonedRoot,\n textContent: contentModelToText(pasteModel),\n };\n }\n }\n return null;\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"]}
@@ -0,0 +1,5 @@
1
+ import type { ContentModelTable } from 'roosterjs-content-model-types';
2
+ /**
3
+ * @internal
4
+ */
5
+ export declare function preprocessTable(table: ContentModelTable): void;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.preprocessTable = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
6
+ /**
7
+ * @internal
8
+ */
9
+ function preprocessTable(table) {
10
+ var sel = (0, roosterjs_content_model_dom_1.getSelectedCells)(table);
11
+ table.rows = table.rows
12
+ .map(function (row) {
13
+ return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, row), { cells: row.cells.filter(function (cell) { return cell.isSelected; }) });
14
+ })
15
+ .filter(function (row) { return row.cells.length > 0; });
16
+ delete table.format.width;
17
+ table.widths = sel
18
+ ? table.widths.filter(function (_, index) { return index >= (sel === null || sel === void 0 ? void 0 : sel.firstColumn) && index <= (sel === null || sel === void 0 ? void 0 : sel.lastColumn); })
19
+ : [];
20
+ }
21
+ exports.preprocessTable = preprocessTable;
22
+ //# sourceMappingURL=preprocessTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preprocessTable.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/cutCopy/preprocessTable.ts"],"names":[],"mappings":";;;;AAAA,2EAA+D;AAG/D;;GAEG;AACH,SAAgB,eAAe,CAAC,KAAwB;IACpD,IAAM,GAAG,GAAG,IAAA,8CAAgB,EAAC,KAAK,CAAC,CAAC;IACpC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;SAClB,GAAG,CAAC,UAAA,GAAG;QACJ,uDACO,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;AAhBD,0CAgBC","sourcesContent":["import { getSelectedCells } from 'roosterjs-content-model-dom';\nimport type { ContentModelTable } from 'roosterjs-content-model-types';\n\n/**\n * @internal\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"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pruneUnselectedModel.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/cutCopy/pruneUnselectedModel.ts"],"names":[],"mappings":";;;;AASA;;GAEG;AACH,SAAgB,oBAAoB,CAChC,KAA0E;IAE1E,4BAA4B,CAAC,KAAK,EAAE,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAEzE,MAAM,CAAC,KAAK,CAAC,CAAC;AAClB,CAAC;AAND,oDAMC;AAED,SAAS,4BAA4B,CACjC,KAA0E,EAC1E,uBAAgC;;IAEhC,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE;QAC3D,IAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAElC,QAAQ,KAAK,CAAC,SAAS,EAAE;YACrB,KAAK,YAAY;gBACb,4BAA4B,CAAC,KAAK,EAAE,uBAAuB,CAAC,CAAC;gBAC7D,IACI,KAAK,CAAC,cAAc,IAAI,SAAS;oBAC7B,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU;oBAC/C,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,EAChC;oBACE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;iBACjC;gBACD,MAAM;YACV,KAAK,SAAS,CAAC;YACf,KAAK,QAAQ;gBACT,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE;oBACnB,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;iBACjC;qBAAM;oBACH,uBAAuB,GAAG,IAAI,CAAC;iBAClC;gBACD,MAAM;YACV,KAAK,WAAW;gBACZ,IAAM,WAAW,GAA0B,EAAE,CAAC;;oBAC9C,KAAsB,IAAA,oBAAA,sBAAA,KAAK,CAAC,QAAQ,CAAA,CAAA,gBAAA,4BAAE;wBAAjC,IAAM,OAAO,WAAA;wBACd,IAAI,OAAO,CAAC,WAAW,IAAI,SAAS,EAAE;4BAClC,oBAAoB,CAAC,OAAO,CAAC,CAAC;4BAC9B,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,UAAU,EAAE;gCACjD,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;6BAC7B;yBACJ;6BAAM,IAAI,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,WAAW,IAAI,iBAAiB,EAAE;4BACvE,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;yBAC7B;qBACJ;;;;;;;;;gBACD,KAAK,CAAC,QAAQ,GAAG,WAAW,CAAC;gBAC7B,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE;oBAC5B,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;iBACjC;qBAAM;oBACH,uBAAuB,GAAG,IAAI,CAAC;iBAClC;gBACD,MAAM;YACV,KAAK,OAAO;gBACR,IAAM,YAAY,GAA2B,EAAE,CAAC;gBAChD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;oBACxC,IAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;wBACvC,IAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;wBAC1B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;4BAClB,4BAA4B,CAAC,IAAI,EAAE,uBAAuB,CAAC,CAAC;yBAC/D;6BAAM;4BACH,uBAAuB,GAAG,IAAI,CAAC;yBAClC;qBACJ;oBAED,IAAM,QAAQ,GAA4B,EAAE,CAAC;oBAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;wBACvC,IAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;wBAC1B,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;4BAC3C,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;yBACvB;qBACJ;oBACD,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC;oBAErB,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;wBACtB,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;qBAC1B;iBACJ;gBAED,IACI,CAAC,uBAAuB;oBACxB,YAAY,CAAC,MAAM,IAAI,CAAC;oBACxB,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC;oBACjC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,EACtC;oBACE,IAAM,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBACtC,CAAA,KAAA,KAAK,CAAC,MAAM,CAAA,CAAC,MAAM,uCAAC,KAAK,EAAE,CAAC,uBAAK,IAAI,CAAC,MAAM,WAAE;iBACjD;qBAAM,IAAI,YAAY,CAAC,MAAM,IAAI,CAAC,EAAE;oBACjC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;iBACjC;qBAAM;oBACH,KAAK,CAAC,IAAI,GAAG,YAAY,CAAC;iBAC7B;gBACD,MAAM;SACb;KACJ;IACD,OAAO,uBAAuB,CAAC;AACnC,CAAC;AAED,SAAS,MAAM,CAAC,KAA0E;IACtF,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5B,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE;QAC1B,OAAO,KAAK,CAAC,SAAS,IAAI,YAAY,EAAE;YACpC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;YAC5B,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAExB,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;gBACzB,OAAO;aACV;SACJ;QAED,IAAI,KAAK,CAAC,SAAS,IAAI,WAAW,EAAE;YAChC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;YACxB,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;YAClB,8BAA8B,CAAC,KAAK,CAAC,CAAC;SACzC;KACJ;AACL,CAAC;AAED,SAAS,8BAA8B,CAAC,MAA6B;IACjE,IAAM,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS,EAAE;QACrB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YACzD,IAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACvC,OAAO,CAAC,MAAM,mDACP,MAAM,CAAC,aAAa,GACpB,OAAO,CAAC,MAAM,CACpB,CAAC;SACL;KACJ;AACL,CAAC","sourcesContent":["import type {\n ContentModelBlockGroupBase,\n ContentModelBlockGroupType,\n ContentModelParagraph,\n ContentModelSegment,\n ContentModelTableCell,\n ContentModelTableRow,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function pruneUnselectedModel(\n model: ContentModelBlockGroupBase<ContentModelBlockGroupType, HTMLElement>\n) {\n pruneUnselectedModelInternal(model, false /* isSelectionAfterElement */);\n\n unwrap(model);\n}\n\nfunction pruneUnselectedModelInternal(\n model: ContentModelBlockGroupBase<ContentModelBlockGroupType, HTMLElement>,\n isSelectionAfterElement: boolean\n) {\n for (let index = model.blocks.length - 1; index >= 0; index--) {\n const block = model.blocks[index];\n\n switch (block.blockType) {\n case 'BlockGroup':\n pruneUnselectedModelInternal(block, isSelectionAfterElement);\n if (\n block.blockGroupType == 'General'\n ? block.blocks.length == 0 && !block.isSelected\n : block.blocks.length == 0\n ) {\n model.blocks.splice(index, 1);\n }\n break;\n case 'Divider':\n case 'Entity':\n if (!block.isSelected) {\n model.blocks.splice(index, 1);\n } else {\n isSelectionAfterElement = true;\n }\n break;\n case 'Paragraph':\n const newSegments: ContentModelSegment[] = [];\n for (const segment of block.segments) {\n if (segment.segmentType == 'General') {\n pruneUnselectedModel(segment);\n if (segment.blocks.length > 0 || segment.isSelected) {\n newSegments.push(segment);\n }\n } else if (segment.isSelected && segment.segmentType != 'SelectionMarker') {\n newSegments.push(segment);\n }\n }\n block.segments = newSegments;\n if (block.segments.length == 0) {\n model.blocks.splice(index, 1);\n } else {\n isSelectionAfterElement = true;\n }\n break;\n case 'Table':\n const filteredRows: ContentModelTableRow[] = [];\n for (let i = 0; i < block.rows.length; i++) {\n const row = block.rows[i];\n for (let j = 0; j < row.cells.length; j++) {\n const cell = row.cells[j];\n if (!cell.isSelected) {\n pruneUnselectedModelInternal(cell, isSelectionAfterElement);\n } else {\n isSelectionAfterElement = true;\n }\n }\n\n const newCells: ContentModelTableCell[] = [];\n for (let k = 0; k < row.cells.length; k++) {\n const cell = row.cells[k];\n if (cell.isSelected || cell.blocks.length > 0) {\n newCells.push(cell);\n }\n }\n row.cells = newCells;\n\n if (row.cells.length > 0) {\n filteredRows.push(row);\n }\n }\n\n if (\n !isSelectionAfterElement &&\n filteredRows.length == 1 &&\n filteredRows[0].cells.length == 1 &&\n !filteredRows[0].cells[0].isSelected\n ) {\n const cell = filteredRows[0].cells[0];\n model.blocks.splice(index, 1, ...cell.blocks);\n } else if (filteredRows.length == 0) {\n model.blocks.splice(index, 1);\n } else {\n block.rows = filteredRows;\n }\n break;\n }\n }\n return isSelectionAfterElement;\n}\n\nfunction unwrap(model: ContentModelBlockGroupBase<ContentModelBlockGroupType, HTMLElement>) {\n let block = model.blocks[0];\n if (model.blocks.length == 1) {\n while (block.blockType == 'BlockGroup') {\n model.blocks = block.blocks;\n block = model.blocks[0];\n\n if (model.blocks.length > 1) {\n return;\n }\n }\n\n if (block.blockType == 'Paragraph') {\n block.isImplicit = true;\n block.format = {};\n inheritSegmentFormatToChildren(block);\n }\n }\n}\n\nfunction inheritSegmentFormatToChildren(parent: ContentModelParagraph) {\n const value = parent.segmentFormat;\n if (value !== undefined) {\n for (let index = 0; index < parent.segments.length; index++) {\n const segment = parent.segments[index];\n segment.format = {\n ...parent.segmentFormat,\n ...segment.format,\n };\n }\n }\n}\n"]}
@@ -23,14 +23,7 @@ function scrollCaretIntoView(core, selection) {
23
23
  var visibleRect = core.api.getVisibleViewport(core);
24
24
  var scrollContainer = core.domEvent.scrollContainer;
25
25
  if (rect && visibleRect) {
26
- if (rect.bottom > visibleRect.bottom) {
27
- var zoomScale = core.domHelper.calculateZoomScale();
28
- scrollContainer.scrollTop += (rect.bottom - visibleRect.bottom) / zoomScale;
29
- }
30
- else if (rect.top < visibleRect.top) {
31
- var zoomScale = core.domHelper.calculateZoomScale();
32
- scrollContainer.scrollTop += (rect.top - visibleRect.top) / zoomScale;
33
- }
26
+ (0, roosterjs_content_model_dom_1.scrollRectIntoView)(scrollContainer, visibleRect, core.domHelper, rect);
34
27
  }
35
28
  }
36
29
  exports.scrollCaretIntoView = scrollCaretIntoView;
@@ -1 +1 @@
1
- {"version":3,"file":"scrollCaretIntoView.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/formatContentModel/scrollCaretIntoView.ts"],"names":[],"mappings":";;;AAAA,2EAAoE;AAGpE;;GAEG;AACH,SAAgB,mBAAmB,CAAC,IAAgB,EAAE,SAA0C;IAC5F,IAAM,IAAI,GAAG,IAAA,mDAAqB,EAC9B,IAAI,CAAC,YAAY,CAAC,aAAa,EAC/B,SAAS,CAAC,IAAI,IAAI,OAAO;QACrB,CAAC,CAAC;YACI,IAAI,EAAE,SAAS,CAAC,KAAK;YACrB,MAAM,EAAE,CAAC;SACZ;QACH,CAAC,CAAC,SAAS,CAAC,UAAU;YACtB,CAAC,CAAC;gBACI,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,cAAc;gBACpC,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,WAAW;aACtC;YACH,CAAC,CAAC;gBACI,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,YAAY;gBAClC,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,SAAS;aACpC,CACV,CAAC;IACF,IAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACtD,IAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;IAEtD,IAAI,IAAI,IAAI,WAAW,EAAE;QACrB,IAAI,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE;YAClC,IAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,CAAC;YAEtD,eAAe,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;SAC/E;aAAM,IAAI,IAAI,CAAC,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE;YACnC,IAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,CAAC;YAEtD,eAAe,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;SACzE;KACJ;AACL,CAAC;AAhCD,kDAgCC","sourcesContent":["import { getDOMInsertPointRect } from 'roosterjs-content-model-dom';\nimport type { EditorCore, ImageSelection, RangeSelection } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function scrollCaretIntoView(core: EditorCore, selection: RangeSelection | ImageSelection) {\n const rect = getDOMInsertPointRect(\n core.physicalRoot.ownerDocument,\n selection.type == 'image'\n ? {\n node: selection.image,\n offset: 0,\n }\n : selection.isReverted\n ? {\n node: selection.range.startContainer,\n offset: selection.range.startOffset,\n }\n : {\n node: selection.range.endContainer,\n offset: selection.range.endOffset,\n }\n );\n const visibleRect = core.api.getVisibleViewport(core);\n const scrollContainer = core.domEvent.scrollContainer;\n\n if (rect && visibleRect) {\n if (rect.bottom > visibleRect.bottom) {\n const zoomScale = core.domHelper.calculateZoomScale();\n\n scrollContainer.scrollTop += (rect.bottom - visibleRect.bottom) / zoomScale;\n } else if (rect.top < visibleRect.top) {\n const zoomScale = core.domHelper.calculateZoomScale();\n\n scrollContainer.scrollTop += (rect.top - visibleRect.top) / zoomScale;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"scrollCaretIntoView.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/formatContentModel/scrollCaretIntoView.ts"],"names":[],"mappings":";;;AAAA,2EAAwF;AAGxF;;GAEG;AACH,SAAgB,mBAAmB,CAAC,IAAgB,EAAE,SAA0C;IAC5F,IAAM,IAAI,GAAG,IAAA,mDAAqB,EAC9B,IAAI,CAAC,YAAY,CAAC,aAAa,EAC/B,SAAS,CAAC,IAAI,IAAI,OAAO;QACrB,CAAC,CAAC;YACI,IAAI,EAAE,SAAS,CAAC,KAAK;YACrB,MAAM,EAAE,CAAC;SACZ;QACH,CAAC,CAAC,SAAS,CAAC,UAAU;YACtB,CAAC,CAAC;gBACI,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,cAAc;gBACpC,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,WAAW;aACtC;YACH,CAAC,CAAC;gBACI,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,YAAY;gBAClC,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,SAAS;aACpC,CACV,CAAC;IACF,IAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACtD,IAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;IAEtD,IAAI,IAAI,IAAI,WAAW,EAAE;QACrB,IAAA,gDAAkB,EAAC,eAAe,EAAE,WAAW,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;KAC1E;AACL,CAAC;AAxBD,kDAwBC","sourcesContent":["import { getDOMInsertPointRect, scrollRectIntoView } from 'roosterjs-content-model-dom';\nimport type { EditorCore, ImageSelection, RangeSelection } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function scrollCaretIntoView(core: EditorCore, selection: RangeSelection | ImageSelection) {\n const rect = getDOMInsertPointRect(\n core.physicalRoot.ownerDocument,\n selection.type == 'image'\n ? {\n node: selection.image,\n offset: 0,\n }\n : selection.isReverted\n ? {\n node: selection.range.startContainer,\n offset: selection.range.startOffset,\n }\n : {\n node: selection.range.endContainer,\n offset: selection.range.endOffset,\n }\n );\n const visibleRect = core.api.getVisibleViewport(core);\n const scrollContainer = core.domEvent.scrollContainer;\n\n if (rect && visibleRect) {\n scrollRectIntoView(scrollContainer, visibleRect, core.domHelper, rect);\n }\n}\n"]}
@@ -72,6 +72,7 @@ var setDOMSelection = function (core, selection, skipSelectionChangedEvent) {
72
72
  firstColumn: firstCell.col,
73
73
  lastRow: lastCell.row,
74
74
  lastColumn: lastCell.col,
75
+ tableSelectionInfo: selection.tableSelectionInfo,
75
76
  };
76
77
  var tableId = (0, ensureUniqueId_1.ensureUniqueId)(table, TABLE_ID);
77
78
  var tableSelector = (0, roosterjs_content_model_dom_1.getSafeIdSelector)(tableId);
@@ -1 +1 @@
1
- {"version":3,"file":"setDOMSelection.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/setDOMSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { addRangeToSelection } from './addRangeToSelection';\nimport { areSameSelections } from '../../corePlugin/cache/areSameSelections';\nimport { ensureUniqueId } from '../setEditorStyle/ensureUniqueId';\nimport { findLastedCoInMergedCell } from './findLastedCoInMergedCell';\nimport { findTableCellElement } from './findTableCellElement';\nimport { toggleCaret } from './toggleCaret';\nimport {\n getSafeIdSelector,\n isNodeOfType,\n parseTableCells,\n toArray,\n} from 'roosterjs-content-model-dom';\nimport type {\n ParsedTable,\n SelectionChangedEvent,\n SetDOMSelection,\n TableCellCoordinate,\n} from 'roosterjs-content-model-types';\n\nconst DOM_SELECTION_CSS_KEY = '_DOMSelection';\nconst HIDE_SELECTION_CSS_KEY = '_DOMSelectionHideSelection';\nconst IMAGE_ID = 'image';\nconst TABLE_ID = 'table';\nconst TRANSPARENT_SELECTION_CSS_RULE = 'background-color: transparent !important;';\nconst SELECTION_SELECTOR = '*::selection';\nconst DEFAULT_SELECTION_BORDER_COLOR = '#DB626C';\n\n/**\n * @internal\n */\nexport const setDOMSelection: SetDOMSelection = (core, selection, skipSelectionChangedEvent) => {\n const existingSelection = core.api.getDOMSelection(core);\n\n if (existingSelection && selection && areSameSelections(existingSelection, selection)) {\n return;\n }\n\n // We are applying a new selection, so we don't need to apply cached selection in DOMEventPlugin.\n // Set skipReselectOnFocus to skip this behavior\n const skipReselectOnFocus = core.selection.skipReselectOnFocus;\n\n const doc = core.physicalRoot.ownerDocument;\n const isDarkMode = core.lifecycle.isDarkMode;\n core.selection.skipReselectOnFocus = true;\n core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, null /*cssRule*/);\n core.api.setEditorStyle(core, HIDE_SELECTION_CSS_KEY, null /*cssRule*/);\n\n toggleCaret(core, false /* hide */);\n\n try {\n switch (selection?.type) {\n case 'image':\n const image = selection.image;\n\n core.selection.selection = selection;\n\n const imageSelectionColor = isDarkMode\n ? core.selection.imageSelectionBorderColorDark\n : core.selection.imageSelectionBorderColor;\n\n core.api.setEditorStyle(\n core,\n DOM_SELECTION_CSS_KEY,\n `outline-style:solid!important; outline-color:${\n imageSelectionColor || DEFAULT_SELECTION_BORDER_COLOR\n }!important;`,\n [getSafeIdSelector(ensureUniqueId(image, IMAGE_ID))]\n );\n core.api.setEditorStyle(\n core,\n HIDE_SELECTION_CSS_KEY,\n TRANSPARENT_SELECTION_CSS_RULE,\n [SELECTION_SELECTOR]\n );\n\n setRangeSelection(doc, image, false /* collapse */);\n break;\n case 'table':\n const { table, firstColumn, firstRow, lastColumn, lastRow } = selection;\n const parsedTable = parseTableCells(selection.table);\n let firstCell = {\n row: Math.min(firstRow, lastRow),\n col: Math.min(firstColumn, lastColumn),\n cell: <HTMLTableCellElement | null>null,\n };\n let lastCell = {\n row: Math.max(firstRow, lastRow),\n col: Math.max(firstColumn, lastColumn),\n };\n\n firstCell = findTableCellElement(parsedTable, firstCell) || firstCell;\n lastCell = findLastedCoInMergedCell(parsedTable, lastCell) || lastCell;\n\n if (\n isNaN(firstCell.row) ||\n isNaN(firstCell.col) ||\n isNaN(lastCell.row) ||\n isNaN(lastCell.col)\n ) {\n return;\n }\n\n selection = {\n type: 'table',\n table,\n firstRow: firstCell.row,\n firstColumn: firstCell.col,\n lastRow: lastCell.row,\n lastColumn: lastCell.col,\n };\n\n const tableId = ensureUniqueId(table, TABLE_ID);\n const tableSelector = getSafeIdSelector(tableId);\n\n const tableSelectors =\n firstCell.row == 0 &&\n firstCell.col == 0 &&\n lastCell.row == parsedTable.length - 1 &&\n lastCell.col == (parsedTable[lastCell.row]?.length ?? 0) - 1\n ? [tableSelector, `${tableSelector} *`]\n : handleTableSelected(\n parsedTable,\n tableSelector,\n table,\n firstCell,\n lastCell\n );\n\n core.selection.selection = selection;\n\n const tableSelectionColor = isDarkMode\n ? core.selection.tableCellSelectionBackgroundColorDark\n : core.selection.tableCellSelectionBackgroundColor;\n core.api.setEditorStyle(\n core,\n DOM_SELECTION_CSS_KEY,\n `background-color:${tableSelectionColor}!important;`,\n tableSelectors\n );\n core.api.setEditorStyle(\n core,\n HIDE_SELECTION_CSS_KEY,\n TRANSPARENT_SELECTION_CSS_RULE,\n [SELECTION_SELECTOR]\n );\n\n toggleCaret(core, true /* hide */);\n\n const nodeToSelect = firstCell.cell?.firstElementChild || firstCell.cell;\n\n if (nodeToSelect) {\n setRangeSelection(\n doc,\n (nodeToSelect as HTMLElement) || undefined,\n true /* collapse */\n );\n }\n\n break;\n case 'range':\n addRangeToSelection(doc, selection.range, selection.isReverted);\n\n core.selection.selection = core.domHelper.hasFocus() ? null : selection;\n break;\n\n default:\n core.selection.selection = null;\n break;\n }\n } finally {\n core.selection.skipReselectOnFocus = skipReselectOnFocus;\n }\n\n if (!skipSelectionChangedEvent) {\n const eventData: SelectionChangedEvent = {\n eventType: 'selectionChanged',\n newSelection: selection,\n };\n\n core.api.triggerEvent(core, eventData, true /*broadcast*/);\n }\n};\n\nfunction handleTableSelected(\n parsedTable: ParsedTable,\n tableSelector: string,\n table: HTMLTableElement,\n firstCell: TableCellCoordinate,\n lastCell: TableCellCoordinate\n) {\n const selectors: string[] = [];\n\n // Get whether table has thead, tbody or tfoot, then Set the start and end of each of the table children,\n // so we can build the selector according the element between the table and the row.\n let cont = 0;\n const indexes = toArray(table.childNodes)\n .filter(\n (node): node is HTMLTableSectionElement =>\n ['THEAD', 'TBODY', 'TFOOT'].indexOf(\n isNodeOfType(node, 'ELEMENT_NODE') ? node.tagName : ''\n ) > -1\n )\n .map(node => {\n const result = {\n el: node.tagName,\n start: cont,\n end: node.childNodes.length + cont,\n };\n\n cont = result.end;\n return result;\n });\n\n parsedTable.forEach((row, rowIndex) => {\n let tdCount = 0;\n\n //Get current TBODY/THEAD/TFOOT\n const midElement = indexes.filter(ind => ind.start <= rowIndex && ind.end > rowIndex)[0];\n const middleElSelector = midElement ? '>' + midElement.el + '>' : '>';\n const currentRow =\n midElement && rowIndex + 1 >= midElement.start\n ? rowIndex + 1 - midElement.start\n : rowIndex + 1;\n\n for (let cellIndex = 0; cellIndex < row.length; cellIndex++) {\n const cell = row[cellIndex];\n\n if (typeof cell == 'object') {\n tdCount++;\n\n if (\n rowIndex >= firstCell.row &&\n rowIndex <= lastCell.row &&\n cellIndex >= firstCell.col &&\n cellIndex <= lastCell.col\n ) {\n const selector = `${tableSelector}${middleElSelector} tr:nth-child(${currentRow})>${cell.tagName}:nth-child(${tdCount})`;\n\n selectors.push(selector, selector + ' *');\n }\n }\n }\n });\n\n return selectors;\n}\n\nfunction setRangeSelection(doc: Document, element: HTMLElement | undefined, collapse: boolean) {\n if (element && doc.contains(element)) {\n const range = doc.createRange();\n let isReverted: boolean | undefined = undefined;\n\n range.selectNode(element);\n if (collapse) {\n range.collapse();\n } else {\n const selection = doc.defaultView?.getSelection();\n const range = selection && selection.rangeCount > 0 && selection.getRangeAt(0);\n if (selection && range) {\n isReverted =\n selection.focusNode != range.endContainer ||\n selection.focusOffset != range.endOffset;\n }\n }\n\n addRangeToSelection(doc, range, isReverted);\n }\n}\n"]}
1
+ {"version":3,"file":"setDOMSelection.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/setDOMSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { addRangeToSelection } from './addRangeToSelection';\nimport { areSameSelections } from '../../corePlugin/cache/areSameSelections';\nimport { ensureUniqueId } from '../setEditorStyle/ensureUniqueId';\nimport { findLastedCoInMergedCell } from './findLastedCoInMergedCell';\nimport { findTableCellElement } from './findTableCellElement';\nimport { toggleCaret } from './toggleCaret';\nimport {\n getSafeIdSelector,\n isNodeOfType,\n parseTableCells,\n toArray,\n} from 'roosterjs-content-model-dom';\nimport type {\n ParsedTable,\n SelectionChangedEvent,\n SetDOMSelection,\n TableCellCoordinate,\n} from 'roosterjs-content-model-types';\n\nconst DOM_SELECTION_CSS_KEY = '_DOMSelection';\nconst HIDE_SELECTION_CSS_KEY = '_DOMSelectionHideSelection';\nconst IMAGE_ID = 'image';\nconst TABLE_ID = 'table';\nconst TRANSPARENT_SELECTION_CSS_RULE = 'background-color: transparent !important;';\nconst SELECTION_SELECTOR = '*::selection';\nconst DEFAULT_SELECTION_BORDER_COLOR = '#DB626C';\n\n/**\n * @internal\n */\nexport const setDOMSelection: SetDOMSelection = (core, selection, skipSelectionChangedEvent) => {\n const existingSelection = core.api.getDOMSelection(core);\n\n if (existingSelection && selection && areSameSelections(existingSelection, selection)) {\n return;\n }\n\n // We are applying a new selection, so we don't need to apply cached selection in DOMEventPlugin.\n // Set skipReselectOnFocus to skip this behavior\n const skipReselectOnFocus = core.selection.skipReselectOnFocus;\n\n const doc = core.physicalRoot.ownerDocument;\n const isDarkMode = core.lifecycle.isDarkMode;\n core.selection.skipReselectOnFocus = true;\n core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, null /*cssRule*/);\n core.api.setEditorStyle(core, HIDE_SELECTION_CSS_KEY, null /*cssRule*/);\n\n toggleCaret(core, false /* hide */);\n\n try {\n switch (selection?.type) {\n case 'image':\n const image = selection.image;\n\n core.selection.selection = selection;\n\n const imageSelectionColor = isDarkMode\n ? core.selection.imageSelectionBorderColorDark\n : core.selection.imageSelectionBorderColor;\n\n core.api.setEditorStyle(\n core,\n DOM_SELECTION_CSS_KEY,\n `outline-style:solid!important; outline-color:${\n imageSelectionColor || DEFAULT_SELECTION_BORDER_COLOR\n }!important;`,\n [getSafeIdSelector(ensureUniqueId(image, IMAGE_ID))]\n );\n core.api.setEditorStyle(\n core,\n HIDE_SELECTION_CSS_KEY,\n TRANSPARENT_SELECTION_CSS_RULE,\n [SELECTION_SELECTOR]\n );\n\n setRangeSelection(doc, image, false /* collapse */);\n break;\n case 'table':\n const { table, firstColumn, firstRow, lastColumn, lastRow } = selection;\n const parsedTable = parseTableCells(selection.table);\n let firstCell = {\n row: Math.min(firstRow, lastRow),\n col: Math.min(firstColumn, lastColumn),\n cell: <HTMLTableCellElement | null>null,\n };\n let lastCell = {\n row: Math.max(firstRow, lastRow),\n col: Math.max(firstColumn, lastColumn),\n };\n\n firstCell = findTableCellElement(parsedTable, firstCell) || firstCell;\n lastCell = findLastedCoInMergedCell(parsedTable, lastCell) || lastCell;\n\n if (\n isNaN(firstCell.row) ||\n isNaN(firstCell.col) ||\n isNaN(lastCell.row) ||\n isNaN(lastCell.col)\n ) {\n return;\n }\n\n selection = {\n type: 'table',\n table,\n firstRow: firstCell.row,\n firstColumn: firstCell.col,\n lastRow: lastCell.row,\n lastColumn: lastCell.col,\n tableSelectionInfo: selection.tableSelectionInfo,\n };\n\n const tableId = ensureUniqueId(table, TABLE_ID);\n const tableSelector = getSafeIdSelector(tableId);\n\n const tableSelectors =\n firstCell.row == 0 &&\n firstCell.col == 0 &&\n lastCell.row == parsedTable.length - 1 &&\n lastCell.col == (parsedTable[lastCell.row]?.length ?? 0) - 1\n ? [tableSelector, `${tableSelector} *`]\n : handleTableSelected(\n parsedTable,\n tableSelector,\n table,\n firstCell,\n lastCell\n );\n\n core.selection.selection = selection;\n\n const tableSelectionColor = isDarkMode\n ? core.selection.tableCellSelectionBackgroundColorDark\n : core.selection.tableCellSelectionBackgroundColor;\n core.api.setEditorStyle(\n core,\n DOM_SELECTION_CSS_KEY,\n `background-color:${tableSelectionColor}!important;`,\n tableSelectors\n );\n core.api.setEditorStyle(\n core,\n HIDE_SELECTION_CSS_KEY,\n TRANSPARENT_SELECTION_CSS_RULE,\n [SELECTION_SELECTOR]\n );\n\n toggleCaret(core, true /* hide */);\n\n const nodeToSelect = firstCell.cell?.firstElementChild || firstCell.cell;\n\n if (nodeToSelect) {\n setRangeSelection(\n doc,\n (nodeToSelect as HTMLElement) || undefined,\n true /* collapse */\n );\n }\n\n break;\n case 'range':\n addRangeToSelection(doc, selection.range, selection.isReverted);\n\n core.selection.selection = core.domHelper.hasFocus() ? null : selection;\n break;\n\n default:\n core.selection.selection = null;\n break;\n }\n } finally {\n core.selection.skipReselectOnFocus = skipReselectOnFocus;\n }\n\n if (!skipSelectionChangedEvent) {\n const eventData: SelectionChangedEvent = {\n eventType: 'selectionChanged',\n newSelection: selection,\n };\n\n core.api.triggerEvent(core, eventData, true /*broadcast*/);\n }\n};\n\nfunction handleTableSelected(\n parsedTable: ParsedTable,\n tableSelector: string,\n table: HTMLTableElement,\n firstCell: TableCellCoordinate,\n lastCell: TableCellCoordinate\n) {\n const selectors: string[] = [];\n\n // Get whether table has thead, tbody or tfoot, then Set the start and end of each of the table children,\n // so we can build the selector according the element between the table and the row.\n let cont = 0;\n const indexes = toArray(table.childNodes)\n .filter(\n (node): node is HTMLTableSectionElement =>\n ['THEAD', 'TBODY', 'TFOOT'].indexOf(\n isNodeOfType(node, 'ELEMENT_NODE') ? node.tagName : ''\n ) > -1\n )\n .map(node => {\n const result = {\n el: node.tagName,\n start: cont,\n end: node.childNodes.length + cont,\n };\n\n cont = result.end;\n return result;\n });\n\n parsedTable.forEach((row, rowIndex) => {\n let tdCount = 0;\n\n //Get current TBODY/THEAD/TFOOT\n const midElement = indexes.filter(ind => ind.start <= rowIndex && ind.end > rowIndex)[0];\n const middleElSelector = midElement ? '>' + midElement.el + '>' : '>';\n const currentRow =\n midElement && rowIndex + 1 >= midElement.start\n ? rowIndex + 1 - midElement.start\n : rowIndex + 1;\n\n for (let cellIndex = 0; cellIndex < row.length; cellIndex++) {\n const cell = row[cellIndex];\n\n if (typeof cell == 'object') {\n tdCount++;\n\n if (\n rowIndex >= firstCell.row &&\n rowIndex <= lastCell.row &&\n cellIndex >= firstCell.col &&\n cellIndex <= lastCell.col\n ) {\n const selector = `${tableSelector}${middleElSelector} tr:nth-child(${currentRow})>${cell.tagName}:nth-child(${tdCount})`;\n\n selectors.push(selector, selector + ' *');\n }\n }\n }\n });\n\n return selectors;\n}\n\nfunction setRangeSelection(doc: Document, element: HTMLElement | undefined, collapse: boolean) {\n if (element && doc.contains(element)) {\n const range = doc.createRange();\n let isReverted: boolean | undefined = undefined;\n\n range.selectNode(element);\n if (collapse) {\n range.collapse();\n } else {\n const selection = doc.defaultView?.getSelection();\n const range = selection && selection.rangeCount > 0 && selection.getRangeAt(0);\n if (selection && range) {\n isReverted =\n selection.focusNode != range.endContainer ||\n selection.focusOffset != range.endOffset;\n }\n }\n\n addRangeToSelection(doc, range, isReverted);\n }\n}\n"]}
@@ -49,7 +49,6 @@ var CachePlugin = /** @class */ (function () {
49
49
  };
50
50
  this.state = {
51
51
  domIndexer: new domIndexerImpl_1.DomIndexerImpl(option.experimentalFeatures &&
52
- option.experimentalFeatures.indexOf('PersistCache') >= 0, option.experimentalFeatures &&
53
52
  option.experimentalFeatures.indexOf('KeepSelectionMarkerWhenEnteringTextNode') >= 0),
54
53
  textMutationObserver: (0, textMutationObserver_1.createTextMutationObserver)(contentDiv, this.onMutation),
55
54
  };
@@ -1 +1 @@
1
- {"version":3,"file":"CachePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/CachePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { areSameSelections } from './areSameSelections';\nimport { createParagraphMap } from './ParagraphMapImpl';\nimport { createTextMutationObserver } from './textMutationObserver';\nimport { DomIndexerImpl } from './domIndexerImpl';\nimport { updateCache } from './updateCache';\nimport type { Mutation } from './MutationType';\nimport type {\n CachePluginState,\n IEditor,\n PluginEvent,\n PluginWithState,\n EditorOptions,\n} from 'roosterjs-content-model-types';\n\n/**\n * ContentModel cache plugin manages cached Content Model, and refresh the cache when necessary\n */\nclass CachePlugin implements PluginWithState<CachePluginState> {\n private editor: IEditor | null = null;\n private state: CachePluginState;\n\n /**\n * Construct a new instance of CachePlugin class\n * @param option The editor option\n * @param contentDiv The editor content DIV\n */\n constructor(option: EditorOptions, contentDiv: HTMLDivElement) {\n this.state = {\n domIndexer: new DomIndexerImpl(\n option.experimentalFeatures &&\n option.experimentalFeatures.indexOf('PersistCache') >= 0,\n option.experimentalFeatures &&\n option.experimentalFeatures.indexOf(\n 'KeepSelectionMarkerWhenEnteringTextNode'\n ) >= 0\n ),\n textMutationObserver: createTextMutationObserver(contentDiv, this.onMutation),\n };\n\n if (option.enableParagraphMap) {\n this.state.paragraphMap = createParagraphMap();\n }\n }\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Cache';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n this.editor.getDocument().addEventListener('selectionchange', this.onNativeSelectionChange);\n\n this.state.textMutationObserver.startObserving();\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.state.textMutationObserver.stopObserving();\n\n if (this.editor) {\n this.editor\n .getDocument()\n .removeEventListener('selectionchange', this.onNativeSelectionChange);\n this.editor = null;\n }\n }\n\n /**\n * Get plugin state object\n */\n getState(): CachePluginState {\n return this.state;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (!this.editor) {\n return;\n }\n\n switch (event.eventType) {\n case 'logicalRootChanged':\n this.invalidateCache();\n\n this.state.textMutationObserver.stopObserving();\n this.state.textMutationObserver = createTextMutationObserver(\n event.logicalRoot,\n this.onMutation\n );\n this.state.textMutationObserver.startObserving();\n break;\n\n case 'selectionChanged':\n this.updateCachedModel(this.editor);\n break;\n\n case 'contentChanged':\n const { contentModel, selection } = event;\n\n if (contentModel) {\n updateCache(this.state, contentModel, selection);\n } else {\n this.invalidateCache();\n }\n\n break;\n }\n }\n\n private onMutation = (mutation: Mutation) => {\n if (this.editor) {\n switch (mutation.type) {\n case 'childList':\n if (\n !this.state.domIndexer.reconcileChildList(\n mutation.addedNodes,\n mutation.removedNodes\n )\n ) {\n this.invalidateCache();\n }\n break;\n\n case 'text':\n this.updateCachedModel(this.editor, true /*forceUpdate*/);\n break;\n\n case 'elementId':\n const element = mutation.element;\n\n if (!this.state.domIndexer.reconcileElementId(element)) {\n this.invalidateCache();\n }\n\n break;\n\n case 'unknown':\n this.invalidateCache();\n break;\n }\n }\n };\n\n private onNativeSelectionChange = () => {\n if (this.editor?.hasFocus()) {\n this.updateCachedModel(this.editor);\n }\n };\n\n private invalidateCache() {\n if (!this.editor?.isInShadowEdit()) {\n this.state.cachedModel = undefined;\n this.state.cachedSelection = undefined;\n\n // Clear paragraph indexer to prevent stale references to old paragraphs\n // It will be rebuild next time when we create a new Content Model\n this.state.paragraphMap?.clear();\n }\n }\n\n private updateCachedModel(editor: IEditor, forceUpdate?: boolean) {\n if (editor.isInShadowEdit()) {\n return;\n }\n\n const cachedSelection = this.state.cachedSelection;\n this.state.cachedSelection = undefined; // Clear it to force getDOMSelection() retrieve the latest selection range\n\n const newRangeEx = editor.getDOMSelection() || undefined;\n const model = this.state.cachedModel;\n const isSelectionChanged =\n forceUpdate ||\n !cachedSelection ||\n !newRangeEx ||\n !areSameSelections(newRangeEx, cachedSelection);\n\n if (isSelectionChanged) {\n if (\n !model ||\n !newRangeEx ||\n !this.state.domIndexer.reconcileSelection(model, newRangeEx, cachedSelection)\n ) {\n this.invalidateCache();\n } else {\n updateCache(this.state, model, newRangeEx);\n }\n } else {\n this.state.cachedSelection = cachedSelection;\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of CachePlugin class.\n * @param option The editor option\n * @param contentDiv The editor content DIV\n */\nexport function createCachePlugin(\n option: EditorOptions,\n contentDiv: HTMLDivElement\n): PluginWithState<CachePluginState> {\n return new CachePlugin(option, contentDiv);\n}\n"]}
1
+ {"version":3,"file":"CachePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/CachePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { areSameSelections } from './areSameSelections';\nimport { createParagraphMap } from './ParagraphMapImpl';\nimport { createTextMutationObserver } from './textMutationObserver';\nimport { DomIndexerImpl } from './domIndexerImpl';\nimport { updateCache } from './updateCache';\nimport type { Mutation } from './MutationType';\nimport type {\n CachePluginState,\n IEditor,\n PluginEvent,\n PluginWithState,\n EditorOptions,\n} from 'roosterjs-content-model-types';\n\n/**\n * ContentModel cache plugin manages cached Content Model, and refresh the cache when necessary\n */\nclass CachePlugin implements PluginWithState<CachePluginState> {\n private editor: IEditor | null = null;\n private state: CachePluginState;\n\n /**\n * Construct a new instance of CachePlugin class\n * @param option The editor option\n * @param contentDiv The editor content DIV\n */\n constructor(option: EditorOptions, contentDiv: HTMLDivElement) {\n this.state = {\n domIndexer: new DomIndexerImpl(\n option.experimentalFeatures &&\n option.experimentalFeatures.indexOf(\n 'KeepSelectionMarkerWhenEnteringTextNode'\n ) >= 0\n ),\n textMutationObserver: createTextMutationObserver(contentDiv, this.onMutation),\n };\n\n if (option.enableParagraphMap) {\n this.state.paragraphMap = createParagraphMap();\n }\n }\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Cache';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n this.editor.getDocument().addEventListener('selectionchange', this.onNativeSelectionChange);\n\n this.state.textMutationObserver.startObserving();\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.state.textMutationObserver.stopObserving();\n\n if (this.editor) {\n this.editor\n .getDocument()\n .removeEventListener('selectionchange', this.onNativeSelectionChange);\n this.editor = null;\n }\n }\n\n /**\n * Get plugin state object\n */\n getState(): CachePluginState {\n return this.state;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (!this.editor) {\n return;\n }\n\n switch (event.eventType) {\n case 'logicalRootChanged':\n this.invalidateCache();\n\n this.state.textMutationObserver.stopObserving();\n this.state.textMutationObserver = createTextMutationObserver(\n event.logicalRoot,\n this.onMutation\n );\n this.state.textMutationObserver.startObserving();\n break;\n\n case 'selectionChanged':\n this.updateCachedModel(this.editor);\n break;\n\n case 'contentChanged':\n const { contentModel, selection } = event;\n\n if (contentModel) {\n updateCache(this.state, contentModel, selection);\n } else {\n this.invalidateCache();\n }\n\n break;\n }\n }\n\n private onMutation = (mutation: Mutation) => {\n if (this.editor) {\n switch (mutation.type) {\n case 'childList':\n if (\n !this.state.domIndexer.reconcileChildList(\n mutation.addedNodes,\n mutation.removedNodes\n )\n ) {\n this.invalidateCache();\n }\n break;\n\n case 'text':\n this.updateCachedModel(this.editor, true /*forceUpdate*/);\n break;\n\n case 'elementId':\n const element = mutation.element;\n\n if (!this.state.domIndexer.reconcileElementId(element)) {\n this.invalidateCache();\n }\n\n break;\n\n case 'unknown':\n this.invalidateCache();\n break;\n }\n }\n };\n\n private onNativeSelectionChange = () => {\n if (this.editor?.hasFocus()) {\n this.updateCachedModel(this.editor);\n }\n };\n\n private invalidateCache() {\n if (!this.editor?.isInShadowEdit()) {\n this.state.cachedModel = undefined;\n this.state.cachedSelection = undefined;\n\n // Clear paragraph indexer to prevent stale references to old paragraphs\n // It will be rebuild next time when we create a new Content Model\n this.state.paragraphMap?.clear();\n }\n }\n\n private updateCachedModel(editor: IEditor, forceUpdate?: boolean) {\n if (editor.isInShadowEdit()) {\n return;\n }\n\n const cachedSelection = this.state.cachedSelection;\n this.state.cachedSelection = undefined; // Clear it to force getDOMSelection() retrieve the latest selection range\n\n const newRangeEx = editor.getDOMSelection() || undefined;\n const model = this.state.cachedModel;\n const isSelectionChanged =\n forceUpdate ||\n !cachedSelection ||\n !newRangeEx ||\n !areSameSelections(newRangeEx, cachedSelection);\n\n if (isSelectionChanged) {\n if (\n !model ||\n !newRangeEx ||\n !this.state.domIndexer.reconcileSelection(model, newRangeEx, cachedSelection)\n ) {\n this.invalidateCache();\n } else {\n updateCache(this.state, model, newRangeEx);\n }\n } else {\n this.state.cachedSelection = cachedSelection;\n }\n }\n}\n\n/**\n * @internal\n * Create a new instance of CachePlugin class.\n * @param option The editor option\n * @param contentDiv The editor content DIV\n */\nexport function createCachePlugin(\n option: EditorOptions,\n contentDiv: HTMLDivElement\n): PluginWithState<CachePluginState> {\n return new CachePlugin(option, contentDiv);\n}\n"]}
@@ -42,9 +42,8 @@ export interface IndexedEntityDelimiter extends Text {
42
42
  * Implementation of DomIndexer
43
43
  */
44
44
  export declare class DomIndexerImpl implements DomIndexer {
45
- private readonly persistCache?;
46
45
  private readonly keepSelectionMarkerWhenEnteringTextNode?;
47
- constructor(persistCache?: boolean | undefined, keepSelectionMarkerWhenEnteringTextNode?: boolean | undefined);
46
+ constructor(keepSelectionMarkerWhenEnteringTextNode?: boolean | undefined);
48
47
  onSegment(segmentNode: Node, paragraph: ContentModelParagraph, segment: ContentModelSegment[]): void;
49
48
  onParagraph(paragraphElement: HTMLElement): void;
50
49
  onTable(tableElement: HTMLTableElement, table: ContentModelTable): void;
@@ -44,8 +44,7 @@ function unindex(node) {
44
44
  * Implementation of DomIndexer
45
45
  */
46
46
  var DomIndexerImpl = /** @class */ (function () {
47
- function DomIndexerImpl(persistCache, keepSelectionMarkerWhenEnteringTextNode) {
48
- this.persistCache = persistCache;
47
+ function DomIndexerImpl(keepSelectionMarkerWhenEnteringTextNode) {
49
48
  this.keepSelectionMarkerWhenEnteringTextNode = keepSelectionMarkerWhenEnteringTextNode;
50
49
  }
51
50
  DomIndexerImpl.prototype.onSegment = function (segmentNode, paragraph, segment) {
@@ -180,9 +179,6 @@ var DomIndexerImpl = /** @class */ (function () {
180
179
  return false;
181
180
  };
182
181
  DomIndexerImpl.prototype.reconcileChildList = function (addedNodes, removedNodes) {
183
- if (!this.persistCache) {
184
- return false;
185
- }
186
182
  var canHandle = true;
187
183
  var context = {
188
184
  segIndex: -1,
@@ -337,9 +333,6 @@ var DomIndexerImpl = /** @class */ (function () {
337
333
  (_a = paragraph.segments).splice.apply(_a, (0, tslib_1.__spreadArray)([firstIndex, lastIndex - firstIndex + 1], (0, tslib_1.__read)(newSegments), false));
338
334
  }
339
335
  this.onSegment(textNode, paragraph, textSegments);
340
- if (!this.persistCache) {
341
- delete paragraph.cachedElement;
342
- }
343
336
  }
344
337
  else if ((first === null || first === void 0 ? void 0 : first.segmentType) == 'Entity' && first == last) {
345
338
  var wrapper = first.wrapper;