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 | * @param {string | Function} type
|
22 | * @param {Props} props
|
23 | * @param {Children} children
|
24 | * @param {Element} element
|
25 | * @param {Key} key
|
26 | * @param {number} flag
|
27 | * @return {VNode} VNode
|
28 | */
|
29 |
|
30 | /**
|
31 | * Create a virtual node with the provided properties.
|
32 | * @param {string | Function} type
|
33 | * @param {Props} props
|
34 | * @param {Children} children
|
35 | * @param {Element} element
|
36 | * @param {string | number | null} key
|
37 | * @param {number} flag
|
38 | * @return {VNode} VNode
|
39 | */
|
40 | export function createVNode(type, props, children, element, key, flag) {
|
41 | return {
|
42 | type,
|
43 | props,
|
44 | children,
|
45 | element,
|
46 | key,
|
47 | flag
|
48 | }
|
49 | }
|
50 |
|
51 | /**
|
52 | * Create a virtual text node.
|
53 | * @param {string} text
|
54 | * @param {Element} [element]
|
55 | * @return {VNode} VNode
|
56 | */
|
57 | export function createTextVNode(text, element) {
|
58 | return createVNode(text, EMPTY_OBJECT, EMPTY_ARRAY, element, null, TEXT_NODE)
|
59 | }
|
60 |
|
61 | /**
|
62 | * Create a virtual node represeting an element and its children.
|
63 | * @param {Element} element
|
64 | * @return {VNode} VNode
|
65 | */
|
66 | export function vnodeFromElement(element) {
|
67 | return createVNode(
|
68 | element.nodeName.toLowerCase(),
|
69 | EMPTY_OBJECT,
|
70 | EMPTY_ARRAY.map.call(element.childNodes, vnodeFromChild),
|
71 | element,
|
72 | null,
|
73 | RECYCLED_NODE
|
74 | )
|
75 | }
|
76 |
|
77 | /**
|
78 | * Cycle through the child nodes of an element and create virtual nodes of them.
|
79 | * @param {Element} element
|
80 | * @return {VNode}
|
81 | */
|
82 | function vnodeFromChild(element) {
|
83 | if (element.nodeType === 3) {
|
84 | return createTextVNode(element.nodeValue, element)
|
85 | } else {
|
86 | return vnodeFromElement(element)
|
87 | }
|
88 | }
|