react 0.12.0-rc1 → 0.13.0-alpha.1

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 (79) hide show
  1. package/dist/JSXTransformer.js +1862 -519
  2. package/dist/react-with-addons.js +4099 -3299
  3. package/dist/react-with-addons.min.js +6 -6
  4. package/dist/react.js +3893 -3353
  5. package/dist/react.min.js +6 -6
  6. package/lib/BeforeInputEventPlugin.js +388 -111
  7. package/lib/CSSProperty.js +5 -2
  8. package/lib/CSSPropertyOperations.js +20 -0
  9. package/lib/ChangeEventPlugin.js +2 -2
  10. package/lib/Danger.js +1 -1
  11. package/lib/DefaultEventPluginOrder.js +0 -1
  12. package/lib/ExecutionEnvironment.js +2 -3
  13. package/lib/FallbackCompositionState.js +87 -0
  14. package/lib/HTMLDOMPropertyConfig.js +7 -0
  15. package/lib/Object.assign.js +3 -1
  16. package/lib/React.js +14 -49
  17. package/lib/ReactBrowserComponentMixin.js +2 -12
  18. package/lib/ReactBrowserEventEmitter.js +2 -4
  19. package/lib/ReactCSSTransitionGroup.js +3 -0
  20. package/lib/ReactCSSTransitionGroupChild.js +8 -0
  21. package/lib/ReactChildReconciler.js +121 -0
  22. package/lib/ReactClass.js +916 -0
  23. package/lib/ReactComponent.js +36 -286
  24. package/lib/ReactComponentBrowserEnvironment.js +9 -82
  25. package/lib/ReactComponentEnvironment.js +57 -0
  26. package/lib/ReactCompositeComponent.js +608 -1026
  27. package/lib/ReactContext.js +5 -1
  28. package/lib/ReactDOM.js +2 -7
  29. package/lib/ReactDOMButton.js +4 -5
  30. package/lib/ReactDOMComponent.js +97 -69
  31. package/lib/ReactDOMForm.js +4 -5
  32. package/lib/ReactDOMIDOperations.js +55 -73
  33. package/lib/ReactDOMImg.js +3 -5
  34. package/lib/ReactDOMInput.js +4 -5
  35. package/lib/ReactDOMOption.js +4 -5
  36. package/lib/ReactDOMSelect.js +55 -63
  37. package/lib/ReactDOMSelection.js +5 -1
  38. package/lib/{ReactTextComponent.js → ReactDOMTextComponent.js} +54 -34
  39. package/lib/ReactDOMTextarea.js +4 -5
  40. package/lib/ReactDefaultInjection.js +13 -7
  41. package/lib/ReactDefaultPerf.js +7 -6
  42. package/lib/ReactDefaultPerfAnalysis.js +1 -1
  43. package/lib/ReactElement.js +24 -5
  44. package/lib/ReactElementValidator.js +101 -52
  45. package/lib/ReactEmptyComponent.js +17 -10
  46. package/lib/ReactInjection.js +6 -4
  47. package/lib/ReactInputSelection.js +2 -3
  48. package/lib/ReactInstanceMap.js +47 -0
  49. package/lib/ReactMount.js +193 -64
  50. package/lib/ReactMultiChild.js +32 -42
  51. package/lib/ReactNativeComponent.js +46 -9
  52. package/lib/ReactOwner.js +3 -47
  53. package/lib/ReactPerf.js +20 -0
  54. package/lib/ReactPropTransferer.js +0 -55
  55. package/lib/ReactPropTypes.js +1 -17
  56. package/lib/ReactRef.js +96 -0
  57. package/lib/ReactServerRendering.js +3 -2
  58. package/lib/ReactTestUtils.js +82 -25
  59. package/lib/ReactTransitionGroup.js +47 -6
  60. package/lib/ReactUpdates.js +43 -42
  61. package/lib/SyntheticMouseEvent.js +1 -3
  62. package/lib/ViewportMetrics.js +1 -4
  63. package/lib/accumulate.js +47 -0
  64. package/lib/cloneWithProps.js +2 -2
  65. package/lib/copyProperties.js +2 -0
  66. package/lib/createFullPageComponent.js +2 -2
  67. package/lib/findDOMNode.js +52 -0
  68. package/lib/flattenChildren.js +1 -14
  69. package/lib/getIteratorFn.js +42 -0
  70. package/lib/instantiateReactComponent.js +88 -65
  71. package/lib/isNode.js +3 -4
  72. package/lib/isTextInputElement.js +1 -2
  73. package/lib/shouldUpdateReactComponent.js +13 -5
  74. package/lib/traverseAllChildren.js +110 -54
  75. package/lib/warning.js +1 -1
  76. package/package.json +1 -1
  77. package/lib/CompositionEventPlugin.js +0 -257
  78. package/lib/ReactLegacyElement.js +0 -232
  79. package/lib/deprecated.js +0 -47
@@ -14,7 +14,6 @@
14
14
  var BeforeInputEventPlugin = require("./BeforeInputEventPlugin");
15
15
  var ChangeEventPlugin = require("./ChangeEventPlugin");
16
16
  var ClientReactRootIndex = require("./ClientReactRootIndex");
17
- var CompositionEventPlugin = require("./CompositionEventPlugin");
18
17
  var DefaultEventPluginOrder = require("./DefaultEventPluginOrder");
19
18
  var EnterLeaveEventPlugin = require("./EnterLeaveEventPlugin");
20
19
  var ExecutionEnvironment = require("./ExecutionEnvironment");
@@ -28,14 +27,17 @@ var ReactDOMComponent = require("./ReactDOMComponent");
28
27
  var ReactDOMButton = require("./ReactDOMButton");
29
28
  var ReactDOMForm = require("./ReactDOMForm");
30
29
  var ReactDOMImg = require("./ReactDOMImg");
30
+ var ReactDOMIDOperations = require("./ReactDOMIDOperations");
31
31
  var ReactDOMInput = require("./ReactDOMInput");
32
32
  var ReactDOMOption = require("./ReactDOMOption");
33
33
  var ReactDOMSelect = require("./ReactDOMSelect");
34
34
  var ReactDOMTextarea = require("./ReactDOMTextarea");
35
+ var ReactDOMTextComponent = require("./ReactDOMTextComponent");
35
36
  var ReactEventListener = require("./ReactEventListener");
36
37
  var ReactInjection = require("./ReactInjection");
37
38
  var ReactInstanceHandles = require("./ReactInstanceHandles");
38
39
  var ReactMount = require("./ReactMount");
40
+ var ReactReconcileTransaction = require("./ReactReconcileTransaction");
39
41
  var SelectEventPlugin = require("./SelectEventPlugin");
40
42
  var ServerReactRootIndex = require("./ServerReactRootIndex");
41
43
  var SimpleEventPlugin = require("./SimpleEventPlugin");
@@ -63,7 +65,6 @@ function inject() {
63
65
  SimpleEventPlugin: SimpleEventPlugin,
64
66
  EnterLeaveEventPlugin: EnterLeaveEventPlugin,
65
67
  ChangeEventPlugin: ChangeEventPlugin,
66
- CompositionEventPlugin: CompositionEventPlugin,
67
68
  MobileSafariClickEventPlugin: MobileSafariClickEventPlugin,
68
69
  SelectEventPlugin: SelectEventPlugin,
69
70
  BeforeInputEventPlugin: BeforeInputEventPlugin
@@ -73,6 +74,14 @@ function inject() {
73
74
  ReactDOMComponent
74
75
  );
75
76
 
77
+ ReactInjection.NativeComponent.injectTextComponentClass(
78
+ ReactDOMTextComponent
79
+ );
80
+
81
+ // This needs to happen before createFullPageComponent() otherwise the mixin
82
+ // won't be included.
83
+ ReactInjection.Class.injectMixin(ReactBrowserComponentMixin);
84
+
76
85
  ReactInjection.NativeComponent.injectComponentClasses({
77
86
  'button': ReactDOMButton,
78
87
  'form': ReactDOMForm,
@@ -87,17 +96,13 @@ function inject() {
87
96
  'body': createFullPageComponent('body')
88
97
  });
89
98
 
90
- // This needs to happen after createFullPageComponent() otherwise the mixin
91
- // gets double injected.
92
- ReactInjection.CompositeComponent.injectMixin(ReactBrowserComponentMixin);
93
-
94
99
  ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig);
95
100
  ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig);
96
101
 
97
102
  ReactInjection.EmptyComponent.injectEmptyComponent('noscript');
98
103
 
99
104
  ReactInjection.Updates.injectReconcileTransaction(
100
- ReactComponentBrowserEnvironment.ReactReconcileTransaction
105
+ ReactReconcileTransaction
101
106
  );
102
107
  ReactInjection.Updates.injectBatchingStrategy(
103
108
  ReactDefaultBatchingStrategy
@@ -110,6 +115,7 @@ function inject() {
110
115
  );
111
116
 
112
117
  ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment);
118
+ ReactInjection.DOMComponent.injectIDOperations(ReactDOMIDOperations);
113
119
 
114
120
  if ("production" !== process.env.NODE_ENV) {
115
121
  var url = (ExecutionEnvironment.canUseDOM && window.location.href) || '';
@@ -137,7 +137,7 @@ var ReactDefaultPerf = {
137
137
  },
138
138
 
139
139
  measure: function(moduleName, fnName, func) {
140
- return function() {var args=Array.prototype.slice.call(arguments,0);
140
+ return function() {for (var args=[],$__0=0,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]);
141
141
  var totalTime;
142
142
  var rv;
143
143
  var start;
@@ -169,7 +169,7 @@ var ReactDefaultPerf = {
169
169
  rv = func.apply(this, args);
170
170
  totalTime = performanceNow() - start;
171
171
 
172
- if (fnName === 'mountImageIntoNode') {
172
+ if (fnName === '_mountImageIntoNode') {
173
173
  var mountID = ReactMount.getID(args[1]);
174
174
  ReactDefaultPerf._recordWrite(mountID, fnName, totalTime, args[0]);
175
175
  } else if (fnName === 'dangerouslyProcessChildrenUpdates') {
@@ -206,9 +206,9 @@ var ReactDefaultPerf = {
206
206
  }
207
207
  return rv;
208
208
  } else if (moduleName === 'ReactCompositeComponent' && (
209
- fnName === 'mountComponent' ||
210
- fnName === 'updateComponent' || // TODO: receiveComponent()?
211
- fnName === '_renderValidatedComponent')) {
209
+ (// TODO: receiveComponent()?
210
+ (fnName === 'mountComponent' ||
211
+ fnName === 'updateComponent' || fnName === '_renderValidatedComponent')))) {
212
212
 
213
213
  var rootNodeID = fnName === 'mountComponent' ?
214
214
  args[0] :
@@ -244,7 +244,8 @@ var ReactDefaultPerf = {
244
244
 
245
245
  entry.displayNames[rootNodeID] = {
246
246
  current: this.constructor.displayName,
247
- owner: this._owner ? this._owner.constructor.displayName : '<root>'
247
+ owner: this._currentElement._owner ?
248
+ this._currentElement._owner.constructor.displayName : '<root>'
248
249
  };
249
250
 
250
251
  return rv;
@@ -14,7 +14,7 @@ var assign = require("./Object.assign");
14
14
  // Don't try to save users less than 1.2ms (a number I made up)
15
15
  var DONT_CARE_THRESHOLD = 1.2;
16
16
  var DOM_OPERATION_TYPES = {
17
- 'mountImageIntoNode': 'set innerHTML',
17
+ '_mountImageIntoNode': 'set innerHTML',
18
18
  INSERT_MARKUP: 'set innerHTML',
19
19
  MOVE_EXISTING: 'move',
20
20
  REMOVE_NODE: 'remove',
@@ -85,7 +85,7 @@ function defineMutationMembrane(prototype) {
85
85
  * @param {*} type
86
86
  * @param {string|object} ref
87
87
  * @param {*} key
88
- * @params {*} props
88
+ * @param {*} props
89
89
  * @internal
90
90
  */
91
91
  var ReactElement = function(type, key, ref, owner, context, props) {
@@ -106,7 +106,21 @@ var ReactElement = function(type, key, ref, owner, context, props) {
106
106
  // an external backing store so that we can freeze the whole object.
107
107
  // This can be replaced with a WeakMap once they are implemented in
108
108
  // commonly used development environments.
109
- this._store = { validated: false, props: props };
109
+ this._store = { props: props };
110
+
111
+ // To make comparing ReactElements easier for testing purposes, we make
112
+ // the validation flag non-enumerable (where possible, which should
113
+ // include every environment we run tests in), so the test framework
114
+ // ignores it.
115
+ try {
116
+ Object.defineProperty(this._store, 'validated', {
117
+ configurable: false,
118
+ enumerable: false,
119
+ writable: true
120
+ });
121
+ } catch (x) {
122
+ }
123
+ this._store.validated = false;
110
124
 
111
125
  // We're not allowed to set props directly on the object so we early
112
126
  // return and rely on the prototype membrane to forward to the backing
@@ -120,12 +134,16 @@ var ReactElement = function(type, key, ref, owner, context, props) {
120
134
  this.props = props;
121
135
  };
122
136
 
137
+ // We intentionally don't expose the function on the constructor property.
138
+ // ReactElement should be indistinguishable from a plain object.
139
+ ReactElement.prototype = {
140
+ _isReactElement: true
141
+ };
142
+
123
143
  if ("production" !== process.env.NODE_ENV) {
124
144
  defineMutationMembrane(ReactElement.prototype);
125
145
  }
126
146
 
127
- ReactElement.prototype._isReactElement = true;
128
-
129
147
  ReactElement.createElement = function(type, config, children) {
130
148
  var propName;
131
149
 
@@ -161,7 +179,7 @@ ReactElement.createElement = function(type, config, children) {
161
179
  }
162
180
 
163
181
  // Resolve default props
164
- if (type.defaultProps) {
182
+ if (type && type.defaultProps) {
165
183
  var defaultProps = type.defaultProps;
166
184
  for (propName in defaultProps) {
167
185
  if (typeof props[propName] === 'undefined') {
@@ -186,6 +204,7 @@ ReactElement.createFactory = function(type) {
186
204
  // easily accessed on elements. E.g. <Foo />.type === Foo.type.
187
205
  // This should not be named `constructor` since this may not be the function
188
206
  // that created the element, and it may not even be a constructor.
207
+ // Legacy hook TODO: Warn if this is accessed
189
208
  factory.type = type;
190
209
  return factory;
191
210
  };
@@ -22,7 +22,9 @@ var ReactElement = require("./ReactElement");
22
22
  var ReactPropTypeLocations = require("./ReactPropTypeLocations");
23
23
  var ReactCurrentOwner = require("./ReactCurrentOwner");
24
24
 
25
+ var getIteratorFn = require("./getIteratorFn");
25
26
  var monitorCodeUse = require("./monitorCodeUse");
27
+ var warning = require("./warning");
26
28
 
27
29
  /**
28
30
  * Warn if there's no key explicitly set on dynamic arrays of children or
@@ -39,6 +41,24 @@ var loggedTypeFailures = {};
39
41
 
40
42
  var NUMERIC_PROPERTY_REGEX = /^\d+$/;
41
43
 
44
+ /**
45
+ * Gets the instance's name for use in warnings.
46
+ *
47
+ * @internal
48
+ * @return {?string} Display name or undefined
49
+ */
50
+ function getName(instance) {
51
+ var publicInstance = instance && instance.getPublicInstance();
52
+ if (!publicInstance) {
53
+ return undefined;
54
+ }
55
+ var constructor = publicInstance.constructor;
56
+ if (!constructor) {
57
+ return undefined;
58
+ }
59
+ return constructor.displayName || constructor.name || undefined;
60
+ }
61
+
42
62
  /**
43
63
  * Gets the current owner's displayName for use in warnings.
44
64
  *
@@ -47,29 +67,31 @@ var NUMERIC_PROPERTY_REGEX = /^\d+$/;
47
67
  */
48
68
  function getCurrentOwnerDisplayName() {
49
69
  var current = ReactCurrentOwner.current;
50
- return current && current.constructor.displayName || undefined;
70
+ return (
71
+ current && getName(current) || undefined
72
+ );
51
73
  }
52
74
 
53
75
  /**
54
- * Warn if the component doesn't have an explicit key assigned to it.
55
- * This component is in an array. The array could grow and shrink or be
76
+ * Warn if the element doesn't have an explicit key assigned to it.
77
+ * This element is in an array. The array could grow and shrink or be
56
78
  * reordered. All children that haven't already been validated are required to
57
79
  * have a "key" property assigned to it.
58
80
  *
59
81
  * @internal
60
- * @param {ReactComponent} component Component that requires a key.
61
- * @param {*} parentType component's parent's type.
82
+ * @param {ReactElement} element Element that requires a key.
83
+ * @param {*} parentType element's parent's type.
62
84
  */
63
- function validateExplicitKey(component, parentType) {
64
- if (component._store.validated || component.key != null) {
85
+ function validateExplicitKey(element, parentType) {
86
+ if (element._store.validated || element.key != null) {
65
87
  return;
66
88
  }
67
- component._store.validated = true;
89
+ element._store.validated = true;
68
90
 
69
91
  warnAndMonitorForKeyUse(
70
92
  'react_key_warning',
71
- 'Each child in an array should have a unique "key" prop.',
72
- component,
93
+ 'Each child in an array or iterator should have a unique "key" prop.',
94
+ element,
73
95
  parentType
74
96
  );
75
97
  }
@@ -80,17 +102,17 @@ function validateExplicitKey(component, parentType) {
80
102
  *
81
103
  * @internal
82
104
  * @param {string} name Property name of the key.
83
- * @param {ReactComponent} component Component that requires a key.
84
- * @param {*} parentType component's parent's type.
105
+ * @param {ReactElement} element Component that requires a key.
106
+ * @param {*} parentType element's parent's type.
85
107
  */
86
- function validatePropertyKey(name, component, parentType) {
108
+ function validatePropertyKey(name, element, parentType) {
87
109
  if (!NUMERIC_PROPERTY_REGEX.test(name)) {
88
110
  return;
89
111
  }
90
112
  warnAndMonitorForKeyUse(
91
113
  'react_numeric_key_warning',
92
114
  'Child objects should have non-numeric keys so ordering is preserved.',
93
- component,
115
+ element,
94
116
  parentType
95
117
  );
96
118
  }
@@ -101,12 +123,12 @@ function validatePropertyKey(name, component, parentType) {
101
123
  * @internal
102
124
  * @param {string} warningID The id used when logging.
103
125
  * @param {string} message The base warning that gets output.
104
- * @param {ReactComponent} component Component that requires a key.
105
- * @param {*} parentType component's parent's type.
126
+ * @param {ReactElement} element Component that requires a key.
127
+ * @param {*} parentType element's parent's type.
106
128
  */
107
- function warnAndMonitorForKeyUse(warningID, message, component, parentType) {
129
+ function warnAndMonitorForKeyUse(warningID, message, element, parentType) {
108
130
  var ownerName = getCurrentOwnerDisplayName();
109
- var parentName = parentType.displayName;
131
+ var parentName = parentType.displayName || parentType.name;
110
132
 
111
133
  var useName = ownerName || parentName;
112
134
  var memoizer = ownerHasKeyUseWarning[warningID];
@@ -117,15 +139,17 @@ function warnAndMonitorForKeyUse(warningID, message, component, parentType) {
117
139
 
118
140
  message += ownerName ?
119
141
  (" Check the render method of " + ownerName + ".") :
120
- (" Check the renderComponent call using <" + parentName + ">.");
142
+ (" Check the React.render call using <" + parentName + ">.");
121
143
 
122
144
  // Usually the current owner is the offender, but if it accepts children as a
123
145
  // property, it may be the creator of the child that's responsible for
124
146
  // assigning it a key.
125
147
  var childOwnerName = null;
126
- if (component._owner && component._owner !== ReactCurrentOwner.current) {
148
+ if (element &&
149
+ element._owner &&
150
+ element._owner !== ReactCurrentOwner.current) {
127
151
  // Name of the component that originally created this child.
128
- childOwnerName = component._owner.constructor.displayName;
152
+ childOwnerName = getName(element._owner);
129
153
 
130
154
  message += (" It was passed a child from " + childOwnerName + ".");
131
155
  }
@@ -154,30 +178,43 @@ function monitorUseOfObjectMap() {
154
178
  }
155
179
 
156
180
  /**
157
- * Ensure that every component either is passed in a static location, in an
181
+ * Ensure that every element either is passed in a static location, in an
158
182
  * array with an explicit keys property defined, or in an object literal
159
183
  * with valid key property.
160
184
  *
161
185
  * @internal
162
- * @param {*} component Statically passed child of any type.
163
- * @param {*} parentType component's parent's type.
164
- * @return {boolean}
186
+ * @param {ReactNode} node Statically passed child of any type.
187
+ * @param {*} parentType node's parent's type.
165
188
  */
166
- function validateChildKeys(component, parentType) {
167
- if (Array.isArray(component)) {
168
- for (var i = 0; i < component.length; i++) {
169
- var child = component[i];
189
+ function validateChildKeys(node, parentType) {
190
+ if (Array.isArray(node)) {
191
+ for (var i = 0; i < node.length; i++) {
192
+ var child = node[i];
170
193
  if (ReactElement.isValidElement(child)) {
171
194
  validateExplicitKey(child, parentType);
172
195
  }
173
196
  }
174
- } else if (ReactElement.isValidElement(component)) {
175
- // This component was passed in a valid location.
176
- component._store.validated = true;
177
- } else if (component && typeof component === 'object') {
178
- monitorUseOfObjectMap();
179
- for (var name in component) {
180
- validatePropertyKey(name, component[name], parentType);
197
+ } else if (ReactElement.isValidElement(node)) {
198
+ // This element was passed in a valid location.
199
+ node._store.validated = true;
200
+ } else if (node) {
201
+ var iteratorFn = getIteratorFn(node);
202
+ // Entry iterators provide implicit keys.
203
+ if (iteratorFn && iteratorFn !== node.entries) {
204
+ var iterator = iteratorFn.call(node);
205
+ var step;
206
+ while (!(step = iterator.next()).done) {
207
+ if (ReactElement.isValidElement(step.value)) {
208
+ validateExplicitKey(step.value, parentType);
209
+ }
210
+ }
211
+ } else if (typeof node === 'object') {
212
+ monitorUseOfObjectMap();
213
+ for (var key in node) {
214
+ if (node.hasOwnProperty(key)) {
215
+ validatePropertyKey(key, node[key], parentType);
216
+ }
217
+ }
181
218
  }
182
219
  }
183
220
  }
@@ -220,6 +257,15 @@ function checkPropTypes(componentName, propTypes, props, location) {
220
257
  var ReactElementValidator = {
221
258
 
222
259
  createElement: function(type, props, children) {
260
+ // We warn in this case but don't throw. We expect the element creation to
261
+ // succeed and there will likely be errors in render.
262
+ ("production" !== process.env.NODE_ENV ? warning(
263
+ type != null,
264
+ 'React.createElement: type should not be null or undefined. It should ' +
265
+ 'be a string (for DOM elements) or a ReactClass (for composite ' +
266
+ 'components).'
267
+ ) : null);
268
+
223
269
  var element = ReactElement.createElement.apply(this, arguments);
224
270
 
225
271
  // The result can be nullish if a mock or a custom function is used.
@@ -232,22 +278,24 @@ var ReactElementValidator = {
232
278
  validateChildKeys(arguments[i], type);
233
279
  }
234
280
 
235
- var name = type.displayName;
236
- if (type.propTypes) {
237
- checkPropTypes(
238
- name,
239
- type.propTypes,
240
- element.props,
241
- ReactPropTypeLocations.prop
242
- );
243
- }
244
- if (type.contextTypes) {
245
- checkPropTypes(
246
- name,
247
- type.contextTypes,
248
- element._context,
249
- ReactPropTypeLocations.context
250
- );
281
+ if (type) {
282
+ var name = type.displayName || type.name;
283
+ if (type.propTypes) {
284
+ checkPropTypes(
285
+ name,
286
+ type.propTypes,
287
+ element.props,
288
+ ReactPropTypeLocations.prop
289
+ );
290
+ }
291
+ if (type.contextTypes) {
292
+ checkPropTypes(
293
+ name,
294
+ type.contextTypes,
295
+ element._context,
296
+ ReactPropTypeLocations.context
297
+ );
298
+ }
251
299
  }
252
300
  return element;
253
301
  },
@@ -257,6 +305,7 @@ var ReactElementValidator = {
257
305
  null,
258
306
  type
259
307
  );
308
+ // Legacy hook TODO: Warn if this is accessed
260
309
  validatedFactory.type = type;
261
310
  return validatedFactory;
262
311
  }
@@ -12,6 +12,7 @@
12
12
  "use strict";
13
13
 
14
14
  var ReactElement = require("./ReactElement");
15
+ var ReactInstanceMap = require("./ReactInstanceMap");
15
16
 
16
17
  var invariant = require("./invariant");
17
18
 
@@ -26,17 +27,25 @@ var ReactEmptyComponentInjection = {
26
27
  }
27
28
  };
28
29
 
29
- /**
30
- * @return {ReactComponent} component The injected empty component.
31
- */
32
- function getEmptyComponent() {
30
+ var ReactEmptyComponentType = function() {};
31
+ ReactEmptyComponentType.prototype.componentDidMount = function() {
32
+ var internalInstance = ReactInstanceMap.get(this);
33
+ registerNullComponentID(internalInstance._rootNodeID);
34
+ };
35
+ ReactEmptyComponentType.prototype.componentWillUnmount = function() {
36
+ var internalInstance = ReactInstanceMap.get(this);
37
+ deregisterNullComponentID(internalInstance._rootNodeID);
38
+ };
39
+ ReactEmptyComponentType.prototype.render = function() {
33
40
  ("production" !== process.env.NODE_ENV ? invariant(
34
41
  component,
35
42
  'Trying to return null from a render, but no null placeholder component ' +
36
43
  'was injected.'
37
44
  ) : invariant(component));
38
45
  return component();
39
- }
46
+ };
47
+
48
+ var emptyElement = ReactElement.createElement(ReactEmptyComponentType);
40
49
 
41
50
  /**
42
51
  * Mark the component as having rendered to null.
@@ -59,15 +68,13 @@ function deregisterNullComponentID(id) {
59
68
  * @return {boolean} True if the component is rendered to null.
60
69
  */
61
70
  function isNullComponentID(id) {
62
- return nullComponentIdsRegistry[id];
71
+ return !!nullComponentIdsRegistry[id];
63
72
  }
64
73
 
65
74
  var ReactEmptyComponent = {
66
- deregisterNullComponentID: deregisterNullComponentID,
67
- getEmptyComponent: getEmptyComponent,
75
+ emptyElement: emptyElement,
68
76
  injection: ReactEmptyComponentInjection,
69
- isNullComponentID: isNullComponentID,
70
- registerNullComponentID: registerNullComponentID
77
+ isNullComponentID: isNullComponentID
71
78
  };
72
79
 
73
80
  module.exports = ReactEmptyComponent;