react 0.12.0 → 0.13.0-alpha.2

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 (153) hide show
  1. package/dist/JSXTransformer.js +2345 -910
  2. package/dist/react-with-addons.js +5273 -4111
  3. package/dist/react-with-addons.min.js +5 -6
  4. package/dist/react.js +4840 -3940
  5. package/dist/react.min.js +5 -6
  6. package/lib/AutoFocusMixin.js +1 -1
  7. package/lib/BeforeInputEventPlugin.js +389 -112
  8. package/lib/CSSProperty.js +6 -3
  9. package/lib/CSSPropertyOperations.js +21 -1
  10. package/lib/CallbackQueue.js +2 -2
  11. package/lib/ChangeEventPlugin.js +3 -3
  12. package/lib/ClientReactRootIndex.js +1 -1
  13. package/lib/DOMChildrenOperations.js +6 -4
  14. package/lib/DOMProperty.js +1 -1
  15. package/lib/DOMPropertyOperations.js +1 -1
  16. package/lib/Danger.js +7 -6
  17. package/lib/DefaultEventPluginOrder.js +1 -2
  18. package/lib/EnterLeaveEventPlugin.js +1 -1
  19. package/lib/EventConstants.js +1 -1
  20. package/lib/EventPluginHub.js +9 -7
  21. package/lib/EventPluginRegistry.js +1 -1
  22. package/lib/EventPluginUtils.js +1 -1
  23. package/lib/EventPropagators.js +1 -1
  24. package/lib/ExecutionEnvironment.js +2 -3
  25. package/lib/FallbackCompositionState.js +89 -0
  26. package/lib/HTMLDOMPropertyConfig.js +19 -7
  27. package/lib/LinkedStateMixin.js +1 -1
  28. package/lib/LinkedValueUtils.js +3 -3
  29. package/lib/LocalEventTrapMixin.js +1 -1
  30. package/lib/MobileSafariClickEventPlugin.js +1 -1
  31. package/lib/Object.assign.js +3 -1
  32. package/lib/PooledClass.js +1 -1
  33. package/lib/React.js +17 -50
  34. package/lib/ReactBrowserComponentMixin.js +3 -13
  35. package/lib/ReactBrowserEventEmitter.js +4 -6
  36. package/lib/ReactCSSTransitionGroup.js +4 -1
  37. package/lib/ReactCSSTransitionGroupChild.js +12 -2
  38. package/lib/ReactChildReconciler.js +121 -0
  39. package/lib/ReactChildren.js +10 -8
  40. package/lib/ReactClass.js +874 -0
  41. package/lib/ReactComponent.js +45 -286
  42. package/lib/ReactComponentBase.js +126 -0
  43. package/lib/ReactComponentBrowserEnvironment.js +10 -83
  44. package/lib/ReactComponentEnvironment.js +57 -0
  45. package/lib/ReactComponentWithPureRenderMixin.js +1 -1
  46. package/lib/ReactCompositeComponent.js +700 -1045
  47. package/lib/ReactContext.js +6 -2
  48. package/lib/ReactCurrentOwner.js +1 -1
  49. package/lib/ReactDOM.js +3 -8
  50. package/lib/ReactDOMButton.js +5 -6
  51. package/lib/ReactDOMComponent.js +120 -77
  52. package/lib/ReactDOMForm.js +5 -6
  53. package/lib/ReactDOMIDOperations.js +56 -74
  54. package/lib/ReactDOMImg.js +4 -6
  55. package/lib/ReactDOMInput.js +5 -6
  56. package/lib/ReactDOMOption.js +5 -6
  57. package/lib/ReactDOMSelect.js +57 -65
  58. package/lib/ReactDOMSelection.js +6 -2
  59. package/lib/ReactDOMTextComponent.js +124 -0
  60. package/lib/ReactDOMTextarea.js +5 -6
  61. package/lib/ReactDefaultBatchingStrategy.js +1 -1
  62. package/lib/ReactDefaultInjection.js +14 -8
  63. package/lib/ReactDefaultPerf.js +8 -7
  64. package/lib/ReactDefaultPerfAnalysis.js +1 -1
  65. package/lib/ReactElement.js +22 -15
  66. package/lib/ReactElementValidator.js +192 -53
  67. package/lib/ReactEmptyComponent.js +29 -11
  68. package/lib/ReactEventEmitterMixin.js +1 -1
  69. package/lib/ReactEventListener.js +3 -3
  70. package/lib/ReactInjection.js +7 -5
  71. package/lib/ReactInputSelection.js +3 -4
  72. package/lib/ReactInstanceHandles.js +3 -2
  73. package/lib/ReactInstanceMap.js +47 -0
  74. package/lib/ReactLink.js +1 -1
  75. package/lib/ReactMarkupChecksum.js +1 -1
  76. package/lib/ReactMount.js +202 -66
  77. package/lib/ReactMultiChild.js +44 -45
  78. package/lib/ReactMultiChildUpdateTypes.js +1 -1
  79. package/lib/ReactNativeComponent.js +47 -10
  80. package/lib/ReactOwner.js +4 -48
  81. package/lib/ReactPerf.js +21 -1
  82. package/lib/ReactPropTransferer.js +2 -57
  83. package/lib/ReactPropTypeLocationNames.js +1 -1
  84. package/lib/ReactPropTypeLocations.js +1 -1
  85. package/lib/ReactPropTypes.js +14 -22
  86. package/lib/ReactPutListenerQueue.js +1 -1
  87. package/lib/ReactReconcileTransaction.js +1 -1
  88. package/lib/ReactRef.js +96 -0
  89. package/lib/ReactRootIndex.js +1 -1
  90. package/lib/ReactServerRendering.js +5 -3
  91. package/lib/ReactServerRenderingTransaction.js +1 -1
  92. package/lib/ReactStateSetters.js +1 -1
  93. package/lib/ReactTestUtils.js +83 -26
  94. package/lib/ReactTransitionChildMapping.js +1 -1
  95. package/lib/ReactTransitionEvents.js +1 -1
  96. package/lib/ReactTransitionGroup.js +48 -7
  97. package/lib/ReactUpdates.js +46 -45
  98. package/lib/ReactWithAddons.js +1 -1
  99. package/lib/SVGDOMPropertyConfig.js +1 -1
  100. package/lib/SelectEventPlugin.js +3 -3
  101. package/lib/ServerReactRootIndex.js +1 -1
  102. package/lib/SimpleEventPlugin.js +1 -1
  103. package/lib/SyntheticClipboardEvent.js +1 -2
  104. package/lib/SyntheticCompositionEvent.js +1 -2
  105. package/lib/SyntheticDragEvent.js +1 -1
  106. package/lib/SyntheticEvent.js +11 -3
  107. package/lib/SyntheticFocusEvent.js +1 -1
  108. package/lib/SyntheticInputEvent.js +1 -2
  109. package/lib/SyntheticKeyboardEvent.js +1 -1
  110. package/lib/SyntheticMouseEvent.js +2 -4
  111. package/lib/SyntheticTouchEvent.js +1 -1
  112. package/lib/SyntheticUIEvent.js +1 -1
  113. package/lib/SyntheticWheelEvent.js +1 -1
  114. package/lib/Transaction.js +3 -3
  115. package/lib/ViewportMetrics.js +2 -5
  116. package/lib/accumulate.js +47 -0
  117. package/lib/accumulateInto.js +1 -1
  118. package/lib/adler32.js +1 -1
  119. package/lib/cloneWithProps.js +3 -3
  120. package/lib/copyProperties.js +2 -0
  121. package/lib/createFullPageComponent.js +3 -3
  122. package/lib/dangerousStyleValue.js +1 -1
  123. package/lib/escapeTextForBrowser.js +6 -6
  124. package/lib/findDOMNode.js +51 -0
  125. package/lib/flattenChildren.js +11 -22
  126. package/lib/forEachAccumulated.js +1 -1
  127. package/lib/getEventCharCode.js +1 -1
  128. package/lib/getEventKey.js +1 -1
  129. package/lib/getEventModifierState.js +1 -1
  130. package/lib/getEventTarget.js +1 -1
  131. package/lib/getIteratorFn.js +42 -0
  132. package/lib/getNodeForCharacterOffset.js +2 -2
  133. package/lib/getReactRootElementInContainer.js +1 -1
  134. package/lib/getTextContentAccessor.js +1 -1
  135. package/lib/instantiateReactComponent.js +89 -66
  136. package/lib/isEventSupported.js +1 -1
  137. package/lib/isNode.js +3 -4
  138. package/lib/isTextInputElement.js +2 -3
  139. package/lib/joinClasses.js +1 -1
  140. package/lib/keyMirror.js +1 -1
  141. package/lib/memoizeStringOnly.js +4 -5
  142. package/lib/onlyChild.js +1 -1
  143. package/lib/setInnerHTML.js +12 -1
  144. package/lib/shallowEqual.js +1 -1
  145. package/lib/shouldUpdateReactComponent.js +48 -6
  146. package/lib/traverseAllChildren.js +111 -55
  147. package/lib/update.js +1 -1
  148. package/lib/warning.js +9 -2
  149. package/package.json +1 -1
  150. package/lib/CompositionEventPlugin.js +0 -257
  151. package/lib/ReactLegacyElement.js +0 -243
  152. package/lib/ReactTextComponent.js +0 -104
  153. package/lib/deprecated.js +0 -47
@@ -9,9 +9,11 @@
9
9
  * @providesModule ReactContext
10
10
  */
11
11
 
12
- "use strict";
12
+ 'use strict';
13
13
 
14
14
  var assign = require("./Object.assign");
15
+ var emptyObject = require("./emptyObject");
16
+ var monitorCodeUse = require("./monitorCodeUse");
15
17
 
16
18
  /**
17
19
  * Keeps track of the current context.
@@ -25,7 +27,7 @@ var ReactContext = {
25
27
  * @internal
26
28
  * @type {object}
27
29
  */
28
- current: {},
30
+ current: emptyObject,
29
31
 
30
32
  /**
31
33
  * Temporarily extends the current context while executing scopedCallback.
@@ -44,6 +46,8 @@ var ReactContext = {
44
46
  * @return {ReactComponent|array<ReactComponent>}
45
47
  */
46
48
  withContext: function(newContext, scopedCallback) {
49
+ monitorCodeUse('react_with_context', {newContext: newContext});
50
+
47
51
  var result;
48
52
  var previousContext = ReactContext.current;
49
53
  ReactContext.current = assign({}, previousContext, newContext);
@@ -9,7 +9,7 @@
9
9
  * @providesModule ReactCurrentOwner
10
10
  */
11
11
 
12
- "use strict";
12
+ 'use strict';
13
13
 
14
14
  /**
15
15
  * Keeps track of the current owner.
package/lib/ReactDOM.js CHANGED
@@ -10,11 +10,10 @@
10
10
  * @typechecks static-only
11
11
  */
12
12
 
13
- "use strict";
13
+ 'use strict';
14
14
 
15
15
  var ReactElement = require("./ReactElement");
16
16
  var ReactElementValidator = require("./ReactElementValidator");
17
- var ReactLegacyElement = require("./ReactLegacyElement");
18
17
 
19
18
  var mapObject = require("./mapObject");
20
19
 
@@ -26,13 +25,9 @@ var mapObject = require("./mapObject");
26
25
  */
27
26
  function createDOMFactory(tag) {
28
27
  if ("production" !== process.env.NODE_ENV) {
29
- return ReactLegacyElement.markNonLegacyFactory(
30
- ReactElementValidator.createFactory(tag)
31
- );
28
+ return ReactElementValidator.createFactory(tag);
32
29
  }
33
- return ReactLegacyElement.markNonLegacyFactory(
34
- ReactElement.createFactory(tag)
35
- );
30
+ return ReactElement.createFactory(tag);
36
31
  }
37
32
 
38
33
  /**
@@ -9,18 +9,16 @@
9
9
  * @providesModule ReactDOMButton
10
10
  */
11
11
 
12
- "use strict";
12
+ 'use strict';
13
13
 
14
14
  var AutoFocusMixin = require("./AutoFocusMixin");
15
15
  var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
16
- var ReactCompositeComponent = require("./ReactCompositeComponent");
16
+ var ReactClass = require("./ReactClass");
17
17
  var ReactElement = require("./ReactElement");
18
- var ReactDOM = require("./ReactDOM");
19
18
 
20
19
  var keyMirror = require("./keyMirror");
21
20
 
22
- // Store a reference to the <button> `ReactDOMComponent`. TODO: use string
23
- var button = ReactElement.createFactory(ReactDOM.button.type);
21
+ var button = ReactElement.createFactory('button');
24
22
 
25
23
  var mouseListenerNames = keyMirror({
26
24
  onClick: true,
@@ -39,8 +37,9 @@ var mouseListenerNames = keyMirror({
39
37
  * Implements a <button> native component that does not receive mouse events
40
38
  * when `disabled` is set.
41
39
  */
42
- var ReactDOMButton = ReactCompositeComponent.createClass({
40
+ var ReactDOMButton = ReactClass.createClass({
43
41
  displayName: 'ReactDOMButton',
42
+ tagName: 'BUTTON',
44
43
 
45
44
  mixins: [AutoFocusMixin, ReactBrowserComponentMixin],
46
45
 
@@ -10,12 +10,13 @@
10
10
  * @typechecks static-only
11
11
  */
12
12
 
13
- "use strict";
13
+ /* global hasOwnProperty:true */
14
+
15
+ 'use strict';
14
16
 
15
17
  var CSSPropertyOperations = require("./CSSPropertyOperations");
16
18
  var DOMProperty = require("./DOMProperty");
17
19
  var DOMPropertyOperations = require("./DOMPropertyOperations");
18
- var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
19
20
  var ReactComponent = require("./ReactComponent");
20
21
  var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
21
22
  var ReactMount = require("./ReactMount");
@@ -28,6 +29,7 @@ var invariant = require("./invariant");
28
29
  var isEventSupported = require("./isEventSupported");
29
30
  var keyOf = require("./keyOf");
30
31
  var monitorCodeUse = require("./monitorCodeUse");
32
+ var warning = require("./warning");
31
33
 
32
34
  var deleteListener = ReactBrowserEventEmitter.deleteListener;
33
35
  var listenTo = ReactBrowserEventEmitter.listenTo;
@@ -40,6 +42,11 @@ var STYLE = keyOf({style: null});
40
42
 
41
43
  var ELEMENT_NODE_TYPE = 1;
42
44
 
45
+ /**
46
+ * Optionally injectable operations for mutating the DOM
47
+ */
48
+ var BackendIDOperations = null;
49
+
43
50
  /**
44
51
  * @param {?object} props
45
52
  */
@@ -48,24 +55,37 @@ function assertValidProps(props) {
48
55
  return;
49
56
  }
50
57
  // Note the use of `==` which checks for null or undefined.
51
- ("production" !== process.env.NODE_ENV ? invariant(
52
- props.children == null || props.dangerouslySetInnerHTML == null,
53
- 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'
54
- ) : invariant(props.children == null || props.dangerouslySetInnerHTML == null));
58
+ if (props.dangerouslySetInnerHTML != null) {
59
+ ("production" !== process.env.NODE_ENV ? invariant(
60
+ props.children == null,
61
+ 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'
62
+ ) : invariant(props.children == null));
63
+ ("production" !== process.env.NODE_ENV ? invariant(
64
+ props.dangerouslySetInnerHTML.__html != null,
65
+ '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' +
66
+ 'For more information, lookup documentation on `dangerouslySetInnerHTML`.'
67
+ ) : invariant(props.dangerouslySetInnerHTML.__html != null));
68
+ }
55
69
  if ("production" !== process.env.NODE_ENV) {
70
+ ("production" !== process.env.NODE_ENV ? warning(
71
+ props.innerHTML == null,
72
+ 'Directly setting property `innerHTML` is not permitted. ' +
73
+ 'For more information, lookup documentation on `dangerouslySetInnerHTML`.'
74
+ ) : null);
56
75
  if (props.contentEditable && props.children != null) {
57
76
  console.warn(
58
77
  'A component is `contentEditable` and contains `children` managed by ' +
59
- 'React. It is now your responsibility to guarantee that none of those '+
60
- 'nodes are unexpectedly modified or duplicated. This is probably not ' +
61
- 'intentional.'
78
+ 'React. It is now your responsibility to guarantee that none of ' +
79
+ 'those nodes are unexpectedly modified or duplicated. This is ' +
80
+ 'probably not intentional.'
62
81
  );
63
82
  }
64
83
  }
65
84
  ("production" !== process.env.NODE_ENV ? invariant(
66
85
  props.style == null || typeof props.style === 'object',
67
86
  'The `style` prop expects a mapping from style properties to values, ' +
68
- 'not a string.'
87
+ 'not a string. For example, style={{marginRight: spacing + \'em\'}} when ' +
88
+ 'using JSX.'
69
89
  ) : invariant(props.style == null || typeof props.style === 'object'));
70
90
  }
71
91
 
@@ -148,7 +168,9 @@ function validateDangerousTag(tag) {
148
168
  function ReactDOMComponent(tag) {
149
169
  validateDangerousTag(tag);
150
170
  this._tag = tag;
151
- this.tagName = tag.toUpperCase();
171
+ this._renderedChildren = null;
172
+ this._previousStyleCopy = null;
173
+ this._rootNodeID = null;
152
174
  }
153
175
 
154
176
  ReactDOMComponent.displayName = 'ReactDOMComponent';
@@ -162,28 +184,24 @@ ReactDOMComponent.Mixin = {
162
184
  * @internal
163
185
  * @param {string} rootID The root DOM ID for this node.
164
186
  * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
165
- * @param {number} mountDepth number of components in the owner hierarchy
166
187
  * @return {string} The computed markup.
167
188
  */
168
- mountComponent: ReactPerf.measure(
169
- 'ReactDOMComponent',
170
- 'mountComponent',
171
- function(rootID, transaction, mountDepth) {
172
- ReactComponent.Mixin.mountComponent.call(
173
- this,
174
- rootID,
175
- transaction,
176
- mountDepth
177
- );
178
- assertValidProps(this.props);
179
- var closeTag = omittedCloseTags[this._tag] ? '' : '</' + this._tag + '>';
180
- return (
181
- this._createOpenTagMarkupAndPutListeners(transaction) +
182
- this._createContentMarkup(transaction) +
183
- closeTag
184
- );
185
- }
186
- ),
189
+ mountComponent: function(rootID, transaction, context) {
190
+ ReactComponent.Mixin.mountComponent.call(
191
+ this,
192
+ rootID,
193
+ transaction,
194
+ context
195
+ );
196
+ this._rootNodeID = rootID;
197
+ assertValidProps(this._currentElement.props);
198
+ var closeTag = omittedCloseTags[this._tag] ? '' : '</' + this._tag + '>';
199
+ return (
200
+ this._createOpenTagMarkupAndPutListeners(transaction) +
201
+ this._createContentMarkup(transaction, context) +
202
+ closeTag
203
+ );
204
+ },
187
205
 
188
206
  /**
189
207
  * Creates markup for the open tag and all attributes.
@@ -198,7 +216,7 @@ ReactDOMComponent.Mixin = {
198
216
  * @return {string} Markup of opening tag.
199
217
  */
200
218
  _createOpenTagMarkupAndPutListeners: function(transaction) {
201
- var props = this.props;
219
+ var props = this._currentElement.props;
202
220
  var ret = '<' + this._tag;
203
221
 
204
222
  for (var propKey in props) {
@@ -214,7 +232,7 @@ ReactDOMComponent.Mixin = {
214
232
  } else {
215
233
  if (propKey === STYLE) {
216
234
  if (propValue) {
217
- propValue = props.style = assign({}, props.style);
235
+ propValue = this._previousStyleCopy = assign({}, props.style);
218
236
  }
219
237
  propValue = CSSPropertyOperations.createMarkupForStyles(propValue);
220
238
  }
@@ -241,33 +259,47 @@ ReactDOMComponent.Mixin = {
241
259
  *
242
260
  * @private
243
261
  * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
262
+ * @param {object} context
244
263
  * @return {string} Content markup.
245
264
  */
246
- _createContentMarkup: function(transaction) {
265
+ _createContentMarkup: function(transaction, context) {
266
+ var prefix = '';
267
+ if (this._tag === 'listing' ||
268
+ this._tag === 'pre' ||
269
+ this._tag === 'textarea') {
270
+ // Add an initial newline because browsers ignore the first newline in
271
+ // a <listing>, <pre>, or <textarea> as an "authoring convenience" -- see
272
+ // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody.
273
+ prefix = '\n';
274
+ }
275
+
276
+ var props = this._currentElement.props;
277
+
247
278
  // Intentional use of != to avoid catching zero/false.
248
- var innerHTML = this.props.dangerouslySetInnerHTML;
279
+ var innerHTML = props.dangerouslySetInnerHTML;
249
280
  if (innerHTML != null) {
250
281
  if (innerHTML.__html != null) {
251
- return innerHTML.__html;
282
+ return prefix + innerHTML.__html;
252
283
  }
253
284
  } else {
254
285
  var contentToUse =
255
- CONTENT_TYPES[typeof this.props.children] ? this.props.children : null;
256
- var childrenToUse = contentToUse != null ? null : this.props.children;
286
+ CONTENT_TYPES[typeof props.children] ? props.children : null;
287
+ var childrenToUse = contentToUse != null ? null : props.children;
257
288
  if (contentToUse != null) {
258
- return escapeTextForBrowser(contentToUse);
289
+ return prefix + escapeTextForBrowser(contentToUse);
259
290
  } else if (childrenToUse != null) {
260
291
  var mountImages = this.mountChildren(
261
292
  childrenToUse,
262
- transaction
293
+ transaction,
294
+ context
263
295
  );
264
- return mountImages.join('');
296
+ return prefix + mountImages.join('');
265
297
  }
266
298
  }
267
- return '';
299
+ return prefix;
268
300
  },
269
301
 
270
- receiveComponent: function(nextElement, transaction) {
302
+ receiveComponent: function(nextElement, transaction, context) {
271
303
  if (nextElement === this._currentElement &&
272
304
  nextElement._owner != null) {
273
305
  // Since elements are immutable after the owner is rendered,
@@ -275,16 +307,14 @@ ReactDOMComponent.Mixin = {
275
307
  // superfluous reconcile. It's possible for state to be mutable but such
276
308
  // change should trigger an update of the owner which would recreate
277
309
  // the element. We explicitly check for the existence of an owner since
278
- // it's possible for a element created outside a composite to be
310
+ // it's possible for an element created outside a composite to be
279
311
  // deeply mutated and reused.
280
312
  return;
281
313
  }
282
314
 
283
- ReactComponent.Mixin.receiveComponent.call(
284
- this,
285
- nextElement,
286
- transaction
287
- );
315
+ var prevElement = this._currentElement;
316
+ this._currentElement = nextElement;
317
+ this.updateComponent(transaction, prevElement, nextElement, context);
288
318
  },
289
319
 
290
320
  /**
@@ -293,23 +323,22 @@ ReactDOMComponent.Mixin = {
293
323
  *
294
324
  * @param {ReactReconcileTransaction} transaction
295
325
  * @param {ReactElement} prevElement
326
+ * @param {ReactElement} nextElement
296
327
  * @internal
297
328
  * @overridable
298
329
  */
299
- updateComponent: ReactPerf.measure(
300
- 'ReactDOMComponent',
301
- 'updateComponent',
302
- function(transaction, prevElement) {
303
- assertValidProps(this._currentElement.props);
304
- ReactComponent.Mixin.updateComponent.call(
305
- this,
306
- transaction,
307
- prevElement
308
- );
309
- this._updateDOMProperties(prevElement.props, transaction);
310
- this._updateDOMChildren(prevElement.props, transaction);
311
- }
312
- ),
330
+ updateComponent: function(transaction, prevElement, nextElement, context) {
331
+ assertValidProps(this._currentElement.props);
332
+ ReactComponent.Mixin.updateComponent.call(
333
+ this,
334
+ transaction,
335
+ prevElement,
336
+ nextElement,
337
+ context
338
+ );
339
+ this._updateDOMProperties(prevElement.props, transaction);
340
+ this._updateDOMChildren(prevElement.props, transaction, context);
341
+ },
313
342
 
314
343
  /**
315
344
  * Reconciles the properties by detecting differences in property values and
@@ -327,7 +356,7 @@ ReactDOMComponent.Mixin = {
327
356
  * @param {ReactReconcileTransaction} transaction
328
357
  */
329
358
  _updateDOMProperties: function(lastProps, transaction) {
330
- var nextProps = this.props;
359
+ var nextProps = this._currentElement.props;
331
360
  var propKey;
332
361
  var styleName;
333
362
  var styleUpdates;
@@ -337,7 +366,7 @@ ReactDOMComponent.Mixin = {
337
366
  continue;
338
367
  }
339
368
  if (propKey === STYLE) {
340
- var lastStyle = lastProps[propKey];
369
+ var lastStyle = this._previousStyleCopy;
341
370
  for (styleName in lastStyle) {
342
371
  if (lastStyle.hasOwnProperty(styleName)) {
343
372
  styleUpdates = styleUpdates || {};
@@ -349,7 +378,7 @@ ReactDOMComponent.Mixin = {
349
378
  } else if (
350
379
  DOMProperty.isStandardName[propKey] ||
351
380
  DOMProperty.isCustomAttribute(propKey)) {
352
- ReactComponent.BackendIDOperations.deletePropertyByID(
381
+ BackendIDOperations.deletePropertyByID(
353
382
  this._rootNodeID,
354
383
  propKey
355
384
  );
@@ -357,13 +386,15 @@ ReactDOMComponent.Mixin = {
357
386
  }
358
387
  for (propKey in nextProps) {
359
388
  var nextProp = nextProps[propKey];
360
- var lastProp = lastProps[propKey];
389
+ var lastProp = propKey === STYLE ?
390
+ this._previousStyleCopy :
391
+ lastProps[propKey];
361
392
  if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) {
362
393
  continue;
363
394
  }
364
395
  if (propKey === STYLE) {
365
396
  if (nextProp) {
366
- nextProp = nextProps.style = assign({}, nextProp);
397
+ nextProp = this._previousStyleCopy = assign({}, nextProp);
367
398
  }
368
399
  if (lastProp) {
369
400
  // Unset styles on `lastProp` but not on `nextProp`.
@@ -391,7 +422,7 @@ ReactDOMComponent.Mixin = {
391
422
  } else if (
392
423
  DOMProperty.isStandardName[propKey] ||
393
424
  DOMProperty.isCustomAttribute(propKey)) {
394
- ReactComponent.BackendIDOperations.updatePropertyByID(
425
+ BackendIDOperations.updatePropertyByID(
395
426
  this._rootNodeID,
396
427
  propKey,
397
428
  nextProp
@@ -399,7 +430,7 @@ ReactDOMComponent.Mixin = {
399
430
  }
400
431
  }
401
432
  if (styleUpdates) {
402
- ReactComponent.BackendIDOperations.updateStylesByID(
433
+ BackendIDOperations.updateStylesByID(
403
434
  this._rootNodeID,
404
435
  styleUpdates
405
436
  );
@@ -413,8 +444,8 @@ ReactDOMComponent.Mixin = {
413
444
  * @param {object} lastProps
414
445
  * @param {ReactReconcileTransaction} transaction
415
446
  */
416
- _updateDOMChildren: function(lastProps, transaction) {
417
- var nextProps = this.props;
447
+ _updateDOMChildren: function(lastProps, transaction, context) {
448
+ var nextProps = this._currentElement.props;
418
449
 
419
450
  var lastContent =
420
451
  CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null;
@@ -437,7 +468,7 @@ ReactDOMComponent.Mixin = {
437
468
  var lastHasContentOrHtml = lastContent != null || lastHtml != null;
438
469
  var nextHasContentOrHtml = nextContent != null || nextHtml != null;
439
470
  if (lastChildren != null && nextChildren == null) {
440
- this.updateChildren(null, transaction);
471
+ this.updateChildren(null, transaction, context);
441
472
  } else if (lastHasContentOrHtml && !nextHasContentOrHtml) {
442
473
  this.updateTextContent('');
443
474
  }
@@ -448,13 +479,13 @@ ReactDOMComponent.Mixin = {
448
479
  }
449
480
  } else if (nextHtml != null) {
450
481
  if (lastHtml !== nextHtml) {
451
- ReactComponent.BackendIDOperations.updateInnerHTMLByID(
482
+ BackendIDOperations.updateInnerHTMLByID(
452
483
  this._rootNodeID,
453
484
  nextHtml
454
485
  );
455
486
  }
456
487
  } else if (nextChildren != null) {
457
- this.updateChildren(nextChildren, transaction);
488
+ this.updateChildren(nextChildren, transaction, context);
458
489
  }
459
490
  },
460
491
 
@@ -468,16 +499,28 @@ ReactDOMComponent.Mixin = {
468
499
  this.unmountChildren();
469
500
  ReactBrowserEventEmitter.deleteAllListeners(this._rootNodeID);
470
501
  ReactComponent.Mixin.unmountComponent.call(this);
502
+ ReactMount.purgeID(this._rootNodeID);
503
+ this._rootNodeID = null;
471
504
  }
472
505
 
473
506
  };
474
507
 
508
+ ReactPerf.measureMethods(ReactDOMComponent, 'ReactDOMComponent', {
509
+ mountComponent: 'mountComponent',
510
+ updateComponent: 'updateComponent'
511
+ });
512
+
475
513
  assign(
476
514
  ReactDOMComponent.prototype,
477
515
  ReactComponent.Mixin,
478
516
  ReactDOMComponent.Mixin,
479
- ReactMultiChild.Mixin,
480
- ReactBrowserComponentMixin
517
+ ReactMultiChild.Mixin
481
518
  );
482
519
 
520
+ ReactDOMComponent.injection = {
521
+ injectIDOperations: function(IDOperations) {
522
+ ReactDOMComponent.BackendIDOperations = BackendIDOperations = IDOperations;
523
+ }
524
+ };
525
+
483
526
  module.exports = ReactDOMComponent;