/
childProcessor.ts
83 lines (74 loc) · 2.68 KB
/
childProcessor.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import { addSelectionMarker } from '../utils/addSelectionMarker';
import { getRegularSelectionOffsets } from '../utils/getRegularSelectionOffsets';
import { isNodeOfType } from '../../domUtils/isNodeOfType';
import type {
ContentModelBlockGroup,
DomToModelContext,
ElementProcessor,
} from 'roosterjs-content-model-types';
/**
* Content Model Element Processor for child elements
* @param group The parent block group
* @param parent Parent DOM node to process
* @param context DOM to Content Model context
*/
export const childProcessor: ElementProcessor<ParentNode> = (
group: ContentModelBlockGroup,
parent: ParentNode,
context: DomToModelContext
) => {
const [nodeStartOffset, nodeEndOffset] = getRegularSelectionOffsets(context, parent);
let index = 0;
for (let child = parent.firstChild; child; child = child.nextSibling) {
handleRegularSelection(index, context, group, nodeStartOffset, nodeEndOffset, parent);
processChildNode(group, child, context);
index++;
}
handleRegularSelection(index, context, group, nodeStartOffset, nodeEndOffset, parent);
};
/**
* Helper function for processing child node
* @param group The parent block group
* @param parent Parent DOM node to process
* @param context DOM to Content Model context
*
*/
export function processChildNode(
group: ContentModelBlockGroup,
child: Node,
context: DomToModelContext
) {
if (isNodeOfType(child, 'ELEMENT_NODE') && child.style.display != 'none') {
context.elementProcessors.element(group, child, context);
} else if (isNodeOfType(child, 'TEXT_NODE')) {
context.elementProcessors['#text'](group, child, context);
}
}
/**
* Helper function to handle regular (range based) selection when process child node
* @param index Index of current child node in its parent
* @param context DOM to Content Model context
* @param group The parent block group
* @param nodeStartOffset Start offset of current regular selection
* @param nodeEndOffset End offset of current regular selection
* @param container The container node of this selection
*/
export function handleRegularSelection(
index: number,
context: DomToModelContext,
group: ContentModelBlockGroup,
nodeStartOffset: number,
nodeEndOffset: number,
container?: Node
) {
if (index == nodeStartOffset) {
context.isInSelection = true;
addSelectionMarker(group, context, container, index);
}
if (index == nodeEndOffset && context.selection?.type == 'range') {
if (!context.selection.range.collapsed) {
addSelectionMarker(group, context, container, index);
}
context.isInSelection = false;
}
}