react 15.1.0 → 15.2.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 (124) hide show
  1. package/dist/react-with-addons.js +2685 -1842
  2. package/dist/react-with-addons.min.js +6 -6
  3. package/dist/react.js +2400 -1691
  4. package/dist/react.min.js +6 -6
  5. package/lib/CSSPropertyOperations.js +1 -1
  6. package/lib/CallbackQueue.js +3 -2
  7. package/lib/DOMChildrenOperations.js +9 -9
  8. package/lib/DOMLazyTree.js +3 -2
  9. package/lib/DOMProperty.js +5 -12
  10. package/lib/DOMPropertyOperations.js +21 -15
  11. package/lib/Danger.js +5 -101
  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/KeyEscapeUtils.js +2 -1
  18. package/lib/LinkedValueUtils.js +5 -3
  19. package/lib/NativeMethodsMixin.js +6 -4
  20. package/lib/PooledClass.js +4 -2
  21. package/lib/React.js +1 -1
  22. package/lib/ReactCSSTransitionGroupChild.js +15 -8
  23. package/lib/ReactChildReconciler.js +17 -8
  24. package/lib/ReactClass.js +14 -13
  25. package/lib/ReactComponent.js +3 -6
  26. package/lib/ReactComponentEnvironment.js +3 -1
  27. package/lib/ReactComponentTreeDevtool.js +89 -16
  28. package/lib/ReactComponentTreeTestUtils.js +87 -0
  29. package/lib/ReactCompositeComponent.js +87 -117
  30. package/lib/ReactDOM.js +2 -2
  31. package/lib/ReactDOMButton.js +2 -2
  32. package/lib/ReactDOMComponent.js +130 -76
  33. package/lib/ReactDOMComponentTree.js +23 -21
  34. package/lib/ReactDOMDebugTool.js +17 -11
  35. package/lib/ReactDOMEmptyComponent.js +9 -9
  36. package/lib/ReactDOMFactories.js +1 -1
  37. package/lib/ReactDOMFiber.js +78 -0
  38. package/lib/ReactDOMInput.js +64 -26
  39. package/lib/ReactDOMInstrumentation.js +7 -2
  40. package/lib/ReactDOMNullInputValuePropDevtool.js +43 -0
  41. package/lib/ReactDOMOption.js +40 -26
  42. package/lib/ReactDOMSelect.js +3 -16
  43. package/lib/ReactDOMTextComponent.js +21 -20
  44. package/lib/ReactDOMTextarea.js +59 -46
  45. package/lib/ReactDOMTreeTraversal.js +18 -16
  46. package/lib/ReactDOMUnknownPropertyDevtool.js +65 -17
  47. package/lib/ReactDebugTool.js +148 -95
  48. package/lib/ReactDefaultInjection.js +2 -2
  49. package/lib/ReactElement.js +64 -25
  50. package/lib/ReactElementValidator.js +26 -81
  51. package/lib/ReactEventListener.js +2 -2
  52. package/lib/ReactFeatureFlags.js +1 -0
  53. package/lib/ReactFragment.js +3 -1
  54. package/lib/{ReactNativeComponent.js → ReactHostComponent.js} +10 -29
  55. package/lib/{ReactNativeOperationHistoryDevtool.js → ReactHostOperationHistoryDevtool.js} +5 -5
  56. package/lib/ReactInjection.js +2 -2
  57. package/lib/ReactInstanceHandles.js +8 -6
  58. package/lib/ReactInstrumentation.js +7 -2
  59. package/lib/ReactMount.js +38 -32
  60. package/lib/ReactMultiChild.js +38 -11
  61. package/lib/ReactNativeAttributePayload.js +5 -2
  62. package/lib/ReactNativeBaseComponent.js +7 -7
  63. package/lib/ReactNativeBridgeEventPlugin.js +1 -1
  64. package/lib/ReactNativeComponentTree.js +8 -6
  65. package/lib/ReactNativeDOMIDOperations.js +1 -2
  66. package/lib/ReactNativeDefaultInjection.js +9 -7
  67. package/lib/ReactNativeGlobalResponderHandler.js +1 -1
  68. package/lib/ReactNativeMount.js +3 -14
  69. package/lib/ReactNativeReconcileTransaction.js +16 -0
  70. package/lib/ReactNativeTagHandles.js +3 -1
  71. package/lib/ReactNativeTextComponent.js +10 -9
  72. package/lib/ReactNativeTreeTraversal.js +11 -11
  73. package/lib/ReactNodeTypes.js +6 -3
  74. package/lib/ReactNoop.js +173 -0
  75. package/lib/ReactNoopUpdateQueue.js +6 -5
  76. package/lib/ReactOwner.js +4 -2
  77. package/lib/ReactPerf.js +83 -7
  78. package/lib/ReactPropTypes.js +23 -0
  79. package/lib/ReactReconcileTransaction.js +17 -1
  80. package/lib/ReactReconciler.js +12 -7
  81. package/lib/ReactServerRendering.js +5 -7
  82. package/lib/ReactServerRenderingTransaction.js +17 -0
  83. package/lib/ReactServerUpdateQueue.js +141 -0
  84. package/lib/ReactSimpleEmptyComponent.js +4 -4
  85. package/lib/ReactTestMount.js +115 -0
  86. package/lib/ReactTestReconcileTransaction.js +108 -0
  87. package/lib/ReactTestRenderer.js +133 -0
  88. package/lib/ReactTestUtils.js +17 -10
  89. package/lib/ReactTransitionChildMapping.js +7 -1
  90. package/lib/ReactTransitionGroup.js +41 -6
  91. package/lib/ReactUpdateQueue.js +13 -3
  92. package/lib/ReactUpdates.js +10 -18
  93. package/lib/ReactVersion.js +1 -1
  94. package/lib/ResponderEventPlugin.js +9 -7
  95. package/lib/ResponderTouchHistoryStore.js +99 -95
  96. package/lib/SimpleEventPlugin.js +3 -1
  97. package/lib/SyntheticEvent.js +2 -3
  98. package/lib/SyntheticUIEvent.js +1 -1
  99. package/lib/Transaction.js +4 -2
  100. package/lib/accumulate.js +17 -15
  101. package/lib/accumulateInto.js +11 -12
  102. package/lib/adler32.js +1 -0
  103. package/lib/checkReactTypeSpec.js +73 -0
  104. package/lib/createReactNativeComponentClass.js +2 -2
  105. package/lib/dangerousStyleValue.js +3 -1
  106. package/lib/deprecated.js +7 -1
  107. package/lib/escapeTextContentForBrowser.js +96 -12
  108. package/lib/findDOMNode.js +6 -4
  109. package/lib/findNodeHandle.js +5 -3
  110. package/lib/flattenChildren.js +22 -10
  111. package/lib/forEachAccumulated.js +3 -2
  112. package/lib/{getNativeComponentFromComposite.js → getHostComponentFromComposite.js} +4 -4
  113. package/lib/getIteratorFn.js +1 -0
  114. package/lib/instantiateReactComponent.js +21 -19
  115. package/lib/isTextInputElement.js +11 -1
  116. package/lib/onlyChild.js +3 -1
  117. package/lib/reactComponentExpect.js +3 -3
  118. package/lib/reactProdInvariant.js +39 -0
  119. package/lib/setInnerHTML.js +17 -1
  120. package/lib/setTextContent.js +8 -0
  121. package/lib/traverseAllChildren.js +3 -1
  122. package/lib/update.js +12 -11
  123. package/package.json +2 -2
  124. package/lib/MetaMatchers.js +0 -118
package/lib/ReactDOM.js CHANGED
@@ -21,7 +21,7 @@ var ReactUpdates = require('./ReactUpdates');
21
21
  var ReactVersion = require('./ReactVersion');
22
22
 
23
23
  var findDOMNode = require('./findDOMNode');
24
- var getNativeComponentFromComposite = require('./getNativeComponentFromComposite');
24
+ var getHostComponentFromComposite = require('./getHostComponentFromComposite');
25
25
  var renderSubtreeIntoContainer = require('./renderSubtreeIntoContainer');
26
26
  var warning = require('fbjs/lib/warning');
27
27
 
@@ -48,7 +48,7 @@ if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && typeof __REACT_DEVT
48
48
  getNodeFromInstance: function (inst) {
49
49
  // inst is an internal instance (but could be a composite)
50
50
  if (inst._renderedComponent) {
51
- inst = getNativeComponentFromComposite(inst);
51
+ inst = getHostComponentFromComposite(inst);
52
52
  }
53
53
  if (inst) {
54
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');
@@ -141,18 +142,18 @@ function assertValidProps(component, props) {
141
142
  }
142
143
  // Note the use of `==` which checks for null or undefined.
143
144
  if (voidElementTags[component._tag]) {
144
- !(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 neither have `children` nor use `dangerouslySetInnerHTML`.%s', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : _prodInvariant('137', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : void 0;
145
146
  }
146
147
  if (props.dangerouslySetInnerHTML != null) {
147
- !(props.children == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : invariant(false) : void 0;
148
- !(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;
149
150
  }
150
151
  if (process.env.NODE_ENV !== 'production') {
151
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;
152
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;
153
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;
154
155
  }
155
- !(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;
156
157
  }
157
158
 
158
159
  function enqueuePutListener(inst, registrationName, listener, transaction) {
@@ -164,7 +165,7 @@ function enqueuePutListener(inst, registrationName, listener, transaction) {
164
165
  // bubble.
165
166
  process.env.NODE_ENV !== 'production' ? warning(registrationName !== 'onScroll' || isEventSupported('scroll', true), 'This browser doesn\'t support the `onScroll` event') : void 0;
166
167
  }
167
- var containerInfo = inst._nativeContainerInfo;
168
+ var containerInfo = inst._hostContainerInfo;
168
169
  var isDocumentFragment = containerInfo._node && containerInfo._node.nodeType === DOC_FRAGMENT_TYPE;
169
170
  var doc = isDocumentFragment ? containerInfo._node : containerInfo._ownerDocument;
170
171
  listenTo(registrationName, doc);
@@ -180,6 +181,16 @@ function putListener() {
180
181
  EventPluginHub.putListener(listenerToPut.inst, listenerToPut.registrationName, listenerToPut.listener);
181
182
  }
182
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
+
183
194
  function optionPostMount() {
184
195
  var inst = this;
185
196
  ReactDOMOption.postMountWrapper(inst);
@@ -187,14 +198,34 @@ function optionPostMount() {
187
198
 
188
199
  var setContentChildForInstrumentation = emptyFunction;
189
200
  if (process.env.NODE_ENV !== 'production') {
190
- setContentChildForInstrumentation = function (contentToUse) {
201
+ setContentChildForInstrumentation = function (content) {
202
+ var hasExistingContent = this._contentDebugID != null;
191
203
  var debugID = this._debugID;
192
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
+
193
214
  this._contentDebugID = contentDebugID;
215
+ var text = '' + content;
216
+
194
217
  ReactInstrumentation.debugTool.onSetDisplayName(contentDebugID, '#text');
195
- ReactInstrumentation.debugTool.onSetText(contentDebugID, '' + contentToUse);
196
- ReactInstrumentation.debugTool.onMountComponent(contentDebugID);
197
- ReactInstrumentation.debugTool.onSetChildren(debugID, [contentDebugID]);
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
+ }
198
229
  };
199
230
  }
200
231
 
@@ -230,9 +261,9 @@ function trapBubbledEventsLocal() {
230
261
  var inst = this;
231
262
  // If a component renders to null or if another component fatals and causes
232
263
  // the state of the tree to be corrupted, `node` here can be null.
233
- !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;
234
265
  var node = getNode(inst);
235
- !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;
236
267
 
237
268
  switch (inst._tag) {
238
269
  case 'iframe':
@@ -249,7 +280,9 @@ function trapBubbledEventsLocal() {
249
280
  inst._wrapperState.listeners.push(ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes[event], mediaEvents[event], node));
250
281
  }
251
282
  }
252
-
283
+ break;
284
+ case 'source':
285
+ inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topError, 'error', node)];
253
286
  break;
254
287
  case 'img':
255
288
  inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topError, 'error', node), ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load', node)];
@@ -314,7 +347,7 @@ var hasOwnProperty = {}.hasOwnProperty;
314
347
 
315
348
  function validateDangerousTag(tag) {
316
349
  if (!hasOwnProperty.call(validatedTagCache, tag)) {
317
- !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;
318
351
  validatedTagCache[tag] = true;
319
352
  }
320
353
  }
@@ -348,17 +381,17 @@ function ReactDOMComponent(element) {
348
381
  this._renderedChildren = null;
349
382
  this._previousStyle = null;
350
383
  this._previousStyleCopy = null;
351
- this._nativeNode = null;
352
- this._nativeParent = null;
384
+ this._hostNode = null;
385
+ this._hostParent = null;
353
386
  this._rootNodeID = null;
354
387
  this._domID = null;
355
- this._nativeContainerInfo = null;
388
+ this._hostContainerInfo = null;
356
389
  this._wrapperState = null;
357
390
  this._topLevelWrapper = null;
358
391
  this._flags = 0;
359
392
  if (process.env.NODE_ENV !== 'production') {
360
393
  this._ancestorInfo = null;
361
- this._contentDebugID = null;
394
+ setContentChildForInstrumentation.call(this, null);
362
395
  }
363
396
  }
364
397
 
@@ -373,50 +406,52 @@ ReactDOMComponent.Mixin = {
373
406
  * @internal
374
407
  * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
375
408
  * @param {?ReactDOMComponent} the containing DOM component instance
376
- * @param {?object} info about the native container
409
+ * @param {?object} info about the host container
377
410
  * @param {object} context
378
411
  * @return {string} The computed markup.
379
412
  */
380
- mountComponent: function (transaction, nativeParent, nativeContainerInfo, context) {
413
+ mountComponent: function (transaction, hostParent, hostContainerInfo, context) {
381
414
  this._rootNodeID = globalIdCounter++;
382
- this._domID = nativeContainerInfo._idCounter++;
383
- this._nativeParent = nativeParent;
384
- this._nativeContainerInfo = nativeContainerInfo;
415
+ this._domID = hostContainerInfo._idCounter++;
416
+ this._hostParent = hostParent;
417
+ this._hostContainerInfo = hostContainerInfo;
385
418
 
386
419
  var props = this._currentElement.props;
387
420
 
388
421
  switch (this._tag) {
422
+ case 'audio':
423
+ case 'form':
389
424
  case 'iframe':
390
- case 'object':
391
425
  case 'img':
392
- case 'form':
426
+ case 'link':
427
+ case 'object':
428
+ case 'source':
393
429
  case 'video':
394
- case 'audio':
395
430
  this._wrapperState = {
396
431
  listeners: null
397
432
  };
398
433
  transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
399
434
  break;
400
435
  case 'button':
401
- props = ReactDOMButton.getNativeProps(this, props, nativeParent);
436
+ props = ReactDOMButton.getHostProps(this, props, hostParent);
402
437
  break;
403
438
  case 'input':
404
- ReactDOMInput.mountWrapper(this, props, nativeParent);
405
- props = ReactDOMInput.getNativeProps(this, props);
439
+ ReactDOMInput.mountWrapper(this, props, hostParent);
440
+ props = ReactDOMInput.getHostProps(this, props);
406
441
  transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
407
442
  break;
408
443
  case 'option':
409
- ReactDOMOption.mountWrapper(this, props, nativeParent);
410
- props = ReactDOMOption.getNativeProps(this, props);
444
+ ReactDOMOption.mountWrapper(this, props, hostParent);
445
+ props = ReactDOMOption.getHostProps(this, props);
411
446
  break;
412
447
  case 'select':
413
- ReactDOMSelect.mountWrapper(this, props, nativeParent);
414
- props = ReactDOMSelect.getNativeProps(this, props);
448
+ ReactDOMSelect.mountWrapper(this, props, hostParent);
449
+ props = ReactDOMSelect.getHostProps(this, props);
415
450
  transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
416
451
  break;
417
452
  case 'textarea':
418
- ReactDOMTextarea.mountWrapper(this, props, nativeParent);
419
- props = ReactDOMTextarea.getNativeProps(this, props);
453
+ ReactDOMTextarea.mountWrapper(this, props, hostParent);
454
+ props = ReactDOMTextarea.getHostProps(this, props);
420
455
  transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
421
456
  break;
422
457
  }
@@ -427,12 +462,12 @@ ReactDOMComponent.Mixin = {
427
462
  // tags get no namespace.
428
463
  var namespaceURI;
429
464
  var parentTag;
430
- if (nativeParent != null) {
431
- namespaceURI = nativeParent._namespaceURI;
432
- parentTag = nativeParent._tag;
433
- } else if (nativeContainerInfo._tag) {
434
- namespaceURI = nativeContainerInfo._namespaceURI;
435
- 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;
436
471
  }
437
472
  if (namespaceURI == null || namespaceURI === DOMNamespaces.svg && parentTag === 'foreignobject') {
438
473
  namespaceURI = DOMNamespaces.html;
@@ -448,10 +483,10 @@ ReactDOMComponent.Mixin = {
448
483
 
449
484
  if (process.env.NODE_ENV !== 'production') {
450
485
  var parentInfo;
451
- if (nativeParent != null) {
452
- parentInfo = nativeParent._ancestorInfo;
453
- } else if (nativeContainerInfo._tag) {
454
- parentInfo = nativeContainerInfo._ancestorInfo;
486
+ if (hostParent != null) {
487
+ parentInfo = hostParent._ancestorInfo;
488
+ } else if (hostContainerInfo._tag) {
489
+ parentInfo = hostContainerInfo._ancestorInfo;
455
490
  }
456
491
  if (parentInfo) {
457
492
  // parentInfo should always be present except for the top-level
@@ -463,7 +498,7 @@ ReactDOMComponent.Mixin = {
463
498
 
464
499
  var mountImage;
465
500
  if (transaction.useCreateElement) {
466
- var ownerDocument = nativeContainerInfo._ownerDocument;
501
+ var ownerDocument = hostContainerInfo._ownerDocument;
467
502
  var el;
468
503
  if (namespaceURI === DOMNamespaces.html) {
469
504
  if (this._tag === 'script') {
@@ -473,15 +508,20 @@ ReactDOMComponent.Mixin = {
473
508
  var type = this._currentElement.type;
474
509
  div.innerHTML = '<' + type + '></' + type + '>';
475
510
  el = div.removeChild(div.firstChild);
511
+ } else if (props.is) {
512
+ el = ownerDocument.createElement(this._currentElement.type, props.is);
476
513
  } else {
477
- el = ownerDocument.createElement(this._currentElement.type, props.is || null);
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
517
+ el = ownerDocument.createElement(this._currentElement.type);
478
518
  }
479
519
  } else {
480
520
  el = ownerDocument.createElementNS(namespaceURI, this._currentElement.type);
481
521
  }
482
522
  ReactDOMComponentTree.precacheNode(this, el);
483
523
  this._flags |= Flags.hasCachedChildNodes;
484
- if (!this._nativeParent) {
524
+ if (!this._hostParent) {
485
525
  DOMPropertyOperations.setAttributeForRoot(el);
486
526
  }
487
527
  this._updateDOMProperties(null, props, transaction);
@@ -499,16 +539,31 @@ ReactDOMComponent.Mixin = {
499
539
  }
500
540
 
501
541
  switch (this._tag) {
502
- case 'button':
503
542
  case 'input':
504
- case 'select':
543
+ transaction.getReactMountReady().enqueue(inputPostMount, this);
544
+ if (props.autoFocus) {
545
+ transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this);
546
+ }
547
+ break;
505
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':
506
560
  if (props.autoFocus) {
507
561
  transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this);
508
562
  }
509
563
  break;
510
564
  case 'option':
511
565
  transaction.getReactMountReady().enqueue(optionPostMount, this);
566
+ break;
512
567
  }
513
568
 
514
569
  return mountImage;
@@ -573,7 +628,7 @@ ReactDOMComponent.Mixin = {
573
628
  return ret;
574
629
  }
575
630
 
576
- if (!this._nativeParent) {
631
+ if (!this._hostParent) {
577
632
  ret += ' ' + DOMPropertyOperations.createMarkupForRoot();
578
633
  }
579
634
  ret += ' ' + DOMPropertyOperations.createMarkupForID(this._domID);
@@ -669,7 +724,7 @@ ReactDOMComponent.Mixin = {
669
724
  },
670
725
 
671
726
  /**
672
- * Updates a native DOM component after it has already been allocated and
727
+ * Updates a DOM component after it has already been allocated and
673
728
  * attached to the DOM. Reconciles the root DOM node, then recurses.
674
729
  *
675
730
  * @param {ReactReconcileTransaction} transaction
@@ -684,26 +739,26 @@ ReactDOMComponent.Mixin = {
684
739
 
685
740
  switch (this._tag) {
686
741
  case 'button':
687
- lastProps = ReactDOMButton.getNativeProps(this, lastProps);
688
- nextProps = ReactDOMButton.getNativeProps(this, nextProps);
742
+ lastProps = ReactDOMButton.getHostProps(this, lastProps);
743
+ nextProps = ReactDOMButton.getHostProps(this, nextProps);
689
744
  break;
690
745
  case 'input':
691
746
  ReactDOMInput.updateWrapper(this);
692
- lastProps = ReactDOMInput.getNativeProps(this, lastProps);
693
- nextProps = ReactDOMInput.getNativeProps(this, nextProps);
747
+ lastProps = ReactDOMInput.getHostProps(this, lastProps);
748
+ nextProps = ReactDOMInput.getHostProps(this, nextProps);
694
749
  break;
695
750
  case 'option':
696
- lastProps = ReactDOMOption.getNativeProps(this, lastProps);
697
- nextProps = ReactDOMOption.getNativeProps(this, nextProps);
751
+ lastProps = ReactDOMOption.getHostProps(this, lastProps);
752
+ nextProps = ReactDOMOption.getHostProps(this, nextProps);
698
753
  break;
699
754
  case 'select':
700
- lastProps = ReactDOMSelect.getNativeProps(this, lastProps);
701
- nextProps = ReactDOMSelect.getNativeProps(this, nextProps);
755
+ lastProps = ReactDOMSelect.getHostProps(this, lastProps);
756
+ nextProps = ReactDOMSelect.getHostProps(this, nextProps);
702
757
  break;
703
758
  case 'textarea':
704
759
  ReactDOMTextarea.updateWrapper(this);
705
- lastProps = ReactDOMTextarea.getNativeProps(this, lastProps);
706
- nextProps = ReactDOMTextarea.getNativeProps(this, nextProps);
760
+ lastProps = ReactDOMTextarea.getHostProps(this, lastProps);
761
+ nextProps = ReactDOMTextarea.getHostProps(this, nextProps);
707
762
  break;
708
763
  }
709
764
 
@@ -758,6 +813,10 @@ ReactDOMComponent.Mixin = {
758
813
  // listener (e.g., onClick={null})
759
814
  deleteListener(this, propKey);
760
815
  }
816
+ } else if (isCustomComponent(this._tag, lastProps)) {
817
+ if (!RESERVED_PROPS.hasOwnProperty(propKey)) {
818
+ DOMPropertyOperations.deleteValueForAttribute(getNode(this), propKey);
819
+ }
761
820
  } else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {
762
821
  DOMPropertyOperations.deleteValueForProperty(getNode(this), propKey);
763
822
  }
@@ -861,7 +920,6 @@ ReactDOMComponent.Mixin = {
861
920
  if (lastContent !== nextContent) {
862
921
  this.updateTextContent('' + nextContent);
863
922
  if (process.env.NODE_ENV !== 'production') {
864
- this._contentDebugID = this._debugID + '#text';
865
923
  setContentChildForInstrumentation.call(this, nextContent);
866
924
  }
867
925
  }
@@ -874,17 +932,14 @@ ReactDOMComponent.Mixin = {
874
932
  }
875
933
  } else if (nextChildren != null) {
876
934
  if (process.env.NODE_ENV !== 'production') {
877
- if (this._contentDebugID) {
878
- ReactInstrumentation.debugTool.onUnmountComponent(this._contentDebugID);
879
- this._contentDebugID = null;
880
- }
935
+ setContentChildForInstrumentation.call(this, null);
881
936
  }
882
937
 
883
938
  this.updateChildren(nextChildren, transaction, context);
884
939
  }
885
940
  },
886
941
 
887
- getNativeNode: function () {
942
+ getHostNode: function () {
888
943
  return getNode(this);
889
944
  },
890
945
 
@@ -896,12 +951,14 @@ ReactDOMComponent.Mixin = {
896
951
  */
897
952
  unmountComponent: function (safely) {
898
953
  switch (this._tag) {
954
+ case 'audio':
955
+ case 'form':
899
956
  case 'iframe':
900
- case 'object':
901
957
  case 'img':
902
- case 'form':
958
+ case 'link':
959
+ case 'object':
960
+ case 'source':
903
961
  case 'video':
904
- case 'audio':
905
962
  var listeners = this._wrapperState.listeners;
906
963
  if (listeners) {
907
964
  for (var i = 0; i < listeners.length; i++) {
@@ -918,7 +975,7 @@ ReactDOMComponent.Mixin = {
918
975
  * take advantage of React's reconciliation for styling and <title>
919
976
  * management. So we just document it and throw in dangerous cases.
920
977
  */
921
- !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;
922
979
  break;
923
980
  }
924
981
 
@@ -931,10 +988,7 @@ ReactDOMComponent.Mixin = {
931
988
  this._wrapperState = null;
932
989
 
933
990
  if (process.env.NODE_ENV !== 'production') {
934
- if (this._contentDebugID) {
935
- ReactInstrumentation.debugTool.onUnmountComponent(this._contentDebugID);
936
- this._contentDebugID = null;
937
- }
991
+ setContentChildForInstrumentation.call(this, null);
938
992
  }
939
993
  },
940
994