Skip to content

Commit

Permalink
Standalone editor: remove SelectionRangeEx from Content Model (#2103)
Browse files Browse the repository at this point in the history
* Remove SelectionRangeEx from ContentModel

* fix test

* improve

* fix build

* fix test
  • Loading branch information
JiuqingSong authored Sep 28, 2023
1 parent 24e280c commit 4de6e53
Show file tree
Hide file tree
Showing 63 changed files with 1,078 additions and 1,165 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { createContentModelDocument } from '../modelApi/creators/createContentModelDocument';
import { normalizeContentModel } from '../modelApi/common/normalizeContentModel';
import type { ContentModelDocument, DomToModelContext } from 'roosterjs-content-model-types';
import type { SelectionRangeEx } from 'roosterjs-editor-types';
import type {
ContentModelDocument,
DOMSelection,
DomToModelContext,
} from 'roosterjs-content-model-types';

/**
* Create Content Model from DOM tree in this editor
Expand All @@ -13,11 +16,11 @@ import type { SelectionRangeEx } from 'roosterjs-editor-types';
export function domToContentModel(
root: HTMLElement | DocumentFragment,
context: DomToModelContext,
selection?: SelectionRangeEx
selection?: DOMSelection
): ContentModelDocument {
const model = createContentModelDocument(context.defaultFormat);

context.rangeEx = selection;
context.selection = selection;
context.elementProcessors.child(model, root, context);

normalizeContentModel(model);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { addSelectionMarker } from '../utils/addSelectionMarker';
import { getRegularSelectionOffsets } from '../utils/getRegularSelectionOffsets';
import { isNodeOfType } from '../../domUtils/isNodeOfType';
import { SelectionRangeTypes } from 'roosterjs-editor-types';
import type {
ContentModelBlockGroup,
DomToModelContext,
Expand Down Expand Up @@ -73,8 +72,8 @@ export function handleRegularSelection(
addSelectionMarker(group, context);
}

if (index == nodeEndOffset && context.rangeEx?.type == SelectionRangeTypes.Normal) {
if (!context.rangeEx.areAllCollapsed) {
if (index == nodeEndOffset && context.selection?.type == 'range') {
if (!context.selection.range.collapsed) {
addSelectionMarker(group, context);
}
context.isInSelection = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { addDecorators } from '../../modelApi/common/addDecorators';
import { addSegment } from '../../modelApi/common/addSegment';
import { createImage } from '../../modelApi/creators/createImage';
import { parseFormat } from '../utils/parseFormat';
import { SelectionRangeTypes } from 'roosterjs-editor-types';
import { stackFormat } from '../utils/stackFormat';
import type { ContentModelImageFormat, ElementProcessor } from 'roosterjs-content-model-types';

Expand Down Expand Up @@ -33,10 +32,7 @@ export const imageProcessor: ElementProcessor<HTMLImageElement> = (group, elemen
if (context.isInSelection) {
image.isSelected = true;
}
if (
context.rangeEx?.type == SelectionRangeTypes.ImageSelection &&
context.rangeEx.image == element
) {
if (context.selection?.type == 'image' && context.selection.image == element) {
image.isSelectedAsImageSelection = true;
image.isSelected = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { createTableCell } from '../../modelApi/creators/createTableCell';
import { getBoundingClientRect } from '../utils/getBoundingClientRect';
import { parseFormat } from '../utils/parseFormat';
import { safeInstanceOf } from 'roosterjs-editor-dom';
import { SelectionRangeTypes } from 'roosterjs-editor-types';
import { stackFormat } from '../utils/stackFormat';
import type {
ContentModelTableCellFormat,
Expand Down Expand Up @@ -41,16 +40,9 @@ export const tableProcessor: ElementProcessor<HTMLTableElement> = (
parseFormat(tableElement, context.formatParsers.block, context.blockFormat, context);

const table = createTable(tableElement.rows.length, context.blockFormat);
const tableSelection =
context.rangeEx?.type == SelectionRangeTypes.TableSelection
? context.rangeEx
: null;
const tableSelection = context.selection?.type == 'table' ? context.selection : null;
const selectedTable = tableSelection?.table;
const coordinates = tableSelection?.coordinates;
const hasTableSelection =
selectedTable == tableElement &&
!!coordinates?.firstCell &&
!!coordinates?.lastCell;
const hasTableSelection = selectedTable == tableElement;

if (context.allowCacheElement) {
table.cachedElement = tableElement;
Expand Down Expand Up @@ -229,10 +221,11 @@ export const tableProcessor: ElementProcessor<HTMLTableElement> = (
if (
(hasSelectionBeforeCell && hasSelectionAfterCell) ||
(hasTableSelection &&
row >= coordinates.firstCell.y &&
row <= coordinates.lastCell.y &&
targetCol >= coordinates.firstCell.x &&
targetCol <= coordinates.lastCell.x)
tableSelection &&
row >= tableSelection.firstRow &&
row <= tableSelection.lastRow &&
targetCol >= tableSelection.firstColumn &&
targetCol <= tableSelection.lastColumn)
) {
cell.isSelected = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ export const textProcessor: ElementProcessor<Text> = (
const subText = txt.substring(0, txtEndOffset);
segments.push(addTextSegment(group, subText, paragraph, context));

if (context.rangeEx && !context.rangeEx.areAllCollapsed) {
if (
context.selection &&
(context.selection.type != 'range' || !context.selection.range.collapsed)
) {
addSelectionMarker(group, context);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { SelectionRangeTypes } from 'roosterjs-editor-types';
import type { DomToModelContext } from 'roosterjs-content-model-types';

/**
Expand All @@ -12,8 +11,7 @@ export function getRegularSelectionOffsets(
context: DomToModelContext,
currentContainer: Node
): [number, number] {
const range =
context.rangeEx?.type == SelectionRangeTypes.Normal ? context.rangeEx.ranges[0] : null;
const range = context.selection?.type == 'range' ? context.selection.range : null;

let startOffset = range?.startContainer == currentContainer ? range.startOffset : -1;
let endOffset = range?.endContainer == currentContainer ? range.endOffset! : -1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { createRange, Position, toArray } from 'roosterjs-editor-dom';
import { isNodeOfType } from '../domUtils/isNodeOfType';
import { SelectionRangeTypes } from 'roosterjs-editor-types';
import type {
ContentModelDocument,
DOMSelection,
ModelToDomBlockAndSegmentNode,
ModelToDomContext,
OnNodeCreated,
} from 'roosterjs-content-model-types';
import type { NodePosition, SelectionRangeEx } from 'roosterjs-editor-types';
import type { NodePosition } from 'roosterjs-editor-types';

/**
* Create DOM tree fragment from Content Model document
Expand All @@ -26,7 +26,7 @@ export function contentModelToDom(
model: ContentModelDocument,
context: ModelToDomContext,
onNodeCreated?: OnNodeCreated
): SelectionRangeEx | null {
): DOMSelection | null {
context.onNodeCreated = onNodeCreated;

context.modelHandlers.blockGroupChildren(doc, root, model, context);
Expand All @@ -38,7 +38,7 @@ export function contentModelToDom(
return range;
}

function extractSelectionRange(context: ModelToDomContext): SelectionRangeEx | null {
function extractSelectionRange(context: ModelToDomContext): DOMSelection | null {
const {
regularSelection: { start, end },
tableSelection,
Expand All @@ -48,35 +48,18 @@ function extractSelectionRange(context: ModelToDomContext): SelectionRangeEx | n
let startPosition: NodePosition | undefined;
let endPosition: NodePosition | undefined;

if (imageSelection?.image) {
return {
type: SelectionRangeTypes.ImageSelection,
ranges: [createRange(imageSelection.image)],
areAllCollapsed: false,
image: imageSelection.image,
};
if (imageSelection) {
return imageSelection;
} else if (
(startPosition = start && calcPosition(start)) &&
(endPosition = end && calcPosition(end))
) {
const range = createRange(startPosition, endPosition);

return {
type: SelectionRangeTypes.Normal,
ranges: [createRange(startPosition, endPosition)],
areAllCollapsed: range.collapsed,
};
} else if (tableSelection?.table) {
return {
type: SelectionRangeTypes.TableSelection,
ranges: [],
areAllCollapsed: false,
table: tableSelection.table,
coordinates: {
firstCell: tableSelection.firstCell,
lastCell: tableSelection.lastCell,
},
type: 'range',
range: createRange(startPosition, endPosition),
};
} else if (tableSelection) {
return tableSelection;
} else {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const handleImage: ContentModelSegmentHandler<ContentModelImage> = (

if (imageModel.isSelectedAsImageSelection) {
context.imageSelection = {
type: 'image',
image: img,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {
ContentModelBlockHandler,
ContentModelTable,
ModelToDomContext,
TableSelection,
} from 'roosterjs-content-model-types';

/**
Expand Down Expand Up @@ -76,18 +77,21 @@ export const handleTable: ContentModelBlockHandler<ContentModelTable> = (
const cell = tableRow.cells[col];

if (cell.isSelected) {
context.tableSelection = context.tableSelection || {
const tableSelection: TableSelection = context.tableSelection || {
type: 'table',
table: tableNode,
firstCell: { x: col, y: row },
lastCell: { x: col, y: row },
firstColumn: col,
lastColumn: col,
firstRow: row,
lastRow: row,
};

if (context.tableSelection.table == tableNode) {
const lastCell = context.tableSelection.lastCell;

lastCell.x = Math.max(lastCell.x, col);
lastCell.y = Math.max(lastCell.y, row);
if (tableSelection.table == tableNode) {
tableSelection.lastColumn = Math.max(tableSelection.lastColumn, col);
tableSelection.lastRow = Math.max(tableSelection.lastRow, row);
}

context.tableSelection = tableSelection;
}

if (!cell.spanAbove && !cell.spanLeft) {
Expand Down
Loading

0 comments on commit 4de6e53

Please sign in to comment.