react / react-0.13.3 / examples / basic-commonjs / node_modules / reactify / node_modules / react-tools / src / utils / ReactChildren.js
81152 views/**1* Copyright 2013-2014, Facebook, Inc.2* All rights reserved.3*4* This source code is licensed under the BSD-style license found in the5* LICENSE file in the root directory of this source tree. An additional grant6* of patent rights can be found in the PATENTS file in the same directory.7*8* @providesModule ReactChildren9*/1011"use strict";1213var PooledClass = require('PooledClass');1415var traverseAllChildren = require('traverseAllChildren');16var warning = require('warning');1718var twoArgumentPooler = PooledClass.twoArgumentPooler;19var threeArgumentPooler = PooledClass.threeArgumentPooler;2021/**22* PooledClass representing the bookkeeping associated with performing a child23* traversal. Allows avoiding binding callbacks.24*25* @constructor ForEachBookKeeping26* @param {!function} forEachFunction Function to perform traversal with.27* @param {?*} forEachContext Context to perform context with.28*/29function ForEachBookKeeping(forEachFunction, forEachContext) {30this.forEachFunction = forEachFunction;31this.forEachContext = forEachContext;32}33PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler);3435function forEachSingleChild(traverseContext, child, name, i) {36var forEachBookKeeping = traverseContext;37forEachBookKeeping.forEachFunction.call(38forEachBookKeeping.forEachContext, child, i);39}4041/**42* Iterates through children that are typically specified as `props.children`.43*44* The provided forEachFunc(child, index) will be called for each45* leaf child.46*47* @param {?*} children Children tree container.48* @param {function(*, int)} forEachFunc.49* @param {*} forEachContext Context for forEachContext.50*/51function forEachChildren(children, forEachFunc, forEachContext) {52if (children == null) {53return children;54}5556var traverseContext =57ForEachBookKeeping.getPooled(forEachFunc, forEachContext);58traverseAllChildren(children, forEachSingleChild, traverseContext);59ForEachBookKeeping.release(traverseContext);60}6162/**63* PooledClass representing the bookkeeping associated with performing a child64* mapping. Allows avoiding binding callbacks.65*66* @constructor MapBookKeeping67* @param {!*} mapResult Object containing the ordered map of results.68* @param {!function} mapFunction Function to perform mapping with.69* @param {?*} mapContext Context to perform mapping with.70*/71function MapBookKeeping(mapResult, mapFunction, mapContext) {72this.mapResult = mapResult;73this.mapFunction = mapFunction;74this.mapContext = mapContext;75}76PooledClass.addPoolingTo(MapBookKeeping, threeArgumentPooler);7778function mapSingleChildIntoContext(traverseContext, child, name, i) {79var mapBookKeeping = traverseContext;80var mapResult = mapBookKeeping.mapResult;8182var keyUnique = !mapResult.hasOwnProperty(name);83warning(84keyUnique,85'ReactChildren.map(...): Encountered two children with the same key, ' +86'`%s`. Child keys must be unique; when two children share a key, only ' +87'the first child will be used.',88name89);9091if (keyUnique) {92var mappedChild =93mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i);94mapResult[name] = mappedChild;95}96}9798/**99* Maps children that are typically specified as `props.children`.100*101* The provided mapFunction(child, key, index) will be called for each102* leaf child.103*104* TODO: This may likely break any calls to `ReactChildren.map` that were105* previously relying on the fact that we guarded against null children.106*107* @param {?*} children Children tree container.108* @param {function(*, int)} mapFunction.109* @param {*} mapContext Context for mapFunction.110* @return {object} Object containing the ordered map of results.111*/112function mapChildren(children, func, context) {113if (children == null) {114return children;115}116117var mapResult = {};118var traverseContext = MapBookKeeping.getPooled(mapResult, func, context);119traverseAllChildren(children, mapSingleChildIntoContext, traverseContext);120MapBookKeeping.release(traverseContext);121return mapResult;122}123124function forEachSingleChildDummy(traverseContext, child, name, i) {125return null;126}127128/**129* Count the number of children that are typically specified as130* `props.children`.131*132* @param {?*} children Children tree container.133* @return {number} The number of children.134*/135function countChildren(children, context) {136return traverseAllChildren(children, forEachSingleChildDummy, null);137}138139var ReactChildren = {140forEach: forEachChildren,141map: mapChildren,142count: countChildren143};144145module.exports = ReactChildren;146147148