Dashboard sipadu mbip
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

react-dom-unstable-native-dependencies.development.js 60KB

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