You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
3.1 KiB
100 lines
3.1 KiB
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* |
|
* This source code is licensed under the MIT license found in the |
|
* LICENSE file in the root directory of this source tree. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var flattenChildren = require('./flattenChildren'); |
|
|
|
var ReactTransitionChildMapping = { |
|
/** |
|
* Given `this.props.children`, return an object mapping key to child. Just |
|
* simple syntactic sugar around flattenChildren(). |
|
* |
|
* @param {*} children `this.props.children` |
|
* @param {number=} selfDebugID Optional debugID of the current internal instance. |
|
* @return {object} Mapping of key to child |
|
*/ |
|
getChildMapping: function (children, selfDebugID) { |
|
if (!children) { |
|
return children; |
|
} |
|
|
|
if (process.env.NODE_ENV !== 'production') { |
|
return flattenChildren(children, selfDebugID); |
|
} |
|
|
|
return flattenChildren(children); |
|
}, |
|
|
|
/** |
|
* When you're adding or removing children some may be added or removed in the |
|
* same render pass. We want to show *both* since we want to simultaneously |
|
* animate elements in and out. This function takes a previous set of keys |
|
* and a new set of keys and merges them with its best guess of the correct |
|
* ordering. In the future we may expose some of the utilities in |
|
* ReactMultiChild to make this easy, but for now React itself does not |
|
* directly have this concept of the union of prevChildren and nextChildren |
|
* so we implement it here. |
|
* |
|
* @param {object} prev prev children as returned from |
|
* `ReactTransitionChildMapping.getChildMapping()`. |
|
* @param {object} next next children as returned from |
|
* `ReactTransitionChildMapping.getChildMapping()`. |
|
* @return {object} a key set that contains all keys in `prev` and all keys |
|
* in `next` in a reasonable order. |
|
*/ |
|
mergeChildMappings: function (prev, next) { |
|
prev = prev || {}; |
|
next = next || {}; |
|
|
|
function getValueForKey(key) { |
|
if (next.hasOwnProperty(key)) { |
|
return next[key]; |
|
} else { |
|
return prev[key]; |
|
} |
|
} |
|
|
|
// For each key of `next`, the list of keys to insert before that key in |
|
// the combined list |
|
var nextKeysPending = {}; |
|
|
|
var pendingKeys = []; |
|
for (var prevKey in prev) { |
|
if (next.hasOwnProperty(prevKey)) { |
|
if (pendingKeys.length) { |
|
nextKeysPending[prevKey] = pendingKeys; |
|
pendingKeys = []; |
|
} |
|
} else { |
|
pendingKeys.push(prevKey); |
|
} |
|
} |
|
|
|
var i; |
|
var childMapping = {}; |
|
for (var nextKey in next) { |
|
if (nextKeysPending.hasOwnProperty(nextKey)) { |
|
for (i = 0; i < nextKeysPending[nextKey].length; i++) { |
|
var pendingNextKey = nextKeysPending[nextKey][i]; |
|
childMapping[nextKeysPending[nextKey][i]] = getValueForKey(pendingNextKey); |
|
} |
|
} |
|
childMapping[nextKey] = getValueForKey(nextKey); |
|
} |
|
|
|
// Finally, add the keys which didn't appear before any key in `next` |
|
for (i = 0; i < pendingKeys.length; i++) { |
|
childMapping[pendingKeys[i]] = getValueForKey(pendingKeys[i]); |
|
} |
|
|
|
return childMapping; |
|
} |
|
}; |
|
|
|
module.exports = ReactTransitionChildMapping; |