roosterjs-content-model-dom 9.11.2 → 9.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/lib/formatHandlers/block/htmlAlignFormatHandler.js +9 -6
  2. package/lib/formatHandlers/block/htmlAlignFormatHandler.js.map +1 -1
  3. package/lib/modelApi/common/normalizeParagraph.js +36 -0
  4. package/lib/modelApi/common/normalizeParagraph.js.map +1 -1
  5. package/lib/modelApi/editing/deleteExpandedSelection.js +1 -1
  6. package/lib/modelApi/editing/deleteExpandedSelection.js.map +1 -1
  7. package/lib/modelApi/editing/getSegmentTextFormat.d.ts +2 -1
  8. package/lib/modelApi/editing/getSegmentTextFormat.js +12 -8
  9. package/lib/modelApi/editing/getSegmentTextFormat.js.map +1 -1
  10. package/lib/modelApi/editing/mergeModel.js +18 -4
  11. package/lib/modelApi/editing/mergeModel.js.map +1 -1
  12. package/lib/modelToDom/contentModelToDom.js +6 -3
  13. package/lib/modelToDom/contentModelToDom.js.map +1 -1
  14. package/lib/modelToDom/handlers/handleParagraph.js +1 -1
  15. package/lib/modelToDom/handlers/handleParagraph.js.map +1 -1
  16. package/lib/modelToDom/optimizers/optimize.d.ts +2 -1
  17. package/lib/modelToDom/optimizers/optimize.js +41 -2
  18. package/lib/modelToDom/optimizers/optimize.js.map +1 -1
  19. package/lib-amd/formatHandlers/block/htmlAlignFormatHandler.js +9 -6
  20. package/lib-amd/formatHandlers/block/htmlAlignFormatHandler.js.map +1 -1
  21. package/lib-amd/modelApi/common/normalizeParagraph.js +36 -1
  22. package/lib-amd/modelApi/common/normalizeParagraph.js.map +1 -1
  23. package/lib-amd/modelApi/editing/deleteExpandedSelection.js +1 -1
  24. package/lib-amd/modelApi/editing/deleteExpandedSelection.js.map +1 -1
  25. package/lib-amd/modelApi/editing/getSegmentTextFormat.d.ts +2 -1
  26. package/lib-amd/modelApi/editing/getSegmentTextFormat.js +12 -8
  27. package/lib-amd/modelApi/editing/getSegmentTextFormat.js.map +1 -1
  28. package/lib-amd/modelApi/editing/mergeModel.js +18 -4
  29. package/lib-amd/modelApi/editing/mergeModel.js.map +1 -1
  30. package/lib-amd/modelToDom/contentModelToDom.js +6 -3
  31. package/lib-amd/modelToDom/contentModelToDom.js.map +1 -1
  32. package/lib-amd/modelToDom/handlers/handleParagraph.js +1 -1
  33. package/lib-amd/modelToDom/handlers/handleParagraph.js.map +1 -1
  34. package/lib-amd/modelToDom/optimizers/optimize.d.ts +2 -1
  35. package/lib-amd/modelToDom/optimizers/optimize.js +41 -3
  36. package/lib-amd/modelToDom/optimizers/optimize.js.map +1 -1
  37. package/lib-mjs/formatHandlers/block/htmlAlignFormatHandler.js +9 -6
  38. package/lib-mjs/formatHandlers/block/htmlAlignFormatHandler.js.map +1 -1
  39. package/lib-mjs/modelApi/common/normalizeParagraph.js +37 -1
  40. package/lib-mjs/modelApi/common/normalizeParagraph.js.map +1 -1
  41. package/lib-mjs/modelApi/editing/deleteExpandedSelection.js +1 -1
  42. package/lib-mjs/modelApi/editing/deleteExpandedSelection.js.map +1 -1
  43. package/lib-mjs/modelApi/editing/getSegmentTextFormat.d.ts +2 -1
  44. package/lib-mjs/modelApi/editing/getSegmentTextFormat.js +12 -8
  45. package/lib-mjs/modelApi/editing/getSegmentTextFormat.js.map +1 -1
  46. package/lib-mjs/modelApi/editing/mergeModel.js +18 -4
  47. package/lib-mjs/modelApi/editing/mergeModel.js.map +1 -1
  48. package/lib-mjs/modelToDom/contentModelToDom.js +6 -3
  49. package/lib-mjs/modelToDom/contentModelToDom.js.map +1 -1
  50. package/lib-mjs/modelToDom/handlers/handleParagraph.js +1 -1
  51. package/lib-mjs/modelToDom/handlers/handleParagraph.js.map +1 -1
  52. package/lib-mjs/modelToDom/optimizers/optimize.d.ts +2 -1
  53. package/lib-mjs/modelToDom/optimizers/optimize.js +41 -2
  54. package/lib-mjs/modelToDom/optimizers/optimize.js.map +1 -1
  55. package/package.json +2 -2
@@ -8,12 +8,15 @@ var directionFormatHandler_1 = require("./directionFormatHandler");
8
8
  */
9
9
  exports.htmlAlignFormatHandler = {
10
10
  parse: function (format, element, context, defaultStyle) {
11
- directionFormatHandler_1.directionFormatHandler.parse(format, element, context, defaultStyle);
12
- var htmlAlign = element.getAttribute('align');
13
- if (htmlAlign) {
14
- format.htmlAlign = (0, dir_1.calcAlign)(htmlAlign, format.direction);
15
- delete format.textAlign;
16
- delete context.blockFormat.textAlign;
11
+ // When there is text-align in CSS style on the same element, we should ignore HTML align
12
+ if (!element.style.textAlign) {
13
+ directionFormatHandler_1.directionFormatHandler.parse(format, element, context, defaultStyle);
14
+ var htmlAlign = element.getAttribute('align');
15
+ if (htmlAlign) {
16
+ format.htmlAlign = (0, dir_1.calcAlign)(htmlAlign, format.direction);
17
+ delete format.textAlign;
18
+ delete context.blockFormat.textAlign;
19
+ }
17
20
  }
18
21
  },
19
22
  apply: function (format, element) {
@@ -1 +1 @@
1
- {"version":3,"file":"htmlAlignFormatHandler.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/formatHandlers/block/htmlAlignFormatHandler.ts"],"names":[],"mappings":";;;AAAA,oCAAoD;AACpD,mEAAkE;AAQlE;;GAEG;AACU,QAAA,sBAAsB,GAE/B;IACA,KAAK,EAAE,UAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY;QAC1C,+CAAsB,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QAErE,IAAM,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAEhD,IAAI,SAAS,EAAE;YACX,MAAM,CAAC,SAAS,GAAG,IAAA,eAAS,EAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;YAC1D,OAAO,MAAM,CAAC,SAAS,CAAC;YACxB,OAAO,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC;SACxC;IACL,CAAC;IACD,KAAK,EAAE,UAAC,MAAM,EAAE,OAAO;QACnB,IAAM,GAAG,GAAkB,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;QAErE,IAAI,MAAM,CAAC,SAAS,EAAE;YAClB,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,eAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;SACnE;IACL,CAAC;CACJ,CAAC","sourcesContent":["import { calcAlign, ResultMap } from '../utils/dir';\nimport { directionFormatHandler } from './directionFormatHandler';\nimport type {\n DirectionFormat,\n HtmlAlignFormat,\n TextAlignFormat,\n} from 'roosterjs-content-model-types';\nimport type { FormatHandler } from '../FormatHandler';\n\n/**\n * @internal\n */\nexport const htmlAlignFormatHandler: FormatHandler<\n DirectionFormat & HtmlAlignFormat & TextAlignFormat\n> = {\n parse: (format, element, context, defaultStyle) => {\n directionFormatHandler.parse(format, element, context, defaultStyle);\n\n const htmlAlign = element.getAttribute('align');\n\n if (htmlAlign) {\n format.htmlAlign = calcAlign(htmlAlign, format.direction);\n delete format.textAlign;\n delete context.blockFormat.textAlign;\n }\n },\n apply: (format, element) => {\n const dir: 'ltr' | 'rtl' = format.direction == 'rtl' ? 'rtl' : 'ltr';\n\n if (format.htmlAlign) {\n element.setAttribute('align', ResultMap[format.htmlAlign][dir]);\n }\n },\n};\n"]}
1
+ {"version":3,"file":"htmlAlignFormatHandler.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/formatHandlers/block/htmlAlignFormatHandler.ts"],"names":[],"mappings":";;;AAAA,oCAAoD;AACpD,mEAAkE;AAQlE;;GAEG;AACU,QAAA,sBAAsB,GAE/B;IACA,KAAK,EAAE,UAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY;QAC1C,yFAAyF;QACzF,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE;YAC1B,+CAAsB,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;YAErE,IAAM,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAEhD,IAAI,SAAS,EAAE;gBACX,MAAM,CAAC,SAAS,GAAG,IAAA,eAAS,EAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;gBAC1D,OAAO,MAAM,CAAC,SAAS,CAAC;gBACxB,OAAO,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC;aACxC;SACJ;IACL,CAAC;IACD,KAAK,EAAE,UAAC,MAAM,EAAE,OAAO;QACnB,IAAM,GAAG,GAAkB,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;QAErE,IAAI,MAAM,CAAC,SAAS,EAAE;YAClB,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,eAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;SACnE;IACL,CAAC;CACJ,CAAC","sourcesContent":["import { calcAlign, ResultMap } from '../utils/dir';\nimport { directionFormatHandler } from './directionFormatHandler';\nimport type {\n DirectionFormat,\n HtmlAlignFormat,\n TextAlignFormat,\n} from 'roosterjs-content-model-types';\nimport type { FormatHandler } from '../FormatHandler';\n\n/**\n * @internal\n */\nexport const htmlAlignFormatHandler: FormatHandler<\n DirectionFormat & HtmlAlignFormat & TextAlignFormat\n> = {\n parse: (format, element, context, defaultStyle) => {\n // When there is text-align in CSS style on the same element, we should ignore HTML align\n if (!element.style.textAlign) {\n directionFormatHandler.parse(format, element, context, defaultStyle);\n\n const htmlAlign = element.getAttribute('align');\n\n if (htmlAlign) {\n format.htmlAlign = calcAlign(htmlAlign, format.direction);\n delete format.textAlign;\n delete context.blockFormat.textAlign;\n }\n }\n },\n apply: (format, element) => {\n const dir: 'ltr' | 'rtl' = format.direction == 'rtl' ? 'rtl' : 'ltr';\n\n if (format.htmlAlign) {\n element.setAttribute('align', ResultMap[format.htmlAlign][dir]);\n }\n },\n};\n"]}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.normalizeParagraph = void 0;
4
+ var tslib_1 = require("tslib");
4
5
  var areSameFormats_1 = require("../../domToModel/utils/areSameFormats");
5
6
  var createBr_1 = require("../creators/createBr");
6
7
  var isEmpty_1 = require("./isEmpty");
@@ -36,6 +37,7 @@ function normalizeParagraph(paragraph) {
36
37
  }
37
38
  removeEmptyLinks(paragraph);
38
39
  removeEmptySegments(paragraph);
40
+ mergeTextSegments(paragraph);
39
41
  moveUpSegmentFormat(paragraph);
40
42
  }
41
43
  exports.normalizeParagraph = normalizeParagraph;
@@ -53,6 +55,40 @@ function removeEmptySegments(block) {
53
55
  }
54
56
  }
55
57
  }
58
+ function mergeTextSegments(block) {
59
+ var lastText = null;
60
+ for (var i = 0; i < block.segments.length; i++) {
61
+ var segment = block.segments[i];
62
+ if (segment.segmentType != 'Text') {
63
+ lastText = null;
64
+ }
65
+ else if (!lastText || !segmentsWithSameFormat(lastText, segment)) {
66
+ lastText = segment;
67
+ }
68
+ else {
69
+ var _a = (0, tslib_1.__read)((0, mutate_1.mutateSegments)(block, [lastText, segment]), 2), mutableBlock = _a[0], _b = (0, tslib_1.__read)(_a[1], 1), mutableLastText = _b[0];
70
+ mutableLastText.text += segment.text;
71
+ mutableBlock.segments.splice(i, 1);
72
+ i--;
73
+ }
74
+ }
75
+ }
76
+ function segmentsWithSameFormat(seg1, seg2) {
77
+ return (!!seg1.isSelected == !!seg2.isSelected &&
78
+ (0, areSameFormats_1.areSameFormats)(seg1.format, seg2.format) &&
79
+ areSameLinks(seg1.link, seg2.link) &&
80
+ areSameCodes(seg1.code, seg2.code));
81
+ }
82
+ function areSameLinks(link1, link2) {
83
+ return ((!link1 && !link2) ||
84
+ (link1 &&
85
+ link2 &&
86
+ (0, areSameFormats_1.areSameFormats)(link1.format, link2.format) &&
87
+ (0, areSameFormats_1.areSameFormats)(link1.dataset, link2.dataset)));
88
+ }
89
+ function areSameCodes(code1, code2) {
90
+ return (!code1 && !code2) || (code1 && code2 && (0, areSameFormats_1.areSameFormats)(code1.format, code2.format));
91
+ }
56
92
  function removeEmptyLinks(paragraph) {
57
93
  var marker = paragraph.segments.find(function (x) { return x.segmentType == 'SelectionMarker'; });
58
94
  if (marker) {
@@ -1 +1 @@
1
- {"version":3,"file":"normalizeParagraph.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelApi/common/normalizeParagraph.ts"],"names":[],"mappings":"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","sourcesContent":["import { areSameFormats } from '../../domToModel/utils/areSameFormats';\nimport { createBr } from '../creators/createBr';\nimport { isSegmentEmpty } from './isEmpty';\nimport { isWhiteSpacePreserved } from '../../domUtils/isWhiteSpacePreserved';\nimport { mutateBlock, mutateSegment } from './mutate';\nimport { normalizeAllSegments } from './normalizeSegment';\nimport type {\n ContentModelSegmentFormat,\n ReadonlyContentModelParagraph,\n ReadonlyContentModelSegment,\n} from 'roosterjs-content-model-types';\n\n/**\n * @param paragraph The paragraph to normalize\n * Normalize a paragraph. If it is empty, add a BR segment to make sure it can insert content\n */\nexport function normalizeParagraph(paragraph: ReadonlyContentModelParagraph) {\n const segments = paragraph.segments;\n\n if (!paragraph.isImplicit && segments.length > 0) {\n const last = segments[segments.length - 1];\n const secondLast = segments[segments.length - 2];\n\n if (\n last.segmentType == 'SelectionMarker' &&\n (!secondLast || secondLast.segmentType == 'Br')\n ) {\n mutateBlock(paragraph).segments.push(createBr(last.format));\n } else if (segments.length > 1 && segments[segments.length - 1].segmentType == 'Br') {\n const noMarkerSegments = segments.filter(x => x.segmentType != 'SelectionMarker');\n\n // When there is content with a <BR> tag at the end, we can remove the BR.\n // But if there are more than one <BR> at the end, do not remove them.\n if (\n noMarkerSegments.length > 1 &&\n noMarkerSegments[noMarkerSegments.length - 2].segmentType != 'Br'\n ) {\n mutateBlock(paragraph).segments.pop();\n }\n }\n\n normalizeParagraphStyle(paragraph);\n }\n\n if (!isWhiteSpacePreserved(paragraph.format.whiteSpace)) {\n normalizeAllSegments(paragraph);\n }\n\n removeEmptyLinks(paragraph);\n\n removeEmptySegments(paragraph);\n\n moveUpSegmentFormat(paragraph);\n}\n\nfunction normalizeParagraphStyle(paragraph: ReadonlyContentModelParagraph) {\n // New paragraph should not have white-space style\n if (\n paragraph.format.whiteSpace &&\n paragraph.segments.every(\n seg => seg.segmentType == 'Br' || seg.segmentType == 'SelectionMarker'\n )\n ) {\n delete mutateBlock(paragraph).format.whiteSpace;\n }\n}\n\nfunction removeEmptySegments(block: ReadonlyContentModelParagraph) {\n for (let j = block.segments.length - 1; j >= 0; j--) {\n if (isSegmentEmpty(block.segments[j])) {\n mutateBlock(block).segments.splice(j, 1);\n }\n }\n}\n\nfunction removeEmptyLinks(paragraph: ReadonlyContentModelParagraph) {\n const marker = paragraph.segments.find(x => x.segmentType == 'SelectionMarker');\n if (marker) {\n const markerIndex = paragraph.segments.indexOf(marker);\n const prev = paragraph.segments[markerIndex - 1];\n const next = paragraph.segments[markerIndex + 1];\n\n if (\n (prev &&\n !prev.link &&\n areSameFormats(prev.format, marker.format) &&\n (!next || (!next.link && areSameFormats(next.format, marker.format))) &&\n marker.link) ||\n (!prev &&\n marker.link &&\n next &&\n !next.link &&\n areSameFormats(next.format, marker.format))\n ) {\n mutateSegment(paragraph, marker, mutableMarker => {\n delete mutableMarker.link;\n });\n }\n }\n}\n\ntype FormatsToMoveUp = 'fontFamily' | 'fontSize' | 'textColor';\nconst formatsToMoveUp: FormatsToMoveUp[] = ['fontFamily', 'fontSize', 'textColor'];\n\n// When all segments are sharing the same segment format (font name, size and color), we can move its format to paragraph\nfunction moveUpSegmentFormat(paragraph: ReadonlyContentModelParagraph) {\n if (!paragraph.decorator) {\n const segments = paragraph.segments.filter(x => x.segmentType != 'SelectionMarker');\n const target = paragraph.segmentFormat || {};\n let changed = false;\n\n formatsToMoveUp.forEach(key => {\n changed = internalMoveUpSegmentFormat(segments, target, key) || changed;\n });\n\n if (changed) {\n mutateBlock(paragraph).segmentFormat = target;\n }\n }\n}\n\nfunction internalMoveUpSegmentFormat(\n segments: ReadonlyContentModelSegment[],\n target: ContentModelSegmentFormat,\n formatKey: FormatsToMoveUp\n): boolean {\n const firstFormat = segments[0]?.format;\n\n if (\n firstFormat?.[formatKey] &&\n segments.every(segment => segment.format[formatKey] == firstFormat[formatKey]) &&\n target[formatKey] != firstFormat[formatKey]\n ) {\n target[formatKey] = firstFormat[formatKey];\n return true;\n } else {\n return false;\n }\n}\n"]}
1
+ {"version":3,"file":"normalizeParagraph.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelApi/common/normalizeParagraph.ts"],"names":[],"mappings":";;;;AAAA,wEAAuE;AACvE,iDAAgD;AAChD,qCAA2C;AAC3C,8EAA6E;AAC7E,mCAAsE;AACtE,uDAA0D;AAW1D;;;GAGG;AACH,SAAgB,kBAAkB,CAAC,SAAwC;IACvE,IAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC;IAEpC,IAAI,CAAC,SAAS,CAAC,UAAU,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;QAC9C,IAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC3C,IAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAEjD,IACI,IAAI,CAAC,WAAW,IAAI,iBAAiB;YACrC,CAAC,CAAC,UAAU,IAAI,UAAU,CAAC,WAAW,IAAI,IAAI,CAAC,EACjD;YACE,IAAA,oBAAW,EAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAA,mBAAQ,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;SAC/D;aAAM,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,IAAI,EAAE;YACjF,IAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,WAAW,IAAI,iBAAiB,EAAlC,CAAkC,CAAC,CAAC;YAElF,0EAA0E;YAC1E,sEAAsE;YACtE,IACI,gBAAgB,CAAC,MAAM,GAAG,CAAC;gBAC3B,gBAAgB,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,IAAI,EACnE;gBACE,IAAA,oBAAW,EAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;aACzC;SACJ;QAED,uBAAuB,CAAC,SAAS,CAAC,CAAC;KACtC;IAED,IAAI,CAAC,IAAA,6CAAqB,EAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;QACrD,IAAA,uCAAoB,EAAC,SAAS,CAAC,CAAC;KACnC;IAED,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC5B,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAC/B,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC7B,mBAAmB,CAAC,SAAS,CAAC,CAAC;AACnC,CAAC;AApCD,gDAoCC;AAED,SAAS,uBAAuB,CAAC,SAAwC;IACrE,kDAAkD;IAClD,IACI,SAAS,CAAC,MAAM,CAAC,UAAU;QAC3B,SAAS,CAAC,QAAQ,CAAC,KAAK,CACpB,UAAA,GAAG,IAAI,OAAA,GAAG,CAAC,WAAW,IAAI,IAAI,IAAI,GAAG,CAAC,WAAW,IAAI,iBAAiB,EAA/D,CAA+D,CACzE,EACH;QACE,OAAO,IAAA,oBAAW,EAAC,SAAS,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;KACnD;AACL,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAoC;IAC7D,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;QACjD,IAAI,IAAA,wBAAc,EAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE;YACnC,IAAA,oBAAW,EAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;SAC5C;KACJ;AACL,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAoC;IAC3D,IAAI,QAAQ,GAAoC,IAAI,CAAC;IAErD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QAC5C,IAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAElC,IAAI,OAAO,CAAC,WAAW,IAAI,MAAM,EAAE;YAC/B,QAAQ,GAAG,IAAI,CAAC;SACnB;aAAM,IAAI,CAAC,QAAQ,IAAI,CAAC,sBAAsB,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE;YAChE,QAAQ,GAAG,OAAO,CAAC;SACtB;aAAM;YACG,IAAA,KAAA,oBAAoC,IAAA,uBAAc,EAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAA,EAA7E,YAAY,QAAA,EAAE,KAAA,6BAAiB,EAAhB,eAAe,QAA+C,CAAC;YAEpF,eAAoC,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAC3D,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACnC,CAAC,EAAE,CAAC;SACP;KACJ;AACL,CAAC;AAED,SAAS,sBAAsB,CAC3B,IAAiC,EACjC,IAAiC;IAEjC,OAAO,CACH,CAAC,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU;QACtC,IAAA,+BAAc,EAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;QACxC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC;QAClC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CACrC,CAAC;AACN,CAAC;AAED,SAAS,YAAY,CACjB,KAA2C,EAC3C,KAA2C;IAE3C,OAAO,CACH,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC;QAClB,CAAC,KAAK;YACF,KAAK;YACL,IAAA,+BAAc,EAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;YAC1C,IAAA,+BAAc,EAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CACpD,CAAC;AACN,CAAC;AAED,SAAS,YAAY,CACjB,KAA2C,EAC3C,KAA2C;IAE3C,OAAO,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,IAAI,IAAA,+BAAc,EAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;AAChG,CAAC;AAED,SAAS,gBAAgB,CAAC,SAAwC;IAC9D,IAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,WAAW,IAAI,iBAAiB,EAAlC,CAAkC,CAAC,CAAC;IAChF,IAAI,MAAM,EAAE;QACR,IAAM,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvD,IAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;QACjD,IAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;QAEjD,IACI,CAAC,IAAI;YACD,CAAC,IAAI,CAAC,IAAI;YACV,IAAA,+BAAc,EAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;YAC1C,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,IAAA,+BAAc,EAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;YACrE,MAAM,CAAC,IAAI,CAAC;YAChB,CAAC,CAAC,IAAI;gBACF,MAAM,CAAC,IAAI;gBACX,IAAI;gBACJ,CAAC,IAAI,CAAC,IAAI;gBACV,IAAA,+BAAc,EAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EACjD;YACE,IAAA,sBAAa,EAAC,SAAS,EAAE,MAAM,EAAE,UAAA,aAAa;gBAC1C,OAAO,aAAa,CAAC,IAAI,CAAC;YAC9B,CAAC,CAAC,CAAC;SACN;KACJ;AACL,CAAC;AAGD,IAAM,eAAe,GAAsB,CAAC,YAAY,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;AAEnF,yHAAyH;AACzH,SAAS,mBAAmB,CAAC,SAAwC;IACjE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE;QACtB,IAAM,UAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,WAAW,IAAI,iBAAiB,EAAlC,CAAkC,CAAC,CAAC;QACpF,IAAM,QAAM,GAAG,SAAS,CAAC,aAAa,IAAI,EAAE,CAAC;QAC7C,IAAI,SAAO,GAAG,KAAK,CAAC;QAEpB,eAAe,CAAC,OAAO,CAAC,UAAA,GAAG;YACvB,SAAO,GAAG,2BAA2B,CAAC,UAAQ,EAAE,QAAM,EAAE,GAAG,CAAC,IAAI,SAAO,CAAC;QAC5E,CAAC,CAAC,CAAC;QAEH,IAAI,SAAO,EAAE;YACT,IAAA,oBAAW,EAAC,SAAS,CAAC,CAAC,aAAa,GAAG,QAAM,CAAC;SACjD;KACJ;AACL,CAAC;AAED,SAAS,2BAA2B,CAChC,QAAuC,EACvC,MAAiC,EACjC,SAA0B;;IAE1B,IAAM,WAAW,GAAG,MAAA,QAAQ,CAAC,CAAC,CAAC,0CAAE,MAAM,CAAC;IAExC,IACI,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAG,SAAS,CAAC;QACxB,QAAQ,CAAC,KAAK,CAAC,UAAA,OAAO,IAAI,OAAA,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,WAAW,CAAC,SAAS,CAAC,EAAnD,CAAmD,CAAC;QAC9E,MAAM,CAAC,SAAS,CAAC,IAAI,WAAW,CAAC,SAAS,CAAC,EAC7C;QACE,MAAM,CAAC,SAAS,CAAC,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC;KACf;SAAM;QACH,OAAO,KAAK,CAAC;KAChB;AACL,CAAC","sourcesContent":["import { areSameFormats } from '../../domToModel/utils/areSameFormats';\nimport { createBr } from '../creators/createBr';\nimport { isSegmentEmpty } from './isEmpty';\nimport { isWhiteSpacePreserved } from '../../domUtils/isWhiteSpacePreserved';\nimport { mutateBlock, mutateSegment, mutateSegments } from './mutate';\nimport { normalizeAllSegments } from './normalizeSegment';\nimport type {\n ContentModelSegmentFormat,\n ContentModelText,\n ReadonlyContentModelCode,\n ReadonlyContentModelLink,\n ReadonlyContentModelParagraph,\n ReadonlyContentModelSegment,\n ReadonlyContentModelText,\n} from 'roosterjs-content-model-types';\n\n/**\n * @param paragraph The paragraph to normalize\n * Normalize a paragraph. If it is empty, add a BR segment to make sure it can insert content\n */\nexport function normalizeParagraph(paragraph: ReadonlyContentModelParagraph) {\n const segments = paragraph.segments;\n\n if (!paragraph.isImplicit && segments.length > 0) {\n const last = segments[segments.length - 1];\n const secondLast = segments[segments.length - 2];\n\n if (\n last.segmentType == 'SelectionMarker' &&\n (!secondLast || secondLast.segmentType == 'Br')\n ) {\n mutateBlock(paragraph).segments.push(createBr(last.format));\n } else if (segments.length > 1 && segments[segments.length - 1].segmentType == 'Br') {\n const noMarkerSegments = segments.filter(x => x.segmentType != 'SelectionMarker');\n\n // When there is content with a <BR> tag at the end, we can remove the BR.\n // But if there are more than one <BR> at the end, do not remove them.\n if (\n noMarkerSegments.length > 1 &&\n noMarkerSegments[noMarkerSegments.length - 2].segmentType != 'Br'\n ) {\n mutateBlock(paragraph).segments.pop();\n }\n }\n\n normalizeParagraphStyle(paragraph);\n }\n\n if (!isWhiteSpacePreserved(paragraph.format.whiteSpace)) {\n normalizeAllSegments(paragraph);\n }\n\n removeEmptyLinks(paragraph);\n removeEmptySegments(paragraph);\n mergeTextSegments(paragraph);\n moveUpSegmentFormat(paragraph);\n}\n\nfunction normalizeParagraphStyle(paragraph: ReadonlyContentModelParagraph) {\n // New paragraph should not have white-space style\n if (\n paragraph.format.whiteSpace &&\n paragraph.segments.every(\n seg => seg.segmentType == 'Br' || seg.segmentType == 'SelectionMarker'\n )\n ) {\n delete mutateBlock(paragraph).format.whiteSpace;\n }\n}\n\nfunction removeEmptySegments(block: ReadonlyContentModelParagraph) {\n for (let j = block.segments.length - 1; j >= 0; j--) {\n if (isSegmentEmpty(block.segments[j])) {\n mutateBlock(block).segments.splice(j, 1);\n }\n }\n}\n\nfunction mergeTextSegments(block: ReadonlyContentModelParagraph) {\n let lastText: ReadonlyContentModelText | null = null;\n\n for (let i = 0; i < block.segments.length; i++) {\n const segment = block.segments[i];\n\n if (segment.segmentType != 'Text') {\n lastText = null;\n } else if (!lastText || !segmentsWithSameFormat(lastText, segment)) {\n lastText = segment;\n } else {\n const [mutableBlock, [mutableLastText]] = mutateSegments(block, [lastText, segment]);\n\n (mutableLastText as ContentModelText).text += segment.text;\n mutableBlock.segments.splice(i, 1);\n i--;\n }\n }\n}\n\nfunction segmentsWithSameFormat(\n seg1: ReadonlyContentModelSegment,\n seg2: ReadonlyContentModelSegment\n) {\n return (\n !!seg1.isSelected == !!seg2.isSelected &&\n areSameFormats(seg1.format, seg2.format) &&\n areSameLinks(seg1.link, seg2.link) &&\n areSameCodes(seg1.code, seg2.code)\n );\n}\n\nfunction areSameLinks(\n link1: ReadonlyContentModelLink | undefined,\n link2: ReadonlyContentModelLink | undefined\n) {\n return (\n (!link1 && !link2) ||\n (link1 &&\n link2 &&\n areSameFormats(link1.format, link2.format) &&\n areSameFormats(link1.dataset, link2.dataset))\n );\n}\n\nfunction areSameCodes(\n code1: ReadonlyContentModelCode | undefined,\n code2: ReadonlyContentModelCode | undefined\n) {\n return (!code1 && !code2) || (code1 && code2 && areSameFormats(code1.format, code2.format));\n}\n\nfunction removeEmptyLinks(paragraph: ReadonlyContentModelParagraph) {\n const marker = paragraph.segments.find(x => x.segmentType == 'SelectionMarker');\n if (marker) {\n const markerIndex = paragraph.segments.indexOf(marker);\n const prev = paragraph.segments[markerIndex - 1];\n const next = paragraph.segments[markerIndex + 1];\n\n if (\n (prev &&\n !prev.link &&\n areSameFormats(prev.format, marker.format) &&\n (!next || (!next.link && areSameFormats(next.format, marker.format))) &&\n marker.link) ||\n (!prev &&\n marker.link &&\n next &&\n !next.link &&\n areSameFormats(next.format, marker.format))\n ) {\n mutateSegment(paragraph, marker, mutableMarker => {\n delete mutableMarker.link;\n });\n }\n }\n}\n\ntype FormatsToMoveUp = 'fontFamily' | 'fontSize' | 'textColor';\nconst formatsToMoveUp: FormatsToMoveUp[] = ['fontFamily', 'fontSize', 'textColor'];\n\n// When all segments are sharing the same segment format (font name, size and color), we can move its format to paragraph\nfunction moveUpSegmentFormat(paragraph: ReadonlyContentModelParagraph) {\n if (!paragraph.decorator) {\n const segments = paragraph.segments.filter(x => x.segmentType != 'SelectionMarker');\n const target = paragraph.segmentFormat || {};\n let changed = false;\n\n formatsToMoveUp.forEach(key => {\n changed = internalMoveUpSegmentFormat(segments, target, key) || changed;\n });\n\n if (changed) {\n mutateBlock(paragraph).segmentFormat = target;\n }\n }\n}\n\nfunction internalMoveUpSegmentFormat(\n segments: ReadonlyContentModelSegment[],\n target: ContentModelSegmentFormat,\n formatKey: FormatsToMoveUp\n): boolean {\n const firstFormat = segments[0]?.format;\n\n if (\n firstFormat?.[formatKey] &&\n segments.every(segment => segment.format[formatKey] == firstFormat[formatKey]) &&\n target[formatKey] != firstFormat[formatKey]\n ) {\n target[formatKey] = firstFormat[formatKey];\n return true;\n } else {\n return false;\n }\n}\n"]}
@@ -41,7 +41,7 @@ function deleteExpandedSelection(model, formatContext) {
41
41
  // so we can put cursor here after delete
42
42
  paragraph = block_1;
43
43
  insertMarkerIndex = indexes[0];
44
- markerFormat = (0, getSegmentTextFormat_1.getSegmentTextFormat)(segments[0]);
44
+ markerFormat = (0, getSegmentTextFormat_1.getSegmentTextFormat)(segments[0], true /*includingBIU*/);
45
45
  context.lastParagraph = paragraph;
46
46
  context.lastTableContext = tableContext;
47
47
  segments.forEach(function (segment, i) {
@@ -1 +1 @@
1
- {"version":3,"file":"deleteExpandedSelection.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelApi/editing/deleteExpandedSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { createBr } from '../creators/createBr';\nimport { createParagraph } from '../creators/createParagraph';\nimport { createSelectionMarker } from '../creators/createSelectionMarker';\nimport { deleteBlock } from './deleteBlock';\nimport { deleteSegment } from './deleteSegment';\nimport { getSegmentTextFormat } from './getSegmentTextFormat';\nimport { iterateSelections } from '../selection/iterateSelections';\nimport { mutateBlock, mutateSegments } from '../common/mutate';\nimport { setParagraphNotImplicit } from '../block/setParagraphNotImplicit';\nimport type {\n ContentModelSelectionMarker,\n DeleteSelectionContext,\n FormatContentModelContext,\n InsertPoint,\n IterateSelectionsOption,\n ReadonlyContentModelBlockGroup,\n ReadonlyContentModelDocument,\n ReadonlyTableSelectionContext,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\nconst DeleteSelectionIteratingOptions: IterateSelectionsOption = {\n contentUnderSelectedTableCell: 'ignoreForTableOrCell', // When a table cell is selected, we replace all content for this cell, so no need to go into its content\n contentUnderSelectedGeneralElement: 'generalElementOnly', // When a general element is selected, we replace the whole element so no need to go into its content\n includeListFormatHolder: 'never',\n};\n\n/**\n * @internal\n * Iterate the model and find all selected content if any, delete them, and keep/create an insert point\n * at the first deleted position so that we know where to put cursor to after delete\n */\nexport function deleteExpandedSelection(\n model: ReadonlyContentModelDocument,\n formatContext?: FormatContentModelContext\n): DeleteSelectionContext {\n const context: DeleteSelectionContext = {\n deleteResult: 'notDeleted',\n insertPoint: null,\n formatContext,\n };\n\n iterateSelections(\n model,\n (path, tableContext, readonlyBlock, readonlySegments) => {\n // Set paragraph, format and index for default position where we will put cursor to.\n // Later we can overwrite these info when process the selections\n let paragraph: ShallowMutableContentModelParagraph = createParagraph(\n true /*implicit*/,\n undefined /*blockFormat*/,\n model.format\n );\n let markerFormat = model.format;\n let insertMarkerIndex = 0;\n\n if (readonlySegments && readonlyBlock?.blockType == 'Paragraph') {\n const [block, segments, indexes] = mutateSegments(readonlyBlock, readonlySegments);\n\n // Delete segments inside a paragraph\n if (segments[0]) {\n // Now that we have found a paragraph with selections, we can overwrite the default paragraph with this one\n // so we can put cursor here after delete\n paragraph = block;\n insertMarkerIndex = indexes[0];\n markerFormat = getSegmentTextFormat(segments[0]);\n\n context.lastParagraph = paragraph;\n context.lastTableContext = tableContext;\n\n segments.forEach((segment, i) => {\n if (\n i == 0 &&\n !context.insertPoint &&\n segment.segmentType == 'SelectionMarker'\n ) {\n // First time we hit a selection and it is a selection marker, just mark it and not need to delete\n // because this is possible a collapsed selection, then it will be handled later\n context.insertPoint = createInsertPoint(\n segment,\n block,\n path,\n tableContext\n );\n } else if (deleteSegment(block, segment, context.formatContext)) {\n context.deleteResult = 'range';\n }\n });\n\n // Since we are operating on this paragraph and it possible we delete everything from this paragraph,\n // Need to make it \"not implicit\" so that it will always have a container element, so that when we do normalization\n // of this paragraph, a BR can be added if need\n if (context.deleteResult == 'range') {\n setParagraphNotImplicit(block);\n }\n }\n } else if (readonlyBlock) {\n // Delete a whole block (divider, table, ...)\n const blocks = mutateBlock(path[0]).blocks;\n\n if (deleteBlock(blocks, readonlyBlock, paragraph, context.formatContext)) {\n context.deleteResult = 'range';\n }\n } else if (tableContext) {\n // Delete a whole table cell\n const { table, colIndex, rowIndex } = tableContext;\n const mutableTable = mutateBlock(table);\n const row = mutableTable.rows[rowIndex];\n const cell = mutateBlock(row.cells[colIndex]);\n\n path = [cell, ...path];\n paragraph.segments.push(createBr(model.format));\n cell.blocks = [paragraph];\n\n context.deleteResult = 'range';\n }\n\n if (!context.insertPoint) {\n // If we have not got a insert point after delete and we have a paragraph to put an insert point in, create insert point now\n const marker = createSelectionMarker(markerFormat);\n\n setParagraphNotImplicit(paragraph);\n paragraph.segments.splice(insertMarkerIndex, 0, marker);\n context.insertPoint = createInsertPoint(marker, paragraph, path, tableContext);\n }\n },\n DeleteSelectionIteratingOptions\n );\n\n return context;\n}\n\nfunction createInsertPoint(\n marker: ContentModelSelectionMarker,\n paragraph: ShallowMutableContentModelParagraph,\n path: ReadonlyContentModelBlockGroup[],\n tableContext: ReadonlyTableSelectionContext | undefined\n): InsertPoint {\n return {\n marker,\n paragraph,\n path,\n tableContext,\n };\n}\n"]}
1
+ {"version":3,"file":"deleteExpandedSelection.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelApi/editing/deleteExpandedSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { createBr } from '../creators/createBr';\nimport { createParagraph } from '../creators/createParagraph';\nimport { createSelectionMarker } from '../creators/createSelectionMarker';\nimport { deleteBlock } from './deleteBlock';\nimport { deleteSegment } from './deleteSegment';\nimport { getSegmentTextFormat } from './getSegmentTextFormat';\nimport { iterateSelections } from '../selection/iterateSelections';\nimport { mutateBlock, mutateSegments } from '../common/mutate';\nimport { setParagraphNotImplicit } from '../block/setParagraphNotImplicit';\nimport type {\n ContentModelSelectionMarker,\n DeleteSelectionContext,\n FormatContentModelContext,\n InsertPoint,\n IterateSelectionsOption,\n ReadonlyContentModelBlockGroup,\n ReadonlyContentModelDocument,\n ReadonlyTableSelectionContext,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\nconst DeleteSelectionIteratingOptions: IterateSelectionsOption = {\n contentUnderSelectedTableCell: 'ignoreForTableOrCell', // When a table cell is selected, we replace all content for this cell, so no need to go into its content\n contentUnderSelectedGeneralElement: 'generalElementOnly', // When a general element is selected, we replace the whole element so no need to go into its content\n includeListFormatHolder: 'never',\n};\n\n/**\n * @internal\n * Iterate the model and find all selected content if any, delete them, and keep/create an insert point\n * at the first deleted position so that we know where to put cursor to after delete\n */\nexport function deleteExpandedSelection(\n model: ReadonlyContentModelDocument,\n formatContext?: FormatContentModelContext\n): DeleteSelectionContext {\n const context: DeleteSelectionContext = {\n deleteResult: 'notDeleted',\n insertPoint: null,\n formatContext,\n };\n\n iterateSelections(\n model,\n (path, tableContext, readonlyBlock, readonlySegments) => {\n // Set paragraph, format and index for default position where we will put cursor to.\n // Later we can overwrite these info when process the selections\n let paragraph: ShallowMutableContentModelParagraph = createParagraph(\n true /*implicit*/,\n undefined /*blockFormat*/,\n model.format\n );\n let markerFormat = model.format;\n let insertMarkerIndex = 0;\n\n if (readonlySegments && readonlyBlock?.blockType == 'Paragraph') {\n const [block, segments, indexes] = mutateSegments(readonlyBlock, readonlySegments);\n\n // Delete segments inside a paragraph\n if (segments[0]) {\n // Now that we have found a paragraph with selections, we can overwrite the default paragraph with this one\n // so we can put cursor here after delete\n paragraph = block;\n insertMarkerIndex = indexes[0];\n markerFormat = getSegmentTextFormat(segments[0], true /*includingBIU*/);\n\n context.lastParagraph = paragraph;\n context.lastTableContext = tableContext;\n\n segments.forEach((segment, i) => {\n if (\n i == 0 &&\n !context.insertPoint &&\n segment.segmentType == 'SelectionMarker'\n ) {\n // First time we hit a selection and it is a selection marker, just mark it and not need to delete\n // because this is possible a collapsed selection, then it will be handled later\n context.insertPoint = createInsertPoint(\n segment,\n block,\n path,\n tableContext\n );\n } else if (deleteSegment(block, segment, context.formatContext)) {\n context.deleteResult = 'range';\n }\n });\n\n // Since we are operating on this paragraph and it possible we delete everything from this paragraph,\n // Need to make it \"not implicit\" so that it will always have a container element, so that when we do normalization\n // of this paragraph, a BR can be added if need\n if (context.deleteResult == 'range') {\n setParagraphNotImplicit(block);\n }\n }\n } else if (readonlyBlock) {\n // Delete a whole block (divider, table, ...)\n const blocks = mutateBlock(path[0]).blocks;\n\n if (deleteBlock(blocks, readonlyBlock, paragraph, context.formatContext)) {\n context.deleteResult = 'range';\n }\n } else if (tableContext) {\n // Delete a whole table cell\n const { table, colIndex, rowIndex } = tableContext;\n const mutableTable = mutateBlock(table);\n const row = mutableTable.rows[rowIndex];\n const cell = mutateBlock(row.cells[colIndex]);\n\n path = [cell, ...path];\n paragraph.segments.push(createBr(model.format));\n cell.blocks = [paragraph];\n\n context.deleteResult = 'range';\n }\n\n if (!context.insertPoint) {\n // If we have not got a insert point after delete and we have a paragraph to put an insert point in, create insert point now\n const marker = createSelectionMarker(markerFormat);\n\n setParagraphNotImplicit(paragraph);\n paragraph.segments.splice(insertMarkerIndex, 0, marker);\n context.insertPoint = createInsertPoint(marker, paragraph, path, tableContext);\n }\n },\n DeleteSelectionIteratingOptions\n );\n\n return context;\n}\n\nfunction createInsertPoint(\n marker: ContentModelSelectionMarker,\n paragraph: ShallowMutableContentModelParagraph,\n path: ReadonlyContentModelBlockGroup[],\n tableContext: ReadonlyTableSelectionContext | undefined\n): InsertPoint {\n return {\n marker,\n paragraph,\n path,\n tableContext,\n };\n}\n"]}
@@ -2,6 +2,7 @@ import type { ContentModelSegmentFormat, ReadonlyContentModelSegment } from 'roo
2
2
  /**
3
3
  * Get the text format of a segment, this function will return only format that is applicable to text
4
4
  * @param segment The segment to get format from
5
+ * @param includingBIU When pass true, also get Bold/Italic/Underline format
5
6
  * @returns
6
7
  */
7
- export declare function getSegmentTextFormat(segment: ReadonlyContentModelSegment): ContentModelSegmentFormat;
8
+ export declare function getSegmentTextFormat(segment: ReadonlyContentModelSegment, includingBIU?: boolean): ContentModelSegmentFormat;
@@ -4,18 +4,22 @@ exports.getSegmentTextFormat = void 0;
4
4
  /**
5
5
  * Get the text format of a segment, this function will return only format that is applicable to text
6
6
  * @param segment The segment to get format from
7
+ * @param includingBIU When pass true, also get Bold/Italic/Underline format
7
8
  * @returns
8
9
  */
9
- function getSegmentTextFormat(segment) {
10
+ function getSegmentTextFormat(segment, includingBIU) {
10
11
  var _a;
11
- var _b = (_a = segment === null || segment === void 0 ? void 0 : segment.format) !== null && _a !== void 0 ? _a : {}, fontFamily = _b.fontFamily, fontSize = _b.fontSize, textColor = _b.textColor, backgroundColor = _b.backgroundColor, letterSpacing = _b.letterSpacing, lineHeight = _b.lineHeight;
12
+ var format = (_a = segment.format) !== null && _a !== void 0 ? _a : {};
12
13
  var textFormat = {
13
- fontFamily: fontFamily,
14
- fontSize: fontSize,
15
- textColor: textColor,
16
- backgroundColor: backgroundColor,
17
- letterSpacing: letterSpacing,
18
- lineHeight: lineHeight,
14
+ fontFamily: format.fontFamily,
15
+ fontSize: format.fontSize,
16
+ textColor: format.textColor,
17
+ backgroundColor: format.backgroundColor,
18
+ letterSpacing: format.letterSpacing,
19
+ lineHeight: format.lineHeight,
20
+ fontWeight: includingBIU ? format.fontWeight : undefined,
21
+ italic: includingBIU ? format.italic : undefined,
22
+ underline: includingBIU ? format.underline : undefined,
19
23
  };
20
24
  return removeUndefinedValues(textFormat);
21
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"getSegmentTextFormat.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelApi/editing/getSegmentTextFormat.ts"],"names":[],"mappings":";;;AAKA;;;;GAIG;AACH,SAAgB,oBAAoB,CAChC,OAAoC;;IAE9B,IAAA,KACF,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,mCAAI,EAAE,EADjB,UAAU,gBAAA,EAAE,QAAQ,cAAA,EAAE,SAAS,eAAA,EAAE,eAAe,qBAAA,EAAE,aAAa,mBAAA,EAAE,UAAU,gBAC1D,CAAC;IAE1B,IAAM,UAAU,GAA8B;QAC1C,UAAU,YAAA;QACV,QAAQ,UAAA;QACR,SAAS,WAAA;QACT,eAAe,iBAAA;QACf,aAAa,eAAA;QACb,UAAU,YAAA;KACb,CAAC;IAEF,OAAO,qBAAqB,CAAC,UAAU,CAAC,CAAC;AAC7C,CAAC;AAhBD,oDAgBC;AAED,IAAM,qBAAqB,GAAG,UAAC,MAAiC;IAC5D,IAAM,UAAU,GAA2D,EAAE,CAAC;IAC9E,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,UAAA,GAAG;QAC1B,IAAM,KAAK,GAAG,MAAM,CAAC,GAAsC,CAAC,CAAC;QAE7D,IAAI,KAAK,KAAK,SAAS,EAAE;YACrB,UAAU,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;SAC3B;IACL,CAAC,CAAC,CAAC;IACH,OAAO,UAAU,CAAC;AACtB,CAAC,CAAC","sourcesContent":["import type {\n ContentModelSegmentFormat,\n ReadonlyContentModelSegment,\n} from 'roosterjs-content-model-types';\n\n/**\n * Get the text format of a segment, this function will return only format that is applicable to text\n * @param segment The segment to get format from\n * @returns\n */\nexport function getSegmentTextFormat(\n segment: ReadonlyContentModelSegment\n): ContentModelSegmentFormat {\n const { fontFamily, fontSize, textColor, backgroundColor, letterSpacing, lineHeight } =\n segment?.format ?? {};\n\n const textFormat: ContentModelSegmentFormat = {\n fontFamily,\n fontSize,\n textColor,\n backgroundColor,\n letterSpacing,\n lineHeight,\n };\n\n return removeUndefinedValues(textFormat);\n}\n\nconst removeUndefinedValues = (format: ContentModelSegmentFormat): ContentModelSegmentFormat => {\n const textFormat: Record<string, string | undefined | boolean | never[]> = {};\n Object.keys(format).filter(key => {\n const value = format[key as keyof ContentModelSegmentFormat];\n\n if (value !== undefined) {\n textFormat[key] = value;\n }\n });\n return textFormat;\n};\n"]}
1
+ {"version":3,"file":"getSegmentTextFormat.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelApi/editing/getSegmentTextFormat.ts"],"names":[],"mappings":";;;AAKA;;;;;GAKG;AACH,SAAgB,oBAAoB,CAChC,OAAoC,EACpC,YAAsB;;IAEtB,IAAM,MAAM,GAAG,MAAA,OAAO,CAAC,MAAM,mCAAI,EAAE,CAAC;IACpC,IAAM,UAAU,GAA8B;QAC1C,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;QACxD,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;QAChD,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;KACzD,CAAC;IAEF,OAAO,qBAAqB,CAAC,UAAU,CAAC,CAAC;AAC7C,CAAC;AAlBD,oDAkBC;AAED,IAAM,qBAAqB,GAAG,UAAC,MAAiC;IAC5D,IAAM,UAAU,GAA2D,EAAE,CAAC;IAC9E,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,UAAA,GAAG;QAC1B,IAAM,KAAK,GAAG,MAAM,CAAC,GAAsC,CAAC,CAAC;QAE7D,IAAI,KAAK,KAAK,SAAS,EAAE;YACrB,UAAU,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;SAC3B;IACL,CAAC,CAAC,CAAC;IACH,OAAO,UAAU,CAAC;AACtB,CAAC,CAAC","sourcesContent":["import type {\n ContentModelSegmentFormat,\n ReadonlyContentModelSegment,\n} from 'roosterjs-content-model-types';\n\n/**\n * Get the text format of a segment, this function will return only format that is applicable to text\n * @param segment The segment to get format from\n * @param includingBIU When pass true, also get Bold/Italic/Underline format\n * @returns\n */\nexport function getSegmentTextFormat(\n segment: ReadonlyContentModelSegment,\n includingBIU?: boolean\n): ContentModelSegmentFormat {\n const format = segment.format ?? {};\n const textFormat: ContentModelSegmentFormat = {\n fontFamily: format.fontFamily,\n fontSize: format.fontSize,\n textColor: format.textColor,\n backgroundColor: format.backgroundColor,\n letterSpacing: format.letterSpacing,\n lineHeight: format.lineHeight,\n fontWeight: includingBIU ? format.fontWeight : undefined,\n italic: includingBIU ? format.italic : undefined,\n underline: includingBIU ? format.underline : undefined,\n };\n\n return removeUndefinedValues(textFormat);\n}\n\nconst removeUndefinedValues = (format: ContentModelSegmentFormat): ContentModelSegmentFormat => {\n const textFormat: Record<string, string | undefined | boolean | never[]> = {};\n Object.keys(format).filter(key => {\n const value = format[key as keyof ContentModelSegmentFormat];\n\n if (value !== undefined) {\n textFormat[key] = value;\n }\n });\n return textFormat;\n};\n"]}
@@ -286,12 +286,26 @@ function getSegmentFormatInLinkFormat(targetFormat) {
286
286
  return result;
287
287
  }
288
288
  function mergeLinkFormat(applyDefaultFormatOption, targetFormat, sourceFormat) {
289
- return applyDefaultFormatOption == 'mergeAll'
290
- ? (0, tslib_1.__assign)((0, tslib_1.__assign)({}, getSegmentFormatInLinkFormat(targetFormat)), sourceFormat) : (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, getFormatWithoutSegmentFormat(sourceFormat)), getSegmentFormatInLinkFormat(targetFormat)), getSemanticFormat(sourceFormat)), getHyperlinkTextColor(sourceFormat));
289
+ switch (applyDefaultFormatOption) {
290
+ case 'mergeAll':
291
+ case 'preferSource':
292
+ return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, getSegmentFormatInLinkFormat(targetFormat)), sourceFormat);
293
+ case 'keepSourceEmphasisFormat':
294
+ return (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, getFormatWithoutSegmentFormat(sourceFormat)), getSegmentFormatInLinkFormat(targetFormat)), getSemanticFormat(sourceFormat)), getHyperlinkTextColor(sourceFormat));
295
+ case 'preferTarget':
296
+ return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, sourceFormat), getSegmentFormatInLinkFormat(targetFormat));
297
+ }
291
298
  }
292
299
  function mergeSegmentFormat(applyDefaultFormatOption, targetFormat, sourceFormat) {
293
- return applyDefaultFormatOption == 'mergeAll'
294
- ? (0, tslib_1.__assign)((0, tslib_1.__assign)({}, targetFormat), sourceFormat) : (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, getFormatWithoutSegmentFormat(sourceFormat)), targetFormat), getSemanticFormat(sourceFormat));
300
+ switch (applyDefaultFormatOption) {
301
+ case 'mergeAll':
302
+ case 'preferSource':
303
+ return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, targetFormat), sourceFormat);
304
+ case 'preferTarget':
305
+ return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, sourceFormat), targetFormat);
306
+ case 'keepSourceEmphasisFormat':
307
+ return (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, getFormatWithoutSegmentFormat(sourceFormat)), targetFormat), getSemanticFormat(sourceFormat));
308
+ }
295
309
  }
296
310
  function getSemanticFormat(segmentFormat) {
297
311
  var result = {};
@@ -1 +1 @@
1
- {"version":3,"file":"mergeModel.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelApi/editing/mergeModel.ts"],"names":[],"mappings":"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","sourcesContent":["import { addBlock } from '../common/addBlock';\nimport { addSegment } from '../common/addSegment';\nimport { applyTableFormat } from './applyTableFormat';\nimport { createListItem } from '../creators/createListItem';\nimport { createParagraph } from '../creators/createParagraph';\nimport { createSelectionMarker } from '../creators/createSelectionMarker';\nimport { createTableCell } from '../creators/createTableCell';\nimport { deleteSelection } from './deleteSelection';\nimport { EmptySegmentFormat } from '../../constants/EmptySegmentFormat';\nimport { getClosestAncestorBlockGroupIndex } from './getClosestAncestorBlockGroupIndex';\nimport { getObjectKeys } from '../..//domUtils/getObjectKeys';\nimport { mutateBlock } from '../common/mutate';\nimport { normalizeContentModel } from '../common/normalizeContentModel';\nimport { normalizeTable } from './normalizeTable';\nimport type {\n ContentModelBlock,\n ContentModelBlockFormat,\n ContentModelDocument,\n ContentModelHyperLinkFormat,\n ContentModelListItem,\n ContentModelParagraph,\n ContentModelSegmentFormat,\n ContentModelTable,\n FormatContentModelContext,\n InsertPoint,\n MergeModelOption,\n ReadonlyContentModelBlock,\n ReadonlyContentModelBlockGroup,\n ReadonlyContentModelDocument,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\nconst HeadingTags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];\nconst KeysOfSegmentFormat = getObjectKeys(EmptySegmentFormat);\n\n/**\n * Merge source model into target mode\n * @param target Target Content Model that will merge content into\n * @param source Source Content Model will be merged to target model\n * @param context Format context. When call this function inside formatContentModel, provide this context so that formatContentModel will do extra handling to the result\n * @param options More options, see MergeModelOption\n * @returns Insert point after merge, or null if there is no insert point\n */\nexport function mergeModel(\n target: ReadonlyContentModelDocument,\n source: ContentModelDocument,\n context?: FormatContentModelContext,\n options?: MergeModelOption\n): InsertPoint | null {\n const insertPosition =\n options?.insertPosition ?? deleteSelection(target, [], context).insertPoint;\n\n const { addParagraphAfterMergedContent, mergeFormat, mergeTable } = options || {};\n\n if (addParagraphAfterMergedContent && !mergeTable) {\n const { paragraph, marker } = insertPosition || {};\n const newPara = createParagraph(false /* isImplicit */, paragraph?.format, marker?.format);\n addBlock(source, newPara);\n }\n\n if (insertPosition) {\n if (mergeFormat && mergeFormat != 'none') {\n const newFormat: ContentModelSegmentFormat = {\n ...(target.format || {}),\n ...insertPosition.marker.format,\n };\n\n applyDefaultFormat(source, newFormat, mergeFormat);\n }\n\n for (let i = 0; i < source.blocks.length; i++) {\n const block = source.blocks[i];\n\n switch (block.blockType) {\n case 'Paragraph':\n mergeParagraph(insertPosition, block, i == 0, context, options);\n break;\n\n case 'Divider':\n insertBlock(insertPosition, block);\n break;\n\n case 'Entity':\n insertBlock(insertPosition, block);\n context?.newEntities.push(block);\n break;\n\n case 'Table':\n if (source.blocks.length == 1 && mergeTable) {\n mergeTables(insertPosition, block, source);\n } else {\n insertBlock(insertPosition, block);\n }\n break;\n\n case 'BlockGroup':\n switch (block.blockGroupType) {\n case 'General':\n case 'FormatContainer':\n insertBlock(insertPosition, block);\n break;\n case 'ListItem':\n mergeList(insertPosition, block);\n break;\n }\n break;\n }\n }\n }\n\n normalizeContentModel(target);\n\n return insertPosition;\n}\n\nfunction mergeParagraph(\n markerPosition: InsertPoint,\n newPara: ContentModelParagraph,\n mergeToCurrentParagraph: boolean,\n context?: FormatContentModelContext,\n option?: MergeModelOption\n) {\n const { paragraph, marker } = markerPosition;\n const newParagraph = mergeToCurrentParagraph\n ? paragraph\n : splitParagraph(markerPosition, newPara.format);\n const segmentIndex = newParagraph.segments.indexOf(marker);\n\n if (option?.mergeFormat == 'none' && mergeToCurrentParagraph) {\n newParagraph.segments.forEach(segment => {\n segment.format = { ...(newParagraph.segmentFormat || {}), ...segment.format };\n });\n delete newParagraph.segmentFormat;\n }\n if (segmentIndex >= 0) {\n for (let i = 0; i < newPara.segments.length; i++) {\n const segment = newPara.segments[i];\n\n newParagraph.segments.splice(segmentIndex + i, 0, segment);\n\n if (context) {\n if (segment.segmentType == 'Entity') {\n context.newEntities.push(segment);\n }\n\n if (segment.segmentType == 'Image') {\n context.newImages.push(segment);\n }\n }\n }\n }\n\n if (newPara.decorator) {\n newParagraph.decorator = { ...newPara.decorator };\n if (HeadingTags.indexOf(newParagraph.decorator.tagName) > -1) {\n const sourceKeys: (keyof ContentModelSegmentFormat)[] = getObjectKeys(\n newParagraph.decorator.format\n );\n const segmentDecoratorKeys: (keyof ContentModelSegmentFormat)[] = getObjectKeys(\n newParagraph.segmentFormat || {}\n );\n\n sourceKeys.forEach(key => {\n if (segmentDecoratorKeys.indexOf(key) > -1) {\n delete newParagraph.segmentFormat?.[key];\n }\n });\n }\n }\n\n if (!mergeToCurrentParagraph) {\n newParagraph.format = newPara.format;\n } else {\n newParagraph.format = {\n ...newParagraph.format,\n ...newPara.format,\n };\n }\n}\n\nfunction mergeTables(\n markerPosition: InsertPoint,\n newTable: ContentModelTable,\n source: ContentModelDocument\n) {\n const { tableContext, marker } = markerPosition;\n\n if (tableContext && source.blocks.length == 1 && source.blocks[0] == newTable) {\n const { table: readonlyTable, colIndex, rowIndex } = tableContext;\n const table = mutateBlock(readonlyTable);\n\n for (let i = 0; i < newTable.rows.length; i++) {\n for (let j = 0; j < newTable.rows[i].cells.length; j++) {\n const newCell = newTable.rows[i].cells[j];\n\n if (i == 0 && colIndex + j >= table.rows[0].cells.length) {\n for (let k = 0; k < table.rows.length; k++) {\n const leftCell = table.rows[k]?.cells[colIndex + j - 1];\n table.rows[k].cells[colIndex + j] = createTableCell(\n false /*spanLeft*/,\n false /*spanAbove*/,\n leftCell?.isHeader,\n leftCell?.format\n );\n }\n }\n\n if (j == 0 && rowIndex + i >= table.rows.length) {\n if (!table.rows[rowIndex + i]) {\n table.rows[rowIndex + i] = {\n cells: [],\n format: {},\n height: 0,\n };\n }\n\n for (let k = 0; k < table.rows[rowIndex].cells.length; k++) {\n const aboveCell = table.rows[rowIndex + i - 1]?.cells[k];\n table.rows[rowIndex + i].cells[k] = createTableCell(\n false /*spanLeft*/,\n false /*spanAbove*/,\n false /*isHeader*/,\n aboveCell?.format\n );\n }\n }\n\n const oldCell = table.rows[rowIndex + i].cells[colIndex + j];\n table.rows[rowIndex + i].cells[colIndex + j] = newCell;\n\n if (i == 0 && j == 0) {\n const newMarker = createSelectionMarker(marker.format);\n const newPara = addSegment(newCell, newMarker);\n\n if (markerPosition.path[0] == oldCell) {\n // Update insert point to match the change result\n markerPosition.path[0] = newCell;\n markerPosition.marker = newMarker;\n markerPosition.paragraph = newPara;\n }\n }\n }\n }\n\n normalizeTable(table, markerPosition.marker.format);\n applyTableFormat(table, undefined /*newFormat*/, true /*keepCellShade*/);\n } else {\n insertBlock(markerPosition, newTable);\n }\n}\n\nfunction mergeList(markerPosition: InsertPoint, newList: ContentModelListItem) {\n splitParagraph(markerPosition, newList.format);\n\n const { path, paragraph } = markerPosition;\n\n const listItemIndex = getClosestAncestorBlockGroupIndex(path, ['ListItem']);\n const listItem = path[listItemIndex] as ContentModelListItem;\n const listParent = path[listItemIndex + 1]; // It is ok here when index is -1, that means there is no list and we just insert a new paragraph and use path[0] as its parent\n const blockIndex = listParent.blocks.indexOf(listItem || paragraph);\n\n if (blockIndex >= 0) {\n mutateBlock(listParent).blocks.splice(blockIndex, 0, newList);\n }\n\n if (listItem) {\n listItem?.levels.forEach((level, i) => {\n newList.levels[i] = { ...level };\n });\n }\n}\n\nfunction splitParagraph(markerPosition: InsertPoint, newParaFormat: ContentModelBlockFormat) {\n const { paragraph, marker, path } = markerPosition;\n const segmentIndex = paragraph.segments.indexOf(marker);\n const paraIndex = path[0].blocks.indexOf(paragraph);\n const newParagraph: ShallowMutableContentModelParagraph = createParagraph(\n false /*isImplicit*/,\n { ...paragraph.format, ...newParaFormat },\n paragraph.segmentFormat\n );\n\n if (segmentIndex >= 0) {\n newParagraph.segments = paragraph.segments.splice(segmentIndex);\n }\n\n if (paraIndex >= 0) {\n mutateBlock(path[0]).blocks.splice(paraIndex + 1, 0, newParagraph);\n }\n\n const listItemIndex = getClosestAncestorBlockGroupIndex(\n path,\n ['ListItem'],\n ['FormatContainer', 'TableCell']\n );\n const listItem = path[listItemIndex] as ContentModelListItem;\n\n if (listItem) {\n const listParent = listItemIndex >= 0 ? path[listItemIndex + 1] : null;\n const blockIndex = listParent ? listParent.blocks.indexOf(listItem) : -1;\n\n if (blockIndex >= 0 && listParent) {\n const newListItem = createListItem(listItem.levels, listItem.formatHolder.format);\n\n if (paraIndex >= 0) {\n newListItem.blocks = listItem.blocks.splice(paraIndex + 1);\n }\n\n if (blockIndex >= 0) {\n mutateBlock(listParent).blocks.splice(blockIndex + 1, 0, newListItem);\n }\n\n path[listItemIndex] = newListItem;\n }\n }\n\n markerPosition.paragraph = newParagraph;\n\n return newParagraph;\n}\n\nfunction insertBlock(markerPosition: InsertPoint, block: ContentModelBlock) {\n const { path } = markerPosition;\n const newParaFormat = block.blockType !== 'Paragraph' ? {} : block.format;\n const newPara = splitParagraph(markerPosition, newParaFormat);\n const blockIndex = path[0].blocks.indexOf(newPara);\n\n if (blockIndex >= 0) {\n mutateBlock(path[0]).blocks.splice(blockIndex, 0, block);\n }\n}\n\nfunction applyDefaultFormat(\n group: ReadonlyContentModelBlockGroup,\n format: ContentModelSegmentFormat,\n applyDefaultFormatOption: 'mergeAll' | 'keepSourceEmphasisFormat'\n) {\n group.blocks.forEach(block => {\n mergeBlockFormat(applyDefaultFormatOption, block);\n\n switch (block.blockType) {\n case 'BlockGroup':\n if (block.blockGroupType == 'ListItem') {\n mutateBlock(block).formatHolder.format = mergeSegmentFormat(\n applyDefaultFormatOption,\n format,\n block.formatHolder.format\n );\n }\n applyDefaultFormat(block, format, applyDefaultFormatOption);\n break;\n\n case 'Table':\n block.rows.forEach(row =>\n row.cells.forEach(cell => {\n applyDefaultFormat(cell, format, applyDefaultFormatOption);\n })\n );\n break;\n\n case 'Paragraph':\n const paragraphFormat = block.decorator?.format || {};\n const paragraph = mutateBlock(block);\n\n paragraph.segments.forEach(segment => {\n if (segment.segmentType == 'General') {\n applyDefaultFormat(segment, format, applyDefaultFormatOption);\n }\n\n segment.format = mergeSegmentFormat(applyDefaultFormatOption, format, {\n ...paragraphFormat,\n ...segment.format,\n });\n\n if (segment.link) {\n segment.link.format = mergeLinkFormat(\n applyDefaultFormatOption,\n format,\n segment.link.format\n );\n }\n });\n\n if (applyDefaultFormatOption === 'keepSourceEmphasisFormat') {\n delete paragraph.decorator;\n }\n break;\n }\n });\n}\n\nfunction mergeBlockFormat(applyDefaultFormatOption: string, block: ReadonlyContentModelBlock) {\n if (applyDefaultFormatOption == 'keepSourceEmphasisFormat' && block.format.backgroundColor) {\n delete mutateBlock(block).format.backgroundColor;\n }\n}\n\n/**\n * Hyperlink format type definition only contains backgroundColor and underline.\n * So create a minimum object with the styles supported in Hyperlink to be used in merge.\n */\nfunction getSegmentFormatInLinkFormat(\n targetFormat: ContentModelSegmentFormat\n): ContentModelSegmentFormat {\n const result: ContentModelHyperLinkFormat = {};\n if (targetFormat.backgroundColor) {\n result.backgroundColor = targetFormat.backgroundColor;\n }\n if (targetFormat.underline) {\n result.underline = targetFormat.underline;\n }\n\n return result;\n}\n\nfunction mergeLinkFormat(\n applyDefaultFormatOption: 'mergeAll' | 'keepSourceEmphasisFormat',\n targetFormat: ContentModelSegmentFormat,\n sourceFormat: ContentModelHyperLinkFormat\n) {\n return applyDefaultFormatOption == 'mergeAll'\n ? { ...getSegmentFormatInLinkFormat(targetFormat), ...sourceFormat }\n : {\n // Hyperlink segment format contains other attributes such as LinkFormat\n // so we have to retain them\n ...getFormatWithoutSegmentFormat(sourceFormat),\n // Link format only have Text color, background color, Underline, but only\n // text color + background color should be merged from the target\n ...getSegmentFormatInLinkFormat(targetFormat),\n // Get the semantic format of the source\n ...getSemanticFormat(sourceFormat),\n // The text color of the hyperlink should not be merged and\n // we should always retain the source text color\n ...getHyperlinkTextColor(sourceFormat),\n };\n}\n\nfunction mergeSegmentFormat(\n applyDefaultFormatOption: 'mergeAll' | 'keepSourceEmphasisFormat',\n targetFormat: ContentModelSegmentFormat,\n sourceFormat: ContentModelSegmentFormat\n): ContentModelSegmentFormat {\n return applyDefaultFormatOption == 'mergeAll'\n ? { ...targetFormat, ...sourceFormat }\n : {\n ...getFormatWithoutSegmentFormat(sourceFormat),\n ...targetFormat,\n ...getSemanticFormat(sourceFormat),\n };\n}\n\nfunction getSemanticFormat(segmentFormat: ContentModelSegmentFormat): ContentModelSegmentFormat {\n const result: ContentModelSegmentFormat = {};\n\n const { fontWeight, italic, underline } = segmentFormat;\n\n if (fontWeight && fontWeight != 'normal') {\n result.fontWeight = fontWeight;\n }\n if (italic) {\n result.italic = italic;\n }\n if (underline) {\n result.underline = underline;\n }\n\n return result;\n}\n\n/**\n * Segment format can also contain other type of metadata, for example in Images/Hyperlink,\n * we want to preserve these properties when merging format\n */\nfunction getFormatWithoutSegmentFormat(\n sourceFormat: ContentModelSegmentFormat\n): ContentModelSegmentFormat {\n const resultFormat = {\n ...sourceFormat,\n };\n KeysOfSegmentFormat.forEach(key => delete resultFormat[key]);\n return resultFormat;\n}\nfunction getHyperlinkTextColor(sourceFormat: ContentModelHyperLinkFormat) {\n const result: ContentModelHyperLinkFormat = {};\n if (sourceFormat.textColor) {\n result.textColor = sourceFormat.textColor;\n }\n\n return result;\n}\n"]}
1
+ {"version":3,"file":"mergeModel.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelApi/editing/mergeModel.ts"],"names":[],"mappings":"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","sourcesContent":["import { addBlock } from '../common/addBlock';\nimport { addSegment } from '../common/addSegment';\nimport { applyTableFormat } from './applyTableFormat';\nimport { createListItem } from '../creators/createListItem';\nimport { createParagraph } from '../creators/createParagraph';\nimport { createSelectionMarker } from '../creators/createSelectionMarker';\nimport { createTableCell } from '../creators/createTableCell';\nimport { deleteSelection } from './deleteSelection';\nimport { EmptySegmentFormat } from '../../constants/EmptySegmentFormat';\nimport { getClosestAncestorBlockGroupIndex } from './getClosestAncestorBlockGroupIndex';\nimport { getObjectKeys } from '../..//domUtils/getObjectKeys';\nimport { mutateBlock } from '../common/mutate';\nimport { normalizeContentModel } from '../common/normalizeContentModel';\nimport { normalizeTable } from './normalizeTable';\nimport type {\n ContentModelBlock,\n ContentModelBlockFormat,\n ContentModelDocument,\n ContentModelHyperLinkFormat,\n ContentModelListItem,\n ContentModelParagraph,\n ContentModelSegmentFormat,\n ContentModelTable,\n FormatContentModelContext,\n InsertPoint,\n MergeModelOption,\n ReadonlyContentModelBlock,\n ReadonlyContentModelBlockGroup,\n ReadonlyContentModelDocument,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\nconst HeadingTags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];\nconst KeysOfSegmentFormat = getObjectKeys(EmptySegmentFormat);\n\ntype MergeFormatTypes = 'mergeAll' | 'keepSourceEmphasisFormat' | 'preferSource' | 'preferTarget';\n\n/**\n * Merge source model into target mode\n * @param target Target Content Model that will merge content into\n * @param source Source Content Model will be merged to target model\n * @param context Format context. When call this function inside formatContentModel, provide this context so that formatContentModel will do extra handling to the result\n * @param options More options, see MergeModelOption\n * @returns Insert point after merge, or null if there is no insert point\n */\nexport function mergeModel(\n target: ReadonlyContentModelDocument,\n source: ContentModelDocument,\n context?: FormatContentModelContext,\n options?: MergeModelOption\n): InsertPoint | null {\n const insertPosition =\n options?.insertPosition ?? deleteSelection(target, [], context).insertPoint;\n\n const { addParagraphAfterMergedContent, mergeFormat, mergeTable } = options || {};\n\n if (addParagraphAfterMergedContent && !mergeTable) {\n const { paragraph, marker } = insertPosition || {};\n const newPara = createParagraph(false /* isImplicit */, paragraph?.format, marker?.format);\n addBlock(source, newPara);\n }\n\n if (insertPosition) {\n if (mergeFormat && mergeFormat != 'none') {\n const newFormat: ContentModelSegmentFormat = {\n ...(target.format || {}),\n ...insertPosition.marker.format,\n };\n\n applyDefaultFormat(source, newFormat, mergeFormat);\n }\n\n for (let i = 0; i < source.blocks.length; i++) {\n const block = source.blocks[i];\n\n switch (block.blockType) {\n case 'Paragraph':\n mergeParagraph(insertPosition, block, i == 0, context, options);\n break;\n\n case 'Divider':\n insertBlock(insertPosition, block);\n break;\n\n case 'Entity':\n insertBlock(insertPosition, block);\n context?.newEntities.push(block);\n break;\n\n case 'Table':\n if (source.blocks.length == 1 && mergeTable) {\n mergeTables(insertPosition, block, source);\n } else {\n insertBlock(insertPosition, block);\n }\n break;\n\n case 'BlockGroup':\n switch (block.blockGroupType) {\n case 'General':\n case 'FormatContainer':\n insertBlock(insertPosition, block);\n break;\n case 'ListItem':\n mergeList(insertPosition, block);\n break;\n }\n break;\n }\n }\n }\n\n normalizeContentModel(target);\n\n return insertPosition;\n}\n\nfunction mergeParagraph(\n markerPosition: InsertPoint,\n newPara: ContentModelParagraph,\n mergeToCurrentParagraph: boolean,\n context?: FormatContentModelContext,\n option?: MergeModelOption\n) {\n const { paragraph, marker } = markerPosition;\n const newParagraph = mergeToCurrentParagraph\n ? paragraph\n : splitParagraph(markerPosition, newPara.format);\n const segmentIndex = newParagraph.segments.indexOf(marker);\n\n if (option?.mergeFormat == 'none' && mergeToCurrentParagraph) {\n newParagraph.segments.forEach(segment => {\n segment.format = { ...(newParagraph.segmentFormat || {}), ...segment.format };\n });\n delete newParagraph.segmentFormat;\n }\n if (segmentIndex >= 0) {\n for (let i = 0; i < newPara.segments.length; i++) {\n const segment = newPara.segments[i];\n\n newParagraph.segments.splice(segmentIndex + i, 0, segment);\n\n if (context) {\n if (segment.segmentType == 'Entity') {\n context.newEntities.push(segment);\n }\n\n if (segment.segmentType == 'Image') {\n context.newImages.push(segment);\n }\n }\n }\n }\n\n if (newPara.decorator) {\n newParagraph.decorator = { ...newPara.decorator };\n if (HeadingTags.indexOf(newParagraph.decorator.tagName) > -1) {\n const sourceKeys: (keyof ContentModelSegmentFormat)[] = getObjectKeys(\n newParagraph.decorator.format\n );\n const segmentDecoratorKeys: (keyof ContentModelSegmentFormat)[] = getObjectKeys(\n newParagraph.segmentFormat || {}\n );\n\n sourceKeys.forEach(key => {\n if (segmentDecoratorKeys.indexOf(key) > -1) {\n delete newParagraph.segmentFormat?.[key];\n }\n });\n }\n }\n\n if (!mergeToCurrentParagraph) {\n newParagraph.format = newPara.format;\n } else {\n newParagraph.format = {\n ...newParagraph.format,\n ...newPara.format,\n };\n }\n}\n\nfunction mergeTables(\n markerPosition: InsertPoint,\n newTable: ContentModelTable,\n source: ContentModelDocument\n) {\n const { tableContext, marker } = markerPosition;\n\n if (tableContext && source.blocks.length == 1 && source.blocks[0] == newTable) {\n const { table: readonlyTable, colIndex, rowIndex } = tableContext;\n const table = mutateBlock(readonlyTable);\n\n for (let i = 0; i < newTable.rows.length; i++) {\n for (let j = 0; j < newTable.rows[i].cells.length; j++) {\n const newCell = newTable.rows[i].cells[j];\n\n if (i == 0 && colIndex + j >= table.rows[0].cells.length) {\n for (let k = 0; k < table.rows.length; k++) {\n const leftCell = table.rows[k]?.cells[colIndex + j - 1];\n table.rows[k].cells[colIndex + j] = createTableCell(\n false /*spanLeft*/,\n false /*spanAbove*/,\n leftCell?.isHeader,\n leftCell?.format\n );\n }\n }\n\n if (j == 0 && rowIndex + i >= table.rows.length) {\n if (!table.rows[rowIndex + i]) {\n table.rows[rowIndex + i] = {\n cells: [],\n format: {},\n height: 0,\n };\n }\n\n for (let k = 0; k < table.rows[rowIndex].cells.length; k++) {\n const aboveCell = table.rows[rowIndex + i - 1]?.cells[k];\n table.rows[rowIndex + i].cells[k] = createTableCell(\n false /*spanLeft*/,\n false /*spanAbove*/,\n false /*isHeader*/,\n aboveCell?.format\n );\n }\n }\n\n const oldCell = table.rows[rowIndex + i].cells[colIndex + j];\n table.rows[rowIndex + i].cells[colIndex + j] = newCell;\n\n if (i == 0 && j == 0) {\n const newMarker = createSelectionMarker(marker.format);\n const newPara = addSegment(newCell, newMarker);\n\n if (markerPosition.path[0] == oldCell) {\n // Update insert point to match the change result\n markerPosition.path[0] = newCell;\n markerPosition.marker = newMarker;\n markerPosition.paragraph = newPara;\n }\n }\n }\n }\n\n normalizeTable(table, markerPosition.marker.format);\n applyTableFormat(table, undefined /*newFormat*/, true /*keepCellShade*/);\n } else {\n insertBlock(markerPosition, newTable);\n }\n}\n\nfunction mergeList(markerPosition: InsertPoint, newList: ContentModelListItem) {\n splitParagraph(markerPosition, newList.format);\n\n const { path, paragraph } = markerPosition;\n\n const listItemIndex = getClosestAncestorBlockGroupIndex(path, ['ListItem']);\n const listItem = path[listItemIndex] as ContentModelListItem;\n const listParent = path[listItemIndex + 1]; // It is ok here when index is -1, that means there is no list and we just insert a new paragraph and use path[0] as its parent\n const blockIndex = listParent.blocks.indexOf(listItem || paragraph);\n\n if (blockIndex >= 0) {\n mutateBlock(listParent).blocks.splice(blockIndex, 0, newList);\n }\n\n if (listItem) {\n listItem?.levels.forEach((level, i) => {\n newList.levels[i] = { ...level };\n });\n }\n}\n\nfunction splitParagraph(markerPosition: InsertPoint, newParaFormat: ContentModelBlockFormat) {\n const { paragraph, marker, path } = markerPosition;\n const segmentIndex = paragraph.segments.indexOf(marker);\n const paraIndex = path[0].blocks.indexOf(paragraph);\n const newParagraph: ShallowMutableContentModelParagraph = createParagraph(\n false /*isImplicit*/,\n { ...paragraph.format, ...newParaFormat },\n paragraph.segmentFormat\n );\n\n if (segmentIndex >= 0) {\n newParagraph.segments = paragraph.segments.splice(segmentIndex);\n }\n\n if (paraIndex >= 0) {\n mutateBlock(path[0]).blocks.splice(paraIndex + 1, 0, newParagraph);\n }\n\n const listItemIndex = getClosestAncestorBlockGroupIndex(\n path,\n ['ListItem'],\n ['FormatContainer', 'TableCell']\n );\n const listItem = path[listItemIndex] as ContentModelListItem;\n\n if (listItem) {\n const listParent = listItemIndex >= 0 ? path[listItemIndex + 1] : null;\n const blockIndex = listParent ? listParent.blocks.indexOf(listItem) : -1;\n\n if (blockIndex >= 0 && listParent) {\n const newListItem = createListItem(listItem.levels, listItem.formatHolder.format);\n\n if (paraIndex >= 0) {\n newListItem.blocks = listItem.blocks.splice(paraIndex + 1);\n }\n\n if (blockIndex >= 0) {\n mutateBlock(listParent).blocks.splice(blockIndex + 1, 0, newListItem);\n }\n\n path[listItemIndex] = newListItem;\n }\n }\n\n markerPosition.paragraph = newParagraph;\n\n return newParagraph;\n}\n\nfunction insertBlock(markerPosition: InsertPoint, block: ContentModelBlock) {\n const { path } = markerPosition;\n const newParaFormat = block.blockType !== 'Paragraph' ? {} : block.format;\n const newPara = splitParagraph(markerPosition, newParaFormat);\n const blockIndex = path[0].blocks.indexOf(newPara);\n\n if (blockIndex >= 0) {\n mutateBlock(path[0]).blocks.splice(blockIndex, 0, block);\n }\n}\n\nfunction applyDefaultFormat(\n group: ReadonlyContentModelBlockGroup,\n format: ContentModelSegmentFormat,\n applyDefaultFormatOption: MergeFormatTypes\n) {\n group.blocks.forEach(block => {\n mergeBlockFormat(applyDefaultFormatOption, block);\n\n switch (block.blockType) {\n case 'BlockGroup':\n if (block.blockGroupType == 'ListItem') {\n mutateBlock(block).formatHolder.format = mergeSegmentFormat(\n applyDefaultFormatOption,\n format,\n block.formatHolder.format\n );\n }\n applyDefaultFormat(block, format, applyDefaultFormatOption);\n break;\n\n case 'Table':\n block.rows.forEach(row =>\n row.cells.forEach(cell => {\n applyDefaultFormat(cell, format, applyDefaultFormatOption);\n })\n );\n break;\n\n case 'Paragraph':\n const paragraphFormat = block.decorator?.format || {};\n const paragraph = mutateBlock(block);\n\n paragraph.segments.forEach(segment => {\n if (segment.segmentType == 'General') {\n applyDefaultFormat(segment, format, applyDefaultFormatOption);\n }\n\n segment.format = mergeSegmentFormat(applyDefaultFormatOption, format, {\n ...paragraphFormat,\n ...segment.format,\n });\n\n if (segment.link) {\n segment.link.format = mergeLinkFormat(\n applyDefaultFormatOption,\n format,\n segment.link.format\n );\n }\n });\n\n if (applyDefaultFormatOption === 'keepSourceEmphasisFormat') {\n delete paragraph.decorator;\n }\n break;\n }\n });\n}\n\nfunction mergeBlockFormat(applyDefaultFormatOption: string, block: ReadonlyContentModelBlock) {\n if (applyDefaultFormatOption == 'keepSourceEmphasisFormat' && block.format.backgroundColor) {\n delete mutateBlock(block).format.backgroundColor;\n }\n}\n\n/**\n * Hyperlink format type definition only contains backgroundColor and underline.\n * So create a minimum object with the styles supported in Hyperlink to be used in merge.\n */\nfunction getSegmentFormatInLinkFormat(\n targetFormat: ContentModelSegmentFormat\n): ContentModelSegmentFormat {\n const result: ContentModelHyperLinkFormat = {};\n if (targetFormat.backgroundColor) {\n result.backgroundColor = targetFormat.backgroundColor;\n }\n if (targetFormat.underline) {\n result.underline = targetFormat.underline;\n }\n\n return result;\n}\n\nfunction mergeLinkFormat(\n applyDefaultFormatOption: MergeFormatTypes,\n targetFormat: ContentModelSegmentFormat,\n sourceFormat: ContentModelHyperLinkFormat\n) {\n switch (applyDefaultFormatOption) {\n case 'mergeAll':\n case 'preferSource':\n return { ...getSegmentFormatInLinkFormat(targetFormat), ...sourceFormat };\n case 'keepSourceEmphasisFormat':\n return {\n // Hyperlink segment format contains other attributes such as LinkFormat\n // so we have to retain them\n ...getFormatWithoutSegmentFormat(sourceFormat),\n // Link format only have Text color, background color, Underline, but only\n // text color + background color should be merged from the target\n ...getSegmentFormatInLinkFormat(targetFormat),\n // Get the semantic format of the source\n ...getSemanticFormat(sourceFormat),\n // The text color of the hyperlink should not be merged and\n // we should always retain the source text color\n ...getHyperlinkTextColor(sourceFormat),\n };\n case 'preferTarget':\n return { ...sourceFormat, ...getSegmentFormatInLinkFormat(targetFormat) };\n }\n}\n\nfunction mergeSegmentFormat(\n applyDefaultFormatOption: MergeFormatTypes,\n targetFormat: ContentModelSegmentFormat,\n sourceFormat: ContentModelSegmentFormat\n): ContentModelSegmentFormat {\n switch (applyDefaultFormatOption) {\n case 'mergeAll':\n case 'preferSource':\n return { ...targetFormat, ...sourceFormat };\n case 'preferTarget':\n return { ...sourceFormat, ...targetFormat };\n case 'keepSourceEmphasisFormat':\n return {\n ...getFormatWithoutSegmentFormat(sourceFormat),\n ...targetFormat,\n ...getSemanticFormat(sourceFormat),\n };\n }\n}\n\nfunction getSemanticFormat(segmentFormat: ContentModelSegmentFormat): ContentModelSegmentFormat {\n const result: ContentModelSegmentFormat = {};\n\n const { fontWeight, italic, underline } = segmentFormat;\n\n if (fontWeight && fontWeight != 'normal') {\n result.fontWeight = fontWeight;\n }\n if (italic) {\n result.italic = italic;\n }\n if (underline) {\n result.underline = underline;\n }\n\n return result;\n}\n\n/**\n * Segment format can also contain other type of metadata, for example in Images/Hyperlink,\n * we want to preserve these properties when merging format\n */\nfunction getFormatWithoutSegmentFormat(\n sourceFormat: ContentModelSegmentFormat\n): ContentModelSegmentFormat {\n const resultFormat = {\n ...sourceFormat,\n };\n KeysOfSegmentFormat.forEach(key => delete resultFormat[key]);\n return resultFormat;\n}\nfunction getHyperlinkTextColor(sourceFormat: ContentModelHyperLinkFormat) {\n const result: ContentModelHyperLinkFormat = {};\n if (sourceFormat.textColor) {\n result.textColor = sourceFormat.textColor;\n }\n\n return result;\n}\n"]}
@@ -52,14 +52,17 @@ function extractSelectionRange(doc, context) {
52
52
  }
53
53
  }
54
54
  function calcPosition(pos) {
55
- var _a, _b, _c;
55
+ var _a, _b, _c, _d, _e;
56
56
  var result;
57
57
  if (pos.block) {
58
58
  if (!pos.segment) {
59
59
  result = { container: pos.block, offset: 0 };
60
60
  }
61
61
  else if ((0, isNodeOfType_1.isNodeOfType)(pos.segment, 'TEXT_NODE')) {
62
- result = { container: pos.segment, offset: ((_a = pos.segment.nodeValue) === null || _a === void 0 ? void 0 : _a.length) || 0 };
62
+ result = {
63
+ container: pos.segment,
64
+ offset: (_c = (_a = pos.offset) !== null && _a !== void 0 ? _a : (_b = pos.segment.nodeValue) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0,
65
+ };
63
66
  }
64
67
  else if (pos.segment.parentNode) {
65
68
  result = {
@@ -78,7 +81,7 @@ function calcPosition(pos) {
78
81
  result = {
79
82
  container: container,
80
83
  offset: (0, isNodeOfType_1.isNodeOfType)(container, 'TEXT_NODE')
81
- ? (_c = (_b = container.nodeValue) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0
84
+ ? (_e = (_d = container.nodeValue) === null || _d === void 0 ? void 0 : _d.length) !== null && _e !== void 0 ? _e : 0
82
85
  : container.childNodes.length,
83
86
  };
84
87
  }
@@ -1 +1 @@
1
- {"version":3,"file":"contentModelToDom.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-dom/lib/modelToDom/contentModelToDom.ts"],"names":[],"mappings":"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","sourcesContent":["import { isNodeOfType } from '../domUtils/isNodeOfType';\nimport { toArray } from '../domUtils/toArray';\nimport type { ContentModelDocumentWithPersistedCache } from '../modelApi/selection/iterateSelections';\nimport type {\n ContentModelDocument,\n DOMSelection,\n ModelToDomBlockAndSegmentNode,\n ModelToDomContext,\n} from 'roosterjs-content-model-types';\n\n/**\n * Create DOM tree fragment from Content Model document\n * @param doc Document object of the target DOM tree\n * @param root Target node that will become the container of new DOM tree.\n * When a DOM node with existing node is passed, it will be merged with content model so that unchanged blocks\n * won't be touched.\n * @param model The content model document to generate DOM tree from\n * @param context The context object for Content Model to DOM conversion\n * @returns The selection range created in DOM tree from this model, or null when there is no selection\n */\nexport function contentModelToDom(\n doc: Document,\n root: Node,\n model: ContentModelDocument,\n context: ModelToDomContext\n): DOMSelection | null {\n context.modelHandlers.blockGroupChildren(doc, root, model, context);\n\n const range = extractSelectionRange(doc, context);\n\n if (model.hasRevertedRangeSelection && range?.type == 'range') {\n range.isReverted = true;\n }\n\n if (context.domIndexer && context.allowCacheElement) {\n (model as ContentModelDocumentWithPersistedCache).persistCache = true;\n }\n\n root.normalize();\n\n return range;\n}\n\nfunction extractSelectionRange(doc: Document, context: ModelToDomContext): DOMSelection | null {\n const {\n regularSelection: { start, end },\n tableSelection,\n imageSelection,\n } = context;\n\n let startPosition: { container: Node; offset: number } | undefined;\n let endPosition: { container: Node; offset: number } | undefined;\n\n if (imageSelection) {\n return imageSelection;\n } else if (\n (startPosition = start && calcPosition(start)) &&\n (endPosition = end && calcPosition(end))\n ) {\n const range = doc.createRange();\n\n range.setStart(startPosition.container, startPosition.offset);\n range.setEnd(endPosition.container, endPosition.offset);\n\n return {\n type: 'range',\n range,\n isReverted: false,\n };\n } else if (tableSelection) {\n return tableSelection;\n } else {\n return null;\n }\n}\n\nfunction calcPosition(\n pos: ModelToDomBlockAndSegmentNode\n): { container: Node; offset: number } | undefined {\n let result: { container: Node; offset: number } | undefined;\n\n if (pos.block) {\n if (!pos.segment) {\n result = { container: pos.block, offset: 0 };\n } else if (isNodeOfType(pos.segment, 'TEXT_NODE')) {\n result = { container: pos.segment, offset: pos.segment.nodeValue?.length || 0 };\n } else if (pos.segment.parentNode) {\n result = {\n container: pos.segment.parentNode,\n offset:\n toArray(pos.segment.parentNode.childNodes as NodeListOf<Node>).indexOf(\n pos.segment\n ) + 1,\n };\n }\n }\n\n if (result && isNodeOfType(result.container, 'DOCUMENT_FRAGMENT_NODE')) {\n const childNodes = result.container.childNodes;\n\n if (childNodes.length > result.offset) {\n result = { container: childNodes[result.offset], offset: 0 };\n } else if (result.container.lastChild) {\n const container = result.container.lastChild;\n result = {\n container,\n offset: isNodeOfType(container, 'TEXT_NODE')\n ? container.nodeValue?.length ?? 0\n : container.childNodes.length,\n };\n } else {\n result = undefined;\n }\n }\n\n return result;\n}\n"]}
1
+ {"version":3,"file":"contentModelToDom.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-dom/lib/modelToDom/contentModelToDom.ts"],"names":[],"mappings":"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","sourcesContent":["import { isNodeOfType } from '../domUtils/isNodeOfType';\nimport { toArray } from '../domUtils/toArray';\nimport type { ContentModelDocumentWithPersistedCache } from '../modelApi/selection/iterateSelections';\nimport type {\n ContentModelDocument,\n DOMSelection,\n ModelToDomBlockAndSegmentNode,\n ModelToDomContext,\n} from 'roosterjs-content-model-types';\n\n/**\n * Create DOM tree fragment from Content Model document\n * @param doc Document object of the target DOM tree\n * @param root Target node that will become the container of new DOM tree.\n * When a DOM node with existing node is passed, it will be merged with content model so that unchanged blocks\n * won't be touched.\n * @param model The content model document to generate DOM tree from\n * @param context The context object for Content Model to DOM conversion\n * @returns The selection range created in DOM tree from this model, or null when there is no selection\n */\nexport function contentModelToDom(\n doc: Document,\n root: Node,\n model: ContentModelDocument,\n context: ModelToDomContext\n): DOMSelection | null {\n context.modelHandlers.blockGroupChildren(doc, root, model, context);\n\n const range = extractSelectionRange(doc, context);\n\n if (model.hasRevertedRangeSelection && range?.type == 'range') {\n range.isReverted = true;\n }\n\n if (context.domIndexer && context.allowCacheElement) {\n (model as ContentModelDocumentWithPersistedCache).persistCache = true;\n }\n\n root.normalize();\n\n return range;\n}\n\nfunction extractSelectionRange(doc: Document, context: ModelToDomContext): DOMSelection | null {\n const {\n regularSelection: { start, end },\n tableSelection,\n imageSelection,\n } = context;\n\n let startPosition: { container: Node; offset: number } | undefined;\n let endPosition: { container: Node; offset: number } | undefined;\n\n if (imageSelection) {\n return imageSelection;\n } else if (\n (startPosition = start && calcPosition(start)) &&\n (endPosition = end && calcPosition(end))\n ) {\n const range = doc.createRange();\n\n range.setStart(startPosition.container, startPosition.offset);\n range.setEnd(endPosition.container, endPosition.offset);\n\n return {\n type: 'range',\n range,\n isReverted: false,\n };\n } else if (tableSelection) {\n return tableSelection;\n } else {\n return null;\n }\n}\n\nfunction calcPosition(\n pos: ModelToDomBlockAndSegmentNode\n): { container: Node; offset: number } | undefined {\n let result: { container: Node; offset: number } | undefined;\n\n if (pos.block) {\n if (!pos.segment) {\n result = { container: pos.block, offset: 0 };\n } else if (isNodeOfType(pos.segment, 'TEXT_NODE')) {\n result = {\n container: pos.segment,\n offset: pos.offset ?? pos.segment.nodeValue?.length ?? 0,\n };\n } else if (pos.segment.parentNode) {\n result = {\n container: pos.segment.parentNode,\n offset:\n toArray(pos.segment.parentNode.childNodes as NodeListOf<Node>).indexOf(\n pos.segment\n ) + 1,\n };\n }\n }\n\n if (result && isNodeOfType(result.container, 'DOCUMENT_FRAGMENT_NODE')) {\n const childNodes = result.container.childNodes;\n\n if (childNodes.length > result.offset) {\n result = { container: childNodes[result.offset], offset: 0 };\n } else if (result.container.lastChild) {\n const container = result.container.lastChild;\n result = {\n container,\n offset: isNodeOfType(container, 'TEXT_NODE')\n ? container.nodeValue?.length ?? 0\n : container.childNodes.length,\n };\n } else {\n result = undefined;\n }\n }\n\n return result;\n}\n"]}
@@ -62,7 +62,7 @@ var handleParagraph = function (doc, parent, paragraph, context, refNode) {
62
62
  else {
63
63
  handleSegments();
64
64
  }
65
- (0, optimize_1.optimize)(container);
65
+ (0, optimize_1.optimize)(container, context);
66
66
  // It is possible the next sibling node is changed during processing child segments
67
67
  // e.g. When this paragraph is an implicit paragraph and it contains an inline entity segment
68
68
  // The segment will be appended to container as child then the container will be removed
@@ -1 +1 @@
1
- {"version":3,"file":"handleParagraph.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/handlers/handleParagraph.ts"],"names":[],"mappings":"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","sourcesContent":["import { applyFormat } from '../utils/applyFormat';\nimport { getObjectKeys } from '../../domUtils/getObjectKeys';\nimport { optimize } from '../optimizers/optimize';\nimport { reuseCachedElement } from '../../domUtils/reuseCachedElement';\nimport { stackFormat } from '../utils/stackFormat';\nimport { unwrap } from '../../domUtils/unwrap';\nimport type {\n ContentModelBlockHandler,\n ContentModelParagraph,\n ModelToDomContext,\n} from 'roosterjs-content-model-types';\n\nconst DefaultParagraphTag = 'div';\n\n/**\n * @internal\n */\nexport const handleParagraph: ContentModelBlockHandler<ContentModelParagraph> = (\n doc: Document,\n parent: Node,\n paragraph: ContentModelParagraph,\n context: ModelToDomContext,\n refNode: Node | null\n) => {\n let container = context.allowCacheElement ? paragraph.cachedElement : undefined;\n\n if (container && paragraph.segments.every(x => x.segmentType != 'General' && !x.isSelected)) {\n refNode = reuseCachedElement(parent, container, refNode);\n } else {\n stackFormat(context, paragraph.decorator?.tagName || null, () => {\n const needParagraphWrapper =\n !paragraph.isImplicit ||\n !!paragraph.decorator ||\n (getObjectKeys(paragraph.format).length > 0 &&\n paragraph.segments.some(segment => segment.segmentType != 'SelectionMarker'));\n const formatOnWrapper = needParagraphWrapper\n ? {\n ...(paragraph.decorator?.format || {}),\n ...paragraph.segmentFormat,\n }\n : {};\n\n container = doc.createElement(paragraph.decorator?.tagName || DefaultParagraphTag);\n\n parent.insertBefore(container, refNode);\n\n context.regularSelection.current = {\n block: needParagraphWrapper ? container : container.parentNode,\n segment: null,\n };\n\n const handleSegments = () => {\n const parent = container;\n\n if (parent) {\n const firstSegment = paragraph.segments[0];\n\n if (firstSegment?.segmentType == 'SelectionMarker') {\n // Make sure there is a segment created before selection marker.\n // If selection marker is the first selected segment in a paragraph, create a dummy text node,\n // so after rewrite, the regularSelection object can have a valid segment object set to the text node.\n context.modelHandlers.text(\n doc,\n parent,\n {\n ...firstSegment,\n segmentType: 'Text',\n text: '',\n },\n context,\n []\n );\n }\n\n paragraph.segments.forEach(segment => {\n const newSegments: Node[] = [];\n context.modelHandlers.segment(doc, parent, segment, context, newSegments);\n\n newSegments.forEach(node => {\n context.domIndexer?.onSegment(node, paragraph, [segment]);\n });\n });\n }\n };\n\n if (needParagraphWrapper) {\n stackFormat(context, formatOnWrapper, handleSegments);\n\n applyFormat(container, context.formatAppliers.block, paragraph.format, context);\n applyFormat(container, context.formatAppliers.container, paragraph.format, context);\n applyFormat(\n container,\n context.formatAppliers.segmentOnBlock,\n formatOnWrapper,\n context\n );\n } else {\n handleSegments();\n }\n\n optimize(container);\n\n // It is possible the next sibling node is changed during processing child segments\n // e.g. When this paragraph is an implicit paragraph and it contains an inline entity segment\n // The segment will be appended to container as child then the container will be removed\n // since this paragraph it is implicit. In that case container.nextSibling will become original\n // inline entity's next sibling. So reset refNode to its real next sibling (after change) here\n // to make sure the value is correct.\n refNode = container.nextSibling;\n\n if (container) {\n context.onNodeCreated?.(paragraph, container);\n context.domIndexer?.onParagraph(container);\n }\n\n if (needParagraphWrapper) {\n if (context.allowCacheElement) {\n paragraph.cachedElement = container;\n }\n } else {\n unwrap(container);\n container = undefined;\n }\n });\n }\n\n return refNode;\n};\n"]}
1
+ {"version":3,"file":"handleParagraph.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/handlers/handleParagraph.ts"],"names":[],"mappings":"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","sourcesContent":["import { applyFormat } from '../utils/applyFormat';\nimport { getObjectKeys } from '../../domUtils/getObjectKeys';\nimport { optimize } from '../optimizers/optimize';\nimport { reuseCachedElement } from '../../domUtils/reuseCachedElement';\nimport { stackFormat } from '../utils/stackFormat';\nimport { unwrap } from '../../domUtils/unwrap';\nimport type {\n ContentModelBlockHandler,\n ContentModelParagraph,\n ModelToDomContext,\n} from 'roosterjs-content-model-types';\n\nconst DefaultParagraphTag = 'div';\n\n/**\n * @internal\n */\nexport const handleParagraph: ContentModelBlockHandler<ContentModelParagraph> = (\n doc: Document,\n parent: Node,\n paragraph: ContentModelParagraph,\n context: ModelToDomContext,\n refNode: Node | null\n) => {\n let container = context.allowCacheElement ? paragraph.cachedElement : undefined;\n\n if (container && paragraph.segments.every(x => x.segmentType != 'General' && !x.isSelected)) {\n refNode = reuseCachedElement(parent, container, refNode);\n } else {\n stackFormat(context, paragraph.decorator?.tagName || null, () => {\n const needParagraphWrapper =\n !paragraph.isImplicit ||\n !!paragraph.decorator ||\n (getObjectKeys(paragraph.format).length > 0 &&\n paragraph.segments.some(segment => segment.segmentType != 'SelectionMarker'));\n const formatOnWrapper = needParagraphWrapper\n ? {\n ...(paragraph.decorator?.format || {}),\n ...paragraph.segmentFormat,\n }\n : {};\n\n container = doc.createElement(paragraph.decorator?.tagName || DefaultParagraphTag);\n\n parent.insertBefore(container, refNode);\n\n context.regularSelection.current = {\n block: needParagraphWrapper ? container : container.parentNode,\n segment: null,\n };\n\n const handleSegments = () => {\n const parent = container;\n\n if (parent) {\n const firstSegment = paragraph.segments[0];\n\n if (firstSegment?.segmentType == 'SelectionMarker') {\n // Make sure there is a segment created before selection marker.\n // If selection marker is the first selected segment in a paragraph, create a dummy text node,\n // so after rewrite, the regularSelection object can have a valid segment object set to the text node.\n context.modelHandlers.text(\n doc,\n parent,\n {\n ...firstSegment,\n segmentType: 'Text',\n text: '',\n },\n context,\n []\n );\n }\n\n paragraph.segments.forEach(segment => {\n const newSegments: Node[] = [];\n context.modelHandlers.segment(doc, parent, segment, context, newSegments);\n\n newSegments.forEach(node => {\n context.domIndexer?.onSegment(node, paragraph, [segment]);\n });\n });\n }\n };\n\n if (needParagraphWrapper) {\n stackFormat(context, formatOnWrapper, handleSegments);\n\n applyFormat(container, context.formatAppliers.block, paragraph.format, context);\n applyFormat(container, context.formatAppliers.container, paragraph.format, context);\n applyFormat(\n container,\n context.formatAppliers.segmentOnBlock,\n formatOnWrapper,\n context\n );\n } else {\n handleSegments();\n }\n\n optimize(container, context);\n\n // It is possible the next sibling node is changed during processing child segments\n // e.g. When this paragraph is an implicit paragraph and it contains an inline entity segment\n // The segment will be appended to container as child then the container will be removed\n // since this paragraph it is implicit. In that case container.nextSibling will become original\n // inline entity's next sibling. So reset refNode to its real next sibling (after change) here\n // to make sure the value is correct.\n refNode = container.nextSibling;\n\n if (container) {\n context.onNodeCreated?.(paragraph, container);\n context.domIndexer?.onParagraph(container);\n }\n\n if (needParagraphWrapper) {\n if (context.allowCacheElement) {\n paragraph.cachedElement = container;\n }\n } else {\n unwrap(container);\n container = undefined;\n }\n });\n }\n\n return refNode;\n};\n"]}
@@ -1,4 +1,5 @@
1
+ import type { ModelToDomContext } from 'roosterjs-content-model-types';
1
2
  /**
2
3
  * @internal
3
4
  */
4
- export declare function optimize(root: Node): void;
5
+ export declare function optimize(root: Node, context: ModelToDomContext): void;