roosterjs-content-model-plugins 9.29.0 → 9.30.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 (46) hide show
  1. package/lib/edit/inputSteps/handleEnterOnParagraph.js +1 -1
  2. package/lib/edit/inputSteps/handleEnterOnParagraph.js.map +1 -1
  3. package/lib/edit/utils/splitParagraph.d.ts +4 -2
  4. package/lib/edit/utils/splitParagraph.js +9 -4
  5. package/lib/edit/utils/splitParagraph.js.map +1 -1
  6. package/lib/imageEdit/ImageEditPlugin.d.ts +1 -0
  7. package/lib/imageEdit/ImageEditPlugin.js +10 -0
  8. package/lib/imageEdit/ImageEditPlugin.js.map +1 -1
  9. package/lib/paste/PowerPoint/processPastedContentFromPowerPoint.js +1 -5
  10. package/lib/paste/PowerPoint/processPastedContentFromPowerPoint.js.map +1 -1
  11. package/lib/paste/WordDesktop/processWordLists.js +41 -1
  12. package/lib/paste/WordDesktop/processWordLists.js.map +1 -1
  13. package/lib/paste/utils/customListUtils.d.ts +1 -1
  14. package/lib/paste/utils/customListUtils.js +10 -5
  15. package/lib/paste/utils/customListUtils.js.map +1 -1
  16. package/lib-amd/edit/inputSteps/handleEnterOnParagraph.js +1 -1
  17. package/lib-amd/edit/inputSteps/handleEnterOnParagraph.js.map +1 -1
  18. package/lib-amd/edit/utils/splitParagraph.d.ts +4 -2
  19. package/lib-amd/edit/utils/splitParagraph.js +9 -4
  20. package/lib-amd/edit/utils/splitParagraph.js.map +1 -1
  21. package/lib-amd/imageEdit/ImageEditPlugin.d.ts +1 -0
  22. package/lib-amd/imageEdit/ImageEditPlugin.js +10 -0
  23. package/lib-amd/imageEdit/ImageEditPlugin.js.map +1 -1
  24. package/lib-amd/paste/PowerPoint/processPastedContentFromPowerPoint.js +1 -5
  25. package/lib-amd/paste/PowerPoint/processPastedContentFromPowerPoint.js.map +1 -1
  26. package/lib-amd/paste/WordDesktop/processWordLists.js +41 -2
  27. package/lib-amd/paste/WordDesktop/processWordLists.js.map +1 -1
  28. package/lib-amd/paste/utils/customListUtils.d.ts +1 -1
  29. package/lib-amd/paste/utils/customListUtils.js +10 -6
  30. package/lib-amd/paste/utils/customListUtils.js.map +1 -1
  31. package/lib-mjs/edit/inputSteps/handleEnterOnParagraph.js +1 -1
  32. package/lib-mjs/edit/inputSteps/handleEnterOnParagraph.js.map +1 -1
  33. package/lib-mjs/edit/utils/splitParagraph.d.ts +4 -2
  34. package/lib-mjs/edit/utils/splitParagraph.js +9 -4
  35. package/lib-mjs/edit/utils/splitParagraph.js.map +1 -1
  36. package/lib-mjs/imageEdit/ImageEditPlugin.d.ts +1 -0
  37. package/lib-mjs/imageEdit/ImageEditPlugin.js +10 -0
  38. package/lib-mjs/imageEdit/ImageEditPlugin.js.map +1 -1
  39. package/lib-mjs/paste/PowerPoint/processPastedContentFromPowerPoint.js +1 -5
  40. package/lib-mjs/paste/PowerPoint/processPastedContentFromPowerPoint.js.map +1 -1
  41. package/lib-mjs/paste/WordDesktop/processWordLists.js +41 -1
  42. package/lib-mjs/paste/WordDesktop/processWordLists.js.map +1 -1
  43. package/lib-mjs/paste/utils/customListUtils.d.ts +1 -1
  44. package/lib-mjs/paste/utils/customListUtils.js +10 -5
  45. package/lib-mjs/paste/utils/customListUtils.js.map +1 -1
  46. package/package.json +5 -5
@@ -11,7 +11,7 @@ var handleEnterOnParagraph = function (context) {
11
11
  var _c = context.insertPoint, paragraph = _c.paragraph, path = _c.path;
12
12
  var paraIndex = (_b = (_a = path[0]) === null || _a === void 0 ? void 0 : _a.blocks.indexOf(paragraph)) !== null && _b !== void 0 ? _b : -1;
13
13
  if (context.deleteResult == 'notDeleted' && paraIndex >= 0) {
14
- var newPara = (0, splitParagraph_1.splitParagraph)(context.insertPoint);
14
+ var newPara = (0, splitParagraph_1.splitParagraph)(context.insertPoint, false /* removeImplicitParagraph */);
15
15
  (0, roosterjs_content_model_dom_1.mutateBlock)(path[0]).blocks.splice(paraIndex + 1, 0, newPara);
16
16
  context.deleteResult = 'range';
17
17
  context.lastParagraph = newPara;
@@ -1 +1 @@
1
- {"version":3,"file":"handleEnterOnParagraph.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnParagraph.ts"],"names":[],"mappings":";;;AAAA,2EAA0D;AAC1D,0DAAyD;AAGzD;;GAEG;AACI,IAAM,sBAAsB,GAAwB,UAAA,OAAO;;IACxD,IAAA,KAAsB,OAAO,CAAC,WAAW,EAAvC,SAAS,eAAA,EAAE,IAAI,UAAwB,CAAC;IAChD,IAAM,SAAS,GAAG,MAAA,MAAA,IAAI,CAAC,CAAC,CAAC,0CAAE,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,mCAAI,CAAC,CAAC,CAAC;IAE3D,IAAI,OAAO,CAAC,YAAY,IAAI,YAAY,IAAI,SAAS,IAAI,CAAC,EAAE;QACxD,IAAM,OAAO,GAAG,IAAA,+BAAc,EAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAEpD,IAAA,yCAAW,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;QAE9D,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC;QAC/B,OAAO,CAAC,aAAa,GAAG,OAAO,CAAC;QAChC,OAAO,CAAC,WAAW,CAAC,SAAS,GAAG,OAAO,CAAC;KAC3C;AACL,CAAC,CAAC;AAbW,QAAA,sBAAsB,0BAajC","sourcesContent":["import { mutateBlock } from 'roosterjs-content-model-dom';\nimport { splitParagraph } from '../utils/splitParagraph';\nimport type { DeleteSelectionStep } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const handleEnterOnParagraph: DeleteSelectionStep = context => {\n const { paragraph, path } = context.insertPoint;\n const paraIndex = path[0]?.blocks.indexOf(paragraph) ?? -1;\n\n if (context.deleteResult == 'notDeleted' && paraIndex >= 0) {\n const newPara = splitParagraph(context.insertPoint);\n\n mutateBlock(path[0]).blocks.splice(paraIndex + 1, 0, newPara);\n\n context.deleteResult = 'range';\n context.lastParagraph = newPara;\n context.insertPoint.paragraph = newPara;\n }\n};\n"]}
1
+ {"version":3,"file":"handleEnterOnParagraph.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/edit/inputSteps/handleEnterOnParagraph.ts"],"names":[],"mappings":";;;AAAA,2EAA0D;AAC1D,0DAAyD;AAGzD;;GAEG;AACI,IAAM,sBAAsB,GAAwB,UAAA,OAAO;;IACxD,IAAA,KAAsB,OAAO,CAAC,WAAW,EAAvC,SAAS,eAAA,EAAE,IAAI,UAAwB,CAAC;IAChD,IAAM,SAAS,GAAG,MAAA,MAAA,IAAI,CAAC,CAAC,CAAC,0CAAE,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,mCAAI,CAAC,CAAC,CAAC;IAE3D,IAAI,OAAO,CAAC,YAAY,IAAI,YAAY,IAAI,SAAS,IAAI,CAAC,EAAE;QACxD,IAAM,OAAO,GAAG,IAAA,+BAAc,EAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,6BAA6B,CAAC,CAAC;QAEzF,IAAA,yCAAW,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;QAE9D,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC;QAC/B,OAAO,CAAC,aAAa,GAAG,OAAO,CAAC;QAChC,OAAO,CAAC,WAAW,CAAC,SAAS,GAAG,OAAO,CAAC;KAC3C;AACL,CAAC,CAAC;AAbW,QAAA,sBAAsB,0BAajC","sourcesContent":["import { mutateBlock } from 'roosterjs-content-model-dom';\nimport { splitParagraph } from '../utils/splitParagraph';\nimport type { DeleteSelectionStep } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const handleEnterOnParagraph: DeleteSelectionStep = context => {\n const { paragraph, path } = context.insertPoint;\n const paraIndex = path[0]?.blocks.indexOf(paragraph) ?? -1;\n\n if (context.deleteResult == 'notDeleted' && paraIndex >= 0) {\n const newPara = splitParagraph(context.insertPoint, false /* removeImplicitParagraph */);\n\n mutateBlock(path[0]).blocks.splice(paraIndex + 1, 0, newPara);\n\n context.deleteResult = 'range';\n context.lastParagraph = newPara;\n context.insertPoint.paragraph = newPara;\n }\n};\n"]}
@@ -4,7 +4,9 @@ import type { InsertPoint, ShallowMutableContentModelParagraph } from 'roosterjs
4
4
  * Split the given paragraph from insert point into two paragraphs,
5
5
  * and move the selection marker to the beginning of the second paragraph
6
6
  * @param insertPoint The input insert point which includes the paragraph and selection marker
7
- * @param formatKeys The format that needs to be copied from the splitted paragraph, if not specified, some default format will be copied
7
+ * @param removeImplicitParagraph Whether to remove the implicit paragraph if it becomes empty after split
8
+ * * If set to false, the implicit paragraph will be preserved even if it becomes empty
9
+ * * If set to true, the implicit paragraph will be removed if it becomes empty
8
10
  * @returns The new paragraph it created
9
11
  */
10
- export declare function splitParagraph(insertPoint: InsertPoint): ShallowMutableContentModelParagraph;
12
+ export declare function splitParagraph(insertPoint: InsertPoint, removeImplicitParagraph?: boolean): ShallowMutableContentModelParagraph;
@@ -8,21 +8,26 @@ var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
8
8
  * Split the given paragraph from insert point into two paragraphs,
9
9
  * and move the selection marker to the beginning of the second paragraph
10
10
  * @param insertPoint The input insert point which includes the paragraph and selection marker
11
- * @param formatKeys The format that needs to be copied from the splitted paragraph, if not specified, some default format will be copied
11
+ * @param removeImplicitParagraph Whether to remove the implicit paragraph if it becomes empty after split
12
+ * * If set to false, the implicit paragraph will be preserved even if it becomes empty
13
+ * * If set to true, the implicit paragraph will be removed if it becomes empty
12
14
  * @returns The new paragraph it created
13
15
  */
14
- function splitParagraph(insertPoint) {
16
+ function splitParagraph(insertPoint, removeImplicitParagraph) {
15
17
  var _a;
18
+ if (removeImplicitParagraph === void 0) { removeImplicitParagraph = true; }
16
19
  var paragraph = insertPoint.paragraph, marker = insertPoint.marker;
17
20
  var newParagraph = (0, roosterjs_content_model_dom_1.createParagraph)(false /*isImplicit*/, {}, paragraph.segmentFormat);
18
21
  (0, roosterjs_content_model_dom_1.copyFormat)(newParagraph.format, paragraph.format, roosterjs_content_model_dom_1.ParagraphFormats);
19
22
  var markerIndex = paragraph.segments.indexOf(marker);
20
23
  var segments = paragraph.segments.splice(markerIndex, paragraph.segments.length - markerIndex);
21
24
  (_a = newParagraph.segments).push.apply(_a, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(segments), false));
22
- if (paragraph.segments.length == 0 && !paragraph.isImplicit) {
25
+ var isEmptyParagraph = paragraph.segments.length == 0;
26
+ var shouldPreserveImplicitParagraph = !paragraph.isImplicit || !removeImplicitParagraph;
27
+ if (isEmptyParagraph && shouldPreserveImplicitParagraph) {
23
28
  paragraph.segments.push((0, roosterjs_content_model_dom_1.createBr)(marker.format));
24
29
  }
25
- else if (paragraph.segments.length > 0) {
30
+ else if (!isEmptyParagraph) {
26
31
  (0, roosterjs_content_model_dom_1.setParagraphNotImplicit)(paragraph);
27
32
  }
28
33
  insertPoint.paragraph = newParagraph;
@@ -1 +1 @@
1
- {"version":3,"file":"splitParagraph.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/edit/utils/splitParagraph.ts"],"names":[],"mappings":";;;;AAAA,2EAOqC;AAMrC;;;;;;;GAOG;AACH,SAAgB,cAAc,CAAC,WAAwB;;IAC3C,IAAA,SAAS,GAAa,WAAW,UAAxB,EAAE,MAAM,GAAK,WAAW,OAAhB,CAAiB;IAC1C,IAAM,YAAY,GAAwC,IAAA,6CAAe,EACrE,KAAK,CAAC,cAAc,EACpB,EAAE,EACF,SAAS,CAAC,aAAa,CAC1B,CAAC;IAEF,IAAA,wCAAU,EAAC,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,8CAAgB,CAAC,CAAC;IAEpE,IAAM,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,IAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CACtC,WAAW,EACX,SAAS,CAAC,QAAQ,CAAC,MAAM,GAAG,WAAW,CAC1C,CAAC;IAEF,CAAA,KAAA,YAAY,CAAC,QAAQ,CAAA,CAAC,IAAI,8DAAI,QAAQ,WAAE;IAExC,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;QACzD,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAA,sCAAQ,EAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;KACpD;SAAM,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;QACtC,IAAA,qDAAuB,EAAC,SAAS,CAAC,CAAC;KACtC;IAED,WAAW,CAAC,SAAS,GAAG,YAAY,CAAC;IAErC,IAAA,gDAAkB,EAAC,SAAS,CAAC,CAAC;IAE9B,OAAO,YAAY,CAAC;AACxB,CAAC;AA7BD,wCA6BC","sourcesContent":["import {\n copyFormat,\n createBr,\n createParagraph,\n normalizeParagraph,\n ParagraphFormats,\n setParagraphNotImplicit,\n} from 'roosterjs-content-model-dom';\nimport type {\n InsertPoint,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Split the given paragraph from insert point into two paragraphs,\n * and move the selection marker to the beginning of the second paragraph\n * @param insertPoint The input insert point which includes the paragraph and selection marker\n * @param formatKeys The format that needs to be copied from the splitted paragraph, if not specified, some default format will be copied\n * @returns The new paragraph it created\n */\nexport function splitParagraph(insertPoint: InsertPoint) {\n const { paragraph, marker } = insertPoint;\n const newParagraph: ShallowMutableContentModelParagraph = createParagraph(\n false /*isImplicit*/,\n {},\n paragraph.segmentFormat\n );\n\n copyFormat(newParagraph.format, paragraph.format, ParagraphFormats);\n\n const markerIndex = paragraph.segments.indexOf(marker);\n const segments = paragraph.segments.splice(\n markerIndex,\n paragraph.segments.length - markerIndex\n );\n\n newParagraph.segments.push(...segments);\n\n if (paragraph.segments.length == 0 && !paragraph.isImplicit) {\n paragraph.segments.push(createBr(marker.format));\n } else if (paragraph.segments.length > 0) {\n setParagraphNotImplicit(paragraph);\n }\n\n insertPoint.paragraph = newParagraph;\n\n normalizeParagraph(paragraph);\n\n return newParagraph;\n}\n"]}
1
+ {"version":3,"file":"splitParagraph.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/edit/utils/splitParagraph.ts"],"names":[],"mappings":";;;;AAAA,2EAOqC;AAMrC;;;;;;;;;GASG;AACH,SAAgB,cAAc,CAC1B,WAAwB,EACxB,uBAAuC;;IAAvC,wCAAA,EAAA,8BAAuC;IAE/B,IAAA,SAAS,GAAa,WAAW,UAAxB,EAAE,MAAM,GAAK,WAAW,OAAhB,CAAiB;IAC1C,IAAM,YAAY,GAAwC,IAAA,6CAAe,EACrE,KAAK,CAAC,cAAc,EACpB,EAAE,EACF,SAAS,CAAC,aAAa,CAC1B,CAAC;IAEF,IAAA,wCAAU,EAAC,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,8CAAgB,CAAC,CAAC;IAEpE,IAAM,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,IAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CACtC,WAAW,EACX,SAAS,CAAC,QAAQ,CAAC,MAAM,GAAG,WAAW,CAC1C,CAAC;IAEF,CAAA,KAAA,YAAY,CAAC,QAAQ,CAAA,CAAC,IAAI,8DAAI,QAAQ,WAAE;IAExC,IAAM,gBAAgB,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC;IACxD,IAAM,+BAA+B,GAAG,CAAC,SAAS,CAAC,UAAU,IAAI,CAAC,uBAAuB,CAAC;IAE1F,IAAI,gBAAgB,IAAI,+BAA+B,EAAE;QACrD,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAA,sCAAQ,EAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;KACpD;SAAM,IAAI,CAAC,gBAAgB,EAAE;QAC1B,IAAA,qDAAuB,EAAC,SAAS,CAAC,CAAC;KACtC;IAED,WAAW,CAAC,SAAS,GAAG,YAAY,CAAC;IAErC,IAAA,gDAAkB,EAAC,SAAS,CAAC,CAAC;IAE9B,OAAO,YAAY,CAAC;AACxB,CAAC;AAnCD,wCAmCC","sourcesContent":["import {\n copyFormat,\n createBr,\n createParagraph,\n normalizeParagraph,\n ParagraphFormats,\n setParagraphNotImplicit,\n} from 'roosterjs-content-model-dom';\nimport type {\n InsertPoint,\n ShallowMutableContentModelParagraph,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Split the given paragraph from insert point into two paragraphs,\n * and move the selection marker to the beginning of the second paragraph\n * @param insertPoint The input insert point which includes the paragraph and selection marker\n * @param removeImplicitParagraph Whether to remove the implicit paragraph if it becomes empty after split\n * * If set to false, the implicit paragraph will be preserved even if it becomes empty\n * * If set to true, the implicit paragraph will be removed if it becomes empty\n * @returns The new paragraph it created\n */\nexport function splitParagraph(\n insertPoint: InsertPoint,\n removeImplicitParagraph: boolean = true\n): ShallowMutableContentModelParagraph {\n const { paragraph, marker } = insertPoint;\n const newParagraph: ShallowMutableContentModelParagraph = createParagraph(\n false /*isImplicit*/,\n {},\n paragraph.segmentFormat\n );\n\n copyFormat(newParagraph.format, paragraph.format, ParagraphFormats);\n\n const markerIndex = paragraph.segments.indexOf(marker);\n const segments = paragraph.segments.splice(\n markerIndex,\n paragraph.segments.length - markerIndex\n );\n\n newParagraph.segments.push(...segments);\n\n const isEmptyParagraph = paragraph.segments.length == 0;\n const shouldPreserveImplicitParagraph = !paragraph.isImplicit || !removeImplicitParagraph;\n\n if (isEmptyParagraph && shouldPreserveImplicitParagraph) {\n paragraph.segments.push(createBr(marker.format));\n } else if (!isEmptyParagraph) {\n setParagraphNotImplicit(paragraph);\n }\n\n insertPoint.paragraph = newParagraph;\n\n normalizeParagraph(paragraph);\n\n return newParagraph;\n}\n"]}
@@ -51,6 +51,7 @@ export declare class ImageEditPlugin implements ImageEditor, EditorPlugin {
51
51
  * @param event The event to handle:
52
52
  */
53
53
  onPluginEvent(event: PluginEvent): void;
54
+ private handleBeforeLogicalRootChange;
54
55
  private removeImageEditing;
55
56
  private isImageSelection;
56
57
  private mouseUpHandler;
@@ -147,6 +147,16 @@ var ImageEditPlugin = /** @class */ (function () {
147
147
  case 'extractContentWithDom':
148
148
  this.removeImageEditing(event.clonedRoot);
149
149
  break;
150
+ case 'beforeLogicalRootChange':
151
+ this.handleBeforeLogicalRootChange();
152
+ break;
153
+ }
154
+ };
155
+ ImageEditPlugin.prototype.handleBeforeLogicalRootChange = function () {
156
+ if (this.isEditing && this.editor && !this.editor.isDisposed()) {
157
+ this.applyFormatWithContentModel(this.editor, this.isCropMode, false /* shouldSelectImage */);
158
+ this.removeImageWrapper();
159
+ this.cleanInfo();
150
160
  }
151
161
  };
152
162
  ImageEditPlugin.prototype.removeImageEditing = function (clonedRoot) {
@@ -1 +1 @@
1
- {"version":3,"file":"ImageEditPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/imageEdit/ImageEditPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { applyChange } from './utils/applyChange';\nimport { canRegenerateImage } from './utils/canRegenerateImage';\nimport { checkIfImageWasResized, isASmallImage } from './utils/imageEditUtils';\nimport { createImageWrapper } from './utils/createImageWrapper';\nimport { Cropper } from './Cropper/cropperContext';\nimport { EDITING_MARKER, findEditingImage } from './utils/findEditingImage';\nimport { getDropAndDragHelpers } from './utils/getDropAndDragHelpers';\nimport { getHTMLImageOptions } from './utils/getHTMLImageOptions';\nimport { getSelectedImage } from './utils/getSelectedImage';\nimport { getSelectedImageMetadata, updateImageEditInfo } from './utils/updateImageEditInfo';\nimport { ImageEditElementClass } from './types/ImageEditElementClass';\nimport { normalizeImageSelection } from './utils/normalizeImageSelection';\nimport { Resizer } from './Resizer/resizerContext';\nimport { Rotator } from './Rotator/rotatorContext';\nimport { updateRotateHandle } from './Rotator/updateRotateHandle';\nimport { updateWrapper } from './utils/updateWrapper';\nimport {\n ChangeSource,\n getSafeIdSelector,\n getSelectedParagraphs,\n isElementOfType,\n isNodeOfType,\n mutateBlock,\n mutateSegment,\n setImageState,\n unwrap,\n} from 'roosterjs-content-model-dom';\nimport type { DragAndDropHelper } from '../pluginUtils/DragAndDrop/DragAndDropHelper';\nimport type { DragAndDropContext } from './types/DragAndDropContext';\nimport type { ImageHtmlOptions } from './types/ImageHtmlOptions';\nimport type { ImageEditOptions } from './types/ImageEditOptions';\nimport type {\n ContentChangedEvent,\n ContentModelImage,\n EditorPlugin,\n IEditor,\n ImageEditOperation,\n ImageEditor,\n ImageMetadataFormat,\n KeyDownEvent,\n MouseDownEvent,\n MouseUpEvent,\n PluginEvent,\n} from 'roosterjs-content-model-types';\n\nconst DefaultOptions: Partial<ImageEditOptions> = {\n borderColor: '#DB626C',\n minWidth: 10,\n minHeight: 10,\n preserveRatio: true,\n disableRotate: false,\n disableSideResize: false,\n onSelectState: ['resize', 'rotate'],\n};\n\nconst MouseRightButton = 2;\nconst DRAG_ID = '_dragging';\nconst IMAGE_EDIT_CLASS = 'imageEdit';\nconst IMAGE_EDIT_CLASS_CARET = 'imageEditCaretColor';\nconst IMAGE_EDIT_FORMAT_EVENT = 'ImageEditEvent';\n\n/**\n * ImageEdit plugin handles the following image editing features:\n * - Resize image\n * - Crop image\n * - Rotate image\n * - Flip image\n */\nexport class ImageEditPlugin implements ImageEditor, EditorPlugin {\n protected editor: IEditor | null = null;\n private shadowSpan: HTMLSpanElement | null = null;\n private selectedImage: HTMLImageElement | null = null;\n protected wrapper: HTMLSpanElement | null = null;\n protected imageEditInfo: ImageMetadataFormat | null = null;\n private imageHTMLOptions: ImageHtmlOptions | null = null;\n private dndHelpers: DragAndDropHelper<DragAndDropContext, any>[] = [];\n private clonedImage: HTMLImageElement | null = null;\n private lastSrc: string | null = null;\n private wasImageResized: boolean = false;\n private isCropMode: boolean = false;\n private resizers: HTMLDivElement[] = [];\n private rotators: HTMLDivElement[] = [];\n private croppers: HTMLDivElement[] = [];\n private zoomScale: number = 1;\n private disposer: (() => void) | null = null;\n protected isEditing = false;\n\n constructor(protected options: ImageEditOptions = DefaultOptions) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'ImageEdit';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n this.disposer = editor.attachDomEvent({\n blur: {\n beforeDispatch: () => {\n if (this.isEditing && this.editor && !this.editor.isDisposed()) {\n this.applyFormatWithContentModel(\n this.editor,\n this.isCropMode,\n true /* shouldSelectImage */\n );\n }\n },\n },\n dragstart: {\n beforeDispatch: ev => {\n if (this.editor) {\n const target = ev.target as Node;\n if (this.isImageSelection(target)) {\n target.id = target.id + DRAG_ID;\n }\n }\n },\n },\n dragend: {\n beforeDispatch: ev => {\n if (this.editor) {\n const target = ev.target as Node;\n if (this.isImageSelection(target) && target.id.includes(DRAG_ID)) {\n target.id = target.id.replace(DRAG_ID, '').trim();\n }\n }\n },\n },\n });\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n if (this.disposer) {\n this.disposer();\n this.disposer = null;\n }\n this.isEditing = false;\n this.cleanInfo();\n this.editor = null;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (!this.editor) {\n return;\n }\n switch (event.eventType) {\n case 'mouseDown':\n this.mouseDownHandler(this.editor, event);\n break;\n case 'mouseUp':\n this.mouseUpHandler(this.editor, event);\n break;\n case 'keyDown':\n this.keyDownHandler(this.editor, event);\n break;\n case 'contentChanged':\n this.contentChangedHandler(this.editor, event);\n break;\n case 'extractContentWithDom':\n this.removeImageEditing(event.clonedRoot);\n break;\n }\n }\n\n private removeImageEditing(clonedRoot: HTMLElement) {\n const images = clonedRoot.querySelectorAll('img');\n images.forEach(image => {\n if (image.dataset.editingInfo) {\n delete image.dataset.editingInfo;\n }\n });\n }\n\n private isImageSelection(target: Node): target is HTMLElement {\n return (\n isNodeOfType(target, 'ELEMENT_NODE') &&\n (isElementOfType(target, 'img') ||\n !!(\n isElementOfType(target, 'span') &&\n target.firstElementChild &&\n isNodeOfType(target.firstElementChild, 'ELEMENT_NODE') &&\n isElementOfType(target.firstElementChild, 'img')\n ))\n );\n }\n\n private mouseUpHandler(editor: IEditor, event: MouseUpEvent) {\n const selection = editor.getDOMSelection();\n if ((selection && selection.type == 'image') || this.isEditing) {\n const shouldSelectImage =\n this.isImageSelection(event.rawEvent.target as Node) &&\n event.rawEvent.button === MouseRightButton;\n this.applyFormatWithContentModel(editor, this.isCropMode, shouldSelectImage);\n }\n }\n\n private mouseDownHandler(editor: IEditor, event: MouseDownEvent) {\n if (\n this.isEditing &&\n this.isImageSelection(event.rawEvent.target as Node) &&\n event.rawEvent.button !== MouseRightButton &&\n !this.isCropMode\n ) {\n this.applyFormatWithContentModel(\n editor,\n this.isCropMode,\n this.shadowSpan === event.rawEvent.target\n );\n }\n }\n\n private onDropHandler(editor: IEditor) {\n const selection = editor.getDOMSelection();\n if (selection?.type == 'image') {\n editor.formatContentModel(model => {\n const imageDragged = findEditingImage(model, selection.image.id);\n const imageDropped = findEditingImage(\n model,\n selection.image.id.replace(DRAG_ID, '').trim()\n );\n if (imageDragged && imageDropped) {\n const draggedIndex = imageDragged.paragraph.segments.indexOf(\n imageDragged.image\n );\n mutateBlock(imageDragged.paragraph).segments.splice(draggedIndex, 1);\n const segment = imageDropped.image;\n const paragraph = imageDropped.paragraph;\n mutateSegment(paragraph, segment, image => {\n image.isSelected = true;\n image.isSelectedAsImageSelection = true;\n });\n\n return true;\n }\n return false;\n });\n }\n }\n\n private keyDownHandler(editor: IEditor, event: KeyDownEvent) {\n if (this.isEditing) {\n if (\n event.rawEvent.key === 'Escape' ||\n event.rawEvent.key === 'Delete' ||\n event.rawEvent.key === 'Backspace'\n ) {\n if (event.rawEvent.key === 'Escape') {\n this.removeImageWrapper();\n }\n this.cleanInfo();\n } else {\n if (event.rawEvent.key == 'Enter' && this.isCropMode) {\n event.rawEvent.preventDefault();\n }\n this.applyFormatWithContentModel(\n editor,\n this.isCropMode,\n true /** should selectImage */,\n false /* isApiOperation */\n );\n }\n }\n }\n\n private setContentHandler(editor: IEditor) {\n const selection = editor.getDOMSelection();\n if (selection?.type == 'image') {\n this.cleanInfo();\n setImageState(selection.image, '');\n this.isEditing = false;\n this.isCropMode = false;\n }\n }\n\n private formatEventHandler(event: ContentChangedEvent) {\n if (this.isEditing && event.formatApiName !== IMAGE_EDIT_FORMAT_EVENT) {\n this.cleanInfo();\n this.isEditing = false;\n this.isCropMode = false;\n }\n }\n\n private contentChangedHandler(editor: IEditor, event: ContentChangedEvent) {\n switch (event.source) {\n case ChangeSource.SetContent:\n this.setContentHandler(editor);\n break;\n case ChangeSource.Format:\n this.formatEventHandler(event);\n break;\n case ChangeSource.Drop:\n this.onDropHandler(editor);\n break;\n }\n }\n\n /**\n * EXPOSED FOR TESTING PURPOSE ONLY\n */\n protected applyFormatWithContentModel(\n editor: IEditor,\n isCropMode: boolean,\n shouldSelectImage: boolean,\n isApiOperation?: boolean\n ) {\n let editingImageModel: ContentModelImage | undefined;\n const selection = editor.getDOMSelection();\n\n editor.formatContentModel(\n model => {\n const editingImage = getSelectedImage(model);\n const previousSelectedImage = isApiOperation\n ? editingImage\n : findEditingImage(model);\n let result = false;\n\n if (\n shouldSelectImage ||\n previousSelectedImage?.image != editingImage?.image ||\n previousSelectedImage?.image.format.imageState == EDITING_MARKER ||\n isApiOperation\n ) {\n const { lastSrc, selectedImage, imageEditInfo, clonedImage } = this;\n if (\n (this.isEditing || isApiOperation) &&\n previousSelectedImage &&\n lastSrc &&\n selectedImage &&\n imageEditInfo &&\n clonedImage\n ) {\n mutateSegment(\n previousSelectedImage.paragraph,\n previousSelectedImage.image,\n image => {\n applyChange(\n editor,\n selectedImage,\n image,\n imageEditInfo,\n lastSrc,\n this.wasImageResized || this.isCropMode,\n clonedImage\n );\n\n image.isSelected = shouldSelectImage;\n image.isSelectedAsImageSelection = shouldSelectImage;\n image.format.imageState = undefined;\n\n if (selection?.type == 'range' && !selection.range.collapsed) {\n const selectedParagraphs = getSelectedParagraphs(model, true);\n const isImageInRange = selectedParagraphs.some(paragraph =>\n paragraph.segments.includes(image)\n );\n if (isImageInRange) {\n image.isSelected = true;\n }\n }\n }\n );\n\n if (shouldSelectImage) {\n normalizeImageSelection(previousSelectedImage);\n }\n\n this.cleanInfo();\n result = true;\n }\n\n this.isEditing = false;\n this.isCropMode = false;\n\n if (\n editingImage &&\n selection?.type == 'image' &&\n !shouldSelectImage &&\n !isApiOperation\n ) {\n this.isEditing = true;\n this.isCropMode = isCropMode;\n mutateSegment(editingImage.paragraph, editingImage.image, image => {\n editingImageModel = image;\n this.imageEditInfo = updateImageEditInfo(image, selection.image);\n image.format.imageState = 'isEditing';\n });\n\n result = true;\n }\n }\n\n return result;\n },\n {\n onNodeCreated: (model, node) => {\n if (\n !isApiOperation &&\n editingImageModel &&\n editingImageModel == model &&\n editingImageModel.format.imageState == EDITING_MARKER &&\n isNodeOfType(node, 'ELEMENT_NODE') &&\n isElementOfType(node, 'img')\n ) {\n if (isCropMode) {\n this.startCropMode(editor, node);\n } else {\n this.startRotateAndResize(editor, node);\n }\n }\n },\n apiName: IMAGE_EDIT_FORMAT_EVENT,\n },\n {\n tryGetFromCache: true,\n }\n );\n }\n\n private startEditing(\n editor: IEditor,\n image: HTMLImageElement,\n apiOperation: ImageEditOperation[]\n ) {\n if (!this.imageEditInfo) {\n this.imageEditInfo = getSelectedImageMetadata(editor, image);\n }\n this.lastSrc = image.getAttribute('src');\n this.imageHTMLOptions = getHTMLImageOptions(editor, this.options, this.imageEditInfo);\n const {\n resizers,\n rotators,\n wrapper,\n shadowSpan,\n imageClone,\n croppers,\n } = createImageWrapper(\n editor,\n image,\n this.options,\n this.imageEditInfo,\n this.imageHTMLOptions,\n apiOperation\n );\n this.shadowSpan = shadowSpan;\n this.selectedImage = image;\n this.wrapper = wrapper;\n this.clonedImage = imageClone;\n this.wasImageResized = checkIfImageWasResized(image);\n this.resizers = resizers;\n this.rotators = rotators;\n this.croppers = croppers;\n this.zoomScale = editor.getDOMHelper().calculateZoomScale();\n\n editor.setEditorStyle(IMAGE_EDIT_CLASS, `outline-style:none!important;`, [\n `span:has(>img${getSafeIdSelector(this.selectedImage.id)})`,\n ]);\n\n editor.setEditorStyle(IMAGE_EDIT_CLASS_CARET, `caret-color: transparent;`);\n }\n\n public startRotateAndResize(editor: IEditor, image: HTMLImageElement) {\n if (this.imageEditInfo) {\n this.startEditing(editor, image, ['resize', 'rotate']);\n if (this.selectedImage && this.imageEditInfo && this.wrapper && this.clonedImage) {\n const isMobileOrTable = !!editor.getEnvironment().isMobileOrTablet;\n this.dndHelpers = [\n ...getDropAndDragHelpers(\n this.wrapper,\n this.imageEditInfo,\n this.options,\n ImageEditElementClass.ResizeHandle,\n Resizer,\n () => {\n if (\n this.imageEditInfo &&\n this.selectedImage &&\n this.wrapper &&\n this.clonedImage\n ) {\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper,\n this.resizers\n );\n this.wasImageResized = true;\n }\n },\n this.zoomScale,\n isMobileOrTable\n ),\n ...getDropAndDragHelpers(\n this.wrapper,\n this.imageEditInfo,\n this.options,\n ImageEditElementClass.RotateHandle,\n Rotator,\n () => {\n if (\n this.imageEditInfo &&\n this.selectedImage &&\n this.wrapper &&\n this.clonedImage\n ) {\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper\n );\n this.updateRotateHandleState(\n editor,\n this.selectedImage,\n this.wrapper,\n this.rotators,\n this.imageEditInfo?.angleRad\n );\n }\n },\n this.zoomScale,\n isMobileOrTable\n ),\n ];\n\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper,\n this.resizers\n );\n\n this.updateRotateHandleState(\n editor,\n this.selectedImage,\n this.wrapper,\n this.rotators,\n this.imageEditInfo?.angleRad\n );\n }\n }\n }\n\n private updateRotateHandleState(\n editor: IEditor,\n image: HTMLImageElement,\n wrapper: HTMLSpanElement,\n rotators: HTMLDivElement[],\n angleRad: number | undefined\n ) {\n const viewport = editor.getVisibleViewport();\n const smallImage = isASmallImage(image.width, image.height);\n if (viewport && rotators && rotators.length > 0) {\n const rotator = rotators[0];\n const rotatorHandle = rotator.firstElementChild;\n if (\n isNodeOfType(rotatorHandle, 'ELEMENT_NODE') &&\n isElementOfType(rotatorHandle, 'div')\n ) {\n updateRotateHandle(\n viewport,\n angleRad ?? 0,\n wrapper,\n rotator,\n rotatorHandle,\n smallImage\n );\n }\n }\n }\n\n public isOperationAllowed(operation: ImageEditOperation): boolean {\n return (\n operation === 'resize' ||\n operation === 'rotate' ||\n operation === 'flip' ||\n operation === 'crop'\n );\n }\n\n public canRegenerateImage(image: HTMLImageElement): boolean {\n return canRegenerateImage(image);\n }\n\n private startCropMode(editor: IEditor, image: HTMLImageElement) {\n if (this.imageEditInfo) {\n this.startEditing(editor, image, ['crop']);\n if (this.imageEditInfo && this.selectedImage && this.wrapper && this.clonedImage) {\n this.dndHelpers = [\n ...getDropAndDragHelpers(\n this.wrapper,\n this.imageEditInfo,\n this.options,\n ImageEditElementClass.CropHandle,\n Cropper,\n () => {\n if (\n this.imageEditInfo &&\n this.selectedImage &&\n this.wrapper &&\n this.clonedImage\n ) {\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper,\n undefined,\n this.croppers\n );\n this.isCropMode = true;\n }\n },\n this.zoomScale,\n !!editor.getEnvironment().isMobileOrTablet\n ),\n ];\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper,\n undefined,\n this.croppers\n );\n }\n }\n }\n\n public cropImage() {\n if (!this.editor) {\n return;\n }\n if (!this.editor.getEnvironment().isSafari) {\n this.editor.focus(); // Safari will keep the selection when click crop, then the focus() call should not be called\n }\n const selection = this.editor.getDOMSelection();\n if (selection?.type == 'image') {\n this.applyFormatWithContentModel(\n this.editor,\n true /* isCropMode */,\n false /* shouldSelectImage */\n );\n }\n }\n\n private editImage(\n editor: IEditor,\n image: HTMLImageElement,\n apiOperation: ImageEditOperation[],\n operation: (imageEditInfo: ImageMetadataFormat) => void\n ) {\n this.startEditing(editor, image, apiOperation);\n if (!this.selectedImage || !this.imageEditInfo || !this.wrapper || !this.clonedImage) {\n return;\n }\n\n operation(this.imageEditInfo);\n\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper\n );\n\n this.applyFormatWithContentModel(\n editor,\n false /* isCrop */,\n true /* shouldSelect*/,\n true /* isApiOperation */\n );\n }\n\n /**\n * Exported for testing purpose only\n */\n public cleanInfo() {\n this.editor?.setEditorStyle(IMAGE_EDIT_CLASS, null);\n this.editor?.setEditorStyle(IMAGE_EDIT_CLASS_CARET, null);\n this.selectedImage = null;\n this.shadowSpan = null;\n this.wrapper = null;\n this.imageEditInfo = null;\n this.imageHTMLOptions = null;\n this.dndHelpers.forEach(helper => helper.dispose());\n this.dndHelpers = [];\n this.clonedImage = null;\n this.lastSrc = null;\n this.wasImageResized = false;\n this.isCropMode = false;\n this.resizers = [];\n this.rotators = [];\n this.croppers = [];\n }\n\n private removeImageWrapper() {\n let image: HTMLImageElement | null = null;\n if (this.shadowSpan && this.shadowSpan.parentElement) {\n if (\n this.shadowSpan.firstElementChild &&\n isNodeOfType(this.shadowSpan.firstElementChild, 'ELEMENT_NODE') &&\n isElementOfType(this.shadowSpan.firstElementChild, 'img')\n ) {\n image = this.shadowSpan.firstElementChild;\n }\n unwrap(this.shadowSpan);\n this.shadowSpan = null;\n this.wrapper = null;\n }\n\n return image;\n }\n\n public flipImage(direction: 'horizontal' | 'vertical') {\n const selection = this.editor?.getDOMSelection();\n if (!this.editor || !selection || selection.type !== 'image') {\n return;\n }\n const image = selection.image;\n if (this.editor) {\n this.editImage(this.editor, image, ['flip'], imageEditInfo => {\n const angleRad = imageEditInfo.angleRad || 0;\n const isInVerticalPostion =\n (angleRad >= Math.PI / 2 && angleRad < (3 * Math.PI) / 4) ||\n (angleRad <= -Math.PI / 2 && angleRad > (-3 * Math.PI) / 4);\n if (isInVerticalPostion) {\n if (direction === 'horizontal') {\n imageEditInfo.flippedVertical = !imageEditInfo.flippedVertical;\n } else {\n imageEditInfo.flippedHorizontal = !imageEditInfo.flippedHorizontal;\n }\n } else {\n if (direction === 'vertical') {\n imageEditInfo.flippedVertical = !imageEditInfo.flippedVertical;\n } else {\n imageEditInfo.flippedHorizontal = !imageEditInfo.flippedHorizontal;\n }\n }\n });\n }\n }\n\n public rotateImage(angleRad: number) {\n const selection = this.editor?.getDOMSelection();\n if (!this.editor || !selection || selection.type !== 'image') {\n return;\n }\n const image = selection.image;\n if (this.editor) {\n this.editImage(this.editor, image, [], imageEditInfo => {\n imageEditInfo.angleRad = (imageEditInfo.angleRad || 0) + angleRad;\n });\n }\n }\n}\n"]}
1
+ {"version":3,"file":"ImageEditPlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/imageEdit/ImageEditPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { applyChange } from './utils/applyChange';\nimport { canRegenerateImage } from './utils/canRegenerateImage';\nimport { checkIfImageWasResized, isASmallImage } from './utils/imageEditUtils';\nimport { createImageWrapper } from './utils/createImageWrapper';\nimport { Cropper } from './Cropper/cropperContext';\nimport { EDITING_MARKER, findEditingImage } from './utils/findEditingImage';\nimport { getDropAndDragHelpers } from './utils/getDropAndDragHelpers';\nimport { getHTMLImageOptions } from './utils/getHTMLImageOptions';\nimport { getSelectedImage } from './utils/getSelectedImage';\nimport { getSelectedImageMetadata, updateImageEditInfo } from './utils/updateImageEditInfo';\nimport { ImageEditElementClass } from './types/ImageEditElementClass';\nimport { normalizeImageSelection } from './utils/normalizeImageSelection';\nimport { Resizer } from './Resizer/resizerContext';\nimport { Rotator } from './Rotator/rotatorContext';\nimport { updateRotateHandle } from './Rotator/updateRotateHandle';\nimport { updateWrapper } from './utils/updateWrapper';\nimport {\n ChangeSource,\n getSafeIdSelector,\n getSelectedParagraphs,\n isElementOfType,\n isNodeOfType,\n mutateBlock,\n mutateSegment,\n setImageState,\n unwrap,\n} from 'roosterjs-content-model-dom';\nimport type { DragAndDropHelper } from '../pluginUtils/DragAndDrop/DragAndDropHelper';\nimport type { DragAndDropContext } from './types/DragAndDropContext';\nimport type { ImageHtmlOptions } from './types/ImageHtmlOptions';\nimport type { ImageEditOptions } from './types/ImageEditOptions';\nimport type {\n ContentChangedEvent,\n ContentModelImage,\n EditorPlugin,\n IEditor,\n ImageEditOperation,\n ImageEditor,\n ImageMetadataFormat,\n KeyDownEvent,\n MouseDownEvent,\n MouseUpEvent,\n PluginEvent,\n} from 'roosterjs-content-model-types';\n\nconst DefaultOptions: Partial<ImageEditOptions> = {\n borderColor: '#DB626C',\n minWidth: 10,\n minHeight: 10,\n preserveRatio: true,\n disableRotate: false,\n disableSideResize: false,\n onSelectState: ['resize', 'rotate'],\n};\n\nconst MouseRightButton = 2;\nconst DRAG_ID = '_dragging';\nconst IMAGE_EDIT_CLASS = 'imageEdit';\nconst IMAGE_EDIT_CLASS_CARET = 'imageEditCaretColor';\nconst IMAGE_EDIT_FORMAT_EVENT = 'ImageEditEvent';\n\n/**\n * ImageEdit plugin handles the following image editing features:\n * - Resize image\n * - Crop image\n * - Rotate image\n * - Flip image\n */\nexport class ImageEditPlugin implements ImageEditor, EditorPlugin {\n protected editor: IEditor | null = null;\n private shadowSpan: HTMLSpanElement | null = null;\n private selectedImage: HTMLImageElement | null = null;\n protected wrapper: HTMLSpanElement | null = null;\n protected imageEditInfo: ImageMetadataFormat | null = null;\n private imageHTMLOptions: ImageHtmlOptions | null = null;\n private dndHelpers: DragAndDropHelper<DragAndDropContext, any>[] = [];\n private clonedImage: HTMLImageElement | null = null;\n private lastSrc: string | null = null;\n private wasImageResized: boolean = false;\n private isCropMode: boolean = false;\n private resizers: HTMLDivElement[] = [];\n private rotators: HTMLDivElement[] = [];\n private croppers: HTMLDivElement[] = [];\n private zoomScale: number = 1;\n private disposer: (() => void) | null = null;\n protected isEditing = false;\n\n constructor(protected options: ImageEditOptions = DefaultOptions) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'ImageEdit';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n this.disposer = editor.attachDomEvent({\n blur: {\n beforeDispatch: () => {\n if (this.isEditing && this.editor && !this.editor.isDisposed()) {\n this.applyFormatWithContentModel(\n this.editor,\n this.isCropMode,\n true /* shouldSelectImage */\n );\n }\n },\n },\n dragstart: {\n beforeDispatch: ev => {\n if (this.editor) {\n const target = ev.target as Node;\n if (this.isImageSelection(target)) {\n target.id = target.id + DRAG_ID;\n }\n }\n },\n },\n dragend: {\n beforeDispatch: ev => {\n if (this.editor) {\n const target = ev.target as Node;\n if (this.isImageSelection(target) && target.id.includes(DRAG_ID)) {\n target.id = target.id.replace(DRAG_ID, '').trim();\n }\n }\n },\n },\n });\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n if (this.disposer) {\n this.disposer();\n this.disposer = null;\n }\n this.isEditing = false;\n this.cleanInfo();\n this.editor = null;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (!this.editor) {\n return;\n }\n switch (event.eventType) {\n case 'mouseDown':\n this.mouseDownHandler(this.editor, event);\n break;\n case 'mouseUp':\n this.mouseUpHandler(this.editor, event);\n break;\n case 'keyDown':\n this.keyDownHandler(this.editor, event);\n break;\n case 'contentChanged':\n this.contentChangedHandler(this.editor, event);\n break;\n case 'extractContentWithDom':\n this.removeImageEditing(event.clonedRoot);\n break;\n case 'beforeLogicalRootChange':\n this.handleBeforeLogicalRootChange();\n break;\n }\n }\n\n private handleBeforeLogicalRootChange() {\n if (this.isEditing && this.editor && !this.editor.isDisposed()) {\n this.applyFormatWithContentModel(\n this.editor,\n this.isCropMode,\n false /* shouldSelectImage */\n );\n this.removeImageWrapper();\n this.cleanInfo();\n }\n }\n\n private removeImageEditing(clonedRoot: HTMLElement) {\n const images = clonedRoot.querySelectorAll('img');\n images.forEach(image => {\n if (image.dataset.editingInfo) {\n delete image.dataset.editingInfo;\n }\n });\n }\n\n private isImageSelection(target: Node): target is HTMLElement {\n return (\n isNodeOfType(target, 'ELEMENT_NODE') &&\n (isElementOfType(target, 'img') ||\n !!(\n isElementOfType(target, 'span') &&\n target.firstElementChild &&\n isNodeOfType(target.firstElementChild, 'ELEMENT_NODE') &&\n isElementOfType(target.firstElementChild, 'img')\n ))\n );\n }\n\n private mouseUpHandler(editor: IEditor, event: MouseUpEvent) {\n const selection = editor.getDOMSelection();\n if ((selection && selection.type == 'image') || this.isEditing) {\n const shouldSelectImage =\n this.isImageSelection(event.rawEvent.target as Node) &&\n event.rawEvent.button === MouseRightButton;\n this.applyFormatWithContentModel(editor, this.isCropMode, shouldSelectImage);\n }\n }\n\n private mouseDownHandler(editor: IEditor, event: MouseDownEvent) {\n if (\n this.isEditing &&\n this.isImageSelection(event.rawEvent.target as Node) &&\n event.rawEvent.button !== MouseRightButton &&\n !this.isCropMode\n ) {\n this.applyFormatWithContentModel(\n editor,\n this.isCropMode,\n this.shadowSpan === event.rawEvent.target\n );\n }\n }\n\n private onDropHandler(editor: IEditor) {\n const selection = editor.getDOMSelection();\n if (selection?.type == 'image') {\n editor.formatContentModel(model => {\n const imageDragged = findEditingImage(model, selection.image.id);\n const imageDropped = findEditingImage(\n model,\n selection.image.id.replace(DRAG_ID, '').trim()\n );\n if (imageDragged && imageDropped) {\n const draggedIndex = imageDragged.paragraph.segments.indexOf(\n imageDragged.image\n );\n mutateBlock(imageDragged.paragraph).segments.splice(draggedIndex, 1);\n const segment = imageDropped.image;\n const paragraph = imageDropped.paragraph;\n mutateSegment(paragraph, segment, image => {\n image.isSelected = true;\n image.isSelectedAsImageSelection = true;\n });\n\n return true;\n }\n return false;\n });\n }\n }\n\n private keyDownHandler(editor: IEditor, event: KeyDownEvent) {\n if (this.isEditing) {\n if (\n event.rawEvent.key === 'Escape' ||\n event.rawEvent.key === 'Delete' ||\n event.rawEvent.key === 'Backspace'\n ) {\n if (event.rawEvent.key === 'Escape') {\n this.removeImageWrapper();\n }\n this.cleanInfo();\n } else {\n if (event.rawEvent.key == 'Enter' && this.isCropMode) {\n event.rawEvent.preventDefault();\n }\n this.applyFormatWithContentModel(\n editor,\n this.isCropMode,\n true /** should selectImage */,\n false /* isApiOperation */\n );\n }\n }\n }\n\n private setContentHandler(editor: IEditor) {\n const selection = editor.getDOMSelection();\n if (selection?.type == 'image') {\n this.cleanInfo();\n setImageState(selection.image, '');\n this.isEditing = false;\n this.isCropMode = false;\n }\n }\n\n private formatEventHandler(event: ContentChangedEvent) {\n if (this.isEditing && event.formatApiName !== IMAGE_EDIT_FORMAT_EVENT) {\n this.cleanInfo();\n this.isEditing = false;\n this.isCropMode = false;\n }\n }\n\n private contentChangedHandler(editor: IEditor, event: ContentChangedEvent) {\n switch (event.source) {\n case ChangeSource.SetContent:\n this.setContentHandler(editor);\n break;\n case ChangeSource.Format:\n this.formatEventHandler(event);\n break;\n case ChangeSource.Drop:\n this.onDropHandler(editor);\n break;\n }\n }\n\n /**\n * EXPOSED FOR TESTING PURPOSE ONLY\n */\n protected applyFormatWithContentModel(\n editor: IEditor,\n isCropMode: boolean,\n shouldSelectImage: boolean,\n isApiOperation?: boolean\n ) {\n let editingImageModel: ContentModelImage | undefined;\n const selection = editor.getDOMSelection();\n\n editor.formatContentModel(\n model => {\n const editingImage = getSelectedImage(model);\n const previousSelectedImage = isApiOperation\n ? editingImage\n : findEditingImage(model);\n let result = false;\n\n if (\n shouldSelectImage ||\n previousSelectedImage?.image != editingImage?.image ||\n previousSelectedImage?.image.format.imageState == EDITING_MARKER ||\n isApiOperation\n ) {\n const { lastSrc, selectedImage, imageEditInfo, clonedImage } = this;\n if (\n (this.isEditing || isApiOperation) &&\n previousSelectedImage &&\n lastSrc &&\n selectedImage &&\n imageEditInfo &&\n clonedImage\n ) {\n mutateSegment(\n previousSelectedImage.paragraph,\n previousSelectedImage.image,\n image => {\n applyChange(\n editor,\n selectedImage,\n image,\n imageEditInfo,\n lastSrc,\n this.wasImageResized || this.isCropMode,\n clonedImage\n );\n\n image.isSelected = shouldSelectImage;\n image.isSelectedAsImageSelection = shouldSelectImage;\n image.format.imageState = undefined;\n\n if (selection?.type == 'range' && !selection.range.collapsed) {\n const selectedParagraphs = getSelectedParagraphs(model, true);\n const isImageInRange = selectedParagraphs.some(paragraph =>\n paragraph.segments.includes(image)\n );\n if (isImageInRange) {\n image.isSelected = true;\n }\n }\n }\n );\n\n if (shouldSelectImage) {\n normalizeImageSelection(previousSelectedImage);\n }\n\n this.cleanInfo();\n result = true;\n }\n\n this.isEditing = false;\n this.isCropMode = false;\n\n if (\n editingImage &&\n selection?.type == 'image' &&\n !shouldSelectImage &&\n !isApiOperation\n ) {\n this.isEditing = true;\n this.isCropMode = isCropMode;\n mutateSegment(editingImage.paragraph, editingImage.image, image => {\n editingImageModel = image;\n this.imageEditInfo = updateImageEditInfo(image, selection.image);\n image.format.imageState = 'isEditing';\n });\n\n result = true;\n }\n }\n\n return result;\n },\n {\n onNodeCreated: (model, node) => {\n if (\n !isApiOperation &&\n editingImageModel &&\n editingImageModel == model &&\n editingImageModel.format.imageState == EDITING_MARKER &&\n isNodeOfType(node, 'ELEMENT_NODE') &&\n isElementOfType(node, 'img')\n ) {\n if (isCropMode) {\n this.startCropMode(editor, node);\n } else {\n this.startRotateAndResize(editor, node);\n }\n }\n },\n apiName: IMAGE_EDIT_FORMAT_EVENT,\n },\n {\n tryGetFromCache: true,\n }\n );\n }\n\n private startEditing(\n editor: IEditor,\n image: HTMLImageElement,\n apiOperation: ImageEditOperation[]\n ) {\n if (!this.imageEditInfo) {\n this.imageEditInfo = getSelectedImageMetadata(editor, image);\n }\n this.lastSrc = image.getAttribute('src');\n this.imageHTMLOptions = getHTMLImageOptions(editor, this.options, this.imageEditInfo);\n const {\n resizers,\n rotators,\n wrapper,\n shadowSpan,\n imageClone,\n croppers,\n } = createImageWrapper(\n editor,\n image,\n this.options,\n this.imageEditInfo,\n this.imageHTMLOptions,\n apiOperation\n );\n this.shadowSpan = shadowSpan;\n this.selectedImage = image;\n this.wrapper = wrapper;\n this.clonedImage = imageClone;\n this.wasImageResized = checkIfImageWasResized(image);\n this.resizers = resizers;\n this.rotators = rotators;\n this.croppers = croppers;\n this.zoomScale = editor.getDOMHelper().calculateZoomScale();\n\n editor.setEditorStyle(IMAGE_EDIT_CLASS, `outline-style:none!important;`, [\n `span:has(>img${getSafeIdSelector(this.selectedImage.id)})`,\n ]);\n\n editor.setEditorStyle(IMAGE_EDIT_CLASS_CARET, `caret-color: transparent;`);\n }\n\n public startRotateAndResize(editor: IEditor, image: HTMLImageElement) {\n if (this.imageEditInfo) {\n this.startEditing(editor, image, ['resize', 'rotate']);\n if (this.selectedImage && this.imageEditInfo && this.wrapper && this.clonedImage) {\n const isMobileOrTable = !!editor.getEnvironment().isMobileOrTablet;\n this.dndHelpers = [\n ...getDropAndDragHelpers(\n this.wrapper,\n this.imageEditInfo,\n this.options,\n ImageEditElementClass.ResizeHandle,\n Resizer,\n () => {\n if (\n this.imageEditInfo &&\n this.selectedImage &&\n this.wrapper &&\n this.clonedImage\n ) {\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper,\n this.resizers\n );\n this.wasImageResized = true;\n }\n },\n this.zoomScale,\n isMobileOrTable\n ),\n ...getDropAndDragHelpers(\n this.wrapper,\n this.imageEditInfo,\n this.options,\n ImageEditElementClass.RotateHandle,\n Rotator,\n () => {\n if (\n this.imageEditInfo &&\n this.selectedImage &&\n this.wrapper &&\n this.clonedImage\n ) {\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper\n );\n this.updateRotateHandleState(\n editor,\n this.selectedImage,\n this.wrapper,\n this.rotators,\n this.imageEditInfo?.angleRad\n );\n }\n },\n this.zoomScale,\n isMobileOrTable\n ),\n ];\n\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper,\n this.resizers\n );\n\n this.updateRotateHandleState(\n editor,\n this.selectedImage,\n this.wrapper,\n this.rotators,\n this.imageEditInfo?.angleRad\n );\n }\n }\n }\n\n private updateRotateHandleState(\n editor: IEditor,\n image: HTMLImageElement,\n wrapper: HTMLSpanElement,\n rotators: HTMLDivElement[],\n angleRad: number | undefined\n ) {\n const viewport = editor.getVisibleViewport();\n const smallImage = isASmallImage(image.width, image.height);\n if (viewport && rotators && rotators.length > 0) {\n const rotator = rotators[0];\n const rotatorHandle = rotator.firstElementChild;\n if (\n isNodeOfType(rotatorHandle, 'ELEMENT_NODE') &&\n isElementOfType(rotatorHandle, 'div')\n ) {\n updateRotateHandle(\n viewport,\n angleRad ?? 0,\n wrapper,\n rotator,\n rotatorHandle,\n smallImage\n );\n }\n }\n }\n\n public isOperationAllowed(operation: ImageEditOperation): boolean {\n return (\n operation === 'resize' ||\n operation === 'rotate' ||\n operation === 'flip' ||\n operation === 'crop'\n );\n }\n\n public canRegenerateImage(image: HTMLImageElement): boolean {\n return canRegenerateImage(image);\n }\n\n private startCropMode(editor: IEditor, image: HTMLImageElement) {\n if (this.imageEditInfo) {\n this.startEditing(editor, image, ['crop']);\n if (this.imageEditInfo && this.selectedImage && this.wrapper && this.clonedImage) {\n this.dndHelpers = [\n ...getDropAndDragHelpers(\n this.wrapper,\n this.imageEditInfo,\n this.options,\n ImageEditElementClass.CropHandle,\n Cropper,\n () => {\n if (\n this.imageEditInfo &&\n this.selectedImage &&\n this.wrapper &&\n this.clonedImage\n ) {\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper,\n undefined,\n this.croppers\n );\n this.isCropMode = true;\n }\n },\n this.zoomScale,\n !!editor.getEnvironment().isMobileOrTablet\n ),\n ];\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper,\n undefined,\n this.croppers\n );\n }\n }\n }\n\n public cropImage() {\n if (!this.editor) {\n return;\n }\n if (!this.editor.getEnvironment().isSafari) {\n this.editor.focus(); // Safari will keep the selection when click crop, then the focus() call should not be called\n }\n const selection = this.editor.getDOMSelection();\n if (selection?.type == 'image') {\n this.applyFormatWithContentModel(\n this.editor,\n true /* isCropMode */,\n false /* shouldSelectImage */\n );\n }\n }\n\n private editImage(\n editor: IEditor,\n image: HTMLImageElement,\n apiOperation: ImageEditOperation[],\n operation: (imageEditInfo: ImageMetadataFormat) => void\n ) {\n this.startEditing(editor, image, apiOperation);\n if (!this.selectedImage || !this.imageEditInfo || !this.wrapper || !this.clonedImage) {\n return;\n }\n\n operation(this.imageEditInfo);\n\n updateWrapper(\n this.imageEditInfo,\n this.options,\n this.selectedImage,\n this.clonedImage,\n this.wrapper\n );\n\n this.applyFormatWithContentModel(\n editor,\n false /* isCrop */,\n true /* shouldSelect*/,\n true /* isApiOperation */\n );\n }\n\n /**\n * Exported for testing purpose only\n */\n public cleanInfo() {\n this.editor?.setEditorStyle(IMAGE_EDIT_CLASS, null);\n this.editor?.setEditorStyle(IMAGE_EDIT_CLASS_CARET, null);\n this.selectedImage = null;\n this.shadowSpan = null;\n this.wrapper = null;\n this.imageEditInfo = null;\n this.imageHTMLOptions = null;\n this.dndHelpers.forEach(helper => helper.dispose());\n this.dndHelpers = [];\n this.clonedImage = null;\n this.lastSrc = null;\n this.wasImageResized = false;\n this.isCropMode = false;\n this.resizers = [];\n this.rotators = [];\n this.croppers = [];\n }\n\n private removeImageWrapper() {\n let image: HTMLImageElement | null = null;\n if (this.shadowSpan && this.shadowSpan.parentElement) {\n if (\n this.shadowSpan.firstElementChild &&\n isNodeOfType(this.shadowSpan.firstElementChild, 'ELEMENT_NODE') &&\n isElementOfType(this.shadowSpan.firstElementChild, 'img')\n ) {\n image = this.shadowSpan.firstElementChild;\n }\n unwrap(this.shadowSpan);\n this.shadowSpan = null;\n this.wrapper = null;\n }\n\n return image;\n }\n\n public flipImage(direction: 'horizontal' | 'vertical') {\n const selection = this.editor?.getDOMSelection();\n if (!this.editor || !selection || selection.type !== 'image') {\n return;\n }\n const image = selection.image;\n if (this.editor) {\n this.editImage(this.editor, image, ['flip'], imageEditInfo => {\n const angleRad = imageEditInfo.angleRad || 0;\n const isInVerticalPostion =\n (angleRad >= Math.PI / 2 && angleRad < (3 * Math.PI) / 4) ||\n (angleRad <= -Math.PI / 2 && angleRad > (-3 * Math.PI) / 4);\n if (isInVerticalPostion) {\n if (direction === 'horizontal') {\n imageEditInfo.flippedVertical = !imageEditInfo.flippedVertical;\n } else {\n imageEditInfo.flippedHorizontal = !imageEditInfo.flippedHorizontal;\n }\n } else {\n if (direction === 'vertical') {\n imageEditInfo.flippedVertical = !imageEditInfo.flippedVertical;\n } else {\n imageEditInfo.flippedHorizontal = !imageEditInfo.flippedHorizontal;\n }\n }\n });\n }\n }\n\n public rotateImage(angleRad: number) {\n const selection = this.editor?.getDOMSelection();\n if (!this.editor || !selection || selection.type !== 'image') {\n return;\n }\n const image = selection.image;\n if (this.editor) {\n this.editImage(this.editor, image, [], imageEditInfo => {\n imageEditInfo.angleRad = (imageEditInfo.angleRad || 0) + angleRad;\n });\n }\n }\n}\n"]}
@@ -52,11 +52,7 @@ function processPastedContentFromPowerPoint(event, domCreator) {
52
52
  : undefined,
53
53
  };
54
54
  // Process the Div element as a list item.
55
- (0, customListUtils_1.processAsListItem)(context, element, group, listMetadata, function (listItem) {
56
- var _a;
57
- var currentMarkerSize = listItem.formatHolder.format.fontSize;
58
- var bulletElementSize = (_a = bulletElement.parentElement) === null || _a === void 0 ? void 0 : _a.style.fontSize;
59
- listItem.formatHolder.format.fontSize = bulletElementSize || currentMarkerSize;
55
+ (0, customListUtils_1.processAsListItem)(context, element, group, listMetadata, bulletElement, function (listItem) {
60
56
  if (isNewList_1) {
61
57
  listItem.levels[listItem.levels.length - 1].format.startNumberOverride = parseInt(startNumberOverrideOrBullet_1);
62
58
  }
@@ -1 +1 @@
1
- {"version":3,"file":"processPastedContentFromPowerPoint.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/paste/PowerPoint/processPastedContentFromPowerPoint.ts"],"names":[],"mappings":"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","sourcesContent":["import { addParser } from '../utils/addParser';\nimport { processAsListItem, setupListFormat } from '../utils/customListUtils';\nimport { removeNegativeTextIndentParser } from '../parsers/removeNegativeTextIndentParser';\nimport { setProcessor } from '../utils/setProcessor';\nimport {\n BulletListType,\n getOrderedListNumberStr,\n moveChildNodes,\n NumberingListType,\n} from 'roosterjs-content-model-dom';\nimport type {\n BeforePasteEvent,\n ContentModelListItemLevelFormat,\n DOMCreator,\n} from 'roosterjs-content-model-types';\n\nconst BulletSelector = '* > span > span[style*=mso-special-format]';\nconst MsOfficeSpecialFormat = 'mso-special-format';\nconst CssStyleKey = 'style';\nconst MsoSpecialFormatRegex = /mso-special-format:\\s*([^;]*)/;\n\nconst clearListItemStyles = (format: ContentModelListItemLevelFormat): void => {\n delete format.textAlign;\n delete format.marginLeft;\n delete format.paddingLeft;\n};\n/**\n * @internal\n * Convert pasted content from PowerPoint\n * @param event The BeforePaste event\n */\n\nexport function processPastedContentFromPowerPoint(\n event: BeforePasteEvent,\n domCreator: DOMCreator\n) {\n const { fragment, clipboardData, domToModelOption } = event;\n\n if (clipboardData.html && !clipboardData.text && clipboardData.image) {\n // It is possible that PowerPoint copied both image and HTML but not plain text.\n // We always prefer HTML if any.\n const doc = domCreator.htmlToDOM(clipboardData.html);\n\n moveChildNodes(fragment, doc?.body);\n }\n\n addParser(domToModelOption, 'block', removeNegativeTextIndentParser);\n\n setProcessor(domToModelOption, 'element', (group, element, context) => {\n const style = element.getAttribute(CssStyleKey) || '';\n // If the element is the bullet element, just ignore it, otherwise we will see an extra bullet in the list\n if (style.includes(MsOfficeSpecialFormat) && context.listFormat.levels.length > 0) {\n return;\n }\n const bulletElement = element.querySelector(BulletSelector) as HTMLElement;\n if (bulletElement) {\n const {\n depth,\n unorderedBulletType,\n orderedBulletType,\n startNumberOverrideOrBullet,\n isOrderedList,\n isNewList,\n } = extractPowerPointListInfo(element, bulletElement);\n\n // Setup the listformat with the metadata extracted from the bullet element\n setupListFormat(\n isOrderedList ? 'OL' : 'UL',\n element,\n context,\n depth,\n context.listFormat,\n group,\n [clearListItemStyles]\n );\n\n // Set the metadata for the list item, which will be used to set the correct bullet style type\n const listMetadata = {\n unorderedStyleType:\n !isOrderedList && unorderedBulletType\n ? BulletListType[unorderedBulletType]\n : undefined,\n orderedStyleType:\n isOrderedList && orderedBulletType\n ? NumberingListType[orderedBulletType]\n : undefined,\n };\n\n // Process the Div element as a list item.\n processAsListItem(context, element, group, listMetadata, listItem => {\n const currentMarkerSize = listItem.formatHolder.format.fontSize;\n const bulletElementSize = bulletElement.parentElement?.style.fontSize;\n listItem.formatHolder.format.fontSize = bulletElementSize || currentMarkerSize;\n if (isNewList) {\n listItem.levels[\n listItem.levels.length - 1\n ].format.startNumberOverride = parseInt(startNumberOverrideOrBullet);\n }\n clearListItemStyles(listItem.levels[listItem.levels.length - 1].format);\n clearListItemStyles(listItem.format);\n });\n } else {\n context.defaultElementProcessors.element?.(group, element, context);\n }\n });\n}\n\n/**\n * Extract list information from PowerPoint pasted content\n *\n * The lists from PowerPoint are represent as:\n *\n * - The class 0# represents the depth of the list, if the list is in the first level, the class attribute wont be present.\n * - The mso-special-format style represents the type of bullet and the start of the list.\n * The first part of the mso-special-format is the type of bullet, and the second part is the start of the list.\n * - All the items that are in the same list have the same mso-special-format style. Which we are leveraging to identify when a list is new or part of the existing list thread.\n *\n * @example\n * ` <div class=\"O1\" style=\"...\">\n <span style=\"font-size: 5pt\"\n ><span style=\"mso-special-format: 'numbullet6\\,1'; font-family: +mj-lt\"\n >i.</span\n ></span\n ><span style=\"...;\">123</span>\n </div> `\n *\n * @param element The element to extract list information from\n * @param bulletElement The bullet element to extract list information from\n * @returns The extracted list information\n */\nfunction extractPowerPointListInfo(element: HTMLElement, bulletElement: HTMLElement) {\n const className = element.className.substring(1) || '0';\n const depth = parseInt(className) + 1;\n const style = bulletElement.getAttribute(CssStyleKey) || '';\n const msoSpecialFormat = style.match(MsoSpecialFormatRegex);\n const [bulletTypeHtml, startNumberOverrideOrBullet] =\n msoSpecialFormat?.[1].replace('\"', '').split('\\\\,') || [];\n const isOrderedList = OrderedListStyleMap.has(bulletTypeHtml);\n\n const unorderedBulletType = UnorderedBullets.get(bulletElement.innerText);\n const orderedBulletType = OrderedListStyleMap.get(bulletTypeHtml);\n\n return {\n depth,\n unorderedBulletType,\n orderedBulletType,\n startNumberOverrideOrBullet,\n isOrderedList,\n isNewList:\n isOrderedList &&\n !!orderedBulletType &&\n bulletElement.innerText ===\n getPptListStart(orderedBulletType, startNumberOverrideOrBullet),\n };\n}\n\nconst UnorderedBullets: Map<string, keyof typeof BulletListType> = new Map([\n ['•', 'Disc'],\n ['o', 'Circle'],\n ['§', 'Square'],\n ['q', 'BoxShadow'],\n ['v', 'Xrhombus'],\n ['Ø', 'ShortArrow'],\n ['ü', 'CheckMark'],\n]);\n\nconst OrderedListStyleMap: Map<string, keyof typeof NumberingListType> = new Map([\n ['numbullet1', 'UpperAlpha'],\n ['numbullet2', 'DecimalParenthesis'],\n ['numbullet3', 'Decimal'],\n ['numbullet7', 'UpperRoman'],\n ['numbullet9', 'LowerAlphaParenthesis'],\n ['numbullet0', 'LowerAlpha'],\n ['numbullet6', 'LowerRoman'],\n]);\n\nfunction getPptListStart(\n orderedBulletType: keyof typeof NumberingListType,\n startNumberOverride: string\n) {\n const bullet = getOrderedListNumberStr(\n NumberingListType[orderedBulletType],\n parseInt(startNumberOverride)\n );\n switch (orderedBulletType) {\n case 'Decimal':\n case 'UpperAlpha':\n case 'LowerAlpha':\n case 'UpperRoman':\n case 'LowerRoman':\n return bullet + '.';\n case 'DecimalParenthesis':\n case 'LowerAlphaParenthesis':\n return bullet + ')';\n\n default:\n return undefined;\n }\n}\n"]}
1
+ {"version":3,"file":"processPastedContentFromPowerPoint.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/paste/PowerPoint/processPastedContentFromPowerPoint.ts"],"names":[],"mappings":"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","sourcesContent":["import { addParser } from '../utils/addParser';\nimport { processAsListItem, setupListFormat } from '../utils/customListUtils';\nimport { removeNegativeTextIndentParser } from '../parsers/removeNegativeTextIndentParser';\nimport { setProcessor } from '../utils/setProcessor';\nimport {\n BulletListType,\n getOrderedListNumberStr,\n moveChildNodes,\n NumberingListType,\n} from 'roosterjs-content-model-dom';\nimport type {\n BeforePasteEvent,\n ContentModelListItemLevelFormat,\n DOMCreator,\n} from 'roosterjs-content-model-types';\n\nconst BulletSelector = '* > span > span[style*=mso-special-format]';\nconst MsOfficeSpecialFormat = 'mso-special-format';\nconst CssStyleKey = 'style';\nconst MsoSpecialFormatRegex = /mso-special-format:\\s*([^;]*)/;\n\nconst clearListItemStyles = (format: ContentModelListItemLevelFormat): void => {\n delete format.textAlign;\n delete format.marginLeft;\n delete format.paddingLeft;\n};\n/**\n * @internal\n * Convert pasted content from PowerPoint\n * @param event The BeforePaste event\n */\n\nexport function processPastedContentFromPowerPoint(\n event: BeforePasteEvent,\n domCreator: DOMCreator\n) {\n const { fragment, clipboardData, domToModelOption } = event;\n\n if (clipboardData.html && !clipboardData.text && clipboardData.image) {\n // It is possible that PowerPoint copied both image and HTML but not plain text.\n // We always prefer HTML if any.\n const doc = domCreator.htmlToDOM(clipboardData.html);\n\n moveChildNodes(fragment, doc?.body);\n }\n\n addParser(domToModelOption, 'block', removeNegativeTextIndentParser);\n\n setProcessor(domToModelOption, 'element', (group, element, context) => {\n const style = element.getAttribute(CssStyleKey) || '';\n // If the element is the bullet element, just ignore it, otherwise we will see an extra bullet in the list\n if (style.includes(MsOfficeSpecialFormat) && context.listFormat.levels.length > 0) {\n return;\n }\n const bulletElement = element.querySelector(BulletSelector) as HTMLElement;\n if (bulletElement) {\n const {\n depth,\n unorderedBulletType,\n orderedBulletType,\n startNumberOverrideOrBullet,\n isOrderedList,\n isNewList,\n } = extractPowerPointListInfo(element, bulletElement);\n\n // Setup the listformat with the metadata extracted from the bullet element\n setupListFormat(\n isOrderedList ? 'OL' : 'UL',\n element,\n context,\n depth,\n context.listFormat,\n group,\n [clearListItemStyles]\n );\n\n // Set the metadata for the list item, which will be used to set the correct bullet style type\n const listMetadata = {\n unorderedStyleType:\n !isOrderedList && unorderedBulletType\n ? BulletListType[unorderedBulletType]\n : undefined,\n orderedStyleType:\n isOrderedList && orderedBulletType\n ? NumberingListType[orderedBulletType]\n : undefined,\n };\n\n // Process the Div element as a list item.\n processAsListItem(context, element, group, listMetadata, bulletElement, listItem => {\n if (isNewList) {\n listItem.levels[\n listItem.levels.length - 1\n ].format.startNumberOverride = parseInt(startNumberOverrideOrBullet);\n }\n clearListItemStyles(listItem.levels[listItem.levels.length - 1].format);\n clearListItemStyles(listItem.format);\n });\n } else {\n context.defaultElementProcessors.element?.(group, element, context);\n }\n });\n}\n\n/**\n * Extract list information from PowerPoint pasted content\n *\n * The lists from PowerPoint are represent as:\n *\n * - The class 0# represents the depth of the list, if the list is in the first level, the class attribute wont be present.\n * - The mso-special-format style represents the type of bullet and the start of the list.\n * The first part of the mso-special-format is the type of bullet, and the second part is the start of the list.\n * - All the items that are in the same list have the same mso-special-format style. Which we are leveraging to identify when a list is new or part of the existing list thread.\n *\n * @example\n * ` <div class=\"O1\" style=\"...\">\n <span style=\"font-size: 5pt\"\n ><span style=\"mso-special-format: 'numbullet6\\,1'; font-family: +mj-lt\"\n >i.</span\n ></span\n ><span style=\"...;\">123</span>\n </div> `\n *\n * @param element The element to extract list information from\n * @param bulletElement The bullet element to extract list information from\n * @returns The extracted list information\n */\nfunction extractPowerPointListInfo(element: HTMLElement, bulletElement: HTMLElement) {\n const className = element.className.substring(1) || '0';\n const depth = parseInt(className) + 1;\n const style = bulletElement.getAttribute(CssStyleKey) || '';\n const msoSpecialFormat = style.match(MsoSpecialFormatRegex);\n const [bulletTypeHtml, startNumberOverrideOrBullet] =\n msoSpecialFormat?.[1].replace('\"', '').split('\\\\,') || [];\n const isOrderedList = OrderedListStyleMap.has(bulletTypeHtml);\n\n const unorderedBulletType = UnorderedBullets.get(bulletElement.innerText);\n const orderedBulletType = OrderedListStyleMap.get(bulletTypeHtml);\n\n return {\n depth,\n unorderedBulletType,\n orderedBulletType,\n startNumberOverrideOrBullet,\n isOrderedList,\n isNewList:\n isOrderedList &&\n !!orderedBulletType &&\n bulletElement.innerText ===\n getPptListStart(orderedBulletType, startNumberOverrideOrBullet),\n };\n}\n\nconst UnorderedBullets: Map<string, keyof typeof BulletListType> = new Map([\n ['•', 'Disc'],\n ['o', 'Circle'],\n ['§', 'Square'],\n ['q', 'BoxShadow'],\n ['v', 'Xrhombus'],\n ['Ø', 'ShortArrow'],\n ['ü', 'CheckMark'],\n]);\n\nconst OrderedListStyleMap: Map<string, keyof typeof NumberingListType> = new Map([\n ['numbullet1', 'UpperAlpha'],\n ['numbullet2', 'DecimalParenthesis'],\n ['numbullet3', 'Decimal'],\n ['numbullet7', 'UpperRoman'],\n ['numbullet9', 'LowerAlphaParenthesis'],\n ['numbullet0', 'LowerAlpha'],\n ['numbullet6', 'LowerRoman'],\n]);\n\nfunction getPptListStart(\n orderedBulletType: keyof typeof NumberingListType,\n startNumberOverride: string\n) {\n const bullet = getOrderedListNumberStr(\n NumberingListType[orderedBulletType],\n parseInt(startNumberOverride)\n );\n switch (orderedBulletType) {\n case 'Decimal':\n case 'UpperAlpha':\n case 'LowerAlpha':\n case 'UpperRoman':\n case 'LowerRoman':\n return bullet + '.';\n case 'DecimalParenthesis':\n case 'LowerAlphaParenthesis':\n return bullet + ')';\n\n default:\n return undefined;\n }\n}\n"]}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.processWordList = void 0;
4
4
  var tslib_1 = require("tslib");
5
+ var getStyles_1 = require("../utils/getStyles");
5
6
  var customListUtils_1 = require("../utils/customListUtils");
6
7
  var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
7
8
  /** Word list metadata style name */
@@ -59,7 +60,7 @@ function processWordList(styles, group, element, context, metadata) {
59
60
  orderedStyleType: listType_1 == 'OL' ? bullet : undefined,
60
61
  }
61
62
  : undefined;
62
- (0, customListUtils_1.processAsListItem)(context, element, group, listFormatMetadata, function (listItem) {
63
+ (0, customListUtils_1.processAsListItem)(context, element, group, listFormatMetadata, getBulletElement(element), function (listItem) {
63
64
  if (listType_1 == 'OL') {
64
65
  setStartNumber(listItem, context, listMetadata_1, element);
65
66
  }
@@ -162,4 +163,43 @@ function wordListPaddingParser(format, element) {
162
163
  format.paddingRight = '0px';
163
164
  }
164
165
  }
166
+ /**
167
+ * Get the bullet element from word list item.
168
+ * The first element of the list contains the bullet element, which contains the mso-list:ignore style.
169
+ * @example
170
+ * <p class=MsoListParagraphCxSpFirst style='text-indent:-18.0pt;mso-list:l0 level1 lfo1'>
171
+ * <![if !supportLists]>
172
+ * <span lang=EN-US style='mso-fareast-font-family:Aptos;mso-fareast-theme-font:minor-latin; mso-bidi-font-family:Aptos;mso-bidi-theme-font:minor-latin;color:#C00000; mso-ansi-language:EN-US'>
173
+ * <span style='mso-list:Ignore'> <-- This is the bullet element
174
+ * 1.
175
+ * <span style='font:7.0pt "Times New Roman"'>
176
+ * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
177
+ * </span>
178
+ * </span>
179
+ * </span>
180
+ * <![endif]>
181
+ * <span lang=EN-US style='color:#C00000; mso-ansi-language:EN-US'>
182
+ * Content in list<o:p></o:p>
183
+ * </span>
184
+ * </p>
185
+ * @returns
186
+ */
187
+ function getBulletElement(element) {
188
+ var firstChild = element.firstElementChild;
189
+ var isBulletElement = false;
190
+ if (firstChild) {
191
+ for (var i = 0; i < firstChild.childNodes.length; i++) {
192
+ var child = firstChild.childNodes[i];
193
+ if ((0, roosterjs_content_model_dom_1.isNodeOfType)(child, 'ELEMENT_NODE')) {
194
+ var styles = (0, getStyles_1.getStyles)(child);
195
+ var wordListStyle = styles[MSO_LIST] || '';
196
+ if (wordListStyle.toLowerCase() === MSO_LIST_IGNORE) {
197
+ isBulletElement = true;
198
+ break;
199
+ }
200
+ }
201
+ }
202
+ }
203
+ return firstChild && isBulletElement ? firstChild : undefined;
204
+ }
165
205
  //# sourceMappingURL=processWordLists.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"processWordLists.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processWordLists.ts"],"names":[],"mappings":"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","sourcesContent":["import { processAsListItem, setupListFormat } from '../utils/customListUtils';\nimport {\n getListStyleTypeFromString,\n isElementOfType,\n isEmpty,\n isNodeOfType,\n} from 'roosterjs-content-model-dom';\nimport type { WordMetadata } from './WordMetadata';\nimport type {\n ContentModelBlockGroup,\n ContentModelListItem,\n ContentModelListItemFormat,\n ContentModelListItemLevelFormat,\n ContentModelListLevel,\n DomToModelContext,\n DomToModelListFormat,\n} from 'roosterjs-content-model-types';\n\n/** Word list metadata style name */\nconst MSO_LIST = 'mso-list';\nconst MSO_LIST_IGNORE = 'ignore';\nconst WORD_FIRST_LIST = 'l0';\nconst TEMPLATE_VALUE_REGEX = /%[0-9a-zA-Z]+/g;\n\ninterface WordDesktopListFormat extends DomToModelListFormat {\n wordLevel?: number | '';\n wordList?: string;\n wordKnownLevels?: Map<string, ContentModelListLevel[]>;\n}\n\ninterface WordListFormat extends ContentModelListItemFormat {\n wordList?: string;\n}\n\nconst BULLET_METADATA = 'bullet';\n/**\n * @internal\n * @param styles\n * @param group\n * @param element\n * @param context\n * @returns\n */\nexport function processWordList(\n styles: Record<string, string>,\n group: ContentModelBlockGroup,\n element: HTMLElement,\n context: DomToModelContext,\n metadata: Map<string, WordMetadata>\n) {\n const listFormat = context.listFormat as WordDesktopListFormat;\n if (!listFormat.wordKnownLevels) {\n listFormat.wordKnownLevels = new Map<string, ContentModelListLevel[]>();\n }\n const wordListStyle = styles[MSO_LIST] || '';\n\n // If the element contains Ignore style, do not process it,\n // Usually this element contains the fake bullet used in Word Desktop.\n if (wordListStyle.toLowerCase() === MSO_LIST_IGNORE) {\n return true;\n }\n\n const [lNumber, level] = wordListStyle.split(' ');\n // Try get the list metadata from word, which follows this format: l1 level1 lfo2\n // If we are able to get the level property means we can process this element to be a list\n listFormat.wordLevel = level && parseInt(level.substr('level'.length));\n listFormat.wordList = lNumber || WORD_FIRST_LIST;\n\n if (listFormat.levels.length == 0) {\n listFormat.levels =\n (listFormat.wordList && listFormat.wordKnownLevels.get(listFormat.wordList)) || [];\n }\n\n if (wordListStyle && group && typeof listFormat.wordLevel === 'number') {\n const { wordLevel, wordList } = listFormat;\n // Retrieve the Fake bullet on the element and also the list type\n const listMetadata = metadata.get(`${lNumber}:${level}`);\n const listType =\n listMetadata?.['mso-level-number-format']?.toLowerCase() != BULLET_METADATA\n ? 'OL'\n : 'UL';\n\n // Create the new level of the list item and parse the format\n setupListFormat(listType, element, context, wordLevel, listFormat, group, [\n wordListPaddingParser,\n ]);\n (listFormat.levels[listFormat.levels.length - 1]\n .format as WordListFormat).wordList = wordList;\n\n const bullet = getBulletFromMetadata(listMetadata, listType);\n const listFormatMetadata = bullet\n ? {\n unorderedStyleType: listType == 'UL' ? bullet : undefined,\n orderedStyleType: listType == 'OL' ? bullet : undefined,\n }\n : undefined;\n\n processAsListItem(context, element, group, listFormatMetadata, listItem => {\n if (listType == 'OL') {\n setStartNumber(listItem, context, listMetadata, element);\n }\n });\n\n if (\n listFormat.levels.length > 0 &&\n listFormat.wordKnownLevels.get(wordList) != listFormat.levels\n ) {\n listFormat.wordKnownLevels.set(wordList, [...listFormat.levels]);\n }\n return true;\n }\n\n return false;\n}\n\nfunction getBulletFromMetadata(listMetadata: WordMetadata | undefined, listType: 'OL' | 'UL') {\n const templateType = listMetadata?.['mso-level-number-format'] || 'decimal';\n let templateFinal: string;\n\n if (listMetadata?.['mso-level-text']) {\n let templateValue: string = '';\n switch (templateType) {\n case 'alpha-upper':\n templateValue = 'UpperAlpha';\n break;\n case 'alpha-lower':\n templateValue = 'LowerAlpha';\n break;\n case 'roman-lower':\n templateValue = 'LowerRoman';\n break;\n case 'roman-upper':\n templateValue = 'UpperRoman';\n break;\n default:\n templateValue = 'Number';\n break;\n }\n const template = (listMetadata['mso-level-text'] || '')\n .replace('\\\\', '')\n .replace('\"', '')\n .replace(TEMPLATE_VALUE_REGEX, '${' + templateValue + '}');\n\n templateFinal = '\"' + template + ' \"';\n } else {\n switch (templateType) {\n case 'alpha-lower':\n templateFinal = 'lower-alpha';\n break;\n case 'roman-lower':\n templateFinal = 'lower-roman';\n break;\n case 'roman-upper':\n templateFinal = 'upper-roman';\n break;\n default:\n templateFinal = 'decimal';\n break;\n }\n }\n\n return getListStyleTypeFromString(listType, templateFinal);\n}\n\nfunction setStartNumber(\n listItem: ContentModelListItem,\n context: DomToModelContext,\n listMetadata: WordMetadata | undefined,\n element: HTMLElement\n) {\n const {\n listParent,\n wordList,\n wordKnownLevels,\n wordLevel,\n levels,\n } = context.listFormat as WordDesktopListFormat;\n\n const block = getLastNotEmptyBlock(listParent);\n if (\n (block?.blockType != 'BlockGroup' ||\n block.blockGroupType != 'ListItem' ||\n (wordLevel &&\n (block.levels[wordLevel]?.format as WordListFormat)?.wordList != wordList)) &&\n wordList\n ) {\n const start = listMetadata?.['mso-level-start-at']\n ? parseInt(listMetadata['mso-level-start-at'])\n : NaN;\n const knownLevel = wordKnownLevels?.get(wordList) || [];\n\n if (start != undefined && !isNaN(start) && knownLevel.length != levels.length) {\n listItem.levels[listItem.levels.length - 1].format.startNumberOverride = start;\n } else if (\n isElementOfType(element, 'li') &&\n isNodeOfType(element.parentElement, 'ELEMENT_NODE') &&\n isElementOfType(element.parentElement, 'ol') &&\n element.parentElement.firstElementChild == element &&\n knownLevel.length != element.parentElement.start\n ) {\n listItem.levels[listItem.levels.length - 1].format.startNumberOverride =\n element.parentElement.start;\n }\n }\n}\n\nfunction getLastNotEmptyBlock(listParent: ContentModelBlockGroup | undefined) {\n for (let index = (listParent?.blocks.length || 0) - 1; index > 0; index--) {\n const result = listParent?.blocks[index];\n if (result && !isEmpty(result)) {\n return result;\n }\n }\n\n return undefined;\n}\n\nfunction wordListPaddingParser(\n format: ContentModelListItemLevelFormat,\n element: HTMLElement\n): void {\n if (element.style.marginLeft && element.style.marginLeft != '0in') {\n format.paddingLeft = '0px';\n }\n if (element.style.marginRight && element.style.marginRight != '0in') {\n format.paddingRight = '0px';\n }\n}\n"]}
1
+ {"version":3,"file":"processWordLists.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processWordLists.ts"],"names":[],"mappings":"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","sourcesContent":["import { getStyles } from '../utils/getStyles';\nimport { processAsListItem, setupListFormat } from '../utils/customListUtils';\nimport {\n getListStyleTypeFromString,\n isElementOfType,\n isEmpty,\n isNodeOfType,\n} from 'roosterjs-content-model-dom';\nimport type { WordMetadata } from './WordMetadata';\nimport type {\n ContentModelBlockGroup,\n ContentModelListItem,\n ContentModelListItemFormat,\n ContentModelListItemLevelFormat,\n ContentModelListLevel,\n DomToModelContext,\n DomToModelListFormat,\n} from 'roosterjs-content-model-types';\n\n/** Word list metadata style name */\nconst MSO_LIST = 'mso-list';\nconst MSO_LIST_IGNORE = 'ignore';\nconst WORD_FIRST_LIST = 'l0';\nconst TEMPLATE_VALUE_REGEX = /%[0-9a-zA-Z]+/g;\nconst BULLET_METADATA = 'bullet';\n\ninterface WordDesktopListFormat extends DomToModelListFormat {\n wordLevel?: number | '';\n wordList?: string;\n wordKnownLevels?: Map<string, ContentModelListLevel[]>;\n}\n\ninterface WordListFormat extends ContentModelListItemFormat {\n wordList?: string;\n}\n\n/**\n * @internal\n * @param styles\n * @param group\n * @param element\n * @param context\n * @returns\n */\nexport function processWordList(\n styles: Record<string, string>,\n group: ContentModelBlockGroup,\n element: HTMLElement,\n context: DomToModelContext,\n metadata: Map<string, WordMetadata>\n) {\n const listFormat = context.listFormat as WordDesktopListFormat;\n if (!listFormat.wordKnownLevels) {\n listFormat.wordKnownLevels = new Map<string, ContentModelListLevel[]>();\n }\n const wordListStyle = styles[MSO_LIST] || '';\n\n // If the element contains Ignore style, do not process it,\n // Usually this element contains the fake bullet used in Word Desktop.\n if (wordListStyle.toLowerCase() === MSO_LIST_IGNORE) {\n return true;\n }\n\n const [lNumber, level] = wordListStyle.split(' ');\n // Try get the list metadata from word, which follows this format: l1 level1 lfo2\n // If we are able to get the level property means we can process this element to be a list\n listFormat.wordLevel = level && parseInt(level.substr('level'.length));\n listFormat.wordList = lNumber || WORD_FIRST_LIST;\n\n if (listFormat.levels.length == 0) {\n listFormat.levels =\n (listFormat.wordList && listFormat.wordKnownLevels.get(listFormat.wordList)) || [];\n }\n\n if (wordListStyle && group && typeof listFormat.wordLevel === 'number') {\n const { wordLevel, wordList } = listFormat;\n // Retrieve the Fake bullet on the element and also the list type\n const listMetadata = metadata.get(`${lNumber}:${level}`);\n const listType =\n listMetadata?.['mso-level-number-format']?.toLowerCase() != BULLET_METADATA\n ? 'OL'\n : 'UL';\n\n // Create the new level of the list item and parse the format\n setupListFormat(listType, element, context, wordLevel, listFormat, group, [\n wordListPaddingParser,\n ]);\n (listFormat.levels[listFormat.levels.length - 1]\n .format as WordListFormat).wordList = wordList;\n\n const bullet = getBulletFromMetadata(listMetadata, listType);\n const listFormatMetadata = bullet\n ? {\n unorderedStyleType: listType == 'UL' ? bullet : undefined,\n orderedStyleType: listType == 'OL' ? bullet : undefined,\n }\n : undefined;\n\n processAsListItem(\n context,\n element,\n group,\n listFormatMetadata,\n getBulletElement(element),\n listItem => {\n if (listType == 'OL') {\n setStartNumber(listItem, context, listMetadata, element);\n }\n }\n );\n\n if (\n listFormat.levels.length > 0 &&\n listFormat.wordKnownLevels.get(wordList) != listFormat.levels\n ) {\n listFormat.wordKnownLevels.set(wordList, [...listFormat.levels]);\n }\n return true;\n }\n\n return false;\n}\n\nfunction getBulletFromMetadata(listMetadata: WordMetadata | undefined, listType: 'OL' | 'UL') {\n const templateType = listMetadata?.['mso-level-number-format'] || 'decimal';\n let templateFinal: string;\n\n if (listMetadata?.['mso-level-text']) {\n let templateValue: string = '';\n switch (templateType) {\n case 'alpha-upper':\n templateValue = 'UpperAlpha';\n break;\n case 'alpha-lower':\n templateValue = 'LowerAlpha';\n break;\n case 'roman-lower':\n templateValue = 'LowerRoman';\n break;\n case 'roman-upper':\n templateValue = 'UpperRoman';\n break;\n default:\n templateValue = 'Number';\n break;\n }\n const template = (listMetadata['mso-level-text'] || '')\n .replace('\\\\', '')\n .replace('\"', '')\n .replace(TEMPLATE_VALUE_REGEX, '${' + templateValue + '}');\n\n templateFinal = '\"' + template + ' \"';\n } else {\n switch (templateType) {\n case 'alpha-lower':\n templateFinal = 'lower-alpha';\n break;\n case 'roman-lower':\n templateFinal = 'lower-roman';\n break;\n case 'roman-upper':\n templateFinal = 'upper-roman';\n break;\n default:\n templateFinal = 'decimal';\n break;\n }\n }\n\n return getListStyleTypeFromString(listType, templateFinal);\n}\n\nfunction setStartNumber(\n listItem: ContentModelListItem,\n context: DomToModelContext,\n listMetadata: WordMetadata | undefined,\n element: HTMLElement\n) {\n const {\n listParent,\n wordList,\n wordKnownLevels,\n wordLevel,\n levels,\n } = context.listFormat as WordDesktopListFormat;\n\n const block = getLastNotEmptyBlock(listParent);\n if (\n (block?.blockType != 'BlockGroup' ||\n block.blockGroupType != 'ListItem' ||\n (wordLevel &&\n (block.levels[wordLevel]?.format as WordListFormat)?.wordList != wordList)) &&\n wordList\n ) {\n const start = listMetadata?.['mso-level-start-at']\n ? parseInt(listMetadata['mso-level-start-at'])\n : NaN;\n const knownLevel = wordKnownLevels?.get(wordList) || [];\n\n if (start != undefined && !isNaN(start) && knownLevel.length != levels.length) {\n listItem.levels[listItem.levels.length - 1].format.startNumberOverride = start;\n } else if (\n isElementOfType(element, 'li') &&\n isNodeOfType(element.parentElement, 'ELEMENT_NODE') &&\n isElementOfType(element.parentElement, 'ol') &&\n element.parentElement.firstElementChild == element &&\n knownLevel.length != element.parentElement.start\n ) {\n listItem.levels[listItem.levels.length - 1].format.startNumberOverride =\n element.parentElement.start;\n }\n }\n}\n\nfunction getLastNotEmptyBlock(listParent: ContentModelBlockGroup | undefined) {\n for (let index = (listParent?.blocks.length || 0) - 1; index > 0; index--) {\n const result = listParent?.blocks[index];\n if (result && !isEmpty(result)) {\n return result;\n }\n }\n\n return undefined;\n}\n\nfunction wordListPaddingParser(\n format: ContentModelListItemLevelFormat,\n element: HTMLElement\n): void {\n if (element.style.marginLeft && element.style.marginLeft != '0in') {\n format.paddingLeft = '0px';\n }\n if (element.style.marginRight && element.style.marginRight != '0in') {\n format.paddingRight = '0px';\n }\n}\n/**\n * Get the bullet element from word list item.\n * The first element of the list contains the bullet element, which contains the mso-list:ignore style.\n * @example\n * <p class=MsoListParagraphCxSpFirst style='text-indent:-18.0pt;mso-list:l0 level1 lfo1'>\n * <![if !supportLists]>\n * <span lang=EN-US style='mso-fareast-font-family:Aptos;mso-fareast-theme-font:minor-latin; mso-bidi-font-family:Aptos;mso-bidi-theme-font:minor-latin;color:#C00000; mso-ansi-language:EN-US'>\n * <span style='mso-list:Ignore'> <-- This is the bullet element\n * 1.\n * <span style='font:7.0pt \"Times New Roman\"'>\n * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n * </span>\n * </span>\n * </span>\n * <![endif]>\n * <span lang=EN-US style='color:#C00000; mso-ansi-language:EN-US'>\n * Content in list<o:p></o:p>\n * </span>\n * </p>\n * @returns\n */\nfunction getBulletElement(element: HTMLElement): HTMLElement | undefined {\n const firstChild = element.firstElementChild;\n let isBulletElement = false;\n\n if (firstChild) {\n for (let i = 0; i < firstChild.childNodes.length; i++) {\n const child = firstChild.childNodes[i];\n if (isNodeOfType(child, 'ELEMENT_NODE')) {\n const styles = getStyles(child);\n const wordListStyle = styles[MSO_LIST] || '';\n\n if (wordListStyle.toLowerCase() === MSO_LIST_IGNORE) {\n isBulletElement = true;\n break;\n }\n }\n }\n }\n\n return firstChild && isBulletElement ? (firstChild as HTMLElement) : undefined;\n}\n"]}
@@ -6,4 +6,4 @@ export declare function setupListFormat(listType: 'OL' | 'UL', element: HTMLElem
6
6
  /**
7
7
  * @internal
8
8
  */
9
- export declare function processAsListItem(context: DomToModelContext, element: HTMLElement, group: ContentModelBlockGroup, listFormatMetadata: ListMetadataFormat | undefined, beforeProcessingChildren?: (listItem: ContentModelListItem) => void): void;
9
+ export declare function processAsListItem(context: DomToModelContext, element: HTMLElement, group: ContentModelBlockGroup, listFormatMetadata: ListMetadataFormat | undefined, bulletElement: HTMLElement | undefined, beforeProcessingChildren?: (listItem: ContentModelListItem) => void): void;