diff options
Diffstat (limited to 'node_modules/react-dom/cjs/react-dom-unstable-native-dependencies.development.js')
-rw-r--r-- | node_modules/react-dom/cjs/react-dom-unstable-native-dependencies.development.js | 2160 |
1 files changed, 2160 insertions, 0 deletions
diff --git a/node_modules/react-dom/cjs/react-dom-unstable-native-dependencies.development.js b/node_modules/react-dom/cjs/react-dom-unstable-native-dependencies.development.js new file mode 100644 index 000000000..b625e1904 --- /dev/null +++ b/node_modules/react-dom/cjs/react-dom-unstable-native-dependencies.development.js @@ -0,0 +1,2160 @@ +/** @license React v16.0.0 + * react-dom-unstable-native-dependencies.development.js + * + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +'use strict'; + + +if (process.env.NODE_ENV !== "production") { +(function() { + +'use strict'; + +var invariant = require('fbjs/lib/invariant'); +var require$$0 = require('fbjs/lib/warning'); +var objectAssign$1 = require('object-assign'); +var emptyFunction = require('fbjs/lib/emptyFunction'); +var reactDom = require('react-dom'); + +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @providesModule reactProdInvariant + * + */ + +var ReactErrorUtils = { + // Used by Fiber to simulate a try-catch. + _caughtError: null, + _hasCaughtError: false, + + // Used by event system to capture/rethrow the first error. + _rethrowError: null, + _hasRethrowError: false, + + injection: { + injectErrorUtils: function (injectedErrorUtils) { + !(typeof injectedErrorUtils.invokeGuardedCallback === 'function') ? invariant(false, 'Injected invokeGuardedCallback() must be a function.') : void 0; + invokeGuardedCallback = injectedErrorUtils.invokeGuardedCallback; + } + }, + + /** + * Call a function while guarding against errors that happens within it. + * Returns an error if it throws, otherwise null. + * + * In production, this is implemented using a try-catch. The reason we don't + * use a try-catch directly is so that we can swap out a different + * implementation in DEV mode. + * + * @param {String} name of the guard to use for logging or debugging + * @param {Function} func The function to invoke + * @param {*} context The context to use when calling the function + * @param {...*} args Arguments for function + */ + invokeGuardedCallback: function (name, func, context, a, b, c, d, e, f) { + invokeGuardedCallback.apply(ReactErrorUtils, arguments); + }, + + /** + * Same as invokeGuardedCallback, but instead of returning an error, it stores + * it in a global so it can be rethrown by `rethrowCaughtError` later. + * TODO: See if _caughtError and _rethrowError can be unified. + * + * @param {String} name of the guard to use for logging or debugging + * @param {Function} func The function to invoke + * @param {*} context The context to use when calling the function + * @param {...*} args Arguments for function + */ + invokeGuardedCallbackAndCatchFirstError: function (name, func, context, a, b, c, d, e, f) { + ReactErrorUtils.invokeGuardedCallback.apply(this, arguments); + if (ReactErrorUtils.hasCaughtError()) { + var error = ReactErrorUtils.clearCaughtError(); + if (!ReactErrorUtils._hasRethrowError) { + ReactErrorUtils._hasRethrowError = true; + ReactErrorUtils._rethrowError = error; + } + } + }, + + /** + * During execution of guarded functions we will capture the first error which + * we will rethrow to be handled by the top level error handler. + */ + rethrowCaughtError: function () { + return rethrowCaughtError.apply(ReactErrorUtils, arguments); + }, + + hasCaughtError: function () { + return ReactErrorUtils._hasCaughtError; + }, + + clearCaughtError: function () { + if (ReactErrorUtils._hasCaughtError) { + var error = ReactErrorUtils._caughtError; + ReactErrorUtils._caughtError = null; + ReactErrorUtils._hasCaughtError = false; + return error; + } else { + invariant(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.'); + } + } +}; + +var invokeGuardedCallback = function (name, func, context, a, b, c, d, e, f) { + ReactErrorUtils._hasCaughtError = false; + ReactErrorUtils._caughtError = null; + var funcArgs = Array.prototype.slice.call(arguments, 3); + try { + func.apply(context, funcArgs); + } catch (error) { + ReactErrorUtils._caughtError = error; + ReactErrorUtils._hasCaughtError = true; + } +}; + +{ + // In DEV mode, we swap out invokeGuardedCallback for a special version + // that plays more nicely with the browser's DevTools. The idea is to preserve + // "Pause on exceptions" behavior. Because React wraps all user-provided + // functions in invokeGuardedCallback, and the production version of + // invokeGuardedCallback uses a try-catch, all user exceptions are treated + // like caught exceptions, and the DevTools won't pause unless the developer + // takes the extra step of enabling pause on caught exceptions. This is + // untintuitive, though, because even though React has caught the error, from + // the developer's perspective, the error is uncaught. + // + // To preserve the expected "Pause on exceptions" behavior, we don't use a + // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake + // DOM node, and call the user-provided callback from inside an event handler + // for that fake event. If the callback throws, the error is "captured" using + // a global event handler. But because the error happens in a different + // event loop context, it does not interrupt the normal program flow. + // Effectively, this gives us try-catch behavior without actually using + // try-catch. Neat! + + // Check that the browser supports the APIs we need to implement our special + // DEV version of invokeGuardedCallback + if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') { + var fakeNode = document.createElement('react'); + + var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) { + // Keeps track of whether the user-provided callback threw an error. We + // set this to true at the beginning, then set it to false right after + // calling the function. If the function errors, `didError` will never be + // set to false. This strategy works even if the browser is flaky and + // fails to call our global error handler, because it doesn't rely on + // the error event at all. + var didError = true; + + // Create an event handler for our fake event. We will synchronously + // dispatch our fake event using `dispatchEvent`. Inside the handler, we + // call the user-provided callback. + var funcArgs = Array.prototype.slice.call(arguments, 3); + function callCallback() { + // We immediately remove the callback from event listeners so that + // nested `invokeGuardedCallback` calls do not clash. Otherwise, a + // nested call would trigger the fake event handlers of any call higher + // in the stack. + fakeNode.removeEventListener(evtType, callCallback, false); + func.apply(context, funcArgs); + didError = false; + } + + // Create a global error event handler. We use this to capture the value + // that was thrown. It's possible that this error handler will fire more + // than once; for example, if non-React code also calls `dispatchEvent` + // and a handler for that event throws. We should be resilient to most of + // those cases. Even if our error event handler fires more than once, the + // last error event is always used. If the callback actually does error, + // we know that the last error event is the correct one, because it's not + // possible for anything else to have happened in between our callback + // erroring and the code that follows the `dispatchEvent` call below. If + // the callback doesn't error, but the error event was fired, we know to + // ignore it because `didError` will be false, as described above. + var error = void 0; + // Use this to track whether the error event is ever called. + var didSetError = false; + var isCrossOriginError = false; + + function onError(event) { + error = event.error; + didSetError = true; + if (error === null && event.colno === 0 && event.lineno === 0) { + isCrossOriginError = true; + } + } + + // Create a fake event type. + var evtType = 'react-' + (name ? name : 'invokeguardedcallback'); + + // Attach our event handlers + window.addEventListener('error', onError); + fakeNode.addEventListener(evtType, callCallback, false); + + // Synchronously dispatch our fake event. If the user-provided function + // errors, it will trigger our global error handler. + var evt = document.createEvent('Event'); + evt.initEvent(evtType, false, false); + fakeNode.dispatchEvent(evt); + + if (didError) { + if (!didSetError) { + // The callback errored, but the error event never fired. + error = new Error('An error was thrown inside one of your components, but React ' + "doesn't know what it was. This is likely due to browser " + 'flakiness. React does its best to preserve the "Pause on ' + 'exceptions" behavior of the DevTools, which requires some ' + "DEV-mode only tricks. It's possible that these don't work in " + 'your browser. Try triggering the error in production mode, ' + 'or switching to a modern browser. If you suspect that this is ' + 'actually an issue with React, please file an issue.'); + } else if (isCrossOriginError) { + error = new Error("A cross-origin error was thrown. React doesn't have access to " + 'the actual error object in development. ' + 'See https://fb.me/react-crossorigin-error for more information.'); + } + ReactErrorUtils._hasCaughtError = true; + ReactErrorUtils._caughtError = error; + } else { + ReactErrorUtils._hasCaughtError = false; + ReactErrorUtils._caughtError = null; + } + + // Remove our event listeners + window.removeEventListener('error', onError); + }; + + invokeGuardedCallback = invokeGuardedCallbackDev; + } +} + +var rethrowCaughtError = function () { + if (ReactErrorUtils._hasRethrowError) { + var error = ReactErrorUtils._rethrowError; + ReactErrorUtils._rethrowError = null; + ReactErrorUtils._hasRethrowError = false; + throw error; + } +}; + +var ReactErrorUtils_1 = ReactErrorUtils; + +{ + var warning = require$$0; +} + +/** + * Injected dependencies: + */ + +/** + * - `ComponentTree`: [required] Module that can convert between React instances + * and actual node references. + */ +var ComponentTree; +var injection = { + injectComponentTree: function (Injected) { + ComponentTree = Injected; + { + warning(Injected && Injected.getNodeFromInstance && Injected.getInstanceFromNode, 'EventPluginUtils.injection.injectComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.'); + } + } +}; + +function isEndish(topLevelType) { + return topLevelType === 'topMouseUp' || topLevelType === 'topTouchEnd' || topLevelType === 'topTouchCancel'; +} + +function isMoveish(topLevelType) { + return topLevelType === 'topMouseMove' || topLevelType === 'topTouchMove'; +} +function isStartish(topLevelType) { + return topLevelType === 'topMouseDown' || topLevelType === 'topTouchStart'; +} + +var validateEventDispatches; +{ + validateEventDispatches = function (event) { + var dispatchListeners = event._dispatchListeners; + var dispatchInstances = event._dispatchInstances; + + var listenersIsArr = Array.isArray(dispatchListeners); + var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0; + + var instancesIsArr = Array.isArray(dispatchInstances); + var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0; + + warning(instancesIsArr === listenersIsArr && instancesLen === listenersLen, 'EventPluginUtils: Invalid `event`.'); + }; +} + +/** + * Dispatch the event to the listener. + * @param {SyntheticEvent} event SyntheticEvent to handle + * @param {boolean} simulated If the event is simulated (changes exn behavior) + * @param {function} listener Application-level callback + * @param {*} inst Internal component instance + */ +function executeDispatch(event, simulated, listener, inst) { + var type = event.type || 'unknown-event'; + event.currentTarget = EventPluginUtils.getNodeFromInstance(inst); + ReactErrorUtils_1.invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event); + event.currentTarget = null; +} + +/** + * Standard/simple iteration through an event's collected dispatches. + */ +function executeDispatchesInOrder(event, simulated) { + var dispatchListeners = event._dispatchListeners; + var dispatchInstances = event._dispatchInstances; + { + validateEventDispatches(event); + } + if (Array.isArray(dispatchListeners)) { + for (var i = 0; i < dispatchListeners.length; i++) { + if (event.isPropagationStopped()) { + break; + } + // Listeners and Instances are two parallel arrays that are always in sync. + executeDispatch(event, simulated, dispatchListeners[i], dispatchInstances[i]); + } + } else if (dispatchListeners) { + executeDispatch(event, simulated, dispatchListeners, dispatchInstances); + } + event._dispatchListeners = null; + event._dispatchInstances = null; +} + +/** + * Standard/simple iteration through an event's collected dispatches, but stops + * at the first dispatch execution returning true, and returns that id. + * + * @return {?string} id of the first dispatch execution who's listener returns + * true, or null if no listener returned true. + */ +function executeDispatchesInOrderStopAtTrueImpl(event) { + var dispatchListeners = event._dispatchListeners; + var dispatchInstances = event._dispatchInstances; + { + validateEventDispatches(event); + } + if (Array.isArray(dispatchListeners)) { + for (var i = 0; i < dispatchListeners.length; i++) { + if (event.isPropagationStopped()) { + break; + } + // Listeners and Instances are two parallel arrays that are always in sync. + if (dispatchListeners[i](event, dispatchInstances[i])) { + return dispatchInstances[i]; + } + } + } else if (dispatchListeners) { + if (dispatchListeners(event, dispatchInstances)) { + return dispatchInstances; + } + } + return null; +} + +/** + * @see executeDispatchesInOrderStopAtTrueImpl + */ +function executeDispatchesInOrderStopAtTrue(event) { + var ret = executeDispatchesInOrderStopAtTrueImpl(event); + event._dispatchInstances = null; + event._dispatchListeners = null; + return ret; +} + +/** + * Execution of a "direct" dispatch - there must be at most one dispatch + * accumulated on the event or it is considered an error. It doesn't really make + * sense for an event with multiple dispatches (bubbled) to keep track of the + * return values at each dispatch execution, but it does tend to make sense when + * dealing with "direct" dispatches. + * + * @return {*} The return value of executing the single dispatch. + */ +function executeDirectDispatch(event) { + { + validateEventDispatches(event); + } + var dispatchListener = event._dispatchListeners; + var dispatchInstance = event._dispatchInstances; + !!Array.isArray(dispatchListener) ? invariant(false, 'executeDirectDispatch(...): Invalid `event`.') : void 0; + event.currentTarget = dispatchListener ? EventPluginUtils.getNodeFromInstance(dispatchInstance) : null; + var res = dispatchListener ? dispatchListener(event) : null; + event.currentTarget = null; + event._dispatchListeners = null; + event._dispatchInstances = null; + return res; +} + +/** + * @param {SyntheticEvent} event + * @return {boolean} True iff number of dispatches accumulated is greater than 0. + */ +function hasDispatches(event) { + return !!event._dispatchListeners; +} + +/** + * General utilities that are useful in creating custom Event Plugins. + */ +var EventPluginUtils = { + isEndish: isEndish, + isMoveish: isMoveish, + isStartish: isStartish, + + executeDirectDispatch: executeDirectDispatch, + executeDispatchesInOrder: executeDispatchesInOrder, + executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue, + hasDispatches: hasDispatches, + + getFiberCurrentPropsFromNode: function (node) { + return ComponentTree.getFiberCurrentPropsFromNode(node); + }, + getInstanceFromNode: function (node) { + return ComponentTree.getInstanceFromNode(node); + }, + getNodeFromInstance: function (node) { + return ComponentTree.getNodeFromInstance(node); + }, + + injection: injection +}; + +var EventPluginUtils_1 = EventPluginUtils; + +/** + * Injectable ordering of event plugins. + */ +var eventPluginOrder = null; + +/** + * Injectable mapping from names to event plugin modules. + */ +var namesToPlugins = {}; + +/** + * Recomputes the plugin list using the injected plugins and plugin ordering. + * + * @private + */ +function recomputePluginOrdering() { + if (!eventPluginOrder) { + // Wait until an `eventPluginOrder` is injected. + return; + } + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName]; + var pluginIndex = eventPluginOrder.indexOf(pluginName); + !(pluginIndex > -1) ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : void 0; + if (EventPluginRegistry.plugins[pluginIndex]) { + continue; + } + !pluginModule.extractEvents ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : void 0; + EventPluginRegistry.plugins[pluginIndex] = pluginModule; + var publishedEvents = pluginModule.eventTypes; + for (var eventName in publishedEvents) { + !publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : void 0; + } + } +} + +/** + * Publishes an event so that it can be dispatched by the supplied plugin. + * + * @param {object} dispatchConfig Dispatch configuration for the event. + * @param {object} PluginModule Plugin publishing the event. + * @return {boolean} True if the event was successfully published. + * @private + */ +function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { + !!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName) ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : void 0; + EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig; + + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; + if (phasedRegistrationNames) { + for (var phaseName in phasedRegistrationNames) { + if (phasedRegistrationNames.hasOwnProperty(phaseName)) { + var phasedRegistrationName = phasedRegistrationNames[phaseName]; + publishRegistrationName(phasedRegistrationName, pluginModule, eventName); + } + } + return true; + } else if (dispatchConfig.registrationName) { + publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName); + return true; + } + return false; +} + +/** + * Publishes a registration name that is used to identify dispatched events. + * + * @param {string} registrationName Registration name to add. + * @param {object} PluginModule Plugin publishing the event. + * @private + */ +function publishRegistrationName(registrationName, pluginModule, eventName) { + !!EventPluginRegistry.registrationNameModules[registrationName] ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : void 0; + EventPluginRegistry.registrationNameModules[registrationName] = pluginModule; + EventPluginRegistry.registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies; + + { + var lowerCasedName = registrationName.toLowerCase(); + EventPluginRegistry.possibleRegistrationNames[lowerCasedName] = registrationName; + + if (registrationName === 'onDoubleClick') { + EventPluginRegistry.possibleRegistrationNames.ondblclick = registrationName; + } + } +} + +/** + * Registers plugins so that they can extract and dispatch events. + * + * @see {EventPluginHub} + */ +var EventPluginRegistry = { + /** + * Ordered list of injected plugins. + */ + plugins: [], + + /** + * Mapping from event name to dispatch config + */ + eventNameDispatchConfigs: {}, + + /** + * Mapping from registration name to plugin module + */ + registrationNameModules: {}, + + /** + * Mapping from registration name to event name + */ + registrationNameDependencies: {}, + + /** + * Mapping from lowercase registration names to the properly cased version, + * used to warn in the case of missing event handlers. Available + * only in true. + * @type {Object} + */ + possibleRegistrationNames: {}, + // Trust the developer to only use possibleRegistrationNames in true + + /** + * Injects an ordering of plugins (by plugin name). This allows the ordering + * to be decoupled from injection of the actual plugins so that ordering is + * always deterministic regardless of packaging, on-the-fly injection, etc. + * + * @param {array} InjectedEventPluginOrder + * @internal + * @see {EventPluginHub.injection.injectEventPluginOrder} + */ + injectEventPluginOrder: function (injectedEventPluginOrder) { + !!eventPluginOrder ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.') : void 0; + // Clone the ordering so it cannot be dynamically mutated. + eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); + recomputePluginOrdering(); + }, + + /** + * Injects plugins to be used by `EventPluginHub`. The plugin names must be + * in the ordering injected by `injectEventPluginOrder`. + * + * Plugins can be injected as part of page initialization or on-the-fly. + * + * @param {object} injectedNamesToPlugins Map from names to plugin modules. + * @internal + * @see {EventPluginHub.injection.injectEventPluginsByName} + */ + injectEventPluginsByName: function (injectedNamesToPlugins) { + var isOrderingDirty = false; + for (var pluginName in injectedNamesToPlugins) { + if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { + continue; + } + var pluginModule = injectedNamesToPlugins[pluginName]; + if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) { + !!namesToPlugins[pluginName] ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : void 0; + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = true; + } + } + if (isOrderingDirty) { + recomputePluginOrdering(); + } + } +}; + +var EventPluginRegistry_1 = EventPluginRegistry; + +/** + * Accumulates items that must not be null or undefined into the first one. This + * is used to conserve memory by avoiding array allocations, and thus sacrifices + * API cleanness. Since `current` can be null before being passed in and not + * null after this function, make sure to assign it back to `current`: + * + * `a = accumulateInto(a, b);` + * + * This API should be sparingly used. Try `accumulate` for something cleaner. + * + * @return {*|array<*>} An accumulation of items. + */ + +function accumulateInto(current, next) { + !(next != null) ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : void 0; + + if (current == null) { + return next; + } + + // Both are not empty. Warning: Never call x.concat(y) when you are not + // certain that x is an Array (x could be a string with concat method). + if (Array.isArray(current)) { + if (Array.isArray(next)) { + current.push.apply(current, next); + return current; + } + current.push(next); + return current; + } + + if (Array.isArray(next)) { + // A bit too dangerous to mutate `next`. + return [current].concat(next); + } + + return [current, next]; +} + +var accumulateInto_1 = accumulateInto; + +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @providesModule forEachAccumulated + * + */ + +/** + * @param {array} arr an "accumulation" of items which is either an Array or + * a single item. Useful when paired with the `accumulate` module. This is a + * simple utility that allows us to reason about a collection of items, but + * handling the case when there is exactly one item (and we do not need to + * allocate an array). + * @param {function} cb Callback invoked with each element or a collection. + * @param {?} [scope] Scope used as `this` in a callback. + */ + +function forEachAccumulated(arr, cb, scope) { + if (Array.isArray(arr)) { + arr.forEach(cb, scope); + } else if (arr) { + cb.call(scope, arr); + } +} + +var forEachAccumulated_1 = forEachAccumulated; + +/** + * Internal queue of events that have accumulated their dispatches and are + * waiting to have their dispatches executed. + */ +var eventQueue = null; + +/** + * Dispatches an event and releases it back into the pool, unless persistent. + * + * @param {?object} event Synthetic event to be dispatched. + * @param {boolean} simulated If the event is simulated (changes exn behavior) + * @private + */ +var executeDispatchesAndRelease = function (event, simulated) { + if (event) { + EventPluginUtils_1.executeDispatchesInOrder(event, simulated); + + if (!event.isPersistent()) { + event.constructor.release(event); + } + } +}; +var executeDispatchesAndReleaseSimulated = function (e) { + return executeDispatchesAndRelease(e, true); +}; +var executeDispatchesAndReleaseTopLevel = function (e) { + return executeDispatchesAndRelease(e, false); +}; + +function isInteractive(tag) { + return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea'; +} + +function shouldPreventMouseEvent(name, type, props) { + switch (name) { + case 'onClick': + case 'onClickCapture': + case 'onDoubleClick': + case 'onDoubleClickCapture': + case 'onMouseDown': + case 'onMouseDownCapture': + case 'onMouseMove': + case 'onMouseMoveCapture': + case 'onMouseUp': + case 'onMouseUpCapture': + return !!(props.disabled && isInteractive(type)); + default: + return false; + } +} + +/** + * This is a unified interface for event plugins to be installed and configured. + * + * Event plugins can implement the following properties: + * + * `extractEvents` {function(string, DOMEventTarget, string, object): *} + * Required. When a top-level event is fired, this method is expected to + * extract synthetic events that will in turn be queued and dispatched. + * + * `eventTypes` {object} + * Optional, plugins that fire events must publish a mapping of registration + * names that are used to register listeners. Values of this mapping must + * be objects that contain `registrationName` or `phasedRegistrationNames`. + * + * `executeDispatch` {function(object, function, string)} + * Optional, allows plugins to override how an event gets dispatched. By + * default, the listener is simply invoked. + * + * Each plugin that is injected into `EventsPluginHub` is immediately operable. + * + * @public + */ +var EventPluginHub = { + /** + * Methods for injecting dependencies. + */ + injection: { + /** + * @param {array} InjectedEventPluginOrder + * @public + */ + injectEventPluginOrder: EventPluginRegistry_1.injectEventPluginOrder, + + /** + * @param {object} injectedNamesToPlugins Map from names to plugin modules. + */ + injectEventPluginsByName: EventPluginRegistry_1.injectEventPluginsByName + }, + + /** + * @param {object} inst The instance, which is the source of events. + * @param {string} registrationName Name of listener (e.g. `onClick`). + * @return {?function} The stored callback. + */ + getListener: function (inst, registrationName) { + var listener; + + // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not + // live here; needs to be moved to a better place soon + if (typeof inst.tag === 'number') { + var stateNode = inst.stateNode; + if (!stateNode) { + // Work in progress (ex: onload events in incremental mode). + return null; + } + var props = EventPluginUtils_1.getFiberCurrentPropsFromNode(stateNode); + if (!props) { + // Work in progress. + return null; + } + listener = props[registrationName]; + if (shouldPreventMouseEvent(registrationName, inst.type, props)) { + return null; + } + } else { + var currentElement = inst._currentElement; + if (typeof currentElement === 'string' || typeof currentElement === 'number') { + // Text node, let it bubble through. + return null; + } + if (!inst._rootNodeID) { + // If the instance is already unmounted, we have no listeners. + return null; + } + var _props = currentElement.props; + listener = _props[registrationName]; + if (shouldPreventMouseEvent(registrationName, currentElement.type, _props)) { + return null; + } + } + + !(!listener || typeof listener === 'function') ? invariant(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener) : void 0; + return listener; + }, + + /** + * Allows registered plugins an opportunity to extract events from top-level + * native browser events. + * + * @return {*} An accumulation of synthetic events. + * @internal + */ + extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { + var events; + var plugins = EventPluginRegistry_1.plugins; + for (var i = 0; i < plugins.length; i++) { + // Not every plugin in the ordering may be loaded at runtime. + var possiblePlugin = plugins[i]; + if (possiblePlugin) { + var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); + if (extractedEvents) { + events = accumulateInto_1(events, extractedEvents); + } + } + } + return events; + }, + + /** + * Enqueues a synthetic event that should be dispatched when + * `processEventQueue` is invoked. + * + * @param {*} events An accumulation of synthetic events. + * @internal + */ + enqueueEvents: function (events) { + if (events) { + eventQueue = accumulateInto_1(eventQueue, events); + } + }, + + /** + * Dispatches all synthetic events on the event queue. + * + * @internal + */ + processEventQueue: function (simulated) { + // Set `eventQueue` to null before processing it so that we can tell if more + // events get enqueued while processing. + var processingEventQueue = eventQueue; + eventQueue = null; + if (simulated) { + forEachAccumulated_1(processingEventQueue, executeDispatchesAndReleaseSimulated); + } else { + forEachAccumulated_1(processingEventQueue, executeDispatchesAndReleaseTopLevel); + } + !!eventQueue ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : void 0; + // This would be a good time to rethrow if any of the event handlers threw. + ReactErrorUtils_1.rethrowCaughtError(); + } +}; + +var EventPluginHub_1 = EventPluginHub; + +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @providesModule ReactTypeOfWork + * + */ + +var ReactTypeOfWork = { + IndeterminateComponent: 0, // Before we know whether it is functional or class + FunctionalComponent: 1, + ClassComponent: 2, + HostRoot: 3, // Root of a host tree. Could be nested inside another node. + HostPortal: 4, // A subtree. Could be an entry point to a different renderer. + HostComponent: 5, + HostText: 6, + CoroutineComponent: 7, + CoroutineHandlerPhase: 8, + YieldComponent: 9, + Fragment: 10 +}; + +var HostComponent = ReactTypeOfWork.HostComponent; + +function getParent(inst) { + if (inst._hostParent !== undefined) { + return inst._hostParent; + } + if (typeof inst.tag === 'number') { + do { + inst = inst['return']; + // TODO: If this is a HostRoot we might want to bail out. + // That is depending on if we want nested subtrees (layers) to bubble + // events to their parent. We could also go through parentNode on the + // host node but that wouldn't work for React Native and doesn't let us + // do the portal feature. + } while (inst && inst.tag !== HostComponent); + if (inst) { + return inst; + } + } + return null; +} + +/** + * Return the lowest common ancestor of A and B, or null if they are in + * different trees. + */ +function getLowestCommonAncestor(instA, instB) { + var depthA = 0; + for (var tempA = instA; tempA; tempA = getParent(tempA)) { + depthA++; + } + var depthB = 0; + for (var tempB = instB; tempB; tempB = getParent(tempB)) { + depthB++; + } + + // If A is deeper, crawl up. + while (depthA - depthB > 0) { + instA = getParent(instA); + depthA--; + } + + // If B is deeper, crawl up. + while (depthB - depthA > 0) { + instB = getParent(instB); + depthB--; + } + + // Walk in lockstep until we find a match. + var depth = depthA; + while (depth--) { + if (instA === instB || instA === instB.alternate) { + return instA; + } + instA = getParent(instA); + instB = getParent(instB); + } + return null; +} + +/** + * Return if A is an ancestor of B. + */ +function isAncestor(instA, instB) { + while (instB) { + if (instA === instB || instA === instB.alternate) { + return true; + } + instB = getParent(instB); + } + return false; +} + +/** + * Return the parent instance of the passed-in instance. + */ +function getParentInstance(inst) { + return getParent(inst); +} + +/** + * Simulates the traversal of a two-phase, capture/bubble event dispatch. + */ +function traverseTwoPhase(inst, fn, arg) { + var path = []; + while (inst) { + path.push(inst); + inst = getParent(inst); + } + var i; + for (i = path.length; i-- > 0;) { + fn(path[i], 'captured', arg); + } + for (i = 0; i < path.length; i++) { + fn(path[i], 'bubbled', arg); + } +} + +/** + * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that + * should would receive a `mouseEnter` or `mouseLeave` event. + * + * Does not invoke the callback on the nearest common ancestor because nothing + * "entered" or "left" that element. + */ +function traverseEnterLeave(from, to, fn, argFrom, argTo) { + var common = from && to ? getLowestCommonAncestor(from, to) : null; + var pathFrom = []; + while (from && from !== common) { + pathFrom.push(from); + from = getParent(from); + } + var pathTo = []; + while (to && to !== common) { + pathTo.push(to); + to = getParent(to); + } + var i; + for (i = 0; i < pathFrom.length; i++) { + fn(pathFrom[i], 'bubbled', argFrom); + } + for (i = pathTo.length; i-- > 0;) { + fn(pathTo[i], 'captured', argTo); + } +} + +var ReactTreeTraversal = { + isAncestor: isAncestor, + getLowestCommonAncestor: getLowestCommonAncestor, + getParentInstance: getParentInstance, + traverseTwoPhase: traverseTwoPhase, + traverseEnterLeave: traverseEnterLeave +}; + +var getListener = EventPluginHub_1.getListener; + +{ + var warning$1 = require$$0; +} + +/** + * Some event types have a notion of different registration names for different + * "phases" of propagation. This finds listeners by a given phase. + */ +function listenerAtPhase(inst, event, propagationPhase) { + var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase]; + return getListener(inst, registrationName); +} + +/** + * Tags a `SyntheticEvent` with dispatched listeners. Creating this function + * here, allows us to not have to bind or create functions for each event. + * Mutating the event's members allows us to not have to create a wrapping + * "dispatch" object that pairs the event with the listener. + */ +function accumulateDirectionalDispatches(inst, phase, event) { + { + warning$1(inst, 'Dispatching inst must not be null'); + } + var listener = listenerAtPhase(inst, event, phase); + if (listener) { + event._dispatchListeners = accumulateInto_1(event._dispatchListeners, listener); + event._dispatchInstances = accumulateInto_1(event._dispatchInstances, inst); + } +} + +/** + * Collect dispatches (must be entirely collected before dispatching - see unit + * tests). Lazily allocate the array to conserve memory. We must loop through + * each event and perform the traversal for each one. We cannot perform a + * single traversal for the entire collection of events because each event may + * have a different target. + */ +function accumulateTwoPhaseDispatchesSingle(event) { + if (event && event.dispatchConfig.phasedRegistrationNames) { + ReactTreeTraversal.traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); + } +} + +/** + * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. + */ +function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { + if (event && event.dispatchConfig.phasedRegistrationNames) { + var targetInst = event._targetInst; + var parentInst = targetInst ? ReactTreeTraversal.getParentInstance(targetInst) : null; + ReactTreeTraversal.traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event); + } +} + +/** + * Accumulates without regard to direction, does not look for phased + * registration names. Same as `accumulateDirectDispatchesSingle` but without + * requiring that the `dispatchMarker` be the same as the dispatched ID. + */ +function accumulateDispatches(inst, ignoredDirection, event) { + if (inst && event && event.dispatchConfig.registrationName) { + var registrationName = event.dispatchConfig.registrationName; + var listener = getListener(inst, registrationName); + if (listener) { + event._dispatchListeners = accumulateInto_1(event._dispatchListeners, listener); + event._dispatchInstances = accumulateInto_1(event._dispatchInstances, inst); + } + } +} + +/** + * Accumulates dispatches on an `SyntheticEvent`, but only for the + * `dispatchMarker`. + * @param {SyntheticEvent} event + */ +function accumulateDirectDispatchesSingle(event) { + if (event && event.dispatchConfig.registrationName) { + accumulateDispatches(event._targetInst, null, event); + } +} + +function accumulateTwoPhaseDispatches(events) { + forEachAccumulated_1(events, accumulateTwoPhaseDispatchesSingle); +} + +function accumulateTwoPhaseDispatchesSkipTarget(events) { + forEachAccumulated_1(events, accumulateTwoPhaseDispatchesSingleSkipTarget); +} + +function accumulateEnterLeaveDispatches(leave, enter, from, to) { + ReactTreeTraversal.traverseEnterLeave(from, to, accumulateDispatches, leave, enter); +} + +function accumulateDirectDispatches(events) { + forEachAccumulated_1(events, accumulateDirectDispatchesSingle); +} + +/** + * A small set of propagation patterns, each of which will accept a small amount + * of information, and generate a set of "dispatch ready event objects" - which + * are sets of events that have already been annotated with a set of dispatched + * listener functions/ids. The API is designed this way to discourage these + * propagation strategies from actually executing the dispatches, since we + * always want to collect the entire set of dispatches before executing even a + * single one. + * + * @constructor EventPropagators + */ +var EventPropagators = { + accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches, + accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget, + accumulateDirectDispatches: accumulateDirectDispatches, + accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches +}; + +var EventPropagators_1 = EventPropagators; + +var didWarnForAddedNewProperty = false; +var isProxySupported = typeof Proxy === 'function'; +var EVENT_POOL_SIZE = 10; + +{ + var warning$2 = require$$0; +} + +var shouldBeReleasedProperties = ['dispatchConfig', '_targetInst', 'nativeEvent', 'isDefaultPrevented', 'isPropagationStopped', '_dispatchListeners', '_dispatchInstances']; + +/** + * @interface Event + * @see http://www.w3.org/TR/DOM-Level-3-Events/ + */ +var EventInterface = { + type: null, + target: null, + // currentTarget is set when dispatching; no use in copying it here + currentTarget: emptyFunction.thatReturnsNull, + eventPhase: null, + bubbles: null, + cancelable: null, + timeStamp: function (event) { + return event.timeStamp || Date.now(); + }, + defaultPrevented: null, + isTrusted: null +}; + +/** + * Synthetic events are dispatched by event plugins, typically in response to a + * top-level event delegation handler. + * + * These systems should generally use pooling to reduce the frequency of garbage + * collection. The system should check `isPersistent` to determine whether the + * event should be released into the pool after being dispatched. Users that + * need a persisted event should invoke `persist`. + * + * Synthetic events (and subclasses) implement the DOM Level 3 Events API by + * normalizing browser quirks. Subclasses do not necessarily have to implement a + * DOM interface; custom application-specific events can also subclass this. + * + * @param {object} dispatchConfig Configuration used to dispatch this event. + * @param {*} targetInst Marker identifying the event target. + * @param {object} nativeEvent Native browser event. + * @param {DOMEventTarget} nativeEventTarget Target node. + */ +function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) { + { + // these have a getter/setter for warnings + delete this.nativeEvent; + delete this.preventDefault; + delete this.stopPropagation; + } + + this.dispatchConfig = dispatchConfig; + this._targetInst = targetInst; + this.nativeEvent = nativeEvent; + + var Interface = this.constructor.Interface; + for (var propName in Interface) { + if (!Interface.hasOwnProperty(propName)) { + continue; + } + { + delete this[propName]; // this has a getter/setter for warnings + } + var normalize = Interface[propName]; + if (normalize) { + this[propName] = normalize(nativeEvent); + } else { + if (propName === 'target') { + this.target = nativeEventTarget; + } else { + this[propName] = nativeEvent[propName]; + } + } + } + + var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false; + if (defaultPrevented) { + this.isDefaultPrevented = emptyFunction.thatReturnsTrue; + } else { + this.isDefaultPrevented = emptyFunction.thatReturnsFalse; + } + this.isPropagationStopped = emptyFunction.thatReturnsFalse; + return this; +} + +objectAssign$1(SyntheticEvent.prototype, { + preventDefault: function () { + this.defaultPrevented = true; + var event = this.nativeEvent; + if (!event) { + return; + } + + if (event.preventDefault) { + event.preventDefault(); + } else if (typeof event.returnValue !== 'unknown') { + event.returnValue = false; + } + this.isDefaultPrevented = emptyFunction.thatReturnsTrue; + }, + + stopPropagation: function () { + var event = this.nativeEvent; + if (!event) { + return; + } + + if (event.stopPropagation) { + event.stopPropagation(); + } else if (typeof event.cancelBubble !== 'unknown') { + // The ChangeEventPlugin registers a "propertychange" event for + // IE. This event does not support bubbling or cancelling, and + // any references to cancelBubble throw "Member not found". A + // typeof check of "unknown" circumvents this issue (and is also + // IE specific). + event.cancelBubble = true; + } + + this.isPropagationStopped = emptyFunction.thatReturnsTrue; + }, + + /** + * We release all dispatched `SyntheticEvent`s after each event loop, adding + * them back into the pool. This allows a way to hold onto a reference that + * won't be added back into the pool. + */ + persist: function () { + this.isPersistent = emptyFunction.thatReturnsTrue; + }, + + /** + * Checks if this event should be released back into the pool. + * + * @return {boolean} True if this should not be released, false otherwise. + */ + isPersistent: emptyFunction.thatReturnsFalse, + + /** + * `PooledClass` looks for `destructor` on each instance it releases. + */ + destructor: function () { + var Interface = this.constructor.Interface; + for (var propName in Interface) { + { + Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName])); + } + } + for (var i = 0; i < shouldBeReleasedProperties.length; i++) { + this[shouldBeReleasedProperties[i]] = null; + } + { + Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null)); + Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', emptyFunction)); + Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', emptyFunction)); + } + } +}); + +SyntheticEvent.Interface = EventInterface; + +/** + * Helper to reduce boilerplate when creating subclasses. + * + * @param {function} Class + * @param {?object} Interface + */ +SyntheticEvent.augmentClass = function (Class, Interface) { + var Super = this; + + var E = function () {}; + E.prototype = Super.prototype; + var prototype = new E(); + + objectAssign$1(prototype, Class.prototype); + Class.prototype = prototype; + Class.prototype.constructor = Class; + + Class.Interface = objectAssign$1({}, Super.Interface, Interface); + Class.augmentClass = Super.augmentClass; + addEventPoolingTo(Class); +}; + +/** Proxying after everything set on SyntheticEvent + * to resolve Proxy issue on some WebKit browsers + * in which some Event properties are set to undefined (GH#10010) + */ +{ + if (isProxySupported) { + /*eslint-disable no-func-assign */ + SyntheticEvent = new Proxy(SyntheticEvent, { + construct: function (target, args) { + return this.apply(target, Object.create(target.prototype), args); + }, + apply: function (constructor, that, args) { + return new Proxy(constructor.apply(that, args), { + set: function (target, prop, value) { + if (prop !== 'isPersistent' && !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1) { + warning$2(didWarnForAddedNewProperty || target.isPersistent(), "This synthetic event is reused for performance reasons. If you're " + "seeing this, you're adding a new property in the synthetic event object. " + 'The property is never released. See ' + 'https://fb.me/react-event-pooling for more information.'); + didWarnForAddedNewProperty = true; + } + target[prop] = value; + return true; + } + }); + } + }); + /*eslint-enable no-func-assign */ + } +} + +addEventPoolingTo(SyntheticEvent); + +var SyntheticEvent_1 = SyntheticEvent; + +/** + * Helper to nullify syntheticEvent instance properties when destructing + * + * @param {String} propName + * @param {?object} getVal + * @return {object} defineProperty object + */ +function getPooledWarningPropertyDefinition(propName, getVal) { + var isFunction = typeof getVal === 'function'; + return { + configurable: true, + set: set, + get: get + }; + + function set(val) { + var action = isFunction ? 'setting the method' : 'setting the property'; + warn(action, 'This is effectively a no-op'); + return val; + } + + function get() { + var action = isFunction ? 'accessing the method' : 'accessing the property'; + var result = isFunction ? 'This is a no-op function' : 'This is set to null'; + warn(action, result); + return getVal; + } + + function warn(action, result) { + var warningCondition = false; + warning$2(warningCondition, "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); + } +} + +function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { + var EventConstructor = this; + if (EventConstructor.eventPool.length) { + var instance = EventConstructor.eventPool.pop(); + EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst); + return instance; + } + return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst); +} + +function releasePooledEvent(event) { + var EventConstructor = this; + !(event instanceof EventConstructor) ? invariant(false, 'Trying to release an event instance into a pool of a different type.') : void 0; + event.destructor(); + if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { + EventConstructor.eventPool.push(event); + } +} + +function addEventPoolingTo(EventConstructor) { + EventConstructor.eventPool = []; + EventConstructor.getPooled = getPooledEvent; + EventConstructor.release = releasePooledEvent; +} + +/** + * `touchHistory` isn't actually on the native event, but putting it in the + * interface will ensure that it is cleaned up when pooled/destroyed. The + * `ResponderEventPlugin` will populate it appropriately. + */ +var ResponderEventInterface = { + touchHistory: function (nativeEvent) { + return null; // Actually doesn't even look at the native event. + } +}; + +/** + * @param {object} dispatchConfig Configuration used to dispatch this event. + * @param {string} dispatchMarker Marker identifying the event target. + * @param {object} nativeEvent Native event. + * @extends {SyntheticEvent} + */ +function ResponderSyntheticEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { + return SyntheticEvent_1.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); +} + +SyntheticEvent_1.augmentClass(ResponderSyntheticEvent, ResponderEventInterface); + +var ResponderSyntheticEvent_1 = ResponderSyntheticEvent; + +var isEndish$2 = EventPluginUtils_1.isEndish; +var isMoveish$2 = EventPluginUtils_1.isMoveish; +var isStartish$2 = EventPluginUtils_1.isStartish; + + +{ + var warning$3 = require$$0; +} + +/** + * Tracks the position and time of each active touch by `touch.identifier`. We + * should typically only see IDs in the range of 1-20 because IDs get recycled + * when touches end and start again. + */ + + +var MAX_TOUCH_BANK = 20; +var touchBank = []; +var touchHistory = { + touchBank: touchBank, + numberActiveTouches: 0, + // If there is only one active touch, we remember its location. This prevents + // us having to loop through all of the touches all the time in the most + // common case. + indexOfSingleActiveTouch: -1, + mostRecentTimeStamp: 0 +}; + +function timestampForTouch(touch) { + // The legacy internal implementation provides "timeStamp", which has been + // renamed to "timestamp". Let both work for now while we iron it out + // TODO (evv): rename timeStamp to timestamp in internal code + return touch.timeStamp || touch.timestamp; +} + +/** + * TODO: Instead of making gestures recompute filtered velocity, we could + * include a built in velocity computation that can be reused globally. + */ +function createTouchRecord(touch) { + return { + touchActive: true, + startPageX: touch.pageX, + startPageY: touch.pageY, + startTimeStamp: timestampForTouch(touch), + currentPageX: touch.pageX, + currentPageY: touch.pageY, + currentTimeStamp: timestampForTouch(touch), + previousPageX: touch.pageX, + previousPageY: touch.pageY, + previousTimeStamp: timestampForTouch(touch) + }; +} + +function resetTouchRecord(touchRecord, touch) { + touchRecord.touchActive = true; + touchRecord.startPageX = touch.pageX; + touchRecord.startPageY = touch.pageY; + touchRecord.startTimeStamp = timestampForTouch(touch); + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchRecord.previousPageX = touch.pageX; + touchRecord.previousPageY = touch.pageY; + touchRecord.previousTimeStamp = timestampForTouch(touch); +} + +function getTouchIdentifier(_ref) { + var identifier = _ref.identifier; + + !(identifier != null) ? invariant(false, 'Touch object is missing identifier.') : void 0; + { + warning$3(identifier <= MAX_TOUCH_BANK, '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); + } + return identifier; +} + +function recordTouchStart(touch) { + var identifier = getTouchIdentifier(touch); + var touchRecord = touchBank[identifier]; + if (touchRecord) { + resetTouchRecord(touchRecord, touch); + } else { + touchBank[identifier] = createTouchRecord(touch); + } + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); +} + +function recordTouchMove(touch) { + var touchRecord = touchBank[getTouchIdentifier(touch)]; + if (touchRecord) { + touchRecord.touchActive = true; + touchRecord.previousPageX = touchRecord.currentPageX; + touchRecord.previousPageY = touchRecord.currentPageY; + touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); + } else { + console.error('Cannot record touch move without a touch start.\n' + 'Touch Move: %s\n', 'Touch Bank: %s', printTouch(touch), printTouchBank()); + } +} + +function recordTouchEnd(touch) { + var touchRecord = touchBank[getTouchIdentifier(touch)]; + if (touchRecord) { + touchRecord.touchActive = false; + touchRecord.previousPageX = touchRecord.currentPageX; + touchRecord.previousPageY = touchRecord.currentPageY; + touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); + } else { + console.error('Cannot record touch end without a touch start.\n' + 'Touch End: %s\n', 'Touch Bank: %s', printTouch(touch), printTouchBank()); + } +} + +function printTouch(touch) { + return JSON.stringify({ + identifier: touch.identifier, + pageX: touch.pageX, + pageY: touch.pageY, + timestamp: timestampForTouch(touch) + }); +} + +function printTouchBank() { + var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK)); + if (touchBank.length > MAX_TOUCH_BANK) { + printed += ' (original size: ' + touchBank.length + ')'; + } + return printed; +} + +var ResponderTouchHistoryStore = { + recordTouchTrack: function (topLevelType, nativeEvent) { + if (isMoveish$2(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchMove); + } else if (isStartish$2(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchStart); + touchHistory.numberActiveTouches = nativeEvent.touches.length; + if (touchHistory.numberActiveTouches === 1) { + touchHistory.indexOfSingleActiveTouch = nativeEvent.touches[0].identifier; + } + } else if (isEndish$2(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchEnd); + touchHistory.numberActiveTouches = nativeEvent.touches.length; + if (touchHistory.numberActiveTouches === 1) { + for (var i = 0; i < touchBank.length; i++) { + var touchTrackToCheck = touchBank[i]; + if (touchTrackToCheck != null && touchTrackToCheck.touchActive) { + touchHistory.indexOfSingleActiveTouch = i; + break; + } + } + { + var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; + warning$3(activeRecord != null && activeRecord.touchActive, 'Cannot find single active touch.'); + } + } + } + }, + + + touchHistory: touchHistory +}; + +var ResponderTouchHistoryStore_1 = ResponderTouchHistoryStore; + +/** + * Accumulates items that must not be null or undefined. + * + * This is used to conserve memory by avoiding array allocations. + * + * @return {*|array<*>} An accumulation of items. + */ +function accumulate(current, next) { + !(next != null) ? invariant(false, 'accumulate(...): Accumulated items must be not be null or undefined.') : void 0; + + if (current == null) { + return next; + } + + // Both are not empty. Warning: Never call x.concat(y) when you are not + // certain that x is an Array (x could be a string with concat method). + if (Array.isArray(current)) { + return current.concat(next); + } + + if (Array.isArray(next)) { + return [current].concat(next); + } + + return [current, next]; +} + +var accumulate_1 = accumulate; + +var isStartish$1 = EventPluginUtils_1.isStartish; +var isMoveish$1 = EventPluginUtils_1.isMoveish; +var isEndish$1 = EventPluginUtils_1.isEndish; +var executeDirectDispatch$1 = EventPluginUtils_1.executeDirectDispatch; +var hasDispatches$1 = EventPluginUtils_1.hasDispatches; +var executeDispatchesInOrderStopAtTrue$1 = EventPluginUtils_1.executeDispatchesInOrderStopAtTrue; + +/** + * Instance of element that should respond to touch/move types of interactions, + * as indicated explicitly by relevant callbacks. + */ +var responderInst = null; + +/** + * Count of current touches. A textInput should become responder iff the + * selection changes while there is a touch on the screen. + */ +var trackedTouchCount = 0; + +/** + * Last reported number of active touches. + */ +var previousActiveTouches = 0; + +var changeResponder = function (nextResponderInst, blockHostResponder) { + var oldResponderInst = responderInst; + responderInst = nextResponderInst; + if (ResponderEventPlugin.GlobalResponderHandler !== null) { + ResponderEventPlugin.GlobalResponderHandler.onChange(oldResponderInst, nextResponderInst, blockHostResponder); + } +}; + +var eventTypes = { + /** + * On a `touchStart`/`mouseDown`, is it desired that this element become the + * responder? + */ + startShouldSetResponder: { + phasedRegistrationNames: { + bubbled: 'onStartShouldSetResponder', + captured: 'onStartShouldSetResponderCapture' + } + }, + + /** + * On a `scroll`, is it desired that this element become the responder? This + * is usually not needed, but should be used to retroactively infer that a + * `touchStart` had occurred during momentum scroll. During a momentum scroll, + * a touch start will be immediately followed by a scroll event if the view is + * currently scrolling. + * + * TODO: This shouldn't bubble. + */ + scrollShouldSetResponder: { + phasedRegistrationNames: { + bubbled: 'onScrollShouldSetResponder', + captured: 'onScrollShouldSetResponderCapture' + } + }, + + /** + * On text selection change, should this element become the responder? This + * is needed for text inputs or other views with native selection, so the + * JS view can claim the responder. + * + * TODO: This shouldn't bubble. + */ + selectionChangeShouldSetResponder: { + phasedRegistrationNames: { + bubbled: 'onSelectionChangeShouldSetResponder', + captured: 'onSelectionChangeShouldSetResponderCapture' + } + }, + + /** + * On a `touchMove`/`mouseMove`, is it desired that this element become the + * responder? + */ + moveShouldSetResponder: { + phasedRegistrationNames: { + bubbled: 'onMoveShouldSetResponder', + captured: 'onMoveShouldSetResponderCapture' + } + }, + + /** + * Direct responder events dispatched directly to responder. Do not bubble. + */ + responderStart: { registrationName: 'onResponderStart' }, + responderMove: { registrationName: 'onResponderMove' }, + responderEnd: { registrationName: 'onResponderEnd' }, + responderRelease: { registrationName: 'onResponderRelease' }, + responderTerminationRequest: { + registrationName: 'onResponderTerminationRequest' + }, + responderGrant: { registrationName: 'onResponderGrant' }, + responderReject: { registrationName: 'onResponderReject' }, + responderTerminate: { registrationName: 'onResponderTerminate' } +}; + +/** + * + * Responder System: + * ---------------- + * + * - A global, solitary "interaction lock" on a view. + * - If a node becomes the responder, it should convey visual feedback + * immediately to indicate so, either by highlighting or moving accordingly. + * - To be the responder means, that touches are exclusively important to that + * responder view, and no other view. + * - While touches are still occurring, the responder lock can be transferred to + * a new view, but only to increasingly "higher" views (meaning ancestors of + * the current responder). + * + * Responder being granted: + * ------------------------ + * + * - Touch starts, moves, and scrolls can cause an ID to become the responder. + * - We capture/bubble `startShouldSetResponder`/`moveShouldSetResponder` to + * the "appropriate place". + * - If nothing is currently the responder, the "appropriate place" is the + * initiating event's `targetID`. + * - If something *is* already the responder, the "appropriate place" is the + * first common ancestor of the event target and the current `responderInst`. + * - Some negotiation happens: See the timing diagram below. + * - Scrolled views automatically become responder. The reasoning is that a + * platform scroll view that isn't built on top of the responder system has + * began scrolling, and the active responder must now be notified that the + * interaction is no longer locked to it - the system has taken over. + * + * - Responder being released: + * As soon as no more touches that *started* inside of descendants of the + * *current* responderInst, an `onResponderRelease` event is dispatched to the + * current responder, and the responder lock is released. + * + * TODO: + * - on "end", a callback hook for `onResponderEndShouldRemainResponder` that + * determines if the responder lock should remain. + * - If a view shouldn't "remain" the responder, any active touches should by + * default be considered "dead" and do not influence future negotiations or + * bubble paths. It should be as if those touches do not exist. + * -- For multitouch: Usually a translate-z will choose to "remain" responder + * after one out of many touches ended. For translate-y, usually the view + * doesn't wish to "remain" responder after one of many touches end. + * - Consider building this on top of a `stopPropagation` model similar to + * `W3C` events. + * - Ensure that `onResponderTerminate` is called on touch cancels, whether or + * not `onResponderTerminationRequest` returns `true` or `false`. + * + */ + +/* Negotiation Performed + +-----------------------+ + / \ +Process low level events to + Current Responder + wantsResponderID +determine who to perform negot-| (if any exists at all) | +iation/transition | Otherwise just pass through| +-------------------------------+----------------------------+------------------+ +Bubble to find first ID | | +to return true:wantsResponderID| | + | | + +-------------+ | | + | onTouchStart| | | + +------+------+ none | | + | return| | ++-----------v-------------+true| +------------------------+ | +|onStartShouldSetResponder|----->|onResponderStart (cur) |<-----------+ ++-----------+-------------+ | +------------------------+ | | + | | | +--------+-------+ + | returned true for| false:REJECT +-------->|onResponderReject + | wantsResponderID | | | +----------------+ + | (now attempt | +------------------+-----+ | + | handoff) | | onResponder | | + +------------------->| TerminationRequest| | + | +------------------+-----+ | + | | | +----------------+ + | true:GRANT +-------->|onResponderGrant| + | | +--------+-------+ + | +------------------------+ | | + | | onResponderTerminate |<-----------+ + | +------------------+-----+ | + | | | +----------------+ + | +-------->|onResponderStart| + | | +----------------+ +Bubble to find first ID | | +to return true:wantsResponderID| | + | | + +-------------+ | | + | onTouchMove | | | + +------+------+ none | | + | return| | ++-----------v-------------+true| +------------------------+ | +|onMoveShouldSetResponder |----->|onResponderMove (cur) |<-----------+ ++-----------+-------------+ | +------------------------+ | | + | | | +--------+-------+ + | returned true for| false:REJECT +-------->|onResponderRejec| + | wantsResponderID | | | +----------------+ + | (now attempt | +------------------+-----+ | + | handoff) | | onResponder | | + +------------------->| TerminationRequest| | + | +------------------+-----+ | + | | | +----------------+ + | true:GRANT +-------->|onResponderGrant| + | | +--------+-------+ + | +------------------------+ | | + | | onResponderTerminate |<-----------+ + | +------------------+-----+ | + | | | +----------------+ + | +-------->|onResponderMove | + | | +----------------+ + | | + | | + Some active touch started| | + inside current responder | +------------------------+ | + +------------------------->| onResponderEnd | | + | | +------------------------+ | + +---+---------+ | | + | onTouchEnd | | | + +---+---------+ | | + | | +------------------------+ | + +------------------------->| onResponderEnd | | + No active touches started| +-----------+------------+ | + inside current responder | | | + | v | + | +------------------------+ | + | | onResponderRelease | | + | +------------------------+ | + | | + + + */ + +/** + * A note about event ordering in the `EventPluginHub`. + * + * Suppose plugins are injected in the following order: + * + * `[R, S, C]` + * + * To help illustrate the example, assume `S` is `SimpleEventPlugin` (for + * `onClick` etc) and `R` is `ResponderEventPlugin`. + * + * "Deferred-Dispatched Events": + * + * - The current event plugin system will traverse the list of injected plugins, + * in order, and extract events by collecting the plugin's return value of + * `extractEvents()`. + * - These events that are returned from `extractEvents` are "deferred + * dispatched events". + * - When returned from `extractEvents`, deferred-dispatched events contain an + * "accumulation" of deferred dispatches. + * - These deferred dispatches are accumulated/collected before they are + * returned, but processed at a later time by the `EventPluginHub` (hence the + * name deferred). + * + * In the process of returning their deferred-dispatched events, event plugins + * themselves can dispatch events on-demand without returning them from + * `extractEvents`. Plugins might want to do this, so that they can use event + * dispatching as a tool that helps them decide which events should be extracted + * in the first place. + * + * "On-Demand-Dispatched Events": + * + * - On-demand-dispatched events are not returned from `extractEvents`. + * - On-demand-dispatched events are dispatched during the process of returning + * the deferred-dispatched events. + * - They should not have side effects. + * - They should be avoided, and/or eventually be replaced with another + * abstraction that allows event plugins to perform multiple "rounds" of event + * extraction. + * + * Therefore, the sequence of event dispatches becomes: + * + * - `R`s on-demand events (if any) (dispatched by `R` on-demand) + * - `S`s on-demand events (if any) (dispatched by `S` on-demand) + * - `C`s on-demand events (if any) (dispatched by `C` on-demand) + * - `R`s extracted events (if any) (dispatched by `EventPluginHub`) + * - `S`s extracted events (if any) (dispatched by `EventPluginHub`) + * - `C`s extracted events (if any) (dispatched by `EventPluginHub`) + * + * In the case of `ResponderEventPlugin`: If the `startShouldSetResponder` + * on-demand dispatch returns `true` (and some other details are satisfied) the + * `onResponderGrant` deferred dispatched event is returned from + * `extractEvents`. The sequence of dispatch executions in this case + * will appear as follows: + * + * - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand) + * - `touchStartCapture` (`EventPluginHub` dispatches as usual) + * - `touchStart` (`EventPluginHub` dispatches as usual) + * - `responderGrant/Reject` (`EventPluginHub` dispatches as usual) + */ + +function setResponderAndExtractTransfer(topLevelType, targetInst, nativeEvent, nativeEventTarget) { + var shouldSetEventType = isStartish$1(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish$1(topLevelType) ? eventTypes.moveShouldSetResponder : topLevelType === 'topSelectionChange' ? eventTypes.selectionChangeShouldSetResponder : eventTypes.scrollShouldSetResponder; + + // TODO: stop one short of the current responder. + var bubbleShouldSetFrom = !responderInst ? targetInst : ReactTreeTraversal.getLowestCommonAncestor(responderInst, targetInst); + + // When capturing/bubbling the "shouldSet" event, we want to skip the target + // (deepest ID) if it happens to be the current responder. The reasoning: + // It's strange to get an `onMoveShouldSetResponder` when you're *already* + // the responder. + var skipOverBubbleShouldSetFrom = bubbleShouldSetFrom === responderInst; + var shouldSetEvent = ResponderSyntheticEvent_1.getPooled(shouldSetEventType, bubbleShouldSetFrom, nativeEvent, nativeEventTarget); + shouldSetEvent.touchHistory = ResponderTouchHistoryStore_1.touchHistory; + if (skipOverBubbleShouldSetFrom) { + EventPropagators_1.accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent); + } else { + EventPropagators_1.accumulateTwoPhaseDispatches(shouldSetEvent); + } + var wantsResponderInst = executeDispatchesInOrderStopAtTrue$1(shouldSetEvent); + if (!shouldSetEvent.isPersistent()) { + shouldSetEvent.constructor.release(shouldSetEvent); + } + + if (!wantsResponderInst || wantsResponderInst === responderInst) { + return null; + } + var extracted; + var grantEvent = ResponderSyntheticEvent_1.getPooled(eventTypes.responderGrant, wantsResponderInst, nativeEvent, nativeEventTarget); + grantEvent.touchHistory = ResponderTouchHistoryStore_1.touchHistory; + + EventPropagators_1.accumulateDirectDispatches(grantEvent); + var blockHostResponder = executeDirectDispatch$1(grantEvent) === true; + if (responderInst) { + var terminationRequestEvent = ResponderSyntheticEvent_1.getPooled(eventTypes.responderTerminationRequest, responderInst, nativeEvent, nativeEventTarget); + terminationRequestEvent.touchHistory = ResponderTouchHistoryStore_1.touchHistory; + EventPropagators_1.accumulateDirectDispatches(terminationRequestEvent); + var shouldSwitch = !hasDispatches$1(terminationRequestEvent) || executeDirectDispatch$1(terminationRequestEvent); + if (!terminationRequestEvent.isPersistent()) { + terminationRequestEvent.constructor.release(terminationRequestEvent); + } + + if (shouldSwitch) { + var terminateEvent = ResponderSyntheticEvent_1.getPooled(eventTypes.responderTerminate, responderInst, nativeEvent, nativeEventTarget); + terminateEvent.touchHistory = ResponderTouchHistoryStore_1.touchHistory; + EventPropagators_1.accumulateDirectDispatches(terminateEvent); + extracted = accumulate_1(extracted, [grantEvent, terminateEvent]); + changeResponder(wantsResponderInst, blockHostResponder); + } else { + var rejectEvent = ResponderSyntheticEvent_1.getPooled(eventTypes.responderReject, wantsResponderInst, nativeEvent, nativeEventTarget); + rejectEvent.touchHistory = ResponderTouchHistoryStore_1.touchHistory; + EventPropagators_1.accumulateDirectDispatches(rejectEvent); + extracted = accumulate_1(extracted, rejectEvent); + } + } else { + extracted = accumulate_1(extracted, grantEvent); + changeResponder(wantsResponderInst, blockHostResponder); + } + return extracted; +} + +/** + * A transfer is a negotiation between a currently set responder and the next + * element to claim responder status. Any start event could trigger a transfer + * of responderInst. Any move event could trigger a transfer. + * + * @param {string} topLevelType Record from `BrowserEventConstants`. + * @return {boolean} True if a transfer of responder could possibly occur. + */ +function canTriggerTransfer(topLevelType, topLevelInst, nativeEvent) { + return topLevelInst && ( + // responderIgnoreScroll: We are trying to migrate away from specifically + // tracking native scroll events here and responderIgnoreScroll indicates we + // will send topTouchCancel to handle canceling touch events instead + topLevelType === 'topScroll' && !nativeEvent.responderIgnoreScroll || trackedTouchCount > 0 && topLevelType === 'topSelectionChange' || isStartish$1(topLevelType) || isMoveish$1(topLevelType)); +} + +/** + * Returns whether or not this touch end event makes it such that there are no + * longer any touches that started inside of the current `responderInst`. + * + * @param {NativeEvent} nativeEvent Native touch end event. + * @return {boolean} Whether or not this touch end event ends the responder. + */ +function noResponderTouches(nativeEvent) { + var touches = nativeEvent.touches; + if (!touches || touches.length === 0) { + return true; + } + for (var i = 0; i < touches.length; i++) { + var activeTouch = touches[i]; + var target = activeTouch.target; + if (target !== null && target !== undefined && target !== 0) { + // Is the original touch location inside of the current responder? + var targetInst = EventPluginUtils_1.getInstanceFromNode(target); + if (ReactTreeTraversal.isAncestor(responderInst, targetInst)) { + return false; + } + } + } + return true; +} + +var ResponderEventPlugin = { + /* For unit testing only */ + _getResponder: function () { + return responderInst; + }, + + eventTypes: eventTypes, + + /** + * We must be resilient to `targetInst` being `null` on `touchMove` or + * `touchEnd`. On certain platforms, this means that a native scroll has + * assumed control and the original touch targets are destroyed. + */ + extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { + if (isStartish$1(topLevelType)) { + trackedTouchCount += 1; + } else if (isEndish$1(topLevelType)) { + if (trackedTouchCount >= 0) { + trackedTouchCount -= 1; + } else { + console.error('Ended a touch event which was not counted in `trackedTouchCount`.'); + return null; + } + } + + ResponderTouchHistoryStore_1.recordTouchTrack(topLevelType, nativeEvent); + + 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. + // Regardless, whoever is the responder after any potential transfer, we + // direct all touch start/move/ends to them in the form of + // `onResponderMove/Start/End`. These will be called for *every* additional + // finger that move/start/end, dispatched directly to whoever is the + // current responder at that moment, until the responder is "released". + // + // These multiple individual change touch events are are always bookended + // by `onResponderGrant`, and one of + // (`onResponderRelease/onResponderTerminate`). + var isResponderTouchStart = responderInst && isStartish$1(topLevelType); + var isResponderTouchMove = responderInst && isMoveish$1(topLevelType); + var isResponderTouchEnd = responderInst && isEndish$1(topLevelType); + var incrementalTouch = isResponderTouchStart ? eventTypes.responderStart : isResponderTouchMove ? eventTypes.responderMove : isResponderTouchEnd ? eventTypes.responderEnd : null; + + if (incrementalTouch) { + var gesture = ResponderSyntheticEvent_1.getPooled(incrementalTouch, responderInst, nativeEvent, nativeEventTarget); + gesture.touchHistory = ResponderTouchHistoryStore_1.touchHistory; + EventPropagators_1.accumulateDirectDispatches(gesture); + extracted = accumulate_1(extracted, gesture); + } + + var isResponderTerminate = responderInst && topLevelType === 'topTouchCancel'; + var isResponderRelease = responderInst && !isResponderTerminate && isEndish$1(topLevelType) && noResponderTouches(nativeEvent); + var finalTouch = isResponderTerminate ? eventTypes.responderTerminate : isResponderRelease ? eventTypes.responderRelease : null; + if (finalTouch) { + var finalEvent = ResponderSyntheticEvent_1.getPooled(finalTouch, responderInst, nativeEvent, nativeEventTarget); + finalEvent.touchHistory = ResponderTouchHistoryStore_1.touchHistory; + EventPropagators_1.accumulateDirectDispatches(finalEvent); + extracted = accumulate_1(extracted, finalEvent); + changeResponder(null); + } + + var numberActiveTouches = ResponderTouchHistoryStore_1.touchHistory.numberActiveTouches; + if (ResponderEventPlugin.GlobalInteractionHandler && numberActiveTouches !== previousActiveTouches) { + ResponderEventPlugin.GlobalInteractionHandler.onChange(numberActiveTouches); + } + previousActiveTouches = numberActiveTouches; + + return extracted; + }, + + GlobalResponderHandler: null, + GlobalInteractionHandler: null, + + injection: { + /** + * @param {{onChange: (ReactID, ReactID) => void} GlobalResponderHandler + * Object that handles any change in responder. Use this to inject + * integration with an existing touch handling system etc. + */ + injectGlobalResponderHandler: function (GlobalResponderHandler) { + ResponderEventPlugin.GlobalResponderHandler = GlobalResponderHandler; + }, + + /** + * @param {{onChange: (numberActiveTouches) => void} GlobalInteractionHandler + * Object that handles any change in the number of active touches. + */ + injectGlobalInteractionHandler: function (GlobalInteractionHandler) { + ResponderEventPlugin.GlobalInteractionHandler = GlobalInteractionHandler; + } + } +}; + +var ResponderEventPlugin_1 = ResponderEventPlugin; + +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @providesModule ReactDOMUnstableNativeDependenciesEntry + */ + + + + + +var ReactDOMUnstableNativeDependencies = { + injectComponentTree: EventPluginUtils_1.injection.injectComponentTree, + ResponderEventPlugin: ResponderEventPlugin_1, + ResponderTouchHistoryStore: ResponderTouchHistoryStore_1 +}; + +// Inject react-dom's ComponentTree into this module. + +var ReactDOMComponentTree = reactDom.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactDOMComponentTree; + +ReactDOMUnstableNativeDependencies.injectComponentTree(ReactDOMComponentTree); + +var ReactDOMUnstableNativeDependenciesEntry = ReactDOMUnstableNativeDependencies; + +module.exports = ReactDOMUnstableNativeDependenciesEntry; + +})(); +} |