react 0.10.0 → 0.11.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 (104) hide show
  1. package/README.md +3 -0
  2. package/dist/JSXTransformer.js +20344 -0
  3. package/dist/react-with-addons.js +20276 -0
  4. package/dist/react-with-addons.min.js +22 -0
  5. package/dist/react.js +18484 -0
  6. package/dist/react.min.js +21 -0
  7. package/lib/BeforeInputEventPlugin.js +222 -0
  8. package/lib/CSSPropertyOperations.js +3 -3
  9. package/lib/{ReactMountReady.js → CallbackQueue.js} +32 -24
  10. package/lib/ChangeEventPlugin.js +1 -1
  11. package/lib/CompositionEventPlugin.js +5 -1
  12. package/lib/DOMChildrenOperations.js +21 -14
  13. package/lib/DOMProperty.js +45 -17
  14. package/lib/DOMPropertyOperations.js +22 -10
  15. package/lib/DefaultEventPluginOrder.js +1 -0
  16. package/lib/EventConstants.js +1 -0
  17. package/lib/EventListener.js +5 -2
  18. package/lib/EventPluginHub.js +0 -5
  19. package/lib/EventPluginRegistry.js +6 -4
  20. package/lib/EventPluginUtils.js +11 -1
  21. package/lib/ExecutionEnvironment.js +8 -2
  22. package/lib/{DefaultDOMPropertyConfig.js → HTMLDOMPropertyConfig.js} +42 -49
  23. package/lib/LinkedValueUtils.js +21 -22
  24. package/lib/LocalEventTrapMixin.js +52 -0
  25. package/lib/React.js +57 -3
  26. package/lib/ReactBrowserComponentMixin.js +4 -0
  27. package/lib/{ReactEventEmitter.js → ReactBrowserEventEmitter.js} +115 -94
  28. package/lib/ReactCSSTransitionGroup.js +2 -0
  29. package/lib/ReactCSSTransitionGroupChild.js +2 -5
  30. package/lib/ReactChildren.js +31 -10
  31. package/lib/ReactComponent.js +88 -237
  32. package/lib/ReactComponentBrowserEnvironment.js +3 -2
  33. package/lib/ReactComponentWithPureRenderMixin.js +54 -0
  34. package/lib/ReactCompositeComponent.js +222 -384
  35. package/lib/ReactDOM.js +22 -18
  36. package/lib/ReactDOMComponent.js +26 -24
  37. package/lib/ReactDOMForm.js +5 -13
  38. package/lib/ReactDOMIDOperations.js +2 -31
  39. package/lib/ReactDOMImg.js +5 -14
  40. package/lib/ReactDOMSelect.js +16 -15
  41. package/lib/ReactDOMSelection.js +35 -10
  42. package/lib/ReactDOMTextarea.js +2 -4
  43. package/lib/ReactDefaultBatchingStrategy.js +3 -3
  44. package/lib/ReactDefaultInjection.js +18 -15
  45. package/lib/ReactDefaultPerf.js +28 -11
  46. package/lib/ReactDefaultPerfAnalysis.js +4 -0
  47. package/lib/ReactDescriptor.js +251 -0
  48. package/lib/ReactDescriptorValidator.js +283 -0
  49. package/lib/ReactEmptyComponent.js +78 -0
  50. package/lib/ReactEventEmitterMixin.js +1 -3
  51. package/lib/ReactEventListener.js +189 -0
  52. package/lib/ReactInjection.js +4 -2
  53. package/lib/ReactLink.js +24 -0
  54. package/lib/ReactMount.js +51 -19
  55. package/lib/ReactMultiChild.js +9 -11
  56. package/lib/ReactPropTransferer.js +44 -29
  57. package/lib/ReactPropTypes.js +226 -242
  58. package/lib/ReactPutListenerQueue.js +2 -2
  59. package/lib/ReactReconcileTransaction.js +14 -14
  60. package/lib/ReactServerRendering.js +5 -5
  61. package/lib/ReactServerRenderingTransaction.js +4 -5
  62. package/lib/ReactTestUtils.js +39 -21
  63. package/lib/ReactTextComponent.js +8 -22
  64. package/lib/ReactTransitionChildMapping.js +2 -2
  65. package/lib/ReactTransitionEvents.js +19 -0
  66. package/lib/ReactTransitionGroup.js +9 -6
  67. package/lib/ReactUpdates.js +139 -22
  68. package/lib/ReactWithAddons.js +5 -2
  69. package/lib/SVGDOMPropertyConfig.js +97 -0
  70. package/lib/SimpleEventPlugin.js +7 -1
  71. package/lib/SyntheticInputEvent.js +52 -0
  72. package/lib/SyntheticKeyboardEvent.js +33 -4
  73. package/lib/SyntheticMouseEvent.js +3 -0
  74. package/lib/SyntheticTouchEvent.js +4 -1
  75. package/lib/SyntheticUIEvent.js +24 -2
  76. package/lib/Transaction.js +0 -32
  77. package/lib/cloneWithProps.js +3 -1
  78. package/lib/createFullPageComponent.js +1 -1
  79. package/lib/dangerousStyleValue.js +11 -5
  80. package/lib/escapeTextForBrowser.js +2 -3
  81. package/lib/flattenChildren.js +9 -7
  82. package/lib/getEventKey.js +35 -5
  83. package/lib/getEventModifierState.js +52 -0
  84. package/lib/getMarkupWrap.js +2 -0
  85. package/lib/getTextContentAccessor.js +1 -1
  86. package/lib/hyphenate.js +3 -0
  87. package/lib/hyphenateStyleName.js +46 -0
  88. package/lib/instantiateReactComponent.js +13 -21
  89. package/lib/invariant.js +17 -19
  90. package/lib/{objMap.js → mapObject.js} +8 -3
  91. package/lib/mergeHelpers.js +11 -0
  92. package/lib/mergeInto.js +3 -2
  93. package/lib/onlyChild.js +3 -3
  94. package/lib/performance.js +33 -0
  95. package/lib/performanceNow.js +5 -14
  96. package/lib/setInnerHTML.js +85 -0
  97. package/lib/shouldUpdateReactComponent.js +12 -29
  98. package/lib/toArray.js +1 -1
  99. package/lib/traverseAllChildren.js +7 -4
  100. package/lib/update.js +57 -45
  101. package/package.json +4 -3
  102. package/lib/ReactEventTopLevelCallback.js +0 -149
  103. package/lib/createObjectFrom.js +0 -61
  104. package/lib/objMapKeyVal.js +0 -47
@@ -22,7 +22,6 @@
22
22
  var ReactPropTypes = require("./ReactPropTypes");
23
23
 
24
24
  var invariant = require("./invariant");
25
- var warning = require("./warning");
26
25
 
27
26
  var hasReadOnlyValue = {
28
27
  'button': true,
@@ -36,9 +35,9 @@ var hasReadOnlyValue = {
36
35
 
37
36
  function _assertSingleLink(input) {
38
37
  ("production" !== process.env.NODE_ENV ? invariant(
39
- input.props.checkedLink == null || input.props.valueLink == null,
40
- 'Cannot provide a checkedLink and a valueLink. If you want to use ' +
41
- 'checkedLink, you probably don\'t want to use valueLink and vice versa.'
38
+ input.props.checkedLink == null || input.props.valueLink == null,
39
+ 'Cannot provide a checkedLink and a valueLink. If you want to use ' +
40
+ 'checkedLink, you probably don\'t want to use valueLink and vice versa.'
42
41
  ) : invariant(input.props.checkedLink == null || input.props.valueLink == null));
43
42
  }
44
43
  function _assertValueLink(input) {
@@ -84,33 +83,33 @@ var LinkedValueUtils = {
84
83
  Mixin: {
85
84
  propTypes: {
86
85
  value: function(props, propName, componentName) {
87
- if ("production" !== process.env.NODE_ENV) {
88
- ("production" !== process.env.NODE_ENV ? warning(
89
- !props[propName] ||
86
+ if (!props[propName] ||
90
87
  hasReadOnlyValue[props.type] ||
91
88
  props.onChange ||
92
89
  props.readOnly ||
93
- props.disabled,
94
- 'You provided a `value` prop to a form field without an ' +
95
- '`onChange` handler. This will render a read-only field. If ' +
96
- 'the field should be mutable use `defaultValue`. Otherwise, ' +
97
- 'set either `onChange` or `readOnly`.'
98
- ) : null);
90
+ props.disabled) {
91
+ return;
99
92
  }
93
+ return new Error(
94
+ 'You provided a `value` prop to a form field without an ' +
95
+ '`onChange` handler. This will render a read-only field. If ' +
96
+ 'the field should be mutable use `defaultValue`. Otherwise, ' +
97
+ 'set either `onChange` or `readOnly`.'
98
+ );
100
99
  },
101
100
  checked: function(props, propName, componentName) {
102
- if ("production" !== process.env.NODE_ENV) {
103
- ("production" !== process.env.NODE_ENV ? warning(
104
- !props[propName] ||
101
+ if (!props[propName] ||
105
102
  props.onChange ||
106
103
  props.readOnly ||
107
- props.disabled,
108
- 'You provided a `checked` prop to a form field without an ' +
109
- '`onChange` handler. This will render a read-only field. If ' +
110
- 'the field should be mutable use `defaultChecked`. Otherwise, ' +
111
- 'set either `onChange` or `readOnly`.'
112
- ) : null);
104
+ props.disabled) {
105
+ return;
113
106
  }
107
+ return new Error(
108
+ 'You provided a `checked` prop to a form field without an ' +
109
+ '`onChange` handler. This will render a read-only field. If ' +
110
+ 'the field should be mutable use `defaultChecked`. Otherwise, ' +
111
+ 'set either `onChange` or `readOnly`.'
112
+ );
114
113
  },
115
114
  onChange: ReactPropTypes.func
116
115
  }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Copyright 2014 Facebook, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ * @providesModule LocalEventTrapMixin
17
+ */
18
+
19
+ "use strict";
20
+
21
+ var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
22
+
23
+ var accumulate = require("./accumulate");
24
+ var forEachAccumulated = require("./forEachAccumulated");
25
+ var invariant = require("./invariant");
26
+
27
+ function remove(event) {
28
+ event.remove();
29
+ }
30
+
31
+ var LocalEventTrapMixin = {
32
+ trapBubbledEvent:function(topLevelType, handlerBaseName) {
33
+ ("production" !== process.env.NODE_ENV ? invariant(this.isMounted(), 'Must be mounted to trap events') : invariant(this.isMounted()));
34
+ var listener = ReactBrowserEventEmitter.trapBubbledEvent(
35
+ topLevelType,
36
+ handlerBaseName,
37
+ this.getDOMNode()
38
+ );
39
+ this._localEventListeners = accumulate(this._localEventListeners, listener);
40
+ },
41
+
42
+ // trapCapturedEvent would look nearly identical. We don't implement that
43
+ // method because it isn't currently needed.
44
+
45
+ componentWillUnmount:function() {
46
+ if (this._localEventListeners) {
47
+ forEachAccumulated(this._localEventListeners, remove);
48
+ }
49
+ }
50
+ };
51
+
52
+ module.exports = LocalEventTrapMixin;
package/lib/React.js CHANGED
@@ -25,6 +25,7 @@ var ReactComponent = require("./ReactComponent");
25
25
  var ReactCompositeComponent = require("./ReactCompositeComponent");
26
26
  var ReactContext = require("./ReactContext");
27
27
  var ReactCurrentOwner = require("./ReactCurrentOwner");
28
+ var ReactDescriptor = require("./ReactDescriptor");
28
29
  var ReactDOM = require("./ReactDOM");
29
30
  var ReactDOMComponent = require("./ReactDOMComponent");
30
31
  var ReactDefaultInjection = require("./ReactDefaultInjection");
@@ -37,13 +38,26 @@ var ReactServerRendering = require("./ReactServerRendering");
37
38
  var ReactTextComponent = require("./ReactTextComponent");
38
39
 
39
40
  var onlyChild = require("./onlyChild");
41
+ var warning = require("./warning");
40
42
 
41
43
  ReactDefaultInjection.inject();
42
44
 
45
+ // Specifying arguments isn't necessary since we just use apply anyway, but it
46
+ // makes it clear for those actually consuming this API.
47
+ function createDescriptor(type, props, children) {
48
+ var args = Array.prototype.slice.call(arguments, 1);
49
+ return type.apply(null, args);
50
+ }
51
+
52
+ if ("production" !== process.env.NODE_ENV) {
53
+ var _warnedForDeprecation = false;
54
+ }
55
+
43
56
  var React = {
44
57
  Children: {
45
58
  map: ReactChildren.map,
46
59
  forEach: ReactChildren.forEach,
60
+ count: ReactChildren.count,
47
61
  only: onlyChild
48
62
  },
49
63
  DOM: ReactDOM,
@@ -52,6 +66,18 @@ var React = {
52
66
  EventPluginUtils.useTouchEvents = shouldUseTouch;
53
67
  },
54
68
  createClass: ReactCompositeComponent.createClass,
69
+ createDescriptor: function() {
70
+ if ("production" !== process.env.NODE_ENV) {
71
+ ("production" !== process.env.NODE_ENV ? warning(
72
+ _warnedForDeprecation,
73
+ 'React.createDescriptor is deprecated and will be removed in the ' +
74
+ 'next version of React. Use React.createElement instead.'
75
+ ) : null);
76
+ _warnedForDeprecation = true;
77
+ }
78
+ return createDescriptor.apply(this, arguments);
79
+ },
80
+ createElement: createDescriptor,
55
81
  constructAndRenderComponent: ReactMount.constructAndRenderComponent,
56
82
  constructAndRenderComponentByID: ReactMount.constructAndRenderComponentByID,
57
83
  renderComponent: ReactPerf.measure(
@@ -63,8 +89,8 @@ var React = {
63
89
  renderComponentToStaticMarkup:
64
90
  ReactServerRendering.renderComponentToStaticMarkup,
65
91
  unmountComponentAtNode: ReactMount.unmountComponentAtNode,
66
- isValidClass: ReactCompositeComponent.isValidClass,
67
- isValidComponent: ReactComponent.isValidComponent,
92
+ isValidClass: ReactDescriptor.isValidFactory,
93
+ isValidComponent: ReactDescriptor.isValidDescriptor,
68
94
  withContext: ReactContext.withContext,
69
95
  __internals: {
70
96
  Component: ReactComponent,
@@ -87,11 +113,39 @@ if ("production" !== process.env.NODE_ENV) {
87
113
  'Download the React DevTools for a better development experience: ' +
88
114
  'http://fb.me/react-devtools'
89
115
  );
116
+
117
+ var expectedFeatures = [
118
+ // shims
119
+ Array.isArray,
120
+ Array.prototype.every,
121
+ Array.prototype.forEach,
122
+ Array.prototype.indexOf,
123
+ Array.prototype.map,
124
+ Date.now,
125
+ Function.prototype.bind,
126
+ Object.keys,
127
+ String.prototype.split,
128
+ String.prototype.trim,
129
+
130
+ // shams
131
+ Object.create,
132
+ Object.freeze
133
+ ];
134
+
135
+ for (var i in expectedFeatures) {
136
+ if (!expectedFeatures[i]) {
137
+ console.error(
138
+ 'One or more ES5 shim/shams expected by React are not available: ' +
139
+ 'http://fb.me/react-warning-polyfills'
140
+ );
141
+ break;
142
+ }
143
+ }
90
144
  }
91
145
  }
92
146
 
93
147
  // Version exists only in the open-source version of React, not in Facebook's
94
148
  // internal version.
95
- React.version = '0.10.0';
149
+ React.version = '0.11.2';
96
150
 
97
151
  module.exports = React;
@@ -18,6 +18,7 @@
18
18
 
19
19
  "use strict";
20
20
 
21
+ var ReactEmptyComponent = require("./ReactEmptyComponent");
21
22
  var ReactMount = require("./ReactMount");
22
23
 
23
24
  var invariant = require("./invariant");
@@ -35,6 +36,9 @@ var ReactBrowserComponentMixin = {
35
36
  this.isMounted(),
36
37
  'getDOMNode(): A component must be mounted to have a DOM node.'
37
38
  ) : invariant(this.isMounted()));
39
+ if (ReactEmptyComponent.isNullComponentID(this._rootNodeID)) {
40
+ return null;
41
+ }
38
42
  return ReactMount.getNode(this._rootNodeID);
39
43
  }
40
44
  };
@@ -13,29 +13,31 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  *
16
- * @providesModule ReactEventEmitter
16
+ * @providesModule ReactBrowserEventEmitter
17
17
  * @typechecks static-only
18
18
  */
19
19
 
20
20
  "use strict";
21
21
 
22
22
  var EventConstants = require("./EventConstants");
23
- var EventListener = require("./EventListener");
24
23
  var EventPluginHub = require("./EventPluginHub");
25
24
  var EventPluginRegistry = require("./EventPluginRegistry");
26
- var ExecutionEnvironment = require("./ExecutionEnvironment");
27
25
  var ReactEventEmitterMixin = require("./ReactEventEmitterMixin");
28
26
  var ViewportMetrics = require("./ViewportMetrics");
29
27
 
30
- var invariant = require("./invariant");
31
28
  var isEventSupported = require("./isEventSupported");
32
29
  var merge = require("./merge");
33
30
 
34
31
  /**
35
- * Summary of `ReactEventEmitter` event handling:
32
+ * Summary of `ReactBrowserEventEmitter` event handling:
36
33
  *
37
- * - Top-level delegation is used to trap native browser events. We normalize
38
- * and de-duplicate events to account for browser quirks.
34
+ * - Top-level delegation is used to trap most native browser events. This
35
+ * may only occur in the main thread and is the responsibility of
36
+ * ReactEventListener, which is injected and can therefore support pluggable
37
+ * event sources. This is the only work that occurs in the main thread.
38
+ *
39
+ * - We normalize and de-duplicate events to account for browser quirks. This
40
+ * may be done in the worker thread.
39
41
  *
40
42
  * - Forward these native events (with the associated top-level type used to
41
43
  * trap it) to `EventPluginHub`, which in turn will ask plugins if they want
@@ -48,11 +50,16 @@ var merge = require("./merge");
48
50
  *
49
51
  * Overview of React and the event system:
50
52
  *
51
- * .
52
53
  * +------------+ .
53
54
  * | DOM | .
55
+ * +------------+ .
56
+ * | .
57
+ * v .
58
+ * +------------+ .
59
+ * | ReactEvent | .
60
+ * | Listener | .
54
61
  * +------------+ . +-----------+
55
- * + . +--------+|SimpleEvent|
62
+ * | . +--------+|SimpleEvent|
56
63
  * | . | |Plugin |
57
64
  * +-----|------+ . v +-----------+
58
65
  * | | | . +--------------+ +------------+
@@ -115,6 +122,7 @@ var topEventMapping = {
115
122
  topPaste: 'paste',
116
123
  topScroll: 'scroll',
117
124
  topSelectionChange: 'selectionchange',
125
+ topTextInput: 'textInput',
118
126
  topTouchCancel: 'touchcancel',
119
127
  topTouchEnd: 'touchend',
120
128
  topTouchMove: 'touchmove',
@@ -128,7 +136,9 @@ var topEventMapping = {
128
136
  var topListenersIDKey = "_reactListenersID" + String(Math.random()).slice(2);
129
137
 
130
138
  function getListeningForDocument(mountAt) {
131
- if (mountAt[topListenersIDKey] == null) {
139
+ // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`
140
+ // directly.
141
+ if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {
132
142
  mountAt[topListenersIDKey] = reactTopListenersCounter++;
133
143
  alreadyListeningTo[mountAt[topListenersIDKey]] = {};
134
144
  }
@@ -136,64 +146,31 @@ function getListeningForDocument(mountAt) {
136
146
  }
137
147
 
138
148
  /**
139
- * Traps top-level events by using event bubbling.
149
+ * `ReactBrowserEventEmitter` is used to attach top-level event listeners. For
150
+ * example:
140
151
  *
141
- * @param {string} topLevelType Record from `EventConstants`.
142
- * @param {string} handlerBaseName Event name (e.g. "click").
143
- * @param {DOMEventTarget} element Element on which to attach listener.
144
- * @internal
145
- */
146
- function trapBubbledEvent(topLevelType, handlerBaseName, element) {
147
- EventListener.listen(
148
- element,
149
- handlerBaseName,
150
- ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback(
151
- topLevelType
152
- )
153
- );
154
- }
155
-
156
- /**
157
- * Traps a top-level event by using event capturing.
158
- *
159
- * @param {string} topLevelType Record from `EventConstants`.
160
- * @param {string} handlerBaseName Event name (e.g. "click").
161
- * @param {DOMEventTarget} element Element on which to attach listener.
162
- * @internal
163
- */
164
- function trapCapturedEvent(topLevelType, handlerBaseName, element) {
165
- EventListener.capture(
166
- element,
167
- handlerBaseName,
168
- ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback(
169
- topLevelType
170
- )
171
- );
172
- }
173
-
174
- /**
175
- * `ReactEventEmitter` is used to attach top-level event listeners. For example:
176
- *
177
- * ReactEventEmitter.putListener('myID', 'onClick', myFunction);
152
+ * ReactBrowserEventEmitter.putListener('myID', 'onClick', myFunction);
178
153
  *
179
154
  * This would allocate a "registration" of `('onClick', myFunction)` on 'myID'.
180
155
  *
181
156
  * @internal
182
157
  */
183
- var ReactEventEmitter = merge(ReactEventEmitterMixin, {
158
+ var ReactBrowserEventEmitter = merge(ReactEventEmitterMixin, {
184
159
 
185
160
  /**
186
- * React references `ReactEventTopLevelCallback` using this property in order
187
- * to allow dependency injection.
161
+ * Injectable event backend
188
162
  */
189
- TopLevelCallbackCreator: null,
163
+ ReactEventListener: null,
190
164
 
191
165
  injection: {
192
166
  /**
193
- * @param {function} TopLevelCallbackCreator
167
+ * @param {object} ReactEventListener
194
168
  */
195
- injectTopLevelCallbackCreator: function(TopLevelCallbackCreator) {
196
- ReactEventEmitter.TopLevelCallbackCreator = TopLevelCallbackCreator;
169
+ injectReactEventListener: function(ReactEventListener) {
170
+ ReactEventListener.setHandleTopLevel(
171
+ ReactBrowserEventEmitter.handleTopLevel
172
+ );
173
+ ReactBrowserEventEmitter.ReactEventListener = ReactEventListener;
197
174
  }
198
175
  },
199
176
 
@@ -203,13 +180,8 @@ var ReactEventEmitter = merge(ReactEventEmitterMixin, {
203
180
  * @param {boolean} enabled True if callbacks should be enabled.
204
181
  */
205
182
  setEnabled: function(enabled) {
206
- ("production" !== process.env.NODE_ENV ? invariant(
207
- ExecutionEnvironment.canUseDOM,
208
- 'setEnabled(...): Cannot toggle event listening in a Worker thread. ' +
209
- 'This is likely a bug in the framework. Please report immediately.'
210
- ) : invariant(ExecutionEnvironment.canUseDOM));
211
- if (ReactEventEmitter.TopLevelCallbackCreator) {
212
- ReactEventEmitter.TopLevelCallbackCreator.setEnabled(enabled);
183
+ if (ReactBrowserEventEmitter.ReactEventListener) {
184
+ ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled);
213
185
  }
214
186
  },
215
187
 
@@ -218,8 +190,8 @@ var ReactEventEmitter = merge(ReactEventEmitterMixin, {
218
190
  */
219
191
  isEnabled: function() {
220
192
  return !!(
221
- ReactEventEmitter.TopLevelCallbackCreator &&
222
- ReactEventEmitter.TopLevelCallbackCreator.isEnabled()
193
+ ReactBrowserEventEmitter.ReactEventListener &&
194
+ ReactBrowserEventEmitter.ReactEventListener.isEnabled()
223
195
  );
224
196
  },
225
197
 
@@ -242,10 +214,10 @@ var ReactEventEmitter = merge(ReactEventEmitterMixin, {
242
214
  * they bubble to document.
243
215
  *
244
216
  * @param {string} registrationName Name of listener (e.g. `onClick`).
245
- * @param {DOMDocument} contentDocument Document which owns the container
217
+ * @param {object} contentDocumentHandle Document which owns the container
246
218
  */
247
- listenTo: function(registrationName, contentDocument) {
248
- var mountAt = contentDocument;
219
+ listenTo: function(registrationName, contentDocumentHandle) {
220
+ var mountAt = contentDocumentHandle;
249
221
  var isListening = getListeningForDocument(mountAt);
250
222
  var dependencies = EventPluginRegistry.
251
223
  registrationNameDependencies[registrationName];
@@ -253,47 +225,85 @@ var ReactEventEmitter = merge(ReactEventEmitterMixin, {
253
225
  var topLevelTypes = EventConstants.topLevelTypes;
254
226
  for (var i = 0, l = dependencies.length; i < l; i++) {
255
227
  var dependency = dependencies[i];
256
- if (!isListening[dependency]) {
257
- var topLevelType = topLevelTypes[dependency];
258
-
259
- if (topLevelType === topLevelTypes.topWheel) {
228
+ if (!(
229
+ isListening.hasOwnProperty(dependency) &&
230
+ isListening[dependency]
231
+ )) {
232
+ if (dependency === topLevelTypes.topWheel) {
260
233
  if (isEventSupported('wheel')) {
261
- trapBubbledEvent(topLevelTypes.topWheel, 'wheel', mountAt);
234
+ ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
235
+ topLevelTypes.topWheel,
236
+ 'wheel',
237
+ mountAt
238
+ );
262
239
  } else if (isEventSupported('mousewheel')) {
263
- trapBubbledEvent(topLevelTypes.topWheel, 'mousewheel', mountAt);
240
+ ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
241
+ topLevelTypes.topWheel,
242
+ 'mousewheel',
243
+ mountAt
244
+ );
264
245
  } else {
265
246
  // Firefox needs to capture a different mouse scroll event.
266
247
  // @see http://www.quirksmode.org/dom/events/tests/scroll.html
267
- trapBubbledEvent(
248
+ ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
268
249
  topLevelTypes.topWheel,
269
250
  'DOMMouseScroll',
270
- mountAt);
251
+ mountAt
252
+ );
271
253
  }
272
- } else if (topLevelType === topLevelTypes.topScroll) {
254
+ } else if (dependency === topLevelTypes.topScroll) {
273
255
 
274
256
  if (isEventSupported('scroll', true)) {
275
- trapCapturedEvent(topLevelTypes.topScroll, 'scroll', mountAt);
257
+ ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(
258
+ topLevelTypes.topScroll,
259
+ 'scroll',
260
+ mountAt
261
+ );
276
262
  } else {
277
- trapBubbledEvent(topLevelTypes.topScroll, 'scroll', window);
263
+ ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
264
+ topLevelTypes.topScroll,
265
+ 'scroll',
266
+ ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE
267
+ );
278
268
  }
279
- } else if (topLevelType === topLevelTypes.topFocus ||
280
- topLevelType === topLevelTypes.topBlur) {
269
+ } else if (dependency === topLevelTypes.topFocus ||
270
+ dependency === topLevelTypes.topBlur) {
281
271
 
282
272
  if (isEventSupported('focus', true)) {
283
- trapCapturedEvent(topLevelTypes.topFocus, 'focus', mountAt);
284
- trapCapturedEvent(topLevelTypes.topBlur, 'blur', mountAt);
273
+ ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(
274
+ topLevelTypes.topFocus,
275
+ 'focus',
276
+ mountAt
277
+ );
278
+ ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(
279
+ topLevelTypes.topBlur,
280
+ 'blur',
281
+ mountAt
282
+ );
285
283
  } else if (isEventSupported('focusin')) {
286
284
  // IE has `focusin` and `focusout` events which bubble.
287
285
  // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
288
- trapBubbledEvent(topLevelTypes.topFocus, 'focusin', mountAt);
289
- trapBubbledEvent(topLevelTypes.topBlur, 'focusout', mountAt);
286
+ ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
287
+ topLevelTypes.topFocus,
288
+ 'focusin',
289
+ mountAt
290
+ );
291
+ ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
292
+ topLevelTypes.topBlur,
293
+ 'focusout',
294
+ mountAt
295
+ );
290
296
  }
291
297
 
292
298
  // to make sure blur and focus event listeners are only attached once
293
299
  isListening[topLevelTypes.topBlur] = true;
294
300
  isListening[topLevelTypes.topFocus] = true;
295
- } else if (topEventMapping[dependency]) {
296
- trapBubbledEvent(topLevelType, topEventMapping[dependency], mountAt);
301
+ } else if (topEventMapping.hasOwnProperty(dependency)) {
302
+ ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
303
+ dependency,
304
+ topEventMapping[dependency],
305
+ mountAt
306
+ );
297
307
  }
298
308
 
299
309
  isListening[dependency] = true;
@@ -301,6 +311,22 @@ var ReactEventEmitter = merge(ReactEventEmitterMixin, {
301
311
  }
302
312
  },
303
313
 
314
+ trapBubbledEvent: function(topLevelType, handlerBaseName, handle) {
315
+ return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
316
+ topLevelType,
317
+ handlerBaseName,
318
+ handle
319
+ );
320
+ },
321
+
322
+ trapCapturedEvent: function(topLevelType, handlerBaseName, handle) {
323
+ return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(
324
+ topLevelType,
325
+ handlerBaseName,
326
+ handle
327
+ );
328
+ },
329
+
304
330
  /**
305
331
  * Listens to window scroll and resize events. We cache scroll values so that
306
332
  * application code can access them without triggering reflows.
@@ -312,8 +338,7 @@ var ReactEventEmitter = merge(ReactEventEmitterMixin, {
312
338
  ensureScrollValueMonitoring: function(){
313
339
  if (!isMonitoringScrollValue) {
314
340
  var refresh = ViewportMetrics.refreshScrollValues;
315
- EventListener.listen(window, 'scroll', refresh);
316
- EventListener.listen(window, 'resize', refresh);
341
+ ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh);
317
342
  isMonitoringScrollValue = true;
318
343
  }
319
344
  },
@@ -328,12 +353,8 @@ var ReactEventEmitter = merge(ReactEventEmitterMixin, {
328
353
 
329
354
  deleteListener: EventPluginHub.deleteListener,
330
355
 
331
- deleteAllListeners: EventPluginHub.deleteAllListeners,
332
-
333
- trapBubbledEvent: trapBubbledEvent,
334
-
335
- trapCapturedEvent: trapCapturedEvent
356
+ deleteAllListeners: EventPluginHub.deleteAllListeners
336
357
 
337
358
  });
338
359
 
339
- module.exports = ReactEventEmitter;
360
+ module.exports = ReactBrowserEventEmitter;