roosterjs-content-model-dom 9.53.0 → 9.54.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/domToModel/context/createDomToModelContext.d.ts +1 -1
- package/lib/domToModel/context/createDomToModelContext.js.map +1 -1
- package/lib/domToModel/processors/formatContainerProcessor.js +3 -1
- package/lib/domToModel/processors/formatContainerProcessor.js.map +1 -1
- package/lib/modelApi/selection/setSelection.js +32 -6
- package/lib/modelApi/selection/setSelection.js.map +1 -1
- package/lib/modelToDom/handlers/handleBlockGroupChildren.js +9 -2
- package/lib/modelToDom/handlers/handleBlockGroupChildren.js.map +1 -1
- package/lib-amd/domToModel/context/createDomToModelContext.d.ts +1 -1
- package/lib-amd/domToModel/context/createDomToModelContext.js.map +1 -1
- package/lib-amd/domToModel/processors/formatContainerProcessor.js +3 -1
- package/lib-amd/domToModel/processors/formatContainerProcessor.js.map +1 -1
- package/lib-amd/modelApi/selection/setSelection.js +32 -7
- package/lib-amd/modelApi/selection/setSelection.js.map +1 -1
- package/lib-amd/modelToDom/handlers/handleBlockGroupChildren.js +9 -2
- package/lib-amd/modelToDom/handlers/handleBlockGroupChildren.js.map +1 -1
- package/lib-mjs/domToModel/context/createDomToModelContext.d.ts +1 -1
- package/lib-mjs/domToModel/context/createDomToModelContext.js.map +1 -1
- package/lib-mjs/domToModel/processors/formatContainerProcessor.js +3 -1
- package/lib-mjs/domToModel/processors/formatContainerProcessor.js.map +1 -1
- package/lib-mjs/modelApi/selection/setSelection.js +32 -6
- package/lib-mjs/modelApi/selection/setSelection.js.map +1 -1
- package/lib-mjs/modelToDom/handlers/handleBlockGroupChildren.js +9 -2
- package/lib-mjs/modelToDom/handlers/handleBlockGroupChildren.js.map +1 -1
- package/package.json +2 -2
|
@@ -10,7 +10,7 @@ export declare function createDomToModelContext(editorContext?: EditorContext, .
|
|
|
10
10
|
* @param config A full config object to define how to convert DOM tree to Content Model
|
|
11
11
|
* @param editorContext Context of editor
|
|
12
12
|
*/
|
|
13
|
-
export declare function createDomToModelContextWithConfig(config: DomToModelSettings, editorContext?: EditorContext):
|
|
13
|
+
export declare function createDomToModelContextWithConfig(config: DomToModelSettings, editorContext?: EditorContext): DomToModelContext;
|
|
14
14
|
/**
|
|
15
15
|
* Create Dom to Content Model Config object
|
|
16
16
|
* @param options All customizations of content model creation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDomToModelContext.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/context/createDomToModelContext.ts"],"names":[],"mappings":"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","sourcesContent":["import { defaultProcessorMap } from './defaultProcessors';\nimport { getObjectKeys } from '../../domUtils/getObjectKeys';\nimport {\n defaultFormatKeysPerCategory,\n defaultFormatParsers,\n} from '../../formatHandlers/defaultFormatHandlers';\nimport type {\n ContentModelBlockFormat,\n DomToModelContext,\n DomToModelDecoratorContext,\n DomToModelFormatContext,\n DomToModelOption,\n DomToModelSelectionContext,\n DomToModelSettings,\n EditorContext,\n FormatParser,\n FormatParsers,\n FormatParsersPerCategory,\n TextFormatParser,\n} from 'roosterjs-content-model-types';\n\n/**\n * Create context object for DOM to Content Model conversion\n * @param editorContext Context of editor\n * @param options Option array to customize the DOM to Model conversion behavior\n */\nexport function createDomToModelContext(\n editorContext?: EditorContext,\n ...options: (DomToModelOption | undefined)[]\n): DomToModelContext {\n return createDomToModelContextWithConfig(createDomToModelConfig(options), editorContext);\n}\n\n/**\n * Create context object for DOM to Content Model conversion with an existing configure\n * @param config A full config object to define how to convert DOM tree to Content Model\n * @param editorContext Context of editor\n */\nexport function createDomToModelContextWithConfig(\n config: DomToModelSettings,\n editorContext?: EditorContext\n) {\n return Object.assign(\n {},\n editorContext,\n createDomToModelSelectionContext(),\n createDomToModelFormatContext(editorContext?.isRootRtl),\n createDomToModelDecoratorContext(),\n config\n );\n}\n\nfunction createDomToModelSelectionContext(): DomToModelSelectionContext {\n return { isInSelection: false };\n}\n\nfunction createDomToModelFormatContext(isRootRtl?: boolean): DomToModelFormatContext {\n const blockFormat: ContentModelBlockFormat = isRootRtl ? { direction: 'rtl' } : {};\n\n return {\n blockFormat,\n segmentFormat: {},\n\n listFormat: {\n levels: [],\n threadItemCounts: [],\n },\n };\n}\n\nfunction createDomToModelDecoratorContext(): DomToModelDecoratorContext {\n return {\n link: {\n format: {},\n dataset: {},\n },\n code: {\n format: {},\n },\n blockDecorator: {\n format: {},\n tagName: '',\n },\n };\n}\n\n/**\n * Create Dom to Content Model Config object\n * @param options All customizations of content model creation\n */\nexport function createDomToModelConfig(\n options: (DomToModelOption | undefined)[]\n): DomToModelSettings {\n return {\n elementProcessors: Object.assign(\n {},\n defaultProcessorMap,\n ...options.map(x => x?.processorOverride)\n ),\n formatParsers: buildFormatParsers(\n options.map(x => x?.formatParserOverride),\n options.map(x => x?.additionalFormatParsers)\n ),\n defaultElementProcessors: defaultProcessorMap,\n defaultFormatParsers,\n processNonVisibleElements: options.some(x => !!x?.processNonVisibleElements),\n };\n}\n\n/**\n * @internal Export for test only\n * Build format parsers used by DOM to Content Model conversion\n * @param override\n * @param additionalParsersArray\n * @returns\n */\nexport function buildFormatParsers(\n overrides: (Partial<FormatParsers> | undefined)[] = [],\n additionalParsersArray: (Partial<FormatParsersPerCategory> | undefined)[] = []\n): FormatParsersPerCategory {\n const combinedOverrides = Object.assign({}, ...overrides);\n\n const result = getObjectKeys(defaultFormatKeysPerCategory).reduce(\n (result, key) => {\n const value = defaultFormatKeysPerCategory[key]\n .map(\n formatKey =>\n (combinedOverrides[formatKey] === undefined\n ? defaultFormatParsers[formatKey]\n : combinedOverrides[formatKey]) as FormatParser<any>\n )\n .concat(\n ...additionalParsersArray.map(\n parsers => (parsers?.[key] ?? []) as FormatParser<any>[]\n )\n );\n\n result[key] = value;\n\n return result;\n },\n {\n text: [] as TextFormatParser[],\n } as FormatParsersPerCategory\n );\n\n additionalParsersArray.forEach(parsers => {\n if (parsers?.text) {\n result.text = result.text.concat(parsers.text);\n }\n });\n\n return result;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createDomToModelContext.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/context/createDomToModelContext.ts"],"names":[],"mappings":"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","sourcesContent":["import { defaultProcessorMap } from './defaultProcessors';\nimport { getObjectKeys } from '../../domUtils/getObjectKeys';\nimport {\n defaultFormatKeysPerCategory,\n defaultFormatParsers,\n} from '../../formatHandlers/defaultFormatHandlers';\nimport type {\n ContentModelBlockFormat,\n DomToModelContext,\n DomToModelDecoratorContext,\n DomToModelFormatContext,\n DomToModelOption,\n DomToModelSelectionContext,\n DomToModelSettings,\n EditorContext,\n FormatParser,\n FormatParsers,\n FormatParsersPerCategory,\n TextFormatParser,\n} from 'roosterjs-content-model-types';\n\n/**\n * Create context object for DOM to Content Model conversion\n * @param editorContext Context of editor\n * @param options Option array to customize the DOM to Model conversion behavior\n */\nexport function createDomToModelContext(\n editorContext?: EditorContext,\n ...options: (DomToModelOption | undefined)[]\n): DomToModelContext {\n return createDomToModelContextWithConfig(createDomToModelConfig(options), editorContext);\n}\n\n/**\n * Create context object for DOM to Content Model conversion with an existing configure\n * @param config A full config object to define how to convert DOM tree to Content Model\n * @param editorContext Context of editor\n */\nexport function createDomToModelContextWithConfig(\n config: DomToModelSettings,\n editorContext?: EditorContext\n): DomToModelContext {\n return Object.assign(\n {},\n editorContext,\n createDomToModelSelectionContext(),\n createDomToModelFormatContext(editorContext?.isRootRtl),\n createDomToModelDecoratorContext(),\n config\n );\n}\n\nfunction createDomToModelSelectionContext(): DomToModelSelectionContext {\n return { isInSelection: false };\n}\n\nfunction createDomToModelFormatContext(isRootRtl?: boolean): DomToModelFormatContext {\n const blockFormat: ContentModelBlockFormat = isRootRtl ? { direction: 'rtl' } : {};\n\n return {\n blockFormat,\n segmentFormat: {},\n\n listFormat: {\n levels: [],\n threadItemCounts: [],\n },\n };\n}\n\nfunction createDomToModelDecoratorContext(): DomToModelDecoratorContext {\n return {\n link: {\n format: {},\n dataset: {},\n },\n code: {\n format: {},\n },\n blockDecorator: {\n format: {},\n tagName: '',\n },\n };\n}\n\n/**\n * Create Dom to Content Model Config object\n * @param options All customizations of content model creation\n */\nexport function createDomToModelConfig(\n options: (DomToModelOption | undefined)[]\n): DomToModelSettings {\n return {\n elementProcessors: Object.assign(\n {},\n defaultProcessorMap,\n ...options.map(x => x?.processorOverride)\n ),\n formatParsers: buildFormatParsers(\n options.map(x => x?.formatParserOverride),\n options.map(x => x?.additionalFormatParsers)\n ),\n defaultElementProcessors: defaultProcessorMap,\n defaultFormatParsers,\n processNonVisibleElements: options.some(x => !!x?.processNonVisibleElements),\n };\n}\n\n/**\n * @internal Export for test only\n * Build format parsers used by DOM to Content Model conversion\n * @param override\n * @param additionalParsersArray\n * @returns\n */\nexport function buildFormatParsers(\n overrides: (Partial<FormatParsers> | undefined)[] = [],\n additionalParsersArray: (Partial<FormatParsersPerCategory> | undefined)[] = []\n): FormatParsersPerCategory {\n const combinedOverrides = Object.assign({}, ...overrides);\n\n const result = getObjectKeys(defaultFormatKeysPerCategory).reduce(\n (result, key) => {\n const value = defaultFormatKeysPerCategory[key]\n .map(\n formatKey =>\n (combinedOverrides[formatKey] === undefined\n ? defaultFormatParsers[formatKey]\n : combinedOverrides[formatKey]) as FormatParser<any>\n )\n .concat(\n ...additionalParsersArray.map(\n parsers => (parsers?.[key] ?? []) as FormatParser<any>[]\n )\n );\n\n result[key] = value;\n\n return result;\n },\n {\n text: [] as TextFormatParser[],\n } as FormatParsersPerCategory\n );\n\n additionalParsersArray.forEach(parsers => {\n if (parsers?.text) {\n result.text = result.text.concat(parsers.text);\n }\n });\n\n return result;\n}\n"]}
|
|
@@ -55,7 +55,9 @@ var formatContainerProcessorInternal = function (group, element, context, forceF
|
|
|
55
55
|
if (element.style.fontSize && parseInt(element.style.fontSize) == 0) {
|
|
56
56
|
formatContainer.zeroFontSize = true;
|
|
57
57
|
}
|
|
58
|
-
if (
|
|
58
|
+
if (!context.skipFormatContainerFallbackCheck &&
|
|
59
|
+
shouldFallbackToParagraph(formatContainer) &&
|
|
60
|
+
!forceFormatContainer) {
|
|
59
61
|
// For DIV container that only has one paragraph child, container style can be merged into paragraph
|
|
60
62
|
// and no need to have this container
|
|
61
63
|
var paragraph = formatContainer.blocks[0];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatContainerProcessor.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/processors/formatContainerProcessor.ts"],"names":[],"mappings":";;;;AAAA,2DAA0D;AAC1D,uFAAsF;AACtF,2EAA0E;AAC1E,4DAA2D;AAC3D,oDAAmD;AACnD,wFAAuF;AACvF,oDAAmD;AAYnD;;GAEG;AACU,QAAA,aAAa,GAA6C;IACnE,YAAY;IACZ,aAAa;IACb,aAAa;IACb,cAAc;CACjB,CAAC;AAEF;;;;;;;GAOG;AACI,IAAM,wBAAwB,GAAkC,UACnE,KAAK,EACL,OAAO,EACP,OAAO;IAEP,gCAAgC,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,0BAA0B,CAAC,CAAC;AAChG,CAAC,CAAC;AANW,QAAA,wBAAwB,4BAMnC;AAEF;;GAEG;AACI,IAAM,6BAA6B,GAAkC,UACxE,KAAK,EACL,OAAO,EACP,OAAO;IAEP,gCAAgC,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,0BAA0B,CAAC,CAAC;AAC/F,CAAC,CAAC;AANW,QAAA,6BAA6B,iCAMxC;AAEF,IAAM,gCAAgC,GAAG,UACrC,KAA6B,EAC7B,OAAoB,EACpB,OAA0B,EAC1B,oBAA6B;IAE7B,IAAA,yBAAW,EAAC,OAAO,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,cAAc,EAAE,EAAE;QACjF,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAChF,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,cAAc,EAAE,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAE3F,IAAM,MAAM,6BACL,OAAO,CAAC,WAAW,CACzB,CAAC;QAEF,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAEvE,IAAM,OAAO,GACT,IAAA,iCAAe,EAAC,OAAO,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QACxF,IAAM,eAAe,GAAG,IAAA,6CAAqB,EAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAE/D,0FAA0F;QAC1F,kEAAkE;QAClE,mFAAmF;QACnF,qBAAa,CAAC,OAAO,CAAC,UAAA,KAAK;YACvB,OAAO,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,iBAAiB,CAAC,KAAK,CAAC,eAAe,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAEnE,IAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,IAAI,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YACjE,eAAe,CAAC,YAAY,GAAG,IAAI,CAAC;SACvC;QAED,
|
|
1
|
+
{"version":3,"file":"formatContainerProcessor.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/processors/formatContainerProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["import { addBlock } from '../../modelApi/common/addBlock';\nimport { createFormatContainer } from '../../modelApi/creators/createFormatContainer';\nimport { createParagraph } from '../../modelApi/creators/createParagraph';\nimport { getDefaultStyle } from '../utils/getDefaultStyle';\nimport { parseFormat } from '../utils/parseFormat';\nimport { setParagraphNotImplicit } from '../../modelApi/block/setParagraphNotImplicit';\nimport { stackFormat } from '../utils/stackFormat';\nimport type {\n ContentModelBlockGroup,\n ContentModelFormatContainer,\n ContentModelFormatContainerFormat,\n ContentModelParagraph,\n DomToModelContext,\n ElementProcessor,\n MarginFormat,\n PaddingFormat,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const ContextStyles: (keyof (MarginFormat & PaddingFormat))[] = [\n 'marginLeft',\n 'marginRight',\n 'paddingLeft',\n 'paddingRight',\n];\n\n/**\n * Content Model Element Processor for format container elements (e.g., blockquote, div)\n * Processes elements that create FormatContainer blocks in the content model.\n * This processor can be used in processorOverride to customize how specific elements are processed.\n * @param group The parent block group\n * @param element The DOM element to process\n * @param context DOM to Content Model context\n */\nexport const formatContainerProcessor: ElementProcessor<HTMLElement> = (\n group,\n element,\n context\n) => {\n formatContainerProcessorInternal(group, element, context, false /* forceFormatContainer */);\n};\n\n/**\n * @internal\n */\nexport const forceFormatContainerProcessor: ElementProcessor<HTMLElement> = (\n group,\n element,\n context\n) => {\n formatContainerProcessorInternal(group, element, context, true /* forceFormatContainer */);\n};\n\nconst formatContainerProcessorInternal = (\n group: ContentModelBlockGroup,\n element: HTMLElement,\n context: DomToModelContext,\n forceFormatContainer: boolean\n) => {\n stackFormat(context, { segment: 'shallowCloneForBlock', paragraph: 'shallowClone' }, () => {\n parseFormat(element, context.formatParsers.block, context.blockFormat, context);\n parseFormat(element, context.formatParsers.segmentOnBlock, context.segmentFormat, context);\n\n const format: ContentModelFormatContainerFormat = {\n ...context.blockFormat,\n };\n\n parseFormat(element, context.formatParsers.container, format, context);\n\n const tagName =\n getDefaultStyle(element).display == 'block' ? element.tagName.toLowerCase() : 'div';\n const formatContainer = createFormatContainer(tagName, format);\n\n // It is possible to inherit margin left/right styles from parent DIV or other containers,\n // since we are going into a deeper level of format container now,\n // the container will render these styles so no need to keep them in context format\n ContextStyles.forEach(style => {\n delete context.blockFormat[style];\n });\n\n context.elementProcessors.child(formatContainer, element, context);\n\n if (element.style.fontSize && parseInt(element.style.fontSize) == 0) {\n formatContainer.zeroFontSize = true;\n }\n\n if (\n !context.skipFormatContainerFallbackCheck &&\n shouldFallbackToParagraph(formatContainer) &&\n !forceFormatContainer\n ) {\n // For DIV container that only has one paragraph child, container style can be merged into paragraph\n // and no need to have this container\n const paragraph = formatContainer.blocks[0] as ContentModelParagraph;\n\n if (formatContainer.zeroFontSize) {\n paragraph.segmentFormat = Object.assign({}, paragraph.segmentFormat, {\n fontSize: '0',\n });\n }\n\n Object.assign(paragraph.format, formatContainer.format);\n setParagraphNotImplicit(paragraph);\n addBlock(group, paragraph);\n } else {\n addBlock(group, formatContainer);\n }\n });\n\n addBlock(group, createParagraph(true /*isImplicit*/, context.blockFormat));\n};\n\nfunction shouldFallbackToParagraph(formatContainer: ContentModelFormatContainer) {\n const firstChild = formatContainer.blocks[0];\n\n return (\n formatContainer.tagName == 'div' &&\n formatContainer.blocks.length == 1 &&\n firstChild.blockType == 'Paragraph' &&\n firstChild.isImplicit\n );\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.setSelection = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
4
5
|
var isGeneralSegment_1 = require("../typeCheck/isGeneralSegment");
|
|
5
6
|
var mutate_1 = require("../common/mutate");
|
|
6
7
|
/**
|
|
@@ -38,6 +39,7 @@ function setSelectionToBlockGroup(group, isInSelection, start, end) {
|
|
|
38
39
|
});
|
|
39
40
|
}
|
|
40
41
|
function setSelectionToBlock(block, isInSelection, start, end) {
|
|
42
|
+
var _a;
|
|
41
43
|
switch (block.blockType) {
|
|
42
44
|
case 'BlockGroup':
|
|
43
45
|
return setSelectionToBlockGroup(block, isInSelection, start, end);
|
|
@@ -58,16 +60,31 @@ function setSelectionToBlock(block, isInSelection, start, end) {
|
|
|
58
60
|
return isInSelection;
|
|
59
61
|
});
|
|
60
62
|
case 'Paragraph':
|
|
61
|
-
var
|
|
63
|
+
var state_1 = {
|
|
64
|
+
segmentsToDelete: [],
|
|
65
|
+
boundaryMarkers: [],
|
|
66
|
+
hasSelectedNonMarker: false,
|
|
67
|
+
};
|
|
62
68
|
block.segments.forEach(function (segment, i) {
|
|
63
69
|
isInSelection = handleSelection(isInSelection, segment, start, end, function (isInSelection) {
|
|
64
|
-
return setSelectionToSegment(block, segment, isInSelection,
|
|
70
|
+
return setSelectionToSegment(block, segment, isInSelection, state_1, start, end, i);
|
|
65
71
|
});
|
|
66
72
|
});
|
|
67
|
-
if (
|
|
73
|
+
if (state_1.hasSelectedNonMarker) {
|
|
74
|
+
// This paragraph contains a real (non-marker) selected segment, so any leading/trailing
|
|
75
|
+
// selection marker of the range is redundant within this paragraph and can be removed.
|
|
76
|
+
// We only do this within the same paragraph: a boundary marker at a paragraph edge must be
|
|
77
|
+
// kept to distinguish "selection starts at the beginning of this line" from "selection
|
|
78
|
+
// starts at the end of the previous line".
|
|
79
|
+
(_a = state_1.segmentsToDelete).push.apply(_a, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(state_1.boundaryMarkers), false));
|
|
80
|
+
}
|
|
81
|
+
if (state_1.segmentsToDelete.length > 0) {
|
|
68
82
|
var mutablePara = (0, mutate_1.mutateBlock)(block);
|
|
69
83
|
var index = void 0;
|
|
70
|
-
|
|
84
|
+
// Sort ascending so the pop()-based splice below always removes the highest index first,
|
|
85
|
+
// keeping the remaining indices valid (boundary markers may sit before queued deletions).
|
|
86
|
+
state_1.segmentsToDelete.sort(function (a, b) { return a - b; });
|
|
87
|
+
while ((index = state_1.segmentsToDelete.pop()) !== undefined) {
|
|
71
88
|
if (index >= 0) {
|
|
72
89
|
mutablePara.segments.splice(index, 1);
|
|
73
90
|
}
|
|
@@ -116,14 +133,23 @@ function findCell(table, cell) {
|
|
|
116
133
|
: -1;
|
|
117
134
|
return { row: row, col: col };
|
|
118
135
|
}
|
|
119
|
-
function setSelectionToSegment(paragraph, segment, isInSelection,
|
|
136
|
+
function setSelectionToSegment(paragraph, segment, isInSelection, state, start, end, i) {
|
|
137
|
+
if (segment.segmentType != 'SelectionMarker' && isInSelection) {
|
|
138
|
+
state.hasSelectedNonMarker = true;
|
|
139
|
+
}
|
|
120
140
|
switch (segment.segmentType) {
|
|
121
141
|
case 'SelectionMarker':
|
|
122
142
|
if (!isInSelection || (segment != start && segment != end)) {
|
|
123
143
|
// Delete the selection marker when
|
|
124
144
|
// 1. It is not in selection any more. Or
|
|
125
145
|
// 2. It is in middle of selection, so no need to have it
|
|
126
|
-
segmentsToDelete.push(i);
|
|
146
|
+
state.segmentsToDelete.push(i);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
// It is a leading/trailing selection marker of a range selection. Keep it for now, but
|
|
150
|
+
// remember it so it can be removed later if this same paragraph also contains a real
|
|
151
|
+
// (non-marker) selected segment, in which case the marker is redundant.
|
|
152
|
+
state.boundaryMarkers.push(i);
|
|
127
153
|
}
|
|
128
154
|
return isInSelection;
|
|
129
155
|
case 'General':
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setSelection.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelApi/selection/setSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { isGeneralSegment } from '../typeCheck/isGeneralSegment';\nimport { mutateBlock, mutateSegment } from '../common/mutate';\nimport type {\n MutableType,\n ReadonlyContentModelBlock,\n ReadonlyContentModelBlockGroup,\n ReadonlyContentModelParagraph,\n ReadonlyContentModelSegment,\n ReadonlyContentModelTable,\n ReadonlySelectable,\n ShallowMutableSelectable,\n TableCellCoordinate,\n} from 'roosterjs-content-model-types';\n\n/**\n * Set selection into Content Model. If the Content Model already has selection, existing selection will be overwritten by the new one.\n * @param group The root level group of Content Model\n * @param start The start selected element. If not passed, existing selection of content model will be cleared\n * @param end The end selected element. If not passed, only the start element will be selected. If passed, all elements between start and end elements will be selected\n */\nexport function setSelection(\n group: ReadonlyContentModelBlockGroup,\n start?: ReadonlySelectable,\n end?: ReadonlySelectable\n) {\n setSelectionToBlockGroup(group, false /*isInSelection*/, start || null, end || null);\n}\n\nfunction setSelectionToBlockGroup(\n group: ReadonlyContentModelBlockGroup,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n): boolean {\n return handleSelection(isInSelection, group, start, end, isInSelection => {\n if (isGeneralSegment(group) && needToSetSelection(group, isInSelection)) {\n setIsSelected(mutateBlock(group), isInSelection);\n }\n\n const blocksToDelete: number[] = [];\n\n group.blocks.forEach((block, i) => {\n isInSelection = setSelectionToBlock(block, isInSelection, start, end);\n\n if (block.blockType == 'Paragraph' && block.segments.length == 0 && block.isImplicit) {\n blocksToDelete.push(i);\n }\n });\n\n let index: number | undefined;\n\n if (blocksToDelete.length > 0) {\n const mutableGroup = mutateBlock(group);\n\n while ((index = blocksToDelete.pop()) !== undefined) {\n if (index >= 0) {\n mutableGroup.blocks.splice(index, 1);\n }\n }\n }\n\n return isInSelection;\n });\n}\n\nfunction setSelectionToBlock(\n block: ReadonlyContentModelBlock,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n) {\n switch (block.blockType) {\n case 'BlockGroup':\n return setSelectionToBlockGroup(block, isInSelection, start, end);\n\n case 'Table':\n return setSelectionToTable(block, isInSelection, start, end);\n\n case 'Divider':\n case 'Entity':\n return handleSelection(isInSelection, block, start, end, isInSelection => {\n if (needToSetSelection(block, isInSelection)) {\n const mutableBlock = mutateBlock(block);\n\n if (isInSelection) {\n mutableBlock.isSelected = true;\n } else {\n delete mutableBlock.isSelected;\n }\n }\n\n return isInSelection;\n });\n\n case 'Paragraph':\n const segmentsToDelete: number[] = [];\n\n block.segments.forEach((segment, i) => {\n isInSelection = handleSelection(\n isInSelection,\n segment,\n start,\n end,\n isInSelection => {\n return setSelectionToSegment(\n block,\n segment,\n isInSelection,\n segmentsToDelete,\n start,\n end,\n i\n );\n }\n );\n });\n\n if (segmentsToDelete.length > 0) {\n const mutablePara = mutateBlock(block);\n\n let index: number | undefined;\n\n while ((index = segmentsToDelete.pop()) !== undefined) {\n if (index >= 0) {\n mutablePara.segments.splice(index, 1);\n }\n }\n }\n\n return isInSelection;\n\n default:\n return isInSelection;\n }\n}\n\nfunction setSelectionToTable(\n table: ReadonlyContentModelTable,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n): boolean {\n const first = findCell(table, start);\n const last = end ? findCell(table, end) : first;\n\n if (!isInSelection) {\n for (let row = 0; row < table.rows.length; row++) {\n const currentRow = table.rows[row];\n for (let col = 0; col < currentRow.cells.length; col++) {\n const currentCell = table.rows[row].cells[col];\n const isSelected =\n row >= first.row && row <= last.row && col >= first.col && col <= last.col;\n\n if (needToSetSelection(currentCell, isSelected)) {\n setIsSelected(mutateBlock(currentCell), isSelected);\n }\n\n if (!isSelected) {\n setSelectionToBlockGroup(currentCell, false /*isInSelection*/, start, end);\n }\n }\n }\n } else {\n table.rows.forEach(row =>\n row.cells.forEach(cell => {\n const wasInSelection = isInSelection;\n\n isInSelection = setSelectionToBlockGroup(cell, isInSelection, start, end);\n\n if (wasInSelection && isInSelection) {\n mutateBlock(cell).isSelected = true;\n }\n })\n );\n }\n\n return isInSelection;\n}\n\nfunction findCell(\n table: ReadonlyContentModelTable,\n cell: ReadonlySelectable | null\n): TableCellCoordinate {\n let col = -1;\n const row = cell\n ? table.rows.findIndex(\n row => (col = (row.cells as ReadonlyArray<ReadonlySelectable>).indexOf(cell)) >= 0\n )\n : -1;\n\n return { row, col };\n}\n\nfunction setSelectionToSegment(\n paragraph: ReadonlyContentModelParagraph,\n segment: ReadonlyContentModelSegment,\n isInSelection: boolean,\n segmentsToDelete: number[],\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null,\n i: number\n) {\n switch (segment.segmentType) {\n case 'SelectionMarker':\n if (!isInSelection || (segment != start && segment != end)) {\n // Delete the selection marker when\n // 1. It is not in selection any more. Or\n // 2. It is in middle of selection, so no need to have it\n segmentsToDelete.push(i);\n }\n return isInSelection;\n\n case 'General':\n internalSetSelectionToSegment(paragraph, segment, isInSelection);\n\n return segment != start && segment != end\n ? setSelectionToBlockGroup(segment, isInSelection, start, end)\n : isInSelection;\n\n case 'Image':\n const isSelectedAsImageSelection = start == segment && (!end || end == segment);\n\n internalSetSelectionToSegment(\n paragraph,\n segment,\n isInSelection,\n !segment.isSelectedAsImageSelection != !isSelectedAsImageSelection\n ? image => (image.isSelectedAsImageSelection = isSelectedAsImageSelection)\n : undefined\n );\n\n return isInSelection;\n default:\n internalSetSelectionToSegment(paragraph, segment, isInSelection);\n return isInSelection;\n }\n}\n\nfunction internalSetSelectionToSegment<T extends ReadonlyContentModelSegment>(\n paragraph: ReadonlyContentModelParagraph,\n segment: T,\n isInSelection: boolean,\n additionAction?: (segment: MutableType<T>) => void\n) {\n if (additionAction || needToSetSelection(segment, isInSelection)) {\n mutateSegment(paragraph, segment, mutableSegment => {\n setIsSelected(mutableSegment, isInSelection);\n additionAction?.(mutableSegment);\n });\n }\n}\n\nfunction needToSetSelection(selectable: ReadonlySelectable, isSelected: boolean) {\n return !selectable.isSelected != !isSelected;\n}\n\nfunction setIsSelected(selectable: ShallowMutableSelectable, value: boolean) {\n if (value) {\n selectable.isSelected = true;\n } else {\n delete selectable.isSelected;\n }\n\n return value;\n}\n\nfunction handleSelection(\n isInSelection: boolean,\n model: ReadonlyContentModelBlockGroup | ReadonlyContentModelBlock | ReadonlyContentModelSegment,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null,\n callback: (isInSelection: boolean) => boolean\n) {\n isInSelection = isInSelection || model == start;\n isInSelection = callback(isInSelection);\n return isInSelection && !!end && model != end;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"setSelection.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelApi/selection/setSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { isGeneralSegment } from '../typeCheck/isGeneralSegment';\nimport { mutateBlock, mutateSegment } from '../common/mutate';\nimport type {\n MutableType,\n ReadonlyContentModelBlock,\n ReadonlyContentModelBlockGroup,\n ReadonlyContentModelParagraph,\n ReadonlyContentModelSegment,\n ReadonlyContentModelTable,\n ReadonlySelectable,\n ShallowMutableSelectable,\n TableCellCoordinate,\n} from 'roosterjs-content-model-types';\n\n/**\n * Set selection into Content Model. If the Content Model already has selection, existing selection will be overwritten by the new one.\n * @param group The root level group of Content Model\n * @param start The start selected element. If not passed, existing selection of content model will be cleared\n * @param end The end selected element. If not passed, only the start element will be selected. If passed, all elements between start and end elements will be selected\n */\nexport function setSelection(\n group: ReadonlyContentModelBlockGroup,\n start?: ReadonlySelectable,\n end?: ReadonlySelectable\n) {\n setSelectionToBlockGroup(group, false /*isInSelection*/, start || null, end || null);\n}\n\nfunction setSelectionToBlockGroup(\n group: ReadonlyContentModelBlockGroup,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n): boolean {\n return handleSelection(isInSelection, group, start, end, isInSelection => {\n if (isGeneralSegment(group) && needToSetSelection(group, isInSelection)) {\n setIsSelected(mutateBlock(group), isInSelection);\n }\n\n const blocksToDelete: number[] = [];\n\n group.blocks.forEach((block, i) => {\n isInSelection = setSelectionToBlock(block, isInSelection, start, end);\n\n if (block.blockType == 'Paragraph' && block.segments.length == 0 && block.isImplicit) {\n blocksToDelete.push(i);\n }\n });\n\n let index: number | undefined;\n\n if (blocksToDelete.length > 0) {\n const mutableGroup = mutateBlock(group);\n\n while ((index = blocksToDelete.pop()) !== undefined) {\n if (index >= 0) {\n mutableGroup.blocks.splice(index, 1);\n }\n }\n }\n\n return isInSelection;\n });\n}\n\nfunction setSelectionToBlock(\n block: ReadonlyContentModelBlock,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n) {\n switch (block.blockType) {\n case 'BlockGroup':\n return setSelectionToBlockGroup(block, isInSelection, start, end);\n\n case 'Table':\n return setSelectionToTable(block, isInSelection, start, end);\n\n case 'Divider':\n case 'Entity':\n return handleSelection(isInSelection, block, start, end, isInSelection => {\n if (needToSetSelection(block, isInSelection)) {\n const mutableBlock = mutateBlock(block);\n\n if (isInSelection) {\n mutableBlock.isSelected = true;\n } else {\n delete mutableBlock.isSelected;\n }\n }\n\n return isInSelection;\n });\n\n case 'Paragraph':\n const state: ParagraphSelectionState = {\n segmentsToDelete: [],\n boundaryMarkers: [],\n hasSelectedNonMarker: false,\n };\n\n block.segments.forEach((segment, i) => {\n isInSelection = handleSelection(\n isInSelection,\n segment,\n start,\n end,\n isInSelection => {\n return setSelectionToSegment(\n block,\n segment,\n isInSelection,\n state,\n start,\n end,\n i\n );\n }\n );\n });\n\n if (state.hasSelectedNonMarker) {\n // This paragraph contains a real (non-marker) selected segment, so any leading/trailing\n // selection marker of the range is redundant within this paragraph and can be removed.\n // We only do this within the same paragraph: a boundary marker at a paragraph edge must be\n // kept to distinguish \"selection starts at the beginning of this line\" from \"selection\n // starts at the end of the previous line\".\n state.segmentsToDelete.push(...state.boundaryMarkers);\n }\n\n if (state.segmentsToDelete.length > 0) {\n const mutablePara = mutateBlock(block);\n\n let index: number | undefined;\n\n // Sort ascending so the pop()-based splice below always removes the highest index first,\n // keeping the remaining indices valid (boundary markers may sit before queued deletions).\n state.segmentsToDelete.sort((a, b) => a - b);\n\n while ((index = state.segmentsToDelete.pop()) !== undefined) {\n if (index >= 0) {\n mutablePara.segments.splice(index, 1);\n }\n }\n }\n\n return isInSelection;\n\n default:\n return isInSelection;\n }\n}\n\nfunction setSelectionToTable(\n table: ReadonlyContentModelTable,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n): boolean {\n const first = findCell(table, start);\n const last = end ? findCell(table, end) : first;\n\n if (!isInSelection) {\n for (let row = 0; row < table.rows.length; row++) {\n const currentRow = table.rows[row];\n for (let col = 0; col < currentRow.cells.length; col++) {\n const currentCell = table.rows[row].cells[col];\n const isSelected =\n row >= first.row && row <= last.row && col >= first.col && col <= last.col;\n\n if (needToSetSelection(currentCell, isSelected)) {\n setIsSelected(mutateBlock(currentCell), isSelected);\n }\n\n if (!isSelected) {\n setSelectionToBlockGroup(currentCell, false /*isInSelection*/, start, end);\n }\n }\n }\n } else {\n table.rows.forEach(row =>\n row.cells.forEach(cell => {\n const wasInSelection = isInSelection;\n\n isInSelection = setSelectionToBlockGroup(cell, isInSelection, start, end);\n\n if (wasInSelection && isInSelection) {\n mutateBlock(cell).isSelected = true;\n }\n })\n );\n }\n\n return isInSelection;\n}\n\nfunction findCell(\n table: ReadonlyContentModelTable,\n cell: ReadonlySelectable | null\n): TableCellCoordinate {\n let col = -1;\n const row = cell\n ? table.rows.findIndex(\n row => (col = (row.cells as ReadonlyArray<ReadonlySelectable>).indexOf(cell)) >= 0\n )\n : -1;\n\n return { row, col };\n}\n\ninterface ParagraphSelectionState {\n // Indexes of segments to delete after the paragraph is fully processed\n segmentsToDelete: number[];\n\n // Indexes of leading/trailing selection markers of the range that are kept for now, but will be\n // removed if this paragraph also contains a real (non-marker) selected segment\n boundaryMarkers: number[];\n\n // Whether this paragraph contains at least one selected segment that is not a selection marker\n hasSelectedNonMarker: boolean;\n}\n\nfunction setSelectionToSegment(\n paragraph: ReadonlyContentModelParagraph,\n segment: ReadonlyContentModelSegment,\n isInSelection: boolean,\n state: ParagraphSelectionState,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null,\n i: number\n) {\n if (segment.segmentType != 'SelectionMarker' && isInSelection) {\n state.hasSelectedNonMarker = true;\n }\n\n switch (segment.segmentType) {\n case 'SelectionMarker':\n if (!isInSelection || (segment != start && segment != end)) {\n // Delete the selection marker when\n // 1. It is not in selection any more. Or\n // 2. It is in middle of selection, so no need to have it\n state.segmentsToDelete.push(i);\n } else {\n // It is a leading/trailing selection marker of a range selection. Keep it for now, but\n // remember it so it can be removed later if this same paragraph also contains a real\n // (non-marker) selected segment, in which case the marker is redundant.\n state.boundaryMarkers.push(i);\n }\n return isInSelection;\n\n case 'General':\n internalSetSelectionToSegment(paragraph, segment, isInSelection);\n\n return segment != start && segment != end\n ? setSelectionToBlockGroup(segment, isInSelection, start, end)\n : isInSelection;\n\n case 'Image':\n const isSelectedAsImageSelection = start == segment && (!end || end == segment);\n\n internalSetSelectionToSegment(\n paragraph,\n segment,\n isInSelection,\n !segment.isSelectedAsImageSelection != !isSelectedAsImageSelection\n ? image => (image.isSelectedAsImageSelection = isSelectedAsImageSelection)\n : undefined\n );\n\n return isInSelection;\n default:\n internalSetSelectionToSegment(paragraph, segment, isInSelection);\n return isInSelection;\n }\n}\n\nfunction internalSetSelectionToSegment<T extends ReadonlyContentModelSegment>(\n paragraph: ReadonlyContentModelParagraph,\n segment: T,\n isInSelection: boolean,\n additionAction?: (segment: MutableType<T>) => void\n) {\n if (additionAction || needToSetSelection(segment, isInSelection)) {\n mutateSegment(paragraph, segment, mutableSegment => {\n setIsSelected(mutableSegment, isInSelection);\n additionAction?.(mutableSegment);\n });\n }\n}\n\nfunction needToSetSelection(selectable: ReadonlySelectable, isSelected: boolean) {\n return !selectable.isSelected != !isSelected;\n}\n\nfunction setIsSelected(selectable: ShallowMutableSelectable, value: boolean) {\n if (value) {\n selectable.isSelected = true;\n } else {\n delete selectable.isSelected;\n }\n\n return value;\n}\n\nfunction handleSelection(\n isInSelection: boolean,\n model: ReadonlyContentModelBlockGroup | ReadonlyContentModelBlock | ReadonlyContentModelSegment,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null,\n callback: (isInSelection: boolean) => boolean\n) {\n isInSelection = isInSelection || model == start;\n isInSelection = callback(isInSelection);\n return isInSelection && !!end && model != end;\n}\n"]}
|
|
@@ -29,7 +29,7 @@ var handleBlockGroupChildren = function (doc, parent, group, context) {
|
|
|
29
29
|
(_a = context.domIndexer) === null || _a === void 0 ? void 0 : _a.onBlockEntity(childBlock, group);
|
|
30
30
|
}
|
|
31
31
|
});
|
|
32
|
-
cleanUpNodeStack(listFormat.nodeStack, context);
|
|
32
|
+
cleanUpNodeStack(listFormat.nodeStack, context, parent);
|
|
33
33
|
// Remove all rest node if any since they don't appear in content model
|
|
34
34
|
(0, cleanUpRestNodes_1.cleanUpRestNodes)(refNode, context.rewriteFromModel);
|
|
35
35
|
}
|
|
@@ -38,7 +38,7 @@ var handleBlockGroupChildren = function (doc, parent, group, context) {
|
|
|
38
38
|
}
|
|
39
39
|
};
|
|
40
40
|
exports.handleBlockGroupChildren = handleBlockGroupChildren;
|
|
41
|
-
function cleanUpNodeStack(nodeStack, context) {
|
|
41
|
+
function cleanUpNodeStack(nodeStack, context, leavingParent) {
|
|
42
42
|
var _a, _b;
|
|
43
43
|
if (nodeStack.length > 0) {
|
|
44
44
|
// Clear list stack, only run to nodeStack[1] because nodeStack[0] is the parent node
|
|
@@ -46,6 +46,13 @@ function cleanUpNodeStack(nodeStack, context) {
|
|
|
46
46
|
var node = (_b = (_a = nodeStack.pop()) === null || _a === void 0 ? void 0 : _a.refNode) !== null && _b !== void 0 ? _b : null;
|
|
47
47
|
(0, cleanUpRestNodes_1.cleanUpRestNodes)(node, context.rewriteFromModel);
|
|
48
48
|
}
|
|
49
|
+
if (leavingParent && nodeStack[0].node == leavingParent) {
|
|
50
|
+
// When leaving a parent node that is the same with the root of node stack
|
|
51
|
+
// It means the whole list node stack is being invalidated, so we clear it
|
|
52
|
+
while (nodeStack.length > 0) {
|
|
53
|
+
nodeStack.pop();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
49
56
|
}
|
|
50
57
|
}
|
|
51
58
|
//# sourceMappingURL=handleBlockGroupChildren.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handleBlockGroupChildren.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/handlers/handleBlockGroupChildren.ts"],"names":[],"mappings":";;;AAAA,8DAA6D;AAQ7D;;GAEG;AACI,IAAM,wBAAwB,GAAgD,UACjF,GAAa,EACb,MAAY,EACZ,KAA6B,EAC7B,OAA0B;IAElB,IAAA,UAAU,GAAK,OAAO,WAAZ,CAAa;IAC/B,IAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC;IACvC,IAAI,OAAO,GAAgB,MAAM,CAAC,UAAU,CAAC;IAE7C,IAAI;QACA,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,UAAC,UAAU,EAAE,KAAK;;YACnC,2CAA2C;YAC3C,wEAAwE;YACxE,sFAAsF;YACtF,+FAA+F;YAC/F,IACI,KAAK,IAAI,CAAC;gBACV,UAAU,CAAC,SAAS,IAAI,YAAY;gBACpC,UAAU,CAAC,cAAc,IAAI,UAAU,EACzC;gBACE,gBAAgB,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;gBAEhD,IAAI,UAAU,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;oBACjC,UAAU,CAAC,SAAS,GAAG,EAAE,CAAC;iBAC7B;aACJ;YAED,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAEjF,IAAI,UAAU,CAAC,SAAS,IAAI,QAAQ,EAAE;gBAClC,MAAA,OAAO,CAAC,UAAU,0CAAE,aAAa,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;aACxD;QACL,CAAC,CAAC,CAAC;QAEH,gBAAgB,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"handleBlockGroupChildren.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/handlers/handleBlockGroupChildren.ts"],"names":[],"mappings":";;;AAAA,8DAA6D;AAQ7D;;GAEG;AACI,IAAM,wBAAwB,GAAgD,UACjF,GAAa,EACb,MAAY,EACZ,KAA6B,EAC7B,OAA0B;IAElB,IAAA,UAAU,GAAK,OAAO,WAAZ,CAAa;IAC/B,IAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC;IACvC,IAAI,OAAO,GAAgB,MAAM,CAAC,UAAU,CAAC;IAE7C,IAAI;QACA,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,UAAC,UAAU,EAAE,KAAK;;YACnC,2CAA2C;YAC3C,wEAAwE;YACxE,sFAAsF;YACtF,+FAA+F;YAC/F,IACI,KAAK,IAAI,CAAC;gBACV,UAAU,CAAC,SAAS,IAAI,YAAY;gBACpC,UAAU,CAAC,cAAc,IAAI,UAAU,EACzC;gBACE,gBAAgB,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;gBAEhD,IAAI,UAAU,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;oBACjC,UAAU,CAAC,SAAS,GAAG,EAAE,CAAC;iBAC7B;aACJ;YAED,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAEjF,IAAI,UAAU,CAAC,SAAS,IAAI,QAAQ,EAAE;gBAClC,MAAA,OAAO,CAAC,UAAU,0CAAE,aAAa,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;aACxD;QACL,CAAC,CAAC,CAAC;QAEH,gBAAgB,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAExD,uEAAuE;QACvE,IAAA,mCAAgB,EAAC,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;KACvD;YAAS;QACN,UAAU,CAAC,SAAS,GAAG,SAAS,CAAC;KACpC;AACL,CAAC,CAAC;AA1CW,QAAA,wBAAwB,4BA0CnC;AAEF,SAAS,gBAAgB,CACrB,SAAoC,EACpC,OAA0B,EAC1B,aAAoB;;IAEpB,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;QACtB,qFAAqF;QACrF,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC3C,IAAM,IAAI,GAAG,MAAA,MAAA,SAAS,CAAC,GAAG,EAAE,0CAAE,OAAO,mCAAI,IAAI,CAAC;YAE9C,IAAA,mCAAgB,EAAC,IAAI,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;SACpD;QAED,IAAI,aAAa,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,aAAa,EAAE;YACrD,0EAA0E;YAC1E,0EAA0E;YAC1E,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;gBACzB,SAAS,CAAC,GAAG,EAAE,CAAC;aACnB;SACJ;KACJ;AACL,CAAC","sourcesContent":["import { cleanUpRestNodes } from '../utils/cleanUpRestNodes';\nimport type {\n ContentModelBlockGroup,\n ContentModelHandler,\n ModelToDomContext,\n ModelToDomListStackItem,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const handleBlockGroupChildren: ContentModelHandler<ContentModelBlockGroup> = (\n doc: Document,\n parent: Node,\n group: ContentModelBlockGroup,\n context: ModelToDomContext\n) => {\n const { listFormat } = context;\n const nodeStack = listFormat.nodeStack;\n let refNode: Node | null = parent.firstChild;\n\n try {\n group.blocks.forEach((childBlock, index) => {\n // When process list, we need a node stack.\n // When there are two continuous lists, they should share the same stack\n // so that list items with same type/threadId can be merged into the same list element\n // In other cases, clear the stack so that two separate lists won't share the same list element\n if (\n index == 0 ||\n childBlock.blockType != 'BlockGroup' ||\n childBlock.blockGroupType != 'ListItem'\n ) {\n cleanUpNodeStack(listFormat.nodeStack, context);\n\n if (listFormat.nodeStack.length > 0) {\n listFormat.nodeStack = [];\n }\n }\n\n refNode = context.modelHandlers.block(doc, parent, childBlock, context, refNode);\n\n if (childBlock.blockType == 'Entity') {\n context.domIndexer?.onBlockEntity(childBlock, group);\n }\n });\n\n cleanUpNodeStack(listFormat.nodeStack, context, parent);\n\n // Remove all rest node if any since they don't appear in content model\n cleanUpRestNodes(refNode, context.rewriteFromModel);\n } finally {\n listFormat.nodeStack = nodeStack;\n }\n};\n\nfunction cleanUpNodeStack(\n nodeStack: ModelToDomListStackItem[],\n context: ModelToDomContext,\n leavingParent?: Node\n) {\n if (nodeStack.length > 0) {\n // Clear list stack, only run to nodeStack[1] because nodeStack[0] is the parent node\n for (let i = nodeStack.length - 1; i > 0; i--) {\n const node = nodeStack.pop()?.refNode ?? null;\n\n cleanUpRestNodes(node, context.rewriteFromModel);\n }\n\n if (leavingParent && nodeStack[0].node == leavingParent) {\n // When leaving a parent node that is the same with the root of node stack\n // It means the whole list node stack is being invalidated, so we clear it\n while (nodeStack.length > 0) {\n nodeStack.pop();\n }\n }\n }\n}\n"]}
|
|
@@ -10,7 +10,7 @@ export declare function createDomToModelContext(editorContext?: EditorContext, .
|
|
|
10
10
|
* @param config A full config object to define how to convert DOM tree to Content Model
|
|
11
11
|
* @param editorContext Context of editor
|
|
12
12
|
*/
|
|
13
|
-
export declare function createDomToModelContextWithConfig(config: DomToModelSettings, editorContext?: EditorContext):
|
|
13
|
+
export declare function createDomToModelContextWithConfig(config: DomToModelSettings, editorContext?: EditorContext): DomToModelContext;
|
|
14
14
|
/**
|
|
15
15
|
* Create Dom to Content Model Config object
|
|
16
16
|
* @param options All customizations of content model creation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDomToModelContext.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/context/createDomToModelContext.ts"],"names":[],"mappings":"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","sourcesContent":["import { defaultProcessorMap } from './defaultProcessors';\nimport { getObjectKeys } from '../../domUtils/getObjectKeys';\nimport {\n defaultFormatKeysPerCategory,\n defaultFormatParsers,\n} from '../../formatHandlers/defaultFormatHandlers';\nimport type {\n ContentModelBlockFormat,\n DomToModelContext,\n DomToModelDecoratorContext,\n DomToModelFormatContext,\n DomToModelOption,\n DomToModelSelectionContext,\n DomToModelSettings,\n EditorContext,\n FormatParser,\n FormatParsers,\n FormatParsersPerCategory,\n TextFormatParser,\n} from 'roosterjs-content-model-types';\n\n/**\n * Create context object for DOM to Content Model conversion\n * @param editorContext Context of editor\n * @param options Option array to customize the DOM to Model conversion behavior\n */\nexport function createDomToModelContext(\n editorContext?: EditorContext,\n ...options: (DomToModelOption | undefined)[]\n): DomToModelContext {\n return createDomToModelContextWithConfig(createDomToModelConfig(options), editorContext);\n}\n\n/**\n * Create context object for DOM to Content Model conversion with an existing configure\n * @param config A full config object to define how to convert DOM tree to Content Model\n * @param editorContext Context of editor\n */\nexport function createDomToModelContextWithConfig(\n config: DomToModelSettings,\n editorContext?: EditorContext\n) {\n return Object.assign(\n {},\n editorContext,\n createDomToModelSelectionContext(),\n createDomToModelFormatContext(editorContext?.isRootRtl),\n createDomToModelDecoratorContext(),\n config\n );\n}\n\nfunction createDomToModelSelectionContext(): DomToModelSelectionContext {\n return { isInSelection: false };\n}\n\nfunction createDomToModelFormatContext(isRootRtl?: boolean): DomToModelFormatContext {\n const blockFormat: ContentModelBlockFormat = isRootRtl ? { direction: 'rtl' } : {};\n\n return {\n blockFormat,\n segmentFormat: {},\n\n listFormat: {\n levels: [],\n threadItemCounts: [],\n },\n };\n}\n\nfunction createDomToModelDecoratorContext(): DomToModelDecoratorContext {\n return {\n link: {\n format: {},\n dataset: {},\n },\n code: {\n format: {},\n },\n blockDecorator: {\n format: {},\n tagName: '',\n },\n };\n}\n\n/**\n * Create Dom to Content Model Config object\n * @param options All customizations of content model creation\n */\nexport function createDomToModelConfig(\n options: (DomToModelOption | undefined)[]\n): DomToModelSettings {\n return {\n elementProcessors: Object.assign(\n {},\n defaultProcessorMap,\n ...options.map(x => x?.processorOverride)\n ),\n formatParsers: buildFormatParsers(\n options.map(x => x?.formatParserOverride),\n options.map(x => x?.additionalFormatParsers)\n ),\n defaultElementProcessors: defaultProcessorMap,\n defaultFormatParsers,\n processNonVisibleElements: options.some(x => !!x?.processNonVisibleElements),\n };\n}\n\n/**\n * @internal Export for test only\n * Build format parsers used by DOM to Content Model conversion\n * @param override\n * @param additionalParsersArray\n * @returns\n */\nexport function buildFormatParsers(\n overrides: (Partial<FormatParsers> | undefined)[] = [],\n additionalParsersArray: (Partial<FormatParsersPerCategory> | undefined)[] = []\n): FormatParsersPerCategory {\n const combinedOverrides = Object.assign({}, ...overrides);\n\n const result = getObjectKeys(defaultFormatKeysPerCategory).reduce(\n (result, key) => {\n const value = defaultFormatKeysPerCategory[key]\n .map(\n formatKey =>\n (combinedOverrides[formatKey] === undefined\n ? defaultFormatParsers[formatKey]\n : combinedOverrides[formatKey]) as FormatParser<any>\n )\n .concat(\n ...additionalParsersArray.map(\n parsers => (parsers?.[key] ?? []) as FormatParser<any>[]\n )\n );\n\n result[key] = value;\n\n return result;\n },\n {\n text: [] as TextFormatParser[],\n } as FormatParsersPerCategory\n );\n\n additionalParsersArray.forEach(parsers => {\n if (parsers?.text) {\n result.text = result.text.concat(parsers.text);\n }\n });\n\n return result;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createDomToModelContext.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/context/createDomToModelContext.ts"],"names":[],"mappings":"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","sourcesContent":["import { defaultProcessorMap } from './defaultProcessors';\nimport { getObjectKeys } from '../../domUtils/getObjectKeys';\nimport {\n defaultFormatKeysPerCategory,\n defaultFormatParsers,\n} from '../../formatHandlers/defaultFormatHandlers';\nimport type {\n ContentModelBlockFormat,\n DomToModelContext,\n DomToModelDecoratorContext,\n DomToModelFormatContext,\n DomToModelOption,\n DomToModelSelectionContext,\n DomToModelSettings,\n EditorContext,\n FormatParser,\n FormatParsers,\n FormatParsersPerCategory,\n TextFormatParser,\n} from 'roosterjs-content-model-types';\n\n/**\n * Create context object for DOM to Content Model conversion\n * @param editorContext Context of editor\n * @param options Option array to customize the DOM to Model conversion behavior\n */\nexport function createDomToModelContext(\n editorContext?: EditorContext,\n ...options: (DomToModelOption | undefined)[]\n): DomToModelContext {\n return createDomToModelContextWithConfig(createDomToModelConfig(options), editorContext);\n}\n\n/**\n * Create context object for DOM to Content Model conversion with an existing configure\n * @param config A full config object to define how to convert DOM tree to Content Model\n * @param editorContext Context of editor\n */\nexport function createDomToModelContextWithConfig(\n config: DomToModelSettings,\n editorContext?: EditorContext\n): DomToModelContext {\n return Object.assign(\n {},\n editorContext,\n createDomToModelSelectionContext(),\n createDomToModelFormatContext(editorContext?.isRootRtl),\n createDomToModelDecoratorContext(),\n config\n );\n}\n\nfunction createDomToModelSelectionContext(): DomToModelSelectionContext {\n return { isInSelection: false };\n}\n\nfunction createDomToModelFormatContext(isRootRtl?: boolean): DomToModelFormatContext {\n const blockFormat: ContentModelBlockFormat = isRootRtl ? { direction: 'rtl' } : {};\n\n return {\n blockFormat,\n segmentFormat: {},\n\n listFormat: {\n levels: [],\n threadItemCounts: [],\n },\n };\n}\n\nfunction createDomToModelDecoratorContext(): DomToModelDecoratorContext {\n return {\n link: {\n format: {},\n dataset: {},\n },\n code: {\n format: {},\n },\n blockDecorator: {\n format: {},\n tagName: '',\n },\n };\n}\n\n/**\n * Create Dom to Content Model Config object\n * @param options All customizations of content model creation\n */\nexport function createDomToModelConfig(\n options: (DomToModelOption | undefined)[]\n): DomToModelSettings {\n return {\n elementProcessors: Object.assign(\n {},\n defaultProcessorMap,\n ...options.map(x => x?.processorOverride)\n ),\n formatParsers: buildFormatParsers(\n options.map(x => x?.formatParserOverride),\n options.map(x => x?.additionalFormatParsers)\n ),\n defaultElementProcessors: defaultProcessorMap,\n defaultFormatParsers,\n processNonVisibleElements: options.some(x => !!x?.processNonVisibleElements),\n };\n}\n\n/**\n * @internal Export for test only\n * Build format parsers used by DOM to Content Model conversion\n * @param override\n * @param additionalParsersArray\n * @returns\n */\nexport function buildFormatParsers(\n overrides: (Partial<FormatParsers> | undefined)[] = [],\n additionalParsersArray: (Partial<FormatParsersPerCategory> | undefined)[] = []\n): FormatParsersPerCategory {\n const combinedOverrides = Object.assign({}, ...overrides);\n\n const result = getObjectKeys(defaultFormatKeysPerCategory).reduce(\n (result, key) => {\n const value = defaultFormatKeysPerCategory[key]\n .map(\n formatKey =>\n (combinedOverrides[formatKey] === undefined\n ? defaultFormatParsers[formatKey]\n : combinedOverrides[formatKey]) as FormatParser<any>\n )\n .concat(\n ...additionalParsersArray.map(\n parsers => (parsers?.[key] ?? []) as FormatParser<any>[]\n )\n );\n\n result[key] = value;\n\n return result;\n },\n {\n text: [] as TextFormatParser[],\n } as FormatParsersPerCategory\n );\n\n additionalParsersArray.forEach(parsers => {\n if (parsers?.text) {\n result.text = result.text.concat(parsers.text);\n }\n });\n\n return result;\n}\n"]}
|
|
@@ -48,7 +48,9 @@ define(["require", "exports", "tslib", "../../modelApi/common/addBlock", "../../
|
|
|
48
48
|
if (element.style.fontSize && parseInt(element.style.fontSize) == 0) {
|
|
49
49
|
formatContainer.zeroFontSize = true;
|
|
50
50
|
}
|
|
51
|
-
if (
|
|
51
|
+
if (!context.skipFormatContainerFallbackCheck &&
|
|
52
|
+
shouldFallbackToParagraph(formatContainer) &&
|
|
53
|
+
!forceFormatContainer) {
|
|
52
54
|
// For DIV container that only has one paragraph child, container style can be merged into paragraph
|
|
53
55
|
// and no need to have this container
|
|
54
56
|
var paragraph = formatContainer.blocks[0];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatContainerProcessor.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/processors/formatContainerProcessor.ts"],"names":[],"mappings":";;;;IAkBA;;OAEG;IACU,QAAA,aAAa,GAA6C;QACnE,YAAY;QACZ,aAAa;QACb,aAAa;QACb,cAAc;KACjB,CAAC;IAEF;;;;;;;OAOG;IACI,IAAM,wBAAwB,GAAkC,UACnE,KAAK,EACL,OAAO,EACP,OAAO;QAEP,gCAAgC,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAChG,CAAC,CAAC;IANW,QAAA,wBAAwB,4BAMnC;IAEF;;OAEG;IACI,IAAM,6BAA6B,GAAkC,UACxE,KAAK,EACL,OAAO,EACP,OAAO;QAEP,gCAAgC,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAC/F,CAAC,CAAC;IANW,QAAA,6BAA6B,iCAMxC;IAEF,IAAM,gCAAgC,GAAG,UACrC,KAA6B,EAC7B,OAAoB,EACpB,OAA0B,EAC1B,oBAA6B;QAE7B,IAAA,yBAAW,EAAC,OAAO,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,cAAc,EAAE,EAAE;YACjF,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YAChF,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,cAAc,EAAE,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;YAE3F,IAAM,MAAM,6BACL,OAAO,CAAC,WAAW,CACzB,CAAC;YAEF,IAAA,yBAAW,EAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;YAEvE,IAAM,OAAO,GACT,IAAA,iCAAe,EAAC,OAAO,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;YACxF,IAAM,eAAe,GAAG,IAAA,6CAAqB,EAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAE/D,0FAA0F;YAC1F,kEAAkE;YAClE,mFAAmF;YACnF,qBAAa,CAAC,OAAO,CAAC,UAAA,KAAK;gBACvB,OAAO,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACtC,CAAC,CAAC,CAAC;YAEH,OAAO,CAAC,iBAAiB,CAAC,KAAK,CAAC,eAAe,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAEnE,IAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,IAAI,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;gBACjE,eAAe,CAAC,YAAY,GAAG,IAAI,CAAC;aACvC;YAED,
|
|
1
|
+
{"version":3,"file":"formatContainerProcessor.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/processors/formatContainerProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["import { addBlock } from '../../modelApi/common/addBlock';\nimport { createFormatContainer } from '../../modelApi/creators/createFormatContainer';\nimport { createParagraph } from '../../modelApi/creators/createParagraph';\nimport { getDefaultStyle } from '../utils/getDefaultStyle';\nimport { parseFormat } from '../utils/parseFormat';\nimport { setParagraphNotImplicit } from '../../modelApi/block/setParagraphNotImplicit';\nimport { stackFormat } from '../utils/stackFormat';\nimport type {\n ContentModelBlockGroup,\n ContentModelFormatContainer,\n ContentModelFormatContainerFormat,\n ContentModelParagraph,\n DomToModelContext,\n ElementProcessor,\n MarginFormat,\n PaddingFormat,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const ContextStyles: (keyof (MarginFormat & PaddingFormat))[] = [\n 'marginLeft',\n 'marginRight',\n 'paddingLeft',\n 'paddingRight',\n];\n\n/**\n * Content Model Element Processor for format container elements (e.g., blockquote, div)\n * Processes elements that create FormatContainer blocks in the content model.\n * This processor can be used in processorOverride to customize how specific elements are processed.\n * @param group The parent block group\n * @param element The DOM element to process\n * @param context DOM to Content Model context\n */\nexport const formatContainerProcessor: ElementProcessor<HTMLElement> = (\n group,\n element,\n context\n) => {\n formatContainerProcessorInternal(group, element, context, false /* forceFormatContainer */);\n};\n\n/**\n * @internal\n */\nexport const forceFormatContainerProcessor: ElementProcessor<HTMLElement> = (\n group,\n element,\n context\n) => {\n formatContainerProcessorInternal(group, element, context, true /* forceFormatContainer */);\n};\n\nconst formatContainerProcessorInternal = (\n group: ContentModelBlockGroup,\n element: HTMLElement,\n context: DomToModelContext,\n forceFormatContainer: boolean\n) => {\n stackFormat(context, { segment: 'shallowCloneForBlock', paragraph: 'shallowClone' }, () => {\n parseFormat(element, context.formatParsers.block, context.blockFormat, context);\n parseFormat(element, context.formatParsers.segmentOnBlock, context.segmentFormat, context);\n\n const format: ContentModelFormatContainerFormat = {\n ...context.blockFormat,\n };\n\n parseFormat(element, context.formatParsers.container, format, context);\n\n const tagName =\n getDefaultStyle(element).display == 'block' ? element.tagName.toLowerCase() : 'div';\n const formatContainer = createFormatContainer(tagName, format);\n\n // It is possible to inherit margin left/right styles from parent DIV or other containers,\n // since we are going into a deeper level of format container now,\n // the container will render these styles so no need to keep them in context format\n ContextStyles.forEach(style => {\n delete context.blockFormat[style];\n });\n\n context.elementProcessors.child(formatContainer, element, context);\n\n if (element.style.fontSize && parseInt(element.style.fontSize) == 0) {\n formatContainer.zeroFontSize = true;\n }\n\n if (\n !context.skipFormatContainerFallbackCheck &&\n shouldFallbackToParagraph(formatContainer) &&\n !forceFormatContainer\n ) {\n // For DIV container that only has one paragraph child, container style can be merged into paragraph\n // and no need to have this container\n const paragraph = formatContainer.blocks[0] as ContentModelParagraph;\n\n if (formatContainer.zeroFontSize) {\n paragraph.segmentFormat = Object.assign({}, paragraph.segmentFormat, {\n fontSize: '0',\n });\n }\n\n Object.assign(paragraph.format, formatContainer.format);\n setParagraphNotImplicit(paragraph);\n addBlock(group, paragraph);\n } else {\n addBlock(group, formatContainer);\n }\n });\n\n addBlock(group, createParagraph(true /*isImplicit*/, context.blockFormat));\n};\n\nfunction shouldFallbackToParagraph(formatContainer: ContentModelFormatContainer) {\n const firstChild = formatContainer.blocks[0];\n\n return (\n formatContainer.tagName == 'div' &&\n formatContainer.blocks.length == 1 &&\n firstChild.blockType == 'Paragraph' &&\n firstChild.isImplicit\n );\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
define(["require", "exports", "../typeCheck/isGeneralSegment", "../common/mutate"], function (require, exports, isGeneralSegment_1, mutate_1) {
|
|
1
|
+
define(["require", "exports", "tslib", "../typeCheck/isGeneralSegment", "../common/mutate"], function (require, exports, tslib_1, isGeneralSegment_1, mutate_1) {
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.setSelection = void 0;
|
|
@@ -37,6 +37,7 @@ define(["require", "exports", "../typeCheck/isGeneralSegment", "../common/mutate
|
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
39
|
function setSelectionToBlock(block, isInSelection, start, end) {
|
|
40
|
+
var _a;
|
|
40
41
|
switch (block.blockType) {
|
|
41
42
|
case 'BlockGroup':
|
|
42
43
|
return setSelectionToBlockGroup(block, isInSelection, start, end);
|
|
@@ -57,16 +58,31 @@ define(["require", "exports", "../typeCheck/isGeneralSegment", "../common/mutate
|
|
|
57
58
|
return isInSelection;
|
|
58
59
|
});
|
|
59
60
|
case 'Paragraph':
|
|
60
|
-
var
|
|
61
|
+
var state_1 = {
|
|
62
|
+
segmentsToDelete: [],
|
|
63
|
+
boundaryMarkers: [],
|
|
64
|
+
hasSelectedNonMarker: false,
|
|
65
|
+
};
|
|
61
66
|
block.segments.forEach(function (segment, i) {
|
|
62
67
|
isInSelection = handleSelection(isInSelection, segment, start, end, function (isInSelection) {
|
|
63
|
-
return setSelectionToSegment(block, segment, isInSelection,
|
|
68
|
+
return setSelectionToSegment(block, segment, isInSelection, state_1, start, end, i);
|
|
64
69
|
});
|
|
65
70
|
});
|
|
66
|
-
if (
|
|
71
|
+
if (state_1.hasSelectedNonMarker) {
|
|
72
|
+
// This paragraph contains a real (non-marker) selected segment, so any leading/trailing
|
|
73
|
+
// selection marker of the range is redundant within this paragraph and can be removed.
|
|
74
|
+
// We only do this within the same paragraph: a boundary marker at a paragraph edge must be
|
|
75
|
+
// kept to distinguish "selection starts at the beginning of this line" from "selection
|
|
76
|
+
// starts at the end of the previous line".
|
|
77
|
+
(_a = state_1.segmentsToDelete).push.apply(_a, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(state_1.boundaryMarkers), false));
|
|
78
|
+
}
|
|
79
|
+
if (state_1.segmentsToDelete.length > 0) {
|
|
67
80
|
var mutablePara = (0, mutate_1.mutateBlock)(block);
|
|
68
81
|
var index = void 0;
|
|
69
|
-
|
|
82
|
+
// Sort ascending so the pop()-based splice below always removes the highest index first,
|
|
83
|
+
// keeping the remaining indices valid (boundary markers may sit before queued deletions).
|
|
84
|
+
state_1.segmentsToDelete.sort(function (a, b) { return a - b; });
|
|
85
|
+
while ((index = state_1.segmentsToDelete.pop()) !== undefined) {
|
|
70
86
|
if (index >= 0) {
|
|
71
87
|
mutablePara.segments.splice(index, 1);
|
|
72
88
|
}
|
|
@@ -115,14 +131,23 @@ define(["require", "exports", "../typeCheck/isGeneralSegment", "../common/mutate
|
|
|
115
131
|
: -1;
|
|
116
132
|
return { row: row, col: col };
|
|
117
133
|
}
|
|
118
|
-
function setSelectionToSegment(paragraph, segment, isInSelection,
|
|
134
|
+
function setSelectionToSegment(paragraph, segment, isInSelection, state, start, end, i) {
|
|
135
|
+
if (segment.segmentType != 'SelectionMarker' && isInSelection) {
|
|
136
|
+
state.hasSelectedNonMarker = true;
|
|
137
|
+
}
|
|
119
138
|
switch (segment.segmentType) {
|
|
120
139
|
case 'SelectionMarker':
|
|
121
140
|
if (!isInSelection || (segment != start && segment != end)) {
|
|
122
141
|
// Delete the selection marker when
|
|
123
142
|
// 1. It is not in selection any more. Or
|
|
124
143
|
// 2. It is in middle of selection, so no need to have it
|
|
125
|
-
segmentsToDelete.push(i);
|
|
144
|
+
state.segmentsToDelete.push(i);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
// It is a leading/trailing selection marker of a range selection. Keep it for now, but
|
|
148
|
+
// remember it so it can be removed later if this same paragraph also contains a real
|
|
149
|
+
// (non-marker) selected segment, in which case the marker is redundant.
|
|
150
|
+
state.boundaryMarkers.push(i);
|
|
126
151
|
}
|
|
127
152
|
return isInSelection;
|
|
128
153
|
case 'General':
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setSelection.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelApi/selection/setSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { isGeneralSegment } from '../typeCheck/isGeneralSegment';\nimport { mutateBlock, mutateSegment } from '../common/mutate';\nimport type {\n MutableType,\n ReadonlyContentModelBlock,\n ReadonlyContentModelBlockGroup,\n ReadonlyContentModelParagraph,\n ReadonlyContentModelSegment,\n ReadonlyContentModelTable,\n ReadonlySelectable,\n ShallowMutableSelectable,\n TableCellCoordinate,\n} from 'roosterjs-content-model-types';\n\n/**\n * Set selection into Content Model. If the Content Model already has selection, existing selection will be overwritten by the new one.\n * @param group The root level group of Content Model\n * @param start The start selected element. If not passed, existing selection of content model will be cleared\n * @param end The end selected element. If not passed, only the start element will be selected. If passed, all elements between start and end elements will be selected\n */\nexport function setSelection(\n group: ReadonlyContentModelBlockGroup,\n start?: ReadonlySelectable,\n end?: ReadonlySelectable\n) {\n setSelectionToBlockGroup(group, false /*isInSelection*/, start || null, end || null);\n}\n\nfunction setSelectionToBlockGroup(\n group: ReadonlyContentModelBlockGroup,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n): boolean {\n return handleSelection(isInSelection, group, start, end, isInSelection => {\n if (isGeneralSegment(group) && needToSetSelection(group, isInSelection)) {\n setIsSelected(mutateBlock(group), isInSelection);\n }\n\n const blocksToDelete: number[] = [];\n\n group.blocks.forEach((block, i) => {\n isInSelection = setSelectionToBlock(block, isInSelection, start, end);\n\n if (block.blockType == 'Paragraph' && block.segments.length == 0 && block.isImplicit) {\n blocksToDelete.push(i);\n }\n });\n\n let index: number | undefined;\n\n if (blocksToDelete.length > 0) {\n const mutableGroup = mutateBlock(group);\n\n while ((index = blocksToDelete.pop()) !== undefined) {\n if (index >= 0) {\n mutableGroup.blocks.splice(index, 1);\n }\n }\n }\n\n return isInSelection;\n });\n}\n\nfunction setSelectionToBlock(\n block: ReadonlyContentModelBlock,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n) {\n switch (block.blockType) {\n case 'BlockGroup':\n return setSelectionToBlockGroup(block, isInSelection, start, end);\n\n case 'Table':\n return setSelectionToTable(block, isInSelection, start, end);\n\n case 'Divider':\n case 'Entity':\n return handleSelection(isInSelection, block, start, end, isInSelection => {\n if (needToSetSelection(block, isInSelection)) {\n const mutableBlock = mutateBlock(block);\n\n if (isInSelection) {\n mutableBlock.isSelected = true;\n } else {\n delete mutableBlock.isSelected;\n }\n }\n\n return isInSelection;\n });\n\n case 'Paragraph':\n const segmentsToDelete: number[] = [];\n\n block.segments.forEach((segment, i) => {\n isInSelection = handleSelection(\n isInSelection,\n segment,\n start,\n end,\n isInSelection => {\n return setSelectionToSegment(\n block,\n segment,\n isInSelection,\n segmentsToDelete,\n start,\n end,\n i\n );\n }\n );\n });\n\n if (segmentsToDelete.length > 0) {\n const mutablePara = mutateBlock(block);\n\n let index: number | undefined;\n\n while ((index = segmentsToDelete.pop()) !== undefined) {\n if (index >= 0) {\n mutablePara.segments.splice(index, 1);\n }\n }\n }\n\n return isInSelection;\n\n default:\n return isInSelection;\n }\n}\n\nfunction setSelectionToTable(\n table: ReadonlyContentModelTable,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n): boolean {\n const first = findCell(table, start);\n const last = end ? findCell(table, end) : first;\n\n if (!isInSelection) {\n for (let row = 0; row < table.rows.length; row++) {\n const currentRow = table.rows[row];\n for (let col = 0; col < currentRow.cells.length; col++) {\n const currentCell = table.rows[row].cells[col];\n const isSelected =\n row >= first.row && row <= last.row && col >= first.col && col <= last.col;\n\n if (needToSetSelection(currentCell, isSelected)) {\n setIsSelected(mutateBlock(currentCell), isSelected);\n }\n\n if (!isSelected) {\n setSelectionToBlockGroup(currentCell, false /*isInSelection*/, start, end);\n }\n }\n }\n } else {\n table.rows.forEach(row =>\n row.cells.forEach(cell => {\n const wasInSelection = isInSelection;\n\n isInSelection = setSelectionToBlockGroup(cell, isInSelection, start, end);\n\n if (wasInSelection && isInSelection) {\n mutateBlock(cell).isSelected = true;\n }\n })\n );\n }\n\n return isInSelection;\n}\n\nfunction findCell(\n table: ReadonlyContentModelTable,\n cell: ReadonlySelectable | null\n): TableCellCoordinate {\n let col = -1;\n const row = cell\n ? table.rows.findIndex(\n row => (col = (row.cells as ReadonlyArray<ReadonlySelectable>).indexOf(cell)) >= 0\n )\n : -1;\n\n return { row, col };\n}\n\nfunction setSelectionToSegment(\n paragraph: ReadonlyContentModelParagraph,\n segment: ReadonlyContentModelSegment,\n isInSelection: boolean,\n segmentsToDelete: number[],\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null,\n i: number\n) {\n switch (segment.segmentType) {\n case 'SelectionMarker':\n if (!isInSelection || (segment != start && segment != end)) {\n // Delete the selection marker when\n // 1. It is not in selection any more. Or\n // 2. It is in middle of selection, so no need to have it\n segmentsToDelete.push(i);\n }\n return isInSelection;\n\n case 'General':\n internalSetSelectionToSegment(paragraph, segment, isInSelection);\n\n return segment != start && segment != end\n ? setSelectionToBlockGroup(segment, isInSelection, start, end)\n : isInSelection;\n\n case 'Image':\n const isSelectedAsImageSelection = start == segment && (!end || end == segment);\n\n internalSetSelectionToSegment(\n paragraph,\n segment,\n isInSelection,\n !segment.isSelectedAsImageSelection != !isSelectedAsImageSelection\n ? image => (image.isSelectedAsImageSelection = isSelectedAsImageSelection)\n : undefined\n );\n\n return isInSelection;\n default:\n internalSetSelectionToSegment(paragraph, segment, isInSelection);\n return isInSelection;\n }\n}\n\nfunction internalSetSelectionToSegment<T extends ReadonlyContentModelSegment>(\n paragraph: ReadonlyContentModelParagraph,\n segment: T,\n isInSelection: boolean,\n additionAction?: (segment: MutableType<T>) => void\n) {\n if (additionAction || needToSetSelection(segment, isInSelection)) {\n mutateSegment(paragraph, segment, mutableSegment => {\n setIsSelected(mutableSegment, isInSelection);\n additionAction?.(mutableSegment);\n });\n }\n}\n\nfunction needToSetSelection(selectable: ReadonlySelectable, isSelected: boolean) {\n return !selectable.isSelected != !isSelected;\n}\n\nfunction setIsSelected(selectable: ShallowMutableSelectable, value: boolean) {\n if (value) {\n selectable.isSelected = true;\n } else {\n delete selectable.isSelected;\n }\n\n return value;\n}\n\nfunction handleSelection(\n isInSelection: boolean,\n model: ReadonlyContentModelBlockGroup | ReadonlyContentModelBlock | ReadonlyContentModelSegment,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null,\n callback: (isInSelection: boolean) => boolean\n) {\n isInSelection = isInSelection || model == start;\n isInSelection = callback(isInSelection);\n return isInSelection && !!end && model != end;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"setSelection.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelApi/selection/setSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { isGeneralSegment } from '../typeCheck/isGeneralSegment';\nimport { mutateBlock, mutateSegment } from '../common/mutate';\nimport type {\n MutableType,\n ReadonlyContentModelBlock,\n ReadonlyContentModelBlockGroup,\n ReadonlyContentModelParagraph,\n ReadonlyContentModelSegment,\n ReadonlyContentModelTable,\n ReadonlySelectable,\n ShallowMutableSelectable,\n TableCellCoordinate,\n} from 'roosterjs-content-model-types';\n\n/**\n * Set selection into Content Model. If the Content Model already has selection, existing selection will be overwritten by the new one.\n * @param group The root level group of Content Model\n * @param start The start selected element. If not passed, existing selection of content model will be cleared\n * @param end The end selected element. If not passed, only the start element will be selected. If passed, all elements between start and end elements will be selected\n */\nexport function setSelection(\n group: ReadonlyContentModelBlockGroup,\n start?: ReadonlySelectable,\n end?: ReadonlySelectable\n) {\n setSelectionToBlockGroup(group, false /*isInSelection*/, start || null, end || null);\n}\n\nfunction setSelectionToBlockGroup(\n group: ReadonlyContentModelBlockGroup,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n): boolean {\n return handleSelection(isInSelection, group, start, end, isInSelection => {\n if (isGeneralSegment(group) && needToSetSelection(group, isInSelection)) {\n setIsSelected(mutateBlock(group), isInSelection);\n }\n\n const blocksToDelete: number[] = [];\n\n group.blocks.forEach((block, i) => {\n isInSelection = setSelectionToBlock(block, isInSelection, start, end);\n\n if (block.blockType == 'Paragraph' && block.segments.length == 0 && block.isImplicit) {\n blocksToDelete.push(i);\n }\n });\n\n let index: number | undefined;\n\n if (blocksToDelete.length > 0) {\n const mutableGroup = mutateBlock(group);\n\n while ((index = blocksToDelete.pop()) !== undefined) {\n if (index >= 0) {\n mutableGroup.blocks.splice(index, 1);\n }\n }\n }\n\n return isInSelection;\n });\n}\n\nfunction setSelectionToBlock(\n block: ReadonlyContentModelBlock,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n) {\n switch (block.blockType) {\n case 'BlockGroup':\n return setSelectionToBlockGroup(block, isInSelection, start, end);\n\n case 'Table':\n return setSelectionToTable(block, isInSelection, start, end);\n\n case 'Divider':\n case 'Entity':\n return handleSelection(isInSelection, block, start, end, isInSelection => {\n if (needToSetSelection(block, isInSelection)) {\n const mutableBlock = mutateBlock(block);\n\n if (isInSelection) {\n mutableBlock.isSelected = true;\n } else {\n delete mutableBlock.isSelected;\n }\n }\n\n return isInSelection;\n });\n\n case 'Paragraph':\n const state: ParagraphSelectionState = {\n segmentsToDelete: [],\n boundaryMarkers: [],\n hasSelectedNonMarker: false,\n };\n\n block.segments.forEach((segment, i) => {\n isInSelection = handleSelection(\n isInSelection,\n segment,\n start,\n end,\n isInSelection => {\n return setSelectionToSegment(\n block,\n segment,\n isInSelection,\n state,\n start,\n end,\n i\n );\n }\n );\n });\n\n if (state.hasSelectedNonMarker) {\n // This paragraph contains a real (non-marker) selected segment, so any leading/trailing\n // selection marker of the range is redundant within this paragraph and can be removed.\n // We only do this within the same paragraph: a boundary marker at a paragraph edge must be\n // kept to distinguish \"selection starts at the beginning of this line\" from \"selection\n // starts at the end of the previous line\".\n state.segmentsToDelete.push(...state.boundaryMarkers);\n }\n\n if (state.segmentsToDelete.length > 0) {\n const mutablePara = mutateBlock(block);\n\n let index: number | undefined;\n\n // Sort ascending so the pop()-based splice below always removes the highest index first,\n // keeping the remaining indices valid (boundary markers may sit before queued deletions).\n state.segmentsToDelete.sort((a, b) => a - b);\n\n while ((index = state.segmentsToDelete.pop()) !== undefined) {\n if (index >= 0) {\n mutablePara.segments.splice(index, 1);\n }\n }\n }\n\n return isInSelection;\n\n default:\n return isInSelection;\n }\n}\n\nfunction setSelectionToTable(\n table: ReadonlyContentModelTable,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n): boolean {\n const first = findCell(table, start);\n const last = end ? findCell(table, end) : first;\n\n if (!isInSelection) {\n for (let row = 0; row < table.rows.length; row++) {\n const currentRow = table.rows[row];\n for (let col = 0; col < currentRow.cells.length; col++) {\n const currentCell = table.rows[row].cells[col];\n const isSelected =\n row >= first.row && row <= last.row && col >= first.col && col <= last.col;\n\n if (needToSetSelection(currentCell, isSelected)) {\n setIsSelected(mutateBlock(currentCell), isSelected);\n }\n\n if (!isSelected) {\n setSelectionToBlockGroup(currentCell, false /*isInSelection*/, start, end);\n }\n }\n }\n } else {\n table.rows.forEach(row =>\n row.cells.forEach(cell => {\n const wasInSelection = isInSelection;\n\n isInSelection = setSelectionToBlockGroup(cell, isInSelection, start, end);\n\n if (wasInSelection && isInSelection) {\n mutateBlock(cell).isSelected = true;\n }\n })\n );\n }\n\n return isInSelection;\n}\n\nfunction findCell(\n table: ReadonlyContentModelTable,\n cell: ReadonlySelectable | null\n): TableCellCoordinate {\n let col = -1;\n const row = cell\n ? table.rows.findIndex(\n row => (col = (row.cells as ReadonlyArray<ReadonlySelectable>).indexOf(cell)) >= 0\n )\n : -1;\n\n return { row, col };\n}\n\ninterface ParagraphSelectionState {\n // Indexes of segments to delete after the paragraph is fully processed\n segmentsToDelete: number[];\n\n // Indexes of leading/trailing selection markers of the range that are kept for now, but will be\n // removed if this paragraph also contains a real (non-marker) selected segment\n boundaryMarkers: number[];\n\n // Whether this paragraph contains at least one selected segment that is not a selection marker\n hasSelectedNonMarker: boolean;\n}\n\nfunction setSelectionToSegment(\n paragraph: ReadonlyContentModelParagraph,\n segment: ReadonlyContentModelSegment,\n isInSelection: boolean,\n state: ParagraphSelectionState,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null,\n i: number\n) {\n if (segment.segmentType != 'SelectionMarker' && isInSelection) {\n state.hasSelectedNonMarker = true;\n }\n\n switch (segment.segmentType) {\n case 'SelectionMarker':\n if (!isInSelection || (segment != start && segment != end)) {\n // Delete the selection marker when\n // 1. It is not in selection any more. Or\n // 2. It is in middle of selection, so no need to have it\n state.segmentsToDelete.push(i);\n } else {\n // It is a leading/trailing selection marker of a range selection. Keep it for now, but\n // remember it so it can be removed later if this same paragraph also contains a real\n // (non-marker) selected segment, in which case the marker is redundant.\n state.boundaryMarkers.push(i);\n }\n return isInSelection;\n\n case 'General':\n internalSetSelectionToSegment(paragraph, segment, isInSelection);\n\n return segment != start && segment != end\n ? setSelectionToBlockGroup(segment, isInSelection, start, end)\n : isInSelection;\n\n case 'Image':\n const isSelectedAsImageSelection = start == segment && (!end || end == segment);\n\n internalSetSelectionToSegment(\n paragraph,\n segment,\n isInSelection,\n !segment.isSelectedAsImageSelection != !isSelectedAsImageSelection\n ? image => (image.isSelectedAsImageSelection = isSelectedAsImageSelection)\n : undefined\n );\n\n return isInSelection;\n default:\n internalSetSelectionToSegment(paragraph, segment, isInSelection);\n return isInSelection;\n }\n}\n\nfunction internalSetSelectionToSegment<T extends ReadonlyContentModelSegment>(\n paragraph: ReadonlyContentModelParagraph,\n segment: T,\n isInSelection: boolean,\n additionAction?: (segment: MutableType<T>) => void\n) {\n if (additionAction || needToSetSelection(segment, isInSelection)) {\n mutateSegment(paragraph, segment, mutableSegment => {\n setIsSelected(mutableSegment, isInSelection);\n additionAction?.(mutableSegment);\n });\n }\n}\n\nfunction needToSetSelection(selectable: ReadonlySelectable, isSelected: boolean) {\n return !selectable.isSelected != !isSelected;\n}\n\nfunction setIsSelected(selectable: ShallowMutableSelectable, value: boolean) {\n if (value) {\n selectable.isSelected = true;\n } else {\n delete selectable.isSelected;\n }\n\n return value;\n}\n\nfunction handleSelection(\n isInSelection: boolean,\n model: ReadonlyContentModelBlockGroup | ReadonlyContentModelBlock | ReadonlyContentModelSegment,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null,\n callback: (isInSelection: boolean) => boolean\n) {\n isInSelection = isInSelection || model == start;\n isInSelection = callback(isInSelection);\n return isInSelection && !!end && model != end;\n}\n"]}
|
|
@@ -29,7 +29,7 @@ define(["require", "exports", "../utils/cleanUpRestNodes"], function (require, e
|
|
|
29
29
|
(_a = context.domIndexer) === null || _a === void 0 ? void 0 : _a.onBlockEntity(childBlock, group);
|
|
30
30
|
}
|
|
31
31
|
});
|
|
32
|
-
cleanUpNodeStack(listFormat.nodeStack, context);
|
|
32
|
+
cleanUpNodeStack(listFormat.nodeStack, context, parent);
|
|
33
33
|
// Remove all rest node if any since they don't appear in content model
|
|
34
34
|
(0, cleanUpRestNodes_1.cleanUpRestNodes)(refNode, context.rewriteFromModel);
|
|
35
35
|
}
|
|
@@ -38,7 +38,7 @@ define(["require", "exports", "../utils/cleanUpRestNodes"], function (require, e
|
|
|
38
38
|
}
|
|
39
39
|
};
|
|
40
40
|
exports.handleBlockGroupChildren = handleBlockGroupChildren;
|
|
41
|
-
function cleanUpNodeStack(nodeStack, context) {
|
|
41
|
+
function cleanUpNodeStack(nodeStack, context, leavingParent) {
|
|
42
42
|
var _a, _b;
|
|
43
43
|
if (nodeStack.length > 0) {
|
|
44
44
|
// Clear list stack, only run to nodeStack[1] because nodeStack[0] is the parent node
|
|
@@ -46,6 +46,13 @@ define(["require", "exports", "../utils/cleanUpRestNodes"], function (require, e
|
|
|
46
46
|
var node = (_b = (_a = nodeStack.pop()) === null || _a === void 0 ? void 0 : _a.refNode) !== null && _b !== void 0 ? _b : null;
|
|
47
47
|
(0, cleanUpRestNodes_1.cleanUpRestNodes)(node, context.rewriteFromModel);
|
|
48
48
|
}
|
|
49
|
+
if (leavingParent && nodeStack[0].node == leavingParent) {
|
|
50
|
+
// When leaving a parent node that is the same with the root of node stack
|
|
51
|
+
// It means the whole list node stack is being invalidated, so we clear it
|
|
52
|
+
while (nodeStack.length > 0) {
|
|
53
|
+
nodeStack.pop();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
49
56
|
}
|
|
50
57
|
}
|
|
51
58
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handleBlockGroupChildren.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/handlers/handleBlockGroupChildren.ts"],"names":[],"mappings":";;;;IAQA;;OAEG;IACI,IAAM,wBAAwB,GAAgD,UACjF,GAAa,EACb,MAAY,EACZ,KAA6B,EAC7B,OAA0B;QAElB,IAAA,UAAU,GAAK,OAAO,WAAZ,CAAa;QAC/B,IAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC;QACvC,IAAI,OAAO,GAAgB,MAAM,CAAC,UAAU,CAAC;QAE7C,IAAI;YACA,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,UAAC,UAAU,EAAE,KAAK;;gBACnC,2CAA2C;gBAC3C,wEAAwE;gBACxE,sFAAsF;gBACtF,+FAA+F;gBAC/F,IACI,KAAK,IAAI,CAAC;oBACV,UAAU,CAAC,SAAS,IAAI,YAAY;oBACpC,UAAU,CAAC,cAAc,IAAI,UAAU,EACzC;oBACE,gBAAgB,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;oBAEhD,IAAI,UAAU,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;wBACjC,UAAU,CAAC,SAAS,GAAG,EAAE,CAAC;qBAC7B;iBACJ;gBAED,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;gBAEjF,IAAI,UAAU,CAAC,SAAS,IAAI,QAAQ,EAAE;oBAClC,MAAA,OAAO,CAAC,UAAU,0CAAE,aAAa,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;iBACxD;YACL,CAAC,CAAC,CAAC;YAEH,gBAAgB,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"handleBlockGroupChildren.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/handlers/handleBlockGroupChildren.ts"],"names":[],"mappings":";;;;IAQA;;OAEG;IACI,IAAM,wBAAwB,GAAgD,UACjF,GAAa,EACb,MAAY,EACZ,KAA6B,EAC7B,OAA0B;QAElB,IAAA,UAAU,GAAK,OAAO,WAAZ,CAAa;QAC/B,IAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC;QACvC,IAAI,OAAO,GAAgB,MAAM,CAAC,UAAU,CAAC;QAE7C,IAAI;YACA,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,UAAC,UAAU,EAAE,KAAK;;gBACnC,2CAA2C;gBAC3C,wEAAwE;gBACxE,sFAAsF;gBACtF,+FAA+F;gBAC/F,IACI,KAAK,IAAI,CAAC;oBACV,UAAU,CAAC,SAAS,IAAI,YAAY;oBACpC,UAAU,CAAC,cAAc,IAAI,UAAU,EACzC;oBACE,gBAAgB,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;oBAEhD,IAAI,UAAU,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;wBACjC,UAAU,CAAC,SAAS,GAAG,EAAE,CAAC;qBAC7B;iBACJ;gBAED,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;gBAEjF,IAAI,UAAU,CAAC,SAAS,IAAI,QAAQ,EAAE;oBAClC,MAAA,OAAO,CAAC,UAAU,0CAAE,aAAa,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;iBACxD;YACL,CAAC,CAAC,CAAC;YAEH,gBAAgB,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;YAExD,uEAAuE;YACvE,IAAA,mCAAgB,EAAC,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;SACvD;gBAAS;YACN,UAAU,CAAC,SAAS,GAAG,SAAS,CAAC;SACpC;IACL,CAAC,CAAC;IA1CW,QAAA,wBAAwB,4BA0CnC;IAEF,SAAS,gBAAgB,CACrB,SAAoC,EACpC,OAA0B,EAC1B,aAAoB;;QAEpB,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;YACtB,qFAAqF;YACrF,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;gBAC3C,IAAM,IAAI,GAAG,MAAA,MAAA,SAAS,CAAC,GAAG,EAAE,0CAAE,OAAO,mCAAI,IAAI,CAAC;gBAE9C,IAAA,mCAAgB,EAAC,IAAI,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;aACpD;YAED,IAAI,aAAa,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,aAAa,EAAE;gBACrD,0EAA0E;gBAC1E,0EAA0E;gBAC1E,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;oBACzB,SAAS,CAAC,GAAG,EAAE,CAAC;iBACnB;aACJ;SACJ;IACL,CAAC","sourcesContent":["import { cleanUpRestNodes } from '../utils/cleanUpRestNodes';\nimport type {\n ContentModelBlockGroup,\n ContentModelHandler,\n ModelToDomContext,\n ModelToDomListStackItem,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const handleBlockGroupChildren: ContentModelHandler<ContentModelBlockGroup> = (\n doc: Document,\n parent: Node,\n group: ContentModelBlockGroup,\n context: ModelToDomContext\n) => {\n const { listFormat } = context;\n const nodeStack = listFormat.nodeStack;\n let refNode: Node | null = parent.firstChild;\n\n try {\n group.blocks.forEach((childBlock, index) => {\n // When process list, we need a node stack.\n // When there are two continuous lists, they should share the same stack\n // so that list items with same type/threadId can be merged into the same list element\n // In other cases, clear the stack so that two separate lists won't share the same list element\n if (\n index == 0 ||\n childBlock.blockType != 'BlockGroup' ||\n childBlock.blockGroupType != 'ListItem'\n ) {\n cleanUpNodeStack(listFormat.nodeStack, context);\n\n if (listFormat.nodeStack.length > 0) {\n listFormat.nodeStack = [];\n }\n }\n\n refNode = context.modelHandlers.block(doc, parent, childBlock, context, refNode);\n\n if (childBlock.blockType == 'Entity') {\n context.domIndexer?.onBlockEntity(childBlock, group);\n }\n });\n\n cleanUpNodeStack(listFormat.nodeStack, context, parent);\n\n // Remove all rest node if any since they don't appear in content model\n cleanUpRestNodes(refNode, context.rewriteFromModel);\n } finally {\n listFormat.nodeStack = nodeStack;\n }\n};\n\nfunction cleanUpNodeStack(\n nodeStack: ModelToDomListStackItem[],\n context: ModelToDomContext,\n leavingParent?: Node\n) {\n if (nodeStack.length > 0) {\n // Clear list stack, only run to nodeStack[1] because nodeStack[0] is the parent node\n for (let i = nodeStack.length - 1; i > 0; i--) {\n const node = nodeStack.pop()?.refNode ?? null;\n\n cleanUpRestNodes(node, context.rewriteFromModel);\n }\n\n if (leavingParent && nodeStack[0].node == leavingParent) {\n // When leaving a parent node that is the same with the root of node stack\n // It means the whole list node stack is being invalidated, so we clear it\n while (nodeStack.length > 0) {\n nodeStack.pop();\n }\n }\n }\n}\n"]}
|
|
@@ -10,7 +10,7 @@ export declare function createDomToModelContext(editorContext?: EditorContext, .
|
|
|
10
10
|
* @param config A full config object to define how to convert DOM tree to Content Model
|
|
11
11
|
* @param editorContext Context of editor
|
|
12
12
|
*/
|
|
13
|
-
export declare function createDomToModelContextWithConfig(config: DomToModelSettings, editorContext?: EditorContext):
|
|
13
|
+
export declare function createDomToModelContextWithConfig(config: DomToModelSettings, editorContext?: EditorContext): DomToModelContext;
|
|
14
14
|
/**
|
|
15
15
|
* Create Dom to Content Model Config object
|
|
16
16
|
* @param options All customizations of content model creation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDomToModelContext.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/context/createDomToModelContext.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EACH,4BAA4B,EAC5B,oBAAoB,GACvB,MAAM,4CAA4C,CAAC;AAgBpD;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CACnC,aAA6B;IAC7B,iBAA4C;SAA5C,UAA4C,EAA5C,qBAA4C,EAA5C,IAA4C;QAA5C,gCAA4C;;IAE5C,OAAO,iCAAiC,CAAC,sBAAsB,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,CAAC;AAC7F,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iCAAiC,CAC7C,MAA0B,EAC1B,aAA6B;IAE7B,OAAO,MAAM,CAAC,MAAM,CAChB,EAAE,EACF,aAAa,EACb,gCAAgC,EAAE,EAClC,6BAA6B,CAAC,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,SAAS,CAAC,EACvD,gCAAgC,EAAE,EAClC,MAAM,CACT,CAAC;AACN,CAAC;AAED,SAAS,gCAAgC;IACrC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;AACpC,CAAC;AAED,SAAS,6BAA6B,CAAC,SAAmB;IACtD,IAAM,WAAW,GAA4B,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAEnF,OAAO;QACH,WAAW,aAAA;QACX,aAAa,EAAE,EAAE;QAEjB,UAAU,EAAE;YACR,MAAM,EAAE,EAAE;YACV,gBAAgB,EAAE,EAAE;SACvB;KACJ,CAAC;AACN,CAAC;AAED,SAAS,gCAAgC;IACrC,OAAO;QACH,IAAI,EAAE;YACF,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,EAAE;SACd;QACD,IAAI,EAAE;YACF,MAAM,EAAE,EAAE;SACb;QACD,cAAc,EAAE;YACZ,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,EAAE;SACd;KACJ,CAAC;AACN,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAClC,OAAyC;IAEzC,OAAO;QACH,iBAAiB,EAAE,MAAM,CAAC,MAAM,OAAb,MAAM,iBACrB,EAAE;YACF,mBAAmB,UAChB,OAAO,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,iBAAiB,EAApB,CAAoB,CAAC,UAC5C;QACD,aAAa,EAAE,kBAAkB,CAC7B,OAAO,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,oBAAoB,EAAvB,CAAuB,CAAC,EACzC,OAAO,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,uBAAuB,EAA1B,CAA0B,CAAC,CAC/C;QACD,wBAAwB,EAAE,mBAAmB;QAC7C,oBAAoB,sBAAA;QACpB,yBAAyB,EAAE,OAAO,CAAC,IAAI,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,yBAAyB,CAAA,EAA9B,CAA8B,CAAC;KAC/E,CAAC;AACN,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAC9B,SAAsD,EACtD,sBAA8E;IAD9E,0BAAA,EAAA,cAAsD;IACtD,uCAAA,EAAA,2BAA8E;IAE9E,IAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,OAAb,MAAM,iBAAQ,EAAE,UAAK,SAAS,UAAC,CAAC;IAE1D,IAAM,MAAM,GAAG,aAAa,CAAC,4BAA4B,CAAC,CAAC,MAAM,CAC7D,UAAC,MAAM,EAAE,GAAG;;QACR,IAAM,KAAK,GAAG,CAAA,KAAA,4BAA4B,CAAC,GAAG,CAAC;aAC1C,GAAG,CACA,UAAA,SAAS;YACL,OAAA,CAAC,iBAAiB,CAAC,SAAS,CAAC,KAAK,SAAS;gBACvC,CAAC,CAAC,oBAAoB,CAAC,SAAS,CAAC;gBACjC,CAAC,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAsB;QAFxD,CAEwD,CAC/D,CAAA;aACA,MAAM,oCACA,sBAAsB,CAAC,GAAG,CACzB,UAAA,OAAO,YAAI,OAAA,CAAC,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAG,GAAG,CAAC,mCAAI,EAAE,CAAwB,CAAA,EAAA,CAC3D,UACJ,CAAC;QAEN,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAEpB,OAAO,MAAM,CAAC;IAClB,CAAC,EACD;QACI,IAAI,EAAE,EAAwB;KACL,CAChC,CAAC;IAEF,sBAAsB,CAAC,OAAO,CAAC,UAAA,OAAO;QAClC,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,EAAE;YACf,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;SAClD;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAClB,CAAC","sourcesContent":["import { defaultProcessorMap } from './defaultProcessors';\nimport { getObjectKeys } from '../../domUtils/getObjectKeys';\nimport {\n defaultFormatKeysPerCategory,\n defaultFormatParsers,\n} from '../../formatHandlers/defaultFormatHandlers';\nimport type {\n ContentModelBlockFormat,\n DomToModelContext,\n DomToModelDecoratorContext,\n DomToModelFormatContext,\n DomToModelOption,\n DomToModelSelectionContext,\n DomToModelSettings,\n EditorContext,\n FormatParser,\n FormatParsers,\n FormatParsersPerCategory,\n TextFormatParser,\n} from 'roosterjs-content-model-types';\n\n/**\n * Create context object for DOM to Content Model conversion\n * @param editorContext Context of editor\n * @param options Option array to customize the DOM to Model conversion behavior\n */\nexport function createDomToModelContext(\n editorContext?: EditorContext,\n ...options: (DomToModelOption | undefined)[]\n): DomToModelContext {\n return createDomToModelContextWithConfig(createDomToModelConfig(options), editorContext);\n}\n\n/**\n * Create context object for DOM to Content Model conversion with an existing configure\n * @param config A full config object to define how to convert DOM tree to Content Model\n * @param editorContext Context of editor\n */\nexport function createDomToModelContextWithConfig(\n config: DomToModelSettings,\n editorContext?: EditorContext\n) {\n return Object.assign(\n {},\n editorContext,\n createDomToModelSelectionContext(),\n createDomToModelFormatContext(editorContext?.isRootRtl),\n createDomToModelDecoratorContext(),\n config\n );\n}\n\nfunction createDomToModelSelectionContext(): DomToModelSelectionContext {\n return { isInSelection: false };\n}\n\nfunction createDomToModelFormatContext(isRootRtl?: boolean): DomToModelFormatContext {\n const blockFormat: ContentModelBlockFormat = isRootRtl ? { direction: 'rtl' } : {};\n\n return {\n blockFormat,\n segmentFormat: {},\n\n listFormat: {\n levels: [],\n threadItemCounts: [],\n },\n };\n}\n\nfunction createDomToModelDecoratorContext(): DomToModelDecoratorContext {\n return {\n link: {\n format: {},\n dataset: {},\n },\n code: {\n format: {},\n },\n blockDecorator: {\n format: {},\n tagName: '',\n },\n };\n}\n\n/**\n * Create Dom to Content Model Config object\n * @param options All customizations of content model creation\n */\nexport function createDomToModelConfig(\n options: (DomToModelOption | undefined)[]\n): DomToModelSettings {\n return {\n elementProcessors: Object.assign(\n {},\n defaultProcessorMap,\n ...options.map(x => x?.processorOverride)\n ),\n formatParsers: buildFormatParsers(\n options.map(x => x?.formatParserOverride),\n options.map(x => x?.additionalFormatParsers)\n ),\n defaultElementProcessors: defaultProcessorMap,\n defaultFormatParsers,\n processNonVisibleElements: options.some(x => !!x?.processNonVisibleElements),\n };\n}\n\n/**\n * @internal Export for test only\n * Build format parsers used by DOM to Content Model conversion\n * @param override\n * @param additionalParsersArray\n * @returns\n */\nexport function buildFormatParsers(\n overrides: (Partial<FormatParsers> | undefined)[] = [],\n additionalParsersArray: (Partial<FormatParsersPerCategory> | undefined)[] = []\n): FormatParsersPerCategory {\n const combinedOverrides = Object.assign({}, ...overrides);\n\n const result = getObjectKeys(defaultFormatKeysPerCategory).reduce(\n (result, key) => {\n const value = defaultFormatKeysPerCategory[key]\n .map(\n formatKey =>\n (combinedOverrides[formatKey] === undefined\n ? defaultFormatParsers[formatKey]\n : combinedOverrides[formatKey]) as FormatParser<any>\n )\n .concat(\n ...additionalParsersArray.map(\n parsers => (parsers?.[key] ?? []) as FormatParser<any>[]\n )\n );\n\n result[key] = value;\n\n return result;\n },\n {\n text: [] as TextFormatParser[],\n } as FormatParsersPerCategory\n );\n\n additionalParsersArray.forEach(parsers => {\n if (parsers?.text) {\n result.text = result.text.concat(parsers.text);\n }\n });\n\n return result;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createDomToModelContext.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/context/createDomToModelContext.ts"],"names":[],"mappings":"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","sourcesContent":["import { defaultProcessorMap } from './defaultProcessors';\nimport { getObjectKeys } from '../../domUtils/getObjectKeys';\nimport {\n defaultFormatKeysPerCategory,\n defaultFormatParsers,\n} from '../../formatHandlers/defaultFormatHandlers';\nimport type {\n ContentModelBlockFormat,\n DomToModelContext,\n DomToModelDecoratorContext,\n DomToModelFormatContext,\n DomToModelOption,\n DomToModelSelectionContext,\n DomToModelSettings,\n EditorContext,\n FormatParser,\n FormatParsers,\n FormatParsersPerCategory,\n TextFormatParser,\n} from 'roosterjs-content-model-types';\n\n/**\n * Create context object for DOM to Content Model conversion\n * @param editorContext Context of editor\n * @param options Option array to customize the DOM to Model conversion behavior\n */\nexport function createDomToModelContext(\n editorContext?: EditorContext,\n ...options: (DomToModelOption | undefined)[]\n): DomToModelContext {\n return createDomToModelContextWithConfig(createDomToModelConfig(options), editorContext);\n}\n\n/**\n * Create context object for DOM to Content Model conversion with an existing configure\n * @param config A full config object to define how to convert DOM tree to Content Model\n * @param editorContext Context of editor\n */\nexport function createDomToModelContextWithConfig(\n config: DomToModelSettings,\n editorContext?: EditorContext\n): DomToModelContext {\n return Object.assign(\n {},\n editorContext,\n createDomToModelSelectionContext(),\n createDomToModelFormatContext(editorContext?.isRootRtl),\n createDomToModelDecoratorContext(),\n config\n );\n}\n\nfunction createDomToModelSelectionContext(): DomToModelSelectionContext {\n return { isInSelection: false };\n}\n\nfunction createDomToModelFormatContext(isRootRtl?: boolean): DomToModelFormatContext {\n const blockFormat: ContentModelBlockFormat = isRootRtl ? { direction: 'rtl' } : {};\n\n return {\n blockFormat,\n segmentFormat: {},\n\n listFormat: {\n levels: [],\n threadItemCounts: [],\n },\n };\n}\n\nfunction createDomToModelDecoratorContext(): DomToModelDecoratorContext {\n return {\n link: {\n format: {},\n dataset: {},\n },\n code: {\n format: {},\n },\n blockDecorator: {\n format: {},\n tagName: '',\n },\n };\n}\n\n/**\n * Create Dom to Content Model Config object\n * @param options All customizations of content model creation\n */\nexport function createDomToModelConfig(\n options: (DomToModelOption | undefined)[]\n): DomToModelSettings {\n return {\n elementProcessors: Object.assign(\n {},\n defaultProcessorMap,\n ...options.map(x => x?.processorOverride)\n ),\n formatParsers: buildFormatParsers(\n options.map(x => x?.formatParserOverride),\n options.map(x => x?.additionalFormatParsers)\n ),\n defaultElementProcessors: defaultProcessorMap,\n defaultFormatParsers,\n processNonVisibleElements: options.some(x => !!x?.processNonVisibleElements),\n };\n}\n\n/**\n * @internal Export for test only\n * Build format parsers used by DOM to Content Model conversion\n * @param override\n * @param additionalParsersArray\n * @returns\n */\nexport function buildFormatParsers(\n overrides: (Partial<FormatParsers> | undefined)[] = [],\n additionalParsersArray: (Partial<FormatParsersPerCategory> | undefined)[] = []\n): FormatParsersPerCategory {\n const combinedOverrides = Object.assign({}, ...overrides);\n\n const result = getObjectKeys(defaultFormatKeysPerCategory).reduce(\n (result, key) => {\n const value = defaultFormatKeysPerCategory[key]\n .map(\n formatKey =>\n (combinedOverrides[formatKey] === undefined\n ? defaultFormatParsers[formatKey]\n : combinedOverrides[formatKey]) as FormatParser<any>\n )\n .concat(\n ...additionalParsersArray.map(\n parsers => (parsers?.[key] ?? []) as FormatParser<any>[]\n )\n );\n\n result[key] = value;\n\n return result;\n },\n {\n text: [] as TextFormatParser[],\n } as FormatParsersPerCategory\n );\n\n additionalParsersArray.forEach(parsers => {\n if (parsers?.text) {\n result.text = result.text.concat(parsers.text);\n }\n });\n\n return result;\n}\n"]}
|
|
@@ -50,7 +50,9 @@ var formatContainerProcessorInternal = function (group, element, context, forceF
|
|
|
50
50
|
if (element.style.fontSize && parseInt(element.style.fontSize) == 0) {
|
|
51
51
|
formatContainer.zeroFontSize = true;
|
|
52
52
|
}
|
|
53
|
-
if (
|
|
53
|
+
if (!context.skipFormatContainerFallbackCheck &&
|
|
54
|
+
shouldFallbackToParagraph(formatContainer) &&
|
|
55
|
+
!forceFormatContainer) {
|
|
54
56
|
// For DIV container that only has one paragraph child, container style can be merged into paragraph
|
|
55
57
|
// and no need to have this container
|
|
56
58
|
var paragraph = formatContainer.blocks[0];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatContainerProcessor.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/processors/formatContainerProcessor.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+CAA+C,CAAC;AACtF,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,8CAA8C,CAAC;AACvF,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAYnD;;GAEG;AACH,MAAM,CAAC,IAAM,aAAa,GAA6C;IACnE,YAAY;IACZ,aAAa;IACb,aAAa;IACb,cAAc;CACjB,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,IAAM,wBAAwB,GAAkC,UACnE,KAAK,EACL,OAAO,EACP,OAAO;IAEP,gCAAgC,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,0BAA0B,CAAC,CAAC;AAChG,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,IAAM,6BAA6B,GAAkC,UACxE,KAAK,EACL,OAAO,EACP,OAAO;IAEP,gCAAgC,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,0BAA0B,CAAC,CAAC;AAC/F,CAAC,CAAC;AAEF,IAAM,gCAAgC,GAAG,UACrC,KAA6B,EAC7B,OAAoB,EACpB,OAA0B,EAC1B,oBAA6B;IAE7B,WAAW,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,cAAc,EAAE,EAAE;QACjF,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAChF,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,cAAc,EAAE,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAE3F,IAAM,MAAM,gBACL,OAAO,CAAC,WAAW,CACzB,CAAC;QAEF,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAEvE,IAAM,OAAO,GACT,eAAe,CAAC,OAAO,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QACxF,IAAM,eAAe,GAAG,qBAAqB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAE/D,0FAA0F;QAC1F,kEAAkE;QAClE,mFAAmF;QACnF,aAAa,CAAC,OAAO,CAAC,UAAA,KAAK;YACvB,OAAO,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,iBAAiB,CAAC,KAAK,CAAC,eAAe,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAEnE,IAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,IAAI,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YACjE,eAAe,CAAC,YAAY,GAAG,IAAI,CAAC;SACvC;QAED,
|
|
1
|
+
{"version":3,"file":"formatContainerProcessor.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/domToModel/processors/formatContainerProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["import { addBlock } from '../../modelApi/common/addBlock';\nimport { createFormatContainer } from '../../modelApi/creators/createFormatContainer';\nimport { createParagraph } from '../../modelApi/creators/createParagraph';\nimport { getDefaultStyle } from '../utils/getDefaultStyle';\nimport { parseFormat } from '../utils/parseFormat';\nimport { setParagraphNotImplicit } from '../../modelApi/block/setParagraphNotImplicit';\nimport { stackFormat } from '../utils/stackFormat';\nimport type {\n ContentModelBlockGroup,\n ContentModelFormatContainer,\n ContentModelFormatContainerFormat,\n ContentModelParagraph,\n DomToModelContext,\n ElementProcessor,\n MarginFormat,\n PaddingFormat,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const ContextStyles: (keyof (MarginFormat & PaddingFormat))[] = [\n 'marginLeft',\n 'marginRight',\n 'paddingLeft',\n 'paddingRight',\n];\n\n/**\n * Content Model Element Processor for format container elements (e.g., blockquote, div)\n * Processes elements that create FormatContainer blocks in the content model.\n * This processor can be used in processorOverride to customize how specific elements are processed.\n * @param group The parent block group\n * @param element The DOM element to process\n * @param context DOM to Content Model context\n */\nexport const formatContainerProcessor: ElementProcessor<HTMLElement> = (\n group,\n element,\n context\n) => {\n formatContainerProcessorInternal(group, element, context, false /* forceFormatContainer */);\n};\n\n/**\n * @internal\n */\nexport const forceFormatContainerProcessor: ElementProcessor<HTMLElement> = (\n group,\n element,\n context\n) => {\n formatContainerProcessorInternal(group, element, context, true /* forceFormatContainer */);\n};\n\nconst formatContainerProcessorInternal = (\n group: ContentModelBlockGroup,\n element: HTMLElement,\n context: DomToModelContext,\n forceFormatContainer: boolean\n) => {\n stackFormat(context, { segment: 'shallowCloneForBlock', paragraph: 'shallowClone' }, () => {\n parseFormat(element, context.formatParsers.block, context.blockFormat, context);\n parseFormat(element, context.formatParsers.segmentOnBlock, context.segmentFormat, context);\n\n const format: ContentModelFormatContainerFormat = {\n ...context.blockFormat,\n };\n\n parseFormat(element, context.formatParsers.container, format, context);\n\n const tagName =\n getDefaultStyle(element).display == 'block' ? element.tagName.toLowerCase() : 'div';\n const formatContainer = createFormatContainer(tagName, format);\n\n // It is possible to inherit margin left/right styles from parent DIV or other containers,\n // since we are going into a deeper level of format container now,\n // the container will render these styles so no need to keep them in context format\n ContextStyles.forEach(style => {\n delete context.blockFormat[style];\n });\n\n context.elementProcessors.child(formatContainer, element, context);\n\n if (element.style.fontSize && parseInt(element.style.fontSize) == 0) {\n formatContainer.zeroFontSize = true;\n }\n\n if (\n !context.skipFormatContainerFallbackCheck &&\n shouldFallbackToParagraph(formatContainer) &&\n !forceFormatContainer\n ) {\n // For DIV container that only has one paragraph child, container style can be merged into paragraph\n // and no need to have this container\n const paragraph = formatContainer.blocks[0] as ContentModelParagraph;\n\n if (formatContainer.zeroFontSize) {\n paragraph.segmentFormat = Object.assign({}, paragraph.segmentFormat, {\n fontSize: '0',\n });\n }\n\n Object.assign(paragraph.format, formatContainer.format);\n setParagraphNotImplicit(paragraph);\n addBlock(group, paragraph);\n } else {\n addBlock(group, formatContainer);\n }\n });\n\n addBlock(group, createParagraph(true /*isImplicit*/, context.blockFormat));\n};\n\nfunction shouldFallbackToParagraph(formatContainer: ContentModelFormatContainer) {\n const firstChild = formatContainer.blocks[0];\n\n return (\n formatContainer.tagName == 'div' &&\n formatContainer.blocks.length == 1 &&\n firstChild.blockType == 'Paragraph' &&\n firstChild.isImplicit\n );\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { __read, __spreadArray } from "tslib";
|
|
1
2
|
import { isGeneralSegment } from '../typeCheck/isGeneralSegment';
|
|
2
3
|
import { mutateBlock, mutateSegment } from '../common/mutate';
|
|
3
4
|
/**
|
|
@@ -34,6 +35,7 @@ function setSelectionToBlockGroup(group, isInSelection, start, end) {
|
|
|
34
35
|
});
|
|
35
36
|
}
|
|
36
37
|
function setSelectionToBlock(block, isInSelection, start, end) {
|
|
38
|
+
var _a;
|
|
37
39
|
switch (block.blockType) {
|
|
38
40
|
case 'BlockGroup':
|
|
39
41
|
return setSelectionToBlockGroup(block, isInSelection, start, end);
|
|
@@ -54,16 +56,31 @@ function setSelectionToBlock(block, isInSelection, start, end) {
|
|
|
54
56
|
return isInSelection;
|
|
55
57
|
});
|
|
56
58
|
case 'Paragraph':
|
|
57
|
-
var
|
|
59
|
+
var state_1 = {
|
|
60
|
+
segmentsToDelete: [],
|
|
61
|
+
boundaryMarkers: [],
|
|
62
|
+
hasSelectedNonMarker: false,
|
|
63
|
+
};
|
|
58
64
|
block.segments.forEach(function (segment, i) {
|
|
59
65
|
isInSelection = handleSelection(isInSelection, segment, start, end, function (isInSelection) {
|
|
60
|
-
return setSelectionToSegment(block, segment, isInSelection,
|
|
66
|
+
return setSelectionToSegment(block, segment, isInSelection, state_1, start, end, i);
|
|
61
67
|
});
|
|
62
68
|
});
|
|
63
|
-
if (
|
|
69
|
+
if (state_1.hasSelectedNonMarker) {
|
|
70
|
+
// This paragraph contains a real (non-marker) selected segment, so any leading/trailing
|
|
71
|
+
// selection marker of the range is redundant within this paragraph and can be removed.
|
|
72
|
+
// We only do this within the same paragraph: a boundary marker at a paragraph edge must be
|
|
73
|
+
// kept to distinguish "selection starts at the beginning of this line" from "selection
|
|
74
|
+
// starts at the end of the previous line".
|
|
75
|
+
(_a = state_1.segmentsToDelete).push.apply(_a, __spreadArray([], __read(state_1.boundaryMarkers), false));
|
|
76
|
+
}
|
|
77
|
+
if (state_1.segmentsToDelete.length > 0) {
|
|
64
78
|
var mutablePara = mutateBlock(block);
|
|
65
79
|
var index = void 0;
|
|
66
|
-
|
|
80
|
+
// Sort ascending so the pop()-based splice below always removes the highest index first,
|
|
81
|
+
// keeping the remaining indices valid (boundary markers may sit before queued deletions).
|
|
82
|
+
state_1.segmentsToDelete.sort(function (a, b) { return a - b; });
|
|
83
|
+
while ((index = state_1.segmentsToDelete.pop()) !== undefined) {
|
|
67
84
|
if (index >= 0) {
|
|
68
85
|
mutablePara.segments.splice(index, 1);
|
|
69
86
|
}
|
|
@@ -112,14 +129,23 @@ function findCell(table, cell) {
|
|
|
112
129
|
: -1;
|
|
113
130
|
return { row: row, col: col };
|
|
114
131
|
}
|
|
115
|
-
function setSelectionToSegment(paragraph, segment, isInSelection,
|
|
132
|
+
function setSelectionToSegment(paragraph, segment, isInSelection, state, start, end, i) {
|
|
133
|
+
if (segment.segmentType != 'SelectionMarker' && isInSelection) {
|
|
134
|
+
state.hasSelectedNonMarker = true;
|
|
135
|
+
}
|
|
116
136
|
switch (segment.segmentType) {
|
|
117
137
|
case 'SelectionMarker':
|
|
118
138
|
if (!isInSelection || (segment != start && segment != end)) {
|
|
119
139
|
// Delete the selection marker when
|
|
120
140
|
// 1. It is not in selection any more. Or
|
|
121
141
|
// 2. It is in middle of selection, so no need to have it
|
|
122
|
-
segmentsToDelete.push(i);
|
|
142
|
+
state.segmentsToDelete.push(i);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
// It is a leading/trailing selection marker of a range selection. Keep it for now, but
|
|
146
|
+
// remember it so it can be removed later if this same paragraph also contains a real
|
|
147
|
+
// (non-marker) selected segment, in which case the marker is redundant.
|
|
148
|
+
state.boundaryMarkers.push(i);
|
|
123
149
|
}
|
|
124
150
|
return isInSelection;
|
|
125
151
|
case 'General':
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setSelection.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelApi/selection/setSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { isGeneralSegment } from '../typeCheck/isGeneralSegment';\nimport { mutateBlock, mutateSegment } from '../common/mutate';\nimport type {\n MutableType,\n ReadonlyContentModelBlock,\n ReadonlyContentModelBlockGroup,\n ReadonlyContentModelParagraph,\n ReadonlyContentModelSegment,\n ReadonlyContentModelTable,\n ReadonlySelectable,\n ShallowMutableSelectable,\n TableCellCoordinate,\n} from 'roosterjs-content-model-types';\n\n/**\n * Set selection into Content Model. If the Content Model already has selection, existing selection will be overwritten by the new one.\n * @param group The root level group of Content Model\n * @param start The start selected element. If not passed, existing selection of content model will be cleared\n * @param end The end selected element. If not passed, only the start element will be selected. If passed, all elements between start and end elements will be selected\n */\nexport function setSelection(\n group: ReadonlyContentModelBlockGroup,\n start?: ReadonlySelectable,\n end?: ReadonlySelectable\n) {\n setSelectionToBlockGroup(group, false /*isInSelection*/, start || null, end || null);\n}\n\nfunction setSelectionToBlockGroup(\n group: ReadonlyContentModelBlockGroup,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n): boolean {\n return handleSelection(isInSelection, group, start, end, isInSelection => {\n if (isGeneralSegment(group) && needToSetSelection(group, isInSelection)) {\n setIsSelected(mutateBlock(group), isInSelection);\n }\n\n const blocksToDelete: number[] = [];\n\n group.blocks.forEach((block, i) => {\n isInSelection = setSelectionToBlock(block, isInSelection, start, end);\n\n if (block.blockType == 'Paragraph' && block.segments.length == 0 && block.isImplicit) {\n blocksToDelete.push(i);\n }\n });\n\n let index: number | undefined;\n\n if (blocksToDelete.length > 0) {\n const mutableGroup = mutateBlock(group);\n\n while ((index = blocksToDelete.pop()) !== undefined) {\n if (index >= 0) {\n mutableGroup.blocks.splice(index, 1);\n }\n }\n }\n\n return isInSelection;\n });\n}\n\nfunction setSelectionToBlock(\n block: ReadonlyContentModelBlock,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n) {\n switch (block.blockType) {\n case 'BlockGroup':\n return setSelectionToBlockGroup(block, isInSelection, start, end);\n\n case 'Table':\n return setSelectionToTable(block, isInSelection, start, end);\n\n case 'Divider':\n case 'Entity':\n return handleSelection(isInSelection, block, start, end, isInSelection => {\n if (needToSetSelection(block, isInSelection)) {\n const mutableBlock = mutateBlock(block);\n\n if (isInSelection) {\n mutableBlock.isSelected = true;\n } else {\n delete mutableBlock.isSelected;\n }\n }\n\n return isInSelection;\n });\n\n case 'Paragraph':\n const segmentsToDelete: number[] = [];\n\n block.segments.forEach((segment, i) => {\n isInSelection = handleSelection(\n isInSelection,\n segment,\n start,\n end,\n isInSelection => {\n return setSelectionToSegment(\n block,\n segment,\n isInSelection,\n segmentsToDelete,\n start,\n end,\n i\n );\n }\n );\n });\n\n if (segmentsToDelete.length > 0) {\n const mutablePara = mutateBlock(block);\n\n let index: number | undefined;\n\n while ((index = segmentsToDelete.pop()) !== undefined) {\n if (index >= 0) {\n mutablePara.segments.splice(index, 1);\n }\n }\n }\n\n return isInSelection;\n\n default:\n return isInSelection;\n }\n}\n\nfunction setSelectionToTable(\n table: ReadonlyContentModelTable,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n): boolean {\n const first = findCell(table, start);\n const last = end ? findCell(table, end) : first;\n\n if (!isInSelection) {\n for (let row = 0; row < table.rows.length; row++) {\n const currentRow = table.rows[row];\n for (let col = 0; col < currentRow.cells.length; col++) {\n const currentCell = table.rows[row].cells[col];\n const isSelected =\n row >= first.row && row <= last.row && col >= first.col && col <= last.col;\n\n if (needToSetSelection(currentCell, isSelected)) {\n setIsSelected(mutateBlock(currentCell), isSelected);\n }\n\n if (!isSelected) {\n setSelectionToBlockGroup(currentCell, false /*isInSelection*/, start, end);\n }\n }\n }\n } else {\n table.rows.forEach(row =>\n row.cells.forEach(cell => {\n const wasInSelection = isInSelection;\n\n isInSelection = setSelectionToBlockGroup(cell, isInSelection, start, end);\n\n if (wasInSelection && isInSelection) {\n mutateBlock(cell).isSelected = true;\n }\n })\n );\n }\n\n return isInSelection;\n}\n\nfunction findCell(\n table: ReadonlyContentModelTable,\n cell: ReadonlySelectable | null\n): TableCellCoordinate {\n let col = -1;\n const row = cell\n ? table.rows.findIndex(\n row => (col = (row.cells as ReadonlyArray<ReadonlySelectable>).indexOf(cell)) >= 0\n )\n : -1;\n\n return { row, col };\n}\n\nfunction setSelectionToSegment(\n paragraph: ReadonlyContentModelParagraph,\n segment: ReadonlyContentModelSegment,\n isInSelection: boolean,\n segmentsToDelete: number[],\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null,\n i: number\n) {\n switch (segment.segmentType) {\n case 'SelectionMarker':\n if (!isInSelection || (segment != start && segment != end)) {\n // Delete the selection marker when\n // 1. It is not in selection any more. Or\n // 2. It is in middle of selection, so no need to have it\n segmentsToDelete.push(i);\n }\n return isInSelection;\n\n case 'General':\n internalSetSelectionToSegment(paragraph, segment, isInSelection);\n\n return segment != start && segment != end\n ? setSelectionToBlockGroup(segment, isInSelection, start, end)\n : isInSelection;\n\n case 'Image':\n const isSelectedAsImageSelection = start == segment && (!end || end == segment);\n\n internalSetSelectionToSegment(\n paragraph,\n segment,\n isInSelection,\n !segment.isSelectedAsImageSelection != !isSelectedAsImageSelection\n ? image => (image.isSelectedAsImageSelection = isSelectedAsImageSelection)\n : undefined\n );\n\n return isInSelection;\n default:\n internalSetSelectionToSegment(paragraph, segment, isInSelection);\n return isInSelection;\n }\n}\n\nfunction internalSetSelectionToSegment<T extends ReadonlyContentModelSegment>(\n paragraph: ReadonlyContentModelParagraph,\n segment: T,\n isInSelection: boolean,\n additionAction?: (segment: MutableType<T>) => void\n) {\n if (additionAction || needToSetSelection(segment, isInSelection)) {\n mutateSegment(paragraph, segment, mutableSegment => {\n setIsSelected(mutableSegment, isInSelection);\n additionAction?.(mutableSegment);\n });\n }\n}\n\nfunction needToSetSelection(selectable: ReadonlySelectable, isSelected: boolean) {\n return !selectable.isSelected != !isSelected;\n}\n\nfunction setIsSelected(selectable: ShallowMutableSelectable, value: boolean) {\n if (value) {\n selectable.isSelected = true;\n } else {\n delete selectable.isSelected;\n }\n\n return value;\n}\n\nfunction handleSelection(\n isInSelection: boolean,\n model: ReadonlyContentModelBlockGroup | ReadonlyContentModelBlock | ReadonlyContentModelSegment,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null,\n callback: (isInSelection: boolean) => boolean\n) {\n isInSelection = isInSelection || model == start;\n isInSelection = callback(isInSelection);\n return isInSelection && !!end && model != end;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"setSelection.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelApi/selection/setSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { isGeneralSegment } from '../typeCheck/isGeneralSegment';\nimport { mutateBlock, mutateSegment } from '../common/mutate';\nimport type {\n MutableType,\n ReadonlyContentModelBlock,\n ReadonlyContentModelBlockGroup,\n ReadonlyContentModelParagraph,\n ReadonlyContentModelSegment,\n ReadonlyContentModelTable,\n ReadonlySelectable,\n ShallowMutableSelectable,\n TableCellCoordinate,\n} from 'roosterjs-content-model-types';\n\n/**\n * Set selection into Content Model. If the Content Model already has selection, existing selection will be overwritten by the new one.\n * @param group The root level group of Content Model\n * @param start The start selected element. If not passed, existing selection of content model will be cleared\n * @param end The end selected element. If not passed, only the start element will be selected. If passed, all elements between start and end elements will be selected\n */\nexport function setSelection(\n group: ReadonlyContentModelBlockGroup,\n start?: ReadonlySelectable,\n end?: ReadonlySelectable\n) {\n setSelectionToBlockGroup(group, false /*isInSelection*/, start || null, end || null);\n}\n\nfunction setSelectionToBlockGroup(\n group: ReadonlyContentModelBlockGroup,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n): boolean {\n return handleSelection(isInSelection, group, start, end, isInSelection => {\n if (isGeneralSegment(group) && needToSetSelection(group, isInSelection)) {\n setIsSelected(mutateBlock(group), isInSelection);\n }\n\n const blocksToDelete: number[] = [];\n\n group.blocks.forEach((block, i) => {\n isInSelection = setSelectionToBlock(block, isInSelection, start, end);\n\n if (block.blockType == 'Paragraph' && block.segments.length == 0 && block.isImplicit) {\n blocksToDelete.push(i);\n }\n });\n\n let index: number | undefined;\n\n if (blocksToDelete.length > 0) {\n const mutableGroup = mutateBlock(group);\n\n while ((index = blocksToDelete.pop()) !== undefined) {\n if (index >= 0) {\n mutableGroup.blocks.splice(index, 1);\n }\n }\n }\n\n return isInSelection;\n });\n}\n\nfunction setSelectionToBlock(\n block: ReadonlyContentModelBlock,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n) {\n switch (block.blockType) {\n case 'BlockGroup':\n return setSelectionToBlockGroup(block, isInSelection, start, end);\n\n case 'Table':\n return setSelectionToTable(block, isInSelection, start, end);\n\n case 'Divider':\n case 'Entity':\n return handleSelection(isInSelection, block, start, end, isInSelection => {\n if (needToSetSelection(block, isInSelection)) {\n const mutableBlock = mutateBlock(block);\n\n if (isInSelection) {\n mutableBlock.isSelected = true;\n } else {\n delete mutableBlock.isSelected;\n }\n }\n\n return isInSelection;\n });\n\n case 'Paragraph':\n const state: ParagraphSelectionState = {\n segmentsToDelete: [],\n boundaryMarkers: [],\n hasSelectedNonMarker: false,\n };\n\n block.segments.forEach((segment, i) => {\n isInSelection = handleSelection(\n isInSelection,\n segment,\n start,\n end,\n isInSelection => {\n return setSelectionToSegment(\n block,\n segment,\n isInSelection,\n state,\n start,\n end,\n i\n );\n }\n );\n });\n\n if (state.hasSelectedNonMarker) {\n // This paragraph contains a real (non-marker) selected segment, so any leading/trailing\n // selection marker of the range is redundant within this paragraph and can be removed.\n // We only do this within the same paragraph: a boundary marker at a paragraph edge must be\n // kept to distinguish \"selection starts at the beginning of this line\" from \"selection\n // starts at the end of the previous line\".\n state.segmentsToDelete.push(...state.boundaryMarkers);\n }\n\n if (state.segmentsToDelete.length > 0) {\n const mutablePara = mutateBlock(block);\n\n let index: number | undefined;\n\n // Sort ascending so the pop()-based splice below always removes the highest index first,\n // keeping the remaining indices valid (boundary markers may sit before queued deletions).\n state.segmentsToDelete.sort((a, b) => a - b);\n\n while ((index = state.segmentsToDelete.pop()) !== undefined) {\n if (index >= 0) {\n mutablePara.segments.splice(index, 1);\n }\n }\n }\n\n return isInSelection;\n\n default:\n return isInSelection;\n }\n}\n\nfunction setSelectionToTable(\n table: ReadonlyContentModelTable,\n isInSelection: boolean,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null\n): boolean {\n const first = findCell(table, start);\n const last = end ? findCell(table, end) : first;\n\n if (!isInSelection) {\n for (let row = 0; row < table.rows.length; row++) {\n const currentRow = table.rows[row];\n for (let col = 0; col < currentRow.cells.length; col++) {\n const currentCell = table.rows[row].cells[col];\n const isSelected =\n row >= first.row && row <= last.row && col >= first.col && col <= last.col;\n\n if (needToSetSelection(currentCell, isSelected)) {\n setIsSelected(mutateBlock(currentCell), isSelected);\n }\n\n if (!isSelected) {\n setSelectionToBlockGroup(currentCell, false /*isInSelection*/, start, end);\n }\n }\n }\n } else {\n table.rows.forEach(row =>\n row.cells.forEach(cell => {\n const wasInSelection = isInSelection;\n\n isInSelection = setSelectionToBlockGroup(cell, isInSelection, start, end);\n\n if (wasInSelection && isInSelection) {\n mutateBlock(cell).isSelected = true;\n }\n })\n );\n }\n\n return isInSelection;\n}\n\nfunction findCell(\n table: ReadonlyContentModelTable,\n cell: ReadonlySelectable | null\n): TableCellCoordinate {\n let col = -1;\n const row = cell\n ? table.rows.findIndex(\n row => (col = (row.cells as ReadonlyArray<ReadonlySelectable>).indexOf(cell)) >= 0\n )\n : -1;\n\n return { row, col };\n}\n\ninterface ParagraphSelectionState {\n // Indexes of segments to delete after the paragraph is fully processed\n segmentsToDelete: number[];\n\n // Indexes of leading/trailing selection markers of the range that are kept for now, but will be\n // removed if this paragraph also contains a real (non-marker) selected segment\n boundaryMarkers: number[];\n\n // Whether this paragraph contains at least one selected segment that is not a selection marker\n hasSelectedNonMarker: boolean;\n}\n\nfunction setSelectionToSegment(\n paragraph: ReadonlyContentModelParagraph,\n segment: ReadonlyContentModelSegment,\n isInSelection: boolean,\n state: ParagraphSelectionState,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null,\n i: number\n) {\n if (segment.segmentType != 'SelectionMarker' && isInSelection) {\n state.hasSelectedNonMarker = true;\n }\n\n switch (segment.segmentType) {\n case 'SelectionMarker':\n if (!isInSelection || (segment != start && segment != end)) {\n // Delete the selection marker when\n // 1. It is not in selection any more. Or\n // 2. It is in middle of selection, so no need to have it\n state.segmentsToDelete.push(i);\n } else {\n // It is a leading/trailing selection marker of a range selection. Keep it for now, but\n // remember it so it can be removed later if this same paragraph also contains a real\n // (non-marker) selected segment, in which case the marker is redundant.\n state.boundaryMarkers.push(i);\n }\n return isInSelection;\n\n case 'General':\n internalSetSelectionToSegment(paragraph, segment, isInSelection);\n\n return segment != start && segment != end\n ? setSelectionToBlockGroup(segment, isInSelection, start, end)\n : isInSelection;\n\n case 'Image':\n const isSelectedAsImageSelection = start == segment && (!end || end == segment);\n\n internalSetSelectionToSegment(\n paragraph,\n segment,\n isInSelection,\n !segment.isSelectedAsImageSelection != !isSelectedAsImageSelection\n ? image => (image.isSelectedAsImageSelection = isSelectedAsImageSelection)\n : undefined\n );\n\n return isInSelection;\n default:\n internalSetSelectionToSegment(paragraph, segment, isInSelection);\n return isInSelection;\n }\n}\n\nfunction internalSetSelectionToSegment<T extends ReadonlyContentModelSegment>(\n paragraph: ReadonlyContentModelParagraph,\n segment: T,\n isInSelection: boolean,\n additionAction?: (segment: MutableType<T>) => void\n) {\n if (additionAction || needToSetSelection(segment, isInSelection)) {\n mutateSegment(paragraph, segment, mutableSegment => {\n setIsSelected(mutableSegment, isInSelection);\n additionAction?.(mutableSegment);\n });\n }\n}\n\nfunction needToSetSelection(selectable: ReadonlySelectable, isSelected: boolean) {\n return !selectable.isSelected != !isSelected;\n}\n\nfunction setIsSelected(selectable: ShallowMutableSelectable, value: boolean) {\n if (value) {\n selectable.isSelected = true;\n } else {\n delete selectable.isSelected;\n }\n\n return value;\n}\n\nfunction handleSelection(\n isInSelection: boolean,\n model: ReadonlyContentModelBlockGroup | ReadonlyContentModelBlock | ReadonlyContentModelSegment,\n start: ReadonlySelectable | null,\n end: ReadonlySelectable | null,\n callback: (isInSelection: boolean) => boolean\n) {\n isInSelection = isInSelection || model == start;\n isInSelection = callback(isInSelection);\n return isInSelection && !!end && model != end;\n}\n"]}
|
|
@@ -26,7 +26,7 @@ export var handleBlockGroupChildren = function (doc, parent, group, context) {
|
|
|
26
26
|
(_a = context.domIndexer) === null || _a === void 0 ? void 0 : _a.onBlockEntity(childBlock, group);
|
|
27
27
|
}
|
|
28
28
|
});
|
|
29
|
-
cleanUpNodeStack(listFormat.nodeStack, context);
|
|
29
|
+
cleanUpNodeStack(listFormat.nodeStack, context, parent);
|
|
30
30
|
// Remove all rest node if any since they don't appear in content model
|
|
31
31
|
cleanUpRestNodes(refNode, context.rewriteFromModel);
|
|
32
32
|
}
|
|
@@ -34,7 +34,7 @@ export var handleBlockGroupChildren = function (doc, parent, group, context) {
|
|
|
34
34
|
listFormat.nodeStack = nodeStack;
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
|
-
function cleanUpNodeStack(nodeStack, context) {
|
|
37
|
+
function cleanUpNodeStack(nodeStack, context, leavingParent) {
|
|
38
38
|
var _a, _b;
|
|
39
39
|
if (nodeStack.length > 0) {
|
|
40
40
|
// Clear list stack, only run to nodeStack[1] because nodeStack[0] is the parent node
|
|
@@ -42,6 +42,13 @@ function cleanUpNodeStack(nodeStack, context) {
|
|
|
42
42
|
var node = (_b = (_a = nodeStack.pop()) === null || _a === void 0 ? void 0 : _a.refNode) !== null && _b !== void 0 ? _b : null;
|
|
43
43
|
cleanUpRestNodes(node, context.rewriteFromModel);
|
|
44
44
|
}
|
|
45
|
+
if (leavingParent && nodeStack[0].node == leavingParent) {
|
|
46
|
+
// When leaving a parent node that is the same with the root of node stack
|
|
47
|
+
// It means the whole list node stack is being invalidated, so we clear it
|
|
48
|
+
while (nodeStack.length > 0) {
|
|
49
|
+
nodeStack.pop();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
45
52
|
}
|
|
46
53
|
}
|
|
47
54
|
//# sourceMappingURL=handleBlockGroupChildren.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handleBlockGroupChildren.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/handlers/handleBlockGroupChildren.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAQ7D;;GAEG;AACH,MAAM,CAAC,IAAM,wBAAwB,GAAgD,UACjF,GAAa,EACb,MAAY,EACZ,KAA6B,EAC7B,OAA0B;IAElB,IAAA,UAAU,GAAK,OAAO,WAAZ,CAAa;IAC/B,IAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC;IACvC,IAAI,OAAO,GAAgB,MAAM,CAAC,UAAU,CAAC;IAE7C,IAAI;QACA,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,UAAC,UAAU,EAAE,KAAK;;YACnC,2CAA2C;YAC3C,wEAAwE;YACxE,sFAAsF;YACtF,+FAA+F;YAC/F,IACI,KAAK,IAAI,CAAC;gBACV,UAAU,CAAC,SAAS,IAAI,YAAY;gBACpC,UAAU,CAAC,cAAc,IAAI,UAAU,EACzC;gBACE,gBAAgB,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;gBAEhD,IAAI,UAAU,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;oBACjC,UAAU,CAAC,SAAS,GAAG,EAAE,CAAC;iBAC7B;aACJ;YAED,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAEjF,IAAI,UAAU,CAAC,SAAS,IAAI,QAAQ,EAAE;gBAClC,MAAA,OAAO,CAAC,UAAU,0CAAE,aAAa,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;aACxD;QACL,CAAC,CAAC,CAAC;QAEH,gBAAgB,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"handleBlockGroupChildren.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-dom/lib/modelToDom/handlers/handleBlockGroupChildren.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAQ7D;;GAEG;AACH,MAAM,CAAC,IAAM,wBAAwB,GAAgD,UACjF,GAAa,EACb,MAAY,EACZ,KAA6B,EAC7B,OAA0B;IAElB,IAAA,UAAU,GAAK,OAAO,WAAZ,CAAa;IAC/B,IAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC;IACvC,IAAI,OAAO,GAAgB,MAAM,CAAC,UAAU,CAAC;IAE7C,IAAI;QACA,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,UAAC,UAAU,EAAE,KAAK;;YACnC,2CAA2C;YAC3C,wEAAwE;YACxE,sFAAsF;YACtF,+FAA+F;YAC/F,IACI,KAAK,IAAI,CAAC;gBACV,UAAU,CAAC,SAAS,IAAI,YAAY;gBACpC,UAAU,CAAC,cAAc,IAAI,UAAU,EACzC;gBACE,gBAAgB,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;gBAEhD,IAAI,UAAU,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;oBACjC,UAAU,CAAC,SAAS,GAAG,EAAE,CAAC;iBAC7B;aACJ;YAED,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAEjF,IAAI,UAAU,CAAC,SAAS,IAAI,QAAQ,EAAE;gBAClC,MAAA,OAAO,CAAC,UAAU,0CAAE,aAAa,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;aACxD;QACL,CAAC,CAAC,CAAC;QAEH,gBAAgB,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAExD,uEAAuE;QACvE,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;KACvD;YAAS;QACN,UAAU,CAAC,SAAS,GAAG,SAAS,CAAC;KACpC;AACL,CAAC,CAAC;AAEF,SAAS,gBAAgB,CACrB,SAAoC,EACpC,OAA0B,EAC1B,aAAoB;;IAEpB,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;QACtB,qFAAqF;QACrF,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC3C,IAAM,IAAI,GAAG,MAAA,MAAA,SAAS,CAAC,GAAG,EAAE,0CAAE,OAAO,mCAAI,IAAI,CAAC;YAE9C,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;SACpD;QAED,IAAI,aAAa,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,aAAa,EAAE;YACrD,0EAA0E;YAC1E,0EAA0E;YAC1E,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;gBACzB,SAAS,CAAC,GAAG,EAAE,CAAC;aACnB;SACJ;KACJ;AACL,CAAC","sourcesContent":["import { cleanUpRestNodes } from '../utils/cleanUpRestNodes';\nimport type {\n ContentModelBlockGroup,\n ContentModelHandler,\n ModelToDomContext,\n ModelToDomListStackItem,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n */\nexport const handleBlockGroupChildren: ContentModelHandler<ContentModelBlockGroup> = (\n doc: Document,\n parent: Node,\n group: ContentModelBlockGroup,\n context: ModelToDomContext\n) => {\n const { listFormat } = context;\n const nodeStack = listFormat.nodeStack;\n let refNode: Node | null = parent.firstChild;\n\n try {\n group.blocks.forEach((childBlock, index) => {\n // When process list, we need a node stack.\n // When there are two continuous lists, they should share the same stack\n // so that list items with same type/threadId can be merged into the same list element\n // In other cases, clear the stack so that two separate lists won't share the same list element\n if (\n index == 0 ||\n childBlock.blockType != 'BlockGroup' ||\n childBlock.blockGroupType != 'ListItem'\n ) {\n cleanUpNodeStack(listFormat.nodeStack, context);\n\n if (listFormat.nodeStack.length > 0) {\n listFormat.nodeStack = [];\n }\n }\n\n refNode = context.modelHandlers.block(doc, parent, childBlock, context, refNode);\n\n if (childBlock.blockType == 'Entity') {\n context.domIndexer?.onBlockEntity(childBlock, group);\n }\n });\n\n cleanUpNodeStack(listFormat.nodeStack, context, parent);\n\n // Remove all rest node if any since they don't appear in content model\n cleanUpRestNodes(refNode, context.rewriteFromModel);\n } finally {\n listFormat.nodeStack = nodeStack;\n }\n};\n\nfunction cleanUpNodeStack(\n nodeStack: ModelToDomListStackItem[],\n context: ModelToDomContext,\n leavingParent?: Node\n) {\n if (nodeStack.length > 0) {\n // Clear list stack, only run to nodeStack[1] because nodeStack[0] is the parent node\n for (let i = nodeStack.length - 1; i > 0; i--) {\n const node = nodeStack.pop()?.refNode ?? null;\n\n cleanUpRestNodes(node, context.rewriteFromModel);\n }\n\n if (leavingParent && nodeStack[0].node == leavingParent) {\n // When leaving a parent node that is the same with the root of node stack\n // It means the whole list node stack is being invalidated, so we clear it\n while (nodeStack.length > 0) {\n nodeStack.pop();\n }\n }\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
"description": "Content Model for roosterjs",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"tslib": "^2.3.1",
|
|
6
|
-
"roosterjs-content-model-types": "^9.
|
|
6
|
+
"roosterjs-content-model-types": "^9.54.0"
|
|
7
7
|
},
|
|
8
|
-
"version": "9.
|
|
8
|
+
"version": "9.54.0",
|
|
9
9
|
"main": "./lib/index.js",
|
|
10
10
|
"typings": "./lib/index.d.ts",
|
|
11
11
|
"module": "./lib-mjs/index.js",
|