diff --git a/wp-includes/js/dist/vendor/react-dom.js b/wp-includes/js/dist/vendor/react-dom.js index b6e607e7ee..1b85aa6dc8 100644 --- a/wp-includes/js/dist/vendor/react-dom.js +++ b/wp-includes/js/dist/vendor/react-dom.js @@ -1,4 +1,4 @@ -/** @license React v16.8.4 +/** @license React v16.9.0 * react-dom.development.js * * Copyright (c) Facebook, Inc. and its affiliates. @@ -15,6 +15,19 @@ (global.ReactDOM = factory(global.React)); }(this, (function (React) { 'use strict'; +// Do not require this module directly! Use normal `invariant` calls with +// template literal strings. The messages will be converted to ReactError during +// build, and in production they will be minified. + +// Do not require this module directly! Use normal `invariant` calls with +// template literal strings. The messages will be converted to ReactError during +// build, and in production they will be minified. + +function ReactError(error) { + error.name = 'Invariant Violation'; + return error; +} + /** * Use invariant() to assert state which your program assumes to be true. * @@ -26,41 +39,220 @@ * will remain to ensure logic does not differ in production. */ -var validateFormat = function () {}; - -{ - validateFormat = function (format) { - if (format === undefined) { - throw new Error('invariant requires an error message argument'); +(function () { + if (!React) { + { + throw ReactError(Error('ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.')); } - }; -} + } +})(); -function invariant(condition, format, a, b, c, d, e, f) { - validateFormat(format); +/** + * Injectable ordering of event plugins. + */ +var eventPluginOrder = null; - if (!condition) { - var error = void 0; - if (format === undefined) { - error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); - } else { - var args = [a, b, c, d, e, f]; - var argIndex = 0; - error = new Error(format.replace(/%s/g, function () { - return args[argIndex++]; - })); - error.name = 'Invariant Violation'; +/** + * 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); + (function () { + if (!(pluginIndex > -1)) { + { + throw ReactError(Error('EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `' + pluginName + '`.')); + } + } + })(); + if (plugins[pluginIndex]) { + continue; + } + (function () { + if (!pluginModule.extractEvents) { + { + throw ReactError(Error('EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `' + pluginName + '` does not.')); + } + } + })(); + plugins[pluginIndex] = pluginModule; + var publishedEvents = pluginModule.eventTypes; + for (var eventName in publishedEvents) { + (function () { + if (!publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName)) { + { + throw ReactError(Error('EventPluginRegistry: Failed to publish event `' + eventName + '` for plugin `' + pluginName + '`.')); + } + } + })(); } - - error.framesToPop = 1; // we don't care about invariant's own frame - throw error; } } -// Relying on the `invariant()` implementation lets us -// preserve the format and params in the www builds. +/** + * 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) { + (function () { + if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) { + { + throw ReactError(Error('EventPluginHub: More than one plugin attempted to publish the same event name, `' + eventName + '`.')); + } + } + })(); + eventNameDispatchConfigs[eventName] = dispatchConfig; -!React ? invariant(false, 'ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.') : void 0; + 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) { + (function () { + if (!!registrationNameModules[registrationName]) { + { + throw ReactError(Error('EventPluginHub: More than one plugin attempted to publish the same registration name, `' + registrationName + '`.')); + } + } + })(); + registrationNameModules[registrationName] = pluginModule; + registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies; + + { + var lowerCasedName = registrationName.toLowerCase(); + possibleRegistrationNames[lowerCasedName] = registrationName; + + if (registrationName === 'onDoubleClick') { + possibleRegistrationNames.ondblclick = registrationName; + } + } +} + +/** + * Registers plugins so that they can extract and dispatch events. + * + * @see {EventPluginHub} + */ + +/** + * Ordered list of injected plugins. + */ +var plugins = []; + +/** + * Mapping from event name to dispatch config + */ +var eventNameDispatchConfigs = {}; + +/** + * Mapping from registration name to plugin module + */ +var registrationNameModules = {}; + +/** + * Mapping from registration name to event name + */ +var 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} + */ +var 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} + */ +function injectEventPluginOrder(injectedEventPluginOrder) { + (function () { + if (!!eventPluginOrder) { + { + throw ReactError(Error('EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.')); + } + } + })(); + // 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} + */ +function injectEventPluginsByName(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) { + (function () { + if (!!namesToPlugins[pluginName]) { + { + throw ReactError(Error('EventPluginRegistry: Cannot inject two different event plugins using the same name, `' + pluginName + '`.')); + } + } + })(); + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = true; + } + } + if (isOrderingDirty) { + recomputePluginOrdering(); + } +} var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); @@ -101,7 +293,13 @@ var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) // when we call document.createEvent(). However this can cause confusing // errors: https://github.com/facebookincubator/create-react-app/issues/3482 // So we preemptively throw with a better message instead. - !(typeof document !== 'undefined') ? invariant(false, 'The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous.') : void 0; + (function () { + if (!(typeof document !== 'undefined')) { + { + throw ReactError(Error('The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous.')); + } + } + })(); var evt = document.createEvent('Event'); // Keeps track of whether the user-provided callback threw an error. We @@ -295,172 +493,13 @@ function clearCaughtError() { caughtError = null; 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.'); - } -} - -/** - * 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 (plugins[pluginIndex]) { - continue; - } - !pluginModule.extractEvents ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : void 0; - 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) { - !!eventNameDispatchConfigs.hasOwnProperty(eventName) ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : void 0; - 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); + (function () { + { + { + throw ReactError(Error('clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.')); + } } - } - 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) { - !!registrationNameModules[registrationName] ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : void 0; - registrationNameModules[registrationName] = pluginModule; - registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies; - - { - var lowerCasedName = registrationName.toLowerCase(); - possibleRegistrationNames[lowerCasedName] = registrationName; - - if (registrationName === 'onDoubleClick') { - possibleRegistrationNames.ondblclick = registrationName; - } - } -} - -/** - * Registers plugins so that they can extract and dispatch events. - * - * @see {EventPluginHub} - */ - -/** - * Ordered list of injected plugins. - */ -var plugins = []; - -/** - * Mapping from event name to dispatch config - */ -var eventNameDispatchConfigs = {}; - -/** - * Mapping from registration name to plugin module - */ -var registrationNameModules = {}; - -/** - * Mapping from registration name to event name - */ -var 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} - */ -var 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} - */ -function injectEventPluginOrder(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} - */ -function injectEventPluginsByName(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(); + })(); } } @@ -615,7 +654,13 @@ function executeDispatchesInOrder(event) { */ function accumulateInto(current, next) { - !(next != null) ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : void 0; + (function () { + if (!(next != null)) { + { + throw ReactError(Error('accumulateInto(...): Accumulated items must not be null or undefined.')); + } + } + })(); if (current == null) { return next; @@ -682,6 +727,32 @@ var executeDispatchesAndReleaseTopLevel = function (e) { return executeDispatchesAndRelease(e); }; +function runEventsInBatch(events) { + if (events !== null) { + eventQueue = accumulateInto(eventQueue, events); + } + + // 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 (!processingEventQueue) { + return; + } + + forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); + (function () { + if (!!eventQueue) { + { + throw ReactError(Error('processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.')); + } + } + })(); + // This would be a good time to rethrow if any of the event handlers threw. + rethrowCaughtError(); +} + function isInteractive(tag) { return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea'; } @@ -767,7 +838,13 @@ function getListener(inst, registrationName) { if (shouldPreventMouseEvent(registrationName, inst.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; + (function () { + if (!(!listener || typeof listener === 'function')) { + { + throw ReactError(Error('Expected `' + registrationName + '` listener to be a function, instead got a value of `' + typeof listener + '` type.')); + } + } + })(); return listener; } @@ -778,7 +855,7 @@ function getListener(inst, registrationName) { * @return {*} An accumulation of synthetic events. * @internal */ -function extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) { +function extractPluginEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) { var events = null; for (var i = 0; i < plugins.length; i++) { // Not every plugin in the ordering may be loaded at runtime. @@ -793,28 +870,8 @@ function extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) return events; } -function runEventsInBatch(events) { - if (events !== null) { - eventQueue = accumulateInto(eventQueue, events); - } - - // 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 (!processingEventQueue) { - return; - } - - forEachAccumulated(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. - rethrowCaughtError(); -} - -function runExtractedEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) { - var events = extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); +function runExtractedPluginEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) { + var events = extractPluginEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); runEventsInBatch(events); } @@ -837,6 +894,8 @@ var SimpleMemoComponent = 15; var LazyComponent = 16; var IncompleteClassComponent = 17; var DehydratedSuspenseComponent = 18; +var SuspenseListComponent = 19; +var FundamentalComponent = 20; var randomKey = Math.random().toString(36).slice(2); var internalInstanceKey = '__reactInternalInstance$' + randomKey; @@ -903,7 +962,13 @@ function getNodeFromInstance$1(inst) { // Without this first invariant, passing a non-DOM-component triggers the next // invariant for a missing parent, which is super confusing. - invariant(false, 'getNodeFromInstance: Invalid argument.'); + (function () { + { + { + throw ReactError(Error('getNodeFromInstance: Invalid argument.')); + } + } + })(); } function getFiberCurrentPropsFromNode$1(node) { @@ -1132,9 +1197,9 @@ function accumulateDirectDispatches(events) { forEachAccumulated(events, accumulateDirectDispatchesSingle); } -var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); +var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined'); -// Do not uses the below two methods directly! +// Do not use the below two methods directly! // Instead use constants exported from DOMTopLevelEventTypes in ReactDOM. // (It is the only module that is allowed to access these methods.) @@ -1645,7 +1710,13 @@ function getPooledEvent(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; + (function () { + if (!(event instanceof EventConstructor)) { + { + throw ReactError(Error('Trying to release an event instance into a pool of a different type.')); + } + } + })(); event.destructor(); if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { EventConstructor.eventPool.push(event); @@ -2080,7 +2151,13 @@ function restoreStateOfTarget(target) { // Unmounted return; } - !(typeof restoreImpl === 'function') ? invariant(false, 'setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue.') : void 0; + (function () { + if (!(typeof restoreImpl === 'function')) { + { + throw ReactError(Error('setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue.')); + } + } + })(); var props = getFiberCurrentPropsFromNode(internalInstance.stateNode); restoreImpl(internalInstance.stateNode, internalInstance.type, props); } @@ -2122,6 +2199,94 @@ function restoreStateIfNeeded() { } } +var enableUserTimingAPI = true; + +// Helps identify side effects in begin-phase lifecycle hooks and setState reducers: +var debugRenderPhaseSideEffects = false; + +// In some cases, StrictMode should also double-render lifecycles. +// This can be confusing for tests though, +// And it can be bad for performance in production. +// This feature flag can be used to control the behavior: +var debugRenderPhaseSideEffectsForStrictMode = true; + +// To preserve the "Pause on caught exceptions" behavior of the debugger, we +// replay the begin phase of a failed component inside invokeGuardedCallback. +var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; + +// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6: +var warnAboutDeprecatedLifecycles = true; + +// Gather advanced timing metrics for Profiler subtrees. +var enableProfilerTimer = true; + +// Trace which interactions trigger each commit. +var enableSchedulerTracing = true; + +// Only used in www builds. +var enableSuspenseServerRenderer = false; // TODO: true? Here it might just be false. + +// Only used in www builds. + + +// Only used in www builds. + + +// Disable javascript: URL strings in href for XSS protection. +var disableJavaScriptURLs = false; + +// React Fire: prevent the value and checked attributes from syncing +// with their related DOM properties +var disableInputAttributeSyncing = false; + +// These APIs will no longer be "unstable" in the upcoming 16.7 release, +// Control this behavior with a flag to support 16.6 minor releases in the meanwhile. +var enableStableConcurrentModeAPIs = false; + +var warnAboutShorthandPropertyCollision = false; + +// See https://github.com/react-native-community/discussions-and-proposals/issues/72 for more information +// This is a flag so we can fix warnings in RN core before turning it on + + +// Experimental React Flare event system and event components support. +var enableFlareAPI = false; + +// Experimental Host Component support. +var enableFundamentalAPI = false; + +// New API for JSX transforms to target - https://github.com/reactjs/rfcs/pull/107 + + +// We will enforce mocking scheduler with scheduler/unstable_mock at some point. (v17?) +// Till then, we warn about the missing mock, but still fallback to a sync mode compatible version +var warnAboutUnmockedScheduler = false; +// Temporary flag to revert the fix in #15650 +var revertPassiveEffectsChange = false; + +// For tests, we flush suspense fallbacks in an act scope; +// *except* in some of our own tests, where we test incremental loading states. +var flushSuspenseFallbacksInTests = true; + +// Changes priority of some events like mousemove to user-blocking priority, +// but without making them discrete. The flag exists in case it causes +// starvation problems. +var enableUserBlockingEvents = false; + +// Add a callback property to suspense to notify which promises are currently +// in the update queue. This allows reporting and tracing of what is causing +// the user to see a loading state. +var enableSuspenseCallback = false; + +// Part of the simplification of React.createElement so we can eventually move +// from React.createElement to React.jsx +// https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md +var warnAboutDefaultPropsOnFunctionComponents = false; + +var disableLegacyContext = false; + +var disableSchedulerTimeoutBasedOnReactExpirationTime = false; + // Used as a way to call batchedUpdates when we don't have a reference to // the renderer. Such as when we're dispatching events or if third party // libraries need to call batchedUpdates. Eventually, this API will go away when @@ -2129,51 +2294,100 @@ function restoreStateIfNeeded() { // scheduled work and instead do synchronous work. // Defaults -var _batchedUpdatesImpl = function (fn, bookkeeping) { +var batchedUpdatesImpl = function (fn, bookkeeping) { return fn(bookkeeping); }; -var _interactiveUpdatesImpl = function (fn, a, b) { - return fn(a, b); +var discreteUpdatesImpl = function (fn, a, b, c) { + return fn(a, b, c); }; -var _flushInteractiveUpdatesImpl = function () {}; +var flushDiscreteUpdatesImpl = function () {}; +var batchedEventUpdatesImpl = batchedUpdatesImpl; + +var isInsideEventHandler = false; + +function finishEventHandler() { + // Here we wait until all updates have propagated, which is important + // when using controlled components within layers: + // https://github.com/facebook/react/issues/1698 + // Then we restore state of any controlled component. + var controlledComponentsHavePendingUpdates = needsStateRestore(); + if (controlledComponentsHavePendingUpdates) { + // If a controlled event was fired, we may need to restore the state of + // the DOM node back to the controlled value. This is necessary when React + // bails out of the update without touching the DOM. + flushDiscreteUpdatesImpl(); + restoreStateIfNeeded(); + } +} -var isBatching = false; function batchedUpdates(fn, bookkeeping) { - if (isBatching) { + if (isInsideEventHandler) { // If we are currently inside another batch, we need to wait until it // fully completes before restoring state. return fn(bookkeeping); } - isBatching = true; + isInsideEventHandler = true; try { - return _batchedUpdatesImpl(fn, bookkeeping); + return batchedUpdatesImpl(fn, bookkeeping); } finally { - // Here we wait until all updates have propagated, which is important - // when using controlled components within layers: - // https://github.com/facebook/react/issues/1698 - // Then we restore state of any controlled component. - isBatching = false; - var controlledComponentsHavePendingUpdates = needsStateRestore(); - if (controlledComponentsHavePendingUpdates) { - // If a controlled event was fired, we may need to restore the state of - // the DOM node back to the controlled value. This is necessary when React - // bails out of the update without touching the DOM. - _flushInteractiveUpdatesImpl(); - restoreStateIfNeeded(); + isInsideEventHandler = false; + finishEventHandler(); + } +} + +function batchedEventUpdates(fn, a, b) { + if (isInsideEventHandler) { + // If we are currently inside another batch, we need to wait until it + // fully completes before restoring state. + return fn(a, b); + } + isInsideEventHandler = true; + try { + return batchedEventUpdatesImpl(fn, a, b); + } finally { + isInsideEventHandler = false; + finishEventHandler(); + } +} + +function discreteUpdates(fn, a, b, c) { + var prevIsInsideEventHandler = isInsideEventHandler; + isInsideEventHandler = true; + try { + return discreteUpdatesImpl(fn, a, b, c); + } finally { + isInsideEventHandler = prevIsInsideEventHandler; + if (!isInsideEventHandler) { + finishEventHandler(); } } } -function interactiveUpdates(fn, a, b) { - return _interactiveUpdatesImpl(fn, a, b); +var lastFlushedEventTimeStamp = 0; +function flushDiscreteUpdatesIfNeeded(timeStamp) { + // event.timeStamp isn't overly reliable due to inconsistencies in + // how different browsers have historically provided the time stamp. + // Some browsers provide high-resolution time stamps for all events, + // some provide low-resolution time stamps for all events. FF < 52 + // even mixes both time stamps together. Some browsers even report + // negative time stamps or time stamps that are 0 (iOS9) in some cases. + // Given we are only comparing two time stamps with equality (!==), + // we are safe from the resolution differences. If the time stamp is 0 + // we bail-out of preventing the flush, which can affect semantics, + // such as if an earlier flush removes or adds event listeners that + // are fired in the subsequent flush. However, this is the same + // behaviour as we had before this change, so the risks are low. + if (!isInsideEventHandler && (!enableFlareAPI || timeStamp === 0 || lastFlushedEventTimeStamp !== timeStamp)) { + lastFlushedEventTimeStamp = timeStamp; + flushDiscreteUpdatesImpl(); + } } - - -function setBatchingImplementation(batchedUpdatesImpl, interactiveUpdatesImpl, flushInteractiveUpdatesImpl) { - _batchedUpdatesImpl = batchedUpdatesImpl; - _interactiveUpdatesImpl = interactiveUpdatesImpl; - _flushInteractiveUpdatesImpl = flushInteractiveUpdatesImpl; +function setBatchingImplementation(_batchedUpdatesImpl, _discreteUpdatesImpl, _flushDiscreteUpdatesImpl, _batchedEventUpdatesImpl) { + batchedUpdatesImpl = _batchedUpdatesImpl; + discreteUpdatesImpl = _discreteUpdatesImpl; + flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl; + batchedEventUpdatesImpl = _batchedEventUpdatesImpl; } /** @@ -2391,6 +2605,11 @@ if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) { current: null }; } +if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) { + ReactSharedInternals.ReactCurrentBatchConfig = { + suspense: null + }; +} var BEFORE_SLASH_RE = /^(.*)[\\\/]/; @@ -2431,12 +2650,17 @@ var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeac var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2; var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd; var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; +// TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary +// (unstable) APIs that have been removed. Can we remove the symbols? var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf; var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0; var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1; +var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8; var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3; var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4; +var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5; +var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6; var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; var FAUX_ITERATOR_SYMBOL = '@@iterator'; @@ -2482,8 +2706,6 @@ function getComponentName(type) { return type; } switch (type) { - case REACT_CONCURRENT_MODE_TYPE: - return 'ConcurrentMode'; case REACT_FRAGMENT_TYPE: return 'Fragment'; case REACT_PORTAL_TYPE: @@ -2494,6 +2716,8 @@ function getComponentName(type) { return 'StrictMode'; case REACT_SUSPENSE_TYPE: return 'Suspense'; + case REACT_SUSPENSE_LIST_TYPE: + return 'SuspenseList'; } if (typeof type === 'object') { switch (type.$$typeof) { @@ -2512,6 +2736,7 @@ function getComponentName(type) { if (resolvedThenable) { return getComponentName(resolvedThenable); } + break; } } } @@ -2762,13 +2987,14 @@ function getPropertyInfo(name) { return properties.hasOwnProperty(name) ? properties[name] : null; } -function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace) { +function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL) { this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN; this.attributeName = attributeName; this.attributeNamespace = attributeNamespace; this.mustUseProperty = mustUseProperty; this.propertyName = name; this.type = type; + this.sanitizeURL = sanitizeURL; } // When adding attributes to this list, be sure to also add them to @@ -2784,8 +3010,9 @@ var properties = {}; 'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) { properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty name, // attributeName - null); -} // attributeNamespace + null, // attributeNamespace + false); +} // sanitizeURL ); // A few React string attributes have a different name. @@ -2796,8 +3023,9 @@ var properties = {}; properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty attributeName, // attributeName - null); -} // attributeNamespace + null, // attributeNamespace + false); +} // sanitizeURL ); // These are "enumerated" HTML attributes that accept "true" and "false". @@ -2806,8 +3034,9 @@ var properties = {}; ['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) { properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty name.toLowerCase(), // attributeName - null); -} // attributeNamespace + null, // attributeNamespace + false); +} // sanitizeURL ); // These are "enumerated" SVG attributes that accept "true" and "false". @@ -2817,21 +3046,23 @@ var properties = {}; ['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) { properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty name, // attributeName - null); -} // attributeNamespace + null, // attributeNamespace + false); +} // sanitizeURL ); // These are HTML boolean attributes. ['allowFullScreen', 'async', // Note: there is a special case that prevents it from being written to the DOM // on the client side because the browsers are inconsistent. Instead we call focus(). -'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', +'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', // Microdata 'itemScope'].forEach(function (name) { properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty name.toLowerCase(), // attributeName - null); -} // attributeNamespace + null, // attributeNamespace + false); +} // sanitizeURL ); // These are the few React props that we set as DOM properties @@ -2842,8 +3073,9 @@ var properties = {}; 'multiple', 'muted', 'selected'].forEach(function (name) { properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty name, // attributeName - null); -} // attributeNamespace + null, // attributeNamespace + false); +} // sanitizeURL ); // These are HTML attributes that are "overloaded booleans": they behave like @@ -2851,24 +3083,27 @@ var properties = {}; ['capture', 'download'].forEach(function (name) { properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty name, // attributeName - null); -} // attributeNamespace + null, // attributeNamespace + false); +} // sanitizeURL ); // These are HTML attributes that must be positive numbers. ['cols', 'rows', 'size', 'span'].forEach(function (name) { properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty name, // attributeName - null); -} // attributeNamespace + null, // attributeNamespace + false); +} // sanitizeURL ); // These are HTML attributes that must be numbers. ['rowSpan', 'start'].forEach(function (name) { properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty name.toLowerCase(), // attributeName - null); -} // attributeNamespace + null, // attributeNamespace + false); +} // sanitizeURL ); var CAMELIZE = /[\-\:]([a-z])/g; @@ -2884,23 +3119,26 @@ var capitalize = function (token) { ['accent-height', 'alignment-baseline', 'arabic-form', 'baseline-shift', 'cap-height', 'clip-path', 'clip-rule', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'dominant-baseline', 'enable-background', 'fill-opacity', 'fill-rule', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-name', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'horiz-adv-x', 'horiz-origin-x', 'image-rendering', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start', 'overline-position', 'overline-thickness', 'paint-order', 'panose-1', 'pointer-events', 'rendering-intent', 'shape-rendering', 'stop-color', 'stop-opacity', 'strikethrough-position', 'strikethrough-thickness', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-decoration', 'text-rendering', 'underline-position', 'underline-thickness', 'unicode-bidi', 'unicode-range', 'units-per-em', 'v-alphabetic', 'v-hanging', 'v-ideographic', 'v-mathematical', 'vector-effect', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'word-spacing', 'writing-mode', 'xmlns:xlink', 'x-height'].forEach(function (attributeName) { var name = attributeName.replace(CAMELIZE, capitalize); properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty - attributeName, null); -} // attributeNamespace + attributeName, null, // attributeNamespace + false); +} // sanitizeURL ); // String SVG attributes with the xlink namespace. -['xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) { +['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) { var name = attributeName.replace(CAMELIZE, capitalize); properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty - attributeName, 'http://www.w3.org/1999/xlink'); -}); + attributeName, 'http://www.w3.org/1999/xlink', false); +} // sanitizeURL +); // String SVG attributes with the xml namespace. ['xml:base', 'xml:lang', 'xml:space'].forEach(function (attributeName) { var name = attributeName.replace(CAMELIZE, capitalize); properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty - attributeName, 'http://www.w3.org/XML/1998/namespace'); -}); + attributeName, 'http://www.w3.org/XML/1998/namespace', false); +} // sanitizeURL +); // These attribute exists both in HTML and SVG. // The attribute name is case-sensitive in SVG so we can't just use @@ -2908,10 +3146,59 @@ var capitalize = function (token) { ['tabIndex', 'crossOrigin'].forEach(function (attributeName) { properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty attributeName.toLowerCase(), // attributeName - null); -} // attributeNamespace + null, // attributeNamespace + false); +} // sanitizeURL ); +// These attributes accept URLs. These must not allow javascript: URLS. +// These will also need to accept Trusted Types object in the future. +var xlinkHref = 'xlinkHref'; +properties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty +'xlink:href', 'http://www.w3.org/1999/xlink', true); + +['src', 'href', 'action', 'formAction'].forEach(function (attributeName) { + properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty + attributeName.toLowerCase(), // attributeName + null, // attributeNamespace + true); +} // sanitizeURL +); + +var ReactDebugCurrentFrame$1 = null; +{ + ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame; +} + +// A javascript: URL can contain leading C0 control or \u0020 SPACE, +// and any newline or tab are filtered out as if they're not part of the URL. +// https://url.spec.whatwg.org/#url-parsing +// Tab or newline are defined as \r\n\t: +// https://infra.spec.whatwg.org/#ascii-tab-or-newline +// A C0 control is a code point in the range \u0000 NULL to \u001F +// INFORMATION SEPARATOR ONE, inclusive: +// https://infra.spec.whatwg.org/#c0-control-or-space + +/* eslint-disable max-len */ +var isJavaScriptProtocol = /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i; + +var didWarn = false; + +function sanitizeURL(url) { + if (disableJavaScriptURLs) { + (function () { + if (!!isJavaScriptProtocol.test(url)) { + { + throw ReactError(Error('React has blocked a javascript: URL as a security precaution.' + (ReactDebugCurrentFrame$1.getStackAddendum()))); + } + } + })(); + } else if (true && !didWarn && isJavaScriptProtocol.test(url)) { + didWarn = true; + warning$1(false, 'A future version of React will block javascript: URLs as a security precaution. ' + 'Use event handlers instead if you can. If you need to generate unsafe HTML try ' + 'using dangerouslySetInnerHTML instead. React was passed %s.', JSON.stringify(url)); + } +} + /** * Get the value for a property on a node. Only used in DEV for SSR validation. * The "expected" argument is used as a hint of what the expected value is. @@ -2924,6 +3211,13 @@ function getValueForProperty(node, name, expected, propertyInfo) { return node[propertyName]; } else { + if (!disableJavaScriptURLs && propertyInfo.sanitizeURL) { + // If we haven't fully disabled javascript: URLs, and if + // the hydration is successful of a javascript: URL, we + // still want to warn on the client. + sanitizeURL('' + expected); + } + var attributeName = propertyInfo.attributeName; var stringValue = null; @@ -3051,6 +3345,9 @@ function setValueForProperty(node, name, value, isCustomComponentTag) { // `setAttribute` with objects becomes only `[object]` in IE8/9, // ('' + value) makes it output the correct toString()-value. attributeValue = '' + value; + if (propertyInfo.sanitizeURL) { + sanitizeURL(attributeValue); + } } if (attributeNamespace) { node.setAttributeNS(attributeNamespace, attributeName, attributeValue); @@ -3186,14 +3483,14 @@ function checkPropTypes(typeSpecs, values, location, componentName, getStack) { var checkPropTypes_1 = checkPropTypes; -var ReactDebugCurrentFrame$1 = null; +var ReactDebugCurrentFrame$2 = null; var ReactControlledValuePropTypes = { checkPropTypes: null }; { - ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame; + ReactDebugCurrentFrame$2 = ReactSharedInternals.ReactDebugCurrentFrame; var hasReadOnlyValue = { button: true, @@ -3207,13 +3504,13 @@ var ReactControlledValuePropTypes = { var propTypes = { value: function (props, propName, componentName) { - if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null) { + if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null || enableFlareAPI && props.listeners) { return null; } return new Error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.'); }, checked: function (props, propName, componentName) { - if (props.onChange || props.readOnly || props.disabled || props[propName] == null) { + if (props.onChange || props.readOnly || props.disabled || props[propName] == null || enableFlareAPI && props.listeners) { return null; } return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.'); @@ -3225,53 +3522,10 @@ var ReactControlledValuePropTypes = { * this outside of the ReactDOM controlled form components. */ ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) { - checkPropTypes_1(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$1.getStackAddendum); + checkPropTypes_1(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$2.getStackAddendum); }; } -var enableUserTimingAPI = true; - -// Helps identify side effects in begin-phase lifecycle hooks and setState reducers: -var debugRenderPhaseSideEffects = false; - -// In some cases, StrictMode should also double-render lifecycles. -// This can be confusing for tests though, -// And it can be bad for performance in production. -// This feature flag can be used to control the behavior: -var debugRenderPhaseSideEffectsForStrictMode = true; - -// To preserve the "Pause on caught exceptions" behavior of the debugger, we -// replay the begin phase of a failed component inside invokeGuardedCallback. -var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; - -// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6: -var warnAboutDeprecatedLifecycles = false; - -// Gather advanced timing metrics for Profiler subtrees. -var enableProfilerTimer = true; - -// Trace which interactions trigger each commit. -var enableSchedulerTracing = true; - -// Only used in www builds. -var enableSuspenseServerRenderer = false; // TODO: true? Here it might just be false. - -// Only used in www builds. - - -// Only used in www builds. - - -// React Fire: prevent the value and checked attributes from syncing -// with their related DOM properties -var disableInputAttributeSyncing = false; - -// These APIs will no longer be "unstable" in the upcoming 16.7 release, -// Control this behavior with a flag to support 16.6 minor releases in the meanwhile. -var enableStableConcurrentModeAPIs = false; - -var warnAboutShorthandPropertyCollision = false; - // TODO: direct imports like some-package/src/* are bad. Fix me. var didWarnValueDefaultValue = false; var didWarnCheckedDefaultChecked = false; @@ -3564,7 +3818,13 @@ function updateNamedCousins(rootNode, props) { // That's probably okay; we don't support it just as we don't support // mixing React radio buttons with non-React ones. var otherProps = getFiberCurrentPropsFromNode$1(otherNode); - !otherProps ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : void 0; + (function () { + if (!otherProps) { + { + throw ReactError(Error('ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.')); + } + } + })(); // We need update the tracked value on the named cousin since the value // was changed but the input saw no event or value set @@ -4107,6 +4367,756 @@ function shallowEqual(objA, objB) { return true; } +var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; + +var _ReactInternals$Sched = ReactInternals$1.Scheduler; +var unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback; +var unstable_now = _ReactInternals$Sched.unstable_now; +var unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback; +var unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield; +var unstable_requestPaint = _ReactInternals$Sched.unstable_requestPaint; +var unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode; +var unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority; +var unstable_next = _ReactInternals$Sched.unstable_next; +var unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution; +var unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution; +var unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel; +var unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority; +var unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority; +var unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority; +var unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority; +var unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority; +var unstable_forceFrameRate = _ReactInternals$Sched.unstable_forceFrameRate; +var unstable_flushAllWithoutAsserting = _ReactInternals$Sched.unstable_flushAllWithoutAsserting; + +var PLUGIN_EVENT_SYSTEM = 1; +var RESPONDER_EVENT_SYSTEM = 1 << 1; +var IS_PASSIVE = 1 << 2; +var IS_ACTIVE = 1 << 3; +var PASSIVE_NOT_SUPPORTED = 1 << 4; + +function createResponderListener(responder, props) { + var eventResponderListener = { + responder: responder, + props: props + }; + { + Object.freeze(eventResponderListener); + } + return eventResponderListener; +} + +function isFiberSuspenseAndTimedOut(fiber) { + return fiber.tag === SuspenseComponent && fiber.memoizedState !== null; +} + +function getSuspenseFallbackChild(fiber) { + return fiber.child.sibling.child; +} + + + + + +function createResponderInstance(responder, responderProps, responderState, target, fiber) { + return { + fiber: fiber, + props: responderProps, + responder: responder, + rootEventTypes: null, + state: responderState, + target: target + }; +} + +var DiscreteEvent = 0; +var UserBlockingEvent = 1; +var ContinuousEvent = 2; + +// Intentionally not named imports because Rollup would use dynamic dispatch for +// CommonJS interop named imports. +var UserBlockingPriority$1 = unstable_UserBlockingPriority; +var runWithPriority$1 = unstable_runWithPriority; + + +var listenToResponderEventTypesImpl = void 0; + +function setListenToResponderEventTypes(_listenToResponderEventTypesImpl) { + listenToResponderEventTypesImpl = _listenToResponderEventTypesImpl; +} + +var activeTimeouts = new Map(); +var rootEventTypesToEventResponderInstances = new Map(); +var ownershipChangeListeners = new Set(); + +var globalOwner = null; + +var currentTimeStamp = 0; +var currentTimers = new Map(); +var currentInstance = null; +var currentEventQueue = null; +var currentEventQueuePriority = ContinuousEvent; +var currentTimerIDCounter = 0; +var currentDocument = null; + +var eventResponderContext = { + dispatchEvent: function (eventValue, eventListener, eventPriority) { + validateResponderContext(); + validateEventValue(eventValue); + if (eventPriority < currentEventQueuePriority) { + currentEventQueuePriority = eventPriority; + } + currentEventQueue.push(createEventQueueItem(eventValue, eventListener)); + }, + isTargetWithinResponder: function (target) { + validateResponderContext(); + if (target != null) { + var fiber = getClosestInstanceFromNode(target); + var responderFiber = currentInstance.fiber; + + while (fiber !== null) { + if (fiber === responderFiber || fiber.alternate === responderFiber) { + return true; + } + fiber = fiber.return; + } + } + return false; + }, + isTargetWithinResponderScope: function (target) { + validateResponderContext(); + var componentInstance = currentInstance; + var responder = componentInstance.responder; + + if (target != null) { + var fiber = getClosestInstanceFromNode(target); + var responderFiber = currentInstance.fiber; + + while (fiber !== null) { + if (fiber === responderFiber || fiber.alternate === responderFiber) { + return true; + } + if (doesFiberHaveResponder(fiber, responder)) { + return false; + } + fiber = fiber.return; + } + } + return false; + }, + isTargetWithinNode: function (childTarget, parentTarget) { + validateResponderContext(); + var childFiber = getClosestInstanceFromNode(childTarget); + var parentFiber = getClosestInstanceFromNode(parentTarget); + var parentAlternateFiber = parentFiber.alternate; + + var node = childFiber; + while (node !== null) { + if (node === parentFiber || node === parentAlternateFiber) { + return true; + } + node = node.return; + } + return false; + }, + addRootEventTypes: function (rootEventTypes) { + validateResponderContext(); + var activeDocument = getActiveDocument(); + listenToResponderEventTypesImpl(rootEventTypes, activeDocument); + for (var i = 0; i < rootEventTypes.length; i++) { + var rootEventType = rootEventTypes[i]; + var eventResponderInstance = currentInstance; + registerRootEventType(rootEventType, eventResponderInstance); + } + }, + removeRootEventTypes: function (rootEventTypes) { + validateResponderContext(); + for (var i = 0; i < rootEventTypes.length; i++) { + var rootEventType = rootEventTypes[i]; + var rootEventResponders = rootEventTypesToEventResponderInstances.get(rootEventType); + var rootEventTypesSet = currentInstance.rootEventTypes; + if (rootEventTypesSet !== null) { + rootEventTypesSet.delete(rootEventType); + } + if (rootEventResponders !== undefined) { + rootEventResponders.delete(currentInstance); + } + } + }, + hasOwnership: function () { + validateResponderContext(); + return globalOwner === currentInstance; + }, + requestGlobalOwnership: function () { + validateResponderContext(); + if (globalOwner !== null) { + return false; + } + globalOwner = currentInstance; + triggerOwnershipListeners(); + return true; + }, + releaseOwnership: function () { + validateResponderContext(); + return releaseOwnershipForEventResponderInstance(currentInstance); + }, + setTimeout: function (func, delay) { + validateResponderContext(); + if (currentTimers === null) { + currentTimers = new Map(); + } + var timeout = currentTimers.get(delay); + + var timerId = currentTimerIDCounter++; + if (timeout === undefined) { + var _timers = new Map(); + var _id = setTimeout(function () { + processTimers(_timers, delay); + }, delay); + timeout = { + id: _id, + timers: _timers + }; + currentTimers.set(delay, timeout); + } + timeout.timers.set(timerId, { + instance: currentInstance, + func: func, + id: timerId, + timeStamp: currentTimeStamp + }); + activeTimeouts.set(timerId, timeout); + return timerId; + }, + clearTimeout: function (timerId) { + validateResponderContext(); + var timeout = activeTimeouts.get(timerId); + + if (timeout !== undefined) { + var _timers2 = timeout.timers; + _timers2.delete(timerId); + if (_timers2.size === 0) { + clearTimeout(timeout.id); + } + } + }, + getFocusableElementsInScope: function (deep) { + validateResponderContext(); + var focusableElements = []; + var eventResponderInstance = currentInstance; + var currentResponder = eventResponderInstance.responder; + var focusScopeFiber = eventResponderInstance.fiber; + if (deep) { + var deepNode = focusScopeFiber.return; + while (deepNode !== null) { + if (doesFiberHaveResponder(deepNode, currentResponder)) { + focusScopeFiber = deepNode; + } + deepNode = deepNode.return; + } + } + var child = focusScopeFiber.child; + + if (child !== null) { + collectFocusableElements(child, focusableElements); + } + return focusableElements; + }, + + getActiveDocument: getActiveDocument, + objectAssign: _assign, + getTimeStamp: function () { + validateResponderContext(); + return currentTimeStamp; + }, + isTargetWithinHostComponent: function (target, elementType) { + validateResponderContext(); + var fiber = getClosestInstanceFromNode(target); + + while (fiber !== null) { + if (fiber.tag === HostComponent && fiber.type === elementType) { + return true; + } + fiber = fiber.return; + } + return false; + }, + + enqueueStateRestore: enqueueStateRestore +}; + +function validateEventValue(eventValue) { + if (typeof eventValue === 'object' && eventValue !== null) { + var target = eventValue.target, + type = eventValue.type, + _timeStamp = eventValue.timeStamp; + + + if (target == null || type == null || _timeStamp == null) { + throw new Error('context.dispatchEvent: "target", "timeStamp", and "type" fields on event object are required.'); + } + var showWarning = function (name) { + { + warning$1(false, '%s is not available on event objects created from event responder modules (React Flare). ' + 'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.%s }`', name, name); + } + }; + eventValue.preventDefault = function () { + { + showWarning('preventDefault()'); + } + }; + eventValue.stopPropagation = function () { + { + showWarning('stopPropagation()'); + } + }; + eventValue.isDefaultPrevented = function () { + { + showWarning('isDefaultPrevented()'); + } + }; + eventValue.isPropagationStopped = function () { + { + showWarning('isPropagationStopped()'); + } + }; + // $FlowFixMe: we don't need value, Flow thinks we do + Object.defineProperty(eventValue, 'nativeEvent', { + get: function () { + { + showWarning('nativeEvent'); + } + } + }); + } +} + +function collectFocusableElements(node, focusableElements) { + if (isFiberSuspenseAndTimedOut(node)) { + var fallbackChild = getSuspenseFallbackChild(node); + if (fallbackChild !== null) { + collectFocusableElements(fallbackChild, focusableElements); + } + } else { + if (isFiberHostComponentFocusable(node)) { + focusableElements.push(node.stateNode); + } else { + var child = node.child; + + if (child !== null) { + collectFocusableElements(child, focusableElements); + } + } + } + var sibling = node.sibling; + + if (sibling !== null) { + collectFocusableElements(sibling, focusableElements); + } +} + +function createEventQueueItem(value, listener) { + return { + value: value, + listener: listener + }; +} + +function doesFiberHaveResponder(fiber, responder) { + if (fiber.tag === HostComponent) { + var dependencies = fiber.dependencies; + if (dependencies !== null) { + var respondersMap = dependencies.responders; + if (respondersMap !== null && respondersMap.has(responder)) { + return true; + } + } + } + return false; +} + +function getActiveDocument() { + return currentDocument; +} + +function releaseOwnershipForEventResponderInstance(eventResponderInstance) { + if (globalOwner === eventResponderInstance) { + globalOwner = null; + triggerOwnershipListeners(); + return true; + } + return false; +} + +function isFiberHostComponentFocusable(fiber) { + if (fiber.tag !== HostComponent) { + return false; + } + var type = fiber.type, + memoizedProps = fiber.memoizedProps; + + if (memoizedProps.tabIndex === -1 || memoizedProps.disabled) { + return false; + } + if (memoizedProps.tabIndex === 0 || memoizedProps.contentEditable === true) { + return true; + } + if (type === 'a' || type === 'area') { + return !!memoizedProps.href && memoizedProps.rel !== 'ignore'; + } + if (type === 'input') { + return memoizedProps.type !== 'hidden' && memoizedProps.type !== 'file'; + } + return type === 'button' || type === 'textarea' || type === 'object' || type === 'select' || type === 'iframe' || type === 'embed'; +} + +function processTimers(timers, delay) { + var timersArr = Array.from(timers.values()); + currentEventQueuePriority = ContinuousEvent; + try { + for (var i = 0; i < timersArr.length; i++) { + var _timersArr$i = timersArr[i], + _instance = _timersArr$i.instance, + _func = _timersArr$i.func, + _id2 = _timersArr$i.id, + _timeStamp2 = _timersArr$i.timeStamp; + + currentInstance = _instance; + currentEventQueue = []; + currentTimeStamp = _timeStamp2 + delay; + try { + _func(); + } finally { + activeTimeouts.delete(_id2); + } + } + processEventQueue(); + } finally { + currentTimers = null; + currentInstance = null; + currentEventQueue = null; + currentTimeStamp = 0; + } +} + +function createDOMResponderEvent(topLevelType, nativeEvent, nativeEventTarget, passive, passiveSupported) { + var _ref = nativeEvent, + pointerType = _ref.pointerType; + + var eventPointerType = ''; + var pointerId = null; + + if (pointerType !== undefined) { + eventPointerType = pointerType; + pointerId = nativeEvent.pointerId; + } else if (nativeEvent.key !== undefined) { + eventPointerType = 'keyboard'; + } else if (nativeEvent.button !== undefined) { + eventPointerType = 'mouse'; + } else if (nativeEvent.changedTouches !== undefined) { + eventPointerType = 'touch'; + } + + return { + nativeEvent: nativeEvent, + passive: passive, + passiveSupported: passiveSupported, + pointerId: pointerId, + pointerType: eventPointerType, + responderTarget: null, + target: nativeEventTarget, + type: topLevelType + }; +} + +function processEvents(eventQueue) { + for (var i = 0, length = eventQueue.length; i < length; i++) { + var _eventQueue$i = eventQueue[i], + _value = _eventQueue$i.value, + _listener = _eventQueue$i.listener; + + var type = typeof _value === 'object' && _value !== null ? _value.type : ''; + invokeGuardedCallbackAndCatchFirstError(type, _listener, undefined, _value); + } +} + +function processEventQueue() { + var eventQueue = currentEventQueue; + if (eventQueue.length === 0) { + return; + } + switch (currentEventQueuePriority) { + case DiscreteEvent: + { + flushDiscreteUpdatesIfNeeded(currentTimeStamp); + discreteUpdates(function () { + batchedEventUpdates(processEvents, eventQueue); + }); + break; + } + case UserBlockingEvent: + { + if (enableUserBlockingEvents) { + runWithPriority$1(UserBlockingPriority$1, batchedEventUpdates.bind(null, processEvents, eventQueue)); + } else { + batchedEventUpdates(processEvents, eventQueue); + } + break; + } + case ContinuousEvent: + { + batchedEventUpdates(processEvents, eventQueue); + break; + } + } +} + +function responderEventTypesContainType(eventTypes, type) { + for (var i = 0, len = eventTypes.length; i < len; i++) { + if (eventTypes[i] === type) { + return true; + } + } + return false; +} + +function validateResponderTargetEventTypes(eventType, responder) { + var targetEventTypes = responder.targetEventTypes; + // Validate the target event type exists on the responder + + if (targetEventTypes !== null) { + return responderEventTypesContainType(targetEventTypes, eventType); + } + return false; +} + +function validateOwnership(responderInstance) { + return globalOwner === null || globalOwner === responderInstance; +} + +function traverseAndHandleEventResponderInstances(topLevelType, targetFiber, nativeEvent, nativeEventTarget, eventSystemFlags) { + var isPassiveEvent = (eventSystemFlags & IS_PASSIVE) !== 0; + var isPassiveSupported = (eventSystemFlags & PASSIVE_NOT_SUPPORTED) === 0; + var isPassive = isPassiveEvent || !isPassiveSupported; + var eventType = isPassive ? topLevelType : topLevelType + '_active'; + + // Trigger event responders in this order: + // - Bubble target responder phase + // - Root responder phase + + var visitedResponders = new Set(); + var responderEvent = createDOMResponderEvent(topLevelType, nativeEvent, nativeEventTarget, isPassiveEvent, isPassiveSupported); + var node = targetFiber; + while (node !== null) { + var _node = node, + dependencies = _node.dependencies, + tag = _node.tag; + + if (tag === HostComponent && dependencies !== null) { + var respondersMap = dependencies.responders; + if (respondersMap !== null) { + var responderInstances = Array.from(respondersMap.values()); + for (var i = 0, length = responderInstances.length; i < length; i++) { + var responderInstance = responderInstances[i]; + + if (validateOwnership(responderInstance)) { + var props = responderInstance.props, + responder = responderInstance.responder, + state = responderInstance.state, + target = responderInstance.target; + + if (!visitedResponders.has(responder) && validateResponderTargetEventTypes(eventType, responder)) { + visitedResponders.add(responder); + var onEvent = responder.onEvent; + if (onEvent !== null) { + currentInstance = responderInstance; + responderEvent.responderTarget = target; + onEvent(responderEvent, eventResponderContext, props, state); + } + } + } + } + } + } + node = node.return; + } + // Root phase + var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get(eventType); + if (rootEventResponderInstances !== undefined) { + var _responderInstances = Array.from(rootEventResponderInstances); + + for (var _i = 0; _i < _responderInstances.length; _i++) { + var _responderInstance = _responderInstances[_i]; + if (!validateOwnership(_responderInstance)) { + continue; + } + var _props = _responderInstance.props, + _responder = _responderInstance.responder, + _state = _responderInstance.state, + _target = _responderInstance.target; + + var onRootEvent = _responder.onRootEvent; + if (onRootEvent !== null) { + currentInstance = _responderInstance; + responderEvent.responderTarget = _target; + onRootEvent(responderEvent, eventResponderContext, _props, _state); + } + } + } +} + +function triggerOwnershipListeners() { + var listeningInstances = Array.from(ownershipChangeListeners); + var previousInstance = currentInstance; + var previousEventQueuePriority = currentEventQueuePriority; + var previousEventQueue = currentEventQueue; + try { + for (var i = 0; i < listeningInstances.length; i++) { + var _instance2 = listeningInstances[i]; + var props = _instance2.props, + responder = _instance2.responder, + state = _instance2.state; + + currentInstance = _instance2; + currentEventQueuePriority = ContinuousEvent; + currentEventQueue = []; + var onOwnershipChange = responder.onOwnershipChange; + if (onOwnershipChange !== null) { + onOwnershipChange(eventResponderContext, props, state); + } + } + processEventQueue(); + } finally { + currentInstance = previousInstance; + currentEventQueue = previousEventQueue; + currentEventQueuePriority = previousEventQueuePriority; + } +} + +function mountEventResponder(responder, responderInstance, props, state) { + if (responder.onOwnershipChange !== null) { + ownershipChangeListeners.add(responderInstance); + } + var onMount = responder.onMount; + if (onMount !== null) { + currentEventQueuePriority = ContinuousEvent; + currentInstance = responderInstance; + currentEventQueue = []; + try { + onMount(eventResponderContext, props, state); + processEventQueue(); + } finally { + currentEventQueue = null; + currentInstance = null; + currentTimers = null; + } + } +} + +function unmountEventResponder(responderInstance) { + var responder = responderInstance.responder; + var onUnmount = responder.onUnmount; + if (onUnmount !== null) { + var props = responderInstance.props, + state = responderInstance.state; + + currentEventQueue = []; + currentEventQueuePriority = ContinuousEvent; + currentInstance = responderInstance; + try { + onUnmount(eventResponderContext, props, state); + processEventQueue(); + } finally { + currentEventQueue = null; + currentInstance = null; + currentTimers = null; + } + } + releaseOwnershipForEventResponderInstance(responderInstance); + if (responder.onOwnershipChange !== null) { + ownershipChangeListeners.delete(responderInstance); + } + var rootEventTypesSet = responderInstance.rootEventTypes; + if (rootEventTypesSet !== null) { + var rootEventTypes = Array.from(rootEventTypesSet); + + for (var i = 0; i < rootEventTypes.length; i++) { + var topLevelEventType = rootEventTypes[i]; + var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get(topLevelEventType); + if (rootEventResponderInstances !== undefined) { + rootEventResponderInstances.delete(responderInstance); + } + } + } +} + +function validateResponderContext() { + (function () { + if (!(currentInstance !== null)) { + { + throw ReactError(Error('An event responder context was used outside of an event cycle. Use context.setTimeout() to use asynchronous responder context outside of event cycle .')); + } + } + })(); +} + +function dispatchEventForResponderEventSystem(topLevelType, targetFiber, nativeEvent, nativeEventTarget, eventSystemFlags) { + if (enableFlareAPI) { + var previousEventQueue = currentEventQueue; + var previousInstance = currentInstance; + var previousTimers = currentTimers; + var previousTimeStamp = currentTimeStamp; + var previousDocument = currentDocument; + var previousEventQueuePriority = currentEventQueuePriority; + currentTimers = null; + currentEventQueue = []; + currentEventQueuePriority = ContinuousEvent; + // nodeType 9 is DOCUMENT_NODE + currentDocument = nativeEventTarget.nodeType === 9 ? nativeEventTarget : nativeEventTarget.ownerDocument; + // We might want to control timeStamp another way here + currentTimeStamp = nativeEvent.timeStamp; + try { + traverseAndHandleEventResponderInstances(topLevelType, targetFiber, nativeEvent, nativeEventTarget, eventSystemFlags); + processEventQueue(); + } finally { + currentTimers = previousTimers; + currentInstance = previousInstance; + currentEventQueue = previousEventQueue; + currentTimeStamp = previousTimeStamp; + currentDocument = previousDocument; + currentEventQueuePriority = previousEventQueuePriority; + } + } +} + +function addRootEventTypesForResponderInstance(responderInstance, rootEventTypes) { + for (var i = 0; i < rootEventTypes.length; i++) { + var rootEventType = rootEventTypes[i]; + registerRootEventType(rootEventType, responderInstance); + } +} + +function registerRootEventType(rootEventType, eventResponderInstance) { + var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get(rootEventType); + if (rootEventResponderInstances === undefined) { + rootEventResponderInstances = new Set(); + rootEventTypesToEventResponderInstances.set(rootEventType, rootEventResponderInstances); + } + var rootEventTypesSet = eventResponderInstance.rootEventTypes; + if (rootEventTypesSet === null) { + rootEventTypesSet = eventResponderInstance.rootEventTypes = new Set(); + } + (function () { + if (!!rootEventTypesSet.has(rootEventType)) { + { + throw ReactError(Error('addRootEventTypes() found a duplicate root event type of "' + rootEventType + '". This might be because the event type exists in the event responder "rootEventTypes" array or because of a previous addRootEventTypes() using this root event type.')); + } + } + })(); + rootEventTypesSet.add(rootEventType); + rootEventResponderInstances.add(eventResponderInstance); +} + /** * `ReactInstanceMap` maintains a mapping from a public facing stateful * instance (key) and the internal representation (value). This allows public @@ -4219,7 +5229,13 @@ function isMounted(component) { } function assertIsMounted(fiber) { - !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0; + (function () { + if (!(isFiberMountedImpl(fiber) === MOUNTED)) { + { + throw ReactError(Error('Unable to find node on an unmounted component.')); + } + } + })(); } function findCurrentFiberUsingSlowPath(fiber) { @@ -4227,7 +5243,13 @@ function findCurrentFiberUsingSlowPath(fiber) { if (!alternate) { // If there is no alternate, then we only need to check if it is mounted. var state = isFiberMountedImpl(fiber); - !(state !== UNMOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0; + (function () { + if (!(state !== UNMOUNTED)) { + { + throw ReactError(Error('Unable to find node on an unmounted component.')); + } + } + })(); if (state === MOUNTING) { return null; } @@ -4240,11 +5262,24 @@ function findCurrentFiberUsingSlowPath(fiber) { var b = alternate; while (true) { var parentA = a.return; - var parentB = parentA ? parentA.alternate : null; - if (!parentA || !parentB) { + if (parentA === null) { // We're at the root. break; } + var parentB = parentA.alternate; + if (parentB === null) { + // There is no alternate. This is an unusual case. Currently, it only + // happens when a Suspense component is hidden. An extra fragment fiber + // is inserted in between the Suspense fiber and its children. Skip + // over this extra fragment fiber and proceed to the next parent. + var nextParent = parentA.return; + if (nextParent !== null) { + a = b = nextParent; + continue; + } + // If there's no parent, we're at the root. + break; + } // If both copies of the parent fiber point to the same child, we can // assume that the child is current. This happens when we bailout on low @@ -4266,7 +5301,13 @@ function findCurrentFiberUsingSlowPath(fiber) { } // We should never have an alternate for any mounting node. So the only // way this could possibly happen is if this was unmounted, if at all. - invariant(false, 'Unable to find node on an unmounted component.'); + (function () { + { + { + throw ReactError(Error('Unable to find node on an unmounted component.')); + } + } + })(); } if (a.return !== b.return) { @@ -4317,15 +5358,33 @@ function findCurrentFiberUsingSlowPath(fiber) { } _child = _child.sibling; } - !didFindChild ? invariant(false, 'Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.') : void 0; + (function () { + if (!didFindChild) { + { + throw ReactError(Error('Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.')); + } + } + })(); } } - !(a.alternate === b) ? invariant(false, 'Return fibers should always be each others\' alternates. This error is likely caused by a bug in React. Please file an issue.') : void 0; + (function () { + if (!(a.alternate === b)) { + { + throw ReactError(Error('Return fibers should always be each others\' alternates. This error is likely caused by a bug in React. Please file an issue.')); + } + } + })(); } // If the root is not a host container, we're in a disconnected tree. I.e. // unmounted. - !(a.tag === HostRoot) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0; + (function () { + if (!(a.tag === HostRoot)) { + { + throw ReactError(Error('Unable to find node on an unmounted component.')); + } + } + })(); if (a.stateNode.current === a) { // We've determined that A is the current branch. return fiber; @@ -4376,7 +5435,7 @@ function findCurrentHostFiberWithNoPortals(parent) { // Next we'll drill down this component to find the first HostComponent/Text. var node = currentParent; while (true) { - if (node.tag === HostComponent || node.tag === HostText) { + if (node.tag === HostComponent || node.tag === HostText || node.tag === FundamentalComponent) { return node; } else if (node.child && node.tag !== HostPortal) { node.child.return = node; @@ -4408,6 +5467,13 @@ function addEventCaptureListener(element, eventType, listener) { element.addEventListener(eventType, listener, true); } +function addEventCaptureListenerWithPassiveFlag(element, eventType, listener, passive) { + element.addEventListener(eventType, listener, { + capture: true, + passive: passive + }); +} + /** * @interface Event * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface @@ -4703,47 +5769,49 @@ var SyntheticWheelEvent = SyntheticMouseEvent.extend({ * ]); */ -var interactiveEventTypeNames = [[TOP_BLUR, 'blur'], [TOP_CANCEL, 'cancel'], [TOP_CLICK, 'click'], [TOP_CLOSE, 'close'], [TOP_CONTEXT_MENU, 'contextMenu'], [TOP_COPY, 'copy'], [TOP_CUT, 'cut'], [TOP_AUX_CLICK, 'auxClick'], [TOP_DOUBLE_CLICK, 'doubleClick'], [TOP_DRAG_END, 'dragEnd'], [TOP_DRAG_START, 'dragStart'], [TOP_DROP, 'drop'], [TOP_FOCUS, 'focus'], [TOP_INPUT, 'input'], [TOP_INVALID, 'invalid'], [TOP_KEY_DOWN, 'keyDown'], [TOP_KEY_PRESS, 'keyPress'], [TOP_KEY_UP, 'keyUp'], [TOP_MOUSE_DOWN, 'mouseDown'], [TOP_MOUSE_UP, 'mouseUp'], [TOP_PASTE, 'paste'], [TOP_PAUSE, 'pause'], [TOP_PLAY, 'play'], [TOP_POINTER_CANCEL, 'pointerCancel'], [TOP_POINTER_DOWN, 'pointerDown'], [TOP_POINTER_UP, 'pointerUp'], [TOP_RATE_CHANGE, 'rateChange'], [TOP_RESET, 'reset'], [TOP_SEEKED, 'seeked'], [TOP_SUBMIT, 'submit'], [TOP_TOUCH_CANCEL, 'touchCancel'], [TOP_TOUCH_END, 'touchEnd'], [TOP_TOUCH_START, 'touchStart'], [TOP_VOLUME_CHANGE, 'volumeChange']]; -var nonInteractiveEventTypeNames = [[TOP_ABORT, 'abort'], [TOP_ANIMATION_END, 'animationEnd'], [TOP_ANIMATION_ITERATION, 'animationIteration'], [TOP_ANIMATION_START, 'animationStart'], [TOP_CAN_PLAY, 'canPlay'], [TOP_CAN_PLAY_THROUGH, 'canPlayThrough'], [TOP_DRAG, 'drag'], [TOP_DRAG_ENTER, 'dragEnter'], [TOP_DRAG_EXIT, 'dragExit'], [TOP_DRAG_LEAVE, 'dragLeave'], [TOP_DRAG_OVER, 'dragOver'], [TOP_DURATION_CHANGE, 'durationChange'], [TOP_EMPTIED, 'emptied'], [TOP_ENCRYPTED, 'encrypted'], [TOP_ENDED, 'ended'], [TOP_ERROR, 'error'], [TOP_GOT_POINTER_CAPTURE, 'gotPointerCapture'], [TOP_LOAD, 'load'], [TOP_LOADED_DATA, 'loadedData'], [TOP_LOADED_METADATA, 'loadedMetadata'], [TOP_LOAD_START, 'loadStart'], [TOP_LOST_POINTER_CAPTURE, 'lostPointerCapture'], [TOP_MOUSE_MOVE, 'mouseMove'], [TOP_MOUSE_OUT, 'mouseOut'], [TOP_MOUSE_OVER, 'mouseOver'], [TOP_PLAYING, 'playing'], [TOP_POINTER_MOVE, 'pointerMove'], [TOP_POINTER_OUT, 'pointerOut'], [TOP_POINTER_OVER, 'pointerOver'], [TOP_PROGRESS, 'progress'], [TOP_SCROLL, 'scroll'], [TOP_SEEKING, 'seeking'], [TOP_STALLED, 'stalled'], [TOP_SUSPEND, 'suspend'], [TOP_TIME_UPDATE, 'timeUpdate'], [TOP_TOGGLE, 'toggle'], [TOP_TOUCH_MOVE, 'touchMove'], [TOP_TRANSITION_END, 'transitionEnd'], [TOP_WAITING, 'waiting'], [TOP_WHEEL, 'wheel']]; +var eventTuples = [ +// Discrete events +[TOP_BLUR, 'blur', DiscreteEvent], [TOP_CANCEL, 'cancel', DiscreteEvent], [TOP_CLICK, 'click', DiscreteEvent], [TOP_CLOSE, 'close', DiscreteEvent], [TOP_CONTEXT_MENU, 'contextMenu', DiscreteEvent], [TOP_COPY, 'copy', DiscreteEvent], [TOP_CUT, 'cut', DiscreteEvent], [TOP_AUX_CLICK, 'auxClick', DiscreteEvent], [TOP_DOUBLE_CLICK, 'doubleClick', DiscreteEvent], [TOP_DRAG_END, 'dragEnd', DiscreteEvent], [TOP_DRAG_START, 'dragStart', DiscreteEvent], [TOP_DROP, 'drop', DiscreteEvent], [TOP_FOCUS, 'focus', DiscreteEvent], [TOP_INPUT, 'input', DiscreteEvent], [TOP_INVALID, 'invalid', DiscreteEvent], [TOP_KEY_DOWN, 'keyDown', DiscreteEvent], [TOP_KEY_PRESS, 'keyPress', DiscreteEvent], [TOP_KEY_UP, 'keyUp', DiscreteEvent], [TOP_MOUSE_DOWN, 'mouseDown', DiscreteEvent], [TOP_MOUSE_UP, 'mouseUp', DiscreteEvent], [TOP_PASTE, 'paste', DiscreteEvent], [TOP_PAUSE, 'pause', DiscreteEvent], [TOP_PLAY, 'play', DiscreteEvent], [TOP_POINTER_CANCEL, 'pointerCancel', DiscreteEvent], [TOP_POINTER_DOWN, 'pointerDown', DiscreteEvent], [TOP_POINTER_UP, 'pointerUp', DiscreteEvent], [TOP_RATE_CHANGE, 'rateChange', DiscreteEvent], [TOP_RESET, 'reset', DiscreteEvent], [TOP_SEEKED, 'seeked', DiscreteEvent], [TOP_SUBMIT, 'submit', DiscreteEvent], [TOP_TOUCH_CANCEL, 'touchCancel', DiscreteEvent], [TOP_TOUCH_END, 'touchEnd', DiscreteEvent], [TOP_TOUCH_START, 'touchStart', DiscreteEvent], [TOP_VOLUME_CHANGE, 'volumeChange', DiscreteEvent], + +// User-blocking events +[TOP_DRAG, 'drag', UserBlockingEvent], [TOP_DRAG_ENTER, 'dragEnter', UserBlockingEvent], [TOP_DRAG_EXIT, 'dragExit', UserBlockingEvent], [TOP_DRAG_LEAVE, 'dragLeave', UserBlockingEvent], [TOP_DRAG_OVER, 'dragOver', UserBlockingEvent], [TOP_MOUSE_MOVE, 'mouseMove', UserBlockingEvent], [TOP_MOUSE_OUT, 'mouseOut', UserBlockingEvent], [TOP_MOUSE_OVER, 'mouseOver', UserBlockingEvent], [TOP_POINTER_MOVE, 'pointerMove', UserBlockingEvent], [TOP_POINTER_OUT, 'pointerOut', UserBlockingEvent], [TOP_POINTER_OVER, 'pointerOver', UserBlockingEvent], [TOP_SCROLL, 'scroll', UserBlockingEvent], [TOP_TOGGLE, 'toggle', UserBlockingEvent], [TOP_TOUCH_MOVE, 'touchMove', UserBlockingEvent], [TOP_WHEEL, 'wheel', UserBlockingEvent], + +// Continuous events +[TOP_ABORT, 'abort', ContinuousEvent], [TOP_ANIMATION_END, 'animationEnd', ContinuousEvent], [TOP_ANIMATION_ITERATION, 'animationIteration', ContinuousEvent], [TOP_ANIMATION_START, 'animationStart', ContinuousEvent], [TOP_CAN_PLAY, 'canPlay', ContinuousEvent], [TOP_CAN_PLAY_THROUGH, 'canPlayThrough', ContinuousEvent], [TOP_DURATION_CHANGE, 'durationChange', ContinuousEvent], [TOP_EMPTIED, 'emptied', ContinuousEvent], [TOP_ENCRYPTED, 'encrypted', ContinuousEvent], [TOP_ENDED, 'ended', ContinuousEvent], [TOP_ERROR, 'error', ContinuousEvent], [TOP_GOT_POINTER_CAPTURE, 'gotPointerCapture', ContinuousEvent], [TOP_LOAD, 'load', ContinuousEvent], [TOP_LOADED_DATA, 'loadedData', ContinuousEvent], [TOP_LOADED_METADATA, 'loadedMetadata', ContinuousEvent], [TOP_LOAD_START, 'loadStart', ContinuousEvent], [TOP_LOST_POINTER_CAPTURE, 'lostPointerCapture', ContinuousEvent], [TOP_PLAYING, 'playing', ContinuousEvent], [TOP_PROGRESS, 'progress', ContinuousEvent], [TOP_SEEKING, 'seeking', ContinuousEvent], [TOP_STALLED, 'stalled', ContinuousEvent], [TOP_SUSPEND, 'suspend', ContinuousEvent], [TOP_TIME_UPDATE, 'timeUpdate', ContinuousEvent], [TOP_TRANSITION_END, 'transitionEnd', ContinuousEvent], [TOP_WAITING, 'waiting', ContinuousEvent]]; var eventTypes$4 = {}; var topLevelEventsToDispatchConfig = {}; -function addEventTypeNameToConfig(_ref, isInteractive) { - var topEvent = _ref[0], - event = _ref[1]; +for (var i = 0; i < eventTuples.length; i++) { + var eventTuple = eventTuples[i]; + var topEvent = eventTuple[0]; + var event = eventTuple[1]; + var eventPriority = eventTuple[2]; var capitalizedEvent = event[0].toUpperCase() + event.slice(1); var onEvent = 'on' + capitalizedEvent; - var type = { + var config = { phasedRegistrationNames: { bubbled: onEvent, captured: onEvent + 'Capture' }, dependencies: [topEvent], - isInteractive: isInteractive + eventPriority: eventPriority }; - eventTypes$4[event] = type; - topLevelEventsToDispatchConfig[topEvent] = type; + eventTypes$4[event] = config; + topLevelEventsToDispatchConfig[topEvent] = config; } -interactiveEventTypeNames.forEach(function (eventTuple) { - addEventTypeNameToConfig(eventTuple, true); -}); -nonInteractiveEventTypeNames.forEach(function (eventTuple) { - addEventTypeNameToConfig(eventTuple, false); -}); - // Only used in DEV for exhaustiveness validation. var knownHTMLTopLevelTypes = [TOP_ABORT, TOP_CANCEL, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, TOP_CLOSE, TOP_DURATION_CHANGE, TOP_EMPTIED, TOP_ENCRYPTED, TOP_ENDED, TOP_ERROR, TOP_INPUT, TOP_INVALID, TOP_LOAD, TOP_LOADED_DATA, TOP_LOADED_METADATA, TOP_LOAD_START, TOP_PAUSE, TOP_PLAY, TOP_PLAYING, TOP_PROGRESS, TOP_RATE_CHANGE, TOP_RESET, TOP_SEEKED, TOP_SEEKING, TOP_STALLED, TOP_SUBMIT, TOP_SUSPEND, TOP_TIME_UPDATE, TOP_TOGGLE, TOP_VOLUME_CHANGE, TOP_WAITING]; var SimpleEventPlugin = { eventTypes: eventTypes$4, - isInteractiveTopLevelEventType: function (topLevelType) { + getEventPriority: function (topLevelType) { var config = topLevelEventsToDispatchConfig[topLevelType]; - return config !== undefined && config.isInteractive === true; + return config !== undefined ? config.eventPriority : ContinuousEvent; }, @@ -4851,7 +5919,31 @@ var SimpleEventPlugin = { } }; -var isInteractiveTopLevelEventType = SimpleEventPlugin.isInteractiveTopLevelEventType; +var passiveBrowserEventsSupported = false; + +// Check if browser support events with passive listeners +// https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support +if (enableFlareAPI && canUseDOM) { + try { + var options = {}; + // $FlowFixMe: Ignore Flow complaining about needing a value + Object.defineProperty(options, 'passive', { + get: function () { + passiveBrowserEventsSupported = true; + } + }); + window.addEventListener('test', options, options); + window.removeEventListener('test', options, options); + } catch (e) { + passiveBrowserEventsSupported = false; + } +} + +// Intentionally not named imports because Rollup would use dynamic dispatch for +// CommonJS interop named imports. +var UserBlockingPriority = unstable_UserBlockingPriority; +var runWithPriority = unstable_runWithPriority; +var getEventPriority = SimpleEventPlugin.getEventPriority; var CALLBACK_BOOKKEEPING_POOL_SIZE = 10; @@ -4913,7 +6005,8 @@ function handleTopLevel(bookKeeping) { var ancestor = targetInst; do { if (!ancestor) { - bookKeeping.ancestors.push(ancestor); + var _ancestors = bookKeeping.ancestors; + _ancestors.push(ancestor); break; } var root = findRootContainerNode(ancestor); @@ -4926,7 +6019,11 @@ function handleTopLevel(bookKeeping) { for (var i = 0; i < bookKeeping.ancestors.length; i++) { targetInst = bookKeeping.ancestors[i]; - runExtractedEventsInBatch(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent)); + var eventTarget = getEventTarget(bookKeeping.nativeEvent); + var _topLevelType = bookKeeping.topLevelType; + var _nativeEvent = bookKeeping.nativeEvent; + + runExtractedPluginEventsInBatch(_topLevelType, targetInst, _nativeEvent, eventTarget); } } @@ -4941,57 +6038,99 @@ function isEnabled() { return _enabled; } -/** - * Traps top-level events by using event bubbling. - * - * @param {number} topLevelType Number from `TopLevelEventTypes`. - * @param {object} element Element on which to attach listener. - * @return {?object} An object with a remove function which will forcefully - * remove the listener. - * @internal - */ function trapBubbledEvent(topLevelType, element) { - if (!element) { - return null; - } - var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent; - - addEventBubbleListener(element, getRawEventName(topLevelType), - // Check if interactive and wrap in interactiveUpdates - dispatch.bind(null, topLevelType)); + trapEventForPluginEventSystem(element, topLevelType, false); } -/** - * Traps a top-level event by using event capturing. - * - * @param {number} topLevelType Number from `TopLevelEventTypes`. - * @param {object} element Element on which to attach listener. - * @return {?object} An object with a remove function which will forcefully - * remove the listener. - * @internal - */ function trapCapturedEvent(topLevelType, element) { - if (!element) { - return null; + trapEventForPluginEventSystem(element, topLevelType, true); +} + +function trapEventForResponderEventSystem(element, topLevelType, passive) { + if (enableFlareAPI) { + var rawEventName = getRawEventName(topLevelType); + var eventFlags = RESPONDER_EVENT_SYSTEM; + + // If passive option is not supported, then the event will be + // active and not passive, but we flag it as using not being + // supported too. This way the responder event plugins know, + // and can provide polyfills if needed. + if (passive) { + if (passiveBrowserEventsSupported) { + eventFlags |= IS_PASSIVE; + } else { + eventFlags |= IS_ACTIVE; + eventFlags |= PASSIVE_NOT_SUPPORTED; + passive = false; + } + } else { + eventFlags |= IS_ACTIVE; + } + // Check if interactive and wrap in discreteUpdates + var listener = dispatchEvent.bind(null, topLevelType, eventFlags); + if (passiveBrowserEventsSupported) { + addEventCaptureListenerWithPassiveFlag(element, rawEventName, listener, passive); + } else { + addEventCaptureListener(element, rawEventName, listener); + } } - var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent; - - addEventCaptureListener(element, getRawEventName(topLevelType), - // Check if interactive and wrap in interactiveUpdates - dispatch.bind(null, topLevelType)); } -function dispatchInteractiveEvent(topLevelType, nativeEvent) { - interactiveUpdates(dispatchEvent, topLevelType, nativeEvent); +function trapEventForPluginEventSystem(element, topLevelType, capture) { + var listener = void 0; + switch (getEventPriority(topLevelType)) { + case DiscreteEvent: + listener = dispatchDiscreteEvent.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM); + break; + case UserBlockingEvent: + listener = dispatchUserBlockingUpdate.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM); + break; + case ContinuousEvent: + default: + listener = dispatchEvent.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM); + break; + } + + var rawEventName = getRawEventName(topLevelType); + if (capture) { + addEventCaptureListener(element, rawEventName, listener); + } else { + addEventBubbleListener(element, rawEventName, listener); + } } -function dispatchEvent(topLevelType, nativeEvent) { +function dispatchDiscreteEvent(topLevelType, eventSystemFlags, nativeEvent) { + flushDiscreteUpdatesIfNeeded(nativeEvent.timeStamp); + discreteUpdates(dispatchEvent, topLevelType, eventSystemFlags, nativeEvent); +} + +function dispatchUserBlockingUpdate(topLevelType, eventSystemFlags, nativeEvent) { + if (enableUserBlockingEvents) { + runWithPriority(UserBlockingPriority, dispatchEvent.bind(null, topLevelType, eventSystemFlags, nativeEvent)); + } else { + dispatchEvent(topLevelType, eventSystemFlags, nativeEvent); + } +} + +function dispatchEventForPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst) { + var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst); + + try { + // Event queue being processed in the same cycle allows + // `preventDefault`. + batchedEventUpdates(handleTopLevel, bookKeeping); + } finally { + releaseTopLevelCallbackBookKeeping(bookKeeping); + } +} + +function dispatchEvent(topLevelType, eventSystemFlags, nativeEvent) { if (!_enabled) { return; } - var nativeEventTarget = getEventTarget(nativeEvent); var targetInst = getClosestInstanceFromNode(nativeEventTarget); + if (targetInst !== null && typeof targetInst.tag === 'number' && !isFiberMounted(targetInst)) { // If we get an event (ex: img onload) before committing that // component's mount, ignore it for now (that is, treat it as if it was an @@ -5000,14 +6139,15 @@ function dispatchEvent(topLevelType, nativeEvent) { targetInst = null; } - var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst); - - try { - // Event queue being processed in the same cycle allows - // `preventDefault`. - batchedUpdates(handleTopLevel, bookKeeping); - } finally { - releaseTopLevelCallbackBookKeeping(bookKeeping); + if (enableFlareAPI) { + if (eventSystemFlags === PLUGIN_EVENT_SYSTEM) { + dispatchEventForPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst); + } else { + // React Flare event system + dispatchEventForResponderEventSystem(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags); + } + } else { + dispatchEventForPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst); } } @@ -5067,22 +6207,16 @@ function dispatchEvent(topLevelType, nativeEvent) { * React Core . General Purpose Event Plugin System */ -var alreadyListeningTo = {}; -var reactTopListenersCounter = 0; +var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map; +var elementListeningSets = new PossiblyWeakMap(); -/** - * To ensure no conflicts with other potential React instances on the page - */ -var topListenersIDKey = '_reactListenersID' + ('' + Math.random()).slice(2); - -function getListeningForDocument(mountAt) { - // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty` - // directly. - if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) { - mountAt[topListenersIDKey] = reactTopListenersCounter++; - alreadyListeningTo[mountAt[topListenersIDKey]] = {}; +function getListeningSetForElement(element) { + var listeningSet = elementListeningSets.get(element); + if (listeningSet === undefined) { + listeningSet = new Set(); + elementListeningSets.set(element, listeningSet); } - return alreadyListeningTo[mountAt[topListenersIDKey]]; + return listeningSet; } /** @@ -5107,12 +6241,12 @@ function getListeningForDocument(mountAt) { * @param {object} mountAt Container where to mount the listener */ function listenTo(registrationName, mountAt) { - var isListening = getListeningForDocument(mountAt); + var listeningSet = getListeningSetForElement(mountAt); var dependencies = registrationNameDependencies[registrationName]; for (var i = 0; i < dependencies.length; i++) { var dependency = dependencies[i]; - if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) { + if (!listeningSet.has(dependency)) { switch (dependency) { case TOP_SCROLL: trapCapturedEvent(TOP_SCROLL, mountAt); @@ -5123,8 +6257,8 @@ function listenTo(registrationName, mountAt) { trapCapturedEvent(TOP_BLUR, mountAt); // We set the flag for a single dependency later in this function, // but this ensures we mark both as attached rather than just one. - isListening[TOP_BLUR] = true; - isListening[TOP_FOCUS] = true; + listeningSet.add(TOP_BLUR); + listeningSet.add(TOP_FOCUS); break; case TOP_CANCEL: case TOP_CLOSE: @@ -5147,17 +6281,18 @@ function listenTo(registrationName, mountAt) { } break; } - isListening[dependency] = true; + listeningSet.add(dependency); } } } function isListeningToAllDependencies(registrationName, mountAt) { - var isListening = getListeningForDocument(mountAt); + var listeningSet = getListeningSetForElement(mountAt); var dependencies = registrationNameDependencies[registrationName]; + for (var i = 0; i < dependencies.length; i++) { var dependency = dependencies[i]; - if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) { + if (!listeningSet.has(dependency)) { return false; } } @@ -5435,15 +6570,29 @@ function isInDocument(node) { return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node); } +function isSameOriginFrame(iframe) { + try { + // Accessing the contentDocument of a HTMLIframeElement can cause the browser + // to throw, e.g. if it has a cross-origin src attribute. + // Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g: + // iframe.contentDocument.defaultView; + // A safety way is to access one of the cross origin properties: Window or Location + // Which might result in "SecurityError" DOM Exception and it is compatible to Safari. + // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl + + return typeof iframe.contentWindow.location.href === 'string'; + } catch (err) { + return false; + } +} + function getActiveElementDeep() { var win = window; var element = getActiveElement(); while (element instanceof win.HTMLIFrameElement) { - // Accessing the contentDocument of a HTMLIframeElement can cause the browser - // to throw, e.g. if it has a cross-origin src attribute - try { - win = element.contentDocument.defaultView; - } catch (e) { + if (isSameOriginFrame(element)) { + win = element.contentWindow; + } else { return element; } element = getActiveElement(win.document); @@ -5742,6 +6891,11 @@ injection.injectEventPluginsByName({ BeforeInputEventPlugin: BeforeInputEventPlugin }); +function endsWith(subject, search) { + var length = subject.length; + return subject.substring(length - search.length, length) === search; +} + var didWarnSelectedSetOnOption = false; var didWarnInvalidChild = false; @@ -5998,7 +7152,13 @@ var didWarnValDefaultVal = false; function getHostProps$3(element, props) { var node = element; - !(props.dangerouslySetInnerHTML == null) ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on