react 0.8.0 → 0.9.0-rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/README.md +0 -8
  2. package/addons.js +0 -3
  3. package/lib/AutoFocusMixin.js +30 -0
  4. package/lib/CSSCore.js +22 -21
  5. package/lib/CSSProperty.js +31 -0
  6. package/lib/ChangeEventPlugin.js +26 -4
  7. package/lib/ClientReactRootIndex.js +30 -0
  8. package/lib/CompositionEventPlugin.js +57 -9
  9. package/lib/DOMChildrenOperations.js +32 -2
  10. package/lib/DOMProperty.js +2 -0
  11. package/lib/DOMPropertyOperations.js +14 -1
  12. package/lib/Danger.js +8 -7
  13. package/lib/DefaultDOMPropertyConfig.js +12 -2
  14. package/lib/EnterLeaveEventPlugin.js +37 -4
  15. package/lib/EventConstants.js +3 -0
  16. package/lib/EventListener.js +42 -34
  17. package/lib/EventPluginHub.js +113 -12
  18. package/lib/EventPluginRegistry.js +39 -16
  19. package/lib/EventPluginUtils.js +32 -3
  20. package/lib/EventPropagators.js +6 -42
  21. package/lib/ExecutionEnvironment.js +3 -0
  22. package/lib/LinkedValueUtils.js +161 -0
  23. package/lib/PooledClass.js +6 -0
  24. package/lib/React.js +27 -3
  25. package/lib/ReactCSSTransitionGroup.js +65 -0
  26. package/lib/{ReactTransitionableChild.js → ReactCSSTransitionGroupChild.js} +21 -35
  27. package/lib/ReactComponent.js +87 -52
  28. package/lib/ReactComponentBrowserEnvironment.js +67 -49
  29. package/lib/ReactComponentEnvironment.js +2 -0
  30. package/lib/ReactCompositeComponent.js +547 -112
  31. package/lib/ReactContext.js +67 -0
  32. package/lib/ReactDOM.js +13 -0
  33. package/lib/ReactDOMButton.js +4 -0
  34. package/lib/ReactDOMComponent.js +46 -21
  35. package/lib/ReactDOMForm.js +9 -2
  36. package/lib/ReactDOMIDOperations.js +105 -60
  37. package/lib/ReactDOMImg.js +58 -0
  38. package/lib/ReactDOMInput.js +26 -14
  39. package/lib/ReactDOMOption.js +1 -0
  40. package/lib/ReactDOMSelect.js +36 -17
  41. package/lib/ReactDOMTextarea.js +12 -8
  42. package/lib/ReactDefaultInjection.js +50 -26
  43. package/lib/ReactDefaultPerf.js +207 -370
  44. package/lib/ReactDefaultPerfAnalysis.js +199 -0
  45. package/lib/ReactErrorUtils.js +5 -14
  46. package/lib/ReactEventEmitter.js +141 -145
  47. package/lib/ReactEventEmitterMixin.js +0 -32
  48. package/lib/ReactEventTopLevelCallback.js +32 -12
  49. package/lib/ReactInjection.js +39 -0
  50. package/lib/ReactInstanceHandles.js +35 -19
  51. package/lib/ReactLink.js +1 -1
  52. package/lib/ReactMount.js +127 -103
  53. package/lib/ReactMountReady.js +1 -1
  54. package/lib/ReactMultiChild.js +30 -46
  55. package/lib/ReactMultiChildUpdateTypes.js +2 -0
  56. package/lib/ReactOwner.js +10 -2
  57. package/lib/ReactPerf.js +5 -8
  58. package/lib/ReactPropTransferer.js +40 -21
  59. package/lib/ReactPropTypeLocationNames.js +31 -0
  60. package/lib/ReactPropTypeLocations.js +29 -0
  61. package/lib/ReactPropTypes.js +248 -47
  62. package/lib/ReactPutListenerQueue.js +61 -0
  63. package/lib/ReactReconcileTransaction.js +20 -0
  64. package/lib/ReactRootIndex.js +36 -0
  65. package/lib/ReactServerRendering.js +8 -11
  66. package/lib/ReactTextComponent.js +8 -3
  67. package/lib/{ReactTransitionKeySet.js → ReactTransitionChildMapping.js} +42 -47
  68. package/lib/ReactTransitionGroup.js +132 -57
  69. package/lib/ReactUpdates.js +14 -11
  70. package/lib/ReactWithAddons.js +7 -2
  71. package/lib/SelectEventPlugin.js +22 -39
  72. package/lib/ServerReactRootIndex.js +36 -0
  73. package/lib/SimpleEventPlugin.js +54 -6
  74. package/lib/SyntheticClipboardEvent.js +7 -1
  75. package/lib/SyntheticDragEvent.js +44 -0
  76. package/lib/SyntheticEvent.js +2 -1
  77. package/lib/SyntheticKeyboardEvent.js +4 -2
  78. package/lib/SyntheticWheelEvent.js +10 -7
  79. package/lib/Transaction.js +61 -36
  80. package/lib/cloneWithProps.js +59 -0
  81. package/lib/createArrayFrom.js +10 -13
  82. package/lib/createFullPageComponent.js +63 -0
  83. package/lib/cx.js +2 -2
  84. package/lib/flattenChildren.js +5 -2
  85. package/lib/getActiveElement.js +4 -3
  86. package/lib/getEventKey.js +85 -0
  87. package/lib/getMarkupWrap.js +10 -0
  88. package/lib/getTextContentAccessor.js +5 -3
  89. package/lib/getUnboundedScrollPosition.js +2 -2
  90. package/lib/invariant.js +12 -4
  91. package/lib/isEventSupported.js +7 -11
  92. package/lib/mergeHelpers.js +5 -6
  93. package/lib/onlyChild.js +43 -0
  94. package/lib/shouldUpdateReactComponent.js +58 -0
  95. package/lib/toArray.js +75 -0
  96. package/lib/traverseAllChildren.js +69 -7
  97. package/lib/warning.js +40 -0
  98. package/package.json +2 -3
  99. package/react.js +0 -3
  100. package/ReactJSErrors.js +0 -40
  101. package/lib/$.js +0 -46
  102. package/lib/CallbackRegistry.js +0 -91
  103. package/lib/LinkedValueMixin.js +0 -68
  104. package/lib/ex.js +0 -49
  105. package/lib/filterAttributes.js +0 -45
  106. package/lib/ge.js +0 -76
  107. package/lib/mutateHTMLNodeWithMarkup.js +0 -100
@@ -36,11 +36,16 @@ var shouldWrap = {
36
36
  // Force wrapping for SVG elements because if they get created inside a <div>,
37
37
  // they will be initialized in the wrong namespace (and will not display).
38
38
  'circle': true,
39
+ 'defs': true,
39
40
  'g': true,
40
41
  'line': true,
42
+ 'linearGradient': true,
41
43
  'path': true,
44
+ 'polygon': true,
42
45
  'polyline': true,
46
+ 'radialGradient': true,
43
47
  'rect': true,
48
+ 'stop': true,
44
49
  'text': true
45
50
  };
46
51
 
@@ -72,11 +77,16 @@ var markupWrap = {
72
77
  'th': trWrap,
73
78
 
74
79
  'circle': svgWrap,
80
+ 'defs': svgWrap,
75
81
  'g': svgWrap,
76
82
  'line': svgWrap,
83
+ 'linearGradient': svgWrap,
77
84
  'path': svgWrap,
85
+ 'polygon': svgWrap,
78
86
  'polyline': svgWrap,
87
+ 'radialGradient': svgWrap,
79
88
  'rect': svgWrap,
89
+ 'stop': svgWrap,
80
90
  'text': svgWrap
81
91
  };
82
92
 
@@ -30,9 +30,11 @@ var contentKey = null;
30
30
  */
31
31
  function getTextContentAccessor() {
32
32
  if (!contentKey && ExecutionEnvironment.canUseDOM) {
33
- contentKey = 'innerText' in document.createElement('div') ?
34
- 'innerText' :
35
- 'textContent';
33
+ // Prefer textContent to innerText because many browsers support both but
34
+ // SVG <text> elements don't support innerText even when <div> does.
35
+ contentKey = 'textContent' in document.createElement('div') ?
36
+ 'textContent' :
37
+ 'innerText';
36
38
  }
37
39
  return contentKey;
38
40
  }
@@ -32,8 +32,8 @@
32
32
  function getUnboundedScrollPosition(scrollable) {
33
33
  if (scrollable === window) {
34
34
  return {
35
- x: document.documentElement.scrollLeft || document.body.scrollLeft,
36
- y: document.documentElement.scrollTop || document.body.scrollTop
35
+ x: window.pageXOffset || document.documentElement.scrollLeft,
36
+ y: window.pageYOffset || document.documentElement.scrollTop
37
37
  };
38
38
  }
39
39
  return {
package/lib/invariant.js CHANGED
@@ -19,8 +19,9 @@
19
19
  /**
20
20
  * Use invariant() to assert state which your program assumes to be true.
21
21
  *
22
- * Provide sprintf style format and arguments to provide information about
23
- * what broke and what you were expecting.
22
+ * Provide sprintf-style format (only %s is supported) and arguments
23
+ * to provide information about what broke and what you were
24
+ * expecting.
24
25
  *
25
26
  * The invariant message will be stripped in production, but the invariant
26
27
  * will remain to ensure logic does not differ in production.
@@ -28,7 +29,12 @@
28
29
 
29
30
  function invariant(condition) {
30
31
  if (!condition) {
31
- throw new Error('Invariant Violation');
32
+ var error = new Error(
33
+ 'Minified exception occured; use the non-minified dev environment for ' +
34
+ 'the full error message and additional helpful warnings.'
35
+ );
36
+ error.framesToPop = 1;
37
+ throw error;
32
38
  }
33
39
  }
34
40
 
@@ -43,10 +49,12 @@ if ("production" !== process.env.NODE_ENV) {
43
49
  if (!condition) {
44
50
  var args = [a, b, c, d, e, f];
45
51
  var argIndex = 0;
46
- throw new Error(
52
+ var error = new Error(
47
53
  'Invariant Violation: ' +
48
54
  format.replace(/%s/g, function() { return args[argIndex++]; })
49
55
  );
56
+ error.framesToPop = 1; // we don't care about invariant's own frame
57
+ throw error;
50
58
  }
51
59
  };
52
60
 
@@ -20,13 +20,13 @@
20
20
 
21
21
  var ExecutionEnvironment = require("./ExecutionEnvironment");
22
22
 
23
- var testNode, useHasFeature;
23
+ var useHasFeature;
24
24
  if (ExecutionEnvironment.canUseDOM) {
25
- testNode = document.createElement('div');
26
25
  useHasFeature =
27
26
  document.implementation &&
28
27
  document.implementation.hasFeature &&
29
- // `hasFeature` always returns true in Firefox 19+.
28
+ // always returns true in newer browsers as per the standard.
29
+ // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
30
30
  document.implementation.hasFeature('', '') !== true;
31
31
  }
32
32
 
@@ -45,21 +45,18 @@ if (ExecutionEnvironment.canUseDOM) {
45
45
  * @license Modernizr 3.0.0pre (Custom Build) | MIT
46
46
  */
47
47
  function isEventSupported(eventNameSuffix, capture) {
48
- if (!testNode || (capture && !testNode.addEventListener)) {
48
+ if (!ExecutionEnvironment.canUseDOM ||
49
+ capture && !('addEventListener' in document)) {
49
50
  return false;
50
51
  }
51
- var element = document.createElement('div');
52
52
 
53
53
  var eventName = 'on' + eventNameSuffix;
54
- var isSupported = eventName in element;
54
+ var isSupported = eventName in document;
55
55
 
56
56
  if (!isSupported) {
57
+ var element = document.createElement('div');
57
58
  element.setAttribute(eventName, 'return;');
58
59
  isSupported = typeof element[eventName] === 'function';
59
- if (typeof element[eventName] !== 'undefined') {
60
- element[eventName] = undefined;
61
- }
62
- element.removeAttribute(eventName);
63
60
  }
64
61
 
65
62
  if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') {
@@ -67,7 +64,6 @@ function isEventSupported(eventNameSuffix, capture) {
67
64
  isSupported = document.implementation.hasFeature('Events.wheel', '3.0');
68
65
  }
69
66
 
70
- element = null;
71
67
  return isSupported;
72
68
  }
73
69
 
@@ -66,9 +66,9 @@ var mergeHelpers = {
66
66
  checkMergeArrayArgs: function(one, two) {
67
67
  ("production" !== process.env.NODE_ENV ? invariant(
68
68
  Array.isArray(one) && Array.isArray(two),
69
- 'Critical assumptions about the merge functions have been violated. ' +
70
- 'This is the fault of the merge functions themselves, not necessarily ' +
71
- 'the callers.'
69
+ 'Tried to merge arrays, instead got %s and %s.',
70
+ one,
71
+ two
72
72
  ) : invariant(Array.isArray(one) && Array.isArray(two)));
73
73
  },
74
74
 
@@ -87,9 +87,8 @@ var mergeHelpers = {
87
87
  checkMergeObjectArg: function(arg) {
88
88
  ("production" !== process.env.NODE_ENV ? invariant(
89
89
  !isTerminal(arg) && !Array.isArray(arg),
90
- 'Critical assumptions about the merge functions have been violated. ' +
91
- 'This is the fault of the merge functions themselves, not necessarily ' +
92
- 'the callers.'
90
+ 'Tried to merge an object, instead got %s.',
91
+ arg
93
92
  ) : invariant(!isTerminal(arg) && !Array.isArray(arg)));
94
93
  },
95
94
 
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Copyright 2013 Facebook, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ * @providesModule onlyChild
17
+ */
18
+ "use strict";
19
+
20
+ var ReactComponent = require("./ReactComponent");
21
+
22
+ var invariant = require("./invariant");
23
+
24
+ /**
25
+ * Returns the first child in a collection of children and verifies that there
26
+ * is only one child in the collection. The current implementation of this
27
+ * function assumes that a single child gets passed without a wrapper, but the
28
+ * purpose of this helper function is to abstract away the particular structure
29
+ * of children.
30
+ *
31
+ * @param {?object} children Child collection structure.
32
+ * @return {ReactComponent} The first and only `ReactComponent` contained in the
33
+ * structure.
34
+ */
35
+ function onlyChild(children) {
36
+ ("production" !== process.env.NODE_ENV ? invariant(
37
+ ReactComponent.isValidComponent(children),
38
+ 'onlyChild must be passed a children with exactly one child.'
39
+ ) : invariant(ReactComponent.isValidComponent(children)));
40
+ return children;
41
+ }
42
+
43
+ module.exports = onlyChild;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Copyright 2013 Facebook, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ * @providesModule shouldUpdateReactComponent
17
+ * @typechecks static-only
18
+ */
19
+
20
+ "use strict";
21
+
22
+ /**
23
+ * Given a `prevComponent` and `nextComponent`, determines if `prevComponent`
24
+ * should be updated as opposed to being destroyed or replaced.
25
+ *
26
+ * @param {?object} prevComponent
27
+ * @param {?object} nextComponent
28
+ * @return {boolean} True if `prevComponent` should be updated.
29
+ * @protected
30
+ */
31
+ function shouldUpdateReactComponent(prevComponent, nextComponent) {
32
+ // TODO: Remove warning after a release.
33
+ if (prevComponent && nextComponent &&
34
+ prevComponent.constructor === nextComponent.constructor && (
35
+ (prevComponent.props && prevComponent.props.key) ===
36
+ (nextComponent.props && nextComponent.props.key)
37
+ )) {
38
+ if (prevComponent._owner === nextComponent._owner) {
39
+ return true;
40
+ } else {
41
+ if ("production" !== process.env.NODE_ENV) {
42
+ if (prevComponent.state) {
43
+ console.warn(
44
+ 'A recent change to React has been found to impact your code. ' +
45
+ 'A mounted component will now be unmounted and replaced by a ' +
46
+ 'component (of the same class) if their owners are different. ' +
47
+ 'Previously, ownership was not considered when updating.',
48
+ prevComponent,
49
+ nextComponent
50
+ );
51
+ }
52
+ }
53
+ }
54
+ }
55
+ return false;
56
+ }
57
+
58
+ module.exports = shouldUpdateReactComponent;
package/lib/toArray.js ADDED
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Copyright 2014 Facebook, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ * @providesModule toArray
17
+ * @typechecks
18
+ */
19
+
20
+ var invariant = require("./invariant");
21
+
22
+ /**
23
+ * Convert array-like objects to arrays.
24
+ *
25
+ * This API assumes the caller knows the contents of the data type. For less
26
+ * well defined inputs use createArrayFrom.
27
+ *
28
+ * @param {object|function} obj
29
+ * @return {array}
30
+ */
31
+ function toArray(obj) {
32
+ var length = obj.length;
33
+
34
+ // Some browse builtin objects can report typeof 'function' (e.g. NodeList in
35
+ // old versions of Safari).
36
+ ("production" !== process.env.NODE_ENV ? invariant(
37
+ !Array.isArray(obj) &&
38
+ (typeof obj === 'object' || typeof obj === 'function'),
39
+ 'toArray: Array-like object expected'
40
+ ) : invariant(!Array.isArray(obj) &&
41
+ (typeof obj === 'object' || typeof obj === 'function')));
42
+
43
+ ("production" !== process.env.NODE_ENV ? invariant(
44
+ typeof length === 'number',
45
+ 'toArray: Object needs a length property'
46
+ ) : invariant(typeof length === 'number'));
47
+
48
+ ("production" !== process.env.NODE_ENV ? invariant(
49
+ length === 0 ||
50
+ (length - 1) in obj,
51
+ 'toArray: Object should have keys for indices'
52
+ ) : invariant(length === 0 ||
53
+ (length - 1) in obj));
54
+
55
+ // Old IE doesn't give collections access to hasOwnProperty. Assume inputs
56
+ // without method will throw during the slice call and skip straight to the
57
+ // fallback.
58
+ if (obj.hasOwnProperty) {
59
+ try {
60
+ return Array.prototype.slice.call(obj);
61
+ } catch (e) {
62
+ // IE < 9 does not support Array#slice on collections objects
63
+ }
64
+ }
65
+
66
+ // Fall back to copying key by key. This assumes all keys have a value,
67
+ // so will not preserve sparsely populated inputs.
68
+ var ret = Array(length);
69
+ for (var ii = 0; ii < length; ii++) {
70
+ ret[ii] = obj[ii];
71
+ }
72
+ return ret;
73
+ }
74
+
75
+ module.exports = toArray;
@@ -18,11 +18,14 @@
18
18
 
19
19
  "use strict";
20
20
 
21
- var ReactComponent = require("./ReactComponent");
21
+ var ReactInstanceHandles = require("./ReactInstanceHandles");
22
22
  var ReactTextComponent = require("./ReactTextComponent");
23
23
 
24
24
  var invariant = require("./invariant");
25
25
 
26
+ var SEPARATOR = ReactInstanceHandles.SEPARATOR;
27
+ var SUBSEPARATOR = ':';
28
+
26
29
  /**
27
30
  * TODO: Test that:
28
31
  * 1. `mapChildren` transforms strings and numbers into `ReactTextComponent`.
@@ -31,6 +34,58 @@ var invariant = require("./invariant");
31
34
  * });
32
35
  */
33
36
 
37
+ var userProvidedKeyEscaperLookup = {
38
+ '=': '=0',
39
+ '.': '=1',
40
+ ':': '=2'
41
+ };
42
+
43
+ var userProvidedKeyEscapeRegex = /[=.:]/g;
44
+
45
+ function userProvidedKeyEscaper(match) {
46
+ return userProvidedKeyEscaperLookup[match];
47
+ }
48
+
49
+ /**
50
+ * Generate a key string that identifies a component within a set.
51
+ *
52
+ * @param {*} component A component that could contain a manual key.
53
+ * @param {number} index Index that is used if a manual key is not provided.
54
+ * @return {string}
55
+ */
56
+ function getComponentKey(component, index) {
57
+ if (component && component.props && component.props.key != null) {
58
+ // Explicit key
59
+ return wrapUserProvidedKey(component.props.key);
60
+ }
61
+ // Implicit key determined by the index in the set
62
+ return index.toString(36);
63
+ }
64
+
65
+ /**
66
+ * Escape a component key so that it is safe to use in a reactid.
67
+ *
68
+ * @param {*} key Component key to be escaped.
69
+ * @return {string} An escaped string.
70
+ */
71
+ function escapeUserProvidedKey(text) {
72
+ return ('' + text).replace(
73
+ userProvidedKeyEscapeRegex,
74
+ userProvidedKeyEscaper
75
+ );
76
+ }
77
+
78
+ /**
79
+ * Wrap a `key` value explicitly provided by the user to distinguish it from
80
+ * implicitly-generated keys generated by a component's index in its parent.
81
+ *
82
+ * @param {string} key Value of a user-provided `key` attribute
83
+ * @return {string}
84
+ */
85
+ function wrapUserProvidedKey(key) {
86
+ return '$' + escapeUserProvidedKey(key);
87
+ }
88
+
34
89
  /**
35
90
  * @param {?*} children Children tree container.
36
91
  * @param {!string} nameSoFar Name of the key path so far.
@@ -46,7 +101,11 @@ var traverseAllChildrenImpl =
46
101
  if (Array.isArray(children)) {
47
102
  for (var i = 0; i < children.length; i++) {
48
103
  var child = children[i];
49
- var nextName = nameSoFar + ReactComponent.getKey(child, i);
104
+ var nextName = (
105
+ nameSoFar +
106
+ (nameSoFar ? SUBSEPARATOR : SEPARATOR) +
107
+ getComponentKey(child, i)
108
+ );
50
109
  var nextIndex = indexSoFar + subtreeCount;
51
110
  subtreeCount += traverseAllChildrenImpl(
52
111
  child,
@@ -61,10 +120,9 @@ var traverseAllChildrenImpl =
61
120
  var isOnlyChild = nameSoFar === '';
62
121
  // If it's the only child, treat the name as if it was wrapped in an array
63
122
  // so that it's consistent if the number of children grows
64
- var storageName = isOnlyChild ?
65
- ReactComponent.getKey(children, 0):
66
- nameSoFar;
67
- if (children === null || children === undefined || type === 'boolean') {
123
+ var storageName =
124
+ isOnlyChild ? SEPARATOR + getComponentKey(children, 0) : nameSoFar;
125
+ if (children == null || type === 'boolean') {
68
126
  // All of the above are perceived as null.
69
127
  callback(traverseContext, null, storageName, indexSoFar);
70
128
  subtreeCount = 1;
@@ -82,7 +140,11 @@ var traverseAllChildrenImpl =
82
140
  if (children.hasOwnProperty(key)) {
83
141
  subtreeCount += traverseAllChildrenImpl(
84
142
  children[key],
85
- nameSoFar + '{' + key + '}',
143
+ (
144
+ nameSoFar + (nameSoFar ? SUBSEPARATOR : SEPARATOR) +
145
+ wrapUserProvidedKey(key) + SUBSEPARATOR +
146
+ getComponentKey(children[key], 0)
147
+ ),
86
148
  indexSoFar + subtreeCount,
87
149
  callback,
88
150
  traverseContext