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