Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81152 views
1
/**
2
* Copyright 2013-2014, Facebook, Inc.
3
* All rights reserved.
4
*
5
* This source code is licensed under the BSD-style license found in the
6
* LICENSE file in the root directory of this source tree. An additional grant
7
* of patent rights can be found in the PATENTS file in the same directory.
8
*
9
* @providesModule ReactChildren
10
*/
11
12
"use strict";
13
14
var PooledClass = require('PooledClass');
15
16
var traverseAllChildren = require('traverseAllChildren');
17
var warning = require('warning');
18
19
var twoArgumentPooler = PooledClass.twoArgumentPooler;
20
var threeArgumentPooler = PooledClass.threeArgumentPooler;
21
22
/**
23
* PooledClass representing the bookkeeping associated with performing a child
24
* traversal. Allows avoiding binding callbacks.
25
*
26
* @constructor ForEachBookKeeping
27
* @param {!function} forEachFunction Function to perform traversal with.
28
* @param {?*} forEachContext Context to perform context with.
29
*/
30
function ForEachBookKeeping(forEachFunction, forEachContext) {
31
this.forEachFunction = forEachFunction;
32
this.forEachContext = forEachContext;
33
}
34
PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler);
35
36
function forEachSingleChild(traverseContext, child, name, i) {
37
var forEachBookKeeping = traverseContext;
38
forEachBookKeeping.forEachFunction.call(
39
forEachBookKeeping.forEachContext, child, i);
40
}
41
42
/**
43
* Iterates through children that are typically specified as `props.children`.
44
*
45
* The provided forEachFunc(child, index) will be called for each
46
* leaf child.
47
*
48
* @param {?*} children Children tree container.
49
* @param {function(*, int)} forEachFunc.
50
* @param {*} forEachContext Context for forEachContext.
51
*/
52
function forEachChildren(children, forEachFunc, forEachContext) {
53
if (children == null) {
54
return children;
55
}
56
57
var traverseContext =
58
ForEachBookKeeping.getPooled(forEachFunc, forEachContext);
59
traverseAllChildren(children, forEachSingleChild, traverseContext);
60
ForEachBookKeeping.release(traverseContext);
61
}
62
63
/**
64
* PooledClass representing the bookkeeping associated with performing a child
65
* mapping. Allows avoiding binding callbacks.
66
*
67
* @constructor MapBookKeeping
68
* @param {!*} mapResult Object containing the ordered map of results.
69
* @param {!function} mapFunction Function to perform mapping with.
70
* @param {?*} mapContext Context to perform mapping with.
71
*/
72
function MapBookKeeping(mapResult, mapFunction, mapContext) {
73
this.mapResult = mapResult;
74
this.mapFunction = mapFunction;
75
this.mapContext = mapContext;
76
}
77
PooledClass.addPoolingTo(MapBookKeeping, threeArgumentPooler);
78
79
function mapSingleChildIntoContext(traverseContext, child, name, i) {
80
var mapBookKeeping = traverseContext;
81
var mapResult = mapBookKeeping.mapResult;
82
83
var keyUnique = !mapResult.hasOwnProperty(name);
84
warning(
85
keyUnique,
86
'ReactChildren.map(...): Encountered two children with the same key, ' +
87
'`%s`. Child keys must be unique; when two children share a key, only ' +
88
'the first child will be used.',
89
name
90
);
91
92
if (keyUnique) {
93
var mappedChild =
94
mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i);
95
mapResult[name] = mappedChild;
96
}
97
}
98
99
/**
100
* Maps children that are typically specified as `props.children`.
101
*
102
* The provided mapFunction(child, key, index) will be called for each
103
* leaf child.
104
*
105
* TODO: This may likely break any calls to `ReactChildren.map` that were
106
* previously relying on the fact that we guarded against null children.
107
*
108
* @param {?*} children Children tree container.
109
* @param {function(*, int)} mapFunction.
110
* @param {*} mapContext Context for mapFunction.
111
* @return {object} Object containing the ordered map of results.
112
*/
113
function mapChildren(children, func, context) {
114
if (children == null) {
115
return children;
116
}
117
118
var mapResult = {};
119
var traverseContext = MapBookKeeping.getPooled(mapResult, func, context);
120
traverseAllChildren(children, mapSingleChildIntoContext, traverseContext);
121
MapBookKeeping.release(traverseContext);
122
return mapResult;
123
}
124
125
function forEachSingleChildDummy(traverseContext, child, name, i) {
126
return null;
127
}
128
129
/**
130
* Count the number of children that are typically specified as
131
* `props.children`.
132
*
133
* @param {?*} children Children tree container.
134
* @return {number} The number of children.
135
*/
136
function countChildren(children, context) {
137
return traverseAllChildren(children, forEachSingleChildDummy, null);
138
}
139
140
var ReactChildren = {
141
forEach: forEachChildren,
142
map: mapChildren,
143
count: countChildren
144
};
145
146
module.exports = ReactChildren;
147
148