roosterjs-content-model-plugins 0.20.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.
- package/LICENSE +25 -0
- package/README.md +262 -0
- package/lib/edit/ContentModelEditPlugin.d.ts +35 -0
- package/lib/edit/ContentModelEditPlugin.js +71 -0
- package/lib/edit/ContentModelEditPlugin.js.map +1 -0
- package/lib/edit/deleteSteps/deleteAllSegmentBefore.d.ts +5 -0
- package/lib/edit/deleteSteps/deleteAllSegmentBefore.js +20 -0
- package/lib/edit/deleteSteps/deleteAllSegmentBefore.js.map +1 -0
- package/lib/edit/deleteSteps/deleteCollapsedSelection.d.ts +9 -0
- package/lib/edit/deleteSteps/deleteCollapsedSelection.js +91 -0
- package/lib/edit/deleteSteps/deleteCollapsedSelection.js.map +1 -0
- package/lib/edit/deleteSteps/deleteWordSelection.d.ts +9 -0
- package/lib/edit/deleteSteps/deleteWordSelection.js +171 -0
- package/lib/edit/deleteSteps/deleteWordSelection.js.map +1 -0
- package/lib/edit/handleKeyboardEventCommon.d.ts +15 -0
- package/lib/edit/handleKeyboardEventCommon.js +55 -0
- package/lib/edit/handleKeyboardEventCommon.js.map +1 -0
- package/lib/edit/keyboardDelete.d.ts +9 -0
- package/lib/edit/keyboardDelete.js +64 -0
- package/lib/edit/keyboardDelete.js.map +1 -0
- package/lib/edit/utils/getLeafSiblingBlock.d.ts +23 -0
- package/lib/edit/utils/getLeafSiblingBlock.js +76 -0
- package/lib/edit/utils/getLeafSiblingBlock.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +8 -0
- package/lib/index.js.map +1 -0
- package/lib/paste/ContentModelPastePlugin.d.ts +42 -0
- package/lib/paste/ContentModelPastePlugin.js +149 -0
- package/lib/paste/ContentModelPastePlugin.js.map +1 -0
- package/lib/paste/Excel/processPastedContentFromExcel.d.ts +13 -0
- package/lib/paste/Excel/processPastedContentFromExcel.js +83 -0
- package/lib/paste/Excel/processPastedContentFromExcel.js.map +1 -0
- package/lib/paste/PowerPoint/processPastedContentFromPowerPoint.d.ts +7 -0
- package/lib/paste/PowerPoint/processPastedContentFromPowerPoint.js +20 -0
- package/lib/paste/PowerPoint/processPastedContentFromPowerPoint.js.map +1 -0
- package/lib/paste/WacComponents/processPastedContentWacComponents.d.ts +9 -0
- package/lib/paste/WacComponents/processPastedContentWacComponents.js +208 -0
- package/lib/paste/WacComponents/processPastedContentWacComponents.js.map +1 -0
- package/lib/paste/WordDesktop/processPastedContentFromWordDesktop.d.ts +12 -0
- package/lib/paste/WordDesktop/processPastedContentFromWordDesktop.js +70 -0
- package/lib/paste/WordDesktop/processPastedContentFromWordDesktop.js.map +1 -0
- package/lib/paste/WordDesktop/processWordComments.d.ts +7 -0
- package/lib/paste/WordDesktop/processWordComments.js +22 -0
- package/lib/paste/WordDesktop/processWordComments.js.map +1 -0
- package/lib/paste/WordDesktop/processWordLists.d.ts +10 -0
- package/lib/paste/WordDesktop/processWordLists.js +155 -0
- package/lib/paste/WordDesktop/processWordLists.js.map +1 -0
- package/lib/paste/pasteSourceValidations/constants.d.ts +17 -0
- package/lib/paste/pasteSourceValidations/constants.js +22 -0
- package/lib/paste/pasteSourceValidations/constants.js.map +1 -0
- package/lib/paste/pasteSourceValidations/documentContainWacElements.d.ts +8 -0
- package/lib/paste/pasteSourceValidations/documentContainWacElements.js +25 -0
- package/lib/paste/pasteSourceValidations/documentContainWacElements.js.map +1 -0
- package/lib/paste/pasteSourceValidations/getPasteSource.d.ts +27 -0
- package/lib/paste/pasteSourceValidations/getPasteSource.js +44 -0
- package/lib/paste/pasteSourceValidations/getPasteSource.js.map +1 -0
- package/lib/paste/pasteSourceValidations/isExcelDesktopDocument.d.ts +8 -0
- package/lib/paste/pasteSourceValidations/isExcelDesktopDocument.js +17 -0
- package/lib/paste/pasteSourceValidations/isExcelDesktopDocument.js.map +1 -0
- package/lib/paste/pasteSourceValidations/isExcelOnlineDocument.d.ts +8 -0
- package/lib/paste/pasteSourceValidations/isExcelOnlineDocument.js +19 -0
- package/lib/paste/pasteSourceValidations/isExcelOnlineDocument.js.map +1 -0
- package/lib/paste/pasteSourceValidations/isGoogleSheetDocument.d.ts +8 -0
- package/lib/paste/pasteSourceValidations/isGoogleSheetDocument.js +15 -0
- package/lib/paste/pasteSourceValidations/isGoogleSheetDocument.js.map +1 -0
- package/lib/paste/pasteSourceValidations/isPowerPointDesktopDocument.d.ts +8 -0
- package/lib/paste/pasteSourceValidations/isPowerPointDesktopDocument.js +15 -0
- package/lib/paste/pasteSourceValidations/isPowerPointDesktopDocument.js.map +1 -0
- package/lib/paste/pasteSourceValidations/isWordDesktopDocument.d.ts +8 -0
- package/lib/paste/pasteSourceValidations/isWordDesktopDocument.js +19 -0
- package/lib/paste/pasteSourceValidations/isWordDesktopDocument.js.map +1 -0
- package/lib/paste/pasteSourceValidations/shouldConvertToSingleImage.d.ts +9 -0
- package/lib/paste/pasteSourceValidations/shouldConvertToSingleImage.js +19 -0
- package/lib/paste/pasteSourceValidations/shouldConvertToSingleImage.js.map +1 -0
- package/lib/paste/utils/addParser.d.ts +5 -0
- package/lib/paste/utils/addParser.js +17 -0
- package/lib/paste/utils/addParser.js.map +1 -0
- package/lib/paste/utils/deprecatedColorParser.d.ts +5 -0
- package/lib/paste/utils/deprecatedColorParser.js +20 -0
- package/lib/paste/utils/deprecatedColorParser.js.map +1 -0
- package/lib/paste/utils/getStyles.d.ts +6 -0
- package/lib/paste/utils/getStyles.js +23 -0
- package/lib/paste/utils/getStyles.js.map +1 -0
- package/lib/paste/utils/linkParser.d.ts +5 -0
- package/lib/paste/utils/linkParser.js +28 -0
- package/lib/paste/utils/linkParser.js.map +1 -0
- package/lib/paste/utils/setProcessor.d.ts +5 -0
- package/lib/paste/utils/setProcessor.js +14 -0
- package/lib/paste/utils/setProcessor.js.map +1 -0
- package/lib-amd/edit/ContentModelEditPlugin.d.ts +35 -0
- package/lib-amd/edit/ContentModelEditPlugin.js +72 -0
- package/lib-amd/edit/ContentModelEditPlugin.js.map +1 -0
- package/lib-amd/edit/deleteSteps/deleteAllSegmentBefore.d.ts +5 -0
- package/lib-amd/edit/deleteSteps/deleteAllSegmentBefore.js +21 -0
- package/lib-amd/edit/deleteSteps/deleteAllSegmentBefore.js.map +1 -0
- package/lib-amd/edit/deleteSteps/deleteCollapsedSelection.d.ts +9 -0
- package/lib-amd/edit/deleteSteps/deleteCollapsedSelection.js +90 -0
- package/lib-amd/edit/deleteSteps/deleteCollapsedSelection.js.map +1 -0
- package/lib-amd/edit/deleteSteps/deleteWordSelection.d.ts +9 -0
- package/lib-amd/edit/deleteSteps/deleteWordSelection.js +170 -0
- package/lib-amd/edit/deleteSteps/deleteWordSelection.js.map +1 -0
- package/lib-amd/edit/handleKeyboardEventCommon.d.ts +15 -0
- package/lib-amd/edit/handleKeyboardEventCommon.js +56 -0
- package/lib-amd/edit/handleKeyboardEventCommon.js.map +1 -0
- package/lib-amd/edit/keyboardDelete.d.ts +9 -0
- package/lib-amd/edit/keyboardDelete.js +60 -0
- package/lib-amd/edit/keyboardDelete.js.map +1 -0
- package/lib-amd/edit/utils/getLeafSiblingBlock.d.ts +23 -0
- package/lib-amd/edit/utils/getLeafSiblingBlock.js +76 -0
- package/lib-amd/edit/utils/getLeafSiblingBlock.js.map +1 -0
- package/lib-amd/index.d.ts +2 -0
- package/lib-amd/index.js +8 -0
- package/lib-amd/index.js.map +1 -0
- package/lib-amd/paste/ContentModelPastePlugin.d.ts +42 -0
- package/lib-amd/paste/ContentModelPastePlugin.js +141 -0
- package/lib-amd/paste/ContentModelPastePlugin.js.map +1 -0
- package/lib-amd/paste/Excel/processPastedContentFromExcel.d.ts +13 -0
- package/lib-amd/paste/Excel/processPastedContentFromExcel.js +81 -0
- package/lib-amd/paste/Excel/processPastedContentFromExcel.js.map +1 -0
- package/lib-amd/paste/PowerPoint/processPastedContentFromPowerPoint.d.ts +7 -0
- package/lib-amd/paste/PowerPoint/processPastedContentFromPowerPoint.js +21 -0
- package/lib-amd/paste/PowerPoint/processPastedContentFromPowerPoint.js.map +1 -0
- package/lib-amd/paste/WacComponents/processPastedContentWacComponents.d.ts +9 -0
- package/lib-amd/paste/WacComponents/processPastedContentWacComponents.js +207 -0
- package/lib-amd/paste/WacComponents/processPastedContentWacComponents.js.map +1 -0
- package/lib-amd/paste/WordDesktop/processPastedContentFromWordDesktop.d.ts +12 -0
- package/lib-amd/paste/WordDesktop/processPastedContentFromWordDesktop.js +65 -0
- package/lib-amd/paste/WordDesktop/processPastedContentFromWordDesktop.js.map +1 -0
- package/lib-amd/paste/WordDesktop/processWordComments.d.ts +7 -0
- package/lib-amd/paste/WordDesktop/processWordComments.js +23 -0
- package/lib-amd/paste/WordDesktop/processWordComments.js.map +1 -0
- package/lib-amd/paste/WordDesktop/processWordLists.d.ts +10 -0
- package/lib-amd/paste/WordDesktop/processWordLists.js +154 -0
- package/lib-amd/paste/WordDesktop/processWordLists.js.map +1 -0
- package/lib-amd/paste/pasteSourceValidations/constants.d.ts +17 -0
- package/lib-amd/paste/pasteSourceValidations/constants.js +24 -0
- package/lib-amd/paste/pasteSourceValidations/constants.js.map +1 -0
- package/lib-amd/paste/pasteSourceValidations/documentContainWacElements.d.ts +8 -0
- package/lib-amd/paste/pasteSourceValidations/documentContainWacElements.js +27 -0
- package/lib-amd/paste/pasteSourceValidations/documentContainWacElements.js.map +1 -0
- package/lib-amd/paste/pasteSourceValidations/getPasteSource.d.ts +27 -0
- package/lib-amd/paste/pasteSourceValidations/getPasteSource.js +39 -0
- package/lib-amd/paste/pasteSourceValidations/getPasteSource.js.map +1 -0
- package/lib-amd/paste/pasteSourceValidations/isExcelDesktopDocument.d.ts +8 -0
- package/lib-amd/paste/pasteSourceValidations/isExcelDesktopDocument.js +19 -0
- package/lib-amd/paste/pasteSourceValidations/isExcelDesktopDocument.js.map +1 -0
- package/lib-amd/paste/pasteSourceValidations/isExcelOnlineDocument.d.ts +8 -0
- package/lib-amd/paste/pasteSourceValidations/isExcelOnlineDocument.js +21 -0
- package/lib-amd/paste/pasteSourceValidations/isExcelOnlineDocument.js.map +1 -0
- package/lib-amd/paste/pasteSourceValidations/isGoogleSheetDocument.d.ts +8 -0
- package/lib-amd/paste/pasteSourceValidations/isGoogleSheetDocument.js +17 -0
- package/lib-amd/paste/pasteSourceValidations/isGoogleSheetDocument.js.map +1 -0
- package/lib-amd/paste/pasteSourceValidations/isPowerPointDesktopDocument.d.ts +8 -0
- package/lib-amd/paste/pasteSourceValidations/isPowerPointDesktopDocument.js +17 -0
- package/lib-amd/paste/pasteSourceValidations/isPowerPointDesktopDocument.js.map +1 -0
- package/lib-amd/paste/pasteSourceValidations/isWordDesktopDocument.d.ts +8 -0
- package/lib-amd/paste/pasteSourceValidations/isWordDesktopDocument.js +21 -0
- package/lib-amd/paste/pasteSourceValidations/isWordDesktopDocument.js.map +1 -0
- package/lib-amd/paste/pasteSourceValidations/shouldConvertToSingleImage.d.ts +9 -0
- package/lib-amd/paste/pasteSourceValidations/shouldConvertToSingleImage.js +21 -0
- package/lib-amd/paste/pasteSourceValidations/shouldConvertToSingleImage.js.map +1 -0
- package/lib-amd/paste/utils/addParser.d.ts +5 -0
- package/lib-amd/paste/utils/addParser.js +19 -0
- package/lib-amd/paste/utils/addParser.js.map +1 -0
- package/lib-amd/paste/utils/deprecatedColorParser.d.ts +5 -0
- package/lib-amd/paste/utils/deprecatedColorParser.js +21 -0
- package/lib-amd/paste/utils/deprecatedColorParser.js.map +1 -0
- package/lib-amd/paste/utils/getStyles.d.ts +6 -0
- package/lib-amd/paste/utils/getStyles.js +25 -0
- package/lib-amd/paste/utils/getStyles.js.map +1 -0
- package/lib-amd/paste/utils/linkParser.d.ts +5 -0
- package/lib-amd/paste/utils/linkParser.js +29 -0
- package/lib-amd/paste/utils/linkParser.js.map +1 -0
- package/lib-amd/paste/utils/setProcessor.d.ts +5 -0
- package/lib-amd/paste/utils/setProcessor.js +16 -0
- package/lib-amd/paste/utils/setProcessor.js.map +1 -0
- package/lib-mjs/edit/ContentModelEditPlugin.d.ts +35 -0
- package/lib-mjs/edit/ContentModelEditPlugin.js +68 -0
- package/lib-mjs/edit/ContentModelEditPlugin.js.map +1 -0
- package/lib-mjs/edit/deleteSteps/deleteAllSegmentBefore.d.ts +5 -0
- package/lib-mjs/edit/deleteSteps/deleteAllSegmentBefore.js +16 -0
- package/lib-mjs/edit/deleteSteps/deleteAllSegmentBefore.js.map +1 -0
- package/lib-mjs/edit/deleteSteps/deleteCollapsedSelection.d.ts +9 -0
- package/lib-mjs/edit/deleteSteps/deleteCollapsedSelection.js +88 -0
- package/lib-mjs/edit/deleteSteps/deleteCollapsedSelection.js.map +1 -0
- package/lib-mjs/edit/deleteSteps/deleteWordSelection.d.ts +9 -0
- package/lib-mjs/edit/deleteSteps/deleteWordSelection.js +168 -0
- package/lib-mjs/edit/deleteSteps/deleteWordSelection.js.map +1 -0
- package/lib-mjs/edit/handleKeyboardEventCommon.d.ts +15 -0
- package/lib-mjs/edit/handleKeyboardEventCommon.js +49 -0
- package/lib-mjs/edit/handleKeyboardEventCommon.js.map +1 -0
- package/lib-mjs/edit/keyboardDelete.d.ts +9 -0
- package/lib-mjs/edit/keyboardDelete.js +60 -0
- package/lib-mjs/edit/keyboardDelete.js.map +1 -0
- package/lib-mjs/edit/utils/getLeafSiblingBlock.d.ts +23 -0
- package/lib-mjs/edit/utils/getLeafSiblingBlock.js +72 -0
- package/lib-mjs/edit/utils/getLeafSiblingBlock.js.map +1 -0
- package/lib-mjs/index.d.ts +2 -0
- package/lib-mjs/index.js +3 -0
- package/lib-mjs/index.js.map +1 -0
- package/lib-mjs/paste/ContentModelPastePlugin.d.ts +42 -0
- package/lib-mjs/paste/ContentModelPastePlugin.js +146 -0
- package/lib-mjs/paste/ContentModelPastePlugin.js.map +1 -0
- package/lib-mjs/paste/Excel/processPastedContentFromExcel.d.ts +13 -0
- package/lib-mjs/paste/Excel/processPastedContentFromExcel.js +78 -0
- package/lib-mjs/paste/Excel/processPastedContentFromExcel.js.map +1 -0
- package/lib-mjs/paste/PowerPoint/processPastedContentFromPowerPoint.d.ts +7 -0
- package/lib-mjs/paste/PowerPoint/processPastedContentFromPowerPoint.js +16 -0
- package/lib-mjs/paste/PowerPoint/processPastedContentFromPowerPoint.js.map +1 -0
- package/lib-mjs/paste/WacComponents/processPastedContentWacComponents.d.ts +9 -0
- package/lib-mjs/paste/WacComponents/processPastedContentWacComponents.js +204 -0
- package/lib-mjs/paste/WacComponents/processPastedContentWacComponents.js.map +1 -0
- package/lib-mjs/paste/WordDesktop/processPastedContentFromWordDesktop.d.ts +12 -0
- package/lib-mjs/paste/WordDesktop/processPastedContentFromWordDesktop.js +65 -0
- package/lib-mjs/paste/WordDesktop/processPastedContentFromWordDesktop.js.map +1 -0
- package/lib-mjs/paste/WordDesktop/processWordComments.d.ts +7 -0
- package/lib-mjs/paste/WordDesktop/processWordComments.js +18 -0
- package/lib-mjs/paste/WordDesktop/processWordComments.js.map +1 -0
- package/lib-mjs/paste/WordDesktop/processWordLists.d.ts +10 -0
- package/lib-mjs/paste/WordDesktop/processWordLists.js +151 -0
- package/lib-mjs/paste/WordDesktop/processWordLists.js.map +1 -0
- package/lib-mjs/paste/pasteSourceValidations/constants.d.ts +17 -0
- package/lib-mjs/paste/pasteSourceValidations/constants.js +19 -0
- package/lib-mjs/paste/pasteSourceValidations/constants.js.map +1 -0
- package/lib-mjs/paste/pasteSourceValidations/documentContainWacElements.d.ts +8 -0
- package/lib-mjs/paste/pasteSourceValidations/documentContainWacElements.js +21 -0
- package/lib-mjs/paste/pasteSourceValidations/documentContainWacElements.js.map +1 -0
- package/lib-mjs/paste/pasteSourceValidations/getPasteSource.d.ts +27 -0
- package/lib-mjs/paste/pasteSourceValidations/getPasteSource.js +40 -0
- package/lib-mjs/paste/pasteSourceValidations/getPasteSource.js.map +1 -0
- package/lib-mjs/paste/pasteSourceValidations/isExcelDesktopDocument.d.ts +8 -0
- package/lib-mjs/paste/pasteSourceValidations/isExcelDesktopDocument.js +13 -0
- package/lib-mjs/paste/pasteSourceValidations/isExcelDesktopDocument.js.map +1 -0
- package/lib-mjs/paste/pasteSourceValidations/isExcelOnlineDocument.d.ts +8 -0
- package/lib-mjs/paste/pasteSourceValidations/isExcelOnlineDocument.js +15 -0
- package/lib-mjs/paste/pasteSourceValidations/isExcelOnlineDocument.js.map +1 -0
- package/lib-mjs/paste/pasteSourceValidations/isGoogleSheetDocument.d.ts +8 -0
- package/lib-mjs/paste/pasteSourceValidations/isGoogleSheetDocument.js +11 -0
- package/lib-mjs/paste/pasteSourceValidations/isGoogleSheetDocument.js.map +1 -0
- package/lib-mjs/paste/pasteSourceValidations/isPowerPointDesktopDocument.d.ts +8 -0
- package/lib-mjs/paste/pasteSourceValidations/isPowerPointDesktopDocument.js +11 -0
- package/lib-mjs/paste/pasteSourceValidations/isPowerPointDesktopDocument.js.map +1 -0
- package/lib-mjs/paste/pasteSourceValidations/isWordDesktopDocument.d.ts +8 -0
- package/lib-mjs/paste/pasteSourceValidations/isWordDesktopDocument.js +15 -0
- package/lib-mjs/paste/pasteSourceValidations/isWordDesktopDocument.js.map +1 -0
- package/lib-mjs/paste/pasteSourceValidations/shouldConvertToSingleImage.d.ts +9 -0
- package/lib-mjs/paste/pasteSourceValidations/shouldConvertToSingleImage.js +15 -0
- package/lib-mjs/paste/pasteSourceValidations/shouldConvertToSingleImage.js.map +1 -0
- package/lib-mjs/paste/utils/addParser.d.ts +5 -0
- package/lib-mjs/paste/utils/addParser.js +14 -0
- package/lib-mjs/paste/utils/addParser.js.map +1 -0
- package/lib-mjs/paste/utils/deprecatedColorParser.d.ts +5 -0
- package/lib-mjs/paste/utils/deprecatedColorParser.js +16 -0
- package/lib-mjs/paste/utils/deprecatedColorParser.js.map +1 -0
- package/lib-mjs/paste/utils/getStyles.d.ts +6 -0
- package/lib-mjs/paste/utils/getStyles.js +19 -0
- package/lib-mjs/paste/utils/getStyles.js.map +1 -0
- package/lib-mjs/paste/utils/linkParser.d.ts +5 -0
- package/lib-mjs/paste/utils/linkParser.js +24 -0
- package/lib-mjs/paste/utils/linkParser.js.map +1 -0
- package/lib-mjs/paste/utils/setProcessor.d.ts +5 -0
- package/lib-mjs/paste/utils/setProcessor.js +10 -0
- package/lib-mjs/paste/utils/setProcessor.js.map +1 -0
- package/package.json +22 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.ContentModelPastePlugin = void 0;
|
|
5
|
+
var addParser_1 = require("./utils/addParser");
|
|
6
|
+
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
7
|
+
var roosterjs_editor_dom_1 = require("roosterjs-editor-dom");
|
|
8
|
+
var deprecatedColorParser_1 = require("./utils/deprecatedColorParser");
|
|
9
|
+
var getPasteSource_1 = require("./pasteSourceValidations/getPasteSource");
|
|
10
|
+
var linkParser_1 = require("./utils/linkParser");
|
|
11
|
+
var processPastedContentFromExcel_1 = require("./Excel/processPastedContentFromExcel");
|
|
12
|
+
var processPastedContentFromPowerPoint_1 = require("./PowerPoint/processPastedContentFromPowerPoint");
|
|
13
|
+
var processPastedContentFromWordDesktop_1 = require("./WordDesktop/processPastedContentFromWordDesktop");
|
|
14
|
+
var processPastedContentWacComponents_1 = require("./WacComponents/processPastedContentWacComponents");
|
|
15
|
+
// Map old PasteType to new PasteType
|
|
16
|
+
// TODO: We can remove this once we have standalone editor
|
|
17
|
+
var PasteTypeMap = (_a = {},
|
|
18
|
+
_a[3 /* AsImage */] = 'asImage',
|
|
19
|
+
_a[1 /* AsPlainText */] = 'asPlainText',
|
|
20
|
+
_a[2 /* MergeFormat */] = 'mergeFormat',
|
|
21
|
+
_a[0 /* Normal */] = 'normal',
|
|
22
|
+
_a);
|
|
23
|
+
/**
|
|
24
|
+
* Paste plugin, handles BeforePaste event and reformat some special content, including:
|
|
25
|
+
* 1. Content copied from Word
|
|
26
|
+
* 2. Content copied from Excel
|
|
27
|
+
* 3. Content copied from Word Online or OneNote Online
|
|
28
|
+
* 4. Content copied from Power Point
|
|
29
|
+
* (This class is still under development, and may still be changed in the future with some breaking changes)
|
|
30
|
+
*/
|
|
31
|
+
var ContentModelPastePlugin = /** @class */ (function () {
|
|
32
|
+
/**
|
|
33
|
+
* Construct a new instance of Paste class
|
|
34
|
+
* @param unknownTagReplacement Replace solution of unknown tags, default behavior is to replace with SPAN
|
|
35
|
+
*/
|
|
36
|
+
function ContentModelPastePlugin(unknownTagReplacement) {
|
|
37
|
+
if (unknownTagReplacement === void 0) { unknownTagReplacement = 'SPAN'; }
|
|
38
|
+
this.unknownTagReplacement = unknownTagReplacement;
|
|
39
|
+
this.editor = null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get name of this plugin
|
|
43
|
+
*/
|
|
44
|
+
ContentModelPastePlugin.prototype.getName = function () {
|
|
45
|
+
return 'ContentModelPaste';
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* The first method that editor will call to a plugin when editor is initializing.
|
|
49
|
+
* It will pass in the editor instance, plugin should take this chance to save the
|
|
50
|
+
* editor reference so that it can call to any editor method or format API later.
|
|
51
|
+
* @param editor The editor object
|
|
52
|
+
*/
|
|
53
|
+
ContentModelPastePlugin.prototype.initialize = function (editor) {
|
|
54
|
+
// TODO: Later we may need a different interface for Content Model editor plugin
|
|
55
|
+
this.editor = editor;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* The last method that editor will call to a plugin before it is disposed.
|
|
59
|
+
* Plugin can take this chance to clear the reference to editor. After this method is
|
|
60
|
+
* called, plugin should not call to any editor method since it will result in error.
|
|
61
|
+
*/
|
|
62
|
+
ContentModelPastePlugin.prototype.dispose = function () {
|
|
63
|
+
this.editor = null;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Core method for a plugin. Once an event happens in editor, editor will call this
|
|
67
|
+
* method of each plugin to handle the event as long as the event is not handled
|
|
68
|
+
* exclusively by another plugin.
|
|
69
|
+
* @param event The event to handle:
|
|
70
|
+
*/
|
|
71
|
+
ContentModelPastePlugin.prototype.onPluginEvent = function (event) {
|
|
72
|
+
if (!this.editor || event.eventType != 10 /* BeforePaste */) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
var ev = event;
|
|
76
|
+
if (!ev.domToModelOption) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
var pasteSource = (0, getPasteSource_1.getPasteSource)(ev, false);
|
|
80
|
+
var pasteType = PasteTypeMap[ev.pasteType];
|
|
81
|
+
switch (pasteSource) {
|
|
82
|
+
case 'wordDesktop':
|
|
83
|
+
(0, processPastedContentFromWordDesktop_1.processPastedContentFromWordDesktop)(ev);
|
|
84
|
+
break;
|
|
85
|
+
case 'wacComponents':
|
|
86
|
+
(0, processPastedContentWacComponents_1.processPastedContentWacComponents)(ev);
|
|
87
|
+
break;
|
|
88
|
+
case 'excelOnline':
|
|
89
|
+
case 'excelDesktop':
|
|
90
|
+
if (pasteType === 'normal' || pasteType === 'mergeFormat') {
|
|
91
|
+
// Handle HTML copied from Excel
|
|
92
|
+
(0, processPastedContentFromExcel_1.processPastedContentFromExcel)(ev, this.editor.getTrustedHTMLHandler());
|
|
93
|
+
}
|
|
94
|
+
break;
|
|
95
|
+
case 'googleSheets':
|
|
96
|
+
ev.sanitizingOption.additionalTagReplacements["google-sheets-html-origin" /* GOOGLE_SHEET_NODE_NAME */] = '*';
|
|
97
|
+
break;
|
|
98
|
+
case 'powerPointDesktop':
|
|
99
|
+
(0, processPastedContentFromPowerPoint_1.processPastedContentFromPowerPoint)(ev, this.editor.getTrustedHTMLHandler());
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
(0, addParser_1.default)(ev.domToModelOption, 'link', linkParser_1.parseLink);
|
|
103
|
+
(0, addParser_1.default)(ev.domToModelOption, 'tableCell', deprecatedColorParser_1.deprecatedBorderColorParser);
|
|
104
|
+
(0, addParser_1.default)(ev.domToModelOption, 'tableCell', tableBorderParser);
|
|
105
|
+
(0, addParser_1.default)(ev.domToModelOption, 'table', deprecatedColorParser_1.deprecatedBorderColorParser);
|
|
106
|
+
sanitizeBlockStyles(ev.sanitizingOption);
|
|
107
|
+
if (pasteType === 'mergeFormat') {
|
|
108
|
+
(0, addParser_1.default)(ev.domToModelOption, 'block', blockElementParser);
|
|
109
|
+
(0, addParser_1.default)(ev.domToModelOption, 'listLevel', blockElementParser);
|
|
110
|
+
}
|
|
111
|
+
ev.sanitizingOption.unknownTagReplacement = this.unknownTagReplacement;
|
|
112
|
+
};
|
|
113
|
+
return ContentModelPastePlugin;
|
|
114
|
+
}());
|
|
115
|
+
exports.ContentModelPastePlugin = ContentModelPastePlugin;
|
|
116
|
+
/**
|
|
117
|
+
* For block elements that have background color style, remove the background color when user selects the merge current format
|
|
118
|
+
* paste option
|
|
119
|
+
*/
|
|
120
|
+
var blockElementParser = function (format, element) {
|
|
121
|
+
if (element.style.backgroundColor) {
|
|
122
|
+
delete format.backgroundColor;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
function sanitizeBlockStyles(sanitizingOption) {
|
|
126
|
+
(0, roosterjs_editor_dom_1.chainSanitizerCallback)(sanitizingOption.cssStyleCallbacks, 'display', function (value) {
|
|
127
|
+
return value != 'flex'; // return whether we keep the style
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
var ElementBorderKeys = new Map([
|
|
131
|
+
['borderTop', { w: 'borderTopWidth', s: 'borderTopStyle', c: 'borderTopColor' }],
|
|
132
|
+
['borderRight', { w: 'borderRightWidth', s: 'borderRightStyle', c: 'borderRightColor' }],
|
|
133
|
+
['borderBottom', { w: 'borderBottomWidth', s: 'borderBottomStyle', c: 'borderBottomColor' }],
|
|
134
|
+
['borderLeft', { w: 'borderLeftWidth', s: 'borderLeftStyle', c: 'borderLeftColor' }],
|
|
135
|
+
]);
|
|
136
|
+
function tableBorderParser(format, element) {
|
|
137
|
+
roosterjs_content_model_dom_1.BorderKeys.forEach(function (key) {
|
|
138
|
+
if (!format[key]) {
|
|
139
|
+
var styleSet = ElementBorderKeys.get(key);
|
|
140
|
+
if (styleSet &&
|
|
141
|
+
element.style[styleSet.w] &&
|
|
142
|
+
element.style[styleSet.s] &&
|
|
143
|
+
!element.style[styleSet.c]) {
|
|
144
|
+
format[key] = element.style[styleSet.w] + " " + element.style[styleSet.s];
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=ContentModelPastePlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContentModelPastePlugin.js","sourceRoot":"","sources":["../../../../packages-content-model/roosterjs-content-model-plugins/lib/paste/ContentModelPastePlugin.ts"],"names":[],"mappings":";;;;AAAA,+CAA0C;AAC1C,2EAAyD;AACzD,6DAA8D;AAC9D,uEAA4E;AAC5E,0EAAyE;AACzE,iDAA+C;AAG/C,uFAAsF;AACtF,sGAAqG;AACrG,yGAAwG;AACxG,uGAAsG;AAiBtG,qCAAqC;AACrC,0DAA0D;AAC1D,IAAM,YAAY;IACd,sBAAwB,SAAS;IACjC,0BAA4B,aAAa;IACzC,0BAA4B,aAAa;IACzC,qBAAuB,QAAQ;OAClC,CAAC;AAEF;;;;;;;GAOG;AACH;IAGI;;;OAGG;IACH,iCAAoB,qBAAsC;QAAtC,sCAAA,EAAA,8BAAsC;QAAtC,0BAAqB,GAArB,qBAAqB,CAAiB;QANlD,WAAM,GAA+B,IAAI,CAAC;IAMW,CAAC;IAE9D;;OAEG;IACH,yCAAO,GAAP;QACI,OAAO,mBAAmB,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACH,4CAAU,GAAV,UAAW,MAAe;QACtB,gFAAgF;QAChF,IAAI,CAAC,MAAM,GAAG,MAA6B,CAAC;IAChD,CAAC;IAED;;;;OAIG;IACH,yCAAO,GAAP;QACI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACvB,CAAC;IAED;;;;;OAKG;IACH,+CAAa,GAAb,UAAc,KAAkB;QAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,SAAS,wBAA+B,EAAE;YAChE,OAAO;SACV;QAED,IAAM,EAAE,GAAG,KAAqC,CAAC;QAEjD,IAAI,CAAC,EAAE,CAAC,gBAAgB,EAAE;YACtB,OAAO;SACV;QAED,IAAM,WAAW,GAAG,IAAA,+BAAc,EAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAC9C,IAAM,SAAS,GAAG,YAAY,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;QAE7C,QAAQ,WAAW,EAAE;YACjB,KAAK,aAAa;gBACd,IAAA,yEAAmC,EAAC,EAAE,CAAC,CAAC;gBACxC,MAAM;YACV,KAAK,eAAe;gBAChB,IAAA,qEAAiC,EAAC,EAAE,CAAC,CAAC;gBACtC,MAAM;YACV,KAAK,aAAa,CAAC;YACnB,KAAK,cAAc;gBACf,IAAI,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,aAAa,EAAE;oBACvD,gCAAgC;oBAChC,IAAA,6DAA6B,EAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC;iBAC1E;gBACD,MAAM;YACV,KAAK,cAAc;gBACf,EAAE,CAAC,gBAAgB,CAAC,yBAAyB,0DAE5C,GAAG,GAAG,CAAC;gBACR,MAAM;YACV,KAAK,mBAAmB;gBACpB,IAAA,uEAAkC,EAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC;gBAC5E,MAAM;SACb;QAED,IAAA,mBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,MAAM,EAAE,sBAAS,CAAC,CAAC;QAClD,IAAA,mBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,WAAW,EAAE,mDAA2B,CAAC,CAAC;QACzE,IAAA,mBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAC/D,IAAA,mBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,OAAO,EAAE,mDAA2B,CAAC,CAAC;QACrE,mBAAmB,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC;QAEzC,IAAI,SAAS,KAAK,aAAa,EAAE;YAC7B,IAAA,mBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC;YAC5D,IAAA,mBAAS,EAAC,EAAE,CAAC,gBAAgB,EAAE,WAAW,EAAE,kBAAkB,CAAC,CAAC;SACnE;QAED,EAAE,CAAC,gBAAgB,CAAC,qBAAqB,GAAG,IAAI,CAAC,qBAAqB,CAAC;IAC3E,CAAC;IACL,8BAAC;AAAD,CAAC,AA7FD,IA6FC;AA7FY,0DAAuB;AA+FpC;;;GAGG;AACH,IAAM,kBAAkB,GAA0C,UAC9D,MAA+B,EAC/B,OAAoB;IAEpB,IAAI,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE;QAC/B,OAAO,MAAM,CAAC,eAAe,CAAC;KACjC;AACL,CAAC,CAAC;AAEF,SAAS,mBAAmB,CAAC,gBAAgD;IACzE,IAAA,6CAAsB,EAAC,gBAAgB,CAAC,iBAAiB,EAAE,SAAS,EAAE,UAAC,KAAa;QAChF,OAAO,KAAK,IAAI,MAAM,CAAC,CAAC,mCAAmC;IAC/D,CAAC,CAAC,CAAC;AACP,CAAC;AAED,IAAM,iBAAiB,GAAG,IAAI,GAAG,CAO/B;IACE,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAChF,CAAC,aAAa,EAAE,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACxF,CAAC,cAAc,EAAE,EAAE,CAAC,EAAE,mBAAmB,EAAE,CAAC,EAAE,mBAAmB,EAAE,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAC5F,CAAC,YAAY,EAAE,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACvF,CAAC,CAAC;AAEH,SAAS,iBAAiB,CAAC,MAAmC,EAAE,OAAoB;IAChF,wCAAU,CAAC,OAAO,CAAC,UAAA,GAAG;QAClB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;YACd,IAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC5C,IACI,QAAQ;gBACR,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACzB,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACzB,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAC5B;gBACE,MAAM,CAAC,GAAG,CAAC,GAAM,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAG,CAAC;aAC7E;SACJ;IACL,CAAC,CAAC,CAAC;AACP,CAAC","sourcesContent":["import addParser from './utils/addParser';\nimport { BorderKeys } from 'roosterjs-content-model-dom';\nimport { chainSanitizerCallback } from 'roosterjs-editor-dom';\nimport { deprecatedBorderColorParser } from './utils/deprecatedColorParser';\nimport { getPasteSource } from './pasteSourceValidations/getPasteSource';\nimport { parseLink } from './utils/linkParser';\nimport { PastePropertyNames } from './pasteSourceValidations/constants';\nimport { PasteType as OldPasteType, PluginEventType } from 'roosterjs-editor-types';\nimport { processPastedContentFromExcel } from './Excel/processPastedContentFromExcel';\nimport { processPastedContentFromPowerPoint } from './PowerPoint/processPastedContentFromPowerPoint';\nimport { processPastedContentFromWordDesktop } from './WordDesktop/processPastedContentFromWordDesktop';\nimport { processPastedContentWacComponents } from './WacComponents/processPastedContentWacComponents';\nimport type { IContentModelEditor } from 'roosterjs-content-model-editor';\nimport type {\n BorderFormat,\n ContentModelBeforePasteEvent,\n ContentModelBlockFormat,\n ContentModelTableCellFormat,\n FormatParser,\n PasteType,\n} from 'roosterjs-content-model-types';\nimport type {\n EditorPlugin,\n HtmlSanitizerOptions,\n IEditor,\n PluginEvent,\n} from 'roosterjs-editor-types';\n\n// Map old PasteType to new PasteType\n// TODO: We can remove this once we have standalone editor\nconst PasteTypeMap: Record<OldPasteType, PasteType> = {\n [OldPasteType.AsImage]: 'asImage',\n [OldPasteType.AsPlainText]: 'asPlainText',\n [OldPasteType.MergeFormat]: 'mergeFormat',\n [OldPasteType.Normal]: 'normal',\n};\n\n/**\n * Paste plugin, handles BeforePaste event and reformat some special content, including:\n * 1. Content copied from Word\n * 2. Content copied from Excel\n * 3. Content copied from Word Online or OneNote Online\n * 4. Content copied from Power Point\n * (This class is still under development, and may still be changed in the future with some breaking changes)\n */\nexport class ContentModelPastePlugin implements EditorPlugin {\n private editor: IContentModelEditor | null = null;\n\n /**\n * Construct a new instance of Paste class\n * @param unknownTagReplacement Replace solution of unknown tags, default behavior is to replace with SPAN\n */\n constructor(private unknownTagReplacement: string = 'SPAN') {}\n\n /**\n * Get name of this plugin\n */\n getName() {\n return 'ContentModelPaste';\n }\n\n /**\n * The first method that editor will call to a plugin when editor is initializing.\n * It will pass in the editor instance, plugin should take this chance to save the\n * editor reference so that it can call to any editor method or format API later.\n * @param editor The editor object\n */\n initialize(editor: IEditor) {\n // TODO: Later we may need a different interface for Content Model editor plugin\n this.editor = editor as IContentModelEditor;\n }\n\n /**\n * The last method that editor will call to a plugin before it is disposed.\n * Plugin can take this chance to clear the reference to editor. After this method is\n * called, plugin should not call to any editor method since it will result in error.\n */\n dispose() {\n this.editor = null;\n }\n\n /**\n * Core method for a plugin. Once an event happens in editor, editor will call this\n * method of each plugin to handle the event as long as the event is not handled\n * exclusively by another plugin.\n * @param event The event to handle:\n */\n onPluginEvent(event: PluginEvent) {\n if (!this.editor || event.eventType != PluginEventType.BeforePaste) {\n return;\n }\n\n const ev = event as ContentModelBeforePasteEvent;\n\n if (!ev.domToModelOption) {\n return;\n }\n\n const pasteSource = getPasteSource(ev, false);\n const pasteType = PasteTypeMap[ev.pasteType];\n\n switch (pasteSource) {\n case 'wordDesktop':\n processPastedContentFromWordDesktop(ev);\n break;\n case 'wacComponents':\n processPastedContentWacComponents(ev);\n break;\n case 'excelOnline':\n case 'excelDesktop':\n if (pasteType === 'normal' || pasteType === 'mergeFormat') {\n // Handle HTML copied from Excel\n processPastedContentFromExcel(ev, this.editor.getTrustedHTMLHandler());\n }\n break;\n case 'googleSheets':\n ev.sanitizingOption.additionalTagReplacements[\n PastePropertyNames.GOOGLE_SHEET_NODE_NAME\n ] = '*';\n break;\n case 'powerPointDesktop':\n processPastedContentFromPowerPoint(ev, this.editor.getTrustedHTMLHandler());\n break;\n }\n\n addParser(ev.domToModelOption, 'link', parseLink);\n addParser(ev.domToModelOption, 'tableCell', deprecatedBorderColorParser);\n addParser(ev.domToModelOption, 'tableCell', tableBorderParser);\n addParser(ev.domToModelOption, 'table', deprecatedBorderColorParser);\n sanitizeBlockStyles(ev.sanitizingOption);\n\n if (pasteType === 'mergeFormat') {\n addParser(ev.domToModelOption, 'block', blockElementParser);\n addParser(ev.domToModelOption, 'listLevel', blockElementParser);\n }\n\n ev.sanitizingOption.unknownTagReplacement = this.unknownTagReplacement;\n }\n}\n\n/**\n * For block elements that have background color style, remove the background color when user selects the merge current format\n * paste option\n */\nconst blockElementParser: FormatParser<ContentModelBlockFormat> = (\n format: ContentModelBlockFormat,\n element: HTMLElement\n) => {\n if (element.style.backgroundColor) {\n delete format.backgroundColor;\n }\n};\n\nfunction sanitizeBlockStyles(sanitizingOption: Required<HtmlSanitizerOptions>) {\n chainSanitizerCallback(sanitizingOption.cssStyleCallbacks, 'display', (value: string) => {\n return value != 'flex'; // return whether we keep the style\n });\n}\n\nconst ElementBorderKeys = new Map<\n keyof BorderFormat,\n {\n c: keyof CSSStyleDeclaration;\n s: keyof CSSStyleDeclaration;\n w: keyof CSSStyleDeclaration;\n }\n>([\n ['borderTop', { w: 'borderTopWidth', s: 'borderTopStyle', c: 'borderTopColor' }],\n ['borderRight', { w: 'borderRightWidth', s: 'borderRightStyle', c: 'borderRightColor' }],\n ['borderBottom', { w: 'borderBottomWidth', s: 'borderBottomStyle', c: 'borderBottomColor' }],\n ['borderLeft', { w: 'borderLeftWidth', s: 'borderLeftStyle', c: 'borderLeftColor' }],\n]);\n\nfunction tableBorderParser(format: ContentModelTableCellFormat, element: HTMLElement): void {\n BorderKeys.forEach(key => {\n if (!format[key]) {\n const styleSet = ElementBorderKeys.get(key);\n if (\n styleSet &&\n element.style[styleSet.w] &&\n element.style[styleSet.s] &&\n !element.style[styleSet.c]\n ) {\n format[key] = `${element.style[styleSet.w]} ${element.style[styleSet.s]}`;\n }\n }\n });\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TrustedHTMLHandler } from 'roosterjs-editor-types';
|
|
2
|
+
import type { ContentModelBeforePasteEvent } from 'roosterjs-content-model-types';
|
|
3
|
+
/**
|
|
4
|
+
* @internal
|
|
5
|
+
* Convert pasted content from Excel, add borders when source doc doesn't have a border
|
|
6
|
+
* @param event The BeforePaste event
|
|
7
|
+
*/
|
|
8
|
+
export declare function processPastedContentFromExcel(event: ContentModelBeforePasteEvent, trustedHTMLHandler: TrustedHTMLHandler): void;
|
|
9
|
+
/**
|
|
10
|
+
* @internal Export for test only
|
|
11
|
+
* @param html Source html
|
|
12
|
+
*/
|
|
13
|
+
export declare function excelHandler(html: string, htmlBefore: string): string;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.excelHandler = exports.processPastedContentFromExcel = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var addParser_1 = require("../utils/addParser");
|
|
6
|
+
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
7
|
+
var setProcessor_1 = require("../utils/setProcessor");
|
|
8
|
+
var LAST_TD_END_REGEX = /<\/\s*td\s*>((?!<\/\s*tr\s*>)[\s\S])*$/i;
|
|
9
|
+
var LAST_TR_END_REGEX = /<\/\s*tr\s*>((?!<\/\s*table\s*>)[\s\S])*$/i;
|
|
10
|
+
var LAST_TR_REGEX = /<tr[^>]*>[^<]*/i;
|
|
11
|
+
var LAST_TABLE_REGEX = /<table[^>]*>[^<]*/i;
|
|
12
|
+
var DEFAULT_BORDER_STYLE = 'solid 1px #d4d4d4';
|
|
13
|
+
/**
|
|
14
|
+
* @internal
|
|
15
|
+
* Convert pasted content from Excel, add borders when source doc doesn't have a border
|
|
16
|
+
* @param event The BeforePaste event
|
|
17
|
+
*/
|
|
18
|
+
function processPastedContentFromExcel(event, trustedHTMLHandler) {
|
|
19
|
+
var fragment = event.fragment, htmlBefore = event.htmlBefore, clipboardData = event.clipboardData;
|
|
20
|
+
var html = clipboardData.html ? excelHandler(clipboardData.html, htmlBefore) : undefined;
|
|
21
|
+
if (html && clipboardData.html != html) {
|
|
22
|
+
var doc = new DOMParser().parseFromString(trustedHTMLHandler(html), 'text/html');
|
|
23
|
+
(0, roosterjs_content_model_dom_1.moveChildNodes)(fragment, doc === null || doc === void 0 ? void 0 : doc.body);
|
|
24
|
+
}
|
|
25
|
+
// For Excel Online
|
|
26
|
+
var firstChild = fragment.firstChild;
|
|
27
|
+
if ((0, roosterjs_content_model_dom_1.isNodeOfType)(firstChild, 'ELEMENT_NODE') &&
|
|
28
|
+
firstChild.tagName == 'div' &&
|
|
29
|
+
firstChild.firstChild) {
|
|
30
|
+
var tableFound = Array.from(firstChild.childNodes).every(function (child) {
|
|
31
|
+
// Tables pasted from Excel Online should be of the format: 0 to N META tags and 1 TABLE tag
|
|
32
|
+
var tagName = (0, roosterjs_content_model_dom_1.isNodeOfType)(child, 'ELEMENT_NODE') && child.tagName;
|
|
33
|
+
return tagName == 'META'
|
|
34
|
+
? true
|
|
35
|
+
: tagName == 'TABLE'
|
|
36
|
+
? child == firstChild.lastChild
|
|
37
|
+
: false;
|
|
38
|
+
});
|
|
39
|
+
// Extract Table from Div
|
|
40
|
+
if (tableFound && firstChild.lastChild) {
|
|
41
|
+
event.fragment.replaceChildren(firstChild.lastChild);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
(0, addParser_1.default)(event.domToModelOption, 'tableCell', function (format, element) {
|
|
45
|
+
if (element.style.borderStyle === 'none') {
|
|
46
|
+
format.borderBottom = DEFAULT_BORDER_STYLE;
|
|
47
|
+
format.borderLeft = DEFAULT_BORDER_STYLE;
|
|
48
|
+
format.borderRight = DEFAULT_BORDER_STYLE;
|
|
49
|
+
format.borderTop = DEFAULT_BORDER_STYLE;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
(0, setProcessor_1.setProcessor)(event.domToModelOption, 'child', function (group, element, context) {
|
|
53
|
+
var segmentFormat = (0, tslib_1.__assign)({}, context.segmentFormat);
|
|
54
|
+
if (group.blockGroupType === 'TableCell' && group.format.textColor) {
|
|
55
|
+
context.segmentFormat.textColor = group.format.textColor;
|
|
56
|
+
}
|
|
57
|
+
context.defaultElementProcessors.child(group, element, context);
|
|
58
|
+
if (group.blockGroupType === 'TableCell' && group.format.textColor) {
|
|
59
|
+
context.segmentFormat = segmentFormat;
|
|
60
|
+
delete group.format.textColor;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
exports.processPastedContentFromExcel = processPastedContentFromExcel;
|
|
65
|
+
/**
|
|
66
|
+
* @internal Export for test only
|
|
67
|
+
* @param html Source html
|
|
68
|
+
*/
|
|
69
|
+
function excelHandler(html, htmlBefore) {
|
|
70
|
+
if (html.match(LAST_TD_END_REGEX)) {
|
|
71
|
+
var trMatch = htmlBefore.match(LAST_TR_REGEX);
|
|
72
|
+
var tr = trMatch ? trMatch[0] : '<TR>';
|
|
73
|
+
html = tr + html + '</TR>';
|
|
74
|
+
}
|
|
75
|
+
if (html.match(LAST_TR_END_REGEX)) {
|
|
76
|
+
var tableMatch = htmlBefore.match(LAST_TABLE_REGEX);
|
|
77
|
+
var table = tableMatch ? tableMatch[0] : '<TABLE>';
|
|
78
|
+
html = table + html + '</TABLE>';
|
|
79
|
+
}
|
|
80
|
+
return html;
|
|
81
|
+
}
|
|
82
|
+
exports.excelHandler = excelHandler;
|
|
83
|
+
//# sourceMappingURL=processPastedContentFromExcel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processPastedContentFromExcel.js","sourceRoot":"","sources":["../../../../../packages-content-model/roosterjs-content-model-plugins/lib/paste/Excel/processPastedContentFromExcel.ts"],"names":[],"mappings":"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","sourcesContent":["import addParser from '../utils/addParser';\nimport { isNodeOfType, moveChildNodes } from 'roosterjs-content-model-dom';\nimport { setProcessor } from '../utils/setProcessor';\nimport type { TrustedHTMLHandler } from 'roosterjs-editor-types';\nimport type { ContentModelBeforePasteEvent } from 'roosterjs-content-model-types';\n\nconst LAST_TD_END_REGEX = /<\\/\\s*td\\s*>((?!<\\/\\s*tr\\s*>)[\\s\\S])*$/i;\nconst LAST_TR_END_REGEX = /<\\/\\s*tr\\s*>((?!<\\/\\s*table\\s*>)[\\s\\S])*$/i;\nconst LAST_TR_REGEX = /<tr[^>]*>[^<]*/i;\nconst LAST_TABLE_REGEX = /<table[^>]*>[^<]*/i;\nconst DEFAULT_BORDER_STYLE = 'solid 1px #d4d4d4';\n\n/**\n * @internal\n * Convert pasted content from Excel, add borders when source doc doesn't have a border\n * @param event The BeforePaste event\n */\n\nexport function processPastedContentFromExcel(\n event: ContentModelBeforePasteEvent,\n trustedHTMLHandler: TrustedHTMLHandler\n) {\n const { fragment, htmlBefore, clipboardData } = event;\n const html = clipboardData.html ? excelHandler(clipboardData.html, htmlBefore) : undefined;\n\n if (html && clipboardData.html != html) {\n const doc = new DOMParser().parseFromString(trustedHTMLHandler(html), 'text/html');\n moveChildNodes(fragment, doc?.body);\n }\n\n // For Excel Online\n const firstChild = fragment.firstChild;\n if (\n isNodeOfType(firstChild, 'ELEMENT_NODE') &&\n firstChild.tagName == 'div' &&\n firstChild.firstChild\n ) {\n const tableFound = Array.from(firstChild.childNodes).every((child: Node) => {\n // Tables pasted from Excel Online should be of the format: 0 to N META tags and 1 TABLE tag\n const tagName = isNodeOfType(child, 'ELEMENT_NODE') && child.tagName;\n\n return tagName == 'META'\n ? true\n : tagName == 'TABLE'\n ? child == firstChild.lastChild\n : false;\n });\n\n // Extract Table from Div\n if (tableFound && firstChild.lastChild) {\n event.fragment.replaceChildren(firstChild.lastChild);\n }\n }\n\n addParser(event.domToModelOption, 'tableCell', (format, element) => {\n if (element.style.borderStyle === 'none') {\n format.borderBottom = DEFAULT_BORDER_STYLE;\n format.borderLeft = DEFAULT_BORDER_STYLE;\n format.borderRight = DEFAULT_BORDER_STYLE;\n format.borderTop = DEFAULT_BORDER_STYLE;\n }\n });\n\n setProcessor(event.domToModelOption, 'child', (group, element, context) => {\n const segmentFormat = { ...context.segmentFormat };\n if (group.blockGroupType === 'TableCell' && group.format.textColor) {\n context.segmentFormat.textColor = group.format.textColor;\n }\n\n context.defaultElementProcessors.child(group, element, context);\n\n if (group.blockGroupType === 'TableCell' && group.format.textColor) {\n context.segmentFormat = segmentFormat;\n delete group.format.textColor;\n }\n });\n}\n\n/**\n * @internal Export for test only\n * @param html Source html\n */\n\nexport function excelHandler(html: string, htmlBefore: string): string {\n if (html.match(LAST_TD_END_REGEX)) {\n const trMatch = htmlBefore.match(LAST_TR_REGEX);\n const tr = trMatch ? trMatch[0] : '<TR>';\n html = tr + html + '</TR>';\n }\n if (html.match(LAST_TR_END_REGEX)) {\n const tableMatch = htmlBefore.match(LAST_TABLE_REGEX);\n const table = tableMatch ? tableMatch[0] : '<TABLE>';\n html = table + html + '</TABLE>';\n }\n\n return html;\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { BeforePasteEvent, TrustedHTMLHandler } from 'roosterjs-editor-types';
|
|
2
|
+
/**
|
|
3
|
+
* @internal
|
|
4
|
+
* Convert pasted content from PowerPoint
|
|
5
|
+
* @param event The BeforePaste event
|
|
6
|
+
*/
|
|
7
|
+
export declare function processPastedContentFromPowerPoint(event: BeforePasteEvent, trustedHTMLHandler: TrustedHTMLHandler): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.processPastedContentFromPowerPoint = void 0;
|
|
4
|
+
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
5
|
+
/**
|
|
6
|
+
* @internal
|
|
7
|
+
* Convert pasted content from PowerPoint
|
|
8
|
+
* @param event The BeforePaste event
|
|
9
|
+
*/
|
|
10
|
+
function processPastedContentFromPowerPoint(event, trustedHTMLHandler) {
|
|
11
|
+
var fragment = event.fragment, clipboardData = event.clipboardData;
|
|
12
|
+
if (clipboardData.html && !clipboardData.text && clipboardData.image) {
|
|
13
|
+
// It is possible that PowerPoint copied both image and HTML but not plain text.
|
|
14
|
+
// We always prefer HTML if any.
|
|
15
|
+
var doc = new DOMParser().parseFromString(trustedHTMLHandler(clipboardData.html), 'text/html');
|
|
16
|
+
(0, roosterjs_content_model_dom_1.moveChildNodes)(fragment, doc === null || doc === void 0 ? void 0 : doc.body);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.processPastedContentFromPowerPoint = processPastedContentFromPowerPoint;
|
|
20
|
+
//# sourceMappingURL=processPastedContentFromPowerPoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processPastedContentFromPowerPoint.js","sourceRoot":"","sources":["../../../../../packages-content-model/roosterjs-content-model-plugins/lib/paste/PowerPoint/processPastedContentFromPowerPoint.ts"],"names":[],"mappings":";;;AAAA,2EAA6D;AAG7D;;;;GAIG;AAEH,SAAgB,kCAAkC,CAC9C,KAAuB,EACvB,kBAAsC;IAE9B,IAAA,QAAQ,GAAoB,KAAK,SAAzB,EAAE,aAAa,GAAK,KAAK,cAAV,CAAW;IAE1C,IAAI,aAAa,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,IAAI,aAAa,CAAC,KAAK,EAAE;QAClE,gFAAgF;QAChF,gCAAgC;QAChC,IAAM,GAAG,GAAG,IAAI,SAAS,EAAE,CAAC,eAAe,CACvC,kBAAkB,CAAC,aAAa,CAAC,IAAI,CAAC,EACtC,WAAW,CACd,CAAC;QAEF,IAAA,4CAAc,EAAC,QAAQ,EAAE,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,IAAI,CAAC,CAAC;KACvC;AACL,CAAC;AAhBD,gFAgBC","sourcesContent":["import { moveChildNodes } from 'roosterjs-content-model-dom';\nimport type { BeforePasteEvent, TrustedHTMLHandler } from 'roosterjs-editor-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 trustedHTMLHandler: TrustedHTMLHandler\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 = new DOMParser().parseFromString(\n trustedHTMLHandler(clipboardData.html),\n 'text/html'\n );\n\n moveChildNodes(fragment, doc?.body);\n }\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ContentModelBeforePasteEvent } from 'roosterjs-content-model-types';
|
|
2
|
+
/**
|
|
3
|
+
* @internal
|
|
4
|
+
* Convert pasted content from Office Online
|
|
5
|
+
* Once it is known that the document is from WAC
|
|
6
|
+
* We need to remove the display property and margin from all the list item
|
|
7
|
+
* @param ev ContentModelBeforePasteEvent
|
|
8
|
+
*/
|
|
9
|
+
export declare function processPastedContentWacComponents(ev: ContentModelBeforePasteEvent): void;
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.processPastedContentWacComponents = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var addParser_1 = require("../utils/addParser");
|
|
6
|
+
var setProcessor_1 = require("../utils/setProcessor");
|
|
7
|
+
var WAC_IDENTIFY_SELECTOR = 'ul[class^="BulletListStyle"]>.OutlineElement,ol[class^="NumberListStyle"]>.OutlineElement,span.WACImageContainer,span.WACImageBorder';
|
|
8
|
+
var LIST_CONTAINER_ELEMENT_CLASS_NAME = 'ListContainerWrapper';
|
|
9
|
+
var PARAGRAPH = 'Paragraph';
|
|
10
|
+
var TABLE_CONTAINER = 'TableContainer';
|
|
11
|
+
var TEMP_ELEMENTS_CLASSES = [
|
|
12
|
+
'TableInsertRowGapBlank',
|
|
13
|
+
'TableColumnResizeHandle',
|
|
14
|
+
'TableCellTopBorderHandle',
|
|
15
|
+
'TableCellLeftBorderHandle',
|
|
16
|
+
'TableHoverColumnHandle',
|
|
17
|
+
'TableHoverRowHandle',
|
|
18
|
+
'ListMarkerWrappingSpan',
|
|
19
|
+
];
|
|
20
|
+
var CLASSES_TO_KEEP = (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([
|
|
21
|
+
'OutlineElement',
|
|
22
|
+
'NumberListStyle',
|
|
23
|
+
'WACImageContainer',
|
|
24
|
+
'ListContainerWrapper',
|
|
25
|
+
'BulletListStyle'
|
|
26
|
+
], (0, tslib_1.__read)(TEMP_ELEMENTS_CLASSES), false), [
|
|
27
|
+
'TableCellContent',
|
|
28
|
+
PARAGRAPH,
|
|
29
|
+
'WACImageContainer',
|
|
30
|
+
'WACImageBorder',
|
|
31
|
+
TABLE_CONTAINER,
|
|
32
|
+
'LineBreakBlob',
|
|
33
|
+
], false);
|
|
34
|
+
var LIST_ELEMENT_TAGS = ['UL', 'OL', 'LI'];
|
|
35
|
+
var LIST_ELEMENT_SELECTOR = LIST_ELEMENT_TAGS.join(',');
|
|
36
|
+
/**
|
|
37
|
+
* Wac components do not use sub and super tags, instead only add vertical align to a span.
|
|
38
|
+
* This parser normalize the content for content model
|
|
39
|
+
*/
|
|
40
|
+
var wacSubSuperParser = function (format, element) {
|
|
41
|
+
var verticalAlign = element.style.verticalAlign;
|
|
42
|
+
if (verticalAlign === 'super') {
|
|
43
|
+
format.superOrSubScriptSequence = 'super';
|
|
44
|
+
}
|
|
45
|
+
if (verticalAlign === 'sub') {
|
|
46
|
+
format.superOrSubScriptSequence = 'sub';
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* This processor does:
|
|
51
|
+
* 1) Remove the display and margin of the element.
|
|
52
|
+
* 2) When an element should be ignored but should handle the child elements call the default child processor.
|
|
53
|
+
* 3) Removes the End of Paragraph element to avoid empty lines, we should only remove this if the previous element of the EOP is an EmptyTextRun
|
|
54
|
+
* 4) Finally call the default processor.
|
|
55
|
+
* @returns
|
|
56
|
+
*/
|
|
57
|
+
var wacElementProcessor = function (group, element, context) {
|
|
58
|
+
var elementTag = element.tagName;
|
|
59
|
+
if (element.matches(WAC_IDENTIFY_SELECTOR)) {
|
|
60
|
+
element.style.removeProperty('display');
|
|
61
|
+
element.style.removeProperty('margin');
|
|
62
|
+
}
|
|
63
|
+
if (element.classList.contains(LIST_CONTAINER_ELEMENT_CLASS_NAME)) {
|
|
64
|
+
context.elementProcessors.child(group, element, context);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (TEMP_ELEMENTS_CLASSES.some(function (className) { return element.classList.contains(className); })) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
else if (shouldClearListContext(elementTag, element, context)) {
|
|
71
|
+
var listFormat = context.listFormat;
|
|
72
|
+
listFormat.levels = [];
|
|
73
|
+
listFormat.listParent = undefined;
|
|
74
|
+
}
|
|
75
|
+
context.defaultElementProcessors.element(group, element, context);
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* This processor calls the default list processor and then sets the correct list level and list bullet.
|
|
79
|
+
*/
|
|
80
|
+
var wacLiElementProcessor = function (group, element, context) {
|
|
81
|
+
var _a, _b, _c;
|
|
82
|
+
(_b = (_a = context.defaultElementProcessors).li) === null || _b === void 0 ? void 0 : _b.call(_a, group, element, context);
|
|
83
|
+
var listFormat = context.listFormat;
|
|
84
|
+
var listParent = listFormat.listParent;
|
|
85
|
+
if (listParent) {
|
|
86
|
+
var lastblock = listParent.blocks[listParent.blocks.length - 1];
|
|
87
|
+
if (lastblock.blockType == 'BlockGroup' &&
|
|
88
|
+
lastblock.blockGroupType == 'ListItem' &&
|
|
89
|
+
context.listFormat.listParent !== lastblock) {
|
|
90
|
+
var currentLevel = lastblock.levels[lastblock.levels.length - 1];
|
|
91
|
+
// Get item level from 'data-aria-level' attribute
|
|
92
|
+
var level = parseInt((_c = element.getAttribute('data-aria-level')) !== null && _c !== void 0 ? _c : '');
|
|
93
|
+
if (level > 0) {
|
|
94
|
+
if (level > lastblock.levels.length) {
|
|
95
|
+
while (level != lastblock.levels.length) {
|
|
96
|
+
lastblock.levels.push(currentLevel);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
lastblock.levels.splice(level, lastblock.levels.length - 1);
|
|
101
|
+
lastblock.levels[level - 1] = currentLevel;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* This parsers does:
|
|
109
|
+
* 1) Sets the display for dummy item to undefined when the current style is block.
|
|
110
|
+
* 2) Removes the Margin Left
|
|
111
|
+
*/
|
|
112
|
+
var wacListItemParser = function (format, element) {
|
|
113
|
+
if (element.style.display === 'block') {
|
|
114
|
+
format.displayForDummyItem = undefined;
|
|
115
|
+
}
|
|
116
|
+
format.marginLeft = undefined;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Wac usually adds padding to lists which is unwanted so remove it.
|
|
120
|
+
*/
|
|
121
|
+
var wacListLevelParser = function (format) {
|
|
122
|
+
format.marginLeft = undefined;
|
|
123
|
+
format.paddingLeft = undefined;
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* This function returns whether we need to clear the list format.
|
|
127
|
+
* Word Online wraps lists inside divs to have this structure:
|
|
128
|
+
*
|
|
129
|
+
* <div class='ListContainerWrapper'>
|
|
130
|
+
* <ol>...</ol>
|
|
131
|
+
* </div>
|
|
132
|
+
* <div>
|
|
133
|
+
* <p>...</p>
|
|
134
|
+
* <div>
|
|
135
|
+
* <div class='ListContainerWrapper'>
|
|
136
|
+
* <ol>...</ol>
|
|
137
|
+
* </div>
|
|
138
|
+
*
|
|
139
|
+
* So if a elements is not contained inside of a list we should clear the list context to prevent normal text to be
|
|
140
|
+
* transformed into list
|
|
141
|
+
* For the above scenario, if we do not clear the format, the content inside of the second div would be transformed to a list too.
|
|
142
|
+
*/
|
|
143
|
+
function shouldClearListContext(elementTag, element, context) {
|
|
144
|
+
return (context.listFormat.levels.length > 0 &&
|
|
145
|
+
LIST_ELEMENT_TAGS.every(function (tag) { return tag != elementTag; }) &&
|
|
146
|
+
!element.closest(LIST_ELEMENT_SELECTOR));
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* @internal
|
|
150
|
+
* Convert pasted content from Office Online
|
|
151
|
+
* Once it is known that the document is from WAC
|
|
152
|
+
* We need to remove the display property and margin from all the list item
|
|
153
|
+
* @param ev ContentModelBeforePasteEvent
|
|
154
|
+
*/
|
|
155
|
+
function processPastedContentWacComponents(ev) {
|
|
156
|
+
var _a;
|
|
157
|
+
(0, addParser_1.default)(ev.domToModelOption, 'segment', wacSubSuperParser);
|
|
158
|
+
(0, addParser_1.default)(ev.domToModelOption, 'listItemThread', wacListItemParser);
|
|
159
|
+
(0, addParser_1.default)(ev.domToModelOption, 'listLevel', wacListLevelParser);
|
|
160
|
+
(0, addParser_1.default)(ev.domToModelOption, 'container', wacBlockParser);
|
|
161
|
+
(0, setProcessor_1.setProcessor)(ev.domToModelOption, 'element', wacElementProcessor);
|
|
162
|
+
(0, setProcessor_1.setProcessor)(ev.domToModelOption, 'li', wacLiElementProcessor);
|
|
163
|
+
(0, setProcessor_1.setProcessor)(ev.domToModelOption, 'ol', wacListProcessor);
|
|
164
|
+
(0, setProcessor_1.setProcessor)(ev.domToModelOption, 'ul', wacListProcessor);
|
|
165
|
+
(_a = ev.sanitizingOption.additionalAllowedCssClasses).push.apply(_a, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(CLASSES_TO_KEEP), false));
|
|
166
|
+
}
|
|
167
|
+
exports.processPastedContentWacComponents = processPastedContentWacComponents;
|
|
168
|
+
/**
|
|
169
|
+
* List items from word have this format when using List items:
|
|
170
|
+
* @example
|
|
171
|
+
<div>
|
|
172
|
+
<ol></ol>
|
|
173
|
+
</div>
|
|
174
|
+
<div>
|
|
175
|
+
<ol></ol>
|
|
176
|
+
</div>
|
|
177
|
+
<div>
|
|
178
|
+
<ol></ol>
|
|
179
|
+
</div>
|
|
180
|
+
* Due to this the div between each of the lists we need to restore the list context to use the previous list,
|
|
181
|
+
* otherwise it could create a new list instead under the same list element
|
|
182
|
+
*/
|
|
183
|
+
var wacListProcessor = function (group, element, context) {
|
|
184
|
+
var _a, _b, _c, _d, _e;
|
|
185
|
+
var lastBlock = group.blocks[group.blocks.length - 1];
|
|
186
|
+
var isWrappedInContainer = element.closest("." + LIST_CONTAINER_ELEMENT_CLASS_NAME);
|
|
187
|
+
if ((_a = isWrappedInContainer === null || isWrappedInContainer === void 0 ? void 0 : isWrappedInContainer.previousElementSibling) === null || _a === void 0 ? void 0 : _a.classList.contains(LIST_CONTAINER_ELEMENT_CLASS_NAME)) {
|
|
188
|
+
if ((lastBlock === null || lastBlock === void 0 ? void 0 : lastBlock.blockType) === 'BlockGroup' && lastBlock.blockGroupType == 'ListItem') {
|
|
189
|
+
context.listFormat = {
|
|
190
|
+
threadItemCounts: [],
|
|
191
|
+
levels: lastBlock.levels,
|
|
192
|
+
listParent: group,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (element.tagName.toUpperCase() === 'OL') {
|
|
197
|
+
(_c = (_b = context.defaultElementProcessors).ol) === null || _c === void 0 ? void 0 : _c.call(_b, group, element, context);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
(_e = (_d = context.defaultElementProcessors).ul) === null || _e === void 0 ? void 0 : _e.call(_d, group, element, context);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
var wacBlockParser = function (format, element) {
|
|
204
|
+
if (element.classList.contains(TABLE_CONTAINER) && element.style.marginLeft.startsWith('-')) {
|
|
205
|
+
delete format.marginLeft;
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
//# sourceMappingURL=processPastedContentWacComponents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processPastedContentWacComponents.js","sourceRoot":"","sources":["../../../../../packages-content-model/roosterjs-content-model-plugins/lib/paste/WacComponents/processPastedContentWacComponents.ts"],"names":[],"mappings":"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","sourcesContent":["import addParser from '../utils/addParser';\nimport { setProcessor } from '../utils/setProcessor';\nimport type {\n ContentModelBeforePasteEvent,\n ContentModelBlockFormat,\n ContentModelBlockGroup,\n ContentModelListItemLevelFormat,\n ContentModelSegmentFormat,\n DomToModelContext,\n ElementProcessor,\n FormatParser,\n} from 'roosterjs-content-model-types';\n\nconst WAC_IDENTIFY_SELECTOR =\n 'ul[class^=\"BulletListStyle\"]>.OutlineElement,ol[class^=\"NumberListStyle\"]>.OutlineElement,span.WACImageContainer,span.WACImageBorder';\nconst LIST_CONTAINER_ELEMENT_CLASS_NAME = 'ListContainerWrapper';\n\nconst PARAGRAPH = 'Paragraph';\nconst TABLE_CONTAINER = 'TableContainer';\n\nconst TEMP_ELEMENTS_CLASSES = [\n 'TableInsertRowGapBlank',\n 'TableColumnResizeHandle',\n 'TableCellTopBorderHandle',\n 'TableCellLeftBorderHandle',\n 'TableHoverColumnHandle',\n 'TableHoverRowHandle',\n 'ListMarkerWrappingSpan',\n];\n\nconst CLASSES_TO_KEEP = [\n 'OutlineElement',\n 'NumberListStyle',\n 'WACImageContainer',\n 'ListContainerWrapper',\n 'BulletListStyle',\n ...TEMP_ELEMENTS_CLASSES,\n 'TableCellContent',\n PARAGRAPH,\n 'WACImageContainer',\n 'WACImageBorder',\n TABLE_CONTAINER,\n 'LineBreakBlob',\n];\n\nconst LIST_ELEMENT_TAGS = ['UL', 'OL', 'LI'];\nconst LIST_ELEMENT_SELECTOR = LIST_ELEMENT_TAGS.join(',');\n\n/**\n * Wac components do not use sub and super tags, instead only add vertical align to a span.\n * This parser normalize the content for content model\n */\nconst wacSubSuperParser: FormatParser<ContentModelSegmentFormat> = (\n format: ContentModelSegmentFormat,\n element: HTMLElement\n): void => {\n const verticalAlign = element.style.verticalAlign;\n if (verticalAlign === 'super') {\n format.superOrSubScriptSequence = 'super';\n }\n if (verticalAlign === 'sub') {\n format.superOrSubScriptSequence = 'sub';\n }\n};\n\n/**\n * This processor does:\n * 1) Remove the display and margin of the element.\n * 2) When an element should be ignored but should handle the child elements call the default child processor.\n * 3) Removes the End of Paragraph element to avoid empty lines, we should only remove this if the previous element of the EOP is an EmptyTextRun\n * 4) Finally call the default processor.\n * @returns\n */\nconst wacElementProcessor: ElementProcessor<HTMLElement> = (\n group: ContentModelBlockGroup,\n element: HTMLElement,\n context: DomToModelContext\n): void => {\n const elementTag = element.tagName;\n\n if (element.matches(WAC_IDENTIFY_SELECTOR)) {\n element.style.removeProperty('display');\n element.style.removeProperty('margin');\n }\n\n if (element.classList.contains(LIST_CONTAINER_ELEMENT_CLASS_NAME)) {\n context.elementProcessors.child(group, element, context);\n return;\n }\n\n if (TEMP_ELEMENTS_CLASSES.some(className => element.classList.contains(className))) {\n return;\n } else if (shouldClearListContext(elementTag, element, context)) {\n const { listFormat } = context;\n listFormat.levels = [];\n listFormat.listParent = undefined;\n }\n\n context.defaultElementProcessors.element(group, element, context);\n};\n\n/**\n * This processor calls the default list processor and then sets the correct list level and list bullet.\n */\nconst wacLiElementProcessor: ElementProcessor<HTMLLIElement> = (\n group: ContentModelBlockGroup,\n element: HTMLLIElement,\n context: DomToModelContext\n): void => {\n context.defaultElementProcessors.li?.(group, element, context);\n const { listFormat } = context;\n const listParent = listFormat.listParent;\n if (listParent) {\n const lastblock = listParent.blocks[listParent.blocks.length - 1];\n if (\n lastblock.blockType == 'BlockGroup' &&\n lastblock.blockGroupType == 'ListItem' &&\n context.listFormat.listParent !== lastblock\n ) {\n const currentLevel = lastblock.levels[lastblock.levels.length - 1];\n\n // Get item level from 'data-aria-level' attribute\n const level = parseInt(element.getAttribute('data-aria-level') ?? '');\n if (level > 0) {\n if (level > lastblock.levels.length) {\n while (level != lastblock.levels.length) {\n lastblock.levels.push(currentLevel);\n }\n } else {\n lastblock.levels.splice(level, lastblock.levels.length - 1);\n lastblock.levels[level - 1] = currentLevel;\n }\n }\n }\n }\n};\n\n/**\n * This parsers does:\n * 1) Sets the display for dummy item to undefined when the current style is block.\n * 2) Removes the Margin Left\n */\nconst wacListItemParser: FormatParser<ContentModelListItemLevelFormat> = (\n format: ContentModelListItemLevelFormat,\n element: HTMLElement\n): void => {\n if (element.style.display === 'block') {\n format.displayForDummyItem = undefined;\n }\n\n format.marginLeft = undefined;\n};\n\n/**\n * Wac usually adds padding to lists which is unwanted so remove it.\n */\nconst wacListLevelParser: FormatParser<ContentModelListItemLevelFormat> = (\n format: ContentModelListItemLevelFormat\n): void => {\n format.marginLeft = undefined;\n format.paddingLeft = undefined;\n};\n\n/**\n * This function returns whether we need to clear the list format.\n * Word Online wraps lists inside divs to have this structure:\n *\n * <div class='ListContainerWrapper'>\n * <ol>...</ol>\n * </div>\n * <div>\n * <p>...</p>\n * <div>\n * <div class='ListContainerWrapper'>\n * <ol>...</ol>\n * </div>\n *\n * So if a elements is not contained inside of a list we should clear the list context to prevent normal text to be\n * transformed into list\n * For the above scenario, if we do not clear the format, the content inside of the second div would be transformed to a list too.\n */\nfunction shouldClearListContext(\n elementTag: string,\n element: HTMLElement,\n context: DomToModelContext\n) {\n return (\n context.listFormat.levels.length > 0 &&\n LIST_ELEMENT_TAGS.every(tag => tag != elementTag) &&\n !element.closest(LIST_ELEMENT_SELECTOR)\n );\n}\n\n/**\n * @internal\n * Convert pasted content from Office Online\n * Once it is known that the document is from WAC\n * We need to remove the display property and margin from all the list item\n * @param ev ContentModelBeforePasteEvent\n */\nexport function processPastedContentWacComponents(ev: ContentModelBeforePasteEvent) {\n addParser(ev.domToModelOption, 'segment', wacSubSuperParser);\n addParser(ev.domToModelOption, 'listItemThread', wacListItemParser);\n addParser(ev.domToModelOption, 'listLevel', wacListLevelParser);\n addParser(ev.domToModelOption, 'container', wacBlockParser);\n\n setProcessor(ev.domToModelOption, 'element', wacElementProcessor);\n setProcessor(ev.domToModelOption, 'li', wacLiElementProcessor);\n setProcessor(ev.domToModelOption, 'ol', wacListProcessor);\n setProcessor(ev.domToModelOption, 'ul', wacListProcessor);\n ev.sanitizingOption.additionalAllowedCssClasses.push(...CLASSES_TO_KEEP);\n}\n\n/**\n * List items from word have this format when using List items:\n * @example\n <div>\n <ol></ol>\n </div>\n <div>\n <ol></ol>\n </div>\n <div>\n <ol></ol>\n </div>\n * Due to this the div between each of the lists we need to restore the list context to use the previous list,\n * otherwise it could create a new list instead under the same list element\n */\nconst wacListProcessor: ElementProcessor<HTMLOListElement | HTMLUListElement> = (\n group: ContentModelBlockGroup,\n element: HTMLOListElement | HTMLUListElement,\n context: DomToModelContext\n): void => {\n const lastBlock = group.blocks[group.blocks.length - 1];\n const isWrappedInContainer = element.closest(`.${LIST_CONTAINER_ELEMENT_CLASS_NAME}`);\n if (\n isWrappedInContainer?.previousElementSibling?.classList.contains(\n LIST_CONTAINER_ELEMENT_CLASS_NAME\n )\n ) {\n if (lastBlock?.blockType === 'BlockGroup' && lastBlock.blockGroupType == 'ListItem') {\n context.listFormat = {\n threadItemCounts: [],\n levels: lastBlock.levels,\n listParent: group,\n };\n }\n }\n if (element.tagName.toUpperCase() === 'OL') {\n context.defaultElementProcessors.ol?.(group, element as HTMLOListElement, context);\n } else {\n context.defaultElementProcessors.ul?.(group, element as HTMLUListElement, context);\n }\n};\n\nconst wacBlockParser: FormatParser<ContentModelBlockFormat> = (\n format: ContentModelBlockFormat,\n element: HTMLElement\n) => {\n if (element.classList.contains(TABLE_CONTAINER) && element.style.marginLeft.startsWith('-')) {\n delete format.marginLeft;\n }\n};\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ContentModelBeforePasteEvent, ElementProcessor } from 'roosterjs-content-model-types';
|
|
2
|
+
/**
|
|
3
|
+
* @internal
|
|
4
|
+
* Handles Pasted content when source is Word Desktop
|
|
5
|
+
* @param ev ContentModelBeforePasteEvent
|
|
6
|
+
*/
|
|
7
|
+
export declare function processPastedContentFromWordDesktop(ev: ContentModelBeforePasteEvent): void;
|
|
8
|
+
/**
|
|
9
|
+
* @internal
|
|
10
|
+
* Exported only for unit test
|
|
11
|
+
*/
|
|
12
|
+
export declare const wordDesktopElementProcessor: ElementProcessor<HTMLElement>;
|