roosterjs-content-model-plugins 0.21.2 → 0.22.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 (112) hide show
  1. package/lib/edit/deleteSteps/deleteAllSegmentBefore.js +3 -0
  2. package/lib/edit/deleteSteps/deleteAllSegmentBefore.js.map +1 -1
  3. package/lib/edit/deleteSteps/deleteCollapsedSelection.js +3 -0
  4. package/lib/edit/deleteSteps/deleteCollapsedSelection.js.map +1 -1
  5. package/lib/edit/deleteSteps/deleteWordSelection.js +3 -0
  6. package/lib/edit/deleteSteps/deleteWordSelection.js.map +1 -1
  7. package/lib/edit/keyboardInput.js +1 -1
  8. package/lib/edit/keyboardInput.js.map +1 -1
  9. package/lib/entityDelimiter/EntityDelimiterPlugin.js +3 -1
  10. package/lib/entityDelimiter/EntityDelimiterPlugin.js.map +1 -1
  11. package/lib/paste/ContentModelPastePlugin.d.ts +3 -1
  12. package/lib/paste/ContentModelPastePlugin.js +5 -3
  13. package/lib/paste/ContentModelPastePlugin.js.map +1 -1
  14. package/lib/paste/Excel/processPastedContentFromExcel.d.ts +1 -1
  15. package/lib/paste/Excel/processPastedContentFromExcel.js +2 -2
  16. package/lib/paste/Excel/processPastedContentFromExcel.js.map +1 -1
  17. package/lib/paste/WacComponents/constants.d.ts +56 -0
  18. package/lib/paste/WacComponents/constants.js +86 -0
  19. package/lib/paste/WacComponents/constants.js.map +1 -0
  20. package/lib/paste/WacComponents/processPastedContentWacComponents.js +19 -34
  21. package/lib/paste/WacComponents/processPastedContentWacComponents.js.map +1 -1
  22. package/lib/paste/WordDesktop/WordMetadata.d.ts +9 -0
  23. package/lib/paste/WordDesktop/WordMetadata.js +3 -0
  24. package/lib/paste/WordDesktop/WordMetadata.js.map +1 -0
  25. package/lib/paste/WordDesktop/getStyleMetadata.d.ts +23 -0
  26. package/lib/paste/WordDesktop/getStyleMetadata.js +79 -0
  27. package/lib/paste/WordDesktop/getStyleMetadata.js.map +1 -0
  28. package/lib/paste/WordDesktop/processPastedContentFromWordDesktop.d.ts +2 -7
  29. package/lib/paste/WordDesktop/processPastedContentFromWordDesktop.js +14 -14
  30. package/lib/paste/WordDesktop/processPastedContentFromWordDesktop.js.map +1 -1
  31. package/lib/paste/WordDesktop/processWordLists.d.ts +2 -1
  32. package/lib/paste/WordDesktop/processWordLists.js +83 -85
  33. package/lib/paste/WordDesktop/processWordLists.js.map +1 -1
  34. package/lib/paste/pasteSourceValidations/documentContainWacElements.js +2 -11
  35. package/lib/paste/pasteSourceValidations/documentContainWacElements.js.map +1 -1
  36. package/lib/paste/pasteSourceValidations/getPasteSource.d.ts +2 -1
  37. package/lib/paste/pasteSourceValidations/getPasteSource.js.map +1 -1
  38. package/lib-amd/edit/deleteSteps/deleteAllSegmentBefore.js +3 -0
  39. package/lib-amd/edit/deleteSteps/deleteAllSegmentBefore.js.map +1 -1
  40. package/lib-amd/edit/deleteSteps/deleteCollapsedSelection.js +3 -0
  41. package/lib-amd/edit/deleteSteps/deleteCollapsedSelection.js.map +1 -1
  42. package/lib-amd/edit/deleteSteps/deleteWordSelection.js +3 -0
  43. package/lib-amd/edit/deleteSteps/deleteWordSelection.js.map +1 -1
  44. package/lib-amd/edit/keyboardInput.js +1 -1
  45. package/lib-amd/edit/keyboardInput.js.map +1 -1
  46. package/lib-amd/entityDelimiter/EntityDelimiterPlugin.js +3 -1
  47. package/lib-amd/entityDelimiter/EntityDelimiterPlugin.js.map +1 -1
  48. package/lib-amd/paste/ContentModelPastePlugin.d.ts +3 -1
  49. package/lib-amd/paste/ContentModelPastePlugin.js +5 -3
  50. package/lib-amd/paste/ContentModelPastePlugin.js.map +1 -1
  51. package/lib-amd/paste/Excel/processPastedContentFromExcel.d.ts +1 -1
  52. package/lib-amd/paste/Excel/processPastedContentFromExcel.js +2 -2
  53. package/lib-amd/paste/Excel/processPastedContentFromExcel.js.map +1 -1
  54. package/lib-amd/paste/WacComponents/constants.d.ts +56 -0
  55. package/lib-amd/paste/WacComponents/constants.js +87 -0
  56. package/lib-amd/paste/WacComponents/constants.js.map +1 -0
  57. package/lib-amd/paste/WacComponents/processPastedContentWacComponents.js +19 -35
  58. package/lib-amd/paste/WacComponents/processPastedContentWacComponents.js.map +1 -1
  59. package/lib-amd/paste/WordDesktop/WordMetadata.d.ts +9 -0
  60. package/lib-amd/paste/WordDesktop/WordMetadata.js +5 -0
  61. package/lib-amd/paste/WordDesktop/WordMetadata.js.map +1 -0
  62. package/lib-amd/paste/WordDesktop/getStyleMetadata.d.ts +23 -0
  63. package/lib-amd/paste/WordDesktop/getStyleMetadata.js +79 -0
  64. package/lib-amd/paste/WordDesktop/getStyleMetadata.js.map +1 -0
  65. package/lib-amd/paste/WordDesktop/processPastedContentFromWordDesktop.d.ts +2 -7
  66. package/lib-amd/paste/WordDesktop/processPastedContentFromWordDesktop.js +14 -15
  67. package/lib-amd/paste/WordDesktop/processPastedContentFromWordDesktop.js.map +1 -1
  68. package/lib-amd/paste/WordDesktop/processWordLists.d.ts +2 -1
  69. package/lib-amd/paste/WordDesktop/processWordLists.js +83 -85
  70. package/lib-amd/paste/WordDesktop/processWordLists.js.map +1 -1
  71. package/lib-amd/paste/pasteSourceValidations/documentContainWacElements.js +2 -12
  72. package/lib-amd/paste/pasteSourceValidations/documentContainWacElements.js.map +1 -1
  73. package/lib-amd/paste/pasteSourceValidations/getPasteSource.d.ts +2 -1
  74. package/lib-amd/paste/pasteSourceValidations/getPasteSource.js.map +1 -1
  75. package/lib-mjs/edit/deleteSteps/deleteAllSegmentBefore.js +3 -0
  76. package/lib-mjs/edit/deleteSteps/deleteAllSegmentBefore.js.map +1 -1
  77. package/lib-mjs/edit/deleteSteps/deleteCollapsedSelection.js +3 -0
  78. package/lib-mjs/edit/deleteSteps/deleteCollapsedSelection.js.map +1 -1
  79. package/lib-mjs/edit/deleteSteps/deleteWordSelection.js +3 -0
  80. package/lib-mjs/edit/deleteSteps/deleteWordSelection.js.map +1 -1
  81. package/lib-mjs/edit/keyboardInput.js +1 -1
  82. package/lib-mjs/edit/keyboardInput.js.map +1 -1
  83. package/lib-mjs/entityDelimiter/EntityDelimiterPlugin.js +3 -1
  84. package/lib-mjs/entityDelimiter/EntityDelimiterPlugin.js.map +1 -1
  85. package/lib-mjs/paste/ContentModelPastePlugin.d.ts +3 -1
  86. package/lib-mjs/paste/ContentModelPastePlugin.js +5 -3
  87. package/lib-mjs/paste/ContentModelPastePlugin.js.map +1 -1
  88. package/lib-mjs/paste/Excel/processPastedContentFromExcel.d.ts +1 -1
  89. package/lib-mjs/paste/Excel/processPastedContentFromExcel.js +2 -2
  90. package/lib-mjs/paste/Excel/processPastedContentFromExcel.js.map +1 -1
  91. package/lib-mjs/paste/WacComponents/constants.d.ts +56 -0
  92. package/lib-mjs/paste/WacComponents/constants.js +83 -0
  93. package/lib-mjs/paste/WacComponents/constants.js.map +1 -0
  94. package/lib-mjs/paste/WacComponents/processPastedContentWacComponents.js +12 -27
  95. package/lib-mjs/paste/WacComponents/processPastedContentWacComponents.js.map +1 -1
  96. package/lib-mjs/paste/WordDesktop/WordMetadata.d.ts +9 -0
  97. package/lib-mjs/paste/WordDesktop/WordMetadata.js +2 -0
  98. package/lib-mjs/paste/WordDesktop/WordMetadata.js.map +1 -0
  99. package/lib-mjs/paste/WordDesktop/getStyleMetadata.d.ts +23 -0
  100. package/lib-mjs/paste/WordDesktop/getStyleMetadata.js +76 -0
  101. package/lib-mjs/paste/WordDesktop/getStyleMetadata.js.map +1 -0
  102. package/lib-mjs/paste/WordDesktop/processPastedContentFromWordDesktop.d.ts +2 -7
  103. package/lib-mjs/paste/WordDesktop/processPastedContentFromWordDesktop.js +13 -12
  104. package/lib-mjs/paste/WordDesktop/processPastedContentFromWordDesktop.js.map +1 -1
  105. package/lib-mjs/paste/WordDesktop/processWordLists.d.ts +2 -1
  106. package/lib-mjs/paste/WordDesktop/processWordLists.js +84 -86
  107. package/lib-mjs/paste/WordDesktop/processWordLists.js.map +1 -1
  108. package/lib-mjs/paste/pasteSourceValidations/documentContainWacElements.js +1 -10
  109. package/lib-mjs/paste/pasteSourceValidations/documentContainWacElements.js.map +1 -1
  110. package/lib-mjs/paste/pasteSourceValidations/getPasteSource.d.ts +2 -1
  111. package/lib-mjs/paste/pasteSourceValidations/getPasteSource.js.map +1 -1
  112. package/package.json +5 -5
@@ -6,6 +6,9 @@ var roosterjs_content_model_core_1 = require("roosterjs-content-model-core");
6
6
  * @internal
7
7
  */
8
8
  var deleteAllSegmentBefore = function (context) {
9
+ if (context.deleteResult != 'notDeleted') {
10
+ return;
11
+ }
9
12
  var _a = context.insertPoint, paragraph = _a.paragraph, marker = _a.marker;
10
13
  var index = paragraph.segments.indexOf(marker);
11
14
  for (var i = index - 1; i >= 0; i--) {
@@ -1 +1 @@
1
- {"version":3,"file":"deleteAllSegmentBefore.js","sourceRoot":"","sources":["../../../../../packages-content-model/roosterjs-content-model-plugins/lib/edit/deleteSteps/deleteAllSegmentBefore.ts"],"names":[],"mappings":";;;AAAA,6EAA6D;AAG7D;;GAEG;AACI,IAAM,sBAAsB,GAAwB,UAAA,OAAO;IACxD,IAAA,KAAwB,OAAO,CAAC,WAAW,EAAzC,SAAS,eAAA,EAAE,MAAM,YAAwB,CAAC;IAClD,IAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAEjD,KAAK,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;QACjC,IAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAEtC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;QAE1B,IAAI,IAAA,4CAAa,EAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,EAAE;YAC1D,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC;SAClC;KACJ;AACL,CAAC,CAAC;AAbW,QAAA,sBAAsB,0BAajC","sourcesContent":["import { deleteSegment } from 'roosterjs-content-model-core';\nimport type { DeleteSelectionStep } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const deleteAllSegmentBefore: DeleteSelectionStep = context => {\n const { paragraph, marker } = context.insertPoint;\n const index = paragraph.segments.indexOf(marker);\n\n for (let i = index - 1; i >= 0; i--) {\n const segment = paragraph.segments[i];\n\n segment.isSelected = true;\n\n if (deleteSegment(paragraph, segment, context.formatContext)) {\n context.deleteResult = 'range';\n }\n }\n};\n"]}
1
+ {"version":3,"file":"deleteAllSegmentBefore.js","sourceRoot":"","sources":["../../../../../packages-content-model/roosterjs-content-model-plugins/lib/edit/deleteSteps/deleteAllSegmentBefore.ts"],"names":[],"mappings":";;;AAAA,6EAA6D;AAG7D;;GAEG;AACI,IAAM,sBAAsB,GAAwB,UAAA,OAAO;IAC9D,IAAI,OAAO,CAAC,YAAY,IAAI,YAAY,EAAE;QACtC,OAAO;KACV;IAEK,IAAA,KAAwB,OAAO,CAAC,WAAW,EAAzC,SAAS,eAAA,EAAE,MAAM,YAAwB,CAAC;IAClD,IAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAEjD,KAAK,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;QACjC,IAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAEtC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;QAE1B,IAAI,IAAA,4CAAa,EAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,EAAE;YAC1D,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC;SAClC;KACJ;AACL,CAAC,CAAC;AAjBW,QAAA,sBAAsB,0BAiBjC","sourcesContent":["import { deleteSegment } from 'roosterjs-content-model-core';\nimport type { DeleteSelectionStep } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const deleteAllSegmentBefore: DeleteSelectionStep = context => {\n if (context.deleteResult != 'notDeleted') {\n return;\n }\n\n const { paragraph, marker } = context.insertPoint;\n const index = paragraph.segments.indexOf(marker);\n\n for (let i = index - 1; i >= 0; i--) {\n const segment = paragraph.segments[i];\n\n segment.isSelected = true;\n\n if (deleteSegment(paragraph, segment, context.formatContext)) {\n context.deleteResult = 'range';\n }\n }\n};\n"]}
@@ -7,6 +7,9 @@ var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
7
7
  function getDeleteCollapsedSelection(direction) {
8
8
  return function (context) {
9
9
  var _a;
10
+ if (context.deleteResult != 'notDeleted') {
11
+ return;
12
+ }
10
13
  var isForward = direction == 'forward';
11
14
  var _b = context.insertPoint, paragraph = _b.paragraph, marker = _b.marker, path = _b.path, tableContext = _b.tableContext;
12
15
  var segments = paragraph.segments;
@@ -1 +1 @@
1
- {"version":3,"file":"deleteCollapsedSelection.js","sourceRoot":"","sources":["../../../../../packages-content-model/roosterjs-content-model-plugins/lib/edit/deleteSteps/deleteCollapsedSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { deleteBlock, deleteSegment } from 'roosterjs-content-model-core';\nimport { getLeafSiblingBlock } from '../utils/getLeafSiblingBlock';\nimport { setParagraphNotImplicit } from 'roosterjs-content-model-dom';\nimport type { BlockAndPath } from '../utils/getLeafSiblingBlock';\nimport type { ContentModelSegment, DeleteSelectionStep } from 'roosterjs-content-model-types';\n\nfunction getDeleteCollapsedSelection(direction: 'forward' | 'backward'): DeleteSelectionStep {\n return context => {\n const isForward = direction == 'forward';\n const { paragraph, marker, path, tableContext } = context.insertPoint;\n const segments = paragraph.segments;\n\n fixupBr(segments);\n\n const index = segments.indexOf(marker) + (isForward ? 1 : -1);\n const segmentToDelete = segments[index];\n let blockToDelete: BlockAndPath | null;\n\n if (segmentToDelete) {\n if (deleteSegment(paragraph, segmentToDelete, context.formatContext, direction)) {\n context.deleteResult = 'singleChar';\n\n // It is possible that we have deleted everything from this paragraph, so we need to mark it as not implicit\n // to avoid losing its format. See https://github.com/microsoft/roosterjs/issues/1953\n setParagraphNotImplicit(paragraph);\n }\n } else if ((blockToDelete = getLeafSiblingBlock(path, paragraph, isForward))) {\n const { block, path, siblingSegment } = blockToDelete;\n\n if (block.blockType == 'Paragraph') {\n if (siblingSegment) {\n // When selection is under general segment, need to check if it has a sibling sibling, and delete from it\n if (deleteSegment(block, siblingSegment, context.formatContext, direction)) {\n context.deleteResult = 'range';\n }\n } else {\n if (isForward) {\n context.lastParagraph = block;\n } else {\n if (block.segments[block.segments.length - 1]?.segmentType == 'Br') {\n block.segments.pop();\n }\n\n context.insertPoint = {\n marker,\n paragraph: block,\n path,\n tableContext,\n };\n context.lastParagraph = paragraph;\n delete block.cachedElement;\n }\n\n context.deleteResult = 'range';\n }\n\n // When go across table, getLeafSiblingBlock will return null, when we are here, we must be in the same table context\n context.lastTableContext = tableContext;\n } else {\n if (\n deleteBlock(\n path[0].blocks,\n block,\n undefined /*replacement*/,\n context.formatContext,\n direction\n )\n ) {\n context.deleteResult = 'range';\n }\n }\n } else {\n // We have nothing to delete, in this case we don't want browser handle it as well.\n // Because when Backspace on an empty document, it will also delete the only DIV and SPAN element, causes\n // editor is really empty. We don't want that happen. So the handling should stop here.\n context.deleteResult = 'nothingToDelete';\n }\n };\n}\n\n/**\n * If the last segment is BR, remove it for now. We may add it back later when normalize model.\n * So that if this is an empty paragraph, it will start to delete next block\n */\nfunction fixupBr(segments: ContentModelSegment[]) {\n if (segments[segments.length - 1]?.segmentType == 'Br') {\n const segmentsWithoutBr = segments.filter(x => x.segmentType != 'SelectionMarker');\n\n if (segmentsWithoutBr[segmentsWithoutBr.length - 2]?.segmentType != 'Br') {\n segments.pop();\n }\n }\n}\n\n/**\n * @internal if we didn't delete anything, and we want to delete forward, now perform it\n */\nexport const forwardDeleteCollapsedSelection = getDeleteCollapsedSelection('forward');\n\n/**\n * @internal if we didn't delete anything, and we want to delete backward, now perform it\n */\nexport const backwardDeleteCollapsedSelection = getDeleteCollapsedSelection('backward');\n"]}
1
+ {"version":3,"file":"deleteCollapsedSelection.js","sourceRoot":"","sources":["../../../../../packages-content-model/roosterjs-content-model-plugins/lib/edit/deleteSteps/deleteCollapsedSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { deleteBlock, deleteSegment } from 'roosterjs-content-model-core';\nimport { getLeafSiblingBlock } from '../utils/getLeafSiblingBlock';\nimport { setParagraphNotImplicit } from 'roosterjs-content-model-dom';\nimport type { BlockAndPath } from '../utils/getLeafSiblingBlock';\nimport type { ContentModelSegment, DeleteSelectionStep } from 'roosterjs-content-model-types';\n\nfunction getDeleteCollapsedSelection(direction: 'forward' | 'backward'): DeleteSelectionStep {\n return context => {\n if (context.deleteResult != 'notDeleted') {\n return;\n }\n\n const isForward = direction == 'forward';\n const { paragraph, marker, path, tableContext } = context.insertPoint;\n const segments = paragraph.segments;\n\n fixupBr(segments);\n\n const index = segments.indexOf(marker) + (isForward ? 1 : -1);\n const segmentToDelete = segments[index];\n let blockToDelete: BlockAndPath | null;\n\n if (segmentToDelete) {\n if (deleteSegment(paragraph, segmentToDelete, context.formatContext, direction)) {\n context.deleteResult = 'singleChar';\n\n // It is possible that we have deleted everything from this paragraph, so we need to mark it as not implicit\n // to avoid losing its format. See https://github.com/microsoft/roosterjs/issues/1953\n setParagraphNotImplicit(paragraph);\n }\n } else if ((blockToDelete = getLeafSiblingBlock(path, paragraph, isForward))) {\n const { block, path, siblingSegment } = blockToDelete;\n\n if (block.blockType == 'Paragraph') {\n if (siblingSegment) {\n // When selection is under general segment, need to check if it has a sibling sibling, and delete from it\n if (deleteSegment(block, siblingSegment, context.formatContext, direction)) {\n context.deleteResult = 'range';\n }\n } else {\n if (isForward) {\n context.lastParagraph = block;\n } else {\n if (block.segments[block.segments.length - 1]?.segmentType == 'Br') {\n block.segments.pop();\n }\n\n context.insertPoint = {\n marker,\n paragraph: block,\n path,\n tableContext,\n };\n context.lastParagraph = paragraph;\n delete block.cachedElement;\n }\n\n context.deleteResult = 'range';\n }\n\n // When go across table, getLeafSiblingBlock will return null, when we are here, we must be in the same table context\n context.lastTableContext = tableContext;\n } else {\n if (\n deleteBlock(\n path[0].blocks,\n block,\n undefined /*replacement*/,\n context.formatContext,\n direction\n )\n ) {\n context.deleteResult = 'range';\n }\n }\n } else {\n // We have nothing to delete, in this case we don't want browser handle it as well.\n // Because when Backspace on an empty document, it will also delete the only DIV and SPAN element, causes\n // editor is really empty. We don't want that happen. So the handling should stop here.\n context.deleteResult = 'nothingToDelete';\n }\n };\n}\n\n/**\n * If the last segment is BR, remove it for now. We may add it back later when normalize model.\n * So that if this is an empty paragraph, it will start to delete next block\n */\nfunction fixupBr(segments: ContentModelSegment[]) {\n if (segments[segments.length - 1]?.segmentType == 'Br') {\n const segmentsWithoutBr = segments.filter(x => x.segmentType != 'SelectionMarker');\n\n if (segmentsWithoutBr[segmentsWithoutBr.length - 2]?.segmentType != 'Br') {\n segments.pop();\n }\n }\n}\n\n/**\n * @internal if we didn't delete anything, and we want to delete forward, now perform it\n */\nexport const forwardDeleteCollapsedSelection = getDeleteCollapsedSelection('forward');\n\n/**\n * @internal if we didn't delete anything, and we want to delete backward, now perform it\n */\nexport const backwardDeleteCollapsedSelection = getDeleteCollapsedSelection('backward');\n"]}
@@ -15,6 +15,9 @@ var DeleteWordState;
15
15
  })(DeleteWordState || (DeleteWordState = {}));
16
16
  function getDeleteWordSelection(direction) {
17
17
  return function (context) {
18
+ if (context.deleteResult != 'notDeleted') {
19
+ return;
20
+ }
18
21
  var _a = context.insertPoint, marker = _a.marker, paragraph = _a.paragraph;
19
22
  var startIndex = paragraph.segments.indexOf(marker);
20
23
  var deleteNext = direction == 'forward';
@@ -1 +1 @@
1
- {"version":3,"file":"deleteWordSelection.js","sourceRoot":"","sources":["../../../../../packages-content-model/roosterjs-content-model-plugins/lib/edit/deleteSteps/deleteWordSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { isPunctuation, isSpace, normalizeText } from 'roosterjs-content-model-core';\nimport { isWhiteSpacePreserved } from 'roosterjs-content-model-dom';\nimport type {\n ContentModelParagraph,\n DeleteSelectionContext,\n DeleteSelectionStep,\n} from 'roosterjs-content-model-types';\n\nconst enum DeleteWordState {\n Start,\n Punctuation,\n Text,\n NonText,\n Space,\n End,\n}\n\ninterface CharInfo {\n text: boolean;\n space: boolean;\n punctuation: boolean;\n}\n\nfunction getDeleteWordSelection(direction: 'forward' | 'backward'): DeleteSelectionStep {\n return context => {\n const { marker, paragraph } = context.insertPoint;\n const startIndex = paragraph.segments.indexOf(marker);\n const deleteNext = direction == 'forward';\n\n const iterator = iterateSegments(paragraph, startIndex, deleteNext, context);\n let curr = iterator.next();\n\n for (let state = DeleteWordState.Start; state != DeleteWordState.End && !curr.done; ) {\n const { punctuation, space, text } = curr.value;\n\n // This is a state machine of how to delete a whole word together with space and punctuations.\n // For a full state machine chart, see\n // Forward delete: https://github.com/microsoft/roosterjs/blob/master/assets/design-charts/ForwardDeleteWord.png\n // Backward delete: https://github.com/microsoft/roosterjs/blob/master/assets/design-charts/BackwardDeleteWord.png\n switch (state) {\n case DeleteWordState.Start:\n state = space\n ? DeleteWordState.Space\n : punctuation\n ? DeleteWordState.Punctuation\n : DeleteWordState.Text;\n curr = iterator.next(true /*delete*/);\n break;\n\n case DeleteWordState.Punctuation:\n if (deleteNext && space) {\n state = DeleteWordState.NonText;\n curr = iterator.next(true /*delete*/);\n } else if (punctuation) {\n curr = iterator.next(true /*delete*/);\n } else {\n state = DeleteWordState.End;\n }\n break;\n\n case DeleteWordState.Text:\n if (deleteNext && space) {\n state = DeleteWordState.NonText;\n curr = iterator.next(true /*delete*/);\n } else if (text) {\n curr = iterator.next(true /*delete*/);\n } else {\n state = DeleteWordState.End;\n }\n break;\n\n case DeleteWordState.NonText:\n if (punctuation || !space) {\n state = DeleteWordState.End;\n } else {\n curr = iterator.next(true /*delete*/);\n }\n break;\n\n case DeleteWordState.Space:\n if (space) {\n curr = iterator.next(true /*delete*/);\n } else if (punctuation) {\n state = deleteNext ? DeleteWordState.NonText : DeleteWordState.Punctuation;\n curr = iterator.next(true /*delete*/);\n } else {\n state = deleteNext ? DeleteWordState.End : DeleteWordState.Text;\n }\n break;\n }\n }\n };\n}\n\nfunction* iterateSegments(\n paragraph: ContentModelParagraph,\n markerIndex: number,\n forward: boolean,\n context: DeleteSelectionContext\n): Generator<CharInfo, null, boolean> {\n const step = forward ? 1 : -1;\n const segments = paragraph.segments;\n const preserveWhiteSpace = isWhiteSpacePreserved(paragraph);\n\n for (let i = markerIndex + step; i >= 0 && i < segments.length; i += step) {\n const segment = segments[i];\n\n switch (segment.segmentType) {\n case 'Text':\n for (\n let j = forward ? 0 : segment.text.length - 1;\n j >= 0 && j < segment.text.length;\n j += step\n ) {\n const c = segment.text[j];\n const punctuation = isPunctuation(c);\n const space = isSpace(c);\n const text = !punctuation && !space;\n\n if (yield { punctuation, space, text }) {\n let newText = segment.text;\n\n newText = newText.substring(0, j) + newText.substring(j + 1);\n\n if (!preserveWhiteSpace) {\n newText = normalizeText(newText, forward);\n }\n\n context.deleteResult = 'range';\n\n if (newText) {\n segment.text = newText;\n\n if (step > 0) {\n j -= step;\n }\n } else {\n segments.splice(i, 1);\n\n if (step > 0) {\n i -= step;\n }\n\n break;\n }\n }\n }\n break;\n\n case 'Image':\n if (\n yield { punctuation: true, space: false, text: false } // Treat image as punctuation since they have the same behavior.\n ) {\n segments.splice(i, 1);\n\n if (step > 0) {\n i -= step;\n }\n\n context.deleteResult = 'range';\n }\n break;\n\n case 'SelectionMarker':\n break;\n\n default:\n return null;\n }\n }\n\n return null;\n}\n\n/**\n * @internal\n */\nexport const forwardDeleteWordSelection = getDeleteWordSelection('forward');\n\n/**\n * @internal\n */\nexport const backwardDeleteWordSelection = getDeleteWordSelection('backward');\n"]}
1
+ {"version":3,"file":"deleteWordSelection.js","sourceRoot":"","sources":["../../../../../packages-content-model/roosterjs-content-model-plugins/lib/edit/deleteSteps/deleteWordSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { isPunctuation, isSpace, normalizeText } from 'roosterjs-content-model-core';\nimport { isWhiteSpacePreserved } from 'roosterjs-content-model-dom';\nimport type {\n ContentModelParagraph,\n DeleteSelectionContext,\n DeleteSelectionStep,\n} from 'roosterjs-content-model-types';\n\nconst enum DeleteWordState {\n Start,\n Punctuation,\n Text,\n NonText,\n Space,\n End,\n}\n\ninterface CharInfo {\n text: boolean;\n space: boolean;\n punctuation: boolean;\n}\n\nfunction getDeleteWordSelection(direction: 'forward' | 'backward'): DeleteSelectionStep {\n return context => {\n if (context.deleteResult != 'notDeleted') {\n return;\n }\n\n const { marker, paragraph } = context.insertPoint;\n const startIndex = paragraph.segments.indexOf(marker);\n const deleteNext = direction == 'forward';\n\n const iterator = iterateSegments(paragraph, startIndex, deleteNext, context);\n let curr = iterator.next();\n\n for (let state = DeleteWordState.Start; state != DeleteWordState.End && !curr.done; ) {\n const { punctuation, space, text } = curr.value;\n\n // This is a state machine of how to delete a whole word together with space and punctuations.\n // For a full state machine chart, see\n // Forward delete: https://github.com/microsoft/roosterjs/blob/master/assets/design-charts/ForwardDeleteWord.png\n // Backward delete: https://github.com/microsoft/roosterjs/blob/master/assets/design-charts/BackwardDeleteWord.png\n switch (state) {\n case DeleteWordState.Start:\n state = space\n ? DeleteWordState.Space\n : punctuation\n ? DeleteWordState.Punctuation\n : DeleteWordState.Text;\n curr = iterator.next(true /*delete*/);\n break;\n\n case DeleteWordState.Punctuation:\n if (deleteNext && space) {\n state = DeleteWordState.NonText;\n curr = iterator.next(true /*delete*/);\n } else if (punctuation) {\n curr = iterator.next(true /*delete*/);\n } else {\n state = DeleteWordState.End;\n }\n break;\n\n case DeleteWordState.Text:\n if (deleteNext && space) {\n state = DeleteWordState.NonText;\n curr = iterator.next(true /*delete*/);\n } else if (text) {\n curr = iterator.next(true /*delete*/);\n } else {\n state = DeleteWordState.End;\n }\n break;\n\n case DeleteWordState.NonText:\n if (punctuation || !space) {\n state = DeleteWordState.End;\n } else {\n curr = iterator.next(true /*delete*/);\n }\n break;\n\n case DeleteWordState.Space:\n if (space) {\n curr = iterator.next(true /*delete*/);\n } else if (punctuation) {\n state = deleteNext ? DeleteWordState.NonText : DeleteWordState.Punctuation;\n curr = iterator.next(true /*delete*/);\n } else {\n state = deleteNext ? DeleteWordState.End : DeleteWordState.Text;\n }\n break;\n }\n }\n };\n}\n\nfunction* iterateSegments(\n paragraph: ContentModelParagraph,\n markerIndex: number,\n forward: boolean,\n context: DeleteSelectionContext\n): Generator<CharInfo, null, boolean> {\n const step = forward ? 1 : -1;\n const segments = paragraph.segments;\n const preserveWhiteSpace = isWhiteSpacePreserved(paragraph);\n\n for (let i = markerIndex + step; i >= 0 && i < segments.length; i += step) {\n const segment = segments[i];\n\n switch (segment.segmentType) {\n case 'Text':\n for (\n let j = forward ? 0 : segment.text.length - 1;\n j >= 0 && j < segment.text.length;\n j += step\n ) {\n const c = segment.text[j];\n const punctuation = isPunctuation(c);\n const space = isSpace(c);\n const text = !punctuation && !space;\n\n if (yield { punctuation, space, text }) {\n let newText = segment.text;\n\n newText = newText.substring(0, j) + newText.substring(j + 1);\n\n if (!preserveWhiteSpace) {\n newText = normalizeText(newText, forward);\n }\n\n context.deleteResult = 'range';\n\n if (newText) {\n segment.text = newText;\n\n if (step > 0) {\n j -= step;\n }\n } else {\n segments.splice(i, 1);\n\n if (step > 0) {\n i -= step;\n }\n\n break;\n }\n }\n }\n break;\n\n case 'Image':\n if (\n yield { punctuation: true, space: false, text: false } // Treat image as punctuation since they have the same behavior.\n ) {\n segments.splice(i, 1);\n\n if (step > 0) {\n i -= step;\n }\n\n context.deleteResult = 'range';\n }\n break;\n\n case 'SelectionMarker':\n break;\n\n default:\n return null;\n }\n }\n\n return null;\n}\n\n/**\n * @internal\n */\nexport const forwardDeleteWordSelection = getDeleteWordSelection('forward');\n\n/**\n * @internal\n */\nexport const backwardDeleteWordSelection = getDeleteWordSelection('backward');\n"]}
@@ -9,7 +9,7 @@ var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
9
9
  function keyboardInput(editor, rawEvent) {
10
10
  var selection = editor.getDOMSelection();
11
11
  if (shouldInputWithContentModel(selection, rawEvent)) {
12
- editor.addUndoSnapshot();
12
+ editor.takeSnapshot();
13
13
  editor.formatContentModel(function (model, context) {
14
14
  var _a;
15
15
  var result = (0, roosterjs_content_model_core_1.deleteSelection)(model, [], context);
@@ -1 +1 @@
1
- {"version":3,"file":"keyboardInput.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-plugins/lib/edit/keyboardInput.ts"],"names":[],"mappings":";;;AAAA,6EAA8E;AAC9E,2EAAoE;AAIpE;;GAEG;AACH,SAAgB,aAAa,CAAC,MAA2B,EAAE,QAAuB;IAC9E,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAE3C,IAAI,2BAA2B,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE;QAClD,MAAM,CAAC,eAAe,EAAE,CAAC;QAEzB,MAAM,CAAC,kBAAkB,CACrB,UAAC,KAAK,EAAE,OAAO;;YACX,IAAM,MAAM,GAAG,IAAA,8CAAe,EAAC,KAAK,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;YAEnD,0EAA0E;YAC1E,qFAAqF;YACrF,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;YAE/B,oJAAoJ;YACpJ,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAEhC,IAAI,MAAM,CAAC,YAAY,IAAI,OAAO,EAAE;gBAChC,2HAA2H;gBAC3H,OAAO,CAAC,gBAAgB,GAAG,MAAA,MAAM,CAAC,WAAW,0CAAE,MAAM,CAAC,MAAM,CAAC;gBAE7D,IAAA,mDAAqB,EAAC,KAAK,CAAC,CAAC;gBAE7B,sFAAsF;gBACtF,OAAO,IAAI,CAAC;aACf;iBAAM;gBACH,OAAO,KAAK,CAAC;aAChB;QACL,CAAC,EACD;YACI,QAAQ,UAAA;SACX,CACJ,CAAC;QAEF,OAAO,IAAI,CAAC;KACf;AACL,CAAC;AApCD,sCAoCC;AAED,SAAS,2BAA2B,CAAC,SAA8B,EAAE,QAAuB;IACxF,IAAI,CAAC,SAAS,EAAE;QACZ,OAAO,KAAK,CAAC,CAAC,oBAAoB;KACrC;SAAM,IACH,CAAC,IAAA,4CAAa,EAAC,QAAQ,CAAC;QACxB,CAAC,QAAQ,CAAC,GAAG,IAAI,OAAO,IAAI,QAAQ,CAAC,GAAG,IAAI,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,EAClF;QACE,OAAO,SAAS,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,0DAA0D;KAC7H;SAAM;QACH,OAAO,KAAK,CAAC;KAChB;AACL,CAAC","sourcesContent":["import { deleteSelection, isModifierKey } from 'roosterjs-content-model-core';\nimport { normalizeContentModel } from 'roosterjs-content-model-dom';\nimport type { IContentModelEditor } from 'roosterjs-content-model-editor';\nimport type { DOMSelection } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function keyboardInput(editor: IContentModelEditor, rawEvent: KeyboardEvent) {\n const selection = editor.getDOMSelection();\n\n if (shouldInputWithContentModel(selection, rawEvent)) {\n editor.addUndoSnapshot();\n\n editor.formatContentModel(\n (model, context) => {\n const result = deleteSelection(model, [], context);\n\n // We have deleted selection then we will let browser to handle the input.\n // With this combined operation, we don't wan to mass up the cached model so clear it\n context.clearModelCache = true;\n\n // Skip undo snapshot here and add undo snapshot before the operation so that we don't add another undo snapshot in middle of this replace operation\n context.skipUndoSnapshot = true;\n\n if (result.deleteResult == 'range') {\n // We have deleted something, next input should inherit the segment format from deleted content, so set pending format here\n context.newPendingFormat = result.insertPoint?.marker.format;\n\n normalizeContentModel(model);\n\n // Do not preventDefault since we still want browser to handle the final input for now\n return true;\n } else {\n return false;\n }\n },\n {\n rawEvent,\n }\n );\n\n return true;\n }\n}\n\nfunction shouldInputWithContentModel(selection: DOMSelection | null, rawEvent: KeyboardEvent) {\n if (!selection) {\n return false; // Nothing to delete\n } else if (\n !isModifierKey(rawEvent) &&\n (rawEvent.key == 'Enter' || rawEvent.key == 'Space' || rawEvent.key.length == 1)\n ) {\n return selection.type != 'range' || !selection.range.collapsed; // TODO: Also handle Enter key even selection is collapsed\n } else {\n return false;\n }\n}\n"]}
1
+ {"version":3,"file":"keyboardInput.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-plugins/lib/edit/keyboardInput.ts"],"names":[],"mappings":";;;AAAA,6EAA8E;AAC9E,2EAAoE;AAIpE;;GAEG;AACH,SAAgB,aAAa,CAAC,MAA2B,EAAE,QAAuB;IAC9E,IAAM,SAAS,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;IAE3C,IAAI,2BAA2B,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE;QAClD,MAAM,CAAC,YAAY,EAAE,CAAC;QAEtB,MAAM,CAAC,kBAAkB,CACrB,UAAC,KAAK,EAAE,OAAO;;YACX,IAAM,MAAM,GAAG,IAAA,8CAAe,EAAC,KAAK,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;YAEnD,0EAA0E;YAC1E,qFAAqF;YACrF,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;YAE/B,oJAAoJ;YACpJ,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAEhC,IAAI,MAAM,CAAC,YAAY,IAAI,OAAO,EAAE;gBAChC,2HAA2H;gBAC3H,OAAO,CAAC,gBAAgB,GAAG,MAAA,MAAM,CAAC,WAAW,0CAAE,MAAM,CAAC,MAAM,CAAC;gBAE7D,IAAA,mDAAqB,EAAC,KAAK,CAAC,CAAC;gBAE7B,sFAAsF;gBACtF,OAAO,IAAI,CAAC;aACf;iBAAM;gBACH,OAAO,KAAK,CAAC;aAChB;QACL,CAAC,EACD;YACI,QAAQ,UAAA;SACX,CACJ,CAAC;QAEF,OAAO,IAAI,CAAC;KACf;AACL,CAAC;AApCD,sCAoCC;AAED,SAAS,2BAA2B,CAAC,SAA8B,EAAE,QAAuB;IACxF,IAAI,CAAC,SAAS,EAAE;QACZ,OAAO,KAAK,CAAC,CAAC,oBAAoB;KACrC;SAAM,IACH,CAAC,IAAA,4CAAa,EAAC,QAAQ,CAAC;QACxB,CAAC,QAAQ,CAAC,GAAG,IAAI,OAAO,IAAI,QAAQ,CAAC,GAAG,IAAI,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,EAClF;QACE,OAAO,SAAS,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,0DAA0D;KAC7H;SAAM;QACH,OAAO,KAAK,CAAC;KAChB;AACL,CAAC","sourcesContent":["import { deleteSelection, isModifierKey } from 'roosterjs-content-model-core';\nimport { normalizeContentModel } from 'roosterjs-content-model-dom';\nimport type { IContentModelEditor } from 'roosterjs-content-model-editor';\nimport type { DOMSelection } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport function keyboardInput(editor: IContentModelEditor, rawEvent: KeyboardEvent) {\n const selection = editor.getDOMSelection();\n\n if (shouldInputWithContentModel(selection, rawEvent)) {\n editor.takeSnapshot();\n\n editor.formatContentModel(\n (model, context) => {\n const result = deleteSelection(model, [], context);\n\n // We have deleted selection then we will let browser to handle the input.\n // With this combined operation, we don't wan to mass up the cached model so clear it\n context.clearModelCache = true;\n\n // Skip undo snapshot here and add undo snapshot before the operation so that we don't add another undo snapshot in middle of this replace operation\n context.skipUndoSnapshot = true;\n\n if (result.deleteResult == 'range') {\n // We have deleted something, next input should inherit the segment format from deleted content, so set pending format here\n context.newPendingFormat = result.insertPoint?.marker.format;\n\n normalizeContentModel(model);\n\n // Do not preventDefault since we still want browser to handle the final input for now\n return true;\n } else {\n return false;\n }\n },\n {\n rawEvent,\n }\n );\n\n return true;\n }\n}\n\nfunction shouldInputWithContentModel(selection: DOMSelection | null, rawEvent: KeyboardEvent) {\n if (!selection) {\n return false; // Nothing to delete\n } else if (\n !isModifierKey(rawEvent) &&\n (rawEvent.key == 'Enter' || rawEvent.key == 'Space' || rawEvent.key.length == 1)\n ) {\n return selection.type != 'range' || !selection.range.collapsed; // TODO: Also handle Enter key even selection is collapsed\n } else {\n return false;\n }\n}\n"]}
@@ -108,7 +108,9 @@ function normalizeDelimitersInEditor(editor) {
108
108
  exports.normalizeDelimitersInEditor = normalizeDelimitersInEditor;
109
109
  function addDelimitersIfNeeded(nodes) {
110
110
  nodes.forEach(function (node) {
111
- if ((0, roosterjs_content_model_dom_1.isEntityElement)(node)) {
111
+ if ((0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'ELEMENT_NODE') &&
112
+ (0, roosterjs_content_model_dom_1.isEntityElement)(node) &&
113
+ !node.isContentEditable) {
112
114
  (0, roosterjs_content_model_dom_1.addDelimiters)(node.ownerDocument, node);
113
115
  }
114
116
  });
@@ -1 +1 @@
1
- {"version":3,"file":"EntityDelimiterPlugin.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-plugins/lib/entityDelimiter/EntityDelimiterPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { isCharacterValue } from 'roosterjs-content-model-core';\nimport {\n addDelimiters,\n isBlockElement,\n isEntityElement,\n isNodeOfType,\n} from 'roosterjs-content-model-dom';\nimport {\n DelimiterClasses,\n Keys,\n NodeType,\n PluginEventType,\n PositionType,\n SelectionRangeTypes,\n} from 'roosterjs-editor-types';\nimport {\n Position,\n createRange,\n getDelimiterFromElement,\n getEntityFromElement,\n getEntitySelector,\n matchesSelector,\n splitTextNode,\n} from 'roosterjs-editor-dom';\nimport type {\n EditorPlugin,\n IEditor,\n PluginEvent,\n PluginKeyDownEvent,\n} from 'roosterjs-editor-types';\nimport type { IContentModelEditor } from 'roosterjs-content-model-editor';\n\nconst DELIMITER_SELECTOR =\n '.' + DelimiterClasses.DELIMITER_AFTER + ',.' + DelimiterClasses.DELIMITER_BEFORE;\nconst ZERO_WIDTH_SPACE = '\\u200B';\nconst INLINE_ENTITY_SELECTOR = 'span' + getEntitySelector();\n\n/**\n * Entity delimiter plugin helps maintain delimiter elements around an entity so that user can put focus before/after an entity\n */\nexport class EntityDelimiterPlugin implements EditorPlugin {\n private editor: IContentModelEditor | null = null;\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'EntityDelimiter';\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 as IContentModelEditor;\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.editor = null;\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 switch (event.eventType) {\n case PluginEventType.ContentChanged:\n case PluginEventType.EditorReady:\n normalizeDelimitersInEditor(this.editor);\n break;\n\n case PluginEventType.BeforePaste:\n const { fragment } = event;\n addDelimitersIfNeeded(fragment.querySelectorAll(INLINE_ENTITY_SELECTOR));\n\n break;\n\n case PluginEventType.ExtractContentWithDom:\n case PluginEventType.BeforeCutCopy:\n event.clonedRoot.querySelectorAll(DELIMITER_SELECTOR).forEach(node => {\n if (getDelimiterFromElement(node)) {\n removeNode(node);\n } else {\n removeDelimiterAttr(node);\n }\n });\n break;\n\n case PluginEventType.KeyDown:\n handleKeyDownEvent(this.editor, event);\n break;\n }\n }\n }\n}\n\nfunction preventTypeInDelimiter(delimiter: HTMLElement) {\n delimiter.normalize();\n const textNode = delimiter.firstChild as Node;\n const index = textNode.nodeValue?.indexOf(ZERO_WIDTH_SPACE) ?? -1;\n if (index >= 0) {\n splitTextNode(<Text>textNode, index == 0 ? 1 : index, false /* returnFirstPart */);\n let nodeToMove: Node | undefined;\n delimiter.childNodes.forEach(node => {\n if (node.nodeValue !== ZERO_WIDTH_SPACE) {\n nodeToMove = node;\n }\n });\n if (nodeToMove) {\n delimiter.parentElement?.insertBefore(\n nodeToMove,\n delimiter.className == DelimiterClasses.DELIMITER_BEFORE\n ? delimiter\n : delimiter.nextSibling\n );\n const selection = nodeToMove.ownerDocument?.getSelection();\n\n if (selection) {\n selection.setPosition(\n nodeToMove,\n new Position(nodeToMove, PositionType.End).offset\n );\n }\n }\n }\n}\n\n/**\n * @internal\n */\nexport function normalizeDelimitersInEditor(editor: IEditor) {\n removeInvalidDelimiters(editor.queryElements(DELIMITER_SELECTOR));\n addDelimitersIfNeeded(editor.queryElements(INLINE_ENTITY_SELECTOR));\n}\n\nfunction addDelimitersIfNeeded(nodes: Element[] | NodeListOf<Element>) {\n nodes.forEach(node => {\n if (isEntityElement(node)) {\n addDelimiters(node.ownerDocument, node as HTMLElement);\n }\n });\n}\n\nfunction removeNode(el: Node | undefined | null) {\n el?.parentElement?.removeChild(el);\n}\n\nfunction removeInvalidDelimiters(nodes: Element[] | NodeListOf<Element>) {\n nodes.forEach(node => {\n if (getDelimiterFromElement(node)) {\n const sibling = node.classList.contains(DelimiterClasses.DELIMITER_BEFORE)\n ? node.nextElementSibling\n : node.previousElementSibling;\n if (!(isNodeOfType(sibling, 'ELEMENT_NODE') && getEntityFromElement(sibling))) {\n removeNode(node);\n }\n } else {\n removeDelimiterAttr(node);\n }\n });\n}\n\nfunction removeDelimiterAttr(node: Element | undefined | null, checkEntity: boolean = true) {\n if (!node) {\n return;\n }\n\n const isAfter = node.classList.contains(DelimiterClasses.DELIMITER_AFTER);\n const entitySibling = isAfter ? node.previousElementSibling : node.nextElementSibling;\n if (checkEntity && entitySibling && isEntityElement(entitySibling)) {\n return;\n }\n\n node.classList.remove(DelimiterClasses.DELIMITER_AFTER, DelimiterClasses.DELIMITER_BEFORE);\n\n node.normalize();\n node.childNodes.forEach(cn => {\n const index = cn.textContent?.indexOf(ZERO_WIDTH_SPACE) ?? -1;\n if (index >= 0) {\n createRange(cn, index, cn, index + 1)?.deleteContents();\n }\n });\n}\n\nfunction handleCollapsedEnter(editor: IEditor, delimiter: HTMLElement) {\n const isAfter = delimiter.classList.contains(DelimiterClasses.DELIMITER_AFTER);\n const entity = !isAfter ? delimiter.nextSibling : delimiter.previousSibling;\n const block = getBlock(editor, delimiter);\n\n editor.runAsync(() => {\n if (!block) {\n return;\n }\n const blockToCheck = isAfter ? block.nextSibling : block.previousSibling;\n if (blockToCheck && isNodeOfType(blockToCheck, 'ELEMENT_NODE')) {\n const delimiters = blockToCheck.querySelectorAll(DELIMITER_SELECTOR);\n // Check if the last or first delimiter still contain the delimiter class and remove it.\n const delimiterToCheck = delimiters.item(isAfter ? 0 : delimiters.length - 1);\n removeDelimiterAttr(delimiterToCheck);\n }\n\n if (entity && isEntityElement(entity)) {\n const entityElement = entity as HTMLElement;\n const { nextElementSibling, previousElementSibling } = entityElement;\n [nextElementSibling, previousElementSibling].forEach(el => {\n // Check if after Enter the ZWS got removed but we still have a element with the class\n // Remove the attributes of the element if it is invalid now.\n if (el && matchesSelector(el, DELIMITER_SELECTOR) && !getDelimiterFromElement(el)) {\n removeDelimiterAttr(el, false /* checkEntity */);\n }\n });\n\n // Add delimiters to the entity if needed because on Enter we can sometimes lose the ZWS of the element.\n addDelimiters(entityElement.ownerDocument, entityElement);\n }\n });\n}\n\nconst getPosition = (container: HTMLElement | null) => {\n if (container && getDelimiterFromElement(container)) {\n const isAfter = container.classList.contains(DelimiterClasses.DELIMITER_AFTER);\n return new Position(container, isAfter ? PositionType.After : PositionType.Before);\n }\n return undefined;\n};\n\nfunction getBlock(editor: IEditor, element: Node | undefined) {\n if (!element) {\n return undefined;\n }\n\n let block = editor.getBlockElementAtNode(element)?.getStartNode();\n\n while (block && (!isNodeOfType(block, 'ELEMENT_NODE') || !isBlockElement(block))) {\n block = editor.contains(block.parentElement) ? block.parentElement! : undefined;\n }\n\n return block;\n}\n\nfunction handleSelectionNotCollapsed(editor: IEditor, range: Range, event: KeyboardEvent) {\n const { startContainer, endContainer, startOffset, endOffset } = range;\n\n const startElement = editor.getElementAtCursor(DELIMITER_SELECTOR, startContainer);\n const endElement = editor.getElementAtCursor(DELIMITER_SELECTOR, endContainer);\n\n const startUpdate = getPosition(startElement);\n const endUpdate = getPosition(endElement);\n\n if (startUpdate || endUpdate) {\n editor.select(\n startUpdate ?? new Position(startContainer, startOffset),\n endUpdate ?? new Position(endContainer, endOffset)\n );\n }\n editor.runAsync(aEditor => {\n const delimiter = aEditor.getElementAtCursor(DELIMITER_SELECTOR);\n if (delimiter) {\n preventTypeInDelimiter(delimiter);\n if (event.which === Keys.ENTER) {\n removeDelimiterAttr(delimiter);\n }\n }\n });\n}\n\nfunction handleKeyDownEvent(editor: IEditor, event: PluginKeyDownEvent) {\n const range = editor.getSelectionRangeEx();\n const { rawEvent } = event;\n if (range.type != SelectionRangeTypes.Normal) {\n return;\n }\n\n if (range.areAllCollapsed && (isCharacterValue(rawEvent) || rawEvent.which === Keys.ENTER)) {\n const position = editor.getFocusedPosition()?.normalize();\n if (!position) {\n return;\n }\n\n const { element, node } = position;\n const refNode = element == node ? element.childNodes.item(position.offset) : element;\n\n const delimiter = editor.getElementAtCursor(DELIMITER_SELECTOR, refNode);\n if (!delimiter) {\n return;\n }\n\n if (rawEvent.which === Keys.ENTER) {\n handleCollapsedEnter(editor, delimiter);\n } else if (delimiter.firstChild?.nodeType == NodeType.Text) {\n editor.runAsync(() => preventTypeInDelimiter(delimiter));\n }\n } else if (!range.areAllCollapsed && !rawEvent.shiftKey && rawEvent.which != Keys.SHIFT) {\n const currentRange = range.ranges[0];\n if (!currentRange) {\n return;\n }\n handleSelectionNotCollapsed(editor, currentRange, rawEvent);\n }\n}\n"]}
1
+ {"version":3,"file":"EntityDelimiterPlugin.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-plugins/lib/entityDelimiter/EntityDelimiterPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { isCharacterValue } from 'roosterjs-content-model-core';\nimport {\n addDelimiters,\n isBlockElement,\n isEntityElement,\n isNodeOfType,\n} from 'roosterjs-content-model-dom';\nimport {\n DelimiterClasses,\n Keys,\n NodeType,\n PluginEventType,\n PositionType,\n SelectionRangeTypes,\n} from 'roosterjs-editor-types';\nimport {\n Position,\n createRange,\n getDelimiterFromElement,\n getEntityFromElement,\n getEntitySelector,\n matchesSelector,\n splitTextNode,\n} from 'roosterjs-editor-dom';\nimport type {\n EditorPlugin,\n IEditor,\n PluginEvent,\n PluginKeyDownEvent,\n} from 'roosterjs-editor-types';\nimport type { IContentModelEditor } from 'roosterjs-content-model-editor';\n\nconst DELIMITER_SELECTOR =\n '.' + DelimiterClasses.DELIMITER_AFTER + ',.' + DelimiterClasses.DELIMITER_BEFORE;\nconst ZERO_WIDTH_SPACE = '\\u200B';\nconst INLINE_ENTITY_SELECTOR = 'span' + getEntitySelector();\n\n/**\n * Entity delimiter plugin helps maintain delimiter elements around an entity so that user can put focus before/after an entity\n */\nexport class EntityDelimiterPlugin implements EditorPlugin {\n private editor: IContentModelEditor | null = null;\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'EntityDelimiter';\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 as IContentModelEditor;\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.editor = null;\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 switch (event.eventType) {\n case PluginEventType.ContentChanged:\n case PluginEventType.EditorReady:\n normalizeDelimitersInEditor(this.editor);\n break;\n\n case PluginEventType.BeforePaste:\n const { fragment } = event;\n addDelimitersIfNeeded(fragment.querySelectorAll(INLINE_ENTITY_SELECTOR));\n\n break;\n\n case PluginEventType.ExtractContentWithDom:\n case PluginEventType.BeforeCutCopy:\n event.clonedRoot.querySelectorAll(DELIMITER_SELECTOR).forEach(node => {\n if (getDelimiterFromElement(node)) {\n removeNode(node);\n } else {\n removeDelimiterAttr(node);\n }\n });\n break;\n\n case PluginEventType.KeyDown:\n handleKeyDownEvent(this.editor, event);\n break;\n }\n }\n }\n}\n\nfunction preventTypeInDelimiter(delimiter: HTMLElement) {\n delimiter.normalize();\n const textNode = delimiter.firstChild as Node;\n const index = textNode.nodeValue?.indexOf(ZERO_WIDTH_SPACE) ?? -1;\n if (index >= 0) {\n splitTextNode(<Text>textNode, index == 0 ? 1 : index, false /* returnFirstPart */);\n let nodeToMove: Node | undefined;\n delimiter.childNodes.forEach(node => {\n if (node.nodeValue !== ZERO_WIDTH_SPACE) {\n nodeToMove = node;\n }\n });\n if (nodeToMove) {\n delimiter.parentElement?.insertBefore(\n nodeToMove,\n delimiter.className == DelimiterClasses.DELIMITER_BEFORE\n ? delimiter\n : delimiter.nextSibling\n );\n const selection = nodeToMove.ownerDocument?.getSelection();\n\n if (selection) {\n selection.setPosition(\n nodeToMove,\n new Position(nodeToMove, PositionType.End).offset\n );\n }\n }\n }\n}\n\n/**\n * @internal\n */\nexport function normalizeDelimitersInEditor(editor: IEditor) {\n removeInvalidDelimiters(editor.queryElements(DELIMITER_SELECTOR));\n addDelimitersIfNeeded(editor.queryElements(INLINE_ENTITY_SELECTOR));\n}\n\nfunction addDelimitersIfNeeded(nodes: Element[] | NodeListOf<Element>) {\n nodes.forEach(node => {\n if (\n isNodeOfType(node, 'ELEMENT_NODE') &&\n isEntityElement(node) &&\n !node.isContentEditable\n ) {\n addDelimiters(node.ownerDocument, node as HTMLElement);\n }\n });\n}\n\nfunction removeNode(el: Node | undefined | null) {\n el?.parentElement?.removeChild(el);\n}\n\nfunction removeInvalidDelimiters(nodes: Element[] | NodeListOf<Element>) {\n nodes.forEach(node => {\n if (getDelimiterFromElement(node)) {\n const sibling = node.classList.contains(DelimiterClasses.DELIMITER_BEFORE)\n ? node.nextElementSibling\n : node.previousElementSibling;\n if (!(isNodeOfType(sibling, 'ELEMENT_NODE') && getEntityFromElement(sibling))) {\n removeNode(node);\n }\n } else {\n removeDelimiterAttr(node);\n }\n });\n}\n\nfunction removeDelimiterAttr(node: Element | undefined | null, checkEntity: boolean = true) {\n if (!node) {\n return;\n }\n\n const isAfter = node.classList.contains(DelimiterClasses.DELIMITER_AFTER);\n const entitySibling = isAfter ? node.previousElementSibling : node.nextElementSibling;\n if (checkEntity && entitySibling && isEntityElement(entitySibling)) {\n return;\n }\n\n node.classList.remove(DelimiterClasses.DELIMITER_AFTER, DelimiterClasses.DELIMITER_BEFORE);\n\n node.normalize();\n node.childNodes.forEach(cn => {\n const index = cn.textContent?.indexOf(ZERO_WIDTH_SPACE) ?? -1;\n if (index >= 0) {\n createRange(cn, index, cn, index + 1)?.deleteContents();\n }\n });\n}\n\nfunction handleCollapsedEnter(editor: IEditor, delimiter: HTMLElement) {\n const isAfter = delimiter.classList.contains(DelimiterClasses.DELIMITER_AFTER);\n const entity = !isAfter ? delimiter.nextSibling : delimiter.previousSibling;\n const block = getBlock(editor, delimiter);\n\n editor.runAsync(() => {\n if (!block) {\n return;\n }\n const blockToCheck = isAfter ? block.nextSibling : block.previousSibling;\n if (blockToCheck && isNodeOfType(blockToCheck, 'ELEMENT_NODE')) {\n const delimiters = blockToCheck.querySelectorAll(DELIMITER_SELECTOR);\n // Check if the last or first delimiter still contain the delimiter class and remove it.\n const delimiterToCheck = delimiters.item(isAfter ? 0 : delimiters.length - 1);\n removeDelimiterAttr(delimiterToCheck);\n }\n\n if (entity && isEntityElement(entity)) {\n const entityElement = entity as HTMLElement;\n const { nextElementSibling, previousElementSibling } = entityElement;\n [nextElementSibling, previousElementSibling].forEach(el => {\n // Check if after Enter the ZWS got removed but we still have a element with the class\n // Remove the attributes of the element if it is invalid now.\n if (el && matchesSelector(el, DELIMITER_SELECTOR) && !getDelimiterFromElement(el)) {\n removeDelimiterAttr(el, false /* checkEntity */);\n }\n });\n\n // Add delimiters to the entity if needed because on Enter we can sometimes lose the ZWS of the element.\n addDelimiters(entityElement.ownerDocument, entityElement);\n }\n });\n}\n\nconst getPosition = (container: HTMLElement | null) => {\n if (container && getDelimiterFromElement(container)) {\n const isAfter = container.classList.contains(DelimiterClasses.DELIMITER_AFTER);\n return new Position(container, isAfter ? PositionType.After : PositionType.Before);\n }\n return undefined;\n};\n\nfunction getBlock(editor: IEditor, element: Node | undefined) {\n if (!element) {\n return undefined;\n }\n\n let block = editor.getBlockElementAtNode(element)?.getStartNode();\n\n while (block && (!isNodeOfType(block, 'ELEMENT_NODE') || !isBlockElement(block))) {\n block = editor.contains(block.parentElement) ? block.parentElement! : undefined;\n }\n\n return block;\n}\n\nfunction handleSelectionNotCollapsed(editor: IEditor, range: Range, event: KeyboardEvent) {\n const { startContainer, endContainer, startOffset, endOffset } = range;\n\n const startElement = editor.getElementAtCursor(DELIMITER_SELECTOR, startContainer);\n const endElement = editor.getElementAtCursor(DELIMITER_SELECTOR, endContainer);\n\n const startUpdate = getPosition(startElement);\n const endUpdate = getPosition(endElement);\n\n if (startUpdate || endUpdate) {\n editor.select(\n startUpdate ?? new Position(startContainer, startOffset),\n endUpdate ?? new Position(endContainer, endOffset)\n );\n }\n editor.runAsync(aEditor => {\n const delimiter = aEditor.getElementAtCursor(DELIMITER_SELECTOR);\n if (delimiter) {\n preventTypeInDelimiter(delimiter);\n if (event.which === Keys.ENTER) {\n removeDelimiterAttr(delimiter);\n }\n }\n });\n}\n\nfunction handleKeyDownEvent(editor: IEditor, event: PluginKeyDownEvent) {\n const range = editor.getSelectionRangeEx();\n const { rawEvent } = event;\n if (range.type != SelectionRangeTypes.Normal) {\n return;\n }\n\n if (range.areAllCollapsed && (isCharacterValue(rawEvent) || rawEvent.which === Keys.ENTER)) {\n const position = editor.getFocusedPosition()?.normalize();\n if (!position) {\n return;\n }\n\n const { element, node } = position;\n const refNode = element == node ? element.childNodes.item(position.offset) : element;\n\n const delimiter = editor.getElementAtCursor(DELIMITER_SELECTOR, refNode);\n if (!delimiter) {\n return;\n }\n\n if (rawEvent.which === Keys.ENTER) {\n handleCollapsedEnter(editor, delimiter);\n } else if (delimiter.firstChild?.nodeType == NodeType.Text) {\n editor.runAsync(() => preventTypeInDelimiter(delimiter));\n }\n } else if (!range.areAllCollapsed && !rawEvent.shiftKey && rawEvent.which != Keys.SHIFT) {\n const currentRange = range.ranges[0];\n if (!currentRange) {\n return;\n }\n handleSelectionNotCollapsed(editor, currentRange, rawEvent);\n }\n}\n"]}
@@ -9,12 +9,14 @@ import type { EditorPlugin, IEditor, PluginEvent } from 'roosterjs-editor-types'
9
9
  */
10
10
  export declare class ContentModelPastePlugin implements EditorPlugin {
11
11
  private unknownTagReplacement;
12
+ private allowExcelNoBorderTable?;
12
13
  private editor;
13
14
  /**
14
15
  * Construct a new instance of Paste class
15
16
  * @param unknownTagReplacement Replace solution of unknown tags, default behavior is to replace with SPAN
17
+ * @param allowExcelNoBorderTable Allow table copied from Excel without border
16
18
  */
17
- constructor(unknownTagReplacement?: string);
19
+ constructor(unknownTagReplacement?: string, allowExcelNoBorderTable?: boolean | undefined);
18
20
  /**
19
21
  * Get name of this plugin
20
22
  */
@@ -32,10 +32,12 @@ var ContentModelPastePlugin = /** @class */ (function () {
32
32
  /**
33
33
  * Construct a new instance of Paste class
34
34
  * @param unknownTagReplacement Replace solution of unknown tags, default behavior is to replace with SPAN
35
+ * @param allowExcelNoBorderTable Allow table copied from Excel without border
35
36
  */
36
- function ContentModelPastePlugin(unknownTagReplacement) {
37
+ function ContentModelPastePlugin(unknownTagReplacement, allowExcelNoBorderTable) {
37
38
  if (unknownTagReplacement === void 0) { unknownTagReplacement = 'SPAN'; }
38
39
  this.unknownTagReplacement = unknownTagReplacement;
40
+ this.allowExcelNoBorderTable = allowExcelNoBorderTable;
39
41
  this.editor = null;
40
42
  }
41
43
  /**
@@ -80,7 +82,7 @@ var ContentModelPastePlugin = /** @class */ (function () {
80
82
  var pasteType = PasteTypeMap[ev.pasteType];
81
83
  switch (pasteSource) {
82
84
  case 'wordDesktop':
83
- (0, processPastedContentFromWordDesktop_1.processPastedContentFromWordDesktop)(ev);
85
+ (0, processPastedContentFromWordDesktop_1.processPastedContentFromWordDesktop)(ev, this.editor.getTrustedHTMLHandler());
84
86
  break;
85
87
  case 'wacComponents':
86
88
  (0, processPastedContentWacComponents_1.processPastedContentWacComponents)(ev);
@@ -89,7 +91,7 @@ var ContentModelPastePlugin = /** @class */ (function () {
89
91
  case 'excelDesktop':
90
92
  if (pasteType === 'normal' || pasteType === 'mergeFormat') {
91
93
  // Handle HTML copied from Excel
92
- (0, processPastedContentFromExcel_1.processPastedContentFromExcel)(ev, this.editor.getTrustedHTMLHandler());
94
+ (0, processPastedContentFromExcel_1.processPastedContentFromExcel)(ev, this.editor.getTrustedHTMLHandler(), this.allowExcelNoBorderTable);
93
95
  }
94
96
  break;
95
97
  case 'googleSheets':
@@ -1 +1 @@
1
- {"version":3,"file":"ContentModelPastePlugin.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-plugins/lib/paste/ContentModelPastePlugin.ts"],"names":[],"mappings":";;;;AAAA,+CAA0C;AAC1C,2EAAyD;AACzD,6DAA8D;AAC9D,uEAA4E;AAC5E,0EAAyE;AACzE,iDAA+C;AAG/C,uFAAsF;AACtF,sGAAqG;AACrG,yGAAwG;AACxG,uGAAsG;AAiBtG,qCAAqC;AACrC,0DAA0D;AAC1D,IAAM,YAAY;IACd,sBAAwB,SAAS;IACjC,0BAA4B,aAAa;IACzC,0BAA4B,aAAa;IACzC,qBAAuB,QAAQ;OAClC,CAAC;AAEF;;;;;;;GAOG;AACH;IAGI;;;OAGG;IACH,iCAAoB,qBAAsC;QAAtC,sCAAA,EAAA,8BAAsC;QAAtC,0BAAqB,GAArB,qBAAqB,CAAiB;QANlD,WAAM,GAA+B,IAAI,CAAC;IAMW,CAAC;IAE9D;;OAEG;IACH,yCAAO,GAAP;QACI,OAAO,mBAAmB,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACH,4CAAU,GAAV,UAAW,MAAe;QACtB,gFAAgF;QAChF,IAAI,CAAC,MAAM,GAAG,MAA6B,CAAC;IAChD,CAAC;IAED;;;;OAIG;IACH,yCAAO,GAAP;QACI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACvB,CAAC;IAED;;;;;OAKG;IACH,+CAAa,GAAb,UAAc,KAAkB;QAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,SAAS,wBAA+B,EAAE;YAChE,OAAO;SACV;QAED,IAAM,EAAE,GAAG,KAAqC,CAAC;QAEjD,IAAI,CAAC,EAAE,CAAC,gBAAgB,EAAE;YACtB,OAAO;SACV;QAED,IAAM,WAAW,GAAG,IAAA,+BAAc,EAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAC9C,IAAM,SAAS,GAAG,YAAY,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;QAE7C,QAAQ,WAAW,EAAE;YACjB,KAAK,aAAa;gBACd,IAAA,yEAAmC,EAAC,EAAE,CAAC,CAAC;gBACxC,MAAM;YACV,KAAK,eAAe;gBAChB,IAAA,qEAAiC,EAAC,EAAE,CAAC,CAAC;gBACtC,MAAM;YACV,KAAK,aAAa,CAAC;YACnB,KAAK,cAAc;gBACf,IAAI,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,aAAa,EAAE;oBACvD,gCAAgC;oBAChC,IAAA,6DAA6B,EAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC;iBAC1E;gBACD,MAAM;YACV,KAAK,cAAc;gBACf,EAAE,CAAC,gBAAgB,CAAC,yBAAyB,0DAE5C,GAAG,GAAG,CAAC;gBACR,MAAM;YACV,KAAK,mBAAmB;gBACpB,IAAA,uEAAkC,EAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC;gBAC5E,MAAM;SACb;QAED,IAAA,mBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,MAAM,EAAE,sBAAS,CAAC,CAAC;QAClD,IAAA,mBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,WAAW,EAAE,mDAA2B,CAAC,CAAC;QACzE,IAAA,mBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAC/D,IAAA,mBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,OAAO,EAAE,mDAA2B,CAAC,CAAC;QACrE,mBAAmB,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC;QAEzC,IAAI,SAAS,KAAK,aAAa,EAAE;YAC7B,IAAA,mBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC;YAC5D,IAAA,mBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,WAAW,EAAE,kBAAkB,CAAC,CAAC;SACnE;QAED,EAAE,CAAC,gBAAgB,CAAC,qBAAqB,GAAG,IAAI,CAAC,qBAAqB,CAAC;IAC3E,CAAC;IACL,8BAAC;AAAD,CAAC,AA7FD,IA6FC;AA7FY,0DAAuB;AA+FpC;;;GAGG;AACH,IAAM,kBAAkB,GAA0C,UAC9D,MAA+B,EAC/B,OAAoB;IAEpB,IAAI,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE;QAC/B,OAAO,MAAM,CAAC,eAAe,CAAC;KACjC;AACL,CAAC,CAAC;AAEF,SAAS,mBAAmB,CAAC,gBAAgD;IACzE,IAAA,6CAAsB,EAAC,gBAAgB,CAAC,iBAAiB,EAAE,SAAS,EAAE,UAAC,KAAa;QAChF,OAAO,KAAK,IAAI,MAAM,CAAC,CAAC,mCAAmC;IAC/D,CAAC,CAAC,CAAC;AACP,CAAC;AAED,IAAM,iBAAiB,GAAG,IAAI,GAAG,CAO/B;IACE,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAChF,CAAC,aAAa,EAAE,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACxF,CAAC,cAAc,EAAE,EAAE,CAAC,EAAE,mBAAmB,EAAE,CAAC,EAAE,mBAAmB,EAAE,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAC5F,CAAC,YAAY,EAAE,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACvF,CAAC,CAAC;AAEH,SAAS,iBAAiB,CAAC,MAAmC,EAAE,OAAoB;IAChF,wCAAU,CAAC,OAAO,CAAC,UAAA,GAAG;QAClB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;YACd,IAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC5C,IACI,QAAQ;gBACR,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACzB,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACzB,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAC5B;gBACE,MAAM,CAAC,GAAG,CAAC,GAAM,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAG,CAAC;aAC7E;SACJ;IACL,CAAC,CAAC,CAAC;AACP,CAAC","sourcesContent":["import addParser from './utils/addParser';\nimport { BorderKeys } from 'roosterjs-content-model-dom';\nimport { chainSanitizerCallback } from 'roosterjs-editor-dom';\nimport { deprecatedBorderColorParser } from './utils/deprecatedColorParser';\nimport { getPasteSource } from './pasteSourceValidations/getPasteSource';\nimport { parseLink } from './utils/linkParser';\nimport { PastePropertyNames } from './pasteSourceValidations/constants';\nimport { PasteType as OldPasteType, PluginEventType } from 'roosterjs-editor-types';\nimport { processPastedContentFromExcel } from './Excel/processPastedContentFromExcel';\nimport { processPastedContentFromPowerPoint } from './PowerPoint/processPastedContentFromPowerPoint';\nimport { processPastedContentFromWordDesktop } from './WordDesktop/processPastedContentFromWordDesktop';\nimport { processPastedContentWacComponents } from './WacComponents/processPastedContentWacComponents';\nimport type { IContentModelEditor } from 'roosterjs-content-model-editor';\nimport type {\n BorderFormat,\n ContentModelBeforePasteEvent,\n ContentModelBlockFormat,\n ContentModelTableCellFormat,\n FormatParser,\n PasteType,\n} from 'roosterjs-content-model-types';\nimport type {\n EditorPlugin,\n HtmlSanitizerOptions,\n IEditor,\n PluginEvent,\n} from 'roosterjs-editor-types';\n\n// Map old PasteType to new PasteType\n// TODO: We can remove this once we have standalone editor\nconst PasteTypeMap: Record<OldPasteType, PasteType> = {\n [OldPasteType.AsImage]: 'asImage',\n [OldPasteType.AsPlainText]: 'asPlainText',\n [OldPasteType.MergeFormat]: 'mergeFormat',\n [OldPasteType.Normal]: 'normal',\n};\n\n/**\n * Paste plugin, handles BeforePaste event and reformat some special content, including:\n * 1. Content copied from Word\n * 2. Content copied from Excel\n * 3. Content copied from Word Online or OneNote Online\n * 4. Content copied from Power Point\n * (This class is still under development, and may still be changed in the future with some breaking changes)\n */\nexport class ContentModelPastePlugin implements EditorPlugin {\n private editor: IContentModelEditor | null = null;\n\n /**\n * Construct a new instance of Paste class\n * @param unknownTagReplacement Replace solution of unknown tags, default behavior is to replace with SPAN\n */\n constructor(private unknownTagReplacement: string = 'SPAN') {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'ContentModelPaste';\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 // TODO: Later we may need a different interface for Content Model editor plugin\n this.editor = editor as IContentModelEditor;\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.editor = null;\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 || event.eventType != PluginEventType.BeforePaste) {\n return;\n }\n\n const ev = event as ContentModelBeforePasteEvent;\n\n if (!ev.domToModelOption) {\n return;\n }\n\n const pasteSource = getPasteSource(ev, false);\n const pasteType = PasteTypeMap[ev.pasteType];\n\n switch (pasteSource) {\n case 'wordDesktop':\n processPastedContentFromWordDesktop(ev);\n break;\n case 'wacComponents':\n processPastedContentWacComponents(ev);\n break;\n case 'excelOnline':\n case 'excelDesktop':\n if (pasteType === 'normal' || pasteType === 'mergeFormat') {\n // Handle HTML copied from Excel\n processPastedContentFromExcel(ev, this.editor.getTrustedHTMLHandler());\n }\n break;\n case 'googleSheets':\n ev.sanitizingOption.additionalTagReplacements[\n PastePropertyNames.GOOGLE_SHEET_NODE_NAME\n ] = '*';\n break;\n case 'powerPointDesktop':\n processPastedContentFromPowerPoint(ev, this.editor.getTrustedHTMLHandler());\n break;\n }\n\n addParser(ev.domToModelOption, 'link', parseLink);\n addParser(ev.domToModelOption, 'tableCell', deprecatedBorderColorParser);\n addParser(ev.domToModelOption, 'tableCell', tableBorderParser);\n addParser(ev.domToModelOption, 'table', deprecatedBorderColorParser);\n sanitizeBlockStyles(ev.sanitizingOption);\n\n if (pasteType === 'mergeFormat') {\n addParser(ev.domToModelOption, 'block', blockElementParser);\n addParser(ev.domToModelOption, 'listLevel', blockElementParser);\n }\n\n ev.sanitizingOption.unknownTagReplacement = this.unknownTagReplacement;\n }\n}\n\n/**\n * For block elements that have background color style, remove the background color when user selects the merge current format\n * paste option\n */\nconst blockElementParser: FormatParser<ContentModelBlockFormat> = (\n format: ContentModelBlockFormat,\n element: HTMLElement\n) => {\n if (element.style.backgroundColor) {\n delete format.backgroundColor;\n }\n};\n\nfunction sanitizeBlockStyles(sanitizingOption: Required<HtmlSanitizerOptions>) {\n chainSanitizerCallback(sanitizingOption.cssStyleCallbacks, 'display', (value: string) => {\n return value != 'flex'; // return whether we keep the style\n });\n}\n\nconst ElementBorderKeys = new Map<\n keyof BorderFormat,\n {\n c: keyof CSSStyleDeclaration;\n s: keyof CSSStyleDeclaration;\n w: keyof CSSStyleDeclaration;\n }\n>([\n ['borderTop', { w: 'borderTopWidth', s: 'borderTopStyle', c: 'borderTopColor' }],\n ['borderRight', { w: 'borderRightWidth', s: 'borderRightStyle', c: 'borderRightColor' }],\n ['borderBottom', { w: 'borderBottomWidth', s: 'borderBottomStyle', c: 'borderBottomColor' }],\n ['borderLeft', { w: 'borderLeftWidth', s: 'borderLeftStyle', c: 'borderLeftColor' }],\n]);\n\nfunction tableBorderParser(format: ContentModelTableCellFormat, element: HTMLElement): void {\n BorderKeys.forEach(key => {\n if (!format[key]) {\n const styleSet = ElementBorderKeys.get(key);\n if (\n styleSet &&\n element.style[styleSet.w] &&\n element.style[styleSet.s] &&\n !element.style[styleSet.c]\n ) {\n format[key] = `${element.style[styleSet.w]} ${element.style[styleSet.s]}`;\n }\n }\n });\n}\n"]}
1
+ {"version":3,"file":"ContentModelPastePlugin.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-plugins/lib/paste/ContentModelPastePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import addParser from './utils/addParser';\nimport { BorderKeys } from 'roosterjs-content-model-dom';\nimport { chainSanitizerCallback } from 'roosterjs-editor-dom';\nimport { deprecatedBorderColorParser } from './utils/deprecatedColorParser';\nimport { getPasteSource } from './pasteSourceValidations/getPasteSource';\nimport { parseLink } from './utils/linkParser';\nimport { PastePropertyNames } from './pasteSourceValidations/constants';\nimport { PasteType as OldPasteType, PluginEventType } from 'roosterjs-editor-types';\nimport { processPastedContentFromExcel } from './Excel/processPastedContentFromExcel';\nimport { processPastedContentFromPowerPoint } from './PowerPoint/processPastedContentFromPowerPoint';\nimport { processPastedContentFromWordDesktop } from './WordDesktop/processPastedContentFromWordDesktop';\nimport { processPastedContentWacComponents } from './WacComponents/processPastedContentWacComponents';\nimport type { IContentModelEditor } from 'roosterjs-content-model-editor';\nimport type {\n BorderFormat,\n ContentModelBeforePasteEvent,\n ContentModelBlockFormat,\n ContentModelTableCellFormat,\n FormatParser,\n PasteType,\n} from 'roosterjs-content-model-types';\nimport type {\n EditorPlugin,\n HtmlSanitizerOptions,\n IEditor,\n PluginEvent,\n} from 'roosterjs-editor-types';\n\n// Map old PasteType to new PasteType\n// TODO: We can remove this once we have standalone editor\nconst PasteTypeMap: Record<OldPasteType, PasteType> = {\n [OldPasteType.AsImage]: 'asImage',\n [OldPasteType.AsPlainText]: 'asPlainText',\n [OldPasteType.MergeFormat]: 'mergeFormat',\n [OldPasteType.Normal]: 'normal',\n};\n\n/**\n * Paste plugin, handles BeforePaste event and reformat some special content, including:\n * 1. Content copied from Word\n * 2. Content copied from Excel\n * 3. Content copied from Word Online or OneNote Online\n * 4. Content copied from Power Point\n * (This class is still under development, and may still be changed in the future with some breaking changes)\n */\nexport class ContentModelPastePlugin implements EditorPlugin {\n private editor: IContentModelEditor | null = null;\n\n /**\n * Construct a new instance of Paste class\n * @param unknownTagReplacement Replace solution of unknown tags, default behavior is to replace with SPAN\n * @param allowExcelNoBorderTable Allow table copied from Excel without border\n */\n constructor(\n private unknownTagReplacement: string = 'SPAN',\n private allowExcelNoBorderTable?: boolean\n ) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'ContentModelPaste';\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 // TODO: Later we may need a different interface for Content Model editor plugin\n this.editor = editor as IContentModelEditor;\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.editor = null;\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 || event.eventType != PluginEventType.BeforePaste) {\n return;\n }\n\n const ev = event as ContentModelBeforePasteEvent;\n\n if (!ev.domToModelOption) {\n return;\n }\n\n const pasteSource = getPasteSource(ev, false);\n const pasteType = PasteTypeMap[ev.pasteType];\n\n switch (pasteSource) {\n case 'wordDesktop':\n processPastedContentFromWordDesktop(ev, this.editor.getTrustedHTMLHandler());\n break;\n case 'wacComponents':\n processPastedContentWacComponents(ev);\n break;\n case 'excelOnline':\n case 'excelDesktop':\n if (pasteType === 'normal' || pasteType === 'mergeFormat') {\n // Handle HTML copied from Excel\n processPastedContentFromExcel(\n ev,\n this.editor.getTrustedHTMLHandler(),\n this.allowExcelNoBorderTable\n );\n }\n break;\n case 'googleSheets':\n ev.sanitizingOption.additionalTagReplacements[\n PastePropertyNames.GOOGLE_SHEET_NODE_NAME\n ] = '*';\n break;\n case 'powerPointDesktop':\n processPastedContentFromPowerPoint(ev, this.editor.getTrustedHTMLHandler());\n break;\n }\n\n addParser(ev.domToModelOption, 'link', parseLink);\n addParser(ev.domToModelOption, 'tableCell', deprecatedBorderColorParser);\n addParser(ev.domToModelOption, 'tableCell', tableBorderParser);\n addParser(ev.domToModelOption, 'table', deprecatedBorderColorParser);\n sanitizeBlockStyles(ev.sanitizingOption);\n\n if (pasteType === 'mergeFormat') {\n addParser(ev.domToModelOption, 'block', blockElementParser);\n addParser(ev.domToModelOption, 'listLevel', blockElementParser);\n }\n\n ev.sanitizingOption.unknownTagReplacement = this.unknownTagReplacement;\n }\n}\n\n/**\n * For block elements that have background color style, remove the background color when user selects the merge current format\n * paste option\n */\nconst blockElementParser: FormatParser<ContentModelBlockFormat> = (\n format: ContentModelBlockFormat,\n element: HTMLElement\n) => {\n if (element.style.backgroundColor) {\n delete format.backgroundColor;\n }\n};\n\nfunction sanitizeBlockStyles(sanitizingOption: Required<HtmlSanitizerOptions>) {\n chainSanitizerCallback(sanitizingOption.cssStyleCallbacks, 'display', (value: string) => {\n return value != 'flex'; // return whether we keep the style\n });\n}\n\nconst ElementBorderKeys = new Map<\n keyof BorderFormat,\n {\n c: keyof CSSStyleDeclaration;\n s: keyof CSSStyleDeclaration;\n w: keyof CSSStyleDeclaration;\n }\n>([\n ['borderTop', { w: 'borderTopWidth', s: 'borderTopStyle', c: 'borderTopColor' }],\n ['borderRight', { w: 'borderRightWidth', s: 'borderRightStyle', c: 'borderRightColor' }],\n ['borderBottom', { w: 'borderBottomWidth', s: 'borderBottomStyle', c: 'borderBottomColor' }],\n ['borderLeft', { w: 'borderLeftWidth', s: 'borderLeftStyle', c: 'borderLeftColor' }],\n]);\n\nfunction tableBorderParser(format: ContentModelTableCellFormat, element: HTMLElement): void {\n BorderKeys.forEach(key => {\n if (!format[key]) {\n const styleSet = ElementBorderKeys.get(key);\n if (\n styleSet &&\n element.style[styleSet.w] &&\n element.style[styleSet.s] &&\n !element.style[styleSet.c]\n ) {\n format[key] = `${element.style[styleSet.w]} ${element.style[styleSet.s]}`;\n }\n }\n });\n}\n"]}
@@ -5,7 +5,7 @@ import type { ContentModelBeforePasteEvent } from 'roosterjs-content-model-types
5
5
  * Convert pasted content from Excel, add borders when source doc doesn't have a border
6
6
  * @param event The BeforePaste event
7
7
  */
8
- export declare function processPastedContentFromExcel(event: ContentModelBeforePasteEvent, trustedHTMLHandler: TrustedHTMLHandler): void;
8
+ export declare function processPastedContentFromExcel(event: ContentModelBeforePasteEvent, trustedHTMLHandler: TrustedHTMLHandler, allowExcelNoBorderTable?: boolean): void;
9
9
  /**
10
10
  * @internal Export for test only
11
11
  * @param html Source html
@@ -15,7 +15,7 @@ var DEFAULT_BORDER_STYLE = 'solid 1px #d4d4d4';
15
15
  * Convert pasted content from Excel, add borders when source doc doesn't have a border
16
16
  * @param event The BeforePaste event
17
17
  */
18
- function processPastedContentFromExcel(event, trustedHTMLHandler) {
18
+ function processPastedContentFromExcel(event, trustedHTMLHandler, allowExcelNoBorderTable) {
19
19
  var fragment = event.fragment, htmlBefore = event.htmlBefore, clipboardData = event.clipboardData;
20
20
  var html = clipboardData.html ? excelHandler(clipboardData.html, htmlBefore) : undefined;
21
21
  if (html && clipboardData.html != html) {
@@ -42,7 +42,7 @@ function processPastedContentFromExcel(event, trustedHTMLHandler) {
42
42
  }
43
43
  }
44
44
  (0, addParser_1.default)(event.domToModelOption, 'tableCell', function (format, element) {
45
- if (element.style.borderStyle === 'none') {
45
+ if (!allowExcelNoBorderTable && element.style.borderStyle === 'none') {
46
46
  format.borderBottom = DEFAULT_BORDER_STYLE;
47
47
  format.borderLeft = DEFAULT_BORDER_STYLE;
48
48
  format.borderRight = DEFAULT_BORDER_STYLE;
@@ -1 +1 @@
1
- {"version":3,"file":"processPastedContentFromExcel.js","sourceRoot":"","sources":["../../../../../packages-content-model/roosterjs-content-model-plugins/lib/paste/Excel/processPastedContentFromExcel.ts"],"names":[],"mappings":"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","sourcesContent":["import addParser from '../utils/addParser';\nimport { isNodeOfType, moveChildNodes } from 'roosterjs-content-model-dom';\nimport { setProcessor } from '../utils/setProcessor';\nimport type { TrustedHTMLHandler } from 'roosterjs-editor-types';\nimport type { ContentModelBeforePasteEvent } from 'roosterjs-content-model-types';\n\nconst LAST_TD_END_REGEX = /<\\/\\s*td\\s*>((?!<\\/\\s*tr\\s*>)[\\s\\S])*$/i;\nconst LAST_TR_END_REGEX = /<\\/\\s*tr\\s*>((?!<\\/\\s*table\\s*>)[\\s\\S])*$/i;\nconst LAST_TR_REGEX = /<tr[^>]*>[^<]*/i;\nconst LAST_TABLE_REGEX = /<table[^>]*>[^<]*/i;\nconst DEFAULT_BORDER_STYLE = 'solid 1px #d4d4d4';\n\n/**\n * @internal\n * Convert pasted content from Excel, add borders when source doc doesn't have a border\n * @param event The BeforePaste event\n */\n\nexport function processPastedContentFromExcel(\n event: ContentModelBeforePasteEvent,\n trustedHTMLHandler: TrustedHTMLHandler\n) {\n const { fragment, htmlBefore, clipboardData } = event;\n const html = clipboardData.html ? excelHandler(clipboardData.html, htmlBefore) : undefined;\n\n if (html && clipboardData.html != html) {\n const doc = new DOMParser().parseFromString(trustedHTMLHandler(html), 'text/html');\n moveChildNodes(fragment, doc?.body);\n }\n\n // For Excel Online\n const firstChild = fragment.firstChild;\n if (\n isNodeOfType(firstChild, 'ELEMENT_NODE') &&\n firstChild.tagName == 'div' &&\n firstChild.firstChild\n ) {\n const tableFound = Array.from(firstChild.childNodes).every((child: Node) => {\n // Tables pasted from Excel Online should be of the format: 0 to N META tags and 1 TABLE tag\n const tagName = isNodeOfType(child, 'ELEMENT_NODE') && child.tagName;\n\n return tagName == 'META'\n ? true\n : tagName == 'TABLE'\n ? child == firstChild.lastChild\n : false;\n });\n\n // Extract Table from Div\n if (tableFound && firstChild.lastChild) {\n event.fragment.replaceChildren(firstChild.lastChild);\n }\n }\n\n addParser(event.domToModelOption, 'tableCell', (format, element) => {\n if (element.style.borderStyle === 'none') {\n format.borderBottom = DEFAULT_BORDER_STYLE;\n format.borderLeft = DEFAULT_BORDER_STYLE;\n format.borderRight = DEFAULT_BORDER_STYLE;\n format.borderTop = DEFAULT_BORDER_STYLE;\n }\n });\n\n setProcessor(event.domToModelOption, 'child', (group, element, context) => {\n const segmentFormat = { ...context.segmentFormat };\n if (group.blockGroupType === 'TableCell' && group.format.textColor) {\n context.segmentFormat.textColor = group.format.textColor;\n }\n\n context.defaultElementProcessors.child(group, element, context);\n\n if (group.blockGroupType === 'TableCell' && group.format.textColor) {\n context.segmentFormat = segmentFormat;\n delete group.format.textColor;\n }\n });\n}\n\n/**\n * @internal Export for test only\n * @param html Source html\n */\n\nexport function excelHandler(html: string, htmlBefore: string): string {\n if (html.match(LAST_TD_END_REGEX)) {\n const trMatch = htmlBefore.match(LAST_TR_REGEX);\n const tr = trMatch ? trMatch[0] : '<TR>';\n html = tr + html + '</TR>';\n }\n if (html.match(LAST_TR_END_REGEX)) {\n const tableMatch = htmlBefore.match(LAST_TABLE_REGEX);\n const table = tableMatch ? tableMatch[0] : '<TABLE>';\n html = table + html + '</TABLE>';\n }\n\n return html;\n}\n"]}
1
+ {"version":3,"file":"processPastedContentFromExcel.js","sourceRoot":"","sources":["../../../../../packages-content-model/roosterjs-content-model-plugins/lib/paste/Excel/processPastedContentFromExcel.ts"],"names":[],"mappings":"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","sourcesContent":["import addParser from '../utils/addParser';\nimport { isNodeOfType, moveChildNodes } from 'roosterjs-content-model-dom';\nimport { setProcessor } from '../utils/setProcessor';\nimport type { TrustedHTMLHandler } from 'roosterjs-editor-types';\nimport type { ContentModelBeforePasteEvent } from 'roosterjs-content-model-types';\n\nconst LAST_TD_END_REGEX = /<\\/\\s*td\\s*>((?!<\\/\\s*tr\\s*>)[\\s\\S])*$/i;\nconst LAST_TR_END_REGEX = /<\\/\\s*tr\\s*>((?!<\\/\\s*table\\s*>)[\\s\\S])*$/i;\nconst LAST_TR_REGEX = /<tr[^>]*>[^<]*/i;\nconst LAST_TABLE_REGEX = /<table[^>]*>[^<]*/i;\nconst DEFAULT_BORDER_STYLE = 'solid 1px #d4d4d4';\n\n/**\n * @internal\n * Convert pasted content from Excel, add borders when source doc doesn't have a border\n * @param event The BeforePaste event\n */\n\nexport function processPastedContentFromExcel(\n event: ContentModelBeforePasteEvent,\n trustedHTMLHandler: TrustedHTMLHandler,\n allowExcelNoBorderTable?: boolean\n) {\n const { fragment, htmlBefore, clipboardData } = event;\n const html = clipboardData.html ? excelHandler(clipboardData.html, htmlBefore) : undefined;\n\n if (html && clipboardData.html != html) {\n const doc = new DOMParser().parseFromString(trustedHTMLHandler(html), 'text/html');\n moveChildNodes(fragment, doc?.body);\n }\n\n // For Excel Online\n const firstChild = fragment.firstChild;\n if (\n isNodeOfType(firstChild, 'ELEMENT_NODE') &&\n firstChild.tagName == 'div' &&\n firstChild.firstChild\n ) {\n const tableFound = Array.from(firstChild.childNodes).every((child: Node) => {\n // Tables pasted from Excel Online should be of the format: 0 to N META tags and 1 TABLE tag\n const tagName = isNodeOfType(child, 'ELEMENT_NODE') && child.tagName;\n\n return tagName == 'META'\n ? true\n : tagName == 'TABLE'\n ? child == firstChild.lastChild\n : false;\n });\n\n // Extract Table from Div\n if (tableFound && firstChild.lastChild) {\n event.fragment.replaceChildren(firstChild.lastChild);\n }\n }\n\n addParser(event.domToModelOption, 'tableCell', (format, element) => {\n if (!allowExcelNoBorderTable && element.style.borderStyle === 'none') {\n format.borderBottom = DEFAULT_BORDER_STYLE;\n format.borderLeft = DEFAULT_BORDER_STYLE;\n format.borderRight = DEFAULT_BORDER_STYLE;\n format.borderTop = DEFAULT_BORDER_STYLE;\n }\n });\n\n setProcessor(event.domToModelOption, 'child', (group, element, context) => {\n const segmentFormat = { ...context.segmentFormat };\n if (group.blockGroupType === 'TableCell' && group.format.textColor) {\n context.segmentFormat.textColor = group.format.textColor;\n }\n\n context.defaultElementProcessors.child(group, element, context);\n\n if (group.blockGroupType === 'TableCell' && group.format.textColor) {\n context.segmentFormat = segmentFormat;\n delete group.format.textColor;\n }\n });\n}\n\n/**\n * @internal Export for test only\n * @param html Source html\n */\n\nexport function excelHandler(html: string, htmlBefore: string): string {\n if (html.match(LAST_TD_END_REGEX)) {\n const trMatch = htmlBefore.match(LAST_TR_REGEX);\n const tr = trMatch ? trMatch[0] : '<TR>';\n html = tr + html + '</TR>';\n }\n if (html.match(LAST_TR_END_REGEX)) {\n const tableMatch = htmlBefore.match(LAST_TABLE_REGEX);\n const table = tableMatch ? tableMatch[0] : '<TABLE>';\n html = table + html + '</TABLE>';\n }\n\n return html;\n}\n"]}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @internal
3
+ **/
4
+ export declare const WORD_ONLINE_TABLE_TEMP_ELEMENT_CLASSES: string[];
5
+ /**
6
+ * @internal
7
+ **/
8
+ export declare const BULLET_LIST_STYLE: string;
9
+ /**
10
+ * @internal
11
+ **/
12
+ export declare const NUMBER_LIST_STYLE: string;
13
+ /**
14
+ * @internal
15
+ **/
16
+ export declare const IMAGE_BORDER: string;
17
+ /**
18
+ * @internal
19
+ **/
20
+ export declare const IMAGE_CONTAINER: string;
21
+ /**
22
+ * @internal
23
+ **/
24
+ export declare const OUTLINE_ELEMENT: string;
25
+ /**
26
+ * @internal
27
+ **/
28
+ export declare const PARAGRAPH: string;
29
+ /**
30
+ * @internal
31
+ **/
32
+ export declare const LIST_CONTAINER_ELEMENT_CLASS_NAME: string;
33
+ /**
34
+ * @internal
35
+ **/
36
+ export declare const TABLE_CONTAINER: string;
37
+ /**
38
+ * @internal
39
+ **/
40
+ export declare const COMMENT_HIGHLIGHT_CLASS: string;
41
+ /**
42
+ * @internal
43
+ **/
44
+ export declare const COMMENT_HIGHLIGHT_CLICKED_CLASS: string;
45
+ /**
46
+ * @internal
47
+ **/
48
+ export declare const TEMP_ELEMENTS_CLASSES: string[];
49
+ /**
50
+ * @internal
51
+ **/
52
+ export declare const WAC_IDENTIFY_SELECTOR: string;
53
+ /**
54
+ * @internal
55
+ **/
56
+ export declare const CLASSES_TO_KEEP: string[];
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CLASSES_TO_KEEP = exports.WAC_IDENTIFY_SELECTOR = exports.TEMP_ELEMENTS_CLASSES = exports.COMMENT_HIGHLIGHT_CLICKED_CLASS = exports.COMMENT_HIGHLIGHT_CLASS = exports.TABLE_CONTAINER = exports.LIST_CONTAINER_ELEMENT_CLASS_NAME = exports.PARAGRAPH = exports.OUTLINE_ELEMENT = exports.IMAGE_CONTAINER = exports.IMAGE_BORDER = exports.NUMBER_LIST_STYLE = exports.BULLET_LIST_STYLE = exports.WORD_ONLINE_TABLE_TEMP_ELEMENT_CLASSES = void 0;
4
+ var tslib_1 = require("tslib");
5
+ /**
6
+ * @internal
7
+ **/
8
+ exports.WORD_ONLINE_TABLE_TEMP_ELEMENT_CLASSES = [
9
+ 'TableInsertRowGapBlank',
10
+ 'TableColumnResizeHandle',
11
+ 'TableCellTopBorderHandle',
12
+ 'TableCellLeftBorderHandle',
13
+ 'TableHoverColumnHandle',
14
+ 'TableHoverRowHandle',
15
+ ];
16
+ /**
17
+ * @internal
18
+ **/
19
+ exports.BULLET_LIST_STYLE = 'BulletListStyle';
20
+ /**
21
+ * @internal
22
+ **/
23
+ exports.NUMBER_LIST_STYLE = 'NumberListStyle';
24
+ /**
25
+ * @internal
26
+ **/
27
+ exports.IMAGE_BORDER = 'WACImageBorder';
28
+ /**
29
+ * @internal
30
+ **/
31
+ exports.IMAGE_CONTAINER = 'WACImageContainer';
32
+ /**
33
+ * @internal
34
+ **/
35
+ exports.OUTLINE_ELEMENT = 'OutlineElement';
36
+ /**
37
+ * @internal
38
+ **/
39
+ exports.PARAGRAPH = 'Paragraph';
40
+ /**
41
+ * @internal
42
+ **/
43
+ exports.LIST_CONTAINER_ELEMENT_CLASS_NAME = 'ListContainerWrapper';
44
+ /**
45
+ * @internal
46
+ **/
47
+ exports.TABLE_CONTAINER = 'TableContainer';
48
+ /**
49
+ * @internal
50
+ **/
51
+ exports.COMMENT_HIGHLIGHT_CLASS = 'CommentHighlightRest';
52
+ /**
53
+ * @internal
54
+ **/
55
+ exports.COMMENT_HIGHLIGHT_CLICKED_CLASS = 'CommentHighlightClicked';
56
+ /**
57
+ * @internal
58
+ **/
59
+ exports.TEMP_ELEMENTS_CLASSES = (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(exports.WORD_ONLINE_TABLE_TEMP_ELEMENT_CLASSES), false), [
60
+ 'ListMarkerWrappingSpan',
61
+ ], false);
62
+ /**
63
+ * @internal
64
+ **/
65
+ exports.WAC_IDENTIFY_SELECTOR = "ul[class^=\"" + exports.BULLET_LIST_STYLE + "\"]>." + exports.OUTLINE_ELEMENT + ",ol[class^=\"" + exports.NUMBER_LIST_STYLE + "\"]>." + exports.OUTLINE_ELEMENT + ",span." + exports.IMAGE_CONTAINER + ",span." + exports.IMAGE_BORDER + ",." + exports.COMMENT_HIGHLIGHT_CLASS + ",." + exports.COMMENT_HIGHLIGHT_CLICKED_CLASS + "," +
66
+ exports.WORD_ONLINE_TABLE_TEMP_ELEMENT_CLASSES.map(function (c) { return "table div[class^=\"" + c + "\"]"; }).join(',');
67
+ /**
68
+ * @internal
69
+ **/
70
+ exports.CLASSES_TO_KEEP = (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([
71
+ exports.OUTLINE_ELEMENT,
72
+ exports.IMAGE_CONTAINER
73
+ ], (0, tslib_1.__read)(exports.TEMP_ELEMENTS_CLASSES), false), [
74
+ exports.PARAGRAPH,
75
+ exports.IMAGE_BORDER,
76
+ exports.TABLE_CONTAINER,
77
+ exports.COMMENT_HIGHLIGHT_CLASS,
78
+ exports.COMMENT_HIGHLIGHT_CLICKED_CLASS,
79
+ 'NumberListStyle',
80
+ 'ListContainerWrapper',
81
+ 'BulletListStyle',
82
+ 'TableCellContent',
83
+ 'WACImageContainer',
84
+ 'LineBreakBlob',
85
+ ], false);
86
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../../packages-content-model/roosterjs-content-model-plugins/lib/paste/WacComponents/constants.ts"],"names":[],"mappings":";;;;AAAA;;IAEI;AACS,QAAA,sCAAsC,GAAa;IAC5D,wBAAwB;IACxB,yBAAyB;IACzB,0BAA0B;IAC1B,2BAA2B;IAC3B,wBAAwB;IACxB,qBAAqB;CACxB,CAAC;AACF;;IAEI;AACS,QAAA,iBAAiB,GAAW,iBAAiB,CAAC;AAC3D;;IAEI;AACS,QAAA,iBAAiB,GAAW,iBAAiB,CAAC;AAC3D;;IAEI;AACS,QAAA,YAAY,GAAW,gBAAgB,CAAC;AACrD;;IAEI;AACS,QAAA,eAAe,GAAW,mBAAmB,CAAC;AAC3D;;IAEI;AACS,QAAA,eAAe,GAAW,gBAAgB,CAAC;AACxD;;IAEI;AACS,QAAA,SAAS,GAAW,WAAW,CAAC;AAC7C;;IAEI;AACS,QAAA,iCAAiC,GAAW,sBAAsB,CAAC;AAChF;;IAEI;AACS,QAAA,eAAe,GAAW,gBAAgB,CAAC;AACxD;;IAEI;AACS,QAAA,uBAAuB,GAAW,sBAAsB,CAAC;AACtE;;IAEI;AACS,QAAA,+BAA+B,GAAW,yBAAyB,CAAC;AACjF;;IAEI;AACS,QAAA,qBAAqB,iFAC3B,8CAAsC;IACzC,wBAAwB;UAC1B;AACF;;IAEI;AACS,QAAA,qBAAqB,GAC9B,iBAAc,yBAAiB,aAAO,uBAAe,qBAAe,yBAAiB,aAAO,uBAAe,cAAS,uBAAe,cAAS,oBAAY,UAAK,+BAAuB,UAAK,uCAA+B,MAAG;IAC3N,8CAAsC,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,wBAAqB,CAAC,QAAI,EAA1B,CAA0B,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC1F;;IAEI;AACS,QAAA,eAAe;IACxB,uBAAe;IACf,uBAAe;uBACZ,6BAAqB;IACxB,iBAAS;IACT,oBAAY;IACZ,uBAAe;IACf,+BAAuB;IACvB,uCAA+B;IAC/B,iBAAiB;IACjB,sBAAsB;IACtB,iBAAiB;IACjB,kBAAkB;IAClB,mBAAmB;IACnB,eAAe;UACjB","sourcesContent":["/**\n * @internal\n **/\nexport const WORD_ONLINE_TABLE_TEMP_ELEMENT_CLASSES: string[] = [\n 'TableInsertRowGapBlank',\n 'TableColumnResizeHandle',\n 'TableCellTopBorderHandle',\n 'TableCellLeftBorderHandle',\n 'TableHoverColumnHandle',\n 'TableHoverRowHandle',\n];\n/**\n * @internal\n **/\nexport const BULLET_LIST_STYLE: string = 'BulletListStyle';\n/**\n * @internal\n **/\nexport const NUMBER_LIST_STYLE: string = 'NumberListStyle';\n/**\n * @internal\n **/\nexport const IMAGE_BORDER: string = 'WACImageBorder';\n/**\n * @internal\n **/\nexport const IMAGE_CONTAINER: string = 'WACImageContainer';\n/**\n * @internal\n **/\nexport const OUTLINE_ELEMENT: string = 'OutlineElement';\n/**\n * @internal\n **/\nexport const PARAGRAPH: string = 'Paragraph';\n/**\n * @internal\n **/\nexport const LIST_CONTAINER_ELEMENT_CLASS_NAME: string = 'ListContainerWrapper';\n/**\n * @internal\n **/\nexport const TABLE_CONTAINER: string = 'TableContainer';\n/**\n * @internal\n **/\nexport const COMMENT_HIGHLIGHT_CLASS: string = 'CommentHighlightRest';\n/**\n * @internal\n **/\nexport const COMMENT_HIGHLIGHT_CLICKED_CLASS: string = 'CommentHighlightClicked';\n/**\n * @internal\n **/\nexport const TEMP_ELEMENTS_CLASSES: string[] = [\n ...WORD_ONLINE_TABLE_TEMP_ELEMENT_CLASSES,\n 'ListMarkerWrappingSpan',\n];\n/**\n * @internal\n **/\nexport const WAC_IDENTIFY_SELECTOR: string =\n `ul[class^=\"${BULLET_LIST_STYLE}\"]>.${OUTLINE_ELEMENT},ol[class^=\"${NUMBER_LIST_STYLE}\"]>.${OUTLINE_ELEMENT},span.${IMAGE_CONTAINER},span.${IMAGE_BORDER},.${COMMENT_HIGHLIGHT_CLASS},.${COMMENT_HIGHLIGHT_CLICKED_CLASS},` +\n WORD_ONLINE_TABLE_TEMP_ELEMENT_CLASSES.map(c => `table div[class^=\"${c}\"]`).join(',');\n/**\n * @internal\n **/\nexport const CLASSES_TO_KEEP: string[] = [\n OUTLINE_ELEMENT,\n IMAGE_CONTAINER,\n ...TEMP_ELEMENTS_CLASSES,\n PARAGRAPH,\n IMAGE_BORDER,\n TABLE_CONTAINER,\n COMMENT_HIGHLIGHT_CLASS,\n COMMENT_HIGHLIGHT_CLICKED_CLASS,\n 'NumberListStyle',\n 'ListContainerWrapper',\n 'BulletListStyle',\n 'TableCellContent',\n 'WACImageContainer',\n 'LineBreakBlob',\n];\n"]}