roosterjs-content-model-core 9.41.0 → 9.44.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/createModelFromHtml/createDomToModelContextForSanitizing.d.ts +2 -2
- package/lib/command/createModelFromHtml/createDomToModelContextForSanitizing.js +2 -2
- package/lib/command/createModelFromHtml/createDomToModelContextForSanitizing.js.map +1 -1
- package/lib/command/paste/mergePasteContent.js +1 -1
- package/lib/command/paste/mergePasteContent.js.map +1 -1
- package/lib/command/paste/retrieveHtmlInfo.js +2 -14
- package/lib/command/paste/retrieveHtmlInfo.js.map +1 -1
- package/lib/coreApi/createEditorContext/createEditorContext.js +2 -2
- package/lib/coreApi/createEditorContext/createEditorContext.js.map +1 -1
- package/lib/corePlugin/cache/domIndexerImpl.js +3 -3
- package/lib/corePlugin/cache/domIndexerImpl.js.map +1 -1
- package/lib-amd/command/createModelFromHtml/createDomToModelContextForSanitizing.d.ts +2 -2
- package/lib-amd/command/createModelFromHtml/createDomToModelContextForSanitizing.js +2 -2
- package/lib-amd/command/createModelFromHtml/createDomToModelContextForSanitizing.js.map +1 -1
- package/lib-amd/command/paste/mergePasteContent.js +1 -1
- package/lib-amd/command/paste/mergePasteContent.js.map +1 -1
- package/lib-amd/command/paste/retrieveHtmlInfo.js +2 -14
- package/lib-amd/command/paste/retrieveHtmlInfo.js.map +1 -1
- package/lib-amd/coreApi/createEditorContext/createEditorContext.js +2 -2
- package/lib-amd/coreApi/createEditorContext/createEditorContext.js.map +1 -1
- package/lib-amd/corePlugin/cache/domIndexerImpl.js +3 -3
- package/lib-amd/corePlugin/cache/domIndexerImpl.js.map +1 -1
- package/lib-mjs/command/createModelFromHtml/createDomToModelContextForSanitizing.d.ts +2 -2
- package/lib-mjs/command/createModelFromHtml/createDomToModelContextForSanitizing.js +2 -2
- package/lib-mjs/command/createModelFromHtml/createDomToModelContextForSanitizing.js.map +1 -1
- package/lib-mjs/command/paste/mergePasteContent.js +1 -1
- package/lib-mjs/command/paste/mergePasteContent.js.map +1 -1
- package/lib-mjs/command/paste/retrieveHtmlInfo.js +2 -14
- package/lib-mjs/command/paste/retrieveHtmlInfo.js.map +1 -1
- package/lib-mjs/coreApi/createEditorContext/createEditorContext.js +2 -2
- package/lib-mjs/coreApi/createEditorContext/createEditorContext.js.map +1 -1
- package/lib-mjs/corePlugin/cache/domIndexerImpl.js +3 -3
- package/lib-mjs/corePlugin/cache/domIndexerImpl.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ContentModelSegmentFormat, DomToModelContext, DomToModelOption, DomToModelOptionForSanitizing } from 'roosterjs-content-model-types';
|
|
1
|
+
import type { ContentModelSegmentFormat, DOMHelper, DomToModelContext, DomToModelOption, DomToModelOptionForSanitizing } from 'roosterjs-content-model-types';
|
|
2
2
|
/**
|
|
3
3
|
* @internal
|
|
4
4
|
*/
|
|
5
|
-
export declare function createDomToModelContextForSanitizing(document: Document, defaultFormat?: ContentModelSegmentFormat, defaultOption?: DomToModelOption, additionalSanitizingOption?: Partial<DomToModelOptionForSanitizing
|
|
5
|
+
export declare function createDomToModelContextForSanitizing(document: Document, defaultFormat?: ContentModelSegmentFormat, defaultOption?: DomToModelOption, additionalSanitizingOption?: Partial<DomToModelOptionForSanitizing>, domHelper?: DOMHelper): DomToModelContext;
|
|
@@ -24,9 +24,9 @@ var DefaultSanitizingOption = {
|
|
|
24
24
|
/**
|
|
25
25
|
* @internal
|
|
26
26
|
*/
|
|
27
|
-
function createDomToModelContextForSanitizing(document, defaultFormat, defaultOption, additionalSanitizingOption) {
|
|
27
|
+
function createDomToModelContextForSanitizing(document, defaultFormat, defaultOption, additionalSanitizingOption, domHelper) {
|
|
28
28
|
var sanitizingOption = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, DefaultSanitizingOption), additionalSanitizingOption);
|
|
29
|
-
return (0, roosterjs_content_model_dom_1.createDomToModelContext)((0, tslib_1.__assign)((0, tslib_1.__assign)({ defaultFormat: defaultFormat }, (0, getRootComputedStyleForContext_1.getRootComputedStyleForContext)(document)), { experimentalFeatures: [] }), defaultOption, {
|
|
29
|
+
return (0, roosterjs_content_model_dom_1.createDomToModelContext)((0, tslib_1.__assign)((0, tslib_1.__assign)({ defaultFormat: defaultFormat }, (0, getRootComputedStyleForContext_1.getRootComputedStyleForContext)(document)), { experimentalFeatures: [], editorViewWidth: domHelper === null || domHelper === void 0 ? void 0 : domHelper.getClientWidth() }), defaultOption, {
|
|
30
30
|
processorOverride: {
|
|
31
31
|
'#text': pasteTextProcessor_1.pasteTextProcessor,
|
|
32
32
|
entity: (0, pasteEntityProcessor_1.createPasteEntityProcessor)(sanitizingOption),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDomToModelContextForSanitizing.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/createModelFromHtml/createDomToModelContextForSanitizing.ts"],"names":[],"mappings":";;;;AAAA,sFAAqF;AACrF,2EAAsE;AACtE,4EAAiF;AACjF,8EAAmF;AACnF,mHAAkH;AAClH,wFAAmF;AACnF,oFAAmF;AACnF,wEAAuE;AACvE,0FAAyF;
|
|
1
|
+
{"version":3,"file":"createDomToModelContextForSanitizing.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/createModelFromHtml/createDomToModelContextForSanitizing.ts"],"names":[],"mappings":";;;;AAAA,sFAAqF;AACrF,2EAAsE;AACtE,4EAAiF;AACjF,8EAAmF;AACnF,mHAAkH;AAClH,wFAAmF;AACnF,oFAAmF;AACnF,wEAAuE;AACvE,0FAAyF;AASzF,IAAM,uBAAuB,GAAkC;IAC3D,iBAAiB,EAAE,EAAE;IACrB,oBAAoB,EAAE,EAAE;IACxB,uBAAuB,EAAE,EAAE;IAC3B,qBAAqB,EAAE,EAAE;IACzB,wBAAwB,EAAE,EAAE;IAC5B,eAAe,EAAE,EAAE;IACnB,mBAAmB,EAAE,EAAE;IACvB,yBAAyB,EAAE,KAAK;CACnC,CAAC;AAEF;;GAEG;AACH,SAAgB,oCAAoC,CAChD,QAAkB,EAClB,aAAyC,EACzC,aAAgC,EAChC,0BAAmE,EACnE,SAAqB;IAErB,IAAM,gBAAgB,mDACf,uBAAuB,GACvB,0BAA0B,CAChC,CAAC;IAEF,OAAO,IAAA,qDAAuB,gDAEtB,aAAa,eAAA,IACV,IAAA,+DAA8B,EAAC,QAAQ,CAAC,KAC3C,oBAAoB,EAAE,EAAE,EACxB,eAAe,EAAE,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,cAAc,EAAE,KAEhD,aAAa,EACb;QACI,iBAAiB,EAAE;YACf,OAAO,EAAE,uCAAkB;YAC3B,MAAM,EAAE,IAAA,iDAA0B,EAAC,gBAAgB,CAAC;YACpD,GAAG,EAAE,IAAA,mDAA2B,EAAC,gBAAgB,CAAC;SACrD;QACD,oBAAoB,EAAE;YAClB,OAAO,EAAE,mDAAwB;YACjC,UAAU,EAAE,yDAA2B;SAC1C;QACD,uBAAuB,EAAE;YACrB,SAAS,EAAE,CAAC,qDAAyB,CAAC;YACtC,MAAM,EAAE,CAAC,mDAAsB,CAAC;SACnC;KACJ,EACD,gBAAgB,CACnB,CAAC;AACN,CAAC;AArCD,oFAqCC","sourcesContent":["import { containerSizeFormatParser } from '../../override/containerSizeFormatParser';\nimport { createDomToModelContext } from 'roosterjs-content-model-dom';\nimport { createPasteEntityProcessor } from '../../override/pasteEntityProcessor';\nimport { createPasteGeneralProcessor } from '../../override/pasteGeneralProcessor';\nimport { getRootComputedStyleForContext } from '../../coreApi/createEditorContext/getRootComputedStyleForContext';\nimport { pasteBlockEntityParser } from '../../override/pasteCopyBlockEntityParser';\nimport { pasteDisplayFormatParser } from '../../override/pasteDisplayFormatParser';\nimport { pasteTextProcessor } from '../../override/pasteTextProcessor';\nimport { pasteWhiteSpaceFormatParser } from '../../override/pasteWhiteSpaceFormatParser';\nimport type {\n ContentModelSegmentFormat,\n DOMHelper,\n DomToModelContext,\n DomToModelOption,\n DomToModelOptionForSanitizing,\n} from 'roosterjs-content-model-types';\n\nconst DefaultSanitizingOption: DomToModelOptionForSanitizing = {\n processorOverride: {},\n formatParserOverride: {},\n additionalFormatParsers: {},\n additionalAllowedTags: [],\n additionalDisallowedTags: [],\n styleSanitizers: {},\n attributeSanitizers: {},\n processNonVisibleElements: false,\n};\n\n/**\n * @internal\n */\nexport function createDomToModelContextForSanitizing(\n document: Document,\n defaultFormat?: ContentModelSegmentFormat,\n defaultOption?: DomToModelOption,\n additionalSanitizingOption?: Partial<DomToModelOptionForSanitizing>,\n domHelper?: DOMHelper\n): DomToModelContext {\n const sanitizingOption: DomToModelOptionForSanitizing = {\n ...DefaultSanitizingOption,\n ...additionalSanitizingOption,\n };\n\n return createDomToModelContext(\n {\n defaultFormat,\n ...getRootComputedStyleForContext(document),\n experimentalFeatures: [],\n editorViewWidth: domHelper?.getClientWidth(),\n },\n defaultOption,\n {\n processorOverride: {\n '#text': pasteTextProcessor,\n entity: createPasteEntityProcessor(sanitizingOption),\n '*': createPasteGeneralProcessor(sanitizingOption),\n },\n formatParserOverride: {\n display: pasteDisplayFormatParser,\n whiteSpace: pasteWhiteSpaceFormatParser,\n },\n additionalFormatParsers: {\n container: [containerSizeFormatParser],\n entity: [pasteBlockEntityParser],\n },\n },\n sanitizingOption\n );\n}\n"]}
|
|
@@ -25,7 +25,7 @@ function mergePasteContent(editor, eventResult, isFirstPaste) {
|
|
|
25
25
|
var clonedModel = cloneModelForPaste(clipboardData.modelBeforePaste);
|
|
26
26
|
model.blocks = clonedModel.blocks;
|
|
27
27
|
}
|
|
28
|
-
var domToModelContext = (0, createDomToModelContextForSanitizing_1.createDomToModelContextForSanitizing)(editor.getDocument(), undefined /*defaultFormat*/, editor.getEnvironment().domToModelSettings.customized, domToModelOption);
|
|
28
|
+
var domToModelContext = (0, createDomToModelContextForSanitizing_1.createDomToModelContextForSanitizing)(editor.getDocument(), undefined /*defaultFormat*/, editor.getEnvironment().domToModelSettings.customized, domToModelOption, editor.getDOMHelper());
|
|
29
29
|
domToModelContext.segmentFormat = getSegmentFormatForPaste(model, pasteType);
|
|
30
30
|
var pasteModel = (0, roosterjs_content_model_dom_1.domToContentModel)(fragment, domToModelContext);
|
|
31
31
|
var mergeOption = {
|
|
@@ -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;AAarC,IAAM,UAAU,GAAG,YAAY,CAAC;AAEhC,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,kBAAkB,CAAC,KAAmC;IAClE,OAAO,IAAA,wCAAU,EAAC,KAAK,EAAE,WAAW,CAAC,CAAC;AAC1C,CAAC;AAFD,gDAEC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAC7B,MAAe,EACf,WAA6B,EAC7B,YAAqB;IAGjB,IAAA,QAAQ,GAMR,WAAW,SANH,EACR,gBAAgB,GAKhB,WAAW,iBALK,EAChB,eAAe,GAIf,WAAW,gBAJI,EACf,SAAS,GAGT,WAAW,UAHF,EACT,aAAa,GAEb,WAAW,cAFE,EACb,qBAAqB,GACrB,WAAW,sBADU,CACT;IAEhB,MAAM,CAAC,kBAAkB,CACrB,UAAC,KAAK,EAAE,OAAO;QACX,IAAI,CAAC,YAAY,IAAI,aAAa,CAAC,gBAAgB,EAAE;YACjD,IAAM,WAAW,GAAG,kBAAkB,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;YACvE,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;SACrC;QAED,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,
|
|
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 cloneModel,\n domToContentModel,\n getSegmentTextFormat,\n getSelectedSegments,\n mergeModel,\n} from 'roosterjs-content-model-dom';\nimport type {\n BeforePasteEvent,\n CloneModelOptions,\n ContentModelDocument,\n ContentModelSegmentFormat,\n IEditor,\n MergeModelOption,\n PasteType,\n ReadonlyContentModelDocument,\n ShallowMutableContentModelDocument,\n} from 'roosterjs-content-model-types';\n\nconst BlackColor = 'rgb(0,0,0)';\n\nconst CloneOption: CloneModelOptions = {\n includeCachedElement: (node, type) => (type == 'cache' ? undefined : node),\n};\n\n/**\n * @internal\n */\nexport function cloneModelForPaste(model: ReadonlyContentModelDocument) {\n return cloneModel(model, CloneOption);\n}\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,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.retrieveHtmlInfo = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
|
-
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
6
5
|
var convertInlineCss_1 = require("../createModelFromHtml/convertInlineCss");
|
|
6
|
+
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
7
7
|
var START_FRAGMENT = '<!--StartFragment-->';
|
|
8
8
|
var END_FRAGMENT = '<!--EndFragment-->';
|
|
9
9
|
/**
|
|
@@ -15,7 +15,7 @@ function retrieveHtmlInfo(doc, clipboardData) {
|
|
|
15
15
|
globalCssRules: [],
|
|
16
16
|
};
|
|
17
17
|
if (doc) {
|
|
18
|
-
result = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, retrieveHtmlStrings(clipboardData)), { globalCssRules: (0, convertInlineCss_1.retrieveCssRules)(doc), metadata:
|
|
18
|
+
result = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, retrieveHtmlStrings(clipboardData)), { globalCssRules: (0, convertInlineCss_1.retrieveCssRules)(doc), metadata: (0, roosterjs_content_model_dom_1.retrieveDocumentMetadata)(doc), containsBlockElements: checkBlockElements(doc) });
|
|
19
19
|
clipboardData.htmlFirstLevelChildTags = retrieveTopLevelTags(doc);
|
|
20
20
|
}
|
|
21
21
|
return result;
|
|
@@ -37,18 +37,6 @@ function retrieveTopLevelTags(doc) {
|
|
|
37
37
|
}
|
|
38
38
|
return topLevelTags;
|
|
39
39
|
}
|
|
40
|
-
function retrieveMetadata(doc) {
|
|
41
|
-
var _a;
|
|
42
|
-
var result = {};
|
|
43
|
-
var attributes = (_a = doc.querySelector('html')) === null || _a === void 0 ? void 0 : _a.attributes;
|
|
44
|
-
(attributes ? (0, roosterjs_content_model_dom_1.toArray)(attributes) : []).forEach(function (attr) {
|
|
45
|
-
result[attr.name] = attr.value;
|
|
46
|
-
});
|
|
47
|
-
(0, roosterjs_content_model_dom_1.toArray)(doc.querySelectorAll('meta')).forEach(function (meta) {
|
|
48
|
-
result[meta.name] = meta.content;
|
|
49
|
-
});
|
|
50
|
-
return result;
|
|
51
|
-
}
|
|
52
40
|
function retrieveHtmlStrings(clipboardData) {
|
|
53
41
|
var _a;
|
|
54
42
|
var rawHtml = (_a = clipboardData.rawHtml) !== null && _a !== void 0 ? _a : '';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retrieveHtmlInfo.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/retrieveHtmlInfo.ts"],"names":[],"mappings":";;;;AAAA,
|
|
1
|
+
{"version":3,"file":"retrieveHtmlInfo.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/retrieveHtmlInfo.ts"],"names":[],"mappings":";;;;AAAA,4EAA2E;AAC3E,2EAKqC;AAIrC,IAAM,cAAc,GAAG,sBAAsB,CAAC;AAC9C,IAAM,YAAY,GAAG,oBAAoB,CAAC;AAa1C;;GAEG;AACH,SAAgB,gBAAgB,CAC5B,GAAoB,EACpB,aAAqC;IAErC,IAAI,MAAM,GAAsB;QAC5B,QAAQ,EAAE,EAAE;QACZ,cAAc,EAAE,EAAE;KACrB,CAAC;IAEF,IAAI,GAAG,EAAE;QACL,MAAM,mDACC,mBAAmB,CAAC,aAAa,CAAC,KACrC,cAAc,EAAE,IAAA,mCAAgB,EAAC,GAAG,CAAC,EACrC,QAAQ,EAAE,IAAA,sDAAwB,EAAC,GAAG,CAAC,EACvC,qBAAqB,EAAE,kBAAkB,CAAC,GAAG,CAAC,GACjD,CAAC;QAEF,aAAa,CAAC,uBAAuB,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;KACrE;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AArBD,4CAqBC;AAED,SAAS,oBAAoB,CAAC,GAAa;;IACvC,IAAM,YAAY,GAAa,EAAE,CAAC;IAElC,KAAK,IAAI,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE;QACpE,IAAI,IAAA,0CAAY,EAAC,KAAK,EAAE,WAAW,CAAC,EAAE;YAClC,IAAM,aAAa,GAAG,MAAA,KAAK,CAAC,SAAS,0CAAE,OAAO,CAAC,gBAAgB,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;YAE5E,IAAI,aAAa,EAAE;gBACf,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,4CAA4C;aACtE;SACJ;aAAM,IAAI,IAAA,0CAAY,EAAC,KAAK,EAAE,cAAc,CAAC,EAAE;YAC5C,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;SACpC;KACJ;IAED,OAAO,YAAY,CAAC;AACxB,CAAC;AAED,SAAS,mBAAmB,CACxB,aAAqC;;IAKrC,IAAM,OAAO,GAAG,MAAA,aAAa,CAAC,OAAO,mCAAI,EAAE,CAAC;IAC5C,IAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACnD,IAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;IACnD,IAAI,UAAU,GAAG,EAAE,CAAC;IACpB,IAAI,SAAS,GAAG,EAAE,CAAC;IAEnB,IAAI,UAAU,IAAI,CAAC,IAAI,QAAQ,IAAI,UAAU,GAAG,cAAc,CAAC,MAAM,EAAE;QACnE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QAC9C,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9D,aAAa,CAAC,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,UAAU,GAAG,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;KACxF;SAAM;QACH,aAAa,CAAC,IAAI,GAAG,OAAO,CAAC;KAChC;IAED,OAAO,EAAE,UAAU,YAAA,EAAE,SAAS,WAAA,EAAE,CAAC;AACrC,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAa;IACrC,IAAM,QAAQ,GAAG,IAAA,qCAAO,EAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;IAEzD,OAAO,QAAQ,CAAC,IAAI,CAAC,UAAA,EAAE,IAAI,OAAA,IAAA,0CAAY,EAAC,EAAE,EAAE,cAAc,CAAC,IAAI,IAAA,4CAAc,EAAC,EAAE,CAAC,EAAtD,CAAsD,CAAC,CAAC;AACvF,CAAC","sourcesContent":["import { retrieveCssRules } from '../createModelFromHtml/convertInlineCss';\nimport {\n isBlockElement,\n isNodeOfType,\n retrieveDocumentMetadata,\n toArray,\n} from 'roosterjs-content-model-dom';\nimport type { ClipboardData } from 'roosterjs-content-model-types';\nimport type { CssRule } from '../createModelFromHtml/convertInlineCss';\n\nconst START_FRAGMENT = '<!--StartFragment-->';\nconst END_FRAGMENT = '<!--EndFragment-->';\n\n/**\n * @internal\n */\nexport interface HtmlFromClipboard {\n metadata: Record<string, string>;\n globalCssRules: CssRule[];\n htmlBefore?: string;\n htmlAfter?: string;\n containsBlockElements?: boolean;\n}\n\n/**\n * @internal\n */\nexport function retrieveHtmlInfo(\n doc: Document | null,\n clipboardData: Partial<ClipboardData>\n): HtmlFromClipboard {\n let result: HtmlFromClipboard = {\n metadata: {},\n globalCssRules: [],\n };\n\n if (doc) {\n result = {\n ...retrieveHtmlStrings(clipboardData),\n globalCssRules: retrieveCssRules(doc),\n metadata: retrieveDocumentMetadata(doc),\n containsBlockElements: checkBlockElements(doc),\n };\n\n clipboardData.htmlFirstLevelChildTags = retrieveTopLevelTags(doc);\n }\n\n return result;\n}\n\nfunction retrieveTopLevelTags(doc: Document): string[] {\n const topLevelTags: string[] = [];\n\n for (let child = doc.body.firstChild; child; child = child.nextSibling) {\n if (isNodeOfType(child, 'TEXT_NODE')) {\n const trimmedString = child.nodeValue?.replace(/(\\r\\n|\\r|\\n)/gm, '').trim();\n\n if (trimmedString) {\n topLevelTags.push(''); // Push an empty string as tag for text node\n }\n } else if (isNodeOfType(child, 'ELEMENT_NODE')) {\n topLevelTags.push(child.tagName);\n }\n }\n\n return topLevelTags;\n}\n\nfunction retrieveHtmlStrings(\n clipboardData: Partial<ClipboardData>\n): {\n htmlBefore: string;\n htmlAfter: string;\n} {\n const rawHtml = clipboardData.rawHtml ?? '';\n const startIndex = rawHtml.indexOf(START_FRAGMENT);\n const endIndex = rawHtml.lastIndexOf(END_FRAGMENT);\n let htmlBefore = '';\n let htmlAfter = '';\n\n if (startIndex >= 0 && endIndex >= startIndex + START_FRAGMENT.length) {\n htmlBefore = rawHtml.substring(0, startIndex);\n htmlAfter = rawHtml.substring(endIndex + END_FRAGMENT.length);\n clipboardData.html = rawHtml.substring(startIndex + START_FRAGMENT.length, endIndex);\n } else {\n clipboardData.html = rawHtml;\n }\n\n return { htmlBefore, htmlAfter };\n}\n\nfunction checkBlockElements(doc: Document): boolean {\n const elements = toArray(doc.body.querySelectorAll('*'));\n\n return elements.some(el => isNodeOfType(el, 'ELEMENT_NODE') && isBlockElement(el));\n}\n"]}
|
|
@@ -8,10 +8,10 @@ var getRootComputedStyleForContext_1 = require("./getRootComputedStyleForContext
|
|
|
8
8
|
* Create a EditorContext object used by ContentModel API
|
|
9
9
|
*/
|
|
10
10
|
var createEditorContext = function (core, saveIndex) {
|
|
11
|
-
var _a, _b;
|
|
11
|
+
var _a, _b, _c;
|
|
12
12
|
var lifecycle = core.lifecycle, format = core.format, darkColorHandler = core.darkColorHandler, logicalRoot = core.logicalRoot, cache = core.cache, domHelper = core.domHelper;
|
|
13
13
|
saveIndex = saveIndex && !core.lifecycle.shadowEditFragment;
|
|
14
|
-
var context = (0, tslib_1.__assign)({ isDarkMode: lifecycle.isDarkMode, defaultFormat: format.defaultFormat, pendingFormat: (_a = format.pendingFormat) !== null && _a !== void 0 ? _a : undefined, darkColorHandler: darkColorHandler, addDelimiterForEntity: true, allowCacheElement: true, domIndexer: saveIndex ? cache.domIndexer : undefined, zoomScale: domHelper.calculateZoomScale(), experimentalFeatures: (
|
|
14
|
+
var context = (0, tslib_1.__assign)({ isDarkMode: lifecycle.isDarkMode, defaultFormat: format.defaultFormat, pendingFormat: (_a = format.pendingFormat) !== null && _a !== void 0 ? _a : undefined, darkColorHandler: darkColorHandler, addDelimiterForEntity: true, allowCacheElement: true, allowCacheListItem: !!((_b = core.experimentalFeatures) === null || _b === void 0 ? void 0 : _b.includes('CacheList')), domIndexer: saveIndex ? cache.domIndexer : undefined, zoomScale: domHelper.calculateZoomScale(), experimentalFeatures: (_c = core.experimentalFeatures) !== null && _c !== void 0 ? _c : [], paragraphMap: core.cache.paragraphMap, editorViewWidth: domHelper.getClientWidth() }, (0, getRootComputedStyleForContext_1.getRootComputedStyleForContext)(logicalRoot.ownerDocument));
|
|
15
15
|
if (core.domHelper.isRightToLeft()) {
|
|
16
16
|
context.isRootRtl = true;
|
|
17
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createEditorContext.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/createEditorContext/createEditorContext.ts"],"names":[],"mappings":";;;;AAAA,mFAAkF;AAGlF;;;GAGG;AACI,IAAM,mBAAmB,GAAwB,UAAC,IAAI,EAAE,SAAS;;IAC5D,IAAA,SAAS,GAA8D,IAAI,UAAlE,EAAE,MAAM,GAAsD,IAAI,OAA1D,EAAE,gBAAgB,GAAoC,IAAI,iBAAxC,EAAE,WAAW,GAAuB,IAAI,YAA3B,EAAE,KAAK,GAAgB,IAAI,MAApB,EAAE,SAAS,GAAK,IAAI,UAAT,CAAU;IAEpF,SAAS,GAAG,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC;IAE5D,IAAM,OAAO,2BACT,UAAU,EAAE,SAAS,CAAC,UAAU,EAChC,aAAa,EAAE,MAAM,CAAC,aAAa,EACnC,aAAa,EAAE,MAAA,MAAM,CAAC,aAAa,mCAAI,SAAS,EAChD,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,IAAI,EAC3B,iBAAiB,EAAE,IAAI,EACvB,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,EACpD,SAAS,EAAE,SAAS,CAAC,kBAAkB,EAAE,EACzC,oBAAoB,EAAE,MAAA,IAAI,CAAC,oBAAoB,mCAAI,EAAE,EACrD,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,
|
|
1
|
+
{"version":3,"file":"createEditorContext.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/createEditorContext/createEditorContext.ts"],"names":[],"mappings":";;;;AAAA,mFAAkF;AAGlF;;;GAGG;AACI,IAAM,mBAAmB,GAAwB,UAAC,IAAI,EAAE,SAAS;;IAC5D,IAAA,SAAS,GAA8D,IAAI,UAAlE,EAAE,MAAM,GAAsD,IAAI,OAA1D,EAAE,gBAAgB,GAAoC,IAAI,iBAAxC,EAAE,WAAW,GAAuB,IAAI,YAA3B,EAAE,KAAK,GAAgB,IAAI,MAApB,EAAE,SAAS,GAAK,IAAI,UAAT,CAAU;IAEpF,SAAS,GAAG,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC;IAE5D,IAAM,OAAO,2BACT,UAAU,EAAE,SAAS,CAAC,UAAU,EAChC,aAAa,EAAE,MAAM,CAAC,aAAa,EACnC,aAAa,EAAE,MAAA,MAAM,CAAC,aAAa,mCAAI,SAAS,EAChD,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,IAAI,EAC3B,iBAAiB,EAAE,IAAI,EACvB,kBAAkB,EAAE,CAAC,CAAC,CAAA,MAAA,IAAI,CAAC,oBAAoB,0CAAE,QAAQ,CAAC,WAAW,CAAC,CAAA,EACtE,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,EACpD,SAAS,EAAE,SAAS,CAAC,kBAAkB,EAAE,EACzC,oBAAoB,EAAE,MAAA,IAAI,CAAC,oBAAoB,mCAAI,EAAE,EACrD,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,EACrC,eAAe,EAAE,SAAS,CAAC,cAAc,EAAE,IACxC,IAAA,+DAA8B,EAAC,WAAW,CAAC,aAAa,CAAC,CAC/D,CAAC;IAEF,IAAI,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,EAAE;QAChC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;KAC5B;IAED,OAAO,OAAO,CAAC;AACnB,CAAC,CAAC;AA1BW,QAAA,mBAAmB,uBA0B9B","sourcesContent":["import { getRootComputedStyleForContext } from './getRootComputedStyleForContext';\nimport type { EditorContext, CreateEditorContext } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Create a EditorContext object used by ContentModel API\n */\nexport const createEditorContext: CreateEditorContext = (core, saveIndex) => {\n const { lifecycle, format, darkColorHandler, logicalRoot, cache, domHelper } = core;\n\n saveIndex = saveIndex && !core.lifecycle.shadowEditFragment;\n\n const context: EditorContext = {\n isDarkMode: lifecycle.isDarkMode,\n defaultFormat: format.defaultFormat,\n pendingFormat: format.pendingFormat ?? undefined,\n darkColorHandler: darkColorHandler,\n addDelimiterForEntity: true,\n allowCacheElement: true,\n allowCacheListItem: !!core.experimentalFeatures?.includes('CacheList'),\n domIndexer: saveIndex ? cache.domIndexer : undefined,\n zoomScale: domHelper.calculateZoomScale(),\n experimentalFeatures: core.experimentalFeatures ?? [],\n paragraphMap: core.cache.paragraphMap,\n editorViewWidth: domHelper.getClientWidth(),\n ...getRootComputedStyleForContext(logicalRoot.ownerDocument),\n };\n\n if (core.domHelper.isRightToLeft()) {\n context.isRootRtl = true;\n }\n\n return context;\n};\n"]}
|
|
@@ -149,7 +149,7 @@ var DomIndexerImpl = /** @class */ (function () {
|
|
|
149
149
|
var startContainer = newRange.startContainer, startOffset = newRange.startOffset, endContainer = newRange.endContainer, endOffset = newRange.endOffset, collapsed = newRange.collapsed;
|
|
150
150
|
delete model.hasRevertedRangeSelection;
|
|
151
151
|
if (collapsed) {
|
|
152
|
-
return !!this.reconcileNodeSelection(startContainer, startOffset, model.format);
|
|
152
|
+
return !!this.reconcileNodeSelection(startContainer, startOffset, model.format, selectionMarker);
|
|
153
153
|
}
|
|
154
154
|
else if (startContainer == endContainer &&
|
|
155
155
|
(0, roosterjs_content_model_dom_1.isNodeOfType)(startContainer, 'TEXT_NODE')) {
|
|
@@ -237,10 +237,10 @@ var DomIndexerImpl = /** @class */ (function () {
|
|
|
237
237
|
var start = selection.start, end = selection.end;
|
|
238
238
|
return start.node == end.node && start.offset == end.offset;
|
|
239
239
|
};
|
|
240
|
-
DomIndexerImpl.prototype.reconcileNodeSelection = function (node, offset, defaultFormat) {
|
|
240
|
+
DomIndexerImpl.prototype.reconcileNodeSelection = function (node, offset, defaultFormat, selectionMarker) {
|
|
241
241
|
if ((0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'TEXT_NODE')) {
|
|
242
242
|
if (isIndexedSegment(node)) {
|
|
243
|
-
return this.reconcileTextSelection(node, offset);
|
|
243
|
+
return this.reconcileTextSelection(node, offset, undefined, selectionMarker);
|
|
244
244
|
}
|
|
245
245
|
else if (isIndexedDelimiter(node)) {
|
|
246
246
|
return this.reconcileDelimiterSelection(node, defaultFormat);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domIndexerImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/domIndexerImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n EmptySegmentFormat,\n addCode,\n addLink,\n createParagraph,\n createSelectionMarker,\n createText,\n getObjectKeys,\n isElementOfType,\n isEntityDelimiter,\n isNodeOfType,\n setSelection,\n} from 'roosterjs-content-model-dom';\nimport type {\n CacheSelection,\n ContentModelBlockGroup,\n ContentModelDocument,\n ContentModelEntity,\n ContentModelParagraph,\n ContentModelSegment,\n ContentModelSegmentFormat,\n ContentModelSelectionMarker,\n ContentModelTable,\n ContentModelText,\n DomIndexer,\n DOMSelection,\n RangeSelectionForCache,\n Selectable,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal Export for test only\n */\nexport interface SegmentItem {\n paragraph: ContentModelParagraph;\n segments: ContentModelSegment[];\n}\n\n/**\n * @internal Export for test only\n */\nexport interface TableItem {\n table: ContentModelTable;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface BlockEntityDelimiterItem {\n entity: ContentModelEntity;\n parent: ContentModelBlockGroup;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedSegmentNode extends Node {\n __roosterjsContentModel: SegmentItem;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedTableElement extends HTMLTableElement {\n __roosterjsContentModel: TableItem;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedEntityDelimiter extends Text {\n __roosterjsContentModel: BlockEntityDelimiterItem;\n}\n\n/**\n * Context object used by DomIndexer when reconcile mutations with child list\n */\ninterface ReconcileChildListContext {\n /**\n * Index of segment in current paragraph\n */\n segIndex: number;\n\n /**\n * The current paragraph that we are handling\n */\n paragraph?: ContentModelParagraph;\n\n /**\n * Text node that is added from mutation but has not been handled. This can happen when we first see an added node then later we see a removed one.\n * e.g. Type text in an empty paragraph (<div><br></div>), so a text node will be added and <BR> will be removed.\n * Set to a valid text node means we need to handle it later. If it is finally not handled, that means we need to clear cache\n * Set to undefined (initial value) means no pending text node is hit yet (valid case)\n * Set to null means there was a pending text node which is already handled, so if we see another pending text node,\n * we should clear cache since we don't know how to handle it\n */\n pendingTextNode?: Text | null;\n\n /**\n * Format of the removed segment, this will be used as the format for newly created segment\n */\n format?: ContentModelSegmentFormat;\n}\n\nfunction isIndexedSegment(node: Node): node is IndexedSegmentNode {\n const { paragraph, segments } = (node as IndexedSegmentNode).__roosterjsContentModel ?? {};\n\n return (\n paragraph &&\n paragraph.blockType == 'Paragraph' &&\n Array.isArray(paragraph.segments) &&\n Array.isArray(segments) &&\n segments.every(segment => paragraph.segments.includes(segment))\n );\n}\n\nfunction isIndexedDelimiter(node: Node): node is IndexedEntityDelimiter {\n const { entity, parent } = (node as IndexedEntityDelimiter).__roosterjsContentModel ?? {};\n\n return (\n entity?.blockType == 'Entity' &&\n entity.wrapper &&\n parent?.blockGroupType &&\n Array.isArray(parent.blocks)\n );\n}\n\nfunction getIndexedSegmentItem(node: Node | null): SegmentItem | null {\n return node && isIndexedSegment(node) ? node.__roosterjsContentModel : null;\n}\n\nfunction getIndexedTableItem(element: HTMLTableElement): TableItem | null {\n const index = (element as IndexedTableElement).__roosterjsContentModel;\n const table = index?.table;\n\n if (\n table?.blockType == 'Table' &&\n Array.isArray(table.rows) &&\n table.rows.every(\n x => Array.isArray(x?.cells) && x.cells.every(y => y?.blockGroupType == 'TableCell')\n )\n ) {\n return index;\n } else {\n return null;\n }\n}\n\n// Make a node not indexed. Do not export this function since we should not let code outside here know this detail\nfunction unindex(node: Partial<IndexedSegmentNode>) {\n delete node.__roosterjsContentModel;\n}\n\n/**\n * @internal\n * Implementation of DomIndexer\n */\nexport class DomIndexerImpl implements DomIndexer {\n constructor(private readonly keepSelectionMarkerWhenEnteringTextNode?: boolean) {}\n\n onSegment(segmentNode: Node, paragraph: ContentModelParagraph, segment: ContentModelSegment[]) {\n const indexedText = segmentNode as IndexedSegmentNode;\n indexedText.__roosterjsContentModel = {\n paragraph,\n segments: segment,\n };\n }\n\n onParagraph(paragraphElement: HTMLElement) {\n let previousText: Text | null = null;\n\n for (let child = paragraphElement.firstChild; child; child = child.nextSibling) {\n if (isNodeOfType(child, 'TEXT_NODE')) {\n if (!previousText) {\n previousText = child;\n } else {\n const item = getIndexedSegmentItem(previousText);\n\n if (item && isIndexedSegment(child)) {\n item.segments = item.segments.concat(\n child.__roosterjsContentModel.segments\n );\n child.__roosterjsContentModel.segments = [];\n }\n }\n } else if (isNodeOfType(child, 'ELEMENT_NODE')) {\n previousText = null;\n\n this.onParagraph(child);\n } else {\n previousText = null;\n }\n }\n }\n\n onTable(tableElement: HTMLTableElement, table: ContentModelTable) {\n const indexedTable = tableElement as IndexedTableElement;\n indexedTable.__roosterjsContentModel = { table };\n }\n\n onBlockEntity(entity: ContentModelEntity, group: ContentModelBlockGroup) {\n this.onBlockEntityDelimiter(entity.wrapper.previousSibling, entity, group);\n this.onBlockEntityDelimiter(entity.wrapper.nextSibling, entity, group);\n }\n\n onMergeText(targetText: Text, sourceText: Text) {\n if (isIndexedSegment(targetText) && isIndexedSegment(sourceText)) {\n if (targetText.nextSibling == sourceText) {\n targetText.__roosterjsContentModel.segments.push(\n ...sourceText.__roosterjsContentModel.segments\n );\n\n unindex(sourceText);\n }\n } else {\n unindex(sourceText);\n unindex(targetText);\n }\n }\n\n clearIndex(container: Node) {\n internalClearIndex(container);\n }\n\n reconcileSelection(\n model: ContentModelDocument,\n newSelection: DOMSelection,\n oldSelection?: CacheSelection\n ): boolean {\n let selectionMarker: ContentModelSelectionMarker | undefined;\n if (oldSelection) {\n let startNode: Node | undefined;\n\n if (\n oldSelection.type == 'range' &&\n this.isCollapsed(oldSelection) &&\n (startNode = oldSelection.start.node) &&\n isNodeOfType(startNode, 'TEXT_NODE') &&\n isIndexedSegment(startNode) &&\n startNode.__roosterjsContentModel.segments.length > 0\n ) {\n this.reconcileTextSelection(startNode);\n } else {\n selectionMarker = this.selectionMarkerToKeepWhenEnteringTextNode(\n oldSelection,\n newSelection\n );\n\n setSelection(model);\n }\n }\n\n switch (newSelection.type) {\n case 'image':\n const indexedImage = getIndexedSegmentItem(newSelection.image);\n const image = indexedImage?.segments[0];\n\n if (image) {\n image.isSelected = true;\n setSelection(model, image);\n\n return true;\n } else {\n return false;\n }\n\n case 'table':\n const indexedTable = getIndexedTableItem(newSelection.table);\n\n if (indexedTable) {\n const firstCell =\n indexedTable.table.rows[newSelection.firstRow]?.cells[\n newSelection.firstColumn\n ];\n const lastCell =\n indexedTable.table.rows[newSelection.lastRow]?.cells[\n newSelection.lastColumn\n ];\n\n if (firstCell && lastCell) {\n setSelection(model, firstCell, lastCell);\n\n return true;\n }\n }\n\n return false;\n\n case 'range':\n const newRange = newSelection.range;\n if (newRange) {\n const {\n startContainer,\n startOffset,\n endContainer,\n endOffset,\n collapsed,\n } = newRange;\n\n delete model.hasRevertedRangeSelection;\n\n if (collapsed) {\n return !!this.reconcileNodeSelection(\n startContainer,\n startOffset,\n model.format\n );\n } else if (\n startContainer == endContainer &&\n isNodeOfType(startContainer, 'TEXT_NODE')\n ) {\n if (newSelection.isReverted) {\n model.hasRevertedRangeSelection = true;\n }\n\n return (\n isIndexedSegment(startContainer) &&\n !!this.reconcileTextSelection(\n startContainer,\n startOffset,\n endOffset,\n selectionMarker\n )\n );\n } else {\n const marker1 = this.reconcileNodeSelection(startContainer, startOffset);\n const marker2 = this.reconcileNodeSelection(endContainer, endOffset);\n\n if (marker1 && marker2) {\n if (newSelection.isReverted) {\n model.hasRevertedRangeSelection = true;\n }\n\n setSelection(model, marker1, marker2);\n return true;\n } else {\n return false;\n }\n }\n }\n\n break;\n }\n\n return false;\n }\n\n reconcileChildList(addedNodes: ArrayLike<Node>, removedNodes: ArrayLike<Node>): boolean {\n let canHandle = true;\n const context: ReconcileChildListContext = {\n segIndex: -1,\n };\n\n // First process added nodes\n const addedNode = addedNodes[0];\n\n if (addedNodes.length == 1 && isNodeOfType(addedNode, 'TEXT_NODE')) {\n canHandle = this.reconcileAddedNode(addedNode, context);\n } else if (addedNodes.length > 0) {\n canHandle = false;\n }\n\n // Second, process removed nodes\n const removedNode = removedNodes[0];\n\n if (canHandle && removedNodes.length == 1) {\n canHandle = this.reconcileRemovedNode(removedNode, context);\n } else if (removedNodes.length > 0) {\n canHandle = false;\n }\n\n return canHandle && !context.pendingTextNode;\n }\n\n reconcileElementId(element: HTMLElement) {\n if (isElementOfType(element, 'img')) {\n const indexedImg = getIndexedSegmentItem(element);\n\n if (indexedImg?.segments[0]?.segmentType == 'Image') {\n indexedImg.segments[0].format.id = element.id;\n\n return true;\n } else {\n return false;\n }\n } else if (isElementOfType(element, 'table')) {\n const indexedTable = getIndexedTableItem(element);\n\n if (indexedTable) {\n indexedTable.table.format.id = element.id;\n\n return true;\n } else {\n return false;\n }\n } else {\n return false;\n }\n }\n\n private onBlockEntityDelimiter(\n node: Node | null,\n entity: ContentModelEntity,\n parent: ContentModelBlockGroup\n ) {\n if (isNodeOfType(node, 'ELEMENT_NODE') && isEntityDelimiter(node) && node.firstChild) {\n const indexedDelimiter = node.firstChild as IndexedEntityDelimiter;\n\n indexedDelimiter.__roosterjsContentModel = { entity, parent };\n }\n }\n\n private isCollapsed(selection: RangeSelectionForCache): boolean {\n const { start, end } = selection;\n\n return start.node == end.node && start.offset == end.offset;\n }\n\n private reconcileNodeSelection(\n node: Node,\n offset: number,\n defaultFormat?: ContentModelSegmentFormat\n ): Selectable | undefined {\n if (isNodeOfType(node, 'TEXT_NODE')) {\n if (isIndexedSegment(node)) {\n return this.reconcileTextSelection(node, offset);\n } else if (isIndexedDelimiter(node)) {\n return this.reconcileDelimiterSelection(node, defaultFormat);\n } else {\n return undefined;\n }\n } else if (offset >= node.childNodes.length) {\n return this.insertMarker(node.lastChild, true /*isAfter*/);\n } else {\n return this.insertMarker(node.childNodes[offset], false /*isAfter*/);\n }\n }\n\n private insertMarker(node: Node | null, isAfter: boolean): Selectable | undefined {\n let marker: ContentModelSelectionMarker | undefined;\n const segmentItem = node && getIndexedSegmentItem(node);\n\n if (segmentItem) {\n const { paragraph, segments } = segmentItem;\n const index = paragraph.segments.indexOf(segments[0]);\n\n if (index >= 0) {\n const formatSegment =\n (!isAfter && paragraph.segments[index - 1]) || paragraph.segments[index];\n marker = createSelectionMarker(formatSegment.format);\n\n paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);\n }\n }\n\n return marker;\n }\n\n private reconcileTextSelection(\n textNode: IndexedSegmentNode,\n startOffset?: number,\n endOffset?: number,\n selectionMarker?: ContentModelSelectionMarker\n ) {\n const { paragraph, segments } = textNode.__roosterjsContentModel;\n const first = segments[0];\n const last = segments[segments.length - 1];\n let selectable: Selectable | undefined;\n\n if (first?.segmentType == 'Text' && last?.segmentType == 'Text') {\n const newSegments: ContentModelSegment[] = [];\n const txt = textNode.nodeValue || '';\n const textSegments: ContentModelText[] = [];\n\n if (startOffset === undefined) {\n first.text = txt;\n newSegments.push(first);\n textSegments.push(first);\n } else {\n if (startOffset > 0) {\n first.text = txt.substring(0, startOffset);\n newSegments.push(first);\n textSegments.push(first);\n }\n\n if (endOffset === undefined) {\n const marker = createSelectionMarker(selectionMarker?.format ?? first.format);\n newSegments.push(marker);\n\n if (startOffset < (textNode.nodeValue ?? '').length) {\n if (first.link) {\n addLink(marker, first.link);\n }\n\n if (first.code) {\n addCode(marker, first.code);\n }\n }\n\n selectable = marker;\n endOffset = startOffset;\n } else if (endOffset > startOffset) {\n const middle = createText(\n txt.substring(startOffset, endOffset),\n selectionMarker?.format ?? first.format,\n first.link,\n first.code\n );\n\n middle.isSelected = true;\n newSegments.push(middle);\n textSegments.push(middle);\n selectable = middle;\n }\n\n if (endOffset < txt.length) {\n const newLast = createText(\n txt.substring(endOffset),\n selectionMarker?.format ?? first.format,\n first.link,\n first.code\n );\n newSegments.push(newLast);\n textSegments.push(newLast);\n }\n }\n\n let firstIndex = paragraph.segments.indexOf(first);\n let lastIndex = paragraph.segments.indexOf(last);\n\n if (firstIndex >= 0 && lastIndex >= 0) {\n while (\n firstIndex > 0 &&\n paragraph.segments[firstIndex - 1].segmentType == 'SelectionMarker'\n ) {\n firstIndex--;\n }\n\n while (\n lastIndex < paragraph.segments.length - 1 &&\n paragraph.segments[lastIndex + 1].segmentType == 'SelectionMarker'\n ) {\n lastIndex++;\n }\n\n paragraph.segments.splice(firstIndex, lastIndex - firstIndex + 1, ...newSegments);\n }\n\n this.onSegment(textNode, paragraph, textSegments);\n } else if (first?.segmentType == 'Entity' && first == last) {\n const wrapper = first.wrapper;\n const index = paragraph.segments.indexOf(first);\n const delimiter = textNode.parentElement;\n const isBefore = wrapper.previousSibling == delimiter;\n const isAfter = wrapper.nextSibling == delimiter;\n\n if (index >= 0 && delimiter && isEntityDelimiter(delimiter) && (isBefore || isAfter)) {\n const marker = createSelectionMarker(\n selectionMarker?.format ??\n (paragraph.segments[isAfter ? index + 1 : index - 1] ?? first).format\n );\n\n paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);\n\n selectable = marker;\n }\n }\n\n return selectable;\n }\n\n private reconcileDelimiterSelection(\n node: IndexedEntityDelimiter,\n defaultFormat?: ContentModelSegmentFormat\n ) {\n let marker: ContentModelSelectionMarker | undefined;\n\n const { entity, parent } = node.__roosterjsContentModel;\n const index = parent.blocks.indexOf(entity);\n const delimiter = node.parentElement;\n const wrapper = entity.wrapper;\n const isBefore = wrapper.previousSibling == delimiter;\n const isAfter = wrapper.nextSibling == delimiter;\n\n if (index >= 0 && delimiter && isEntityDelimiter(delimiter) && (isBefore || isAfter)) {\n marker = createSelectionMarker(defaultFormat);\n\n const para = createParagraph(\n true /*isImplicit*/,\n undefined /*blockFormat*/,\n defaultFormat\n );\n\n para.segments.push(marker);\n parent.blocks.splice(isBefore ? index : index + 1, 0, para);\n }\n\n return marker;\n }\n\n private reconcileAddedNode(node: Text, context: ReconcileChildListContext): boolean {\n let segmentItem: SegmentItem | null = null;\n let index = -1;\n let existingSegment: ContentModelSegment;\n const { previousSibling, nextSibling } = node;\n\n if (\n (segmentItem = getIndexedSegmentItem(getLastLeaf(previousSibling))) &&\n (existingSegment = segmentItem.segments[segmentItem.segments.length - 1]) &&\n (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0\n ) {\n // When we can find indexed segment before current one, use it as the insert index\n this.indexNode(segmentItem.paragraph, index + 1, node, existingSegment.format);\n } else if (\n (segmentItem = getIndexedSegmentItem(getFirstLeaf(nextSibling))) &&\n (existingSegment = segmentItem.segments[0]) &&\n (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0\n ) {\n // When we can find indexed segment after current one, use it as the insert index\n this.indexNode(segmentItem.paragraph, index, node, existingSegment.format);\n } else if (context.paragraph && context.segIndex >= 0) {\n // When there is indexed paragraph from removed nodes, we can use it as the insert index\n this.indexNode(context.paragraph, context.segIndex, node, context.format);\n } else if (context.pendingTextNode === undefined) {\n // When we can't find the insert index, set current node as pending node\n // so later we can pick it up when we have enough info when processing removed node\n // Only do this when pendingTextNode is undefined. If it is null it means there was already a pending node before\n // and in that case we should return false since we can't handle two pending text node\n context.pendingTextNode = node;\n } else {\n return false;\n }\n\n return true;\n }\n\n private reconcileRemovedNode(node: Node, context: ReconcileChildListContext): boolean {\n let segmentItem: SegmentItem | null = null;\n let removingSegment: ContentModelSegment;\n\n if (\n context.segIndex < 0 &&\n !context.paragraph && // No previous removed segment or related paragraph found, and\n (segmentItem = getIndexedSegmentItem(node)) && // The removed node is indexed, and\n (removingSegment = segmentItem.segments[0]) // There is at least one related segment\n ) {\n // Now we can remove the indexed segment from the paragraph, and remember it, later we may need to use it\n context.format = removingSegment.format;\n context.paragraph = segmentItem.paragraph;\n context.segIndex = segmentItem.paragraph.segments.indexOf(segmentItem.segments[0]);\n\n if (context.segIndex < 0) {\n // Indexed segment is not under paragraph, something wrong happens, we cannot keep handling\n return false;\n }\n\n for (let i = 0; i < segmentItem.segments.length; i++) {\n const index = segmentItem.paragraph.segments.indexOf(segmentItem.segments[i]);\n\n if (index >= 0) {\n segmentItem.paragraph.segments.splice(index, 1);\n }\n }\n\n if (context.pendingTextNode) {\n // If we have pending text node added but not indexed, do it now\n this.indexNode(\n context.paragraph,\n context.segIndex,\n context.pendingTextNode,\n segmentItem.segments[0].format\n );\n\n // Set to null since we have processed it.\n // Next time we see a pending node we know we have already processed one so it is a situation we cannot handle\n context.pendingTextNode = null;\n }\n\n return true;\n } else {\n return false;\n }\n }\n\n private indexNode(\n paragraph: ContentModelParagraph,\n index: number,\n textNode: Text,\n format?: ContentModelSegmentFormat\n ) {\n const copiedFormat = format ? { ...format } : undefined;\n\n if (copiedFormat) {\n getObjectKeys(copiedFormat).forEach(key => {\n if (EmptySegmentFormat[key] === undefined) {\n delete copiedFormat[key];\n }\n });\n }\n\n const text = createText(textNode.textContent ?? '', copiedFormat);\n\n paragraph.segments.splice(index, 0, text);\n this.onSegment(textNode, paragraph, [text]);\n }\n\n private selectionMarkerToKeepWhenEnteringTextNode(\n oldSelection: CacheSelection,\n newSelection: DOMSelection\n ): ContentModelSelectionMarker | undefined {\n // For CJK keyboard input on mobile, we may have a situation like this:\n // User toggle bold/italic/underline on an empty div, the pending format will be applied on the selection marker\n // then type some text, the selection move to the text node and the selection marker will be recreated during the reconciliation and lose its original formatting\n // In this case, we need to keep the original formatting of the selection marker to match the pending format\n\n if (\n this.keepSelectionMarkerWhenEnteringTextNode &&\n oldSelection.type == 'range' &&\n this.isCollapsed(oldSelection) &&\n newSelection.type == 'range' &&\n isNodeOfType(newSelection.range.commonAncestorContainer, 'TEXT_NODE') &&\n newSelection.range.commonAncestorContainer.parentElement == oldSelection.start.node &&\n isIndexedSegment(newSelection.range.commonAncestorContainer) &&\n newSelection.range.commonAncestorContainer.__roosterjsContentModel.paragraph.segments[0]\n .segmentType == 'SelectionMarker'\n ) {\n return newSelection.range.commonAncestorContainer.__roosterjsContentModel.paragraph\n .segments[0];\n }\n return undefined;\n }\n}\n\nfunction getLastLeaf(node: Node | null): Node | null {\n while (node?.lastChild) {\n node = node.lastChild;\n }\n\n return node;\n}\n\nfunction getFirstLeaf(node: Node | null): Node | null {\n while (node?.firstChild) {\n node = node.firstChild;\n }\n\n return node;\n}\n\nfunction internalClearIndex(container: Node) {\n unindex(container as IndexedSegmentNode);\n\n for (let node = container.firstChild; node; node = node.nextSibling) {\n internalClearIndex(node);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"domIndexerImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/domIndexerImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n EmptySegmentFormat,\n addCode,\n addLink,\n createParagraph,\n createSelectionMarker,\n createText,\n getObjectKeys,\n isElementOfType,\n isEntityDelimiter,\n isNodeOfType,\n setSelection,\n} from 'roosterjs-content-model-dom';\nimport type {\n CacheSelection,\n ContentModelBlockGroup,\n ContentModelDocument,\n ContentModelEntity,\n ContentModelParagraph,\n ContentModelSegment,\n ContentModelSegmentFormat,\n ContentModelSelectionMarker,\n ContentModelTable,\n ContentModelText,\n DomIndexer,\n DOMSelection,\n RangeSelectionForCache,\n Selectable,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal Export for test only\n */\nexport interface SegmentItem {\n paragraph: ContentModelParagraph;\n segments: ContentModelSegment[];\n}\n\n/**\n * @internal Export for test only\n */\nexport interface TableItem {\n table: ContentModelTable;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface BlockEntityDelimiterItem {\n entity: ContentModelEntity;\n parent: ContentModelBlockGroup;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedSegmentNode extends Node {\n __roosterjsContentModel: SegmentItem;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedTableElement extends HTMLTableElement {\n __roosterjsContentModel: TableItem;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedEntityDelimiter extends Text {\n __roosterjsContentModel: BlockEntityDelimiterItem;\n}\n\n/**\n * Context object used by DomIndexer when reconcile mutations with child list\n */\ninterface ReconcileChildListContext {\n /**\n * Index of segment in current paragraph\n */\n segIndex: number;\n\n /**\n * The current paragraph that we are handling\n */\n paragraph?: ContentModelParagraph;\n\n /**\n * Text node that is added from mutation but has not been handled. This can happen when we first see an added node then later we see a removed one.\n * e.g. Type text in an empty paragraph (<div><br></div>), so a text node will be added and <BR> will be removed.\n * Set to a valid text node means we need to handle it later. If it is finally not handled, that means we need to clear cache\n * Set to undefined (initial value) means no pending text node is hit yet (valid case)\n * Set to null means there was a pending text node which is already handled, so if we see another pending text node,\n * we should clear cache since we don't know how to handle it\n */\n pendingTextNode?: Text | null;\n\n /**\n * Format of the removed segment, this will be used as the format for newly created segment\n */\n format?: ContentModelSegmentFormat;\n}\n\nfunction isIndexedSegment(node: Node): node is IndexedSegmentNode {\n const { paragraph, segments } = (node as IndexedSegmentNode).__roosterjsContentModel ?? {};\n\n return (\n paragraph &&\n paragraph.blockType == 'Paragraph' &&\n Array.isArray(paragraph.segments) &&\n Array.isArray(segments) &&\n segments.every(segment => paragraph.segments.includes(segment))\n );\n}\n\nfunction isIndexedDelimiter(node: Node): node is IndexedEntityDelimiter {\n const { entity, parent } = (node as IndexedEntityDelimiter).__roosterjsContentModel ?? {};\n\n return (\n entity?.blockType == 'Entity' &&\n entity.wrapper &&\n parent?.blockGroupType &&\n Array.isArray(parent.blocks)\n );\n}\n\nfunction getIndexedSegmentItem(node: Node | null): SegmentItem | null {\n return node && isIndexedSegment(node) ? node.__roosterjsContentModel : null;\n}\n\nfunction getIndexedTableItem(element: HTMLTableElement): TableItem | null {\n const index = (element as IndexedTableElement).__roosterjsContentModel;\n const table = index?.table;\n\n if (\n table?.blockType == 'Table' &&\n Array.isArray(table.rows) &&\n table.rows.every(\n x => Array.isArray(x?.cells) && x.cells.every(y => y?.blockGroupType == 'TableCell')\n )\n ) {\n return index;\n } else {\n return null;\n }\n}\n\n// Make a node not indexed. Do not export this function since we should not let code outside here know this detail\nfunction unindex(node: Partial<IndexedSegmentNode>) {\n delete node.__roosterjsContentModel;\n}\n\n/**\n * @internal\n * Implementation of DomIndexer\n */\nexport class DomIndexerImpl implements DomIndexer {\n constructor(private readonly keepSelectionMarkerWhenEnteringTextNode?: boolean) {}\n\n onSegment(segmentNode: Node, paragraph: ContentModelParagraph, segment: ContentModelSegment[]) {\n const indexedText = segmentNode as IndexedSegmentNode;\n indexedText.__roosterjsContentModel = {\n paragraph,\n segments: segment,\n };\n }\n\n onParagraph(paragraphElement: HTMLElement) {\n let previousText: Text | null = null;\n\n for (let child = paragraphElement.firstChild; child; child = child.nextSibling) {\n if (isNodeOfType(child, 'TEXT_NODE')) {\n if (!previousText) {\n previousText = child;\n } else {\n const item = getIndexedSegmentItem(previousText);\n\n if (item && isIndexedSegment(child)) {\n item.segments = item.segments.concat(\n child.__roosterjsContentModel.segments\n );\n child.__roosterjsContentModel.segments = [];\n }\n }\n } else if (isNodeOfType(child, 'ELEMENT_NODE')) {\n previousText = null;\n\n this.onParagraph(child);\n } else {\n previousText = null;\n }\n }\n }\n\n onTable(tableElement: HTMLTableElement, table: ContentModelTable) {\n const indexedTable = tableElement as IndexedTableElement;\n indexedTable.__roosterjsContentModel = { table };\n }\n\n onBlockEntity(entity: ContentModelEntity, group: ContentModelBlockGroup) {\n this.onBlockEntityDelimiter(entity.wrapper.previousSibling, entity, group);\n this.onBlockEntityDelimiter(entity.wrapper.nextSibling, entity, group);\n }\n\n onMergeText(targetText: Text, sourceText: Text) {\n if (isIndexedSegment(targetText) && isIndexedSegment(sourceText)) {\n if (targetText.nextSibling == sourceText) {\n targetText.__roosterjsContentModel.segments.push(\n ...sourceText.__roosterjsContentModel.segments\n );\n\n unindex(sourceText);\n }\n } else {\n unindex(sourceText);\n unindex(targetText);\n }\n }\n\n clearIndex(container: Node) {\n internalClearIndex(container);\n }\n\n reconcileSelection(\n model: ContentModelDocument,\n newSelection: DOMSelection,\n oldSelection?: CacheSelection\n ): boolean {\n let selectionMarker: ContentModelSelectionMarker | undefined;\n if (oldSelection) {\n let startNode: Node | undefined;\n\n if (\n oldSelection.type == 'range' &&\n this.isCollapsed(oldSelection) &&\n (startNode = oldSelection.start.node) &&\n isNodeOfType(startNode, 'TEXT_NODE') &&\n isIndexedSegment(startNode) &&\n startNode.__roosterjsContentModel.segments.length > 0\n ) {\n this.reconcileTextSelection(startNode);\n } else {\n selectionMarker = this.selectionMarkerToKeepWhenEnteringTextNode(\n oldSelection,\n newSelection\n );\n\n setSelection(model);\n }\n }\n\n switch (newSelection.type) {\n case 'image':\n const indexedImage = getIndexedSegmentItem(newSelection.image);\n const image = indexedImage?.segments[0];\n\n if (image) {\n image.isSelected = true;\n setSelection(model, image);\n\n return true;\n } else {\n return false;\n }\n\n case 'table':\n const indexedTable = getIndexedTableItem(newSelection.table);\n\n if (indexedTable) {\n const firstCell =\n indexedTable.table.rows[newSelection.firstRow]?.cells[\n newSelection.firstColumn\n ];\n const lastCell =\n indexedTable.table.rows[newSelection.lastRow]?.cells[\n newSelection.lastColumn\n ];\n\n if (firstCell && lastCell) {\n setSelection(model, firstCell, lastCell);\n\n return true;\n }\n }\n\n return false;\n\n case 'range':\n const newRange = newSelection.range;\n if (newRange) {\n const {\n startContainer,\n startOffset,\n endContainer,\n endOffset,\n collapsed,\n } = newRange;\n\n delete model.hasRevertedRangeSelection;\n\n if (collapsed) {\n return !!this.reconcileNodeSelection(\n startContainer,\n startOffset,\n model.format,\n selectionMarker\n );\n } else if (\n startContainer == endContainer &&\n isNodeOfType(startContainer, 'TEXT_NODE')\n ) {\n if (newSelection.isReverted) {\n model.hasRevertedRangeSelection = true;\n }\n\n return (\n isIndexedSegment(startContainer) &&\n !!this.reconcileTextSelection(\n startContainer,\n startOffset,\n endOffset,\n selectionMarker\n )\n );\n } else {\n const marker1 = this.reconcileNodeSelection(startContainer, startOffset);\n const marker2 = this.reconcileNodeSelection(endContainer, endOffset);\n\n if (marker1 && marker2) {\n if (newSelection.isReverted) {\n model.hasRevertedRangeSelection = true;\n }\n\n setSelection(model, marker1, marker2);\n return true;\n } else {\n return false;\n }\n }\n }\n\n break;\n }\n\n return false;\n }\n\n reconcileChildList(addedNodes: ArrayLike<Node>, removedNodes: ArrayLike<Node>): boolean {\n let canHandle = true;\n const context: ReconcileChildListContext = {\n segIndex: -1,\n };\n\n // First process added nodes\n const addedNode = addedNodes[0];\n\n if (addedNodes.length == 1 && isNodeOfType(addedNode, 'TEXT_NODE')) {\n canHandle = this.reconcileAddedNode(addedNode, context);\n } else if (addedNodes.length > 0) {\n canHandle = false;\n }\n\n // Second, process removed nodes\n const removedNode = removedNodes[0];\n\n if (canHandle && removedNodes.length == 1) {\n canHandle = this.reconcileRemovedNode(removedNode, context);\n } else if (removedNodes.length > 0) {\n canHandle = false;\n }\n\n return canHandle && !context.pendingTextNode;\n }\n\n reconcileElementId(element: HTMLElement) {\n if (isElementOfType(element, 'img')) {\n const indexedImg = getIndexedSegmentItem(element);\n\n if (indexedImg?.segments[0]?.segmentType == 'Image') {\n indexedImg.segments[0].format.id = element.id;\n\n return true;\n } else {\n return false;\n }\n } else if (isElementOfType(element, 'table')) {\n const indexedTable = getIndexedTableItem(element);\n\n if (indexedTable) {\n indexedTable.table.format.id = element.id;\n\n return true;\n } else {\n return false;\n }\n } else {\n return false;\n }\n }\n\n private onBlockEntityDelimiter(\n node: Node | null,\n entity: ContentModelEntity,\n parent: ContentModelBlockGroup\n ) {\n if (isNodeOfType(node, 'ELEMENT_NODE') && isEntityDelimiter(node) && node.firstChild) {\n const indexedDelimiter = node.firstChild as IndexedEntityDelimiter;\n\n indexedDelimiter.__roosterjsContentModel = { entity, parent };\n }\n }\n\n private isCollapsed(selection: RangeSelectionForCache): boolean {\n const { start, end } = selection;\n\n return start.node == end.node && start.offset == end.offset;\n }\n\n private reconcileNodeSelection(\n node: Node,\n offset: number,\n defaultFormat?: ContentModelSegmentFormat,\n selectionMarker?: ContentModelSelectionMarker\n ): Selectable | undefined {\n if (isNodeOfType(node, 'TEXT_NODE')) {\n if (isIndexedSegment(node)) {\n return this.reconcileTextSelection(node, offset, undefined, selectionMarker);\n } else if (isIndexedDelimiter(node)) {\n return this.reconcileDelimiterSelection(node, defaultFormat);\n } else {\n return undefined;\n }\n } else if (offset >= node.childNodes.length) {\n return this.insertMarker(node.lastChild, true /*isAfter*/);\n } else {\n return this.insertMarker(node.childNodes[offset], false /*isAfter*/);\n }\n }\n\n private insertMarker(node: Node | null, isAfter: boolean): Selectable | undefined {\n let marker: ContentModelSelectionMarker | undefined;\n const segmentItem = node && getIndexedSegmentItem(node);\n\n if (segmentItem) {\n const { paragraph, segments } = segmentItem;\n const index = paragraph.segments.indexOf(segments[0]);\n\n if (index >= 0) {\n const formatSegment =\n (!isAfter && paragraph.segments[index - 1]) || paragraph.segments[index];\n marker = createSelectionMarker(formatSegment.format);\n\n paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);\n }\n }\n\n return marker;\n }\n\n private reconcileTextSelection(\n textNode: IndexedSegmentNode,\n startOffset?: number,\n endOffset?: number,\n selectionMarker?: ContentModelSelectionMarker\n ) {\n const { paragraph, segments } = textNode.__roosterjsContentModel;\n const first = segments[0];\n const last = segments[segments.length - 1];\n let selectable: Selectable | undefined;\n\n if (first?.segmentType == 'Text' && last?.segmentType == 'Text') {\n const newSegments: ContentModelSegment[] = [];\n const txt = textNode.nodeValue || '';\n const textSegments: ContentModelText[] = [];\n\n if (startOffset === undefined) {\n first.text = txt;\n newSegments.push(first);\n textSegments.push(first);\n } else {\n if (startOffset > 0) {\n first.text = txt.substring(0, startOffset);\n newSegments.push(first);\n textSegments.push(first);\n }\n\n if (endOffset === undefined) {\n const marker = createSelectionMarker(selectionMarker?.format ?? first.format);\n newSegments.push(marker);\n\n if (startOffset < (textNode.nodeValue ?? '').length) {\n if (first.link) {\n addLink(marker, first.link);\n }\n\n if (first.code) {\n addCode(marker, first.code);\n }\n }\n\n selectable = marker;\n endOffset = startOffset;\n } else if (endOffset > startOffset) {\n const middle = createText(\n txt.substring(startOffset, endOffset),\n selectionMarker?.format ?? first.format,\n first.link,\n first.code\n );\n\n middle.isSelected = true;\n newSegments.push(middle);\n textSegments.push(middle);\n selectable = middle;\n }\n\n if (endOffset < txt.length) {\n const newLast = createText(\n txt.substring(endOffset),\n selectionMarker?.format ?? first.format,\n first.link,\n first.code\n );\n newSegments.push(newLast);\n textSegments.push(newLast);\n }\n }\n\n let firstIndex = paragraph.segments.indexOf(first);\n let lastIndex = paragraph.segments.indexOf(last);\n\n if (firstIndex >= 0 && lastIndex >= 0) {\n while (\n firstIndex > 0 &&\n paragraph.segments[firstIndex - 1].segmentType == 'SelectionMarker'\n ) {\n firstIndex--;\n }\n\n while (\n lastIndex < paragraph.segments.length - 1 &&\n paragraph.segments[lastIndex + 1].segmentType == 'SelectionMarker'\n ) {\n lastIndex++;\n }\n\n paragraph.segments.splice(firstIndex, lastIndex - firstIndex + 1, ...newSegments);\n }\n\n this.onSegment(textNode, paragraph, textSegments);\n } else if (first?.segmentType == 'Entity' && first == last) {\n const wrapper = first.wrapper;\n const index = paragraph.segments.indexOf(first);\n const delimiter = textNode.parentElement;\n const isBefore = wrapper.previousSibling == delimiter;\n const isAfter = wrapper.nextSibling == delimiter;\n\n if (index >= 0 && delimiter && isEntityDelimiter(delimiter) && (isBefore || isAfter)) {\n const marker = createSelectionMarker(\n selectionMarker?.format ??\n (paragraph.segments[isAfter ? index + 1 : index - 1] ?? first).format\n );\n\n paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);\n\n selectable = marker;\n }\n }\n\n return selectable;\n }\n\n private reconcileDelimiterSelection(\n node: IndexedEntityDelimiter,\n defaultFormat?: ContentModelSegmentFormat\n ) {\n let marker: ContentModelSelectionMarker | undefined;\n\n const { entity, parent } = node.__roosterjsContentModel;\n const index = parent.blocks.indexOf(entity);\n const delimiter = node.parentElement;\n const wrapper = entity.wrapper;\n const isBefore = wrapper.previousSibling == delimiter;\n const isAfter = wrapper.nextSibling == delimiter;\n\n if (index >= 0 && delimiter && isEntityDelimiter(delimiter) && (isBefore || isAfter)) {\n marker = createSelectionMarker(defaultFormat);\n\n const para = createParagraph(\n true /*isImplicit*/,\n undefined /*blockFormat*/,\n defaultFormat\n );\n\n para.segments.push(marker);\n parent.blocks.splice(isBefore ? index : index + 1, 0, para);\n }\n\n return marker;\n }\n\n private reconcileAddedNode(node: Text, context: ReconcileChildListContext): boolean {\n let segmentItem: SegmentItem | null = null;\n let index = -1;\n let existingSegment: ContentModelSegment;\n const { previousSibling, nextSibling } = node;\n\n if (\n (segmentItem = getIndexedSegmentItem(getLastLeaf(previousSibling))) &&\n (existingSegment = segmentItem.segments[segmentItem.segments.length - 1]) &&\n (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0\n ) {\n // When we can find indexed segment before current one, use it as the insert index\n this.indexNode(segmentItem.paragraph, index + 1, node, existingSegment.format);\n } else if (\n (segmentItem = getIndexedSegmentItem(getFirstLeaf(nextSibling))) &&\n (existingSegment = segmentItem.segments[0]) &&\n (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0\n ) {\n // When we can find indexed segment after current one, use it as the insert index\n this.indexNode(segmentItem.paragraph, index, node, existingSegment.format);\n } else if (context.paragraph && context.segIndex >= 0) {\n // When there is indexed paragraph from removed nodes, we can use it as the insert index\n this.indexNode(context.paragraph, context.segIndex, node, context.format);\n } else if (context.pendingTextNode === undefined) {\n // When we can't find the insert index, set current node as pending node\n // so later we can pick it up when we have enough info when processing removed node\n // Only do this when pendingTextNode is undefined. If it is null it means there was already a pending node before\n // and in that case we should return false since we can't handle two pending text node\n context.pendingTextNode = node;\n } else {\n return false;\n }\n\n return true;\n }\n\n private reconcileRemovedNode(node: Node, context: ReconcileChildListContext): boolean {\n let segmentItem: SegmentItem | null = null;\n let removingSegment: ContentModelSegment;\n\n if (\n context.segIndex < 0 &&\n !context.paragraph && // No previous removed segment or related paragraph found, and\n (segmentItem = getIndexedSegmentItem(node)) && // The removed node is indexed, and\n (removingSegment = segmentItem.segments[0]) // There is at least one related segment\n ) {\n // Now we can remove the indexed segment from the paragraph, and remember it, later we may need to use it\n context.format = removingSegment.format;\n context.paragraph = segmentItem.paragraph;\n context.segIndex = segmentItem.paragraph.segments.indexOf(segmentItem.segments[0]);\n\n if (context.segIndex < 0) {\n // Indexed segment is not under paragraph, something wrong happens, we cannot keep handling\n return false;\n }\n\n for (let i = 0; i < segmentItem.segments.length; i++) {\n const index = segmentItem.paragraph.segments.indexOf(segmentItem.segments[i]);\n\n if (index >= 0) {\n segmentItem.paragraph.segments.splice(index, 1);\n }\n }\n\n if (context.pendingTextNode) {\n // If we have pending text node added but not indexed, do it now\n this.indexNode(\n context.paragraph,\n context.segIndex,\n context.pendingTextNode,\n segmentItem.segments[0].format\n );\n\n // Set to null since we have processed it.\n // Next time we see a pending node we know we have already processed one so it is a situation we cannot handle\n context.pendingTextNode = null;\n }\n\n return true;\n } else {\n return false;\n }\n }\n\n private indexNode(\n paragraph: ContentModelParagraph,\n index: number,\n textNode: Text,\n format?: ContentModelSegmentFormat\n ) {\n const copiedFormat = format ? { ...format } : undefined;\n\n if (copiedFormat) {\n getObjectKeys(copiedFormat).forEach(key => {\n if (EmptySegmentFormat[key] === undefined) {\n delete copiedFormat[key];\n }\n });\n }\n\n const text = createText(textNode.textContent ?? '', copiedFormat);\n\n paragraph.segments.splice(index, 0, text);\n this.onSegment(textNode, paragraph, [text]);\n }\n\n private selectionMarkerToKeepWhenEnteringTextNode(\n oldSelection: CacheSelection,\n newSelection: DOMSelection\n ): ContentModelSelectionMarker | undefined {\n // For CJK keyboard input on mobile, we may have a situation like this:\n // User toggle bold/italic/underline on an empty div, the pending format will be applied on the selection marker\n // then type some text, the selection move to the text node and the selection marker will be recreated during the reconciliation and lose its original formatting\n // In this case, we need to keep the original formatting of the selection marker to match the pending format\n\n if (\n this.keepSelectionMarkerWhenEnteringTextNode &&\n oldSelection.type == 'range' &&\n this.isCollapsed(oldSelection) &&\n newSelection.type == 'range' &&\n isNodeOfType(newSelection.range.commonAncestorContainer, 'TEXT_NODE') &&\n newSelection.range.commonAncestorContainer.parentElement == oldSelection.start.node &&\n isIndexedSegment(newSelection.range.commonAncestorContainer) &&\n newSelection.range.commonAncestorContainer.__roosterjsContentModel.paragraph.segments[0]\n .segmentType == 'SelectionMarker'\n ) {\n return newSelection.range.commonAncestorContainer.__roosterjsContentModel.paragraph\n .segments[0];\n }\n return undefined;\n }\n}\n\nfunction getLastLeaf(node: Node | null): Node | null {\n while (node?.lastChild) {\n node = node.lastChild;\n }\n\n return node;\n}\n\nfunction getFirstLeaf(node: Node | null): Node | null {\n while (node?.firstChild) {\n node = node.firstChild;\n }\n\n return node;\n}\n\nfunction internalClearIndex(container: Node) {\n unindex(container as IndexedSegmentNode);\n\n for (let node = container.firstChild; node; node = node.nextSibling) {\n internalClearIndex(node);\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ContentModelSegmentFormat, DomToModelContext, DomToModelOption, DomToModelOptionForSanitizing } from 'roosterjs-content-model-types';
|
|
1
|
+
import type { ContentModelSegmentFormat, DOMHelper, DomToModelContext, DomToModelOption, DomToModelOptionForSanitizing } from 'roosterjs-content-model-types';
|
|
2
2
|
/**
|
|
3
3
|
* @internal
|
|
4
4
|
*/
|
|
5
|
-
export declare function createDomToModelContextForSanitizing(document: Document, defaultFormat?: ContentModelSegmentFormat, defaultOption?: DomToModelOption, additionalSanitizingOption?: Partial<DomToModelOptionForSanitizing
|
|
5
|
+
export declare function createDomToModelContextForSanitizing(document: Document, defaultFormat?: ContentModelSegmentFormat, defaultOption?: DomToModelOption, additionalSanitizingOption?: Partial<DomToModelOptionForSanitizing>, domHelper?: DOMHelper): DomToModelContext;
|
|
@@ -15,9 +15,9 @@ define(["require", "exports", "tslib", "../../override/containerSizeFormatParser
|
|
|
15
15
|
/**
|
|
16
16
|
* @internal
|
|
17
17
|
*/
|
|
18
|
-
function createDomToModelContextForSanitizing(document, defaultFormat, defaultOption, additionalSanitizingOption) {
|
|
18
|
+
function createDomToModelContextForSanitizing(document, defaultFormat, defaultOption, additionalSanitizingOption, domHelper) {
|
|
19
19
|
var sanitizingOption = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, DefaultSanitizingOption), additionalSanitizingOption);
|
|
20
|
-
return (0, roosterjs_content_model_dom_1.createDomToModelContext)((0, tslib_1.__assign)((0, tslib_1.__assign)({ defaultFormat: defaultFormat }, (0, getRootComputedStyleForContext_1.getRootComputedStyleForContext)(document)), { experimentalFeatures: [] }), defaultOption, {
|
|
20
|
+
return (0, roosterjs_content_model_dom_1.createDomToModelContext)((0, tslib_1.__assign)((0, tslib_1.__assign)({ defaultFormat: defaultFormat }, (0, getRootComputedStyleForContext_1.getRootComputedStyleForContext)(document)), { experimentalFeatures: [], editorViewWidth: domHelper === null || domHelper === void 0 ? void 0 : domHelper.getClientWidth() }), defaultOption, {
|
|
21
21
|
processorOverride: {
|
|
22
22
|
'#text': pasteTextProcessor_1.pasteTextProcessor,
|
|
23
23
|
entity: (0, pasteEntityProcessor_1.createPasteEntityProcessor)(sanitizingOption),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDomToModelContextForSanitizing.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/createModelFromHtml/createDomToModelContextForSanitizing.ts"],"names":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"createDomToModelContextForSanitizing.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/createModelFromHtml/createDomToModelContextForSanitizing.ts"],"names":[],"mappings":";;;;IAiBA,IAAM,uBAAuB,GAAkC;QAC3D,iBAAiB,EAAE,EAAE;QACrB,oBAAoB,EAAE,EAAE;QACxB,uBAAuB,EAAE,EAAE;QAC3B,qBAAqB,EAAE,EAAE;QACzB,wBAAwB,EAAE,EAAE;QAC5B,eAAe,EAAE,EAAE;QACnB,mBAAmB,EAAE,EAAE;QACvB,yBAAyB,EAAE,KAAK;KACnC,CAAC;IAEF;;OAEG;IACH,SAAgB,oCAAoC,CAChD,QAAkB,EAClB,aAAyC,EACzC,aAAgC,EAChC,0BAAmE,EACnE,SAAqB;QAErB,IAAM,gBAAgB,mDACf,uBAAuB,GACvB,0BAA0B,CAChC,CAAC;QAEF,OAAO,IAAA,qDAAuB,gDAEtB,aAAa,eAAA,IACV,IAAA,+DAA8B,EAAC,QAAQ,CAAC,KAC3C,oBAAoB,EAAE,EAAE,EACxB,eAAe,EAAE,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,cAAc,EAAE,KAEhD,aAAa,EACb;YACI,iBAAiB,EAAE;gBACf,OAAO,EAAE,uCAAkB;gBAC3B,MAAM,EAAE,IAAA,iDAA0B,EAAC,gBAAgB,CAAC;gBACpD,GAAG,EAAE,IAAA,mDAA2B,EAAC,gBAAgB,CAAC;aACrD;YACD,oBAAoB,EAAE;gBAClB,OAAO,EAAE,mDAAwB;gBACjC,UAAU,EAAE,yDAA2B;aAC1C;YACD,uBAAuB,EAAE;gBACrB,SAAS,EAAE,CAAC,qDAAyB,CAAC;gBACtC,MAAM,EAAE,CAAC,mDAAsB,CAAC;aACnC;SACJ,EACD,gBAAgB,CACnB,CAAC;IACN,CAAC;IArCD,oFAqCC","sourcesContent":["import { containerSizeFormatParser } from '../../override/containerSizeFormatParser';\nimport { createDomToModelContext } from 'roosterjs-content-model-dom';\nimport { createPasteEntityProcessor } from '../../override/pasteEntityProcessor';\nimport { createPasteGeneralProcessor } from '../../override/pasteGeneralProcessor';\nimport { getRootComputedStyleForContext } from '../../coreApi/createEditorContext/getRootComputedStyleForContext';\nimport { pasteBlockEntityParser } from '../../override/pasteCopyBlockEntityParser';\nimport { pasteDisplayFormatParser } from '../../override/pasteDisplayFormatParser';\nimport { pasteTextProcessor } from '../../override/pasteTextProcessor';\nimport { pasteWhiteSpaceFormatParser } from '../../override/pasteWhiteSpaceFormatParser';\nimport type {\n ContentModelSegmentFormat,\n DOMHelper,\n DomToModelContext,\n DomToModelOption,\n DomToModelOptionForSanitizing,\n} from 'roosterjs-content-model-types';\n\nconst DefaultSanitizingOption: DomToModelOptionForSanitizing = {\n processorOverride: {},\n formatParserOverride: {},\n additionalFormatParsers: {},\n additionalAllowedTags: [],\n additionalDisallowedTags: [],\n styleSanitizers: {},\n attributeSanitizers: {},\n processNonVisibleElements: false,\n};\n\n/**\n * @internal\n */\nexport function createDomToModelContextForSanitizing(\n document: Document,\n defaultFormat?: ContentModelSegmentFormat,\n defaultOption?: DomToModelOption,\n additionalSanitizingOption?: Partial<DomToModelOptionForSanitizing>,\n domHelper?: DOMHelper\n): DomToModelContext {\n const sanitizingOption: DomToModelOptionForSanitizing = {\n ...DefaultSanitizingOption,\n ...additionalSanitizingOption,\n };\n\n return createDomToModelContext(\n {\n defaultFormat,\n ...getRootComputedStyleForContext(document),\n experimentalFeatures: [],\n editorViewWidth: domHelper?.getClientWidth(),\n },\n defaultOption,\n {\n processorOverride: {\n '#text': pasteTextProcessor,\n entity: createPasteEntityProcessor(sanitizingOption),\n '*': createPasteGeneralProcessor(sanitizingOption),\n },\n formatParserOverride: {\n display: pasteDisplayFormatParser,\n whiteSpace: pasteWhiteSpaceFormatParser,\n },\n additionalFormatParsers: {\n container: [containerSizeFormatParser],\n entity: [pasteBlockEntityParser],\n },\n },\n sanitizingOption\n );\n}\n"]}
|
|
@@ -23,7 +23,7 @@ define(["require", "exports", "tslib", "../createModelFromHtml/createDomToModelC
|
|
|
23
23
|
var clonedModel = cloneModelForPaste(clipboardData.modelBeforePaste);
|
|
24
24
|
model.blocks = clonedModel.blocks;
|
|
25
25
|
}
|
|
26
|
-
var domToModelContext = (0, createDomToModelContextForSanitizing_1.createDomToModelContextForSanitizing)(editor.getDocument(), undefined /*defaultFormat*/, editor.getEnvironment().domToModelSettings.customized, domToModelOption);
|
|
26
|
+
var domToModelContext = (0, createDomToModelContextForSanitizing_1.createDomToModelContextForSanitizing)(editor.getDocument(), undefined /*defaultFormat*/, editor.getEnvironment().domToModelSettings.customized, domToModelOption, editor.getDOMHelper());
|
|
27
27
|
domToModelContext.segmentFormat = getSegmentFormatForPaste(model, pasteType);
|
|
28
28
|
var pasteModel = (0, roosterjs_content_model_dom_1.domToContentModel)(fragment, domToModelContext);
|
|
29
29
|
var mergeOption = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mergePasteContent.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/paste/mergePasteContent.ts"],"names":[],"mappings":";;;;IAsBA,IAAM,UAAU,GAAG,YAAY,CAAC;IAEhC,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,kBAAkB,CAAC,KAAmC;QAClE,OAAO,IAAA,wCAAU,EAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAC1C,CAAC;IAFD,gDAEC;IAED;;OAEG;IACH,SAAgB,iBAAiB,CAC7B,MAAe,EACf,WAA6B,EAC7B,YAAqB;QAGjB,IAAA,QAAQ,GAMR,WAAW,SANH,EACR,gBAAgB,GAKhB,WAAW,iBALK,EAChB,eAAe,GAIf,WAAW,gBAJI,EACf,SAAS,GAGT,WAAW,UAHF,EACT,aAAa,GAEb,WAAW,cAFE,EACb,qBAAqB,GACrB,WAAW,sBADU,CACT;QAEhB,MAAM,CAAC,kBAAkB,CACrB,UAAC,KAAK,EAAE,OAAO;YACX,IAAI,CAAC,YAAY,IAAI,aAAa,CAAC,gBAAgB,EAAE;gBACjD,IAAM,WAAW,GAAG,kBAAkB,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;gBACvE,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;aACrC;YAED,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,
|
|
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 cloneModel,\n domToContentModel,\n getSegmentTextFormat,\n getSelectedSegments,\n mergeModel,\n} from 'roosterjs-content-model-dom';\nimport type {\n BeforePasteEvent,\n CloneModelOptions,\n ContentModelDocument,\n ContentModelSegmentFormat,\n IEditor,\n MergeModelOption,\n PasteType,\n ReadonlyContentModelDocument,\n ShallowMutableContentModelDocument,\n} from 'roosterjs-content-model-types';\n\nconst BlackColor = 'rgb(0,0,0)';\n\nconst CloneOption: CloneModelOptions = {\n includeCachedElement: (node, type) => (type == 'cache' ? undefined : node),\n};\n\n/**\n * @internal\n */\nexport function cloneModelForPaste(model: ReadonlyContentModelDocument) {\n return cloneModel(model, CloneOption);\n}\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", "tslib", "roosterjs-content-model-dom"
|
|
1
|
+
define(["require", "exports", "tslib", "../createModelFromHtml/convertInlineCss", "roosterjs-content-model-dom"], function (require, exports, tslib_1, convertInlineCss_1, roosterjs_content_model_dom_1) {
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.retrieveHtmlInfo = void 0;
|
|
@@ -13,7 +13,7 @@ define(["require", "exports", "tslib", "roosterjs-content-model-dom", "../create
|
|
|
13
13
|
globalCssRules: [],
|
|
14
14
|
};
|
|
15
15
|
if (doc) {
|
|
16
|
-
result = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, retrieveHtmlStrings(clipboardData)), { globalCssRules: (0, convertInlineCss_1.retrieveCssRules)(doc), metadata:
|
|
16
|
+
result = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, retrieveHtmlStrings(clipboardData)), { globalCssRules: (0, convertInlineCss_1.retrieveCssRules)(doc), metadata: (0, roosterjs_content_model_dom_1.retrieveDocumentMetadata)(doc), containsBlockElements: checkBlockElements(doc) });
|
|
17
17
|
clipboardData.htmlFirstLevelChildTags = retrieveTopLevelTags(doc);
|
|
18
18
|
}
|
|
19
19
|
return result;
|
|
@@ -35,18 +35,6 @@ define(["require", "exports", "tslib", "roosterjs-content-model-dom", "../create
|
|
|
35
35
|
}
|
|
36
36
|
return topLevelTags;
|
|
37
37
|
}
|
|
38
|
-
function retrieveMetadata(doc) {
|
|
39
|
-
var _a;
|
|
40
|
-
var result = {};
|
|
41
|
-
var attributes = (_a = doc.querySelector('html')) === null || _a === void 0 ? void 0 : _a.attributes;
|
|
42
|
-
(attributes ? (0, roosterjs_content_model_dom_1.toArray)(attributes) : []).forEach(function (attr) {
|
|
43
|
-
result[attr.name] = attr.value;
|
|
44
|
-
});
|
|
45
|
-
(0, roosterjs_content_model_dom_1.toArray)(doc.querySelectorAll('meta')).forEach(function (meta) {
|
|
46
|
-
result[meta.name] = meta.content;
|
|
47
|
-
});
|
|
48
|
-
return result;
|
|
49
|
-
}
|
|
50
38
|
function retrieveHtmlStrings(clipboardData) {
|
|
51
39
|
var _a;
|
|
52
40
|
var rawHtml = (_a = clipboardData.rawHtml) !== null && _a !== void 0 ? _a : '';
|