proxy-based Twister client written with react-js
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.

104 lines
3.2 KiB

/**
* Copyright 2013-2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @typechecks static-only
* @providesModule ReactTransitionChildMapping
*/
'use strict';
var ReactChildren = require("./ReactChildren");
var ReactFragment = require("./ReactFragment");
var ReactTransitionChildMapping = {
/**
* Given `this.props.children`, return an object mapping key to child. Just
* simple syntactic sugar around ReactChildren.map().
*
* @param {*} children `this.props.children`
* @return {object} Mapping of key to child
*/
getChildMapping: function(children) {
if (!children) {
return children;
}
return ReactFragment.extract(ReactChildren.map(children, function(child) {
return child;
}));
},
/**
* 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;