react 0.12.1 → 0.13.0-beta.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 (153) hide show
  1. package/dist/JSXTransformer.js +352 -251
  2. package/dist/react-with-addons.js +5409 -4242
  3. package/dist/react-with-addons.min.js +5 -6
  4. package/dist/react.js +5012 -4136
  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 +57 -10
  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 +4 -2
  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 +9 -2
  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 -51
  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 +125 -0
  39. package/lib/ReactChildren.js +10 -8
  40. package/lib/ReactClass.js +916 -0
  41. package/lib/ReactComponent.js +81 -404
  42. package/lib/ReactComponentBrowserEnvironment.js +10 -83
  43. package/lib/ReactComponentEnvironment.js +57 -0
  44. package/lib/ReactComponentWithPureRenderMixin.js +1 -1
  45. package/lib/ReactCompositeComponent.js +533 -1132
  46. package/lib/ReactContext.js +6 -2
  47. package/lib/ReactCurrentOwner.js +1 -1
  48. package/lib/ReactDOM.js +3 -8
  49. package/lib/ReactDOMButton.js +5 -6
  50. package/lib/ReactDOMComponent.js +110 -92
  51. package/lib/ReactDOMForm.js +5 -6
  52. package/lib/ReactDOMIDOperations.js +56 -74
  53. package/lib/ReactDOMImg.js +4 -6
  54. package/lib/ReactDOMInput.js +5 -6
  55. package/lib/ReactDOMOption.js +5 -6
  56. package/lib/ReactDOMSelect.js +57 -65
  57. package/lib/ReactDOMSelection.js +6 -2
  58. package/lib/{ReactTextComponent.js → ReactDOMTextComponent.js} +48 -35
  59. package/lib/ReactDOMTextarea.js +5 -6
  60. package/lib/ReactDefaultBatchingStrategy.js +4 -4
  61. package/lib/ReactDefaultInjection.js +14 -8
  62. package/lib/ReactDefaultPerf.js +16 -7
  63. package/lib/ReactDefaultPerfAnalysis.js +1 -1
  64. package/lib/ReactElement.js +23 -15
  65. package/lib/ReactElementValidator.js +209 -57
  66. package/lib/ReactEmptyComponent.js +29 -11
  67. package/lib/ReactEventEmitterMixin.js +1 -1
  68. package/lib/ReactEventListener.js +3 -4
  69. package/lib/ReactInjection.js +7 -5
  70. package/lib/ReactInputSelection.js +3 -4
  71. package/lib/ReactInstanceHandles.js +3 -2
  72. package/lib/ReactInstanceMap.js +47 -0
  73. package/lib/ReactLifeCycle.js +35 -0
  74. package/lib/ReactLink.js +1 -1
  75. package/lib/ReactMarkupChecksum.js +1 -1
  76. package/lib/ReactMount.js +239 -68
  77. package/lib/ReactMultiChild.js +49 -47
  78. package/lib/ReactMultiChildUpdateTypes.js +1 -1
  79. package/lib/ReactNativeComponent.js +72 -25
  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/ReactReconciler.js +107 -0
  89. package/lib/ReactRef.js +70 -0
  90. package/lib/ReactRootIndex.js +1 -1
  91. package/lib/ReactServerRendering.js +5 -3
  92. package/lib/ReactServerRenderingTransaction.js +1 -1
  93. package/lib/ReactStateSetters.js +1 -1
  94. package/lib/ReactTestUtils.js +112 -26
  95. package/lib/ReactTransitionChildMapping.js +1 -1
  96. package/lib/ReactTransitionEvents.js +1 -1
  97. package/lib/ReactTransitionGroup.js +48 -7
  98. package/lib/ReactUpdateQueue.js +264 -0
  99. package/lib/ReactUpdates.js +48 -61
  100. package/lib/ReactWithAddons.js +1 -1
  101. package/lib/SVGDOMPropertyConfig.js +1 -1
  102. package/lib/SelectEventPlugin.js +3 -3
  103. package/lib/ServerReactRootIndex.js +1 -1
  104. package/lib/SimpleEventPlugin.js +1 -1
  105. package/lib/SyntheticClipboardEvent.js +1 -2
  106. package/lib/SyntheticCompositionEvent.js +1 -2
  107. package/lib/SyntheticDragEvent.js +1 -1
  108. package/lib/SyntheticEvent.js +11 -3
  109. package/lib/SyntheticFocusEvent.js +1 -1
  110. package/lib/SyntheticInputEvent.js +1 -2
  111. package/lib/SyntheticKeyboardEvent.js +1 -1
  112. package/lib/SyntheticMouseEvent.js +2 -4
  113. package/lib/SyntheticTouchEvent.js +1 -1
  114. package/lib/SyntheticUIEvent.js +1 -1
  115. package/lib/SyntheticWheelEvent.js +1 -1
  116. package/lib/Transaction.js +3 -3
  117. package/lib/ViewportMetrics.js +2 -5
  118. package/lib/accumulateInto.js +1 -1
  119. package/lib/adler32.js +1 -1
  120. package/lib/cloneWithProps.js +3 -3
  121. package/lib/copyProperties.js +2 -0
  122. package/lib/createFullPageComponent.js +3 -3
  123. package/lib/dangerousStyleValue.js +1 -1
  124. package/lib/escapeTextForBrowser.js +6 -6
  125. package/lib/findDOMNode.js +51 -0
  126. package/lib/flattenChildren.js +11 -22
  127. package/lib/forEachAccumulated.js +1 -1
  128. package/lib/getEventCharCode.js +1 -1
  129. package/lib/getEventKey.js +1 -1
  130. package/lib/getEventModifierState.js +1 -1
  131. package/lib/getEventTarget.js +1 -1
  132. package/lib/getIteratorFn.js +42 -0
  133. package/lib/getNodeForCharacterOffset.js +2 -2
  134. package/lib/getReactRootElementInContainer.js +1 -1
  135. package/lib/getTextContentAccessor.js +1 -1
  136. package/lib/instantiateReactComponent.js +85 -67
  137. package/lib/isEventSupported.js +1 -1
  138. package/lib/isNode.js +3 -4
  139. package/lib/isTextInputElement.js +2 -3
  140. package/lib/joinClasses.js +1 -1
  141. package/lib/keyMirror.js +1 -1
  142. package/lib/memoizeStringOnly.js +4 -5
  143. package/lib/onlyChild.js +1 -1
  144. package/lib/setInnerHTML.js +12 -1
  145. package/lib/shallowEqual.js +1 -1
  146. package/lib/shouldUpdateReactComponent.js +48 -6
  147. package/lib/traverseAllChildren.js +111 -55
  148. package/lib/update.js +1 -1
  149. package/lib/warning.js +12 -1
  150. package/package.json +1 -1
  151. package/lib/CompositionEventPlugin.js +0 -257
  152. package/lib/ReactLegacyElement.js +0 -243
  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,13 +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
- var ReactComponent = require("./ReactComponent");
20
20
  var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
21
21
  var ReactMount = require("./ReactMount");
22
22
  var ReactMultiChild = require("./ReactMultiChild");
@@ -28,6 +28,7 @@ var invariant = require("./invariant");
28
28
  var isEventSupported = require("./isEventSupported");
29
29
  var keyOf = require("./keyOf");
30
30
  var monitorCodeUse = require("./monitorCodeUse");
31
+ var warning = require("./warning");
31
32
 
32
33
  var deleteListener = ReactBrowserEventEmitter.deleteListener;
33
34
  var listenTo = ReactBrowserEventEmitter.listenTo;
@@ -40,6 +41,11 @@ var STYLE = keyOf({style: null});
40
41
 
41
42
  var ELEMENT_NODE_TYPE = 1;
42
43
 
44
+ /**
45
+ * Optionally injectable operations for mutating the DOM
46
+ */
47
+ var BackendIDOperations = null;
48
+
43
49
  /**
44
50
  * @param {?object} props
45
51
  */
@@ -48,24 +54,37 @@ function assertValidProps(props) {
48
54
  return;
49
55
  }
50
56
  // 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));
57
+ if (props.dangerouslySetInnerHTML != null) {
58
+ ("production" !== process.env.NODE_ENV ? invariant(
59
+ props.children == null,
60
+ 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'
61
+ ) : invariant(props.children == null));
62
+ ("production" !== process.env.NODE_ENV ? invariant(
63
+ props.dangerouslySetInnerHTML.__html != null,
64
+ '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' +
65
+ 'Please visit http://fb.me/react-invariant-dangerously-set-inner-html for more information.'
66
+ ) : invariant(props.dangerouslySetInnerHTML.__html != null));
67
+ }
55
68
  if ("production" !== process.env.NODE_ENV) {
69
+ ("production" !== process.env.NODE_ENV ? warning(
70
+ props.innerHTML == null,
71
+ 'Directly setting property `innerHTML` is not permitted. ' +
72
+ 'For more information, lookup documentation on `dangerouslySetInnerHTML`.'
73
+ ) : null);
56
74
  if (props.contentEditable && props.children != null) {
57
75
  console.warn(
58
76
  '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.'
77
+ 'React. It is now your responsibility to guarantee that none of ' +
78
+ 'those nodes are unexpectedly modified or duplicated. This is ' +
79
+ 'probably not intentional.'
62
80
  );
63
81
  }
64
82
  }
65
83
  ("production" !== process.env.NODE_ENV ? invariant(
66
84
  props.style == null || typeof props.style === 'object',
67
85
  'The `style` prop expects a mapping from style properties to values, ' +
68
- 'not a string.'
86
+ 'not a string. For example, style={{marginRight: spacing + \'em\'}} when ' +
87
+ 'using JSX.'
69
88
  ) : invariant(props.style == null || typeof props.style === 'object'));
70
89
  }
71
90
 
@@ -142,19 +161,24 @@ function validateDangerousTag(tag) {
142
161
  * object mapping of style properties to values.
143
162
  *
144
163
  * @constructor ReactDOMComponent
145
- * @extends ReactComponent
146
164
  * @extends ReactMultiChild
147
165
  */
148
166
  function ReactDOMComponent(tag) {
149
167
  validateDangerousTag(tag);
150
168
  this._tag = tag;
151
- this.tagName = tag.toUpperCase();
169
+ this._renderedChildren = null;
170
+ this._previousStyleCopy = null;
171
+ this._rootNodeID = null;
152
172
  }
153
173
 
154
174
  ReactDOMComponent.displayName = 'ReactDOMComponent';
155
175
 
156
176
  ReactDOMComponent.Mixin = {
157
177
 
178
+ construct: function(element) {
179
+ this._currentElement = element;
180
+ },
181
+
158
182
  /**
159
183
  * Generates root tag markup then recurses. This method has side effects and
160
184
  * is not idempotent.
@@ -162,28 +186,18 @@ ReactDOMComponent.Mixin = {
162
186
  * @internal
163
187
  * @param {string} rootID The root DOM ID for this node.
164
188
  * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
165
- * @param {number} mountDepth number of components in the owner hierarchy
166
189
  * @return {string} The computed markup.
167
190
  */
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
- ),
191
+ mountComponent: function(rootID, transaction, context) {
192
+ this._rootNodeID = rootID;
193
+ assertValidProps(this._currentElement.props);
194
+ var closeTag = omittedCloseTags[this._tag] ? '' : '</' + this._tag + '>';
195
+ return (
196
+ this._createOpenTagMarkupAndPutListeners(transaction) +
197
+ this._createContentMarkup(transaction, context) +
198
+ closeTag
199
+ );
200
+ },
187
201
 
188
202
  /**
189
203
  * Creates markup for the open tag and all attributes.
@@ -198,7 +212,7 @@ ReactDOMComponent.Mixin = {
198
212
  * @return {string} Markup of opening tag.
199
213
  */
200
214
  _createOpenTagMarkupAndPutListeners: function(transaction) {
201
- var props = this.props;
215
+ var props = this._currentElement.props;
202
216
  var ret = '<' + this._tag;
203
217
 
204
218
  for (var propKey in props) {
@@ -214,7 +228,7 @@ ReactDOMComponent.Mixin = {
214
228
  } else {
215
229
  if (propKey === STYLE) {
216
230
  if (propValue) {
217
- propValue = props.style = assign({}, props.style);
231
+ propValue = this._previousStyleCopy = assign({}, props.style);
218
232
  }
219
233
  propValue = CSSPropertyOperations.createMarkupForStyles(propValue);
220
234
  }
@@ -241,50 +255,50 @@ ReactDOMComponent.Mixin = {
241
255
  *
242
256
  * @private
243
257
  * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
258
+ * @param {object} context
244
259
  * @return {string} Content markup.
245
260
  */
246
- _createContentMarkup: function(transaction) {
261
+ _createContentMarkup: function(transaction, context) {
262
+ var prefix = '';
263
+ if (this._tag === 'listing' ||
264
+ this._tag === 'pre' ||
265
+ this._tag === 'textarea') {
266
+ // Add an initial newline because browsers ignore the first newline in
267
+ // a <listing>, <pre>, or <textarea> as an "authoring convenience" -- see
268
+ // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody.
269
+ prefix = '\n';
270
+ }
271
+
272
+ var props = this._currentElement.props;
273
+
247
274
  // Intentional use of != to avoid catching zero/false.
248
- var innerHTML = this.props.dangerouslySetInnerHTML;
275
+ var innerHTML = props.dangerouslySetInnerHTML;
249
276
  if (innerHTML != null) {
250
277
  if (innerHTML.__html != null) {
251
- return innerHTML.__html;
278
+ return prefix + innerHTML.__html;
252
279
  }
253
280
  } else {
254
281
  var contentToUse =
255
- CONTENT_TYPES[typeof this.props.children] ? this.props.children : null;
256
- var childrenToUse = contentToUse != null ? null : this.props.children;
282
+ CONTENT_TYPES[typeof props.children] ? props.children : null;
283
+ var childrenToUse = contentToUse != null ? null : props.children;
257
284
  if (contentToUse != null) {
258
- return escapeTextForBrowser(contentToUse);
285
+ return prefix + escapeTextForBrowser(contentToUse);
259
286
  } else if (childrenToUse != null) {
260
287
  var mountImages = this.mountChildren(
261
288
  childrenToUse,
262
- transaction
289
+ transaction,
290
+ context
263
291
  );
264
- return mountImages.join('');
292
+ return prefix + mountImages.join('');
265
293
  }
266
294
  }
267
- return '';
295
+ return prefix;
268
296
  },
269
297
 
270
- receiveComponent: function(nextElement, transaction) {
271
- if (nextElement === this._currentElement &&
272
- nextElement._owner != null) {
273
- // Since elements are immutable after the owner is rendered,
274
- // we can do a cheap identity compare here to determine if this is a
275
- // superfluous reconcile. It's possible for state to be mutable but such
276
- // change should trigger an update of the owner which would recreate
277
- // 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
279
- // deeply mutated and reused.
280
- return;
281
- }
282
-
283
- ReactComponent.Mixin.receiveComponent.call(
284
- this,
285
- nextElement,
286
- transaction
287
- );
298
+ receiveComponent: function(nextElement, transaction, context) {
299
+ var prevElement = this._currentElement;
300
+ this._currentElement = nextElement;
301
+ this.updateComponent(transaction, prevElement, nextElement, context);
288
302
  },
289
303
 
290
304
  /**
@@ -293,23 +307,15 @@ ReactDOMComponent.Mixin = {
293
307
  *
294
308
  * @param {ReactReconcileTransaction} transaction
295
309
  * @param {ReactElement} prevElement
310
+ * @param {ReactElement} nextElement
296
311
  * @internal
297
312
  * @overridable
298
313
  */
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
- ),
314
+ updateComponent: function(transaction, prevElement, nextElement, context) {
315
+ assertValidProps(this._currentElement.props);
316
+ this._updateDOMProperties(prevElement.props, transaction);
317
+ this._updateDOMChildren(prevElement.props, transaction, context);
318
+ },
313
319
 
314
320
  /**
315
321
  * Reconciles the properties by detecting differences in property values and
@@ -327,7 +333,7 @@ ReactDOMComponent.Mixin = {
327
333
  * @param {ReactReconcileTransaction} transaction
328
334
  */
329
335
  _updateDOMProperties: function(lastProps, transaction) {
330
- var nextProps = this.props;
336
+ var nextProps = this._currentElement.props;
331
337
  var propKey;
332
338
  var styleName;
333
339
  var styleUpdates;
@@ -337,7 +343,7 @@ ReactDOMComponent.Mixin = {
337
343
  continue;
338
344
  }
339
345
  if (propKey === STYLE) {
340
- var lastStyle = lastProps[propKey];
346
+ var lastStyle = this._previousStyleCopy;
341
347
  for (styleName in lastStyle) {
342
348
  if (lastStyle.hasOwnProperty(styleName)) {
343
349
  styleUpdates = styleUpdates || {};
@@ -349,7 +355,7 @@ ReactDOMComponent.Mixin = {
349
355
  } else if (
350
356
  DOMProperty.isStandardName[propKey] ||
351
357
  DOMProperty.isCustomAttribute(propKey)) {
352
- ReactComponent.BackendIDOperations.deletePropertyByID(
358
+ BackendIDOperations.deletePropertyByID(
353
359
  this._rootNodeID,
354
360
  propKey
355
361
  );
@@ -357,13 +363,15 @@ ReactDOMComponent.Mixin = {
357
363
  }
358
364
  for (propKey in nextProps) {
359
365
  var nextProp = nextProps[propKey];
360
- var lastProp = lastProps[propKey];
366
+ var lastProp = propKey === STYLE ?
367
+ this._previousStyleCopy :
368
+ lastProps[propKey];
361
369
  if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) {
362
370
  continue;
363
371
  }
364
372
  if (propKey === STYLE) {
365
373
  if (nextProp) {
366
- nextProp = nextProps.style = assign({}, nextProp);
374
+ nextProp = this._previousStyleCopy = assign({}, nextProp);
367
375
  }
368
376
  if (lastProp) {
369
377
  // Unset styles on `lastProp` but not on `nextProp`.
@@ -391,7 +399,7 @@ ReactDOMComponent.Mixin = {
391
399
  } else if (
392
400
  DOMProperty.isStandardName[propKey] ||
393
401
  DOMProperty.isCustomAttribute(propKey)) {
394
- ReactComponent.BackendIDOperations.updatePropertyByID(
402
+ BackendIDOperations.updatePropertyByID(
395
403
  this._rootNodeID,
396
404
  propKey,
397
405
  nextProp
@@ -399,7 +407,7 @@ ReactDOMComponent.Mixin = {
399
407
  }
400
408
  }
401
409
  if (styleUpdates) {
402
- ReactComponent.BackendIDOperations.updateStylesByID(
410
+ BackendIDOperations.updateStylesByID(
403
411
  this._rootNodeID,
404
412
  styleUpdates
405
413
  );
@@ -413,8 +421,8 @@ ReactDOMComponent.Mixin = {
413
421
  * @param {object} lastProps
414
422
  * @param {ReactReconcileTransaction} transaction
415
423
  */
416
- _updateDOMChildren: function(lastProps, transaction) {
417
- var nextProps = this.props;
424
+ _updateDOMChildren: function(lastProps, transaction, context) {
425
+ var nextProps = this._currentElement.props;
418
426
 
419
427
  var lastContent =
420
428
  CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null;
@@ -437,7 +445,7 @@ ReactDOMComponent.Mixin = {
437
445
  var lastHasContentOrHtml = lastContent != null || lastHtml != null;
438
446
  var nextHasContentOrHtml = nextContent != null || nextHtml != null;
439
447
  if (lastChildren != null && nextChildren == null) {
440
- this.updateChildren(null, transaction);
448
+ this.updateChildren(null, transaction, context);
441
449
  } else if (lastHasContentOrHtml && !nextHasContentOrHtml) {
442
450
  this.updateTextContent('');
443
451
  }
@@ -448,13 +456,13 @@ ReactDOMComponent.Mixin = {
448
456
  }
449
457
  } else if (nextHtml != null) {
450
458
  if (lastHtml !== nextHtml) {
451
- ReactComponent.BackendIDOperations.updateInnerHTMLByID(
459
+ BackendIDOperations.updateInnerHTMLByID(
452
460
  this._rootNodeID,
453
461
  nextHtml
454
462
  );
455
463
  }
456
464
  } else if (nextChildren != null) {
457
- this.updateChildren(nextChildren, transaction);
465
+ this.updateChildren(nextChildren, transaction, context);
458
466
  }
459
467
  },
460
468
 
@@ -467,17 +475,27 @@ ReactDOMComponent.Mixin = {
467
475
  unmountComponent: function() {
468
476
  this.unmountChildren();
469
477
  ReactBrowserEventEmitter.deleteAllListeners(this._rootNodeID);
470
- ReactComponent.Mixin.unmountComponent.call(this);
478
+ ReactMount.purgeID(this._rootNodeID);
479
+ this._rootNodeID = null;
471
480
  }
472
481
 
473
482
  };
474
483
 
484
+ ReactPerf.measureMethods(ReactDOMComponent, 'ReactDOMComponent', {
485
+ mountComponent: 'mountComponent',
486
+ updateComponent: 'updateComponent'
487
+ });
488
+
475
489
  assign(
476
490
  ReactDOMComponent.prototype,
477
- ReactComponent.Mixin,
478
491
  ReactDOMComponent.Mixin,
479
- ReactMultiChild.Mixin,
480
- ReactBrowserComponentMixin
492
+ ReactMultiChild.Mixin
481
493
  );
482
494
 
495
+ ReactDOMComponent.injection = {
496
+ injectIDOperations: function(IDOperations) {
497
+ ReactDOMComponent.BackendIDOperations = BackendIDOperations = IDOperations;
498
+ }
499
+ };
500
+
483
501
  module.exports = ReactDOMComponent;