1 | /**
|
2 | * Copyright (c) 2013-present, Facebook, Inc.
|
3 | *
|
4 | * This source code is licensed under the MIT license found in the
|
5 | * LICENSE file in the root directory of this source tree.
|
6 | *
|
7 | */
|
8 |
|
9 | ;
|
10 |
|
11 | var flattenChildren = require('./flattenChildren');
|
12 |
|
13 | var ReactTransitionChildMapping = {
|
14 | /**
|
15 | * Given `this.props.children`, return an object mapping key to child. Just
|
16 | * simple syntactic sugar around flattenChildren().
|
17 | *
|
18 | * @param {*} children `this.props.children`
|
19 | * @param {number=} selfDebugID Optional debugID of the current internal instance.
|
20 | * @return {object} Mapping of key to child
|
21 | */
|
22 | getChildMapping: function (children, selfDebugID) {
|
23 | if (!children) {
|
24 | return children;
|
25 | }
|
26 |
|
27 | if (process.env.NODE_ENV !== 'production') {
|
28 | return flattenChildren(children, selfDebugID);
|
29 | }
|
30 |
|
31 | return flattenChildren(children);
|
32 | },
|
33 |
|
34 | /**
|
35 | * When you're adding or removing children some may be added or removed in the
|
36 | * same render pass. We want to show *both* since we want to simultaneously
|
37 | * animate elements in and out. This function takes a previous set of keys
|
38 | * and a new set of keys and merges them with its best guess of the correct
|
39 | * ordering. In the future we may expose some of the utilities in
|
40 | * ReactMultiChild to make this easy, but for now React itself does not
|
41 | * directly have this concept of the union of prevChildren and nextChildren
|
42 | * so we implement it here.
|
43 | *
|
44 | * @param {object} prev prev children as returned from
|
45 | * `ReactTransitionChildMapping.getChildMapping()`.
|
46 | * @param {object} next next children as returned from
|
47 | * `ReactTransitionChildMapping.getChildMapping()`.
|
48 | * @return {object} a key set that contains all keys in `prev` and all keys
|
49 | * in `next` in a reasonable order.
|
50 | */
|
51 | mergeChildMappings: function (prev, next) {
|
52 | prev = prev || {};
|
53 | next = next || {};
|
54 |
|
55 | function getValueForKey(key) {
|
56 | if (next.hasOwnProperty(key)) {
|
57 | return next[key];
|
58 | } else {
|
59 | return prev[key];
|
60 | }
|
61 | }
|
62 |
|
63 | // For each key of `next`, the list of keys to insert before that key in
|
64 | // the combined list
|
65 | var nextKeysPending = {};
|
66 |
|
67 | var pendingKeys = [];
|
68 | for (var prevKey in prev) {
|
69 | if (next.hasOwnProperty(prevKey)) {
|
70 | if (pendingKeys.length) {
|
71 | nextKeysPending[prevKey] = pendingKeys;
|
72 | pendingKeys = [];
|
73 | }
|
74 | } else {
|
75 | pendingKeys.push(prevKey);
|
76 | }
|
77 | }
|
78 |
|
79 | var i;
|
80 | var childMapping = {};
|
81 | for (var nextKey in next) {
|
82 | if (nextKeysPending.hasOwnProperty(nextKey)) {
|
83 | for (i = 0; i < nextKeysPending[nextKey].length; i++) {
|
84 | var pendingNextKey = nextKeysPending[nextKey][i];
|
85 | childMapping[nextKeysPending[nextKey][i]] = getValueForKey(pendingNextKey);
|
86 | }
|
87 | }
|
88 | childMapping[nextKey] = getValueForKey(nextKey);
|
89 | }
|
90 |
|
91 | // Finally, add the keys which didn't appear before any key in `next`
|
92 | for (i = 0; i < pendingKeys.length; i++) {
|
93 | childMapping[pendingKeys[i]] = getValueForKey(pendingKeys[i]);
|
94 | }
|
95 |
|
96 | return childMapping;
|
97 | }
|
98 | };
|
99 |
|
100 | module.exports = ReactTransitionChildMapping; |
\ | No newline at end of file |