forked from facebook/react
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathflattenChildren.js
More file actions
93 lines (82 loc) · 2.7 KB
/
flattenChildren.js
File metadata and controls
93 lines (82 loc) · 2.7 KB
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
84
85
86
87
88
89
90
91
92
93
/**
* Copyright 2013 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @providesModule flattenChildren
*/
"use strict";
var ReactTextComponent = require('ReactTextComponent');
var escapeTextForBrowser = require('escapeTextForBrowser');
var throwIf = require('throwIf');
/**
* @polyFill Array.isArray
*/
var INVALID_CHILD = 'INVALID_CHILD';
if (__DEV__) {
INVALID_CHILD =
'You may not pass a child of that type to a React component. It ' +
'is a common mistake to try to pass a standard browser DOM element ' +
'as a child of a React component.';
}
/**
* If there is only a single child, it still needs a name.
*/
var ONLY_CHILD_NAME = '0';
var flattenChildrenImpl = function(res, children, nameSoFar) {
if (Array.isArray(children)) {
for (var i = 0; i < children.length; i++) {
flattenChildrenImpl(res, children[i], nameSoFar + '[' + i + ']');
}
} else {
var type = typeof children;
var isOnlyChild = nameSoFar === '';
var storageName = isOnlyChild ? ONLY_CHILD_NAME : nameSoFar;
if (children === null || children === undefined || type === 'boolean') {
res[storageName] = null;
} else if (children.mountComponentIntoNode) {
/* We found a component instance */
res[storageName] = children;
} else {
if (type === 'object') {
throwIf(children && children.nodeType === 1, INVALID_CHILD);
for (var key in children) {
if (children.hasOwnProperty(key)) {
flattenChildrenImpl(
res,
children[key],
nameSoFar + '{' + escapeTextForBrowser(key) + '}'
);
}
}
} else if (type === 'string') {
res[storageName] = new ReactTextComponent(children);
} else if (type === 'number') {
res[storageName] = new ReactTextComponent('' + children);
}
}
}
};
/**
* Flattens children that are typically specified as `props.children`.
* @return {!Object} flattened children keyed by name.
*/
function flattenChildren(children) {
if (children === null || children === undefined) {
return children;
}
var result = {};
flattenChildrenImpl(result, children, '');
return result;
}
module.exports = flattenChildren;