roosterjs-content-model-core 9.11.1 → 9.12.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.
@@ -249,8 +249,8 @@ var DomIndexerImpl = /** @class */ (function () {
249
249
  };
250
250
  DomIndexerImpl.prototype.reconcileTextSelection = function (textNode, startOffset, endOffset) {
251
251
  var _a;
252
- var _b;
253
- var _c = textNode.__roosterjsContentModel, paragraph = _c.paragraph, segments = _c.segments;
252
+ var _b, _c;
253
+ var _d = textNode.__roosterjsContentModel, paragraph = _d.paragraph, segments = _d.segments;
254
254
  var first = segments[0];
255
255
  var last = segments[segments.length - 1];
256
256
  var selectable;
@@ -272,6 +272,14 @@ var DomIndexerImpl = /** @class */ (function () {
272
272
  if (endOffset === undefined) {
273
273
  var marker = (0, roosterjs_content_model_dom_1.createSelectionMarker)(first.format);
274
274
  newSegments.push(marker);
275
+ if (startOffset < ((_b = textNode.nodeValue) !== null && _b !== void 0 ? _b : '').length) {
276
+ if (first.link) {
277
+ (0, roosterjs_content_model_dom_1.addLink)(marker, first.link);
278
+ }
279
+ if (first.code) {
280
+ (0, roosterjs_content_model_dom_1.addCode)(marker, first.code);
281
+ }
282
+ }
275
283
  selectable = marker;
276
284
  endOffset = startOffset;
277
285
  }
@@ -313,7 +321,7 @@ var DomIndexerImpl = /** @class */ (function () {
313
321
  var isBefore = wrapper.previousSibling == delimiter;
314
322
  var isAfter = wrapper.nextSibling == delimiter;
315
323
  if (index >= 0 && delimiter && (0, roosterjs_content_model_dom_1.isEntityDelimiter)(delimiter) && (isBefore || isAfter)) {
316
- var marker = (0, roosterjs_content_model_dom_1.createSelectionMarker)(((_b = paragraph.segments[isAfter ? index + 1 : index - 1]) !== null && _b !== void 0 ? _b : first).format);
324
+ var marker = (0, roosterjs_content_model_dom_1.createSelectionMarker)(((_c = paragraph.segments[isAfter ? index + 1 : index - 1]) !== null && _c !== void 0 ? _c : first).format);
317
325
  paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);
318
326
  selectable = marker;
319
327
  }
@@ -1 +1 @@
1
- {"version":3,"file":"domIndexerImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/domIndexerImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n EmptySegmentFormat,\n createParagraph,\n createSelectionMarker,\n createText,\n getObjectKeys,\n isElementOfType,\n isEntityDelimiter,\n isNodeOfType,\n setSelection,\n} from 'roosterjs-content-model-dom';\nimport type {\n CacheSelection,\n ContentModelBlockGroup,\n ContentModelDocument,\n ContentModelEntity,\n ContentModelParagraph,\n ContentModelSegment,\n ContentModelSegmentFormat,\n ContentModelSelectionMarker,\n ContentModelTable,\n ContentModelText,\n DomIndexer,\n DOMSelection,\n RangeSelectionForCache,\n Selectable,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal Export for test only\n */\nexport interface SegmentItem {\n paragraph: ContentModelParagraph;\n segments: ContentModelSegment[];\n}\n\n/**\n * @internal Export for test only\n */\nexport interface TableItem {\n table: ContentModelTable;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface BlockEntityDelimiterItem {\n entity: ContentModelEntity;\n parent: ContentModelBlockGroup;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedSegmentNode extends Node {\n __roosterjsContentModel: SegmentItem;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedTableElement extends HTMLTableElement {\n __roosterjsContentModel: TableItem;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedEntityDelimiter extends Text {\n __roosterjsContentModel: BlockEntityDelimiterItem;\n}\n\n/**\n * Context object used by DomIndexer when reconcile mutations with child list\n */\ninterface ReconcileChildListContext {\n /**\n * Index of segment in current paragraph\n */\n segIndex: number;\n\n /**\n * The current paragraph that we are handling\n */\n paragraph?: ContentModelParagraph;\n\n /**\n * Text node that is added from mutation but has not been handled. This can happen when we first see an added node then later we see a removed one.\n * e.g. Type text in an empty paragraph (&lt;div&gt;&lt;br&gt;&lt;/div&gt;), so a text node will be added and &lt;BR&gt; will be removed.\n * Set to a valid text node means we need to handle it later. If it is finally not handled, that means we need to clear cache\n * Set to undefined (initial value) means no pending text node is hit yet (valid case)\n * Set to null means there was a pending text node which is already handled, so if we see another pending text node,\n * we should clear cache since we don't know how to handle it\n */\n pendingTextNode?: Text | null;\n\n /**\n * Format of the removed segment, this will be used as the format for newly created segment\n */\n format?: ContentModelSegmentFormat;\n}\n\nfunction isIndexedSegment(node: Node): node is IndexedSegmentNode {\n const { paragraph, segments } = (node as IndexedSegmentNode).__roosterjsContentModel ?? {};\n\n return (\n paragraph &&\n paragraph.blockType == 'Paragraph' &&\n Array.isArray(paragraph.segments) &&\n Array.isArray(segments)\n );\n}\n\nfunction isIndexedDelimiter(node: Node): node is IndexedEntityDelimiter {\n const { entity, parent } = (node as IndexedEntityDelimiter).__roosterjsContentModel ?? {};\n\n return (\n entity?.blockType == 'Entity' &&\n entity.wrapper &&\n parent?.blockGroupType &&\n Array.isArray(parent.blocks)\n );\n}\n\nfunction getIndexedSegmentItem(node: Node | null): SegmentItem | null {\n return node && isIndexedSegment(node) ? node.__roosterjsContentModel : null;\n}\n\nfunction getIndexedTableItem(element: HTMLTableElement): TableItem | null {\n const index = (element as IndexedTableElement).__roosterjsContentModel;\n const table = index?.table;\n\n if (\n table?.blockType == 'Table' &&\n Array.isArray(table.rows) &&\n table.rows.every(\n x => Array.isArray(x?.cells) && x.cells.every(y => y?.blockGroupType == 'TableCell')\n )\n ) {\n return index;\n } else {\n return null;\n }\n}\n\n/**\n * @internal\n * Implementation of DomIndexer\n */\nexport class DomIndexerImpl implements DomIndexer {\n constructor(private readonly persistCache?: boolean) {}\n\n onSegment(segmentNode: Node, paragraph: ContentModelParagraph, segment: ContentModelSegment[]) {\n const indexedText = segmentNode as IndexedSegmentNode;\n indexedText.__roosterjsContentModel = {\n paragraph,\n segments: segment,\n };\n }\n\n onParagraph(paragraphElement: HTMLElement) {\n let previousText: Text | null = null;\n\n for (let child = paragraphElement.firstChild; child; child = child.nextSibling) {\n if (isNodeOfType(child, 'TEXT_NODE')) {\n if (!previousText) {\n previousText = child;\n } else {\n const item = getIndexedSegmentItem(previousText);\n\n if (item && isIndexedSegment(child)) {\n item.segments = item.segments.concat(\n child.__roosterjsContentModel.segments\n );\n child.__roosterjsContentModel.segments = [];\n }\n }\n } else if (isNodeOfType(child, 'ELEMENT_NODE')) {\n previousText = null;\n\n this.onParagraph(child);\n } else {\n previousText = null;\n }\n }\n }\n\n onTable(tableElement: HTMLTableElement, table: ContentModelTable) {\n const indexedTable = tableElement as IndexedTableElement;\n indexedTable.__roosterjsContentModel = { table };\n }\n\n onBlockEntity(entity: ContentModelEntity, group: ContentModelBlockGroup) {\n this.onBlockEntityDelimiter(entity.wrapper.previousSibling, entity, group);\n this.onBlockEntityDelimiter(entity.wrapper.nextSibling, entity, group);\n }\n\n reconcileSelection(\n model: ContentModelDocument,\n newSelection: DOMSelection,\n oldSelection?: CacheSelection\n ): boolean {\n if (oldSelection) {\n if (\n oldSelection.type == 'range' &&\n this.isCollapsed(oldSelection) &&\n isNodeOfType(oldSelection.start.node, 'TEXT_NODE') &&\n isIndexedSegment(oldSelection.start.node)\n ) {\n this.reconcileTextSelection(oldSelection.start.node);\n } else {\n setSelection(model);\n }\n }\n\n switch (newSelection.type) {\n case 'image':\n const indexedImage = getIndexedSegmentItem(newSelection.image);\n const image = indexedImage?.segments[0];\n\n if (image) {\n image.isSelected = true;\n setSelection(model, image);\n\n return true;\n } else {\n return false;\n }\n\n case 'table':\n const indexedTable = getIndexedTableItem(newSelection.table);\n\n if (indexedTable) {\n const firstCell =\n indexedTable.table.rows[newSelection.firstRow]?.cells[\n newSelection.firstColumn\n ];\n const lastCell =\n indexedTable.table.rows[newSelection.lastRow]?.cells[\n newSelection.lastColumn\n ];\n\n if (firstCell && lastCell) {\n setSelection(model, firstCell, lastCell);\n\n return true;\n }\n }\n\n return false;\n\n case 'range':\n const newRange = newSelection.range;\n if (newRange) {\n const {\n startContainer,\n startOffset,\n endContainer,\n endOffset,\n collapsed,\n } = newRange;\n\n delete model.hasRevertedRangeSelection;\n\n if (collapsed) {\n return !!this.reconcileNodeSelection(\n startContainer,\n startOffset,\n model.format\n );\n } else if (\n startContainer == endContainer &&\n isNodeOfType(startContainer, 'TEXT_NODE')\n ) {\n if (newSelection.isReverted) {\n model.hasRevertedRangeSelection = true;\n }\n\n return (\n isIndexedSegment(startContainer) &&\n !!this.reconcileTextSelection(startContainer, startOffset, endOffset)\n );\n } else {\n const marker1 = this.reconcileNodeSelection(startContainer, startOffset);\n const marker2 = this.reconcileNodeSelection(endContainer, endOffset);\n\n if (marker1 && marker2) {\n if (newSelection.isReverted) {\n model.hasRevertedRangeSelection = true;\n }\n\n setSelection(model, marker1, marker2);\n return true;\n } else {\n return false;\n }\n }\n }\n\n break;\n }\n\n return false;\n }\n\n reconcileChildList(addedNodes: ArrayLike<Node>, removedNodes: ArrayLike<Node>): boolean {\n if (!this.persistCache) {\n return false;\n }\n\n let canHandle = true;\n const context: ReconcileChildListContext = {\n segIndex: -1,\n };\n\n // First process added nodes\n const addedNode = addedNodes[0];\n\n if (addedNodes.length == 1 && isNodeOfType(addedNode, 'TEXT_NODE')) {\n canHandle = this.reconcileAddedNode(addedNode, context);\n } else if (addedNodes.length > 0) {\n canHandle = false;\n }\n\n // Second, process removed nodes\n const removedNode = removedNodes[0];\n\n if (canHandle && removedNodes.length == 1) {\n canHandle = this.reconcileRemovedNode(removedNode, context);\n } else if (removedNodes.length > 0) {\n canHandle = false;\n }\n\n return canHandle && !context.pendingTextNode;\n }\n\n reconcileElementId(element: HTMLElement) {\n if (isElementOfType(element, 'img')) {\n const indexedImg = getIndexedSegmentItem(element);\n\n if (indexedImg?.segments[0]?.segmentType == 'Image') {\n indexedImg.segments[0].format.id = element.id;\n\n return true;\n } else {\n return false;\n }\n } else if (isElementOfType(element, 'table')) {\n const indexedTable = getIndexedTableItem(element);\n\n if (indexedTable) {\n indexedTable.table.format.id = element.id;\n\n return true;\n } else {\n return false;\n }\n } else {\n return false;\n }\n }\n\n private onBlockEntityDelimiter(\n node: Node | null,\n entity: ContentModelEntity,\n parent: ContentModelBlockGroup\n ) {\n if (isNodeOfType(node, 'ELEMENT_NODE') && isEntityDelimiter(node) && node.firstChild) {\n const indexedDelimiter = node.firstChild as IndexedEntityDelimiter;\n\n indexedDelimiter.__roosterjsContentModel = { entity, parent };\n }\n }\n\n private isCollapsed(selection: RangeSelectionForCache): boolean {\n const { start, end } = selection;\n\n return start.node == end.node && start.offset == end.offset;\n }\n\n private reconcileNodeSelection(\n node: Node,\n offset: number,\n defaultFormat?: ContentModelSegmentFormat\n ): Selectable | undefined {\n if (isNodeOfType(node, 'TEXT_NODE')) {\n if (isIndexedSegment(node)) {\n return this.reconcileTextSelection(node, offset);\n } else if (isIndexedDelimiter(node)) {\n return this.reconcileDelimiterSelection(node, defaultFormat);\n } else {\n return undefined;\n }\n } else if (offset >= node.childNodes.length) {\n return this.insertMarker(node.lastChild, true /*isAfter*/);\n } else {\n return this.insertMarker(node.childNodes[offset], false /*isAfter*/);\n }\n }\n\n private insertMarker(node: Node | null, isAfter: boolean): Selectable | undefined {\n let marker: ContentModelSelectionMarker | undefined;\n const segmentItem = node && getIndexedSegmentItem(node);\n\n if (segmentItem) {\n const { paragraph, segments } = segmentItem;\n const index = paragraph.segments.indexOf(segments[0]);\n\n if (index >= 0) {\n const formatSegment =\n (!isAfter && paragraph.segments[index - 1]) || paragraph.segments[index];\n marker = createSelectionMarker(formatSegment.format);\n\n paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);\n }\n }\n\n return marker;\n }\n\n private reconcileTextSelection(\n textNode: IndexedSegmentNode,\n startOffset?: number,\n endOffset?: number\n ) {\n const { paragraph, segments } = textNode.__roosterjsContentModel;\n const first = segments[0];\n const last = segments[segments.length - 1];\n let selectable: Selectable | undefined;\n\n if (first?.segmentType == 'Text' && last?.segmentType == 'Text') {\n const newSegments: ContentModelSegment[] = [];\n const txt = textNode.nodeValue || '';\n const textSegments: ContentModelText[] = [];\n\n if (startOffset === undefined) {\n first.text = txt;\n newSegments.push(first);\n textSegments.push(first);\n } else {\n if (startOffset > 0) {\n first.text = txt.substring(0, startOffset);\n newSegments.push(first);\n textSegments.push(first);\n }\n\n if (endOffset === undefined) {\n const marker = createSelectionMarker(first.format);\n newSegments.push(marker);\n\n selectable = marker;\n endOffset = startOffset;\n } else if (endOffset > startOffset) {\n const middle = createText(\n txt.substring(startOffset, endOffset),\n first.format,\n first.link,\n first.code\n );\n\n middle.isSelected = true;\n newSegments.push(middle);\n textSegments.push(middle);\n selectable = middle;\n }\n\n if (endOffset < txt.length) {\n const newLast = createText(\n txt.substring(endOffset),\n first.format,\n first.link,\n first.code\n );\n newSegments.push(newLast);\n textSegments.push(newLast);\n }\n }\n\n let firstIndex = paragraph.segments.indexOf(first);\n let lastIndex = paragraph.segments.indexOf(last);\n\n if (firstIndex >= 0 && lastIndex >= 0) {\n while (\n firstIndex > 0 &&\n paragraph.segments[firstIndex - 1].segmentType == 'SelectionMarker'\n ) {\n firstIndex--;\n }\n\n while (\n lastIndex < paragraph.segments.length - 1 &&\n paragraph.segments[lastIndex + 1].segmentType == 'SelectionMarker'\n ) {\n lastIndex++;\n }\n\n paragraph.segments.splice(firstIndex, lastIndex - firstIndex + 1, ...newSegments);\n }\n\n this.onSegment(textNode, paragraph, textSegments);\n\n if (!this.persistCache) {\n delete paragraph.cachedElement;\n }\n } else if (first?.segmentType == 'Entity' && first == last) {\n const wrapper = first.wrapper;\n const index = paragraph.segments.indexOf(first);\n const delimiter = textNode.parentElement;\n const isBefore = wrapper.previousSibling == delimiter;\n const isAfter = wrapper.nextSibling == delimiter;\n\n if (index >= 0 && delimiter && isEntityDelimiter(delimiter) && (isBefore || isAfter)) {\n const marker = createSelectionMarker(\n (paragraph.segments[isAfter ? index + 1 : index - 1] ?? first).format\n );\n\n paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);\n\n selectable = marker;\n }\n }\n\n return selectable;\n }\n\n private reconcileDelimiterSelection(\n node: IndexedEntityDelimiter,\n defaultFormat?: ContentModelSegmentFormat\n ) {\n let marker: ContentModelSelectionMarker | undefined;\n\n const { entity, parent } = node.__roosterjsContentModel;\n const index = parent.blocks.indexOf(entity);\n const delimiter = node.parentElement;\n const wrapper = entity.wrapper;\n const isBefore = wrapper.previousSibling == delimiter;\n const isAfter = wrapper.nextSibling == delimiter;\n\n if (index >= 0 && delimiter && isEntityDelimiter(delimiter) && (isBefore || isAfter)) {\n marker = createSelectionMarker(defaultFormat);\n\n const para = createParagraph(\n true /*isImplicit*/,\n undefined /*blockFormat*/,\n defaultFormat\n );\n\n para.segments.push(marker);\n parent.blocks.splice(isBefore ? index : index + 1, 0, para);\n }\n\n return marker;\n }\n\n private reconcileAddedNode(node: Text, context: ReconcileChildListContext): boolean {\n let segmentItem: SegmentItem | null = null;\n let index = -1;\n let existingSegment: ContentModelSegment;\n const { previousSibling, nextSibling } = node;\n\n if (\n (segmentItem = getIndexedSegmentItem(previousSibling)) &&\n (existingSegment = segmentItem.segments[segmentItem.segments.length - 1]) &&\n (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0\n ) {\n // When we can find indexed segment before current one, use it as the insert index\n this.indexNode(segmentItem.paragraph, index + 1, node, existingSegment.format);\n } else if (\n (segmentItem = getIndexedSegmentItem(nextSibling)) &&\n (existingSegment = segmentItem.segments[0]) &&\n (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0\n ) {\n // When we can find indexed segment after current one, use it as the insert index\n this.indexNode(segmentItem.paragraph, index, node, existingSegment.format);\n } else if (context.paragraph && context.segIndex >= 0) {\n // When there is indexed paragraph from removed nodes, we can use it as the insert index\n this.indexNode(context.paragraph, context.segIndex, node, context.format);\n } else if (context.pendingTextNode === undefined) {\n // When we can't find the insert index, set current node as pending node\n // so later we can pick it up when we have enough info when processing removed node\n // Only do this when pendingTextNode is undefined. If it is null it means there was already a pending node before\n // and in that case we should return false since we can't handle two pending text node\n context.pendingTextNode = node;\n } else {\n return false;\n }\n\n return true;\n }\n\n private reconcileRemovedNode(node: Node, context: ReconcileChildListContext): boolean {\n let segmentItem: SegmentItem | null = null;\n let removingSegment: ContentModelSegment;\n\n if (\n context.segIndex < 0 &&\n !context.paragraph && // No previous removed segment or related paragraph found, and\n (segmentItem = getIndexedSegmentItem(node)) && // The removed node is indexed, and\n (removingSegment = segmentItem.segments[0]) // There is at least one related segment\n ) {\n // Now we can remove the indexed segment from the paragraph, and remember it, later we may need to use it\n context.format = removingSegment.format;\n context.paragraph = segmentItem.paragraph;\n context.segIndex = segmentItem.paragraph.segments.indexOf(segmentItem.segments[0]);\n\n if (context.segIndex < 0) {\n // Indexed segment is not under paragraph, something wrong happens, we cannot keep handling\n return false;\n }\n\n for (let i = 0; i < segmentItem.segments.length; i++) {\n const index = segmentItem.paragraph.segments.indexOf(segmentItem.segments[i]);\n\n if (index >= 0) {\n segmentItem.paragraph.segments.splice(index, 1);\n }\n }\n\n if (context.pendingTextNode) {\n // If we have pending text node added but not indexed, do it now\n this.indexNode(\n context.paragraph,\n context.segIndex,\n context.pendingTextNode,\n segmentItem.segments[0].format\n );\n\n // Set to null since we have processed it.\n // Next time we see a pending node we know we have already processed one so it is a situation we cannot handle\n context.pendingTextNode = null;\n }\n\n return true;\n } else {\n return false;\n }\n }\n\n private indexNode(\n paragraph: ContentModelParagraph,\n index: number,\n textNode: Text,\n format?: ContentModelSegmentFormat\n ) {\n const copiedFormat = format ? { ...format } : undefined;\n\n if (copiedFormat) {\n getObjectKeys(copiedFormat).forEach(key => {\n if (EmptySegmentFormat[key] === undefined) {\n delete copiedFormat[key];\n }\n });\n }\n\n const text = createText(textNode.textContent ?? '', copiedFormat);\n\n paragraph.segments.splice(index, 0, text);\n this.onSegment(textNode, paragraph, [text]);\n }\n}\n"]}
1
+ {"version":3,"file":"domIndexerImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/domIndexerImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n EmptySegmentFormat,\n addCode,\n addLink,\n createParagraph,\n createSelectionMarker,\n createText,\n getObjectKeys,\n isElementOfType,\n isEntityDelimiter,\n isNodeOfType,\n setSelection,\n} from 'roosterjs-content-model-dom';\nimport type {\n CacheSelection,\n ContentModelBlockGroup,\n ContentModelDocument,\n ContentModelEntity,\n ContentModelParagraph,\n ContentModelSegment,\n ContentModelSegmentFormat,\n ContentModelSelectionMarker,\n ContentModelTable,\n ContentModelText,\n DomIndexer,\n DOMSelection,\n RangeSelectionForCache,\n Selectable,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal Export for test only\n */\nexport interface SegmentItem {\n paragraph: ContentModelParagraph;\n segments: ContentModelSegment[];\n}\n\n/**\n * @internal Export for test only\n */\nexport interface TableItem {\n table: ContentModelTable;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface BlockEntityDelimiterItem {\n entity: ContentModelEntity;\n parent: ContentModelBlockGroup;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedSegmentNode extends Node {\n __roosterjsContentModel: SegmentItem;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedTableElement extends HTMLTableElement {\n __roosterjsContentModel: TableItem;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedEntityDelimiter extends Text {\n __roosterjsContentModel: BlockEntityDelimiterItem;\n}\n\n/**\n * Context object used by DomIndexer when reconcile mutations with child list\n */\ninterface ReconcileChildListContext {\n /**\n * Index of segment in current paragraph\n */\n segIndex: number;\n\n /**\n * The current paragraph that we are handling\n */\n paragraph?: ContentModelParagraph;\n\n /**\n * Text node that is added from mutation but has not been handled. This can happen when we first see an added node then later we see a removed one.\n * e.g. Type text in an empty paragraph (&lt;div&gt;&lt;br&gt;&lt;/div&gt;), so a text node will be added and &lt;BR&gt; will be removed.\n * Set to a valid text node means we need to handle it later. If it is finally not handled, that means we need to clear cache\n * Set to undefined (initial value) means no pending text node is hit yet (valid case)\n * Set to null means there was a pending text node which is already handled, so if we see another pending text node,\n * we should clear cache since we don't know how to handle it\n */\n pendingTextNode?: Text | null;\n\n /**\n * Format of the removed segment, this will be used as the format for newly created segment\n */\n format?: ContentModelSegmentFormat;\n}\n\nfunction isIndexedSegment(node: Node): node is IndexedSegmentNode {\n const { paragraph, segments } = (node as IndexedSegmentNode).__roosterjsContentModel ?? {};\n\n return (\n paragraph &&\n paragraph.blockType == 'Paragraph' &&\n Array.isArray(paragraph.segments) &&\n Array.isArray(segments)\n );\n}\n\nfunction isIndexedDelimiter(node: Node): node is IndexedEntityDelimiter {\n const { entity, parent } = (node as IndexedEntityDelimiter).__roosterjsContentModel ?? {};\n\n return (\n entity?.blockType == 'Entity' &&\n entity.wrapper &&\n parent?.blockGroupType &&\n Array.isArray(parent.blocks)\n );\n}\n\nfunction getIndexedSegmentItem(node: Node | null): SegmentItem | null {\n return node && isIndexedSegment(node) ? node.__roosterjsContentModel : null;\n}\n\nfunction getIndexedTableItem(element: HTMLTableElement): TableItem | null {\n const index = (element as IndexedTableElement).__roosterjsContentModel;\n const table = index?.table;\n\n if (\n table?.blockType == 'Table' &&\n Array.isArray(table.rows) &&\n table.rows.every(\n x => Array.isArray(x?.cells) && x.cells.every(y => y?.blockGroupType == 'TableCell')\n )\n ) {\n return index;\n } else {\n return null;\n }\n}\n\n/**\n * @internal\n * Implementation of DomIndexer\n */\nexport class DomIndexerImpl implements DomIndexer {\n constructor(private readonly persistCache?: boolean) {}\n\n onSegment(segmentNode: Node, paragraph: ContentModelParagraph, segment: ContentModelSegment[]) {\n const indexedText = segmentNode as IndexedSegmentNode;\n indexedText.__roosterjsContentModel = {\n paragraph,\n segments: segment,\n };\n }\n\n onParagraph(paragraphElement: HTMLElement) {\n let previousText: Text | null = null;\n\n for (let child = paragraphElement.firstChild; child; child = child.nextSibling) {\n if (isNodeOfType(child, 'TEXT_NODE')) {\n if (!previousText) {\n previousText = child;\n } else {\n const item = getIndexedSegmentItem(previousText);\n\n if (item && isIndexedSegment(child)) {\n item.segments = item.segments.concat(\n child.__roosterjsContentModel.segments\n );\n child.__roosterjsContentModel.segments = [];\n }\n }\n } else if (isNodeOfType(child, 'ELEMENT_NODE')) {\n previousText = null;\n\n this.onParagraph(child);\n } else {\n previousText = null;\n }\n }\n }\n\n onTable(tableElement: HTMLTableElement, table: ContentModelTable) {\n const indexedTable = tableElement as IndexedTableElement;\n indexedTable.__roosterjsContentModel = { table };\n }\n\n onBlockEntity(entity: ContentModelEntity, group: ContentModelBlockGroup) {\n this.onBlockEntityDelimiter(entity.wrapper.previousSibling, entity, group);\n this.onBlockEntityDelimiter(entity.wrapper.nextSibling, entity, group);\n }\n\n reconcileSelection(\n model: ContentModelDocument,\n newSelection: DOMSelection,\n oldSelection?: CacheSelection\n ): boolean {\n if (oldSelection) {\n if (\n oldSelection.type == 'range' &&\n this.isCollapsed(oldSelection) &&\n isNodeOfType(oldSelection.start.node, 'TEXT_NODE') &&\n isIndexedSegment(oldSelection.start.node)\n ) {\n this.reconcileTextSelection(oldSelection.start.node);\n } else {\n setSelection(model);\n }\n }\n\n switch (newSelection.type) {\n case 'image':\n const indexedImage = getIndexedSegmentItem(newSelection.image);\n const image = indexedImage?.segments[0];\n\n if (image) {\n image.isSelected = true;\n setSelection(model, image);\n\n return true;\n } else {\n return false;\n }\n\n case 'table':\n const indexedTable = getIndexedTableItem(newSelection.table);\n\n if (indexedTable) {\n const firstCell =\n indexedTable.table.rows[newSelection.firstRow]?.cells[\n newSelection.firstColumn\n ];\n const lastCell =\n indexedTable.table.rows[newSelection.lastRow]?.cells[\n newSelection.lastColumn\n ];\n\n if (firstCell && lastCell) {\n setSelection(model, firstCell, lastCell);\n\n return true;\n }\n }\n\n return false;\n\n case 'range':\n const newRange = newSelection.range;\n if (newRange) {\n const {\n startContainer,\n startOffset,\n endContainer,\n endOffset,\n collapsed,\n } = newRange;\n\n delete model.hasRevertedRangeSelection;\n\n if (collapsed) {\n return !!this.reconcileNodeSelection(\n startContainer,\n startOffset,\n model.format\n );\n } else if (\n startContainer == endContainer &&\n isNodeOfType(startContainer, 'TEXT_NODE')\n ) {\n if (newSelection.isReverted) {\n model.hasRevertedRangeSelection = true;\n }\n\n return (\n isIndexedSegment(startContainer) &&\n !!this.reconcileTextSelection(startContainer, startOffset, endOffset)\n );\n } else {\n const marker1 = this.reconcileNodeSelection(startContainer, startOffset);\n const marker2 = this.reconcileNodeSelection(endContainer, endOffset);\n\n if (marker1 && marker2) {\n if (newSelection.isReverted) {\n model.hasRevertedRangeSelection = true;\n }\n\n setSelection(model, marker1, marker2);\n return true;\n } else {\n return false;\n }\n }\n }\n\n break;\n }\n\n return false;\n }\n\n reconcileChildList(addedNodes: ArrayLike<Node>, removedNodes: ArrayLike<Node>): boolean {\n if (!this.persistCache) {\n return false;\n }\n\n let canHandle = true;\n const context: ReconcileChildListContext = {\n segIndex: -1,\n };\n\n // First process added nodes\n const addedNode = addedNodes[0];\n\n if (addedNodes.length == 1 && isNodeOfType(addedNode, 'TEXT_NODE')) {\n canHandle = this.reconcileAddedNode(addedNode, context);\n } else if (addedNodes.length > 0) {\n canHandle = false;\n }\n\n // Second, process removed nodes\n const removedNode = removedNodes[0];\n\n if (canHandle && removedNodes.length == 1) {\n canHandle = this.reconcileRemovedNode(removedNode, context);\n } else if (removedNodes.length > 0) {\n canHandle = false;\n }\n\n return canHandle && !context.pendingTextNode;\n }\n\n reconcileElementId(element: HTMLElement) {\n if (isElementOfType(element, 'img')) {\n const indexedImg = getIndexedSegmentItem(element);\n\n if (indexedImg?.segments[0]?.segmentType == 'Image') {\n indexedImg.segments[0].format.id = element.id;\n\n return true;\n } else {\n return false;\n }\n } else if (isElementOfType(element, 'table')) {\n const indexedTable = getIndexedTableItem(element);\n\n if (indexedTable) {\n indexedTable.table.format.id = element.id;\n\n return true;\n } else {\n return false;\n }\n } else {\n return false;\n }\n }\n\n private onBlockEntityDelimiter(\n node: Node | null,\n entity: ContentModelEntity,\n parent: ContentModelBlockGroup\n ) {\n if (isNodeOfType(node, 'ELEMENT_NODE') && isEntityDelimiter(node) && node.firstChild) {\n const indexedDelimiter = node.firstChild as IndexedEntityDelimiter;\n\n indexedDelimiter.__roosterjsContentModel = { entity, parent };\n }\n }\n\n private isCollapsed(selection: RangeSelectionForCache): boolean {\n const { start, end } = selection;\n\n return start.node == end.node && start.offset == end.offset;\n }\n\n private reconcileNodeSelection(\n node: Node,\n offset: number,\n defaultFormat?: ContentModelSegmentFormat\n ): Selectable | undefined {\n if (isNodeOfType(node, 'TEXT_NODE')) {\n if (isIndexedSegment(node)) {\n return this.reconcileTextSelection(node, offset);\n } else if (isIndexedDelimiter(node)) {\n return this.reconcileDelimiterSelection(node, defaultFormat);\n } else {\n return undefined;\n }\n } else if (offset >= node.childNodes.length) {\n return this.insertMarker(node.lastChild, true /*isAfter*/);\n } else {\n return this.insertMarker(node.childNodes[offset], false /*isAfter*/);\n }\n }\n\n private insertMarker(node: Node | null, isAfter: boolean): Selectable | undefined {\n let marker: ContentModelSelectionMarker | undefined;\n const segmentItem = node && getIndexedSegmentItem(node);\n\n if (segmentItem) {\n const { paragraph, segments } = segmentItem;\n const index = paragraph.segments.indexOf(segments[0]);\n\n if (index >= 0) {\n const formatSegment =\n (!isAfter && paragraph.segments[index - 1]) || paragraph.segments[index];\n marker = createSelectionMarker(formatSegment.format);\n\n paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);\n }\n }\n\n return marker;\n }\n\n private reconcileTextSelection(\n textNode: IndexedSegmentNode,\n startOffset?: number,\n endOffset?: number\n ) {\n const { paragraph, segments } = textNode.__roosterjsContentModel;\n const first = segments[0];\n const last = segments[segments.length - 1];\n let selectable: Selectable | undefined;\n\n if (first?.segmentType == 'Text' && last?.segmentType == 'Text') {\n const newSegments: ContentModelSegment[] = [];\n const txt = textNode.nodeValue || '';\n const textSegments: ContentModelText[] = [];\n\n if (startOffset === undefined) {\n first.text = txt;\n newSegments.push(first);\n textSegments.push(first);\n } else {\n if (startOffset > 0) {\n first.text = txt.substring(0, startOffset);\n newSegments.push(first);\n textSegments.push(first);\n }\n\n if (endOffset === undefined) {\n const marker = createSelectionMarker(first.format);\n newSegments.push(marker);\n\n if (startOffset < (textNode.nodeValue ?? '').length) {\n if (first.link) {\n addLink(marker, first.link);\n }\n\n if (first.code) {\n addCode(marker, first.code);\n }\n }\n\n selectable = marker;\n endOffset = startOffset;\n } else if (endOffset > startOffset) {\n const middle = createText(\n txt.substring(startOffset, endOffset),\n first.format,\n first.link,\n first.code\n );\n\n middle.isSelected = true;\n newSegments.push(middle);\n textSegments.push(middle);\n selectable = middle;\n }\n\n if (endOffset < txt.length) {\n const newLast = createText(\n txt.substring(endOffset),\n first.format,\n first.link,\n first.code\n );\n newSegments.push(newLast);\n textSegments.push(newLast);\n }\n }\n\n let firstIndex = paragraph.segments.indexOf(first);\n let lastIndex = paragraph.segments.indexOf(last);\n\n if (firstIndex >= 0 && lastIndex >= 0) {\n while (\n firstIndex > 0 &&\n paragraph.segments[firstIndex - 1].segmentType == 'SelectionMarker'\n ) {\n firstIndex--;\n }\n\n while (\n lastIndex < paragraph.segments.length - 1 &&\n paragraph.segments[lastIndex + 1].segmentType == 'SelectionMarker'\n ) {\n lastIndex++;\n }\n\n paragraph.segments.splice(firstIndex, lastIndex - firstIndex + 1, ...newSegments);\n }\n\n this.onSegment(textNode, paragraph, textSegments);\n\n if (!this.persistCache) {\n delete paragraph.cachedElement;\n }\n } else if (first?.segmentType == 'Entity' && first == last) {\n const wrapper = first.wrapper;\n const index = paragraph.segments.indexOf(first);\n const delimiter = textNode.parentElement;\n const isBefore = wrapper.previousSibling == delimiter;\n const isAfter = wrapper.nextSibling == delimiter;\n\n if (index >= 0 && delimiter && isEntityDelimiter(delimiter) && (isBefore || isAfter)) {\n const marker = createSelectionMarker(\n (paragraph.segments[isAfter ? index + 1 : index - 1] ?? first).format\n );\n\n paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);\n\n selectable = marker;\n }\n }\n\n return selectable;\n }\n\n private reconcileDelimiterSelection(\n node: IndexedEntityDelimiter,\n defaultFormat?: ContentModelSegmentFormat\n ) {\n let marker: ContentModelSelectionMarker | undefined;\n\n const { entity, parent } = node.__roosterjsContentModel;\n const index = parent.blocks.indexOf(entity);\n const delimiter = node.parentElement;\n const wrapper = entity.wrapper;\n const isBefore = wrapper.previousSibling == delimiter;\n const isAfter = wrapper.nextSibling == delimiter;\n\n if (index >= 0 && delimiter && isEntityDelimiter(delimiter) && (isBefore || isAfter)) {\n marker = createSelectionMarker(defaultFormat);\n\n const para = createParagraph(\n true /*isImplicit*/,\n undefined /*blockFormat*/,\n defaultFormat\n );\n\n para.segments.push(marker);\n parent.blocks.splice(isBefore ? index : index + 1, 0, para);\n }\n\n return marker;\n }\n\n private reconcileAddedNode(node: Text, context: ReconcileChildListContext): boolean {\n let segmentItem: SegmentItem | null = null;\n let index = -1;\n let existingSegment: ContentModelSegment;\n const { previousSibling, nextSibling } = node;\n\n if (\n (segmentItem = getIndexedSegmentItem(previousSibling)) &&\n (existingSegment = segmentItem.segments[segmentItem.segments.length - 1]) &&\n (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0\n ) {\n // When we can find indexed segment before current one, use it as the insert index\n this.indexNode(segmentItem.paragraph, index + 1, node, existingSegment.format);\n } else if (\n (segmentItem = getIndexedSegmentItem(nextSibling)) &&\n (existingSegment = segmentItem.segments[0]) &&\n (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0\n ) {\n // When we can find indexed segment after current one, use it as the insert index\n this.indexNode(segmentItem.paragraph, index, node, existingSegment.format);\n } else if (context.paragraph && context.segIndex >= 0) {\n // When there is indexed paragraph from removed nodes, we can use it as the insert index\n this.indexNode(context.paragraph, context.segIndex, node, context.format);\n } else if (context.pendingTextNode === undefined) {\n // When we can't find the insert index, set current node as pending node\n // so later we can pick it up when we have enough info when processing removed node\n // Only do this when pendingTextNode is undefined. If it is null it means there was already a pending node before\n // and in that case we should return false since we can't handle two pending text node\n context.pendingTextNode = node;\n } else {\n return false;\n }\n\n return true;\n }\n\n private reconcileRemovedNode(node: Node, context: ReconcileChildListContext): boolean {\n let segmentItem: SegmentItem | null = null;\n let removingSegment: ContentModelSegment;\n\n if (\n context.segIndex < 0 &&\n !context.paragraph && // No previous removed segment or related paragraph found, and\n (segmentItem = getIndexedSegmentItem(node)) && // The removed node is indexed, and\n (removingSegment = segmentItem.segments[0]) // There is at least one related segment\n ) {\n // Now we can remove the indexed segment from the paragraph, and remember it, later we may need to use it\n context.format = removingSegment.format;\n context.paragraph = segmentItem.paragraph;\n context.segIndex = segmentItem.paragraph.segments.indexOf(segmentItem.segments[0]);\n\n if (context.segIndex < 0) {\n // Indexed segment is not under paragraph, something wrong happens, we cannot keep handling\n return false;\n }\n\n for (let i = 0; i < segmentItem.segments.length; i++) {\n const index = segmentItem.paragraph.segments.indexOf(segmentItem.segments[i]);\n\n if (index >= 0) {\n segmentItem.paragraph.segments.splice(index, 1);\n }\n }\n\n if (context.pendingTextNode) {\n // If we have pending text node added but not indexed, do it now\n this.indexNode(\n context.paragraph,\n context.segIndex,\n context.pendingTextNode,\n segmentItem.segments[0].format\n );\n\n // Set to null since we have processed it.\n // Next time we see a pending node we know we have already processed one so it is a situation we cannot handle\n context.pendingTextNode = null;\n }\n\n return true;\n } else {\n return false;\n }\n }\n\n private indexNode(\n paragraph: ContentModelParagraph,\n index: number,\n textNode: Text,\n format?: ContentModelSegmentFormat\n ) {\n const copiedFormat = format ? { ...format } : undefined;\n\n if (copiedFormat) {\n getObjectKeys(copiedFormat).forEach(key => {\n if (EmptySegmentFormat[key] === undefined) {\n delete copiedFormat[key];\n }\n });\n }\n\n const text = createText(textNode.textContent ?? '', copiedFormat);\n\n paragraph.segments.splice(index, 0, text);\n this.onSegment(textNode, paragraph, [text]);\n }\n}\n"]}
@@ -248,8 +248,8 @@ define(["require", "exports", "tslib", "roosterjs-content-model-dom"], function
248
248
  };
249
249
  DomIndexerImpl.prototype.reconcileTextSelection = function (textNode, startOffset, endOffset) {
250
250
  var _a;
251
- var _b;
252
- var _c = textNode.__roosterjsContentModel, paragraph = _c.paragraph, segments = _c.segments;
251
+ var _b, _c;
252
+ var _d = textNode.__roosterjsContentModel, paragraph = _d.paragraph, segments = _d.segments;
253
253
  var first = segments[0];
254
254
  var last = segments[segments.length - 1];
255
255
  var selectable;
@@ -271,6 +271,14 @@ define(["require", "exports", "tslib", "roosterjs-content-model-dom"], function
271
271
  if (endOffset === undefined) {
272
272
  var marker = (0, roosterjs_content_model_dom_1.createSelectionMarker)(first.format);
273
273
  newSegments.push(marker);
274
+ if (startOffset < ((_b = textNode.nodeValue) !== null && _b !== void 0 ? _b : '').length) {
275
+ if (first.link) {
276
+ (0, roosterjs_content_model_dom_1.addLink)(marker, first.link);
277
+ }
278
+ if (first.code) {
279
+ (0, roosterjs_content_model_dom_1.addCode)(marker, first.code);
280
+ }
281
+ }
274
282
  selectable = marker;
275
283
  endOffset = startOffset;
276
284
  }
@@ -312,7 +320,7 @@ define(["require", "exports", "tslib", "roosterjs-content-model-dom"], function
312
320
  var isBefore = wrapper.previousSibling == delimiter;
313
321
  var isAfter = wrapper.nextSibling == delimiter;
314
322
  if (index >= 0 && delimiter && (0, roosterjs_content_model_dom_1.isEntityDelimiter)(delimiter) && (isBefore || isAfter)) {
315
- var marker = (0, roosterjs_content_model_dom_1.createSelectionMarker)(((_b = paragraph.segments[isAfter ? index + 1 : index - 1]) !== null && _b !== void 0 ? _b : first).format);
323
+ var marker = (0, roosterjs_content_model_dom_1.createSelectionMarker)(((_c = paragraph.segments[isAfter ? index + 1 : index - 1]) !== null && _c !== void 0 ? _c : first).format);
316
324
  paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);
317
325
  selectable = marker;
318
326
  }
@@ -1 +1 @@
1
- {"version":3,"file":"domIndexerImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/domIndexerImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n EmptySegmentFormat,\n createParagraph,\n createSelectionMarker,\n createText,\n getObjectKeys,\n isElementOfType,\n isEntityDelimiter,\n isNodeOfType,\n setSelection,\n} from 'roosterjs-content-model-dom';\nimport type {\n CacheSelection,\n ContentModelBlockGroup,\n ContentModelDocument,\n ContentModelEntity,\n ContentModelParagraph,\n ContentModelSegment,\n ContentModelSegmentFormat,\n ContentModelSelectionMarker,\n ContentModelTable,\n ContentModelText,\n DomIndexer,\n DOMSelection,\n RangeSelectionForCache,\n Selectable,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal Export for test only\n */\nexport interface SegmentItem {\n paragraph: ContentModelParagraph;\n segments: ContentModelSegment[];\n}\n\n/**\n * @internal Export for test only\n */\nexport interface TableItem {\n table: ContentModelTable;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface BlockEntityDelimiterItem {\n entity: ContentModelEntity;\n parent: ContentModelBlockGroup;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedSegmentNode extends Node {\n __roosterjsContentModel: SegmentItem;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedTableElement extends HTMLTableElement {\n __roosterjsContentModel: TableItem;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedEntityDelimiter extends Text {\n __roosterjsContentModel: BlockEntityDelimiterItem;\n}\n\n/**\n * Context object used by DomIndexer when reconcile mutations with child list\n */\ninterface ReconcileChildListContext {\n /**\n * Index of segment in current paragraph\n */\n segIndex: number;\n\n /**\n * The current paragraph that we are handling\n */\n paragraph?: ContentModelParagraph;\n\n /**\n * Text node that is added from mutation but has not been handled. This can happen when we first see an added node then later we see a removed one.\n * e.g. Type text in an empty paragraph (&lt;div&gt;&lt;br&gt;&lt;/div&gt;), so a text node will be added and &lt;BR&gt; will be removed.\n * Set to a valid text node means we need to handle it later. If it is finally not handled, that means we need to clear cache\n * Set to undefined (initial value) means no pending text node is hit yet (valid case)\n * Set to null means there was a pending text node which is already handled, so if we see another pending text node,\n * we should clear cache since we don't know how to handle it\n */\n pendingTextNode?: Text | null;\n\n /**\n * Format of the removed segment, this will be used as the format for newly created segment\n */\n format?: ContentModelSegmentFormat;\n}\n\nfunction isIndexedSegment(node: Node): node is IndexedSegmentNode {\n const { paragraph, segments } = (node as IndexedSegmentNode).__roosterjsContentModel ?? {};\n\n return (\n paragraph &&\n paragraph.blockType == 'Paragraph' &&\n Array.isArray(paragraph.segments) &&\n Array.isArray(segments)\n );\n}\n\nfunction isIndexedDelimiter(node: Node): node is IndexedEntityDelimiter {\n const { entity, parent } = (node as IndexedEntityDelimiter).__roosterjsContentModel ?? {};\n\n return (\n entity?.blockType == 'Entity' &&\n entity.wrapper &&\n parent?.blockGroupType &&\n Array.isArray(parent.blocks)\n );\n}\n\nfunction getIndexedSegmentItem(node: Node | null): SegmentItem | null {\n return node && isIndexedSegment(node) ? node.__roosterjsContentModel : null;\n}\n\nfunction getIndexedTableItem(element: HTMLTableElement): TableItem | null {\n const index = (element as IndexedTableElement).__roosterjsContentModel;\n const table = index?.table;\n\n if (\n table?.blockType == 'Table' &&\n Array.isArray(table.rows) &&\n table.rows.every(\n x => Array.isArray(x?.cells) && x.cells.every(y => y?.blockGroupType == 'TableCell')\n )\n ) {\n return index;\n } else {\n return null;\n }\n}\n\n/**\n * @internal\n * Implementation of DomIndexer\n */\nexport class DomIndexerImpl implements DomIndexer {\n constructor(private readonly persistCache?: boolean) {}\n\n onSegment(segmentNode: Node, paragraph: ContentModelParagraph, segment: ContentModelSegment[]) {\n const indexedText = segmentNode as IndexedSegmentNode;\n indexedText.__roosterjsContentModel = {\n paragraph,\n segments: segment,\n };\n }\n\n onParagraph(paragraphElement: HTMLElement) {\n let previousText: Text | null = null;\n\n for (let child = paragraphElement.firstChild; child; child = child.nextSibling) {\n if (isNodeOfType(child, 'TEXT_NODE')) {\n if (!previousText) {\n previousText = child;\n } else {\n const item = getIndexedSegmentItem(previousText);\n\n if (item && isIndexedSegment(child)) {\n item.segments = item.segments.concat(\n child.__roosterjsContentModel.segments\n );\n child.__roosterjsContentModel.segments = [];\n }\n }\n } else if (isNodeOfType(child, 'ELEMENT_NODE')) {\n previousText = null;\n\n this.onParagraph(child);\n } else {\n previousText = null;\n }\n }\n }\n\n onTable(tableElement: HTMLTableElement, table: ContentModelTable) {\n const indexedTable = tableElement as IndexedTableElement;\n indexedTable.__roosterjsContentModel = { table };\n }\n\n onBlockEntity(entity: ContentModelEntity, group: ContentModelBlockGroup) {\n this.onBlockEntityDelimiter(entity.wrapper.previousSibling, entity, group);\n this.onBlockEntityDelimiter(entity.wrapper.nextSibling, entity, group);\n }\n\n reconcileSelection(\n model: ContentModelDocument,\n newSelection: DOMSelection,\n oldSelection?: CacheSelection\n ): boolean {\n if (oldSelection) {\n if (\n oldSelection.type == 'range' &&\n this.isCollapsed(oldSelection) &&\n isNodeOfType(oldSelection.start.node, 'TEXT_NODE') &&\n isIndexedSegment(oldSelection.start.node)\n ) {\n this.reconcileTextSelection(oldSelection.start.node);\n } else {\n setSelection(model);\n }\n }\n\n switch (newSelection.type) {\n case 'image':\n const indexedImage = getIndexedSegmentItem(newSelection.image);\n const image = indexedImage?.segments[0];\n\n if (image) {\n image.isSelected = true;\n setSelection(model, image);\n\n return true;\n } else {\n return false;\n }\n\n case 'table':\n const indexedTable = getIndexedTableItem(newSelection.table);\n\n if (indexedTable) {\n const firstCell =\n indexedTable.table.rows[newSelection.firstRow]?.cells[\n newSelection.firstColumn\n ];\n const lastCell =\n indexedTable.table.rows[newSelection.lastRow]?.cells[\n newSelection.lastColumn\n ];\n\n if (firstCell && lastCell) {\n setSelection(model, firstCell, lastCell);\n\n return true;\n }\n }\n\n return false;\n\n case 'range':\n const newRange = newSelection.range;\n if (newRange) {\n const {\n startContainer,\n startOffset,\n endContainer,\n endOffset,\n collapsed,\n } = newRange;\n\n delete model.hasRevertedRangeSelection;\n\n if (collapsed) {\n return !!this.reconcileNodeSelection(\n startContainer,\n startOffset,\n model.format\n );\n } else if (\n startContainer == endContainer &&\n isNodeOfType(startContainer, 'TEXT_NODE')\n ) {\n if (newSelection.isReverted) {\n model.hasRevertedRangeSelection = true;\n }\n\n return (\n isIndexedSegment(startContainer) &&\n !!this.reconcileTextSelection(startContainer, startOffset, endOffset)\n );\n } else {\n const marker1 = this.reconcileNodeSelection(startContainer, startOffset);\n const marker2 = this.reconcileNodeSelection(endContainer, endOffset);\n\n if (marker1 && marker2) {\n if (newSelection.isReverted) {\n model.hasRevertedRangeSelection = true;\n }\n\n setSelection(model, marker1, marker2);\n return true;\n } else {\n return false;\n }\n }\n }\n\n break;\n }\n\n return false;\n }\n\n reconcileChildList(addedNodes: ArrayLike<Node>, removedNodes: ArrayLike<Node>): boolean {\n if (!this.persistCache) {\n return false;\n }\n\n let canHandle = true;\n const context: ReconcileChildListContext = {\n segIndex: -1,\n };\n\n // First process added nodes\n const addedNode = addedNodes[0];\n\n if (addedNodes.length == 1 && isNodeOfType(addedNode, 'TEXT_NODE')) {\n canHandle = this.reconcileAddedNode(addedNode, context);\n } else if (addedNodes.length > 0) {\n canHandle = false;\n }\n\n // Second, process removed nodes\n const removedNode = removedNodes[0];\n\n if (canHandle && removedNodes.length == 1) {\n canHandle = this.reconcileRemovedNode(removedNode, context);\n } else if (removedNodes.length > 0) {\n canHandle = false;\n }\n\n return canHandle && !context.pendingTextNode;\n }\n\n reconcileElementId(element: HTMLElement) {\n if (isElementOfType(element, 'img')) {\n const indexedImg = getIndexedSegmentItem(element);\n\n if (indexedImg?.segments[0]?.segmentType == 'Image') {\n indexedImg.segments[0].format.id = element.id;\n\n return true;\n } else {\n return false;\n }\n } else if (isElementOfType(element, 'table')) {\n const indexedTable = getIndexedTableItem(element);\n\n if (indexedTable) {\n indexedTable.table.format.id = element.id;\n\n return true;\n } else {\n return false;\n }\n } else {\n return false;\n }\n }\n\n private onBlockEntityDelimiter(\n node: Node | null,\n entity: ContentModelEntity,\n parent: ContentModelBlockGroup\n ) {\n if (isNodeOfType(node, 'ELEMENT_NODE') && isEntityDelimiter(node) && node.firstChild) {\n const indexedDelimiter = node.firstChild as IndexedEntityDelimiter;\n\n indexedDelimiter.__roosterjsContentModel = { entity, parent };\n }\n }\n\n private isCollapsed(selection: RangeSelectionForCache): boolean {\n const { start, end } = selection;\n\n return start.node == end.node && start.offset == end.offset;\n }\n\n private reconcileNodeSelection(\n node: Node,\n offset: number,\n defaultFormat?: ContentModelSegmentFormat\n ): Selectable | undefined {\n if (isNodeOfType(node, 'TEXT_NODE')) {\n if (isIndexedSegment(node)) {\n return this.reconcileTextSelection(node, offset);\n } else if (isIndexedDelimiter(node)) {\n return this.reconcileDelimiterSelection(node, defaultFormat);\n } else {\n return undefined;\n }\n } else if (offset >= node.childNodes.length) {\n return this.insertMarker(node.lastChild, true /*isAfter*/);\n } else {\n return this.insertMarker(node.childNodes[offset], false /*isAfter*/);\n }\n }\n\n private insertMarker(node: Node | null, isAfter: boolean): Selectable | undefined {\n let marker: ContentModelSelectionMarker | undefined;\n const segmentItem = node && getIndexedSegmentItem(node);\n\n if (segmentItem) {\n const { paragraph, segments } = segmentItem;\n const index = paragraph.segments.indexOf(segments[0]);\n\n if (index >= 0) {\n const formatSegment =\n (!isAfter && paragraph.segments[index - 1]) || paragraph.segments[index];\n marker = createSelectionMarker(formatSegment.format);\n\n paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);\n }\n }\n\n return marker;\n }\n\n private reconcileTextSelection(\n textNode: IndexedSegmentNode,\n startOffset?: number,\n endOffset?: number\n ) {\n const { paragraph, segments } = textNode.__roosterjsContentModel;\n const first = segments[0];\n const last = segments[segments.length - 1];\n let selectable: Selectable | undefined;\n\n if (first?.segmentType == 'Text' && last?.segmentType == 'Text') {\n const newSegments: ContentModelSegment[] = [];\n const txt = textNode.nodeValue || '';\n const textSegments: ContentModelText[] = [];\n\n if (startOffset === undefined) {\n first.text = txt;\n newSegments.push(first);\n textSegments.push(first);\n } else {\n if (startOffset > 0) {\n first.text = txt.substring(0, startOffset);\n newSegments.push(first);\n textSegments.push(first);\n }\n\n if (endOffset === undefined) {\n const marker = createSelectionMarker(first.format);\n newSegments.push(marker);\n\n selectable = marker;\n endOffset = startOffset;\n } else if (endOffset > startOffset) {\n const middle = createText(\n txt.substring(startOffset, endOffset),\n first.format,\n first.link,\n first.code\n );\n\n middle.isSelected = true;\n newSegments.push(middle);\n textSegments.push(middle);\n selectable = middle;\n }\n\n if (endOffset < txt.length) {\n const newLast = createText(\n txt.substring(endOffset),\n first.format,\n first.link,\n first.code\n );\n newSegments.push(newLast);\n textSegments.push(newLast);\n }\n }\n\n let firstIndex = paragraph.segments.indexOf(first);\n let lastIndex = paragraph.segments.indexOf(last);\n\n if (firstIndex >= 0 && lastIndex >= 0) {\n while (\n firstIndex > 0 &&\n paragraph.segments[firstIndex - 1].segmentType == 'SelectionMarker'\n ) {\n firstIndex--;\n }\n\n while (\n lastIndex < paragraph.segments.length - 1 &&\n paragraph.segments[lastIndex + 1].segmentType == 'SelectionMarker'\n ) {\n lastIndex++;\n }\n\n paragraph.segments.splice(firstIndex, lastIndex - firstIndex + 1, ...newSegments);\n }\n\n this.onSegment(textNode, paragraph, textSegments);\n\n if (!this.persistCache) {\n delete paragraph.cachedElement;\n }\n } else if (first?.segmentType == 'Entity' && first == last) {\n const wrapper = first.wrapper;\n const index = paragraph.segments.indexOf(first);\n const delimiter = textNode.parentElement;\n const isBefore = wrapper.previousSibling == delimiter;\n const isAfter = wrapper.nextSibling == delimiter;\n\n if (index >= 0 && delimiter && isEntityDelimiter(delimiter) && (isBefore || isAfter)) {\n const marker = createSelectionMarker(\n (paragraph.segments[isAfter ? index + 1 : index - 1] ?? first).format\n );\n\n paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);\n\n selectable = marker;\n }\n }\n\n return selectable;\n }\n\n private reconcileDelimiterSelection(\n node: IndexedEntityDelimiter,\n defaultFormat?: ContentModelSegmentFormat\n ) {\n let marker: ContentModelSelectionMarker | undefined;\n\n const { entity, parent } = node.__roosterjsContentModel;\n const index = parent.blocks.indexOf(entity);\n const delimiter = node.parentElement;\n const wrapper = entity.wrapper;\n const isBefore = wrapper.previousSibling == delimiter;\n const isAfter = wrapper.nextSibling == delimiter;\n\n if (index >= 0 && delimiter && isEntityDelimiter(delimiter) && (isBefore || isAfter)) {\n marker = createSelectionMarker(defaultFormat);\n\n const para = createParagraph(\n true /*isImplicit*/,\n undefined /*blockFormat*/,\n defaultFormat\n );\n\n para.segments.push(marker);\n parent.blocks.splice(isBefore ? index : index + 1, 0, para);\n }\n\n return marker;\n }\n\n private reconcileAddedNode(node: Text, context: ReconcileChildListContext): boolean {\n let segmentItem: SegmentItem | null = null;\n let index = -1;\n let existingSegment: ContentModelSegment;\n const { previousSibling, nextSibling } = node;\n\n if (\n (segmentItem = getIndexedSegmentItem(previousSibling)) &&\n (existingSegment = segmentItem.segments[segmentItem.segments.length - 1]) &&\n (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0\n ) {\n // When we can find indexed segment before current one, use it as the insert index\n this.indexNode(segmentItem.paragraph, index + 1, node, existingSegment.format);\n } else if (\n (segmentItem = getIndexedSegmentItem(nextSibling)) &&\n (existingSegment = segmentItem.segments[0]) &&\n (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0\n ) {\n // When we can find indexed segment after current one, use it as the insert index\n this.indexNode(segmentItem.paragraph, index, node, existingSegment.format);\n } else if (context.paragraph && context.segIndex >= 0) {\n // When there is indexed paragraph from removed nodes, we can use it as the insert index\n this.indexNode(context.paragraph, context.segIndex, node, context.format);\n } else if (context.pendingTextNode === undefined) {\n // When we can't find the insert index, set current node as pending node\n // so later we can pick it up when we have enough info when processing removed node\n // Only do this when pendingTextNode is undefined. If it is null it means there was already a pending node before\n // and in that case we should return false since we can't handle two pending text node\n context.pendingTextNode = node;\n } else {\n return false;\n }\n\n return true;\n }\n\n private reconcileRemovedNode(node: Node, context: ReconcileChildListContext): boolean {\n let segmentItem: SegmentItem | null = null;\n let removingSegment: ContentModelSegment;\n\n if (\n context.segIndex < 0 &&\n !context.paragraph && // No previous removed segment or related paragraph found, and\n (segmentItem = getIndexedSegmentItem(node)) && // The removed node is indexed, and\n (removingSegment = segmentItem.segments[0]) // There is at least one related segment\n ) {\n // Now we can remove the indexed segment from the paragraph, and remember it, later we may need to use it\n context.format = removingSegment.format;\n context.paragraph = segmentItem.paragraph;\n context.segIndex = segmentItem.paragraph.segments.indexOf(segmentItem.segments[0]);\n\n if (context.segIndex < 0) {\n // Indexed segment is not under paragraph, something wrong happens, we cannot keep handling\n return false;\n }\n\n for (let i = 0; i < segmentItem.segments.length; i++) {\n const index = segmentItem.paragraph.segments.indexOf(segmentItem.segments[i]);\n\n if (index >= 0) {\n segmentItem.paragraph.segments.splice(index, 1);\n }\n }\n\n if (context.pendingTextNode) {\n // If we have pending text node added but not indexed, do it now\n this.indexNode(\n context.paragraph,\n context.segIndex,\n context.pendingTextNode,\n segmentItem.segments[0].format\n );\n\n // Set to null since we have processed it.\n // Next time we see a pending node we know we have already processed one so it is a situation we cannot handle\n context.pendingTextNode = null;\n }\n\n return true;\n } else {\n return false;\n }\n }\n\n private indexNode(\n paragraph: ContentModelParagraph,\n index: number,\n textNode: Text,\n format?: ContentModelSegmentFormat\n ) {\n const copiedFormat = format ? { ...format } : undefined;\n\n if (copiedFormat) {\n getObjectKeys(copiedFormat).forEach(key => {\n if (EmptySegmentFormat[key] === undefined) {\n delete copiedFormat[key];\n }\n });\n }\n\n const text = createText(textNode.textContent ?? '', copiedFormat);\n\n paragraph.segments.splice(index, 0, text);\n this.onSegment(textNode, paragraph, [text]);\n }\n}\n"]}
1
+ {"version":3,"file":"domIndexerImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/domIndexerImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n EmptySegmentFormat,\n addCode,\n addLink,\n createParagraph,\n createSelectionMarker,\n createText,\n getObjectKeys,\n isElementOfType,\n isEntityDelimiter,\n isNodeOfType,\n setSelection,\n} from 'roosterjs-content-model-dom';\nimport type {\n CacheSelection,\n ContentModelBlockGroup,\n ContentModelDocument,\n ContentModelEntity,\n ContentModelParagraph,\n ContentModelSegment,\n ContentModelSegmentFormat,\n ContentModelSelectionMarker,\n ContentModelTable,\n ContentModelText,\n DomIndexer,\n DOMSelection,\n RangeSelectionForCache,\n Selectable,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal Export for test only\n */\nexport interface SegmentItem {\n paragraph: ContentModelParagraph;\n segments: ContentModelSegment[];\n}\n\n/**\n * @internal Export for test only\n */\nexport interface TableItem {\n table: ContentModelTable;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface BlockEntityDelimiterItem {\n entity: ContentModelEntity;\n parent: ContentModelBlockGroup;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedSegmentNode extends Node {\n __roosterjsContentModel: SegmentItem;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedTableElement extends HTMLTableElement {\n __roosterjsContentModel: TableItem;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedEntityDelimiter extends Text {\n __roosterjsContentModel: BlockEntityDelimiterItem;\n}\n\n/**\n * Context object used by DomIndexer when reconcile mutations with child list\n */\ninterface ReconcileChildListContext {\n /**\n * Index of segment in current paragraph\n */\n segIndex: number;\n\n /**\n * The current paragraph that we are handling\n */\n paragraph?: ContentModelParagraph;\n\n /**\n * Text node that is added from mutation but has not been handled. This can happen when we first see an added node then later we see a removed one.\n * e.g. Type text in an empty paragraph (&lt;div&gt;&lt;br&gt;&lt;/div&gt;), so a text node will be added and &lt;BR&gt; will be removed.\n * Set to a valid text node means we need to handle it later. If it is finally not handled, that means we need to clear cache\n * Set to undefined (initial value) means no pending text node is hit yet (valid case)\n * Set to null means there was a pending text node which is already handled, so if we see another pending text node,\n * we should clear cache since we don't know how to handle it\n */\n pendingTextNode?: Text | null;\n\n /**\n * Format of the removed segment, this will be used as the format for newly created segment\n */\n format?: ContentModelSegmentFormat;\n}\n\nfunction isIndexedSegment(node: Node): node is IndexedSegmentNode {\n const { paragraph, segments } = (node as IndexedSegmentNode).__roosterjsContentModel ?? {};\n\n return (\n paragraph &&\n paragraph.blockType == 'Paragraph' &&\n Array.isArray(paragraph.segments) &&\n Array.isArray(segments)\n );\n}\n\nfunction isIndexedDelimiter(node: Node): node is IndexedEntityDelimiter {\n const { entity, parent } = (node as IndexedEntityDelimiter).__roosterjsContentModel ?? {};\n\n return (\n entity?.blockType == 'Entity' &&\n entity.wrapper &&\n parent?.blockGroupType &&\n Array.isArray(parent.blocks)\n );\n}\n\nfunction getIndexedSegmentItem(node: Node | null): SegmentItem | null {\n return node && isIndexedSegment(node) ? node.__roosterjsContentModel : null;\n}\n\nfunction getIndexedTableItem(element: HTMLTableElement): TableItem | null {\n const index = (element as IndexedTableElement).__roosterjsContentModel;\n const table = index?.table;\n\n if (\n table?.blockType == 'Table' &&\n Array.isArray(table.rows) &&\n table.rows.every(\n x => Array.isArray(x?.cells) && x.cells.every(y => y?.blockGroupType == 'TableCell')\n )\n ) {\n return index;\n } else {\n return null;\n }\n}\n\n/**\n * @internal\n * Implementation of DomIndexer\n */\nexport class DomIndexerImpl implements DomIndexer {\n constructor(private readonly persistCache?: boolean) {}\n\n onSegment(segmentNode: Node, paragraph: ContentModelParagraph, segment: ContentModelSegment[]) {\n const indexedText = segmentNode as IndexedSegmentNode;\n indexedText.__roosterjsContentModel = {\n paragraph,\n segments: segment,\n };\n }\n\n onParagraph(paragraphElement: HTMLElement) {\n let previousText: Text | null = null;\n\n for (let child = paragraphElement.firstChild; child; child = child.nextSibling) {\n if (isNodeOfType(child, 'TEXT_NODE')) {\n if (!previousText) {\n previousText = child;\n } else {\n const item = getIndexedSegmentItem(previousText);\n\n if (item && isIndexedSegment(child)) {\n item.segments = item.segments.concat(\n child.__roosterjsContentModel.segments\n );\n child.__roosterjsContentModel.segments = [];\n }\n }\n } else if (isNodeOfType(child, 'ELEMENT_NODE')) {\n previousText = null;\n\n this.onParagraph(child);\n } else {\n previousText = null;\n }\n }\n }\n\n onTable(tableElement: HTMLTableElement, table: ContentModelTable) {\n const indexedTable = tableElement as IndexedTableElement;\n indexedTable.__roosterjsContentModel = { table };\n }\n\n onBlockEntity(entity: ContentModelEntity, group: ContentModelBlockGroup) {\n this.onBlockEntityDelimiter(entity.wrapper.previousSibling, entity, group);\n this.onBlockEntityDelimiter(entity.wrapper.nextSibling, entity, group);\n }\n\n reconcileSelection(\n model: ContentModelDocument,\n newSelection: DOMSelection,\n oldSelection?: CacheSelection\n ): boolean {\n if (oldSelection) {\n if (\n oldSelection.type == 'range' &&\n this.isCollapsed(oldSelection) &&\n isNodeOfType(oldSelection.start.node, 'TEXT_NODE') &&\n isIndexedSegment(oldSelection.start.node)\n ) {\n this.reconcileTextSelection(oldSelection.start.node);\n } else {\n setSelection(model);\n }\n }\n\n switch (newSelection.type) {\n case 'image':\n const indexedImage = getIndexedSegmentItem(newSelection.image);\n const image = indexedImage?.segments[0];\n\n if (image) {\n image.isSelected = true;\n setSelection(model, image);\n\n return true;\n } else {\n return false;\n }\n\n case 'table':\n const indexedTable = getIndexedTableItem(newSelection.table);\n\n if (indexedTable) {\n const firstCell =\n indexedTable.table.rows[newSelection.firstRow]?.cells[\n newSelection.firstColumn\n ];\n const lastCell =\n indexedTable.table.rows[newSelection.lastRow]?.cells[\n newSelection.lastColumn\n ];\n\n if (firstCell && lastCell) {\n setSelection(model, firstCell, lastCell);\n\n return true;\n }\n }\n\n return false;\n\n case 'range':\n const newRange = newSelection.range;\n if (newRange) {\n const {\n startContainer,\n startOffset,\n endContainer,\n endOffset,\n collapsed,\n } = newRange;\n\n delete model.hasRevertedRangeSelection;\n\n if (collapsed) {\n return !!this.reconcileNodeSelection(\n startContainer,\n startOffset,\n model.format\n );\n } else if (\n startContainer == endContainer &&\n isNodeOfType(startContainer, 'TEXT_NODE')\n ) {\n if (newSelection.isReverted) {\n model.hasRevertedRangeSelection = true;\n }\n\n return (\n isIndexedSegment(startContainer) &&\n !!this.reconcileTextSelection(startContainer, startOffset, endOffset)\n );\n } else {\n const marker1 = this.reconcileNodeSelection(startContainer, startOffset);\n const marker2 = this.reconcileNodeSelection(endContainer, endOffset);\n\n if (marker1 && marker2) {\n if (newSelection.isReverted) {\n model.hasRevertedRangeSelection = true;\n }\n\n setSelection(model, marker1, marker2);\n return true;\n } else {\n return false;\n }\n }\n }\n\n break;\n }\n\n return false;\n }\n\n reconcileChildList(addedNodes: ArrayLike<Node>, removedNodes: ArrayLike<Node>): boolean {\n if (!this.persistCache) {\n return false;\n }\n\n let canHandle = true;\n const context: ReconcileChildListContext = {\n segIndex: -1,\n };\n\n // First process added nodes\n const addedNode = addedNodes[0];\n\n if (addedNodes.length == 1 && isNodeOfType(addedNode, 'TEXT_NODE')) {\n canHandle = this.reconcileAddedNode(addedNode, context);\n } else if (addedNodes.length > 0) {\n canHandle = false;\n }\n\n // Second, process removed nodes\n const removedNode = removedNodes[0];\n\n if (canHandle && removedNodes.length == 1) {\n canHandle = this.reconcileRemovedNode(removedNode, context);\n } else if (removedNodes.length > 0) {\n canHandle = false;\n }\n\n return canHandle && !context.pendingTextNode;\n }\n\n reconcileElementId(element: HTMLElement) {\n if (isElementOfType(element, 'img')) {\n const indexedImg = getIndexedSegmentItem(element);\n\n if (indexedImg?.segments[0]?.segmentType == 'Image') {\n indexedImg.segments[0].format.id = element.id;\n\n return true;\n } else {\n return false;\n }\n } else if (isElementOfType(element, 'table')) {\n const indexedTable = getIndexedTableItem(element);\n\n if (indexedTable) {\n indexedTable.table.format.id = element.id;\n\n return true;\n } else {\n return false;\n }\n } else {\n return false;\n }\n }\n\n private onBlockEntityDelimiter(\n node: Node | null,\n entity: ContentModelEntity,\n parent: ContentModelBlockGroup\n ) {\n if (isNodeOfType(node, 'ELEMENT_NODE') && isEntityDelimiter(node) && node.firstChild) {\n const indexedDelimiter = node.firstChild as IndexedEntityDelimiter;\n\n indexedDelimiter.__roosterjsContentModel = { entity, parent };\n }\n }\n\n private isCollapsed(selection: RangeSelectionForCache): boolean {\n const { start, end } = selection;\n\n return start.node == end.node && start.offset == end.offset;\n }\n\n private reconcileNodeSelection(\n node: Node,\n offset: number,\n defaultFormat?: ContentModelSegmentFormat\n ): Selectable | undefined {\n if (isNodeOfType(node, 'TEXT_NODE')) {\n if (isIndexedSegment(node)) {\n return this.reconcileTextSelection(node, offset);\n } else if (isIndexedDelimiter(node)) {\n return this.reconcileDelimiterSelection(node, defaultFormat);\n } else {\n return undefined;\n }\n } else if (offset >= node.childNodes.length) {\n return this.insertMarker(node.lastChild, true /*isAfter*/);\n } else {\n return this.insertMarker(node.childNodes[offset], false /*isAfter*/);\n }\n }\n\n private insertMarker(node: Node | null, isAfter: boolean): Selectable | undefined {\n let marker: ContentModelSelectionMarker | undefined;\n const segmentItem = node && getIndexedSegmentItem(node);\n\n if (segmentItem) {\n const { paragraph, segments } = segmentItem;\n const index = paragraph.segments.indexOf(segments[0]);\n\n if (index >= 0) {\n const formatSegment =\n (!isAfter && paragraph.segments[index - 1]) || paragraph.segments[index];\n marker = createSelectionMarker(formatSegment.format);\n\n paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);\n }\n }\n\n return marker;\n }\n\n private reconcileTextSelection(\n textNode: IndexedSegmentNode,\n startOffset?: number,\n endOffset?: number\n ) {\n const { paragraph, segments } = textNode.__roosterjsContentModel;\n const first = segments[0];\n const last = segments[segments.length - 1];\n let selectable: Selectable | undefined;\n\n if (first?.segmentType == 'Text' && last?.segmentType == 'Text') {\n const newSegments: ContentModelSegment[] = [];\n const txt = textNode.nodeValue || '';\n const textSegments: ContentModelText[] = [];\n\n if (startOffset === undefined) {\n first.text = txt;\n newSegments.push(first);\n textSegments.push(first);\n } else {\n if (startOffset > 0) {\n first.text = txt.substring(0, startOffset);\n newSegments.push(first);\n textSegments.push(first);\n }\n\n if (endOffset === undefined) {\n const marker = createSelectionMarker(first.format);\n newSegments.push(marker);\n\n if (startOffset < (textNode.nodeValue ?? '').length) {\n if (first.link) {\n addLink(marker, first.link);\n }\n\n if (first.code) {\n addCode(marker, first.code);\n }\n }\n\n selectable = marker;\n endOffset = startOffset;\n } else if (endOffset > startOffset) {\n const middle = createText(\n txt.substring(startOffset, endOffset),\n first.format,\n first.link,\n first.code\n );\n\n middle.isSelected = true;\n newSegments.push(middle);\n textSegments.push(middle);\n selectable = middle;\n }\n\n if (endOffset < txt.length) {\n const newLast = createText(\n txt.substring(endOffset),\n first.format,\n first.link,\n first.code\n );\n newSegments.push(newLast);\n textSegments.push(newLast);\n }\n }\n\n let firstIndex = paragraph.segments.indexOf(first);\n let lastIndex = paragraph.segments.indexOf(last);\n\n if (firstIndex >= 0 && lastIndex >= 0) {\n while (\n firstIndex > 0 &&\n paragraph.segments[firstIndex - 1].segmentType == 'SelectionMarker'\n ) {\n firstIndex--;\n }\n\n while (\n lastIndex < paragraph.segments.length - 1 &&\n paragraph.segments[lastIndex + 1].segmentType == 'SelectionMarker'\n ) {\n lastIndex++;\n }\n\n paragraph.segments.splice(firstIndex, lastIndex - firstIndex + 1, ...newSegments);\n }\n\n this.onSegment(textNode, paragraph, textSegments);\n\n if (!this.persistCache) {\n delete paragraph.cachedElement;\n }\n } else if (first?.segmentType == 'Entity' && first == last) {\n const wrapper = first.wrapper;\n const index = paragraph.segments.indexOf(first);\n const delimiter = textNode.parentElement;\n const isBefore = wrapper.previousSibling == delimiter;\n const isAfter = wrapper.nextSibling == delimiter;\n\n if (index >= 0 && delimiter && isEntityDelimiter(delimiter) && (isBefore || isAfter)) {\n const marker = createSelectionMarker(\n (paragraph.segments[isAfter ? index + 1 : index - 1] ?? first).format\n );\n\n paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);\n\n selectable = marker;\n }\n }\n\n return selectable;\n }\n\n private reconcileDelimiterSelection(\n node: IndexedEntityDelimiter,\n defaultFormat?: ContentModelSegmentFormat\n ) {\n let marker: ContentModelSelectionMarker | undefined;\n\n const { entity, parent } = node.__roosterjsContentModel;\n const index = parent.blocks.indexOf(entity);\n const delimiter = node.parentElement;\n const wrapper = entity.wrapper;\n const isBefore = wrapper.previousSibling == delimiter;\n const isAfter = wrapper.nextSibling == delimiter;\n\n if (index >= 0 && delimiter && isEntityDelimiter(delimiter) && (isBefore || isAfter)) {\n marker = createSelectionMarker(defaultFormat);\n\n const para = createParagraph(\n true /*isImplicit*/,\n undefined /*blockFormat*/,\n defaultFormat\n );\n\n para.segments.push(marker);\n parent.blocks.splice(isBefore ? index : index + 1, 0, para);\n }\n\n return marker;\n }\n\n private reconcileAddedNode(node: Text, context: ReconcileChildListContext): boolean {\n let segmentItem: SegmentItem | null = null;\n let index = -1;\n let existingSegment: ContentModelSegment;\n const { previousSibling, nextSibling } = node;\n\n if (\n (segmentItem = getIndexedSegmentItem(previousSibling)) &&\n (existingSegment = segmentItem.segments[segmentItem.segments.length - 1]) &&\n (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0\n ) {\n // When we can find indexed segment before current one, use it as the insert index\n this.indexNode(segmentItem.paragraph, index + 1, node, existingSegment.format);\n } else if (\n (segmentItem = getIndexedSegmentItem(nextSibling)) &&\n (existingSegment = segmentItem.segments[0]) &&\n (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0\n ) {\n // When we can find indexed segment after current one, use it as the insert index\n this.indexNode(segmentItem.paragraph, index, node, existingSegment.format);\n } else if (context.paragraph && context.segIndex >= 0) {\n // When there is indexed paragraph from removed nodes, we can use it as the insert index\n this.indexNode(context.paragraph, context.segIndex, node, context.format);\n } else if (context.pendingTextNode === undefined) {\n // When we can't find the insert index, set current node as pending node\n // so later we can pick it up when we have enough info when processing removed node\n // Only do this when pendingTextNode is undefined. If it is null it means there was already a pending node before\n // and in that case we should return false since we can't handle two pending text node\n context.pendingTextNode = node;\n } else {\n return false;\n }\n\n return true;\n }\n\n private reconcileRemovedNode(node: Node, context: ReconcileChildListContext): boolean {\n let segmentItem: SegmentItem | null = null;\n let removingSegment: ContentModelSegment;\n\n if (\n context.segIndex < 0 &&\n !context.paragraph && // No previous removed segment or related paragraph found, and\n (segmentItem = getIndexedSegmentItem(node)) && // The removed node is indexed, and\n (removingSegment = segmentItem.segments[0]) // There is at least one related segment\n ) {\n // Now we can remove the indexed segment from the paragraph, and remember it, later we may need to use it\n context.format = removingSegment.format;\n context.paragraph = segmentItem.paragraph;\n context.segIndex = segmentItem.paragraph.segments.indexOf(segmentItem.segments[0]);\n\n if (context.segIndex < 0) {\n // Indexed segment is not under paragraph, something wrong happens, we cannot keep handling\n return false;\n }\n\n for (let i = 0; i < segmentItem.segments.length; i++) {\n const index = segmentItem.paragraph.segments.indexOf(segmentItem.segments[i]);\n\n if (index >= 0) {\n segmentItem.paragraph.segments.splice(index, 1);\n }\n }\n\n if (context.pendingTextNode) {\n // If we have pending text node added but not indexed, do it now\n this.indexNode(\n context.paragraph,\n context.segIndex,\n context.pendingTextNode,\n segmentItem.segments[0].format\n );\n\n // Set to null since we have processed it.\n // Next time we see a pending node we know we have already processed one so it is a situation we cannot handle\n context.pendingTextNode = null;\n }\n\n return true;\n } else {\n return false;\n }\n }\n\n private indexNode(\n paragraph: ContentModelParagraph,\n index: number,\n textNode: Text,\n format?: ContentModelSegmentFormat\n ) {\n const copiedFormat = format ? { ...format } : undefined;\n\n if (copiedFormat) {\n getObjectKeys(copiedFormat).forEach(key => {\n if (EmptySegmentFormat[key] === undefined) {\n delete copiedFormat[key];\n }\n });\n }\n\n const text = createText(textNode.textContent ?? '', copiedFormat);\n\n paragraph.segments.splice(index, 0, text);\n this.onSegment(textNode, paragraph, [text]);\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { __assign, __read, __spreadArray } from "tslib";
2
- import { EmptySegmentFormat, createParagraph, createSelectionMarker, createText, getObjectKeys, isElementOfType, isEntityDelimiter, isNodeOfType, setSelection, } from 'roosterjs-content-model-dom';
2
+ import { EmptySegmentFormat, addCode, addLink, createParagraph, createSelectionMarker, createText, getObjectKeys, isElementOfType, isEntityDelimiter, isNodeOfType, setSelection, } from 'roosterjs-content-model-dom';
3
3
  function isIndexedSegment(node) {
4
4
  var _a;
5
5
  var _b = (_a = node.__roosterjsContentModel) !== null && _a !== void 0 ? _a : {}, paragraph = _b.paragraph, segments = _b.segments;
@@ -246,8 +246,8 @@ var DomIndexerImpl = /** @class */ (function () {
246
246
  };
247
247
  DomIndexerImpl.prototype.reconcileTextSelection = function (textNode, startOffset, endOffset) {
248
248
  var _a;
249
- var _b;
250
- var _c = textNode.__roosterjsContentModel, paragraph = _c.paragraph, segments = _c.segments;
249
+ var _b, _c;
250
+ var _d = textNode.__roosterjsContentModel, paragraph = _d.paragraph, segments = _d.segments;
251
251
  var first = segments[0];
252
252
  var last = segments[segments.length - 1];
253
253
  var selectable;
@@ -269,6 +269,14 @@ var DomIndexerImpl = /** @class */ (function () {
269
269
  if (endOffset === undefined) {
270
270
  var marker = createSelectionMarker(first.format);
271
271
  newSegments.push(marker);
272
+ if (startOffset < ((_b = textNode.nodeValue) !== null && _b !== void 0 ? _b : '').length) {
273
+ if (first.link) {
274
+ addLink(marker, first.link);
275
+ }
276
+ if (first.code) {
277
+ addCode(marker, first.code);
278
+ }
279
+ }
272
280
  selectable = marker;
273
281
  endOffset = startOffset;
274
282
  }
@@ -310,7 +318,7 @@ var DomIndexerImpl = /** @class */ (function () {
310
318
  var isBefore = wrapper.previousSibling == delimiter;
311
319
  var isAfter = wrapper.nextSibling == delimiter;
312
320
  if (index >= 0 && delimiter && isEntityDelimiter(delimiter) && (isBefore || isAfter)) {
313
- var marker = createSelectionMarker(((_b = paragraph.segments[isAfter ? index + 1 : index - 1]) !== null && _b !== void 0 ? _b : first).format);
321
+ var marker = createSelectionMarker(((_c = paragraph.segments[isAfter ? index + 1 : index - 1]) !== null && _c !== void 0 ? _c : first).format);
314
322
  paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);
315
323
  selectable = marker;
316
324
  }
@@ -1 +1 @@
1
- {"version":3,"file":"domIndexerImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/domIndexerImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n EmptySegmentFormat,\n createParagraph,\n createSelectionMarker,\n createText,\n getObjectKeys,\n isElementOfType,\n isEntityDelimiter,\n isNodeOfType,\n setSelection,\n} from 'roosterjs-content-model-dom';\nimport type {\n CacheSelection,\n ContentModelBlockGroup,\n ContentModelDocument,\n ContentModelEntity,\n ContentModelParagraph,\n ContentModelSegment,\n ContentModelSegmentFormat,\n ContentModelSelectionMarker,\n ContentModelTable,\n ContentModelText,\n DomIndexer,\n DOMSelection,\n RangeSelectionForCache,\n Selectable,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal Export for test only\n */\nexport interface SegmentItem {\n paragraph: ContentModelParagraph;\n segments: ContentModelSegment[];\n}\n\n/**\n * @internal Export for test only\n */\nexport interface TableItem {\n table: ContentModelTable;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface BlockEntityDelimiterItem {\n entity: ContentModelEntity;\n parent: ContentModelBlockGroup;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedSegmentNode extends Node {\n __roosterjsContentModel: SegmentItem;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedTableElement extends HTMLTableElement {\n __roosterjsContentModel: TableItem;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedEntityDelimiter extends Text {\n __roosterjsContentModel: BlockEntityDelimiterItem;\n}\n\n/**\n * Context object used by DomIndexer when reconcile mutations with child list\n */\ninterface ReconcileChildListContext {\n /**\n * Index of segment in current paragraph\n */\n segIndex: number;\n\n /**\n * The current paragraph that we are handling\n */\n paragraph?: ContentModelParagraph;\n\n /**\n * Text node that is added from mutation but has not been handled. This can happen when we first see an added node then later we see a removed one.\n * e.g. Type text in an empty paragraph (&lt;div&gt;&lt;br&gt;&lt;/div&gt;), so a text node will be added and &lt;BR&gt; will be removed.\n * Set to a valid text node means we need to handle it later. If it is finally not handled, that means we need to clear cache\n * Set to undefined (initial value) means no pending text node is hit yet (valid case)\n * Set to null means there was a pending text node which is already handled, so if we see another pending text node,\n * we should clear cache since we don't know how to handle it\n */\n pendingTextNode?: Text | null;\n\n /**\n * Format of the removed segment, this will be used as the format for newly created segment\n */\n format?: ContentModelSegmentFormat;\n}\n\nfunction isIndexedSegment(node: Node): node is IndexedSegmentNode {\n const { paragraph, segments } = (node as IndexedSegmentNode).__roosterjsContentModel ?? {};\n\n return (\n paragraph &&\n paragraph.blockType == 'Paragraph' &&\n Array.isArray(paragraph.segments) &&\n Array.isArray(segments)\n );\n}\n\nfunction isIndexedDelimiter(node: Node): node is IndexedEntityDelimiter {\n const { entity, parent } = (node as IndexedEntityDelimiter).__roosterjsContentModel ?? {};\n\n return (\n entity?.blockType == 'Entity' &&\n entity.wrapper &&\n parent?.blockGroupType &&\n Array.isArray(parent.blocks)\n );\n}\n\nfunction getIndexedSegmentItem(node: Node | null): SegmentItem | null {\n return node && isIndexedSegment(node) ? node.__roosterjsContentModel : null;\n}\n\nfunction getIndexedTableItem(element: HTMLTableElement): TableItem | null {\n const index = (element as IndexedTableElement).__roosterjsContentModel;\n const table = index?.table;\n\n if (\n table?.blockType == 'Table' &&\n Array.isArray(table.rows) &&\n table.rows.every(\n x => Array.isArray(x?.cells) && x.cells.every(y => y?.blockGroupType == 'TableCell')\n )\n ) {\n return index;\n } else {\n return null;\n }\n}\n\n/**\n * @internal\n * Implementation of DomIndexer\n */\nexport class DomIndexerImpl implements DomIndexer {\n constructor(private readonly persistCache?: boolean) {}\n\n onSegment(segmentNode: Node, paragraph: ContentModelParagraph, segment: ContentModelSegment[]) {\n const indexedText = segmentNode as IndexedSegmentNode;\n indexedText.__roosterjsContentModel = {\n paragraph,\n segments: segment,\n };\n }\n\n onParagraph(paragraphElement: HTMLElement) {\n let previousText: Text | null = null;\n\n for (let child = paragraphElement.firstChild; child; child = child.nextSibling) {\n if (isNodeOfType(child, 'TEXT_NODE')) {\n if (!previousText) {\n previousText = child;\n } else {\n const item = getIndexedSegmentItem(previousText);\n\n if (item && isIndexedSegment(child)) {\n item.segments = item.segments.concat(\n child.__roosterjsContentModel.segments\n );\n child.__roosterjsContentModel.segments = [];\n }\n }\n } else if (isNodeOfType(child, 'ELEMENT_NODE')) {\n previousText = null;\n\n this.onParagraph(child);\n } else {\n previousText = null;\n }\n }\n }\n\n onTable(tableElement: HTMLTableElement, table: ContentModelTable) {\n const indexedTable = tableElement as IndexedTableElement;\n indexedTable.__roosterjsContentModel = { table };\n }\n\n onBlockEntity(entity: ContentModelEntity, group: ContentModelBlockGroup) {\n this.onBlockEntityDelimiter(entity.wrapper.previousSibling, entity, group);\n this.onBlockEntityDelimiter(entity.wrapper.nextSibling, entity, group);\n }\n\n reconcileSelection(\n model: ContentModelDocument,\n newSelection: DOMSelection,\n oldSelection?: CacheSelection\n ): boolean {\n if (oldSelection) {\n if (\n oldSelection.type == 'range' &&\n this.isCollapsed(oldSelection) &&\n isNodeOfType(oldSelection.start.node, 'TEXT_NODE') &&\n isIndexedSegment(oldSelection.start.node)\n ) {\n this.reconcileTextSelection(oldSelection.start.node);\n } else {\n setSelection(model);\n }\n }\n\n switch (newSelection.type) {\n case 'image':\n const indexedImage = getIndexedSegmentItem(newSelection.image);\n const image = indexedImage?.segments[0];\n\n if (image) {\n image.isSelected = true;\n setSelection(model, image);\n\n return true;\n } else {\n return false;\n }\n\n case 'table':\n const indexedTable = getIndexedTableItem(newSelection.table);\n\n if (indexedTable) {\n const firstCell =\n indexedTable.table.rows[newSelection.firstRow]?.cells[\n newSelection.firstColumn\n ];\n const lastCell =\n indexedTable.table.rows[newSelection.lastRow]?.cells[\n newSelection.lastColumn\n ];\n\n if (firstCell && lastCell) {\n setSelection(model, firstCell, lastCell);\n\n return true;\n }\n }\n\n return false;\n\n case 'range':\n const newRange = newSelection.range;\n if (newRange) {\n const {\n startContainer,\n startOffset,\n endContainer,\n endOffset,\n collapsed,\n } = newRange;\n\n delete model.hasRevertedRangeSelection;\n\n if (collapsed) {\n return !!this.reconcileNodeSelection(\n startContainer,\n startOffset,\n model.format\n );\n } else if (\n startContainer == endContainer &&\n isNodeOfType(startContainer, 'TEXT_NODE')\n ) {\n if (newSelection.isReverted) {\n model.hasRevertedRangeSelection = true;\n }\n\n return (\n isIndexedSegment(startContainer) &&\n !!this.reconcileTextSelection(startContainer, startOffset, endOffset)\n );\n } else {\n const marker1 = this.reconcileNodeSelection(startContainer, startOffset);\n const marker2 = this.reconcileNodeSelection(endContainer, endOffset);\n\n if (marker1 && marker2) {\n if (newSelection.isReverted) {\n model.hasRevertedRangeSelection = true;\n }\n\n setSelection(model, marker1, marker2);\n return true;\n } else {\n return false;\n }\n }\n }\n\n break;\n }\n\n return false;\n }\n\n reconcileChildList(addedNodes: ArrayLike<Node>, removedNodes: ArrayLike<Node>): boolean {\n if (!this.persistCache) {\n return false;\n }\n\n let canHandle = true;\n const context: ReconcileChildListContext = {\n segIndex: -1,\n };\n\n // First process added nodes\n const addedNode = addedNodes[0];\n\n if (addedNodes.length == 1 && isNodeOfType(addedNode, 'TEXT_NODE')) {\n canHandle = this.reconcileAddedNode(addedNode, context);\n } else if (addedNodes.length > 0) {\n canHandle = false;\n }\n\n // Second, process removed nodes\n const removedNode = removedNodes[0];\n\n if (canHandle && removedNodes.length == 1) {\n canHandle = this.reconcileRemovedNode(removedNode, context);\n } else if (removedNodes.length > 0) {\n canHandle = false;\n }\n\n return canHandle && !context.pendingTextNode;\n }\n\n reconcileElementId(element: HTMLElement) {\n if (isElementOfType(element, 'img')) {\n const indexedImg = getIndexedSegmentItem(element);\n\n if (indexedImg?.segments[0]?.segmentType == 'Image') {\n indexedImg.segments[0].format.id = element.id;\n\n return true;\n } else {\n return false;\n }\n } else if (isElementOfType(element, 'table')) {\n const indexedTable = getIndexedTableItem(element);\n\n if (indexedTable) {\n indexedTable.table.format.id = element.id;\n\n return true;\n } else {\n return false;\n }\n } else {\n return false;\n }\n }\n\n private onBlockEntityDelimiter(\n node: Node | null,\n entity: ContentModelEntity,\n parent: ContentModelBlockGroup\n ) {\n if (isNodeOfType(node, 'ELEMENT_NODE') && isEntityDelimiter(node) && node.firstChild) {\n const indexedDelimiter = node.firstChild as IndexedEntityDelimiter;\n\n indexedDelimiter.__roosterjsContentModel = { entity, parent };\n }\n }\n\n private isCollapsed(selection: RangeSelectionForCache): boolean {\n const { start, end } = selection;\n\n return start.node == end.node && start.offset == end.offset;\n }\n\n private reconcileNodeSelection(\n node: Node,\n offset: number,\n defaultFormat?: ContentModelSegmentFormat\n ): Selectable | undefined {\n if (isNodeOfType(node, 'TEXT_NODE')) {\n if (isIndexedSegment(node)) {\n return this.reconcileTextSelection(node, offset);\n } else if (isIndexedDelimiter(node)) {\n return this.reconcileDelimiterSelection(node, defaultFormat);\n } else {\n return undefined;\n }\n } else if (offset >= node.childNodes.length) {\n return this.insertMarker(node.lastChild, true /*isAfter*/);\n } else {\n return this.insertMarker(node.childNodes[offset], false /*isAfter*/);\n }\n }\n\n private insertMarker(node: Node | null, isAfter: boolean): Selectable | undefined {\n let marker: ContentModelSelectionMarker | undefined;\n const segmentItem = node && getIndexedSegmentItem(node);\n\n if (segmentItem) {\n const { paragraph, segments } = segmentItem;\n const index = paragraph.segments.indexOf(segments[0]);\n\n if (index >= 0) {\n const formatSegment =\n (!isAfter && paragraph.segments[index - 1]) || paragraph.segments[index];\n marker = createSelectionMarker(formatSegment.format);\n\n paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);\n }\n }\n\n return marker;\n }\n\n private reconcileTextSelection(\n textNode: IndexedSegmentNode,\n startOffset?: number,\n endOffset?: number\n ) {\n const { paragraph, segments } = textNode.__roosterjsContentModel;\n const first = segments[0];\n const last = segments[segments.length - 1];\n let selectable: Selectable | undefined;\n\n if (first?.segmentType == 'Text' && last?.segmentType == 'Text') {\n const newSegments: ContentModelSegment[] = [];\n const txt = textNode.nodeValue || '';\n const textSegments: ContentModelText[] = [];\n\n if (startOffset === undefined) {\n first.text = txt;\n newSegments.push(first);\n textSegments.push(first);\n } else {\n if (startOffset > 0) {\n first.text = txt.substring(0, startOffset);\n newSegments.push(first);\n textSegments.push(first);\n }\n\n if (endOffset === undefined) {\n const marker = createSelectionMarker(first.format);\n newSegments.push(marker);\n\n selectable = marker;\n endOffset = startOffset;\n } else if (endOffset > startOffset) {\n const middle = createText(\n txt.substring(startOffset, endOffset),\n first.format,\n first.link,\n first.code\n );\n\n middle.isSelected = true;\n newSegments.push(middle);\n textSegments.push(middle);\n selectable = middle;\n }\n\n if (endOffset < txt.length) {\n const newLast = createText(\n txt.substring(endOffset),\n first.format,\n first.link,\n first.code\n );\n newSegments.push(newLast);\n textSegments.push(newLast);\n }\n }\n\n let firstIndex = paragraph.segments.indexOf(first);\n let lastIndex = paragraph.segments.indexOf(last);\n\n if (firstIndex >= 0 && lastIndex >= 0) {\n while (\n firstIndex > 0 &&\n paragraph.segments[firstIndex - 1].segmentType == 'SelectionMarker'\n ) {\n firstIndex--;\n }\n\n while (\n lastIndex < paragraph.segments.length - 1 &&\n paragraph.segments[lastIndex + 1].segmentType == 'SelectionMarker'\n ) {\n lastIndex++;\n }\n\n paragraph.segments.splice(firstIndex, lastIndex - firstIndex + 1, ...newSegments);\n }\n\n this.onSegment(textNode, paragraph, textSegments);\n\n if (!this.persistCache) {\n delete paragraph.cachedElement;\n }\n } else if (first?.segmentType == 'Entity' && first == last) {\n const wrapper = first.wrapper;\n const index = paragraph.segments.indexOf(first);\n const delimiter = textNode.parentElement;\n const isBefore = wrapper.previousSibling == delimiter;\n const isAfter = wrapper.nextSibling == delimiter;\n\n if (index >= 0 && delimiter && isEntityDelimiter(delimiter) && (isBefore || isAfter)) {\n const marker = createSelectionMarker(\n (paragraph.segments[isAfter ? index + 1 : index - 1] ?? first).format\n );\n\n paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);\n\n selectable = marker;\n }\n }\n\n return selectable;\n }\n\n private reconcileDelimiterSelection(\n node: IndexedEntityDelimiter,\n defaultFormat?: ContentModelSegmentFormat\n ) {\n let marker: ContentModelSelectionMarker | undefined;\n\n const { entity, parent } = node.__roosterjsContentModel;\n const index = parent.blocks.indexOf(entity);\n const delimiter = node.parentElement;\n const wrapper = entity.wrapper;\n const isBefore = wrapper.previousSibling == delimiter;\n const isAfter = wrapper.nextSibling == delimiter;\n\n if (index >= 0 && delimiter && isEntityDelimiter(delimiter) && (isBefore || isAfter)) {\n marker = createSelectionMarker(defaultFormat);\n\n const para = createParagraph(\n true /*isImplicit*/,\n undefined /*blockFormat*/,\n defaultFormat\n );\n\n para.segments.push(marker);\n parent.blocks.splice(isBefore ? index : index + 1, 0, para);\n }\n\n return marker;\n }\n\n private reconcileAddedNode(node: Text, context: ReconcileChildListContext): boolean {\n let segmentItem: SegmentItem | null = null;\n let index = -1;\n let existingSegment: ContentModelSegment;\n const { previousSibling, nextSibling } = node;\n\n if (\n (segmentItem = getIndexedSegmentItem(previousSibling)) &&\n (existingSegment = segmentItem.segments[segmentItem.segments.length - 1]) &&\n (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0\n ) {\n // When we can find indexed segment before current one, use it as the insert index\n this.indexNode(segmentItem.paragraph, index + 1, node, existingSegment.format);\n } else if (\n (segmentItem = getIndexedSegmentItem(nextSibling)) &&\n (existingSegment = segmentItem.segments[0]) &&\n (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0\n ) {\n // When we can find indexed segment after current one, use it as the insert index\n this.indexNode(segmentItem.paragraph, index, node, existingSegment.format);\n } else if (context.paragraph && context.segIndex >= 0) {\n // When there is indexed paragraph from removed nodes, we can use it as the insert index\n this.indexNode(context.paragraph, context.segIndex, node, context.format);\n } else if (context.pendingTextNode === undefined) {\n // When we can't find the insert index, set current node as pending node\n // so later we can pick it up when we have enough info when processing removed node\n // Only do this when pendingTextNode is undefined. If it is null it means there was already a pending node before\n // and in that case we should return false since we can't handle two pending text node\n context.pendingTextNode = node;\n } else {\n return false;\n }\n\n return true;\n }\n\n private reconcileRemovedNode(node: Node, context: ReconcileChildListContext): boolean {\n let segmentItem: SegmentItem | null = null;\n let removingSegment: ContentModelSegment;\n\n if (\n context.segIndex < 0 &&\n !context.paragraph && // No previous removed segment or related paragraph found, and\n (segmentItem = getIndexedSegmentItem(node)) && // The removed node is indexed, and\n (removingSegment = segmentItem.segments[0]) // There is at least one related segment\n ) {\n // Now we can remove the indexed segment from the paragraph, and remember it, later we may need to use it\n context.format = removingSegment.format;\n context.paragraph = segmentItem.paragraph;\n context.segIndex = segmentItem.paragraph.segments.indexOf(segmentItem.segments[0]);\n\n if (context.segIndex < 0) {\n // Indexed segment is not under paragraph, something wrong happens, we cannot keep handling\n return false;\n }\n\n for (let i = 0; i < segmentItem.segments.length; i++) {\n const index = segmentItem.paragraph.segments.indexOf(segmentItem.segments[i]);\n\n if (index >= 0) {\n segmentItem.paragraph.segments.splice(index, 1);\n }\n }\n\n if (context.pendingTextNode) {\n // If we have pending text node added but not indexed, do it now\n this.indexNode(\n context.paragraph,\n context.segIndex,\n context.pendingTextNode,\n segmentItem.segments[0].format\n );\n\n // Set to null since we have processed it.\n // Next time we see a pending node we know we have already processed one so it is a situation we cannot handle\n context.pendingTextNode = null;\n }\n\n return true;\n } else {\n return false;\n }\n }\n\n private indexNode(\n paragraph: ContentModelParagraph,\n index: number,\n textNode: Text,\n format?: ContentModelSegmentFormat\n ) {\n const copiedFormat = format ? { ...format } : undefined;\n\n if (copiedFormat) {\n getObjectKeys(copiedFormat).forEach(key => {\n if (EmptySegmentFormat[key] === undefined) {\n delete copiedFormat[key];\n }\n });\n }\n\n const text = createText(textNode.textContent ?? '', copiedFormat);\n\n paragraph.segments.splice(index, 0, text);\n this.onSegment(textNode, paragraph, [text]);\n }\n}\n"]}
1
+ {"version":3,"file":"domIndexerImpl.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/corePlugin/cache/domIndexerImpl.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n EmptySegmentFormat,\n addCode,\n addLink,\n createParagraph,\n createSelectionMarker,\n createText,\n getObjectKeys,\n isElementOfType,\n isEntityDelimiter,\n isNodeOfType,\n setSelection,\n} from 'roosterjs-content-model-dom';\nimport type {\n CacheSelection,\n ContentModelBlockGroup,\n ContentModelDocument,\n ContentModelEntity,\n ContentModelParagraph,\n ContentModelSegment,\n ContentModelSegmentFormat,\n ContentModelSelectionMarker,\n ContentModelTable,\n ContentModelText,\n DomIndexer,\n DOMSelection,\n RangeSelectionForCache,\n Selectable,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal Export for test only\n */\nexport interface SegmentItem {\n paragraph: ContentModelParagraph;\n segments: ContentModelSegment[];\n}\n\n/**\n * @internal Export for test only\n */\nexport interface TableItem {\n table: ContentModelTable;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface BlockEntityDelimiterItem {\n entity: ContentModelEntity;\n parent: ContentModelBlockGroup;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedSegmentNode extends Node {\n __roosterjsContentModel: SegmentItem;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedTableElement extends HTMLTableElement {\n __roosterjsContentModel: TableItem;\n}\n\n/**\n * @internal Export for test only\n */\nexport interface IndexedEntityDelimiter extends Text {\n __roosterjsContentModel: BlockEntityDelimiterItem;\n}\n\n/**\n * Context object used by DomIndexer when reconcile mutations with child list\n */\ninterface ReconcileChildListContext {\n /**\n * Index of segment in current paragraph\n */\n segIndex: number;\n\n /**\n * The current paragraph that we are handling\n */\n paragraph?: ContentModelParagraph;\n\n /**\n * Text node that is added from mutation but has not been handled. This can happen when we first see an added node then later we see a removed one.\n * e.g. Type text in an empty paragraph (&lt;div&gt;&lt;br&gt;&lt;/div&gt;), so a text node will be added and &lt;BR&gt; will be removed.\n * Set to a valid text node means we need to handle it later. If it is finally not handled, that means we need to clear cache\n * Set to undefined (initial value) means no pending text node is hit yet (valid case)\n * Set to null means there was a pending text node which is already handled, so if we see another pending text node,\n * we should clear cache since we don't know how to handle it\n */\n pendingTextNode?: Text | null;\n\n /**\n * Format of the removed segment, this will be used as the format for newly created segment\n */\n format?: ContentModelSegmentFormat;\n}\n\nfunction isIndexedSegment(node: Node): node is IndexedSegmentNode {\n const { paragraph, segments } = (node as IndexedSegmentNode).__roosterjsContentModel ?? {};\n\n return (\n paragraph &&\n paragraph.blockType == 'Paragraph' &&\n Array.isArray(paragraph.segments) &&\n Array.isArray(segments)\n );\n}\n\nfunction isIndexedDelimiter(node: Node): node is IndexedEntityDelimiter {\n const { entity, parent } = (node as IndexedEntityDelimiter).__roosterjsContentModel ?? {};\n\n return (\n entity?.blockType == 'Entity' &&\n entity.wrapper &&\n parent?.blockGroupType &&\n Array.isArray(parent.blocks)\n );\n}\n\nfunction getIndexedSegmentItem(node: Node | null): SegmentItem | null {\n return node && isIndexedSegment(node) ? node.__roosterjsContentModel : null;\n}\n\nfunction getIndexedTableItem(element: HTMLTableElement): TableItem | null {\n const index = (element as IndexedTableElement).__roosterjsContentModel;\n const table = index?.table;\n\n if (\n table?.blockType == 'Table' &&\n Array.isArray(table.rows) &&\n table.rows.every(\n x => Array.isArray(x?.cells) && x.cells.every(y => y?.blockGroupType == 'TableCell')\n )\n ) {\n return index;\n } else {\n return null;\n }\n}\n\n/**\n * @internal\n * Implementation of DomIndexer\n */\nexport class DomIndexerImpl implements DomIndexer {\n constructor(private readonly persistCache?: boolean) {}\n\n onSegment(segmentNode: Node, paragraph: ContentModelParagraph, segment: ContentModelSegment[]) {\n const indexedText = segmentNode as IndexedSegmentNode;\n indexedText.__roosterjsContentModel = {\n paragraph,\n segments: segment,\n };\n }\n\n onParagraph(paragraphElement: HTMLElement) {\n let previousText: Text | null = null;\n\n for (let child = paragraphElement.firstChild; child; child = child.nextSibling) {\n if (isNodeOfType(child, 'TEXT_NODE')) {\n if (!previousText) {\n previousText = child;\n } else {\n const item = getIndexedSegmentItem(previousText);\n\n if (item && isIndexedSegment(child)) {\n item.segments = item.segments.concat(\n child.__roosterjsContentModel.segments\n );\n child.__roosterjsContentModel.segments = [];\n }\n }\n } else if (isNodeOfType(child, 'ELEMENT_NODE')) {\n previousText = null;\n\n this.onParagraph(child);\n } else {\n previousText = null;\n }\n }\n }\n\n onTable(tableElement: HTMLTableElement, table: ContentModelTable) {\n const indexedTable = tableElement as IndexedTableElement;\n indexedTable.__roosterjsContentModel = { table };\n }\n\n onBlockEntity(entity: ContentModelEntity, group: ContentModelBlockGroup) {\n this.onBlockEntityDelimiter(entity.wrapper.previousSibling, entity, group);\n this.onBlockEntityDelimiter(entity.wrapper.nextSibling, entity, group);\n }\n\n reconcileSelection(\n model: ContentModelDocument,\n newSelection: DOMSelection,\n oldSelection?: CacheSelection\n ): boolean {\n if (oldSelection) {\n if (\n oldSelection.type == 'range' &&\n this.isCollapsed(oldSelection) &&\n isNodeOfType(oldSelection.start.node, 'TEXT_NODE') &&\n isIndexedSegment(oldSelection.start.node)\n ) {\n this.reconcileTextSelection(oldSelection.start.node);\n } else {\n setSelection(model);\n }\n }\n\n switch (newSelection.type) {\n case 'image':\n const indexedImage = getIndexedSegmentItem(newSelection.image);\n const image = indexedImage?.segments[0];\n\n if (image) {\n image.isSelected = true;\n setSelection(model, image);\n\n return true;\n } else {\n return false;\n }\n\n case 'table':\n const indexedTable = getIndexedTableItem(newSelection.table);\n\n if (indexedTable) {\n const firstCell =\n indexedTable.table.rows[newSelection.firstRow]?.cells[\n newSelection.firstColumn\n ];\n const lastCell =\n indexedTable.table.rows[newSelection.lastRow]?.cells[\n newSelection.lastColumn\n ];\n\n if (firstCell && lastCell) {\n setSelection(model, firstCell, lastCell);\n\n return true;\n }\n }\n\n return false;\n\n case 'range':\n const newRange = newSelection.range;\n if (newRange) {\n const {\n startContainer,\n startOffset,\n endContainer,\n endOffset,\n collapsed,\n } = newRange;\n\n delete model.hasRevertedRangeSelection;\n\n if (collapsed) {\n return !!this.reconcileNodeSelection(\n startContainer,\n startOffset,\n model.format\n );\n } else if (\n startContainer == endContainer &&\n isNodeOfType(startContainer, 'TEXT_NODE')\n ) {\n if (newSelection.isReverted) {\n model.hasRevertedRangeSelection = true;\n }\n\n return (\n isIndexedSegment(startContainer) &&\n !!this.reconcileTextSelection(startContainer, startOffset, endOffset)\n );\n } else {\n const marker1 = this.reconcileNodeSelection(startContainer, startOffset);\n const marker2 = this.reconcileNodeSelection(endContainer, endOffset);\n\n if (marker1 && marker2) {\n if (newSelection.isReverted) {\n model.hasRevertedRangeSelection = true;\n }\n\n setSelection(model, marker1, marker2);\n return true;\n } else {\n return false;\n }\n }\n }\n\n break;\n }\n\n return false;\n }\n\n reconcileChildList(addedNodes: ArrayLike<Node>, removedNodes: ArrayLike<Node>): boolean {\n if (!this.persistCache) {\n return false;\n }\n\n let canHandle = true;\n const context: ReconcileChildListContext = {\n segIndex: -1,\n };\n\n // First process added nodes\n const addedNode = addedNodes[0];\n\n if (addedNodes.length == 1 && isNodeOfType(addedNode, 'TEXT_NODE')) {\n canHandle = this.reconcileAddedNode(addedNode, context);\n } else if (addedNodes.length > 0) {\n canHandle = false;\n }\n\n // Second, process removed nodes\n const removedNode = removedNodes[0];\n\n if (canHandle && removedNodes.length == 1) {\n canHandle = this.reconcileRemovedNode(removedNode, context);\n } else if (removedNodes.length > 0) {\n canHandle = false;\n }\n\n return canHandle && !context.pendingTextNode;\n }\n\n reconcileElementId(element: HTMLElement) {\n if (isElementOfType(element, 'img')) {\n const indexedImg = getIndexedSegmentItem(element);\n\n if (indexedImg?.segments[0]?.segmentType == 'Image') {\n indexedImg.segments[0].format.id = element.id;\n\n return true;\n } else {\n return false;\n }\n } else if (isElementOfType(element, 'table')) {\n const indexedTable = getIndexedTableItem(element);\n\n if (indexedTable) {\n indexedTable.table.format.id = element.id;\n\n return true;\n } else {\n return false;\n }\n } else {\n return false;\n }\n }\n\n private onBlockEntityDelimiter(\n node: Node | null,\n entity: ContentModelEntity,\n parent: ContentModelBlockGroup\n ) {\n if (isNodeOfType(node, 'ELEMENT_NODE') && isEntityDelimiter(node) && node.firstChild) {\n const indexedDelimiter = node.firstChild as IndexedEntityDelimiter;\n\n indexedDelimiter.__roosterjsContentModel = { entity, parent };\n }\n }\n\n private isCollapsed(selection: RangeSelectionForCache): boolean {\n const { start, end } = selection;\n\n return start.node == end.node && start.offset == end.offset;\n }\n\n private reconcileNodeSelection(\n node: Node,\n offset: number,\n defaultFormat?: ContentModelSegmentFormat\n ): Selectable | undefined {\n if (isNodeOfType(node, 'TEXT_NODE')) {\n if (isIndexedSegment(node)) {\n return this.reconcileTextSelection(node, offset);\n } else if (isIndexedDelimiter(node)) {\n return this.reconcileDelimiterSelection(node, defaultFormat);\n } else {\n return undefined;\n }\n } else if (offset >= node.childNodes.length) {\n return this.insertMarker(node.lastChild, true /*isAfter*/);\n } else {\n return this.insertMarker(node.childNodes[offset], false /*isAfter*/);\n }\n }\n\n private insertMarker(node: Node | null, isAfter: boolean): Selectable | undefined {\n let marker: ContentModelSelectionMarker | undefined;\n const segmentItem = node && getIndexedSegmentItem(node);\n\n if (segmentItem) {\n const { paragraph, segments } = segmentItem;\n const index = paragraph.segments.indexOf(segments[0]);\n\n if (index >= 0) {\n const formatSegment =\n (!isAfter && paragraph.segments[index - 1]) || paragraph.segments[index];\n marker = createSelectionMarker(formatSegment.format);\n\n paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);\n }\n }\n\n return marker;\n }\n\n private reconcileTextSelection(\n textNode: IndexedSegmentNode,\n startOffset?: number,\n endOffset?: number\n ) {\n const { paragraph, segments } = textNode.__roosterjsContentModel;\n const first = segments[0];\n const last = segments[segments.length - 1];\n let selectable: Selectable | undefined;\n\n if (first?.segmentType == 'Text' && last?.segmentType == 'Text') {\n const newSegments: ContentModelSegment[] = [];\n const txt = textNode.nodeValue || '';\n const textSegments: ContentModelText[] = [];\n\n if (startOffset === undefined) {\n first.text = txt;\n newSegments.push(first);\n textSegments.push(first);\n } else {\n if (startOffset > 0) {\n first.text = txt.substring(0, startOffset);\n newSegments.push(first);\n textSegments.push(first);\n }\n\n if (endOffset === undefined) {\n const marker = createSelectionMarker(first.format);\n newSegments.push(marker);\n\n if (startOffset < (textNode.nodeValue ?? '').length) {\n if (first.link) {\n addLink(marker, first.link);\n }\n\n if (first.code) {\n addCode(marker, first.code);\n }\n }\n\n selectable = marker;\n endOffset = startOffset;\n } else if (endOffset > startOffset) {\n const middle = createText(\n txt.substring(startOffset, endOffset),\n first.format,\n first.link,\n first.code\n );\n\n middle.isSelected = true;\n newSegments.push(middle);\n textSegments.push(middle);\n selectable = middle;\n }\n\n if (endOffset < txt.length) {\n const newLast = createText(\n txt.substring(endOffset),\n first.format,\n first.link,\n first.code\n );\n newSegments.push(newLast);\n textSegments.push(newLast);\n }\n }\n\n let firstIndex = paragraph.segments.indexOf(first);\n let lastIndex = paragraph.segments.indexOf(last);\n\n if (firstIndex >= 0 && lastIndex >= 0) {\n while (\n firstIndex > 0 &&\n paragraph.segments[firstIndex - 1].segmentType == 'SelectionMarker'\n ) {\n firstIndex--;\n }\n\n while (\n lastIndex < paragraph.segments.length - 1 &&\n paragraph.segments[lastIndex + 1].segmentType == 'SelectionMarker'\n ) {\n lastIndex++;\n }\n\n paragraph.segments.splice(firstIndex, lastIndex - firstIndex + 1, ...newSegments);\n }\n\n this.onSegment(textNode, paragraph, textSegments);\n\n if (!this.persistCache) {\n delete paragraph.cachedElement;\n }\n } else if (first?.segmentType == 'Entity' && first == last) {\n const wrapper = first.wrapper;\n const index = paragraph.segments.indexOf(first);\n const delimiter = textNode.parentElement;\n const isBefore = wrapper.previousSibling == delimiter;\n const isAfter = wrapper.nextSibling == delimiter;\n\n if (index >= 0 && delimiter && isEntityDelimiter(delimiter) && (isBefore || isAfter)) {\n const marker = createSelectionMarker(\n (paragraph.segments[isAfter ? index + 1 : index - 1] ?? first).format\n );\n\n paragraph.segments.splice(isAfter ? index + 1 : index, 0, marker);\n\n selectable = marker;\n }\n }\n\n return selectable;\n }\n\n private reconcileDelimiterSelection(\n node: IndexedEntityDelimiter,\n defaultFormat?: ContentModelSegmentFormat\n ) {\n let marker: ContentModelSelectionMarker | undefined;\n\n const { entity, parent } = node.__roosterjsContentModel;\n const index = parent.blocks.indexOf(entity);\n const delimiter = node.parentElement;\n const wrapper = entity.wrapper;\n const isBefore = wrapper.previousSibling == delimiter;\n const isAfter = wrapper.nextSibling == delimiter;\n\n if (index >= 0 && delimiter && isEntityDelimiter(delimiter) && (isBefore || isAfter)) {\n marker = createSelectionMarker(defaultFormat);\n\n const para = createParagraph(\n true /*isImplicit*/,\n undefined /*blockFormat*/,\n defaultFormat\n );\n\n para.segments.push(marker);\n parent.blocks.splice(isBefore ? index : index + 1, 0, para);\n }\n\n return marker;\n }\n\n private reconcileAddedNode(node: Text, context: ReconcileChildListContext): boolean {\n let segmentItem: SegmentItem | null = null;\n let index = -1;\n let existingSegment: ContentModelSegment;\n const { previousSibling, nextSibling } = node;\n\n if (\n (segmentItem = getIndexedSegmentItem(previousSibling)) &&\n (existingSegment = segmentItem.segments[segmentItem.segments.length - 1]) &&\n (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0\n ) {\n // When we can find indexed segment before current one, use it as the insert index\n this.indexNode(segmentItem.paragraph, index + 1, node, existingSegment.format);\n } else if (\n (segmentItem = getIndexedSegmentItem(nextSibling)) &&\n (existingSegment = segmentItem.segments[0]) &&\n (index = segmentItem.paragraph.segments.indexOf(existingSegment)) >= 0\n ) {\n // When we can find indexed segment after current one, use it as the insert index\n this.indexNode(segmentItem.paragraph, index, node, existingSegment.format);\n } else if (context.paragraph && context.segIndex >= 0) {\n // When there is indexed paragraph from removed nodes, we can use it as the insert index\n this.indexNode(context.paragraph, context.segIndex, node, context.format);\n } else if (context.pendingTextNode === undefined) {\n // When we can't find the insert index, set current node as pending node\n // so later we can pick it up when we have enough info when processing removed node\n // Only do this when pendingTextNode is undefined. If it is null it means there was already a pending node before\n // and in that case we should return false since we can't handle two pending text node\n context.pendingTextNode = node;\n } else {\n return false;\n }\n\n return true;\n }\n\n private reconcileRemovedNode(node: Node, context: ReconcileChildListContext): boolean {\n let segmentItem: SegmentItem | null = null;\n let removingSegment: ContentModelSegment;\n\n if (\n context.segIndex < 0 &&\n !context.paragraph && // No previous removed segment or related paragraph found, and\n (segmentItem = getIndexedSegmentItem(node)) && // The removed node is indexed, and\n (removingSegment = segmentItem.segments[0]) // There is at least one related segment\n ) {\n // Now we can remove the indexed segment from the paragraph, and remember it, later we may need to use it\n context.format = removingSegment.format;\n context.paragraph = segmentItem.paragraph;\n context.segIndex = segmentItem.paragraph.segments.indexOf(segmentItem.segments[0]);\n\n if (context.segIndex < 0) {\n // Indexed segment is not under paragraph, something wrong happens, we cannot keep handling\n return false;\n }\n\n for (let i = 0; i < segmentItem.segments.length; i++) {\n const index = segmentItem.paragraph.segments.indexOf(segmentItem.segments[i]);\n\n if (index >= 0) {\n segmentItem.paragraph.segments.splice(index, 1);\n }\n }\n\n if (context.pendingTextNode) {\n // If we have pending text node added but not indexed, do it now\n this.indexNode(\n context.paragraph,\n context.segIndex,\n context.pendingTextNode,\n segmentItem.segments[0].format\n );\n\n // Set to null since we have processed it.\n // Next time we see a pending node we know we have already processed one so it is a situation we cannot handle\n context.pendingTextNode = null;\n }\n\n return true;\n } else {\n return false;\n }\n }\n\n private indexNode(\n paragraph: ContentModelParagraph,\n index: number,\n textNode: Text,\n format?: ContentModelSegmentFormat\n ) {\n const copiedFormat = format ? { ...format } : undefined;\n\n if (copiedFormat) {\n getObjectKeys(copiedFormat).forEach(key => {\n if (EmptySegmentFormat[key] === undefined) {\n delete copiedFormat[key];\n }\n });\n }\n\n const text = createText(textNode.textContent ?? '', copiedFormat);\n\n paragraph.segments.splice(index, 0, text);\n this.onSegment(textNode, paragraph, [text]);\n }\n}\n"]}
package/package.json CHANGED
@@ -3,10 +3,10 @@
3
3
  "description": "Core editor for roosterjs",
4
4
  "dependencies": {
5
5
  "tslib": "^2.3.1",
6
- "roosterjs-content-model-dom": "^9.11.0",
7
- "roosterjs-content-model-types": "^9.11.0"
6
+ "roosterjs-content-model-dom": "^9.12.0",
7
+ "roosterjs-content-model-types": "^9.12.0"
8
8
  },
9
- "version": "9.11.1",
9
+ "version": "9.12.0",
10
10
  "main": "./lib/index.js",
11
11
  "typings": "./lib/index.d.ts",
12
12
  "module": "./lib-mjs/index.js",