react 0.13.3 → 0.14.0-alpha1

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 (193) hide show
  1. package/addons.js +7 -0
  2. package/addons/CSSTransitionGroup.js +1 -0
  3. package/addons/LinkedStateMixin.js +1 -0
  4. package/addons/Perf.js +1 -0
  5. package/addons/PureRenderMixin.js +1 -0
  6. package/addons/TestUtils.js +1 -0
  7. package/addons/TransitionGroup.js +1 -0
  8. package/addons/batchedUpdates.js +1 -0
  9. package/addons/cloneWithProps.js +1 -0
  10. package/addons/createFragment.js +1 -0
  11. package/addons/renderSubtreeIntoContainer.js +1 -0
  12. package/addons/shallowCompare.js +1 -0
  13. package/addons/update.js +1 -0
  14. package/dist/JSXTransformer.js +3355 -1685
  15. package/dist/react-with-addons.js +3092 -5145
  16. package/dist/react-with-addons.min.js +6 -8
  17. package/dist/react.js +2772 -4594
  18. package/dist/react.min.js +5 -6
  19. package/lib/AutoFocusMixin.js +4 -3
  20. package/lib/BeforeInputEventPlugin.js +30 -118
  21. package/lib/CSSCore.js +12 -23
  22. package/lib/CSSProperty.js +4 -3
  23. package/lib/CSSPropertyOperations.js +14 -30
  24. package/lib/CallbackQueue.js +7 -10
  25. package/lib/ChangeEventPlugin.js +24 -88
  26. package/lib/ClientReactRootIndex.js +2 -2
  27. package/lib/DOMChildrenOperations.js +13 -33
  28. package/lib/DOMProperty.js +41 -65
  29. package/lib/DOMPropertyOperations.js +30 -51
  30. package/lib/Danger.js +19 -60
  31. package/lib/DefaultEventPluginOrder.js +2 -12
  32. package/lib/EnterLeaveEventPlugin.js +11 -33
  33. package/lib/EventConstants.js +2 -2
  34. package/lib/EventListener.js +11 -13
  35. package/lib/EventPluginHub.js +44 -47
  36. package/lib/EventPluginRegistry.js +18 -74
  37. package/lib/EventPluginUtils.js +27 -38
  38. package/lib/EventPropagators.js +23 -26
  39. package/lib/ExecutionEnvironment.js +4 -8
  40. package/lib/FallbackCompositionState.js +3 -3
  41. package/lib/HTMLDOMPropertyConfig.js +5 -17
  42. package/lib/LinkedStateMixin.js +3 -6
  43. package/lib/LinkedValueUtils.js +34 -64
  44. package/lib/LocalEventTrapMixin.js +9 -16
  45. package/lib/Object.assign.js +1 -1
  46. package/lib/PooledClass.js +8 -11
  47. package/lib/React.js +20 -38
  48. package/lib/ReactBrowserComponentMixin.js +9 -2
  49. package/lib/ReactBrowserEventEmitter.js +26 -82
  50. package/lib/ReactCSSTransitionGroup.js +13 -24
  51. package/lib/ReactCSSTransitionGroupChild.js +18 -28
  52. package/lib/ReactChildReconciler.js +11 -19
  53. package/lib/ReactChildren.js +7 -16
  54. package/lib/ReactClass.js +78 -231
  55. package/lib/ReactComponent.js +17 -51
  56. package/lib/ReactComponentBrowserEnvironment.js +4 -6
  57. package/lib/ReactComponentEnvironment.js +6 -12
  58. package/lib/ReactComponentWithPureRenderMixin.js +4 -5
  59. package/lib/ReactCompositeComponent.js +83 -318
  60. package/lib/ReactContext.js +2 -44
  61. package/lib/ReactCurrentOwner.js +1 -3
  62. package/lib/ReactDOM.js +3 -2
  63. package/lib/ReactDOMButton.js +3 -4
  64. package/lib/ReactDOMComponent.js +182 -148
  65. package/lib/ReactDOMForm.js +3 -3
  66. package/lib/ReactDOMIDOperations.js +11 -20
  67. package/lib/ReactDOMIframe.js +3 -3
  68. package/lib/ReactDOMImg.js +3 -3
  69. package/lib/ReactDOMInput.js +22 -35
  70. package/lib/ReactDOMOption.js +52 -10
  71. package/lib/ReactDOMSelect.js +50 -28
  72. package/lib/ReactDOMSelection.js +5 -20
  73. package/lib/ReactDOMTextComponent.js +17 -18
  74. package/lib/ReactDOMTextarea.js +15 -27
  75. package/lib/ReactDefaultBatchingStrategy.js +9 -13
  76. package/lib/ReactDefaultInjection.js +21 -40
  77. package/lib/ReactDefaultPerf.js +36 -69
  78. package/lib/ReactDefaultPerfAnalysis.js +8 -14
  79. package/lib/ReactElement.js +35 -72
  80. package/lib/ReactElementValidator.js +51 -110
  81. package/lib/ReactEmptyComponent.js +7 -11
  82. package/lib/ReactErrorUtils.js +2 -2
  83. package/lib/ReactEventEmitterMixin.js +3 -12
  84. package/lib/ReactEventListener.js +16 -38
  85. package/lib/ReactFragment.js +23 -54
  86. package/lib/ReactInjection.js +1 -1
  87. package/lib/ReactInputSelection.js +11 -21
  88. package/lib/ReactInstanceHandles.js +27 -57
  89. package/lib/ReactInstanceMap.js +5 -5
  90. package/lib/ReactLifeCycle.js +1 -1
  91. package/lib/ReactLink.js +2 -4
  92. package/lib/ReactMarkupChecksum.js +5 -10
  93. package/lib/ReactMount.js +136 -260
  94. package/lib/ReactMultiChild.js +19 -45
  95. package/lib/ReactMultiChildUpdateTypes.js +1 -1
  96. package/lib/ReactNativeComponent.js +7 -11
  97. package/lib/ReactOwner.js +7 -24
  98. package/lib/ReactPerf.js +8 -12
  99. package/lib/ReactPropTransferer.js +4 -4
  100. package/lib/ReactPropTypeLocationNames.js +2 -2
  101. package/lib/ReactPropTypeLocations.js +1 -1
  102. package/lib/ReactPropTypes.js +13 -46
  103. package/lib/ReactReconcileTransaction.js +9 -34
  104. package/lib/ReactReconciler.js +9 -19
  105. package/lib/ReactRef.js +5 -8
  106. package/lib/ReactRootIndex.js +2 -2
  107. package/lib/ReactServerRendering.js +7 -15
  108. package/lib/ReactServerRenderingTransaction.js +7 -32
  109. package/lib/ReactStateSetters.js +6 -6
  110. package/lib/ReactTestUtils.js +89 -165
  111. package/lib/ReactTransitionChildMapping.js +5 -7
  112. package/lib/ReactTransitionEvents.js +5 -5
  113. package/lib/ReactTransitionGroup.js +30 -52
  114. package/lib/ReactUpdateQueue.js +27 -90
  115. package/lib/ReactUpdates.js +27 -79
  116. package/lib/ReactWithAddons.js +7 -6
  117. package/lib/SVGDOMPropertyConfig.js +39 -2
  118. package/lib/SelectEventPlugin.js +28 -29
  119. package/lib/ServerReactRootIndex.js +2 -2
  120. package/lib/SimpleEventPlugin.js +136 -128
  121. package/lib/SyntheticClipboardEvent.js +3 -7
  122. package/lib/SyntheticCompositionEvent.js +3 -9
  123. package/lib/SyntheticDragEvent.js +1 -1
  124. package/lib/SyntheticEvent.js +8 -10
  125. package/lib/SyntheticFocusEvent.js +1 -1
  126. package/lib/SyntheticInputEvent.js +3 -9
  127. package/lib/SyntheticKeyboardEvent.js +4 -4
  128. package/lib/SyntheticMouseEvent.js +8 -14
  129. package/lib/SyntheticTouchEvent.js +1 -1
  130. package/lib/SyntheticUIEvent.js +3 -3
  131. package/lib/SyntheticWheelEvent.js +11 -15
  132. package/lib/Transaction.js +12 -24
  133. package/lib/ViewportMetrics.js +2 -2
  134. package/lib/accumulateInto.js +2 -5
  135. package/lib/adler32.js +2 -2
  136. package/lib/camelize.js +4 -2
  137. package/lib/camelizeStyleName.js +2 -2
  138. package/lib/cloneWithProps.js +5 -11
  139. package/lib/containsNode.js +29 -16
  140. package/lib/createArrayFromMixed.js +17 -16
  141. package/lib/createFullPageComponent.js +4 -11
  142. package/lib/createNodesFromMarkup.js +6 -8
  143. package/lib/dangerousStyleValue.js +2 -3
  144. package/lib/emptyFunction.js +10 -4
  145. package/lib/emptyObject.js +1 -1
  146. package/lib/escapeTextContentForBrowser.js +1 -1
  147. package/lib/findDOMNode.js +5 -24
  148. package/lib/flattenChildren.js +4 -10
  149. package/lib/focusNode.js +2 -3
  150. package/lib/forEachAccumulated.js +2 -2
  151. package/lib/getActiveElement.js +4 -2
  152. package/lib/getEventCharCode.js +1 -1
  153. package/lib/getEventKey.js +1 -1
  154. package/lib/getEventModifierState.js +1 -1
  155. package/lib/getEventTarget.js +1 -1
  156. package/lib/getIteratorFn.js +2 -4
  157. package/lib/getMarkupWrap.js +5 -5
  158. package/lib/getNodeForCharacterOffset.js +1 -1
  159. package/lib/getTextContentAccessor.js +2 -4
  160. package/lib/getUnboundedScrollPosition.js +1 -1
  161. package/lib/hyphenate.js +3 -1
  162. package/lib/hyphenateStyleName.js +2 -2
  163. package/lib/instantiateReactComponent.js +14 -38
  164. package/lib/invariant.js +8 -12
  165. package/lib/isEventSupported.js +7 -10
  166. package/lib/isNode.js +4 -6
  167. package/lib/isTextInputElement.js +2 -4
  168. package/lib/isTextNode.js +3 -1
  169. package/lib/joinClasses.js +2 -2
  170. package/lib/keyMirror.js +3 -6
  171. package/lib/keyOf.js +4 -3
  172. package/lib/mapObject.js +1 -1
  173. package/lib/memoizeStringOnly.js +2 -2
  174. package/lib/onlyChild.js +2 -5
  175. package/lib/performance.js +2 -5
  176. package/lib/performanceNow.js +3 -1
  177. package/lib/quoteAttributeValueForBrowser.js +1 -1
  178. package/lib/renderSubtreeIntoContainer.js +16 -0
  179. package/lib/setInnerHTML.js +11 -8
  180. package/lib/setTextContent.js +3 -3
  181. package/lib/shallowCompare.js +24 -0
  182. package/lib/shallowEqual.js +17 -11
  183. package/lib/shouldUpdateReactComponent.js +3 -64
  184. package/lib/toArray.js +8 -19
  185. package/lib/traverseAllChildren.js +19 -82
  186. package/lib/update.js +25 -85
  187. package/lib/validateDOMNesting.js +264 -0
  188. package/lib/warning.js +17 -15
  189. package/package.json +3 -3
  190. package/lib/MobileSafariClickEventPlugin.js +0 -56
  191. package/lib/ReactPutListenerQueue.js +0 -54
  192. package/lib/cx.js +0 -52
  193. package/lib/getReactRootElementInContainer.js +0 -33
@@ -29,18 +29,14 @@ var asapEnqueued = false;
29
29
  var batchingStrategy = null;
30
30
 
31
31
  function ensureInjected() {
32
- ("production" !== process.env.NODE_ENV ? invariant(
33
- ReactUpdates.ReactReconcileTransaction && batchingStrategy,
34
- 'ReactUpdates: must inject a reconcile transaction class and batching ' +
35
- 'strategy'
36
- ) : invariant(ReactUpdates.ReactReconcileTransaction && batchingStrategy));
32
+ 'production' !== process.env.NODE_ENV ? invariant(ReactUpdates.ReactReconcileTransaction && batchingStrategy, 'ReactUpdates: must inject a reconcile transaction class and batching ' + 'strategy') : invariant(ReactUpdates.ReactReconcileTransaction && batchingStrategy);
37
33
  }
38
34
 
39
35
  var NESTED_UPDATES = {
40
- initialize: function() {
36
+ initialize: function () {
41
37
  this.dirtyComponentsLength = dirtyComponents.length;
42
38
  },
43
- close: function() {
39
+ close: function () {
44
40
  if (this.dirtyComponentsLength !== dirtyComponents.length) {
45
41
  // Additional updates were enqueued by componentDidUpdate handlers or
46
42
  // similar; before our own UPDATE_QUEUEING wrapper closes, we want to run
@@ -56,10 +52,10 @@ var NESTED_UPDATES = {
56
52
  };
57
53
 
58
54
  var UPDATE_QUEUEING = {
59
- initialize: function() {
55
+ initialize: function () {
60
56
  this.callbackQueue.reset();
61
57
  },
62
- close: function() {
58
+ close: function () {
63
59
  this.callbackQueue.notifyAll();
64
60
  }
65
61
  };
@@ -70,18 +66,15 @@ function ReactUpdatesFlushTransaction() {
70
66
  this.reinitializeTransaction();
71
67
  this.dirtyComponentsLength = null;
72
68
  this.callbackQueue = CallbackQueue.getPooled();
73
- this.reconcileTransaction =
74
- ReactUpdates.ReactReconcileTransaction.getPooled();
69
+ this.reconcileTransaction = ReactUpdates.ReactReconcileTransaction.getPooled();
75
70
  }
76
71
 
77
- assign(
78
- ReactUpdatesFlushTransaction.prototype,
79
- Transaction.Mixin, {
80
- getTransactionWrappers: function() {
72
+ assign(ReactUpdatesFlushTransaction.prototype, Transaction.Mixin, {
73
+ getTransactionWrappers: function () {
81
74
  return TRANSACTION_WRAPPERS;
82
75
  },
83
76
 
84
- destructor: function() {
77
+ destructor: function () {
85
78
  this.dirtyComponentsLength = null;
86
79
  CallbackQueue.release(this.callbackQueue);
87
80
  this.callbackQueue = null;
@@ -89,25 +82,18 @@ assign(
89
82
  this.reconcileTransaction = null;
90
83
  },
91
84
 
92
- perform: function(method, scope, a) {
85
+ perform: function (method, scope, a) {
93
86
  // Essentially calls `this.reconcileTransaction.perform(method, scope, a)`
94
87
  // with this transaction's wrappers around it.
95
- return Transaction.Mixin.perform.call(
96
- this,
97
- this.reconcileTransaction.perform,
98
- this.reconcileTransaction,
99
- method,
100
- scope,
101
- a
102
- );
88
+ return Transaction.Mixin.perform.call(this, this.reconcileTransaction.perform, this.reconcileTransaction, method, scope, a);
103
89
  }
104
90
  });
105
91
 
106
92
  PooledClass.addPoolingTo(ReactUpdatesFlushTransaction);
107
93
 
108
- function batchedUpdates(callback, a, b, c, d) {
94
+ function batchedUpdates(callback, a, b, c, d, e) {
109
95
  ensureInjected();
110
- batchingStrategy.batchedUpdates(callback, a, b, c, d);
96
+ batchingStrategy.batchedUpdates(callback, a, b, c, d, e);
111
97
  }
112
98
 
113
99
  /**
@@ -123,13 +109,7 @@ function mountOrderComparator(c1, c2) {
123
109
 
124
110
  function runBatchedUpdates(transaction) {
125
111
  var len = transaction.dirtyComponentsLength;
126
- ("production" !== process.env.NODE_ENV ? invariant(
127
- len === dirtyComponents.length,
128
- 'Expected flush transaction\'s stored dirty-components length (%s) to ' +
129
- 'match dirty-components array length (%s).',
130
- len,
131
- dirtyComponents.length
132
- ) : invariant(len === dirtyComponents.length));
112
+ 'production' !== process.env.NODE_ENV ? invariant(len === dirtyComponents.length, 'Expected flush transaction\'s stored dirty-components length (%s) to ' + 'match dirty-components array length (%s).', len, dirtyComponents.length) : invariant(len === dirtyComponents.length);
133
113
 
134
114
  // Since reconciling a component higher in the owner hierarchy usually (not
135
115
  // always -- see shouldComponentUpdate()) will reconcile children, reconcile
@@ -148,23 +128,17 @@ function runBatchedUpdates(transaction) {
148
128
  var callbacks = component._pendingCallbacks;
149
129
  component._pendingCallbacks = null;
150
130
 
151
- ReactReconciler.performUpdateIfNecessary(
152
- component,
153
- transaction.reconcileTransaction
154
- );
131
+ ReactReconciler.performUpdateIfNecessary(component, transaction.reconcileTransaction);
155
132
 
156
133
  if (callbacks) {
157
134
  for (var j = 0; j < callbacks.length; j++) {
158
- transaction.callbackQueue.enqueue(
159
- callbacks[j],
160
- component.getPublicInstance()
161
- );
135
+ transaction.callbackQueue.enqueue(callbacks[j], component.getPublicInstance());
162
136
  }
163
137
  }
164
138
  }
165
139
  }
166
140
 
167
- var flushBatchedUpdates = function() {
141
+ var flushBatchedUpdates = function () {
168
142
  // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents
169
143
  // array and perform any updates enqueued by mount-ready handlers (i.e.,
170
144
  // componentDidUpdate) but we need to check here too in order to catch
@@ -185,11 +159,7 @@ var flushBatchedUpdates = function() {
185
159
  }
186
160
  }
187
161
  };
188
- flushBatchedUpdates = ReactPerf.measure(
189
- 'ReactUpdates',
190
- 'flushBatchedUpdates',
191
- flushBatchedUpdates
192
- );
162
+ flushBatchedUpdates = ReactPerf.measure('ReactUpdates', 'flushBatchedUpdates', flushBatchedUpdates);
193
163
 
194
164
  /**
195
165
  * Mark a component as needing a rerender, adding an optional callback to a
@@ -203,13 +173,7 @@ function enqueueUpdate(component) {
203
173
  // verify that that's the case. (This is called by each top-level update
204
174
  // function, like setProps, setState, forceUpdate, etc.; creation and
205
175
  // destruction of top-level components is guarded in ReactMount.)
206
- ("production" !== process.env.NODE_ENV ? warning(
207
- ReactCurrentOwner.current == null,
208
- 'enqueueUpdate(): Render methods should be a pure function of props ' +
209
- 'and state; triggering nested component updates from render is not ' +
210
- 'allowed. If necessary, trigger nested updates in ' +
211
- 'componentDidUpdate.'
212
- ) : null);
176
+ 'production' !== process.env.NODE_ENV ? warning(ReactCurrentOwner.current == null, 'enqueueUpdate(): Render methods should be a pure function of props ' + 'and state; triggering nested component updates from render is not ' + 'allowed. If necessary, trigger nested updates in ' + 'componentDidUpdate.') : null;
213
177
 
214
178
  if (!batchingStrategy.isBatchingUpdates) {
215
179
  batchingStrategy.batchedUpdates(enqueueUpdate, component);
@@ -224,37 +188,21 @@ function enqueueUpdate(component) {
224
188
  * if no updates are currently being performed.
225
189
  */
226
190
  function asap(callback, context) {
227
- ("production" !== process.env.NODE_ENV ? invariant(
228
- batchingStrategy.isBatchingUpdates,
229
- 'ReactUpdates.asap: Can\'t enqueue an asap callback in a context where' +
230
- 'updates are not being batched.'
231
- ) : invariant(batchingStrategy.isBatchingUpdates));
191
+ 'production' !== process.env.NODE_ENV ? invariant(batchingStrategy.isBatchingUpdates, 'ReactUpdates.asap: Can\'t enqueue an asap callback in a context where' + 'updates are not being batched.') : invariant(batchingStrategy.isBatchingUpdates);
232
192
  asapCallbackQueue.enqueue(callback, context);
233
193
  asapEnqueued = true;
234
194
  }
235
195
 
236
196
  var ReactUpdatesInjection = {
237
- injectReconcileTransaction: function(ReconcileTransaction) {
238
- ("production" !== process.env.NODE_ENV ? invariant(
239
- ReconcileTransaction,
240
- 'ReactUpdates: must provide a reconcile transaction class'
241
- ) : invariant(ReconcileTransaction));
197
+ injectReconcileTransaction: function (ReconcileTransaction) {
198
+ 'production' !== process.env.NODE_ENV ? invariant(ReconcileTransaction, 'ReactUpdates: must provide a reconcile transaction class') : invariant(ReconcileTransaction);
242
199
  ReactUpdates.ReactReconcileTransaction = ReconcileTransaction;
243
200
  },
244
201
 
245
- injectBatchingStrategy: function(_batchingStrategy) {
246
- ("production" !== process.env.NODE_ENV ? invariant(
247
- _batchingStrategy,
248
- 'ReactUpdates: must provide a batching strategy'
249
- ) : invariant(_batchingStrategy));
250
- ("production" !== process.env.NODE_ENV ? invariant(
251
- typeof _batchingStrategy.batchedUpdates === 'function',
252
- 'ReactUpdates: must provide a batchedUpdates() function'
253
- ) : invariant(typeof _batchingStrategy.batchedUpdates === 'function'));
254
- ("production" !== process.env.NODE_ENV ? invariant(
255
- typeof _batchingStrategy.isBatchingUpdates === 'boolean',
256
- 'ReactUpdates: must provide an isBatchingUpdates boolean attribute'
257
- ) : invariant(typeof _batchingStrategy.isBatchingUpdates === 'boolean'));
202
+ injectBatchingStrategy: function (_batchingStrategy) {
203
+ 'production' !== process.env.NODE_ENV ? invariant(_batchingStrategy, 'ReactUpdates: must provide a batching strategy') : invariant(_batchingStrategy);
204
+ 'production' !== process.env.NODE_ENV ? invariant(typeof _batchingStrategy.batchedUpdates === 'function', 'ReactUpdates: must provide a batchedUpdates() function') : invariant(typeof _batchingStrategy.batchedUpdates === 'function');
205
+ 'production' !== process.env.NODE_ENV ? invariant(typeof _batchingStrategy.isBatchingUpdates === 'boolean', 'ReactUpdates: must provide an isBatchingUpdates boolean attribute') : invariant(typeof _batchingStrategy.isBatchingUpdates === 'boolean');
258
206
  batchingStrategy = _batchingStrategy;
259
207
  }
260
208
  };
@@ -275,4 +223,4 @@ var ReactUpdates = {
275
223
  asap: asap
276
224
  };
277
225
 
278
- module.exports = ReactUpdates;
226
+ module.exports = ReactUpdates;
@@ -20,15 +20,15 @@
20
20
 
21
21
  var LinkedStateMixin = require("./LinkedStateMixin");
22
22
  var React = require("./React");
23
- var ReactComponentWithPureRenderMixin =
24
- require("./ReactComponentWithPureRenderMixin");
23
+ var ReactComponentWithPureRenderMixin = require("./ReactComponentWithPureRenderMixin");
25
24
  var ReactCSSTransitionGroup = require("./ReactCSSTransitionGroup");
26
25
  var ReactFragment = require("./ReactFragment");
27
26
  var ReactTransitionGroup = require("./ReactTransitionGroup");
28
27
  var ReactUpdates = require("./ReactUpdates");
29
28
 
30
- var cx = require("./cx");
31
29
  var cloneWithProps = require("./cloneWithProps");
30
+ var renderSubtreeIntoContainer = require("./renderSubtreeIntoContainer");
31
+ var shallowCompare = require("./shallowCompare");
32
32
  var update = require("./update");
33
33
 
34
34
  React.addons = {
@@ -38,15 +38,16 @@ React.addons = {
38
38
  TransitionGroup: ReactTransitionGroup,
39
39
 
40
40
  batchedUpdates: ReactUpdates.batchedUpdates,
41
- classSet: cx,
42
41
  cloneWithProps: cloneWithProps,
43
42
  createFragment: ReactFragment.create,
43
+ renderSubtreeIntoContainer: renderSubtreeIntoContainer,
44
+ shallowCompare: shallowCompare,
44
45
  update: update
45
46
  };
46
47
 
47
- if ("production" !== process.env.NODE_ENV) {
48
+ if ('production' !== process.env.NODE_ENV) {
48
49
  React.addons.Perf = require("./ReactDefaultPerf");
49
50
  React.addons.TestUtils = require("./ReactTestUtils");
50
51
  }
51
52
 
52
- module.exports = React;
53
+ module.exports = React;
@@ -17,6 +17,11 @@ var DOMProperty = require("./DOMProperty");
17
17
 
18
18
  var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE;
19
19
 
20
+ var NS = {
21
+ xlink: 'http://www.w3.org/1999/xlink',
22
+ xml: 'http://www.w3.org/XML/1998/namespace'
23
+ };
24
+
20
25
  var SVGDOMPropertyConfig = {
21
26
  Properties: {
22
27
  clipPath: MUST_USE_ATTRIBUTE,
@@ -60,10 +65,32 @@ var SVGDOMPropertyConfig = {
60
65
  x1: MUST_USE_ATTRIBUTE,
61
66
  x2: MUST_USE_ATTRIBUTE,
62
67
  x: MUST_USE_ATTRIBUTE,
68
+ xlinkActuate: MUST_USE_ATTRIBUTE,
69
+ xlinkArcrole: MUST_USE_ATTRIBUTE,
70
+ xlinkHref: MUST_USE_ATTRIBUTE,
71
+ xlinkRole: MUST_USE_ATTRIBUTE,
72
+ xlinkShow: MUST_USE_ATTRIBUTE,
73
+ xlinkTitle: MUST_USE_ATTRIBUTE,
74
+ xlinkType: MUST_USE_ATTRIBUTE,
75
+ xmlBase: MUST_USE_ATTRIBUTE,
76
+ xmlLang: MUST_USE_ATTRIBUTE,
77
+ xmlSpace: MUST_USE_ATTRIBUTE,
63
78
  y1: MUST_USE_ATTRIBUTE,
64
79
  y2: MUST_USE_ATTRIBUTE,
65
80
  y: MUST_USE_ATTRIBUTE
66
81
  },
82
+ DOMAttributeNamespaces: {
83
+ xlinkActuate: NS.xlink,
84
+ xlinkArcrole: NS.xlink,
85
+ xlinkHref: NS.xlink,
86
+ xlinkRole: NS.xlink,
87
+ xlinkShow: NS.xlink,
88
+ xlinkTitle: NS.xlink,
89
+ xlinkType: NS.xlink,
90
+ xmlBase: NS.xml,
91
+ xmlLang: NS.xml,
92
+ xmlSpace: NS.xml
93
+ },
67
94
  DOMAttributeNames: {
68
95
  clipPath: 'clip-path',
69
96
  fillOpacity: 'fill-opacity',
@@ -85,8 +112,18 @@ var SVGDOMPropertyConfig = {
85
112
  strokeOpacity: 'stroke-opacity',
86
113
  strokeWidth: 'stroke-width',
87
114
  textAnchor: 'text-anchor',
88
- viewBox: 'viewBox'
115
+ viewBox: 'viewBox',
116
+ xlinkActuate: 'xlink:actuate',
117
+ xlinkArcrole: 'xlink:arcrole',
118
+ xlinkHref: 'xlink:href',
119
+ xlinkRole: 'xlink:role',
120
+ xlinkShow: 'xlink:show',
121
+ xlinkTitle: 'xlink:title',
122
+ xlinkType: 'xlink:type',
123
+ xmlBase: 'xml:base',
124
+ xmlLang: 'xml:lang',
125
+ xmlSpace: 'xml:space'
89
126
  }
90
127
  };
91
128
 
92
- module.exports = SVGDOMPropertyConfig;
129
+ module.exports = SVGDOMPropertyConfig;
@@ -26,18 +26,10 @@ var topLevelTypes = EventConstants.topLevelTypes;
26
26
  var eventTypes = {
27
27
  select: {
28
28
  phasedRegistrationNames: {
29
- bubbled: keyOf({onSelect: null}),
30
- captured: keyOf({onSelectCapture: null})
29
+ bubbled: keyOf({ onSelect: null }),
30
+ captured: keyOf({ onSelectCapture: null })
31
31
  },
32
- dependencies: [
33
- topLevelTypes.topBlur,
34
- topLevelTypes.topContextMenu,
35
- topLevelTypes.topFocus,
36
- topLevelTypes.topKeyDown,
37
- topLevelTypes.topMouseDown,
38
- topLevelTypes.topMouseUp,
39
- topLevelTypes.topSelectionChange
40
- ]
32
+ dependencies: [topLevelTypes.topBlur, topLevelTypes.topContextMenu, topLevelTypes.topFocus, topLevelTypes.topKeyDown, topLevelTypes.topMouseDown, topLevelTypes.topMouseUp, topLevelTypes.topSelectionChange]
41
33
  }
42
34
  };
43
35
 
@@ -46,6 +38,11 @@ var activeElementID = null;
46
38
  var lastSelection = null;
47
39
  var mouseDown = false;
48
40
 
41
+ // Track whether a listener exists for this plugin. If none exist, we do
42
+ // not extract events.
43
+ var hasListener = false;
44
+ var ON_SELECT_KEY = keyOf({ onSelect: null });
45
+
49
46
  /**
50
47
  * Get an object which is a unique representation of the current selection.
51
48
  *
@@ -56,8 +53,7 @@ var mouseDown = false;
56
53
  * @param {object}
57
54
  */
58
55
  function getSelection(node) {
59
- if ('selectionStart' in node &&
60
- ReactInputSelection.hasSelectionCapabilities(node)) {
56
+ if ('selectionStart' in node && ReactInputSelection.hasSelectionCapabilities(node)) {
61
57
  return {
62
58
  start: node.selectionStart,
63
59
  end: node.selectionEnd
@@ -92,9 +88,7 @@ function constructSelectEvent(nativeEvent) {
92
88
  // selection (this matches native `select` event behavior). In HTML5, select
93
89
  // fires only on input and textarea thus if there's no focused element we
94
90
  // won't dispatch.
95
- if (mouseDown ||
96
- activeElement == null ||
97
- activeElement !== getActiveElement()) {
91
+ if (mouseDown || activeElement == null || activeElement !== getActiveElement()) {
98
92
  return null;
99
93
  }
100
94
 
@@ -103,11 +97,7 @@ function constructSelectEvent(nativeEvent) {
103
97
  if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
104
98
  lastSelection = currentSelection;
105
99
 
106
- var syntheticEvent = SyntheticEvent.getPooled(
107
- eventTypes.select,
108
- activeElementID,
109
- nativeEvent
110
- );
100
+ var syntheticEvent = SyntheticEvent.getPooled(eventTypes.select, activeElementID, nativeEvent);
111
101
 
112
102
  syntheticEvent.type = 'select';
113
103
  syntheticEvent.target = activeElement;
@@ -116,6 +106,8 @@ function constructSelectEvent(nativeEvent) {
116
106
 
117
107
  return syntheticEvent;
118
108
  }
109
+
110
+ return null;
119
111
  }
120
112
 
121
113
  /**
@@ -144,17 +136,16 @@ var SelectEventPlugin = {
144
136
  * @return {*} An accumulation of synthetic events.
145
137
  * @see {EventPluginHub.extractEvents}
146
138
  */
147
- extractEvents: function(
148
- topLevelType,
149
- topLevelTarget,
150
- topLevelTargetID,
151
- nativeEvent) {
139
+ extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent) {
140
+
141
+ if (!hasListener) {
142
+ return null;
143
+ }
152
144
 
153
145
  switch (topLevelType) {
154
146
  // Track the input node that has focus.
155
147
  case topLevelTypes.topFocus:
156
- if (isTextInputElement(topLevelTarget) ||
157
- topLevelTarget.contentEditable === 'true') {
148
+ if (isTextInputElement(topLevelTarget) || topLevelTarget.contentEditable === 'true') {
158
149
  activeElement = topLevelTarget;
159
150
  activeElementID = topLevelTargetID;
160
151
  lastSelection = null;
@@ -187,7 +178,15 @@ var SelectEventPlugin = {
187
178
  case topLevelTypes.topKeyUp:
188
179
  return constructSelectEvent(nativeEvent);
189
180
  }
181
+
182
+ return null;
183
+ },
184
+
185
+ didPutListener: function (id, registrationName, listener) {
186
+ if (registrationName === ON_SELECT_KEY) {
187
+ hasListener = true;
188
+ }
190
189
  }
191
190
  };
192
191
 
193
- module.exports = SelectEventPlugin;
192
+ module.exports = SelectEventPlugin;
@@ -21,9 +21,9 @@
21
21
  var GLOBAL_MOUNT_POINT_MAX = Math.pow(2, 53);
22
22
 
23
23
  var ServerReactRootIndex = {
24
- createReactRootIndex: function() {
24
+ createReactRootIndex: function () {
25
25
  return Math.ceil(Math.random() * GLOBAL_MOUNT_POINT_MAX);
26
26
  }
27
27
  };
28
28
 
29
- module.exports = ServerReactRootIndex;
29
+ module.exports = ServerReactRootIndex;
@@ -12,8 +12,10 @@
12
12
  'use strict';
13
13
 
14
14
  var EventConstants = require("./EventConstants");
15
+ var EventListener = require("./EventListener");
15
16
  var EventPluginUtils = require("./EventPluginUtils");
16
17
  var EventPropagators = require("./EventPropagators");
18
+ var ReactMount = require("./ReactMount");
17
19
  var SyntheticClipboardEvent = require("./SyntheticClipboardEvent");
18
20
  var SyntheticEvent = require("./SyntheticEvent");
19
21
  var SyntheticFocusEvent = require("./SyntheticFocusEvent");
@@ -24,8 +26,8 @@ var SyntheticTouchEvent = require("./SyntheticTouchEvent");
24
26
  var SyntheticUIEvent = require("./SyntheticUIEvent");
25
27
  var SyntheticWheelEvent = require("./SyntheticWheelEvent");
26
28
 
29
+ var emptyFunction = require("./emptyFunction");
27
30
  var getEventCharCode = require("./getEventCharCode");
28
-
29
31
  var invariant = require("./invariant");
30
32
  var keyOf = require("./keyOf");
31
33
  var warning = require("./warning");
@@ -35,260 +37,263 @@ var topLevelTypes = EventConstants.topLevelTypes;
35
37
  var eventTypes = {
36
38
  blur: {
37
39
  phasedRegistrationNames: {
38
- bubbled: keyOf({onBlur: true}),
39
- captured: keyOf({onBlurCapture: true})
40
+ bubbled: keyOf({ onBlur: true }),
41
+ captured: keyOf({ onBlurCapture: true })
40
42
  }
41
43
  },
42
44
  click: {
43
45
  phasedRegistrationNames: {
44
- bubbled: keyOf({onClick: true}),
45
- captured: keyOf({onClickCapture: true})
46
+ bubbled: keyOf({ onClick: true }),
47
+ captured: keyOf({ onClickCapture: true })
46
48
  }
47
49
  },
48
50
  contextMenu: {
49
51
  phasedRegistrationNames: {
50
- bubbled: keyOf({onContextMenu: true}),
51
- captured: keyOf({onContextMenuCapture: true})
52
+ bubbled: keyOf({ onContextMenu: true }),
53
+ captured: keyOf({ onContextMenuCapture: true })
52
54
  }
53
55
  },
54
56
  copy: {
55
57
  phasedRegistrationNames: {
56
- bubbled: keyOf({onCopy: true}),
57
- captured: keyOf({onCopyCapture: true})
58
+ bubbled: keyOf({ onCopy: true }),
59
+ captured: keyOf({ onCopyCapture: true })
58
60
  }
59
61
  },
60
62
  cut: {
61
63
  phasedRegistrationNames: {
62
- bubbled: keyOf({onCut: true}),
63
- captured: keyOf({onCutCapture: true})
64
+ bubbled: keyOf({ onCut: true }),
65
+ captured: keyOf({ onCutCapture: true })
64
66
  }
65
67
  },
66
68
  doubleClick: {
67
69
  phasedRegistrationNames: {
68
- bubbled: keyOf({onDoubleClick: true}),
69
- captured: keyOf({onDoubleClickCapture: true})
70
+ bubbled: keyOf({ onDoubleClick: true }),
71
+ captured: keyOf({ onDoubleClickCapture: true })
70
72
  }
71
73
  },
72
74
  drag: {
73
75
  phasedRegistrationNames: {
74
- bubbled: keyOf({onDrag: true}),
75
- captured: keyOf({onDragCapture: true})
76
+ bubbled: keyOf({ onDrag: true }),
77
+ captured: keyOf({ onDragCapture: true })
76
78
  }
77
79
  },
78
80
  dragEnd: {
79
81
  phasedRegistrationNames: {
80
- bubbled: keyOf({onDragEnd: true}),
81
- captured: keyOf({onDragEndCapture: true})
82
+ bubbled: keyOf({ onDragEnd: true }),
83
+ captured: keyOf({ onDragEndCapture: true })
82
84
  }
83
85
  },
84
86
  dragEnter: {
85
87
  phasedRegistrationNames: {
86
- bubbled: keyOf({onDragEnter: true}),
87
- captured: keyOf({onDragEnterCapture: true})
88
+ bubbled: keyOf({ onDragEnter: true }),
89
+ captured: keyOf({ onDragEnterCapture: true })
88
90
  }
89
91
  },
90
92
  dragExit: {
91
93
  phasedRegistrationNames: {
92
- bubbled: keyOf({onDragExit: true}),
93
- captured: keyOf({onDragExitCapture: true})
94
+ bubbled: keyOf({ onDragExit: true }),
95
+ captured: keyOf({ onDragExitCapture: true })
94
96
  }
95
97
  },
96
98
  dragLeave: {
97
99
  phasedRegistrationNames: {
98
- bubbled: keyOf({onDragLeave: true}),
99
- captured: keyOf({onDragLeaveCapture: true})
100
+ bubbled: keyOf({ onDragLeave: true }),
101
+ captured: keyOf({ onDragLeaveCapture: true })
100
102
  }
101
103
  },
102
104
  dragOver: {
103
105
  phasedRegistrationNames: {
104
- bubbled: keyOf({onDragOver: true}),
105
- captured: keyOf({onDragOverCapture: true})
106
+ bubbled: keyOf({ onDragOver: true }),
107
+ captured: keyOf({ onDragOverCapture: true })
106
108
  }
107
109
  },
108
110
  dragStart: {
109
111
  phasedRegistrationNames: {
110
- bubbled: keyOf({onDragStart: true}),
111
- captured: keyOf({onDragStartCapture: true})
112
+ bubbled: keyOf({ onDragStart: true }),
113
+ captured: keyOf({ onDragStartCapture: true })
112
114
  }
113
115
  },
114
116
  drop: {
115
117
  phasedRegistrationNames: {
116
- bubbled: keyOf({onDrop: true}),
117
- captured: keyOf({onDropCapture: true})
118
+ bubbled: keyOf({ onDrop: true }),
119
+ captured: keyOf({ onDropCapture: true })
118
120
  }
119
121
  },
120
122
  focus: {
121
123
  phasedRegistrationNames: {
122
- bubbled: keyOf({onFocus: true}),
123
- captured: keyOf({onFocusCapture: true})
124
+ bubbled: keyOf({ onFocus: true }),
125
+ captured: keyOf({ onFocusCapture: true })
124
126
  }
125
127
  },
126
128
  input: {
127
129
  phasedRegistrationNames: {
128
- bubbled: keyOf({onInput: true}),
129
- captured: keyOf({onInputCapture: true})
130
+ bubbled: keyOf({ onInput: true }),
131
+ captured: keyOf({ onInputCapture: true })
130
132
  }
131
133
  },
132
134
  keyDown: {
133
135
  phasedRegistrationNames: {
134
- bubbled: keyOf({onKeyDown: true}),
135
- captured: keyOf({onKeyDownCapture: true})
136
+ bubbled: keyOf({ onKeyDown: true }),
137
+ captured: keyOf({ onKeyDownCapture: true })
136
138
  }
137
139
  },
138
140
  keyPress: {
139
141
  phasedRegistrationNames: {
140
- bubbled: keyOf({onKeyPress: true}),
141
- captured: keyOf({onKeyPressCapture: true})
142
+ bubbled: keyOf({ onKeyPress: true }),
143
+ captured: keyOf({ onKeyPressCapture: true })
142
144
  }
143
145
  },
144
146
  keyUp: {
145
147
  phasedRegistrationNames: {
146
- bubbled: keyOf({onKeyUp: true}),
147
- captured: keyOf({onKeyUpCapture: true})
148
+ bubbled: keyOf({ onKeyUp: true }),
149
+ captured: keyOf({ onKeyUpCapture: true })
148
150
  }
149
151
  },
150
152
  load: {
151
153
  phasedRegistrationNames: {
152
- bubbled: keyOf({onLoad: true}),
153
- captured: keyOf({onLoadCapture: true})
154
+ bubbled: keyOf({ onLoad: true }),
155
+ captured: keyOf({ onLoadCapture: true })
154
156
  }
155
157
  },
156
158
  error: {
157
159
  phasedRegistrationNames: {
158
- bubbled: keyOf({onError: true}),
159
- captured: keyOf({onErrorCapture: true})
160
+ bubbled: keyOf({ onError: true }),
161
+ captured: keyOf({ onErrorCapture: true })
160
162
  }
161
163
  },
162
164
  // Note: We do not allow listening to mouseOver events. Instead, use the
163
165
  // onMouseEnter/onMouseLeave created by `EnterLeaveEventPlugin`.
164
166
  mouseDown: {
165
167
  phasedRegistrationNames: {
166
- bubbled: keyOf({onMouseDown: true}),
167
- captured: keyOf({onMouseDownCapture: true})
168
+ bubbled: keyOf({ onMouseDown: true }),
169
+ captured: keyOf({ onMouseDownCapture: true })
168
170
  }
169
171
  },
170
172
  mouseMove: {
171
173
  phasedRegistrationNames: {
172
- bubbled: keyOf({onMouseMove: true}),
173
- captured: keyOf({onMouseMoveCapture: true})
174
+ bubbled: keyOf({ onMouseMove: true }),
175
+ captured: keyOf({ onMouseMoveCapture: true })
174
176
  }
175
177
  },
176
178
  mouseOut: {
177
179
  phasedRegistrationNames: {
178
- bubbled: keyOf({onMouseOut: true}),
179
- captured: keyOf({onMouseOutCapture: true})
180
+ bubbled: keyOf({ onMouseOut: true }),
181
+ captured: keyOf({ onMouseOutCapture: true })
180
182
  }
181
183
  },
182
184
  mouseOver: {
183
185
  phasedRegistrationNames: {
184
- bubbled: keyOf({onMouseOver: true}),
185
- captured: keyOf({onMouseOverCapture: true})
186
+ bubbled: keyOf({ onMouseOver: true }),
187
+ captured: keyOf({ onMouseOverCapture: true })
186
188
  }
187
189
  },
188
190
  mouseUp: {
189
191
  phasedRegistrationNames: {
190
- bubbled: keyOf({onMouseUp: true}),
191
- captured: keyOf({onMouseUpCapture: true})
192
+ bubbled: keyOf({ onMouseUp: true }),
193
+ captured: keyOf({ onMouseUpCapture: true })
192
194
  }
193
195
  },
194
196
  paste: {
195
197
  phasedRegistrationNames: {
196
- bubbled: keyOf({onPaste: true}),
197
- captured: keyOf({onPasteCapture: true})
198
+ bubbled: keyOf({ onPaste: true }),
199
+ captured: keyOf({ onPasteCapture: true })
198
200
  }
199
201
  },
200
202
  reset: {
201
203
  phasedRegistrationNames: {
202
- bubbled: keyOf({onReset: true}),
203
- captured: keyOf({onResetCapture: true})
204
+ bubbled: keyOf({ onReset: true }),
205
+ captured: keyOf({ onResetCapture: true })
204
206
  }
205
207
  },
206
208
  scroll: {
207
209
  phasedRegistrationNames: {
208
- bubbled: keyOf({onScroll: true}),
209
- captured: keyOf({onScrollCapture: true})
210
+ bubbled: keyOf({ onScroll: true }),
211
+ captured: keyOf({ onScrollCapture: true })
210
212
  }
211
213
  },
212
214
  submit: {
213
215
  phasedRegistrationNames: {
214
- bubbled: keyOf({onSubmit: true}),
215
- captured: keyOf({onSubmitCapture: true})
216
+ bubbled: keyOf({ onSubmit: true }),
217
+ captured: keyOf({ onSubmitCapture: true })
216
218
  }
217
219
  },
218
220
  touchCancel: {
219
221
  phasedRegistrationNames: {
220
- bubbled: keyOf({onTouchCancel: true}),
221
- captured: keyOf({onTouchCancelCapture: true})
222
+ bubbled: keyOf({ onTouchCancel: true }),
223
+ captured: keyOf({ onTouchCancelCapture: true })
222
224
  }
223
225
  },
224
226
  touchEnd: {
225
227
  phasedRegistrationNames: {
226
- bubbled: keyOf({onTouchEnd: true}),
227
- captured: keyOf({onTouchEndCapture: true})
228
+ bubbled: keyOf({ onTouchEnd: true }),
229
+ captured: keyOf({ onTouchEndCapture: true })
228
230
  }
229
231
  },
230
232
  touchMove: {
231
233
  phasedRegistrationNames: {
232
- bubbled: keyOf({onTouchMove: true}),
233
- captured: keyOf({onTouchMoveCapture: true})
234
+ bubbled: keyOf({ onTouchMove: true }),
235
+ captured: keyOf({ onTouchMoveCapture: true })
234
236
  }
235
237
  },
236
238
  touchStart: {
237
239
  phasedRegistrationNames: {
238
- bubbled: keyOf({onTouchStart: true}),
239
- captured: keyOf({onTouchStartCapture: true})
240
+ bubbled: keyOf({ onTouchStart: true }),
241
+ captured: keyOf({ onTouchStartCapture: true })
240
242
  }
241
243
  },
242
244
  wheel: {
243
245
  phasedRegistrationNames: {
244
- bubbled: keyOf({onWheel: true}),
245
- captured: keyOf({onWheelCapture: true})
246
+ bubbled: keyOf({ onWheel: true }),
247
+ captured: keyOf({ onWheelCapture: true })
246
248
  }
247
249
  }
248
250
  };
249
251
 
250
252
  var topLevelEventsToDispatchConfig = {
251
- topBlur: eventTypes.blur,
252
- topClick: eventTypes.click,
253
+ topBlur: eventTypes.blur,
254
+ topClick: eventTypes.click,
253
255
  topContextMenu: eventTypes.contextMenu,
254
- topCopy: eventTypes.copy,
255
- topCut: eventTypes.cut,
256
+ topCopy: eventTypes.copy,
257
+ topCut: eventTypes.cut,
256
258
  topDoubleClick: eventTypes.doubleClick,
257
- topDrag: eventTypes.drag,
258
- topDragEnd: eventTypes.dragEnd,
259
- topDragEnter: eventTypes.dragEnter,
260
- topDragExit: eventTypes.dragExit,
261
- topDragLeave: eventTypes.dragLeave,
262
- topDragOver: eventTypes.dragOver,
263
- topDragStart: eventTypes.dragStart,
264
- topDrop: eventTypes.drop,
265
- topError: eventTypes.error,
266
- topFocus: eventTypes.focus,
267
- topInput: eventTypes.input,
268
- topKeyDown: eventTypes.keyDown,
269
- topKeyPress: eventTypes.keyPress,
270
- topKeyUp: eventTypes.keyUp,
271
- topLoad: eventTypes.load,
272
- topMouseDown: eventTypes.mouseDown,
273
- topMouseMove: eventTypes.mouseMove,
274
- topMouseOut: eventTypes.mouseOut,
275
- topMouseOver: eventTypes.mouseOver,
276
- topMouseUp: eventTypes.mouseUp,
277
- topPaste: eventTypes.paste,
278
- topReset: eventTypes.reset,
279
- topScroll: eventTypes.scroll,
280
- topSubmit: eventTypes.submit,
259
+ topDrag: eventTypes.drag,
260
+ topDragEnd: eventTypes.dragEnd,
261
+ topDragEnter: eventTypes.dragEnter,
262
+ topDragExit: eventTypes.dragExit,
263
+ topDragLeave: eventTypes.dragLeave,
264
+ topDragOver: eventTypes.dragOver,
265
+ topDragStart: eventTypes.dragStart,
266
+ topDrop: eventTypes.drop,
267
+ topError: eventTypes.error,
268
+ topFocus: eventTypes.focus,
269
+ topInput: eventTypes.input,
270
+ topKeyDown: eventTypes.keyDown,
271
+ topKeyPress: eventTypes.keyPress,
272
+ topKeyUp: eventTypes.keyUp,
273
+ topLoad: eventTypes.load,
274
+ topMouseDown: eventTypes.mouseDown,
275
+ topMouseMove: eventTypes.mouseMove,
276
+ topMouseOut: eventTypes.mouseOut,
277
+ topMouseOver: eventTypes.mouseOver,
278
+ topMouseUp: eventTypes.mouseUp,
279
+ topPaste: eventTypes.paste,
280
+ topReset: eventTypes.reset,
281
+ topScroll: eventTypes.scroll,
282
+ topSubmit: eventTypes.submit,
281
283
  topTouchCancel: eventTypes.touchCancel,
282
- topTouchEnd: eventTypes.touchEnd,
283
- topTouchMove: eventTypes.touchMove,
284
- topTouchStart: eventTypes.touchStart,
285
- topWheel: eventTypes.wheel
284
+ topTouchEnd: eventTypes.touchEnd,
285
+ topTouchMove: eventTypes.touchMove,
286
+ topTouchStart: eventTypes.touchStart,
287
+ topWheel: eventTypes.wheel
286
288
  };
287
289
 
288
290
  for (var type in topLevelEventsToDispatchConfig) {
289
291
  topLevelEventsToDispatchConfig[type].dependencies = [type];
290
292
  }
291
293
 
294
+ var ON_CLICK_KEY = keyOf({ onClick: null });
295
+ var onClickListeners = {};
296
+
292
297
  var SimpleEventPlugin = {
293
298
 
294
299
  eventTypes: eventTypes,
@@ -301,15 +306,10 @@ var SimpleEventPlugin = {
301
306
  * @param {function} Application-level callback.
302
307
  * @param {string} domID DOM ID to pass to the callback.
303
308
  */
304
- executeDispatch: function(event, listener, domID) {
309
+ executeDispatch: function (event, listener, domID) {
305
310
  var returnValue = EventPluginUtils.executeDispatch(event, listener, domID);
306
311
 
307
- ("production" !== process.env.NODE_ENV ? warning(
308
- typeof returnValue !== 'boolean',
309
- 'Returning `false` from an event handler is deprecated and will be ' +
310
- 'ignored in a future release. Instead, manually call ' +
311
- 'e.stopPropagation() or e.preventDefault(), as appropriate.'
312
- ) : null);
312
+ 'production' !== process.env.NODE_ENV ? warning(typeof returnValue !== 'boolean', 'Returning `false` from an event handler is deprecated and will be ' + 'ignored in a future release. Instead, manually call ' + 'e.stopPropagation() or e.preventDefault(), as appropriate.') : null;
313
313
 
314
314
  if (returnValue === false) {
315
315
  event.stopPropagation();
@@ -325,11 +325,7 @@ var SimpleEventPlugin = {
325
325
  * @return {*} An accumulation of synthetic events.
326
326
  * @see {EventPluginHub.extractEvents}
327
327
  */
328
- extractEvents: function(
329
- topLevelType,
330
- topLevelTarget,
331
- topLevelTargetID,
332
- nativeEvent) {
328
+ extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent) {
333
329
  var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
334
330
  if (!dispatchConfig) {
335
331
  return null;
@@ -352,7 +348,7 @@ var SimpleEventPlugin = {
352
348
  if (getEventCharCode(nativeEvent) === 0) {
353
349
  return null;
354
350
  }
355
- /* falls through */
351
+ /* falls through */
356
352
  case topLevelTypes.topKeyDown:
357
353
  case topLevelTypes.topKeyUp:
358
354
  EventConstructor = SyntheticKeyboardEvent;
@@ -367,7 +363,7 @@ var SimpleEventPlugin = {
367
363
  if (nativeEvent.button === 2) {
368
364
  return null;
369
365
  }
370
- /* falls through */
366
+ /* falls through */
371
367
  case topLevelTypes.topContextMenu:
372
368
  case topLevelTypes.topDoubleClick:
373
369
  case topLevelTypes.topMouseDown:
@@ -405,20 +401,32 @@ var SimpleEventPlugin = {
405
401
  EventConstructor = SyntheticClipboardEvent;
406
402
  break;
407
403
  }
408
- ("production" !== process.env.NODE_ENV ? invariant(
409
- EventConstructor,
410
- 'SimpleEventPlugin: Unhandled event type, `%s`.',
411
- topLevelType
412
- ) : invariant(EventConstructor));
413
- var event = EventConstructor.getPooled(
414
- dispatchConfig,
415
- topLevelTargetID,
416
- nativeEvent
417
- );
404
+ 'production' !== process.env.NODE_ENV ? invariant(EventConstructor, 'SimpleEventPlugin: Unhandled event type, `%s`.', topLevelType) : invariant(EventConstructor);
405
+ var event = EventConstructor.getPooled(dispatchConfig, topLevelTargetID, nativeEvent);
418
406
  EventPropagators.accumulateTwoPhaseDispatches(event);
419
407
  return event;
408
+ },
409
+
410
+ didPutListener: function (id, registrationName, listener) {
411
+ // Mobile Safari does not fire properly bubble click events on
412
+ // non-interactive elements, which means delegated click listeners do not
413
+ // fire. The workaround for this bug involves attaching an empty click
414
+ // listener on the target node.
415
+ if (registrationName === ON_CLICK_KEY) {
416
+ var node = ReactMount.getNode(id);
417
+ if (!onClickListeners[id]) {
418
+ onClickListeners[id] = EventListener.listen(node, 'click', emptyFunction);
419
+ }
420
+ }
421
+ },
422
+
423
+ willDeleteListener: function (id, registrationName) {
424
+ if (registrationName === ON_CLICK_KEY) {
425
+ onClickListeners[id].remove();
426
+ delete onClickListeners[id];
427
+ }
420
428
  }
421
429
 
422
430
  };
423
431
 
424
- module.exports = SimpleEventPlugin;
432
+ module.exports = SimpleEventPlugin;