@samitouri / QOS-React-2 / commits / 4deb0d619c
Fork 0

The library for web and native user interfaces.

Fix Clicks in Mobile Safari

This works around a bug with listening to clicks using event delegation on Mobile Safari using an event plugin. NOTE: We don't enable touch events by default, so I don't know if would want to inject this plugin by default. In fact, I'm not sure what our strategy is at all for when to invoke `React.useTouchEvents(true)`.

Tim Yung committed Jul 22, 2013 at 18:28 UTC 4deb0d619c06e8f0d30f972a6412d65f19b7f921
3 files changed +68 -2
src/core/ReactDefaultInjection.js
+3 -1
@@ -34,6 +34,7 @@ var ChangeEventPlugin = require('ChangeEventPlugin');
34 var EventPluginHub = require('EventPluginHub');
35 var ReactInstanceHandles = require('ReactInstanceHandles');
36 var SimpleEventPlugin = require('SimpleEventPlugin');
37 +var MobileSafariClickEventPlugin = require('MobileSafariClickEventPlugin');
38
39 function inject() {
40 /**
@@ -49,7 +50,8 @@ function inject() {
50 EventPluginHub.injection.injectEventPluginsByName({
51 'SimpleEventPlugin': SimpleEventPlugin,
52 'EnterLeaveEventPlugin': EnterLeaveEventPlugin,
52 - 'ChangeEventPlugin': ChangeEventPlugin
53 + 'ChangeEventPlugin': ChangeEventPlugin,
54 + 'MobileSafariClickEventPlugin': MobileSafariClickEventPlugin
55 });
56
57 ReactDOM.injection.injectComponentClasses({
src/eventPlugins/DefaultEventPluginOrder.js
+2 -1
@@ -35,7 +35,8 @@ var DefaultEventPluginOrder = [
35 keyOf({TapEventPlugin: null}),
36 keyOf({EnterLeaveEventPlugin: null}),
37 keyOf({ChangeEventPlugin: null}),
38 - keyOf({AnalyticsEventPlugin: null})
38 + keyOf({AnalyticsEventPlugin: null}),
39 + keyOf({MobileSafariClickEventPlugin: null})
40 ];
41
42 module.exports = DefaultEventPluginOrder;
src/eventPlugins/MobileSafariClickEventPlugin.js new
+63
@@ -0,0 +1,63 @@
1 +/**
2 + * Copyright 2013 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 MobileSafariClickEventPlugin
17 + * @typechecks static-only
18 + */
19 +
20 +"use strict";
21 +
22 +var EventConstants = require('EventConstants');
23 +
24 +var emptyFunction = require('emptyFunction');
25 +
26 +var topLevelTypes = EventConstants.topLevelTypes;
27 +
28 +/**
29 + * Mobile Safari does not fire properly bubble click events on non-interactive
30 + * elements, which means delegated click listeners do not fire. The workaround
31 + * for this bug involves attaching an empty click listener on the target node.
32 + *
33 + * This particular plugin works around the bug by attaching an empty click
34 + * listener on `touchstart` (which does fire on every element).
35 + */
36 +var MobileSafariClickEventPlugin = {
37 +
38 + eventTypes: null,
39 +
40 + /**
41 + * @param {string} topLevelType Record from `EventConstants`.
42 + * @param {DOMEventTarget} topLevelTarget The listening component root node.
43 + * @param {string} topLevelTargetID ID of `topLevelTarget`.
44 + * @param {object} nativeEvent Native browser event.
45 + * @return {*} An accumulation of synthetic events.
46 + * @see {EventPluginHub.extractEvents}
47 + */
48 + extractEvents: function(
49 + topLevelType,
50 + topLevelTarget,
51 + topLevelTargetID,
52 + nativeEvent) {
53 + if (topLevelType === topLevelTypes.topTouchStart) {
54 + var target = nativeEvent.target;
55 + if (target && !target.onclick) {
56 + target.onclick = emptyFunction;
57 + }
58 + }
59 + }
60 +
61 +};
62 +
63 +module.exports = MobileSafariClickEventPlugin;