react 0.12.0-rc1 → 0.13.0-alpha.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 (79) hide show
  1. package/dist/JSXTransformer.js +1862 -519
  2. package/dist/react-with-addons.js +4099 -3299
  3. package/dist/react-with-addons.min.js +6 -6
  4. package/dist/react.js +3893 -3353
  5. package/dist/react.min.js +6 -6
  6. package/lib/BeforeInputEventPlugin.js +388 -111
  7. package/lib/CSSProperty.js +5 -2
  8. package/lib/CSSPropertyOperations.js +20 -0
  9. package/lib/ChangeEventPlugin.js +2 -2
  10. package/lib/Danger.js +1 -1
  11. package/lib/DefaultEventPluginOrder.js +0 -1
  12. package/lib/ExecutionEnvironment.js +2 -3
  13. package/lib/FallbackCompositionState.js +87 -0
  14. package/lib/HTMLDOMPropertyConfig.js +7 -0
  15. package/lib/Object.assign.js +3 -1
  16. package/lib/React.js +14 -49
  17. package/lib/ReactBrowserComponentMixin.js +2 -12
  18. package/lib/ReactBrowserEventEmitter.js +2 -4
  19. package/lib/ReactCSSTransitionGroup.js +3 -0
  20. package/lib/ReactCSSTransitionGroupChild.js +8 -0
  21. package/lib/ReactChildReconciler.js +121 -0
  22. package/lib/ReactClass.js +916 -0
  23. package/lib/ReactComponent.js +36 -286
  24. package/lib/ReactComponentBrowserEnvironment.js +9 -82
  25. package/lib/ReactComponentEnvironment.js +57 -0
  26. package/lib/ReactCompositeComponent.js +608 -1026
  27. package/lib/ReactContext.js +5 -1
  28. package/lib/ReactDOM.js +2 -7
  29. package/lib/ReactDOMButton.js +4 -5
  30. package/lib/ReactDOMComponent.js +97 -69
  31. package/lib/ReactDOMForm.js +4 -5
  32. package/lib/ReactDOMIDOperations.js +55 -73
  33. package/lib/ReactDOMImg.js +3 -5
  34. package/lib/ReactDOMInput.js +4 -5
  35. package/lib/ReactDOMOption.js +4 -5
  36. package/lib/ReactDOMSelect.js +55 -63
  37. package/lib/ReactDOMSelection.js +5 -1
  38. package/lib/{ReactTextComponent.js → ReactDOMTextComponent.js} +54 -34
  39. package/lib/ReactDOMTextarea.js +4 -5
  40. package/lib/ReactDefaultInjection.js +13 -7
  41. package/lib/ReactDefaultPerf.js +7 -6
  42. package/lib/ReactDefaultPerfAnalysis.js +1 -1
  43. package/lib/ReactElement.js +24 -5
  44. package/lib/ReactElementValidator.js +101 -52
  45. package/lib/ReactEmptyComponent.js +17 -10
  46. package/lib/ReactInjection.js +6 -4
  47. package/lib/ReactInputSelection.js +2 -3
  48. package/lib/ReactInstanceMap.js +47 -0
  49. package/lib/ReactMount.js +193 -64
  50. package/lib/ReactMultiChild.js +32 -42
  51. package/lib/ReactNativeComponent.js +46 -9
  52. package/lib/ReactOwner.js +3 -47
  53. package/lib/ReactPerf.js +20 -0
  54. package/lib/ReactPropTransferer.js +0 -55
  55. package/lib/ReactPropTypes.js +1 -17
  56. package/lib/ReactRef.js +96 -0
  57. package/lib/ReactServerRendering.js +3 -2
  58. package/lib/ReactTestUtils.js +82 -25
  59. package/lib/ReactTransitionGroup.js +47 -6
  60. package/lib/ReactUpdates.js +43 -42
  61. package/lib/SyntheticMouseEvent.js +1 -3
  62. package/lib/ViewportMetrics.js +1 -4
  63. package/lib/accumulate.js +47 -0
  64. package/lib/cloneWithProps.js +2 -2
  65. package/lib/copyProperties.js +2 -0
  66. package/lib/createFullPageComponent.js +2 -2
  67. package/lib/findDOMNode.js +52 -0
  68. package/lib/flattenChildren.js +1 -14
  69. package/lib/getIteratorFn.js +42 -0
  70. package/lib/instantiateReactComponent.js +88 -65
  71. package/lib/isNode.js +3 -4
  72. package/lib/isTextInputElement.js +1 -2
  73. package/lib/shouldUpdateReactComponent.js +13 -5
  74. package/lib/traverseAllChildren.js +110 -54
  75. package/lib/warning.js +1 -1
  76. package/package.json +1 -1
  77. package/lib/CompositionEventPlugin.js +0 -257
  78. package/lib/ReactLegacyElement.js +0 -232
  79. package/lib/deprecated.js +0 -47
@@ -14,7 +14,6 @@
14
14
  var ReactElement = require("./ReactElement");
15
15
  var ReactPropTypeLocationNames = require("./ReactPropTypeLocationNames");
16
16
 
17
- var deprecated = require("./deprecated");
18
17
  var emptyFunction = require("./emptyFunction");
19
18
 
20
19
  /**
@@ -85,22 +84,7 @@ var ReactPropTypes = {
85
84
  objectOf: createObjectOfTypeChecker,
86
85
  oneOf: createEnumTypeChecker,
87
86
  oneOfType: createUnionTypeChecker,
88
- shape: createShapeTypeChecker,
89
-
90
- component: deprecated(
91
- 'React.PropTypes',
92
- 'component',
93
- 'element',
94
- this,
95
- elementTypeChecker
96
- ),
97
- renderable: deprecated(
98
- 'React.PropTypes',
99
- 'renderable',
100
- 'node',
101
- this,
102
- nodeTypeChecker
103
- )
87
+ shape: createShapeTypeChecker
104
88
  };
105
89
 
106
90
  function createChainableTypeChecker(validate) {
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Copyright 2013-2014, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ * @providesModule ReactRef
10
+ */
11
+
12
+ "use strict";
13
+
14
+ var ReactUpdates = require("./ReactUpdates");
15
+
16
+ var accumulate = require("./accumulate");
17
+ var assign = require("./Object.assign");
18
+ var forEachAccumulated = require("./forEachAccumulated");
19
+ var invariant = require("./invariant");
20
+
21
+ function ReactRef() {
22
+ this._value = null;
23
+ this._successCallbacks = null;
24
+ this._failureCallbacks = null;
25
+ }
26
+
27
+ /**
28
+ * Call the enqueued success or failure callbacks for a ref, as appropriate.
29
+ */
30
+ function dispatchCallbacks() {
31
+ /*jshint validthis:true */
32
+ var successCallbacks = this._successCallbacks;
33
+ var failureCallbacks = this._failureCallbacks;
34
+ this._successCallbacks = null;
35
+ this._failureCallbacks = null;
36
+
37
+ if (this._value) {
38
+ forEachAccumulated(successCallbacks, callSuccess, this);
39
+ } else {
40
+ forEachAccumulated(failureCallbacks, callFailure);
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Call a single success callback, passing the ref's value.
46
+ */
47
+ function callSuccess(cb) {
48
+ /*jshint validthis:true */
49
+ cb(this._value);
50
+ }
51
+
52
+ /**
53
+ * Call a single failure callback, passing no arguments.
54
+ */
55
+ function callFailure(cb) {
56
+ cb();
57
+ }
58
+
59
+ assign(ReactRef.prototype, {
60
+ /**
61
+ * Get the value of a ref asynchronously. Accepts a success callback and an
62
+ * optional failure callback. If the ref has been rendered, the success
63
+ * callback will be called with the component instance; otherwise, the failure
64
+ * callback will be executed.
65
+ *
66
+ * @param {function} success Callback in case of success
67
+ * @param {?function} failure Callback in case of failure
68
+ */
69
+ then: function(success, failure) {
70
+ ("production" !== process.env.NODE_ENV ? invariant(
71
+ typeof success === 'function',
72
+ 'ReactRef.then(...): Must provide a success callback.'
73
+ ) : invariant(typeof success === 'function'));
74
+ if (this._successCallbacks == null) {
75
+ ReactUpdates.asap(dispatchCallbacks, this);
76
+ }
77
+ this._successCallbacks = accumulate(this._successCallbacks, success);
78
+ if (failure) {
79
+ this._failureCallbacks = accumulate(this._failureCallbacks, failure);
80
+ }
81
+ }
82
+ });
83
+
84
+ ReactRef.attachRef = function(ref, value) {
85
+ ref._value = value.getPublicInstance();
86
+ };
87
+
88
+ ReactRef.detachRef = function(ref, value) {
89
+ // Check that `component` is still the current ref because we do not want to
90
+ // detach the ref if another component stole it.
91
+ if (ref._value === value) {
92
+ ref._value = null;
93
+ }
94
+ };
95
+
96
+ module.exports = ReactRef;
@@ -17,6 +17,7 @@ var ReactMarkupChecksum = require("./ReactMarkupChecksum");
17
17
  var ReactServerRenderingTransaction =
18
18
  require("./ReactServerRenderingTransaction");
19
19
 
20
+ var emptyObject = require("./emptyObject");
20
21
  var instantiateReactComponent = require("./instantiateReactComponent");
21
22
  var invariant = require("./invariant");
22
23
 
@@ -37,7 +38,7 @@ function renderToString(element) {
37
38
 
38
39
  return transaction.perform(function() {
39
40
  var componentInstance = instantiateReactComponent(element, null);
40
- var markup = componentInstance.mountComponent(id, transaction, 0);
41
+ var markup = componentInstance.mountComponent(id, transaction, emptyObject);
41
42
  return ReactMarkupChecksum.addChecksumToMarkup(markup);
42
43
  }, null);
43
44
  } finally {
@@ -63,7 +64,7 @@ function renderToStaticMarkup(element) {
63
64
 
64
65
  return transaction.perform(function() {
65
66
  var componentInstance = instantiateReactComponent(element, null);
66
- return componentInstance.mountComponent(id, transaction, 0);
67
+ return componentInstance.mountComponent(id, transaction, emptyObject);
67
68
  }, null);
68
69
  } finally {
69
70
  ReactServerRenderingTransaction.release(transaction);
@@ -17,8 +17,10 @@ var EventPropagators = require("./EventPropagators");
17
17
  var React = require("./React");
18
18
  var ReactElement = require("./ReactElement");
19
19
  var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
20
+ var ReactCompositeComponent = require("./ReactCompositeComponent");
21
+ var ReactInstanceHandles = require("./ReactInstanceHandles");
22
+ var ReactInstanceMap = require("./ReactInstanceMap");
20
23
  var ReactMount = require("./ReactMount");
21
- var ReactTextComponent = require("./ReactTextComponent");
22
24
  var ReactUpdates = require("./ReactUpdates");
23
25
  var SyntheticEvent = require("./SyntheticEvent");
24
26
 
@@ -55,12 +57,14 @@ var ReactTestUtils = {
55
57
  isElementOfType: function(inst, convenienceConstructor) {
56
58
  return (
57
59
  ReactElement.isValidElement(inst) &&
58
- inst.type === convenienceConstructor.type
60
+ inst.type === convenienceConstructor
59
61
  );
60
62
  },
61
63
 
62
64
  isDOMComponent: function(inst) {
63
- return !!(inst && inst.mountComponent && inst.tagName);
65
+ // TODO: Fix this heuristic. It's just here because composites can currently
66
+ // pretend to be DOM components.
67
+ return !!(inst && inst.getDOMNode && inst.tagName);
64
68
  },
65
69
 
66
70
  isDOMComponentElement: function(inst) {
@@ -76,7 +80,7 @@ var ReactTestUtils = {
76
80
 
77
81
  isCompositeComponentWithType: function(inst, type) {
78
82
  return !!(ReactTestUtils.isCompositeComponent(inst) &&
79
- (inst.constructor === type.type));
83
+ (inst.constructor === type));
80
84
  },
81
85
 
82
86
  isCompositeComponentElement: function(inst) {
@@ -97,8 +101,12 @@ var ReactTestUtils = {
97
101
  (inst.constructor === type));
98
102
  },
99
103
 
100
- isTextComponent: function(inst) {
101
- return inst instanceof ReactTextComponent.type;
104
+ getRenderedChildOfCompositeComponent: function(inst) {
105
+ if (!ReactTestUtils.isCompositeComponent(inst)) {
106
+ return null;
107
+ }
108
+ var internalInstance = ReactInstanceMap.get(inst);
109
+ return internalInstance._renderedComponent.getPublicInstance();
102
110
  },
103
111
 
104
112
  findAllInRenderedTree: function(inst, test) {
@@ -107,19 +115,31 @@ var ReactTestUtils = {
107
115
  }
108
116
  var ret = test(inst) ? [inst] : [];
109
117
  if (ReactTestUtils.isDOMComponent(inst)) {
110
- var renderedChildren = inst._renderedChildren;
118
+ var internalInstance = ReactInstanceMap.get(inst);
119
+ var renderedChildren = internalInstance
120
+ ._renderedComponent
121
+ ._renderedChildren;
111
122
  var key;
112
123
  for (key in renderedChildren) {
113
124
  if (!renderedChildren.hasOwnProperty(key)) {
114
125
  continue;
115
126
  }
127
+ if (!renderedChildren[key].getPublicInstance) {
128
+ continue;
129
+ }
116
130
  ret = ret.concat(
117
- ReactTestUtils.findAllInRenderedTree(renderedChildren[key], test)
131
+ ReactTestUtils.findAllInRenderedTree(
132
+ renderedChildren[key].getPublicInstance(),
133
+ test
134
+ )
118
135
  );
119
136
  }
120
137
  } else if (ReactTestUtils.isCompositeComponent(inst)) {
121
138
  ret = ret.concat(
122
- ReactTestUtils.findAllInRenderedTree(inst._renderedComponent, test)
139
+ ReactTestUtils.findAllInRenderedTree(
140
+ ReactTestUtils.getRenderedChildOfCompositeComponent(inst),
141
+ test
142
+ )
123
143
  );
124
144
  }
125
145
  return ret;
@@ -134,8 +154,7 @@ var ReactTestUtils = {
134
154
  return ReactTestUtils.findAllInRenderedTree(root, function(inst) {
135
155
  var instClassName = inst.props.className;
136
156
  return ReactTestUtils.isDOMComponent(inst) && (
137
- instClassName &&
138
- (' ' + instClassName + ' ').indexOf(' ' + className + ' ') !== -1
157
+ (instClassName && (' ' + instClassName + ' ').indexOf(' ' + className + ' ') !== -1)
139
158
  );
140
159
  });
141
160
  },
@@ -150,7 +169,9 @@ var ReactTestUtils = {
150
169
  var all =
151
170
  ReactTestUtils.scryRenderedDOMComponentsWithClass(root, className);
152
171
  if (all.length !== 1) {
153
- throw new Error('Did not find exactly one match for class:' + className);
172
+ throw new Error('Did not find exactly one match '+
173
+ '(found: ' + all.length + ') for class:' + className
174
+ );
154
175
  }
155
176
  return all[0];
156
177
  },
@@ -231,21 +252,14 @@ var ReactTestUtils = {
231
252
  mockComponent: function(module, mockTagName) {
232
253
  mockTagName = mockTagName || module.mockTagName || "div";
233
254
 
234
- var ConvenienceConstructor = React.createClass({displayName: 'ConvenienceConstructor',
235
- render: function() {
236
- return React.createElement(
237
- mockTagName,
238
- null,
239
- this.props.children
240
- );
241
- }
255
+ module.prototype.render.mockImplementation(function() {
256
+ return React.createElement(
257
+ mockTagName,
258
+ null,
259
+ this.props.children
260
+ );
242
261
  });
243
262
 
244
- module.mockImplementation(ConvenienceConstructor);
245
-
246
- module.type = ConvenienceConstructor.type;
247
- module.isReactLegacyFactory = true;
248
-
249
263
  return this;
250
264
  },
251
265
 
@@ -290,10 +304,53 @@ var ReactTestUtils = {
290
304
  };
291
305
  },
292
306
 
307
+ createRenderer: function() {
308
+ return new ReactShallowRenderer();
309
+ },
310
+
293
311
  Simulate: null,
294
312
  SimulateNative: {}
295
313
  };
296
314
 
315
+ /**
316
+ * @class ReactShallowRenderer
317
+ */
318
+ var ReactShallowRenderer = function() {
319
+ this._instance = null;
320
+ };
321
+
322
+ ReactShallowRenderer.prototype.getRenderOutput = function() {
323
+ return (this._instance && this._instance._renderedComponent) || null;
324
+ };
325
+
326
+ var ShallowComponentWrapper = function(inst) {
327
+ this._instance = inst;
328
+ };
329
+ assign(
330
+ ShallowComponentWrapper.prototype,
331
+ ReactCompositeComponent.ShallowMixin
332
+ );
333
+
334
+ ReactShallowRenderer.prototype.render = function(element, context) {
335
+ var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
336
+ this._render(element, transaction, context);
337
+ ReactUpdates.ReactReconcileTransaction.release(transaction);
338
+ };
339
+
340
+ ReactShallowRenderer.prototype._render = function(element, transaction, context) {
341
+ if (!this._instance) {
342
+ var rootID = ReactInstanceHandles.createReactRootID();
343
+ var instance = new ShallowComponentWrapper(new element.type(element.props));
344
+ instance.construct(element);
345
+
346
+ instance.mountComponent(rootID, transaction, context);
347
+
348
+ this._instance = instance;
349
+ } else {
350
+ this._instance.receiveComponent(element, transaction, context);
351
+ }
352
+ };
353
+
297
354
  /**
298
355
  * Exports:
299
356
  *
@@ -39,6 +39,21 @@ var ReactTransitionGroup = React.createClass({
39
39
  };
40
40
  },
41
41
 
42
+ componentWillMount: function() {
43
+ this.currentlyTransitioningKeys = {};
44
+ this.keysToEnter = [];
45
+ this.keysToLeave = [];
46
+ },
47
+
48
+ componentDidMount: function() {
49
+ var initialChildMapping = this.state.children;
50
+ for (var key in initialChildMapping) {
51
+ if (initialChildMapping[key]) {
52
+ this.performAppear(key);
53
+ }
54
+ }
55
+ },
56
+
42
57
  componentWillReceiveProps: function(nextProps) {
43
58
  var nextChildMapping = ReactTransitionChildMapping.getChildMapping(
44
59
  nextProps.children
@@ -73,12 +88,6 @@ var ReactTransitionGroup = React.createClass({
73
88
  // If we want to someday check for reordering, we could do it here.
74
89
  },
75
90
 
76
- componentWillMount: function() {
77
- this.currentlyTransitioningKeys = {};
78
- this.keysToEnter = [];
79
- this.keysToLeave = [];
80
- },
81
-
82
91
  componentDidUpdate: function() {
83
92
  var keysToEnter = this.keysToEnter;
84
93
  this.keysToEnter = [];
@@ -89,6 +98,38 @@ var ReactTransitionGroup = React.createClass({
89
98
  keysToLeave.forEach(this.performLeave);
90
99
  },
91
100
 
101
+ performAppear: function(key) {
102
+ this.currentlyTransitioningKeys[key] = true;
103
+
104
+ var component = this.refs[key];
105
+
106
+ if (component.componentWillAppear) {
107
+ component.componentWillAppear(
108
+ this._handleDoneAppearing.bind(this, key)
109
+ );
110
+ } else {
111
+ this._handleDoneAppearing(key);
112
+ }
113
+ },
114
+
115
+ _handleDoneAppearing: function(key) {
116
+ var component = this.refs[key];
117
+ if (component.componentDidAppear) {
118
+ component.componentDidAppear();
119
+ }
120
+
121
+ delete this.currentlyTransitioningKeys[key];
122
+
123
+ var currentChildMapping = ReactTransitionChildMapping.getChildMapping(
124
+ this.props.children
125
+ );
126
+
127
+ if (!currentChildMapping || !currentChildMapping.hasOwnProperty(key)) {
128
+ // This was removed before it had fully appeared. Remove it.
129
+ this.performLeave(key);
130
+ }
131
+ },
132
+
92
133
  performEnter: function(key) {
93
134
  this.currentlyTransitioningKeys[key] = true;
94
135
 
@@ -110,14 +110,14 @@ function batchedUpdates(callback, a, b) {
110
110
  }
111
111
 
112
112
  /**
113
- * Array comparator for ReactComponents by owner depth
113
+ * Array comparator for ReactComponents by mount ordering.
114
114
  *
115
115
  * @param {ReactComponent} c1 first component you're comparing
116
116
  * @param {ReactComponent} c2 second component you're comparing
117
117
  * @return {number} Return value usable by Array.prototype.sort().
118
118
  */
119
- function mountDepthComparator(c1, c2) {
120
- return c1._mountDepth - c2._mountDepth;
119
+ function mountOrderComparator(c1, c2) {
120
+ return c1._mountOrder - c2._mountOrder;
121
121
  }
122
122
 
123
123
  function runBatchedUpdates(transaction) {
@@ -133,56 +133,57 @@ function runBatchedUpdates(transaction) {
133
133
  // Since reconciling a component higher in the owner hierarchy usually (not
134
134
  // always -- see shouldComponentUpdate()) will reconcile children, reconcile
135
135
  // them before their children by sorting the array.
136
- dirtyComponents.sort(mountDepthComparator);
136
+ dirtyComponents.sort(mountOrderComparator);
137
137
 
138
138
  for (var i = 0; i < len; i++) {
139
- // If a component is unmounted before pending changes apply, ignore them
140
- // TODO: Queue unmounts in the same list to avoid this happening at all
139
+ // If a component is unmounted before pending changes apply, it will still
140
+ // be here, but we assume that it has cleared its _pendingCallbacks and
141
+ // that performUpdateIfNecessary is a noop.
141
142
  var component = dirtyComponents[i];
142
- if (component.isMounted()) {
143
- // If performUpdateIfNecessary happens to enqueue any new updates, we
144
- // shouldn't execute the callbacks until the next render happens, so
145
- // stash the callbacks first
146
- var callbacks = component._pendingCallbacks;
147
- component._pendingCallbacks = null;
148
- component.performUpdateIfNecessary(transaction.reconcileTransaction);
149
-
150
- if (callbacks) {
151
- for (var j = 0; j < callbacks.length; j++) {
152
- transaction.callbackQueue.enqueue(
153
- callbacks[j],
154
- component
155
- );
156
- }
143
+
144
+ // If performUpdateIfNecessary happens to enqueue any new updates, we
145
+ // shouldn't execute the callbacks until the next render happens, so
146
+ // stash the callbacks first
147
+ var callbacks = component._pendingCallbacks;
148
+ component._pendingCallbacks = null;
149
+ component.performUpdateIfNecessary(transaction.reconcileTransaction);
150
+
151
+ if (callbacks) {
152
+ for (var j = 0; j < callbacks.length; j++) {
153
+ transaction.callbackQueue.enqueue(
154
+ callbacks[j],
155
+ component
156
+ );
157
157
  }
158
158
  }
159
159
  }
160
160
  }
161
161
 
162
- var flushBatchedUpdates = ReactPerf.measure(
163
- 'ReactUpdates',
164
- 'flushBatchedUpdates',
165
- function() {
166
- // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents
167
- // array and perform any updates enqueued by mount-ready handlers (i.e.,
168
- // componentDidUpdate) but we need to check here too in order to catch
169
- // updates enqueued by setState callbacks and asap calls.
170
- while (dirtyComponents.length || asapEnqueued) {
171
- if (dirtyComponents.length) {
172
- var transaction = ReactUpdatesFlushTransaction.getPooled();
173
- transaction.perform(runBatchedUpdates, null, transaction);
174
- ReactUpdatesFlushTransaction.release(transaction);
175
- }
162
+ var flushBatchedUpdates = function() {
163
+ // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents
164
+ // array and perform any updates enqueued by mount-ready handlers (i.e.,
165
+ // componentDidUpdate) but we need to check here too in order to catch
166
+ // updates enqueued by setState callbacks and asap calls.
167
+ while (dirtyComponents.length || asapEnqueued) {
168
+ if (dirtyComponents.length) {
169
+ var transaction = ReactUpdatesFlushTransaction.getPooled();
170
+ transaction.perform(runBatchedUpdates, null, transaction);
171
+ ReactUpdatesFlushTransaction.release(transaction);
172
+ }
176
173
 
177
- if (asapEnqueued) {
178
- asapEnqueued = false;
179
- var queue = asapCallbackQueue;
180
- asapCallbackQueue = CallbackQueue.getPooled();
181
- queue.notifyAll();
182
- CallbackQueue.release(queue);
183
- }
174
+ if (asapEnqueued) {
175
+ asapEnqueued = false;
176
+ var queue = asapCallbackQueue;
177
+ asapCallbackQueue = CallbackQueue.getPooled();
178
+ queue.notifyAll();
179
+ CallbackQueue.release(queue);
184
180
  }
185
181
  }
182
+ };
183
+ flushBatchedUpdates = ReactPerf.measure(
184
+ 'ReactUpdates',
185
+ 'flushBatchedUpdates',
186
+ flushBatchedUpdates
186
187
  );
187
188
 
188
189
  /**