react-dom 16.10.2 → 16.13.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.
- package/build-info.json +5 -5
- package/cjs/react-dom-server.browser.development.js +411 -729
- package/cjs/react-dom-server.browser.production.min.js +41 -41
- package/cjs/react-dom-server.node.development.js +406 -720
- package/cjs/react-dom-server.node.production.min.js +40 -40
- package/cjs/react-dom-test-utils.development.js +200 -393
- package/cjs/react-dom-test-utils.production.min.js +22 -22
- package/cjs/react-dom-unstable-fizz.browser.development.js +11 -25
- package/cjs/react-dom-unstable-fizz.browser.production.min.js +3 -3
- package/cjs/react-dom-unstable-fizz.node.development.js +24 -27
- package/cjs/react-dom-unstable-fizz.node.production.min.js +4 -3
- package/cjs/react-dom-unstable-native-dependencies.development.js +203 -338
- package/cjs/react-dom-unstable-native-dependencies.production.min.js +23 -27
- package/cjs/react-dom.development.js +10451 -13365
- package/cjs/react-dom.production.min.js +280 -281
- package/cjs/react-dom.profiling.min.js +285 -285
- package/package.json +3 -3
- package/umd/react-dom-server.browser.development.js +3310 -3639
- package/umd/react-dom-server.browser.production.min.js +38 -38
- package/umd/react-dom-test-utils.development.js +1181 -1374
- package/umd/react-dom-test-utils.production.min.js +23 -23
- package/umd/react-dom-unstable-fizz.browser.development.js +105 -119
- package/umd/react-dom-unstable-fizz.browser.production.min.js +3 -3
- package/umd/react-dom-unstable-native-dependencies.development.js +1326 -1462
- package/umd/react-dom-unstable-native-dependencies.production.min.js +21 -22
- package/umd/react-dom.development.js +19905 -22830
- package/umd/react-dom.production.min.js +229 -234
- package/umd/react-dom.profiling.min.js +237 -241
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license React v16.
|
|
1
|
+
/** @license React v16.13.1
|
|
2
2
|
* react-dom-unstable-native-dependencies.development.js
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
@@ -10,1755 +10,1619 @@
|
|
|
10
10
|
'use strict';
|
|
11
11
|
|
|
12
12
|
(function (global, factory) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}(this, (function (ReactDOM,React) { 'use strict';
|
|
17
|
-
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
error.name = 'Invariant Violation';
|
|
27
|
-
return error;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Use invariant() to assert state which your program assumes to be true.
|
|
32
|
-
*
|
|
33
|
-
* Provide sprintf-style format (only %s is supported) and arguments
|
|
34
|
-
* to provide information about what broke and what you were
|
|
35
|
-
* expecting.
|
|
36
|
-
*
|
|
37
|
-
* The invariant message will be stripped in production, but the invariant
|
|
38
|
-
* will remain to ensure logic does not differ in production.
|
|
39
|
-
*/
|
|
40
|
-
|
|
41
|
-
{
|
|
42
|
-
// In DEV mode, we swap out invokeGuardedCallback for a special version
|
|
43
|
-
// that plays more nicely with the browser's DevTools. The idea is to preserve
|
|
44
|
-
// "Pause on exceptions" behavior. Because React wraps all user-provided
|
|
45
|
-
// functions in invokeGuardedCallback, and the production version of
|
|
46
|
-
// invokeGuardedCallback uses a try-catch, all user exceptions are treated
|
|
47
|
-
// like caught exceptions, and the DevTools won't pause unless the developer
|
|
48
|
-
// takes the extra step of enabling pause on caught exceptions. This is
|
|
49
|
-
// unintuitive, though, because even though React has caught the error, from
|
|
50
|
-
// the developer's perspective, the error is uncaught.
|
|
51
|
-
//
|
|
52
|
-
// To preserve the expected "Pause on exceptions" behavior, we don't use a
|
|
53
|
-
// try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
|
|
54
|
-
// DOM node, and call the user-provided callback from inside an event handler
|
|
55
|
-
// for that fake event. If the callback throws, the error is "captured" using
|
|
56
|
-
// a global event handler. But because the error happens in a different
|
|
57
|
-
// event loop context, it does not interrupt the normal program flow.
|
|
58
|
-
// Effectively, this gives us try-catch behavior without actually using
|
|
59
|
-
// try-catch. Neat!
|
|
60
|
-
// Check that the browser supports the APIs we need to implement our special
|
|
61
|
-
// DEV version of invokeGuardedCallback
|
|
62
|
-
if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
|
|
63
|
-
var fakeNode = document.createElement('react');
|
|
64
|
-
|
|
65
|
-
|
|
13
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react-dom'), require('react')) :
|
|
14
|
+
typeof define === 'function' && define.amd ? define(['react-dom', 'react'], factory) :
|
|
15
|
+
(global = global || self, global.ReactDOMUnstableNativeDependencies = factory(global.ReactDOM, global.React));
|
|
16
|
+
}(this, (function (ReactDOM, React) { 'use strict';
|
|
17
|
+
|
|
18
|
+
var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions.
|
|
19
|
+
// Current owner and dispatcher used to share the same ref,
|
|
20
|
+
// but PR #14548 split them out to better support the react-debug-tools package.
|
|
21
|
+
|
|
22
|
+
if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
|
|
23
|
+
ReactSharedInternals.ReactCurrentDispatcher = {
|
|
24
|
+
current: null
|
|
25
|
+
};
|
|
66
26
|
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Call a function while guarding against errors that happens within it.
|
|
71
|
-
* Returns an error if it throws, otherwise null.
|
|
72
|
-
*
|
|
73
|
-
* In production, this is implemented using a try-catch. The reason we don't
|
|
74
|
-
* use a try-catch directly is so that we can swap out a different
|
|
75
|
-
* implementation in DEV mode.
|
|
76
|
-
*
|
|
77
|
-
* @param {String} name of the guard to use for logging or debugging
|
|
78
|
-
* @param {Function} func The function to invoke
|
|
79
|
-
* @param {*} context The context to use when calling the function
|
|
80
|
-
* @param {...*} args Arguments for function
|
|
81
|
-
*/
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Same as invokeGuardedCallback, but instead of returning an error, it stores
|
|
86
|
-
* it in a global so it can be rethrown by `rethrowCaughtError` later.
|
|
87
|
-
* TODO: See if caughtError and rethrowError can be unified.
|
|
88
|
-
*
|
|
89
|
-
* @param {String} name of the guard to use for logging or debugging
|
|
90
|
-
* @param {Function} func The function to invoke
|
|
91
|
-
* @param {*} context The context to use when calling the function
|
|
92
|
-
* @param {...*} args Arguments for function
|
|
93
|
-
*/
|
|
94
27
|
|
|
28
|
+
if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
|
|
29
|
+
ReactSharedInternals.ReactCurrentBatchConfig = {
|
|
30
|
+
suspense: null
|
|
31
|
+
};
|
|
32
|
+
}
|
|
95
33
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
34
|
+
// by calls to these methods by a Babel plugin.
|
|
35
|
+
//
|
|
36
|
+
// In PROD (or in packages without access to React internals),
|
|
37
|
+
// they are left as they are instead.
|
|
100
38
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
*/
|
|
107
|
-
var warningWithoutStack = function () {};
|
|
39
|
+
function warn(format) {
|
|
40
|
+
{
|
|
41
|
+
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
42
|
+
args[_key - 1] = arguments[_key];
|
|
43
|
+
}
|
|
108
44
|
|
|
109
|
-
|
|
110
|
-
warningWithoutStack = function (condition, format) {
|
|
111
|
-
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
|
112
|
-
args[_key - 2] = arguments[_key];
|
|
45
|
+
printWarning('warn', format, args);
|
|
113
46
|
}
|
|
47
|
+
}
|
|
48
|
+
function error(format) {
|
|
49
|
+
{
|
|
50
|
+
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
51
|
+
args[_key2 - 1] = arguments[_key2];
|
|
52
|
+
}
|
|
114
53
|
|
|
115
|
-
|
|
116
|
-
throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
|
|
54
|
+
printWarning('error', format, args);
|
|
117
55
|
}
|
|
56
|
+
}
|
|
118
57
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
58
|
+
function printWarning(level, format, args) {
|
|
59
|
+
// When changing this logic, you might want to also
|
|
60
|
+
// update consoleWithStackDev.www.js as well.
|
|
61
|
+
{
|
|
62
|
+
var hasExistingStack = args.length > 0 && typeof args[args.length - 1] === 'string' && args[args.length - 1].indexOf('\n in') === 0;
|
|
123
63
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
64
|
+
if (!hasExistingStack) {
|
|
65
|
+
var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
|
|
66
|
+
var stack = ReactDebugCurrentFrame.getStackAddendum();
|
|
67
|
+
|
|
68
|
+
if (stack !== '') {
|
|
69
|
+
format += '%s';
|
|
70
|
+
args = args.concat([stack]);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
127
73
|
|
|
128
|
-
if (typeof console !== 'undefined') {
|
|
129
74
|
var argsWithFormat = args.map(function (item) {
|
|
130
75
|
return '' + item;
|
|
131
|
-
});
|
|
76
|
+
}); // Careful: RN currently depends on this prefix
|
|
77
|
+
|
|
132
78
|
argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
|
|
133
79
|
// breaks IE9: https://github.com/facebook/react/issues/13610
|
|
134
|
-
|
|
135
|
-
|
|
80
|
+
// eslint-disable-next-line react-internal/no-production-logging
|
|
81
|
+
|
|
82
|
+
Function.prototype.apply.call(console[level], console, argsWithFormat);
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
// --- Welcome to debugging React ---
|
|
86
|
+
// This error was thrown as a convenience so that you can use this stack
|
|
87
|
+
// to find the callsite that caused this warning to fire.
|
|
88
|
+
var argIndex = 0;
|
|
89
|
+
var message = 'Warning: ' + format.replace(/%s/g, function () {
|
|
90
|
+
return args[argIndex++];
|
|
91
|
+
});
|
|
92
|
+
throw new Error(message);
|
|
93
|
+
} catch (x) {}
|
|
136
94
|
}
|
|
95
|
+
}
|
|
137
96
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
97
|
+
{
|
|
98
|
+
// In DEV mode, we swap out invokeGuardedCallback for a special version
|
|
99
|
+
// that plays more nicely with the browser's DevTools. The idea is to preserve
|
|
100
|
+
// "Pause on exceptions" behavior. Because React wraps all user-provided
|
|
101
|
+
// functions in invokeGuardedCallback, and the production version of
|
|
102
|
+
// invokeGuardedCallback uses a try-catch, all user exceptions are treated
|
|
103
|
+
// like caught exceptions, and the DevTools won't pause unless the developer
|
|
104
|
+
// takes the extra step of enabling pause on caught exceptions. This is
|
|
105
|
+
// unintuitive, though, because even though React has caught the error, from
|
|
106
|
+
// the developer's perspective, the error is uncaught.
|
|
107
|
+
//
|
|
108
|
+
// To preserve the expected "Pause on exceptions" behavior, we don't use a
|
|
109
|
+
// try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
|
|
110
|
+
// DOM node, and call the user-provided callback from inside an event handler
|
|
111
|
+
// for that fake event. If the callback throws, the error is "captured" using
|
|
112
|
+
// a global event handler. But because the error happens in a different
|
|
113
|
+
// event loop context, it does not interrupt the normal program flow.
|
|
114
|
+
// Effectively, this gives us try-catch behavior without actually using
|
|
115
|
+
// try-catch. Neat!
|
|
116
|
+
// Check that the browser supports the APIs we need to implement our special
|
|
117
|
+
// DEV version of invokeGuardedCallback
|
|
118
|
+
if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
|
|
119
|
+
var fakeNode = document.createElement('react');
|
|
120
|
+
}
|
|
121
|
+
}
|
|
150
122
|
|
|
151
|
-
var
|
|
123
|
+
var getFiberCurrentPropsFromNode = null;
|
|
124
|
+
var getInstanceFromNode = null;
|
|
125
|
+
var getNodeFromInstance = null;
|
|
126
|
+
function setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) {
|
|
127
|
+
getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl;
|
|
128
|
+
getInstanceFromNode = getInstanceFromNodeImpl;
|
|
129
|
+
getNodeFromInstance = getNodeFromInstanceImpl;
|
|
152
130
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
131
|
+
{
|
|
132
|
+
if (!getNodeFromInstance || !getInstanceFromNode) {
|
|
133
|
+
error('EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
var validateEventDispatches;
|
|
160
138
|
|
|
161
139
|
{
|
|
162
|
-
|
|
140
|
+
validateEventDispatches = function (event) {
|
|
141
|
+
var dispatchListeners = event._dispatchListeners;
|
|
142
|
+
var dispatchInstances = event._dispatchInstances;
|
|
143
|
+
var listenersIsArr = Array.isArray(dispatchListeners);
|
|
144
|
+
var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
|
|
145
|
+
var instancesIsArr = Array.isArray(dispatchInstances);
|
|
146
|
+
var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
|
|
147
|
+
|
|
148
|
+
if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) {
|
|
149
|
+
error('EventPluginUtils: Invalid `event`.');
|
|
150
|
+
}
|
|
151
|
+
};
|
|
163
152
|
}
|
|
164
|
-
|
|
165
|
-
|
|
153
|
+
/**
|
|
154
|
+
* Standard/simple iteration through an event's collected dispatches, but stops
|
|
155
|
+
* at the first dispatch execution returning true, and returns that id.
|
|
156
|
+
*
|
|
157
|
+
* @return {?string} id of the first dispatch execution who's listener returns
|
|
158
|
+
* true, or null if no listener returned true.
|
|
159
|
+
*/
|
|
166
160
|
|
|
167
|
-
{
|
|
168
|
-
validateEventDispatches = function (event) {
|
|
161
|
+
function executeDispatchesInOrderStopAtTrueImpl(event) {
|
|
169
162
|
var dispatchListeners = event._dispatchListeners;
|
|
170
163
|
var dispatchInstances = event._dispatchInstances;
|
|
171
|
-
var listenersIsArr = Array.isArray(dispatchListeners);
|
|
172
|
-
var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
|
|
173
|
-
var instancesIsArr = Array.isArray(dispatchInstances);
|
|
174
|
-
var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
|
|
175
|
-
!(instancesIsArr === listenersIsArr && instancesLen === listenersLen) ? warningWithoutStack$1(false, 'EventPluginUtils: Invalid `event`.') : void 0;
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Dispatch the event to the listener.
|
|
180
|
-
* @param {SyntheticEvent} event SyntheticEvent to handle
|
|
181
|
-
* @param {function} listener Application-level callback
|
|
182
|
-
* @param {*} inst Internal component instance
|
|
183
|
-
*/
|
|
184
|
-
|
|
185
164
|
|
|
165
|
+
{
|
|
166
|
+
validateEventDispatches(event);
|
|
167
|
+
}
|
|
186
168
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Standard/simple iteration through an event's collected dispatches, but stops
|
|
194
|
-
* at the first dispatch execution returning true, and returns that id.
|
|
195
|
-
*
|
|
196
|
-
* @return {?string} id of the first dispatch execution who's listener returns
|
|
197
|
-
* true, or null if no listener returned true.
|
|
198
|
-
*/
|
|
199
|
-
|
|
200
|
-
function executeDispatchesInOrderStopAtTrueImpl(event) {
|
|
201
|
-
var dispatchListeners = event._dispatchListeners;
|
|
202
|
-
var dispatchInstances = event._dispatchInstances;
|
|
203
|
-
|
|
204
|
-
{
|
|
205
|
-
validateEventDispatches(event);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
if (Array.isArray(dispatchListeners)) {
|
|
209
|
-
for (var i = 0; i < dispatchListeners.length; i++) {
|
|
210
|
-
if (event.isPropagationStopped()) {
|
|
211
|
-
break;
|
|
212
|
-
} // Listeners and Instances are two parallel arrays that are always in sync.
|
|
169
|
+
if (Array.isArray(dispatchListeners)) {
|
|
170
|
+
for (var i = 0; i < dispatchListeners.length; i++) {
|
|
171
|
+
if (event.isPropagationStopped()) {
|
|
172
|
+
break;
|
|
173
|
+
} // Listeners and Instances are two parallel arrays that are always in sync.
|
|
213
174
|
|
|
214
175
|
|
|
215
|
-
|
|
216
|
-
|
|
176
|
+
if (dispatchListeners[i](event, dispatchInstances[i])) {
|
|
177
|
+
return dispatchInstances[i];
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
} else if (dispatchListeners) {
|
|
181
|
+
if (dispatchListeners(event, dispatchInstances)) {
|
|
182
|
+
return dispatchInstances;
|
|
217
183
|
}
|
|
218
184
|
}
|
|
219
|
-
} else if (dispatchListeners) {
|
|
220
|
-
if (dispatchListeners(event, dispatchInstances)) {
|
|
221
|
-
return dispatchInstances;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
return null;
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* @see executeDispatchesInOrderStopAtTrueImpl
|
|
229
|
-
*/
|
|
230
185
|
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* @see executeDispatchesInOrderStopAtTrueImpl
|
|
190
|
+
*/
|
|
231
191
|
|
|
232
|
-
function executeDispatchesInOrderStopAtTrue(event) {
|
|
233
|
-
var ret = executeDispatchesInOrderStopAtTrueImpl(event);
|
|
234
|
-
event._dispatchInstances = null;
|
|
235
|
-
event._dispatchListeners = null;
|
|
236
|
-
return ret;
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Execution of a "direct" dispatch - there must be at most one dispatch
|
|
240
|
-
* accumulated on the event or it is considered an error. It doesn't really make
|
|
241
|
-
* sense for an event with multiple dispatches (bubbled) to keep track of the
|
|
242
|
-
* return values at each dispatch execution, but it does tend to make sense when
|
|
243
|
-
* dealing with "direct" dispatches.
|
|
244
|
-
*
|
|
245
|
-
* @return {*} The return value of executing the single dispatch.
|
|
246
|
-
*/
|
|
247
192
|
|
|
248
|
-
function
|
|
249
|
-
|
|
250
|
-
|
|
193
|
+
function executeDispatchesInOrderStopAtTrue(event) {
|
|
194
|
+
var ret = executeDispatchesInOrderStopAtTrueImpl(event);
|
|
195
|
+
event._dispatchInstances = null;
|
|
196
|
+
event._dispatchListeners = null;
|
|
197
|
+
return ret;
|
|
251
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* Execution of a "direct" dispatch - there must be at most one dispatch
|
|
201
|
+
* accumulated on the event or it is considered an error. It doesn't really make
|
|
202
|
+
* sense for an event with multiple dispatches (bubbled) to keep track of the
|
|
203
|
+
* return values at each dispatch execution, but it does tend to make sense when
|
|
204
|
+
* dealing with "direct" dispatches.
|
|
205
|
+
*
|
|
206
|
+
* @return {*} The return value of executing the single dispatch.
|
|
207
|
+
*/
|
|
252
208
|
|
|
253
|
-
|
|
254
|
-
|
|
209
|
+
function executeDirectDispatch(event) {
|
|
210
|
+
{
|
|
211
|
+
validateEventDispatches(event);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
var dispatchListener = event._dispatchListeners;
|
|
215
|
+
var dispatchInstance = event._dispatchInstances;
|
|
255
216
|
|
|
256
|
-
(function () {
|
|
257
217
|
if (!!Array.isArray(dispatchListener)) {
|
|
258
218
|
{
|
|
259
|
-
throw
|
|
219
|
+
throw Error( "executeDirectDispatch(...): Invalid `event`." );
|
|
260
220
|
}
|
|
261
221
|
}
|
|
262
|
-
})();
|
|
263
|
-
|
|
264
|
-
event.currentTarget = dispatchListener ? getNodeFromInstance$1(dispatchInstance) : null;
|
|
265
|
-
var res = dispatchListener ? dispatchListener(event) : null;
|
|
266
|
-
event.currentTarget = null;
|
|
267
|
-
event._dispatchListeners = null;
|
|
268
|
-
event._dispatchInstances = null;
|
|
269
|
-
return res;
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* @param {SyntheticEvent} event
|
|
273
|
-
* @return {boolean} True iff number of dispatches accumulated is greater than 0.
|
|
274
|
-
*/
|
|
275
222
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
223
|
+
event.currentTarget = dispatchListener ? getNodeFromInstance(dispatchInstance) : null;
|
|
224
|
+
var res = dispatchListener ? dispatchListener(event) : null;
|
|
225
|
+
event.currentTarget = null;
|
|
226
|
+
event._dispatchListeners = null;
|
|
227
|
+
event._dispatchInstances = null;
|
|
228
|
+
return res;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* @param {SyntheticEvent} event
|
|
232
|
+
* @return {boolean} True iff number of dispatches accumulated is greater than 0.
|
|
233
|
+
*/
|
|
281
234
|
|
|
282
|
-
|
|
235
|
+
function hasDispatches(event) {
|
|
236
|
+
return !!event._dispatchListeners;
|
|
237
|
+
}
|
|
283
238
|
|
|
284
|
-
|
|
239
|
+
var HostComponent = 5;
|
|
285
240
|
|
|
286
|
-
|
|
241
|
+
function getParent(inst) {
|
|
242
|
+
do {
|
|
243
|
+
inst = inst.return; // TODO: If this is a HostRoot we might want to bail out.
|
|
244
|
+
// That is depending on if we want nested subtrees (layers) to bubble
|
|
245
|
+
// events to their parent. We could also go through parentNode on the
|
|
246
|
+
// host node but that wouldn't work for React Native and doesn't let us
|
|
247
|
+
// do the portal feature.
|
|
248
|
+
} while (inst && inst.tag !== HostComponent);
|
|
287
249
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
// That is depending on if we want nested subtrees (layers) to bubble
|
|
292
|
-
// events to their parent. We could also go through parentNode on the
|
|
293
|
-
// host node but that wouldn't work for React Native and doesn't let us
|
|
294
|
-
// do the portal feature.
|
|
295
|
-
} while (inst && inst.tag !== HostComponent);
|
|
250
|
+
if (inst) {
|
|
251
|
+
return inst;
|
|
252
|
+
}
|
|
296
253
|
|
|
297
|
-
|
|
298
|
-
return inst;
|
|
254
|
+
return null;
|
|
299
255
|
}
|
|
256
|
+
/**
|
|
257
|
+
* Return the lowest common ancestor of A and B, or null if they are in
|
|
258
|
+
* different trees.
|
|
259
|
+
*/
|
|
300
260
|
|
|
301
|
-
return null;
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Return the lowest common ancestor of A and B, or null if they are in
|
|
305
|
-
* different trees.
|
|
306
|
-
*/
|
|
307
261
|
|
|
262
|
+
function getLowestCommonAncestor(instA, instB) {
|
|
263
|
+
var depthA = 0;
|
|
308
264
|
|
|
309
|
-
|
|
310
|
-
|
|
265
|
+
for (var tempA = instA; tempA; tempA = getParent(tempA)) {
|
|
266
|
+
depthA++;
|
|
267
|
+
}
|
|
311
268
|
|
|
312
|
-
|
|
313
|
-
depthA++;
|
|
314
|
-
}
|
|
269
|
+
var depthB = 0;
|
|
315
270
|
|
|
316
|
-
|
|
271
|
+
for (var tempB = instB; tempB; tempB = getParent(tempB)) {
|
|
272
|
+
depthB++;
|
|
273
|
+
} // If A is deeper, crawl up.
|
|
317
274
|
|
|
318
|
-
for (var tempB = instB; tempB; tempB = getParent(tempB)) {
|
|
319
|
-
depthB++;
|
|
320
|
-
} // If A is deeper, crawl up.
|
|
321
275
|
|
|
276
|
+
while (depthA - depthB > 0) {
|
|
277
|
+
instA = getParent(instA);
|
|
278
|
+
depthA--;
|
|
279
|
+
} // If B is deeper, crawl up.
|
|
322
280
|
|
|
323
|
-
while (depthA - depthB > 0) {
|
|
324
|
-
instA = getParent(instA);
|
|
325
|
-
depthA--;
|
|
326
|
-
} // If B is deeper, crawl up.
|
|
327
281
|
|
|
282
|
+
while (depthB - depthA > 0) {
|
|
283
|
+
instB = getParent(instB);
|
|
284
|
+
depthB--;
|
|
285
|
+
} // Walk in lockstep until we find a match.
|
|
328
286
|
|
|
329
|
-
while (depthB - depthA > 0) {
|
|
330
|
-
instB = getParent(instB);
|
|
331
|
-
depthB--;
|
|
332
|
-
} // Walk in lockstep until we find a match.
|
|
333
287
|
|
|
288
|
+
var depth = depthA;
|
|
334
289
|
|
|
335
|
-
|
|
290
|
+
while (depth--) {
|
|
291
|
+
if (instA === instB || instA === instB.alternate) {
|
|
292
|
+
return instA;
|
|
293
|
+
}
|
|
336
294
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
return instA;
|
|
295
|
+
instA = getParent(instA);
|
|
296
|
+
instB = getParent(instB);
|
|
340
297
|
}
|
|
341
298
|
|
|
342
|
-
|
|
343
|
-
instB = getParent(instB);
|
|
299
|
+
return null;
|
|
344
300
|
}
|
|
301
|
+
/**
|
|
302
|
+
* Return if A is an ancestor of B.
|
|
303
|
+
*/
|
|
345
304
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
305
|
+
function isAncestor(instA, instB) {
|
|
306
|
+
while (instB) {
|
|
307
|
+
if (instA === instB || instA === instB.alternate) {
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
351
310
|
|
|
352
|
-
|
|
353
|
-
while (instB) {
|
|
354
|
-
if (instA === instB || instA === instB.alternate) {
|
|
355
|
-
return true;
|
|
311
|
+
instB = getParent(instB);
|
|
356
312
|
}
|
|
357
313
|
|
|
358
|
-
|
|
314
|
+
return false;
|
|
359
315
|
}
|
|
316
|
+
/**
|
|
317
|
+
* Return the parent instance of the passed-in instance.
|
|
318
|
+
*/
|
|
360
319
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
320
|
+
function getParentInstance(inst) {
|
|
321
|
+
return getParent(inst);
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Simulates the traversal of a two-phase, capture/bubble event dispatch.
|
|
325
|
+
*/
|
|
366
326
|
|
|
367
|
-
function
|
|
368
|
-
|
|
369
|
-
}
|
|
370
|
-
/**
|
|
371
|
-
* Simulates the traversal of a two-phase, capture/bubble event dispatch.
|
|
372
|
-
*/
|
|
327
|
+
function traverseTwoPhase(inst, fn, arg) {
|
|
328
|
+
var path = [];
|
|
373
329
|
|
|
374
|
-
|
|
375
|
-
|
|
330
|
+
while (inst) {
|
|
331
|
+
path.push(inst);
|
|
332
|
+
inst = getParent(inst);
|
|
333
|
+
}
|
|
376
334
|
|
|
377
|
-
|
|
378
|
-
path.push(inst);
|
|
379
|
-
inst = getParent(inst);
|
|
380
|
-
}
|
|
335
|
+
var i;
|
|
381
336
|
|
|
382
|
-
|
|
337
|
+
for (i = path.length; i-- > 0;) {
|
|
338
|
+
fn(path[i], 'captured', arg);
|
|
339
|
+
}
|
|
383
340
|
|
|
384
|
-
|
|
385
|
-
|
|
341
|
+
for (i = 0; i < path.length; i++) {
|
|
342
|
+
fn(path[i], 'bubbled', arg);
|
|
343
|
+
}
|
|
386
344
|
}
|
|
387
345
|
|
|
388
|
-
|
|
389
|
-
|
|
346
|
+
function isInteractive(tag) {
|
|
347
|
+
return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
|
|
390
348
|
}
|
|
391
|
-
}
|
|
392
|
-
/**
|
|
393
|
-
* Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
|
|
394
|
-
* should would receive a `mouseEnter` or `mouseLeave` event.
|
|
395
|
-
*
|
|
396
|
-
* Does not invoke the callback on the nearest common ancestor because nothing
|
|
397
|
-
* "entered" or "left" that element.
|
|
398
|
-
*/
|
|
399
349
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
350
|
+
function shouldPreventMouseEvent(name, type, props) {
|
|
351
|
+
switch (name) {
|
|
352
|
+
case 'onClick':
|
|
353
|
+
case 'onClickCapture':
|
|
354
|
+
case 'onDoubleClick':
|
|
355
|
+
case 'onDoubleClickCapture':
|
|
356
|
+
case 'onMouseDown':
|
|
357
|
+
case 'onMouseDownCapture':
|
|
358
|
+
case 'onMouseMove':
|
|
359
|
+
case 'onMouseMoveCapture':
|
|
360
|
+
case 'onMouseUp':
|
|
361
|
+
case 'onMouseUpCapture':
|
|
362
|
+
case 'onMouseEnter':
|
|
363
|
+
return !!(props.disabled && isInteractive(type));
|
|
364
|
+
|
|
365
|
+
default:
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* @param {object} inst The instance, which is the source of events.
|
|
371
|
+
* @param {string} registrationName Name of listener (e.g. `onClick`).
|
|
372
|
+
* @return {?function} The stored callback.
|
|
373
|
+
*/
|
|
415
374
|
|
|
416
375
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
376
|
+
function getListener(inst, registrationName) {
|
|
377
|
+
var listener; // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
|
|
378
|
+
// live here; needs to be moved to a better place soon
|
|
420
379
|
|
|
380
|
+
var stateNode = inst.stateNode;
|
|
421
381
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
382
|
+
if (!stateNode) {
|
|
383
|
+
// Work in progress (ex: onload events in incremental mode).
|
|
384
|
+
return null;
|
|
385
|
+
}
|
|
425
386
|
|
|
387
|
+
var props = getFiberCurrentPropsFromNode(stateNode);
|
|
426
388
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
* @type {Object}
|
|
432
|
-
*/
|
|
389
|
+
if (!props) {
|
|
390
|
+
// Work in progress.
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
433
393
|
|
|
434
|
-
|
|
394
|
+
listener = props[registrationName];
|
|
435
395
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
* always deterministic regardless of packaging, on-the-fly injection, etc.
|
|
440
|
-
*
|
|
441
|
-
* @param {array} InjectedEventPluginOrder
|
|
442
|
-
* @internal
|
|
443
|
-
* @see {EventPluginHub.injection.injectEventPluginOrder}
|
|
444
|
-
*/
|
|
396
|
+
if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
445
399
|
|
|
400
|
+
if (!(!listener || typeof listener === 'function')) {
|
|
401
|
+
{
|
|
402
|
+
throw Error( "Expected `" + registrationName + "` listener to be a function, instead got a value of `" + typeof listener + "` type." );
|
|
403
|
+
}
|
|
404
|
+
}
|
|
446
405
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
* in the ordering injected by `injectEventPluginOrder`.
|
|
450
|
-
*
|
|
451
|
-
* Plugins can be injected as part of page initialization or on-the-fly.
|
|
452
|
-
*
|
|
453
|
-
* @param {object} injectedNamesToPlugins Map from names to plugin modules.
|
|
454
|
-
* @internal
|
|
455
|
-
* @see {EventPluginHub.injection.injectEventPluginsByName}
|
|
456
|
-
*/
|
|
406
|
+
return listener;
|
|
407
|
+
}
|
|
457
408
|
|
|
458
|
-
/**
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
409
|
+
/**
|
|
410
|
+
* Accumulates items that must not be null or undefined into the first one. This
|
|
411
|
+
* is used to conserve memory by avoiding array allocations, and thus sacrifices
|
|
412
|
+
* API cleanness. Since `current` can be null before being passed in and not
|
|
413
|
+
* null after this function, make sure to assign it back to `current`:
|
|
414
|
+
*
|
|
415
|
+
* `a = accumulateInto(a, b);`
|
|
416
|
+
*
|
|
417
|
+
* This API should be sparingly used. Try `accumulate` for something cleaner.
|
|
418
|
+
*
|
|
419
|
+
* @return {*|array<*>} An accumulation of items.
|
|
420
|
+
*/
|
|
470
421
|
|
|
471
|
-
function accumulateInto(current, next) {
|
|
472
|
-
(function () {
|
|
422
|
+
function accumulateInto(current, next) {
|
|
473
423
|
if (!(next != null)) {
|
|
474
424
|
{
|
|
475
|
-
throw
|
|
425
|
+
throw Error( "accumulateInto(...): Accumulated items must not be null or undefined." );
|
|
476
426
|
}
|
|
477
427
|
}
|
|
478
|
-
})();
|
|
479
428
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
429
|
+
if (current == null) {
|
|
430
|
+
return next;
|
|
431
|
+
} // Both are not empty. Warning: Never call x.concat(y) when you are not
|
|
432
|
+
// certain that x is an Array (x could be a string with concat method).
|
|
484
433
|
|
|
485
434
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
435
|
+
if (Array.isArray(current)) {
|
|
436
|
+
if (Array.isArray(next)) {
|
|
437
|
+
current.push.apply(current, next);
|
|
438
|
+
return current;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
current.push(next);
|
|
489
442
|
return current;
|
|
490
443
|
}
|
|
491
444
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
445
|
+
if (Array.isArray(next)) {
|
|
446
|
+
// A bit too dangerous to mutate `next`.
|
|
447
|
+
return [current].concat(next);
|
|
448
|
+
}
|
|
495
449
|
|
|
496
|
-
|
|
497
|
-
// A bit too dangerous to mutate `next`.
|
|
498
|
-
return [current].concat(next);
|
|
450
|
+
return [current, next];
|
|
499
451
|
}
|
|
500
452
|
|
|
501
|
-
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
} else if (arr) {
|
|
517
|
-
cb.call(scope, arr);
|
|
453
|
+
/**
|
|
454
|
+
* @param {array} arr an "accumulation" of items which is either an Array or
|
|
455
|
+
* a single item. Useful when paired with the `accumulate` module. This is a
|
|
456
|
+
* simple utility that allows us to reason about a collection of items, but
|
|
457
|
+
* handling the case when there is exactly one item (and we do not need to
|
|
458
|
+
* allocate an array).
|
|
459
|
+
* @param {function} cb Callback invoked with each element or a collection.
|
|
460
|
+
* @param {?} [scope] Scope used as `this` in a callback.
|
|
461
|
+
*/
|
|
462
|
+
function forEachAccumulated(arr, cb, scope) {
|
|
463
|
+
if (Array.isArray(arr)) {
|
|
464
|
+
arr.forEach(cb, scope);
|
|
465
|
+
} else if (arr) {
|
|
466
|
+
cb.call(scope, arr);
|
|
467
|
+
}
|
|
518
468
|
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
case 'onClick':
|
|
528
|
-
case 'onClickCapture':
|
|
529
|
-
case 'onDoubleClick':
|
|
530
|
-
case 'onDoubleClickCapture':
|
|
531
|
-
case 'onMouseDown':
|
|
532
|
-
case 'onMouseDownCapture':
|
|
533
|
-
case 'onMouseMove':
|
|
534
|
-
case 'onMouseMoveCapture':
|
|
535
|
-
case 'onMouseUp':
|
|
536
|
-
case 'onMouseUpCapture':
|
|
537
|
-
return !!(props.disabled && isInteractive(type));
|
|
538
|
-
|
|
539
|
-
default:
|
|
540
|
-
return false;
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Some event types have a notion of different registration names for different
|
|
472
|
+
* "phases" of propagation. This finds listeners by a given phase.
|
|
473
|
+
*/
|
|
474
|
+
function listenerAtPhase(inst, event, propagationPhase) {
|
|
475
|
+
var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
|
|
476
|
+
return getListener(inst, registrationName);
|
|
541
477
|
}
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
*
|
|
552
|
-
* `eventTypes` {object}
|
|
553
|
-
* Optional, plugins that fire events must publish a mapping of registration
|
|
554
|
-
* names that are used to register listeners. Values of this mapping must
|
|
555
|
-
* be objects that contain `registrationName` or `phasedRegistrationNames`.
|
|
556
|
-
*
|
|
557
|
-
* `executeDispatch` {function(object, function, string)}
|
|
558
|
-
* Optional, allows plugins to override how an event gets dispatched. By
|
|
559
|
-
* default, the listener is simply invoked.
|
|
560
|
-
*
|
|
561
|
-
* Each plugin that is injected into `EventsPluginHub` is immediately operable.
|
|
562
|
-
*
|
|
563
|
-
* @public
|
|
564
|
-
*/
|
|
478
|
+
/**
|
|
479
|
+
* A small set of propagation patterns, each of which will accept a small amount
|
|
480
|
+
* of information, and generate a set of "dispatch ready event objects" - which
|
|
481
|
+
* are sets of events that have already been annotated with a set of dispatched
|
|
482
|
+
* listener functions/ids. The API is designed this way to discourage these
|
|
483
|
+
* propagation strategies from actually executing the dispatches, since we
|
|
484
|
+
* always want to collect the entire set of dispatches before executing even a
|
|
485
|
+
* single one.
|
|
486
|
+
*/
|
|
565
487
|
|
|
566
|
-
/**
|
|
567
|
-
|
|
568
|
-
|
|
488
|
+
/**
|
|
489
|
+
* Tags a `SyntheticEvent` with dispatched listeners. Creating this function
|
|
490
|
+
* here, allows us to not have to bind or create functions for each event.
|
|
491
|
+
* Mutating the event's members allows us to not have to create a wrapping
|
|
492
|
+
* "dispatch" object that pairs the event with the listener.
|
|
493
|
+
*/
|
|
569
494
|
|
|
570
495
|
|
|
496
|
+
function accumulateDirectionalDispatches(inst, phase, event) {
|
|
497
|
+
{
|
|
498
|
+
if (!inst) {
|
|
499
|
+
error('Dispatching inst must not be null');
|
|
500
|
+
}
|
|
501
|
+
}
|
|
571
502
|
|
|
572
|
-
|
|
573
|
-
* @param {object} inst The instance, which is the source of events.
|
|
574
|
-
* @param {string} registrationName Name of listener (e.g. `onClick`).
|
|
575
|
-
* @return {?function} The stored callback.
|
|
576
|
-
*/
|
|
503
|
+
var listener = listenerAtPhase(inst, event, phase);
|
|
577
504
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
505
|
+
if (listener) {
|
|
506
|
+
event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
|
|
507
|
+
event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Collect dispatches (must be entirely collected before dispatching - see unit
|
|
512
|
+
* tests). Lazily allocate the array to conserve memory. We must loop through
|
|
513
|
+
* each event and perform the traversal for each one. We cannot perform a
|
|
514
|
+
* single traversal for the entire collection of events because each event may
|
|
515
|
+
* have a different target.
|
|
516
|
+
*/
|
|
581
517
|
|
|
582
|
-
var stateNode = inst.stateNode;
|
|
583
518
|
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
519
|
+
function accumulateTwoPhaseDispatchesSingle(event) {
|
|
520
|
+
if (event && event.dispatchConfig.phasedRegistrationNames) {
|
|
521
|
+
traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
|
|
522
|
+
}
|
|
587
523
|
}
|
|
524
|
+
/**
|
|
525
|
+
* Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID.
|
|
526
|
+
*/
|
|
588
527
|
|
|
589
|
-
var props = getFiberCurrentPropsFromNode$1(stateNode);
|
|
590
528
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
529
|
+
function accumulateTwoPhaseDispatchesSingleSkipTarget(event) {
|
|
530
|
+
if (event && event.dispatchConfig.phasedRegistrationNames) {
|
|
531
|
+
var targetInst = event._targetInst;
|
|
532
|
+
var parentInst = targetInst ? getParentInstance(targetInst) : null;
|
|
533
|
+
traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event);
|
|
534
|
+
}
|
|
594
535
|
}
|
|
536
|
+
/**
|
|
537
|
+
* Accumulates without regard to direction, does not look for phased
|
|
538
|
+
* registration names. Same as `accumulateDirectDispatchesSingle` but without
|
|
539
|
+
* requiring that the `dispatchMarker` be the same as the dispatched ID.
|
|
540
|
+
*/
|
|
595
541
|
|
|
596
|
-
listener = props[registrationName];
|
|
597
542
|
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
543
|
+
function accumulateDispatches(inst, ignoredDirection, event) {
|
|
544
|
+
if (inst && event && event.dispatchConfig.registrationName) {
|
|
545
|
+
var registrationName = event.dispatchConfig.registrationName;
|
|
546
|
+
var listener = getListener(inst, registrationName);
|
|
601
547
|
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
throw ReactError(Error("Expected `" + registrationName + "` listener to be a function, instead got a value of `" + typeof listener + "` type."));
|
|
548
|
+
if (listener) {
|
|
549
|
+
event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
|
|
550
|
+
event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
|
|
606
551
|
}
|
|
607
552
|
}
|
|
608
|
-
})();
|
|
609
|
-
|
|
610
|
-
return listener;
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
/**
|
|
614
|
-
* Some event types have a notion of different registration names for different
|
|
615
|
-
* "phases" of propagation. This finds listeners by a given phase.
|
|
616
|
-
*/
|
|
617
|
-
function listenerAtPhase(inst, event, propagationPhase) {
|
|
618
|
-
var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
|
|
619
|
-
return getListener(inst, registrationName);
|
|
620
|
-
}
|
|
621
|
-
/**
|
|
622
|
-
* A small set of propagation patterns, each of which will accept a small amount
|
|
623
|
-
* of information, and generate a set of "dispatch ready event objects" - which
|
|
624
|
-
* are sets of events that have already been annotated with a set of dispatched
|
|
625
|
-
* listener functions/ids. The API is designed this way to discourage these
|
|
626
|
-
* propagation strategies from actually executing the dispatches, since we
|
|
627
|
-
* always want to collect the entire set of dispatches before executing even a
|
|
628
|
-
* single one.
|
|
629
|
-
*/
|
|
630
|
-
|
|
631
|
-
/**
|
|
632
|
-
* Tags a `SyntheticEvent` with dispatched listeners. Creating this function
|
|
633
|
-
* here, allows us to not have to bind or create functions for each event.
|
|
634
|
-
* Mutating the event's members allows us to not have to create a wrapping
|
|
635
|
-
* "dispatch" object that pairs the event with the listener.
|
|
636
|
-
*/
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
function accumulateDirectionalDispatches(inst, phase, event) {
|
|
640
|
-
{
|
|
641
|
-
!inst ? warningWithoutStack$1(false, 'Dispatching inst must not be null') : void 0;
|
|
642
553
|
}
|
|
554
|
+
/**
|
|
555
|
+
* Accumulates dispatches on an `SyntheticEvent`, but only for the
|
|
556
|
+
* `dispatchMarker`.
|
|
557
|
+
* @param {SyntheticEvent} event
|
|
558
|
+
*/
|
|
643
559
|
|
|
644
|
-
var listener = listenerAtPhase(inst, event, phase);
|
|
645
560
|
|
|
646
|
-
|
|
647
|
-
event
|
|
648
|
-
|
|
561
|
+
function accumulateDirectDispatchesSingle(event) {
|
|
562
|
+
if (event && event.dispatchConfig.registrationName) {
|
|
563
|
+
accumulateDispatches(event._targetInst, null, event);
|
|
564
|
+
}
|
|
649
565
|
}
|
|
650
|
-
}
|
|
651
|
-
/**
|
|
652
|
-
* Collect dispatches (must be entirely collected before dispatching - see unit
|
|
653
|
-
* tests). Lazily allocate the array to conserve memory. We must loop through
|
|
654
|
-
* each event and perform the traversal for each one. We cannot perform a
|
|
655
|
-
* single traversal for the entire collection of events because each event may
|
|
656
|
-
* have a different target.
|
|
657
|
-
*/
|
|
658
|
-
|
|
659
566
|
|
|
660
|
-
function
|
|
661
|
-
|
|
662
|
-
traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
|
|
567
|
+
function accumulateTwoPhaseDispatches(events) {
|
|
568
|
+
forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
|
|
663
569
|
}
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
* Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID.
|
|
667
|
-
*/
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
function accumulateTwoPhaseDispatchesSingleSkipTarget(event) {
|
|
671
|
-
if (event && event.dispatchConfig.phasedRegistrationNames) {
|
|
672
|
-
var targetInst = event._targetInst;
|
|
673
|
-
var parentInst = targetInst ? getParentInstance(targetInst) : null;
|
|
674
|
-
traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event);
|
|
570
|
+
function accumulateTwoPhaseDispatchesSkipTarget(events) {
|
|
571
|
+
forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget);
|
|
675
572
|
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
* Accumulates without regard to direction, does not look for phased
|
|
679
|
-
* registration names. Same as `accumulateDirectDispatchesSingle` but without
|
|
680
|
-
* requiring that the `dispatchMarker` be the same as the dispatched ID.
|
|
681
|
-
*/
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
function accumulateDispatches(inst, ignoredDirection, event) {
|
|
685
|
-
if (inst && event && event.dispatchConfig.registrationName) {
|
|
686
|
-
var registrationName = event.dispatchConfig.registrationName;
|
|
687
|
-
var listener = getListener(inst, registrationName);
|
|
688
|
-
|
|
689
|
-
if (listener) {
|
|
690
|
-
event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
|
|
691
|
-
event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
|
|
692
|
-
}
|
|
573
|
+
function accumulateDirectDispatches(events) {
|
|
574
|
+
forEachAccumulated(events, accumulateDirectDispatchesSingle);
|
|
693
575
|
}
|
|
694
|
-
}
|
|
695
|
-
/**
|
|
696
|
-
* Accumulates dispatches on an `SyntheticEvent`, but only for the
|
|
697
|
-
* `dispatchMarker`.
|
|
698
|
-
* @param {SyntheticEvent} event
|
|
699
|
-
*/
|
|
700
576
|
|
|
577
|
+
var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
578
|
+
var _assign = ReactInternals.assign;
|
|
701
579
|
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
function accumulateTwoPhaseDispatches(events) {
|
|
709
|
-
forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
|
|
710
|
-
}
|
|
711
|
-
function accumulateTwoPhaseDispatchesSkipTarget(events) {
|
|
712
|
-
forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget);
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
function accumulateDirectDispatches(events) {
|
|
716
|
-
forEachAccumulated(events, accumulateDirectDispatchesSingle);
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
720
|
-
var _assign = ReactInternals.assign;
|
|
721
|
-
|
|
722
|
-
/* eslint valid-typeof: 0 */
|
|
723
|
-
var EVENT_POOL_SIZE = 10;
|
|
724
|
-
/**
|
|
725
|
-
* @interface Event
|
|
726
|
-
* @see http://www.w3.org/TR/DOM-Level-3-Events/
|
|
727
|
-
*/
|
|
728
|
-
|
|
729
|
-
var EventInterface = {
|
|
730
|
-
type: null,
|
|
731
|
-
target: null,
|
|
732
|
-
// currentTarget is set when dispatching; no use in copying it here
|
|
733
|
-
currentTarget: function () {
|
|
734
|
-
return null;
|
|
735
|
-
},
|
|
736
|
-
eventPhase: null,
|
|
737
|
-
bubbles: null,
|
|
738
|
-
cancelable: null,
|
|
739
|
-
timeStamp: function (event) {
|
|
740
|
-
return event.timeStamp || Date.now();
|
|
741
|
-
},
|
|
742
|
-
defaultPrevented: null,
|
|
743
|
-
isTrusted: null
|
|
744
|
-
};
|
|
745
|
-
|
|
746
|
-
function functionThatReturnsTrue() {
|
|
747
|
-
return true;
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
function functionThatReturnsFalse() {
|
|
751
|
-
return false;
|
|
752
|
-
}
|
|
753
|
-
/**
|
|
754
|
-
* Synthetic events are dispatched by event plugins, typically in response to a
|
|
755
|
-
* top-level event delegation handler.
|
|
756
|
-
*
|
|
757
|
-
* These systems should generally use pooling to reduce the frequency of garbage
|
|
758
|
-
* collection. The system should check `isPersistent` to determine whether the
|
|
759
|
-
* event should be released into the pool after being dispatched. Users that
|
|
760
|
-
* need a persisted event should invoke `persist`.
|
|
761
|
-
*
|
|
762
|
-
* Synthetic events (and subclasses) implement the DOM Level 3 Events API by
|
|
763
|
-
* normalizing browser quirks. Subclasses do not necessarily have to implement a
|
|
764
|
-
* DOM interface; custom application-specific events can also subclass this.
|
|
765
|
-
*
|
|
766
|
-
* @param {object} dispatchConfig Configuration used to dispatch this event.
|
|
767
|
-
* @param {*} targetInst Marker identifying the event target.
|
|
768
|
-
* @param {object} nativeEvent Native browser event.
|
|
769
|
-
* @param {DOMEventTarget} nativeEventTarget Target node.
|
|
770
|
-
*/
|
|
580
|
+
var EVENT_POOL_SIZE = 10;
|
|
581
|
+
/**
|
|
582
|
+
* @interface Event
|
|
583
|
+
* @see http://www.w3.org/TR/DOM-Level-3-Events/
|
|
584
|
+
*/
|
|
771
585
|
|
|
586
|
+
var EventInterface = {
|
|
587
|
+
type: null,
|
|
588
|
+
target: null,
|
|
589
|
+
// currentTarget is set when dispatching; no use in copying it here
|
|
590
|
+
currentTarget: function () {
|
|
591
|
+
return null;
|
|
592
|
+
},
|
|
593
|
+
eventPhase: null,
|
|
594
|
+
bubbles: null,
|
|
595
|
+
cancelable: null,
|
|
596
|
+
timeStamp: function (event) {
|
|
597
|
+
return event.timeStamp || Date.now();
|
|
598
|
+
},
|
|
599
|
+
defaultPrevented: null,
|
|
600
|
+
isTrusted: null
|
|
601
|
+
};
|
|
772
602
|
|
|
773
|
-
function
|
|
774
|
-
|
|
775
|
-
// these have a getter/setter for warnings
|
|
776
|
-
delete this.nativeEvent;
|
|
777
|
-
delete this.preventDefault;
|
|
778
|
-
delete this.stopPropagation;
|
|
779
|
-
delete this.isDefaultPrevented;
|
|
780
|
-
delete this.isPropagationStopped;
|
|
603
|
+
function functionThatReturnsTrue() {
|
|
604
|
+
return true;
|
|
781
605
|
}
|
|
782
606
|
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
607
|
+
function functionThatReturnsFalse() {
|
|
608
|
+
return false;
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Synthetic events are dispatched by event plugins, typically in response to a
|
|
612
|
+
* top-level event delegation handler.
|
|
613
|
+
*
|
|
614
|
+
* These systems should generally use pooling to reduce the frequency of garbage
|
|
615
|
+
* collection. The system should check `isPersistent` to determine whether the
|
|
616
|
+
* event should be released into the pool after being dispatched. Users that
|
|
617
|
+
* need a persisted event should invoke `persist`.
|
|
618
|
+
*
|
|
619
|
+
* Synthetic events (and subclasses) implement the DOM Level 3 Events API by
|
|
620
|
+
* normalizing browser quirks. Subclasses do not necessarily have to implement a
|
|
621
|
+
* DOM interface; custom application-specific events can also subclass this.
|
|
622
|
+
*
|
|
623
|
+
* @param {object} dispatchConfig Configuration used to dispatch this event.
|
|
624
|
+
* @param {*} targetInst Marker identifying the event target.
|
|
625
|
+
* @param {object} nativeEvent Native browser event.
|
|
626
|
+
* @param {DOMEventTarget} nativeEventTarget Target node.
|
|
627
|
+
*/
|
|
787
628
|
|
|
788
|
-
for (var propName in Interface) {
|
|
789
|
-
if (!Interface.hasOwnProperty(propName)) {
|
|
790
|
-
continue;
|
|
791
|
-
}
|
|
792
629
|
|
|
630
|
+
function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
|
|
793
631
|
{
|
|
794
|
-
|
|
632
|
+
// these have a getter/setter for warnings
|
|
633
|
+
delete this.nativeEvent;
|
|
634
|
+
delete this.preventDefault;
|
|
635
|
+
delete this.stopPropagation;
|
|
636
|
+
delete this.isDefaultPrevented;
|
|
637
|
+
delete this.isPropagationStopped;
|
|
795
638
|
}
|
|
796
639
|
|
|
797
|
-
|
|
640
|
+
this.dispatchConfig = dispatchConfig;
|
|
641
|
+
this._targetInst = targetInst;
|
|
642
|
+
this.nativeEvent = nativeEvent;
|
|
643
|
+
var Interface = this.constructor.Interface;
|
|
798
644
|
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
if (propName === 'target') {
|
|
803
|
-
this.target = nativeEventTarget;
|
|
804
|
-
} else {
|
|
805
|
-
this[propName] = nativeEvent[propName];
|
|
645
|
+
for (var propName in Interface) {
|
|
646
|
+
if (!Interface.hasOwnProperty(propName)) {
|
|
647
|
+
continue;
|
|
806
648
|
}
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
649
|
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
this.isDefaultPrevented = functionThatReturnsTrue;
|
|
814
|
-
} else {
|
|
815
|
-
this.isDefaultPrevented = functionThatReturnsFalse;
|
|
816
|
-
}
|
|
650
|
+
{
|
|
651
|
+
delete this[propName]; // this has a getter/setter for warnings
|
|
652
|
+
}
|
|
817
653
|
|
|
818
|
-
|
|
819
|
-
return this;
|
|
820
|
-
}
|
|
654
|
+
var normalize = Interface[propName];
|
|
821
655
|
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
656
|
+
if (normalize) {
|
|
657
|
+
this[propName] = normalize(nativeEvent);
|
|
658
|
+
} else {
|
|
659
|
+
if (propName === 'target') {
|
|
660
|
+
this.target = nativeEventTarget;
|
|
661
|
+
} else {
|
|
662
|
+
this[propName] = nativeEvent[propName];
|
|
663
|
+
}
|
|
664
|
+
}
|
|
829
665
|
}
|
|
830
666
|
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
667
|
+
var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
|
|
668
|
+
|
|
669
|
+
if (defaultPrevented) {
|
|
670
|
+
this.isDefaultPrevented = functionThatReturnsTrue;
|
|
671
|
+
} else {
|
|
672
|
+
this.isDefaultPrevented = functionThatReturnsFalse;
|
|
835
673
|
}
|
|
836
674
|
|
|
837
|
-
this.
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
var event = this.nativeEvent;
|
|
675
|
+
this.isPropagationStopped = functionThatReturnsFalse;
|
|
676
|
+
return this;
|
|
677
|
+
}
|
|
841
678
|
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
679
|
+
_assign(SyntheticEvent.prototype, {
|
|
680
|
+
preventDefault: function () {
|
|
681
|
+
this.defaultPrevented = true;
|
|
682
|
+
var event = this.nativeEvent;
|
|
845
683
|
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
// The ChangeEventPlugin registers a "propertychange" event for
|
|
850
|
-
// IE. This event does not support bubbling or cancelling, and
|
|
851
|
-
// any references to cancelBubble throw "Member not found". A
|
|
852
|
-
// typeof check of "unknown" circumvents this issue (and is also
|
|
853
|
-
// IE specific).
|
|
854
|
-
event.cancelBubble = true;
|
|
855
|
-
}
|
|
684
|
+
if (!event) {
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
856
687
|
|
|
857
|
-
|
|
858
|
-
|
|
688
|
+
if (event.preventDefault) {
|
|
689
|
+
event.preventDefault();
|
|
690
|
+
} else if (typeof event.returnValue !== 'unknown') {
|
|
691
|
+
event.returnValue = false;
|
|
692
|
+
}
|
|
859
693
|
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
*/
|
|
865
|
-
persist: function () {
|
|
866
|
-
this.isPersistent = functionThatReturnsTrue;
|
|
867
|
-
},
|
|
694
|
+
this.isDefaultPrevented = functionThatReturnsTrue;
|
|
695
|
+
},
|
|
696
|
+
stopPropagation: function () {
|
|
697
|
+
var event = this.nativeEvent;
|
|
868
698
|
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
* @return {boolean} True if this should not be released, false otherwise.
|
|
873
|
-
*/
|
|
874
|
-
isPersistent: functionThatReturnsFalse,
|
|
699
|
+
if (!event) {
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
875
702
|
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
703
|
+
if (event.stopPropagation) {
|
|
704
|
+
event.stopPropagation();
|
|
705
|
+
} else if (typeof event.cancelBubble !== 'unknown') {
|
|
706
|
+
// The ChangeEventPlugin registers a "propertychange" event for
|
|
707
|
+
// IE. This event does not support bubbling or cancelling, and
|
|
708
|
+
// any references to cancelBubble throw "Member not found". A
|
|
709
|
+
// typeof check of "unknown" circumvents this issue (and is also
|
|
710
|
+
// IE specific).
|
|
711
|
+
event.cancelBubble = true;
|
|
712
|
+
}
|
|
881
713
|
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
714
|
+
this.isPropagationStopped = functionThatReturnsTrue;
|
|
715
|
+
},
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* We release all dispatched `SyntheticEvent`s after each event loop, adding
|
|
719
|
+
* them back into the pool. This allows a way to hold onto a reference that
|
|
720
|
+
* won't be added back into the pool.
|
|
721
|
+
*/
|
|
722
|
+
persist: function () {
|
|
723
|
+
this.isPersistent = functionThatReturnsTrue;
|
|
724
|
+
},
|
|
725
|
+
|
|
726
|
+
/**
|
|
727
|
+
* Checks if this event should be released back into the pool.
|
|
728
|
+
*
|
|
729
|
+
* @return {boolean} True if this should not be released, false otherwise.
|
|
730
|
+
*/
|
|
731
|
+
isPersistent: functionThatReturnsFalse,
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* `PooledClass` looks for `destructor` on each instance it releases.
|
|
735
|
+
*/
|
|
736
|
+
destructor: function () {
|
|
737
|
+
var Interface = this.constructor.Interface;
|
|
738
|
+
|
|
739
|
+
for (var propName in Interface) {
|
|
740
|
+
{
|
|
741
|
+
Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
|
|
742
|
+
}
|
|
885
743
|
}
|
|
886
|
-
}
|
|
887
744
|
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
745
|
+
this.dispatchConfig = null;
|
|
746
|
+
this._targetInst = null;
|
|
747
|
+
this.nativeEvent = null;
|
|
748
|
+
this.isDefaultPrevented = functionThatReturnsFalse;
|
|
749
|
+
this.isPropagationStopped = functionThatReturnsFalse;
|
|
750
|
+
this._dispatchListeners = null;
|
|
751
|
+
this._dispatchInstances = null;
|
|
895
752
|
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
753
|
+
{
|
|
754
|
+
Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
|
|
755
|
+
Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse));
|
|
756
|
+
Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse));
|
|
757
|
+
Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {}));
|
|
758
|
+
Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {}));
|
|
759
|
+
}
|
|
902
760
|
}
|
|
903
|
-
}
|
|
904
|
-
});
|
|
761
|
+
});
|
|
905
762
|
|
|
906
|
-
SyntheticEvent.Interface = EventInterface;
|
|
907
|
-
/**
|
|
908
|
-
|
|
909
|
-
|
|
763
|
+
SyntheticEvent.Interface = EventInterface;
|
|
764
|
+
/**
|
|
765
|
+
* Helper to reduce boilerplate when creating subclasses.
|
|
766
|
+
*/
|
|
910
767
|
|
|
911
|
-
SyntheticEvent.extend = function (Interface) {
|
|
912
|
-
|
|
768
|
+
SyntheticEvent.extend = function (Interface) {
|
|
769
|
+
var Super = this;
|
|
913
770
|
|
|
914
|
-
|
|
771
|
+
var E = function () {};
|
|
915
772
|
|
|
916
|
-
|
|
917
|
-
|
|
773
|
+
E.prototype = Super.prototype;
|
|
774
|
+
var prototype = new E();
|
|
918
775
|
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
776
|
+
function Class() {
|
|
777
|
+
return Super.apply(this, arguments);
|
|
778
|
+
}
|
|
922
779
|
|
|
923
|
-
|
|
780
|
+
_assign(prototype, Class.prototype);
|
|
924
781
|
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
};
|
|
782
|
+
Class.prototype = prototype;
|
|
783
|
+
Class.prototype.constructor = Class;
|
|
784
|
+
Class.Interface = _assign({}, Super.Interface, Interface);
|
|
785
|
+
Class.extend = Super.extend;
|
|
786
|
+
addEventPoolingTo(Class);
|
|
787
|
+
return Class;
|
|
788
|
+
};
|
|
932
789
|
|
|
933
|
-
addEventPoolingTo(SyntheticEvent);
|
|
934
|
-
/**
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
790
|
+
addEventPoolingTo(SyntheticEvent);
|
|
791
|
+
/**
|
|
792
|
+
* Helper to nullify syntheticEvent instance properties when destructing
|
|
793
|
+
*
|
|
794
|
+
* @param {String} propName
|
|
795
|
+
* @param {?object} getVal
|
|
796
|
+
* @return {object} defineProperty object
|
|
797
|
+
*/
|
|
941
798
|
|
|
942
|
-
function getPooledWarningPropertyDefinition(propName, getVal) {
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
799
|
+
function getPooledWarningPropertyDefinition(propName, getVal) {
|
|
800
|
+
var isFunction = typeof getVal === 'function';
|
|
801
|
+
return {
|
|
802
|
+
configurable: true,
|
|
803
|
+
set: set,
|
|
804
|
+
get: get
|
|
805
|
+
};
|
|
806
|
+
|
|
807
|
+
function set(val) {
|
|
808
|
+
var action = isFunction ? 'setting the method' : 'setting the property';
|
|
809
|
+
warn(action, 'This is effectively a no-op');
|
|
810
|
+
return val;
|
|
811
|
+
}
|
|
949
812
|
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
813
|
+
function get() {
|
|
814
|
+
var action = isFunction ? 'accessing the method' : 'accessing the property';
|
|
815
|
+
var result = isFunction ? 'This is a no-op function' : 'This is set to null';
|
|
816
|
+
warn(action, result);
|
|
817
|
+
return getVal;
|
|
818
|
+
}
|
|
955
819
|
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
820
|
+
function warn(action, result) {
|
|
821
|
+
{
|
|
822
|
+
error("This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
961
825
|
}
|
|
962
826
|
|
|
963
|
-
function
|
|
964
|
-
var
|
|
965
|
-
!warningCondition ? warningWithoutStack$1(false, "This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0;
|
|
966
|
-
}
|
|
967
|
-
}
|
|
827
|
+
function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
|
|
828
|
+
var EventConstructor = this;
|
|
968
829
|
|
|
969
|
-
|
|
970
|
-
|
|
830
|
+
if (EventConstructor.eventPool.length) {
|
|
831
|
+
var instance = EventConstructor.eventPool.pop();
|
|
832
|
+
EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
|
|
833
|
+
return instance;
|
|
834
|
+
}
|
|
971
835
|
|
|
972
|
-
|
|
973
|
-
var instance = EventConstructor.eventPool.pop();
|
|
974
|
-
EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
|
|
975
|
-
return instance;
|
|
836
|
+
return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);
|
|
976
837
|
}
|
|
977
838
|
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
function releasePooledEvent(event) {
|
|
982
|
-
var EventConstructor = this;
|
|
839
|
+
function releasePooledEvent(event) {
|
|
840
|
+
var EventConstructor = this;
|
|
983
841
|
|
|
984
|
-
(function () {
|
|
985
842
|
if (!(event instanceof EventConstructor)) {
|
|
986
843
|
{
|
|
987
|
-
throw
|
|
844
|
+
throw Error( "Trying to release an event instance into a pool of a different type." );
|
|
988
845
|
}
|
|
989
846
|
}
|
|
990
|
-
})();
|
|
991
847
|
|
|
992
|
-
|
|
848
|
+
event.destructor();
|
|
993
849
|
|
|
994
|
-
|
|
995
|
-
|
|
850
|
+
if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
|
|
851
|
+
EventConstructor.eventPool.push(event);
|
|
852
|
+
}
|
|
996
853
|
}
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
function addEventPoolingTo(EventConstructor) {
|
|
1000
|
-
EventConstructor.eventPool = [];
|
|
1001
|
-
EventConstructor.getPooled = getPooledEvent;
|
|
1002
|
-
EventConstructor.release = releasePooledEvent;
|
|
1003
|
-
}
|
|
1004
|
-
|
|
1005
|
-
/**
|
|
1006
|
-
* `touchHistory` isn't actually on the native event, but putting it in the
|
|
1007
|
-
* interface will ensure that it is cleaned up when pooled/destroyed. The
|
|
1008
|
-
* `ResponderEventPlugin` will populate it appropriately.
|
|
1009
|
-
*/
|
|
1010
854
|
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
855
|
+
function addEventPoolingTo(EventConstructor) {
|
|
856
|
+
EventConstructor.eventPool = [];
|
|
857
|
+
EventConstructor.getPooled = getPooledEvent;
|
|
858
|
+
EventConstructor.release = releasePooledEvent;
|
|
1014
859
|
}
|
|
1015
|
-
});
|
|
1016
|
-
|
|
1017
|
-
// Note: ideally these would be imported from DOMTopLevelEventTypes,
|
|
1018
|
-
// but our build system currently doesn't let us do that from a fork.
|
|
1019
|
-
var TOP_TOUCH_START = 'touchstart';
|
|
1020
|
-
var TOP_TOUCH_MOVE = 'touchmove';
|
|
1021
|
-
var TOP_TOUCH_END = 'touchend';
|
|
1022
|
-
var TOP_TOUCH_CANCEL = 'touchcancel';
|
|
1023
|
-
var TOP_SCROLL = 'scroll';
|
|
1024
|
-
var TOP_SELECTION_CHANGE = 'selectionchange';
|
|
1025
|
-
var TOP_MOUSE_DOWN = 'mousedown';
|
|
1026
|
-
var TOP_MOUSE_MOVE = 'mousemove';
|
|
1027
|
-
var TOP_MOUSE_UP = 'mouseup';
|
|
1028
|
-
function isStartish(topLevelType) {
|
|
1029
|
-
return topLevelType === TOP_TOUCH_START || topLevelType === TOP_MOUSE_DOWN;
|
|
1030
|
-
}
|
|
1031
|
-
function isMoveish(topLevelType) {
|
|
1032
|
-
return topLevelType === TOP_TOUCH_MOVE || topLevelType === TOP_MOUSE_MOVE;
|
|
1033
|
-
}
|
|
1034
|
-
function isEndish(topLevelType) {
|
|
1035
|
-
return topLevelType === TOP_TOUCH_END || topLevelType === TOP_TOUCH_CANCEL || topLevelType === TOP_MOUSE_UP;
|
|
1036
|
-
}
|
|
1037
|
-
var startDependencies = [TOP_TOUCH_START, TOP_MOUSE_DOWN];
|
|
1038
|
-
var moveDependencies = [TOP_TOUCH_MOVE, TOP_MOUSE_MOVE];
|
|
1039
|
-
var endDependencies = [TOP_TOUCH_CANCEL, TOP_TOUCH_END, TOP_MOUSE_UP];
|
|
1040
|
-
|
|
1041
|
-
/**
|
|
1042
|
-
* Tracks the position and time of each active touch by `touch.identifier`. We
|
|
1043
|
-
* should typically only see IDs in the range of 1-20 because IDs get recycled
|
|
1044
|
-
* when touches end and start again.
|
|
1045
|
-
*/
|
|
1046
|
-
|
|
1047
|
-
var MAX_TOUCH_BANK = 20;
|
|
1048
|
-
var touchBank = [];
|
|
1049
|
-
var touchHistory = {
|
|
1050
|
-
touchBank: touchBank,
|
|
1051
|
-
numberActiveTouches: 0,
|
|
1052
|
-
// If there is only one active touch, we remember its location. This prevents
|
|
1053
|
-
// us having to loop through all of the touches all the time in the most
|
|
1054
|
-
// common case.
|
|
1055
|
-
indexOfSingleActiveTouch: -1,
|
|
1056
|
-
mostRecentTimeStamp: 0
|
|
1057
|
-
};
|
|
1058
|
-
|
|
1059
|
-
function timestampForTouch(touch) {
|
|
1060
|
-
// The legacy internal implementation provides "timeStamp", which has been
|
|
1061
|
-
// renamed to "timestamp". Let both work for now while we iron it out
|
|
1062
|
-
// TODO (evv): rename timeStamp to timestamp in internal code
|
|
1063
|
-
return touch.timeStamp || touch.timestamp;
|
|
1064
|
-
}
|
|
1065
|
-
/**
|
|
1066
|
-
* TODO: Instead of making gestures recompute filtered velocity, we could
|
|
1067
|
-
* include a built in velocity computation that can be reused globally.
|
|
1068
|
-
*/
|
|
1069
860
|
|
|
861
|
+
/**
|
|
862
|
+
* `touchHistory` isn't actually on the native event, but putting it in the
|
|
863
|
+
* interface will ensure that it is cleaned up when pooled/destroyed. The
|
|
864
|
+
* `ResponderEventPlugin` will populate it appropriately.
|
|
865
|
+
*/
|
|
1070
866
|
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
startPageX: touch.pageX,
|
|
1075
|
-
startPageY: touch.pageY,
|
|
1076
|
-
startTimeStamp: timestampForTouch(touch),
|
|
1077
|
-
currentPageX: touch.pageX,
|
|
1078
|
-
currentPageY: touch.pageY,
|
|
1079
|
-
currentTimeStamp: timestampForTouch(touch),
|
|
1080
|
-
previousPageX: touch.pageX,
|
|
1081
|
-
previousPageY: touch.pageY,
|
|
1082
|
-
previousTimeStamp: timestampForTouch(touch)
|
|
1083
|
-
};
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
function resetTouchRecord(touchRecord, touch) {
|
|
1087
|
-
touchRecord.touchActive = true;
|
|
1088
|
-
touchRecord.startPageX = touch.pageX;
|
|
1089
|
-
touchRecord.startPageY = touch.pageY;
|
|
1090
|
-
touchRecord.startTimeStamp = timestampForTouch(touch);
|
|
1091
|
-
touchRecord.currentPageX = touch.pageX;
|
|
1092
|
-
touchRecord.currentPageY = touch.pageY;
|
|
1093
|
-
touchRecord.currentTimeStamp = timestampForTouch(touch);
|
|
1094
|
-
touchRecord.previousPageX = touch.pageX;
|
|
1095
|
-
touchRecord.previousPageY = touch.pageY;
|
|
1096
|
-
touchRecord.previousTimeStamp = timestampForTouch(touch);
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
function getTouchIdentifier(_ref) {
|
|
1100
|
-
var identifier = _ref.identifier;
|
|
1101
|
-
|
|
1102
|
-
(function () {
|
|
1103
|
-
if (!(identifier != null)) {
|
|
1104
|
-
{
|
|
1105
|
-
throw ReactError(Error("Touch object is missing identifier."));
|
|
1106
|
-
}
|
|
867
|
+
var ResponderSyntheticEvent = SyntheticEvent.extend({
|
|
868
|
+
touchHistory: function (nativeEvent) {
|
|
869
|
+
return null; // Actually doesn't even look at the native event.
|
|
1107
870
|
}
|
|
1108
|
-
})
|
|
871
|
+
});
|
|
1109
872
|
|
|
1110
|
-
|
|
1111
|
-
|
|
873
|
+
// Note: ideally these would be imported from DOMTopLevelEventTypes,
|
|
874
|
+
// but our build system currently doesn't let us do that from a fork.
|
|
875
|
+
var TOP_TOUCH_START = 'touchstart';
|
|
876
|
+
var TOP_TOUCH_MOVE = 'touchmove';
|
|
877
|
+
var TOP_TOUCH_END = 'touchend';
|
|
878
|
+
var TOP_TOUCH_CANCEL = 'touchcancel';
|
|
879
|
+
var TOP_SCROLL = 'scroll';
|
|
880
|
+
var TOP_SELECTION_CHANGE = 'selectionchange';
|
|
881
|
+
var TOP_MOUSE_DOWN = 'mousedown';
|
|
882
|
+
var TOP_MOUSE_MOVE = 'mousemove';
|
|
883
|
+
var TOP_MOUSE_UP = 'mouseup';
|
|
884
|
+
function isStartish(topLevelType) {
|
|
885
|
+
return topLevelType === TOP_TOUCH_START || topLevelType === TOP_MOUSE_DOWN;
|
|
1112
886
|
}
|
|
887
|
+
function isMoveish(topLevelType) {
|
|
888
|
+
return topLevelType === TOP_TOUCH_MOVE || topLevelType === TOP_MOUSE_MOVE;
|
|
889
|
+
}
|
|
890
|
+
function isEndish(topLevelType) {
|
|
891
|
+
return topLevelType === TOP_TOUCH_END || topLevelType === TOP_TOUCH_CANCEL || topLevelType === TOP_MOUSE_UP;
|
|
892
|
+
}
|
|
893
|
+
var startDependencies = [TOP_TOUCH_START, TOP_MOUSE_DOWN];
|
|
894
|
+
var moveDependencies = [TOP_TOUCH_MOVE, TOP_MOUSE_MOVE];
|
|
895
|
+
var endDependencies = [TOP_TOUCH_CANCEL, TOP_TOUCH_END, TOP_MOUSE_UP];
|
|
1113
896
|
|
|
1114
|
-
|
|
1115
|
-
|
|
897
|
+
/**
|
|
898
|
+
* Tracks the position and time of each active touch by `touch.identifier`. We
|
|
899
|
+
* should typically only see IDs in the range of 1-20 because IDs get recycled
|
|
900
|
+
* when touches end and start again.
|
|
901
|
+
*/
|
|
1116
902
|
|
|
1117
|
-
|
|
1118
|
-
var
|
|
1119
|
-
var
|
|
903
|
+
var MAX_TOUCH_BANK = 20;
|
|
904
|
+
var touchBank = [];
|
|
905
|
+
var touchHistory = {
|
|
906
|
+
touchBank: touchBank,
|
|
907
|
+
numberActiveTouches: 0,
|
|
908
|
+
// If there is only one active touch, we remember its location. This prevents
|
|
909
|
+
// us having to loop through all of the touches all the time in the most
|
|
910
|
+
// common case.
|
|
911
|
+
indexOfSingleActiveTouch: -1,
|
|
912
|
+
mostRecentTimeStamp: 0
|
|
913
|
+
};
|
|
1120
914
|
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
915
|
+
function timestampForTouch(touch) {
|
|
916
|
+
// The legacy internal implementation provides "timeStamp", which has been
|
|
917
|
+
// renamed to "timestamp". Let both work for now while we iron it out
|
|
918
|
+
// TODO (evv): rename timeStamp to timestamp in internal code
|
|
919
|
+
return touch.timeStamp || touch.timestamp;
|
|
1125
920
|
}
|
|
921
|
+
/**
|
|
922
|
+
* TODO: Instead of making gestures recompute filtered velocity, we could
|
|
923
|
+
* include a built in velocity computation that can be reused globally.
|
|
924
|
+
*/
|
|
1126
925
|
|
|
1127
|
-
touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
|
|
1128
|
-
}
|
|
1129
926
|
|
|
1130
|
-
function
|
|
1131
|
-
|
|
927
|
+
function createTouchRecord(touch) {
|
|
928
|
+
return {
|
|
929
|
+
touchActive: true,
|
|
930
|
+
startPageX: touch.pageX,
|
|
931
|
+
startPageY: touch.pageY,
|
|
932
|
+
startTimeStamp: timestampForTouch(touch),
|
|
933
|
+
currentPageX: touch.pageX,
|
|
934
|
+
currentPageY: touch.pageY,
|
|
935
|
+
currentTimeStamp: timestampForTouch(touch),
|
|
936
|
+
previousPageX: touch.pageX,
|
|
937
|
+
previousPageY: touch.pageY,
|
|
938
|
+
previousTimeStamp: timestampForTouch(touch)
|
|
939
|
+
};
|
|
940
|
+
}
|
|
1132
941
|
|
|
1133
|
-
|
|
942
|
+
function resetTouchRecord(touchRecord, touch) {
|
|
1134
943
|
touchRecord.touchActive = true;
|
|
1135
|
-
touchRecord.
|
|
1136
|
-
touchRecord.
|
|
1137
|
-
touchRecord.
|
|
944
|
+
touchRecord.startPageX = touch.pageX;
|
|
945
|
+
touchRecord.startPageY = touch.pageY;
|
|
946
|
+
touchRecord.startTimeStamp = timestampForTouch(touch);
|
|
1138
947
|
touchRecord.currentPageX = touch.pageX;
|
|
1139
948
|
touchRecord.currentPageY = touch.pageY;
|
|
1140
949
|
touchRecord.currentTimeStamp = timestampForTouch(touch);
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
950
|
+
touchRecord.previousPageX = touch.pageX;
|
|
951
|
+
touchRecord.previousPageY = touch.pageY;
|
|
952
|
+
touchRecord.previousTimeStamp = timestampForTouch(touch);
|
|
1144
953
|
}
|
|
1145
|
-
}
|
|
1146
954
|
|
|
1147
|
-
function
|
|
1148
|
-
|
|
955
|
+
function getTouchIdentifier(_ref) {
|
|
956
|
+
var identifier = _ref.identifier;
|
|
957
|
+
|
|
958
|
+
if (!(identifier != null)) {
|
|
959
|
+
{
|
|
960
|
+
throw Error( "Touch object is missing identifier." );
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
{
|
|
965
|
+
if (identifier > MAX_TOUCH_BANK) {
|
|
966
|
+
error('Touch identifier %s is greater than maximum supported %s which causes ' + 'performance issues backfilling array locations for all of the indices.', identifier, MAX_TOUCH_BANK);
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
return identifier;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
function recordTouchStart(touch) {
|
|
974
|
+
var identifier = getTouchIdentifier(touch);
|
|
975
|
+
var touchRecord = touchBank[identifier];
|
|
976
|
+
|
|
977
|
+
if (touchRecord) {
|
|
978
|
+
resetTouchRecord(touchRecord, touch);
|
|
979
|
+
} else {
|
|
980
|
+
touchBank[identifier] = createTouchRecord(touch);
|
|
981
|
+
}
|
|
1149
982
|
|
|
1150
|
-
if (touchRecord) {
|
|
1151
|
-
touchRecord.touchActive = false;
|
|
1152
|
-
touchRecord.previousPageX = touchRecord.currentPageX;
|
|
1153
|
-
touchRecord.previousPageY = touchRecord.currentPageY;
|
|
1154
|
-
touchRecord.previousTimeStamp = touchRecord.currentTimeStamp;
|
|
1155
|
-
touchRecord.currentPageX = touch.pageX;
|
|
1156
|
-
touchRecord.currentPageY = touch.pageY;
|
|
1157
|
-
touchRecord.currentTimeStamp = timestampForTouch(touch);
|
|
1158
983
|
touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
|
|
1159
|
-
} else {
|
|
1160
|
-
console.warn('Cannot record touch end without a touch start.\n' + 'Touch End: %s\n', 'Touch Bank: %s', printTouch(touch), printTouchBank());
|
|
1161
984
|
}
|
|
1162
|
-
}
|
|
1163
|
-
|
|
1164
|
-
function printTouch(touch) {
|
|
1165
|
-
return JSON.stringify({
|
|
1166
|
-
identifier: touch.identifier,
|
|
1167
|
-
pageX: touch.pageX,
|
|
1168
|
-
pageY: touch.pageY,
|
|
1169
|
-
timestamp: timestampForTouch(touch)
|
|
1170
|
-
});
|
|
1171
|
-
}
|
|
1172
985
|
|
|
1173
|
-
function
|
|
1174
|
-
|
|
986
|
+
function recordTouchMove(touch) {
|
|
987
|
+
var touchRecord = touchBank[getTouchIdentifier(touch)];
|
|
988
|
+
|
|
989
|
+
if (touchRecord) {
|
|
990
|
+
touchRecord.touchActive = true;
|
|
991
|
+
touchRecord.previousPageX = touchRecord.currentPageX;
|
|
992
|
+
touchRecord.previousPageY = touchRecord.currentPageY;
|
|
993
|
+
touchRecord.previousTimeStamp = touchRecord.currentTimeStamp;
|
|
994
|
+
touchRecord.currentPageX = touch.pageX;
|
|
995
|
+
touchRecord.currentPageY = touch.pageY;
|
|
996
|
+
touchRecord.currentTimeStamp = timestampForTouch(touch);
|
|
997
|
+
touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
|
|
998
|
+
} else {
|
|
999
|
+
{
|
|
1000
|
+
warn('Cannot record touch move without a touch start.\n' + 'Touch Move: %s\n' + 'Touch Bank: %s', printTouch(touch), printTouchBank());
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
function recordTouchEnd(touch) {
|
|
1006
|
+
var touchRecord = touchBank[getTouchIdentifier(touch)];
|
|
1007
|
+
|
|
1008
|
+
if (touchRecord) {
|
|
1009
|
+
touchRecord.touchActive = false;
|
|
1010
|
+
touchRecord.previousPageX = touchRecord.currentPageX;
|
|
1011
|
+
touchRecord.previousPageY = touchRecord.currentPageY;
|
|
1012
|
+
touchRecord.previousTimeStamp = touchRecord.currentTimeStamp;
|
|
1013
|
+
touchRecord.currentPageX = touch.pageX;
|
|
1014
|
+
touchRecord.currentPageY = touch.pageY;
|
|
1015
|
+
touchRecord.currentTimeStamp = timestampForTouch(touch);
|
|
1016
|
+
touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
|
|
1017
|
+
} else {
|
|
1018
|
+
{
|
|
1019
|
+
warn('Cannot record touch end without a touch start.\n' + 'Touch End: %s\n' + 'Touch Bank: %s', printTouch(touch), printTouchBank());
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1175
1023
|
|
|
1176
|
-
|
|
1177
|
-
|
|
1024
|
+
function printTouch(touch) {
|
|
1025
|
+
return JSON.stringify({
|
|
1026
|
+
identifier: touch.identifier,
|
|
1027
|
+
pageX: touch.pageX,
|
|
1028
|
+
pageY: touch.pageY,
|
|
1029
|
+
timestamp: timestampForTouch(touch)
|
|
1030
|
+
});
|
|
1178
1031
|
}
|
|
1179
1032
|
|
|
1180
|
-
|
|
1181
|
-
|
|
1033
|
+
function printTouchBank() {
|
|
1034
|
+
var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK));
|
|
1182
1035
|
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
nativeEvent.changedTouches.forEach(recordTouchMove);
|
|
1187
|
-
} else if (isStartish(topLevelType)) {
|
|
1188
|
-
nativeEvent.changedTouches.forEach(recordTouchStart);
|
|
1189
|
-
touchHistory.numberActiveTouches = nativeEvent.touches.length;
|
|
1036
|
+
if (touchBank.length > MAX_TOUCH_BANK) {
|
|
1037
|
+
printed += ' (original size: ' + touchBank.length + ')';
|
|
1038
|
+
}
|
|
1190
1039
|
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
}
|
|
1194
|
-
} else if (isEndish(topLevelType)) {
|
|
1195
|
-
nativeEvent.changedTouches.forEach(recordTouchEnd);
|
|
1196
|
-
touchHistory.numberActiveTouches = nativeEvent.touches.length;
|
|
1040
|
+
return printed;
|
|
1041
|
+
}
|
|
1197
1042
|
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1043
|
+
var ResponderTouchHistoryStore = {
|
|
1044
|
+
recordTouchTrack: function (topLevelType, nativeEvent) {
|
|
1045
|
+
if (isMoveish(topLevelType)) {
|
|
1046
|
+
nativeEvent.changedTouches.forEach(recordTouchMove);
|
|
1047
|
+
} else if (isStartish(topLevelType)) {
|
|
1048
|
+
nativeEvent.changedTouches.forEach(recordTouchStart);
|
|
1049
|
+
touchHistory.numberActiveTouches = nativeEvent.touches.length;
|
|
1201
1050
|
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
break;
|
|
1205
|
-
}
|
|
1051
|
+
if (touchHistory.numberActiveTouches === 1) {
|
|
1052
|
+
touchHistory.indexOfSingleActiveTouch = nativeEvent.touches[0].identifier;
|
|
1206
1053
|
}
|
|
1054
|
+
} else if (isEndish(topLevelType)) {
|
|
1055
|
+
nativeEvent.changedTouches.forEach(recordTouchEnd);
|
|
1056
|
+
touchHistory.numberActiveTouches = nativeEvent.touches.length;
|
|
1057
|
+
|
|
1058
|
+
if (touchHistory.numberActiveTouches === 1) {
|
|
1059
|
+
for (var i = 0; i < touchBank.length; i++) {
|
|
1060
|
+
var touchTrackToCheck = touchBank[i];
|
|
1061
|
+
|
|
1062
|
+
if (touchTrackToCheck != null && touchTrackToCheck.touchActive) {
|
|
1063
|
+
touchHistory.indexOfSingleActiveTouch = i;
|
|
1064
|
+
break;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1207
1067
|
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1068
|
+
{
|
|
1069
|
+
var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch];
|
|
1070
|
+
|
|
1071
|
+
if (activeRecord == null || !activeRecord.touchActive) {
|
|
1072
|
+
error('Cannot find single active touch.');
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1211
1075
|
}
|
|
1212
1076
|
}
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
};
|
|
1077
|
+
},
|
|
1078
|
+
touchHistory: touchHistory
|
|
1079
|
+
};
|
|
1217
1080
|
|
|
1218
|
-
/**
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1081
|
+
/**
|
|
1082
|
+
* Accumulates items that must not be null or undefined.
|
|
1083
|
+
*
|
|
1084
|
+
* This is used to conserve memory by avoiding array allocations.
|
|
1085
|
+
*
|
|
1086
|
+
* @return {*|array<*>} An accumulation of items.
|
|
1087
|
+
*/
|
|
1225
1088
|
|
|
1226
|
-
function accumulate(current, next) {
|
|
1227
|
-
(function () {
|
|
1089
|
+
function accumulate(current, next) {
|
|
1228
1090
|
if (!(next != null)) {
|
|
1229
1091
|
{
|
|
1230
|
-
throw
|
|
1092
|
+
throw Error( "accumulate(...): Accumulated items must not be null or undefined." );
|
|
1231
1093
|
}
|
|
1232
1094
|
}
|
|
1233
|
-
})();
|
|
1234
1095
|
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1096
|
+
if (current == null) {
|
|
1097
|
+
return next;
|
|
1098
|
+
} // Both are not empty. Warning: Never call x.concat(y) when you are not
|
|
1099
|
+
// certain that x is an Array (x could be a string with concat method).
|
|
1239
1100
|
|
|
1240
1101
|
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1102
|
+
if (Array.isArray(current)) {
|
|
1103
|
+
return current.concat(next);
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
if (Array.isArray(next)) {
|
|
1107
|
+
return [current].concat(next);
|
|
1108
|
+
}
|
|
1244
1109
|
|
|
1245
|
-
|
|
1246
|
-
return [current].concat(next);
|
|
1110
|
+
return [current, next];
|
|
1247
1111
|
}
|
|
1248
1112
|
|
|
1249
|
-
|
|
1250
|
-
|
|
1113
|
+
/**
|
|
1114
|
+
* Instance of element that should respond to touch/move types of interactions,
|
|
1115
|
+
* as indicated explicitly by relevant callbacks.
|
|
1116
|
+
*/
|
|
1251
1117
|
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1118
|
+
var responderInst = null;
|
|
1119
|
+
/**
|
|
1120
|
+
* Count of current touches. A textInput should become responder iff the
|
|
1121
|
+
* selection changes while there is a touch on the screen.
|
|
1122
|
+
*/
|
|
1256
1123
|
|
|
1257
|
-
var
|
|
1258
|
-
/**
|
|
1259
|
-
* Count of current touches. A textInput should become responder iff the
|
|
1260
|
-
* selection changes while there is a touch on the screen.
|
|
1261
|
-
*/
|
|
1124
|
+
var trackedTouchCount = 0;
|
|
1262
1125
|
|
|
1263
|
-
var
|
|
1126
|
+
var changeResponder = function (nextResponderInst, blockHostResponder) {
|
|
1127
|
+
var oldResponderInst = responderInst;
|
|
1128
|
+
responderInst = nextResponderInst;
|
|
1264
1129
|
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1130
|
+
if (ResponderEventPlugin.GlobalResponderHandler !== null) {
|
|
1131
|
+
ResponderEventPlugin.GlobalResponderHandler.onChange(oldResponderInst, nextResponderInst, blockHostResponder);
|
|
1132
|
+
}
|
|
1133
|
+
};
|
|
1268
1134
|
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1135
|
+
var eventTypes = {
|
|
1136
|
+
/**
|
|
1137
|
+
* On a `touchStart`/`mouseDown`, is it desired that this element become the
|
|
1138
|
+
* responder?
|
|
1139
|
+
*/
|
|
1140
|
+
startShouldSetResponder: {
|
|
1141
|
+
phasedRegistrationNames: {
|
|
1142
|
+
bubbled: 'onStartShouldSetResponder',
|
|
1143
|
+
captured: 'onStartShouldSetResponderCapture'
|
|
1144
|
+
},
|
|
1145
|
+
dependencies: startDependencies
|
|
1146
|
+
},
|
|
1273
1147
|
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1148
|
+
/**
|
|
1149
|
+
* On a `scroll`, is it desired that this element become the responder? This
|
|
1150
|
+
* is usually not needed, but should be used to retroactively infer that a
|
|
1151
|
+
* `touchStart` had occurred during momentum scroll. During a momentum scroll,
|
|
1152
|
+
* a touch start will be immediately followed by a scroll event if the view is
|
|
1153
|
+
* currently scrolling.
|
|
1154
|
+
*
|
|
1155
|
+
* TODO: This shouldn't bubble.
|
|
1156
|
+
*/
|
|
1157
|
+
scrollShouldSetResponder: {
|
|
1158
|
+
phasedRegistrationNames: {
|
|
1159
|
+
bubbled: 'onScrollShouldSetResponder',
|
|
1160
|
+
captured: 'onScrollShouldSetResponderCapture'
|
|
1161
|
+
},
|
|
1162
|
+
dependencies: [TOP_SCROLL]
|
|
1283
1163
|
},
|
|
1284
|
-
dependencies: startDependencies
|
|
1285
|
-
},
|
|
1286
1164
|
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1165
|
+
/**
|
|
1166
|
+
* On text selection change, should this element become the responder? This
|
|
1167
|
+
* is needed for text inputs or other views with native selection, so the
|
|
1168
|
+
* JS view can claim the responder.
|
|
1169
|
+
*
|
|
1170
|
+
* TODO: This shouldn't bubble.
|
|
1171
|
+
*/
|
|
1172
|
+
selectionChangeShouldSetResponder: {
|
|
1173
|
+
phasedRegistrationNames: {
|
|
1174
|
+
bubbled: 'onSelectionChangeShouldSetResponder',
|
|
1175
|
+
captured: 'onSelectionChangeShouldSetResponderCapture'
|
|
1176
|
+
},
|
|
1177
|
+
dependencies: [TOP_SELECTION_CHANGE]
|
|
1300
1178
|
},
|
|
1301
|
-
dependencies: [TOP_SCROLL]
|
|
1302
|
-
},
|
|
1303
1179
|
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
captured: 'onSelectionChangeShouldSetResponderCapture'
|
|
1180
|
+
/**
|
|
1181
|
+
* On a `touchMove`/`mouseMove`, is it desired that this element become the
|
|
1182
|
+
* responder?
|
|
1183
|
+
*/
|
|
1184
|
+
moveShouldSetResponder: {
|
|
1185
|
+
phasedRegistrationNames: {
|
|
1186
|
+
bubbled: 'onMoveShouldSetResponder',
|
|
1187
|
+
captured: 'onMoveShouldSetResponderCapture'
|
|
1188
|
+
},
|
|
1189
|
+
dependencies: moveDependencies
|
|
1315
1190
|
},
|
|
1316
|
-
dependencies: [TOP_SELECTION_CHANGE]
|
|
1317
|
-
},
|
|
1318
1191
|
|
|
1192
|
+
/**
|
|
1193
|
+
* Direct responder events dispatched directly to responder. Do not bubble.
|
|
1194
|
+
*/
|
|
1195
|
+
responderStart: {
|
|
1196
|
+
registrationName: 'onResponderStart',
|
|
1197
|
+
dependencies: startDependencies
|
|
1198
|
+
},
|
|
1199
|
+
responderMove: {
|
|
1200
|
+
registrationName: 'onResponderMove',
|
|
1201
|
+
dependencies: moveDependencies
|
|
1202
|
+
},
|
|
1203
|
+
responderEnd: {
|
|
1204
|
+
registrationName: 'onResponderEnd',
|
|
1205
|
+
dependencies: endDependencies
|
|
1206
|
+
},
|
|
1207
|
+
responderRelease: {
|
|
1208
|
+
registrationName: 'onResponderRelease',
|
|
1209
|
+
dependencies: endDependencies
|
|
1210
|
+
},
|
|
1211
|
+
responderTerminationRequest: {
|
|
1212
|
+
registrationName: 'onResponderTerminationRequest',
|
|
1213
|
+
dependencies: []
|
|
1214
|
+
},
|
|
1215
|
+
responderGrant: {
|
|
1216
|
+
registrationName: 'onResponderGrant',
|
|
1217
|
+
dependencies: []
|
|
1218
|
+
},
|
|
1219
|
+
responderReject: {
|
|
1220
|
+
registrationName: 'onResponderReject',
|
|
1221
|
+
dependencies: []
|
|
1222
|
+
},
|
|
1223
|
+
responderTerminate: {
|
|
1224
|
+
registrationName: 'onResponderTerminate',
|
|
1225
|
+
dependencies: []
|
|
1226
|
+
}
|
|
1227
|
+
};
|
|
1319
1228
|
/**
|
|
1320
|
-
*
|
|
1321
|
-
*
|
|
1229
|
+
*
|
|
1230
|
+
* Responder System:
|
|
1231
|
+
* ----------------
|
|
1232
|
+
*
|
|
1233
|
+
* - A global, solitary "interaction lock" on a view.
|
|
1234
|
+
* - If a node becomes the responder, it should convey visual feedback
|
|
1235
|
+
* immediately to indicate so, either by highlighting or moving accordingly.
|
|
1236
|
+
* - To be the responder means, that touches are exclusively important to that
|
|
1237
|
+
* responder view, and no other view.
|
|
1238
|
+
* - While touches are still occurring, the responder lock can be transferred to
|
|
1239
|
+
* a new view, but only to increasingly "higher" views (meaning ancestors of
|
|
1240
|
+
* the current responder).
|
|
1241
|
+
*
|
|
1242
|
+
* Responder being granted:
|
|
1243
|
+
* ------------------------
|
|
1244
|
+
*
|
|
1245
|
+
* - Touch starts, moves, and scrolls can cause an ID to become the responder.
|
|
1246
|
+
* - We capture/bubble `startShouldSetResponder`/`moveShouldSetResponder` to
|
|
1247
|
+
* the "appropriate place".
|
|
1248
|
+
* - If nothing is currently the responder, the "appropriate place" is the
|
|
1249
|
+
* initiating event's `targetID`.
|
|
1250
|
+
* - If something *is* already the responder, the "appropriate place" is the
|
|
1251
|
+
* first common ancestor of the event target and the current `responderInst`.
|
|
1252
|
+
* - Some negotiation happens: See the timing diagram below.
|
|
1253
|
+
* - Scrolled views automatically become responder. The reasoning is that a
|
|
1254
|
+
* platform scroll view that isn't built on top of the responder system has
|
|
1255
|
+
* began scrolling, and the active responder must now be notified that the
|
|
1256
|
+
* interaction is no longer locked to it - the system has taken over.
|
|
1257
|
+
*
|
|
1258
|
+
* - Responder being released:
|
|
1259
|
+
* As soon as no more touches that *started* inside of descendants of the
|
|
1260
|
+
* *current* responderInst, an `onResponderRelease` event is dispatched to the
|
|
1261
|
+
* current responder, and the responder lock is released.
|
|
1262
|
+
*
|
|
1263
|
+
* TODO:
|
|
1264
|
+
* - on "end", a callback hook for `onResponderEndShouldRemainResponder` that
|
|
1265
|
+
* determines if the responder lock should remain.
|
|
1266
|
+
* - If a view shouldn't "remain" the responder, any active touches should by
|
|
1267
|
+
* default be considered "dead" and do not influence future negotiations or
|
|
1268
|
+
* bubble paths. It should be as if those touches do not exist.
|
|
1269
|
+
* -- For multitouch: Usually a translate-z will choose to "remain" responder
|
|
1270
|
+
* after one out of many touches ended. For translate-y, usually the view
|
|
1271
|
+
* doesn't wish to "remain" responder after one of many touches end.
|
|
1272
|
+
* - Consider building this on top of a `stopPropagation` model similar to
|
|
1273
|
+
* `W3C` events.
|
|
1274
|
+
* - Ensure that `onResponderTerminate` is called on touch cancels, whether or
|
|
1275
|
+
* not `onResponderTerminationRequest` returns `true` or `false`.
|
|
1276
|
+
*
|
|
1322
1277
|
*/
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1278
|
+
|
|
1279
|
+
/* Negotiation Performed
|
|
1280
|
+
+-----------------------+
|
|
1281
|
+
/ \
|
|
1282
|
+
Process low level events to + Current Responder + wantsResponderID
|
|
1283
|
+
determine who to perform negot-| (if any exists at all) |
|
|
1284
|
+
iation/transition | Otherwise just pass through|
|
|
1285
|
+
-------------------------------+----------------------------+------------------+
|
|
1286
|
+
Bubble to find first ID | |
|
|
1287
|
+
to return true:wantsResponderID| |
|
|
1288
|
+
| |
|
|
1289
|
+
+-------------+ | |
|
|
1290
|
+
| onTouchStart| | |
|
|
1291
|
+
+------+------+ none | |
|
|
1292
|
+
| return| |
|
|
1293
|
+
+-----------v-------------+true| +------------------------+ |
|
|
1294
|
+
|onStartShouldSetResponder|----->|onResponderStart (cur) |<-----------+
|
|
1295
|
+
+-----------+-------------+ | +------------------------+ | |
|
|
1296
|
+
| | | +--------+-------+
|
|
1297
|
+
| returned true for| false:REJECT +-------->|onResponderReject
|
|
1298
|
+
| wantsResponderID | | | +----------------+
|
|
1299
|
+
| (now attempt | +------------------+-----+ |
|
|
1300
|
+
| handoff) | | onResponder | |
|
|
1301
|
+
+------------------->| TerminationRequest| |
|
|
1302
|
+
| +------------------+-----+ |
|
|
1303
|
+
| | | +----------------+
|
|
1304
|
+
| true:GRANT +-------->|onResponderGrant|
|
|
1305
|
+
| | +--------+-------+
|
|
1306
|
+
| +------------------------+ | |
|
|
1307
|
+
| | onResponderTerminate |<-----------+
|
|
1308
|
+
| +------------------+-----+ |
|
|
1309
|
+
| | | +----------------+
|
|
1310
|
+
| +-------->|onResponderStart|
|
|
1311
|
+
| | +----------------+
|
|
1312
|
+
Bubble to find first ID | |
|
|
1313
|
+
to return true:wantsResponderID| |
|
|
1314
|
+
| |
|
|
1315
|
+
+-------------+ | |
|
|
1316
|
+
| onTouchMove | | |
|
|
1317
|
+
+------+------+ none | |
|
|
1318
|
+
| return| |
|
|
1319
|
+
+-----------v-------------+true| +------------------------+ |
|
|
1320
|
+
|onMoveShouldSetResponder |----->|onResponderMove (cur) |<-----------+
|
|
1321
|
+
+-----------+-------------+ | +------------------------+ | |
|
|
1322
|
+
| | | +--------+-------+
|
|
1323
|
+
| returned true for| false:REJECT +-------->|onResponderRejec|
|
|
1324
|
+
| wantsResponderID | | | +----------------+
|
|
1325
|
+
| (now attempt | +------------------+-----+ |
|
|
1326
|
+
| handoff) | | onResponder | |
|
|
1327
|
+
+------------------->| TerminationRequest| |
|
|
1328
|
+
| +------------------+-----+ |
|
|
1329
|
+
| | | +----------------+
|
|
1330
|
+
| true:GRANT +-------->|onResponderGrant|
|
|
1331
|
+
| | +--------+-------+
|
|
1332
|
+
| +------------------------+ | |
|
|
1333
|
+
| | onResponderTerminate |<-----------+
|
|
1334
|
+
| +------------------+-----+ |
|
|
1335
|
+
| | | +----------------+
|
|
1336
|
+
| +-------->|onResponderMove |
|
|
1337
|
+
| | +----------------+
|
|
1338
|
+
| |
|
|
1339
|
+
| |
|
|
1340
|
+
Some active touch started| |
|
|
1341
|
+
inside current responder | +------------------------+ |
|
|
1342
|
+
+------------------------->| onResponderEnd | |
|
|
1343
|
+
| | +------------------------+ |
|
|
1344
|
+
+---+---------+ | |
|
|
1345
|
+
| onTouchEnd | | |
|
|
1346
|
+
+---+---------+ | |
|
|
1347
|
+
| | +------------------------+ |
|
|
1348
|
+
+------------------------->| onResponderEnd | |
|
|
1349
|
+
No active touches started| +-----------+------------+ |
|
|
1350
|
+
inside current responder | | |
|
|
1351
|
+
| v |
|
|
1352
|
+
| +------------------------+ |
|
|
1353
|
+
| | onResponderRelease | |
|
|
1354
|
+
| +------------------------+ |
|
|
1355
|
+
| |
|
|
1356
|
+
+ + */
|
|
1330
1357
|
|
|
1331
1358
|
/**
|
|
1332
|
-
*
|
|
1359
|
+
* A note about event ordering in the `EventPluginRegistry`.
|
|
1360
|
+
*
|
|
1361
|
+
* Suppose plugins are injected in the following order:
|
|
1362
|
+
*
|
|
1363
|
+
* `[R, S, C]`
|
|
1364
|
+
*
|
|
1365
|
+
* To help illustrate the example, assume `S` is `SimpleEventPlugin` (for
|
|
1366
|
+
* `onClick` etc) and `R` is `ResponderEventPlugin`.
|
|
1367
|
+
*
|
|
1368
|
+
* "Deferred-Dispatched Events":
|
|
1369
|
+
*
|
|
1370
|
+
* - The current event plugin system will traverse the list of injected plugins,
|
|
1371
|
+
* in order, and extract events by collecting the plugin's return value of
|
|
1372
|
+
* `extractEvents()`.
|
|
1373
|
+
* - These events that are returned from `extractEvents` are "deferred
|
|
1374
|
+
* dispatched events".
|
|
1375
|
+
* - When returned from `extractEvents`, deferred-dispatched events contain an
|
|
1376
|
+
* "accumulation" of deferred dispatches.
|
|
1377
|
+
* - These deferred dispatches are accumulated/collected before they are
|
|
1378
|
+
* returned, but processed at a later time by the `EventPluginRegistry` (hence the
|
|
1379
|
+
* name deferred).
|
|
1380
|
+
*
|
|
1381
|
+
* In the process of returning their deferred-dispatched events, event plugins
|
|
1382
|
+
* themselves can dispatch events on-demand without returning them from
|
|
1383
|
+
* `extractEvents`. Plugins might want to do this, so that they can use event
|
|
1384
|
+
* dispatching as a tool that helps them decide which events should be extracted
|
|
1385
|
+
* in the first place.
|
|
1386
|
+
*
|
|
1387
|
+
* "On-Demand-Dispatched Events":
|
|
1388
|
+
*
|
|
1389
|
+
* - On-demand-dispatched events are not returned from `extractEvents`.
|
|
1390
|
+
* - On-demand-dispatched events are dispatched during the process of returning
|
|
1391
|
+
* the deferred-dispatched events.
|
|
1392
|
+
* - They should not have side effects.
|
|
1393
|
+
* - They should be avoided, and/or eventually be replaced with another
|
|
1394
|
+
* abstraction that allows event plugins to perform multiple "rounds" of event
|
|
1395
|
+
* extraction.
|
|
1396
|
+
*
|
|
1397
|
+
* Therefore, the sequence of event dispatches becomes:
|
|
1398
|
+
*
|
|
1399
|
+
* - `R`s on-demand events (if any) (dispatched by `R` on-demand)
|
|
1400
|
+
* - `S`s on-demand events (if any) (dispatched by `S` on-demand)
|
|
1401
|
+
* - `C`s on-demand events (if any) (dispatched by `C` on-demand)
|
|
1402
|
+
* - `R`s extracted events (if any) (dispatched by `EventPluginRegistry`)
|
|
1403
|
+
* - `S`s extracted events (if any) (dispatched by `EventPluginRegistry`)
|
|
1404
|
+
* - `C`s extracted events (if any) (dispatched by `EventPluginRegistry`)
|
|
1405
|
+
*
|
|
1406
|
+
* In the case of `ResponderEventPlugin`: If the `startShouldSetResponder`
|
|
1407
|
+
* on-demand dispatch returns `true` (and some other details are satisfied) the
|
|
1408
|
+
* `onResponderGrant` deferred dispatched event is returned from
|
|
1409
|
+
* `extractEvents`. The sequence of dispatch executions in this case
|
|
1410
|
+
* will appear as follows:
|
|
1411
|
+
*
|
|
1412
|
+
* - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand)
|
|
1413
|
+
* - `touchStartCapture` (`EventPluginRegistry` dispatches as usual)
|
|
1414
|
+
* - `touchStart` (`EventPluginRegistry` dispatches as usual)
|
|
1415
|
+
* - `responderGrant/Reject` (`EventPluginRegistry` dispatches as usual)
|
|
1333
1416
|
*/
|
|
1334
|
-
responderStart: {
|
|
1335
|
-
registrationName: 'onResponderStart',
|
|
1336
|
-
dependencies: startDependencies
|
|
1337
|
-
},
|
|
1338
|
-
responderMove: {
|
|
1339
|
-
registrationName: 'onResponderMove',
|
|
1340
|
-
dependencies: moveDependencies
|
|
1341
|
-
},
|
|
1342
|
-
responderEnd: {
|
|
1343
|
-
registrationName: 'onResponderEnd',
|
|
1344
|
-
dependencies: endDependencies
|
|
1345
|
-
},
|
|
1346
|
-
responderRelease: {
|
|
1347
|
-
registrationName: 'onResponderRelease',
|
|
1348
|
-
dependencies: endDependencies
|
|
1349
|
-
},
|
|
1350
|
-
responderTerminationRequest: {
|
|
1351
|
-
registrationName: 'onResponderTerminationRequest',
|
|
1352
|
-
dependencies: []
|
|
1353
|
-
},
|
|
1354
|
-
responderGrant: {
|
|
1355
|
-
registrationName: 'onResponderGrant',
|
|
1356
|
-
dependencies: []
|
|
1357
|
-
},
|
|
1358
|
-
responderReject: {
|
|
1359
|
-
registrationName: 'onResponderReject',
|
|
1360
|
-
dependencies: []
|
|
1361
|
-
},
|
|
1362
|
-
responderTerminate: {
|
|
1363
|
-
registrationName: 'onResponderTerminate',
|
|
1364
|
-
dependencies: []
|
|
1365
|
-
}
|
|
1366
|
-
};
|
|
1367
|
-
/**
|
|
1368
|
-
*
|
|
1369
|
-
* Responder System:
|
|
1370
|
-
* ----------------
|
|
1371
|
-
*
|
|
1372
|
-
* - A global, solitary "interaction lock" on a view.
|
|
1373
|
-
* - If a node becomes the responder, it should convey visual feedback
|
|
1374
|
-
* immediately to indicate so, either by highlighting or moving accordingly.
|
|
1375
|
-
* - To be the responder means, that touches are exclusively important to that
|
|
1376
|
-
* responder view, and no other view.
|
|
1377
|
-
* - While touches are still occurring, the responder lock can be transferred to
|
|
1378
|
-
* a new view, but only to increasingly "higher" views (meaning ancestors of
|
|
1379
|
-
* the current responder).
|
|
1380
|
-
*
|
|
1381
|
-
* Responder being granted:
|
|
1382
|
-
* ------------------------
|
|
1383
|
-
*
|
|
1384
|
-
* - Touch starts, moves, and scrolls can cause an ID to become the responder.
|
|
1385
|
-
* - We capture/bubble `startShouldSetResponder`/`moveShouldSetResponder` to
|
|
1386
|
-
* the "appropriate place".
|
|
1387
|
-
* - If nothing is currently the responder, the "appropriate place" is the
|
|
1388
|
-
* initiating event's `targetID`.
|
|
1389
|
-
* - If something *is* already the responder, the "appropriate place" is the
|
|
1390
|
-
* first common ancestor of the event target and the current `responderInst`.
|
|
1391
|
-
* - Some negotiation happens: See the timing diagram below.
|
|
1392
|
-
* - Scrolled views automatically become responder. The reasoning is that a
|
|
1393
|
-
* platform scroll view that isn't built on top of the responder system has
|
|
1394
|
-
* began scrolling, and the active responder must now be notified that the
|
|
1395
|
-
* interaction is no longer locked to it - the system has taken over.
|
|
1396
|
-
*
|
|
1397
|
-
* - Responder being released:
|
|
1398
|
-
* As soon as no more touches that *started* inside of descendants of the
|
|
1399
|
-
* *current* responderInst, an `onResponderRelease` event is dispatched to the
|
|
1400
|
-
* current responder, and the responder lock is released.
|
|
1401
|
-
*
|
|
1402
|
-
* TODO:
|
|
1403
|
-
* - on "end", a callback hook for `onResponderEndShouldRemainResponder` that
|
|
1404
|
-
* determines if the responder lock should remain.
|
|
1405
|
-
* - If a view shouldn't "remain" the responder, any active touches should by
|
|
1406
|
-
* default be considered "dead" and do not influence future negotiations or
|
|
1407
|
-
* bubble paths. It should be as if those touches do not exist.
|
|
1408
|
-
* -- For multitouch: Usually a translate-z will choose to "remain" responder
|
|
1409
|
-
* after one out of many touches ended. For translate-y, usually the view
|
|
1410
|
-
* doesn't wish to "remain" responder after one of many touches end.
|
|
1411
|
-
* - Consider building this on top of a `stopPropagation` model similar to
|
|
1412
|
-
* `W3C` events.
|
|
1413
|
-
* - Ensure that `onResponderTerminate` is called on touch cancels, whether or
|
|
1414
|
-
* not `onResponderTerminationRequest` returns `true` or `false`.
|
|
1415
|
-
*
|
|
1416
|
-
*/
|
|
1417
1417
|
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
/ \
|
|
1421
|
-
Process low level events to + Current Responder + wantsResponderID
|
|
1422
|
-
determine who to perform negot-| (if any exists at all) |
|
|
1423
|
-
iation/transition | Otherwise just pass through|
|
|
1424
|
-
-------------------------------+----------------------------+------------------+
|
|
1425
|
-
Bubble to find first ID | |
|
|
1426
|
-
to return true:wantsResponderID| |
|
|
1427
|
-
| |
|
|
1428
|
-
+-------------+ | |
|
|
1429
|
-
| onTouchStart| | |
|
|
1430
|
-
+------+------+ none | |
|
|
1431
|
-
| return| |
|
|
1432
|
-
+-----------v-------------+true| +------------------------+ |
|
|
1433
|
-
|onStartShouldSetResponder|----->|onResponderStart (cur) |<-----------+
|
|
1434
|
-
+-----------+-------------+ | +------------------------+ | |
|
|
1435
|
-
| | | +--------+-------+
|
|
1436
|
-
| returned true for| false:REJECT +-------->|onResponderReject
|
|
1437
|
-
| wantsResponderID | | | +----------------+
|
|
1438
|
-
| (now attempt | +------------------+-----+ |
|
|
1439
|
-
| handoff) | | onResponder | |
|
|
1440
|
-
+------------------->| TerminationRequest| |
|
|
1441
|
-
| +------------------+-----+ |
|
|
1442
|
-
| | | +----------------+
|
|
1443
|
-
| true:GRANT +-------->|onResponderGrant|
|
|
1444
|
-
| | +--------+-------+
|
|
1445
|
-
| +------------------------+ | |
|
|
1446
|
-
| | onResponderTerminate |<-----------+
|
|
1447
|
-
| +------------------+-----+ |
|
|
1448
|
-
| | | +----------------+
|
|
1449
|
-
| +-------->|onResponderStart|
|
|
1450
|
-
| | +----------------+
|
|
1451
|
-
Bubble to find first ID | |
|
|
1452
|
-
to return true:wantsResponderID| |
|
|
1453
|
-
| |
|
|
1454
|
-
+-------------+ | |
|
|
1455
|
-
| onTouchMove | | |
|
|
1456
|
-
+------+------+ none | |
|
|
1457
|
-
| return| |
|
|
1458
|
-
+-----------v-------------+true| +------------------------+ |
|
|
1459
|
-
|onMoveShouldSetResponder |----->|onResponderMove (cur) |<-----------+
|
|
1460
|
-
+-----------+-------------+ | +------------------------+ | |
|
|
1461
|
-
| | | +--------+-------+
|
|
1462
|
-
| returned true for| false:REJECT +-------->|onResponderRejec|
|
|
1463
|
-
| wantsResponderID | | | +----------------+
|
|
1464
|
-
| (now attempt | +------------------+-----+ |
|
|
1465
|
-
| handoff) | | onResponder | |
|
|
1466
|
-
+------------------->| TerminationRequest| |
|
|
1467
|
-
| +------------------+-----+ |
|
|
1468
|
-
| | | +----------------+
|
|
1469
|
-
| true:GRANT +-------->|onResponderGrant|
|
|
1470
|
-
| | +--------+-------+
|
|
1471
|
-
| +------------------------+ | |
|
|
1472
|
-
| | onResponderTerminate |<-----------+
|
|
1473
|
-
| +------------------+-----+ |
|
|
1474
|
-
| | | +----------------+
|
|
1475
|
-
| +-------->|onResponderMove |
|
|
1476
|
-
| | +----------------+
|
|
1477
|
-
| |
|
|
1478
|
-
| |
|
|
1479
|
-
Some active touch started| |
|
|
1480
|
-
inside current responder | +------------------------+ |
|
|
1481
|
-
+------------------------->| onResponderEnd | |
|
|
1482
|
-
| | +------------------------+ |
|
|
1483
|
-
+---+---------+ | |
|
|
1484
|
-
| onTouchEnd | | |
|
|
1485
|
-
+---+---------+ | |
|
|
1486
|
-
| | +------------------------+ |
|
|
1487
|
-
+------------------------->| onResponderEnd | |
|
|
1488
|
-
No active touches started| +-----------+------------+ |
|
|
1489
|
-
inside current responder | | |
|
|
1490
|
-
| v |
|
|
1491
|
-
| +------------------------+ |
|
|
1492
|
-
| | onResponderRelease | |
|
|
1493
|
-
| +------------------------+ |
|
|
1494
|
-
| |
|
|
1495
|
-
+ + */
|
|
1496
|
-
|
|
1497
|
-
/**
|
|
1498
|
-
* A note about event ordering in the `EventPluginHub`.
|
|
1499
|
-
*
|
|
1500
|
-
* Suppose plugins are injected in the following order:
|
|
1501
|
-
*
|
|
1502
|
-
* `[R, S, C]`
|
|
1503
|
-
*
|
|
1504
|
-
* To help illustrate the example, assume `S` is `SimpleEventPlugin` (for
|
|
1505
|
-
* `onClick` etc) and `R` is `ResponderEventPlugin`.
|
|
1506
|
-
*
|
|
1507
|
-
* "Deferred-Dispatched Events":
|
|
1508
|
-
*
|
|
1509
|
-
* - The current event plugin system will traverse the list of injected plugins,
|
|
1510
|
-
* in order, and extract events by collecting the plugin's return value of
|
|
1511
|
-
* `extractEvents()`.
|
|
1512
|
-
* - These events that are returned from `extractEvents` are "deferred
|
|
1513
|
-
* dispatched events".
|
|
1514
|
-
* - When returned from `extractEvents`, deferred-dispatched events contain an
|
|
1515
|
-
* "accumulation" of deferred dispatches.
|
|
1516
|
-
* - These deferred dispatches are accumulated/collected before they are
|
|
1517
|
-
* returned, but processed at a later time by the `EventPluginHub` (hence the
|
|
1518
|
-
* name deferred).
|
|
1519
|
-
*
|
|
1520
|
-
* In the process of returning their deferred-dispatched events, event plugins
|
|
1521
|
-
* themselves can dispatch events on-demand without returning them from
|
|
1522
|
-
* `extractEvents`. Plugins might want to do this, so that they can use event
|
|
1523
|
-
* dispatching as a tool that helps them decide which events should be extracted
|
|
1524
|
-
* in the first place.
|
|
1525
|
-
*
|
|
1526
|
-
* "On-Demand-Dispatched Events":
|
|
1527
|
-
*
|
|
1528
|
-
* - On-demand-dispatched events are not returned from `extractEvents`.
|
|
1529
|
-
* - On-demand-dispatched events are dispatched during the process of returning
|
|
1530
|
-
* the deferred-dispatched events.
|
|
1531
|
-
* - They should not have side effects.
|
|
1532
|
-
* - They should be avoided, and/or eventually be replaced with another
|
|
1533
|
-
* abstraction that allows event plugins to perform multiple "rounds" of event
|
|
1534
|
-
* extraction.
|
|
1535
|
-
*
|
|
1536
|
-
* Therefore, the sequence of event dispatches becomes:
|
|
1537
|
-
*
|
|
1538
|
-
* - `R`s on-demand events (if any) (dispatched by `R` on-demand)
|
|
1539
|
-
* - `S`s on-demand events (if any) (dispatched by `S` on-demand)
|
|
1540
|
-
* - `C`s on-demand events (if any) (dispatched by `C` on-demand)
|
|
1541
|
-
* - `R`s extracted events (if any) (dispatched by `EventPluginHub`)
|
|
1542
|
-
* - `S`s extracted events (if any) (dispatched by `EventPluginHub`)
|
|
1543
|
-
* - `C`s extracted events (if any) (dispatched by `EventPluginHub`)
|
|
1544
|
-
*
|
|
1545
|
-
* In the case of `ResponderEventPlugin`: If the `startShouldSetResponder`
|
|
1546
|
-
* on-demand dispatch returns `true` (and some other details are satisfied) the
|
|
1547
|
-
* `onResponderGrant` deferred dispatched event is returned from
|
|
1548
|
-
* `extractEvents`. The sequence of dispatch executions in this case
|
|
1549
|
-
* will appear as follows:
|
|
1550
|
-
*
|
|
1551
|
-
* - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand)
|
|
1552
|
-
* - `touchStartCapture` (`EventPluginHub` dispatches as usual)
|
|
1553
|
-
* - `touchStart` (`EventPluginHub` dispatches as usual)
|
|
1554
|
-
* - `responderGrant/Reject` (`EventPluginHub` dispatches as usual)
|
|
1555
|
-
*/
|
|
1556
|
-
|
|
1557
|
-
function setResponderAndExtractTransfer(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
|
|
1558
|
-
var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) ? eventTypes.moveShouldSetResponder : topLevelType === TOP_SELECTION_CHANGE ? eventTypes.selectionChangeShouldSetResponder : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder.
|
|
1418
|
+
function setResponderAndExtractTransfer(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
|
|
1419
|
+
var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) ? eventTypes.moveShouldSetResponder : topLevelType === TOP_SELECTION_CHANGE ? eventTypes.selectionChangeShouldSetResponder : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder.
|
|
1559
1420
|
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1421
|
+
var bubbleShouldSetFrom = !responderInst ? targetInst : getLowestCommonAncestor(responderInst, targetInst); // When capturing/bubbling the "shouldSet" event, we want to skip the target
|
|
1422
|
+
// (deepest ID) if it happens to be the current responder. The reasoning:
|
|
1423
|
+
// It's strange to get an `onMoveShouldSetResponder` when you're *already*
|
|
1424
|
+
// the responder.
|
|
1564
1425
|
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1426
|
+
var skipOverBubbleShouldSetFrom = bubbleShouldSetFrom === responderInst;
|
|
1427
|
+
var shouldSetEvent = ResponderSyntheticEvent.getPooled(shouldSetEventType, bubbleShouldSetFrom, nativeEvent, nativeEventTarget);
|
|
1428
|
+
shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
|
1568
1429
|
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1430
|
+
if (skipOverBubbleShouldSetFrom) {
|
|
1431
|
+
accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent);
|
|
1432
|
+
} else {
|
|
1433
|
+
accumulateTwoPhaseDispatches(shouldSetEvent);
|
|
1434
|
+
}
|
|
1574
1435
|
|
|
1575
|
-
|
|
1436
|
+
var wantsResponderInst = executeDispatchesInOrderStopAtTrue(shouldSetEvent);
|
|
1576
1437
|
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1438
|
+
if (!shouldSetEvent.isPersistent()) {
|
|
1439
|
+
shouldSetEvent.constructor.release(shouldSetEvent);
|
|
1440
|
+
}
|
|
1580
1441
|
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1442
|
+
if (!wantsResponderInst || wantsResponderInst === responderInst) {
|
|
1443
|
+
return null;
|
|
1444
|
+
}
|
|
1584
1445
|
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1446
|
+
var extracted;
|
|
1447
|
+
var grantEvent = ResponderSyntheticEvent.getPooled(eventTypes.responderGrant, wantsResponderInst, nativeEvent, nativeEventTarget);
|
|
1448
|
+
grantEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
|
1449
|
+
accumulateDirectDispatches(grantEvent);
|
|
1450
|
+
var blockHostResponder = executeDirectDispatch(grantEvent) === true;
|
|
1590
1451
|
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1452
|
+
if (responderInst) {
|
|
1453
|
+
var terminationRequestEvent = ResponderSyntheticEvent.getPooled(eventTypes.responderTerminationRequest, responderInst, nativeEvent, nativeEventTarget);
|
|
1454
|
+
terminationRequestEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
|
1455
|
+
accumulateDirectDispatches(terminationRequestEvent);
|
|
1456
|
+
var shouldSwitch = !hasDispatches(terminationRequestEvent) || executeDirectDispatch(terminationRequestEvent);
|
|
1596
1457
|
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1458
|
+
if (!terminationRequestEvent.isPersistent()) {
|
|
1459
|
+
terminationRequestEvent.constructor.release(terminationRequestEvent);
|
|
1460
|
+
}
|
|
1600
1461
|
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1462
|
+
if (shouldSwitch) {
|
|
1463
|
+
var terminateEvent = ResponderSyntheticEvent.getPooled(eventTypes.responderTerminate, responderInst, nativeEvent, nativeEventTarget);
|
|
1464
|
+
terminateEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
|
1465
|
+
accumulateDirectDispatches(terminateEvent);
|
|
1466
|
+
extracted = accumulate(extracted, [grantEvent, terminateEvent]);
|
|
1467
|
+
changeResponder(wantsResponderInst, blockHostResponder);
|
|
1468
|
+
} else {
|
|
1469
|
+
var rejectEvent = ResponderSyntheticEvent.getPooled(eventTypes.responderReject, wantsResponderInst, nativeEvent, nativeEventTarget);
|
|
1470
|
+
rejectEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
|
1471
|
+
accumulateDirectDispatches(rejectEvent);
|
|
1472
|
+
extracted = accumulate(extracted, rejectEvent);
|
|
1473
|
+
}
|
|
1607
1474
|
} else {
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
accumulateDirectDispatches(rejectEvent);
|
|
1611
|
-
extracted = accumulate(extracted, rejectEvent);
|
|
1475
|
+
extracted = accumulate(extracted, grantEvent);
|
|
1476
|
+
changeResponder(wantsResponderInst, blockHostResponder);
|
|
1612
1477
|
}
|
|
1613
|
-
} else {
|
|
1614
|
-
extracted = accumulate(extracted, grantEvent);
|
|
1615
|
-
changeResponder(wantsResponderInst, blockHostResponder);
|
|
1616
|
-
}
|
|
1617
1478
|
|
|
1618
|
-
|
|
1619
|
-
}
|
|
1620
|
-
/**
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1479
|
+
return extracted;
|
|
1480
|
+
}
|
|
1481
|
+
/**
|
|
1482
|
+
* A transfer is a negotiation between a currently set responder and the next
|
|
1483
|
+
* element to claim responder status. Any start event could trigger a transfer
|
|
1484
|
+
* of responderInst. Any move event could trigger a transfer.
|
|
1485
|
+
*
|
|
1486
|
+
* @param {string} topLevelType Record from `BrowserEventConstants`.
|
|
1487
|
+
* @return {boolean} True if a transfer of responder could possibly occur.
|
|
1488
|
+
*/
|
|
1628
1489
|
|
|
1629
1490
|
|
|
1630
|
-
function canTriggerTransfer(topLevelType, topLevelInst, nativeEvent) {
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
}
|
|
1636
|
-
/**
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1491
|
+
function canTriggerTransfer(topLevelType, topLevelInst, nativeEvent) {
|
|
1492
|
+
return topLevelInst && ( // responderIgnoreScroll: We are trying to migrate away from specifically
|
|
1493
|
+
// tracking native scroll events here and responderIgnoreScroll indicates we
|
|
1494
|
+
// will send topTouchCancel to handle canceling touch events instead
|
|
1495
|
+
topLevelType === TOP_SCROLL && !nativeEvent.responderIgnoreScroll || trackedTouchCount > 0 && topLevelType === TOP_SELECTION_CHANGE || isStartish(topLevelType) || isMoveish(topLevelType));
|
|
1496
|
+
}
|
|
1497
|
+
/**
|
|
1498
|
+
* Returns whether or not this touch end event makes it such that there are no
|
|
1499
|
+
* longer any touches that started inside of the current `responderInst`.
|
|
1500
|
+
*
|
|
1501
|
+
* @param {NativeEvent} nativeEvent Native touch end event.
|
|
1502
|
+
* @return {boolean} Whether or not this touch end event ends the responder.
|
|
1503
|
+
*/
|
|
1643
1504
|
|
|
1644
1505
|
|
|
1645
|
-
function noResponderTouches(nativeEvent) {
|
|
1646
|
-
|
|
1506
|
+
function noResponderTouches(nativeEvent) {
|
|
1507
|
+
var touches = nativeEvent.touches;
|
|
1647
1508
|
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1509
|
+
if (!touches || touches.length === 0) {
|
|
1510
|
+
return true;
|
|
1511
|
+
}
|
|
1651
1512
|
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1513
|
+
for (var i = 0; i < touches.length; i++) {
|
|
1514
|
+
var activeTouch = touches[i];
|
|
1515
|
+
var target = activeTouch.target;
|
|
1655
1516
|
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1517
|
+
if (target !== null && target !== undefined && target !== 0) {
|
|
1518
|
+
// Is the original touch location inside of the current responder?
|
|
1519
|
+
var targetInst = getInstanceFromNode(target);
|
|
1659
1520
|
|
|
1660
|
-
|
|
1661
|
-
|
|
1521
|
+
if (isAncestor(responderInst, targetInst)) {
|
|
1522
|
+
return false;
|
|
1523
|
+
}
|
|
1662
1524
|
}
|
|
1663
1525
|
}
|
|
1526
|
+
|
|
1527
|
+
return true;
|
|
1664
1528
|
}
|
|
1665
1529
|
|
|
1666
|
-
|
|
1667
|
-
|
|
1530
|
+
var ResponderEventPlugin = {
|
|
1531
|
+
/* For unit testing only */
|
|
1532
|
+
_getResponder: function () {
|
|
1533
|
+
return responderInst;
|
|
1534
|
+
},
|
|
1535
|
+
eventTypes: eventTypes,
|
|
1668
1536
|
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1537
|
+
/**
|
|
1538
|
+
* We must be resilient to `targetInst` being `null` on `touchMove` or
|
|
1539
|
+
* `touchEnd`. On certain platforms, this means that a native scroll has
|
|
1540
|
+
* assumed control and the original touch targets are destroyed.
|
|
1541
|
+
*/
|
|
1542
|
+
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
|
|
1543
|
+
if (isStartish(topLevelType)) {
|
|
1544
|
+
trackedTouchCount += 1;
|
|
1545
|
+
} else if (isEndish(topLevelType)) {
|
|
1546
|
+
if (trackedTouchCount >= 0) {
|
|
1547
|
+
trackedTouchCount -= 1;
|
|
1548
|
+
} else {
|
|
1549
|
+
{
|
|
1550
|
+
warn('Ended a touch event which was not counted in `trackedTouchCount`.');
|
|
1551
|
+
}
|
|
1675
1552
|
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
* `touchEnd`. On certain platforms, this means that a native scroll has
|
|
1679
|
-
* assumed control and the original touch targets are destroyed.
|
|
1680
|
-
*/
|
|
1681
|
-
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
|
|
1682
|
-
if (isStartish(topLevelType)) {
|
|
1683
|
-
trackedTouchCount += 1;
|
|
1684
|
-
} else if (isEndish(topLevelType)) {
|
|
1685
|
-
if (trackedTouchCount >= 0) {
|
|
1686
|
-
trackedTouchCount -= 1;
|
|
1687
|
-
} else {
|
|
1688
|
-
console.warn('Ended a touch event which was not counted in `trackedTouchCount`.');
|
|
1689
|
-
return null;
|
|
1553
|
+
return null;
|
|
1554
|
+
}
|
|
1690
1555
|
}
|
|
1691
|
-
}
|
|
1692
1556
|
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1557
|
+
ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent);
|
|
1558
|
+
var extracted = canTriggerTransfer(topLevelType, targetInst, nativeEvent) ? setResponderAndExtractTransfer(topLevelType, targetInst, nativeEvent, nativeEventTarget) : null; // Responder may or may not have transferred on a new touch start/move.
|
|
1559
|
+
// Regardless, whoever is the responder after any potential transfer, we
|
|
1560
|
+
// direct all touch start/move/ends to them in the form of
|
|
1561
|
+
// `onResponderMove/Start/End`. These will be called for *every* additional
|
|
1562
|
+
// finger that move/start/end, dispatched directly to whoever is the
|
|
1563
|
+
// current responder at that moment, until the responder is "released".
|
|
1564
|
+
//
|
|
1565
|
+
// These multiple individual change touch events are are always bookended
|
|
1566
|
+
// by `onResponderGrant`, and one of
|
|
1567
|
+
// (`onResponderRelease/onResponderTerminate`).
|
|
1568
|
+
|
|
1569
|
+
var isResponderTouchStart = responderInst && isStartish(topLevelType);
|
|
1570
|
+
var isResponderTouchMove = responderInst && isMoveish(topLevelType);
|
|
1571
|
+
var isResponderTouchEnd = responderInst && isEndish(topLevelType);
|
|
1572
|
+
var incrementalTouch = isResponderTouchStart ? eventTypes.responderStart : isResponderTouchMove ? eventTypes.responderMove : isResponderTouchEnd ? eventTypes.responderEnd : null;
|
|
1573
|
+
|
|
1574
|
+
if (incrementalTouch) {
|
|
1575
|
+
var gesture = ResponderSyntheticEvent.getPooled(incrementalTouch, responderInst, nativeEvent, nativeEventTarget);
|
|
1576
|
+
gesture.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
|
1577
|
+
accumulateDirectDispatches(gesture);
|
|
1578
|
+
extracted = accumulate(extracted, gesture);
|
|
1579
|
+
}
|
|
1716
1580
|
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1581
|
+
var isResponderTerminate = responderInst && topLevelType === TOP_TOUCH_CANCEL;
|
|
1582
|
+
var isResponderRelease = responderInst && !isResponderTerminate && isEndish(topLevelType) && noResponderTouches(nativeEvent);
|
|
1583
|
+
var finalTouch = isResponderTerminate ? eventTypes.responderTerminate : isResponderRelease ? eventTypes.responderRelease : null;
|
|
1720
1584
|
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1585
|
+
if (finalTouch) {
|
|
1586
|
+
var finalEvent = ResponderSyntheticEvent.getPooled(finalTouch, responderInst, nativeEvent, nativeEventTarget);
|
|
1587
|
+
finalEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
|
1588
|
+
accumulateDirectDispatches(finalEvent);
|
|
1589
|
+
extracted = accumulate(extracted, finalEvent);
|
|
1590
|
+
changeResponder(null);
|
|
1591
|
+
}
|
|
1728
1592
|
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1593
|
+
return extracted;
|
|
1594
|
+
},
|
|
1595
|
+
GlobalResponderHandler: null,
|
|
1596
|
+
injection: {
|
|
1597
|
+
/**
|
|
1598
|
+
* @param {{onChange: (ReactID, ReactID) => void} GlobalResponderHandler
|
|
1599
|
+
* Object that handles any change in responder. Use this to inject
|
|
1600
|
+
* integration with an existing touch handling system etc.
|
|
1601
|
+
*/
|
|
1602
|
+
injectGlobalResponderHandler: function (GlobalResponderHandler) {
|
|
1603
|
+
ResponderEventPlugin.GlobalResponderHandler = GlobalResponderHandler;
|
|
1604
|
+
}
|
|
1740
1605
|
}
|
|
1741
|
-
}
|
|
1742
|
-
};
|
|
1743
|
-
|
|
1744
|
-
// Keep in sync with ReactDOM.js, ReactTestUtils.js, and ReactTestUtilsAct.js:
|
|
1606
|
+
};
|
|
1745
1607
|
|
|
1746
|
-
|
|
1747
|
-
var getInstanceFromNode = _ReactDOM$__SECRET_IN[0];
|
|
1748
|
-
var getNodeFromInstance = _ReactDOM$__SECRET_IN[1];
|
|
1749
|
-
var getFiberCurrentPropsFromNode = _ReactDOM$__SECRET_IN[2];
|
|
1750
|
-
var injectEventPluginsByName = _ReactDOM$__SECRET_IN[3];
|
|
1751
|
-
setComponentTree(getFiberCurrentPropsFromNode, getInstanceFromNode, getNodeFromInstance);
|
|
1608
|
+
// Keep in sync with ReactDOM.js, ReactTestUtils.js, and ReactTestUtilsAct.js:
|
|
1752
1609
|
|
|
1610
|
+
var _ReactDOM$__SECRET_IN = ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Events,
|
|
1611
|
+
getInstanceFromNode$1 = _ReactDOM$__SECRET_IN[0],
|
|
1612
|
+
getNodeFromInstance$1 = _ReactDOM$__SECRET_IN[1],
|
|
1613
|
+
getFiberCurrentPropsFromNode$1 = _ReactDOM$__SECRET_IN[2],
|
|
1614
|
+
injectEventPluginsByName = _ReactDOM$__SECRET_IN[3];
|
|
1615
|
+
setComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1);
|
|
1753
1616
|
|
|
1754
|
-
var ReactDOMUnstableNativeDependencies = Object.freeze({
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1617
|
+
var ReactDOMUnstableNativeDependencies = /*#__PURE__*/Object.freeze({
|
|
1618
|
+
__proto__: null,
|
|
1619
|
+
ResponderEventPlugin: ResponderEventPlugin,
|
|
1620
|
+
ResponderTouchHistoryStore: ResponderTouchHistoryStore,
|
|
1621
|
+
injectEventPluginsByName: injectEventPluginsByName
|
|
1622
|
+
});
|
|
1759
1623
|
|
|
1760
|
-
var unstableNativeDependencies = ReactDOMUnstableNativeDependencies;
|
|
1624
|
+
var unstableNativeDependencies = ReactDOMUnstableNativeDependencies;
|
|
1761
1625
|
|
|
1762
|
-
return unstableNativeDependencies;
|
|
1626
|
+
return unstableNativeDependencies;
|
|
1763
1627
|
|
|
1764
1628
|
})));
|