roosterjs-content-model-core 9.54.0 → 9.55.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/lib/command/paste/mergePasteContent.d.ts +1 -5
- package/lib/command/paste/mergePasteContent.js +2 -12
- package/lib/command/paste/mergePasteContent.js.map +1 -1
- package/lib/command/paste/paste.js +3 -2
- package/lib/command/paste/paste.js.map +1 -1
- package/lib/corePlugin/copyPaste/CopyPastePlugin.js +1 -1
- package/lib/corePlugin/copyPaste/CopyPastePlugin.js.map +1 -1
- package/lib-amd/command/paste/mergePasteContent.d.ts +1 -5
- package/lib-amd/command/paste/mergePasteContent.js +2 -12
- package/lib-amd/command/paste/mergePasteContent.js.map +1 -1
- package/lib-amd/command/paste/paste.js +2 -2
- package/lib-amd/command/paste/paste.js.map +1 -1
- package/lib-amd/corePlugin/copyPaste/CopyPastePlugin.js +1 -1
- package/lib-amd/corePlugin/copyPaste/CopyPastePlugin.js.map +1 -1
- package/lib-mjs/command/paste/mergePasteContent.d.ts +1 -5
- package/lib-mjs/command/paste/mergePasteContent.js +1 -10
- package/lib-mjs/command/paste/mergePasteContent.js.map +1 -1
- package/lib-mjs/command/paste/paste.js +2 -1
- package/lib-mjs/command/paste/paste.js.map +1 -1
- package/lib-mjs/corePlugin/copyPaste/CopyPastePlugin.js +1 -1
- package/lib-mjs/corePlugin/copyPaste/CopyPastePlugin.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import type { BeforePasteEvent,
|
|
2
|
-
/**
|
|
3
|
-
* @internal
|
|
4
|
-
*/
|
|
5
|
-
export declare function cloneModelForPaste(model: ReadonlyContentModelDocument): ContentModelDocument;
|
|
1
|
+
import type { BeforePasteEvent, IEditor } from 'roosterjs-content-model-types';
|
|
6
2
|
/**
|
|
7
3
|
* @internal
|
|
8
4
|
*/
|
|
@@ -1,20 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.mergePasteContent =
|
|
3
|
+
exports.mergePasteContent = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var createDomToModelContextForSanitizing_1 = require("../createModelFromHtml/createDomToModelContextForSanitizing");
|
|
6
6
|
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
7
7
|
var BlackColor = 'rgb(0,0,0)';
|
|
8
|
-
var CloneOption = {
|
|
9
|
-
includeCachedElement: function (node, type) { return (type == 'cache' ? undefined : node); },
|
|
10
|
-
};
|
|
11
|
-
/**
|
|
12
|
-
* @internal
|
|
13
|
-
*/
|
|
14
|
-
function cloneModelForPaste(model) {
|
|
15
|
-
return (0, roosterjs_content_model_dom_1.cloneModel)(model, CloneOption);
|
|
16
|
-
}
|
|
17
|
-
exports.cloneModelForPaste = cloneModelForPaste;
|
|
18
8
|
/**
|
|
19
9
|
* @internal
|
|
20
10
|
*/
|
|
@@ -22,7 +12,7 @@ function mergePasteContent(editor, eventResult, isFirstPaste) {
|
|
|
22
12
|
var fragment = eventResult.fragment, domToModelOption = eventResult.domToModelOption, customizedMerge = eventResult.customizedMerge, pasteType = eventResult.pasteType, clipboardData = eventResult.clipboardData, containsBlockElements = eventResult.containsBlockElements;
|
|
23
13
|
editor.formatContentModel(function (model, context) {
|
|
24
14
|
if (!isFirstPaste && clipboardData.modelBeforePaste) {
|
|
25
|
-
var clonedModel = cloneModelForPaste(clipboardData.modelBeforePaste);
|
|
15
|
+
var clonedModel = (0, roosterjs_content_model_dom_1.cloneModelForPaste)(clipboardData.modelBeforePaste);
|
|
26
16
|
model.blocks = clonedModel.blocks;
|
|
27
17
|
}
|
|
28
18
|
var domToModelContext = (0, createDomToModelContextForSanitizing_1.createDomToModelContextForSanitizing)(editor.getDocument(), undefined /*defaultFormat*/, editor.getEnvironment().domToModelSettings.customized, domToModelOption, editor.getDOMHelper());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mergePasteContent.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts"],"names":[],"mappings":";;;;AAAA,oHAAmH;AACnH,2EAQqC;
|
|
1
|
+
{"version":3,"file":"mergePasteContent.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts"],"names":[],"mappings":"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","sourcesContent":["import { createDomToModelContextForSanitizing } from '../createModelFromHtml/createDomToModelContextForSanitizing';\nimport {\n ChangeSource,\n EmptySegmentFormat,\n domToContentModel,\n getSegmentTextFormat,\n getSelectedSegments,\n mergeModel,\n cloneModelForPaste,\n} from 'roosterjs-content-model-dom';\nimport type {\n BeforePasteEvent,\n ContentModelDocument,\n ContentModelSegmentFormat,\n IEditor,\n MergeModelOption,\n PasteType,\n ShallowMutableContentModelDocument,\n} from 'roosterjs-content-model-types';\n\nconst BlackColor = 'rgb(0,0,0)';\n\n/**\n * @internal\n */\nexport function mergePasteContent(\n editor: IEditor,\n eventResult: BeforePasteEvent,\n isFirstPaste: boolean\n) {\n const {\n fragment,\n domToModelOption,\n customizedMerge,\n pasteType,\n clipboardData,\n containsBlockElements,\n } = eventResult;\n\n editor.formatContentModel(\n (model, context) => {\n if (!isFirstPaste && clipboardData.modelBeforePaste) {\n const clonedModel = cloneModelForPaste(clipboardData.modelBeforePaste);\n model.blocks = clonedModel.blocks;\n }\n\n const domToModelContext = createDomToModelContextForSanitizing(\n editor.getDocument(),\n undefined /*defaultFormat*/,\n editor.getEnvironment().domToModelSettings.customized,\n domToModelOption,\n editor.getDOMHelper()\n );\n\n domToModelContext.segmentFormat = getSegmentFormatForPaste(model, pasteType);\n\n const pasteModel = domToContentModel(fragment, domToModelContext);\n const mergeOption: MergeModelOption = {\n mergeFormat: pasteType == 'mergeFormat' ? 'keepSourceEmphasisFormat' : 'none',\n mergeTable: shouldMergeTable(pasteModel),\n addParagraphAfterMergedContent: containsBlockElements,\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 ...(pasteType == 'normal' && !containsBlockElements\n ? getLastSegmentFormat(pasteModel)\n : insertPoint.marker.format),\n };\n }\n\n return true;\n },\n {\n changeSource: ChangeSource.Paste,\n getChangeData: () => clipboardData,\n scrollCaretIntoView: true,\n apiName: 'paste',\n }\n );\n}\n\nfunction getSegmentFormatForPaste(\n model: ShallowMutableContentModelDocument,\n pasteType: PasteType\n): ContentModelSegmentFormat {\n const selectedSegment = getSelectedSegments(model, true /*includeFormatHolder*/)[0];\n\n if (selectedSegment) {\n const result = getSegmentTextFormat(selectedSegment);\n if (pasteType == 'normal') {\n // When using normal paste (Keep source formatting) set the default text color to black when creating the\n // Model from the clipboard content, so the elements that do not contain any text color in their style\n // Are set to black. Otherwise, These segments would get the selected segments format or the default text set in the content.\n result.textColor = BlackColor;\n }\n\n return result;\n }\n\n return {};\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\nfunction getLastSegmentFormat(pasteModel: ContentModelDocument): ContentModelSegmentFormat {\n if (pasteModel.blocks.length == 1) {\n const [firstBlock] = pasteModel.blocks;\n\n if (firstBlock.blockType == 'Paragraph') {\n const segment = firstBlock.segments[firstBlock.segments.length - 1];\n\n return {\n ...segment.format,\n };\n }\n }\n\n return {};\n}\n"]}
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.paste = void 0;
|
|
4
4
|
var cleanHtmlComments_1 = require("./cleanHtmlComments");
|
|
5
|
-
var
|
|
5
|
+
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
6
6
|
var convertInlineCss_1 = require("../createModelFromHtml/convertInlineCss");
|
|
7
7
|
var createPasteFragment_1 = require("./createPasteFragment");
|
|
8
8
|
var generatePasteOptionFromPlugins_1 = require("./generatePasteOptionFromPlugins");
|
|
9
|
+
var mergePasteContent_1 = require("./mergePasteContent");
|
|
9
10
|
var retrieveHtmlInfo_1 = require("./retrieveHtmlInfo");
|
|
10
11
|
/**
|
|
11
12
|
* Paste into editor using a clipboardData object
|
|
@@ -21,7 +22,7 @@ function paste(editor, clipboardData, pasteTypeOrGetter) {
|
|
|
21
22
|
if (!clipboardData.modelBeforePaste) {
|
|
22
23
|
isFirstPaste = true;
|
|
23
24
|
editor.formatContentModel(function (model) {
|
|
24
|
-
clipboardData.modelBeforePaste = (0,
|
|
25
|
+
clipboardData.modelBeforePaste = (0, roosterjs_content_model_dom_1.cloneModelForPaste)(model);
|
|
25
26
|
return false;
|
|
26
27
|
});
|
|
27
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paste.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/paste.ts"],"names":[],"mappings":";;;AAAA,yDAAwD;AACxD,
|
|
1
|
+
{"version":3,"file":"paste.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/paste.ts"],"names":[],"mappings":";;;AAAA,yDAAwD;AACxD,2EAAiE;AACjE,4EAA2E;AAC3E,6DAA4D;AAC5D,mFAAkF;AAClF,yDAAwD;AACxD,uDAAsD;AAQtD;;;;;GAKG;AACH,SAAgB,KAAK,CACjB,MAAe,EACf,aAA4B,EAC5B,iBAA+C;;IAA/C,kCAAA,EAAA,4BAA+C;IAE/C,MAAM,CAAC,KAAK,EAAE,CAAC;IACf,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE;QACjC,YAAY,GAAG,IAAI,CAAC;QAEpB,MAAM,CAAC,kBAAkB,CAAC,UAAA,KAAK;YAC3B,aAAa,CAAC,gBAAgB,GAAG,IAAA,gDAAkB,EAAC,KAAK,CAAC,CAAC;YAE3D,OAAO,KAAK,CAAC;QACjB,CAAC,CAAC,CAAC;KACN;IAED,uBAAuB;IACvB,IAAM,UAAU,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;IAC1C,IAAI,CAAC,UAAU,CAAC,UAAU,IAAI,aAAa,CAAC,OAAO,EAAE;QACjD,aAAa,CAAC,OAAO,GAAG,IAAA,qCAAiB,EAAC,aAAa,CAAC,OAAO,CAAC,CAAC;KACpE;IACD,IAAM,GAAG,GAAG,iBAAiB,CAAC,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACjE,IAAM,SAAS,GACX,OAAO,iBAAiB,IAAI,UAAU;QAClC,CAAC,CAAC,iBAAiB,CAAC,GAAG,EAAE,aAAa,CAAC;QACvC,CAAC,CAAC,iBAAiB,CAAC;IAE5B,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,UAAU,CAAC,CACtD,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,YAAY,CAAC,CAAC;AACzD,CAAC;AAzDD,sBAyDC;AAED,SAAS,iBAAiB,CACtB,IAA+B,EAC/B,UAAsB;IAEtB,OAAO,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC","sourcesContent":["import { cleanHtmlComments } from './cleanHtmlComments';\nimport { cloneModelForPaste } from 'roosterjs-content-model-dom';\nimport { convertInlineCss } from '../createModelFromHtml/convertInlineCss';\nimport { createPasteFragment } from './createPasteFragment';\nimport { generatePasteOptionFromPlugins } from './generatePasteOptionFromPlugins';\nimport { mergePasteContent } from './mergePasteContent';\nimport { retrieveHtmlInfo } from './retrieveHtmlInfo';\nimport type {\n PasteTypeOrGetter,\n ClipboardData,\n IEditor,\n DOMCreator,\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 pasteTypeOrGetter Type of content to paste or function that returns the Paste Type to use based on the document and the clipboard Data. @default normal\n */\nexport function paste(\n editor: IEditor,\n clipboardData: ClipboardData,\n pasteTypeOrGetter: PasteTypeOrGetter = 'normal'\n) {\n editor.focus();\n let isFirstPaste = false;\n\n if (!clipboardData.modelBeforePaste) {\n isFirstPaste = true;\n\n editor.formatContentModel(model => {\n clipboardData.modelBeforePaste = cloneModelForPaste(model);\n\n return false;\n });\n }\n\n // 1. Prepare variables\n const domCreator = editor.getDOMCreator();\n if (!domCreator.isBypassed && clipboardData.rawHtml) {\n clipboardData.rawHtml = cleanHtmlComments(clipboardData.rawHtml);\n }\n const doc = createDOMFromHtml(clipboardData.rawHtml, domCreator);\n const pasteType =\n typeof pasteTypeOrGetter == 'function'\n ? pasteTypeOrGetter(doc, clipboardData)\n : pasteTypeOrGetter;\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, domCreator)\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, isFirstPaste);\n}\n\nfunction createDOMFromHtml(\n html: string | null | undefined,\n domCreator: DOMCreator\n): Document | null {\n return html ? domCreator.htmlToDOM(html) : null;\n}\n"]}
|
|
@@ -23,7 +23,7 @@ var CopyPastePlugin = /** @class */ (function () {
|
|
|
23
23
|
var dataTransfer = event.clipboardData;
|
|
24
24
|
if (shouldPreventDefaultPaste(dataTransfer, editor_1)) {
|
|
25
25
|
event.preventDefault();
|
|
26
|
-
(0, roosterjs_content_model_dom_1.extractClipboardItems)((0, roosterjs_content_model_dom_1.toArray)(dataTransfer.items), _this.state.allowedCustomPasteType).then(function (clipboardData) {
|
|
26
|
+
(0, roosterjs_content_model_dom_1.extractClipboardItems)((0, roosterjs_content_model_dom_1.toArray)(dataTransfer.items), _this.state.allowedCustomPasteType, true /* isPasteNative */).then(function (clipboardData) {
|
|
27
27
|
if (!editor_1.isDisposed()) {
|
|
28
28
|
(0, paste_1.paste)(editor_1, clipboardData, _this.state.defaultPasteType);
|
|
29
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts"],"names":[],"mappings":";;;AAAA,2DAA0D;AAC1D,6EAA4E;AAC5E,mDAAkD;AAClD,2EAMqC;AASrC;;GAEG;AACH;IAKI;;;OAGG;IACH,yBAAY,MAAqB;QAAjC,iBAMC;QAdO,WAAM,GAAmB,IAAI,CAAC;QAC9B,aAAQ,GAAwB,IAAI,CAAC;QAkGrC,YAAO,GAAG,UAAC,KAAY;YAC3B,IAAI,KAAI,CAAC,MAAM,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE;gBACxC,IAAM,QAAM,GAAG,KAAI,CAAC,MAAM,CAAC;gBAE3B,IAAM,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC;gBAEzC,IAAI,yBAAyB,CAAC,YAAY,EAAE,QAAM,CAAC,EAAE;oBACjD,KAAK,CAAC,cAAc,EAAE,CAAC;oBACvB,IAAA,mDAAqB,EACjB,IAAA,qCAAO,EAAC,YAAa,CAAC,KAAK,CAAC,EAC5B,KAAI,CAAC,KAAK,CAAC,sBAAsB,
|
|
1
|
+
{"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts"],"names":[],"mappings":";;;AAAA,2DAA0D;AAC1D,6EAA4E;AAC5E,mDAAkD;AAClD,2EAMqC;AASrC;;GAEG;AACH;IAKI;;;OAGG;IACH,yBAAY,MAAqB;QAAjC,iBAMC;QAdO,WAAM,GAAmB,IAAI,CAAC;QAC9B,aAAQ,GAAwB,IAAI,CAAC;QAkGrC,YAAO,GAAG,UAAC,KAAY;YAC3B,IAAI,KAAI,CAAC,MAAM,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE;gBACxC,IAAM,QAAM,GAAG,KAAI,CAAC,MAAM,CAAC;gBAE3B,IAAM,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC;gBAEzC,IAAI,yBAAyB,CAAC,YAAY,EAAE,QAAM,CAAC,EAAE;oBACjD,KAAK,CAAC,cAAc,EAAE,CAAC;oBACvB,IAAA,mDAAqB,EACjB,IAAA,qCAAO,EAAC,YAAa,CAAC,KAAK,CAAC,EAC5B,KAAI,CAAC,KAAK,CAAC,sBAAsB,EACjC,IAAI,CAAC,mBAAmB,CAC3B,CAAC,IAAI,CAAC,UAAC,aAA4B;wBAChC,IAAI,CAAC,QAAM,CAAC,UAAU,EAAE,EAAE;4BACtB,IAAA,aAAK,EAAC,QAAM,EAAE,aAAa,EAAE,KAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;yBAC7D;oBACL,CAAC,CAAC,CAAC;iBACN;aACJ;QACL,CAAC,CAAC;QA7GE,IAAI,CAAC,KAAK,GAAG;YACT,sBAAsB,EAAE,MAAM,CAAC,sBAAsB,IAAI,EAAE;YAC3D,OAAO,EAAE,IAAI;YACb,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;SAC5C,CAAC;IACN,CAAC;IAED;;OAEG;IACH,iCAAO,GAAP;QACI,OAAO,WAAW,CAAC;IACvB,CAAC;IAED;;;OAGG;IACH,oCAAU,GAAV,UAAW,MAAe;QAA1B,iBAaC;QAZG,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;YACvC,KAAK,EAAE;gBACH,cAAc,EAAE,UAAA,CAAC,IAAI,OAAA,KAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAf,CAAe;aACvC;YACD,IAAI,EAAE;gBACF,cAAc,EAAE,UAAA,CAAC,IAAI,OAAA,KAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,EAAlC,CAAkC;aAC1D;YACD,GAAG,EAAE;gBACD,cAAc,EAAE,UAAA,CAAC,IAAI,OAAA,KAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAjC,CAAiC;aACzD;SACJ,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACH,iCAAO,GAAP;;QACI,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;YACpB,MAAA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,0CAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC/D,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;SAC7B;QAED,IAAI,IAAI,CAAC,QAAQ,EAAE;YACf,IAAI,CAAC,QAAQ,EAAE,CAAC;SACnB;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,kCAAQ,GAAR;QACI,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAEO,mCAAS,GAAjB,UAAkB,KAAY,EAAE,KAAc;;QAC1C,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE;YAC1C,OAAO;SACV;QAED,IAAM,kBAAkB,GAAG,IAAA,qCAAiB,EAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAExE,IAAI,kBAAkB,EAAE;YACZ,IAAA,WAAW,GAAkB,kBAAkB,YAApC,EAAE,WAAW,GAAK,kBAAkB,YAAvB,CAAwB;YACxD,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,MAAA,KAAK,CAAC,aAAa,0CAAE,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;YACjE,MAAA,KAAK,CAAC,aAAa,0CAAE,OAAO,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;YAExD,IAAI,KAAK,EAAE;gBACP,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAC1B,UAAC,KAAK,EAAE,OAAO;oBACX,IACI,IAAA,6CAAe,EAAC,KAAK,EAAE,CAAC,iCAAe,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY;wBAC/D,OAAO,EACT;wBACE,IAAA,mDAAqB,EAAC,KAAK,CAAC,CAAC;qBAChC;oBAED,OAAO,IAAI,CAAC;gBAChB,CAAC,EACD;oBACI,OAAO,EAAE,KAAK;oBACd,YAAY,EAAE,0CAAY,CAAC,GAAG;iBACjC,CACJ,CAAC;aACL;SACJ;IACL,CAAC;IAsBL,sBAAC;AAAD,CAAC,AAxHD,IAwHC;AAED,SAAS,gBAAgB,CAAC,KAAY;IAClC,OAAO,CAAC,CAAE,KAAwB,CAAC,aAAa,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,SAAgB,yBAAyB,CACrC,YAAiC,EACjC,MAAe;IAEf,IAAI,CAAC,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK,CAAA,EAAE;QACtB,OAAO,KAAK,CAAC;KAChB;IAED,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,SAAS,EAAE;QACpC,OAAO,IAAI,CAAC;KACf;IAED,mFAAmF;IACnF,mDAAmD;IACnD,OAAO,IAAA,qCAAO,EAAC,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAA,IAAI;QAChC,IAAA,IAAI,GAAK,IAAI,KAAT,CAAU;QACtB,IAAM,YAAY,GAAG,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzD,IAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC3C,OAAO,YAAY,IAAI,MAAM,CAAC;IAClC,CAAC,CAAC,CAAC;AACP,CAAC;AApBD,8DAoBC;AAED;;;;GAIG;AACH,SAAgB,qBAAqB,CACjC,MAAqB;IAErB,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC;AAJD,sDAIC","sourcesContent":["import { deleteEmptyList } from './utils/deleteEmptyList';\nimport { getContentForCopy } from '../../command/cutCopy/getContentForCopy';\nimport { paste } from '../../command/paste/paste';\nimport {\n ChangeSource,\n deleteSelection,\n extractClipboardItems,\n normalizeContentModel,\n toArray,\n} from 'roosterjs-content-model-dom';\nimport type {\n ClipboardData,\n CopyPastePluginState,\n IEditor,\n EditorOptions,\n PluginWithState,\n} from 'roosterjs-content-model-types';\n\n/**\n * Copy and paste plugin for handling onCopy and onPaste event\n */\nclass CopyPastePlugin implements PluginWithState<CopyPastePluginState> {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n private state: CopyPastePluginState;\n\n /**\n * Construct a new instance of CopyPastePlugin\n * @param option The editor option\n */\n constructor(option: EditorOptions) {\n this.state = {\n allowedCustomPasteType: option.allowedCustomPasteType || [],\n tempDiv: null,\n defaultPasteType: option.defaultPasteType,\n };\n }\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'CopyPaste';\n }\n\n /**\n * Initialize this plugin. This should only be called from Editor\n * @param editor Editor instance\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n this.disposer = this.editor.attachDomEvent({\n paste: {\n beforeDispatch: e => this.onPaste(e),\n },\n copy: {\n beforeDispatch: e => this.onCutCopy(e, false /*isCut*/),\n },\n cut: {\n beforeDispatch: e => this.onCutCopy(e, true /*isCut*/),\n },\n });\n }\n\n /**\n * Dispose this plugin\n */\n dispose() {\n if (this.state.tempDiv) {\n this.state.tempDiv.parentNode?.removeChild(this.state.tempDiv);\n this.state.tempDiv = null;\n }\n\n if (this.disposer) {\n this.disposer();\n }\n this.disposer = null;\n this.editor = null;\n }\n\n /**\n * Get plugin state object\n */\n getState() {\n return this.state;\n }\n\n private onCutCopy(event: Event, isCut: boolean) {\n if (!this.editor || !isClipboardEvent(event)) {\n return;\n }\n\n const textAndHtmlContent = getContentForCopy(this.editor, isCut, event);\n\n if (textAndHtmlContent) {\n const { htmlContent, textContent } = textAndHtmlContent;\n event.preventDefault();\n event.clipboardData?.setData('text/html', htmlContent.innerHTML);\n event.clipboardData?.setData('text/plain', textContent);\n\n if (isCut) {\n this.editor.formatContentModel(\n (model, context) => {\n if (\n deleteSelection(model, [deleteEmptyList], context).deleteResult ==\n 'range'\n ) {\n normalizeContentModel(model);\n }\n\n return true;\n },\n {\n apiName: 'cut',\n changeSource: ChangeSource.Cut,\n }\n );\n }\n }\n }\n\n private onPaste = (event: Event) => {\n if (this.editor && isClipboardEvent(event)) {\n const editor = this.editor;\n\n const dataTransfer = event.clipboardData;\n\n if (shouldPreventDefaultPaste(dataTransfer, editor)) {\n event.preventDefault();\n extractClipboardItems(\n toArray(dataTransfer!.items),\n this.state.allowedCustomPasteType,\n true /* isPasteNative */\n ).then((clipboardData: ClipboardData) => {\n if (!editor.isDisposed()) {\n paste(editor, clipboardData, this.state.defaultPasteType);\n }\n });\n }\n }\n };\n}\n\nfunction isClipboardEvent(event: Event): event is ClipboardEvent {\n return !!(event as ClipboardEvent).clipboardData;\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function shouldPreventDefaultPaste(\n dataTransfer: DataTransfer | null,\n editor: IEditor\n): boolean {\n if (!dataTransfer?.items) {\n return false;\n }\n\n if (!editor.getEnvironment().isAndroid) {\n return true;\n }\n\n // On Android, the clipboard data from Office apps is a file, which can't be loaded\n // so we have to allow the default browser behavior\n return toArray(dataTransfer.items).some(item => {\n const { type } = item;\n const isNormalFile = item.kind === 'file' && type !== '';\n const isText = type.indexOf('text/') === 0;\n return isNormalFile || isText;\n });\n}\n\n/**\n * @internal\n * Create a new instance of CopyPastePlugin\n * @param option The editor option\n */\nexport function createCopyPastePlugin(\n option: EditorOptions\n): PluginWithState<CopyPastePluginState> {\n return new CopyPastePlugin(option);\n}\n"]}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import type { BeforePasteEvent,
|
|
2
|
-
/**
|
|
3
|
-
* @internal
|
|
4
|
-
*/
|
|
5
|
-
export declare function cloneModelForPaste(model: ReadonlyContentModelDocument): ContentModelDocument;
|
|
1
|
+
import type { BeforePasteEvent, IEditor } from 'roosterjs-content-model-types';
|
|
6
2
|
/**
|
|
7
3
|
* @internal
|
|
8
4
|
*/
|
|
@@ -1,18 +1,8 @@
|
|
|
1
1
|
define(["require", "exports", "tslib", "../createModelFromHtml/createDomToModelContextForSanitizing", "roosterjs-content-model-dom"], function (require, exports, tslib_1, createDomToModelContextForSanitizing_1, roosterjs_content_model_dom_1) {
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.mergePasteContent =
|
|
4
|
+
exports.mergePasteContent = void 0;
|
|
5
5
|
var BlackColor = 'rgb(0,0,0)';
|
|
6
|
-
var CloneOption = {
|
|
7
|
-
includeCachedElement: function (node, type) { return (type == 'cache' ? undefined : node); },
|
|
8
|
-
};
|
|
9
|
-
/**
|
|
10
|
-
* @internal
|
|
11
|
-
*/
|
|
12
|
-
function cloneModelForPaste(model) {
|
|
13
|
-
return (0, roosterjs_content_model_dom_1.cloneModel)(model, CloneOption);
|
|
14
|
-
}
|
|
15
|
-
exports.cloneModelForPaste = cloneModelForPaste;
|
|
16
6
|
/**
|
|
17
7
|
* @internal
|
|
18
8
|
*/
|
|
@@ -20,7 +10,7 @@ define(["require", "exports", "tslib", "../createModelFromHtml/createDomToModelC
|
|
|
20
10
|
var fragment = eventResult.fragment, domToModelOption = eventResult.domToModelOption, customizedMerge = eventResult.customizedMerge, pasteType = eventResult.pasteType, clipboardData = eventResult.clipboardData, containsBlockElements = eventResult.containsBlockElements;
|
|
21
11
|
editor.formatContentModel(function (model, context) {
|
|
22
12
|
if (!isFirstPaste && clipboardData.modelBeforePaste) {
|
|
23
|
-
var clonedModel = cloneModelForPaste(clipboardData.modelBeforePaste);
|
|
13
|
+
var clonedModel = (0, roosterjs_content_model_dom_1.cloneModelForPaste)(clipboardData.modelBeforePaste);
|
|
24
14
|
model.blocks = clonedModel.blocks;
|
|
25
15
|
}
|
|
26
16
|
var domToModelContext = (0, createDomToModelContextForSanitizing_1.createDomToModelContextForSanitizing)(editor.getDocument(), undefined /*defaultFormat*/, editor.getEnvironment().domToModelSettings.customized, domToModelOption, editor.getDOMHelper());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mergePasteContent.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts"],"names":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"mergePasteContent.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts"],"names":[],"mappings":"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","sourcesContent":["import { createDomToModelContextForSanitizing } from '../createModelFromHtml/createDomToModelContextForSanitizing';\nimport {\n ChangeSource,\n EmptySegmentFormat,\n domToContentModel,\n getSegmentTextFormat,\n getSelectedSegments,\n mergeModel,\n cloneModelForPaste,\n} from 'roosterjs-content-model-dom';\nimport type {\n BeforePasteEvent,\n ContentModelDocument,\n ContentModelSegmentFormat,\n IEditor,\n MergeModelOption,\n PasteType,\n ShallowMutableContentModelDocument,\n} from 'roosterjs-content-model-types';\n\nconst BlackColor = 'rgb(0,0,0)';\n\n/**\n * @internal\n */\nexport function mergePasteContent(\n editor: IEditor,\n eventResult: BeforePasteEvent,\n isFirstPaste: boolean\n) {\n const {\n fragment,\n domToModelOption,\n customizedMerge,\n pasteType,\n clipboardData,\n containsBlockElements,\n } = eventResult;\n\n editor.formatContentModel(\n (model, context) => {\n if (!isFirstPaste && clipboardData.modelBeforePaste) {\n const clonedModel = cloneModelForPaste(clipboardData.modelBeforePaste);\n model.blocks = clonedModel.blocks;\n }\n\n const domToModelContext = createDomToModelContextForSanitizing(\n editor.getDocument(),\n undefined /*defaultFormat*/,\n editor.getEnvironment().domToModelSettings.customized,\n domToModelOption,\n editor.getDOMHelper()\n );\n\n domToModelContext.segmentFormat = getSegmentFormatForPaste(model, pasteType);\n\n const pasteModel = domToContentModel(fragment, domToModelContext);\n const mergeOption: MergeModelOption = {\n mergeFormat: pasteType == 'mergeFormat' ? 'keepSourceEmphasisFormat' : 'none',\n mergeTable: shouldMergeTable(pasteModel),\n addParagraphAfterMergedContent: containsBlockElements,\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 ...(pasteType == 'normal' && !containsBlockElements\n ? getLastSegmentFormat(pasteModel)\n : insertPoint.marker.format),\n };\n }\n\n return true;\n },\n {\n changeSource: ChangeSource.Paste,\n getChangeData: () => clipboardData,\n scrollCaretIntoView: true,\n apiName: 'paste',\n }\n );\n}\n\nfunction getSegmentFormatForPaste(\n model: ShallowMutableContentModelDocument,\n pasteType: PasteType\n): ContentModelSegmentFormat {\n const selectedSegment = getSelectedSegments(model, true /*includeFormatHolder*/)[0];\n\n if (selectedSegment) {\n const result = getSegmentTextFormat(selectedSegment);\n if (pasteType == 'normal') {\n // When using normal paste (Keep source formatting) set the default text color to black when creating the\n // Model from the clipboard content, so the elements that do not contain any text color in their style\n // Are set to black. Otherwise, These segments would get the selected segments format or the default text set in the content.\n result.textColor = BlackColor;\n }\n\n return result;\n }\n\n return {};\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\nfunction getLastSegmentFormat(pasteModel: ContentModelDocument): ContentModelSegmentFormat {\n if (pasteModel.blocks.length == 1) {\n const [firstBlock] = pasteModel.blocks;\n\n if (firstBlock.blockType == 'Paragraph') {\n const segment = firstBlock.segments[firstBlock.segments.length - 1];\n\n return {\n ...segment.format,\n };\n }\n }\n\n return {};\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
define(["require", "exports", "./cleanHtmlComments", "
|
|
1
|
+
define(["require", "exports", "./cleanHtmlComments", "roosterjs-content-model-dom", "../createModelFromHtml/convertInlineCss", "./createPasteFragment", "./generatePasteOptionFromPlugins", "./mergePasteContent", "./retrieveHtmlInfo"], function (require, exports, cleanHtmlComments_1, roosterjs_content_model_dom_1, convertInlineCss_1, createPasteFragment_1, generatePasteOptionFromPlugins_1, mergePasteContent_1, retrieveHtmlInfo_1) {
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.paste = void 0;
|
|
@@ -16,7 +16,7 @@ define(["require", "exports", "./cleanHtmlComments", "./mergePasteContent", "../
|
|
|
16
16
|
if (!clipboardData.modelBeforePaste) {
|
|
17
17
|
isFirstPaste = true;
|
|
18
18
|
editor.formatContentModel(function (model) {
|
|
19
|
-
clipboardData.modelBeforePaste = (0,
|
|
19
|
+
clipboardData.modelBeforePaste = (0, roosterjs_content_model_dom_1.cloneModelForPaste)(model);
|
|
20
20
|
return false;
|
|
21
21
|
});
|
|
22
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paste.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/paste.ts"],"names":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"paste.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/paste.ts"],"names":[],"mappings":";;;;IAcA;;;;;OAKG;IACH,SAAgB,KAAK,CACjB,MAAe,EACf,aAA4B,EAC5B,iBAA+C;;QAA/C,kCAAA,EAAA,4BAA+C;QAE/C,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,IAAI,YAAY,GAAG,KAAK,CAAC;QAEzB,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE;YACjC,YAAY,GAAG,IAAI,CAAC;YAEpB,MAAM,CAAC,kBAAkB,CAAC,UAAA,KAAK;gBAC3B,aAAa,CAAC,gBAAgB,GAAG,IAAA,gDAAkB,EAAC,KAAK,CAAC,CAAC;gBAE3D,OAAO,KAAK,CAAC;YACjB,CAAC,CAAC,CAAC;SACN;QAED,uBAAuB;QACvB,IAAM,UAAU,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;QAC1C,IAAI,CAAC,UAAU,CAAC,UAAU,IAAI,aAAa,CAAC,OAAO,EAAE;YACjD,aAAa,CAAC,OAAO,GAAG,IAAA,qCAAiB,EAAC,aAAa,CAAC,OAAO,CAAC,CAAC;SACpE;QACD,IAAM,GAAG,GAAG,iBAAiB,CAAC,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACjE,IAAM,SAAS,GACX,OAAO,iBAAiB,IAAI,UAAU;YAClC,CAAC,CAAC,iBAAiB,CAAC,GAAG,EAAE,aAAa,CAAC;YACvC,CAAC,CAAC,iBAAiB,CAAC;QAE5B,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,UAAU,CAAC,CACtD,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,YAAY,CAAC,CAAC;IACzD,CAAC;IAzDD,sBAyDC;IAED,SAAS,iBAAiB,CACtB,IAA+B,EAC/B,UAAsB;QAEtB,OAAO,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACpD,CAAC","sourcesContent":["import { cleanHtmlComments } from './cleanHtmlComments';\nimport { cloneModelForPaste } from 'roosterjs-content-model-dom';\nimport { convertInlineCss } from '../createModelFromHtml/convertInlineCss';\nimport { createPasteFragment } from './createPasteFragment';\nimport { generatePasteOptionFromPlugins } from './generatePasteOptionFromPlugins';\nimport { mergePasteContent } from './mergePasteContent';\nimport { retrieveHtmlInfo } from './retrieveHtmlInfo';\nimport type {\n PasteTypeOrGetter,\n ClipboardData,\n IEditor,\n DOMCreator,\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 pasteTypeOrGetter Type of content to paste or function that returns the Paste Type to use based on the document and the clipboard Data. @default normal\n */\nexport function paste(\n editor: IEditor,\n clipboardData: ClipboardData,\n pasteTypeOrGetter: PasteTypeOrGetter = 'normal'\n) {\n editor.focus();\n let isFirstPaste = false;\n\n if (!clipboardData.modelBeforePaste) {\n isFirstPaste = true;\n\n editor.formatContentModel(model => {\n clipboardData.modelBeforePaste = cloneModelForPaste(model);\n\n return false;\n });\n }\n\n // 1. Prepare variables\n const domCreator = editor.getDOMCreator();\n if (!domCreator.isBypassed && clipboardData.rawHtml) {\n clipboardData.rawHtml = cleanHtmlComments(clipboardData.rawHtml);\n }\n const doc = createDOMFromHtml(clipboardData.rawHtml, domCreator);\n const pasteType =\n typeof pasteTypeOrGetter == 'function'\n ? pasteTypeOrGetter(doc, clipboardData)\n : pasteTypeOrGetter;\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, domCreator)\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, isFirstPaste);\n}\n\nfunction createDOMFromHtml(\n html: string | null | undefined,\n domCreator: DOMCreator\n): Document | null {\n return html ? domCreator.htmlToDOM(html) : null;\n}\n"]}
|
|
@@ -20,7 +20,7 @@ define(["require", "exports", "./utils/deleteEmptyList", "../../command/cutCopy/
|
|
|
20
20
|
var dataTransfer = event.clipboardData;
|
|
21
21
|
if (shouldPreventDefaultPaste(dataTransfer, editor_1)) {
|
|
22
22
|
event.preventDefault();
|
|
23
|
-
(0, roosterjs_content_model_dom_1.extractClipboardItems)((0, roosterjs_content_model_dom_1.toArray)(dataTransfer.items), _this.state.allowedCustomPasteType).then(function (clipboardData) {
|
|
23
|
+
(0, roosterjs_content_model_dom_1.extractClipboardItems)((0, roosterjs_content_model_dom_1.toArray)(dataTransfer.items), _this.state.allowedCustomPasteType, true /* isPasteNative */).then(function (clipboardData) {
|
|
24
24
|
if (!editor_1.isDisposed()) {
|
|
25
25
|
(0, paste_1.paste)(editor_1, clipboardData, _this.state.defaultPasteType);
|
|
26
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts"],"names":[],"mappings":";;;;IAkBA;;OAEG;IACH;QAKI;;;WAGG;QACH,yBAAY,MAAqB;YAAjC,iBAMC;YAdO,WAAM,GAAmB,IAAI,CAAC;YAC9B,aAAQ,GAAwB,IAAI,CAAC;YAkGrC,YAAO,GAAG,UAAC,KAAY;gBAC3B,IAAI,KAAI,CAAC,MAAM,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE;oBACxC,IAAM,QAAM,GAAG,KAAI,CAAC,MAAM,CAAC;oBAE3B,IAAM,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC;oBAEzC,IAAI,yBAAyB,CAAC,YAAY,EAAE,QAAM,CAAC,EAAE;wBACjD,KAAK,CAAC,cAAc,EAAE,CAAC;wBACvB,IAAA,mDAAqB,EACjB,IAAA,qCAAO,EAAC,YAAa,CAAC,KAAK,CAAC,EAC5B,KAAI,CAAC,KAAK,CAAC,sBAAsB,
|
|
1
|
+
{"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts"],"names":[],"mappings":";;;;IAkBA;;OAEG;IACH;QAKI;;;WAGG;QACH,yBAAY,MAAqB;YAAjC,iBAMC;YAdO,WAAM,GAAmB,IAAI,CAAC;YAC9B,aAAQ,GAAwB,IAAI,CAAC;YAkGrC,YAAO,GAAG,UAAC,KAAY;gBAC3B,IAAI,KAAI,CAAC,MAAM,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE;oBACxC,IAAM,QAAM,GAAG,KAAI,CAAC,MAAM,CAAC;oBAE3B,IAAM,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC;oBAEzC,IAAI,yBAAyB,CAAC,YAAY,EAAE,QAAM,CAAC,EAAE;wBACjD,KAAK,CAAC,cAAc,EAAE,CAAC;wBACvB,IAAA,mDAAqB,EACjB,IAAA,qCAAO,EAAC,YAAa,CAAC,KAAK,CAAC,EAC5B,KAAI,CAAC,KAAK,CAAC,sBAAsB,EACjC,IAAI,CAAC,mBAAmB,CAC3B,CAAC,IAAI,CAAC,UAAC,aAA4B;4BAChC,IAAI,CAAC,QAAM,CAAC,UAAU,EAAE,EAAE;gCACtB,IAAA,aAAK,EAAC,QAAM,EAAE,aAAa,EAAE,KAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;6BAC7D;wBACL,CAAC,CAAC,CAAC;qBACN;iBACJ;YACL,CAAC,CAAC;YA7GE,IAAI,CAAC,KAAK,GAAG;gBACT,sBAAsB,EAAE,MAAM,CAAC,sBAAsB,IAAI,EAAE;gBAC3D,OAAO,EAAE,IAAI;gBACb,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;aAC5C,CAAC;QACN,CAAC;QAED;;WAEG;QACH,iCAAO,GAAP;YACI,OAAO,WAAW,CAAC;QACvB,CAAC;QAED;;;WAGG;QACH,oCAAU,GAAV,UAAW,MAAe;YAA1B,iBAaC;YAZG,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YACrB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;gBACvC,KAAK,EAAE;oBACH,cAAc,EAAE,UAAA,CAAC,IAAI,OAAA,KAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAf,CAAe;iBACvC;gBACD,IAAI,EAAE;oBACF,cAAc,EAAE,UAAA,CAAC,IAAI,OAAA,KAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,EAAlC,CAAkC;iBAC1D;gBACD,GAAG,EAAE;oBACD,cAAc,EAAE,UAAA,CAAC,IAAI,OAAA,KAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAjC,CAAiC;iBACzD;aACJ,CAAC,CAAC;QACP,CAAC;QAED;;WAEG;QACH,iCAAO,GAAP;;YACI,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;gBACpB,MAAA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,0CAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAC/D,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;aAC7B;YAED,IAAI,IAAI,CAAC,QAAQ,EAAE;gBACf,IAAI,CAAC,QAAQ,EAAE,CAAC;aACnB;YACD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;YACrB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACvB,CAAC;QAED;;WAEG;QACH,kCAAQ,GAAR;YACI,OAAO,IAAI,CAAC,KAAK,CAAC;QACtB,CAAC;QAEO,mCAAS,GAAjB,UAAkB,KAAY,EAAE,KAAc;;YAC1C,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE;gBAC1C,OAAO;aACV;YAED,IAAM,kBAAkB,GAAG,IAAA,qCAAiB,EAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YAExE,IAAI,kBAAkB,EAAE;gBACZ,IAAA,WAAW,GAAkB,kBAAkB,YAApC,EAAE,WAAW,GAAK,kBAAkB,YAAvB,CAAwB;gBACxD,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,MAAA,KAAK,CAAC,aAAa,0CAAE,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;gBACjE,MAAA,KAAK,CAAC,aAAa,0CAAE,OAAO,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;gBAExD,IAAI,KAAK,EAAE;oBACP,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAC1B,UAAC,KAAK,EAAE,OAAO;wBACX,IACI,IAAA,6CAAe,EAAC,KAAK,EAAE,CAAC,iCAAe,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY;4BAC/D,OAAO,EACT;4BACE,IAAA,mDAAqB,EAAC,KAAK,CAAC,CAAC;yBAChC;wBAED,OAAO,IAAI,CAAC;oBAChB,CAAC,EACD;wBACI,OAAO,EAAE,KAAK;wBACd,YAAY,EAAE,0CAAY,CAAC,GAAG;qBACjC,CACJ,CAAC;iBACL;aACJ;QACL,CAAC;QAsBL,sBAAC;IAAD,CAAC,AAxHD,IAwHC;IAED,SAAS,gBAAgB,CAAC,KAAY;QAClC,OAAO,CAAC,CAAE,KAAwB,CAAC,aAAa,CAAC;IACrD,CAAC;IAED;;;OAGG;IACH,SAAgB,yBAAyB,CACrC,YAAiC,EACjC,MAAe;QAEf,IAAI,CAAC,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK,CAAA,EAAE;YACtB,OAAO,KAAK,CAAC;SAChB;QAED,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,SAAS,EAAE;YACpC,OAAO,IAAI,CAAC;SACf;QAED,mFAAmF;QACnF,mDAAmD;QACnD,OAAO,IAAA,qCAAO,EAAC,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAA,IAAI;YAChC,IAAA,IAAI,GAAK,IAAI,KAAT,CAAU;YACtB,IAAM,YAAY,GAAG,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzD,IAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC3C,OAAO,YAAY,IAAI,MAAM,CAAC;QAClC,CAAC,CAAC,CAAC;IACP,CAAC;IApBD,8DAoBC;IAED;;;;OAIG;IACH,SAAgB,qBAAqB,CACjC,MAAqB;QAErB,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAJD,sDAIC","sourcesContent":["import { deleteEmptyList } from './utils/deleteEmptyList';\nimport { getContentForCopy } from '../../command/cutCopy/getContentForCopy';\nimport { paste } from '../../command/paste/paste';\nimport {\n ChangeSource,\n deleteSelection,\n extractClipboardItems,\n normalizeContentModel,\n toArray,\n} from 'roosterjs-content-model-dom';\nimport type {\n ClipboardData,\n CopyPastePluginState,\n IEditor,\n EditorOptions,\n PluginWithState,\n} from 'roosterjs-content-model-types';\n\n/**\n * Copy and paste plugin for handling onCopy and onPaste event\n */\nclass CopyPastePlugin implements PluginWithState<CopyPastePluginState> {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n private state: CopyPastePluginState;\n\n /**\n * Construct a new instance of CopyPastePlugin\n * @param option The editor option\n */\n constructor(option: EditorOptions) {\n this.state = {\n allowedCustomPasteType: option.allowedCustomPasteType || [],\n tempDiv: null,\n defaultPasteType: option.defaultPasteType,\n };\n }\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'CopyPaste';\n }\n\n /**\n * Initialize this plugin. This should only be called from Editor\n * @param editor Editor instance\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n this.disposer = this.editor.attachDomEvent({\n paste: {\n beforeDispatch: e => this.onPaste(e),\n },\n copy: {\n beforeDispatch: e => this.onCutCopy(e, false /*isCut*/),\n },\n cut: {\n beforeDispatch: e => this.onCutCopy(e, true /*isCut*/),\n },\n });\n }\n\n /**\n * Dispose this plugin\n */\n dispose() {\n if (this.state.tempDiv) {\n this.state.tempDiv.parentNode?.removeChild(this.state.tempDiv);\n this.state.tempDiv = null;\n }\n\n if (this.disposer) {\n this.disposer();\n }\n this.disposer = null;\n this.editor = null;\n }\n\n /**\n * Get plugin state object\n */\n getState() {\n return this.state;\n }\n\n private onCutCopy(event: Event, isCut: boolean) {\n if (!this.editor || !isClipboardEvent(event)) {\n return;\n }\n\n const textAndHtmlContent = getContentForCopy(this.editor, isCut, event);\n\n if (textAndHtmlContent) {\n const { htmlContent, textContent } = textAndHtmlContent;\n event.preventDefault();\n event.clipboardData?.setData('text/html', htmlContent.innerHTML);\n event.clipboardData?.setData('text/plain', textContent);\n\n if (isCut) {\n this.editor.formatContentModel(\n (model, context) => {\n if (\n deleteSelection(model, [deleteEmptyList], context).deleteResult ==\n 'range'\n ) {\n normalizeContentModel(model);\n }\n\n return true;\n },\n {\n apiName: 'cut',\n changeSource: ChangeSource.Cut,\n }\n );\n }\n }\n }\n\n private onPaste = (event: Event) => {\n if (this.editor && isClipboardEvent(event)) {\n const editor = this.editor;\n\n const dataTransfer = event.clipboardData;\n\n if (shouldPreventDefaultPaste(dataTransfer, editor)) {\n event.preventDefault();\n extractClipboardItems(\n toArray(dataTransfer!.items),\n this.state.allowedCustomPasteType,\n true /* isPasteNative */\n ).then((clipboardData: ClipboardData) => {\n if (!editor.isDisposed()) {\n paste(editor, clipboardData, this.state.defaultPasteType);\n }\n });\n }\n }\n };\n}\n\nfunction isClipboardEvent(event: Event): event is ClipboardEvent {\n return !!(event as ClipboardEvent).clipboardData;\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function shouldPreventDefaultPaste(\n dataTransfer: DataTransfer | null,\n editor: IEditor\n): boolean {\n if (!dataTransfer?.items) {\n return false;\n }\n\n if (!editor.getEnvironment().isAndroid) {\n return true;\n }\n\n // On Android, the clipboard data from Office apps is a file, which can't be loaded\n // so we have to allow the default browser behavior\n return toArray(dataTransfer.items).some(item => {\n const { type } = item;\n const isNormalFile = item.kind === 'file' && type !== '';\n const isText = type.indexOf('text/') === 0;\n return isNormalFile || isText;\n });\n}\n\n/**\n * @internal\n * Create a new instance of CopyPastePlugin\n * @param option The editor option\n */\nexport function createCopyPastePlugin(\n option: EditorOptions\n): PluginWithState<CopyPastePluginState> {\n return new CopyPastePlugin(option);\n}\n"]}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import type { BeforePasteEvent,
|
|
2
|
-
/**
|
|
3
|
-
* @internal
|
|
4
|
-
*/
|
|
5
|
-
export declare function cloneModelForPaste(model: ReadonlyContentModelDocument): ContentModelDocument;
|
|
1
|
+
import type { BeforePasteEvent, IEditor } from 'roosterjs-content-model-types';
|
|
6
2
|
/**
|
|
7
3
|
* @internal
|
|
8
4
|
*/
|
|
@@ -1,16 +1,7 @@
|
|
|
1
1
|
import { __assign, __read } from "tslib";
|
|
2
2
|
import { createDomToModelContextForSanitizing } from '../createModelFromHtml/createDomToModelContextForSanitizing';
|
|
3
|
-
import { ChangeSource, EmptySegmentFormat,
|
|
3
|
+
import { ChangeSource, EmptySegmentFormat, domToContentModel, getSegmentTextFormat, getSelectedSegments, mergeModel, cloneModelForPaste, } from 'roosterjs-content-model-dom';
|
|
4
4
|
var BlackColor = 'rgb(0,0,0)';
|
|
5
|
-
var CloneOption = {
|
|
6
|
-
includeCachedElement: function (node, type) { return (type == 'cache' ? undefined : node); },
|
|
7
|
-
};
|
|
8
|
-
/**
|
|
9
|
-
* @internal
|
|
10
|
-
*/
|
|
11
|
-
export function cloneModelForPaste(model) {
|
|
12
|
-
return cloneModel(model, CloneOption);
|
|
13
|
-
}
|
|
14
5
|
/**
|
|
15
6
|
* @internal
|
|
16
7
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mergePasteContent.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,oCAAoC,EAAE,MAAM,6DAA6D,CAAC;AACnH,OAAO,EACH,YAAY,EACZ,kBAAkB,EAClB,
|
|
1
|
+
{"version":3,"file":"mergePasteContent.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts"],"names":[],"mappings":"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","sourcesContent":["import { createDomToModelContextForSanitizing } from '../createModelFromHtml/createDomToModelContextForSanitizing';\nimport {\n ChangeSource,\n EmptySegmentFormat,\n domToContentModel,\n getSegmentTextFormat,\n getSelectedSegments,\n mergeModel,\n cloneModelForPaste,\n} from 'roosterjs-content-model-dom';\nimport type {\n BeforePasteEvent,\n ContentModelDocument,\n ContentModelSegmentFormat,\n IEditor,\n MergeModelOption,\n PasteType,\n ShallowMutableContentModelDocument,\n} from 'roosterjs-content-model-types';\n\nconst BlackColor = 'rgb(0,0,0)';\n\n/**\n * @internal\n */\nexport function mergePasteContent(\n editor: IEditor,\n eventResult: BeforePasteEvent,\n isFirstPaste: boolean\n) {\n const {\n fragment,\n domToModelOption,\n customizedMerge,\n pasteType,\n clipboardData,\n containsBlockElements,\n } = eventResult;\n\n editor.formatContentModel(\n (model, context) => {\n if (!isFirstPaste && clipboardData.modelBeforePaste) {\n const clonedModel = cloneModelForPaste(clipboardData.modelBeforePaste);\n model.blocks = clonedModel.blocks;\n }\n\n const domToModelContext = createDomToModelContextForSanitizing(\n editor.getDocument(),\n undefined /*defaultFormat*/,\n editor.getEnvironment().domToModelSettings.customized,\n domToModelOption,\n editor.getDOMHelper()\n );\n\n domToModelContext.segmentFormat = getSegmentFormatForPaste(model, pasteType);\n\n const pasteModel = domToContentModel(fragment, domToModelContext);\n const mergeOption: MergeModelOption = {\n mergeFormat: pasteType == 'mergeFormat' ? 'keepSourceEmphasisFormat' : 'none',\n mergeTable: shouldMergeTable(pasteModel),\n addParagraphAfterMergedContent: containsBlockElements,\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 ...(pasteType == 'normal' && !containsBlockElements\n ? getLastSegmentFormat(pasteModel)\n : insertPoint.marker.format),\n };\n }\n\n return true;\n },\n {\n changeSource: ChangeSource.Paste,\n getChangeData: () => clipboardData,\n scrollCaretIntoView: true,\n apiName: 'paste',\n }\n );\n}\n\nfunction getSegmentFormatForPaste(\n model: ShallowMutableContentModelDocument,\n pasteType: PasteType\n): ContentModelSegmentFormat {\n const selectedSegment = getSelectedSegments(model, true /*includeFormatHolder*/)[0];\n\n if (selectedSegment) {\n const result = getSegmentTextFormat(selectedSegment);\n if (pasteType == 'normal') {\n // When using normal paste (Keep source formatting) set the default text color to black when creating the\n // Model from the clipboard content, so the elements that do not contain any text color in their style\n // Are set to black. Otherwise, These segments would get the selected segments format or the default text set in the content.\n result.textColor = BlackColor;\n }\n\n return result;\n }\n\n return {};\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\nfunction getLastSegmentFormat(pasteModel: ContentModelDocument): ContentModelSegmentFormat {\n if (pasteModel.blocks.length == 1) {\n const [firstBlock] = pasteModel.blocks;\n\n if (firstBlock.blockType == 'Paragraph') {\n const segment = firstBlock.segments[firstBlock.segments.length - 1];\n\n return {\n ...segment.format,\n };\n }\n }\n\n return {};\n}\n"]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { cleanHtmlComments } from './cleanHtmlComments';
|
|
2
|
-
import { cloneModelForPaste
|
|
2
|
+
import { cloneModelForPaste } from 'roosterjs-content-model-dom';
|
|
3
3
|
import { convertInlineCss } from '../createModelFromHtml/convertInlineCss';
|
|
4
4
|
import { createPasteFragment } from './createPasteFragment';
|
|
5
5
|
import { generatePasteOptionFromPlugins } from './generatePasteOptionFromPlugins';
|
|
6
|
+
import { mergePasteContent } from './mergePasteContent';
|
|
6
7
|
import { retrieveHtmlInfo } from './retrieveHtmlInfo';
|
|
7
8
|
/**
|
|
8
9
|
* Paste into editor using a clipboardData object
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paste.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/paste.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"paste.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/paste.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAQtD;;;;;GAKG;AACH,MAAM,UAAU,KAAK,CACjB,MAAe,EACf,aAA4B,EAC5B,iBAA+C;;IAA/C,kCAAA,EAAA,4BAA+C;IAE/C,MAAM,CAAC,KAAK,EAAE,CAAC;IACf,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE;QACjC,YAAY,GAAG,IAAI,CAAC;QAEpB,MAAM,CAAC,kBAAkB,CAAC,UAAA,KAAK;YAC3B,aAAa,CAAC,gBAAgB,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAE3D,OAAO,KAAK,CAAC;QACjB,CAAC,CAAC,CAAC;KACN;IAED,uBAAuB;IACvB,IAAM,UAAU,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;IAC1C,IAAI,CAAC,UAAU,CAAC,UAAU,IAAI,aAAa,CAAC,OAAO,EAAE;QACjD,aAAa,CAAC,OAAO,GAAG,iBAAiB,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;KACpE;IACD,IAAM,GAAG,GAAG,iBAAiB,CAAC,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACjE,IAAM,SAAS,GACX,OAAO,iBAAiB,IAAI,UAAU;QAClC,CAAC,CAAC,iBAAiB,CAAC,GAAG,EAAE,aAAa,CAAC;QACvC,CAAC,CAAC,iBAAiB,CAAC;IAE5B,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,UAAU,CAAC,CACtD,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,YAAY,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,iBAAiB,CACtB,IAA+B,EAC/B,UAAsB;IAEtB,OAAO,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC","sourcesContent":["import { cleanHtmlComments } from './cleanHtmlComments';\nimport { cloneModelForPaste } from 'roosterjs-content-model-dom';\nimport { convertInlineCss } from '../createModelFromHtml/convertInlineCss';\nimport { createPasteFragment } from './createPasteFragment';\nimport { generatePasteOptionFromPlugins } from './generatePasteOptionFromPlugins';\nimport { mergePasteContent } from './mergePasteContent';\nimport { retrieveHtmlInfo } from './retrieveHtmlInfo';\nimport type {\n PasteTypeOrGetter,\n ClipboardData,\n IEditor,\n DOMCreator,\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 pasteTypeOrGetter Type of content to paste or function that returns the Paste Type to use based on the document and the clipboard Data. @default normal\n */\nexport function paste(\n editor: IEditor,\n clipboardData: ClipboardData,\n pasteTypeOrGetter: PasteTypeOrGetter = 'normal'\n) {\n editor.focus();\n let isFirstPaste = false;\n\n if (!clipboardData.modelBeforePaste) {\n isFirstPaste = true;\n\n editor.formatContentModel(model => {\n clipboardData.modelBeforePaste = cloneModelForPaste(model);\n\n return false;\n });\n }\n\n // 1. Prepare variables\n const domCreator = editor.getDOMCreator();\n if (!domCreator.isBypassed && clipboardData.rawHtml) {\n clipboardData.rawHtml = cleanHtmlComments(clipboardData.rawHtml);\n }\n const doc = createDOMFromHtml(clipboardData.rawHtml, domCreator);\n const pasteType =\n typeof pasteTypeOrGetter == 'function'\n ? pasteTypeOrGetter(doc, clipboardData)\n : pasteTypeOrGetter;\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, domCreator)\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, isFirstPaste);\n}\n\nfunction createDOMFromHtml(\n html: string | null | undefined,\n domCreator: DOMCreator\n): Document | null {\n return html ? domCreator.htmlToDOM(html) : null;\n}\n"]}
|
|
@@ -20,7 +20,7 @@ var CopyPastePlugin = /** @class */ (function () {
|
|
|
20
20
|
var dataTransfer = event.clipboardData;
|
|
21
21
|
if (shouldPreventDefaultPaste(dataTransfer, editor_1)) {
|
|
22
22
|
event.preventDefault();
|
|
23
|
-
extractClipboardItems(toArray(dataTransfer.items), _this.state.allowedCustomPasteType).then(function (clipboardData) {
|
|
23
|
+
extractClipboardItems(toArray(dataTransfer.items), _this.state.allowedCustomPasteType, true /* isPasteNative */).then(function (clipboardData) {
|
|
24
24
|
if (!editor_1.isDisposed()) {
|
|
25
25
|
paste(editor_1, clipboardData, _this.state.defaultPasteType);
|
|
26
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EACH,YAAY,EACZ,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,OAAO,GACV,MAAM,6BAA6B,CAAC;AASrC;;GAEG;AACH;IAKI;;;OAGG;IACH,yBAAY,MAAqB;QAAjC,iBAMC;QAdO,WAAM,GAAmB,IAAI,CAAC;QAC9B,aAAQ,GAAwB,IAAI,CAAC;QAkGrC,YAAO,GAAG,UAAC,KAAY;YAC3B,IAAI,KAAI,CAAC,MAAM,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE;gBACxC,IAAM,QAAM,GAAG,KAAI,CAAC,MAAM,CAAC;gBAE3B,IAAM,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC;gBAEzC,IAAI,yBAAyB,CAAC,YAAY,EAAE,QAAM,CAAC,EAAE;oBACjD,KAAK,CAAC,cAAc,EAAE,CAAC;oBACvB,qBAAqB,CACjB,OAAO,CAAC,YAAa,CAAC,KAAK,CAAC,EAC5B,KAAI,CAAC,KAAK,CAAC,sBAAsB,
|
|
1
|
+
{"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/copyPaste/CopyPastePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { deleteEmptyList } from './utils/deleteEmptyList';\nimport { getContentForCopy } from '../../command/cutCopy/getContentForCopy';\nimport { paste } from '../../command/paste/paste';\nimport {\n ChangeSource,\n deleteSelection,\n extractClipboardItems,\n normalizeContentModel,\n toArray,\n} from 'roosterjs-content-model-dom';\nimport type {\n ClipboardData,\n CopyPastePluginState,\n IEditor,\n EditorOptions,\n PluginWithState,\n} from 'roosterjs-content-model-types';\n\n/**\n * Copy and paste plugin for handling onCopy and onPaste event\n */\nclass CopyPastePlugin implements PluginWithState<CopyPastePluginState> {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n private state: CopyPastePluginState;\n\n /**\n * Construct a new instance of CopyPastePlugin\n * @param option The editor option\n */\n constructor(option: EditorOptions) {\n this.state = {\n allowedCustomPasteType: option.allowedCustomPasteType || [],\n tempDiv: null,\n defaultPasteType: option.defaultPasteType,\n };\n }\n\n /**\n * Get a friendly name of this plugin\n */\n getName() {\n return 'CopyPaste';\n }\n\n /**\n * Initialize this plugin. This should only be called from Editor\n * @param editor Editor instance\n */\n initialize(editor: IEditor) {\n this.editor = editor;\n this.disposer = this.editor.attachDomEvent({\n paste: {\n beforeDispatch: e => this.onPaste(e),\n },\n copy: {\n beforeDispatch: e => this.onCutCopy(e, false /*isCut*/),\n },\n cut: {\n beforeDispatch: e => this.onCutCopy(e, true /*isCut*/),\n },\n });\n }\n\n /**\n * Dispose this plugin\n */\n dispose() {\n if (this.state.tempDiv) {\n this.state.tempDiv.parentNode?.removeChild(this.state.tempDiv);\n this.state.tempDiv = null;\n }\n\n if (this.disposer) {\n this.disposer();\n }\n this.disposer = null;\n this.editor = null;\n }\n\n /**\n * Get plugin state object\n */\n getState() {\n return this.state;\n }\n\n private onCutCopy(event: Event, isCut: boolean) {\n if (!this.editor || !isClipboardEvent(event)) {\n return;\n }\n\n const textAndHtmlContent = getContentForCopy(this.editor, isCut, event);\n\n if (textAndHtmlContent) {\n const { htmlContent, textContent } = textAndHtmlContent;\n event.preventDefault();\n event.clipboardData?.setData('text/html', htmlContent.innerHTML);\n event.clipboardData?.setData('text/plain', textContent);\n\n if (isCut) {\n this.editor.formatContentModel(\n (model, context) => {\n if (\n deleteSelection(model, [deleteEmptyList], context).deleteResult ==\n 'range'\n ) {\n normalizeContentModel(model);\n }\n\n return true;\n },\n {\n apiName: 'cut',\n changeSource: ChangeSource.Cut,\n }\n );\n }\n }\n }\n\n private onPaste = (event: Event) => {\n if (this.editor && isClipboardEvent(event)) {\n const editor = this.editor;\n\n const dataTransfer = event.clipboardData;\n\n if (shouldPreventDefaultPaste(dataTransfer, editor)) {\n event.preventDefault();\n extractClipboardItems(\n toArray(dataTransfer!.items),\n this.state.allowedCustomPasteType,\n true /* isPasteNative */\n ).then((clipboardData: ClipboardData) => {\n if (!editor.isDisposed()) {\n paste(editor, clipboardData, this.state.defaultPasteType);\n }\n });\n }\n }\n };\n}\n\nfunction isClipboardEvent(event: Event): event is ClipboardEvent {\n return !!(event as ClipboardEvent).clipboardData;\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport function shouldPreventDefaultPaste(\n dataTransfer: DataTransfer | null,\n editor: IEditor\n): boolean {\n if (!dataTransfer?.items) {\n return false;\n }\n\n if (!editor.getEnvironment().isAndroid) {\n return true;\n }\n\n // On Android, the clipboard data from Office apps is a file, which can't be loaded\n // so we have to allow the default browser behavior\n return toArray(dataTransfer.items).some(item => {\n const { type } = item;\n const isNormalFile = item.kind === 'file' && type !== '';\n const isText = type.indexOf('text/') === 0;\n return isNormalFile || isText;\n });\n}\n\n/**\n * @internal\n * Create a new instance of CopyPastePlugin\n * @param option The editor option\n */\nexport function createCopyPastePlugin(\n option: EditorOptions\n): PluginWithState<CopyPastePluginState> {\n return new CopyPastePlugin(option);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
"description": "Core editor for roosterjs",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"tslib": "^2.3.1",
|
|
6
|
-
"roosterjs-content-model-dom": "^9.
|
|
7
|
-
"roosterjs-content-model-types": "^9.
|
|
6
|
+
"roosterjs-content-model-dom": "^9.55.0",
|
|
7
|
+
"roosterjs-content-model-types": "^9.55.0"
|
|
8
8
|
},
|
|
9
|
-
"version": "9.
|
|
9
|
+
"version": "9.55.0",
|
|
10
10
|
"main": "./lib/index.js",
|
|
11
11
|
"typings": "./lib/index.d.ts",
|
|
12
12
|
"module": "./lib-mjs/index.js",
|