react 0.9.0-rc1 → 0.11.0-rc1

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 (168) hide show
  1. package/README.md +3 -0
  2. package/dist/JSXTransformer.js +13445 -0
  3. package/dist/react-with-addons.js +20226 -0
  4. package/dist/react-with-addons.min.js +22 -0
  5. package/dist/react.js +18434 -0
  6. package/dist/react.min.js +21 -0
  7. package/lib/AutoFocusMixin.js +4 -2
  8. package/lib/BeforeInputEventPlugin.js +222 -0
  9. package/lib/CSSCore.js +1 -1
  10. package/lib/CSSProperty.js +1 -1
  11. package/lib/CSSPropertyOperations.js +4 -4
  12. package/lib/{ReactMountReady.js → CallbackQueue.js} +33 -25
  13. package/lib/ChangeEventPlugin.js +2 -2
  14. package/lib/ClientReactRootIndex.js +1 -1
  15. package/lib/CompositionEventPlugin.js +6 -2
  16. package/lib/DOMChildrenOperations.js +34 -21
  17. package/lib/DOMProperty.js +52 -22
  18. package/lib/DOMPropertyOperations.js +29 -17
  19. package/lib/Danger.js +1 -1
  20. package/lib/DefaultEventPluginOrder.js +2 -1
  21. package/lib/EnterLeaveEventPlugin.js +1 -1
  22. package/lib/EventConstants.js +2 -1
  23. package/lib/EventListener.js +5 -2
  24. package/lib/EventPluginHub.js +5 -6
  25. package/lib/EventPluginRegistry.js +27 -4
  26. package/lib/EventPluginUtils.js +12 -2
  27. package/lib/EventPropagators.js +1 -1
  28. package/lib/ExecutionEnvironment.js +9 -3
  29. package/lib/{DefaultDOMPropertyConfig.js → HTMLDOMPropertyConfig.js} +47 -58
  30. package/lib/LinkedStateMixin.js +1 -1
  31. package/lib/LinkedValueUtils.js +27 -29
  32. package/lib/LocalEventTrapMixin.js +52 -0
  33. package/lib/MobileSafariClickEventPlugin.js +1 -1
  34. package/lib/PooledClass.js +1 -1
  35. package/lib/React.js +39 -4
  36. package/lib/ReactBrowserComponentMixin.js +46 -0
  37. package/lib/{ReactEventEmitter.js → ReactBrowserEventEmitter.js} +118 -95
  38. package/lib/ReactCSSTransitionGroup.js +13 -11
  39. package/lib/ReactCSSTransitionGroupChild.js +3 -6
  40. package/lib/ReactChildren.js +35 -14
  41. package/lib/ReactComponent.js +120 -224
  42. package/lib/ReactComponentBrowserEnvironment.js +4 -37
  43. package/lib/ReactComponentWithPureRenderMixin.js +54 -0
  44. package/lib/ReactCompositeComponent.js +250 -288
  45. package/lib/ReactContext.js +1 -1
  46. package/lib/ReactCurrentOwner.js +1 -1
  47. package/lib/ReactDOM.js +26 -24
  48. package/lib/ReactDOMButton.js +3 -2
  49. package/lib/ReactDOMComponent.js +43 -24
  50. package/lib/ReactDOMForm.js +8 -13
  51. package/lib/ReactDOMIDOperations.js +3 -32
  52. package/lib/ReactDOMImg.js +8 -14
  53. package/lib/ReactDOMInput.js +3 -2
  54. package/lib/ReactDOMOption.js +12 -8
  55. package/lib/ReactDOMSelect.js +19 -17
  56. package/lib/ReactDOMSelection.js +36 -11
  57. package/lib/ReactDOMTextarea.js +10 -8
  58. package/lib/ReactDefaultBatchingStrategy.js +4 -4
  59. package/lib/ReactDefaultInjection.js +28 -15
  60. package/lib/ReactDefaultPerf.js +29 -12
  61. package/lib/ReactDefaultPerfAnalysis.js +5 -1
  62. package/lib/ReactDescriptor.js +243 -0
  63. package/lib/ReactDescriptorValidator.js +283 -0
  64. package/lib/ReactEmptyComponent.js +78 -0
  65. package/lib/ReactErrorUtils.js +1 -1
  66. package/lib/ReactEventEmitterMixin.js +2 -4
  67. package/lib/ReactEventListener.js +189 -0
  68. package/lib/ReactInjection.js +9 -3
  69. package/lib/ReactInputSelection.js +3 -2
  70. package/lib/ReactInstanceHandles.js +1 -1
  71. package/lib/ReactLink.js +25 -1
  72. package/lib/ReactMarkupChecksum.js +1 -1
  73. package/lib/ReactMount.js +62 -22
  74. package/lib/ReactMultiChild.js +19 -14
  75. package/lib/ReactMultiChildUpdateTypes.js +1 -1
  76. package/lib/ReactOwner.js +7 -2
  77. package/lib/ReactPerf.js +1 -1
  78. package/lib/ReactPropTransferer.js +45 -30
  79. package/lib/ReactPropTypeLocationNames.js +1 -1
  80. package/lib/ReactPropTypeLocations.js +1 -1
  81. package/lib/ReactPropTypes.js +222 -238
  82. package/lib/ReactPutListenerQueue.js +3 -3
  83. package/lib/ReactReconcileTransaction.js +22 -21
  84. package/lib/ReactRootIndex.js +1 -1
  85. package/lib/ReactServerRendering.js +42 -12
  86. package/lib/ReactServerRenderingTransaction.js +115 -0
  87. package/lib/ReactStateSetters.js +1 -1
  88. package/lib/ReactTestUtils.js +412 -0
  89. package/lib/ReactTextComponent.js +22 -14
  90. package/lib/ReactTransitionChildMapping.js +3 -3
  91. package/lib/ReactTransitionEvents.js +20 -1
  92. package/lib/ReactTransitionGroup.js +10 -7
  93. package/lib/ReactUpdates.js +140 -23
  94. package/lib/ReactWithAddons.js +13 -3
  95. package/lib/SVGDOMPropertyConfig.js +97 -0
  96. package/lib/SelectEventPlugin.js +1 -1
  97. package/lib/ServerReactRootIndex.js +1 -1
  98. package/lib/SimpleEventPlugin.js +8 -2
  99. package/lib/SyntheticClipboardEvent.js +1 -1
  100. package/lib/SyntheticCompositionEvent.js +1 -1
  101. package/lib/SyntheticDragEvent.js +1 -1
  102. package/lib/SyntheticEvent.js +1 -1
  103. package/lib/SyntheticFocusEvent.js +1 -1
  104. package/lib/SyntheticInputEvent.js +52 -0
  105. package/lib/SyntheticKeyboardEvent.js +34 -5
  106. package/lib/SyntheticMouseEvent.js +4 -1
  107. package/lib/SyntheticTouchEvent.js +5 -2
  108. package/lib/SyntheticUIEvent.js +25 -3
  109. package/lib/SyntheticWheelEvent.js +1 -1
  110. package/lib/Transaction.js +1 -33
  111. package/lib/ViewportMetrics.js +1 -1
  112. package/lib/accumulate.js +1 -1
  113. package/lib/adler32.js +1 -1
  114. package/lib/cloneWithProps.js +11 -9
  115. package/lib/containsNode.js +1 -1
  116. package/lib/copyProperties.js +1 -1
  117. package/lib/createArrayFrom.js +1 -1
  118. package/lib/createFullPageComponent.js +2 -2
  119. package/lib/createNodesFromMarkup.js +1 -1
  120. package/lib/cx.js +1 -1
  121. package/lib/dangerousStyleValue.js +12 -6
  122. package/lib/emptyFunction.js +1 -1
  123. package/lib/{ReactComponentEnvironment.js → emptyObject.js} +7 -6
  124. package/lib/escapeTextForBrowser.js +3 -4
  125. package/lib/flattenChildren.js +10 -8
  126. package/lib/focusNode.js +33 -0
  127. package/lib/forEachAccumulated.js +1 -1
  128. package/lib/getActiveElement.js +1 -1
  129. package/lib/getEventKey.js +36 -6
  130. package/lib/getEventModifierState.js +52 -0
  131. package/lib/getEventTarget.js +1 -1
  132. package/lib/getMarkupWrap.js +3 -1
  133. package/lib/getNodeForCharacterOffset.js +1 -1
  134. package/lib/getReactRootElementInContainer.js +1 -1
  135. package/lib/getTextContentAccessor.js +2 -2
  136. package/lib/getUnboundedScrollPosition.js +1 -1
  137. package/lib/hyphenate.js +4 -1
  138. package/lib/hyphenateStyleName.js +46 -0
  139. package/lib/instantiateReactComponent.js +62 -0
  140. package/lib/invariant.js +21 -23
  141. package/lib/isEventSupported.js +1 -1
  142. package/lib/isNode.js +2 -2
  143. package/lib/isTextInputElement.js +1 -1
  144. package/lib/isTextNode.js +1 -1
  145. package/lib/joinClasses.js +1 -1
  146. package/lib/keyMirror.js +1 -1
  147. package/lib/keyOf.js +1 -1
  148. package/lib/{objMap.js → mapObject.js} +9 -4
  149. package/lib/memoizeStringOnly.js +1 -1
  150. package/lib/merge.js +1 -1
  151. package/lib/mergeHelpers.js +12 -1
  152. package/lib/mergeInto.js +4 -3
  153. package/lib/mixInto.js +1 -1
  154. package/lib/monitorCodeUse.js +37 -0
  155. package/lib/onlyChild.js +4 -4
  156. package/lib/performance.js +33 -0
  157. package/lib/performanceNow.js +6 -15
  158. package/lib/setInnerHTML.js +77 -0
  159. package/lib/shallowEqual.js +1 -1
  160. package/lib/shouldUpdateReactComponent.js +15 -29
  161. package/lib/toArray.js +1 -1
  162. package/lib/traverseAllChildren.js +10 -6
  163. package/lib/update.js +171 -0
  164. package/lib/warning.js +19 -11
  165. package/package.json +5 -3
  166. package/lib/ReactEventTopLevelCallback.js +0 -109
  167. package/lib/createObjectFrom.js +0 -61
  168. package/lib/objMapKeyVal.js +0 -47
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -20,7 +20,9 @@
20
20
  "use strict";
21
21
 
22
22
  var DOMPropertyOperations = require("./DOMPropertyOperations");
23
+ var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
23
24
  var ReactComponent = require("./ReactComponent");
25
+ var ReactDescriptor = require("./ReactDescriptor");
24
26
 
25
27
  var escapeTextForBrowser = require("./escapeTextForBrowser");
26
28
  var mixInto = require("./mixInto");
@@ -40,11 +42,12 @@ var mixInto = require("./mixInto");
40
42
  * @extends ReactComponent
41
43
  * @internal
42
44
  */
43
- var ReactTextComponent = function(initialText) {
44
- this.construct({text: initialText});
45
+ var ReactTextComponent = function(descriptor) {
46
+ this.construct(descriptor);
45
47
  };
46
48
 
47
49
  mixInto(ReactTextComponent, ReactComponent.Mixin);
50
+ mixInto(ReactTextComponent, ReactBrowserComponentMixin);
48
51
  mixInto(ReactTextComponent, {
49
52
 
50
53
  /**
@@ -52,7 +55,7 @@ mixInto(ReactTextComponent, {
52
55
  * any features besides containing text content.
53
56
  *
54
57
  * @param {string} rootID DOM ID of the root node.
55
- * @param {ReactReconcileTransaction} transaction
58
+ * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
56
59
  * @param {number} mountDepth number of components in the owner hierarchy
57
60
  * @return {string} Markup for this text node.
58
61
  * @internal
@@ -64,9 +67,19 @@ mixInto(ReactTextComponent, {
64
67
  transaction,
65
68
  mountDepth
66
69
  );
70
+
71
+ var escapedText = escapeTextForBrowser(this.props);
72
+
73
+ if (transaction.renderToStaticMarkup) {
74
+ // Normally we'd wrap this in a `span` for the reasons stated above, but
75
+ // since this is a situation where React won't take over (static pages),
76
+ // we can simply return the text as it is.
77
+ return escapedText;
78
+ }
79
+
67
80
  return (
68
81
  '<span ' + DOMPropertyOperations.createMarkupForID(rootID) + '>' +
69
- escapeTextForBrowser(this.props.text) +
82
+ escapedText +
70
83
  '</span>'
71
84
  );
72
85
  },
@@ -80,20 +93,15 @@ mixInto(ReactTextComponent, {
80
93
  */
81
94
  receiveComponent: function(nextComponent, transaction) {
82
95
  var nextProps = nextComponent.props;
83
- if (nextProps.text !== this.props.text) {
84
- this.props.text = nextProps.text;
96
+ if (nextProps !== this.props) {
97
+ this.props = nextProps;
85
98
  ReactComponent.BackendIDOperations.updateTextContentByID(
86
99
  this._rootNodeID,
87
- nextProps.text
100
+ nextProps
88
101
  );
89
102
  }
90
103
  }
91
104
 
92
105
  });
93
106
 
94
- // Expose the constructor on itself and the prototype for consistency with other
95
- // descriptors.
96
- ReactTextComponent.type = ReactTextComponent;
97
- ReactTextComponent.prototype.type = ReactTextComponent;
98
-
99
- module.exports = ReactTextComponent;
107
+ module.exports = ReactDescriptor.createFactory(ReactTextComponent);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -70,7 +70,7 @@ var ReactTransitionChildMapping = {
70
70
 
71
71
  var pendingKeys = [];
72
72
  for (var prevKey in prev) {
73
- if (next[prevKey]) {
73
+ if (next.hasOwnProperty(prevKey)) {
74
74
  if (pendingKeys.length) {
75
75
  nextKeysPending[prevKey] = pendingKeys;
76
76
  pendingKeys = [];
@@ -83,7 +83,7 @@ var ReactTransitionChildMapping = {
83
83
  var i;
84
84
  var childMapping = {};
85
85
  for (var nextKey in next) {
86
- if (nextKeysPending[nextKey]) {
86
+ if (nextKeysPending.hasOwnProperty(nextKey)) {
87
87
  for (i = 0; i < nextKeysPending[nextKey].length; i++) {
88
88
  var pendingNextKey = nextKeysPending[nextKey][i];
89
89
  childMapping[nextKeysPending[nextKey][i]] = getValueForKey(
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -20,6 +20,11 @@
20
20
 
21
21
  var ExecutionEnvironment = require("./ExecutionEnvironment");
22
22
 
23
+ /**
24
+ * EVENT_NAME_MAP is used to determine which event fired when a
25
+ * transition/animation ends, based on the style property used to
26
+ * define that event.
27
+ */
23
28
  var EVENT_NAME_MAP = {
24
29
  transitionend: {
25
30
  'transition': 'transitionend',
@@ -43,6 +48,20 @@ var endEvents = [];
43
48
  function detectEvents() {
44
49
  var testEl = document.createElement('div');
45
50
  var style = testEl.style;
51
+
52
+ // On some platforms, in particular some releases of Android 4.x,
53
+ // the un-prefixed "animation" and "transition" properties are defined on the
54
+ // style object but the events that fire will still be prefixed, so we need
55
+ // to check if the un-prefixed events are useable, and if not remove them
56
+ // from the map
57
+ if (!('AnimationEvent' in window)) {
58
+ delete EVENT_NAME_MAP.animationend.animation;
59
+ }
60
+
61
+ if (!('TransitionEvent' in window)) {
62
+ delete EVENT_NAME_MAP.transitionend.transition;
63
+ }
64
+
46
65
  for (var baseEventName in EVENT_NAME_MAP) {
47
66
  var baseEvents = EVENT_NAME_MAP[baseEventName];
48
67
  for (var styleName in baseEvents) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@ var emptyFunction = require("./emptyFunction");
26
26
  var merge = require("./merge");
27
27
 
28
28
  var ReactTransitionGroup = React.createClass({
29
+ displayName: 'ReactTransitionGroup',
29
30
 
30
31
  propTypes: {
31
32
  component: React.PropTypes.func,
@@ -61,15 +62,17 @@ var ReactTransitionGroup = React.createClass({
61
62
  var key;
62
63
 
63
64
  for (key in nextChildMapping) {
64
- if (!prevChildMapping.hasOwnProperty(key) &&
65
- !this.currentlyTransitioningKeys[key]) {
65
+ var hasPrev = prevChildMapping && prevChildMapping.hasOwnProperty(key);
66
+ if (nextChildMapping[key] && !hasPrev &&
67
+ !this.currentlyTransitioningKeys[key]) {
66
68
  this.keysToEnter.push(key);
67
69
  }
68
70
  }
69
71
 
70
72
  for (key in prevChildMapping) {
71
- if (!nextChildMapping.hasOwnProperty(key) &&
72
- !this.currentlyTransitioningKeys[key]) {
73
+ var hasNext = nextChildMapping && nextChildMapping.hasOwnProperty(key);
74
+ if (prevChildMapping[key] && !hasNext &&
75
+ !this.currentlyTransitioningKeys[key]) {
73
76
  this.keysToLeave.push(key);
74
77
  }
75
78
  }
@@ -119,7 +122,7 @@ var ReactTransitionGroup = React.createClass({
119
122
  this.props.children
120
123
  );
121
124
 
122
- if (!currentChildMapping.hasOwnProperty(key)) {
125
+ if (!currentChildMapping || !currentChildMapping.hasOwnProperty(key)) {
123
126
  // This was removed before it had fully entered. Remove it.
124
127
  this.performLeave(key);
125
128
  }
@@ -152,7 +155,7 @@ var ReactTransitionGroup = React.createClass({
152
155
  this.props.children
153
156
  );
154
157
 
155
- if (currentChildMapping.hasOwnProperty(key)) {
158
+ if (currentChildMapping && currentChildMapping.hasOwnProperty(key)) {
156
159
  // This entered again before it fully left. Add it again.
157
160
  this.performEnter(key);
158
161
  } else {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -18,21 +18,99 @@
18
18
 
19
19
  "use strict";
20
20
 
21
+ var CallbackQueue = require("./CallbackQueue");
22
+ var PooledClass = require("./PooledClass");
23
+ var ReactCurrentOwner = require("./ReactCurrentOwner");
21
24
  var ReactPerf = require("./ReactPerf");
25
+ var Transaction = require("./Transaction");
22
26
 
23
27
  var invariant = require("./invariant");
28
+ var mixInto = require("./mixInto");
29
+ var warning = require("./warning");
24
30
 
25
31
  var dirtyComponents = [];
26
32
 
27
33
  var batchingStrategy = null;
28
34
 
29
- function ensureBatchingStrategy() {
30
- ("production" !== process.env.NODE_ENV ? invariant(batchingStrategy, 'ReactUpdates: must inject a batching strategy') : invariant(batchingStrategy));
35
+ function ensureInjected() {
36
+ ("production" !== process.env.NODE_ENV ? invariant(
37
+ ReactUpdates.ReactReconcileTransaction && batchingStrategy,
38
+ 'ReactUpdates: must inject a reconcile transaction class and batching ' +
39
+ 'strategy'
40
+ ) : invariant(ReactUpdates.ReactReconcileTransaction && batchingStrategy));
31
41
  }
32
42
 
33
- function batchedUpdates(callback, param) {
34
- ensureBatchingStrategy();
35
- batchingStrategy.batchedUpdates(callback, param);
43
+ var NESTED_UPDATES = {
44
+ initialize: function() {
45
+ this.dirtyComponentsLength = dirtyComponents.length;
46
+ },
47
+ close: function() {
48
+ if (this.dirtyComponentsLength !== dirtyComponents.length) {
49
+ // Additional updates were enqueued by componentDidUpdate handlers or
50
+ // similar; before our own UPDATE_QUEUEING wrapper closes, we want to run
51
+ // these new updates so that if A's componentDidUpdate calls setState on
52
+ // B, B will update before the callback A's updater provided when calling
53
+ // setState.
54
+ dirtyComponents.splice(0, this.dirtyComponentsLength);
55
+ flushBatchedUpdates();
56
+ } else {
57
+ dirtyComponents.length = 0;
58
+ }
59
+ }
60
+ };
61
+
62
+ var UPDATE_QUEUEING = {
63
+ initialize: function() {
64
+ this.callbackQueue.reset();
65
+ },
66
+ close: function() {
67
+ this.callbackQueue.notifyAll();
68
+ }
69
+ };
70
+
71
+ var TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING];
72
+
73
+ function ReactUpdatesFlushTransaction() {
74
+ this.reinitializeTransaction();
75
+ this.dirtyComponentsLength = null;
76
+ this.callbackQueue = CallbackQueue.getPooled(null);
77
+ this.reconcileTransaction =
78
+ ReactUpdates.ReactReconcileTransaction.getPooled();
79
+ }
80
+
81
+ mixInto(ReactUpdatesFlushTransaction, Transaction.Mixin);
82
+ mixInto(ReactUpdatesFlushTransaction, {
83
+ getTransactionWrappers: function() {
84
+ return TRANSACTION_WRAPPERS;
85
+ },
86
+
87
+ destructor: function() {
88
+ this.dirtyComponentsLength = null;
89
+ CallbackQueue.release(this.callbackQueue);
90
+ this.callbackQueue = null;
91
+ ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction);
92
+ this.reconcileTransaction = null;
93
+ },
94
+
95
+ perform: function(method, scope, a) {
96
+ // Essentially calls `this.reconcileTransaction.perform(method, scope, a)`
97
+ // with this transaction's wrappers around it.
98
+ return Transaction.Mixin.perform.call(
99
+ this,
100
+ this.reconcileTransaction.perform,
101
+ this.reconcileTransaction,
102
+ method,
103
+ scope,
104
+ a
105
+ );
106
+ }
107
+ });
108
+
109
+ PooledClass.addPoolingTo(ReactUpdatesFlushTransaction);
110
+
111
+ function batchedUpdates(callback, a, b) {
112
+ ensureInjected();
113
+ batchingStrategy.batchedUpdates(callback, a, b);
36
114
  }
37
115
 
38
116
  /**
@@ -46,14 +124,22 @@ function mountDepthComparator(c1, c2) {
46
124
  return c1._mountDepth - c2._mountDepth;
47
125
  }
48
126
 
49
- function runBatchedUpdates() {
127
+ function runBatchedUpdates(transaction) {
128
+ var len = transaction.dirtyComponentsLength;
129
+ ("production" !== process.env.NODE_ENV ? invariant(
130
+ len === dirtyComponents.length,
131
+ 'Expected flush transaction\'s stored dirty-components length (%s) to ' +
132
+ 'match dirty-components array length (%s).',
133
+ len,
134
+ dirtyComponents.length
135
+ ) : invariant(len === dirtyComponents.length));
136
+
50
137
  // Since reconciling a component higher in the owner hierarchy usually (not
51
138
  // always -- see shouldComponentUpdate()) will reconcile children, reconcile
52
139
  // them before their children by sorting the array.
53
-
54
140
  dirtyComponents.sort(mountDepthComparator);
55
141
 
56
- for (var i = 0; i < dirtyComponents.length; i++) {
142
+ for (var i = 0; i < len; i++) {
57
143
  // If a component is unmounted before pending changes apply, ignore them
58
144
  // TODO: Queue unmounts in the same list to avoid this happening at all
59
145
  var component = dirtyComponents[i];
@@ -63,29 +149,32 @@ function runBatchedUpdates() {
63
149
  // stash the callbacks first
64
150
  var callbacks = component._pendingCallbacks;
65
151
  component._pendingCallbacks = null;
66
- component.performUpdateIfNecessary();
152
+ component.performUpdateIfNecessary(transaction.reconcileTransaction);
153
+
67
154
  if (callbacks) {
68
155
  for (var j = 0; j < callbacks.length; j++) {
69
- callbacks[j].call(component);
156
+ transaction.callbackQueue.enqueue(
157
+ callbacks[j],
158
+ component
159
+ );
70
160
  }
71
161
  }
72
162
  }
73
163
  }
74
164
  }
75
165
 
76
- function clearDirtyComponents() {
77
- dirtyComponents.length = 0;
78
- }
79
-
80
166
  var flushBatchedUpdates = ReactPerf.measure(
81
167
  'ReactUpdates',
82
168
  'flushBatchedUpdates',
83
169
  function() {
84
- // Run these in separate functions so the JIT can optimize
85
- try {
86
- runBatchedUpdates();
87
- } finally {
88
- clearDirtyComponents();
170
+ // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents
171
+ // array and perform any updates enqueued by mount-ready handlers (i.e.,
172
+ // componentDidUpdate) but we need to check here too in order to catch
173
+ // updates enqueued by setState callbacks.
174
+ while (dirtyComponents.length) {
175
+ var transaction = ReactUpdatesFlushTransaction.getPooled();
176
+ transaction.perform(runBatchedUpdates, null, transaction);
177
+ ReactUpdatesFlushTransaction.release(transaction);
89
178
  }
90
179
  }
91
180
  );
@@ -101,11 +190,23 @@ function enqueueUpdate(component, callback) {
101
190
  '`setState`, `replaceState`, or `forceUpdate` with a callback that ' +
102
191
  'isn\'t callable.'
103
192
  ) : invariant(!callback || typeof callback === "function"));
104
- ensureBatchingStrategy();
193
+ ensureInjected();
194
+
195
+ // Various parts of our code (such as ReactCompositeComponent's
196
+ // _renderValidatedComponent) assume that calls to render aren't nested;
197
+ // verify that that's the case. (This is called by each top-level update
198
+ // function, like setProps, setState, forceUpdate, etc.; creation and
199
+ // destruction of top-level components is guarded in ReactMount.)
200
+ ("production" !== process.env.NODE_ENV ? warning(
201
+ ReactCurrentOwner.current == null,
202
+ 'enqueueUpdate(): Render methods should be a pure function of props ' +
203
+ 'and state; triggering nested component updates from render is not ' +
204
+ 'allowed. If necessary, trigger nested updates in ' +
205
+ 'componentDidUpdate.'
206
+ ) : null);
105
207
 
106
208
  if (!batchingStrategy.isBatchingUpdates) {
107
- component.performUpdateIfNecessary();
108
- callback && callback.call(component);
209
+ batchingStrategy.batchedUpdates(enqueueUpdate, component, callback);
109
210
  return;
110
211
  }
111
212
 
@@ -121,6 +222,14 @@ function enqueueUpdate(component, callback) {
121
222
  }
122
223
 
123
224
  var ReactUpdatesInjection = {
225
+ injectReconcileTransaction: function(ReconcileTransaction) {
226
+ ("production" !== process.env.NODE_ENV ? invariant(
227
+ ReconcileTransaction,
228
+ 'ReactUpdates: must provide a reconcile transaction class'
229
+ ) : invariant(ReconcileTransaction));
230
+ ReactUpdates.ReactReconcileTransaction = ReconcileTransaction;
231
+ },
232
+
124
233
  injectBatchingStrategy: function(_batchingStrategy) {
125
234
  ("production" !== process.env.NODE_ENV ? invariant(
126
235
  _batchingStrategy,
@@ -139,6 +248,14 @@ var ReactUpdatesInjection = {
139
248
  };
140
249
 
141
250
  var ReactUpdates = {
251
+ /**
252
+ * React references `ReactReconcileTransaction` using this property in order
253
+ * to allow dependency injection.
254
+ *
255
+ * @internal
256
+ */
257
+ ReactReconcileTransaction: null,
258
+
142
259
  batchedUpdates: batchedUpdates,
143
260
  enqueueUpdate: enqueueUpdate,
144
261
  flushBatchedUpdates: flushBatchedUpdates,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -27,20 +27,30 @@
27
27
 
28
28
  var LinkedStateMixin = require("./LinkedStateMixin");
29
29
  var React = require("./React");
30
+ var ReactComponentWithPureRenderMixin =
31
+ require("./ReactComponentWithPureRenderMixin");
30
32
  var ReactCSSTransitionGroup = require("./ReactCSSTransitionGroup");
31
33
  var ReactTransitionGroup = require("./ReactTransitionGroup");
32
34
 
33
35
  var cx = require("./cx");
34
36
  var cloneWithProps = require("./cloneWithProps");
37
+ var update = require("./update");
35
38
 
36
39
  React.addons = {
37
- LinkedStateMixin: LinkedStateMixin,
38
40
  CSSTransitionGroup: ReactCSSTransitionGroup,
41
+ LinkedStateMixin: LinkedStateMixin,
42
+ PureRenderMixin: ReactComponentWithPureRenderMixin,
39
43
  TransitionGroup: ReactTransitionGroup,
40
44
 
41
45
  classSet: cx,
42
- cloneWithProps: cloneWithProps
46
+ cloneWithProps: cloneWithProps,
47
+ update: update
43
48
  };
44
49
 
50
+ if ("production" !== process.env.NODE_ENV) {
51
+ React.addons.Perf = require("./ReactDefaultPerf");
52
+ React.addons.TestUtils = require("./ReactTestUtils");
53
+ }
54
+
45
55
  module.exports = React;
46
56