1 | import { EMPTY_OBJECT, EMPTY_ARRAY, TEXT_NODE, RECYCLED_NODE } from './utils'
|
2 | /**
|
3 | * @typedef {Object.<string, any> | {}} Props
|
4 | * @property {Children} Props.children
|
5 | */
|
6 | /**
|
7 | * @typedef {VNode[]} Children
|
8 | */
|
9 | /**
|
10 | * @typedef {string | number | Function} Type
|
11 | * @typedef {number | string | null} Key
|
12 | * @typedef {Object.<string, any>} VNode
|
13 | * @property {Type} VNode.type
|
14 | * @property {Props} VNode.props
|
15 | * @property {Children} VNode.children
|
16 | * @property {Element} VNode.element
|
17 | * @property {Key} [VNode.key]
|
18 | * @property {number} VNode.flag
|
19 | */
|
20 | /**
|
21 | * Create a virtual node with the provided properties.
|
22 | * @param {string | Function} type
|
23 | * @param {Props} props
|
24 | * @param {Children} children
|
25 | * @param {Element} element
|
26 | * @param {string | number | null} key
|
27 | * @param {number} flag
|
28 | * @return {VNode} VNode
|
29 | */
|
30 | export function createVNode(type, props, children, element, key, flag) {
|
31 | return {
|
32 | type,
|
33 | props,
|
34 | children,
|
35 | element,
|
36 | key,
|
37 | flag
|
38 | }
|
39 | }
|
40 |
|
41 | /**
|
42 | * Create a virtual text node.
|
43 | * @param {string} text
|
44 | * @param {Element} [element]
|
45 | * @return {VNode} VNode
|
46 | */
|
47 | export function createTextVNode(text, element) {
|
48 | return createVNode(text, EMPTY_OBJECT, EMPTY_ARRAY, element, null, TEXT_NODE)
|
49 | }
|
50 |
|
51 | /**
|
52 | * Create a virtual node represeting an element and its children.
|
53 | * @param {Element} element
|
54 | * @return {VNode} VNode
|
55 | */
|
56 | export function vnodeFromElement(element) {
|
57 | return createVNode(
|
58 | element.nodeName.toLowerCase(),
|
59 | EMPTY_OBJECT,
|
60 | EMPTY_ARRAY.map.call(element.childNodes, vnodeFromChild),
|
61 | element,
|
62 | null,
|
63 | RECYCLED_NODE
|
64 | )
|
65 | }
|
66 |
|
67 | /**
|
68 | * Cycle through the child nodes of an element and create virtual nodes of them.
|
69 | * @param {Element} element
|
70 | * @return {VNode}
|
71 | */
|
72 | function vnodeFromChild(element) {
|
73 | if (element.nodeType === 3) {
|
74 | return createTextVNode(element.nodeValue, element)
|
75 | } else {
|
76 | return vnodeFromElement(element)
|
77 | }
|
78 | }
|