Skip to content

Commit

Permalink
Remove NodeType from Content Model (#2106)
Browse files Browse the repository at this point in the history
  • Loading branch information
JiuqingSong authored Sep 27, 2023
1 parent 368e88e commit 0c928db
Show file tree
Hide file tree
Showing 14 changed files with 40 additions and 56 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { addSelectionMarker } from '../utils/addSelectionMarker';
import { getRegularSelectionOffsets } from '../utils/getRegularSelectionOffsets';
import { isNodeOfType } from '../../domUtils/isNodeOfType';
import { NodeType, SelectionRangeTypes } from 'roosterjs-editor-types';
import { SelectionRangeTypes } from 'roosterjs-editor-types';
import {
ContentModelBlockGroup,
DomToModelContext,
Expand Down Expand Up @@ -45,9 +45,9 @@ export function processChildNode(
child: Node,
context: DomToModelContext
) {
if (isNodeOfType(child, NodeType.Element) && child.style.display != 'none') {
if (isNodeOfType(child, 'ELEMENT_NODE') && child.style.display != 'none') {
context.elementProcessors.element(group, child, context);
} else if (isNodeOfType(child, NodeType.Text)) {
} else if (isNodeOfType(child, 'TEXT_NODE')) {
context.elementProcessors['#text'](group, child, context);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,57 +1,56 @@
import { NodeType } from 'roosterjs-editor-types';

/**
* A type map from node type number to its type declaration. This is used by utility function isNodeOfType()
*/
export interface NodeTypeMap {
/**
* Attribute node
*/
[NodeType.Attribute]: Attr;
ATTRIBUTE_NODE: Attr;

/**
* Comment node
*/
[NodeType.Comment]: Comment;
COMMENT_NODE: Comment;

/**
* DocumentFragment node
*/
[NodeType.DocumentFragment]: DocumentFragment;
DOCUMENT_FRAGMENT_NODE: DocumentFragment;

/**
* Document node
*/
[NodeType.Document]: Document;
DOCUMENT_NODE: Document;

/**
* DocumentType node
*/
[NodeType.DocumentType]: DocumentType;
DOCUMENT_TYPE_NODE: DocumentType;

/**
* HTMLElement node
*/
[NodeType.Element]: HTMLElement;
ELEMENT_NODE: HTMLElement;

/**
* ProcessingInstruction node
*/
[NodeType.ProcessingInstruction]: ProcessingInstruction;
PROCESSING_INSTRUCTION_NODE: ProcessingInstruction;

/**
* Text node
*/
[NodeType.Text]: Text;
TEXT_NODE: Text;
}

/**
* Type checker for Node. Return true if it of the specified node type
* @param node The node to check
* @param expectedType The type to check
*/
export function isNodeOfType<T extends NodeType>(
export function isNodeOfType<T extends keyof NodeTypeMap>(
node: Node | null | undefined,
expectedType: T
): node is NodeTypeMap[T] {
return !!node && node.nodeType == expectedType;
return !!node && node.nodeType == Node[expectedType];
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { FormatHandler } from '../FormatHandler';
import { getObjectKeys, getTagOfNode } from 'roosterjs-editor-dom';
import { isNodeOfType } from '../../domUtils/isNodeOfType';
import { ListMetadataFormat } from 'roosterjs-content-model-types';
import { NodeType } from 'roosterjs-editor-types';
import { OrderedMap, UnorderedMap } from './listLevelMetadataFormatHandler';

const OrderedMapPlaceholderRegex = /\$\{(\w+)\}/;
Expand Down Expand Up @@ -36,7 +35,7 @@ export const listItemMetadataFormatHandler: FormatHandler<ListMetadataFormat> =
const parent = element.parentNode;
const depth = context.listFormat.nodeStack.length - 2; // Minus two for the parent element and convert length to index

if (depth >= 0 && isNodeOfType(parent, NodeType.Element) && !parent.style.listStyleType) {
if (depth >= 0 && isNodeOfType(parent, 'ELEMENT_NODE') && !parent.style.listStyleType) {
const parentTag = getTagOfNode(parent);
const style =
parentTag == 'OL'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import { createRange, Position, toArray } from 'roosterjs-editor-dom';
import { isNodeOfType } from '../domUtils/isNodeOfType';
import { NodePosition, SelectionRangeEx, SelectionRangeTypes } from 'roosterjs-editor-types';
import {
ContentModelDocument,
ModelToDomBlockAndSegmentNode,
ModelToDomContext,
OnNodeCreated,
} from 'roosterjs-content-model-types';
import {
NodePosition,
NodeType,
SelectionRangeEx,
SelectionRangeTypes,
} from 'roosterjs-editor-types';

/**
* Create DOM tree fragment from Content Model document
Expand Down Expand Up @@ -92,7 +87,7 @@ function calcPosition(pos: ModelToDomBlockAndSegmentNode): NodePosition | undefi
if (pos.block) {
if (!pos.segment) {
result = new Position(pos.block, 0);
} else if (isNodeOfType(pos.segment, NodeType.Text)) {
} else if (isNodeOfType(pos.segment, 'TEXT_NODE')) {
result = new Position(pos.segment, pos.segment.nodeValue?.length || 0);
} else {
result = new Position(
Expand All @@ -104,7 +99,7 @@ function calcPosition(pos: ModelToDomBlockAndSegmentNode): NodePosition | undefi
}
}

if (isNodeOfType(result?.node, NodeType.DocumentFragment)) {
if (isNodeOfType(result?.node, 'DOCUMENT_FRAGMENT_NODE')) {
result = result?.normalize();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { handleSegmentCommon } from '../utils/handleSegmentCommon';
import { isNodeOfType } from '../../domUtils/isNodeOfType';
import { NodeType } from 'roosterjs-editor-types';
import { reuseCachedElement } from '../utils/reuseCachedElement';
import { wrap } from 'roosterjs-editor-dom';
import {
Expand Down Expand Up @@ -51,7 +50,7 @@ export const handleGeneralSegment: ContentModelSegmentHandler<ContentModelGenera
group.element = node;
parent.appendChild(node);

if (isNodeOfType(node, NodeType.Element)) {
if (isNodeOfType(node, 'ELEMENT_NODE')) {
const element = wrap(node, 'span');

handleSegmentCommon(doc, node, element, group, context, segmentNodes);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { isNodeOfType } from '../../domUtils/isNodeOfType';
import { NodeType } from 'roosterjs-editor-types';

const OptimizeTags = ['SPAN', 'B', 'EM', 'I', 'U', 'SUB', 'SUP', 'STRIKE', 'S', 'A', 'CODE'];

Expand All @@ -12,8 +11,8 @@ export function mergeNode(root: Node) {

if (
next &&
isNodeOfType(child, NodeType.Element) &&
isNodeOfType(next, NodeType.Element) &&
isNodeOfType(child, 'ELEMENT_NODE') &&
isNodeOfType(next, 'ELEMENT_NODE') &&
child.tagName == next.tagName &&
OptimizeTags.indexOf(child.tagName) >= 0 &&
hasSameAttributes(child, next)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EntityClasses, NodeType } from 'roosterjs-editor-types';
import { EntityClasses } from 'roosterjs-editor-types';
import { isNodeOfType } from '../../domUtils/isNodeOfType';
import { mergeNode } from './mergeNode';
import { removeUnnecessarySpan } from './removeUnnecessarySpan';
Expand All @@ -11,7 +11,7 @@ export function optimize(root: Node) {
* Do no do any optimization to entity
*/
if (
isNodeOfType(root, NodeType.Element) &&
isNodeOfType(root, 'ELEMENT_NODE') &&
root.classList.contains(EntityClasses.ENTITY_INFO_NAME)
) {
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { isNodeOfType } from '../../domUtils/isNodeOfType';
import { NodeType } from 'roosterjs-editor-types';

/**
* @internal
*/
export function removeUnnecessarySpan(root: Node) {
for (let child = root.firstChild; child; ) {
if (
isNodeOfType(child, NodeType.Element) &&
isNodeOfType(child, 'ELEMENT_NODE') &&
child.tagName == 'SPAN' &&
child.attributes.length == 0
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { getEntityFromElement } from 'roosterjs-editor-dom';
import { isNodeOfType } from '../../domUtils/isNodeOfType';
import { NodeType } from 'roosterjs-editor-types';

/**
* @internal
Expand Down Expand Up @@ -40,5 +39,5 @@ export function removeNode(node: Node): Node | null {
}

function isEntity(node: Node) {
return isNodeOfType(node, NodeType.Element) && !!getEntityFromElement(node);
return isNodeOfType(node, 'ELEMENT_NODE') && !!getEntityFromElement(node);
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import {
SelectionRangeTypes,
SelectionRangeEx,
ColorTransformDirection,
NodeType,
} from 'roosterjs-editor-types';

/**
Expand Down Expand Up @@ -278,7 +277,7 @@ export const onNodeCreated: OnNodeCreated = (_, node): void => {
if (safeInstanceOf(node, 'HTMLTableElement')) {
wrap(node, 'div');
}
if (isNodeOfType(node, NodeType.Element) && !node.isContentEditable) {
if (isNodeOfType(node, 'ELEMENT_NODE') && !node.isContentEditable) {
node.removeAttribute('contenteditable');
}
};
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { getStyles } from 'roosterjs-editor-dom';
import { NodeType } from 'roosterjs-editor-types';
import {
addBlock,
createListItem,
createListLevel,
isNodeOfType,
parseFormat,
} from 'roosterjs-content-model-dom';
import {
Expand Down Expand Up @@ -184,7 +184,7 @@ function getFakeBulletText(node: Node, levels?: number): string {
if (result.length == 0) {
result = 'o';
}
} else if (child.nodeType == NodeType.Element && levels > 1) {
} else if (isNodeOfType(child, 'ELEMENT_NODE') && levels > 1) {
// If this is an element and we are not in the last level, try to get the fake bullet
// out of the child
result = getFakeBulletText(child, levels - 1);
Expand All @@ -201,7 +201,7 @@ function getFakeBulletText(node: Node, levels?: number): string {
* HTML lists
*/
function isIgnoreNode(node: Node): boolean {
if (node.nodeType == NodeType.Element) {
if (isNodeOfType(node, 'ELEMENT_NODE')) {
let listAttribute = getStyles(node as HTMLElement)[MSO_LIST];
if (
listAttribute &&
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { createSelectionMarker, createText, isNodeOfType } from 'roosterjs-content-model-dom';
import { setSelection } from '../../modelApi/selection/setSelection';
import {
NodeType,
SelectionRangeEx,
SelectionRangeTypes,
TableSelection,
} from 'roosterjs-editor-types';
import { SelectionRangeEx, SelectionRangeTypes, TableSelection } from 'roosterjs-editor-types';
import {
ContentModelDocument,
ContentModelDomIndexer,
Expand Down Expand Up @@ -79,7 +74,7 @@ function onParagraph(paragraphElement: HTMLElement) {
let previousText: Text | null = null;

for (let child = paragraphElement.firstChild; child; child = child.nextSibling) {
if (isNodeOfType(child, NodeType.Text)) {
if (isNodeOfType(child, 'TEXT_NODE')) {
if (!previousText) {
previousText = child;
} else {
Expand All @@ -92,7 +87,7 @@ function onParagraph(paragraphElement: HTMLElement) {
child.__roosterjsContentModel.segments = [];
}
}
} else if (isNodeOfType(child, NodeType.Element)) {
} else if (isNodeOfType(child, 'ELEMENT_NODE')) {
previousText = null;

onParagraph(child);
Expand All @@ -118,7 +113,7 @@ function reconcileSelection(
if (
oldRangeEx?.type == SelectionRangeTypes.Normal &&
range?.collapsed &&
isNodeOfType(range.startContainer, NodeType.Text)
isNodeOfType(oldRangeEx.ranges[0].startContainer, 'TEXT_NODE')
) {
if (isIndexedSegment(range.startContainer)) {
reconcileTextSelection(range.startContainer);
Expand Down Expand Up @@ -176,7 +171,7 @@ function reconcileSelection(
return !!reconcileNodeSelection(startContainer, startOffset);
} else if (
startContainer == endContainer &&
isNodeOfType(startContainer, NodeType.Text)
isNodeOfType(startContainer, 'TEXT_NODE')
) {
return (
isIndexedSegment(startContainer) &&
Expand All @@ -202,7 +197,7 @@ function reconcileSelection(
}

function reconcileNodeSelection(node: Node, offset: number): Selectable | undefined {
if (isNodeOfType(node, NodeType.Text)) {
if (isNodeOfType(node, 'TEXT_NODE')) {
return isIndexedSegment(node) ? reconcileTextSelection(node, offset) : undefined;
} else if (offset >= node.childNodes.length) {
return insertMarker(node.lastChild, true /*isAfter*/);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Browser, isModifierKey } from 'roosterjs-editor-dom';
import { ChangeSource, Keys, NodeType, SelectionRangeTypes } from 'roosterjs-editor-types';
import { ChangeSource, Keys, SelectionRangeTypes } from 'roosterjs-editor-types';
import { deleteAllSegmentBefore } from '../../modelApi/edit/deleteSteps/deleteAllSegmentBefore';
import { DeleteResult, DeleteSelectionStep } from '../../modelApi/edit/utils/DeleteSelectionStep';
import { deleteSelection } from '../../modelApi/edit/deleteSelection';
import { formatWithContentModel } from '../utils/formatWithContentModel';
import { IContentModelEditor } from '../../publicTypes/IContentModelEditor';
import { isNodeOfType } from 'roosterjs-content-model-dom';
import {
handleKeyboardEventResult,
shouldDeleteAllSegmentsBefore,
Expand Down Expand Up @@ -77,7 +78,7 @@ function getDeleteSteps(rawEvent: KeyboardEvent): (DeleteSelectionStep | null)[]
function shouldDeleteWithContentModel(range: Range | null, rawEvent: KeyboardEvent) {
return !(
range?.collapsed &&
range.startContainer.nodeType == NodeType.Text &&
isNodeOfType(range.startContainer, 'TEXT_NODE') &&
!isModifierKey(rawEvent) &&
(canDeleteBefore(rawEvent, range) || canDeleteAfter(rawEvent, range))
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { getPendingFormat, setPendingFormat } from '../../modelApi/format/pendin
import { IContentModelEditor } from '../../publicTypes/IContentModelEditor';
import { isBlockElement, Position } from 'roosterjs-editor-dom';
import { isNodeOfType, normalizeContentModel } from 'roosterjs-content-model-dom';
import { NodePosition, NodeType, SelectionRangeTypes } from 'roosterjs-editor-types';
import { NodePosition, SelectionRangeTypes } from 'roosterjs-editor-types';

/**
* @internal
Expand All @@ -20,7 +20,7 @@ export default function applyDefaultFormat(editor: IContentModelEditor) {
let node: Node | null = startPos?.node ?? null;

while (node && editor.contains(node)) {
if (isNodeOfType(node, NodeType.Element) && node.getAttribute?.('style')) {
if (isNodeOfType(node, 'ELEMENT_NODE') && node.getAttribute?.('style')) {
return;
} else if (isBlockElement(node)) {
break;
Expand Down

0 comments on commit 0c928db

Please sign in to comment.