roosterjs-content-model-core 0.28.0 → 0.28.1

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.
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.paste = void 0;
4
+ var mergePasteContent_1 = require("../../utils/paste/mergePasteContent");
4
5
  var convertInlineCss_1 = require("../../utils/convertInlineCss");
5
6
  var createPasteFragment_1 = require("../../utils/paste/createPasteFragment");
6
7
  var generatePasteOptionFromPlugins_1 = require("../../utils/paste/generatePasteOptionFromPlugins");
7
- var mergePasteContent_1 = require("../../utils/paste/mergePasteContent");
8
8
  var retrieveHtmlInfo_1 = require("../../utils/paste/retrieveHtmlInfo");
9
9
  /**
10
10
  * Paste into editor using a clipboardData object
@@ -18,7 +18,7 @@ function paste(editor, clipboardData, pasteType) {
18
18
  editor.focus();
19
19
  var trustedHTMLHandler = editor.getTrustedHTMLHandler();
20
20
  if (!clipboardData.modelBeforePaste) {
21
- clipboardData.modelBeforePaste = editor.getContentModelCopy('connected');
21
+ clipboardData.modelBeforePaste = (0, mergePasteContent_1.cloneModelForPaste)(editor.getContentModelCopy('connected'));
22
22
  }
23
23
  // 1. Prepare variables
24
24
  var doc = createDOMFromHtml(clipboardData.rawHtml, trustedHTMLHandler);
@@ -1 +1 @@
1
- {"version":3,"file":"paste.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/publicApi/paste/paste.ts"],"names":[],"mappings":";;;AAAA,iEAAgE;AAChE,6EAA4E;AAC5E,mGAAkG;AAClG,yEAAwE;AACxE,uEAAsE;AAQtE;;;;;GAKG;AACH,SAAgB,KAAK,CACjB,MAAe,EACf,aAA4B,EAC5B,SAA+B;;IAA/B,0BAAA,EAAA,oBAA+B;IAE/B,MAAM,CAAC,KAAK,EAAE,CAAC;IAEf,IAAM,kBAAkB,GAAG,MAAM,CAAC,qBAAqB,EAAE,CAAC;IAE1D,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE;QACjC,aAAa,CAAC,gBAAgB,GAAG,MAAM,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;KAC5E;IAED,uBAAuB;IACvB,IAAM,GAAG,GAAG,iBAAiB,CAAC,aAAa,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;IAEzE,gCAAgC;IAChC,IAAM,iBAAiB,GAAG,IAAA,mCAAgB,EAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAE/D,4BAA4B;IAC5B,IAAM,cAAc,GAAG,IAAA,yCAAmB,EACtC,MAAM,CAAC,WAAW,EAAE,EACpB,aAAa,EACb,SAAS,EACT,MAAA,CAAC,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC,IAAI;QACxC,CAAC,CAAC,GAAG;QACL,CAAC,CAAC,iBAAiB,CAAC,aAAa,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAC9D,0CAAE,IAAI,CACV,CAAC;IAEF,oEAAoE;IACpE,IAAM,WAAW,GAAG,IAAA,+DAA8B,EAC9C,MAAM,EACN,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,SAAS,CACZ,CAAC;IAEF,sCAAsC;IACtC,IAAA,mCAAgB,EAAC,WAAW,CAAC,QAAQ,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;IAEzE,kDAAkD;IAClD,IAAA,qCAAiB,EAAC,MAAM,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;AAC1D,CAAC;AA5CD,sBA4CC;AAED,SAAS,iBAAiB,CACtB,IAA+B,EAC/B,kBAAsC;IAEtC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC,eAAe,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChG,CAAC","sourcesContent":["import { convertInlineCss } from '../../utils/convertInlineCss';\nimport { createPasteFragment } from '../../utils/paste/createPasteFragment';\nimport { generatePasteOptionFromPlugins } from '../../utils/paste/generatePasteOptionFromPlugins';\nimport { mergePasteContent } from '../../utils/paste/mergePasteContent';\nimport { retrieveHtmlInfo } from '../../utils/paste/retrieveHtmlInfo';\nimport type {\n PasteType,\n ClipboardData,\n TrustedHTMLHandler,\n IEditor,\n} from 'roosterjs-content-model-types';\n\n/**\n * Paste into editor using a clipboardData object\n * @param editor The Editor object.\n * @param clipboardData Clipboard data retrieved from clipboard\n * @param pasteType Type of content to paste. @default normal\n */\nexport function paste(\n editor: IEditor,\n clipboardData: ClipboardData,\n pasteType: PasteType = 'normal'\n) {\n editor.focus();\n\n const trustedHTMLHandler = editor.getTrustedHTMLHandler();\n\n if (!clipboardData.modelBeforePaste) {\n clipboardData.modelBeforePaste = editor.getContentModelCopy('connected');\n }\n\n // 1. Prepare variables\n const doc = createDOMFromHtml(clipboardData.rawHtml, trustedHTMLHandler);\n\n // 2. Handle HTML from clipboard\n const htmlFromClipboard = retrieveHtmlInfo(doc, clipboardData);\n\n // 3. Create target fragment\n const sourceFragment = createPasteFragment(\n editor.getDocument(),\n clipboardData,\n pasteType,\n (clipboardData.rawHtml == clipboardData.html\n ? doc\n : createDOMFromHtml(clipboardData.html, trustedHTMLHandler)\n )?.body\n );\n\n // 4. Trigger BeforePaste event to allow plugins modify the fragment\n const eventResult = generatePasteOptionFromPlugins(\n editor,\n clipboardData,\n sourceFragment,\n htmlFromClipboard,\n pasteType\n );\n\n // 5. Convert global CSS to inline CSS\n convertInlineCss(eventResult.fragment, htmlFromClipboard.globalCssRules);\n\n // 6. Merge pasted content into main Content Model\n mergePasteContent(editor, eventResult, clipboardData);\n}\n\nfunction createDOMFromHtml(\n html: string | null | undefined,\n trustedHTMLHandler: TrustedHTMLHandler\n): Document | null {\n return html ? new DOMParser().parseFromString(trustedHTMLHandler(html), 'text/html') : null;\n}\n"]}
1
+ {"version":3,"file":"paste.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/publicApi/paste/paste.ts"],"names":[],"mappings":";;;AAAA,yEAA4F;AAC5F,iEAAgE;AAChE,6EAA4E;AAC5E,mGAAkG;AAClG,uEAAsE;AAQtE;;;;;GAKG;AACH,SAAgB,KAAK,CACjB,MAAe,EACf,aAA4B,EAC5B,SAA+B;;IAA/B,0BAAA,EAAA,oBAA+B;IAE/B,MAAM,CAAC,KAAK,EAAE,CAAC;IAEf,IAAM,kBAAkB,GAAG,MAAM,CAAC,qBAAqB,EAAE,CAAC;IAE1D,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE;QACjC,aAAa,CAAC,gBAAgB,GAAG,IAAA,sCAAkB,EAC/C,MAAM,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAC1C,CAAC;KACL;IAED,uBAAuB;IACvB,IAAM,GAAG,GAAG,iBAAiB,CAAC,aAAa,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;IAEzE,gCAAgC;IAChC,IAAM,iBAAiB,GAAG,IAAA,mCAAgB,EAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAE/D,4BAA4B;IAC5B,IAAM,cAAc,GAAG,IAAA,yCAAmB,EACtC,MAAM,CAAC,WAAW,EAAE,EACpB,aAAa,EACb,SAAS,EACT,MAAA,CAAC,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC,IAAI;QACxC,CAAC,CAAC,GAAG;QACL,CAAC,CAAC,iBAAiB,CAAC,aAAa,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAC9D,0CAAE,IAAI,CACV,CAAC;IAEF,oEAAoE;IACpE,IAAM,WAAW,GAAG,IAAA,+DAA8B,EAC9C,MAAM,EACN,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,SAAS,CACZ,CAAC;IAEF,sCAAsC;IACtC,IAAA,mCAAgB,EAAC,WAAW,CAAC,QAAQ,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;IAEzE,kDAAkD;IAClD,IAAA,qCAAiB,EAAC,MAAM,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;AAC1D,CAAC;AA9CD,sBA8CC;AAED,SAAS,iBAAiB,CACtB,IAA+B,EAC/B,kBAAsC;IAEtC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC,eAAe,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChG,CAAC","sourcesContent":["import { cloneModelForPaste, mergePasteContent } from '../../utils/paste/mergePasteContent';\nimport { convertInlineCss } from '../../utils/convertInlineCss';\nimport { createPasteFragment } from '../../utils/paste/createPasteFragment';\nimport { generatePasteOptionFromPlugins } from '../../utils/paste/generatePasteOptionFromPlugins';\nimport { retrieveHtmlInfo } from '../../utils/paste/retrieveHtmlInfo';\nimport type {\n PasteType,\n ClipboardData,\n TrustedHTMLHandler,\n IEditor,\n} from 'roosterjs-content-model-types';\n\n/**\n * Paste into editor using a clipboardData object\n * @param editor The Editor object.\n * @param clipboardData Clipboard data retrieved from clipboard\n * @param pasteType Type of content to paste. @default normal\n */\nexport function paste(\n editor: IEditor,\n clipboardData: ClipboardData,\n pasteType: PasteType = 'normal'\n) {\n editor.focus();\n\n const trustedHTMLHandler = editor.getTrustedHTMLHandler();\n\n if (!clipboardData.modelBeforePaste) {\n clipboardData.modelBeforePaste = cloneModelForPaste(\n editor.getContentModelCopy('connected')\n );\n }\n\n // 1. Prepare variables\n const doc = createDOMFromHtml(clipboardData.rawHtml, trustedHTMLHandler);\n\n // 2. Handle HTML from clipboard\n const htmlFromClipboard = retrieveHtmlInfo(doc, clipboardData);\n\n // 3. Create target fragment\n const sourceFragment = createPasteFragment(\n editor.getDocument(),\n clipboardData,\n pasteType,\n (clipboardData.rawHtml == clipboardData.html\n ? doc\n : createDOMFromHtml(clipboardData.html, trustedHTMLHandler)\n )?.body\n );\n\n // 4. Trigger BeforePaste event to allow plugins modify the fragment\n const eventResult = generatePasteOptionFromPlugins(\n editor,\n clipboardData,\n sourceFragment,\n htmlFromClipboard,\n pasteType\n );\n\n // 5. Convert global CSS to inline CSS\n convertInlineCss(eventResult.fragment, htmlFromClipboard.globalCssRules);\n\n // 6. Merge pasted content into main Content Model\n mergePasteContent(editor, eventResult, clipboardData);\n}\n\nfunction createDOMFromHtml(\n html: string | null | undefined,\n trustedHTMLHandler: TrustedHTMLHandler\n): Document | null {\n return html ? new DOMParser().parseFromString(trustedHTMLHandler(html), 'text/html') : null;\n}\n"]}
@@ -1,4 +1,8 @@
1
- import type { BeforePasteEvent, ClipboardData, IEditor } from 'roosterjs-content-model-types';
1
+ import type { BeforePasteEvent, ClipboardData, ContentModelDocument, IEditor } from 'roosterjs-content-model-types';
2
+ /**
3
+ * @internal
4
+ */
5
+ export declare function cloneModelForPaste(model: ContentModelDocument): ContentModelDocument;
2
6
  /**
3
7
  * @internal
4
8
  */
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mergePasteContent = void 0;
3
+ exports.mergePasteContent = exports.cloneModelForPaste = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var ChangeSource_1 = require("../../constants/ChangeSource");
6
6
  var cloneModel_1 = require("../../publicApi/model/cloneModel");
@@ -25,6 +25,13 @@ var EmptySegmentFormat = {
25
25
  var CloneOption = {
26
26
  includeCachedElement: function (node, type) { return (type == 'cache' ? undefined : node); },
27
27
  };
28
+ /**
29
+ * @internal
30
+ */
31
+ function cloneModelForPaste(model) {
32
+ return (0, cloneModel_1.cloneModel)(model, CloneOption);
33
+ }
34
+ exports.cloneModelForPaste = cloneModelForPaste;
28
35
  /**
29
36
  * @internal
30
37
  */
@@ -32,7 +39,7 @@ function mergePasteContent(editor, eventResult, clipboardData) {
32
39
  var fragment = eventResult.fragment, domToModelOption = eventResult.domToModelOption, customizedMerge = eventResult.customizedMerge, pasteType = eventResult.pasteType;
33
40
  editor.formatContentModel(function (model, context) {
34
41
  if (clipboardData.modelBeforePaste) {
35
- var clonedModel = (0, cloneModel_1.cloneModel)(clipboardData.modelBeforePaste, CloneOption);
42
+ var clonedModel = cloneModelForPaste(clipboardData.modelBeforePaste);
36
43
  model.blocks = clonedModel.blocks;
37
44
  }
38
45
  var selectedSegment = (0, collectSelections_1.getSelectedSegments)(model, true /*includeFormatHolder*/)[0];
@@ -1 +1 @@
1
- {"version":3,"file":"mergePasteContent.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/utils/paste/mergePasteContent.ts"],"names":[],"mappings":";;;;AAAA,6DAA4D;AAC5D,+DAA8D;AAC9D,gGAA+F;AAC/F,2EAAgE;AAChE,sFAAqF;AACrF,iFAAkF;AAClF,+DAA8D;AAW9D,IAAM,kBAAkB,GAAwC;IAC5D,eAAe,EAAE,EAAE;IACnB,UAAU,EAAE,EAAE;IACd,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,EAAE;IACd,MAAM,EAAE,KAAK;IACb,aAAa,EAAE,EAAE;IACjB,UAAU,EAAE,EAAE;IACd,aAAa,EAAE,KAAK;IACpB,wBAAwB,EAAE,EAAE;IAC5B,SAAS,EAAE,EAAE;IACb,SAAS,EAAE,KAAK;CACnB,CAAC;AACF,IAAM,WAAW,GAAsB;IACnC,oBAAoB,EAAE,UAAC,IAAI,EAAE,IAAI,IAAK,OAAA,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,EAApC,CAAoC;CAC7E,CAAC;AAEF;;GAEG;AACH,SAAgB,iBAAiB,CAC7B,MAAe,EACf,WAA6B,EAC7B,aAA4B;IAEpB,IAAA,QAAQ,GAAmD,WAAW,SAA9D,EAAE,gBAAgB,GAAiC,WAAW,iBAA5C,EAAE,eAAe,GAAgB,WAAW,gBAA3B,EAAE,SAAS,GAAK,WAAW,UAAhB,CAAiB;IAE/E,MAAM,CAAC,kBAAkB,CACrB,UAAC,KAAK,EAAE,OAAO;QACX,IAAI,aAAa,CAAC,gBAAgB,EAAE;YAChC,IAAM,WAAW,GAAG,IAAA,uBAAU,EAAC,aAAa,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;YAC5E,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;SACrC;QAED,IAAM,eAAe,GAAG,IAAA,uCAAmB,EAAC,KAAK,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC;QACpF,IAAM,iBAAiB,GAAG,IAAA,2EAAoC,EAC1D,MAAM,CAAC,WAAW,EAAE,EACpB,SAAS,CAAC,iBAAiB,EAC3B,MAAM,CAAC,cAAc,EAAE,CAAC,kBAAkB,CAAC,UAAU,EACrD,gBAAgB,CACnB,CAAC;QAEF,iBAAiB,CAAC,aAAa,GAAG,eAAe;YAC7C,CAAC,CAAC,IAAA,2CAAoB,EAAC,eAAe,CAAC;YACvC,CAAC,CAAC,EAAE,CAAC;QAET,IAAM,UAAU,GAAG,IAAA,+CAAiB,EAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;QAClE,IAAM,WAAW,GAAqB;YAClC,WAAW,EAAE,SAAS,IAAI,aAAa,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,MAAM;YAC7E,UAAU,EAAE,gBAAgB,CAAC,UAAU,CAAC;SAC3C,CAAC;QAEF,IAAM,WAAW,GAAG,eAAe;YAC/B,CAAC,CAAC,eAAe,CAAC,KAAK,EAAE,UAAU,CAAC;YACpC,CAAC,CAAC,IAAA,uBAAU,EAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;QAE1D,IAAI,WAAW,EAAE;YACb,OAAO,CAAC,gBAAgB,yEACjB,kBAAkB,GAClB,KAAK,CAAC,MAAM,GACZ,WAAW,CAAC,MAAM,CAAC,MAAM,CAC/B,CAAC;SACL;QAED,OAAO,IAAI,CAAC;IAChB,CAAC,EACD;QACI,YAAY,EAAE,2BAAY,CAAC,KAAK;QAChC,aAAa,EAAE,cAAM,OAAA,aAAa,EAAb,CAAa;QAClC,OAAO,EAAE,OAAO;KACnB,CACJ,CAAC;AACN,CAAC;AApDD,8CAoDC;AAED,SAAS,gBAAgB,CAAC,UAAgC;IACtD,mIAAmI;IACnI,IACI,UAAU,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC;QAC7B,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,OAAO;QAC1C,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,WAAW;QAC9C,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;QAC1C,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,IAAI,EACvD;QACE,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;KAC/B;IACD,6DAA6D;IAC7D,OAAO,UAAU,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,OAAO,CAAC;AACxF,CAAC","sourcesContent":["import { ChangeSource } from '../../constants/ChangeSource';\nimport { cloneModel } from '../../publicApi/model/cloneModel';\nimport { createDomToModelContextForSanitizing } from '../createDomToModelContextForSanitizing';\nimport { domToContentModel } from 'roosterjs-content-model-dom';\nimport { getSegmentTextFormat } from '../../publicApi/domUtils/getSegmentTextFormat';\nimport { getSelectedSegments } from '../../publicApi/selection/collectSelections';\nimport { mergeModel } from '../../publicApi/model/mergeModel';\nimport type { MergeModelOption } from '../../publicApi/model/mergeModel';\nimport type {\n BeforePasteEvent,\n ClipboardData,\n CloneModelOptions,\n ContentModelDocument,\n ContentModelSegmentFormat,\n IEditor,\n} from 'roosterjs-content-model-types';\n\nconst EmptySegmentFormat: Required<ContentModelSegmentFormat> = {\n backgroundColor: '',\n fontFamily: '',\n fontSize: '',\n fontWeight: '',\n italic: false,\n letterSpacing: '',\n lineHeight: '',\n strikethrough: false,\n superOrSubScriptSequence: '',\n textColor: '',\n underline: false,\n};\nconst CloneOption: CloneModelOptions = {\n includeCachedElement: (node, type) => (type == 'cache' ? undefined : node),\n};\n\n/**\n * @internal\n */\nexport function mergePasteContent(\n editor: IEditor,\n eventResult: BeforePasteEvent,\n clipboardData: ClipboardData\n) {\n const { fragment, domToModelOption, customizedMerge, pasteType } = eventResult;\n\n editor.formatContentModel(\n (model, context) => {\n if (clipboardData.modelBeforePaste) {\n const clonedModel = cloneModel(clipboardData.modelBeforePaste, CloneOption);\n model.blocks = clonedModel.blocks;\n }\n\n const selectedSegment = getSelectedSegments(model, true /*includeFormatHolder*/)[0];\n const domToModelContext = createDomToModelContextForSanitizing(\n editor.getDocument(),\n undefined /*defaultFormat*/,\n editor.getEnvironment().domToModelSettings.customized,\n domToModelOption\n );\n\n domToModelContext.segmentFormat = selectedSegment\n ? getSegmentTextFormat(selectedSegment)\n : {};\n\n const pasteModel = domToContentModel(fragment, domToModelContext);\n const mergeOption: MergeModelOption = {\n mergeFormat: pasteType == 'mergeFormat' ? 'keepSourceEmphasisFormat' : 'none',\n mergeTable: shouldMergeTable(pasteModel),\n };\n\n const insertPoint = customizedMerge\n ? customizedMerge(model, pasteModel)\n : mergeModel(model, pasteModel, context, mergeOption);\n\n if (insertPoint) {\n context.newPendingFormat = {\n ...EmptySegmentFormat,\n ...model.format,\n ...insertPoint.marker.format,\n };\n }\n\n return true;\n },\n {\n changeSource: ChangeSource.Paste,\n getChangeData: () => clipboardData,\n apiName: 'paste',\n }\n );\n}\n\nfunction shouldMergeTable(pasteModel: ContentModelDocument): boolean | undefined {\n // If model contains a table and a paragraph element after the table with a single BR segment, remove the Paragraph after the table\n if (\n pasteModel.blocks.length == 2 &&\n pasteModel.blocks[0].blockType === 'Table' &&\n pasteModel.blocks[1].blockType === 'Paragraph' &&\n pasteModel.blocks[1].segments.length === 1 &&\n pasteModel.blocks[1].segments[0].segmentType === 'Br'\n ) {\n pasteModel.blocks.splice(1);\n }\n // Only merge table when the document contain a single table.\n return pasteModel.blocks.length === 1 && pasteModel.blocks[0].blockType === 'Table';\n}\n"]}
1
+ {"version":3,"file":"mergePasteContent.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/utils/paste/mergePasteContent.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource } from '../../constants/ChangeSource';\nimport { cloneModel } from '../../publicApi/model/cloneModel';\nimport { createDomToModelContextForSanitizing } from '../createDomToModelContextForSanitizing';\nimport { domToContentModel } from 'roosterjs-content-model-dom';\nimport { getSegmentTextFormat } from '../../publicApi/domUtils/getSegmentTextFormat';\nimport { getSelectedSegments } from '../../publicApi/selection/collectSelections';\nimport { mergeModel } from '../../publicApi/model/mergeModel';\nimport type { MergeModelOption } from '../../publicApi/model/mergeModel';\nimport type {\n BeforePasteEvent,\n ClipboardData,\n CloneModelOptions,\n ContentModelDocument,\n ContentModelSegmentFormat,\n IEditor,\n} from 'roosterjs-content-model-types';\n\nconst EmptySegmentFormat: Required<ContentModelSegmentFormat> = {\n backgroundColor: '',\n fontFamily: '',\n fontSize: '',\n fontWeight: '',\n italic: false,\n letterSpacing: '',\n lineHeight: '',\n strikethrough: false,\n superOrSubScriptSequence: '',\n textColor: '',\n underline: false,\n};\n\nconst CloneOption: CloneModelOptions = {\n includeCachedElement: (node, type) => (type == 'cache' ? undefined : node),\n};\n\n/**\n * @internal\n */\nexport function cloneModelForPaste(model: ContentModelDocument) {\n return cloneModel(model, CloneOption);\n}\n\n/**\n * @internal\n */\nexport function mergePasteContent(\n editor: IEditor,\n eventResult: BeforePasteEvent,\n clipboardData: ClipboardData\n) {\n const { fragment, domToModelOption, customizedMerge, pasteType } = eventResult;\n\n editor.formatContentModel(\n (model, context) => {\n if (clipboardData.modelBeforePaste) {\n const clonedModel = cloneModelForPaste(clipboardData.modelBeforePaste);\n model.blocks = clonedModel.blocks;\n }\n\n const selectedSegment = getSelectedSegments(model, true /*includeFormatHolder*/)[0];\n const domToModelContext = createDomToModelContextForSanitizing(\n editor.getDocument(),\n undefined /*defaultFormat*/,\n editor.getEnvironment().domToModelSettings.customized,\n domToModelOption\n );\n\n domToModelContext.segmentFormat = selectedSegment\n ? getSegmentTextFormat(selectedSegment)\n : {};\n\n const pasteModel = domToContentModel(fragment, domToModelContext);\n const mergeOption: MergeModelOption = {\n mergeFormat: pasteType == 'mergeFormat' ? 'keepSourceEmphasisFormat' : 'none',\n mergeTable: shouldMergeTable(pasteModel),\n };\n\n const insertPoint = customizedMerge\n ? customizedMerge(model, pasteModel)\n : mergeModel(model, pasteModel, context, mergeOption);\n\n if (insertPoint) {\n context.newPendingFormat = {\n ...EmptySegmentFormat,\n ...model.format,\n ...insertPoint.marker.format,\n };\n }\n\n return true;\n },\n {\n changeSource: ChangeSource.Paste,\n getChangeData: () => clipboardData,\n apiName: 'paste',\n }\n );\n}\n\nfunction shouldMergeTable(pasteModel: ContentModelDocument): boolean | undefined {\n // If model contains a table and a paragraph element after the table with a single BR segment, remove the Paragraph after the table\n if (\n pasteModel.blocks.length == 2 &&\n pasteModel.blocks[0].blockType === 'Table' &&\n pasteModel.blocks[1].blockType === 'Paragraph' &&\n pasteModel.blocks[1].segments.length === 1 &&\n pasteModel.blocks[1].segments[0].segmentType === 'Br'\n ) {\n pasteModel.blocks.splice(1);\n }\n // Only merge table when the document contain a single table.\n return pasteModel.blocks.length === 1 && pasteModel.blocks[0].blockType === 'Table';\n}\n"]}
@@ -1,4 +1,4 @@
1
- define(["require", "exports", "../../utils/convertInlineCss", "../../utils/paste/createPasteFragment", "../../utils/paste/generatePasteOptionFromPlugins", "../../utils/paste/mergePasteContent", "../../utils/paste/retrieveHtmlInfo"], function (require, exports, convertInlineCss_1, createPasteFragment_1, generatePasteOptionFromPlugins_1, mergePasteContent_1, retrieveHtmlInfo_1) {
1
+ define(["require", "exports", "../../utils/paste/mergePasteContent", "../../utils/convertInlineCss", "../../utils/paste/createPasteFragment", "../../utils/paste/generatePasteOptionFromPlugins", "../../utils/paste/retrieveHtmlInfo"], function (require, exports, mergePasteContent_1, convertInlineCss_1, createPasteFragment_1, generatePasteOptionFromPlugins_1, retrieveHtmlInfo_1) {
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.paste = void 0;
@@ -14,7 +14,7 @@ define(["require", "exports", "../../utils/convertInlineCss", "../../utils/paste
14
14
  editor.focus();
15
15
  var trustedHTMLHandler = editor.getTrustedHTMLHandler();
16
16
  if (!clipboardData.modelBeforePaste) {
17
- clipboardData.modelBeforePaste = editor.getContentModelCopy('connected');
17
+ clipboardData.modelBeforePaste = (0, mergePasteContent_1.cloneModelForPaste)(editor.getContentModelCopy('connected'));
18
18
  }
19
19
  // 1. Prepare variables
20
20
  var doc = createDOMFromHtml(clipboardData.rawHtml, trustedHTMLHandler);
@@ -1 +1 @@
1
- {"version":3,"file":"paste.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/publicApi/paste/paste.ts"],"names":[],"mappings":";;;;IAYA;;;;;OAKG;IACH,SAAgB,KAAK,CACjB,MAAe,EACf,aAA4B,EAC5B,SAA+B;;QAA/B,0BAAA,EAAA,oBAA+B;QAE/B,MAAM,CAAC,KAAK,EAAE,CAAC;QAEf,IAAM,kBAAkB,GAAG,MAAM,CAAC,qBAAqB,EAAE,CAAC;QAE1D,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE;YACjC,aAAa,CAAC,gBAAgB,GAAG,MAAM,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;SAC5E;QAED,uBAAuB;QACvB,IAAM,GAAG,GAAG,iBAAiB,CAAC,aAAa,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;QAEzE,gCAAgC;QAChC,IAAM,iBAAiB,GAAG,IAAA,mCAAgB,EAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QAE/D,4BAA4B;QAC5B,IAAM,cAAc,GAAG,IAAA,yCAAmB,EACtC,MAAM,CAAC,WAAW,EAAE,EACpB,aAAa,EACb,SAAS,EACT,MAAA,CAAC,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC,IAAI;YACxC,CAAC,CAAC,GAAG;YACL,CAAC,CAAC,iBAAiB,CAAC,aAAa,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAC9D,0CAAE,IAAI,CACV,CAAC;QAEF,oEAAoE;QACpE,IAAM,WAAW,GAAG,IAAA,+DAA8B,EAC9C,MAAM,EACN,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,SAAS,CACZ,CAAC;QAEF,sCAAsC;QACtC,IAAA,mCAAgB,EAAC,WAAW,CAAC,QAAQ,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;QAEzE,kDAAkD;QAClD,IAAA,qCAAiB,EAAC,MAAM,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;IAC1D,CAAC;IA5CD,sBA4CC;IAED,SAAS,iBAAiB,CACtB,IAA+B,EAC/B,kBAAsC;QAEtC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC,eAAe,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAChG,CAAC","sourcesContent":["import { convertInlineCss } from '../../utils/convertInlineCss';\nimport { createPasteFragment } from '../../utils/paste/createPasteFragment';\nimport { generatePasteOptionFromPlugins } from '../../utils/paste/generatePasteOptionFromPlugins';\nimport { mergePasteContent } from '../../utils/paste/mergePasteContent';\nimport { retrieveHtmlInfo } from '../../utils/paste/retrieveHtmlInfo';\nimport type {\n PasteType,\n ClipboardData,\n TrustedHTMLHandler,\n IEditor,\n} from 'roosterjs-content-model-types';\n\n/**\n * Paste into editor using a clipboardData object\n * @param editor The Editor object.\n * @param clipboardData Clipboard data retrieved from clipboard\n * @param pasteType Type of content to paste. @default normal\n */\nexport function paste(\n editor: IEditor,\n clipboardData: ClipboardData,\n pasteType: PasteType = 'normal'\n) {\n editor.focus();\n\n const trustedHTMLHandler = editor.getTrustedHTMLHandler();\n\n if (!clipboardData.modelBeforePaste) {\n clipboardData.modelBeforePaste = editor.getContentModelCopy('connected');\n }\n\n // 1. Prepare variables\n const doc = createDOMFromHtml(clipboardData.rawHtml, trustedHTMLHandler);\n\n // 2. Handle HTML from clipboard\n const htmlFromClipboard = retrieveHtmlInfo(doc, clipboardData);\n\n // 3. Create target fragment\n const sourceFragment = createPasteFragment(\n editor.getDocument(),\n clipboardData,\n pasteType,\n (clipboardData.rawHtml == clipboardData.html\n ? doc\n : createDOMFromHtml(clipboardData.html, trustedHTMLHandler)\n )?.body\n );\n\n // 4. Trigger BeforePaste event to allow plugins modify the fragment\n const eventResult = generatePasteOptionFromPlugins(\n editor,\n clipboardData,\n sourceFragment,\n htmlFromClipboard,\n pasteType\n );\n\n // 5. Convert global CSS to inline CSS\n convertInlineCss(eventResult.fragment, htmlFromClipboard.globalCssRules);\n\n // 6. Merge pasted content into main Content Model\n mergePasteContent(editor, eventResult, clipboardData);\n}\n\nfunction createDOMFromHtml(\n html: string | null | undefined,\n trustedHTMLHandler: TrustedHTMLHandler\n): Document | null {\n return html ? new DOMParser().parseFromString(trustedHTMLHandler(html), 'text/html') : null;\n}\n"]}
1
+ {"version":3,"file":"paste.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/publicApi/paste/paste.ts"],"names":[],"mappings":";;;;IAYA;;;;;OAKG;IACH,SAAgB,KAAK,CACjB,MAAe,EACf,aAA4B,EAC5B,SAA+B;;QAA/B,0BAAA,EAAA,oBAA+B;QAE/B,MAAM,CAAC,KAAK,EAAE,CAAC;QAEf,IAAM,kBAAkB,GAAG,MAAM,CAAC,qBAAqB,EAAE,CAAC;QAE1D,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE;YACjC,aAAa,CAAC,gBAAgB,GAAG,IAAA,sCAAkB,EAC/C,MAAM,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAC1C,CAAC;SACL;QAED,uBAAuB;QACvB,IAAM,GAAG,GAAG,iBAAiB,CAAC,aAAa,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;QAEzE,gCAAgC;QAChC,IAAM,iBAAiB,GAAG,IAAA,mCAAgB,EAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QAE/D,4BAA4B;QAC5B,IAAM,cAAc,GAAG,IAAA,yCAAmB,EACtC,MAAM,CAAC,WAAW,EAAE,EACpB,aAAa,EACb,SAAS,EACT,MAAA,CAAC,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC,IAAI;YACxC,CAAC,CAAC,GAAG;YACL,CAAC,CAAC,iBAAiB,CAAC,aAAa,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAC9D,0CAAE,IAAI,CACV,CAAC;QAEF,oEAAoE;QACpE,IAAM,WAAW,GAAG,IAAA,+DAA8B,EAC9C,MAAM,EACN,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,SAAS,CACZ,CAAC;QAEF,sCAAsC;QACtC,IAAA,mCAAgB,EAAC,WAAW,CAAC,QAAQ,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;QAEzE,kDAAkD;QAClD,IAAA,qCAAiB,EAAC,MAAM,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;IAC1D,CAAC;IA9CD,sBA8CC;IAED,SAAS,iBAAiB,CACtB,IAA+B,EAC/B,kBAAsC;QAEtC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC,eAAe,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAChG,CAAC","sourcesContent":["import { cloneModelForPaste, mergePasteContent } from '../../utils/paste/mergePasteContent';\nimport { convertInlineCss } from '../../utils/convertInlineCss';\nimport { createPasteFragment } from '../../utils/paste/createPasteFragment';\nimport { generatePasteOptionFromPlugins } from '../../utils/paste/generatePasteOptionFromPlugins';\nimport { retrieveHtmlInfo } from '../../utils/paste/retrieveHtmlInfo';\nimport type {\n PasteType,\n ClipboardData,\n TrustedHTMLHandler,\n IEditor,\n} from 'roosterjs-content-model-types';\n\n/**\n * Paste into editor using a clipboardData object\n * @param editor The Editor object.\n * @param clipboardData Clipboard data retrieved from clipboard\n * @param pasteType Type of content to paste. @default normal\n */\nexport function paste(\n editor: IEditor,\n clipboardData: ClipboardData,\n pasteType: PasteType = 'normal'\n) {\n editor.focus();\n\n const trustedHTMLHandler = editor.getTrustedHTMLHandler();\n\n if (!clipboardData.modelBeforePaste) {\n clipboardData.modelBeforePaste = cloneModelForPaste(\n editor.getContentModelCopy('connected')\n );\n }\n\n // 1. Prepare variables\n const doc = createDOMFromHtml(clipboardData.rawHtml, trustedHTMLHandler);\n\n // 2. Handle HTML from clipboard\n const htmlFromClipboard = retrieveHtmlInfo(doc, clipboardData);\n\n // 3. Create target fragment\n const sourceFragment = createPasteFragment(\n editor.getDocument(),\n clipboardData,\n pasteType,\n (clipboardData.rawHtml == clipboardData.html\n ? doc\n : createDOMFromHtml(clipboardData.html, trustedHTMLHandler)\n )?.body\n );\n\n // 4. Trigger BeforePaste event to allow plugins modify the fragment\n const eventResult = generatePasteOptionFromPlugins(\n editor,\n clipboardData,\n sourceFragment,\n htmlFromClipboard,\n pasteType\n );\n\n // 5. Convert global CSS to inline CSS\n convertInlineCss(eventResult.fragment, htmlFromClipboard.globalCssRules);\n\n // 6. Merge pasted content into main Content Model\n mergePasteContent(editor, eventResult, clipboardData);\n}\n\nfunction createDOMFromHtml(\n html: string | null | undefined,\n trustedHTMLHandler: TrustedHTMLHandler\n): Document | null {\n return html ? new DOMParser().parseFromString(trustedHTMLHandler(html), 'text/html') : null;\n}\n"]}
@@ -1,4 +1,8 @@
1
- import type { BeforePasteEvent, ClipboardData, IEditor } from 'roosterjs-content-model-types';
1
+ import type { BeforePasteEvent, ClipboardData, ContentModelDocument, IEditor } from 'roosterjs-content-model-types';
2
+ /**
3
+ * @internal
4
+ */
5
+ export declare function cloneModelForPaste(model: ContentModelDocument): ContentModelDocument;
2
6
  /**
3
7
  * @internal
4
8
  */
@@ -1,7 +1,7 @@
1
1
  define(["require", "exports", "tslib", "../../constants/ChangeSource", "../../publicApi/model/cloneModel", "../createDomToModelContextForSanitizing", "roosterjs-content-model-dom", "../../publicApi/domUtils/getSegmentTextFormat", "../../publicApi/selection/collectSelections", "../../publicApi/model/mergeModel"], function (require, exports, tslib_1, ChangeSource_1, cloneModel_1, createDomToModelContextForSanitizing_1, roosterjs_content_model_dom_1, getSegmentTextFormat_1, collectSelections_1, mergeModel_1) {
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.mergePasteContent = void 0;
4
+ exports.mergePasteContent = exports.cloneModelForPaste = void 0;
5
5
  var EmptySegmentFormat = {
6
6
  backgroundColor: '',
7
7
  fontFamily: '',
@@ -18,6 +18,13 @@ define(["require", "exports", "tslib", "../../constants/ChangeSource", "../../pu
18
18
  var CloneOption = {
19
19
  includeCachedElement: function (node, type) { return (type == 'cache' ? undefined : node); },
20
20
  };
21
+ /**
22
+ * @internal
23
+ */
24
+ function cloneModelForPaste(model) {
25
+ return (0, cloneModel_1.cloneModel)(model, CloneOption);
26
+ }
27
+ exports.cloneModelForPaste = cloneModelForPaste;
21
28
  /**
22
29
  * @internal
23
30
  */
@@ -25,7 +32,7 @@ define(["require", "exports", "tslib", "../../constants/ChangeSource", "../../pu
25
32
  var fragment = eventResult.fragment, domToModelOption = eventResult.domToModelOption, customizedMerge = eventResult.customizedMerge, pasteType = eventResult.pasteType;
26
33
  editor.formatContentModel(function (model, context) {
27
34
  if (clipboardData.modelBeforePaste) {
28
- var clonedModel = (0, cloneModel_1.cloneModel)(clipboardData.modelBeforePaste, CloneOption);
35
+ var clonedModel = cloneModelForPaste(clipboardData.modelBeforePaste);
29
36
  model.blocks = clonedModel.blocks;
30
37
  }
31
38
  var selectedSegment = (0, collectSelections_1.getSelectedSegments)(model, true /*includeFormatHolder*/)[0];
@@ -1 +1 @@
1
- {"version":3,"file":"mergePasteContent.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/utils/paste/mergePasteContent.ts"],"names":[],"mappings":";;;;IAiBA,IAAM,kBAAkB,GAAwC;QAC5D,eAAe,EAAE,EAAE;QACnB,UAAU,EAAE,EAAE;QACd,QAAQ,EAAE,EAAE;QACZ,UAAU,EAAE,EAAE;QACd,MAAM,EAAE,KAAK;QACb,aAAa,EAAE,EAAE;QACjB,UAAU,EAAE,EAAE;QACd,aAAa,EAAE,KAAK;QACpB,wBAAwB,EAAE,EAAE;QAC5B,SAAS,EAAE,EAAE;QACb,SAAS,EAAE,KAAK;KACnB,CAAC;IACF,IAAM,WAAW,GAAsB;QACnC,oBAAoB,EAAE,UAAC,IAAI,EAAE,IAAI,IAAK,OAAA,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,EAApC,CAAoC;KAC7E,CAAC;IAEF;;OAEG;IACH,SAAgB,iBAAiB,CAC7B,MAAe,EACf,WAA6B,EAC7B,aAA4B;QAEpB,IAAA,QAAQ,GAAmD,WAAW,SAA9D,EAAE,gBAAgB,GAAiC,WAAW,iBAA5C,EAAE,eAAe,GAAgB,WAAW,gBAA3B,EAAE,SAAS,GAAK,WAAW,UAAhB,CAAiB;QAE/E,MAAM,CAAC,kBAAkB,CACrB,UAAC,KAAK,EAAE,OAAO;YACX,IAAI,aAAa,CAAC,gBAAgB,EAAE;gBAChC,IAAM,WAAW,GAAG,IAAA,uBAAU,EAAC,aAAa,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;gBAC5E,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;aACrC;YAED,IAAM,eAAe,GAAG,IAAA,uCAAmB,EAAC,KAAK,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC;YACpF,IAAM,iBAAiB,GAAG,IAAA,2EAAoC,EAC1D,MAAM,CAAC,WAAW,EAAE,EACpB,SAAS,CAAC,iBAAiB,EAC3B,MAAM,CAAC,cAAc,EAAE,CAAC,kBAAkB,CAAC,UAAU,EACrD,gBAAgB,CACnB,CAAC;YAEF,iBAAiB,CAAC,aAAa,GAAG,eAAe;gBAC7C,CAAC,CAAC,IAAA,2CAAoB,EAAC,eAAe,CAAC;gBACvC,CAAC,CAAC,EAAE,CAAC;YAET,IAAM,UAAU,GAAG,IAAA,+CAAiB,EAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;YAClE,IAAM,WAAW,GAAqB;gBAClC,WAAW,EAAE,SAAS,IAAI,aAAa,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,MAAM;gBAC7E,UAAU,EAAE,gBAAgB,CAAC,UAAU,CAAC;aAC3C,CAAC;YAEF,IAAM,WAAW,GAAG,eAAe;gBAC/B,CAAC,CAAC,eAAe,CAAC,KAAK,EAAE,UAAU,CAAC;gBACpC,CAAC,CAAC,IAAA,uBAAU,EAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;YAE1D,IAAI,WAAW,EAAE;gBACb,OAAO,CAAC,gBAAgB,yEACjB,kBAAkB,GAClB,KAAK,CAAC,MAAM,GACZ,WAAW,CAAC,MAAM,CAAC,MAAM,CAC/B,CAAC;aACL;YAED,OAAO,IAAI,CAAC;QAChB,CAAC,EACD;YACI,YAAY,EAAE,2BAAY,CAAC,KAAK;YAChC,aAAa,EAAE,cAAM,OAAA,aAAa,EAAb,CAAa;YAClC,OAAO,EAAE,OAAO;SACnB,CACJ,CAAC;IACN,CAAC;IApDD,8CAoDC;IAED,SAAS,gBAAgB,CAAC,UAAgC;QACtD,mIAAmI;QACnI,IACI,UAAU,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC;YAC7B,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,OAAO;YAC1C,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,WAAW;YAC9C,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;YAC1C,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,IAAI,EACvD;YACE,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;SAC/B;QACD,6DAA6D;QAC7D,OAAO,UAAU,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,OAAO,CAAC;IACxF,CAAC","sourcesContent":["import { ChangeSource } from '../../constants/ChangeSource';\nimport { cloneModel } from '../../publicApi/model/cloneModel';\nimport { createDomToModelContextForSanitizing } from '../createDomToModelContextForSanitizing';\nimport { domToContentModel } from 'roosterjs-content-model-dom';\nimport { getSegmentTextFormat } from '../../publicApi/domUtils/getSegmentTextFormat';\nimport { getSelectedSegments } from '../../publicApi/selection/collectSelections';\nimport { mergeModel } from '../../publicApi/model/mergeModel';\nimport type { MergeModelOption } from '../../publicApi/model/mergeModel';\nimport type {\n BeforePasteEvent,\n ClipboardData,\n CloneModelOptions,\n ContentModelDocument,\n ContentModelSegmentFormat,\n IEditor,\n} from 'roosterjs-content-model-types';\n\nconst EmptySegmentFormat: Required<ContentModelSegmentFormat> = {\n backgroundColor: '',\n fontFamily: '',\n fontSize: '',\n fontWeight: '',\n italic: false,\n letterSpacing: '',\n lineHeight: '',\n strikethrough: false,\n superOrSubScriptSequence: '',\n textColor: '',\n underline: false,\n};\nconst CloneOption: CloneModelOptions = {\n includeCachedElement: (node, type) => (type == 'cache' ? undefined : node),\n};\n\n/**\n * @internal\n */\nexport function mergePasteContent(\n editor: IEditor,\n eventResult: BeforePasteEvent,\n clipboardData: ClipboardData\n) {\n const { fragment, domToModelOption, customizedMerge, pasteType } = eventResult;\n\n editor.formatContentModel(\n (model, context) => {\n if (clipboardData.modelBeforePaste) {\n const clonedModel = cloneModel(clipboardData.modelBeforePaste, CloneOption);\n model.blocks = clonedModel.blocks;\n }\n\n const selectedSegment = getSelectedSegments(model, true /*includeFormatHolder*/)[0];\n const domToModelContext = createDomToModelContextForSanitizing(\n editor.getDocument(),\n undefined /*defaultFormat*/,\n editor.getEnvironment().domToModelSettings.customized,\n domToModelOption\n );\n\n domToModelContext.segmentFormat = selectedSegment\n ? getSegmentTextFormat(selectedSegment)\n : {};\n\n const pasteModel = domToContentModel(fragment, domToModelContext);\n const mergeOption: MergeModelOption = {\n mergeFormat: pasteType == 'mergeFormat' ? 'keepSourceEmphasisFormat' : 'none',\n mergeTable: shouldMergeTable(pasteModel),\n };\n\n const insertPoint = customizedMerge\n ? customizedMerge(model, pasteModel)\n : mergeModel(model, pasteModel, context, mergeOption);\n\n if (insertPoint) {\n context.newPendingFormat = {\n ...EmptySegmentFormat,\n ...model.format,\n ...insertPoint.marker.format,\n };\n }\n\n return true;\n },\n {\n changeSource: ChangeSource.Paste,\n getChangeData: () => clipboardData,\n apiName: 'paste',\n }\n );\n}\n\nfunction shouldMergeTable(pasteModel: ContentModelDocument): boolean | undefined {\n // If model contains a table and a paragraph element after the table with a single BR segment, remove the Paragraph after the table\n if (\n pasteModel.blocks.length == 2 &&\n pasteModel.blocks[0].blockType === 'Table' &&\n pasteModel.blocks[1].blockType === 'Paragraph' &&\n pasteModel.blocks[1].segments.length === 1 &&\n pasteModel.blocks[1].segments[0].segmentType === 'Br'\n ) {\n pasteModel.blocks.splice(1);\n }\n // Only merge table when the document contain a single table.\n return pasteModel.blocks.length === 1 && pasteModel.blocks[0].blockType === 'Table';\n}\n"]}
1
+ {"version":3,"file":"mergePasteContent.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/utils/paste/mergePasteContent.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource } from '../../constants/ChangeSource';\nimport { cloneModel } from '../../publicApi/model/cloneModel';\nimport { createDomToModelContextForSanitizing } from '../createDomToModelContextForSanitizing';\nimport { domToContentModel } from 'roosterjs-content-model-dom';\nimport { getSegmentTextFormat } from '../../publicApi/domUtils/getSegmentTextFormat';\nimport { getSelectedSegments } from '../../publicApi/selection/collectSelections';\nimport { mergeModel } from '../../publicApi/model/mergeModel';\nimport type { MergeModelOption } from '../../publicApi/model/mergeModel';\nimport type {\n BeforePasteEvent,\n ClipboardData,\n CloneModelOptions,\n ContentModelDocument,\n ContentModelSegmentFormat,\n IEditor,\n} from 'roosterjs-content-model-types';\n\nconst EmptySegmentFormat: Required<ContentModelSegmentFormat> = {\n backgroundColor: '',\n fontFamily: '',\n fontSize: '',\n fontWeight: '',\n italic: false,\n letterSpacing: '',\n lineHeight: '',\n strikethrough: false,\n superOrSubScriptSequence: '',\n textColor: '',\n underline: false,\n};\n\nconst CloneOption: CloneModelOptions = {\n includeCachedElement: (node, type) => (type == 'cache' ? undefined : node),\n};\n\n/**\n * @internal\n */\nexport function cloneModelForPaste(model: ContentModelDocument) {\n return cloneModel(model, CloneOption);\n}\n\n/**\n * @internal\n */\nexport function mergePasteContent(\n editor: IEditor,\n eventResult: BeforePasteEvent,\n clipboardData: ClipboardData\n) {\n const { fragment, domToModelOption, customizedMerge, pasteType } = eventResult;\n\n editor.formatContentModel(\n (model, context) => {\n if (clipboardData.modelBeforePaste) {\n const clonedModel = cloneModelForPaste(clipboardData.modelBeforePaste);\n model.blocks = clonedModel.blocks;\n }\n\n const selectedSegment = getSelectedSegments(model, true /*includeFormatHolder*/)[0];\n const domToModelContext = createDomToModelContextForSanitizing(\n editor.getDocument(),\n undefined /*defaultFormat*/,\n editor.getEnvironment().domToModelSettings.customized,\n domToModelOption\n );\n\n domToModelContext.segmentFormat = selectedSegment\n ? getSegmentTextFormat(selectedSegment)\n : {};\n\n const pasteModel = domToContentModel(fragment, domToModelContext);\n const mergeOption: MergeModelOption = {\n mergeFormat: pasteType == 'mergeFormat' ? 'keepSourceEmphasisFormat' : 'none',\n mergeTable: shouldMergeTable(pasteModel),\n };\n\n const insertPoint = customizedMerge\n ? customizedMerge(model, pasteModel)\n : mergeModel(model, pasteModel, context, mergeOption);\n\n if (insertPoint) {\n context.newPendingFormat = {\n ...EmptySegmentFormat,\n ...model.format,\n ...insertPoint.marker.format,\n };\n }\n\n return true;\n },\n {\n changeSource: ChangeSource.Paste,\n getChangeData: () => clipboardData,\n apiName: 'paste',\n }\n );\n}\n\nfunction shouldMergeTable(pasteModel: ContentModelDocument): boolean | undefined {\n // If model contains a table and a paragraph element after the table with a single BR segment, remove the Paragraph after the table\n if (\n pasteModel.blocks.length == 2 &&\n pasteModel.blocks[0].blockType === 'Table' &&\n pasteModel.blocks[1].blockType === 'Paragraph' &&\n pasteModel.blocks[1].segments.length === 1 &&\n pasteModel.blocks[1].segments[0].segmentType === 'Br'\n ) {\n pasteModel.blocks.splice(1);\n }\n // Only merge table when the document contain a single table.\n return pasteModel.blocks.length === 1 && pasteModel.blocks[0].blockType === 'Table';\n}\n"]}
@@ -1,7 +1,7 @@
1
+ import { cloneModelForPaste, mergePasteContent } from '../../utils/paste/mergePasteContent';
1
2
  import { convertInlineCss } from '../../utils/convertInlineCss';
2
3
  import { createPasteFragment } from '../../utils/paste/createPasteFragment';
3
4
  import { generatePasteOptionFromPlugins } from '../../utils/paste/generatePasteOptionFromPlugins';
4
- import { mergePasteContent } from '../../utils/paste/mergePasteContent';
5
5
  import { retrieveHtmlInfo } from '../../utils/paste/retrieveHtmlInfo';
6
6
  /**
7
7
  * Paste into editor using a clipboardData object
@@ -15,7 +15,7 @@ export function paste(editor, clipboardData, pasteType) {
15
15
  editor.focus();
16
16
  var trustedHTMLHandler = editor.getTrustedHTMLHandler();
17
17
  if (!clipboardData.modelBeforePaste) {
18
- clipboardData.modelBeforePaste = editor.getContentModelCopy('connected');
18
+ clipboardData.modelBeforePaste = cloneModelForPaste(editor.getContentModelCopy('connected'));
19
19
  }
20
20
  // 1. Prepare variables
21
21
  var doc = createDOMFromHtml(clipboardData.rawHtml, trustedHTMLHandler);
@@ -1 +1 @@
1
- {"version":3,"file":"paste.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/publicApi/paste/paste.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,8BAA8B,EAAE,MAAM,kDAAkD,CAAC;AAClG,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAQtE;;;;;GAKG;AACH,MAAM,UAAU,KAAK,CACjB,MAAe,EACf,aAA4B,EAC5B,SAA+B;;IAA/B,0BAAA,EAAA,oBAA+B;IAE/B,MAAM,CAAC,KAAK,EAAE,CAAC;IAEf,IAAM,kBAAkB,GAAG,MAAM,CAAC,qBAAqB,EAAE,CAAC;IAE1D,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE;QACjC,aAAa,CAAC,gBAAgB,GAAG,MAAM,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;KAC5E;IAED,uBAAuB;IACvB,IAAM,GAAG,GAAG,iBAAiB,CAAC,aAAa,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;IAEzE,gCAAgC;IAChC,IAAM,iBAAiB,GAAG,gBAAgB,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAE/D,4BAA4B;IAC5B,IAAM,cAAc,GAAG,mBAAmB,CACtC,MAAM,CAAC,WAAW,EAAE,EACpB,aAAa,EACb,SAAS,EACT,MAAA,CAAC,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC,IAAI;QACxC,CAAC,CAAC,GAAG;QACL,CAAC,CAAC,iBAAiB,CAAC,aAAa,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAC9D,0CAAE,IAAI,CACV,CAAC;IAEF,oEAAoE;IACpE,IAAM,WAAW,GAAG,8BAA8B,CAC9C,MAAM,EACN,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,SAAS,CACZ,CAAC;IAEF,sCAAsC;IACtC,gBAAgB,CAAC,WAAW,CAAC,QAAQ,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;IAEzE,kDAAkD;IAClD,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,iBAAiB,CACtB,IAA+B,EAC/B,kBAAsC;IAEtC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC,eAAe,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChG,CAAC","sourcesContent":["import { convertInlineCss } from '../../utils/convertInlineCss';\nimport { createPasteFragment } from '../../utils/paste/createPasteFragment';\nimport { generatePasteOptionFromPlugins } from '../../utils/paste/generatePasteOptionFromPlugins';\nimport { mergePasteContent } from '../../utils/paste/mergePasteContent';\nimport { retrieveHtmlInfo } from '../../utils/paste/retrieveHtmlInfo';\nimport type {\n PasteType,\n ClipboardData,\n TrustedHTMLHandler,\n IEditor,\n} from 'roosterjs-content-model-types';\n\n/**\n * Paste into editor using a clipboardData object\n * @param editor The Editor object.\n * @param clipboardData Clipboard data retrieved from clipboard\n * @param pasteType Type of content to paste. @default normal\n */\nexport function paste(\n editor: IEditor,\n clipboardData: ClipboardData,\n pasteType: PasteType = 'normal'\n) {\n editor.focus();\n\n const trustedHTMLHandler = editor.getTrustedHTMLHandler();\n\n if (!clipboardData.modelBeforePaste) {\n clipboardData.modelBeforePaste = editor.getContentModelCopy('connected');\n }\n\n // 1. Prepare variables\n const doc = createDOMFromHtml(clipboardData.rawHtml, trustedHTMLHandler);\n\n // 2. Handle HTML from clipboard\n const htmlFromClipboard = retrieveHtmlInfo(doc, clipboardData);\n\n // 3. Create target fragment\n const sourceFragment = createPasteFragment(\n editor.getDocument(),\n clipboardData,\n pasteType,\n (clipboardData.rawHtml == clipboardData.html\n ? doc\n : createDOMFromHtml(clipboardData.html, trustedHTMLHandler)\n )?.body\n );\n\n // 4. Trigger BeforePaste event to allow plugins modify the fragment\n const eventResult = generatePasteOptionFromPlugins(\n editor,\n clipboardData,\n sourceFragment,\n htmlFromClipboard,\n pasteType\n );\n\n // 5. Convert global CSS to inline CSS\n convertInlineCss(eventResult.fragment, htmlFromClipboard.globalCssRules);\n\n // 6. Merge pasted content into main Content Model\n mergePasteContent(editor, eventResult, clipboardData);\n}\n\nfunction createDOMFromHtml(\n html: string | null | undefined,\n trustedHTMLHandler: TrustedHTMLHandler\n): Document | null {\n return html ? new DOMParser().parseFromString(trustedHTMLHandler(html), 'text/html') : null;\n}\n"]}
1
+ {"version":3,"file":"paste.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/publicApi/paste/paste.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,8BAA8B,EAAE,MAAM,kDAAkD,CAAC;AAClG,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAQtE;;;;;GAKG;AACH,MAAM,UAAU,KAAK,CACjB,MAAe,EACf,aAA4B,EAC5B,SAA+B;;IAA/B,0BAAA,EAAA,oBAA+B;IAE/B,MAAM,CAAC,KAAK,EAAE,CAAC;IAEf,IAAM,kBAAkB,GAAG,MAAM,CAAC,qBAAqB,EAAE,CAAC;IAE1D,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE;QACjC,aAAa,CAAC,gBAAgB,GAAG,kBAAkB,CAC/C,MAAM,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAC1C,CAAC;KACL;IAED,uBAAuB;IACvB,IAAM,GAAG,GAAG,iBAAiB,CAAC,aAAa,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;IAEzE,gCAAgC;IAChC,IAAM,iBAAiB,GAAG,gBAAgB,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAE/D,4BAA4B;IAC5B,IAAM,cAAc,GAAG,mBAAmB,CACtC,MAAM,CAAC,WAAW,EAAE,EACpB,aAAa,EACb,SAAS,EACT,MAAA,CAAC,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC,IAAI;QACxC,CAAC,CAAC,GAAG;QACL,CAAC,CAAC,iBAAiB,CAAC,aAAa,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAC9D,0CAAE,IAAI,CACV,CAAC;IAEF,oEAAoE;IACpE,IAAM,WAAW,GAAG,8BAA8B,CAC9C,MAAM,EACN,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,SAAS,CACZ,CAAC;IAEF,sCAAsC;IACtC,gBAAgB,CAAC,WAAW,CAAC,QAAQ,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;IAEzE,kDAAkD;IAClD,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,iBAAiB,CACtB,IAA+B,EAC/B,kBAAsC;IAEtC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC,eAAe,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChG,CAAC","sourcesContent":["import { cloneModelForPaste, mergePasteContent } from '../../utils/paste/mergePasteContent';\nimport { convertInlineCss } from '../../utils/convertInlineCss';\nimport { createPasteFragment } from '../../utils/paste/createPasteFragment';\nimport { generatePasteOptionFromPlugins } from '../../utils/paste/generatePasteOptionFromPlugins';\nimport { retrieveHtmlInfo } from '../../utils/paste/retrieveHtmlInfo';\nimport type {\n PasteType,\n ClipboardData,\n TrustedHTMLHandler,\n IEditor,\n} from 'roosterjs-content-model-types';\n\n/**\n * Paste into editor using a clipboardData object\n * @param editor The Editor object.\n * @param clipboardData Clipboard data retrieved from clipboard\n * @param pasteType Type of content to paste. @default normal\n */\nexport function paste(\n editor: IEditor,\n clipboardData: ClipboardData,\n pasteType: PasteType = 'normal'\n) {\n editor.focus();\n\n const trustedHTMLHandler = editor.getTrustedHTMLHandler();\n\n if (!clipboardData.modelBeforePaste) {\n clipboardData.modelBeforePaste = cloneModelForPaste(\n editor.getContentModelCopy('connected')\n );\n }\n\n // 1. Prepare variables\n const doc = createDOMFromHtml(clipboardData.rawHtml, trustedHTMLHandler);\n\n // 2. Handle HTML from clipboard\n const htmlFromClipboard = retrieveHtmlInfo(doc, clipboardData);\n\n // 3. Create target fragment\n const sourceFragment = createPasteFragment(\n editor.getDocument(),\n clipboardData,\n pasteType,\n (clipboardData.rawHtml == clipboardData.html\n ? doc\n : createDOMFromHtml(clipboardData.html, trustedHTMLHandler)\n )?.body\n );\n\n // 4. Trigger BeforePaste event to allow plugins modify the fragment\n const eventResult = generatePasteOptionFromPlugins(\n editor,\n clipboardData,\n sourceFragment,\n htmlFromClipboard,\n pasteType\n );\n\n // 5. Convert global CSS to inline CSS\n convertInlineCss(eventResult.fragment, htmlFromClipboard.globalCssRules);\n\n // 6. Merge pasted content into main Content Model\n mergePasteContent(editor, eventResult, clipboardData);\n}\n\nfunction createDOMFromHtml(\n html: string | null | undefined,\n trustedHTMLHandler: TrustedHTMLHandler\n): Document | null {\n return html ? new DOMParser().parseFromString(trustedHTMLHandler(html), 'text/html') : null;\n}\n"]}
@@ -1,4 +1,8 @@
1
- import type { BeforePasteEvent, ClipboardData, IEditor } from 'roosterjs-content-model-types';
1
+ import type { BeforePasteEvent, ClipboardData, ContentModelDocument, IEditor } from 'roosterjs-content-model-types';
2
+ /**
3
+ * @internal
4
+ */
5
+ export declare function cloneModelForPaste(model: ContentModelDocument): ContentModelDocument;
2
6
  /**
3
7
  * @internal
4
8
  */
@@ -22,6 +22,12 @@ var EmptySegmentFormat = {
22
22
  var CloneOption = {
23
23
  includeCachedElement: function (node, type) { return (type == 'cache' ? undefined : node); },
24
24
  };
25
+ /**
26
+ * @internal
27
+ */
28
+ export function cloneModelForPaste(model) {
29
+ return cloneModel(model, CloneOption);
30
+ }
25
31
  /**
26
32
  * @internal
27
33
  */
@@ -29,7 +35,7 @@ export function mergePasteContent(editor, eventResult, clipboardData) {
29
35
  var fragment = eventResult.fragment, domToModelOption = eventResult.domToModelOption, customizedMerge = eventResult.customizedMerge, pasteType = eventResult.pasteType;
30
36
  editor.formatContentModel(function (model, context) {
31
37
  if (clipboardData.modelBeforePaste) {
32
- var clonedModel = cloneModel(clipboardData.modelBeforePaste, CloneOption);
38
+ var clonedModel = cloneModelForPaste(clipboardData.modelBeforePaste);
33
39
  model.blocks = clonedModel.blocks;
34
40
  }
35
41
  var selectedSegment = getSelectedSegments(model, true /*includeFormatHolder*/)[0];
@@ -1 +1 @@
1
- {"version":3,"file":"mergePasteContent.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/utils/paste/mergePasteContent.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource } from '../../constants/ChangeSource';\nimport { cloneModel } from '../../publicApi/model/cloneModel';\nimport { createDomToModelContextForSanitizing } from '../createDomToModelContextForSanitizing';\nimport { domToContentModel } from 'roosterjs-content-model-dom';\nimport { getSegmentTextFormat } from '../../publicApi/domUtils/getSegmentTextFormat';\nimport { getSelectedSegments } from '../../publicApi/selection/collectSelections';\nimport { mergeModel } from '../../publicApi/model/mergeModel';\nimport type { MergeModelOption } from '../../publicApi/model/mergeModel';\nimport type {\n BeforePasteEvent,\n ClipboardData,\n CloneModelOptions,\n ContentModelDocument,\n ContentModelSegmentFormat,\n IEditor,\n} from 'roosterjs-content-model-types';\n\nconst EmptySegmentFormat: Required<ContentModelSegmentFormat> = {\n backgroundColor: '',\n fontFamily: '',\n fontSize: '',\n fontWeight: '',\n italic: false,\n letterSpacing: '',\n lineHeight: '',\n strikethrough: false,\n superOrSubScriptSequence: '',\n textColor: '',\n underline: false,\n};\nconst CloneOption: CloneModelOptions = {\n includeCachedElement: (node, type) => (type == 'cache' ? undefined : node),\n};\n\n/**\n * @internal\n */\nexport function mergePasteContent(\n editor: IEditor,\n eventResult: BeforePasteEvent,\n clipboardData: ClipboardData\n) {\n const { fragment, domToModelOption, customizedMerge, pasteType } = eventResult;\n\n editor.formatContentModel(\n (model, context) => {\n if (clipboardData.modelBeforePaste) {\n const clonedModel = cloneModel(clipboardData.modelBeforePaste, CloneOption);\n model.blocks = clonedModel.blocks;\n }\n\n const selectedSegment = getSelectedSegments(model, true /*includeFormatHolder*/)[0];\n const domToModelContext = createDomToModelContextForSanitizing(\n editor.getDocument(),\n undefined /*defaultFormat*/,\n editor.getEnvironment().domToModelSettings.customized,\n domToModelOption\n );\n\n domToModelContext.segmentFormat = selectedSegment\n ? getSegmentTextFormat(selectedSegment)\n : {};\n\n const pasteModel = domToContentModel(fragment, domToModelContext);\n const mergeOption: MergeModelOption = {\n mergeFormat: pasteType == 'mergeFormat' ? 'keepSourceEmphasisFormat' : 'none',\n mergeTable: shouldMergeTable(pasteModel),\n };\n\n const insertPoint = customizedMerge\n ? customizedMerge(model, pasteModel)\n : mergeModel(model, pasteModel, context, mergeOption);\n\n if (insertPoint) {\n context.newPendingFormat = {\n ...EmptySegmentFormat,\n ...model.format,\n ...insertPoint.marker.format,\n };\n }\n\n return true;\n },\n {\n changeSource: ChangeSource.Paste,\n getChangeData: () => clipboardData,\n apiName: 'paste',\n }\n );\n}\n\nfunction shouldMergeTable(pasteModel: ContentModelDocument): boolean | undefined {\n // If model contains a table and a paragraph element after the table with a single BR segment, remove the Paragraph after the table\n if (\n pasteModel.blocks.length == 2 &&\n pasteModel.blocks[0].blockType === 'Table' &&\n pasteModel.blocks[1].blockType === 'Paragraph' &&\n pasteModel.blocks[1].segments.length === 1 &&\n pasteModel.blocks[1].segments[0].segmentType === 'Br'\n ) {\n pasteModel.blocks.splice(1);\n }\n // Only merge table when the document contain a single table.\n return pasteModel.blocks.length === 1 && pasteModel.blocks[0].blockType === 'Table';\n}\n"]}
1
+ {"version":3,"file":"mergePasteContent.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/utils/paste/mergePasteContent.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeSource } from '../../constants/ChangeSource';\nimport { cloneModel } from '../../publicApi/model/cloneModel';\nimport { createDomToModelContextForSanitizing } from '../createDomToModelContextForSanitizing';\nimport { domToContentModel } from 'roosterjs-content-model-dom';\nimport { getSegmentTextFormat } from '../../publicApi/domUtils/getSegmentTextFormat';\nimport { getSelectedSegments } from '../../publicApi/selection/collectSelections';\nimport { mergeModel } from '../../publicApi/model/mergeModel';\nimport type { MergeModelOption } from '../../publicApi/model/mergeModel';\nimport type {\n BeforePasteEvent,\n ClipboardData,\n CloneModelOptions,\n ContentModelDocument,\n ContentModelSegmentFormat,\n IEditor,\n} from 'roosterjs-content-model-types';\n\nconst EmptySegmentFormat: Required<ContentModelSegmentFormat> = {\n backgroundColor: '',\n fontFamily: '',\n fontSize: '',\n fontWeight: '',\n italic: false,\n letterSpacing: '',\n lineHeight: '',\n strikethrough: false,\n superOrSubScriptSequence: '',\n textColor: '',\n underline: false,\n};\n\nconst CloneOption: CloneModelOptions = {\n includeCachedElement: (node, type) => (type == 'cache' ? undefined : node),\n};\n\n/**\n * @internal\n */\nexport function cloneModelForPaste(model: ContentModelDocument) {\n return cloneModel(model, CloneOption);\n}\n\n/**\n * @internal\n */\nexport function mergePasteContent(\n editor: IEditor,\n eventResult: BeforePasteEvent,\n clipboardData: ClipboardData\n) {\n const { fragment, domToModelOption, customizedMerge, pasteType } = eventResult;\n\n editor.formatContentModel(\n (model, context) => {\n if (clipboardData.modelBeforePaste) {\n const clonedModel = cloneModelForPaste(clipboardData.modelBeforePaste);\n model.blocks = clonedModel.blocks;\n }\n\n const selectedSegment = getSelectedSegments(model, true /*includeFormatHolder*/)[0];\n const domToModelContext = createDomToModelContextForSanitizing(\n editor.getDocument(),\n undefined /*defaultFormat*/,\n editor.getEnvironment().domToModelSettings.customized,\n domToModelOption\n );\n\n domToModelContext.segmentFormat = selectedSegment\n ? getSegmentTextFormat(selectedSegment)\n : {};\n\n const pasteModel = domToContentModel(fragment, domToModelContext);\n const mergeOption: MergeModelOption = {\n mergeFormat: pasteType == 'mergeFormat' ? 'keepSourceEmphasisFormat' : 'none',\n mergeTable: shouldMergeTable(pasteModel),\n };\n\n const insertPoint = customizedMerge\n ? customizedMerge(model, pasteModel)\n : mergeModel(model, pasteModel, context, mergeOption);\n\n if (insertPoint) {\n context.newPendingFormat = {\n ...EmptySegmentFormat,\n ...model.format,\n ...insertPoint.marker.format,\n };\n }\n\n return true;\n },\n {\n changeSource: ChangeSource.Paste,\n getChangeData: () => clipboardData,\n apiName: 'paste',\n }\n );\n}\n\nfunction shouldMergeTable(pasteModel: ContentModelDocument): boolean | undefined {\n // If model contains a table and a paragraph element after the table with a single BR segment, remove the Paragraph after the table\n if (\n pasteModel.blocks.length == 2 &&\n pasteModel.blocks[0].blockType === 'Table' &&\n pasteModel.blocks[1].blockType === 'Paragraph' &&\n pasteModel.blocks[1].segments.length === 1 &&\n pasteModel.blocks[1].segments[0].segmentType === 'Br'\n ) {\n pasteModel.blocks.splice(1);\n }\n // Only merge table when the document contain a single table.\n return pasteModel.blocks.length === 1 && pasteModel.blocks[0].blockType === 'Table';\n}\n"]}
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "roosterjs-content-model-dom": "^0.28.0",
7
7
  "roosterjs-content-model-types": "^0.28.0"
8
8
  },
9
- "version": "0.28.0",
9
+ "version": "0.28.1",
10
10
  "main": "./lib/index.js",
11
11
  "typings": "./lib/index.d.ts",
12
12
  "module": "./lib-mjs/index.js",