react 15.0.3-alpha.1 → 15.2.0-rc.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 (122) hide show
  1. package/dist/react-with-addons.js +3311 -2007
  2. package/dist/react-with-addons.min.js +7 -6
  3. package/dist/react.js +2734 -2014
  4. package/dist/react.min.js +6 -6
  5. package/lib/CSSPropertyOperations.js +5 -5
  6. package/lib/CallbackQueue.js +3 -2
  7. package/lib/DOMChildrenOperations.js +42 -7
  8. package/lib/DOMLazyTree.js +18 -5
  9. package/lib/DOMProperty.js +6 -4
  10. package/lib/DOMPropertyOperations.js +35 -12
  11. package/lib/Danger.js +10 -8
  12. package/lib/DisabledInputUtils.js +5 -5
  13. package/lib/EventPluginHub.js +8 -2
  14. package/lib/EventPluginRegistry.js +13 -7
  15. package/lib/EventPluginUtils.js +3 -1
  16. package/lib/HTMLDOMPropertyConfig.js +1 -2
  17. package/lib/LinkedStateMixin.js +1 -0
  18. package/lib/LinkedValueUtils.js +5 -3
  19. package/lib/NativeMethodsMixin.js +6 -4
  20. package/lib/PooledClass.js +3 -1
  21. package/lib/React.js +1 -1
  22. package/lib/ReactCSSTransitionGroup.js +5 -0
  23. package/lib/ReactCSSTransitionGroupChild.js +15 -8
  24. package/lib/ReactChildReconciler.js +15 -6
  25. package/lib/ReactChildren.js +9 -1
  26. package/lib/ReactClass.js +15 -13
  27. package/lib/ReactComponent.js +3 -6
  28. package/lib/ReactComponentBrowserEnvironment.js +0 -5
  29. package/lib/ReactComponentEnvironment.js +3 -1
  30. package/lib/ReactComponentTreeDevtool.js +223 -0
  31. package/lib/ReactComponentTreeTestUtils.js +87 -0
  32. package/lib/ReactComponentWithPureRenderMixin.js +2 -0
  33. package/lib/ReactCompositeComponent.js +208 -119
  34. package/lib/ReactDOM.js +3 -6
  35. package/lib/ReactDOMButton.js +2 -2
  36. package/lib/ReactDOMComponent.js +165 -71
  37. package/lib/ReactDOMComponentTree.js +23 -21
  38. package/lib/ReactDOMDebugTool.js +7 -1
  39. package/lib/ReactDOMEmptyComponent.js +9 -9
  40. package/lib/ReactDOMFactories.js +1 -1
  41. package/lib/ReactDOMIDOperations.js +0 -5
  42. package/lib/ReactDOMInput.js +57 -19
  43. package/lib/ReactDOMOption.js +40 -26
  44. package/lib/ReactDOMSelect.js +3 -3
  45. package/lib/ReactDOMTextComponent.js +28 -26
  46. package/lib/ReactDOMTextarea.js +59 -32
  47. package/lib/ReactDOMTreeTraversal.js +18 -16
  48. package/lib/ReactDOMUnknownPropertyDevtool.js +41 -15
  49. package/lib/ReactDebugTool.js +250 -11
  50. package/lib/ReactDefaultInjection.js +2 -11
  51. package/lib/ReactElement.js +90 -25
  52. package/lib/ReactElementValidator.js +26 -81
  53. package/lib/ReactEventListener.js +2 -2
  54. package/lib/ReactFragment.js +8 -3
  55. package/lib/{ReactNativeComponent.js → ReactHostComponent.js} +10 -29
  56. package/lib/ReactHostOperationHistoryDevtool.js +37 -0
  57. package/lib/ReactInjection.js +2 -4
  58. package/lib/ReactInstanceHandles.js +8 -6
  59. package/lib/ReactLink.js +3 -0
  60. package/lib/ReactMount.js +43 -20
  61. package/lib/ReactMultiChild.js +51 -8
  62. package/lib/ReactNativeAttributePayload.js +5 -2
  63. package/lib/ReactNativeBaseComponent.js +7 -7
  64. package/lib/ReactNativeBridgeEventPlugin.js +1 -1
  65. package/lib/ReactNativeComponentTree.js +8 -6
  66. package/lib/ReactNativeDOMIDOperations.js +4 -8
  67. package/lib/ReactNativeDefaultInjection.js +9 -7
  68. package/lib/ReactNativeGlobalResponderHandler.js +1 -1
  69. package/lib/ReactNativeMount.js +25 -8
  70. package/lib/ReactNativeTagHandles.js +3 -1
  71. package/lib/ReactNativeTextComponent.js +18 -9
  72. package/lib/ReactNativeTreeTraversal.js +11 -11
  73. package/lib/ReactNodeTypes.js +5 -3
  74. package/lib/ReactNoop.js +76 -0
  75. package/lib/ReactOwner.js +4 -2
  76. package/lib/ReactPerf.js +473 -75
  77. package/lib/ReactPropTypes.js +23 -0
  78. package/lib/ReactReconcileTransaction.js +1 -1
  79. package/lib/ReactReconciler.js +57 -11
  80. package/lib/ReactServerRendering.js +24 -3
  81. package/lib/ReactServerRenderingTransaction.js +5 -1
  82. package/lib/ReactSimpleEmptyComponent.js +4 -4
  83. package/lib/ReactTestMount.js +126 -0
  84. package/lib/ReactTestReconcileTransaction.js +100 -0
  85. package/lib/ReactTestRenderer.js +133 -0
  86. package/lib/ReactTestUtils.js +25 -10
  87. package/lib/ReactTransitionChildMapping.js +7 -1
  88. package/lib/ReactTransitionGroup.js +44 -5
  89. package/lib/ReactUpdateQueue.js +9 -1
  90. package/lib/ReactUpdates.js +30 -11
  91. package/lib/ReactVersion.js +1 -1
  92. package/lib/ReactWithAddons.js +1 -1
  93. package/lib/ResponderEventPlugin.js +8 -6
  94. package/lib/ResponderTouchHistoryStore.js +6 -4
  95. package/lib/SimpleEventPlugin.js +3 -1
  96. package/lib/SyntheticEvent.js +2 -3
  97. package/lib/SyntheticUIEvent.js +1 -1
  98. package/lib/Transaction.js +4 -2
  99. package/lib/accumulate.js +3 -1
  100. package/lib/accumulateInto.js +3 -1
  101. package/lib/checkReactTypeSpec.js +71 -0
  102. package/lib/createReactNativeComponentClass.js +2 -2
  103. package/lib/dangerousStyleValue.js +3 -1
  104. package/lib/escapeTextContentForBrowser.js +96 -12
  105. package/lib/findDOMNode.js +8 -4
  106. package/lib/findNodeHandle.js +5 -3
  107. package/lib/flattenChildren.js +13 -4
  108. package/lib/{getNativeComponentFromComposite.js → getHostComponentFromComposite.js} +4 -4
  109. package/lib/instantiateReactComponent.js +44 -10
  110. package/lib/onlyChild.js +10 -5
  111. package/lib/reactComponentExpect.js +3 -3
  112. package/lib/reactProdInvariant.js +38 -0
  113. package/lib/setInnerHTML.js +17 -1
  114. package/lib/setTextContent.js +8 -0
  115. package/lib/shallowCompare.js +1 -0
  116. package/lib/traverseAllChildren.js +3 -1
  117. package/lib/update.js +16 -11
  118. package/package.json +2 -2
  119. package/lib/MetaMatchers.js +0 -118
  120. package/lib/ReactDebugInstanceMap.js +0 -102
  121. package/lib/ReactDefaultPerf.js +0 -316
  122. package/lib/ReactDefaultPerfAnalysis.js +0 -210
package/lib/ReactDOM.js CHANGED
@@ -16,23 +16,20 @@
16
16
  var ReactDOMComponentTree = require('./ReactDOMComponentTree');
17
17
  var ReactDefaultInjection = require('./ReactDefaultInjection');
18
18
  var ReactMount = require('./ReactMount');
19
- var ReactPerf = require('./ReactPerf');
20
19
  var ReactReconciler = require('./ReactReconciler');
21
20
  var ReactUpdates = require('./ReactUpdates');
22
21
  var ReactVersion = require('./ReactVersion');
23
22
 
24
23
  var findDOMNode = require('./findDOMNode');
25
- var getNativeComponentFromComposite = require('./getNativeComponentFromComposite');
24
+ var getHostComponentFromComposite = require('./getHostComponentFromComposite');
26
25
  var renderSubtreeIntoContainer = require('./renderSubtreeIntoContainer');
27
26
  var warning = require('fbjs/lib/warning');
28
27
 
29
28
  ReactDefaultInjection.inject();
30
29
 
31
- var render = ReactPerf.measure('React', 'render', ReactMount.render);
32
-
33
30
  var React = {
34
31
  findDOMNode: findDOMNode,
35
- render: render,
32
+ render: ReactMount.render,
36
33
  unmountComponentAtNode: ReactMount.unmountComponentAtNode,
37
34
  version: ReactVersion,
38
35
 
@@ -51,7 +48,7 @@ if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && typeof __REACT_DEVT
51
48
  getNodeFromInstance: function (inst) {
52
49
  // inst is an internal instance (but could be a composite)
53
50
  if (inst._renderedComponent) {
54
- inst = getNativeComponentFromComposite(inst);
51
+ inst = getHostComponentFromComposite(inst);
55
52
  }
56
53
  if (inst) {
57
54
  return ReactDOMComponentTree.getNodeFromInstance(inst);
@@ -14,11 +14,11 @@
14
14
  var DisabledInputUtils = require('./DisabledInputUtils');
15
15
 
16
16
  /**
17
- * Implements a <button> native component that does not receive mouse events
17
+ * Implements a <button> host component that does not receive mouse events
18
18
  * when `disabled` is set.
19
19
  */
20
20
  var ReactDOMButton = {
21
- getNativeProps: DisabledInputUtils.getNativeProps
21
+ getHostProps: DisabledInputUtils.getHostProps
22
22
  };
23
23
 
24
24
  module.exports = ReactDOMButton;
@@ -13,7 +13,8 @@
13
13
 
14
14
  'use strict';
15
15
 
16
- var _assign = require('object-assign');
16
+ var _prodInvariant = require('./reactProdInvariant'),
17
+ _assign = require('object-assign');
17
18
 
18
19
  var AutoFocusUtils = require('./AutoFocusUtils');
19
20
  var CSSPropertyOperations = require('./CSSPropertyOperations');
@@ -33,9 +34,11 @@ var ReactDOMInput = require('./ReactDOMInput');
33
34
  var ReactDOMOption = require('./ReactDOMOption');
34
35
  var ReactDOMSelect = require('./ReactDOMSelect');
35
36
  var ReactDOMTextarea = require('./ReactDOMTextarea');
37
+ var ReactInstrumentation = require('./ReactInstrumentation');
36
38
  var ReactMultiChild = require('./ReactMultiChild');
37
- var ReactPerf = require('./ReactPerf');
39
+ var ReactServerRenderingTransaction = require('./ReactServerRenderingTransaction');
38
40
 
41
+ var emptyFunction = require('fbjs/lib/emptyFunction');
39
42
  var escapeTextContentForBrowser = require('./escapeTextContentForBrowser');
40
43
  var invariant = require('fbjs/lib/invariant');
41
44
  var isEventSupported = require('./isEventSupported');
@@ -139,33 +142,32 @@ function assertValidProps(component, props) {
139
142
  }
140
143
  // Note the use of `==` which checks for null or undefined.
141
144
  if (voidElementTags[component._tag]) {
142
- !(props.children == null && props.dangerouslySetInnerHTML == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s is a void element tag and must not have `children` or ' + 'use `props.dangerouslySetInnerHTML`.%s', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : invariant(false) : void 0;
145
+ !(props.children == null && props.dangerouslySetInnerHTML == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s is a void element tag and must not have `children` or use `props.dangerouslySetInnerHTML`.%s', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : _prodInvariant('59', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : void 0;
143
146
  }
144
147
  if (props.dangerouslySetInnerHTML != null) {
145
- !(props.children == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : invariant(false) : void 0;
146
- !(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML) ? process.env.NODE_ENV !== 'production' ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://fb.me/react-invariant-dangerously-set-inner-html ' + 'for more information.') : invariant(false) : void 0;
148
+ !(props.children == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : _prodInvariant('60') : void 0;
149
+ !(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML) ? process.env.NODE_ENV !== 'production' ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.') : _prodInvariant('61') : void 0;
147
150
  }
148
151
  if (process.env.NODE_ENV !== 'production') {
149
152
  process.env.NODE_ENV !== 'production' ? warning(props.innerHTML == null, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.') : void 0;
150
153
  process.env.NODE_ENV !== 'production' ? warning(props.suppressContentEditableWarning || !props.contentEditable || props.children == null, 'A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.') : void 0;
151
154
  process.env.NODE_ENV !== 'production' ? warning(props.onFocusIn == null && props.onFocusOut == null, 'React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' + 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' + 'are not needed/supported by React.') : void 0;
152
155
  }
153
- !(props.style == null || typeof props.style === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'The `style` prop expects a mapping from style properties to values, ' + 'not a string. For example, style={{marginRight: spacing + \'em\'}} when ' + 'using JSX.%s', getDeclarationErrorAddendum(component)) : invariant(false) : void 0;
156
+ !(props.style == null || typeof props.style === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + \'em\'}} when using JSX.%s', getDeclarationErrorAddendum(component)) : _prodInvariant('62', getDeclarationErrorAddendum(component)) : void 0;
154
157
  }
155
158
 
156
159
  function enqueuePutListener(inst, registrationName, listener, transaction) {
160
+ if (transaction instanceof ReactServerRenderingTransaction) {
161
+ return;
162
+ }
157
163
  if (process.env.NODE_ENV !== 'production') {
158
164
  // IE8 has no API for event capturing and the `onScroll` event doesn't
159
165
  // bubble.
160
166
  process.env.NODE_ENV !== 'production' ? warning(registrationName !== 'onScroll' || isEventSupported('scroll', true), 'This browser doesn\'t support the `onScroll` event') : void 0;
161
167
  }
162
- var containerInfo = inst._nativeContainerInfo;
168
+ var containerInfo = inst._hostContainerInfo;
163
169
  var isDocumentFragment = containerInfo._node && containerInfo._node.nodeType === DOC_FRAGMENT_TYPE;
164
170
  var doc = isDocumentFragment ? containerInfo._node : containerInfo._ownerDocument;
165
- if (!doc) {
166
- // Server rendering.
167
- return;
168
- }
169
171
  listenTo(registrationName, doc);
170
172
  transaction.getReactMountReady().enqueue(putListener, {
171
173
  inst: inst,
@@ -179,11 +181,54 @@ function putListener() {
179
181
  EventPluginHub.putListener(listenerToPut.inst, listenerToPut.registrationName, listenerToPut.listener);
180
182
  }
181
183
 
184
+ function inputPostMount() {
185
+ var inst = this;
186
+ ReactDOMInput.postMountWrapper(inst);
187
+ }
188
+
189
+ function textareaPostMount() {
190
+ var inst = this;
191
+ ReactDOMTextarea.postMountWrapper(inst);
192
+ }
193
+
182
194
  function optionPostMount() {
183
195
  var inst = this;
184
196
  ReactDOMOption.postMountWrapper(inst);
185
197
  }
186
198
 
199
+ var setContentChildForInstrumentation = emptyFunction;
200
+ if (process.env.NODE_ENV !== 'production') {
201
+ setContentChildForInstrumentation = function (content) {
202
+ var hasExistingContent = this._contentDebugID != null;
203
+ var debugID = this._debugID;
204
+ var contentDebugID = debugID + '#text';
205
+
206
+ if (content == null) {
207
+ if (hasExistingContent) {
208
+ ReactInstrumentation.debugTool.onUnmountComponent(this._contentDebugID);
209
+ }
210
+ this._contentDebugID = null;
211
+ return;
212
+ }
213
+
214
+ this._contentDebugID = contentDebugID;
215
+ var text = '' + content;
216
+
217
+ ReactInstrumentation.debugTool.onSetDisplayName(contentDebugID, '#text');
218
+ ReactInstrumentation.debugTool.onSetParent(contentDebugID, debugID);
219
+ ReactInstrumentation.debugTool.onSetText(contentDebugID, text);
220
+
221
+ if (hasExistingContent) {
222
+ ReactInstrumentation.debugTool.onBeforeUpdateComponent(contentDebugID, content);
223
+ ReactInstrumentation.debugTool.onUpdateComponent(contentDebugID);
224
+ } else {
225
+ ReactInstrumentation.debugTool.onBeforeMountComponent(contentDebugID, content);
226
+ ReactInstrumentation.debugTool.onMountComponent(contentDebugID);
227
+ ReactInstrumentation.debugTool.onSetChildren(debugID, [contentDebugID]);
228
+ }
229
+ };
230
+ }
231
+
187
232
  // There are so many media events, it makes sense to just
188
233
  // maintain a list rather than create a `trapBubbledEvent` for each
189
234
  var mediaEvents = {
@@ -216,9 +261,9 @@ function trapBubbledEventsLocal() {
216
261
  var inst = this;
217
262
  // If a component renders to null or if another component fatals and causes
218
263
  // the state of the tree to be corrupted, `node` here can be null.
219
- !inst._rootNodeID ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Must be mounted to trap events') : invariant(false) : void 0;
264
+ !inst._rootNodeID ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Must be mounted to trap events') : _prodInvariant('63') : void 0;
220
265
  var node = getNode(inst);
221
- !node ? process.env.NODE_ENV !== 'production' ? invariant(false, 'trapBubbledEvent(...): Requires node to be rendered.') : invariant(false) : void 0;
266
+ !node ? process.env.NODE_ENV !== 'production' ? invariant(false, 'trapBubbledEvent(...): Requires node to be rendered.') : _prodInvariant('64') : void 0;
222
267
 
223
268
  switch (inst._tag) {
224
269
  case 'iframe':
@@ -235,7 +280,9 @@ function trapBubbledEventsLocal() {
235
280
  inst._wrapperState.listeners.push(ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes[event], mediaEvents[event], node));
236
281
  }
237
282
  }
238
-
283
+ break;
284
+ case 'source':
285
+ inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topError, 'error', node)];
239
286
  break;
240
287
  case 'img':
241
288
  inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topError, 'error', node), ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load', node)];
@@ -300,7 +347,7 @@ var hasOwnProperty = {}.hasOwnProperty;
300
347
 
301
348
  function validateDangerousTag(tag) {
302
349
  if (!hasOwnProperty.call(validatedTagCache, tag)) {
303
- !VALID_TAG_REGEX.test(tag) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Invalid tag: %s', tag) : invariant(false) : void 0;
350
+ !VALID_TAG_REGEX.test(tag) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Invalid tag: %s', tag) : _prodInvariant('65', tag) : void 0;
304
351
  validatedTagCache[tag] = true;
305
352
  }
306
353
  }
@@ -334,16 +381,17 @@ function ReactDOMComponent(element) {
334
381
  this._renderedChildren = null;
335
382
  this._previousStyle = null;
336
383
  this._previousStyleCopy = null;
337
- this._nativeNode = null;
338
- this._nativeParent = null;
384
+ this._hostNode = null;
385
+ this._hostParent = null;
339
386
  this._rootNodeID = null;
340
387
  this._domID = null;
341
- this._nativeContainerInfo = null;
388
+ this._hostContainerInfo = null;
342
389
  this._wrapperState = null;
343
390
  this._topLevelWrapper = null;
344
391
  this._flags = 0;
345
392
  if (process.env.NODE_ENV !== 'production') {
346
393
  this._ancestorInfo = null;
394
+ setContentChildForInstrumentation.call(this, null);
347
395
  }
348
396
  }
349
397
 
@@ -358,50 +406,52 @@ ReactDOMComponent.Mixin = {
358
406
  * @internal
359
407
  * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
360
408
  * @param {?ReactDOMComponent} the containing DOM component instance
361
- * @param {?object} info about the native container
409
+ * @param {?object} info about the host container
362
410
  * @param {object} context
363
411
  * @return {string} The computed markup.
364
412
  */
365
- mountComponent: function (transaction, nativeParent, nativeContainerInfo, context) {
413
+ mountComponent: function (transaction, hostParent, hostContainerInfo, context) {
366
414
  this._rootNodeID = globalIdCounter++;
367
- this._domID = nativeContainerInfo._idCounter++;
368
- this._nativeParent = nativeParent;
369
- this._nativeContainerInfo = nativeContainerInfo;
415
+ this._domID = hostContainerInfo._idCounter++;
416
+ this._hostParent = hostParent;
417
+ this._hostContainerInfo = hostContainerInfo;
370
418
 
371
419
  var props = this._currentElement.props;
372
420
 
373
421
  switch (this._tag) {
422
+ case 'audio':
423
+ case 'form':
374
424
  case 'iframe':
375
- case 'object':
376
425
  case 'img':
377
- case 'form':
426
+ case 'link':
427
+ case 'object':
428
+ case 'source':
378
429
  case 'video':
379
- case 'audio':
380
430
  this._wrapperState = {
381
431
  listeners: null
382
432
  };
383
433
  transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
384
434
  break;
385
435
  case 'button':
386
- props = ReactDOMButton.getNativeProps(this, props, nativeParent);
436
+ props = ReactDOMButton.getHostProps(this, props, hostParent);
387
437
  break;
388
438
  case 'input':
389
- ReactDOMInput.mountWrapper(this, props, nativeParent);
390
- props = ReactDOMInput.getNativeProps(this, props);
439
+ ReactDOMInput.mountWrapper(this, props, hostParent);
440
+ props = ReactDOMInput.getHostProps(this, props);
391
441
  transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
392
442
  break;
393
443
  case 'option':
394
- ReactDOMOption.mountWrapper(this, props, nativeParent);
395
- props = ReactDOMOption.getNativeProps(this, props);
444
+ ReactDOMOption.mountWrapper(this, props, hostParent);
445
+ props = ReactDOMOption.getHostProps(this, props);
396
446
  break;
397
447
  case 'select':
398
- ReactDOMSelect.mountWrapper(this, props, nativeParent);
399
- props = ReactDOMSelect.getNativeProps(this, props);
448
+ ReactDOMSelect.mountWrapper(this, props, hostParent);
449
+ props = ReactDOMSelect.getHostProps(this, props);
400
450
  transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
401
451
  break;
402
452
  case 'textarea':
403
- ReactDOMTextarea.mountWrapper(this, props, nativeParent);
404
- props = ReactDOMTextarea.getNativeProps(this, props);
453
+ ReactDOMTextarea.mountWrapper(this, props, hostParent);
454
+ props = ReactDOMTextarea.getHostProps(this, props);
405
455
  transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
406
456
  break;
407
457
  }
@@ -412,12 +462,12 @@ ReactDOMComponent.Mixin = {
412
462
  // tags get no namespace.
413
463
  var namespaceURI;
414
464
  var parentTag;
415
- if (nativeParent != null) {
416
- namespaceURI = nativeParent._namespaceURI;
417
- parentTag = nativeParent._tag;
418
- } else if (nativeContainerInfo._tag) {
419
- namespaceURI = nativeContainerInfo._namespaceURI;
420
- parentTag = nativeContainerInfo._tag;
465
+ if (hostParent != null) {
466
+ namespaceURI = hostParent._namespaceURI;
467
+ parentTag = hostParent._tag;
468
+ } else if (hostContainerInfo._tag) {
469
+ namespaceURI = hostContainerInfo._namespaceURI;
470
+ parentTag = hostContainerInfo._tag;
421
471
  }
422
472
  if (namespaceURI == null || namespaceURI === DOMNamespaces.svg && parentTag === 'foreignobject') {
423
473
  namespaceURI = DOMNamespaces.html;
@@ -433,10 +483,10 @@ ReactDOMComponent.Mixin = {
433
483
 
434
484
  if (process.env.NODE_ENV !== 'production') {
435
485
  var parentInfo;
436
- if (nativeParent != null) {
437
- parentInfo = nativeParent._ancestorInfo;
438
- } else if (nativeContainerInfo._tag) {
439
- parentInfo = nativeContainerInfo._ancestorInfo;
486
+ if (hostParent != null) {
487
+ parentInfo = hostParent._ancestorInfo;
488
+ } else if (hostContainerInfo._tag) {
489
+ parentInfo = hostContainerInfo._ancestorInfo;
440
490
  }
441
491
  if (parentInfo) {
442
492
  // parentInfo should always be present except for the top-level
@@ -448,7 +498,7 @@ ReactDOMComponent.Mixin = {
448
498
 
449
499
  var mountImage;
450
500
  if (transaction.useCreateElement) {
451
- var ownerDocument = nativeContainerInfo._ownerDocument;
501
+ var ownerDocument = hostContainerInfo._ownerDocument;
452
502
  var el;
453
503
  if (namespaceURI === DOMNamespaces.html) {
454
504
  if (this._tag === 'script') {
@@ -458,7 +508,12 @@ ReactDOMComponent.Mixin = {
458
508
  var type = this._currentElement.type;
459
509
  div.innerHTML = '<' + type + '></' + type + '>';
460
510
  el = div.removeChild(div.firstChild);
511
+ } else if (props.is) {
512
+ el = ownerDocument.createElement(this._currentElement.type, props.is);
461
513
  } else {
514
+ // Separate else branch instead of using `props.is || undefined` above becuase of a Firefox bug.
515
+ // See discussion in https://github.com/facebook/react/pull/6896
516
+ // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
462
517
  el = ownerDocument.createElement(this._currentElement.type);
463
518
  }
464
519
  } else {
@@ -466,7 +521,7 @@ ReactDOMComponent.Mixin = {
466
521
  }
467
522
  ReactDOMComponentTree.precacheNode(this, el);
468
523
  this._flags |= Flags.hasCachedChildNodes;
469
- if (!this._nativeParent) {
524
+ if (!this._hostParent) {
470
525
  DOMPropertyOperations.setAttributeForRoot(el);
471
526
  }
472
527
  this._updateDOMProperties(null, props, transaction);
@@ -484,16 +539,31 @@ ReactDOMComponent.Mixin = {
484
539
  }
485
540
 
486
541
  switch (this._tag) {
487
- case 'button':
488
542
  case 'input':
489
- case 'select':
543
+ transaction.getReactMountReady().enqueue(inputPostMount, this);
544
+ if (props.autoFocus) {
545
+ transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this);
546
+ }
547
+ break;
490
548
  case 'textarea':
549
+ transaction.getReactMountReady().enqueue(textareaPostMount, this);
550
+ if (props.autoFocus) {
551
+ transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this);
552
+ }
553
+ break;
554
+ case 'select':
555
+ if (props.autoFocus) {
556
+ transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this);
557
+ }
558
+ break;
559
+ case 'button':
491
560
  if (props.autoFocus) {
492
561
  transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this);
493
562
  }
494
563
  break;
495
564
  case 'option':
496
565
  transaction.getReactMountReady().enqueue(optionPostMount, this);
566
+ break;
497
567
  }
498
568
 
499
569
  return mountImage;
@@ -558,7 +628,7 @@ ReactDOMComponent.Mixin = {
558
628
  return ret;
559
629
  }
560
630
 
561
- if (!this._nativeParent) {
631
+ if (!this._hostParent) {
562
632
  ret += ' ' + DOMPropertyOperations.createMarkupForRoot();
563
633
  }
564
634
  ret += ' ' + DOMPropertyOperations.createMarkupForID(this._domID);
@@ -589,6 +659,9 @@ ReactDOMComponent.Mixin = {
589
659
  if (contentToUse != null) {
590
660
  // TODO: Validate that text is allowed as a child of this node
591
661
  ret = escapeTextContentForBrowser(contentToUse);
662
+ if (process.env.NODE_ENV !== 'production') {
663
+ setContentChildForInstrumentation.call(this, contentToUse);
664
+ }
592
665
  } else if (childrenToUse != null) {
593
666
  var mountImages = this.mountChildren(childrenToUse, transaction, context);
594
667
  ret = mountImages.join('');
@@ -623,6 +696,9 @@ ReactDOMComponent.Mixin = {
623
696
  var childrenToUse = contentToUse != null ? null : props.children;
624
697
  if (contentToUse != null) {
625
698
  // TODO: Validate that text is allowed as a child of this node
699
+ if (process.env.NODE_ENV !== 'production') {
700
+ setContentChildForInstrumentation.call(this, contentToUse);
701
+ }
626
702
  DOMLazyTree.queueText(lazyTree, contentToUse);
627
703
  } else if (childrenToUse != null) {
628
704
  var mountImages = this.mountChildren(childrenToUse, transaction, context);
@@ -648,7 +724,7 @@ ReactDOMComponent.Mixin = {
648
724
  },
649
725
 
650
726
  /**
651
- * Updates a native DOM component after it has already been allocated and
727
+ * Updates a DOM component after it has already been allocated and
652
728
  * attached to the DOM. Reconciles the root DOM node, then recurses.
653
729
  *
654
730
  * @param {ReactReconcileTransaction} transaction
@@ -663,26 +739,26 @@ ReactDOMComponent.Mixin = {
663
739
 
664
740
  switch (this._tag) {
665
741
  case 'button':
666
- lastProps = ReactDOMButton.getNativeProps(this, lastProps);
667
- nextProps = ReactDOMButton.getNativeProps(this, nextProps);
742
+ lastProps = ReactDOMButton.getHostProps(this, lastProps);
743
+ nextProps = ReactDOMButton.getHostProps(this, nextProps);
668
744
  break;
669
745
  case 'input':
670
746
  ReactDOMInput.updateWrapper(this);
671
- lastProps = ReactDOMInput.getNativeProps(this, lastProps);
672
- nextProps = ReactDOMInput.getNativeProps(this, nextProps);
747
+ lastProps = ReactDOMInput.getHostProps(this, lastProps);
748
+ nextProps = ReactDOMInput.getHostProps(this, nextProps);
673
749
  break;
674
750
  case 'option':
675
- lastProps = ReactDOMOption.getNativeProps(this, lastProps);
676
- nextProps = ReactDOMOption.getNativeProps(this, nextProps);
751
+ lastProps = ReactDOMOption.getHostProps(this, lastProps);
752
+ nextProps = ReactDOMOption.getHostProps(this, nextProps);
677
753
  break;
678
754
  case 'select':
679
- lastProps = ReactDOMSelect.getNativeProps(this, lastProps);
680
- nextProps = ReactDOMSelect.getNativeProps(this, nextProps);
755
+ lastProps = ReactDOMSelect.getHostProps(this, lastProps);
756
+ nextProps = ReactDOMSelect.getHostProps(this, nextProps);
681
757
  break;
682
758
  case 'textarea':
683
759
  ReactDOMTextarea.updateWrapper(this);
684
- lastProps = ReactDOMTextarea.getNativeProps(this, lastProps);
685
- nextProps = ReactDOMTextarea.getNativeProps(this, nextProps);
760
+ lastProps = ReactDOMTextarea.getHostProps(this, lastProps);
761
+ nextProps = ReactDOMTextarea.getHostProps(this, nextProps);
686
762
  break;
687
763
  }
688
764
 
@@ -737,6 +813,10 @@ ReactDOMComponent.Mixin = {
737
813
  // listener (e.g., onClick={null})
738
814
  deleteListener(this, propKey);
739
815
  }
816
+ } else if (isCustomComponent(this._tag, lastProps)) {
817
+ if (!RESERVED_PROPS.hasOwnProperty(propKey)) {
818
+ DOMPropertyOperations.deleteValueForAttribute(getNode(this), propKey);
819
+ }
740
820
  } else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {
741
821
  DOMPropertyOperations.deleteValueForProperty(getNode(this), propKey);
742
822
  }
@@ -831,22 +911,35 @@ ReactDOMComponent.Mixin = {
831
911
  this.updateChildren(null, transaction, context);
832
912
  } else if (lastHasContentOrHtml && !nextHasContentOrHtml) {
833
913
  this.updateTextContent('');
914
+ if (process.env.NODE_ENV !== 'production') {
915
+ ReactInstrumentation.debugTool.onSetChildren(this._debugID, []);
916
+ }
834
917
  }
835
918
 
836
919
  if (nextContent != null) {
837
920
  if (lastContent !== nextContent) {
838
921
  this.updateTextContent('' + nextContent);
922
+ if (process.env.NODE_ENV !== 'production') {
923
+ setContentChildForInstrumentation.call(this, nextContent);
924
+ }
839
925
  }
840
926
  } else if (nextHtml != null) {
841
927
  if (lastHtml !== nextHtml) {
842
928
  this.updateMarkup('' + nextHtml);
843
929
  }
930
+ if (process.env.NODE_ENV !== 'production') {
931
+ ReactInstrumentation.debugTool.onSetChildren(this._debugID, []);
932
+ }
844
933
  } else if (nextChildren != null) {
934
+ if (process.env.NODE_ENV !== 'production') {
935
+ setContentChildForInstrumentation.call(this, null);
936
+ }
937
+
845
938
  this.updateChildren(nextChildren, transaction, context);
846
939
  }
847
940
  },
848
941
 
849
- getNativeNode: function () {
942
+ getHostNode: function () {
850
943
  return getNode(this);
851
944
  },
852
945
 
@@ -858,12 +951,14 @@ ReactDOMComponent.Mixin = {
858
951
  */
859
952
  unmountComponent: function (safely) {
860
953
  switch (this._tag) {
954
+ case 'audio':
955
+ case 'form':
861
956
  case 'iframe':
862
- case 'object':
863
957
  case 'img':
864
- case 'form':
958
+ case 'link':
959
+ case 'object':
960
+ case 'source':
865
961
  case 'video':
866
- case 'audio':
867
962
  var listeners = this._wrapperState.listeners;
868
963
  if (listeners) {
869
964
  for (var i = 0; i < listeners.length; i++) {
@@ -880,7 +975,7 @@ ReactDOMComponent.Mixin = {
880
975
  * take advantage of React's reconciliation for styling and <title>
881
976
  * management. So we just document it and throw in dangerous cases.
882
977
  */
883
- !false ? process.env.NODE_ENV !== 'production' ? invariant(false, '<%s> tried to unmount. Because of cross-browser quirks it is ' + 'impossible to unmount some top-level components (eg <html>, ' + '<head>, and <body>) reliably and efficiently. To fix this, have a ' + 'single top-level component that never unmounts render these ' + 'elements.', this._tag) : invariant(false) : void 0;
978
+ !false ? process.env.NODE_ENV !== 'production' ? invariant(false, '<%s> tried to unmount. Because of cross-browser quirks it is impossible to unmount some top-level components (eg <html>, <head>, and <body>) reliably and efficiently. To fix this, have a single top-level component that never unmounts render these elements.', this._tag) : _prodInvariant('66', this._tag) : void 0;
884
979
  break;
885
980
  }
886
981
 
@@ -891,6 +986,10 @@ ReactDOMComponent.Mixin = {
891
986
  this._rootNodeID = null;
892
987
  this._domID = null;
893
988
  this._wrapperState = null;
989
+
990
+ if (process.env.NODE_ENV !== 'production') {
991
+ setContentChildForInstrumentation.call(this, null);
992
+ }
894
993
  },
895
994
 
896
995
  getPublicInstance: function () {
@@ -899,11 +998,6 @@ ReactDOMComponent.Mixin = {
899
998
 
900
999
  };
901
1000
 
902
- ReactPerf.measureMethods(ReactDOMComponent.Mixin, 'ReactDOMComponent', {
903
- mountComponent: 'mountComponent',
904
- receiveComponent: 'receiveComponent'
905
- });
906
-
907
1001
  _assign(ReactDOMComponent.prototype, ReactDOMComponent.Mixin, ReactMultiChild.Mixin);
908
1002
 
909
1003
  module.exports = ReactDOMComponent;