|
1 |
| -const tree = { |
2 |
| - type: 'View', |
3 |
| - props: {}, |
4 |
| - children: [ |
5 |
| - { |
6 |
| - type: function ParentComponent() {}, |
7 |
| - props: {}, |
8 |
| - children: [ |
9 |
| - { |
10 |
| - type: 'View', |
11 |
| - props: {}, |
12 |
| - children: [ |
13 |
| - { |
14 |
| - type: function MiddleComponent() {}, |
15 |
| - props: {}, |
16 |
| - children: [ |
17 |
| - { |
18 |
| - type: 'View', |
19 |
| - props: {}, |
20 |
| - children: [ |
21 |
| - { |
22 |
| - type: 'Text', |
23 |
| - props: {}, |
24 |
| - children: ['hello'], |
25 |
| - }, |
26 |
| - ], |
27 |
| - }, |
28 |
| - { |
29 |
| - type: 'Text', |
30 |
| - props: {}, |
31 |
| - children: ['world'], |
32 |
| - }, |
33 |
| - ], |
34 |
| - }, |
35 |
| - ], |
36 |
| - }, |
37 |
| - { |
38 |
| - type: 'Text', |
39 |
| - props: {}, |
40 |
| - children: ['hello', ' ', 'world'], |
41 |
| - }, |
42 |
| - ], |
43 |
| - }, |
44 |
| - ], |
45 |
| -}; |
46 |
| - |
47 | 1 | function flat(arr) {
|
48 | 2 | return arr.reduce((arr, toFlatten) => {
|
49 | 3 | return arr.concat(Array.isArray(toFlatten) ? flat(toFlatten) : toFlatten);
|
50 | 4 | }, []);
|
51 | 5 | }
|
52 | 6 |
|
53 | 7 | function toJSON(node) {
|
| 8 | + // If the node is a string return it |
54 | 9 | if (typeof node === 'string') {
|
55 | 10 | return node;
|
56 | 11 | }
|
57 | 12 |
|
| 13 | + // We don't want children being included in the props |
58 | 14 | const { children, ...props } = node.props;
|
59 | 15 |
|
60 |
| - let renderedChildren = []; |
61 |
| - if (node.children && node.children.length) { |
62 |
| - for (let i = 0; i < node.children.length; i++) { |
63 |
| - const renderedChild = toJSON(node.children[i]); |
64 |
| - |
65 |
| - renderedChildren.push(renderedChild); |
66 |
| - } |
67 |
| - } |
68 |
| - |
69 |
| - renderedChildren = flat(renderedChildren); |
| 16 | + // Convert all children to the JSON format |
| 17 | + const renderedChildren = flat(node.children.map(child => toJSON(child))); |
70 | 18 |
|
| 19 | + // If there's no parent, return the base element not in an array |
71 | 20 | if (node.parent === null) {
|
72 | 21 | return renderedChildren[0];
|
73 | 22 | }
|
74 | 23 |
|
| 24 | + // Hoist children so that only "native elements" are in the output |
75 | 25 | if (typeof node.type !== 'string') {
|
76 | 26 | return renderedChildren;
|
77 | 27 | }
|
78 | 28 |
|
79 |
| - const json = { |
| 29 | + // Finally, create the JSON object |
| 30 | + return { |
| 31 | + $$typeof: Symbol.for('react.test.json'), |
| 32 | + parent: node.parent, |
80 | 33 | type: node.type,
|
81 | 34 | props,
|
82 | 35 | children: renderedChildren,
|
83 | 36 | };
|
84 |
| - Object.defineProperty(json, '$$typeof', { |
85 |
| - value: Symbol.for('react.test.json'), |
86 |
| - }); |
87 |
| - Object.defineProperty(json, 'parent', { |
88 |
| - value: node.parent, |
89 |
| - }); |
90 |
| - return json; |
91 | 37 | }
|
92 | 38 |
|
93 |
| -export { toJSON }; |
| 39 | +export { flat, toJSON }; |
0 commit comments