roosterjs-content-model-plugins 9.26.0 → 9.27.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 (139) hide show
  1. package/lib/autoFormat/AutoFormatPlugin.d.ts +4 -1
  2. package/lib/autoFormat/AutoFormatPlugin.js +94 -96
  3. package/lib/autoFormat/AutoFormatPlugin.js.map +1 -1
  4. package/lib/autoFormat/horizontalLine/checkAndInsertHorizontalLine.d.ts +3 -3
  5. package/lib/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js +14 -21
  6. package/lib/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js.map +1 -1
  7. package/lib/edit/EditPlugin.d.ts +9 -0
  8. package/lib/edit/EditPlugin.js +19 -3
  9. package/lib/edit/EditPlugin.js.map +1 -1
  10. package/lib/edit/utils/splitParagraph.d.ts +3 -2
  11. package/lib/edit/utils/splitParagraph.js +41 -2
  12. package/lib/edit/utils/splitParagraph.js.map +1 -1
  13. package/lib/imageEdit/ImageEditPlugin.js +9 -9
  14. package/lib/imageEdit/ImageEditPlugin.js.map +1 -1
  15. package/lib/imageEdit/utils/findEditingImage.d.ts +4 -0
  16. package/lib/imageEdit/utils/findEditingImage.js +7 -2
  17. package/lib/imageEdit/utils/findEditingImage.js.map +1 -1
  18. package/lib/paste/PastePlugin.js +3 -3
  19. package/lib/paste/PastePlugin.js.map +1 -1
  20. package/lib/paste/PowerPoint/processPastedContentFromPowerPoint.js +132 -1
  21. package/lib/paste/PowerPoint/processPastedContentFromPowerPoint.js.map +1 -1
  22. package/lib/paste/WordDesktop/getStyleMetadata.d.ts +2 -2
  23. package/lib/paste/WordDesktop/getStyleMetadata.js +22 -5
  24. package/lib/paste/WordDesktop/getStyleMetadata.js.map +1 -1
  25. package/lib/paste/WordDesktop/processPastedContentFromWordDesktop.d.ts +2 -2
  26. package/lib/paste/WordDesktop/processPastedContentFromWordDesktop.js +5 -5
  27. package/lib/paste/WordDesktop/processPastedContentFromWordDesktop.js.map +1 -1
  28. package/lib/paste/WordDesktop/processWordLists.js +25 -60
  29. package/lib/paste/WordDesktop/processWordLists.js.map +1 -1
  30. package/lib/paste/parsers/deprecatedColorParser.js.map +1 -0
  31. package/lib/paste/parsers/linkParser.js.map +1 -0
  32. package/lib/paste/{WordDesktop → parsers}/removeNegativeTextIndentParser.js +1 -1
  33. package/lib/paste/parsers/removeNegativeTextIndentParser.js.map +1 -0
  34. package/lib/paste/utils/customListUtils.d.ts +9 -0
  35. package/lib/paste/utils/customListUtils.js +63 -0
  36. package/lib/paste/utils/customListUtils.js.map +1 -0
  37. package/lib/watermark/WatermarkPlugin.js +1 -1
  38. package/lib/watermark/WatermarkPlugin.js.map +1 -1
  39. package/lib-amd/autoFormat/AutoFormatPlugin.d.ts +4 -1
  40. package/lib-amd/autoFormat/AutoFormatPlugin.js +94 -96
  41. package/lib-amd/autoFormat/AutoFormatPlugin.js.map +1 -1
  42. package/lib-amd/autoFormat/horizontalLine/checkAndInsertHorizontalLine.d.ts +3 -3
  43. package/lib-amd/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js +15 -21
  44. package/lib-amd/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js.map +1 -1
  45. package/lib-amd/edit/EditPlugin.d.ts +9 -0
  46. package/lib-amd/edit/EditPlugin.js +19 -3
  47. package/lib-amd/edit/EditPlugin.js.map +1 -1
  48. package/lib-amd/edit/utils/splitParagraph.d.ts +3 -2
  49. package/lib-amd/edit/utils/splitParagraph.js +41 -2
  50. package/lib-amd/edit/utils/splitParagraph.js.map +1 -1
  51. package/lib-amd/imageEdit/ImageEditPlugin.js +9 -9
  52. package/lib-amd/imageEdit/ImageEditPlugin.js.map +1 -1
  53. package/lib-amd/imageEdit/utils/findEditingImage.d.ts +4 -0
  54. package/lib-amd/imageEdit/utils/findEditingImage.js +7 -2
  55. package/lib-amd/imageEdit/utils/findEditingImage.js.map +1 -1
  56. package/lib-amd/paste/PastePlugin.js +2 -2
  57. package/lib-amd/paste/PastePlugin.js.map +1 -1
  58. package/lib-amd/paste/PowerPoint/processPastedContentFromPowerPoint.js +128 -2
  59. package/lib-amd/paste/PowerPoint/processPastedContentFromPowerPoint.js.map +1 -1
  60. package/lib-amd/paste/WordDesktop/getStyleMetadata.d.ts +2 -2
  61. package/lib-amd/paste/WordDesktop/getStyleMetadata.js +22 -5
  62. package/lib-amd/paste/WordDesktop/getStyleMetadata.js.map +1 -1
  63. package/lib-amd/paste/WordDesktop/processPastedContentFromWordDesktop.d.ts +2 -2
  64. package/lib-amd/paste/WordDesktop/processPastedContentFromWordDesktop.js +5 -5
  65. package/lib-amd/paste/WordDesktop/processPastedContentFromWordDesktop.js.map +1 -1
  66. package/lib-amd/paste/WordDesktop/processWordLists.js +25 -60
  67. package/lib-amd/paste/WordDesktop/processWordLists.js.map +1 -1
  68. package/lib-amd/paste/parsers/deprecatedColorParser.js.map +1 -0
  69. package/lib-amd/paste/parsers/linkParser.js.map +1 -0
  70. package/lib-amd/paste/{WordDesktop → parsers}/removeNegativeTextIndentParser.js +1 -1
  71. package/lib-amd/paste/parsers/removeNegativeTextIndentParser.js.map +1 -0
  72. package/lib-amd/paste/utils/customListUtils.d.ts +9 -0
  73. package/lib-amd/paste/utils/customListUtils.js +63 -0
  74. package/lib-amd/paste/utils/customListUtils.js.map +1 -0
  75. package/lib-amd/watermark/WatermarkPlugin.js +1 -1
  76. package/lib-amd/watermark/WatermarkPlugin.js.map +1 -1
  77. package/lib-mjs/autoFormat/AutoFormatPlugin.d.ts +4 -1
  78. package/lib-mjs/autoFormat/AutoFormatPlugin.js +95 -97
  79. package/lib-mjs/autoFormat/AutoFormatPlugin.js.map +1 -1
  80. package/lib-mjs/autoFormat/horizontalLine/checkAndInsertHorizontalLine.d.ts +3 -3
  81. package/lib-mjs/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js +15 -22
  82. package/lib-mjs/autoFormat/horizontalLine/checkAndInsertHorizontalLine.js.map +1 -1
  83. package/lib-mjs/edit/EditPlugin.d.ts +9 -0
  84. package/lib-mjs/edit/EditPlugin.js +19 -3
  85. package/lib-mjs/edit/EditPlugin.js.map +1 -1
  86. package/lib-mjs/edit/utils/splitParagraph.d.ts +3 -2
  87. package/lib-mjs/edit/utils/splitParagraph.js +42 -3
  88. package/lib-mjs/edit/utils/splitParagraph.js.map +1 -1
  89. package/lib-mjs/imageEdit/ImageEditPlugin.js +11 -11
  90. package/lib-mjs/imageEdit/ImageEditPlugin.js.map +1 -1
  91. package/lib-mjs/imageEdit/utils/findEditingImage.d.ts +4 -0
  92. package/lib-mjs/imageEdit/utils/findEditingImage.js +6 -1
  93. package/lib-mjs/imageEdit/utils/findEditingImage.js.map +1 -1
  94. package/lib-mjs/paste/PastePlugin.js +3 -3
  95. package/lib-mjs/paste/PastePlugin.js.map +1 -1
  96. package/lib-mjs/paste/PowerPoint/processPastedContentFromPowerPoint.js +133 -2
  97. package/lib-mjs/paste/PowerPoint/processPastedContentFromPowerPoint.js.map +1 -1
  98. package/lib-mjs/paste/WordDesktop/getStyleMetadata.d.ts +2 -2
  99. package/lib-mjs/paste/WordDesktop/getStyleMetadata.js +22 -5
  100. package/lib-mjs/paste/WordDesktop/getStyleMetadata.js.map +1 -1
  101. package/lib-mjs/paste/WordDesktop/processPastedContentFromWordDesktop.d.ts +2 -2
  102. package/lib-mjs/paste/WordDesktop/processPastedContentFromWordDesktop.js +5 -5
  103. package/lib-mjs/paste/WordDesktop/processPastedContentFromWordDesktop.js.map +1 -1
  104. package/lib-mjs/paste/WordDesktop/processWordLists.js +26 -61
  105. package/lib-mjs/paste/WordDesktop/processWordLists.js.map +1 -1
  106. package/lib-mjs/paste/parsers/deprecatedColorParser.js.map +1 -0
  107. package/lib-mjs/paste/parsers/linkParser.js.map +1 -0
  108. package/lib-mjs/paste/{WordDesktop → parsers}/removeNegativeTextIndentParser.js +1 -1
  109. package/lib-mjs/paste/parsers/removeNegativeTextIndentParser.js.map +1 -0
  110. package/lib-mjs/paste/utils/customListUtils.d.ts +9 -0
  111. package/lib-mjs/paste/utils/customListUtils.js +58 -0
  112. package/lib-mjs/paste/utils/customListUtils.js.map +1 -0
  113. package/lib-mjs/watermark/WatermarkPlugin.js +1 -1
  114. package/lib-mjs/watermark/WatermarkPlugin.js.map +1 -1
  115. package/package.json +5 -5
  116. package/lib/paste/WordDesktop/removeNegativeTextIndentParser.js.map +0 -1
  117. package/lib/paste/utils/deprecatedColorParser.js.map +0 -1
  118. package/lib/paste/utils/linkParser.js.map +0 -1
  119. package/lib-amd/paste/WordDesktop/removeNegativeTextIndentParser.js.map +0 -1
  120. package/lib-amd/paste/utils/deprecatedColorParser.js.map +0 -1
  121. package/lib-amd/paste/utils/linkParser.js.map +0 -1
  122. package/lib-mjs/paste/WordDesktop/removeNegativeTextIndentParser.js.map +0 -1
  123. package/lib-mjs/paste/utils/deprecatedColorParser.js.map +0 -1
  124. package/lib-mjs/paste/utils/linkParser.js.map +0 -1
  125. /package/lib/paste/{utils → parsers}/deprecatedColorParser.d.ts +0 -0
  126. /package/lib/paste/{utils → parsers}/deprecatedColorParser.js +0 -0
  127. /package/lib/paste/{utils → parsers}/linkParser.d.ts +0 -0
  128. /package/lib/paste/{utils → parsers}/linkParser.js +0 -0
  129. /package/lib/paste/{WordDesktop → parsers}/removeNegativeTextIndentParser.d.ts +0 -0
  130. /package/lib-amd/paste/{utils → parsers}/deprecatedColorParser.d.ts +0 -0
  131. /package/lib-amd/paste/{utils → parsers}/deprecatedColorParser.js +0 -0
  132. /package/lib-amd/paste/{utils → parsers}/linkParser.d.ts +0 -0
  133. /package/lib-amd/paste/{utils → parsers}/linkParser.js +0 -0
  134. /package/lib-amd/paste/{WordDesktop → parsers}/removeNegativeTextIndentParser.d.ts +0 -0
  135. /package/lib-mjs/paste/{utils → parsers}/deprecatedColorParser.d.ts +0 -0
  136. /package/lib-mjs/paste/{utils → parsers}/deprecatedColorParser.js +0 -0
  137. /package/lib-mjs/paste/{utils → parsers}/linkParser.d.ts +0 -0
  138. /package/lib-mjs/paste/{utils → parsers}/linkParser.js +0 -0
  139. /package/lib-mjs/paste/{WordDesktop → parsers}/removeNegativeTextIndentParser.d.ts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"PastePlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/paste/PastePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { addParser } from './utils/addParser';\nimport { BorderKeys, getObjectKeys } from 'roosterjs-content-model-dom';\nimport { chainSanitizerCallback } from './utils/chainSanitizerCallback';\nimport { DefaultSanitizers } from './DefaultSanitizers';\nimport { deprecatedBorderColorParser } from './utils/deprecatedColorParser';\nimport { getPasteSource } from './pasteSourceValidations/getPasteSource';\nimport { parseLink } from './utils/linkParser';\nimport { PastePropertyNames } from './pasteSourceValidations/constants';\nimport { processPastedContentFromExcel } from './Excel/processPastedContentFromExcel';\nimport { processPastedContentFromOneNote } from './oneNote/processPastedContentFromOneNote';\nimport { processPastedContentFromPowerPoint } from './PowerPoint/processPastedContentFromPowerPoint';\nimport { processPastedContentFromWordDesktop } from './WordDesktop/processPastedContentFromWordDesktop';\nimport { processPastedContentWacComponents } from './WacComponents/processPastedContentWacComponents';\nimport type {\n BeforePasteEvent,\n BorderFormat,\n ContentModelBlockFormat,\n ContentModelTableCellFormat,\n DomToModelOptionForSanitizing,\n EditorPlugin,\n FormatParser,\n IEditor,\n PluginEvent,\n} from 'roosterjs-content-model-types';\n\n/**\n * Paste plugin, handles BeforePaste event and reformat some special content, including:\n * 1. Content copied from Word\n * 2. Content copied from Excel\n * 3. Content copied from Word Online or OneNote Online\n * 4. Content copied from Power Point\n */\nexport class PastePlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n\n /**\n * Construct a new instance of Paste class\n * @param unknownTagReplacement Replace solution of unknown tags, default behavior is to replace with SPAN\n * @param allowExcelNoBorderTable Allow table copied from Excel without border\n */\n constructor(\n private allowExcelNoBorderTable?: boolean,\n private domToModelForSanitizing: Pick<\n DomToModelOptionForSanitizing,\n | 'additionalAllowedTags'\n | 'additionalDisallowedTags'\n | 'styleSanitizers'\n | 'attributeSanitizers'\n > = {\n styleSanitizers: DefaultSanitizers,\n additionalAllowedTags: [],\n additionalDisallowedTags: [],\n attributeSanitizers: {},\n }\n ) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Paste';\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 }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.editor = null;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (!this.editor || event.eventType != 'beforePaste') {\n return;\n }\n\n if (!event.domToModelOption) {\n return;\n }\n\n const pasteSource = getPasteSource(event, false);\n const pasteType = event.pasteType;\n\n switch (pasteSource) {\n case 'wordDesktop':\n processPastedContentFromWordDesktop(event, this.editor.getDOMCreator());\n break;\n case 'wacComponents':\n processPastedContentWacComponents(event);\n break;\n case 'excelOnline':\n case 'excelDesktop':\n case 'excelNonNativeEvent':\n if (pasteType === 'normal' || pasteType === 'mergeFormat') {\n // Handle HTML copied from Excel\n processPastedContentFromExcel(\n event,\n this.editor.getDOMCreator(),\n !!this.allowExcelNoBorderTable,\n pasteSource != 'excelNonNativeEvent' /* isNativeEvent */\n );\n }\n break;\n case 'googleSheets':\n event.domToModelOption.additionalAllowedTags.push(\n PastePropertyNames.GOOGLE_SHEET_NODE_NAME as Lowercase<string>\n );\n break;\n case 'powerPointDesktop':\n processPastedContentFromPowerPoint(event, this.editor.getDOMCreator());\n break;\n\n case 'oneNoteDesktop':\n processPastedContentFromOneNote(event);\n break;\n }\n\n addParser(event.domToModelOption, 'link', parseLink);\n addParser(event.domToModelOption, 'tableCell', deprecatedBorderColorParser);\n addParser(event.domToModelOption, 'tableCell', tableBorderParser);\n addParser(event.domToModelOption, 'table', deprecatedBorderColorParser);\n\n if (pasteType === 'mergeFormat') {\n addParser(event.domToModelOption, 'block', blockElementParser);\n addParser(event.domToModelOption, 'listLevel', blockElementParser);\n }\n\n this.setEventSanitizers(event);\n }\n\n private setEventSanitizers(event: BeforePasteEvent) {\n if (this.domToModelForSanitizing) {\n const {\n styleSanitizers,\n attributeSanitizers,\n additionalAllowedTags,\n additionalDisallowedTags,\n } = this.domToModelForSanitizing;\n getObjectKeys(styleSanitizers).forEach(key =>\n chainSanitizerCallback(\n event.domToModelOption.styleSanitizers,\n key,\n styleSanitizers[key]\n )\n );\n getObjectKeys(attributeSanitizers).forEach(key =>\n chainSanitizerCallback(\n event.domToModelOption.attributeSanitizers,\n key,\n attributeSanitizers[key]\n )\n );\n event.domToModelOption.additionalAllowedTags.push(...additionalAllowedTags);\n event.domToModelOption.additionalDisallowedTags.push(...additionalDisallowedTags);\n }\n }\n}\n\n/**\n * For block elements that have background color style, remove the background color when user selects the merge current format\n * paste option\n */\nconst blockElementParser: FormatParser<ContentModelBlockFormat> = (\n format: ContentModelBlockFormat,\n element: HTMLElement\n) => {\n if (element.style.backgroundColor) {\n delete format.backgroundColor;\n }\n};\n\nconst ElementBorderKeys = new Map<\n keyof BorderFormat,\n {\n c: keyof CSSStyleDeclaration;\n s: keyof CSSStyleDeclaration;\n w: keyof CSSStyleDeclaration;\n }\n>([\n ['borderTop', { w: 'borderTopWidth', s: 'borderTopStyle', c: 'borderTopColor' }],\n ['borderRight', { w: 'borderRightWidth', s: 'borderRightStyle', c: 'borderRightColor' }],\n ['borderBottom', { w: 'borderBottomWidth', s: 'borderBottomStyle', c: 'borderBottomColor' }],\n ['borderLeft', { w: 'borderLeftWidth', s: 'borderLeftStyle', c: 'borderLeftColor' }],\n]);\n\nfunction tableBorderParser(format: ContentModelTableCellFormat, element: HTMLElement): void {\n BorderKeys.forEach(key => {\n if (!format[key]) {\n const styleSet = ElementBorderKeys.get(key);\n if (\n styleSet &&\n element.style[styleSet.w] &&\n element.style[styleSet.s] &&\n !element.style[styleSet.c]\n ) {\n format[key] = `${element.style[styleSet.w]} ${element.style[styleSet.s]}`;\n }\n }\n });\n}\n"]}
1
+ {"version":3,"file":"PastePlugin.js","sourceRoot":"","sources":["../../../../packages/roosterjs-content-model-plugins/lib/paste/PastePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { addParser } from './utils/addParser';\nimport { BorderKeys, getObjectKeys } from 'roosterjs-content-model-dom';\nimport { chainSanitizerCallback } from './utils/chainSanitizerCallback';\nimport { DefaultSanitizers } from './DefaultSanitizers';\nimport { deprecatedBorderColorParser } from './parsers/deprecatedColorParser';\nimport { getPasteSource } from './pasteSourceValidations/getPasteSource';\nimport { parseLink } from './parsers/linkParser';\nimport { PastePropertyNames } from './pasteSourceValidations/constants';\nimport { processPastedContentFromExcel } from './Excel/processPastedContentFromExcel';\nimport { processPastedContentFromOneNote } from './oneNote/processPastedContentFromOneNote';\nimport { processPastedContentFromPowerPoint } from './PowerPoint/processPastedContentFromPowerPoint';\nimport { processPastedContentFromWordDesktop } from './WordDesktop/processPastedContentFromWordDesktop';\nimport { processPastedContentWacComponents } from './WacComponents/processPastedContentWacComponents';\nimport type {\n BeforePasteEvent,\n BorderFormat,\n ContentModelBlockFormat,\n ContentModelTableCellFormat,\n DomToModelOptionForSanitizing,\n EditorPlugin,\n FormatParser,\n IEditor,\n PluginEvent,\n} from 'roosterjs-content-model-types';\n\n/**\n * Paste plugin, handles BeforePaste event and reformat some special content, including:\n * 1. Content copied from Word\n * 2. Content copied from Excel\n * 3. Content copied from Word Online or OneNote Online\n * 4. Content copied from Power Point\n */\nexport class PastePlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n\n /**\n * Construct a new instance of Paste class\n * @param unknownTagReplacement Replace solution of unknown tags, default behavior is to replace with SPAN\n * @param allowExcelNoBorderTable Allow table copied from Excel without border\n */\n constructor(\n private allowExcelNoBorderTable?: boolean,\n private domToModelForSanitizing: Pick<\n DomToModelOptionForSanitizing,\n | 'additionalAllowedTags'\n | 'additionalDisallowedTags'\n | 'styleSanitizers'\n | 'attributeSanitizers'\n > = {\n styleSanitizers: DefaultSanitizers,\n additionalAllowedTags: [],\n additionalDisallowedTags: [],\n attributeSanitizers: {},\n }\n ) {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'Paste';\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 }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.editor = null;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (!this.editor || event.eventType != 'beforePaste') {\n return;\n }\n\n if (!event.domToModelOption) {\n return;\n }\n\n const pasteSource = getPasteSource(event, false);\n const pasteType = event.pasteType;\n\n switch (pasteSource) {\n case 'wordDesktop':\n processPastedContentFromWordDesktop(event);\n break;\n case 'wacComponents':\n processPastedContentWacComponents(event);\n break;\n case 'excelOnline':\n case 'excelDesktop':\n case 'excelNonNativeEvent':\n if (pasteType === 'normal' || pasteType === 'mergeFormat') {\n // Handle HTML copied from Excel\n processPastedContentFromExcel(\n event,\n this.editor.getDOMCreator(),\n !!this.allowExcelNoBorderTable,\n pasteSource != 'excelNonNativeEvent' /* isNativeEvent */\n );\n }\n break;\n case 'googleSheets':\n event.domToModelOption.additionalAllowedTags.push(\n PastePropertyNames.GOOGLE_SHEET_NODE_NAME as Lowercase<string>\n );\n break;\n case 'powerPointDesktop':\n processPastedContentFromPowerPoint(event, this.editor.getDOMCreator());\n break;\n\n case 'oneNoteDesktop':\n processPastedContentFromOneNote(event);\n break;\n }\n\n addParser(event.domToModelOption, 'link', parseLink);\n addParser(event.domToModelOption, 'tableCell', deprecatedBorderColorParser);\n addParser(event.domToModelOption, 'tableCell', tableBorderParser);\n addParser(event.domToModelOption, 'table', deprecatedBorderColorParser);\n\n if (pasteType === 'mergeFormat') {\n addParser(event.domToModelOption, 'block', blockElementParser);\n addParser(event.domToModelOption, 'listLevel', blockElementParser);\n }\n\n this.setEventSanitizers(event);\n }\n\n private setEventSanitizers(event: BeforePasteEvent) {\n if (this.domToModelForSanitizing) {\n const {\n styleSanitizers,\n attributeSanitizers,\n additionalAllowedTags,\n additionalDisallowedTags,\n } = this.domToModelForSanitizing;\n getObjectKeys(styleSanitizers).forEach(key =>\n chainSanitizerCallback(\n event.domToModelOption.styleSanitizers,\n key,\n styleSanitizers[key]\n )\n );\n getObjectKeys(attributeSanitizers).forEach(key =>\n chainSanitizerCallback(\n event.domToModelOption.attributeSanitizers,\n key,\n attributeSanitizers[key]\n )\n );\n event.domToModelOption.additionalAllowedTags.push(...additionalAllowedTags);\n event.domToModelOption.additionalDisallowedTags.push(...additionalDisallowedTags);\n }\n }\n}\n\n/**\n * For block elements that have background color style, remove the background color when user selects the merge current format\n * paste option\n */\nconst blockElementParser: FormatParser<ContentModelBlockFormat> = (\n format: ContentModelBlockFormat,\n element: HTMLElement\n) => {\n if (element.style.backgroundColor) {\n delete format.backgroundColor;\n }\n};\n\nconst ElementBorderKeys = new Map<\n keyof BorderFormat,\n {\n c: keyof CSSStyleDeclaration;\n s: keyof CSSStyleDeclaration;\n w: keyof CSSStyleDeclaration;\n }\n>([\n ['borderTop', { w: 'borderTopWidth', s: 'borderTopStyle', c: 'borderTopColor' }],\n ['borderRight', { w: 'borderRightWidth', s: 'borderRightStyle', c: 'borderRightColor' }],\n ['borderBottom', { w: 'borderBottomWidth', s: 'borderBottomStyle', c: 'borderBottomColor' }],\n ['borderLeft', { w: 'borderLeftWidth', s: 'borderLeftStyle', c: 'borderLeftColor' }],\n]);\n\nfunction tableBorderParser(format: ContentModelTableCellFormat, element: HTMLElement): void {\n BorderKeys.forEach(key => {\n if (!format[key]) {\n const styleSet = ElementBorderKeys.get(key);\n if (\n styleSet &&\n element.style[styleSet.w] &&\n element.style[styleSet.s] &&\n !element.style[styleSet.c]\n ) {\n format[key] = `${element.style[styleSet.w]} ${element.style[styleSet.s]}`;\n }\n }\n });\n}\n"]}
@@ -1,21 +1,147 @@
1
- define(["require", "exports", "roosterjs-content-model-dom"], function (require, exports, roosterjs_content_model_dom_1) {
1
+ define(["require", "exports", "tslib", "../utils/addParser", "../utils/customListUtils", "../parsers/removeNegativeTextIndentParser", "../utils/setProcessor", "roosterjs-content-model-dom"], function (require, exports, tslib_1, addParser_1, customListUtils_1, removeNegativeTextIndentParser_1, setProcessor_1, roosterjs_content_model_dom_1) {
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.processPastedContentFromPowerPoint = void 0;
5
+ var BulletSelector = '* > span > span[style*=mso-special-format]';
6
+ var MsOfficeSpecialFormat = 'mso-special-format';
7
+ var CssStyleKey = 'style';
8
+ var MsoSpecialFormatRegex = /mso-special-format:\s*([^;]*)/;
9
+ var clearListItemStyles = function (format) {
10
+ delete format.textAlign;
11
+ delete format.marginLeft;
12
+ delete format.paddingLeft;
13
+ };
5
14
  /**
6
15
  * @internal
7
16
  * Convert pasted content from PowerPoint
8
17
  * @param event The BeforePaste event
9
18
  */
10
19
  function processPastedContentFromPowerPoint(event, domCreator) {
11
- var fragment = event.fragment, clipboardData = event.clipboardData;
20
+ var fragment = event.fragment, clipboardData = event.clipboardData, domToModelOption = event.domToModelOption;
12
21
  if (clipboardData.html && !clipboardData.text && clipboardData.image) {
13
22
  // It is possible that PowerPoint copied both image and HTML but not plain text.
14
23
  // We always prefer HTML if any.
15
24
  var doc = domCreator.htmlToDOM(clipboardData.html);
16
25
  (0, roosterjs_content_model_dom_1.moveChildNodes)(fragment, doc === null || doc === void 0 ? void 0 : doc.body);
17
26
  }
27
+ (0, addParser_1.addParser)(domToModelOption, 'block', removeNegativeTextIndentParser_1.removeNegativeTextIndentParser);
28
+ (0, setProcessor_1.setProcessor)(domToModelOption, 'element', function (group, element, context) {
29
+ var _a, _b;
30
+ var style = element.getAttribute(CssStyleKey) || '';
31
+ // If the element is the bullet element, just ignore it, otherwise we will see an extra bullet in the list
32
+ if (style.includes(MsOfficeSpecialFormat) && context.listFormat.levels.length > 0) {
33
+ return;
34
+ }
35
+ var bulletElement = element.querySelector(BulletSelector);
36
+ if (bulletElement) {
37
+ var _c = extractPowerPointListInfo(element, bulletElement), depth = _c.depth, unorderedBulletType = _c.unorderedBulletType, orderedBulletType = _c.orderedBulletType, startNumberOverrideOrBullet_1 = _c.startNumberOverrideOrBullet, isOrderedList = _c.isOrderedList, isNewList_1 = _c.isNewList;
38
+ // Setup the listformat with the metadata extracted from the bullet element
39
+ (0, customListUtils_1.setupListFormat)(isOrderedList ? 'OL' : 'UL', element, context, depth, context.listFormat, group, [clearListItemStyles]);
40
+ // Set the metadata for the list item, which will be used to set the correct bullet style type
41
+ var listMetadata = {
42
+ unorderedStyleType: !isOrderedList && unorderedBulletType
43
+ ? roosterjs_content_model_dom_1.BulletListType[unorderedBulletType]
44
+ : undefined,
45
+ orderedStyleType: isOrderedList && orderedBulletType
46
+ ? roosterjs_content_model_dom_1.NumberingListType[orderedBulletType]
47
+ : undefined,
48
+ };
49
+ // Process the Div element as a list item.
50
+ (0, customListUtils_1.processAsListItem)(context, element, group, listMetadata, function (listItem) {
51
+ var _a;
52
+ var currentMarkerSize = listItem.formatHolder.format.fontSize;
53
+ var bulletElementSize = (_a = bulletElement.parentElement) === null || _a === void 0 ? void 0 : _a.style.fontSize;
54
+ listItem.formatHolder.format.fontSize = bulletElementSize || currentMarkerSize;
55
+ if (isNewList_1) {
56
+ listItem.levels[listItem.levels.length - 1].format.startNumberOverride = parseInt(startNumberOverrideOrBullet_1);
57
+ }
58
+ clearListItemStyles(listItem.levels[listItem.levels.length - 1].format);
59
+ clearListItemStyles(listItem.format);
60
+ });
61
+ }
62
+ else {
63
+ (_b = (_a = context.defaultElementProcessors).element) === null || _b === void 0 ? void 0 : _b.call(_a, group, element, context);
64
+ }
65
+ });
18
66
  }
19
67
  exports.processPastedContentFromPowerPoint = processPastedContentFromPowerPoint;
68
+ /**
69
+ * Extract list information from PowerPoint pasted content
70
+ *
71
+ * The lists from PowerPoint are represent as:
72
+ *
73
+ * - The class 0# represents the depth of the list, if the list is in the first level, the class attribute wont be present.
74
+ * - The mso-special-format style represents the type of bullet and the start of the list.
75
+ * The first part of the mso-special-format is the type of bullet, and the second part is the start of the list.
76
+ * - 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.
77
+ *
78
+ * @example
79
+ * ` <div class="O1" style="...">
80
+ <span style="font-size: 5pt"
81
+ ><span style="mso-special-format: 'numbullet6\,1'; font-family: +mj-lt"
82
+ >i.</span
83
+ ></span
84
+ ><span style="...;">123</span>
85
+ </div> `
86
+ *
87
+ * @param element The element to extract list information from
88
+ * @param bulletElement The bullet element to extract list information from
89
+ * @returns The extracted list information
90
+ */
91
+ function extractPowerPointListInfo(element, bulletElement) {
92
+ var className = element.className.substring(1) || '0';
93
+ var depth = parseInt(className) + 1;
94
+ var style = bulletElement.getAttribute(CssStyleKey) || '';
95
+ var msoSpecialFormat = style.match(MsoSpecialFormatRegex);
96
+ var _a = (0, tslib_1.__read)((msoSpecialFormat === null || msoSpecialFormat === void 0 ? void 0 : msoSpecialFormat[1].replace('"', '').split('\\,')) || [], 2), bulletTypeHtml = _a[0], startNumberOverrideOrBullet = _a[1];
97
+ var isOrderedList = OrderedListStyleMap.has(bulletTypeHtml);
98
+ var unorderedBulletType = UnorderedBullets.get(bulletElement.innerText);
99
+ var orderedBulletType = OrderedListStyleMap.get(bulletTypeHtml);
100
+ return {
101
+ depth: depth,
102
+ unorderedBulletType: unorderedBulletType,
103
+ orderedBulletType: orderedBulletType,
104
+ startNumberOverrideOrBullet: startNumberOverrideOrBullet,
105
+ isOrderedList: isOrderedList,
106
+ isNewList: isOrderedList &&
107
+ !!orderedBulletType &&
108
+ bulletElement.innerText ===
109
+ getPptListStart(orderedBulletType, startNumberOverrideOrBullet),
110
+ };
111
+ }
112
+ var UnorderedBullets = new Map([
113
+ ['•', 'Disc'],
114
+ ['o', 'Circle'],
115
+ ['§', 'Square'],
116
+ ['q', 'BoxShadow'],
117
+ ['v', 'Xrhombus'],
118
+ ['Ø', 'ShortArrow'],
119
+ ['ü', 'CheckMark'],
120
+ ]);
121
+ var OrderedListStyleMap = new Map([
122
+ ['numbullet1', 'UpperAlpha'],
123
+ ['numbullet2', 'DecimalParenthesis'],
124
+ ['numbullet3', 'Decimal'],
125
+ ['numbullet7', 'UpperRoman'],
126
+ ['numbullet9', 'LowerAlphaParenthesis'],
127
+ ['numbullet0', 'LowerAlpha'],
128
+ ['numbullet6', 'LowerRoman'],
129
+ ]);
130
+ function getPptListStart(orderedBulletType, startNumberOverride) {
131
+ var bullet = (0, roosterjs_content_model_dom_1.getOrderedListNumberStr)(roosterjs_content_model_dom_1.NumberingListType[orderedBulletType], parseInt(startNumberOverride));
132
+ switch (orderedBulletType) {
133
+ case 'Decimal':
134
+ case 'UpperAlpha':
135
+ case 'LowerAlpha':
136
+ case 'UpperRoman':
137
+ case 'LowerRoman':
138
+ return bullet + '.';
139
+ case 'DecimalParenthesis':
140
+ case 'LowerAlphaParenthesis':
141
+ return bullet + ')';
142
+ default:
143
+ return undefined;
144
+ }
145
+ }
20
146
  });
21
147
  //# sourceMappingURL=processPastedContentFromPowerPoint.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"processPastedContentFromPowerPoint.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/paste/PowerPoint/processPastedContentFromPowerPoint.ts"],"names":[],"mappings":";;;;IAGA;;;;OAIG;IAEH,SAAgB,kCAAkC,CAC9C,KAAuB,EACvB,UAAsB;QAEd,IAAA,QAAQ,GAAoB,KAAK,SAAzB,EAAE,aAAa,GAAK,KAAK,cAAV,CAAW;QAE1C,IAAI,aAAa,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,IAAI,aAAa,CAAC,KAAK,EAAE;YAClE,gFAAgF;YAChF,gCAAgC;YAChC,IAAM,GAAG,GAAG,UAAU,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAErD,IAAA,4CAAc,EAAC,QAAQ,EAAE,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,IAAI,CAAC,CAAC;SACvC;IACL,CAAC;IAbD,gFAaC","sourcesContent":["import { moveChildNodes } from 'roosterjs-content-model-dom';\nimport type { BeforePasteEvent, DOMCreator } from 'roosterjs-content-model-types';\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 } = 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"]}
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,5 +1,5 @@
1
1
  import type { WordMetadata } from './WordMetadata';
2
- import type { BeforePasteEvent, DOMCreator } from 'roosterjs-content-model-types';
2
+ import type { BeforePasteEvent } from 'roosterjs-content-model-types';
3
3
  /**
4
4
  * @internal
5
5
  * Word Desktop content has a style tag that contains data for the lists.
@@ -20,4 +20,4 @@ import type { BeforePasteEvent, DOMCreator } from 'roosterjs-content-model-types
20
20
  * 5. Save data in record and only use the required information.
21
21
  *
22
22
  */
23
- export declare function getStyleMetadata(ev: BeforePasteEvent, domCreator: DOMCreator): Map<string, WordMetadata>;
23
+ export declare function getStyleMetadata(ev: BeforePasteEvent): Map<string, WordMetadata>;
@@ -3,6 +3,25 @@ define(["require", "exports", "tslib", "roosterjs-content-model-dom"], function
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.getStyleMetadata = void 0;
5
5
  var FORMATING_REGEX = /[\n\t'{}"]+/g;
6
+ var STYLE_TAG = '<style>';
7
+ var STYLE_TAG_END = '</style>';
8
+ function extractStyleTagsFromHtml(htmlContent) {
9
+ var styles = [];
10
+ var lowerCaseHtmlContent = htmlContent.toLowerCase();
11
+ var styleStartIndex = lowerCaseHtmlContent.indexOf(STYLE_TAG);
12
+ while (styleStartIndex >= 0) {
13
+ var styleEndIndex = lowerCaseHtmlContent.indexOf(STYLE_TAG_END, styleStartIndex);
14
+ if (styleEndIndex >= 0) {
15
+ var styleContent = htmlContent.substring(styleStartIndex + STYLE_TAG.length, styleEndIndex).trim();
16
+ styles.push(styleContent);
17
+ styleStartIndex = lowerCaseHtmlContent.indexOf(STYLE_TAG, styleEndIndex);
18
+ }
19
+ else {
20
+ break;
21
+ }
22
+ }
23
+ return styles;
24
+ }
6
25
  /**
7
26
  * @internal
8
27
  * Word Desktop content has a style tag that contains data for the lists.
@@ -23,12 +42,10 @@ define(["require", "exports", "tslib", "roosterjs-content-model-dom"], function
23
42
  * 5. Save data in record and only use the required information.
24
43
  *
25
44
  */
26
- function getStyleMetadata(ev, domCreator) {
45
+ function getStyleMetadata(ev) {
27
46
  var metadataMap = new Map();
28
- var doc = domCreator.htmlToDOM(ev.htmlBefore);
29
- var styles = doc.querySelectorAll('style');
30
- styles.forEach(function (style) {
31
- var text = (style === null || style === void 0 ? void 0 : style.innerHTML.trim()) || '';
47
+ var headStyles = extractStyleTagsFromHtml(ev.htmlBefore);
48
+ headStyles.forEach(function (text) {
32
49
  var index = 0;
33
50
  var _loop_1 = function () {
34
51
  var indexAt = text.indexOf('@', index + 1);
@@ -1 +1 @@
1
- {"version":3,"file":"getStyleMetadata.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/getStyleMetadata.ts"],"names":[],"mappings":";;;;IAIA,IAAM,eAAe,GAAG,cAAc,CAAC;IAEvC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,SAAgB,gBAAgB,CAAC,EAAoB,EAAE,UAAsB;QACzE,IAAM,WAAW,GAA8B,IAAI,GAAG,EAAE,CAAC;QACzD,IAAM,GAAG,GAAG,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;QAChD,IAAM,MAAM,GAAG,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAE7C,MAAM,CAAC,OAAO,CAAC,UAAA,KAAK;YAChB,IAAM,IAAI,GAAG,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,SAAS,CAAC,IAAI,EAAE,KAAI,EAAE,CAAC;YAE3C,IAAI,KAAK,GAAG,CAAC,CAAC;;gBAEV,IAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;gBAC7C,IAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;gBACjD,IAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;gBACnD,KAAK,GAAG,OAAO,CAAC;gBAEhB,KAAK;gBACL,IAAM,YAAY,GAAG,IAAI;qBACpB,SAAS,CAAC,OAAO,GAAG,CAAC,EAAE,eAAe,CAAC;qBACvC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC;qBAC5B,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;qBACnB,SAAS,EAAE;qBACX,QAAQ,EAAE,CAAC;gBAEhB,KAAK;gBACL,IAAM,QAAQ,GAAG,IAAI;qBAChB,SAAS,CAAC,eAAe,EAAE,aAAa,GAAG,CAAC,CAAC;qBAC7C,QAAQ,EAAE;qBACV,SAAS,EAAE,CAAC;gBACjB,IAAM,MAAM,GAA2B,EAAE,CAAC;gBAE1C,KAAK;gBACL,IAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACpC,OAAO,CAAC,OAAO,CAAC,UAAA,KAAK;oBACjB,KAAK;oBACC,IAAA,KAAA,oBAAe,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAA,EAA9B,GAAG,QAAA,EAAE,KAAK,QAAoB,CAAC;oBACtC,IAAI,GAAG,IAAI,KAAK,EAAE;wBACd,IAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,CAAC;wBAC5E,IAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,CAAC;wBAChF,KAAK;wBACL,MAAM,CAAC,WAAW,CAAC,GAAG,aAAa,CAAC;qBACvC;gBACL,CAAC,CAAC,CAAC;gBAEH,IAAM,IAAI,GAAiB;oBACvB,yBAAyB,EAAE,MAAM,CAAC,yBAAyB,CAAC;oBAC5D,oBAAoB,EAAE,MAAM,CAAC,oBAAoB,CAAC,IAAI,GAAG;oBACzD,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,CAAC;iBAC7C,CAAC;gBACF,IAAI,IAAA,2CAAa,EAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAA,GAAG,IAAI,OAAA,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAX,CAAW,CAAC,EAAE;oBAC9C,WAAW,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;iBACvC;;YAzCL,OAAO,KAAK,IAAI,CAAC;;aA0ChB;QACL,CAAC,CAAC,CAAC;QACH,OAAO,WAAW,CAAC;IACvB,CAAC;IAtDD,4CAsDC","sourcesContent":["import { getObjectKeys } from 'roosterjs-content-model-dom';\nimport type { WordMetadata } from './WordMetadata';\nimport type { BeforePasteEvent, DOMCreator } from 'roosterjs-content-model-types';\n\nconst FORMATING_REGEX = /[\\n\\t'{}\"]+/g;\n\n/**\n * @internal\n * Word Desktop content has a style tag that contains data for the lists.\n * So this function query that style tag and extract the data from the innerHTML, since it is not available from the HTMLStyleElement.sheet.\n *\n * The format is like:\n * example of style element content\n * @list l0:level1 {\n * styleTag: styleValue;\n * ...\n * }\n *\n * To extract the data:\n * 1. Substring the value of the style selector, using @ index and { index\n * 2. Substring the value of the style rules by Substring the content between { and }\n * 3. Split the value of the rules using ; as separator { styleTag: styleValue; styleTag1: StyleValue1 } = ['styleTag: styleValue', 'styleTag1: StyleValue1']\n * 4. Split the value of the rule using : as separator: styleTag: styleValue = [styleTag, styleValue]\n * 5. Save data in record and only use the required information.\n *\n */\nexport function getStyleMetadata(ev: BeforePasteEvent, domCreator: DOMCreator) {\n const metadataMap: Map<string, WordMetadata> = new Map();\n const doc = domCreator.htmlToDOM(ev.htmlBefore);\n const styles = doc.querySelectorAll('style');\n\n styles.forEach(style => {\n const text = style?.innerHTML.trim() || '';\n\n let index = 0;\n while (index >= 0) {\n const indexAt = text.indexOf('@', index + 1);\n const indexCurlyEnd = text.indexOf('}', indexAt);\n const indexCurlyStart = text.indexOf('{', indexAt);\n index = indexAt;\n\n // 1.\n const metadataName = text\n .substring(indexAt + 1, indexCurlyStart)\n .replace(FORMATING_REGEX, '')\n .replace('list', '')\n .trimRight()\n .trimLeft();\n\n // 2.\n const dataName = text\n .substring(indexCurlyStart, indexCurlyEnd + 1)\n .trimLeft()\n .trimRight();\n const record: Record<string, string> = {};\n\n // 3.\n const entries = dataName.split(';');\n entries.forEach(entry => {\n // 4.\n const [key, value] = entry.split(':');\n if (key && value) {\n const formatedKey = key.replace(FORMATING_REGEX, '').trimRight().trimLeft();\n const formatedValue = value.replace(FORMATING_REGEX, '').trimRight().trimLeft();\n // 5.\n record[formatedKey] = formatedValue;\n }\n });\n\n const data: WordMetadata = {\n 'mso-level-number-format': record['mso-level-number-format'],\n 'mso-level-start-at': record['mso-level-start-at'] || '1',\n 'mso-level-text': record['mso-level-text'],\n };\n if (getObjectKeys(data).some(key => !!data[key])) {\n metadataMap.set(metadataName, data);\n }\n }\n });\n return metadataMap;\n}\n"]}
1
+ {"version":3,"file":"getStyleMetadata.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/getStyleMetadata.ts"],"names":[],"mappings":"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","sourcesContent":["import { getObjectKeys } from 'roosterjs-content-model-dom';\nimport type { WordMetadata } from './WordMetadata';\nimport type { BeforePasteEvent } from 'roosterjs-content-model-types';\n\nconst FORMATING_REGEX = /[\\n\\t'{}\"]+/g;\nconst STYLE_TAG = '<style>';\nconst STYLE_TAG_END = '</style>';\n\nfunction extractStyleTagsFromHtml(htmlContent: string): string[] {\n const styles: string[] = [];\n const lowerCaseHtmlContent = htmlContent.toLowerCase();\n\n let styleStartIndex = lowerCaseHtmlContent.indexOf(STYLE_TAG);\n while (styleStartIndex >= 0) {\n const styleEndIndex = lowerCaseHtmlContent.indexOf(STYLE_TAG_END, styleStartIndex);\n if (styleEndIndex >= 0) {\n const styleContent = htmlContent.substring(styleStartIndex + STYLE_TAG.length, styleEndIndex).trim();\n styles.push(styleContent);\n styleStartIndex = lowerCaseHtmlContent.indexOf(STYLE_TAG, styleEndIndex);\n } else {\n break;\n }\n }\n return styles;\n}\n\n/**\n * @internal\n * Word Desktop content has a style tag that contains data for the lists.\n * So this function query that style tag and extract the data from the innerHTML, since it is not available from the HTMLStyleElement.sheet.\n *\n * The format is like:\n * example of style element content\n * @list l0:level1 {\n * styleTag: styleValue;\n * ...\n * }\n *\n * To extract the data:\n * 1. Substring the value of the style selector, using @ index and { index\n * 2. Substring the value of the style rules by Substring the content between { and }\n * 3. Split the value of the rules using ; as separator { styleTag: styleValue; styleTag1: StyleValue1 } = ['styleTag: styleValue', 'styleTag1: StyleValue1']\n * 4. Split the value of the rule using : as separator: styleTag: styleValue = [styleTag, styleValue]\n * 5. Save data in record and only use the required information.\n *\n */\nexport function getStyleMetadata(ev: BeforePasteEvent) {\n const metadataMap: Map<string, WordMetadata> = new Map();\n const headStyles = extractStyleTagsFromHtml(ev.htmlBefore);\n\n headStyles.forEach(text => {\n let index = 0;\n while (index >= 0) {\n const indexAt = text.indexOf('@', index + 1);\n const indexCurlyEnd = text.indexOf('}', indexAt);\n const indexCurlyStart = text.indexOf('{', indexAt);\n index = indexAt;\n\n // 1.\n const metadataName = text\n .substring(indexAt + 1, indexCurlyStart)\n .replace(FORMATING_REGEX, '')\n .replace('list', '')\n .trimRight()\n .trimLeft();\n\n // 2.\n const dataName = text\n .substring(indexCurlyStart, indexCurlyEnd + 1)\n .trimLeft()\n .trimRight();\n const record: Record<string, string> = {};\n\n // 3.\n const entries = dataName.split(';');\n entries.forEach(entry => {\n // 4.\n const [key, value] = entry.split(':');\n if (key && value) {\n const formatedKey = key.replace(FORMATING_REGEX, '').trimRight().trimLeft();\n const formatedValue = value.replace(FORMATING_REGEX, '').trimRight().trimLeft();\n // 5.\n record[formatedKey] = formatedValue;\n }\n });\n\n const data: WordMetadata = {\n 'mso-level-number-format': record['mso-level-number-format'],\n 'mso-level-start-at': record['mso-level-start-at'] || '1',\n 'mso-level-text': record['mso-level-text'],\n };\n if (getObjectKeys(data).some(key => !!data[key])) {\n metadataMap.set(metadataName, data);\n }\n }\n });\n\n return metadataMap;\n}\n"]}
@@ -1,7 +1,7 @@
1
- import type { BeforePasteEvent, DOMCreator } from 'roosterjs-content-model-types';
1
+ import type { BeforePasteEvent } from 'roosterjs-content-model-types';
2
2
  /**
3
3
  * @internal
4
4
  * Handles Pasted content when source is Word Desktop
5
5
  * @param ev BeforePasteEvent
6
6
  */
7
- export declare function processPastedContentFromWordDesktop(ev: BeforePasteEvent, domCreator: DOMCreator): void;
7
+ export declare function processPastedContentFromWordDesktop(ev: BeforePasteEvent): void;
@@ -1,4 +1,4 @@
1
- define(["require", "exports", "../utils/addParser", "./getStyleMetadata", "../utils/getStyles", "./processWordComments", "./processWordLists", "./removeNegativeTextIndentParser", "../utils/setProcessor"], function (require, exports, addParser_1, getStyleMetadata_1, getStyles_1, processWordComments_1, processWordLists_1, removeNegativeTextIndentParser_1, setProcessor_1) {
1
+ define(["require", "exports", "../utils/addParser", "./getStyleMetadata", "../utils/getStyles", "./processWordComments", "./processWordLists", "../parsers/removeNegativeTextIndentParser", "../utils/setProcessor"], function (require, exports, addParser_1, getStyleMetadata_1, getStyles_1, processWordComments_1, processWordLists_1, removeNegativeTextIndentParser_1, setProcessor_1) {
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.processPastedContentFromWordDesktop = void 0;
@@ -10,8 +10,8 @@ define(["require", "exports", "../utils/addParser", "./getStyleMetadata", "../ut
10
10
  * Handles Pasted content when source is Word Desktop
11
11
  * @param ev BeforePasteEvent
12
12
  */
13
- function processPastedContentFromWordDesktop(ev, domCreator) {
14
- var metadataMap = (0, getStyleMetadata_1.getStyleMetadata)(ev, domCreator);
13
+ function processPastedContentFromWordDesktop(ev) {
14
+ var metadataMap = (0, getStyleMetadata_1.getStyleMetadata)(ev);
15
15
  (0, setProcessor_1.setProcessor)(ev.domToModelOption, 'element', wordDesktopElementProcessor(metadataMap));
16
16
  (0, addParser_1.addParser)(ev.domToModelOption, 'block', adjustPercentileLineHeight);
17
17
  (0, addParser_1.addParser)(ev.domToModelOption, 'block', removeNegativeTextIndentParser_1.removeNegativeTextIndentParser);
@@ -39,12 +39,12 @@ define(["require", "exports", "../utils/addParser", "./getStyleMetadata", "../ut
39
39
  (parsedLineHeight / 100)).toString();
40
40
  }
41
41
  }
42
- function listLevelParser(format, element, context, defaultStyle) {
42
+ var listLevelParser = function (format, element, _context, defaultStyle) {
43
43
  if (element.style.marginLeft != '') {
44
44
  format.marginLeft = defaultStyle.marginLeft;
45
45
  }
46
46
  format.marginBottom = undefined;
47
- }
47
+ };
48
48
  var wordTableParser = function (format) {
49
49
  var _a;
50
50
  if ((_a = format.marginLeft) === null || _a === void 0 ? void 0 : _a.startsWith('-')) {
@@ -1 +1 @@
1
- {"version":3,"file":"processPastedContentFromWordDesktop.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processPastedContentFromWordDesktop.ts"],"names":[],"mappings":";;;;IAmBA,IAAM,gBAAgB,GAAG,GAAG,CAAC;IAC7B,mHAAmH;IACnH,IAAM,sCAAsC,GAAG,GAAG,CAAC;IAEnD;;;;OAIG;IACH,SAAgB,mCAAmC,CAAC,EAAoB,EAAE,UAAsB;QAC5F,IAAM,WAAW,GAA8B,IAAA,mCAAgB,EAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QAEhF,IAAA,2BAAY,EAAC,EAAE,CAAC,gBAAgB,EAAE,SAAS,EAAE,2BAA2B,CAAC,WAAW,CAAC,CAAC,CAAC;QACvF,IAAA,qBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,OAAO,EAAE,0BAA0B,CAAC,CAAC;QACpE,IAAA,qBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,OAAO,EAAE,+DAA8B,CAAC,CAAC;QACxE,IAAA,qBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC;QAC7D,IAAA,qBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC;QAC7D,IAAA,qBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC;IAC7D,CAAC;IATD,kFASC;IAED,IAAM,2BAA2B,GAAG,UAChC,WAAsC;QAEtC,OAAO,UAAC,KAAK,EAAE,OAAO,EAAE,OAAO;YAC3B,IAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,OAAO,CAAC,CAAC;YAClC,4FAA4F;YAC5F,IACI,CAAC,CACG,IAAA,kCAAe,EAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC;gBAC7D,IAAA,yCAAmB,EAAC,MAAM,EAAE,OAAO,CAAC,CACvC,EACH;gBACE,OAAO,CAAC,wBAAwB,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;aACrE;QACL,CAAC,CAAC;IACN,CAAC,CAAC;IAEF,SAAS,0BAA0B,CAAC,MAA+B,EAAE,OAAoB;QACrF,kHAAkH;QAClH,IAAI,gBAAwB,CAAC;QAC7B,IACI,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC;YAC/C,CAAC,KAAK,CAAC,CAAC,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EACjE;YACE,MAAM,CAAC,UAAU,GAAG,CAChB,sCAAsC;gBACtC,CAAC,gBAAgB,GAAG,GAAG,CAAC,CAC3B,CAAC,QAAQ,EAAE,CAAC;SAChB;IACL,CAAC;IAED,SAAS,eAAe,CACpB,MAAuC,EACvC,OAAoB,EACpB,OAA0B,EAC1B,YAAoD;QAEpD,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,EAAE;YAChC,MAAM,CAAC,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC;SAC/C;QAED,MAAM,CAAC,YAAY,GAAG,SAAS,CAAC;IACpC,CAAC;IAED,IAAM,eAAe,GAA0C,UAAC,MAAM;;QAClE,IAAI,MAAA,MAAM,CAAC,UAAU,0CAAE,UAAU,CAAC,GAAG,CAAC,EAAE;YACpC,OAAO,MAAM,CAAC,UAAU,CAAC;SAC5B;IACL,CAAC,CAAC","sourcesContent":["import { addParser } from '../utils/addParser';\nimport { getStyleMetadata } from './getStyleMetadata';\nimport { getStyles } from '../utils/getStyles';\nimport { processWordComments } from './processWordComments';\nimport { processWordList } from './processWordLists';\nimport { removeNegativeTextIndentParser } from './removeNegativeTextIndentParser';\nimport { setProcessor } from '../utils/setProcessor';\nimport type { WordMetadata } from './WordMetadata';\nimport type {\n BeforePasteEvent,\n ContentModelBlockFormat,\n ContentModelListItemLevelFormat,\n ContentModelTableFormat,\n DOMCreator,\n DomToModelContext,\n ElementProcessor,\n FormatParser,\n} from 'roosterjs-content-model-types';\n\nconst PERCENTAGE_REGEX = /%/;\n// Default line height in browsers according to https://developer.mozilla.org/en-US/docs/Web/CSS/line-height#normal\nconst DEFAULT_BROWSER_LINE_HEIGHT_PERCENTAGE = 1.2;\n\n/**\n * @internal\n * Handles Pasted content when source is Word Desktop\n * @param ev BeforePasteEvent\n */\nexport function processPastedContentFromWordDesktop(ev: BeforePasteEvent, domCreator: DOMCreator) {\n const metadataMap: Map<string, WordMetadata> = getStyleMetadata(ev, domCreator);\n\n setProcessor(ev.domToModelOption, 'element', wordDesktopElementProcessor(metadataMap));\n addParser(ev.domToModelOption, 'block', adjustPercentileLineHeight);\n addParser(ev.domToModelOption, 'block', removeNegativeTextIndentParser);\n addParser(ev.domToModelOption, 'listLevel', listLevelParser);\n addParser(ev.domToModelOption, 'container', wordTableParser);\n addParser(ev.domToModelOption, 'table', wordTableParser);\n}\n\nconst wordDesktopElementProcessor = (\n metadataKey: Map<string, WordMetadata>\n): ElementProcessor<HTMLElement> => {\n return (group, element, context) => {\n const styles = getStyles(element);\n // Process Word Lists or Word Commands, otherwise use the default processor on this element.\n if (\n !(\n processWordList(styles, group, element, context, metadataKey) ||\n processWordComments(styles, element)\n )\n ) {\n context.defaultElementProcessors.element(group, element, context);\n }\n };\n};\n\nfunction adjustPercentileLineHeight(format: ContentModelBlockFormat, element: HTMLElement): void {\n //If the line height is less than the browser default line height, line between the text is going to be too narrow\n let parsedLineHeight: number;\n if (\n PERCENTAGE_REGEX.test(element.style.lineHeight) &&\n !isNaN((parsedLineHeight = parseInt(element.style.lineHeight)))\n ) {\n format.lineHeight = (\n DEFAULT_BROWSER_LINE_HEIGHT_PERCENTAGE *\n (parsedLineHeight / 100)\n ).toString();\n }\n}\n\nfunction listLevelParser(\n format: ContentModelListItemLevelFormat,\n element: HTMLElement,\n context: DomToModelContext,\n defaultStyle: Readonly<Partial<CSSStyleDeclaration>>\n): void {\n if (element.style.marginLeft != '') {\n format.marginLeft = defaultStyle.marginLeft;\n }\n\n format.marginBottom = undefined;\n}\n\nconst wordTableParser: FormatParser<ContentModelTableFormat> = (format): void => {\n if (format.marginLeft?.startsWith('-')) {\n delete format.marginLeft;\n }\n};\n"]}
1
+ {"version":3,"file":"processPastedContentFromWordDesktop.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-plugins/lib/paste/WordDesktop/processPastedContentFromWordDesktop.ts"],"names":[],"mappings":";;;;IAkBA,IAAM,gBAAgB,GAAG,GAAG,CAAC;IAC7B,mHAAmH;IACnH,IAAM,sCAAsC,GAAG,GAAG,CAAC;IAEnD;;;;OAIG;IACH,SAAgB,mCAAmC,CAAC,EAAoB;QACpE,IAAM,WAAW,GAA8B,IAAA,mCAAgB,EAAC,EAAE,CAAC,CAAC;QAEpE,IAAA,2BAAY,EAAC,EAAE,CAAC,gBAAgB,EAAE,SAAS,EAAE,2BAA2B,CAAC,WAAW,CAAC,CAAC,CAAC;QACvF,IAAA,qBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,OAAO,EAAE,0BAA0B,CAAC,CAAC;QACpE,IAAA,qBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,OAAO,EAAE,+DAA8B,CAAC,CAAC;QACxE,IAAA,qBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC;QAC7D,IAAA,qBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC;QAC7D,IAAA,qBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC;IAC7D,CAAC;IATD,kFASC;IAED,IAAM,2BAA2B,GAAG,UAChC,WAAsC;QAEtC,OAAO,UAAC,KAAK,EAAE,OAAO,EAAE,OAAO;YAC3B,IAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,OAAO,CAAC,CAAC;YAClC,4FAA4F;YAC5F,IACI,CAAC,CACG,IAAA,kCAAe,EAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC;gBAC7D,IAAA,yCAAmB,EAAC,MAAM,EAAE,OAAO,CAAC,CACvC,EACH;gBACE,OAAO,CAAC,wBAAwB,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;aACrE;QACL,CAAC,CAAC;IACN,CAAC,CAAC;IAEF,SAAS,0BAA0B,CAAC,MAA+B,EAAE,OAAoB;QACrF,kHAAkH;QAClH,IAAI,gBAAwB,CAAC;QAC7B,IACI,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC;YAC/C,CAAC,KAAK,CAAC,CAAC,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EACjE;YACE,MAAM,CAAC,UAAU,GAAG,CAChB,sCAAsC;gBACtC,CAAC,gBAAgB,GAAG,GAAG,CAAC,CAC3B,CAAC,QAAQ,EAAE,CAAC;SAChB;IACL,CAAC;IAED,IAAM,eAAe,GAAkD,UACnE,MAAuC,EACvC,OAAoB,EACpB,QAA2B,EAC3B,YAAoD;QAEpD,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,EAAE;YAChC,MAAM,CAAC,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC;SAC/C;QAED,MAAM,CAAC,YAAY,GAAG,SAAS,CAAC;IACpC,CAAC,CAAC;IAEF,IAAM,eAAe,GAA0C,UAAC,MAAM;;QAClE,IAAI,MAAA,MAAM,CAAC,UAAU,0CAAE,UAAU,CAAC,GAAG,CAAC,EAAE;YACpC,OAAO,MAAM,CAAC,UAAU,CAAC;SAC5B;IACL,CAAC,CAAC","sourcesContent":["import { addParser } from '../utils/addParser';\nimport { getStyleMetadata } from './getStyleMetadata';\nimport { getStyles } from '../utils/getStyles';\nimport { processWordComments } from './processWordComments';\nimport { processWordList } from './processWordLists';\nimport { removeNegativeTextIndentParser } from '../parsers/removeNegativeTextIndentParser';\nimport { setProcessor } from '../utils/setProcessor';\nimport type { WordMetadata } from './WordMetadata';\nimport type {\n BeforePasteEvent,\n ContentModelBlockFormat,\n ContentModelListItemLevelFormat,\n ContentModelTableFormat,\n DomToModelContext,\n ElementProcessor,\n FormatParser,\n} from 'roosterjs-content-model-types';\n\nconst PERCENTAGE_REGEX = /%/;\n// Default line height in browsers according to https://developer.mozilla.org/en-US/docs/Web/CSS/line-height#normal\nconst DEFAULT_BROWSER_LINE_HEIGHT_PERCENTAGE = 1.2;\n\n/**\n * @internal\n * Handles Pasted content when source is Word Desktop\n * @param ev BeforePasteEvent\n */\nexport function processPastedContentFromWordDesktop(ev: BeforePasteEvent) {\n const metadataMap: Map<string, WordMetadata> = getStyleMetadata(ev);\n\n setProcessor(ev.domToModelOption, 'element', wordDesktopElementProcessor(metadataMap));\n addParser(ev.domToModelOption, 'block', adjustPercentileLineHeight);\n addParser(ev.domToModelOption, 'block', removeNegativeTextIndentParser);\n addParser(ev.domToModelOption, 'listLevel', listLevelParser);\n addParser(ev.domToModelOption, 'container', wordTableParser);\n addParser(ev.domToModelOption, 'table', wordTableParser);\n}\n\nconst wordDesktopElementProcessor = (\n metadataKey: Map<string, WordMetadata>\n): ElementProcessor<HTMLElement> => {\n return (group, element, context) => {\n const styles = getStyles(element);\n // Process Word Lists or Word Commands, otherwise use the default processor on this element.\n if (\n !(\n processWordList(styles, group, element, context, metadataKey) ||\n processWordComments(styles, element)\n )\n ) {\n context.defaultElementProcessors.element(group, element, context);\n }\n };\n};\n\nfunction adjustPercentileLineHeight(format: ContentModelBlockFormat, element: HTMLElement): void {\n //If the line height is less than the browser default line height, line between the text is going to be too narrow\n let parsedLineHeight: number;\n if (\n PERCENTAGE_REGEX.test(element.style.lineHeight) &&\n !isNaN((parsedLineHeight = parseInt(element.style.lineHeight)))\n ) {\n format.lineHeight = (\n DEFAULT_BROWSER_LINE_HEIGHT_PERCENTAGE *\n (parsedLineHeight / 100)\n ).toString();\n }\n}\n\nconst listLevelParser: FormatParser<ContentModelListItemLevelFormat> = (\n format: ContentModelListItemLevelFormat,\n element: HTMLElement,\n _context: DomToModelContext,\n defaultStyle: Readonly<Partial<CSSStyleDeclaration>>\n) => {\n if (element.style.marginLeft != '') {\n format.marginLeft = defaultStyle.marginLeft;\n }\n\n format.marginBottom = undefined;\n};\n\nconst wordTableParser: FormatParser<ContentModelTableFormat> = (format): void => {\n if (format.marginLeft?.startsWith('-')) {\n delete format.marginLeft;\n }\n};\n"]}
@@ -1,4 +1,4 @@
1
- define(["require", "exports", "tslib", "./removeNegativeTextIndentParser", "roosterjs-content-model-dom"], function (require, exports, tslib_1, removeNegativeTextIndentParser_1, roosterjs_content_model_dom_1) {
1
+ define(["require", "exports", "tslib", "roosterjs-content-model-dom", "../utils/customListUtils"], function (require, exports, tslib_1, roosterjs_content_model_dom_1, customListUtils_1) {
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.processWordList = void 0;
@@ -40,28 +40,28 @@ define(["require", "exports", "tslib", "./removeNegativeTextIndentParser", "roos
40
40
  if (wordListStyle && group && typeof listFormat.wordLevel === 'number') {
41
41
  var wordLevel = listFormat.wordLevel, wordList = listFormat.wordList;
42
42
  // Retrieve the Fake bullet on the element and also the list type
43
- var listMetadata = metadata.get(lNumber + ":" + level);
44
- var listType = ((_a = listMetadata === null || listMetadata === void 0 ? void 0 : listMetadata['mso-level-number-format']) === null || _a === void 0 ? void 0 : _a.toLowerCase()) != BULLET_METADATA
43
+ var listMetadata_1 = metadata.get(lNumber + ":" + level);
44
+ var listType_1 = ((_a = listMetadata_1 === null || listMetadata_1 === void 0 ? void 0 : listMetadata_1['mso-level-number-format']) === null || _a === void 0 ? void 0 : _a.toLowerCase()) != BULLET_METADATA
45
45
  ? 'OL'
46
46
  : 'UL';
47
47
  // Create the new level of the list item and parse the format
48
- var newLevel = (0, roosterjs_content_model_dom_1.createListLevel)(listType);
49
- (0, roosterjs_content_model_dom_1.parseFormat)(element, (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(context.formatParsers.listLevel), false), [wordListPaddingParser], false), newLevel.format, context);
50
- // If the list format is in a different level, update the array so we get the new item
51
- // To be in the same level as the provided level metadata.
52
- if (wordLevel > listFormat.levels.length) {
53
- while (wordLevel != listFormat.levels.length) {
54
- listFormat.levels.push(newLevel);
55
- }
56
- }
57
- else {
58
- listFormat.levels.splice(wordLevel, listFormat.levels.length - 1);
59
- listFormat.levels[wordLevel - 1] = newLevel;
60
- }
48
+ (0, customListUtils_1.setupListFormat)(listType_1, element, context, wordLevel, listFormat, group, [
49
+ wordListPaddingParser,
50
+ ]);
61
51
  listFormat.levels[listFormat.levels.length - 1]
62
52
  .format.wordList = wordList;
63
- listFormat.listParent = group;
64
- processAsListItem(listFormat, context, element, group, listMetadata);
53
+ var bullet = getBulletFromMetadata(listMetadata_1, listType_1);
54
+ var listFormatMetadata = bullet
55
+ ? {
56
+ unorderedStyleType: listType_1 == 'UL' ? bullet : undefined,
57
+ orderedStyleType: listType_1 == 'OL' ? bullet : undefined,
58
+ }
59
+ : undefined;
60
+ (0, customListUtils_1.processAsListItem)(context, element, group, listFormatMetadata, function (listItem) {
61
+ if (listType_1 == 'OL') {
62
+ setStartNumber(listItem, context, listMetadata_1);
63
+ }
64
+ });
65
65
  if (listFormat.levels.length > 0 &&
66
66
  listFormat.wordKnownLevels.get(wordList) != listFormat.levels) {
67
67
  listFormat.wordKnownLevels.set(wordList, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(listFormat.levels), false));
@@ -71,28 +71,6 @@ define(["require", "exports", "tslib", "./removeNegativeTextIndentParser", "roos
71
71
  return false;
72
72
  }
73
73
  exports.processWordList = processWordList;
74
- function processAsListItem(listFormat, context, element, group, listMetadata) {
75
- var listLevel = listFormat.levels[listFormat.levels.length - 1];
76
- var listType = listLevel.listType;
77
- var bullet = getBulletFromMetadata(listMetadata, listType);
78
- if (bullet) {
79
- (0, roosterjs_content_model_dom_1.updateListMetadata)(listFormat.levels[listFormat.levels.length - 1], function (metadata) {
80
- return Object.assign({}, metadata, {
81
- unorderedStyleType: listType == 'UL' ? bullet : undefined,
82
- orderedStyleType: listType == 'OL' ? bullet : undefined,
83
- });
84
- });
85
- }
86
- var listItem = (0, roosterjs_content_model_dom_1.createListItem)(listFormat.levels, context.segmentFormat);
87
- (0, roosterjs_content_model_dom_1.parseFormat)(element, context.formatParsers.segmentOnBlock, context.segmentFormat, context);
88
- (0, roosterjs_content_model_dom_1.parseFormat)(element, context.formatParsers.listItemElement, listItem.format, context);
89
- (0, roosterjs_content_model_dom_1.parseFormat)(element, [removeNegativeTextIndentParser_1.removeNegativeTextIndentParser, nonListElementParser], listItem.format, context);
90
- if (listType == 'OL') {
91
- setStartNumber(listItem, context, listMetadata);
92
- }
93
- context.elementProcessors.child(listItem, element, context);
94
- (0, roosterjs_content_model_dom_1.addBlock)(group, listItem);
95
- }
96
74
  function getBulletFromMetadata(listMetadata, listType) {
97
75
  var templateType = (listMetadata === null || listMetadata === void 0 ? void 0 : listMetadata['mso-level-number-format']) || 'decimal';
98
76
  var templateFinal;
@@ -139,14 +117,6 @@ define(["require", "exports", "tslib", "./removeNegativeTextIndentParser", "roos
139
117
  }
140
118
  return (0, roosterjs_content_model_dom_1.getListStyleTypeFromString)(listType, templateFinal);
141
119
  }
142
- function wordListPaddingParser(format, element) {
143
- if (element.style.marginLeft && element.style.marginLeft != '0in') {
144
- format.paddingLeft = '0px';
145
- }
146
- if (element.style.marginRight && element.style.marginRight != '0in') {
147
- format.paddingRight = '0px';
148
- }
149
- }
150
120
  function setStartNumber(listItem, context, listMetadata) {
151
121
  var _a, _b;
152
122
  var _c = context.listFormat, listParent = _c.listParent, wordList = _c.wordList, wordKnownLevels = _c.wordKnownLevels, wordLevel = _c.wordLevel, levels = _c.levels;
@@ -174,18 +144,13 @@ define(["require", "exports", "tslib", "./removeNegativeTextIndentParser", "roos
174
144
  }
175
145
  return undefined;
176
146
  }
177
- var nonListElementParser = function (format, element, _context, defaultStyle) {
178
- if (!(0, roosterjs_content_model_dom_1.isElementOfType)(element, 'li')) {
179
- Object.keys(defaultStyle).forEach(function (keyInput) {
180
- var key = keyInput;
181
- var formatKey = keyInput;
182
- if (key != 'display' &&
183
- format[formatKey] != undefined &&
184
- format[formatKey] == defaultStyle[key]) {
185
- delete format[formatKey];
186
- }
187
- });
147
+ function wordListPaddingParser(format, element) {
148
+ if (element.style.marginLeft && element.style.marginLeft != '0in') {
149
+ format.paddingLeft = '0px';
150
+ }
151
+ if (element.style.marginRight && element.style.marginRight != '0in') {
152
+ format.paddingRight = '0px';
188
153
  }
189
- };
154
+ }
190
155
  });
191
156
  //# 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 { removeNegativeTextIndentParser } from './removeNegativeTextIndentParser';\nimport {\n addBlock,\n createListItem,\n createListLevel,\n getListStyleTypeFromString,\n isElementOfType,\n isEmpty,\n parseFormat,\n updateListMetadata,\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 FormatParser,\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\n listFormat.wordList = lNumber || WORD_FIRST_LIST;\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 const newLevel: ContentModelListLevel = createListLevel(listType);\n parseFormat(\n element,\n [...context.formatParsers.listLevel, wordListPaddingParser],\n newLevel.format,\n context\n );\n\n // If the list format is in a different level, update the array so we get the new item\n // To be in the same level as the provided level metadata.\n if (wordLevel > listFormat.levels.length) {\n while (wordLevel != listFormat.levels.length) {\n listFormat.levels.push(newLevel);\n }\n } else {\n listFormat.levels.splice(wordLevel, listFormat.levels.length - 1);\n listFormat.levels[wordLevel - 1] = newLevel;\n }\n (listFormat.levels[listFormat.levels.length - 1]\n .format as WordListFormat).wordList = wordList;\n\n listFormat.listParent = group;\n\n processAsListItem(listFormat, context, element, group, listMetadata);\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 processAsListItem(\n listFormat: WordDesktopListFormat,\n context: DomToModelContext,\n element: HTMLElement,\n group: ContentModelBlockGroup,\n listMetadata: WordMetadata | undefined\n) {\n const listLevel = listFormat.levels[listFormat.levels.length - 1];\n const { listType } = listLevel;\n const bullet = getBulletFromMetadata(listMetadata, listType);\n if (bullet) {\n updateListMetadata(listFormat.levels[listFormat.levels.length - 1], metadata =>\n Object.assign({}, metadata, {\n unorderedStyleType: listType == 'UL' ? bullet : undefined,\n orderedStyleType: listType == 'OL' ? bullet : undefined,\n })\n );\n }\n\n const listItem = createListItem(listFormat.levels, context.segmentFormat);\n\n parseFormat(element, context.formatParsers.segmentOnBlock, context.segmentFormat, context);\n parseFormat(element, context.formatParsers.listItemElement, listItem.format, context);\n parseFormat(\n element,\n [removeNegativeTextIndentParser, nonListElementParser],\n listItem.format,\n context\n );\n\n if (listType == 'OL') {\n setStartNumber(listItem, context, listMetadata);\n }\n\n context.elementProcessors.child(listItem, element, context);\n addBlock(group, listItem);\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 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\nfunction setStartNumber(\n listItem: ContentModelListItem,\n context: DomToModelContext,\n listMetadata: WordMetadata | undefined\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 }\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\nconst nonListElementParser: FormatParser<ContentModelListItemFormat> = (\n format,\n element,\n _context,\n defaultStyle\n): void => {\n if (!isElementOfType(element, 'li')) {\n Object.keys(defaultStyle).forEach(keyInput => {\n const key = keyInput as keyof CSSStyleDeclaration;\n const formatKey = keyInput as keyof ContentModelListItemFormat;\n if (\n key != 'display' &&\n format[formatKey] != undefined &&\n format[formatKey] == defaultStyle[key]\n ) {\n delete format[formatKey];\n }\n });\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 { getListStyleTypeFromString, isEmpty } from 'roosterjs-content-model-dom';\nimport { processAsListItem, setupListFormat } from '../utils/customListUtils';\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);\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) {\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 }\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"]}