/** @license React v16.0.0 * react-dom.development.js * * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ 'use strict'; if (process.env.NODE_ENV !== "production") { (function() { 'use strict'; var react = require('react'); var invariant = require('fbjs/lib/invariant'); var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); var _assign = require('object-assign'); var EventListener = require('fbjs/lib/EventListener'); var require$$0 = require('fbjs/lib/warning'); var hyphenateStyleName = require('fbjs/lib/hyphenateStyleName'); var emptyFunction = require('fbjs/lib/emptyFunction'); var camelizeStyleName = require('fbjs/lib/camelizeStyleName'); var performanceNow = require('fbjs/lib/performanceNow'); var propTypes = require('prop-types'); var emptyObject = require('fbjs/lib/emptyObject'); var checkPropTypes = require('prop-types/checkPropTypes'); var shallowEqual = require('fbjs/lib/shallowEqual'); var containsNode = require('fbjs/lib/containsNode'); var focusNode = require('fbjs/lib/focusNode'); var getActiveElement = require('fbjs/lib/getActiveElement'); /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule reactProdInvariant * */ /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule checkReact * */ !react ? invariant(false, 'ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.') : void 0; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule DOMNamespaces */ var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'; var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML'; var SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; var Namespaces = { html: HTML_NAMESPACE, mathml: MATH_NAMESPACE, svg: SVG_NAMESPACE }; // Assumes there is no parent namespace. function getIntrinsicNamespace(type) { switch (type) { case 'svg': return SVG_NAMESPACE; case 'math': return MATH_NAMESPACE; default: return HTML_NAMESPACE; } } function getChildNamespace$1(parentNamespace, type) { if (parentNamespace == null || parentNamespace === HTML_NAMESPACE) { // No (or default) parent namespace: potential entry point. return getIntrinsicNamespace(type); } if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') { // We're leaving SVG. return HTML_NAMESPACE; } // By default, pass namespace below. return parentNamespace; } var Namespaces_1 = Namespaces; var getIntrinsicNamespace_1 = getIntrinsicNamespace; var getChildNamespace_1 = getChildNamespace$1; var DOMNamespaces = { Namespaces: Namespaces_1, getIntrinsicNamespace: getIntrinsicNamespace_1, getChildNamespace: getChildNamespace_1 }; /** * Injectable ordering of event plugins. */ var eventPluginOrder = null; /** * Injectable mapping from names to event plugin modules. */ var namesToPlugins = {}; /** * Recomputes the plugin list using the injected plugins and plugin ordering. * * @private */ function recomputePluginOrdering() { if (!eventPluginOrder) { // Wait until an `eventPluginOrder` is injected. return; } for (var pluginName in namesToPlugins) { var pluginModule = namesToPlugins[pluginName]; var pluginIndex = eventPluginOrder.indexOf(pluginName); !(pluginIndex > -1) ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : void 0; if (EventPluginRegistry.plugins[pluginIndex]) { continue; } !pluginModule.extractEvents ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : void 0; EventPluginRegistry.plugins[pluginIndex] = pluginModule; var publishedEvents = pluginModule.eventTypes; for (var eventName in publishedEvents) { !publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : void 0; } } } /** * Publishes an event so that it can be dispatched by the supplied plugin. * * @param {object} dispatchConfig Dispatch configuration for the event. * @param {object} PluginModule Plugin publishing the event. * @return {boolean} True if the event was successfully published. * @private */ function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { !!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName) ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : void 0; EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig; var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; if (phasedRegistrationNames) { for (var phaseName in phasedRegistrationNames) { if (phasedRegistrationNames.hasOwnProperty(phaseName)) { var phasedRegistrationName = phasedRegistrationNames[phaseName]; publishRegistrationName(phasedRegistrationName, pluginModule, eventName); } } return true; } else if (dispatchConfig.registrationName) { publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName); return true; } return false; } /** * Publishes a registration name that is used to identify dispatched events. * * @param {string} registrationName Registration name to add. * @param {object} PluginModule Plugin publishing the event. * @private */ function publishRegistrationName(registrationName, pluginModule, eventName) { !!EventPluginRegistry.registrationNameModules[registrationName] ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : void 0; EventPluginRegistry.registrationNameModules[registrationName] = pluginModule; EventPluginRegistry.registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies; { var lowerCasedName = registrationName.toLowerCase(); EventPluginRegistry.possibleRegistrationNames[lowerCasedName] = registrationName; if (registrationName === 'onDoubleClick') { EventPluginRegistry.possibleRegistrationNames.ondblclick = registrationName; } } } /** * Registers plugins so that they can extract and dispatch events. * * @see {EventPluginHub} */ var EventPluginRegistry = { /** * Ordered list of injected plugins. */ plugins: [], /** * Mapping from event name to dispatch config */ eventNameDispatchConfigs: {}, /** * Mapping from registration name to plugin module */ registrationNameModules: {}, /** * Mapping from registration name to event name */ registrationNameDependencies: {}, /** * Mapping from lowercase registration names to the properly cased version, * used to warn in the case of missing event handlers. Available * only in true. * @type {Object} */ possibleRegistrationNames: {}, // Trust the developer to only use possibleRegistrationNames in true /** * Injects an ordering of plugins (by plugin name). This allows the ordering * to be decoupled from injection of the actual plugins so that ordering is * always deterministic regardless of packaging, on-the-fly injection, etc. * * @param {array} InjectedEventPluginOrder * @internal * @see {EventPluginHub.injection.injectEventPluginOrder} */ injectEventPluginOrder: function (injectedEventPluginOrder) { !!eventPluginOrder ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.') : void 0; // Clone the ordering so it cannot be dynamically mutated. eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); recomputePluginOrdering(); }, /** * Injects plugins to be used by `EventPluginHub`. The plugin names must be * in the ordering injected by `injectEventPluginOrder`. * * Plugins can be injected as part of page initialization or on-the-fly. * * @param {object} injectedNamesToPlugins Map from names to plugin modules. * @internal * @see {EventPluginHub.injection.injectEventPluginsByName} */ injectEventPluginsByName: function (injectedNamesToPlugins) { var isOrderingDirty = false; for (var pluginName in injectedNamesToPlugins) { if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { continue; } var pluginModule = injectedNamesToPlugins[pluginName]; if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) { !!namesToPlugins[pluginName] ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : void 0; namesToPlugins[pluginName] = pluginModule; isOrderingDirty = true; } } if (isOrderingDirty) { recomputePluginOrdering(); } } }; var EventPluginRegistry_1 = EventPluginRegistry; // These attributes should be all lowercase to allow for // case insensitive checks var RESERVED_PROPS = { children: true, dangerouslySetInnerHTML: true, autoFocus: true, defaultValue: true, defaultChecked: true, innerHTML: true, suppressContentEditableWarning: true, style: true }; function checkMask(value, bitmask) { return (value & bitmask) === bitmask; } var DOMPropertyInjection = { /** * Mapping from normalized, camelcased property names to a configuration that * specifies how the associated DOM property should be accessed or rendered. */ MUST_USE_PROPERTY: 0x1, HAS_BOOLEAN_VALUE: 0x4, HAS_NUMERIC_VALUE: 0x8, HAS_POSITIVE_NUMERIC_VALUE: 0x10 | 0x8, HAS_OVERLOADED_BOOLEAN_VALUE: 0x20, HAS_STRING_BOOLEAN_VALUE: 0x40, /** * Inject some specialized knowledge about the DOM. This takes a config object * with the following properties: * * Properties: object mapping DOM property name to one of the * DOMPropertyInjection constants or null. If your attribute isn't in here, * it won't get written to the DOM. * * DOMAttributeNames: object mapping React attribute name to the DOM * attribute name. Attribute names not specified use the **lowercase** * normalized name. * * DOMAttributeNamespaces: object mapping React attribute name to the DOM * attribute namespace URL. (Attribute names not specified use no namespace.) * * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. * Property names not specified use the normalized name. * * DOMMutationMethods: Properties that require special mutation methods. If * `value` is undefined, the mutation method should unset the property. * * @param {object} domPropertyConfig the config as described above. */ injectDOMPropertyConfig: function (domPropertyConfig) { var Injection = DOMPropertyInjection; var Properties = domPropertyConfig.Properties || {}; var DOMAttributeNamespaces = domPropertyConfig.DOMAttributeNamespaces || {}; var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; for (var propName in Properties) { !!DOMProperty.properties.hasOwnProperty(propName) ? invariant(false, 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property \'%s\' which has already been injected. You may be accidentally injecting the same DOM property config twice, or you may be injecting two configs that have conflicting property names.', propName) : void 0; var lowerCased = propName.toLowerCase(); var propConfig = Properties[propName]; var propertyInfo = { attributeName: lowerCased, attributeNamespace: null, propertyName: propName, mutationMethod: null, mustUseProperty: checkMask(propConfig, Injection.MUST_USE_PROPERTY), hasBooleanValue: checkMask(propConfig, Injection.HAS_BOOLEAN_VALUE), hasNumericValue: checkMask(propConfig, Injection.HAS_NUMERIC_VALUE), hasPositiveNumericValue: checkMask(propConfig, Injection.HAS_POSITIVE_NUMERIC_VALUE), hasOverloadedBooleanValue: checkMask(propConfig, Injection.HAS_OVERLOADED_BOOLEAN_VALUE), hasStringBooleanValue: checkMask(propConfig, Injection.HAS_STRING_BOOLEAN_VALUE) }; !(propertyInfo.hasBooleanValue + propertyInfo.hasNumericValue + propertyInfo.hasOverloadedBooleanValue <= 1) ? invariant(false, 'DOMProperty: Value can be one of boolean, overloaded boolean, or numeric value, but not a combination: %s', propName) : void 0; if (DOMAttributeNames.hasOwnProperty(propName)) { var attributeName = DOMAttributeNames[propName]; propertyInfo.attributeName = attributeName; } if (DOMAttributeNamespaces.hasOwnProperty(propName)) { propertyInfo.attributeNamespace = DOMAttributeNamespaces[propName]; } if (DOMMutationMethods.hasOwnProperty(propName)) { propertyInfo.mutationMethod = DOMMutationMethods[propName]; } // Downcase references to whitelist properties to check for membership // without case-sensitivity. This allows the whitelist to pick up // `allowfullscreen`, which should be written using the property configuration // for `allowFullscreen` DOMProperty.properties[propName] = propertyInfo; } } }; /* eslint-disable max-len */ var ATTRIBUTE_NAME_START_CHAR = ':A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD'; /* eslint-enable max-len */ /** * DOMProperty exports lookup objects that can be used like functions: * * > DOMProperty.isValid['id'] * true * > DOMProperty.isValid['foobar'] * undefined * * Although this may be confusing, it performs better in general. * * @see http://jsperf.com/key-exists * @see http://jsperf.com/key-missing */ var DOMProperty = { ID_ATTRIBUTE_NAME: 'data-reactid', ROOT_ATTRIBUTE_NAME: 'data-reactroot', ATTRIBUTE_NAME_START_CHAR: ATTRIBUTE_NAME_START_CHAR, ATTRIBUTE_NAME_CHAR: ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040', /** * Map from property "standard name" to an object with info about how to set * the property in the DOM. Each object contains: * * attributeName: * Used when rendering markup or with `*Attribute()`. * attributeNamespace * propertyName: * Used on DOM node instances. (This includes properties that mutate due to * external factors.) * mutationMethod: * If non-null, used instead of the property or `setAttribute()` after * initial render. * mustUseProperty: * Whether the property must be accessed and mutated as an object property. * hasBooleanValue: * Whether the property should be removed when set to a falsey value. * hasNumericValue: * Whether the property must be numeric or parse as a numeric and should be * removed when set to a falsey value. * hasPositiveNumericValue: * Whether the property must be positive numeric or parse as a positive * numeric and should be removed when set to a falsey value. * hasOverloadedBooleanValue: * Whether the property can be used as a flag as well as with a value. * Removed when strictly equal to false; present without a value when * strictly equal to true; present with a value otherwise. */ properties: {}, /** * Checks whether a property name is a writeable attribute. * @method */ shouldSetAttribute: function (name, value) { if (DOMProperty.isReservedProp(name)) { return false; } if ((name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) { return false; } if (value === null) { return true; } switch (typeof value) { case 'boolean': return DOMProperty.shouldAttributeAcceptBooleanValue(name); case 'undefined': case 'number': case 'string': case 'object': return true; default: // function, symbol return false; } }, getPropertyInfo: function (name) { return DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; }, shouldAttributeAcceptBooleanValue: function (name) { if (DOMProperty.isReservedProp(name)) { return true; } var propertyInfo = DOMProperty.getPropertyInfo(name); if (propertyInfo) { return propertyInfo.hasBooleanValue || propertyInfo.hasStringBooleanValue || propertyInfo.hasOverloadedBooleanValue; } var prefix = name.toLowerCase().slice(0, 5); return prefix === 'data-' || prefix === 'aria-'; }, /** * Checks to see if a property name is within the list of properties * reserved for internal React operations. These properties should * not be set on an HTML element. * * @private * @param {string} name * @return {boolean} If the name is within reserved props */ isReservedProp: function (name) { return RESERVED_PROPS.hasOwnProperty(name); }, injection: DOMPropertyInjection }; var DOMProperty_1 = DOMProperty; /** * Copyright (c) 2015-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule ReactDOMComponentFlags */ var ReactDOMComponentFlags = { hasCachedChildNodes: 1 << 0 }; var ReactDOMComponentFlags_1 = ReactDOMComponentFlags; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule ReactTypeOfWork * */ var ReactTypeOfWork = { IndeterminateComponent: 0, // Before we know whether it is functional or class FunctionalComponent: 1, ClassComponent: 2, HostRoot: 3, // Root of a host tree. Could be nested inside another node. HostPortal: 4, // A subtree. Could be an entry point to a different renderer. HostComponent: 5, HostText: 6, CoroutineComponent: 7, CoroutineHandlerPhase: 8, YieldComponent: 9, Fragment: 10 }; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule HTMLNodeType */ /** * HTML nodeType values that represent the type of the node */ var HTMLNodeType = { ELEMENT_NODE: 1, TEXT_NODE: 3, COMMENT_NODE: 8, DOCUMENT_NODE: 9, DOCUMENT_FRAGMENT_NODE: 11 }; var HTMLNodeType_1 = HTMLNodeType; var HostComponent = ReactTypeOfWork.HostComponent; var HostText = ReactTypeOfWork.HostText; var ELEMENT_NODE$1 = HTMLNodeType_1.ELEMENT_NODE; var COMMENT_NODE$1 = HTMLNodeType_1.COMMENT_NODE; var ATTR_NAME = DOMProperty_1.ID_ATTRIBUTE_NAME; var Flags = ReactDOMComponentFlags_1; var randomKey = Math.random().toString(36).slice(2); var internalInstanceKey = '__reactInternalInstance$' + randomKey; var internalEventHandlersKey = '__reactEventHandlers$' + randomKey; /** * Check if a given node should be cached. */ function shouldPrecacheNode(node, nodeID) { return node.nodeType === ELEMENT_NODE$1 && node.getAttribute(ATTR_NAME) === '' + nodeID || node.nodeType === COMMENT_NODE$1 && node.nodeValue === ' react-text: ' + nodeID + ' ' || node.nodeType === COMMENT_NODE$1 && node.nodeValue === ' react-empty: ' + nodeID + ' '; } /** * Drill down (through composites and empty components) until we get a host or * host text component. * * This is pretty polymorphic but unavoidable with the current structure we have * for `_renderedChildren`. */ function getRenderedHostOrTextFromComponent(component) { var rendered; while (rendered = component._renderedComponent) { component = rendered; } return component; } /** * Populate `_hostNode` on the rendered host/text component with the given * DOM node. The passed `inst` can be a composite. */ function precacheNode(inst, node) { var hostInst = getRenderedHostOrTextFromComponent(inst); hostInst._hostNode = node; node[internalInstanceKey] = hostInst; } function precacheFiberNode$1(hostInst, node) { node[internalInstanceKey] = hostInst; } function uncacheNode(inst) { var node = inst._hostNode; if (node) { delete node[internalInstanceKey]; inst._hostNode = null; } } /** * Populate `_hostNode` on each child of `inst`, assuming that the children * match up with the DOM (element) children of `node`. * * We cache entire levels at once to avoid an n^2 problem where we access the * children of a node sequentially and have to walk from the start to our target * node every time. * * Since we update `_renderedChildren` and the actual DOM at (slightly) * different times, we could race here and see a newer `_renderedChildren` than * the DOM nodes we see. To avoid this, ReactMultiChild calls * `prepareToManageChildren` before we change `_renderedChildren`, at which * time the container's child nodes are always cached (until it unmounts). */ function precacheChildNodes(inst, node) { if (inst._flags & Flags.hasCachedChildNodes) { return; } var children = inst._renderedChildren; var childNode = node.firstChild; outer: for (var name in children) { if (!children.hasOwnProperty(name)) { continue; } var childInst = children[name]; var childID = getRenderedHostOrTextFromComponent(childInst)._domID; if (childID === 0) { // We're currently unmounting this child in ReactMultiChild; skip it. continue; } // We assume the child nodes are in the same order as the child instances. for (; childNode !== null; childNode = childNode.nextSibling) { if (shouldPrecacheNode(childNode, childID)) { precacheNode(childInst, childNode); continue outer; } } // We reached the end of the DOM children without finding an ID match. invariant(false, 'Unable to find element with ID %s.', childID); } inst._flags |= Flags.hasCachedChildNodes; } /** * Given a DOM node, return the closest ReactDOMComponent or * ReactDOMTextComponent instance ancestor. */ function getClosestInstanceFromNode(node) { if (node[internalInstanceKey]) { return node[internalInstanceKey]; } // Walk up the tree until we find an ancestor whose instance we have cached. var parents = []; while (!node[internalInstanceKey]) { parents.push(node); if (node.parentNode) { node = node.parentNode; } else { // Top of the tree. This node must not be part of a React tree (or is // unmounted, potentially). return null; } } var closest; var inst = node[internalInstanceKey]; if (inst.tag === HostComponent || inst.tag === HostText) { // In Fiber, this will always be the deepest root. return inst; } for (; node && (inst = node[internalInstanceKey]); node = parents.pop()) { closest = inst; if (parents.length) { precacheChildNodes(inst, node); } } return closest; } /** * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent * instance, or null if the node was not rendered by this React. */ function getInstanceFromNode(node) { var inst = node[internalInstanceKey]; if (inst) { if (inst.tag === HostComponent || inst.tag === HostText) { return inst; } else if (inst._hostNode === node) { return inst; } else { return null; } } inst = getClosestInstanceFromNode(node); if (inst != null && inst._hostNode === node) { return inst; } else { return null; } } /** * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding * DOM node. */ function getNodeFromInstance(inst) { if (inst.tag === HostComponent || inst.tag === HostText) { // In Fiber this, is just the state node right now. We assume it will be // a host component or host text. return inst.stateNode; } // Without this first invariant, passing a non-DOM-component triggers the next // invariant for a missing parent, which is super confusing. !(inst._hostNode !== undefined) ? invariant(false, 'getNodeFromInstance: Invalid argument.') : void 0; if (inst._hostNode) { return inst._hostNode; } // Walk up the tree until we find an ancestor whose DOM node we have cached. var parents = []; while (!inst._hostNode) { parents.push(inst); !inst._hostParent ? invariant(false, 'React DOM tree root should always have a node reference.') : void 0; inst = inst._hostParent; } // Now parents contains each ancestor that does *not* have a cached native // node, and `inst` is the deepest ancestor that does. for (; parents.length; inst = parents.pop()) { precacheChildNodes(inst, inst._hostNode); } return inst._hostNode; } function getFiberCurrentPropsFromNode(node) { return node[internalEventHandlersKey] || null; } function updateFiberProps$1(node, props) { node[internalEventHandlersKey] = props; } var ReactDOMComponentTree = { getClosestInstanceFromNode: getClosestInstanceFromNode, getInstanceFromNode: getInstanceFromNode, getNodeFromInstance: getNodeFromInstance, precacheChildNodes: precacheChildNodes, precacheNode: precacheNode, uncacheNode: uncacheNode, precacheFiberNode: precacheFiberNode$1, getFiberCurrentPropsFromNode: getFiberCurrentPropsFromNode, updateFiberProps: updateFiberProps$1 }; var ReactDOMComponentTree_1 = ReactDOMComponentTree; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule ReactInstanceMap */ /** * `ReactInstanceMap` maintains a mapping from a public facing stateful * instance (key) and the internal representation (value). This allows public * methods to accept the user facing instance as an argument and map them back * to internal methods. */ // TODO: Replace this with ES6: var ReactInstanceMap = new Map(); var ReactInstanceMap = { /** * This API should be called `delete` but we'd have to make sure to always * transform these to strings for IE support. When this transform is fully * supported we can rename it. */ remove: function (key) { key._reactInternalFiber = undefined; }, get: function (key) { return key._reactInternalFiber; }, has: function (key) { return key._reactInternalFiber !== undefined; }, set: function (key, value) { key._reactInternalFiber = value; } }; var ReactInstanceMap_1 = ReactInstanceMap; var ReactInternals = react.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; var ReactGlobalSharedState = { ReactCurrentOwner: ReactInternals.ReactCurrentOwner }; { _assign(ReactGlobalSharedState, { ReactComponentTreeHook: ReactInternals.ReactComponentTreeHook, ReactDebugCurrentFrame: ReactInternals.ReactDebugCurrentFrame }); } var ReactGlobalSharedState_1 = ReactGlobalSharedState; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule getComponentName * */ function getComponentName(instanceOrFiber) { if (typeof instanceOrFiber.getName === 'function') { // Stack reconciler var instance = instanceOrFiber; return instance.getName(); } if (typeof instanceOrFiber.tag === 'number') { // Fiber reconciler var fiber = instanceOrFiber; var type = fiber.type; if (typeof type === 'string') { return type; } if (typeof type === 'function') { return type.displayName || type.name; } } return null; } var getComponentName_1 = getComponentName; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule ReactTypeOfSideEffect * */ var ReactTypeOfSideEffect = { // Don't change these two values: NoEffect: 0, // 0b00000000 PerformedWork: 1, // 0b00000001 // You can change the rest (and add more). Placement: 2, // 0b00000010 Update: 4, // 0b00000100 PlacementAndUpdate: 6, // 0b00000110 Deletion: 8, // 0b00001000 ContentReset: 16, // 0b00010000 Callback: 32, // 0b00100000 Err: 64, // 0b01000000 Ref: 128 }; var ReactCurrentOwner = ReactGlobalSharedState_1.ReactCurrentOwner; { var warning$1 = require$$0; } var ClassComponent = ReactTypeOfWork.ClassComponent; var HostComponent$1 = ReactTypeOfWork.HostComponent; var HostRoot$1 = ReactTypeOfWork.HostRoot; var HostPortal = ReactTypeOfWork.HostPortal; var HostText$1 = ReactTypeOfWork.HostText; var NoEffect = ReactTypeOfSideEffect.NoEffect; var Placement = ReactTypeOfSideEffect.Placement; var MOUNTING = 1; var MOUNTED = 2; var UNMOUNTED = 3; function isFiberMountedImpl(fiber) { var node = fiber; if (!fiber.alternate) { // If there is no alternate, this might be a new tree that isn't inserted // yet. If it is, then it will have a pending insertion effect on it. if ((node.effectTag & Placement) !== NoEffect) { return MOUNTING; } while (node['return']) { node = node['return']; if ((node.effectTag & Placement) !== NoEffect) { return MOUNTING; } } } else { while (node['return']) { node = node['return']; } } if (node.tag === HostRoot$1) { // TODO: Check if this was a nested HostRoot when used with // renderContainerIntoSubtree. return MOUNTED; } // If we didn't hit the root, that means that we're in an disconnected tree // that has been unmounted. return UNMOUNTED; } var isFiberMounted = function (fiber) { return isFiberMountedImpl(fiber) === MOUNTED; }; var isMounted = function (component) { { var owner = ReactCurrentOwner.current; if (owner !== null && owner.tag === ClassComponent) { var ownerFiber = owner; var instance = ownerFiber.stateNode; warning$1(instance._warnedAboutRefsInRender, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName_1(ownerFiber) || 'A component'); instance._warnedAboutRefsInRender = true; } } var fiber = ReactInstanceMap_1.get(component); if (!fiber) { return false; } return isFiberMountedImpl(fiber) === MOUNTED; }; function assertIsMounted(fiber) { !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0; } function findCurrentFiberUsingSlowPath(fiber) { var alternate = fiber.alternate; 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; if (state === MOUNTING) { return null; } return fiber; } // If we have two possible branches, we'll walk backwards up to the root // to see what path the root points to. On the way we may hit one of the // special cases and we'll deal with them. var a = fiber; var b = alternate; while (true) { var parentA = a['return']; var parentB = parentA ? parentA.alternate : null; if (!parentA || !parentB) { // 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 // priority: the bailed out fiber's child reuses the current child. if (parentA.child === parentB.child) { var child = parentA.child; while (child) { if (child === a) { // We've determined that A is the current branch. assertIsMounted(parentA); return fiber; } if (child === b) { // We've determined that B is the current branch. assertIsMounted(parentA); return alternate; } child = child.sibling; } // 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.'); } if (a['return'] !== b['return']) { // The return pointer of A and the return pointer of B point to different // fibers. We assume that return pointers never criss-cross, so A must // belong to the child set of A.return, and B must belong to the child // set of B.return. a = parentA; b = parentB; } else { // The return pointers point to the same fiber. We'll have to use the // default, slow path: scan the child sets of each parent alternate to see // which child belongs to which set. // // Search parent A's child set var didFindChild = false; var _child = parentA.child; while (_child) { if (_child === a) { didFindChild = true; a = parentA; b = parentB; break; } if (_child === b) { didFindChild = true; b = parentA; a = parentB; break; } _child = _child.sibling; } if (!didFindChild) { // Search parent B's child set _child = parentB.child; while (_child) { if (_child === a) { didFindChild = true; a = parentB; b = parentA; break; } if (_child === b) { didFindChild = true; b = parentB; a = parentA; break; } _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; } } !(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; } // If the root is not a host container, we're in a disconnected tree. I.e. // unmounted. !(a.tag === HostRoot$1) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0; if (a.stateNode.current === a) { // We've determined that A is the current branch. return fiber; } // Otherwise B has to be current branch. return alternate; } var findCurrentFiberUsingSlowPath_1 = findCurrentFiberUsingSlowPath; var findCurrentHostFiber = function (parent) { var currentParent = findCurrentFiberUsingSlowPath(parent); if (!currentParent) { return null; } // Next we'll drill down this component to find the first HostComponent/Text. var node = currentParent; while (true) { if (node.tag === HostComponent$1 || node.tag === HostText$1) { return node; } else if (node.child) { node.child['return'] = node; node = node.child; continue; } if (node === currentParent) { return null; } while (!node.sibling) { if (!node['return'] || node['return'] === currentParent) { return null; } node = node['return']; } node.sibling['return'] = node['return']; node = node.sibling; } // Flow needs the return null here, but ESLint complains about it. // eslint-disable-next-line no-unreachable return null; }; var findCurrentHostFiberWithNoPortals = function (parent) { var currentParent = findCurrentFiberUsingSlowPath(parent); if (!currentParent) { return null; } // Next we'll drill down this component to find the first HostComponent/Text. var node = currentParent; while (true) { if (node.tag === HostComponent$1 || node.tag === HostText$1) { return node; } else if (node.child && node.tag !== HostPortal) { node.child['return'] = node; node = node.child; continue; } if (node === currentParent) { return null; } while (!node.sibling) { if (!node['return'] || node['return'] === currentParent) { return null; } node = node['return']; } node.sibling['return'] = node['return']; node = node.sibling; } // Flow needs the return null here, but ESLint complains about it. // eslint-disable-next-line no-unreachable return null; }; var ReactFiberTreeReflection = { isFiberMounted: isFiberMounted, isMounted: isMounted, findCurrentFiberUsingSlowPath: findCurrentFiberUsingSlowPath_1, findCurrentHostFiber: findCurrentHostFiber, findCurrentHostFiberWithNoPortals: findCurrentHostFiberWithNoPortals }; var ReactErrorUtils = { // Used by Fiber to simulate a try-catch. _caughtError: null, _hasCaughtError: false, // Used by event system to capture/rethrow the first error. _rethrowError: null, _hasRethrowError: false, injection: { injectErrorUtils: function (injectedErrorUtils) { !(typeof injectedErrorUtils.invokeGuardedCallback === 'function') ? invariant(false, 'Injected invokeGuardedCallback() must be a function.') : void 0; invokeGuardedCallback = injectedErrorUtils.invokeGuardedCallback; } }, /** * Call a function while guarding against errors that happens within it. * Returns an error if it throws, otherwise null. * * In production, this is implemented using a try-catch. The reason we don't * use a try-catch directly is so that we can swap out a different * implementation in DEV mode. * * @param {String} name of the guard to use for logging or debugging * @param {Function} func The function to invoke * @param {*} context The context to use when calling the function * @param {...*} args Arguments for function */ invokeGuardedCallback: function (name, func, context, a, b, c, d, e, f) { invokeGuardedCallback.apply(ReactErrorUtils, arguments); }, /** * Same as invokeGuardedCallback, but instead of returning an error, it stores * it in a global so it can be rethrown by `rethrowCaughtError` later. * TODO: See if _caughtError and _rethrowError can be unified. * * @param {String} name of the guard to use for logging or debugging * @param {Function} func The function to invoke * @param {*} context The context to use when calling the function * @param {...*} args Arguments for function */ invokeGuardedCallbackAndCatchFirstError: function (name, func, context, a, b, c, d, e, f) { ReactErrorUtils.invokeGuardedCallback.apply(this, arguments); if (ReactErrorUtils.hasCaughtError()) { var error = ReactErrorUtils.clearCaughtError(); if (!ReactErrorUtils._hasRethrowError) { ReactErrorUtils._hasRethrowError = true; ReactErrorUtils._rethrowError = error; } } }, /** * During execution of guarded functions we will capture the first error which * we will rethrow to be handled by the top level error handler. */ rethrowCaughtError: function () { return rethrowCaughtError.apply(ReactErrorUtils, arguments); }, hasCaughtError: function () { return ReactErrorUtils._hasCaughtError; }, clearCaughtError: function () { if (ReactErrorUtils._hasCaughtError) { var error = ReactErrorUtils._caughtError; ReactErrorUtils._caughtError = null; ReactErrorUtils._hasCaughtError = false; return error; } else { invariant(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.'); } } }; var invokeGuardedCallback = function (name, func, context, a, b, c, d, e, f) { ReactErrorUtils._hasCaughtError = false; ReactErrorUtils._caughtError = null; var funcArgs = Array.prototype.slice.call(arguments, 3); try { func.apply(context, funcArgs); } catch (error) { ReactErrorUtils._caughtError = error; ReactErrorUtils._hasCaughtError = true; } }; { // In DEV mode, we swap out invokeGuardedCallback for a special version // that plays more nicely with the browser's DevTools. The idea is to preserve // "Pause on exceptions" behavior. Because React wraps all user-provided // functions in invokeGuardedCallback, and the production version of // invokeGuardedCallback uses a try-catch, all user exceptions are treated // like caught exceptions, and the DevTools won't pause unless the developer // takes the extra step of enabling pause on caught exceptions. This is // untintuitive, though, because even though React has caught the error, from // the developer's perspective, the error is uncaught. // // To preserve the expected "Pause on exceptions" behavior, we don't use a // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake // DOM node, and call the user-provided callback from inside an event handler // for that fake event. If the callback throws, the error is "captured" using // a global event handler. But because the error happens in a different // event loop context, it does not interrupt the normal program flow. // Effectively, this gives us try-catch behavior without actually using // try-catch. Neat! // Check that the browser supports the APIs we need to implement our special // DEV version of invokeGuardedCallback if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') { var fakeNode = document.createElement('react'); var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) { // Keeps track of whether the user-provided callback threw an error. We // set this to true at the beginning, then set it to false right after // calling the function. If the function errors, `didError` will never be // set to false. This strategy works even if the browser is flaky and // fails to call our global error handler, because it doesn't rely on // the error event at all. var didError = true; // Create an event handler for our fake event. We will synchronously // dispatch our fake event using `dispatchEvent`. Inside the handler, we // call the user-provided callback. var funcArgs = Array.prototype.slice.call(arguments, 3); function callCallback() { // We immediately remove the callback from event listeners so that // nested `invokeGuardedCallback` calls do not clash. Otherwise, a // nested call would trigger the fake event handlers of any call higher // in the stack. fakeNode.removeEventListener(evtType, callCallback, false); func.apply(context, funcArgs); didError = false; } // Create a global error event handler. We use this to capture the value // that was thrown. It's possible that this error handler will fire more // than once; for example, if non-React code also calls `dispatchEvent` // and a handler for that event throws. We should be resilient to most of // those cases. Even if our error event handler fires more than once, the // last error event is always used. If the callback actually does error, // we know that the last error event is the correct one, because it's not // possible for anything else to have happened in between our callback // erroring and the code that follows the `dispatchEvent` call below. If // the callback doesn't error, but the error event was fired, we know to // ignore it because `didError` will be false, as described above. var error = void 0; // Use this to track whether the error event is ever called. var didSetError = false; var isCrossOriginError = false; function onError(event) { error = event.error; didSetError = true; if (error === null && event.colno === 0 && event.lineno === 0) { isCrossOriginError = true; } } // Create a fake event type. var evtType = 'react-' + (name ? name : 'invokeguardedcallback'); // Attach our event handlers window.addEventListener('error', onError); fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function // errors, it will trigger our global error handler. var evt = document.createEvent('Event'); evt.initEvent(evtType, false, false); fakeNode.dispatchEvent(evt); if (didError) { if (!didSetError) { // The callback errored, but the error event never fired. error = new Error('An error was thrown inside one of your components, but React ' + "doesn't know what it was. This is likely due to browser " + 'flakiness. React does its best to preserve the "Pause on ' + 'exceptions" behavior of the DevTools, which requires some ' + "DEV-mode only tricks. It's possible that these don't work in " + 'your browser. Try triggering the error in production mode, ' + 'or switching to a modern browser. If you suspect that this is ' + 'actually an issue with React, please file an issue.'); } else if (isCrossOriginError) { error = new Error("A cross-origin error was thrown. React doesn't have access to " + 'the actual error object in development. ' + 'See https://fb.me/react-crossorigin-error for more information.'); } ReactErrorUtils._hasCaughtError = true; ReactErrorUtils._caughtError = error; } else { ReactErrorUtils._hasCaughtError = false; ReactErrorUtils._caughtError = null; } // Remove our event listeners window.removeEventListener('error', onError); }; invokeGuardedCallback = invokeGuardedCallbackDev; } } var rethrowCaughtError = function () { if (ReactErrorUtils._hasRethrowError) { var error = ReactErrorUtils._rethrowError; ReactErrorUtils._rethrowError = null; ReactErrorUtils._hasRethrowError = false; throw error; } }; var ReactErrorUtils_1 = ReactErrorUtils; { var warning$2 = require$$0; } /** * Injected dependencies: */ /** * - `ComponentTree`: [required] Module that can convert between React instances * and actual node references. */ var ComponentTree; var injection = { injectComponentTree: function (Injected) { ComponentTree = Injected; { warning$2(Injected && Injected.getNodeFromInstance && Injected.getInstanceFromNode, 'EventPluginUtils.injection.injectComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.'); } } }; function isEndish(topLevelType) { return topLevelType === 'topMouseUp' || topLevelType === 'topTouchEnd' || topLevelType === 'topTouchCancel'; } function isMoveish(topLevelType) { return topLevelType === 'topMouseMove' || topLevelType === 'topTouchMove'; } function isStartish(topLevelType) { return topLevelType === 'topMouseDown' || topLevelType === 'topTouchStart'; } var validateEventDispatches; { validateEventDispatches = function (event) { var dispatchListeners = event._dispatchListeners; var dispatchInstances = event._dispatchInstances; var listenersIsArr = Array.isArray(dispatchListeners); var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0; var instancesIsArr = Array.isArray(dispatchInstances); var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0; warning$2(instancesIsArr === listenersIsArr && instancesLen === listenersLen, 'EventPluginUtils: Invalid `event`.'); }; } /** * Dispatch the event to the listener. * @param {SyntheticEvent} event SyntheticEvent to handle * @param {boolean} simulated If the event is simulated (changes exn behavior) * @param {function} listener Application-level callback * @param {*} inst Internal component instance */ function executeDispatch(event, simulated, listener, inst) { var type = event.type || 'unknown-event'; event.currentTarget = EventPluginUtils.getNodeFromInstance(inst); ReactErrorUtils_1.invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event); event.currentTarget = null; } /** * Standard/simple iteration through an event's collected dispatches. */ function executeDispatchesInOrder(event, simulated) { var dispatchListeners = event._dispatchListeners; var dispatchInstances = event._dispatchInstances; { validateEventDispatches(event); } if (Array.isArray(dispatchListeners)) { for (var i = 0; i < dispatchListeners.length; i++) { if (event.isPropagationStopped()) { break; } // Listeners and Instances are two parallel arrays that are always in sync. executeDispatch(event, simulated, dispatchListeners[i], dispatchInstances[i]); } } else if (dispatchListeners) { executeDispatch(event, simulated, dispatchListeners, dispatchInstances); } event._dispatchListeners = null; event._dispatchInstances = null; } /** * Standard/simple iteration through an event's collected dispatches, but stops * at the first dispatch execution returning true, and returns that id. * * @return {?string} id of the first dispatch execution who's listener returns * true, or null if no listener returned true. */ function executeDispatchesInOrderStopAtTrueImpl(event) { var dispatchListeners = event._dispatchListeners; var dispatchInstances = event._dispatchInstances; { validateEventDispatches(event); } if (Array.isArray(dispatchListeners)) { for (var i = 0; i < dispatchListeners.length; i++) { if (event.isPropagationStopped()) { break; } // Listeners and Instances are two parallel arrays that are always in sync. if (dispatchListeners[i](event, dispatchInstances[i])) { return dispatchInstances[i]; } } } else if (dispatchListeners) { if (dispatchListeners(event, dispatchInstances)) { return dispatchInstances; } } return null; } /** * @see executeDispatchesInOrderStopAtTrueImpl */ function executeDispatchesInOrderStopAtTrue(event) { var ret = executeDispatchesInOrderStopAtTrueImpl(event); event._dispatchInstances = null; event._dispatchListeners = null; return ret; } /** * Execution of a "direct" dispatch - there must be at most one dispatch * accumulated on the event or it is considered an error. It doesn't really make * sense for an event with multiple dispatches (bubbled) to keep track of the * return values at each dispatch execution, but it does tend to make sense when * dealing with "direct" dispatches. * * @return {*} The return value of executing the single dispatch. */ function executeDirectDispatch(event) { { validateEventDispatches(event); } var dispatchListener = event._dispatchListeners; var dispatchInstance = event._dispatchInstances; !!Array.isArray(dispatchListener) ? invariant(false, 'executeDirectDispatch(...): Invalid `event`.') : void 0; event.currentTarget = dispatchListener ? EventPluginUtils.getNodeFromInstance(dispatchInstance) : null; var res = dispatchListener ? dispatchListener(event) : null; event.currentTarget = null; event._dispatchListeners = null; event._dispatchInstances = null; return res; } /** * @param {SyntheticEvent} event * @return {boolean} True iff number of dispatches accumulated is greater than 0. */ function hasDispatches(event) { return !!event._dispatchListeners; } /** * General utilities that are useful in creating custom Event Plugins. */ var EventPluginUtils = { isEndish: isEndish, isMoveish: isMoveish, isStartish: isStartish, executeDirectDispatch: executeDirectDispatch, executeDispatchesInOrder: executeDispatchesInOrder, executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue, hasDispatches: hasDispatches, getFiberCurrentPropsFromNode: function (node) { return ComponentTree.getFiberCurrentPropsFromNode(node); }, getInstanceFromNode: function (node) { return ComponentTree.getInstanceFromNode(node); }, getNodeFromInstance: function (node) { return ComponentTree.getNodeFromInstance(node); }, injection: injection }; var EventPluginUtils_1 = EventPluginUtils; // Use to restore controlled state after a change event has fired. var fiberHostComponent = null; var ReactControlledComponentInjection = { injectFiberControlledHostComponent: function (hostComponentImpl) { // The fiber implementation doesn't use dynamic dispatch so we need to // inject the implementation. fiberHostComponent = hostComponentImpl; } }; var restoreTarget = null; var restoreQueue = null; function restoreStateOfTarget(target) { // We perform this translation at the end of the event loop so that we // always receive the correct fiber here var internalInstance = EventPluginUtils_1.getInstanceFromNode(target); if (!internalInstance) { // Unmounted return; } if (typeof internalInstance.tag === 'number') { !(fiberHostComponent && typeof fiberHostComponent.restoreControlledState === 'function') ? invariant(false, 'Fiber needs to be injected to handle a fiber target for controlled events. This error is likely caused by a bug in React. Please file an issue.') : void 0; var props = EventPluginUtils_1.getFiberCurrentPropsFromNode(internalInstance.stateNode); fiberHostComponent.restoreControlledState(internalInstance.stateNode, internalInstance.type, props); return; } !(typeof internalInstance.restoreControlledState === 'function') ? invariant(false, 'The internal instance must be a React host component. This error is likely caused by a bug in React. Please file an issue.') : void 0; // If it is not a Fiber, we can just use dynamic dispatch. internalInstance.restoreControlledState(); } var ReactControlledComponent = { injection: ReactControlledComponentInjection, enqueueStateRestore: function (target) { if (restoreTarget) { if (restoreQueue) { restoreQueue.push(target); } else { restoreQueue = [target]; } } else { restoreTarget = target; } }, restoreStateIfNeeded: function () { if (!restoreTarget) { return; } var target = restoreTarget; var queuedTargets = restoreQueue; restoreTarget = null; restoreQueue = null; restoreStateOfTarget(target); if (queuedTargets) { for (var i = 0; i < queuedTargets.length; i++) { restoreStateOfTarget(queuedTargets[i]); } } } }; var ReactControlledComponent_1 = ReactControlledComponent; // Used as a way to call batchedUpdates when we don't know if we're in a Fiber // or Stack context. Such as when we're dispatching events or if third party // libraries need to call batchedUpdates. Eventually, this API will go away when // everything is batched by default. We'll then have a similar API to opt-out of // scheduled work and instead do synchronous work. // Defaults var stackBatchedUpdates = function (fn, a, b, c, d, e) { return fn(a, b, c, d, e); }; var fiberBatchedUpdates = function (fn, bookkeeping) { return fn(bookkeeping); }; function performFiberBatchedUpdates(fn, bookkeeping) { // If we have Fiber loaded, we need to wrap this in a batching call so that // Fiber can apply its default priority for this call. return fiberBatchedUpdates(fn, bookkeeping); } function batchedUpdates(fn, bookkeeping) { // We first perform work with the stack batching strategy, by passing our // indirection to it. return stackBatchedUpdates(performFiberBatchedUpdates, fn, bookkeeping); } var isNestingBatched = false; function batchedUpdatesWithControlledComponents(fn, bookkeeping) { if (isNestingBatched) { // If we are currently inside another batch, we need to wait until it // fully completes before restoring state. Therefore, we add the target to // a queue of work. return batchedUpdates(fn, bookkeeping); } isNestingBatched = true; try { return batchedUpdates(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. isNestingBatched = false; ReactControlledComponent_1.restoreStateIfNeeded(); } } var ReactGenericBatchingInjection = { injectStackBatchedUpdates: function (_batchedUpdates) { stackBatchedUpdates = _batchedUpdates; }, injectFiberBatchedUpdates: function (_batchedUpdates) { fiberBatchedUpdates = _batchedUpdates; } }; var ReactGenericBatching = { batchedUpdates: batchedUpdatesWithControlledComponents, injection: ReactGenericBatchingInjection }; var ReactGenericBatching_1 = ReactGenericBatching; var TEXT_NODE$1 = HTMLNodeType_1.TEXT_NODE; /** * Gets the target node from a native browser event by accounting for * inconsistencies in browser DOM APIs. * * @param {object} nativeEvent Native browser event. * @return {DOMEventTarget} Target node. */ function getEventTarget(nativeEvent) { var target = nativeEvent.target || nativeEvent.srcElement || window; // Normalize SVG <use> element events #4963 if (target.correspondingUseElement) { target = target.correspondingUseElement; } // Safari may fire events on text nodes (Node.TEXT_NODE is 3). // @see http://www.quirksmode.org/js/events_properties.html return target.nodeType === TEXT_NODE$1 ? target.parentNode : target; } var getEventTarget_1 = getEventTarget; var HostRoot = ReactTypeOfWork.HostRoot; var CALLBACK_BOOKKEEPING_POOL_SIZE = 10; var callbackBookkeepingPool = []; /** * Find the deepest React component completely containing the root of the * passed-in instance (for use when entire React trees are nested within each * other). If React trees are not nested, returns null. */ function findRootContainerNode(inst) { // TODO: It may be a good idea to cache this to prevent unnecessary DOM // traversal, but caching is difficult to do correctly without using a // mutation observer to listen for all DOM changes. if (typeof inst.tag === 'number') { while (inst['return']) { inst = inst['return']; } if (inst.tag !== HostRoot) { // This can happen if we're in a detached tree. return null; } return inst.stateNode.containerInfo; } else { while (inst._hostParent) { inst = inst._hostParent; } var rootNode = ReactDOMComponentTree_1.getNodeFromInstance(inst); return rootNode.parentNode; } } // Used to store ancestor hierarchy in top level callback function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst) { if (callbackBookkeepingPool.length) { var instance = callbackBookkeepingPool.pop(); instance.topLevelType = topLevelType; instance.nativeEvent = nativeEvent; instance.targetInst = targetInst; return instance; } return { topLevelType: topLevelType, nativeEvent: nativeEvent, targetInst: targetInst, ancestors: [] }; } function releaseTopLevelCallbackBookKeeping(instance) { instance.topLevelType = null; instance.nativeEvent = null; instance.targetInst = null; instance.ancestors.length = 0; if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) { callbackBookkeepingPool.push(instance); } } function handleTopLevelImpl(bookKeeping) { var targetInst = bookKeeping.targetInst; // Loop through the hierarchy, in case there's any nested components. // It's important that we build the array of ancestors before calling any // event handlers, because event handlers can modify the DOM, leading to // inconsistencies with ReactMount's node cache. See #1105. var ancestor = targetInst; do { if (!ancestor) { bookKeeping.ancestors.push(ancestor); break; } var root = findRootContainerNode(ancestor); if (!root) { break; } bookKeeping.ancestors.push(ancestor); ancestor = ReactDOMComponentTree_1.getClosestInstanceFromNode(root); } while (ancestor); for (var i = 0; i < bookKeeping.ancestors.length; i++) { targetInst = bookKeeping.ancestors[i]; ReactDOMEventListener._handleTopLevel(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget_1(bookKeeping.nativeEvent)); } } var ReactDOMEventListener = { _enabled: true, _handleTopLevel: null, setHandleTopLevel: function (handleTopLevel) { ReactDOMEventListener._handleTopLevel = handleTopLevel; }, setEnabled: function (enabled) { ReactDOMEventListener._enabled = !!enabled; }, isEnabled: function () { return ReactDOMEventListener._enabled; }, /** * Traps top-level events by using event bubbling. * * @param {string} topLevelType Record from `BrowserEventConstants`. * @param {string} handlerBaseName Event name (e.g. "click"). * @param {object} element Element on which to attach listener. * @return {?object} An object with a remove function which will forcefully * remove the listener. * @internal */ trapBubbledEvent: function (topLevelType, handlerBaseName, element) { if (!element) { return null; } return EventListener.listen(element, handlerBaseName, ReactDOMEventListener.dispatchEvent.bind(null, topLevelType)); }, /** * Traps a top-level event by using event capturing. * * @param {string} topLevelType Record from `BrowserEventConstants`. * @param {string} handlerBaseName Event name (e.g. "click"). * @param {object} element Element on which to attach listener. * @return {?object} An object with a remove function which will forcefully * remove the listener. * @internal */ trapCapturedEvent: function (topLevelType, handlerBaseName, element) { if (!element) { return null; } return EventListener.capture(element, handlerBaseName, ReactDOMEventListener.dispatchEvent.bind(null, topLevelType)); }, dispatchEvent: function (topLevelType, nativeEvent) { if (!ReactDOMEventListener._enabled) { return; } var nativeEventTarget = getEventTarget_1(nativeEvent); var targetInst = ReactDOMComponentTree_1.getClosestInstanceFromNode(nativeEventTarget); if (targetInst !== null && typeof targetInst.tag === 'number' && !ReactFiberTreeReflection.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 // event on a non-React tree). We might also consider queueing events and // dispatching them after the mount. targetInst = null; } var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst); try { // Event queue being processed in the same cycle allows // `preventDefault`. ReactGenericBatching_1.batchedUpdates(handleTopLevelImpl, bookKeeping); } finally { releaseTopLevelCallbackBookKeeping(bookKeeping); } } }; var ReactDOMEventListener_1 = ReactDOMEventListener; /** * Accumulates items that must not be null or undefined into the first one. This * is used to conserve memory by avoiding array allocations, and thus sacrifices * API cleanness. Since `current` can be null before being passed in and not * null after this function, make sure to assign it back to `current`: * * `a = accumulateInto(a, b);` * * This API should be sparingly used. Try `accumulate` for something cleaner. * * @return {*|array<*>} An accumulation of items. */ function accumulateInto(current, next) { !(next != null) ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : void 0; if (current == null) { return next; } // Both are not empty. Warning: Never call x.concat(y) when you are not // certain that x is an Array (x could be a string with concat method). if (Array.isArray(current)) { if (Array.isArray(next)) { current.push.apply(current, next); return current; } current.push(next); return current; } if (Array.isArray(next)) { // A bit too dangerous to mutate `next`. return [current].concat(next); } return [current, next]; } var accumulateInto_1 = accumulateInto; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule forEachAccumulated * */ /** * @param {array} arr an "accumulation" of items which is either an Array or * a single item. Useful when paired with the `accumulate` module. This is a * simple utility that allows us to reason about a collection of items, but * handling the case when there is exactly one item (and we do not need to * allocate an array). * @param {function} cb Callback invoked with each element or a collection. * @param {?} [scope] Scope used as `this` in a callback. */ function forEachAccumulated(arr, cb, scope) { if (Array.isArray(arr)) { arr.forEach(cb, scope); } else if (arr) { cb.call(scope, arr); } } var forEachAccumulated_1 = forEachAccumulated; /** * Internal queue of events that have accumulated their dispatches and are * waiting to have their dispatches executed. */ var eventQueue = null; /** * Dispatches an event and releases it back into the pool, unless persistent. * * @param {?object} event Synthetic event to be dispatched. * @param {boolean} simulated If the event is simulated (changes exn behavior) * @private */ var executeDispatchesAndRelease = function (event, simulated) { if (event) { EventPluginUtils_1.executeDispatchesInOrder(event, simulated); if (!event.isPersistent()) { event.constructor.release(event); } } }; var executeDispatchesAndReleaseSimulated = function (e) { return executeDispatchesAndRelease(e, true); }; var executeDispatchesAndReleaseTopLevel = function (e) { return executeDispatchesAndRelease(e, false); }; function isInteractive(tag) { return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea'; } function shouldPreventMouseEvent(name, type, props) { switch (name) { case 'onClick': case 'onClickCapture': case 'onDoubleClick': case 'onDoubleClickCapture': case 'onMouseDown': case 'onMouseDownCapture': case 'onMouseMove': case 'onMouseMoveCapture': case 'onMouseUp': case 'onMouseUpCapture': return !!(props.disabled && isInteractive(type)); default: return false; } } /** * This is a unified interface for event plugins to be installed and configured. * * Event plugins can implement the following properties: * * `extractEvents` {function(string, DOMEventTarget, string, object): *} * Required. When a top-level event is fired, this method is expected to * extract synthetic events that will in turn be queued and dispatched. * * `eventTypes` {object} * Optional, plugins that fire events must publish a mapping of registration * names that are used to register listeners. Values of this mapping must * be objects that contain `registrationName` or `phasedRegistrationNames`. * * `executeDispatch` {function(object, function, string)} * Optional, allows plugins to override how an event gets dispatched. By * default, the listener is simply invoked. * * Each plugin that is injected into `EventsPluginHub` is immediately operable. * * @public */ var EventPluginHub = { /** * Methods for injecting dependencies. */ injection: { /** * @param {array} InjectedEventPluginOrder * @public */ injectEventPluginOrder: EventPluginRegistry_1.injectEventPluginOrder, /** * @param {object} injectedNamesToPlugins Map from names to plugin modules. */ injectEventPluginsByName: EventPluginRegistry_1.injectEventPluginsByName }, /** * @param {object} inst The instance, which is the source of events. * @param {string} registrationName Name of listener (e.g. `onClick`). * @return {?function} The stored callback. */ getListener: function (inst, registrationName) { var listener; // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not // live here; needs to be moved to a better place soon if (typeof inst.tag === 'number') { var stateNode = inst.stateNode; if (!stateNode) { // Work in progress (ex: onload events in incremental mode). return null; } var props = EventPluginUtils_1.getFiberCurrentPropsFromNode(stateNode); if (!props) { // Work in progress. return null; } listener = props[registrationName]; if (shouldPreventMouseEvent(registrationName, inst.type, props)) { return null; } } else { var currentElement = inst._currentElement; if (typeof currentElement === 'string' || typeof currentElement === 'number') { // Text node, let it bubble through. return null; } if (!inst._rootNodeID) { // If the instance is already unmounted, we have no listeners. return null; } var _props = currentElement.props; listener = _props[registrationName]; if (shouldPreventMouseEvent(registrationName, currentElement.type, _props)) { return null; } } !(!listener || typeof listener === 'function') ? invariant(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener) : void 0; return listener; }, /** * Allows registered plugins an opportunity to extract events from top-level * native browser events. * * @return {*} An accumulation of synthetic events. * @internal */ extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { var events; var plugins = EventPluginRegistry_1.plugins; for (var i = 0; i < plugins.length; i++) { // Not every plugin in the ordering may be loaded at runtime. var possiblePlugin = plugins[i]; if (possiblePlugin) { var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); if (extractedEvents) { events = accumulateInto_1(events, extractedEvents); } } } return events; }, /** * Enqueues a synthetic event that should be dispatched when * `processEventQueue` is invoked. * * @param {*} events An accumulation of synthetic events. * @internal */ enqueueEvents: function (events) { if (events) { eventQueue = accumulateInto_1(eventQueue, events); } }, /** * Dispatches all synthetic events on the event queue. * * @internal */ processEventQueue: function (simulated) { // Set `eventQueue` to null before processing it so that we can tell if more // events get enqueued while processing. var processingEventQueue = eventQueue; eventQueue = null; if (simulated) { forEachAccumulated_1(processingEventQueue, executeDispatchesAndReleaseSimulated); } else { forEachAccumulated_1(processingEventQueue, executeDispatchesAndReleaseTopLevel); } !!eventQueue ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : void 0; // This would be a good time to rethrow if any of the event handlers threw. ReactErrorUtils_1.rethrowCaughtError(); } }; var EventPluginHub_1 = EventPluginHub; function runEventQueueInBatch(events) { EventPluginHub_1.enqueueEvents(events); EventPluginHub_1.processEventQueue(false); } var ReactEventEmitterMixin = { /** * Streams a fired top-level event to `EventPluginHub` where plugins have the * opportunity to create `ReactEvent`s to be dispatched. */ handleTopLevel: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { var events = EventPluginHub_1.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); runEventQueueInBatch(events); } }; var ReactEventEmitterMixin_1 = ReactEventEmitterMixin; var useHasFeature; if (ExecutionEnvironment.canUseDOM) { useHasFeature = document.implementation && document.implementation.hasFeature && // always returns true in newer browsers as per the standard. // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature document.implementation.hasFeature('', '') !== true; } /** * Checks if an event is supported in the current execution environment. * * NOTE: This will not work correctly for non-generic events such as `change`, * `reset`, `load`, `error`, and `select`. * * Borrows from Modernizr. * * @param {string} eventNameSuffix Event name, e.g. "click". * @param {?boolean} capture Check if the capture phase is supported. * @return {boolean} True if the event is supported. * @internal * @license Modernizr 3.0.0pre (Custom Build) | MIT */ function isEventSupported(eventNameSuffix, capture) { if (!ExecutionEnvironment.canUseDOM || capture && !('addEventListener' in document)) { return false; } var eventName = 'on' + eventNameSuffix; var isSupported = eventName in document; if (!isSupported) { var element = document.createElement('div'); element.setAttribute(eventName, 'return;'); isSupported = typeof element[eventName] === 'function'; } if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') { // This is the only way to test support for the `wheel` event in IE9+. isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); } return isSupported; } var isEventSupported_1 = isEventSupported; /** * Generate a mapping of standard vendor prefixes using the defined style property and event name. * * @param {string} styleProp * @param {string} eventName * @returns {object} */ function makePrefixMap(styleProp, eventName) { var prefixes = {}; prefixes[styleProp.toLowerCase()] = eventName.toLowerCase(); prefixes['Webkit' + styleProp] = 'webkit' + eventName; prefixes['Moz' + styleProp] = 'moz' + eventName; prefixes['ms' + styleProp] = 'MS' + eventName; prefixes['O' + styleProp] = 'o' + eventName.toLowerCase(); return prefixes; } /** * A list of event names to a configurable list of vendor prefixes. */ var vendorPrefixes = { animationend: makePrefixMap('Animation', 'AnimationEnd'), animationiteration: makePrefixMap('Animation', 'AnimationIteration'), animationstart: makePrefixMap('Animation', 'AnimationStart'), transitionend: makePrefixMap('Transition', 'TransitionEnd') }; /** * Event names that have already been detected and prefixed (if applicable). */ var prefixedEventNames = {}; /** * Element to check for prefixes on. */ var style = {}; /** * Bootstrap if a DOM exists. */ if (ExecutionEnvironment.canUseDOM) { style = document.createElement('div').style; // On some platforms, in particular some releases of Android 4.x, // the un-prefixed "animation" and "transition" properties are defined on the // style object but the events that fire will still be prefixed, so we need // to check if the un-prefixed events are usable, and if not remove them from the map. if (!('AnimationEvent' in window)) { delete vendorPrefixes.animationend.animation; delete vendorPrefixes.animationiteration.animation; delete vendorPrefixes.animationstart.animation; } // Same as above if (!('TransitionEvent' in window)) { delete vendorPrefixes.transitionend.transition; } } /** * Attempts to determine the correct vendor prefixed event name. * * @param {string} eventName * @returns {string} */ function getVendorPrefixedEventName(eventName) { if (prefixedEventNames[eventName]) { return prefixedEventNames[eventName]; } else if (!vendorPrefixes[eventName]) { return eventName; } var prefixMap = vendorPrefixes[eventName]; for (var styleProp in prefixMap) { if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) { return prefixedEventNames[eventName] = prefixMap[styleProp]; } } return ''; } var getVendorPrefixedEventName_1 = getVendorPrefixedEventName; /** * Types of raw signals from the browser caught at the top level. * * For events like 'submit' which don't consistently bubble (which we * trap at a lower node than `document`), binding at `document` would * cause duplicate events so we don't include them here. */ var topLevelTypes$1 = { topAbort: 'abort', topAnimationEnd: getVendorPrefixedEventName_1('animationend') || 'animationend', topAnimationIteration: getVendorPrefixedEventName_1('animationiteration') || 'animationiteration', topAnimationStart: getVendorPrefixedEventName_1('animationstart') || 'animationstart', topBlur: 'blur', topCancel: 'cancel', topCanPlay: 'canplay', topCanPlayThrough: 'canplaythrough', topChange: 'change', topClick: 'click', topClose: 'close', topCompositionEnd: 'compositionend', topCompositionStart: 'compositionstart', topCompositionUpdate: 'compositionupdate', topContextMenu: 'contextmenu', topCopy: 'copy', topCut: 'cut', topDoubleClick: 'dblclick', topDrag: 'drag', topDragEnd: 'dragend', topDragEnter: 'dragenter', topDragExit: 'dragexit', topDragLeave: 'dragleave', topDragOver: 'dragover', topDragStart: 'dragstart', topDrop: 'drop', topDurationChange: 'durationchange', topEmptied: 'emptied', topEncrypted: 'encrypted', topEnded: 'ended', topError: 'error', topFocus: 'focus', topInput: 'input', topKeyDown: 'keydown', topKeyPress: 'keypress', topKeyUp: 'keyup', topLoadedData: 'loadeddata', topLoad: 'load', topLoadedMetadata: 'loadedmetadata', topLoadStart: 'loadstart', topMouseDown: 'mousedown', topMouseMove: 'mousemove', topMouseOut: 'mouseout', topMouseOver: 'mouseover', topMouseUp: 'mouseup', topPaste: 'paste', topPause: 'pause', topPlay: 'play', topPlaying: 'playing', topProgress: 'progress', topRateChange: 'ratechange', topScroll: 'scroll', topSeeked: 'seeked', topSeeking: 'seeking', topSelectionChange: 'selectionchange', topStalled: 'stalled', topSuspend: 'suspend', topTextInput: 'textInput', topTimeUpdate: 'timeupdate', topToggle: 'toggle', topTouchCancel: 'touchcancel', topTouchEnd: 'touchend', topTouchMove: 'touchmove', topTouchStart: 'touchstart', topTransitionEnd: getVendorPrefixedEventName_1('transitionend') || 'transitionend', topVolumeChange: 'volumechange', topWaiting: 'waiting', topWheel: 'wheel' }; var BrowserEventConstants = { topLevelTypes: topLevelTypes$1 }; var BrowserEventConstants_1 = BrowserEventConstants; var topLevelTypes = BrowserEventConstants_1.topLevelTypes; /** * Summary of `ReactBrowserEventEmitter` event handling: * * - Top-level delegation is used to trap most native browser events. This * may only occur in the main thread and is the responsibility of * ReactDOMEventListener, which is injected and can therefore support * pluggable event sources. This is the only work that occurs in the main * thread. * * - We normalize and de-duplicate events to account for browser quirks. This * may be done in the worker thread. * * - Forward these native events (with the associated top-level type used to * trap it) to `EventPluginHub`, which in turn will ask plugins if they want * to extract any synthetic events. * * - The `EventPluginHub` will then process each event by annotating them with * "dispatches", a sequence of listeners and IDs that care about that event. * * - The `EventPluginHub` then dispatches the events. * * Overview of React and the event system: * * +------------+ . * | DOM | . * +------------+ . * | . * v . * +------------+ . * | ReactEvent | . * | Listener | . * +------------+ . +-----------+ * | . +--------+|SimpleEvent| * | . | |Plugin | * +-----|------+ . v +-----------+ * | | | . +--------------+ +------------+ * | +-----------.--->|EventPluginHub| | Event | * | | . | | +-----------+ | Propagators| * | ReactEvent | . | | |TapEvent | |------------| * | Emitter | . | |<---+|Plugin | |other plugin| * | | . | | +-----------+ | utilities | * | +-----------.--->| | +------------+ * | | | . +--------------+ * +-----|------+ . ^ +-----------+ * | . | |Enter/Leave| * + . +-------+|Plugin | * +-------------+ . +-----------+ * | application | . * |-------------| . * | | . * | | . * +-------------+ . * . * React Core . General Purpose Event Plugin System */ var alreadyListeningTo = {}; var reactTopListenersCounter = 0; /** * 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]] = {}; } return alreadyListeningTo[mountAt[topListenersIDKey]]; } var ReactBrowserEventEmitter = _assign({}, ReactEventEmitterMixin_1, { /** * Sets whether or not any created callbacks should be enabled. * * @param {boolean} enabled True if callbacks should be enabled. */ setEnabled: function (enabled) { if (ReactDOMEventListener_1) { ReactDOMEventListener_1.setEnabled(enabled); } }, /** * @return {boolean} True if callbacks are enabled. */ isEnabled: function () { return !!(ReactDOMEventListener_1 && ReactDOMEventListener_1.isEnabled()); }, /** * We listen for bubbled touch events on the document object. * * Firefox v8.01 (and possibly others) exhibited strange behavior when * mounting `onmousemove` events at some node that was not the document * element. The symptoms were that if your mouse is not moving over something * contained within that mount point (for example on the background) the * top-level listeners for `onmousemove` won't be called. However, if you * register the `mousemove` on the document object, then it will of course * catch all `mousemove`s. This along with iOS quirks, justifies restricting * top-level listeners to the document object only, at least for these * movement types of events and possibly all events. * * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html * * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but * they bubble to document. * * @param {string} registrationName Name of listener (e.g. `onClick`). * @param {object} contentDocumentHandle Document which owns the container */ listenTo: function (registrationName, contentDocumentHandle) { var mountAt = contentDocumentHandle; var isListening = getListeningForDocument(mountAt); var dependencies = EventPluginRegistry_1.registrationNameDependencies[registrationName]; for (var i = 0; i < dependencies.length; i++) { var dependency = dependencies[i]; if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) { if (dependency === 'topWheel') { if (isEventSupported_1('wheel')) { ReactDOMEventListener_1.trapBubbledEvent('topWheel', 'wheel', mountAt); } else if (isEventSupported_1('mousewheel')) { ReactDOMEventListener_1.trapBubbledEvent('topWheel', 'mousewheel', mountAt); } else { // Firefox needs to capture a different mouse scroll event. // @see http://www.quirksmode.org/dom/events/tests/scroll.html ReactDOMEventListener_1.trapBubbledEvent('topWheel', 'DOMMouseScroll', mountAt); } } else if (dependency === 'topScroll') { ReactDOMEventListener_1.trapCapturedEvent('topScroll', 'scroll', mountAt); } else if (dependency === 'topFocus' || dependency === 'topBlur') { ReactDOMEventListener_1.trapCapturedEvent('topFocus', 'focus', mountAt); ReactDOMEventListener_1.trapCapturedEvent('topBlur', 'blur', mountAt); // to make sure blur and focus event listeners are only attached once isListening.topBlur = true; isListening.topFocus = true; } else if (dependency === 'topCancel') { if (isEventSupported_1('cancel', true)) { ReactDOMEventListener_1.trapCapturedEvent('topCancel', 'cancel', mountAt); } isListening.topCancel = true; } else if (dependency === 'topClose') { if (isEventSupported_1('close', true)) { ReactDOMEventListener_1.trapCapturedEvent('topClose', 'close', mountAt); } isListening.topClose = true; } else if (topLevelTypes.hasOwnProperty(dependency)) { ReactDOMEventListener_1.trapBubbledEvent(dependency, topLevelTypes[dependency], mountAt); } isListening[dependency] = true; } } }, isListeningToAllDependencies: function (registrationName, mountAt) { var isListening = getListeningForDocument(mountAt); var dependencies = EventPluginRegistry_1.registrationNameDependencies[registrationName]; for (var i = 0; i < dependencies.length; i++) { var dependency = dependencies[i]; if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) { return false; } } return true; }, trapBubbledEvent: function (topLevelType, handlerBaseName, handle) { return ReactDOMEventListener_1.trapBubbledEvent(topLevelType, handlerBaseName, handle); }, trapCapturedEvent: function (topLevelType, handlerBaseName, handle) { return ReactDOMEventListener_1.trapCapturedEvent(topLevelType, handlerBaseName, handle); } }); var ReactBrowserEventEmitter_1 = ReactBrowserEventEmitter; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule ReactDOMFeatureFlags */ var ReactDOMFeatureFlags = { fiberAsyncScheduling: false, useFiber: true }; var ReactDOMFeatureFlags_1 = ReactDOMFeatureFlags; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule CSSProperty */ /** * CSS properties which accept numbers but are not in units of "px". */ var isUnitlessNumber = { animationIterationCount: true, borderImageOutset: true, borderImageSlice: true, borderImageWidth: true, boxFlex: true, boxFlexGroup: true, boxOrdinalGroup: true, columnCount: true, columns: true, flex: true, flexGrow: true, flexPositive: true, flexShrink: true, flexNegative: true, flexOrder: true, gridRow: true, gridRowEnd: true, gridRowSpan: true, gridRowStart: true, gridColumn: true, gridColumnEnd: true, gridColumnSpan: true, gridColumnStart: true, fontWeight: true, lineClamp: true, lineHeight: true, opacity: true, order: true, orphans: true, tabSize: true, widows: true, zIndex: true, zoom: true, // SVG-related properties fillOpacity: true, floodOpacity: true, stopOpacity: true, strokeDasharray: true, strokeDashoffset: true, strokeMiterlimit: true, strokeOpacity: true, strokeWidth: true }; /** * @param {string} prefix vendor-specific prefix, eg: Webkit * @param {string} key style name, eg: transitionDuration * @return {string} style name prefixed with `prefix`, properly camelCased, eg: * WebkitTransitionDuration */ function prefixKey(prefix, key) { return prefix + key.charAt(0).toUpperCase() + key.substring(1); } /** * Support style names that may come passed in prefixed by adding permutations * of vendor prefixes. */ var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an // infinite loop, because it iterates over the newly added props too. Object.keys(isUnitlessNumber).forEach(function (prop) { prefixes.forEach(function (prefix) { isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; }); }); /** * Most style properties can be unset by doing .style[prop] = '' but IE8 * doesn't like doing that with shorthand properties so for the properties that * IE8 breaks on, which are listed here, we instead unset each of the * individual properties. See http://bugs.jquery.com/ticket/12385. * The 4-value 'clock' properties like margin, padding, border-width seem to * behave without any problems. Curiously, list-style works too without any * special prodding. */ var shorthandPropertyExpansions = { background: { backgroundAttachment: true, backgroundColor: true, backgroundImage: true, backgroundPositionX: true, backgroundPositionY: true, backgroundRepeat: true }, backgroundPosition: { backgroundPositionX: true, backgroundPositionY: true }, border: { borderWidth: true, borderStyle: true, borderColor: true }, borderBottom: { borderBottomWidth: true, borderBottomStyle: true, borderBottomColor: true }, borderLeft: { borderLeftWidth: true, borderLeftStyle: true, borderLeftColor: true }, borderRight: { borderRightWidth: true, borderRightStyle: true, borderRightColor: true }, borderTop: { borderTopWidth: true, borderTopStyle: true, borderTopColor: true }, font: { fontStyle: true, fontVariant: true, fontWeight: true, fontSize: true, lineHeight: true, fontFamily: true }, outline: { outlineWidth: true, outlineStyle: true, outlineColor: true } }; var CSSProperty = { isUnitlessNumber: isUnitlessNumber, shorthandPropertyExpansions: shorthandPropertyExpansions }; var CSSProperty_1 = CSSProperty; var isUnitlessNumber$1 = CSSProperty_1.isUnitlessNumber; /** * Convert a value into the proper css writable value. The style name `name` * should be logical (no hyphens), as specified * in `CSSProperty.isUnitlessNumber`. * * @param {string} name CSS property name such as `topMargin`. * @param {*} value CSS property value such as `10px`. * @return {string} Normalized style value with dimensions applied. */ function dangerousStyleValue(name, value, isCustomProperty) { // Note that we've removed escapeTextForBrowser() calls here since the // whole string will be escaped when the attribute is injected into // the markup. If you provide unsafe user data here they can inject // arbitrary CSS which may be problematic (I couldn't repro this): // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/ // This is not an XSS hole but instead a potential CSS injection issue // which has lead to a greater discussion about how we're going to // trust URLs moving forward. See #2115901 var isEmpty = value == null || typeof value === 'boolean' || value === ''; if (isEmpty) { return ''; } if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber$1.hasOwnProperty(name) && isUnitlessNumber$1[name])) { return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers } return ('' + value).trim(); } var dangerousStyleValue_1 = dangerousStyleValue; /** * Copyright (c) 2016-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * * @providesModule describeComponentFrame */ var describeComponentFrame = function (name, source, ownerName) { return '\n in ' + (name || 'Unknown') + (source ? ' (at ' + source.fileName.replace(/^.*[\\\/]/, '') + ':' + source.lineNumber + ')' : ownerName ? ' (created by ' + ownerName + ')' : ''); }; var IndeterminateComponent = ReactTypeOfWork.IndeterminateComponent; var FunctionalComponent = ReactTypeOfWork.FunctionalComponent; var ClassComponent$1 = ReactTypeOfWork.ClassComponent; var HostComponent$2 = ReactTypeOfWork.HostComponent; function describeFiber(fiber) { switch (fiber.tag) { case IndeterminateComponent: case FunctionalComponent: case ClassComponent$1: case HostComponent$2: var owner = fiber._debugOwner; var source = fiber._debugSource; var name = getComponentName_1(fiber); var ownerName = null; if (owner) { ownerName = getComponentName_1(owner); } return describeComponentFrame(name, source, ownerName); default: return ''; } } // This function can only be called with a work-in-progress fiber and // only during begin or complete phase. Do not call it under any other // circumstances. function getStackAddendumByWorkInProgressFiber$1(workInProgress) { var info = ''; var node = workInProgress; do { info += describeFiber(node); // Otherwise this return pointer might point to the wrong tree: node = node['return']; } while (node); return info; } var ReactFiberComponentTreeHook = { getStackAddendumByWorkInProgressFiber: getStackAddendumByWorkInProgressFiber$1 }; var ReactDebugCurrentFrame = ReactGlobalSharedState_1.ReactDebugCurrentFrame; { var getComponentName$3 = getComponentName_1; var _require2$2 = ReactFiberComponentTreeHook, getStackAddendumByWorkInProgressFiber = _require2$2.getStackAddendumByWorkInProgressFiber; } function getCurrentFiberOwnerName$2() { { var fiber = ReactDebugCurrentFiber.current; if (fiber === null) { return null; } if (fiber._debugOwner != null) { return getComponentName$3(fiber._debugOwner); } } return null; } function getCurrentFiberStackAddendum$1() { { var fiber = ReactDebugCurrentFiber.current; if (fiber === null) { return null; } // Safe because if current fiber exists, we are reconciling, // and it is guaranteed to be the work-in-progress version. return getStackAddendumByWorkInProgressFiber(fiber); } return null; } function resetCurrentFiber() { ReactDebugCurrentFrame.getCurrentStack = null; ReactDebugCurrentFiber.current = null; ReactDebugCurrentFiber.phase = null; } function setCurrentFiber(fiber, phase) { ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackAddendum$1; ReactDebugCurrentFiber.current = fiber; ReactDebugCurrentFiber.phase = phase; } var ReactDebugCurrentFiber = { current: null, phase: null, resetCurrentFiber: resetCurrentFiber, setCurrentFiber: setCurrentFiber, getCurrentFiberOwnerName: getCurrentFiberOwnerName$2, getCurrentFiberStackAddendum: getCurrentFiberStackAddendum$1 }; var ReactDebugCurrentFiber_1 = ReactDebugCurrentFiber; var warnValidStyle$1 = emptyFunction; { var camelizeStyleName$1 = camelizeStyleName; var getComponentName$2 = getComponentName_1; var warning$4 = require$$0; var _require$3 = ReactDebugCurrentFiber_1, getCurrentFiberOwnerName$1 = _require$3.getCurrentFiberOwnerName; // 'msTransform' is correct, but the other prefixes should be capitalized var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; // style values shouldn't contain a semicolon var badStyleValueWithSemicolonPattern = /;\s*$/; var warnedStyleNames = {}; var warnedStyleValues = {}; var warnedForNaNValue = false; var warnedForInfinityValue = false; var warnHyphenatedStyleName = function (name, owner) { if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { return; } warnedStyleNames[name] = true; warning$4(false, 'Unsupported style property %s. Did you mean %s?%s', name, camelizeStyleName$1(name), checkRenderMessage(owner)); }; var warnBadVendoredStyleName = function (name, owner) { if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { return; } warnedStyleNames[name] = true; warning$4(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?%s', name, name.charAt(0).toUpperCase() + name.slice(1), checkRenderMessage(owner)); }; var warnStyleValueWithSemicolon = function (name, value, owner) { if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { return; } warnedStyleValues[value] = true; warning$4(false, "Style property values shouldn't contain a semicolon.%s " + 'Try "%s: %s" instead.', checkRenderMessage(owner), name, value.replace(badStyleValueWithSemicolonPattern, '')); }; var warnStyleValueIsNaN = function (name, value, owner) { if (warnedForNaNValue) { return; } warnedForNaNValue = true; warning$4(false, '`NaN` is an invalid value for the `%s` css style property.%s', name, checkRenderMessage(owner)); }; var warnStyleValueIsInfinity = function (name, value, owner) { if (warnedForInfinityValue) { return; } warnedForInfinityValue = true; warning$4(false, '`Infinity` is an invalid value for the `%s` css style property.%s', name, checkRenderMessage(owner)); }; var checkRenderMessage = function (owner) { var ownerName; if (owner != null) { // Stack passes the owner manually all the way to CSSPropertyOperations. ownerName = getComponentName$2(owner); } else { // Fiber doesn't pass it but uses ReactDebugCurrentFiber to track it. // It is only enabled in development and tracks host components too. ownerName = getCurrentFiberOwnerName$1(); // TODO: also report the stack. } if (ownerName) { return '\n\nCheck the render method of `' + ownerName + '`.'; } return ''; }; warnValidStyle$1 = function (name, value, component) { var owner; if (component) { // TODO: this only works with Stack. Seems like we need to add unit tests? owner = component._currentElement._owner; } if (name.indexOf('-') > -1) { warnHyphenatedStyleName(name, owner); } else if (badVendoredStyleNamePattern.test(name)) { warnBadVendoredStyleName(name, owner); } else if (badStyleValueWithSemicolonPattern.test(value)) { warnStyleValueWithSemicolon(name, value, owner); } if (typeof value === 'number') { if (isNaN(value)) { warnStyleValueIsNaN(name, value, owner); } else if (!isFinite(value)) { warnStyleValueIsInfinity(name, value, owner); } } }; } var warnValidStyle_1 = warnValidStyle$1; { var hyphenateStyleName$1 = hyphenateStyleName; var warnValidStyle = warnValidStyle_1; } var hasShorthandPropertyBug = false; if (ExecutionEnvironment.canUseDOM) { var tempStyle = document.createElement('div').style; try { // IE8 throws "Invalid argument." if resetting shorthand style properties. tempStyle.font = ''; } catch (e) { hasShorthandPropertyBug = true; } } /** * Operations for dealing with CSS properties. */ var CSSPropertyOperations = { /** * This creates a string that is expected to be equivalent to the style * attribute generated by server-side rendering. It by-passes warnings and * security checks so it's not safe to use this value for anything other than * comparison. It is only used in DEV for SSR validation. */ createDangerousStringForStyles: function (styles) { { var serialized = ''; var delimiter = ''; for (var styleName in styles) { if (!styles.hasOwnProperty(styleName)) { continue; } var styleValue = styles[styleName]; if (styleValue != null) { var isCustomProperty = styleName.indexOf('--') === 0; serialized += delimiter + hyphenateStyleName$1(styleName) + ':'; serialized += dangerousStyleValue_1(styleName, styleValue, isCustomProperty); delimiter = ';'; } } return serialized || null; } }, /** * Sets the value for multiple styles on a node. If a value is specified as * '' (empty string), the corresponding style property will be unset. * * @param {DOMElement} node * @param {object} styles * @param {ReactDOMComponent} component */ setValueForStyles: function (node, styles, component) { var style = node.style; for (var styleName in styles) { if (!styles.hasOwnProperty(styleName)) { continue; } var isCustomProperty = styleName.indexOf('--') === 0; { if (!isCustomProperty) { warnValidStyle(styleName, styles[styleName], component); } } var styleValue = dangerousStyleValue_1(styleName, styles[styleName], isCustomProperty); if (styleName === 'float') { styleName = 'cssFloat'; } if (isCustomProperty) { style.setProperty(styleName, styleValue); } else if (styleValue) { style[styleName] = styleValue; } else { var expansion = hasShorthandPropertyBug && CSSProperty_1.shorthandPropertyExpansions[styleName]; if (expansion) { // Shorthand property that IE8 won't like unsetting, so unset each // component to placate it for (var individualStyleName in expansion) { style[individualStyleName] = ''; } } else { style[styleName] = ''; } } } } }; var CSSPropertyOperations_1 = CSSPropertyOperations; var ReactInvalidSetStateWarningHook = {}; { var warning$7 = require$$0; var processingChildContext = false; var warnInvalidSetState = function () { warning$7(!processingChildContext, 'setState(...): Cannot call setState() inside getChildContext()'); }; ReactInvalidSetStateWarningHook = { onBeginProcessingChildContext: function () { processingChildContext = true; }, onEndProcessingChildContext: function () { processingChildContext = false; }, onSetState: function () { warnInvalidSetState(); } }; } var ReactInvalidSetStateWarningHook_1 = ReactInvalidSetStateWarningHook; /** * Copyright (c) 2016-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule ReactHostOperationHistoryHook * */ // Trust the developer to only use this with a true check var ReactHostOperationHistoryHook = null; { var history = []; ReactHostOperationHistoryHook = { onHostOperation: function (operation) { history.push(operation); }, clearHistory: function () { if (ReactHostOperationHistoryHook._preventClearing) { // Should only be used for tests. return; } history = []; }, getHistory: function () { return history; } }; } var ReactHostOperationHistoryHook_1 = ReactHostOperationHistoryHook; var ReactComponentTreeHook = ReactGlobalSharedState_1.ReactComponentTreeHook; { var warning$6 = require$$0; } // Trust the developer to only use this with a true check var ReactDebugTool$1 = null; { var hooks = []; var didHookThrowForEvent = {}; var callHook = function (event, fn, context, arg1, arg2, arg3, arg4, arg5) { try { fn.call(context, arg1, arg2, arg3, arg4, arg5); } catch (e) { warning$6(didHookThrowForEvent[event], 'Exception thrown by hook while handling %s: %s', event, e + '\n' + e.stack); didHookThrowForEvent[event] = true; } }; var emitEvent = function (event, arg1, arg2, arg3, arg4, arg5) { for (var i = 0; i < hooks.length; i++) { var hook = hooks[i]; var fn = hook[event]; if (fn) { callHook(event, fn, hook, arg1, arg2, arg3, arg4, arg5); } } }; var isProfiling = false; var flushHistory = []; var lifeCycleTimerStack = []; var currentFlushNesting = 0; var currentFlushMeasurements = []; var currentFlushStartTime = 0; var currentTimerDebugID = null; var currentTimerStartTime = 0; var currentTimerNestedFlushDuration = 0; var currentTimerType = null; var lifeCycleTimerHasWarned = false; var clearHistory = function () { ReactComponentTreeHook.purgeUnmountedComponents(); ReactHostOperationHistoryHook_1.clearHistory(); }; var getTreeSnapshot = function (registeredIDs) { return registeredIDs.reduce(function (tree, id) { var ownerID = ReactComponentTreeHook.getOwnerID(id); var parentID = ReactComponentTreeHook.getParentID(id); tree[id] = { displayName: ReactComponentTreeHook.getDisplayName(id), text: ReactComponentTreeHook.getText(id), updateCount: ReactComponentTreeHook.getUpdateCount(id), childIDs: ReactComponentTreeHook.getChildIDs(id), // Text nodes don't have owners but this is close enough. ownerID: ownerID || parentID && ReactComponentTreeHook.getOwnerID(parentID) || 0, parentID: parentID }; return tree; }, {}); }; var resetMeasurements = function () { var previousStartTime = currentFlushStartTime; var previousMeasurements = currentFlushMeasurements; var previousOperations = ReactHostOperationHistoryHook_1.getHistory(); if (currentFlushNesting === 0) { currentFlushStartTime = 0; currentFlushMeasurements = []; clearHistory(); return; } if (previousMeasurements.length || previousOperations.length) { var registeredIDs = ReactComponentTreeHook.getRegisteredIDs(); flushHistory.push({ duration: performanceNow() - previousStartTime, measurements: previousMeasurements || [], operations: previousOperations || [], treeSnapshot: getTreeSnapshot(registeredIDs) }); } clearHistory(); currentFlushStartTime = performanceNow(); currentFlushMeasurements = []; }; var checkDebugID = function (debugID) { var allowRoot = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; if (allowRoot && debugID === 0) { return; } if (!debugID) { warning$6(false, 'ReactDebugTool: debugID may not be empty.'); } }; var beginLifeCycleTimer = function (debugID, timerType) { if (currentFlushNesting === 0) { return; } if (currentTimerType && !lifeCycleTimerHasWarned) { warning$6(false, 'There is an internal error in the React performance measurement code.' + '\n\nDid not expect %s timer to start while %s timer is still in ' + 'progress for %s instance.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another'); lifeCycleTimerHasWarned = true; } currentTimerStartTime = performanceNow(); currentTimerNestedFlushDuration = 0; currentTimerDebugID = debugID; currentTimerType = timerType; }; var endLifeCycleTimer = function (debugID, timerType) { if (currentFlushNesting === 0) { return; } if (currentTimerType !== timerType && !lifeCycleTimerHasWarned) { warning$6(false, 'There is an internal error in the React performance measurement code. ' + 'We did not expect %s timer to stop while %s timer is still in ' + 'progress for %s instance. Please report this as a bug in React.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another'); lifeCycleTimerHasWarned = true; } if (isProfiling) { currentFlushMeasurements.push({ timerType: timerType, instanceID: debugID, duration: performanceNow() - currentTimerStartTime - currentTimerNestedFlushDuration }); } currentTimerStartTime = 0; currentTimerNestedFlushDuration = 0; currentTimerDebugID = null; currentTimerType = null; }; var pauseCurrentLifeCycleTimer = function () { var currentTimer = { startTime: currentTimerStartTime, nestedFlushStartTime: performanceNow(), debugID: currentTimerDebugID, timerType: currentTimerType }; lifeCycleTimerStack.push(currentTimer); currentTimerStartTime = 0; currentTimerNestedFlushDuration = 0; currentTimerDebugID = null; currentTimerType = null; }; var resumeCurrentLifeCycleTimer = function () { var _lifeCycleTimerStack$ = lifeCycleTimerStack.pop(), startTime = _lifeCycleTimerStack$.startTime, nestedFlushStartTime = _lifeCycleTimerStack$.nestedFlushStartTime, debugID = _lifeCycleTimerStack$.debugID, timerType = _lifeCycleTimerStack$.timerType; var nestedFlushDuration = performanceNow() - nestedFlushStartTime; currentTimerStartTime = startTime; currentTimerNestedFlushDuration += nestedFlushDuration; currentTimerDebugID = debugID; currentTimerType = timerType; }; var lastMarkTimeStamp = 0; var canUsePerformanceMeasure = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function'; var shouldMark = function (debugID) { if (!isProfiling || !canUsePerformanceMeasure) { return false; } var element = ReactComponentTreeHook.getElement(debugID); if (element == null || typeof element !== 'object') { return false; } var isHostElement = typeof element.type === 'string'; if (isHostElement) { return false; } return true; }; var markBegin = function (debugID, markType) { if (!shouldMark(debugID)) { return; } var markName = debugID + '::' + markType; lastMarkTimeStamp = performanceNow(); performance.mark(markName); }; var markEnd = function (debugID, markType) { if (!shouldMark(debugID)) { return; } var markName = debugID + '::' + markType; var displayName = ReactComponentTreeHook.getDisplayName(debugID) || 'Unknown'; // Chrome has an issue of dropping markers recorded too fast: // https://bugs.chromium.org/p/chromium/issues/detail?id=640652 // To work around this, we will not report very small measurements. // I determined the magic number by tweaking it back and forth. // 0.05ms was enough to prevent the issue, but I set it to 0.1ms to be safe. // When the bug is fixed, we can `measure()` unconditionally if we want to. var timeStamp = performanceNow(); if (timeStamp - lastMarkTimeStamp > 0.1) { var measurementName = displayName + ' [' + markType + ']'; performance.measure(measurementName, markName); } performance.clearMarks(markName); if (measurementName) { performance.clearMeasures(measurementName); } }; ReactDebugTool$1 = { addHook: function (hook) { hooks.push(hook); }, removeHook: function (hook) { for (var i = 0; i < hooks.length; i++) { if (hooks[i] === hook) { hooks.splice(i, 1); i--; } } }, isProfiling: function () { return isProfiling; }, beginProfiling: function () { if (isProfiling) { return; } isProfiling = true; flushHistory.length = 0; resetMeasurements(); ReactDebugTool$1.addHook(ReactHostOperationHistoryHook_1); }, endProfiling: function () { if (!isProfiling) { return; } isProfiling = false; resetMeasurements(); ReactDebugTool$1.removeHook(ReactHostOperationHistoryHook_1); }, getFlushHistory: function () { return flushHistory; }, onBeginFlush: function () { currentFlushNesting++; resetMeasurements(); pauseCurrentLifeCycleTimer(); emitEvent('onBeginFlush'); }, onEndFlush: function () { resetMeasurements(); currentFlushNesting--; resumeCurrentLifeCycleTimer(); emitEvent('onEndFlush'); }, onBeginLifeCycleTimer: function (debugID, timerType) { checkDebugID(debugID); emitEvent('onBeginLifeCycleTimer', debugID, timerType); markBegin(debugID, timerType); beginLifeCycleTimer(debugID, timerType); }, onEndLifeCycleTimer: function (debugID, timerType) { checkDebugID(debugID); endLifeCycleTimer(debugID, timerType); markEnd(debugID, timerType); emitEvent('onEndLifeCycleTimer', debugID, timerType); }, onBeginProcessingChildContext: function () { emitEvent('onBeginProcessingChildContext'); }, onEndProcessingChildContext: function () { emitEvent('onEndProcessingChildContext'); }, onHostOperation: function (operation) { checkDebugID(operation.instanceID); emitEvent('onHostOperation', operation); }, onSetState: function () { emitEvent('onSetState'); }, onSetChildren: function (debugID, childDebugIDs) { checkDebugID(debugID); childDebugIDs.forEach(checkDebugID); emitEvent('onSetChildren', debugID, childDebugIDs); }, onBeforeMountComponent: function (debugID, element, parentDebugID) { checkDebugID(debugID); checkDebugID(parentDebugID, true); emitEvent('onBeforeMountComponent', debugID, element, parentDebugID); markBegin(debugID, 'mount'); }, onMountComponent: function (debugID) { checkDebugID(debugID); markEnd(debugID, 'mount'); emitEvent('onMountComponent', debugID); }, onBeforeUpdateComponent: function (debugID, element) { checkDebugID(debugID); emitEvent('onBeforeUpdateComponent', debugID, element); markBegin(debugID, 'update'); }, onUpdateComponent: function (debugID) { checkDebugID(debugID); markEnd(debugID, 'update'); emitEvent('onUpdateComponent', debugID); }, onBeforeUnmountComponent: function (debugID) { checkDebugID(debugID); emitEvent('onBeforeUnmountComponent', debugID); markBegin(debugID, 'unmount'); }, onUnmountComponent: function (debugID) { checkDebugID(debugID); markEnd(debugID, 'unmount'); emitEvent('onUnmountComponent', debugID); }, onTestEvent: function () { emitEvent('onTestEvent'); } }; ReactDebugTool$1.addHook(ReactInvalidSetStateWarningHook_1); ReactDebugTool$1.addHook(ReactComponentTreeHook); var url = ExecutionEnvironment.canUseDOM && window.location.href || ''; if (/[?&]react_perf\b/.test(url)) { ReactDebugTool$1.beginProfiling(); } } var ReactDebugTool_1 = ReactDebugTool$1; // Trust the developer to only use ReactInstrumentation with a true check var debugTool = null; { var ReactDebugTool = ReactDebugTool_1; debugTool = ReactDebugTool; } var ReactInstrumentation = { debugTool: debugTool }; { var warning$5 = require$$0; } // isAttributeNameSafe() is currently duplicated in DOMMarkupOperations. // TODO: Find a better place for this. var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + DOMProperty_1.ATTRIBUTE_NAME_START_CHAR + '][' + DOMProperty_1.ATTRIBUTE_NAME_CHAR + ']*$'); var illegalAttributeNameCache = {}; var validatedAttributeNameCache = {}; function isAttributeNameSafe(attributeName) { if (validatedAttributeNameCache.hasOwnProperty(attributeName)) { return true; } if (illegalAttributeNameCache.hasOwnProperty(attributeName)) { return false; } if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { validatedAttributeNameCache[attributeName] = true; return true; } illegalAttributeNameCache[attributeName] = true; { warning$5(false, 'Invalid attribute name: `%s`', attributeName); } return false; } // shouldIgnoreValue() is currently duplicated in DOMMarkupOperations. // TODO: Find a better place for this. function shouldIgnoreValue(propertyInfo, value) { return value == null || propertyInfo.hasBooleanValue && !value || propertyInfo.hasNumericValue && isNaN(value) || propertyInfo.hasPositiveNumericValue && value < 1 || propertyInfo.hasOverloadedBooleanValue && value === false; } /** * Operations for dealing with DOM properties. */ var DOMPropertyOperations = { setAttributeForID: function (node, id) { node.setAttribute(DOMProperty_1.ID_ATTRIBUTE_NAME, id); }, setAttributeForRoot: function (node) { node.setAttribute(DOMProperty_1.ROOT_ATTRIBUTE_NAME, ''); }, /** * 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. * Some properties have multiple equivalent values. */ getValueForProperty: function (node, name, expected) { { var propertyInfo = DOMProperty_1.getPropertyInfo(name); if (propertyInfo) { var mutationMethod = propertyInfo.mutationMethod; if (mutationMethod || propertyInfo.mustUseProperty) { return node[propertyInfo.propertyName]; } else { var attributeName = propertyInfo.attributeName; var stringValue = null; if (propertyInfo.hasOverloadedBooleanValue) { if (node.hasAttribute(attributeName)) { var value = node.getAttribute(attributeName); if (value === '') { return true; } if (shouldIgnoreValue(propertyInfo, expected)) { return value; } if (value === '' + expected) { return expected; } return value; } } else if (node.hasAttribute(attributeName)) { if (shouldIgnoreValue(propertyInfo, expected)) { // We had an attribute but shouldn't have had one, so read it // for the error message. return node.getAttribute(attributeName); } if (propertyInfo.hasBooleanValue) { // If this was a boolean, it doesn't matter what the value is // the fact that we have it is the same as the expected. return expected; } // Even if this property uses a namespace we use getAttribute // because we assume its namespaced name is the same as our config. // To use getAttributeNS we need the local name which we don't have // in our config atm. stringValue = node.getAttribute(attributeName); } if (shouldIgnoreValue(propertyInfo, expected)) { return stringValue === null ? expected : stringValue; } else if (stringValue === '' + expected) { return expected; } else { return stringValue; } } } } }, /** * Get the value for a attribute on a node. Only used in DEV for SSR validation. * The third argument is used as a hint of what the expected value is. Some * attributes have multiple equivalent values. */ getValueForAttribute: function (node, name, expected) { { if (!isAttributeNameSafe(name)) { return; } if (!node.hasAttribute(name)) { return expected === undefined ? undefined : null; } var value = node.getAttribute(name); if (value === '' + expected) { return expected; } return value; } }, /** * Sets the value for a property on a node. * * @param {DOMElement} node * @param {string} name * @param {*} value */ setValueForProperty: function (node, name, value) { var propertyInfo = DOMProperty_1.getPropertyInfo(name); if (propertyInfo && DOMProperty_1.shouldSetAttribute(name, value)) { var mutationMethod = propertyInfo.mutationMethod; if (mutationMethod) { mutationMethod(node, value); } else if (shouldIgnoreValue(propertyInfo, value)) { DOMPropertyOperations.deleteValueForProperty(node, name); return; } else if (propertyInfo.mustUseProperty) { // Contrary to `setAttribute`, object properties are properly // `toString`ed by IE8/9. node[propertyInfo.propertyName] = value; } else { var attributeName = propertyInfo.attributeName; var namespace = propertyInfo.attributeNamespace; // `setAttribute` with objects becomes only `[object]` in IE8/9, // ('' + value) makes it output the correct toString()-value. if (namespace) { node.setAttributeNS(namespace, attributeName, '' + value); } else if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) { node.setAttribute(attributeName, ''); } else { node.setAttribute(attributeName, '' + value); } } } else { DOMPropertyOperations.setValueForAttribute(node, name, DOMProperty_1.shouldSetAttribute(name, value) ? value : null); return; } { var payload = {}; payload[name] = value; ReactInstrumentation.debugTool.onHostOperation({ instanceID: ReactDOMComponentTree_1.getInstanceFromNode(node)._debugID, type: 'update attribute', payload: payload }); } }, setValueForAttribute: function (node, name, value) { if (!isAttributeNameSafe(name)) { return; } if (value == null) { node.removeAttribute(name); } else { node.setAttribute(name, '' + value); } { var payload = {}; payload[name] = value; ReactInstrumentation.debugTool.onHostOperation({ instanceID: ReactDOMComponentTree_1.getInstanceFromNode(node)._debugID, type: 'update attribute', payload: payload }); } }, /** * Deletes an attributes from a node. * * @param {DOMElement} node * @param {string} name */ deleteValueForAttribute: function (node, name) { node.removeAttribute(name); { ReactInstrumentation.debugTool.onHostOperation({ instanceID: ReactDOMComponentTree_1.getInstanceFromNode(node)._debugID, type: 'remove attribute', payload: name }); } }, /** * Deletes the value for a property on a node. * * @param {DOMElement} node * @param {string} name */ deleteValueForProperty: function (node, name) { var propertyInfo = DOMProperty_1.getPropertyInfo(name); if (propertyInfo) { var mutationMethod = propertyInfo.mutationMethod; if (mutationMethod) { mutationMethod(node, undefined); } else if (propertyInfo.mustUseProperty) { var propName = propertyInfo.propertyName; if (propertyInfo.hasBooleanValue) { node[propName] = false; } else { node[propName] = ''; } } else { node.removeAttribute(propertyInfo.attributeName); } } else { node.removeAttribute(name); } { ReactInstrumentation.debugTool.onHostOperation({ instanceID: ReactDOMComponentTree_1.getInstanceFromNode(node)._debugID, type: 'remove attribute', payload: name }); } } }; var DOMPropertyOperations_1 = DOMPropertyOperations; var ReactControlledValuePropTypes = { checkPropTypes: null }; { var warning$9 = require$$0; var emptyFunction$2 = emptyFunction; var PropTypes = propTypes; var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; ReactControlledValuePropTypes.checkPropTypes = emptyFunction$2; var hasReadOnlyValue = { button: true, checkbox: true, image: true, hidden: true, radio: true, reset: true, submit: true }; var propTypes$1 = { value: function (props, propName, componentName) { if (!props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled) { 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[propName] || props.onChange || props.readOnly || props.disabled) { 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`.'); }, onChange: PropTypes.func }; var loggedTypeFailures = {}; /** * Provide a linked `value` attribute for controlled forms. You should not use * this outside of the ReactDOM controlled form components. */ ReactControlledValuePropTypes.checkPropTypes = function (tagName, props, getStack) { for (var propName in propTypes$1) { if (propTypes$1.hasOwnProperty(propName)) { var error = propTypes$1[propName](props, propName, tagName, 'prop', null, ReactPropTypesSecret); } if (error instanceof Error && !(error.message in loggedTypeFailures)) { // Only monitor this failure once because there tends to be a lot of the // same error. loggedTypeFailures[error.message] = true; warning$9(false, 'Failed form propType: %s%s', error.message, getStack()); } } }; } var ReactControlledValuePropTypes_1 = ReactControlledValuePropTypes; var getCurrentFiberOwnerName$3 = ReactDebugCurrentFiber_1.getCurrentFiberOwnerName; { var _require2$3 = ReactDebugCurrentFiber_1, getCurrentFiberStackAddendum$2 = _require2$3.getCurrentFiberStackAddendum; var warning$8 = require$$0; } var didWarnValueDefaultValue = false; var didWarnCheckedDefaultChecked = false; var didWarnControlledToUncontrolled = false; var didWarnUncontrolledToControlled = false; function isControlled(props) { var usesChecked = props.type === 'checkbox' || props.type === 'radio'; return usesChecked ? props.checked != null : props.value != null; } /** * Implements an <input> host component that allows setting these optional * props: `checked`, `value`, `defaultChecked`, and `defaultValue`. * * If `checked` or `value` are not supplied (or null/undefined), user actions * that affect the checked state or value will trigger updates to the element. * * If they are supplied (and not null/undefined), the rendered element will not * trigger updates to the element. Instead, the props must change in order for * the rendered element to be updated. * * The rendered element will be initialized as unchecked (or `defaultChecked`) * with an empty value (or `defaultValue`). * * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html */ var ReactDOMInput = { getHostProps: function (element, props) { var node = element; var value = props.value; var checked = props.checked; var hostProps = _assign({ // Make sure we set .type before any other properties (setting .value // before .type means .value is lost in IE11 and below) type: undefined, // Make sure we set .step before .value (setting .value before .step // means .value is rounded on mount, based upon step precision) step: undefined, // Make sure we set .min & .max before .value (to ensure proper order // in corner cases such as min or max deriving from value, e.g. Issue #7170) min: undefined, max: undefined }, props, { defaultChecked: undefined, defaultValue: undefined, value: value != null ? value : node._wrapperState.initialValue, checked: checked != null ? checked : node._wrapperState.initialChecked }); return hostProps; }, initWrapperState: function (element, props) { { ReactControlledValuePropTypes_1.checkPropTypes('input', props, getCurrentFiberStackAddendum$2); if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) { warning$8(false, '%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerName$3() || 'A component', props.type); didWarnCheckedDefaultChecked = true; } if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) { warning$8(false, '%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerName$3() || 'A component', props.type); didWarnValueDefaultValue = true; } } var defaultValue = props.defaultValue; var node = element; node._wrapperState = { initialChecked: props.checked != null ? props.checked : props.defaultChecked, initialValue: props.value != null ? props.value : defaultValue, controlled: isControlled(props) }; }, updateWrapper: function (element, props) { var node = element; { var controlled = isControlled(props); if (!node._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) { warning$8(false, 'A component is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components%s', props.type, getCurrentFiberStackAddendum$2()); didWarnUncontrolledToControlled = true; } if (node._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) { warning$8(false, 'A component is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components%s', props.type, getCurrentFiberStackAddendum$2()); didWarnControlledToUncontrolled = true; } } var checked = props.checked; if (checked != null) { DOMPropertyOperations_1.setValueForProperty(node, 'checked', checked || false); } var value = props.value; if (value != null) { if (value === 0 && node.value === '') { node.value = '0'; // Note: IE9 reports a number inputs as 'text', so check props instead. } else if (props.type === 'number') { // Simulate `input.valueAsNumber`. IE9 does not support it var valueAsNumber = parseFloat(node.value) || 0; if ( // eslint-disable-next-line value != valueAsNumber || // eslint-disable-next-line value == valueAsNumber && node.value != value) { // Cast `value` to a string to ensure the value is set correctly. While // browsers typically do this as necessary, jsdom doesn't. node.value = '' + value; } } else if (node.value !== '' + value) { // Cast `value` to a string to ensure the value is set correctly. While // browsers typically do this as necessary, jsdom doesn't. node.value = '' + value; } } else { if (props.value == null && props.defaultValue != null) { // In Chrome, assigning defaultValue to certain input types triggers input validation. // For number inputs, the display value loses trailing decimal points. For email inputs, // Chrome raises "The specified value <x> is not a valid email address". // // Here we check to see if the defaultValue has actually changed, avoiding these problems // when the user is inputting text // // https://github.com/facebook/react/issues/7253 if (node.defaultValue !== '' + props.defaultValue) { node.defaultValue = '' + props.defaultValue; } } if (props.checked == null && props.defaultChecked != null) { node.defaultChecked = !!props.defaultChecked; } } }, postMountWrapper: function (element, props) { var node = element; // Detach value from defaultValue. We won't do anything if we're working on // submit or reset inputs as those values & defaultValues are linked. They // are not resetable nodes so this operation doesn't matter and actually // removes browser-default values (eg "Submit Query") when no value is // provided. switch (props.type) { case 'submit': case 'reset': break; case 'color': case 'date': case 'datetime': case 'datetime-local': case 'month': case 'time': case 'week': // This fixes the no-show issue on iOS Safari and Android Chrome: // https://github.com/facebook/react/issues/7233 node.value = ''; node.value = node.defaultValue; break; default: node.value = node.value; break; } // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug // this is needed to work around a chrome bug where setting defaultChecked // will sometimes influence the value of checked (even after detachment). // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416 // We need to temporarily unset name to avoid disrupting radio button groups. var name = node.name; if (name !== '') { node.name = ''; } node.defaultChecked = !node.defaultChecked; node.defaultChecked = !node.defaultChecked; if (name !== '') { node.name = name; } }, restoreControlledState: function (element, props) { var node = element; ReactDOMInput.updateWrapper(node, props); updateNamedCousins(node, props); } }; function updateNamedCousins(rootNode, props) { var name = props.name; if (props.type === 'radio' && name != null) { var queryRoot = rootNode; while (queryRoot.parentNode) { queryRoot = queryRoot.parentNode; } // If `rootNode.form` was non-null, then we could try `form.elements`, // but that sometimes behaves strangely in IE8. We could also try using // `form.getElementsByName`, but that will only return direct children // and won't include inputs that use the HTML5 `form=` attribute. Since // the input might not even be in a form. It might not even be in the // document. Let's just use the local `querySelectorAll` to ensure we don't // miss anything. var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]'); for (var i = 0; i < group.length; i++) { var otherNode = group[i]; if (otherNode === rootNode || otherNode.form !== rootNode.form) { continue; } // This will throw if radio buttons rendered by different copies of React // and the same name are rendered into the same form (same as #1939). // 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 = ReactDOMComponentTree_1.getFiberCurrentPropsFromNode(otherNode); !otherProps ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : void 0; // If this is a controlled radio button group, forcing the input that // was previously checked to update will cause it to be come re-checked // as appropriate. ReactDOMInput.updateWrapper(otherNode, otherProps); } } } var ReactDOMFiberInput = ReactDOMInput; { var warning$10 = require$$0; } function flattenChildren(children) { var content = ''; // Flatten children and warn if they aren't strings or numbers; // invalid types are ignored. // We can silently skip them because invalid DOM nesting warning // catches these cases in Fiber. react.Children.forEach(children, function (child) { if (child == null) { return; } if (typeof child === 'string' || typeof child === 'number') { content += child; } }); return content; } /** * Implements an <option> host component that warns when `selected` is set. */ var ReactDOMOption = { validateProps: function (element, props) { // TODO (yungsters): Remove support for `selected` in <option>. { warning$10(props.selected == null, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.'); } }, postMountWrapper: function (element, props) { // value="" should make a value attribute (#6219) if (props.value != null) { element.setAttribute('value', props.value); } }, getHostProps: function (element, props) { var hostProps = _assign({ children: undefined }, props); var content = flattenChildren(props.children); if (content) { hostProps.children = content; } return hostProps; } }; var ReactDOMFiberOption = ReactDOMOption; var getCurrentFiberOwnerName$4 = ReactDebugCurrentFiber_1.getCurrentFiberOwnerName; { var didWarnValueDefaultValue$1 = false; var warning$11 = require$$0; var _require2$4 = ReactDebugCurrentFiber_1, getCurrentFiberStackAddendum$3 = _require2$4.getCurrentFiberStackAddendum; } function getDeclarationErrorAddendum() { var ownerName = getCurrentFiberOwnerName$4(); if (ownerName) { return '\n\nCheck the render method of `' + ownerName + '`.'; } return ''; } var valuePropNames = ['value', 'defaultValue']; /** * Validation function for `value` and `defaultValue`. */ function checkSelectPropTypes(props) { ReactControlledValuePropTypes_1.checkPropTypes('select', props, getCurrentFiberStackAddendum$3); for (var i = 0; i < valuePropNames.length; i++) { var propName = valuePropNames[i]; if (props[propName] == null) { continue; } var isArray = Array.isArray(props[propName]); if (props.multiple && !isArray) { warning$11(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum()); } else if (!props.multiple && isArray) { warning$11(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum()); } } } function updateOptions(node, multiple, propValue) { var options = node.options; if (multiple) { var selectedValues = propValue; var selectedValue = {}; for (var i = 0; i < selectedValues.length; i++) { // Prefix to avoid chaos with special keys. selectedValue['$' + selectedValues[i]] = true; } for (var _i = 0; _i < options.length; _i++) { var selected = selectedValue.hasOwnProperty('$' + options[_i].value); if (options[_i].selected !== selected) { options[_i].selected = selected; } } } else { // Do not set `select.value` as exact behavior isn't consistent across all // browsers for all cases. var _selectedValue = '' + propValue; var defaultSelected = null; for (var _i2 = 0; _i2 < options.length; _i2++) { if (options[_i2].value === _selectedValue) { options[_i2].selected = true; return; } if (defaultSelected === null && !options[_i2].disabled) { defaultSelected = options[_i2]; } } if (defaultSelected !== null) { defaultSelected.selected = true; } } } /** * Implements a <select> host component that allows optionally setting the * props `value` and `defaultValue`. If `multiple` is false, the prop must be a * stringable. If `multiple` is true, the prop must be an array of stringables. * * If `value` is not supplied (or null/undefined), user actions that change the * selected option will trigger updates to the rendered options. * * If it is supplied (and not null/undefined), the rendered options will not * update in response to user actions. Instead, the `value` prop must change in * order for the rendered options to update. * * If `defaultValue` is provided, any options with the supplied values will be * selected. */ var ReactDOMSelect = { getHostProps: function (element, props) { return _assign({}, props, { value: undefined }); }, initWrapperState: function (element, props) { var node = element; { checkSelectPropTypes(props); } var value = props.value; node._wrapperState = { initialValue: value != null ? value : props.defaultValue, wasMultiple: !!props.multiple }; { if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) { warning$11(false, 'Select elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled select ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components'); didWarnValueDefaultValue$1 = true; } } }, postMountWrapper: function (element, props) { var node = element; node.multiple = !!props.multiple; var value = props.value; if (value != null) { updateOptions(node, !!props.multiple, value); } else if (props.defaultValue != null) { updateOptions(node, !!props.multiple, props.defaultValue); } }, postUpdateWrapper: function (element, props) { var node = element; // After the initial mount, we control selected-ness manually so don't pass // this value down node._wrapperState.initialValue = undefined; var wasMultiple = node._wrapperState.wasMultiple; node._wrapperState.wasMultiple = !!props.multiple; var value = props.value; if (value != null) { updateOptions(node, !!props.multiple, value); } else if (wasMultiple !== !!props.multiple) { // For simplicity, reapply `defaultValue` if `multiple` is toggled. if (props.defaultValue != null) { updateOptions(node, !!props.multiple, props.defaultValue); } else { // Revert the select back to its default unselected state. updateOptions(node, !!props.multiple, props.multiple ? [] : ''); } } }, restoreControlledState: function (element, props) { var node = element; var value = props.value; if (value != null) { updateOptions(node, !!props.multiple, value); } } }; var ReactDOMFiberSelect = ReactDOMSelect; { var warning$12 = require$$0; var _require$4 = ReactDebugCurrentFiber_1, getCurrentFiberStackAddendum$4 = _require$4.getCurrentFiberStackAddendum; } var didWarnValDefaultVal = false; /** * Implements a <textarea> host component that allows setting `value`, and * `defaultValue`. This differs from the traditional DOM API because value is * usually set as PCDATA children. * * If `value` is not supplied (or null/undefined), user actions that affect the * value will trigger updates to the element. * * If `value` is supplied (and not null/undefined), the rendered element will * not trigger updates to the element. Instead, the `value` prop must change in * order for the rendered element to be updated. * * The rendered element will be initialized with an empty value, the prop * `defaultValue` if specified, or the children content (deprecated). */ var ReactDOMTextarea = { getHostProps: function (element, props) { var node = element; !(props.dangerouslySetInnerHTML == null) ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : void 0; // Always set children to the same thing. In IE9, the selection range will // get reset if `textContent` is mutated. We could add a check in setTextContent // to only set the value if/when the value differs from the node value (which would // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this // solution. The value can be a boolean or object so that's why it's forced // to be a string. var hostProps = _assign({}, props, { value: undefined, defaultValue: undefined, children: '' + node._wrapperState.initialValue }); return hostProps; }, initWrapperState: function (element, props) { var node = element; { ReactControlledValuePropTypes_1.checkPropTypes('textarea', props, getCurrentFiberStackAddendum$4); if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) { warning$12(false, 'Textarea elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled textarea ' + 'and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components'); didWarnValDefaultVal = true; } } var value = props.value; var initialValue = value; // Only bother fetching default value if we're going to use it if (value == null) { var defaultValue = props.defaultValue; // TODO (yungsters): Remove support for children content in <textarea>. var children = props.children; if (children != null) { { warning$12(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.'); } !(defaultValue == null) ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : void 0; if (Array.isArray(children)) { !(children.length <= 1) ? invariant(false, '<textarea> can only have at most one child.') : void 0; children = children[0]; } defaultValue = '' + children; } if (defaultValue == null) { defaultValue = ''; } initialValue = defaultValue; } node._wrapperState = { initialValue: '' + initialValue }; }, updateWrapper: function (element, props) { var node = element; var value = props.value; if (value != null) { // Cast `value` to a string to ensure the value is set correctly. While // browsers typically do this as necessary, jsdom doesn't. var newValue = '' + value; // To avoid side effects (such as losing text selection), only set value if changed if (newValue !== node.value) { node.value = newValue; } if (props.defaultValue == null) { node.defaultValue = newValue; } } if (props.defaultValue != null) { node.defaultValue = props.defaultValue; } }, postMountWrapper: function (element, props) { var node = element; // This is in postMount because we need access to the DOM node, which is not // available until after the component has mounted. var textContent = node.textContent; // Only set node.value if textContent is equal to the expected // initial value. In IE10/IE11 there is a bug where the placeholder attribute // will populate textContent as well. // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/ if (textContent === node._wrapperState.initialValue) { node.value = textContent; } }, restoreControlledState: function (element, props) { // DOM component is still mounted; update ReactDOMTextarea.updateWrapper(element, props); } }; var ReactDOMFiberTextarea = ReactDOMTextarea; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule omittedCloseTags */ // For HTML, certain tags should omit their close tag. We keep a whitelist for // those special-case tags. var omittedCloseTags = { area: true, base: true, br: true, col: true, embed: true, hr: true, img: true, input: true, keygen: true, link: true, meta: true, param: true, source: true, track: true, wbr: true }; var omittedCloseTags_1 = omittedCloseTags; // For HTML, certain tags cannot have children. This has the same purpose as // `omittedCloseTags` except that `menuitem` should still have its closing tag. var voidElementTags = _assign({ menuitem: true }, omittedCloseTags_1); var voidElementTags_1 = voidElementTags; { var warning$13 = require$$0; } var HTML$1 = '__html'; function getDeclarationErrorAddendum$1(getCurrentOwnerName) { { var ownerName = getCurrentOwnerName(); if (ownerName) { // TODO: also report the stack. return '\n\nThis DOM node was rendered by `' + ownerName + '`.'; } } return ''; } function assertValidProps(tag, props, getCurrentOwnerName) { if (!props) { return; } // Note the use of `==` which checks for null or undefined. if (voidElementTags_1[tag]) { !(props.children == null && props.dangerouslySetInnerHTML == null) ? invariant(false, '%s is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.%s', tag, getDeclarationErrorAddendum$1(getCurrentOwnerName)) : void 0; } if (props.dangerouslySetInnerHTML != null) { !(props.children == null) ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : void 0; !(typeof props.dangerouslySetInnerHTML === 'object' && HTML$1 in props.dangerouslySetInnerHTML) ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.') : void 0; } { warning$13(props.suppressContentEditableWarning || !props.contentEditable || props.children == null, 'A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.'); } !(props.style == null || typeof props.style === 'object') ? invariant(false, 'The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + \'em\'}} when using JSX.%s', getDeclarationErrorAddendum$1(getCurrentOwnerName)) : void 0; } var assertValidProps_1 = assertValidProps; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule inputValueTracking * */ function isCheckable(elem) { var type = elem.type; var nodeName = elem.nodeName; return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio'); } function getTracker(node) { return node._valueTracker; } function detachTracker(node) { node._valueTracker = null; } function getValueFromNode(node) { var value = ''; if (!node) { return value; } if (isCheckable(node)) { value = node.checked ? 'true' : 'false'; } else { value = node.value; } return value; } function trackValueOnNode(node) { var valueField = isCheckable(node) ? 'checked' : 'value'; var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField); var currentValue = '' + node[valueField]; // if someone has already defined a value or Safari, then bail // and don't track value will cause over reporting of changes, // but it's better then a hard failure // (needed for certain tests that spyOn input values and Safari) if (node.hasOwnProperty(valueField) || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') { return; } Object.defineProperty(node, valueField, { enumerable: descriptor.enumerable, configurable: true, get: function () { return descriptor.get.call(this); }, set: function (value) { currentValue = '' + value; descriptor.set.call(this, value); } }); var tracker = { getValue: function () { return currentValue; }, setValue: function (value) { currentValue = '' + value; }, stopTracking: function () { detachTracker(node); delete node[valueField]; } }; return tracker; } var inputValueTracking = { // exposed for testing _getTrackerFromNode: getTracker, track: function (node) { if (getTracker(node)) { return; } // TODO: Once it's just Fiber we can move this to node._wrapperState node._valueTracker = trackValueOnNode(node); }, updateValueIfChanged: function (node) { if (!node) { return false; } var tracker = getTracker(node); // if there is no tracker at this point it's unlikely // that trying again will succeed if (!tracker) { return true; } var lastValue = tracker.getValue(); var nextValue = getValueFromNode(node); if (nextValue !== lastValue) { tracker.setValue(nextValue); return true; } return false; }, stopTracking: function (node) { var tracker = getTracker(node); if (tracker) { tracker.stopTracking(); } } }; var inputValueTracking_1 = inputValueTracking; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule isCustomComponent * */ function isCustomComponent(tagName, props) { if (tagName.indexOf('-') === -1) { return typeof props.is === 'string'; } switch (tagName) { // These are reserved SVG and MathML elements. // We don't mind this whitelist too much because we expect it to never grow. // The alternative is to track the namespace in a few places which is convoluted. // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts case 'annotation-xml': case 'color-profile': case 'font-face': case 'font-face-src': case 'font-face-uri': case 'font-face-format': case 'font-face-name': case 'missing-glyph': return false; default: return true; } } var isCustomComponent_1 = isCustomComponent; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule createMicrosoftUnsafeLocalFunction */ /* globals MSApp */ /** * Create a function which has 'unsafe' privileges (required by windows8 apps) */ var createMicrosoftUnsafeLocalFunction = function (func) { if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) { return function (arg0, arg1, arg2, arg3) { MSApp.execUnsafeLocalFunction(function () { return func(arg0, arg1, arg2, arg3); }); }; } else { return func; } }; var createMicrosoftUnsafeLocalFunction_1 = createMicrosoftUnsafeLocalFunction; var Namespaces$1 = DOMNamespaces.Namespaces; // SVG temp container for IE lacking innerHTML var reusableSVGContainer; /** * Set the innerHTML property of a node * * @param {DOMElement} node * @param {string} html * @internal */ var setInnerHTML = createMicrosoftUnsafeLocalFunction_1(function (node, html) { // IE does not have innerHTML for SVG nodes, so instead we inject the // new markup in a temp node and then move the child nodes across into // the target node if (node.namespaceURI === Namespaces$1.svg && !('innerHTML' in node)) { reusableSVGContainer = reusableSVGContainer || document.createElement('div'); reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>'; var svgNode = reusableSVGContainer.firstChild; while (svgNode.firstChild) { node.appendChild(svgNode.firstChild); } } else { node.innerHTML = html; } }); var setInnerHTML_1 = setInnerHTML; /** * Copyright (c) 2016-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * Based on the escape-html library, which is used under the MIT License below: * * Copyright (c) 2012-2013 TJ Holowaychuk * Copyright (c) 2015 Andreas Lubbe * Copyright (c) 2015 Tiancheng "Timothy" Gu * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * 'Software'), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * @providesModule escapeTextContentForBrowser */ // code copied and modified from escape-html /** * Module variables. * @private */ var matchHtmlRegExp = /["'&<>]/; /** * Escape special characters in the given string of html. * * @param {string} string The string to escape for inserting into HTML * @return {string} * @public */ function escapeHtml(string) { var str = '' + string; var match = matchHtmlRegExp.exec(str); if (!match) { return str; } var escape; var html = ''; var index = 0; var lastIndex = 0; for (index = match.index; index < str.length; index++) { switch (str.charCodeAt(index)) { case 34: // " escape = '"'; break; case 38: // & escape = '&'; break; case 39: // ' escape = '''; // modified from escape-html; used to be ''' break; case 60: // < escape = '<'; break; case 62: // > escape = '>'; break; default: continue; } if (lastIndex !== index) { html += str.substring(lastIndex, index); } lastIndex = index + 1; html += escape; } return lastIndex !== index ? html + str.substring(lastIndex, index) : html; } // end code copied and modified from escape-html /** * Escapes text to prevent scripting attacks. * * @param {*} text Text value to escape. * @return {string} An escaped string. */ function escapeTextContentForBrowser(text) { if (typeof text === 'boolean' || typeof text === 'number') { // this shortcircuit helps perf for types that we know will never have // special characters, especially given that this function is used often // for numeric dom ids. return '' + text; } return escapeHtml(text); } var escapeTextContentForBrowser_1 = escapeTextContentForBrowser; var TEXT_NODE$2 = HTMLNodeType_1.TEXT_NODE; /** * Set the textContent property of a node, ensuring that whitespace is preserved * even in IE8. innerText is a poor substitute for textContent and, among many * issues, inserts <br> instead of the literal newline chars. innerHTML behaves * as it should. * * @param {DOMElement} node * @param {string} text * @internal */ var setTextContent = function (node, text) { if (text) { var firstChild = node.firstChild; if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE$2) { firstChild.nodeValue = text; return; } } node.textContent = text; }; if (ExecutionEnvironment.canUseDOM) { if (!('textContent' in document.documentElement)) { setTextContent = function (node, text) { if (node.nodeType === TEXT_NODE$2) { node.nodeValue = text; return; } setInnerHTML_1(node, escapeTextContentForBrowser_1(text)); }; } } var setTextContent_1 = setTextContent; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule validAriaProperties */ var ariaProperties = { 'aria-current': 0, // state 'aria-details': 0, 'aria-disabled': 0, // state 'aria-hidden': 0, // state 'aria-invalid': 0, // state 'aria-keyshortcuts': 0, 'aria-label': 0, 'aria-roledescription': 0, // Widget Attributes 'aria-autocomplete': 0, 'aria-checked': 0, 'aria-expanded': 0, 'aria-haspopup': 0, 'aria-level': 0, 'aria-modal': 0, 'aria-multiline': 0, 'aria-multiselectable': 0, 'aria-orientation': 0, 'aria-placeholder': 0, 'aria-pressed': 0, 'aria-readonly': 0, 'aria-required': 0, 'aria-selected': 0, 'aria-sort': 0, 'aria-valuemax': 0, 'aria-valuemin': 0, 'aria-valuenow': 0, 'aria-valuetext': 0, // Live Region Attributes 'aria-atomic': 0, 'aria-busy': 0, 'aria-live': 0, 'aria-relevant': 0, // Drag-and-Drop Attributes 'aria-dropeffect': 0, 'aria-grabbed': 0, // Relationship Attributes 'aria-activedescendant': 0, 'aria-colcount': 0, 'aria-colindex': 0, 'aria-colspan': 0, 'aria-controls': 0, 'aria-describedby': 0, 'aria-errormessage': 0, 'aria-flowto': 0, 'aria-labelledby': 0, 'aria-owns': 0, 'aria-posinset': 0, 'aria-rowcount': 0, 'aria-rowindex': 0, 'aria-rowspan': 0, 'aria-setsize': 0 }; var validAriaProperties$1 = ariaProperties; var warnedProperties = {}; var rARIA = new RegExp('^(aria)-[' + DOMProperty_1.ATTRIBUTE_NAME_CHAR + ']*$'); var rARIACamel = new RegExp('^(aria)[A-Z][' + DOMProperty_1.ATTRIBUTE_NAME_CHAR + ']*$'); var hasOwnProperty = Object.prototype.hasOwnProperty; { var warning$14 = require$$0; var _require$5 = ReactGlobalSharedState_1, ReactComponentTreeHook$1 = _require$5.ReactComponentTreeHook, ReactDebugCurrentFrame$1 = _require$5.ReactDebugCurrentFrame; var getStackAddendumByID = ReactComponentTreeHook$1.getStackAddendumByID; var validAriaProperties = validAriaProperties$1; } function getStackAddendum(debugID) { if (debugID != null) { // This can only happen on Stack return getStackAddendumByID(debugID); } else { // This can only happen on Fiber / Server var stack = ReactDebugCurrentFrame$1.getStackAddendum(); return stack != null ? stack : ''; } } function validateProperty(tagName, name, debugID) { if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) { return true; } if (rARIACamel.test(name)) { var ariaName = 'aria-' + name.slice(4).toLowerCase(); var correctName = validAriaProperties.hasOwnProperty(ariaName) ? ariaName : null; // If this is an aria-* attribute, but is not listed in the known DOM // DOM properties, then it is an invalid aria-* attribute. if (correctName == null) { warning$14(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.%s', name, getStackAddendum(debugID)); warnedProperties[name] = true; return true; } // aria-* attributes should be lowercase; suggest the lowercase version. if (name !== correctName) { warning$14(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?%s', name, correctName, getStackAddendum(debugID)); warnedProperties[name] = true; return true; } } if (rARIA.test(name)) { var lowerCasedName = name.toLowerCase(); var standardName = validAriaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; // If this is an aria-* attribute, but is not listed in the known DOM // DOM properties, then it is an invalid aria-* attribute. if (standardName == null) { warnedProperties[name] = true; return false; } // aria-* attributes should be lowercase; suggest the lowercase version. if (name !== standardName) { warning$14(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?%s', name, standardName, getStackAddendum(debugID)); warnedProperties[name] = true; return true; } } return true; } function warnInvalidARIAProps(type, props, debugID) { var invalidProps = []; for (var key in props) { var isValid = validateProperty(type, key, debugID); if (!isValid) { invalidProps.push(key); } } var unknownPropString = invalidProps.map(function (prop) { return '`' + prop + '`'; }).join(', '); if (invalidProps.length === 1) { warning$14(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, type, getStackAddendum(debugID)); } else if (invalidProps.length > 1) { warning$14(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, type, getStackAddendum(debugID)); } } function validateProperties(type, props, debugID /* Stack only */) { if (isCustomComponent_1(type, props)) { return; } warnInvalidARIAProps(type, props, debugID); } var ReactDOMInvalidARIAHook$1 = { // Fiber validateProperties: validateProperties, // Stack onBeforeMountComponent: function (debugID, element) { if (true && element != null && typeof element.type === 'string') { validateProperties(element.type, element.props, debugID); } }, onBeforeUpdateComponent: function (debugID, element) { if (true && element != null && typeof element.type === 'string') { validateProperties(element.type, element.props, debugID); } } }; var ReactDOMInvalidARIAHook_1 = ReactDOMInvalidARIAHook$1; { var warning$15 = require$$0; var _require$6 = ReactGlobalSharedState_1, ReactComponentTreeHook$2 = _require$6.ReactComponentTreeHook, ReactDebugCurrentFrame$2 = _require$6.ReactDebugCurrentFrame; var getStackAddendumByID$1 = ReactComponentTreeHook$2.getStackAddendumByID; } var didWarnValueNull = false; function getStackAddendum$1(debugID) { if (debugID != null) { // This can only happen on Stack return getStackAddendumByID$1(debugID); } else { // This can only happen on Fiber / Server var stack = ReactDebugCurrentFrame$2.getStackAddendum(); return stack != null ? stack : ''; } } function validateProperties$1(type, props, debugID /* Stack only */) { if (type !== 'input' && type !== 'textarea' && type !== 'select') { return; } if (props != null && props.value === null && !didWarnValueNull) { warning$15(false, '`value` prop on `%s` should not be null. ' + 'Consider using the empty string to clear the component or `undefined` ' + 'for uncontrolled components.%s', type, getStackAddendum$1(debugID)); didWarnValueNull = true; } } var ReactDOMNullInputValuePropHook$1 = { // Fiber validateProperties: validateProperties$1, // Stack onBeforeMountComponent: function (debugID, element) { if (true && element != null && typeof element.type === 'string') { validateProperties$1(element.type, element.props, debugID); } }, onBeforeUpdateComponent: function (debugID, element) { if (true && element != null && typeof element.type === 'string') { validateProperties$1(element.type, element.props, debugID); } } }; var ReactDOMNullInputValuePropHook_1 = ReactDOMNullInputValuePropHook$1; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule possibleStandardNames */ // When adding attributes to the HTML or SVG whitelist, be sure to // also add them to this module to ensure casing and incorrect name // warnings. var possibleStandardNames$1 = { // HTML accept: 'accept', acceptcharset: 'acceptCharset', 'accept-charset': 'acceptCharset', accesskey: 'accessKey', action: 'action', allowfullscreen: 'allowFullScreen', allowtransparency: 'allowTransparency', alt: 'alt', as: 'as', async: 'async', autocapitalize: 'autoCapitalize', autocomplete: 'autoComplete', autocorrect: 'autoCorrect', autofocus: 'autoFocus', autoplay: 'autoPlay', autosave: 'autoSave', capture: 'capture', cellpadding: 'cellPadding', cellspacing: 'cellSpacing', challenge: 'challenge', charset: 'charSet', checked: 'checked', children: 'children', cite: 'cite', 'class': 'className', classid: 'classID', classname: 'className', cols: 'cols', colspan: 'colSpan', content: 'content', contenteditable: 'contentEditable', contextmenu: 'contextMenu', controls: 'controls', controlslist: 'controlsList', coords: 'coords', crossorigin: 'crossOrigin', dangerouslysetinnerhtml: 'dangerouslySetInnerHTML', data: 'data', datetime: 'dateTime', 'default': 'default', defaultchecked: 'defaultChecked', defaultvalue: 'defaultValue', defer: 'defer', dir: 'dir', disabled: 'disabled', download: 'download', draggable: 'draggable', enctype: 'encType', 'for': 'htmlFor', form: 'form', formmethod: 'formMethod', formaction: 'formAction', formenctype: 'formEncType', formnovalidate: 'formNoValidate', formtarget: 'formTarget', frameborder: 'frameBorder', headers: 'headers', height: 'height', hidden: 'hidden', high: 'high', href: 'href', hreflang: 'hrefLang', htmlfor: 'htmlFor', httpequiv: 'httpEquiv', 'http-equiv': 'httpEquiv', icon: 'icon', id: 'id', innerhtml: 'innerHTML', inputmode: 'inputMode', integrity: 'integrity', is: 'is', itemid: 'itemID', itemprop: 'itemProp', itemref: 'itemRef', itemscope: 'itemScope', itemtype: 'itemType', keyparams: 'keyParams', keytype: 'keyType', kind: 'kind', label: 'label', lang: 'lang', list: 'list', loop: 'loop', low: 'low', manifest: 'manifest', marginwidth: 'marginWidth', marginheight: 'marginHeight', max: 'max', maxlength: 'maxLength', media: 'media', mediagroup: 'mediaGroup', method: 'method', min: 'min', minlength: 'minLength', multiple: 'multiple', muted: 'muted', name: 'name', nonce: 'nonce', novalidate: 'noValidate', open: 'open', optimum: 'optimum', pattern: 'pattern', placeholder: 'placeholder', playsinline: 'playsInline', poster: 'poster', preload: 'preload', profile: 'profile', radiogroup: 'radioGroup', readonly: 'readOnly', referrerpolicy: 'referrerPolicy', rel: 'rel', required: 'required', reversed: 'reversed', role: 'role', rows: 'rows', rowspan: 'rowSpan', sandbox: 'sandbox', scope: 'scope', scoped: 'scoped', scrolling: 'scrolling', seamless: 'seamless', selected: 'selected', shape: 'shape', size: 'size', sizes: 'sizes', span: 'span', spellcheck: 'spellCheck', src: 'src', srcdoc: 'srcDoc', srclang: 'srcLang', srcset: 'srcSet', start: 'start', step: 'step', style: 'style', summary: 'summary', tabindex: 'tabIndex', target: 'target', title: 'title', type: 'type', usemap: 'useMap', value: 'value', width: 'width', wmode: 'wmode', wrap: 'wrap', // SVG about: 'about', accentheight: 'accentHeight', 'accent-height': 'accentHeight', accumulate: 'accumulate', additive: 'additive', alignmentbaseline: 'alignmentBaseline', 'alignment-baseline': 'alignmentBaseline', allowreorder: 'allowReorder', alphabetic: 'alphabetic', amplitude: 'amplitude', arabicform: 'arabicForm', 'arabic-form': 'arabicForm', ascent: 'ascent', attributename: 'attributeName', attributetype: 'attributeType', autoreverse: 'autoReverse', azimuth: 'azimuth', basefrequency: 'baseFrequency', baselineshift: 'baselineShift', 'baseline-shift': 'baselineShift', baseprofile: 'baseProfile', bbox: 'bbox', begin: 'begin', bias: 'bias', by: 'by', calcmode: 'calcMode', capheight: 'capHeight', 'cap-height': 'capHeight', clip: 'clip', clippath: 'clipPath', 'clip-path': 'clipPath', clippathunits: 'clipPathUnits', cliprule: 'clipRule', 'clip-rule': 'clipRule', color: 'color', colorinterpolation: 'colorInterpolation', 'color-interpolation': 'colorInterpolation', colorinterpolationfilters: 'colorInterpolationFilters', 'color-interpolation-filters': 'colorInterpolationFilters', colorprofile: 'colorProfile', 'color-profile': 'colorProfile', colorrendering: 'colorRendering', 'color-rendering': 'colorRendering', contentscripttype: 'contentScriptType', contentstyletype: 'contentStyleType', cursor: 'cursor', cx: 'cx', cy: 'cy', d: 'd', datatype: 'datatype', decelerate: 'decelerate', descent: 'descent', diffuseconstant: 'diffuseConstant', direction: 'direction', display: 'display', divisor: 'divisor', dominantbaseline: 'dominantBaseline', 'dominant-baseline': 'dominantBaseline', dur: 'dur', dx: 'dx', dy: 'dy', edgemode: 'edgeMode', elevation: 'elevation', enablebackground: 'enableBackground', 'enable-background': 'enableBackground', end: 'end', exponent: 'exponent', externalresourcesrequired: 'externalResourcesRequired', fill: 'fill', fillopacity: 'fillOpacity', 'fill-opacity': 'fillOpacity', fillrule: 'fillRule', 'fill-rule': 'fillRule', filter: 'filter', filterres: 'filterRes', filterunits: 'filterUnits', floodopacity: 'floodOpacity', 'flood-opacity': 'floodOpacity', floodcolor: 'floodColor', 'flood-color': 'floodColor', focusable: 'focusable', fontfamily: 'fontFamily', 'font-family': 'fontFamily', fontsize: 'fontSize', 'font-size': 'fontSize', fontsizeadjust: 'fontSizeAdjust', 'font-size-adjust': 'fontSizeAdjust', fontstretch: 'fontStretch', 'font-stretch': 'fontStretch', fontstyle: 'fontStyle', 'font-style': 'fontStyle', fontvariant: 'fontVariant', 'font-variant': 'fontVariant', fontweight: 'fontWeight', 'font-weight': 'fontWeight', format: 'format', from: 'from', fx: 'fx', fy: 'fy', g1: 'g1', g2: 'g2', glyphname: 'glyphName', 'glyph-name': 'glyphName', glyphorientationhorizontal: 'glyphOrientationHorizontal', 'glyph-orientation-horizontal': 'glyphOrientationHorizontal', glyphorientationvertical: 'glyphOrientationVertical', 'glyph-orientation-vertical': 'glyphOrientationVertical', glyphref: 'glyphRef', gradienttransform: 'gradientTransform', gradientunits: 'gradientUnits', hanging: 'hanging', horizadvx: 'horizAdvX', 'horiz-adv-x': 'horizAdvX', horizoriginx: 'horizOriginX', 'horiz-origin-x': 'horizOriginX', ideographic: 'ideographic', imagerendering: 'imageRendering', 'image-rendering': 'imageRendering', in2: 'in2', 'in': 'in', inlist: 'inlist', intercept: 'intercept', k1: 'k1', k2: 'k2', k3: 'k3', k4: 'k4', k: 'k', kernelmatrix: 'kernelMatrix', kernelunitlength: 'kernelUnitLength', kerning: 'kerning', keypoints: 'keyPoints', keysplines: 'keySplines', keytimes: 'keyTimes', lengthadjust: 'lengthAdjust', letterspacing: 'letterSpacing', 'letter-spacing': 'letterSpacing', lightingcolor: 'lightingColor', 'lighting-color': 'lightingColor', limitingconeangle: 'limitingConeAngle', local: 'local', markerend: 'markerEnd', 'marker-end': 'markerEnd', markerheight: 'markerHeight', markermid: 'markerMid', 'marker-mid': 'markerMid', markerstart: 'markerStart', 'marker-start': 'markerStart', markerunits: 'markerUnits', markerwidth: 'markerWidth', mask: 'mask', maskcontentunits: 'maskContentUnits', maskunits: 'maskUnits', mathematical: 'mathematical', mode: 'mode', numoctaves: 'numOctaves', offset: 'offset', opacity: 'opacity', operator: 'operator', order: 'order', orient: 'orient', orientation: 'orientation', origin: 'origin', overflow: 'overflow', overlineposition: 'overlinePosition', 'overline-position': 'overlinePosition', overlinethickness: 'overlineThickness', 'overline-thickness': 'overlineThickness', paintorder: 'paintOrder', 'paint-order': 'paintOrder', panose1: 'panose1', 'panose-1': 'panose1', pathlength: 'pathLength', patterncontentunits: 'patternContentUnits', patterntransform: 'patternTransform', patternunits: 'patternUnits', pointerevents: 'pointerEvents', 'pointer-events': 'pointerEvents', points: 'points', pointsatx: 'pointsAtX', pointsaty: 'pointsAtY', pointsatz: 'pointsAtZ', prefix: 'prefix', preservealpha: 'preserveAlpha', preserveaspectratio: 'preserveAspectRatio', primitiveunits: 'primitiveUnits', property: 'property', r: 'r', radius: 'radius', refx: 'refX', refy: 'refY', renderingintent: 'renderingIntent', 'rendering-intent': 'renderingIntent', repeatcount: 'repeatCount', repeatdur: 'repeatDur', requiredextensions: 'requiredExtensions', requiredfeatures: 'requiredFeatures', resource: 'resource', restart: 'restart', result: 'result', results: 'results', rotate: 'rotate', rx: 'rx', ry: 'ry', scale: 'scale', security: 'security', seed: 'seed', shaperendering: 'shapeRendering', 'shape-rendering': 'shapeRendering', slope: 'slope', spacing: 'spacing', specularconstant: 'specularConstant', specularexponent: 'specularExponent', speed: 'speed', spreadmethod: 'spreadMethod', startoffset: 'startOffset', stddeviation: 'stdDeviation', stemh: 'stemh', stemv: 'stemv', stitchtiles: 'stitchTiles', stopcolor: 'stopColor', 'stop-color': 'stopColor', stopopacity: 'stopOpacity', 'stop-opacity': 'stopOpacity', strikethroughposition: 'strikethroughPosition', 'strikethrough-position': 'strikethroughPosition', strikethroughthickness: 'strikethroughThickness', 'strikethrough-thickness': 'strikethroughThickness', string: 'string', stroke: 'stroke', strokedasharray: 'strokeDasharray', 'stroke-dasharray': 'strokeDasharray', strokedashoffset: 'strokeDashoffset', 'stroke-dashoffset': 'strokeDashoffset', strokelinecap: 'strokeLinecap', 'stroke-linecap': 'strokeLinecap', strokelinejoin: 'strokeLinejoin', 'stroke-linejoin': 'strokeLinejoin', strokemiterlimit: 'strokeMiterlimit', 'stroke-miterlimit': 'strokeMiterlimit', strokewidth: 'strokeWidth', 'stroke-width': 'strokeWidth', strokeopacity: 'strokeOpacity', 'stroke-opacity': 'strokeOpacity', suppresscontenteditablewarning: 'suppressContentEditableWarning', surfacescale: 'surfaceScale', systemlanguage: 'systemLanguage', tablevalues: 'tableValues', targetx: 'targetX', targety: 'targetY', textanchor: 'textAnchor', 'text-anchor': 'textAnchor', textdecoration: 'textDecoration', 'text-decoration': 'textDecoration', textlength: 'textLength', textrendering: 'textRendering', 'text-rendering': 'textRendering', to: 'to', transform: 'transform', 'typeof': 'typeof', u1: 'u1', u2: 'u2', underlineposition: 'underlinePosition', 'underline-position': 'underlinePosition', underlinethickness: 'underlineThickness', 'underline-thickness': 'underlineThickness', unicode: 'unicode', unicodebidi: 'unicodeBidi', 'unicode-bidi': 'unicodeBidi', unicoderange: 'unicodeRange', 'unicode-range': 'unicodeRange', unitsperem: 'unitsPerEm', 'units-per-em': 'unitsPerEm', unselectable: 'unselectable', valphabetic: 'vAlphabetic', 'v-alphabetic': 'vAlphabetic', values: 'values', vectoreffect: 'vectorEffect', 'vector-effect': 'vectorEffect', version: 'version', vertadvy: 'vertAdvY', 'vert-adv-y': 'vertAdvY', vertoriginx: 'vertOriginX', 'vert-origin-x': 'vertOriginX', vertoriginy: 'vertOriginY', 'vert-origin-y': 'vertOriginY', vhanging: 'vHanging', 'v-hanging': 'vHanging', videographic: 'vIdeographic', 'v-ideographic': 'vIdeographic', viewbox: 'viewBox', viewtarget: 'viewTarget', visibility: 'visibility', vmathematical: 'vMathematical', 'v-mathematical': 'vMathematical', vocab: 'vocab', widths: 'widths', wordspacing: 'wordSpacing', 'word-spacing': 'wordSpacing', writingmode: 'writingMode', 'writing-mode': 'writingMode', x1: 'x1', x2: 'x2', x: 'x', xchannelselector: 'xChannelSelector', xheight: 'xHeight', 'x-height': 'xHeight', xlinkactuate: 'xlinkActuate', 'xlink:actuate': 'xlinkActuate', xlinkarcrole: 'xlinkArcrole', 'xlink:arcrole': 'xlinkArcrole', xlinkhref: 'xlinkHref', 'xlink:href': 'xlinkHref', xlinkrole: 'xlinkRole', 'xlink:role': 'xlinkRole', xlinkshow: 'xlinkShow', 'xlink:show': 'xlinkShow', xlinktitle: 'xlinkTitle', 'xlink:title': 'xlinkTitle', xlinktype: 'xlinkType', 'xlink:type': 'xlinkType', xmlbase: 'xmlBase', 'xml:base': 'xmlBase', xmllang: 'xmlLang', 'xml:lang': 'xmlLang', xmlns: 'xmlns', 'xml:space': 'xmlSpace', xmlnsxlink: 'xmlnsXlink', 'xmlns:xlink': 'xmlnsXlink', xmlspace: 'xmlSpace', y1: 'y1', y2: 'y2', y: 'y', ychannelselector: 'yChannelSelector', z: 'z', zoomandpan: 'zoomAndPan' }; var possibleStandardNames_1 = possibleStandardNames$1; { var warning$16 = require$$0; var _require$7 = ReactGlobalSharedState_1, ReactComponentTreeHook$3 = _require$7.ReactComponentTreeHook, ReactDebugCurrentFrame$3 = _require$7.ReactDebugCurrentFrame; var getStackAddendumByID$2 = ReactComponentTreeHook$3.getStackAddendumByID; } function getStackAddendum$2(debugID) { if (debugID != null) { // This can only happen on Stack return getStackAddendumByID$2(debugID); } else { // This can only happen on Fiber / Server var stack = ReactDebugCurrentFrame$3.getStackAddendum(); return stack != null ? stack : ''; } } { var warnedProperties$1 = {}; var hasOwnProperty$1 = Object.prototype.hasOwnProperty; var EVENT_NAME_REGEX = /^on[A-Z]/; var rARIA$1 = new RegExp('^(aria)-[' + DOMProperty_1.ATTRIBUTE_NAME_CHAR + ']*$'); var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + DOMProperty_1.ATTRIBUTE_NAME_CHAR + ']*$'); var possibleStandardNames = possibleStandardNames_1; var validateProperty$1 = function (tagName, name, value, debugID) { if (hasOwnProperty$1.call(warnedProperties$1, name) && warnedProperties$1[name]) { return true; } if (EventPluginRegistry_1.registrationNameModules.hasOwnProperty(name)) { return true; } if (EventPluginRegistry_1.plugins.length === 0 && EVENT_NAME_REGEX.test(name)) { // If no event plugins have been injected, we might be in a server environment. // Don't check events in this case. return true; } var lowerCasedName = name.toLowerCase(); var registrationName = EventPluginRegistry_1.possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? EventPluginRegistry_1.possibleRegistrationNames[lowerCasedName] : null; if (registrationName != null) { warning$16(false, 'Invalid event handler property `%s`. Did you mean `%s`?%s', name, registrationName, getStackAddendum$2(debugID)); warnedProperties$1[name] = true; return true; } if (lowerCasedName.indexOf('on') === 0) { warning$16(false, 'Unknown event handler property `%s`. It will be ignored.%s', name, getStackAddendum$2(debugID)); warnedProperties$1[name] = true; return true; } // Let the ARIA attribute hook validate ARIA attributes if (rARIA$1.test(name) || rARIACamel$1.test(name)) { return true; } if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') { warning$16(false, 'React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' + 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' + 'are not needed/supported by React.'); warnedProperties$1[name] = true; return true; } if (lowerCasedName === 'innerhtml') { warning$16(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.'); warnedProperties$1[name] = true; return true; } if (lowerCasedName === 'aria') { warning$16(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.'); warnedProperties$1[name] = true; return true; } if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') { warning$16(false, 'Received a `%s` for string attribute `is`. If this is expected, cast ' + 'the value to a string.%s', typeof value, getStackAddendum$2(debugID)); warnedProperties$1[name] = true; return true; } if (typeof value === 'number' && isNaN(value)) { warning$16(false, 'Received NaN for numeric attribute `%s`. If this is expected, cast ' + 'the value to a string.%s', name, getStackAddendum$2(debugID)); warnedProperties$1[name] = true; return true; } var isReserved = DOMProperty_1.isReservedProp(name); // Known attributes should match the casing specified in the property config. if (possibleStandardNames.hasOwnProperty(lowerCasedName)) { var standardName = possibleStandardNames[lowerCasedName]; if (standardName !== name) { warning$16(false, 'Invalid DOM property `%s`. Did you mean `%s`?%s', name, standardName, getStackAddendum$2(debugID)); warnedProperties$1[name] = true; return true; } } else if (!isReserved && name !== lowerCasedName) { // Unknown attributes should have lowercase casing since that's how they // will be cased anyway with server rendering. warning$16(false, 'React does not recognize the `%s` prop on a DOM element. If you ' + 'intentionally want it to appear in the DOM as a custom ' + 'attribute, spell it as lowercase `%s` instead. ' + 'If you accidentally passed it from a parent component, remove ' + 'it from the DOM element.%s', name, lowerCasedName, getStackAddendum$2(debugID)); warnedProperties$1[name] = true; return true; } if (typeof value === 'boolean') { warning$16(DOMProperty_1.shouldAttributeAcceptBooleanValue(name), 'Received `%s` for non-boolean attribute `%s`. If this is expected, cast ' + 'the value to a string.%s', value, name, getStackAddendum$2(debugID)); warnedProperties$1[name] = true; return true; } // Now that we've validated casing, do not validate // data types for reserved props if (isReserved) { return true; } // Warn when a known attribute is a bad type if (!DOMProperty_1.shouldSetAttribute(name, value)) { warnedProperties$1[name] = true; return false; } return true; }; } var warnUnknownProperties = function (type, props, debugID) { var unknownProps = []; for (var key in props) { var isValid = validateProperty$1(type, key, props[key], debugID); if (!isValid) { unknownProps.push(key); } } var unknownPropString = unknownProps.map(function (prop) { return '`' + prop + '`'; }).join(', '); if (unknownProps.length === 1) { warning$16(false, 'Invalid value for prop %s on <%s> tag. Either remove it from the element, ' + 'or pass a string or number value to keep it in the DOM. ' + 'For details, see https://fb.me/react-attribute-behavior%s', unknownPropString, type, getStackAddendum$2(debugID)); } else if (unknownProps.length > 1) { warning$16(false, 'Invalid values for props %s on <%s> tag. Either remove them from the element, ' + 'or pass a string or number value to keep them in the DOM. ' + 'For details, see https://fb.me/react-attribute-behavior%s', unknownPropString, type, getStackAddendum$2(debugID)); } }; function validateProperties$2(type, props, debugID /* Stack only */) { if (isCustomComponent_1(type, props)) { return; } warnUnknownProperties(type, props, debugID); } var ReactDOMUnknownPropertyHook$1 = { // Fiber validateProperties: validateProperties$2, // Stack onBeforeMountComponent: function (debugID, element) { if (true && element != null && typeof element.type === 'string') { validateProperties$2(element.type, element.props, debugID); } }, onBeforeUpdateComponent: function (debugID, element) { if (true && element != null && typeof element.type === 'string') { validateProperties$2(element.type, element.props, debugID); } } }; var ReactDOMUnknownPropertyHook_1 = ReactDOMUnknownPropertyHook$1; var getCurrentFiberOwnerName = ReactDebugCurrentFiber_1.getCurrentFiberOwnerName; var DOCUMENT_NODE$1 = HTMLNodeType_1.DOCUMENT_NODE; var DOCUMENT_FRAGMENT_NODE$1 = HTMLNodeType_1.DOCUMENT_FRAGMENT_NODE; { var warning$3 = require$$0; var _require3$1 = ReactDebugCurrentFiber_1, getCurrentFiberStackAddendum = _require3$1.getCurrentFiberStackAddendum; var ReactDOMInvalidARIAHook = ReactDOMInvalidARIAHook_1; var ReactDOMNullInputValuePropHook = ReactDOMNullInputValuePropHook_1; var ReactDOMUnknownPropertyHook = ReactDOMUnknownPropertyHook_1; var validateARIAProperties = ReactDOMInvalidARIAHook.validateProperties; var validateInputProperties = ReactDOMNullInputValuePropHook.validateProperties; var validateUnknownProperties = ReactDOMUnknownPropertyHook.validateProperties; } var didWarnInvalidHydration = false; var didWarnShadyDOM = false; var listenTo = ReactBrowserEventEmitter_1.listenTo; var registrationNameModules = EventPluginRegistry_1.registrationNameModules; var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML'; var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning'; var CHILDREN = 'children'; var STYLE = 'style'; var HTML = '__html'; var HTML_NAMESPACE$1 = DOMNamespaces.Namespaces.html; var getIntrinsicNamespace$1 = DOMNamespaces.getIntrinsicNamespace; { var warnedUnknownTags = { // Chrome is the only major browser not shipping <time>. But as of July // 2017 it intends to ship it due to widespread usage. We intentionally // *don't* warn for <time> even if it's unrecognized by Chrome because // it soon will be, and many apps have been using it anyway. time: true }; var validatePropertiesInDevelopment = function (type, props) { validateARIAProperties(type, props); validateInputProperties(type, props); validateUnknownProperties(type, props); }; var warnForTextDifference = function (serverText, clientText) { if (didWarnInvalidHydration) { return; } didWarnInvalidHydration = true; warning$3(false, 'Text content did not match. Server: "%s" Client: "%s"', serverText, clientText); }; var warnForPropDifference = function (propName, serverValue, clientValue) { if (didWarnInvalidHydration) { return; } didWarnInvalidHydration = true; warning$3(false, 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(serverValue), JSON.stringify(clientValue)); }; var warnForExtraAttributes = function (attributeNames) { if (didWarnInvalidHydration) { return; } didWarnInvalidHydration = true; var names = []; attributeNames.forEach(function (name) { names.push(name); }); warning$3(false, 'Extra attributes from the server: %s', names); }; var warnForInvalidEventListener = function (registrationName, listener) { warning$3(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.%s', registrationName, typeof listener, getCurrentFiberStackAddendum()); }; var testDocument; // Parse the HTML and read it back to normalize the HTML string so that it // can be used for comparison. var normalizeHTML = function (parent, html) { if (!testDocument) { testDocument = document.implementation.createHTMLDocument(); } var testElement = parent.namespaceURI === HTML_NAMESPACE$1 ? testDocument.createElement(parent.tagName) : testDocument.createElementNS(parent.namespaceURI, parent.tagName); testElement.innerHTML = html; return testElement.innerHTML; }; } function ensureListeningTo(rootContainerElement, registrationName) { var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE$1 || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE$1; var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument; listenTo(registrationName, doc); } function getOwnerDocumentFromRootContainer(rootContainerElement) { return rootContainerElement.nodeType === DOCUMENT_NODE$1 ? rootContainerElement : rootContainerElement.ownerDocument; } // There are so many media events, it makes sense to just // maintain a list rather than create a `trapBubbledEvent` for each var mediaEvents = { topAbort: 'abort', topCanPlay: 'canplay', topCanPlayThrough: 'canplaythrough', topDurationChange: 'durationchange', topEmptied: 'emptied', topEncrypted: 'encrypted', topEnded: 'ended', topError: 'error', topLoadedData: 'loadeddata', topLoadedMetadata: 'loadedmetadata', topLoadStart: 'loadstart', topPause: 'pause', topPlay: 'play', topPlaying: 'playing', topProgress: 'progress', topRateChange: 'ratechange', topSeeked: 'seeked', topSeeking: 'seeking', topStalled: 'stalled', topSuspend: 'suspend', topTimeUpdate: 'timeupdate', topVolumeChange: 'volumechange', topWaiting: 'waiting' }; function trapClickOnNonInteractiveElement(node) { // Mobile Safari does not fire properly bubble click events on // non-interactive elements, which means delegated click listeners do not // fire. The workaround for this bug involves attaching an empty click // listener on the target node. // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html // Just set it using the onclick property so that we don't have to manage any // bookkeeping for it. Not sure if we need to clear it when the listener is // removed. // TODO: Only do this for the relevant Safaris maybe? node.onclick = emptyFunction; } function setInitialDOMProperties(domElement, rootContainerElement, nextProps, isCustomComponentTag) { for (var propKey in nextProps) { if (!nextProps.hasOwnProperty(propKey)) { continue; } var nextProp = nextProps[propKey]; if (propKey === STYLE) { { if (nextProp) { // Freeze the next style object so that we can assume it won't be // mutated. We have already warned for this in the past. Object.freeze(nextProp); } } // Relies on `updateStylesByID` not mutating `styleUpdates`. CSSPropertyOperations_1.setValueForStyles(domElement, nextProp); } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { var nextHtml = nextProp ? nextProp[HTML] : undefined; if (nextHtml != null) { setInnerHTML_1(domElement, nextHtml); } } else if (propKey === CHILDREN) { if (typeof nextProp === 'string') { setTextContent_1(domElement, nextProp); } else if (typeof nextProp === 'number') { setTextContent_1(domElement, '' + nextProp); } } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING) { // Noop } else if (registrationNameModules.hasOwnProperty(propKey)) { if (nextProp != null) { if (true && typeof nextProp !== 'function') { warnForInvalidEventListener(propKey, nextProp); } ensureListeningTo(rootContainerElement, propKey); } } else if (isCustomComponentTag) { DOMPropertyOperations_1.setValueForAttribute(domElement, propKey, nextProp); } else if (nextProp != null) { // If we're updating to null or undefined, we should remove the property // from the DOM node instead of inadvertently setting to a string. This // brings us in line with the same behavior we have on initial render. DOMPropertyOperations_1.setValueForProperty(domElement, propKey, nextProp); } } } function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) { // TODO: Handle wasCustomComponentTag for (var i = 0; i < updatePayload.length; i += 2) { var propKey = updatePayload[i]; var propValue = updatePayload[i + 1]; if (propKey === STYLE) { CSSPropertyOperations_1.setValueForStyles(domElement, propValue); } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { setInnerHTML_1(domElement, propValue); } else if (propKey === CHILDREN) { setTextContent_1(domElement, propValue); } else if (isCustomComponentTag) { if (propValue != null) { DOMPropertyOperations_1.setValueForAttribute(domElement, propKey, propValue); } else { DOMPropertyOperations_1.deleteValueForAttribute(domElement, propKey); } } else if (propValue != null) { DOMPropertyOperations_1.setValueForProperty(domElement, propKey, propValue); } else { // If we're updating to null or undefined, we should remove the property // from the DOM node instead of inadvertently setting to a string. This // brings us in line with the same behavior we have on initial render. DOMPropertyOperations_1.deleteValueForProperty(domElement, propKey); } } } var ReactDOMFiberComponent = { createElement: function (type, props, rootContainerElement, parentNamespace) { // We create tags in the namespace of their parent container, except HTML var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement); var domElement; var namespaceURI = parentNamespace; if (namespaceURI === HTML_NAMESPACE$1) { namespaceURI = getIntrinsicNamespace$1(type); } if (namespaceURI === HTML_NAMESPACE$1) { { var isCustomComponentTag = isCustomComponent_1(type, props); // Should this check be gated by parent namespace? Not sure we want to // allow <SVG> or <mATH>. warning$3(isCustomComponentTag || type === type.toLowerCase(), '<%s /> is using uppercase HTML. Always use lowercase HTML tags ' + 'in React.', type); } if (type === 'script') { // Create the script via .innerHTML so its "parser-inserted" flag is // set to true and it does not execute var div = ownerDocument.createElement('div'); div.innerHTML = '<script><' + '/script>'; // eslint-disable-line // This is guaranteed to yield a script element. var firstChild = div.firstChild; domElement = div.removeChild(firstChild); } else if (typeof props.is === 'string') { // $FlowIssue `createElement` should be updated for Web Components domElement = ownerDocument.createElement(type, { is: props.is }); } else { // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug. // See discussion in https://github.com/facebook/react/pull/6896 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240 domElement = ownerDocument.createElement(type); } } else { domElement = ownerDocument.createElementNS(namespaceURI, type); } { if (namespaceURI === HTML_NAMESPACE$1) { if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) { warnedUnknownTags[type] = true; warning$3(false, 'The tag <%s> is unrecognized in this browser. ' + 'If you meant to render a React component, start its name with ' + 'an uppercase letter.', type); } } } return domElement; }, createTextNode: function (text, rootContainerElement) { return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text); }, setInitialProperties: function (domElement, tag, rawProps, rootContainerElement) { var isCustomComponentTag = isCustomComponent_1(tag, rawProps); { validatePropertiesInDevelopment(tag, rawProps); if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) { warning$3(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerName() || 'A component'); didWarnShadyDOM = true; } } // TODO: Make sure that we check isMounted before firing any of these events. var props; switch (tag) { case 'iframe': case 'object': ReactBrowserEventEmitter_1.trapBubbledEvent('topLoad', 'load', domElement); props = rawProps; break; case 'video': case 'audio': // Create listener for each media event for (var event in mediaEvents) { if (mediaEvents.hasOwnProperty(event)) { ReactBrowserEventEmitter_1.trapBubbledEvent(event, mediaEvents[event], domElement); } } props = rawProps; break; case 'source': ReactBrowserEventEmitter_1.trapBubbledEvent('topError', 'error', domElement); props = rawProps; break; case 'img': case 'image': ReactBrowserEventEmitter_1.trapBubbledEvent('topError', 'error', domElement); ReactBrowserEventEmitter_1.trapBubbledEvent('topLoad', 'load', domElement); props = rawProps; break; case 'form': ReactBrowserEventEmitter_1.trapBubbledEvent('topReset', 'reset', domElement); ReactBrowserEventEmitter_1.trapBubbledEvent('topSubmit', 'submit', domElement); props = rawProps; break; case 'details': ReactBrowserEventEmitter_1.trapBubbledEvent('topToggle', 'toggle', domElement); props = rawProps; break; case 'input': ReactDOMFiberInput.initWrapperState(domElement, rawProps); props = ReactDOMFiberInput.getHostProps(domElement, rawProps); ReactBrowserEventEmitter_1.trapBubbledEvent('topInvalid', 'invalid', domElement); // For controlled components we always need to ensure we're listening // to onChange. Even if there is no listener. ensureListeningTo(rootContainerElement, 'onChange'); break; case 'option': ReactDOMFiberOption.validateProps(domElement, rawProps); props = ReactDOMFiberOption.getHostProps(domElement, rawProps); break; case 'select': ReactDOMFiberSelect.initWrapperState(domElement, rawProps); props = ReactDOMFiberSelect.getHostProps(domElement, rawProps); ReactBrowserEventEmitter_1.trapBubbledEvent('topInvalid', 'invalid', domElement); // For controlled components we always need to ensure we're listening // to onChange. Even if there is no listener. ensureListeningTo(rootContainerElement, 'onChange'); break; case 'textarea': ReactDOMFiberTextarea.initWrapperState(domElement, rawProps); props = ReactDOMFiberTextarea.getHostProps(domElement, rawProps); ReactBrowserEventEmitter_1.trapBubbledEvent('topInvalid', 'invalid', domElement); // For controlled components we always need to ensure we're listening // to onChange. Even if there is no listener. ensureListeningTo(rootContainerElement, 'onChange'); break; default: props = rawProps; } assertValidProps_1(tag, props, getCurrentFiberOwnerName); setInitialDOMProperties(domElement, rootContainerElement, props, isCustomComponentTag); switch (tag) { case 'input': // TODO: Make sure we check if this is still unmounted or do any clean // up necessary since we never stop tracking anymore. inputValueTracking_1.track(domElement); ReactDOMFiberInput.postMountWrapper(domElement, rawProps); break; case 'textarea': // TODO: Make sure we check if this is still unmounted or do any clean // up necessary since we never stop tracking anymore. inputValueTracking_1.track(domElement); ReactDOMFiberTextarea.postMountWrapper(domElement, rawProps); break; case 'option': ReactDOMFiberOption.postMountWrapper(domElement, rawProps); break; case 'select': ReactDOMFiberSelect.postMountWrapper(domElement, rawProps); break; default: if (typeof props.onClick === 'function') { // TODO: This cast may not be sound for SVG, MathML or custom elements. trapClickOnNonInteractiveElement(domElement); } break; } }, // Calculate the diff between the two objects. diffProperties: function (domElement, tag, lastRawProps, nextRawProps, rootContainerElement) { { validatePropertiesInDevelopment(tag, nextRawProps); } var updatePayload = null; var lastProps; var nextProps; switch (tag) { case 'input': lastProps = ReactDOMFiberInput.getHostProps(domElement, lastRawProps); nextProps = ReactDOMFiberInput.getHostProps(domElement, nextRawProps); updatePayload = []; break; case 'option': lastProps = ReactDOMFiberOption.getHostProps(domElement, lastRawProps); nextProps = ReactDOMFiberOption.getHostProps(domElement, nextRawProps); updatePayload = []; break; case 'select': lastProps = ReactDOMFiberSelect.getHostProps(domElement, lastRawProps); nextProps = ReactDOMFiberSelect.getHostProps(domElement, nextRawProps); updatePayload = []; break; case 'textarea': lastProps = ReactDOMFiberTextarea.getHostProps(domElement, lastRawProps); nextProps = ReactDOMFiberTextarea.getHostProps(domElement, nextRawProps); updatePayload = []; break; default: lastProps = lastRawProps; nextProps = nextRawProps; if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') { // TODO: This cast may not be sound for SVG, MathML or custom elements. trapClickOnNonInteractiveElement(domElement); } break; } assertValidProps_1(tag, nextProps, getCurrentFiberOwnerName); var propKey; var styleName; var styleUpdates = null; for (propKey in lastProps) { if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) { continue; } if (propKey === STYLE) { var lastStyle = lastProps[propKey]; for (styleName in lastStyle) { if (lastStyle.hasOwnProperty(styleName)) { if (!styleUpdates) { styleUpdates = {}; } styleUpdates[styleName] = ''; } } } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) { // Noop. This is handled by the clear text mechanism. } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING) { // Noop } else if (registrationNameModules.hasOwnProperty(propKey)) { // This is a special case. If any listener updates we need to ensure // that the "current" fiber pointer gets updated so we need a commit // to update this element. if (!updatePayload) { updatePayload = []; } } else { // For all other deleted properties we add it to the queue. We use // the whitelist in the commit phase instead. (updatePayload = updatePayload || []).push(propKey, null); } } for (propKey in nextProps) { var nextProp = nextProps[propKey]; var lastProp = lastProps != null ? lastProps[propKey] : undefined; if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) { continue; } if (propKey === STYLE) { { if (nextProp) { // Freeze the next style object so that we can assume it won't be // mutated. We have already warned for this in the past. Object.freeze(nextProp); } } if (lastProp) { // Unset styles on `lastProp` but not on `nextProp`. for (styleName in lastProp) { if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) { if (!styleUpdates) { styleUpdates = {}; } styleUpdates[styleName] = ''; } } // Update styles that changed since `lastProp`. for (styleName in nextProp) { if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) { if (!styleUpdates) { styleUpdates = {}; } styleUpdates[styleName] = nextProp[styleName]; } } } else { // Relies on `updateStylesByID` not mutating `styleUpdates`. if (!styleUpdates) { if (!updatePayload) { updatePayload = []; } updatePayload.push(propKey, styleUpdates); } styleUpdates = nextProp; } } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { var nextHtml = nextProp ? nextProp[HTML] : undefined; var lastHtml = lastProp ? lastProp[HTML] : undefined; if (nextHtml != null) { if (lastHtml !== nextHtml) { (updatePayload = updatePayload || []).push(propKey, '' + nextHtml); } } else { // TODO: It might be too late to clear this if we have children // inserted already. } } else if (propKey === CHILDREN) { if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) { (updatePayload = updatePayload || []).push(propKey, '' + nextProp); } } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING) { // Noop } else if (registrationNameModules.hasOwnProperty(propKey)) { if (nextProp != null) { // We eagerly listen to this even though we haven't committed yet. if (true && typeof nextProp !== 'function') { warnForInvalidEventListener(propKey, nextProp); } ensureListeningTo(rootContainerElement, propKey); } if (!updatePayload && lastProp !== nextProp) { // This is a special case. If any listener updates we need to ensure // that the "current" props pointer gets updated so we need a commit // to update this element. updatePayload = []; } } else { // For any other property we always add it to the queue and then we // filter it out using the whitelist during the commit. (updatePayload = updatePayload || []).push(propKey, nextProp); } } if (styleUpdates) { (updatePayload = updatePayload || []).push(STYLE, styleUpdates); } return updatePayload; }, // Apply the diff. updateProperties: function (domElement, updatePayload, tag, lastRawProps, nextRawProps) { var wasCustomComponentTag = isCustomComponent_1(tag, lastRawProps); var isCustomComponentTag = isCustomComponent_1(tag, nextRawProps); // Apply the diff. updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag); // TODO: Ensure that an update gets scheduled if any of the special props // changed. switch (tag) { case 'input': // Update the wrapper around inputs *after* updating props. This has to // happen after `updateDOMProperties`. Otherwise HTML5 input validations // raise warnings and prevent the new value from being assigned. ReactDOMFiberInput.updateWrapper(domElement, nextRawProps); // We also check that we haven't missed a value update, such as a // Radio group shifting the checked value to another named radio input. inputValueTracking_1.updateValueIfChanged(domElement); break; case 'textarea': ReactDOMFiberTextarea.updateWrapper(domElement, nextRawProps); break; case 'select': // <select> value update needs to occur after <option> children // reconciliation ReactDOMFiberSelect.postUpdateWrapper(domElement, nextRawProps); break; } }, diffHydratedProperties: function (domElement, tag, rawProps, parentNamespace, rootContainerElement) { { var isCustomComponentTag = isCustomComponent_1(tag, rawProps); validatePropertiesInDevelopment(tag, rawProps); if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) { warning$3(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerName() || 'A component'); didWarnShadyDOM = true; } } // TODO: Make sure that we check isMounted before firing any of these events. switch (tag) { case 'iframe': case 'object': ReactBrowserEventEmitter_1.trapBubbledEvent('topLoad', 'load', domElement); break; case 'video': case 'audio': // Create listener for each media event for (var event in mediaEvents) { if (mediaEvents.hasOwnProperty(event)) { ReactBrowserEventEmitter_1.trapBubbledEvent(event, mediaEvents[event], domElement); } } break; case 'source': ReactBrowserEventEmitter_1.trapBubbledEvent('topError', 'error', domElement); break; case 'img': case 'image': ReactBrowserEventEmitter_1.trapBubbledEvent('topError', 'error', domElement); ReactBrowserEventEmitter_1.trapBubbledEvent('topLoad', 'load', domElement); break; case 'form': ReactBrowserEventEmitter_1.trapBubbledEvent('topReset', 'reset', domElement); ReactBrowserEventEmitter_1.trapBubbledEvent('topSubmit', 'submit', domElement); break; case 'details': ReactBrowserEventEmitter_1.trapBubbledEvent('topToggle', 'toggle', domElement); break; case 'input': ReactDOMFiberInput.initWrapperState(domElement, rawProps); ReactBrowserEventEmitter_1.trapBubbledEvent('topInvalid', 'invalid', domElement); // For controlled components we always need to ensure we're listening // to onChange. Even if there is no listener. ensureListeningTo(rootContainerElement, 'onChange'); break; case 'option': ReactDOMFiberOption.validateProps(domElement, rawProps); break; case 'select': ReactDOMFiberSelect.initWrapperState(domElement, rawProps); ReactBrowserEventEmitter_1.trapBubbledEvent('topInvalid', 'invalid', domElement); // For controlled components we always need to ensure we're listening // to onChange. Even if there is no listener. ensureListeningTo(rootContainerElement, 'onChange'); break; case 'textarea': ReactDOMFiberTextarea.initWrapperState(domElement, rawProps); ReactBrowserEventEmitter_1.trapBubbledEvent('topInvalid', 'invalid', domElement); // For controlled components we always need to ensure we're listening // to onChange. Even if there is no listener. ensureListeningTo(rootContainerElement, 'onChange'); break; } assertValidProps_1(tag, rawProps, getCurrentFiberOwnerName); { var extraAttributeNames = new Set(); var attributes = domElement.attributes; for (var i = 0; i < attributes.length; i++) { var name = attributes[i].name.toLowerCase(); switch (name) { // Built-in SSR attribute is whitelisted case 'data-reactroot': break; // Controlled attributes are not validated // TODO: Only ignore them on controlled tags. case 'value': break; case 'checked': break; case 'selected': break; default: // Intentionally use the original name. // See discussion in https://github.com/facebook/react/pull/10676. extraAttributeNames.add(attributes[i].name); } } } var updatePayload = null; for (var propKey in rawProps) { if (!rawProps.hasOwnProperty(propKey)) { continue; } var nextProp = rawProps[propKey]; if (propKey === CHILDREN) { // For text content children we compare against textContent. This // might match additional HTML that is hidden when we read it using // textContent. E.g. "foo" will match "f<span>oo</span>" but that still // satisfies our requirement. Our requirement is not to produce perfect // HTML and attributes. Ideally we should preserve structure but it's // ok not to if the visible content is still enough to indicate what // even listeners these nodes might be wired up to. // TODO: Warn if there is more than a single textNode as a child. // TODO: Should we use domElement.firstChild.nodeValue to compare? if (typeof nextProp === 'string') { if (domElement.textContent !== nextProp) { { warnForTextDifference(domElement.textContent, nextProp); } updatePayload = [CHILDREN, nextProp]; } } else if (typeof nextProp === 'number') { if (domElement.textContent !== '' + nextProp) { { warnForTextDifference(domElement.textContent, nextProp); } updatePayload = [CHILDREN, '' + nextProp]; } } } else if (registrationNameModules.hasOwnProperty(propKey)) { if (nextProp != null) { if (true && typeof nextProp !== 'function') { warnForInvalidEventListener(propKey, nextProp); } ensureListeningTo(rootContainerElement, propKey); } } else { // Validate that the properties correspond to their expected values. var serverValue; var propertyInfo; if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || // Controlled attributes are not validated // TODO: Only ignore them on controlled tags. propKey === 'value' || propKey === 'checked' || propKey === 'selected') { // Noop } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { var rawHtml = nextProp ? nextProp[HTML] || '' : ''; var serverHTML = domElement.innerHTML; var expectedHTML = normalizeHTML(domElement, rawHtml); if (expectedHTML !== serverHTML) { warnForPropDifference(propKey, serverHTML, expectedHTML); } } else if (propKey === STYLE) { // $FlowFixMe - Should be inferred as not undefined. extraAttributeNames['delete'](propKey); var expectedStyle = CSSPropertyOperations_1.createDangerousStringForStyles(nextProp); serverValue = domElement.getAttribute('style'); if (expectedStyle !== serverValue) { warnForPropDifference(propKey, serverValue, expectedStyle); } } else if (isCustomComponentTag) { // $FlowFixMe - Should be inferred as not undefined. extraAttributeNames['delete'](propKey.toLowerCase()); serverValue = DOMPropertyOperations_1.getValueForAttribute(domElement, propKey, nextProp); if (nextProp !== serverValue) { warnForPropDifference(propKey, serverValue, nextProp); } } else if (DOMProperty_1.shouldSetAttribute(propKey, nextProp)) { if (propertyInfo = DOMProperty_1.getPropertyInfo(propKey)) { // $FlowFixMe - Should be inferred as not undefined. extraAttributeNames['delete'](propertyInfo.attributeName); serverValue = DOMPropertyOperations_1.getValueForProperty(domElement, propKey, nextProp); } else { var ownNamespace = parentNamespace; if (ownNamespace === HTML_NAMESPACE$1) { ownNamespace = getIntrinsicNamespace$1(tag); } if (ownNamespace === HTML_NAMESPACE$1) { // $FlowFixMe - Should be inferred as not undefined. extraAttributeNames['delete'](propKey.toLowerCase()); } else { // $FlowFixMe - Should be inferred as not undefined. extraAttributeNames['delete'](propKey); } serverValue = DOMPropertyOperations_1.getValueForAttribute(domElement, propKey, nextProp); } if (nextProp !== serverValue) { warnForPropDifference(propKey, serverValue, nextProp); } } } } { // $FlowFixMe - Should be inferred as not undefined. if (extraAttributeNames.size > 0) { // $FlowFixMe - Should be inferred as not undefined. warnForExtraAttributes(extraAttributeNames); } } switch (tag) { case 'input': // TODO: Make sure we check if this is still unmounted or do any clean // up necessary since we never stop tracking anymore. inputValueTracking_1.track(domElement); ReactDOMFiberInput.postMountWrapper(domElement, rawProps); break; case 'textarea': // TODO: Make sure we check if this is still unmounted or do any clean // up necessary since we never stop tracking anymore. inputValueTracking_1.track(domElement); ReactDOMFiberTextarea.postMountWrapper(domElement, rawProps); break; case 'select': case 'option': // For input and textarea we current always set the value property at // post mount to force it to diverge from attributes. However, for // option and select we don't quite do the same thing and select // is not resilient to the DOM state changing so we don't do that here. // TODO: Consider not doing this for input and textarea. break; default: if (typeof rawProps.onClick === 'function') { // TODO: This cast may not be sound for SVG, MathML or custom elements. trapClickOnNonInteractiveElement(domElement); } break; } return updatePayload; }, diffHydratedText: function (textNode, text) { var isDifferent = textNode.nodeValue !== text; { if (isDifferent) { warnForTextDifference(textNode.nodeValue, text); } } return isDifferent; }, warnForDeletedHydratableElement: function (parentNode, child) { { if (didWarnInvalidHydration) { return; } didWarnInvalidHydration = true; warning$3(false, 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase()); } }, warnForDeletedHydratableText: function (parentNode, child) { { if (didWarnInvalidHydration) { return; } didWarnInvalidHydration = true; warning$3(false, 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase()); } }, warnForInsertedHydratedElement: function (parentNode, tag, props) { { if (didWarnInvalidHydration) { return; } didWarnInvalidHydration = true; warning$3(false, 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase()); } }, warnForInsertedHydratedText: function (parentNode, text) { { if (text === '') { // We expect to insert empty text nodes since they're not represented in // the HTML. // TODO: Remove this special case if we can just avoid inserting empty // text nodes. return; } if (didWarnInvalidHydration) { return; } didWarnInvalidHydration = true; warning$3(false, 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase()); } }, restoreControlledState: function (domElement, tag, props) { switch (tag) { case 'input': ReactDOMFiberInput.restoreControlledState(domElement, props); return; case 'textarea': ReactDOMFiberTextarea.restoreControlledState(domElement, props); return; case 'select': ReactDOMFiberSelect.restoreControlledState(domElement, props); return; } } }; var ReactDOMFiberComponent_1 = ReactDOMFiberComponent; // This is a built-in polyfill for requestIdleCallback. It works by scheduling // a requestAnimationFrame, storing the time for the start of the frame, then // scheduling a postMessage which gets scheduled after paint. Within the // postMessage handler do as much work as possible until time + frame rate. // By separating the idle call into a separate event tick we ensure that // layout, paint and other browser work is counted against the available time. // The frame rate is dynamically adjusted. { var warning$17 = require$$0; if (ExecutionEnvironment.canUseDOM && typeof requestAnimationFrame !== 'function') { warning$17(false, 'React depends on requestAnimationFrame. Make sure that you load a ' + 'polyfill in older browsers. http://fb.me/react-polyfills'); } } // TODO: There's no way to cancel, because Fiber doesn't atm. var rIC = void 0; if (!ExecutionEnvironment.canUseDOM) { rIC = function (frameCallback) { setTimeout(function () { frameCallback({ timeRemaining: function () { return Infinity; } }); }); return 0; }; } else if (typeof requestIdleCallback !== 'function') { // Polyfill requestIdleCallback. var scheduledRAFCallback = null; var scheduledRICCallback = null; var isIdleScheduled = false; var isAnimationFrameScheduled = false; var frameDeadline = 0; // We start out assuming that we run at 30fps but then the heuristic tracking // will adjust this value to a faster fps if we get more frequent animation // frames. var previousFrameTime = 33; var activeFrameTime = 33; var frameDeadlineObject = { timeRemaining: typeof performance === 'object' && typeof performance.now === 'function' ? function () { // We assume that if we have a performance timer that the rAF callback // gets a performance timer value. Not sure if this is always true. return frameDeadline - performance.now(); } : function () { // As a fallback we use Date.now. return frameDeadline - Date.now(); } }; // We use the postMessage trick to defer idle work until after the repaint. var messageKey = '__reactIdleCallback$' + Math.random().toString(36).slice(2); var idleTick = function (event) { if (event.source !== window || event.data !== messageKey) { return; } isIdleScheduled = false; var callback = scheduledRICCallback; scheduledRICCallback = null; if (callback !== null) { callback(frameDeadlineObject); } }; // Assumes that we have addEventListener in this environment. Might need // something better for old IE. window.addEventListener('message', idleTick, false); var animationTick = function (rafTime) { isAnimationFrameScheduled = false; var nextFrameTime = rafTime - frameDeadline + activeFrameTime; if (nextFrameTime < activeFrameTime && previousFrameTime < activeFrameTime) { if (nextFrameTime < 8) { // Defensive coding. We don't support higher frame rates than 120hz. // If we get lower than that, it is probably a bug. nextFrameTime = 8; } // If one frame goes long, then the next one can be short to catch up. // If two frames are short in a row, then that's an indication that we // actually have a higher frame rate than what we're currently optimizing. // We adjust our heuristic dynamically accordingly. For example, if we're // running on 120hz display or 90hz VR display. // Take the max of the two in case one of them was an anomaly due to // missed frame deadlines. activeFrameTime = nextFrameTime < previousFrameTime ? previousFrameTime : nextFrameTime; } else { previousFrameTime = nextFrameTime; } frameDeadline = rafTime + activeFrameTime; if (!isIdleScheduled) { isIdleScheduled = true; window.postMessage(messageKey, '*'); } var callback = scheduledRAFCallback; scheduledRAFCallback = null; if (callback !== null) { callback(rafTime); } }; rIC = function (callback) { // This assumes that we only schedule one callback at a time because that's // how Fiber uses it. scheduledRICCallback = callback; if (!isAnimationFrameScheduled) { // If rAF didn't already schedule one, we need to schedule a frame. // TODO: If this rAF doesn't materialize because the browser throttles, we // might want to still have setTimeout trigger rIC as a backup to ensure // that we keep performing work. isAnimationFrameScheduled = true; requestAnimationFrame(animationTick); } return 0; }; } else { rIC = requestIdleCallback; } var rIC_1 = rIC; var ReactDOMFrameScheduling = { rIC: rIC_1 }; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule ReactFeatureFlags * */ var ReactFeatureFlags = { enableAsyncSubtreeAPI: true }; var ReactFeatureFlags_1 = ReactFeatureFlags; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule ReactPriorityLevel * */ var ReactPriorityLevel = { NoWork: 0, // No work is pending. SynchronousPriority: 1, // For controlled text inputs. Synchronous side-effects. TaskPriority: 2, // Completes at the end of the current tick. HighPriority: 3, // Interaction that needs to complete pretty soon to feel responsive. LowPriority: 4, // Data fetching, or result from updating stores. OffscreenPriority: 5 }; var CallbackEffect = ReactTypeOfSideEffect.Callback; var NoWork = ReactPriorityLevel.NoWork; var SynchronousPriority = ReactPriorityLevel.SynchronousPriority; var TaskPriority = ReactPriorityLevel.TaskPriority; var ClassComponent$2 = ReactTypeOfWork.ClassComponent; var HostRoot$2 = ReactTypeOfWork.HostRoot; { var warning$19 = require$$0; } // Callbacks are not validated until invocation // Singly linked-list of updates. When an update is scheduled, it is added to // the queue of the current fiber and the work-in-progress fiber. The two queues // are separate but they share a persistent structure. // // During reconciliation, updates are removed from the work-in-progress fiber, // but they remain on the current fiber. That ensures that if a work-in-progress // is aborted, the aborted updates are recovered by cloning from current. // // The work-in-progress queue is always a subset of the current queue. // // When the tree is committed, the work-in-progress becomes the current. var _queue1 = void 0; var _queue2 = void 0; function comparePriority(a, b) { // When comparing update priorities, treat sync and Task work as equal. // TODO: Could we avoid the need for this by always coercing sync priority // to Task when scheduling an update? if ((a === TaskPriority || a === SynchronousPriority) && (b === TaskPriority || b === SynchronousPriority)) { return 0; } if (a === NoWork && b !== NoWork) { return -255; } if (a !== NoWork && b === NoWork) { return 255; } return a - b; } function createUpdateQueue() { var queue = { first: null, last: null, hasForceUpdate: false, callbackList: null }; { queue.isProcessing = false; } return queue; } function cloneUpdate(update) { return { priorityLevel: update.priorityLevel, partialState: update.partialState, callback: update.callback, isReplace: update.isReplace, isForced: update.isForced, isTopLevelUnmount: update.isTopLevelUnmount, next: null }; } function insertUpdateIntoQueue(queue, update, insertAfter, insertBefore) { if (insertAfter !== null) { insertAfter.next = update; } else { // This is the first item in the queue. update.next = queue.first; queue.first = update; } if (insertBefore !== null) { update.next = insertBefore; } else { // This is the last item in the queue. queue.last = update; } } // Returns the update after which the incoming update should be inserted into // the queue, or null if it should be inserted at beginning. function findInsertionPosition(queue, update) { var priorityLevel = update.priorityLevel; var insertAfter = null; var insertBefore = null; if (queue.last !== null && comparePriority(queue.last.priorityLevel, priorityLevel) <= 0) { // Fast path for the common case where the update should be inserted at // the end of the queue. insertAfter = queue.last; } else { insertBefore = queue.first; while (insertBefore !== null && comparePriority(insertBefore.priorityLevel, priorityLevel) <= 0) { insertAfter = insertBefore; insertBefore = insertBefore.next; } } return insertAfter; } function ensureUpdateQueues(fiber) { var alternateFiber = fiber.alternate; var queue1 = fiber.updateQueue; if (queue1 === null) { queue1 = fiber.updateQueue = createUpdateQueue(); } var queue2 = void 0; if (alternateFiber !== null) { queue2 = alternateFiber.updateQueue; if (queue2 === null) { queue2 = alternateFiber.updateQueue = createUpdateQueue(); } } else { queue2 = null; } _queue1 = queue1; // Return null if there is no alternate queue, or if its queue is the same. _queue2 = queue2 !== queue1 ? queue2 : null; } // The work-in-progress queue is a subset of the current queue (if it exists). // We need to insert the incoming update into both lists. However, it's possible // that the correct position in one list will be different from the position in // the other. Consider the following case: // // Current: 3-5-6 // Work-in-progress: 6 // // Then we receive an update with priority 4 and insert it into each list: // // Current: 3-4-5-6 // Work-in-progress: 4-6 // // In the current queue, the new update's `next` pointer points to the update // with priority 5. But in the work-in-progress queue, the pointer points to the // update with priority 6. Because these two queues share the same persistent // data structure, this won't do. (This can only happen when the incoming update // has higher priority than all the updates in the work-in-progress queue.) // // To solve this, in the case where the incoming update needs to be inserted // into two different positions, we'll make a clone of the update and insert // each copy into a separate queue. This forks the list while maintaining a // persistent structure, because the update that is added to the work-in-progress // is always added to the front of the list. // // However, if incoming update is inserted into the same position of both lists, // we shouldn't make a copy. // // If the update is cloned, it returns the cloned update. function insertUpdate(fiber, update) { // We'll have at least one and at most two distinct update queues. ensureUpdateQueues(fiber); var queue1 = _queue1; var queue2 = _queue2; // Warn if an update is scheduled from inside an updater function. { if (queue1.isProcessing || queue2 !== null && queue2.isProcessing) { warning$19(false, 'An update (setState, replaceState, or forceUpdate) was scheduled ' + 'from inside an update function. Update functions should be pure, ' + 'with zero side-effects. Consider using componentDidUpdate or a ' + 'callback.'); } } // Find the insertion position in the first queue. var insertAfter1 = findInsertionPosition(queue1, update); var insertBefore1 = insertAfter1 !== null ? insertAfter1.next : queue1.first; if (queue2 === null) { // If there's no alternate queue, there's nothing else to do but insert. insertUpdateIntoQueue(queue1, update, insertAfter1, insertBefore1); return null; } // If there is an alternate queue, find the insertion position. var insertAfter2 = findInsertionPosition(queue2, update); var insertBefore2 = insertAfter2 !== null ? insertAfter2.next : queue2.first; // Now we can insert into the first queue. This must come after finding both // insertion positions because it mutates the list. insertUpdateIntoQueue(queue1, update, insertAfter1, insertBefore1); // See if the insertion positions are equal. Be careful to only compare // non-null values. if (insertBefore1 === insertBefore2 && insertBefore1 !== null || insertAfter1 === insertAfter2 && insertAfter1 !== null) { // The insertion positions are the same, so when we inserted into the first // queue, it also inserted into the alternate. All we need to do is update // the alternate queue's `first` and `last` pointers, in case they // have changed. if (insertAfter2 === null) { queue2.first = update; } if (insertBefore2 === null) { queue2.last = null; } return null; } else { // The insertion positions are different, so we need to clone the update and // insert the clone into the alternate queue. var update2 = cloneUpdate(update); insertUpdateIntoQueue(queue2, update2, insertAfter2, insertBefore2); return update2; } } function addUpdate(fiber, partialState, callback, priorityLevel) { var update = { priorityLevel: priorityLevel, partialState: partialState, callback: callback, isReplace: false, isForced: false, isTopLevelUnmount: false, next: null }; insertUpdate(fiber, update); } var addUpdate_1 = addUpdate; function addReplaceUpdate(fiber, state, callback, priorityLevel) { var update = { priorityLevel: priorityLevel, partialState: state, callback: callback, isReplace: true, isForced: false, isTopLevelUnmount: false, next: null }; insertUpdate(fiber, update); } var addReplaceUpdate_1 = addReplaceUpdate; function addForceUpdate(fiber, callback, priorityLevel) { var update = { priorityLevel: priorityLevel, partialState: null, callback: callback, isReplace: false, isForced: true, isTopLevelUnmount: false, next: null }; insertUpdate(fiber, update); } var addForceUpdate_1 = addForceUpdate; function getUpdatePriority(fiber) { var updateQueue = fiber.updateQueue; if (updateQueue === null) { return NoWork; } if (fiber.tag !== ClassComponent$2 && fiber.tag !== HostRoot$2) { return NoWork; } return updateQueue.first !== null ? updateQueue.first.priorityLevel : NoWork; } var getUpdatePriority_1 = getUpdatePriority; function addTopLevelUpdate$1(fiber, partialState, callback, priorityLevel) { var isTopLevelUnmount = partialState.element === null; var update = { priorityLevel: priorityLevel, partialState: partialState, callback: callback, isReplace: false, isForced: false, isTopLevelUnmount: isTopLevelUnmount, next: null }; var update2 = insertUpdate(fiber, update); if (isTopLevelUnmount) { // TODO: Redesign the top-level mount/update/unmount API to avoid this // special case. var queue1 = _queue1; var queue2 = _queue2; // Drop all updates that are lower-priority, so that the tree is not // remounted. We need to do this for both queues. if (queue1 !== null && update.next !== null) { update.next = null; queue1.last = update; } if (queue2 !== null && update2 !== null && update2.next !== null) { update2.next = null; queue2.last = update; } } } var addTopLevelUpdate_1 = addTopLevelUpdate$1; function getStateFromUpdate(update, instance, prevState, props) { var partialState = update.partialState; if (typeof partialState === 'function') { var updateFn = partialState; return updateFn.call(instance, prevState, props); } else { return partialState; } } function beginUpdateQueue(current, workInProgress, queue, instance, prevState, props, priorityLevel) { if (current !== null && current.updateQueue === queue) { // We need to create a work-in-progress queue, by cloning the current queue. var currentQueue = queue; queue = workInProgress.updateQueue = { first: currentQueue.first, last: currentQueue.last, // These fields are no longer valid because they were already committed. // Reset them. callbackList: null, hasForceUpdate: false }; } { // Set this flag so we can warn if setState is called inside the update // function of another setState. queue.isProcessing = true; } // Calculate these using the the existing values as a base. var callbackList = queue.callbackList; var hasForceUpdate = queue.hasForceUpdate; // Applies updates with matching priority to the previous state to create // a new state object. var state = prevState; var dontMutatePrevState = true; var update = queue.first; while (update !== null && comparePriority(update.priorityLevel, priorityLevel) <= 0) { // Remove each update from the queue right before it is processed. That way // if setState is called from inside an updater function, the new update // will be inserted in the correct position. queue.first = update.next; if (queue.first === null) { queue.last = null; } var _partialState = void 0; if (update.isReplace) { state = getStateFromUpdate(update, instance, state, props); dontMutatePrevState = true; } else { _partialState = getStateFromUpdate(update, instance, state, props); if (_partialState) { if (dontMutatePrevState) { state = _assign({}, state, _partialState); } else { state = _assign(state, _partialState); } dontMutatePrevState = false; } } if (update.isForced) { hasForceUpdate = true; } // Second condition ignores top-level unmount callbacks if they are not the // last update in the queue, since a subsequent update will cause a remount. if (update.callback !== null && !(update.isTopLevelUnmount && update.next !== null)) { callbackList = callbackList !== null ? callbackList : []; callbackList.push(update.callback); workInProgress.effectTag |= CallbackEffect; } update = update.next; } queue.callbackList = callbackList; queue.hasForceUpdate = hasForceUpdate; if (queue.first === null && callbackList === null && !hasForceUpdate) { // The queue is empty and there are no callbacks. We can reset it. workInProgress.updateQueue = null; } { // No longer processing. queue.isProcessing = false; } return state; } var beginUpdateQueue_1 = beginUpdateQueue; function commitCallbacks(finishedWork, queue, context) { var callbackList = queue.callbackList; if (callbackList === null) { return; } // Set the list to null to make sure they don't get called more than once. queue.callbackList = null; for (var i = 0; i < callbackList.length; i++) { var _callback = callbackList[i]; !(typeof _callback === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback) : void 0; _callback.call(context); } } var commitCallbacks_1 = commitCallbacks; var ReactFiberUpdateQueue = { addUpdate: addUpdate_1, addReplaceUpdate: addReplaceUpdate_1, addForceUpdate: addForceUpdate_1, getUpdatePriority: getUpdatePriority_1, addTopLevelUpdate: addTopLevelUpdate_1, beginUpdateQueue: beginUpdateQueue_1, commitCallbacks: commitCallbacks_1 }; { var warning$21 = require$$0; } var valueStack = []; { var fiberStack = []; } var index = -1; var createCursor$1 = function (defaultValue) { return { current: defaultValue }; }; var isEmpty = function () { return index === -1; }; var pop$1 = function (cursor, fiber) { if (index < 0) { { warning$21(false, 'Unexpected pop.'); } return; } { if (fiber !== fiberStack[index]) { warning$21(false, 'Unexpected Fiber popped.'); } } cursor.current = valueStack[index]; valueStack[index] = null; { fiberStack[index] = null; } index--; }; var push$1 = function (cursor, value, fiber) { index++; valueStack[index] = cursor.current; { fiberStack[index] = fiber; } cursor.current = value; }; var reset = function () { while (index > -1) { valueStack[index] = null; { fiberStack[index] = null; } index--; } }; var ReactFiberStack = { createCursor: createCursor$1, isEmpty: isEmpty, pop: pop$1, push: push$1, reset: reset }; // Trust the developer to only use this with a true check /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule ReactDebugFiberPerf * */ var ReactDebugFiberPerf = null; { var _require$8 = ReactTypeOfWork, HostRoot$4 = _require$8.HostRoot, HostComponent$4 = _require$8.HostComponent, HostText$2 = _require$8.HostText, HostPortal$1 = _require$8.HostPortal, YieldComponent = _require$8.YieldComponent, Fragment = _require$8.Fragment; var getComponentName$5 = getComponentName_1; // Prefix measurements so that it's possible to filter them. // Longer prefixes are hard to read in DevTools. var reactEmoji = '\u269B'; var warningEmoji = '\u26D4'; var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function'; // Keep track of current fiber so that we know the path to unwind on pause. // TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them? var currentFiber = null; // If we're in the middle of user code, which fiber and method is it? // Reusing `currentFiber` would be confusing for this because user code fiber // can change during commit phase too, but we don't need to unwind it (since // lifecycles in the commit phase don't resemble a tree). var currentPhase = null; var currentPhaseFiber = null; // Did lifecycle hook schedule an update? This is often a performance problem, // so we will keep track of it, and include it in the report. // Track commits caused by cascading updates. var isCommitting = false; var hasScheduledUpdateInCurrentCommit = false; var hasScheduledUpdateInCurrentPhase = false; var commitCountInCurrentWorkLoop = 0; var effectCountInCurrentCommit = 0; // During commits, we only show a measurement once per method name // to avoid stretch the commit phase with measurement overhead. var labelsInCurrentCommit = new Set(); var formatMarkName = function (markName) { return reactEmoji + ' ' + markName; }; var formatLabel = function (label, warning) { var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' '; var suffix = warning ? ' Warning: ' + warning : ''; return '' + prefix + label + suffix; }; var beginMark = function (markName) { performance.mark(formatMarkName(markName)); }; var clearMark = function (markName) { performance.clearMarks(formatMarkName(markName)); }; var endMark = function (label, markName, warning) { var formattedMarkName = formatMarkName(markName); var formattedLabel = formatLabel(label, warning); try { performance.measure(formattedLabel, formattedMarkName); } catch (err) {} // If previous mark was missing for some reason, this will throw. // This could only happen if React crashed in an unexpected place earlier. // Don't pile on with more errors. // Clear marks immediately to avoid growing buffer. performance.clearMarks(formattedMarkName); performance.clearMeasures(formattedLabel); }; var getFiberMarkName = function (label, debugID) { return label + ' (#' + debugID + ')'; }; var getFiberLabel = function (componentName, isMounted, phase) { if (phase === null) { // These are composite component total time measurements. return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']'; } else { // Composite component methods. return componentName + '.' + phase; } }; var beginFiberMark = function (fiber, phase) { var componentName = getComponentName$5(fiber) || 'Unknown'; var debugID = fiber._debugID; var isMounted = fiber.alternate !== null; var label = getFiberLabel(componentName, isMounted, phase); if (isCommitting && labelsInCurrentCommit.has(label)) { // During the commit phase, we don't show duplicate labels because // there is a fixed overhead for every measurement, and we don't // want to stretch the commit phase beyond necessary. return false; } labelsInCurrentCommit.add(label); var markName = getFiberMarkName(label, debugID); beginMark(markName); return true; }; var clearFiberMark = function (fiber, phase) { var componentName = getComponentName$5(fiber) || 'Unknown'; var debugID = fiber._debugID; var isMounted = fiber.alternate !== null; var label = getFiberLabel(componentName, isMounted, phase); var markName = getFiberMarkName(label, debugID); clearMark(markName); }; var endFiberMark = function (fiber, phase, warning) { var componentName = getComponentName$5(fiber) || 'Unknown'; var debugID = fiber._debugID; var isMounted = fiber.alternate !== null; var label = getFiberLabel(componentName, isMounted, phase); var markName = getFiberMarkName(label, debugID); endMark(label, markName, warning); }; var shouldIgnoreFiber = function (fiber) { // Host components should be skipped in the timeline. // We could check typeof fiber.type, but does this work with RN? switch (fiber.tag) { case HostRoot$4: case HostComponent$4: case HostText$2: case HostPortal$1: case YieldComponent: case Fragment: return true; default: return false; } }; var clearPendingPhaseMeasurement = function () { if (currentPhase !== null && currentPhaseFiber !== null) { clearFiberMark(currentPhaseFiber, currentPhase); } currentPhaseFiber = null; currentPhase = null; hasScheduledUpdateInCurrentPhase = false; }; var pauseTimers = function () { // Stops all currently active measurements so that they can be resumed // if we continue in a later deferred loop from the same unit of work. var fiber = currentFiber; while (fiber) { if (fiber._debugIsCurrentlyTiming) { endFiberMark(fiber, null, null); } fiber = fiber['return']; } }; var resumeTimersRecursively = function (fiber) { if (fiber['return'] !== null) { resumeTimersRecursively(fiber['return']); } if (fiber._debugIsCurrentlyTiming) { beginFiberMark(fiber, null); } }; var resumeTimers = function () { // Resumes all measurements that were active during the last deferred loop. if (currentFiber !== null) { resumeTimersRecursively(currentFiber); } }; ReactDebugFiberPerf = { recordEffect: function () { effectCountInCurrentCommit++; }, recordScheduleUpdate: function () { if (isCommitting) { hasScheduledUpdateInCurrentCommit = true; } if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') { hasScheduledUpdateInCurrentPhase = true; } }, startWorkTimer: function (fiber) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, this is the fiber to unwind from. currentFiber = fiber; if (!beginFiberMark(fiber, null)) { return; } fiber._debugIsCurrentlyTiming = true; }, cancelWorkTimer: function (fiber) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // Remember we shouldn't complete measurement for this fiber. // Otherwise flamechart will be deep even for small updates. fiber._debugIsCurrentlyTiming = false; clearFiberMark(fiber, null); }, stopWorkTimer: function (fiber) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, its parent is the fiber to unwind from. currentFiber = fiber['return']; if (!fiber._debugIsCurrentlyTiming) { return; } fiber._debugIsCurrentlyTiming = false; endFiberMark(fiber, null, null); }, stopFailedWorkTimer: function (fiber) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, its parent is the fiber to unwind from. currentFiber = fiber['return']; if (!fiber._debugIsCurrentlyTiming) { return; } fiber._debugIsCurrentlyTiming = false; var warning = 'An error was thrown inside this error boundary'; endFiberMark(fiber, null, warning); }, startPhaseTimer: function (fiber, phase) { if (!supportsUserTiming) { return; } clearPendingPhaseMeasurement(); if (!beginFiberMark(fiber, phase)) { return; } currentPhaseFiber = fiber; currentPhase = phase; }, stopPhaseTimer: function () { if (!supportsUserTiming) { return; } if (currentPhase !== null && currentPhaseFiber !== null) { var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null; endFiberMark(currentPhaseFiber, currentPhase, warning); } currentPhase = null; currentPhaseFiber = null; }, startWorkLoopTimer: function () { if (!supportsUserTiming) { return; } commitCountInCurrentWorkLoop = 0; // This is top level call. // Any other measurements are performed within. beginMark('(React Tree Reconciliation)'); // Resume any measurements that were in progress during the last loop. resumeTimers(); }, stopWorkLoopTimer: function () { if (!supportsUserTiming) { return; } var warning = commitCountInCurrentWorkLoop > 1 ? 'There were cascading updates' : null; commitCountInCurrentWorkLoop = 0; // Pause any measurements until the next loop. pauseTimers(); endMark('(React Tree Reconciliation)', '(React Tree Reconciliation)', warning); }, startCommitTimer: function () { if (!supportsUserTiming) { return; } isCommitting = true; hasScheduledUpdateInCurrentCommit = false; labelsInCurrentCommit.clear(); beginMark('(Committing Changes)'); }, stopCommitTimer: function () { if (!supportsUserTiming) { return; } var warning = null; if (hasScheduledUpdateInCurrentCommit) { warning = 'Lifecycle hook scheduled a cascading update'; } else if (commitCountInCurrentWorkLoop > 0) { warning = 'Caused by a cascading update in earlier commit'; } hasScheduledUpdateInCurrentCommit = false; commitCountInCurrentWorkLoop++; isCommitting = false; labelsInCurrentCommit.clear(); endMark('(Committing Changes)', '(Committing Changes)', warning); }, startCommitHostEffectsTimer: function () { if (!supportsUserTiming) { return; } effectCountInCurrentCommit = 0; beginMark('(Committing Host Effects)'); }, stopCommitHostEffectsTimer: function () { if (!supportsUserTiming) { return; } var count = effectCountInCurrentCommit; effectCountInCurrentCommit = 0; endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null); }, startCommitLifeCyclesTimer: function () { if (!supportsUserTiming) { return; } effectCountInCurrentCommit = 0; beginMark('(Calling Lifecycle Methods)'); }, stopCommitLifeCyclesTimer: function () { if (!supportsUserTiming) { return; } var count = effectCountInCurrentCommit; effectCountInCurrentCommit = 0; endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null); } }; } var ReactDebugFiberPerf_1 = ReactDebugFiberPerf; var isFiberMounted$1 = ReactFiberTreeReflection.isFiberMounted; var ClassComponent$3 = ReactTypeOfWork.ClassComponent; var HostRoot$3 = ReactTypeOfWork.HostRoot; var createCursor = ReactFiberStack.createCursor; var pop = ReactFiberStack.pop; var push = ReactFiberStack.push; { var warning$20 = require$$0; var checkPropTypes$1 = checkPropTypes; var ReactDebugCurrentFiber$2 = ReactDebugCurrentFiber_1; var _require4 = ReactDebugFiberPerf_1, startPhaseTimer = _require4.startPhaseTimer, stopPhaseTimer = _require4.stopPhaseTimer; var warnedAboutMissingGetChildContext = {}; } // A cursor to the current merged context object on the stack. var contextStackCursor = createCursor(emptyObject); // A cursor to a boolean indicating whether the context has changed. var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. // We use this to get access to the parent context after we have already // pushed the next context provider, and now need to merge their contexts. var previousContext = emptyObject; function getUnmaskedContext(workInProgress) { var hasOwnContext = isContextProvider$1(workInProgress); if (hasOwnContext) { // If the fiber is a context provider itself, when we read its context // we have already pushed its own child context on the stack. A context // provider should not "see" its own child context. Therefore we read the // previous (parent) context instead for a context provider. return previousContext; } return contextStackCursor.current; } var getUnmaskedContext_1 = getUnmaskedContext; function cacheContext(workInProgress, unmaskedContext, maskedContext) { var instance = workInProgress.stateNode; instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; instance.__reactInternalMemoizedMaskedChildContext = maskedContext; } var cacheContext_1 = cacheContext; var getMaskedContext = function (workInProgress, unmaskedContext) { var type = workInProgress.type; var contextTypes = type.contextTypes; if (!contextTypes) { return emptyObject; } // Avoid recreating masked context unless unmasked context has changed. // Failing to do this will result in unnecessary calls to componentWillReceiveProps. // This may trigger infinite loops if componentWillReceiveProps calls setState. var instance = workInProgress.stateNode; if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) { return instance.__reactInternalMemoizedMaskedChildContext; } var context = {}; for (var key in contextTypes) { context[key] = unmaskedContext[key]; } { var name = getComponentName_1(workInProgress) || 'Unknown'; ReactDebugCurrentFiber$2.setCurrentFiber(workInProgress, null); checkPropTypes$1(contextTypes, context, 'context', name, ReactDebugCurrentFiber$2.getCurrentFiberStackAddendum); ReactDebugCurrentFiber$2.resetCurrentFiber(); } // Cache unmasked context so we can avoid recreating masked context unless necessary. // Context is created before the class component is instantiated so check for instance. if (instance) { cacheContext(workInProgress, unmaskedContext, context); } return context; }; var hasContextChanged = function () { return didPerformWorkStackCursor.current; }; function isContextConsumer(fiber) { return fiber.tag === ClassComponent$3 && fiber.type.contextTypes != null; } var isContextConsumer_1 = isContextConsumer; function isContextProvider$1(fiber) { return fiber.tag === ClassComponent$3 && fiber.type.childContextTypes != null; } var isContextProvider_1 = isContextProvider$1; function popContextProvider(fiber) { if (!isContextProvider$1(fiber)) { return; } pop(didPerformWorkStackCursor, fiber); pop(contextStackCursor, fiber); } var popContextProvider_1 = popContextProvider; var popTopLevelContextObject = function (fiber) { pop(didPerformWorkStackCursor, fiber); pop(contextStackCursor, fiber); }; var pushTopLevelContextObject = function (fiber, context, didChange) { !(contextStackCursor.cursor == null) ? invariant(false, 'Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.') : void 0; push(contextStackCursor, context, fiber); push(didPerformWorkStackCursor, didChange, fiber); }; function processChildContext$1(fiber, parentContext, isReconciling) { var instance = fiber.stateNode; var childContextTypes = fiber.type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. // It has only been added in Fiber to match the (unintentional) behavior in Stack. if (typeof instance.getChildContext !== 'function') { { var componentName = getComponentName_1(fiber) || 'Unknown'; if (!warnedAboutMissingGetChildContext[componentName]) { warnedAboutMissingGetChildContext[componentName] = true; warning$20(false, '%s.childContextTypes is specified but there is no getChildContext() method ' + 'on the instance. You can either define getChildContext() on %s or remove ' + 'childContextTypes from it.', componentName, componentName); } } return parentContext; } var childContext = void 0; { ReactDebugCurrentFiber$2.setCurrentFiber(fiber, 'getChildContext'); startPhaseTimer(fiber, 'getChildContext'); childContext = instance.getChildContext(); stopPhaseTimer(); ReactDebugCurrentFiber$2.resetCurrentFiber(); } for (var contextKey in childContext) { !(contextKey in childContextTypes) ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName_1(fiber) || 'Unknown', contextKey) : void 0; } { var name = getComponentName_1(fiber) || 'Unknown'; // We can only provide accurate element stacks if we pass work-in-progress tree // during the begin or complete phase. However currently this function is also // called from unstable_renderSubtree legacy implementation. In this case it unsafe to // assume anything about the given fiber. We won't pass it down if we aren't sure. // TODO: remove this hack when we delete unstable_renderSubtree in Fiber. var workInProgress = isReconciling ? fiber : null; ReactDebugCurrentFiber$2.setCurrentFiber(workInProgress, null); checkPropTypes$1(childContextTypes, childContext, 'child context', name, ReactDebugCurrentFiber$2.getCurrentFiberStackAddendum); ReactDebugCurrentFiber$2.resetCurrentFiber(); } return _assign({}, parentContext, childContext); } var processChildContext_1 = processChildContext$1; var pushContextProvider = function (workInProgress) { if (!isContextProvider$1(workInProgress)) { return false; } var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. // If the instance does not exist yet, we will push null at first, // and replace it on the stack later when invalidating the context. var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyObject; // Remember the parent context so we can merge with it later. // Inherit the parent's did-perform-work value to avoid inadvertantly blocking updates. previousContext = contextStackCursor.current; push(contextStackCursor, memoizedMergedChildContext, workInProgress); push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress); return true; }; var invalidateContextProvider = function (workInProgress, didChange) { var instance = workInProgress.stateNode; !instance ? invariant(false, 'Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue.') : void 0; if (didChange) { // Merge parent and own context. // Skip this if we're not updating due to sCU. // This avoids unnecessarily recomputing memoized values. var mergedContext = processChildContext$1(workInProgress, previousContext, true); instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. // It is important to unwind the context in the reverse order. pop(didPerformWorkStackCursor, workInProgress); pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. push(contextStackCursor, mergedContext, workInProgress); push(didPerformWorkStackCursor, didChange, workInProgress); } else { pop(didPerformWorkStackCursor, workInProgress); push(didPerformWorkStackCursor, didChange, workInProgress); } }; var resetContext = function () { previousContext = emptyObject; contextStackCursor.current = emptyObject; didPerformWorkStackCursor.current = false; }; var findCurrentUnmaskedContext$1 = function (fiber) { // Currently this is only used with renderSubtreeIntoContainer; not sure if it // makes sense elsewhere !(isFiberMounted$1(fiber) && fiber.tag === ClassComponent$3) ? invariant(false, 'Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue.') : void 0; var node = fiber; while (node.tag !== HostRoot$3) { if (isContextProvider$1(node)) { return node.stateNode.__reactInternalMemoizedMergedChildContext; } var parent = node['return']; !parent ? invariant(false, 'Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.') : void 0; node = parent; } return node.stateNode.context; }; var ReactFiberContext = { getUnmaskedContext: getUnmaskedContext_1, cacheContext: cacheContext_1, getMaskedContext: getMaskedContext, hasContextChanged: hasContextChanged, isContextConsumer: isContextConsumer_1, isContextProvider: isContextProvider_1, popContextProvider: popContextProvider_1, popTopLevelContextObject: popTopLevelContextObject, pushTopLevelContextObject: pushTopLevelContextObject, processChildContext: processChildContext_1, pushContextProvider: pushContextProvider, invalidateContextProvider: invalidateContextProvider, resetContext: resetContext, findCurrentUnmaskedContext: findCurrentUnmaskedContext$1 }; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule ReactTypeOfInternalContext * */ var ReactTypeOfInternalContext = { NoContext: 0, AsyncUpdates: 1 }; var IndeterminateComponent$1 = ReactTypeOfWork.IndeterminateComponent; var ClassComponent$4 = ReactTypeOfWork.ClassComponent; var HostRoot$5 = ReactTypeOfWork.HostRoot; var HostComponent$5 = ReactTypeOfWork.HostComponent; var HostText$3 = ReactTypeOfWork.HostText; var HostPortal$2 = ReactTypeOfWork.HostPortal; var CoroutineComponent = ReactTypeOfWork.CoroutineComponent; var YieldComponent$1 = ReactTypeOfWork.YieldComponent; var Fragment$1 = ReactTypeOfWork.Fragment; var NoWork$1 = ReactPriorityLevel.NoWork; var NoContext = ReactTypeOfInternalContext.NoContext; var NoEffect$1 = ReactTypeOfSideEffect.NoEffect; { var getComponentName$6 = getComponentName_1; var hasBadMapPolyfill = false; try { var nonExtensibleObject = Object.preventExtensions({}); /* eslint-disable no-new */ new Map([[nonExtensibleObject, null]]); new Set([nonExtensibleObject]); /* eslint-enable no-new */ } catch (e) { // TODO: Consider warning about bad polyfills hasBadMapPolyfill = true; } } // A Fiber is work on a Component that needs to be done or was done. There can // be more than one per component. { var debugCounter = 1; } function FiberNode(tag, key, internalContextTag) { // Instance this.tag = tag; this.key = key; this.type = null; this.stateNode = null; // Fiber this['return'] = null; this.child = null; this.sibling = null; this.index = 0; this.ref = null; this.pendingProps = null; this.memoizedProps = null; this.updateQueue = null; this.memoizedState = null; this.internalContextTag = internalContextTag; // Effects this.effectTag = NoEffect$1; this.nextEffect = null; this.firstEffect = null; this.lastEffect = null; this.pendingWorkPriority = NoWork$1; this.alternate = null; { this._debugID = debugCounter++; this._debugSource = null; this._debugOwner = null; this._debugIsCurrentlyTiming = false; if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') { Object.preventExtensions(this); } } } // This is a constructor function, rather than a POJO constructor, still // please ensure we do the following: // 1) Nobody should add any instance methods on this. Instance methods can be // more difficult to predict when they get optimized and they are almost // never inlined properly in static compilers. // 2) Nobody should rely on `instanceof Fiber` for type testing. We should // always know when it is a fiber. // 3) We might want to experiment with using numeric keys since they are easier // to optimize in a non-JIT environment. // 4) We can easily go from a constructor to a createFiber object literal if that // is faster. // 5) It should be easy to port this to a C struct and keep a C implementation // compatible. var createFiber = function (tag, key, internalContextTag) { // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors return new FiberNode(tag, key, internalContextTag); }; function shouldConstruct(Component) { return !!(Component.prototype && Component.prototype.isReactComponent); } // This is used to create an alternate fiber to do work on. var createWorkInProgress = function (current, renderPriority) { var workInProgress = current.alternate; if (workInProgress === null) { // We use a double buffering pooling technique because we know that we'll // only ever need at most two versions of a tree. We pool the "other" unused // node that we're free to reuse. This is lazily created to avoid allocating // extra objects for things that are never updated. It also allow us to // reclaim the extra memory if needed. workInProgress = createFiber(current.tag, current.key, current.internalContextTag); workInProgress.type = current.type; workInProgress.stateNode = current.stateNode; { // DEV-only fields workInProgress._debugID = current._debugID; workInProgress._debugSource = current._debugSource; workInProgress._debugOwner = current._debugOwner; } workInProgress.alternate = current; current.alternate = workInProgress; } else { // We already have an alternate. // Reset the effect tag. workInProgress.effectTag = NoEffect$1; // The effect list is no longer valid. workInProgress.nextEffect = null; workInProgress.firstEffect = null; workInProgress.lastEffect = null; } workInProgress.pendingWorkPriority = renderPriority; workInProgress.child = current.child; workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; // pendingProps is set by the parent during reconciliation. // TODO: Pass this as an argument. // These will be overridden during the parent's reconciliation workInProgress.sibling = current.sibling; workInProgress.index = current.index; workInProgress.ref = current.ref; return workInProgress; }; var createHostRootFiber$1 = function () { var fiber = createFiber(HostRoot$5, null, NoContext); return fiber; }; var createFiberFromElement = function (element, internalContextTag, priorityLevel) { var owner = null; { owner = element._owner; } var fiber = createFiberFromElementType(element.type, element.key, internalContextTag, owner); fiber.pendingProps = element.props; fiber.pendingWorkPriority = priorityLevel; { fiber._debugSource = element._source; fiber._debugOwner = element._owner; } return fiber; }; var createFiberFromFragment = function (elements, internalContextTag, priorityLevel) { // TODO: Consider supporting keyed fragments. Technically, we accidentally // support that in the existing React. var fiber = createFiber(Fragment$1, null, internalContextTag); fiber.pendingProps = elements; fiber.pendingWorkPriority = priorityLevel; return fiber; }; var createFiberFromText = function (content, internalContextTag, priorityLevel) { var fiber = createFiber(HostText$3, null, internalContextTag); fiber.pendingProps = content; fiber.pendingWorkPriority = priorityLevel; return fiber; }; function createFiberFromElementType(type, key, internalContextTag, debugOwner) { var fiber = void 0; if (typeof type === 'function') { fiber = shouldConstruct(type) ? createFiber(ClassComponent$4, key, internalContextTag) : createFiber(IndeterminateComponent$1, key, internalContextTag); fiber.type = type; } else if (typeof type === 'string') { fiber = createFiber(HostComponent$5, key, internalContextTag); fiber.type = type; } else if (typeof type === 'object' && type !== null && typeof type.tag === 'number') { // Currently assumed to be a continuation and therefore is a fiber already. // TODO: The yield system is currently broken for updates in some cases. // The reified yield stores a fiber, but we don't know which fiber that is; // the current or a workInProgress? When the continuation gets rendered here // we don't know if we can reuse that fiber or if we need to clone it. // There is probably a clever way to restructure this. fiber = type; } else { var info = ''; { if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) { info += ' You likely forgot to export your component from the file ' + "it's defined in."; } var ownerName = debugOwner ? getComponentName$6(debugOwner) : null; if (ownerName) { info += '\n\nCheck the render method of `' + ownerName + '`.'; } } invariant(false, 'Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s', type == null ? type : typeof type, info); } return fiber; } var createFiberFromElementType_1 = createFiberFromElementType; var createFiberFromHostInstanceForDeletion = function () { var fiber = createFiber(HostComponent$5, null, NoContext); fiber.type = 'DELETED'; return fiber; }; var createFiberFromCoroutine = function (coroutine, internalContextTag, priorityLevel) { var fiber = createFiber(CoroutineComponent, coroutine.key, internalContextTag); fiber.type = coroutine.handler; fiber.pendingProps = coroutine; fiber.pendingWorkPriority = priorityLevel; return fiber; }; var createFiberFromYield = function (yieldNode, internalContextTag, priorityLevel) { var fiber = createFiber(YieldComponent$1, null, internalContextTag); return fiber; }; var createFiberFromPortal = function (portal, internalContextTag, priorityLevel) { var fiber = createFiber(HostPortal$2, portal.key, internalContextTag); fiber.pendingProps = portal.children || []; fiber.pendingWorkPriority = priorityLevel; fiber.stateNode = { containerInfo: portal.containerInfo, implementation: portal.implementation }; return fiber; }; var largerPriority = function (p1, p2) { return p1 !== NoWork$1 && (p2 === NoWork$1 || p2 > p1) ? p1 : p2; }; var ReactFiber = { createWorkInProgress: createWorkInProgress, createHostRootFiber: createHostRootFiber$1, createFiberFromElement: createFiberFromElement, createFiberFromFragment: createFiberFromFragment, createFiberFromText: createFiberFromText, createFiberFromElementType: createFiberFromElementType_1, createFiberFromHostInstanceForDeletion: createFiberFromHostInstanceForDeletion, createFiberFromCoroutine: createFiberFromCoroutine, createFiberFromYield: createFiberFromYield, createFiberFromPortal: createFiberFromPortal, largerPriority: largerPriority }; var createHostRootFiber = ReactFiber.createHostRootFiber; var createFiberRoot$1 = function (containerInfo) { // Cyclic construction. This cheats the type system right now because // stateNode is any. var uninitializedFiber = createHostRootFiber(); var root = { current: uninitializedFiber, containerInfo: containerInfo, isScheduled: false, nextScheduledRoot: null, context: null, pendingContext: null }; uninitializedFiber.stateNode = root; return root; }; var ReactFiberRoot = { createFiberRoot: createFiberRoot$1 }; var defaultShowDialog = function (capturedError) { return true; }; var showDialog = defaultShowDialog; function logCapturedError$1(capturedError) { var logError = showDialog(capturedError); // Allow injected showDialog() to prevent default console.error logging. // This enables renderers like ReactNative to better manage redbox behavior. if (logError === false) { return; } var error = capturedError.error; { var componentName = capturedError.componentName, componentStack = capturedError.componentStack, errorBoundaryName = capturedError.errorBoundaryName, errorBoundaryFound = capturedError.errorBoundaryFound, willRetry = capturedError.willRetry; var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:'; var errorBoundaryMessage = void 0; // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow. if (errorBoundaryFound && errorBoundaryName) { if (willRetry) { errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.'); } else { errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.'; } } else { errorBoundaryMessage = 'Consider adding an error boundary to your tree to customize error handling behavior.\n' + 'You can learn more about error boundaries at https://fb.me/react-error-boundaries.'; } var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage); // In development, we provide our own message with just the component stack. // We don't include the original error message and JS stack because the browser // has already printed it. Even if the application swallows the error, it is still // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. console.error(combinedMessage); } } var injection$1 = { /** * Display custom dialog for lifecycle errors. * Return false to prevent default behavior of logging to console.error. */ injectDialog: function (fn) { !(showDialog === defaultShowDialog) ? invariant(false, 'The custom dialog was already injected.') : void 0; !(typeof fn === 'function') ? invariant(false, 'Injected showDialog() must be a function.') : void 0; showDialog = fn; } }; var logCapturedError_1 = logCapturedError$1; var ReactFiberErrorLogger = { injection: injection$1, logCapturedError: logCapturedError_1 }; /** * Copyright (c) 2014-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule ReactCoroutine * */ // The Symbol used to tag the special React types. If there is no native Symbol // nor polyfill, then a plain number is used for performance. var REACT_COROUTINE_TYPE$1; var REACT_YIELD_TYPE$1; if (typeof Symbol === 'function' && Symbol['for']) { REACT_COROUTINE_TYPE$1 = Symbol['for']('react.coroutine'); REACT_YIELD_TYPE$1 = Symbol['for']('react.yield'); } else { REACT_COROUTINE_TYPE$1 = 0xeac8; REACT_YIELD_TYPE$1 = 0xeac9; } var createCoroutine = function (children, handler, props) { var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; var coroutine = { // This tag allow us to uniquely identify this as a React Coroutine $$typeof: REACT_COROUTINE_TYPE$1, key: key == null ? null : '' + key, children: children, handler: handler, props: props }; { // TODO: Add _store property for marking this as validated. if (Object.freeze) { Object.freeze(coroutine.props); Object.freeze(coroutine); } } return coroutine; }; var createYield = function (value) { var yieldNode = { // This tag allow us to uniquely identify this as a React Yield $$typeof: REACT_YIELD_TYPE$1, value: value }; { // TODO: Add _store property for marking this as validated. if (Object.freeze) { Object.freeze(yieldNode); } } return yieldNode; }; /** * Verifies the object is a coroutine object. */ var isCoroutine = function (object) { return typeof object === 'object' && object !== null && object.$$typeof === REACT_COROUTINE_TYPE$1; }; /** * Verifies the object is a yield object. */ var isYield = function (object) { return typeof object === 'object' && object !== null && object.$$typeof === REACT_YIELD_TYPE$1; }; var REACT_YIELD_TYPE_1 = REACT_YIELD_TYPE$1; var REACT_COROUTINE_TYPE_1 = REACT_COROUTINE_TYPE$1; var ReactCoroutine = { createCoroutine: createCoroutine, createYield: createYield, isCoroutine: isCoroutine, isYield: isYield, REACT_YIELD_TYPE: REACT_YIELD_TYPE_1, REACT_COROUTINE_TYPE: REACT_COROUTINE_TYPE_1 }; /** * Copyright (c) 2014-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule ReactPortal * */ // The Symbol used to tag the special React types. If there is no native Symbol // nor polyfill, then a plain number is used for performance. var REACT_PORTAL_TYPE$1 = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.portal') || 0xeaca; var createPortal$1 = function (children, containerInfo, // TODO: figure out the API for cross-renderer implementation. implementation) { var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; return { // This tag allow us to uniquely identify this as a React Portal $$typeof: REACT_PORTAL_TYPE$1, key: key == null ? null : '' + key, children: children, containerInfo: containerInfo, implementation: implementation }; }; /** * Verifies the object is a portal object. */ var isPortal = function (object) { return typeof object === 'object' && object !== null && object.$$typeof === REACT_PORTAL_TYPE$1; }; var REACT_PORTAL_TYPE_1 = REACT_PORTAL_TYPE$1; var ReactPortal = { createPortal: createPortal$1, isPortal: isPortal, REACT_PORTAL_TYPE: REACT_PORTAL_TYPE_1 }; var REACT_COROUTINE_TYPE = ReactCoroutine.REACT_COROUTINE_TYPE; var REACT_YIELD_TYPE = ReactCoroutine.REACT_YIELD_TYPE; var REACT_PORTAL_TYPE = ReactPortal.REACT_PORTAL_TYPE; { var _require3$4 = ReactDebugCurrentFiber_1, getCurrentFiberStackAddendum$5 = _require3$4.getCurrentFiberStackAddendum; var warning$24 = require$$0; var didWarnAboutMaps = false; /** * Warn if there's no key explicitly set on dynamic arrays of children or * object keys are not valid. This allows us to keep track of children between * updates. */ var ownerHasKeyUseWarning = {}; var warnForMissingKey = function (child) { if (child === null || typeof child !== 'object') { return; } if (!child._store || child._store.validated || child.key != null) { return; } !(typeof child._store === 'object') ? invariant(false, 'React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue.') : void 0; child._store.validated = true; var currentComponentErrorInfo = 'Each child in an array or iterator should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + (getCurrentFiberStackAddendum$5() || ''); if (ownerHasKeyUseWarning[currentComponentErrorInfo]) { return; } ownerHasKeyUseWarning[currentComponentErrorInfo] = true; warning$24(false, 'Each child in an array or iterator should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.%s', getCurrentFiberStackAddendum$5()); }; } var createWorkInProgress$2 = ReactFiber.createWorkInProgress; var createFiberFromElement$1 = ReactFiber.createFiberFromElement; var createFiberFromFragment$1 = ReactFiber.createFiberFromFragment; var createFiberFromText$1 = ReactFiber.createFiberFromText; var createFiberFromCoroutine$1 = ReactFiber.createFiberFromCoroutine; var createFiberFromYield$1 = ReactFiber.createFiberFromYield; var createFiberFromPortal$1 = ReactFiber.createFiberFromPortal; var isArray = Array.isArray; var FunctionalComponent$2 = ReactTypeOfWork.FunctionalComponent; var ClassComponent$7 = ReactTypeOfWork.ClassComponent; var HostText$5 = ReactTypeOfWork.HostText; var HostPortal$5 = ReactTypeOfWork.HostPortal; var CoroutineComponent$2 = ReactTypeOfWork.CoroutineComponent; var YieldComponent$3 = ReactTypeOfWork.YieldComponent; var Fragment$3 = ReactTypeOfWork.Fragment; var NoEffect$2 = ReactTypeOfSideEffect.NoEffect; var Placement$3 = ReactTypeOfSideEffect.Placement; var Deletion$1 = ReactTypeOfSideEffect.Deletion; var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. // The Symbol used to tag the ReactElement type. If there is no native Symbol // nor polyfill, then a plain number is used for performance. var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7; function getIteratorFn(maybeIterable) { if (maybeIterable === null || typeof maybeIterable === 'undefined') { return null; } var iteratorFn = ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]; if (typeof iteratorFn === 'function') { return iteratorFn; } return null; } function coerceRef(current, element) { var mixedRef = element.ref; if (mixedRef !== null && typeof mixedRef !== 'function') { if (element._owner) { var owner = element._owner; var inst = void 0; if (owner) { if (typeof owner.tag === 'number') { var ownerFiber = owner; !(ownerFiber.tag === ClassComponent$7) ? invariant(false, 'Stateless function components cannot have refs.') : void 0; inst = ownerFiber.stateNode; } else { // Stack inst = owner.getPublicInstance(); } } !inst ? invariant(false, 'Missing owner for string ref %s. This error is likely caused by a bug in React. Please file an issue.', mixedRef) : void 0; var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref if (current !== null && current.ref !== null && current.ref._stringRef === stringRef) { return current.ref; } var ref = function (value) { var refs = inst.refs === emptyObject ? inst.refs = {} : inst.refs; if (value === null) { delete refs[stringRef]; } else { refs[stringRef] = value; } }; ref._stringRef = stringRef; return ref; } else { !(typeof mixedRef === 'string') ? invariant(false, 'Expected ref to be a function or a string.') : void 0; !element._owner ? invariant(false, 'Element ref was specified as a string (%s) but no owner was set. You may have multiple copies of React loaded. (details: https://fb.me/react-refs-must-have-owner).', mixedRef) : void 0; } } return mixedRef; } function throwOnInvalidObjectType(returnFiber, newChild) { if (returnFiber.type !== 'textarea') { var addendum = ''; { addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + (getCurrentFiberStackAddendum$5() || ''); } invariant(false, 'Objects are not valid as a React child (found: %s).%s', Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild, addendum); } } function warnOnFunctionType() { warning$24(false, 'Functions are not valid as a React child. This may happen if ' + 'you return a Component instead of <Component /> from render. ' + 'Or maybe you meant to call this function rather than return it.%s', getCurrentFiberStackAddendum$5() || ''); } // This wrapper function exists because I expect to clone the code in each path // to be able to optimize each path individually by branching early. This needs // a compiler or we can do it manually. Helpers that don't need this branching // live outside of this function. function ChildReconciler(shouldClone, shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (!shouldTrackSideEffects) { // Noop. return; } if (!shouldClone) { // When we're reconciling in place we have a work in progress copy. We // actually want the current copy. If there is no current copy, then we // don't need to track deletion side-effects. if (childToDelete.alternate === null) { return; } childToDelete = childToDelete.alternate; } // Deletions are added in reversed order so we add it to the front. // At this point, the return fiber's effect list is empty except for // deletions, so we can just append the deletion to the list. The remaining // effects aren't added until the complete phase. Once we implement // resuming, this may not be true. var last = returnFiber.lastEffect; if (last !== null) { last.nextEffect = childToDelete; returnFiber.lastEffect = childToDelete; } else { returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; } childToDelete.nextEffect = null; childToDelete.effectTag = Deletion$1; } function deleteRemainingChildren(returnFiber, currentFirstChild) { if (!shouldTrackSideEffects) { // Noop. return null; } // TODO: For the shouldClone case, this could be micro-optimized a bit by // assuming that after the first child we've already added everything. var childToDelete = currentFirstChild; while (childToDelete !== null) { deleteChild(returnFiber, childToDelete); childToDelete = childToDelete.sibling; } return null; } function mapRemainingChildren(returnFiber, currentFirstChild) { // Add the remaining children to a temporary map so that we can find them by // keys quickly. Implicit (null) keys get added to this set with their index var existingChildren = new Map(); var existingChild = currentFirstChild; while (existingChild !== null) { if (existingChild.key !== null) { existingChildren.set(existingChild.key, existingChild); } else { existingChildren.set(existingChild.index, existingChild); } existingChild = existingChild.sibling; } return existingChildren; } function useFiber(fiber, priority) { // We currently set sibling to null and index to 0 here because it is easy // to forget to do before returning it. E.g. for the single child case. if (shouldClone) { var clone = createWorkInProgress$2(fiber, priority); clone.index = 0; clone.sibling = null; return clone; } else { // We override the pending priority even if it is higher, because if // we're reconciling at a lower priority that means that this was // down-prioritized. fiber.pendingWorkPriority = priority; fiber.effectTag = NoEffect$2; fiber.index = 0; fiber.sibling = null; return fiber; } } function placeChild(newFiber, lastPlacedIndex, newIndex) { newFiber.index = newIndex; if (!shouldTrackSideEffects) { // Noop. return lastPlacedIndex; } var current = newFiber.alternate; if (current !== null) { var oldIndex = current.index; if (oldIndex < lastPlacedIndex) { // This is a move. newFiber.effectTag = Placement$3; return lastPlacedIndex; } else { // This item can stay in place. return oldIndex; } } else { // This is an insertion. newFiber.effectTag = Placement$3; return lastPlacedIndex; } } function placeSingleChild(newFiber) { // This is simpler for the single child case. We only need to do a // placement for inserting new children. if (shouldTrackSideEffects && newFiber.alternate === null) { newFiber.effectTag = Placement$3; } return newFiber; } function updateTextNode(returnFiber, current, textContent, priority) { if (current === null || current.tag !== HostText$5) { // Insert var created = createFiberFromText$1(textContent, returnFiber.internalContextTag, priority); created['return'] = returnFiber; return created; } else { // Update var existing = useFiber(current, priority); existing.pendingProps = textContent; existing['return'] = returnFiber; return existing; } } function updateElement(returnFiber, current, element, priority) { if (current === null || current.type !== element.type) { // Insert var created = createFiberFromElement$1(element, returnFiber.internalContextTag, priority); created.ref = coerceRef(current, element); created['return'] = returnFiber; return created; } else { // Move based on index var existing = useFiber(current, priority); existing.ref = coerceRef(current, element); existing.pendingProps = element.props; existing['return'] = returnFiber; { existing._debugSource = element._source; existing._debugOwner = element._owner; } return existing; } } function updateCoroutine(returnFiber, current, coroutine, priority) { // TODO: Should this also compare handler to determine whether to reuse? if (current === null || current.tag !== CoroutineComponent$2) { // Insert var created = createFiberFromCoroutine$1(coroutine, returnFiber.internalContextTag, priority); created['return'] = returnFiber; return created; } else { // Move based on index var existing = useFiber(current, priority); existing.pendingProps = coroutine; existing['return'] = returnFiber; return existing; } } function updateYield(returnFiber, current, yieldNode, priority) { if (current === null || current.tag !== YieldComponent$3) { // Insert var created = createFiberFromYield$1(yieldNode, returnFiber.internalContextTag, priority); created.type = yieldNode.value; created['return'] = returnFiber; return created; } else { // Move based on index var existing = useFiber(current, priority); existing.type = yieldNode.value; existing['return'] = returnFiber; return existing; } } function updatePortal(returnFiber, current, portal, priority) { if (current === null || current.tag !== HostPortal$5 || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) { // Insert var created = createFiberFromPortal$1(portal, returnFiber.internalContextTag, priority); created['return'] = returnFiber; return created; } else { // Update var existing = useFiber(current, priority); existing.pendingProps = portal.children || []; existing['return'] = returnFiber; return existing; } } function updateFragment(returnFiber, current, fragment, priority) { if (current === null || current.tag !== Fragment$3) { // Insert var created = createFiberFromFragment$1(fragment, returnFiber.internalContextTag, priority); created['return'] = returnFiber; return created; } else { // Update var existing = useFiber(current, priority); existing.pendingProps = fragment; existing['return'] = returnFiber; return existing; } } function createChild(returnFiber, newChild, priority) { if (typeof newChild === 'string' || typeof newChild === 'number') { // Text nodes doesn't have keys. If the previous node is implicitly keyed // we can continue to replace it without aborting even if it is not a text // node. var created = createFiberFromText$1('' + newChild, returnFiber.internalContextTag, priority); created['return'] = returnFiber; return created; } if (typeof newChild === 'object' && newChild !== null) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: { var _created = createFiberFromElement$1(newChild, returnFiber.internalContextTag, priority); _created.ref = coerceRef(null, newChild); _created['return'] = returnFiber; return _created; } case REACT_COROUTINE_TYPE: { var _created2 = createFiberFromCoroutine$1(newChild, returnFiber.internalContextTag, priority); _created2['return'] = returnFiber; return _created2; } case REACT_YIELD_TYPE: { var _created3 = createFiberFromYield$1(newChild, returnFiber.internalContextTag, priority); _created3.type = newChild.value; _created3['return'] = returnFiber; return _created3; } case REACT_PORTAL_TYPE: { var _created4 = createFiberFromPortal$1(newChild, returnFiber.internalContextTag, priority); _created4['return'] = returnFiber; return _created4; } } if (isArray(newChild) || getIteratorFn(newChild)) { var _created5 = createFiberFromFragment$1(newChild, returnFiber.internalContextTag, priority); _created5['return'] = returnFiber; return _created5; } throwOnInvalidObjectType(returnFiber, newChild); } { if (typeof newChild === 'function') { warnOnFunctionType(); } } return null; } function updateSlot(returnFiber, oldFiber, newChild, priority) { // Update the fiber if the keys match, otherwise return null. var key = oldFiber !== null ? oldFiber.key : null; if (typeof newChild === 'string' || typeof newChild === 'number') { // Text nodes doesn't have keys. If the previous node is implicitly keyed // we can continue to replace it without aborting even if it is not a text // node. if (key !== null) { return null; } return updateTextNode(returnFiber, oldFiber, '' + newChild, priority); } if (typeof newChild === 'object' && newChild !== null) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: { if (newChild.key === key) { return updateElement(returnFiber, oldFiber, newChild, priority); } else { return null; } } case REACT_COROUTINE_TYPE: { if (newChild.key === key) { return updateCoroutine(returnFiber, oldFiber, newChild, priority); } else { return null; } } case REACT_YIELD_TYPE: { // Yields doesn't have keys. If the previous node is implicitly keyed // we can continue to replace it without aborting even if it is not a // yield. if (key === null) { return updateYield(returnFiber, oldFiber, newChild, priority); } else { return null; } } case REACT_PORTAL_TYPE: { if (newChild.key === key) { return updatePortal(returnFiber, oldFiber, newChild, priority); } else { return null; } } } if (isArray(newChild) || getIteratorFn(newChild)) { // Fragments doesn't have keys so if the previous key is implicit we can // update it. if (key !== null) { return null; } return updateFragment(returnFiber, oldFiber, newChild, priority); } throwOnInvalidObjectType(returnFiber, newChild); } { if (typeof newChild === 'function') { warnOnFunctionType(); } } return null; } function updateFromMap(existingChildren, returnFiber, newIdx, newChild, priority) { if (typeof newChild === 'string' || typeof newChild === 'number') { // Text nodes doesn't have keys, so we neither have to check the old nor // new node for the key. If both are text nodes, they match. var matchedFiber = existingChildren.get(newIdx) || null; return updateTextNode(returnFiber, matchedFiber, '' + newChild, priority); } if (typeof newChild === 'object' && newChild !== null) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: { var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null; return updateElement(returnFiber, _matchedFiber, newChild, priority); } case REACT_COROUTINE_TYPE: { var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null; return updateCoroutine(returnFiber, _matchedFiber2, newChild, priority); } case REACT_YIELD_TYPE: { // Yields doesn't have keys, so we neither have to check the old nor // new node for the key. If both are yields, they match. var _matchedFiber3 = existingChildren.get(newIdx) || null; return updateYield(returnFiber, _matchedFiber3, newChild, priority); } case REACT_PORTAL_TYPE: { var _matchedFiber4 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null; return updatePortal(returnFiber, _matchedFiber4, newChild, priority); } } if (isArray(newChild) || getIteratorFn(newChild)) { var _matchedFiber5 = existingChildren.get(newIdx) || null; return updateFragment(returnFiber, _matchedFiber5, newChild, priority); } throwOnInvalidObjectType(returnFiber, newChild); } { if (typeof newChild === 'function') { warnOnFunctionType(); } } return null; } /** * Warns if there is a duplicate or missing key */ function warnOnInvalidKey(child, knownKeys) { { if (typeof child !== 'object' || child === null) { return knownKeys; } switch (child.$$typeof) { case REACT_ELEMENT_TYPE: case REACT_COROUTINE_TYPE: case REACT_PORTAL_TYPE: warnForMissingKey(child); var key = child.key; if (typeof key !== 'string') { break; } if (knownKeys === null) { knownKeys = new Set(); knownKeys.add(key); break; } if (!knownKeys.has(key)) { knownKeys.add(key); break; } warning$24(false, 'Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.%s', key, getCurrentFiberStackAddendum$5()); break; default: break; } } return knownKeys; } function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, priority) { // This algorithm can't optimize by searching from boths ends since we // don't have backpointers on fibers. I'm trying to see how far we can get // with that model. If it ends up not being worth the tradeoffs, we can // add it later. // Even with a two ended optimization, we'd want to optimize for the case // where there are few changes and brute force the comparison instead of // going for the Map. It'd like to explore hitting that path first in // forward-only mode and only go for the Map once we notice that we need // lots of look ahead. This doesn't handle reversal as well as two ended // search but that's unusual. Besides, for the two ended optimization to // work on Iterables, we'd need to copy the whole set. // In this first iteration, we'll just live with hitting the bad case // (adding everything to a Map) in for every insert/move. // If you change this code, also update reconcileChildrenIterator() which // uses the same algorithm. { // First, validate keys. var knownKeys = null; for (var i = 0; i < newChildren.length; i++) { var child = newChildren[i]; knownKeys = warnOnInvalidKey(child, knownKeys); } } var resultingFirstChild = null; var previousNewFiber = null; var oldFiber = currentFirstChild; var lastPlacedIndex = 0; var newIdx = 0; var nextOldFiber = null; for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) { if (oldFiber.index > newIdx) { nextOldFiber = oldFiber; oldFiber = null; } else { nextOldFiber = oldFiber.sibling; } var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], priority); if (newFiber === null) { // TODO: This breaks on empty slots like null children. That's // unfortunate because it triggers the slow path all the time. We need // a better way to communicate whether this was a miss or null, // boolean, undefined, etc. if (oldFiber === null) { oldFiber = nextOldFiber; } break; } if (shouldTrackSideEffects) { if (oldFiber && newFiber.alternate === null) { // We matched the slot, but we didn't reuse the existing fiber, so we // need to delete the existing child. deleteChild(returnFiber, oldFiber); } } lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx); if (previousNewFiber === null) { // TODO: Move out of the loop. This only happens for the first run. resultingFirstChild = newFiber; } else { // TODO: Defer siblings if we're not at the right index for this slot. // I.e. if we had null values before, then we want to defer this // for each null value. However, we also don't want to call updateSlot // with the previous one. previousNewFiber.sibling = newFiber; } previousNewFiber = newFiber; oldFiber = nextOldFiber; } if (newIdx === newChildren.length) { // We've reached the end of the new children. We can delete the rest. deleteRemainingChildren(returnFiber, oldFiber); return resultingFirstChild; } if (oldFiber === null) { // If we don't have any more existing children we can choose a fast path // since the rest will all be insertions. for (; newIdx < newChildren.length; newIdx++) { var _newFiber = createChild(returnFiber, newChildren[newIdx], priority); if (!_newFiber) { continue; } lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx); if (previousNewFiber === null) { // TODO: Move out of the loop. This only happens for the first run. resultingFirstChild = _newFiber; } else { previousNewFiber.sibling = _newFiber; } previousNewFiber = _newFiber; } return resultingFirstChild; } // Add all children to a key map for quick lookups. var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves. for (; newIdx < newChildren.length; newIdx++) { var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], priority); if (_newFiber2) { if (shouldTrackSideEffects) { if (_newFiber2.alternate !== null) { // The new fiber is a work in progress, but if there exists a // current, that means that we reused the fiber. We need to delete // it from the child list so that we don't add it to the deletion // list. existingChildren['delete'](_newFiber2.key === null ? newIdx : _newFiber2.key); } } lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx); if (previousNewFiber === null) { resultingFirstChild = _newFiber2; } else { previousNewFiber.sibling = _newFiber2; } previousNewFiber = _newFiber2; } } if (shouldTrackSideEffects) { // Any existing children that weren't consumed above were deleted. We need // to add them to the deletion list. existingChildren.forEach(function (child) { return deleteChild(returnFiber, child); }); } return resultingFirstChild; } function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, priority) { // This is the same implementation as reconcileChildrenArray(), // but using the iterator instead. var iteratorFn = getIteratorFn(newChildrenIterable); !(typeof iteratorFn === 'function') ? invariant(false, 'An object is not an iterable. This error is likely caused by a bug in React. Please file an issue.') : void 0; { // Warn about using Maps as children if (typeof newChildrenIterable.entries === 'function') { var possibleMap = newChildrenIterable; if (possibleMap.entries === iteratorFn) { warning$24(didWarnAboutMaps, 'Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.%s', getCurrentFiberStackAddendum$5()); didWarnAboutMaps = true; } } // First, validate keys. // We'll get a different iterator later for the main pass. var _newChildren = iteratorFn.call(newChildrenIterable); if (_newChildren) { var knownKeys = null; var _step = _newChildren.next(); for (; !_step.done; _step = _newChildren.next()) { var child = _step.value; knownKeys = warnOnInvalidKey(child, knownKeys); } } } var newChildren = iteratorFn.call(newChildrenIterable); !(newChildren != null) ? invariant(false, 'An iterable object provided no iterator.') : void 0; var resultingFirstChild = null; var previousNewFiber = null; var oldFiber = currentFirstChild; var lastPlacedIndex = 0; var newIdx = 0; var nextOldFiber = null; var step = newChildren.next(); for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) { if (oldFiber.index > newIdx) { nextOldFiber = oldFiber; oldFiber = null; } else { nextOldFiber = oldFiber.sibling; } var newFiber = updateSlot(returnFiber, oldFiber, step.value, priority); if (newFiber === null) { // TODO: This breaks on empty slots like null children. That's // unfortunate because it triggers the slow path all the time. We need // a better way to communicate whether this was a miss or null, // boolean, undefined, etc. if (!oldFiber) { oldFiber = nextOldFiber; } break; } if (shouldTrackSideEffects) { if (oldFiber && newFiber.alternate === null) { // We matched the slot, but we didn't reuse the existing fiber, so we // need to delete the existing child. deleteChild(returnFiber, oldFiber); } } lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx); if (previousNewFiber === null) { // TODO: Move out of the loop. This only happens for the first run. resultingFirstChild = newFiber; } else { // TODO: Defer siblings if we're not at the right index for this slot. // I.e. if we had null values before, then we want to defer this // for each null value. However, we also don't want to call updateSlot // with the previous one. previousNewFiber.sibling = newFiber; } previousNewFiber = newFiber; oldFiber = nextOldFiber; } if (step.done) { // We've reached the end of the new children. We can delete the rest. deleteRemainingChildren(returnFiber, oldFiber); return resultingFirstChild; } if (oldFiber === null) { // If we don't have any more existing children we can choose a fast path // since the rest will all be insertions. for (; !step.done; newIdx++, step = newChildren.next()) { var _newFiber3 = createChild(returnFiber, step.value, priority); if (_newFiber3 === null) { continue; } lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx); if (previousNewFiber === null) { // TODO: Move out of the loop. This only happens for the first run. resultingFirstChild = _newFiber3; } else { previousNewFiber.sibling = _newFiber3; } previousNewFiber = _newFiber3; } return resultingFirstChild; } // Add all children to a key map for quick lookups. var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves. for (; !step.done; newIdx++, step = newChildren.next()) { var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, priority); if (_newFiber4 !== null) { if (shouldTrackSideEffects) { if (_newFiber4.alternate !== null) { // The new fiber is a work in progress, but if there exists a // current, that means that we reused the fiber. We need to delete // it from the child list so that we don't add it to the deletion // list. existingChildren['delete'](_newFiber4.key === null ? newIdx : _newFiber4.key); } } lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx); if (previousNewFiber === null) { resultingFirstChild = _newFiber4; } else { previousNewFiber.sibling = _newFiber4; } previousNewFiber = _newFiber4; } } if (shouldTrackSideEffects) { // Any existing children that weren't consumed above were deleted. We need // to add them to the deletion list. existingChildren.forEach(function (child) { return deleteChild(returnFiber, child); }); } return resultingFirstChild; } function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, priority) { // There's no need to check for keys on text nodes since we don't have a // way to define them. if (currentFirstChild !== null && currentFirstChild.tag === HostText$5) { // We already have an existing node so let's just update it and delete // the rest. deleteRemainingChildren(returnFiber, currentFirstChild.sibling); var existing = useFiber(currentFirstChild, priority); existing.pendingProps = textContent; existing['return'] = returnFiber; return existing; } // The existing first child is not a text node so we need to create one // and delete the existing ones. deleteRemainingChildren(returnFiber, currentFirstChild); var created = createFiberFromText$1(textContent, returnFiber.internalContextTag, priority); created['return'] = returnFiber; return created; } function reconcileSingleElement(returnFiber, currentFirstChild, element, priority) { var key = element.key; var child = currentFirstChild; while (child !== null) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. if (child.key === key) { if (child.type === element.type) { deleteRemainingChildren(returnFiber, child.sibling); var existing = useFiber(child, priority); existing.ref = coerceRef(child, element); existing.pendingProps = element.props; existing['return'] = returnFiber; { existing._debugSource = element._source; existing._debugOwner = element._owner; } return existing; } else { deleteRemainingChildren(returnFiber, child); break; } } else { deleteChild(returnFiber, child); } child = child.sibling; } var created = createFiberFromElement$1(element, returnFiber.internalContextTag, priority); created.ref = coerceRef(currentFirstChild, element); created['return'] = returnFiber; return created; } function reconcileSingleCoroutine(returnFiber, currentFirstChild, coroutine, priority) { var key = coroutine.key; var child = currentFirstChild; while (child !== null) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. if (child.key === key) { if (child.tag === CoroutineComponent$2) { deleteRemainingChildren(returnFiber, child.sibling); var existing = useFiber(child, priority); existing.pendingProps = coroutine; existing['return'] = returnFiber; return existing; } else { deleteRemainingChildren(returnFiber, child); break; } } else { deleteChild(returnFiber, child); } child = child.sibling; } var created = createFiberFromCoroutine$1(coroutine, returnFiber.internalContextTag, priority); created['return'] = returnFiber; return created; } function reconcileSingleYield(returnFiber, currentFirstChild, yieldNode, priority) { // There's no need to check for keys on yields since they're stateless. var child = currentFirstChild; if (child !== null) { if (child.tag === YieldComponent$3) { deleteRemainingChildren(returnFiber, child.sibling); var existing = useFiber(child, priority); existing.type = yieldNode.value; existing['return'] = returnFiber; return existing; } else { deleteRemainingChildren(returnFiber, child); } } var created = createFiberFromYield$1(yieldNode, returnFiber.internalContextTag, priority); created.type = yieldNode.value; created['return'] = returnFiber; return created; } function reconcileSinglePortal(returnFiber, currentFirstChild, portal, priority) { var key = portal.key; var child = currentFirstChild; while (child !== null) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. if (child.key === key) { if (child.tag === HostPortal$5 && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) { deleteRemainingChildren(returnFiber, child.sibling); var existing = useFiber(child, priority); existing.pendingProps = portal.children || []; existing['return'] = returnFiber; return existing; } else { deleteRemainingChildren(returnFiber, child); break; } } else { deleteChild(returnFiber, child); } child = child.sibling; } var created = createFiberFromPortal$1(portal, returnFiber.internalContextTag, priority); created['return'] = returnFiber; return created; } // This API will tag the children with the side-effect of the reconciliation // itself. They will be added to the side-effect list as we pass through the // children and the parent. function reconcileChildFibers(returnFiber, currentFirstChild, newChild, priority) { // This function is not recursive. // If the top level item is an array, we treat it as a set of children, // not as a fragment. Nested arrays on the other hand will be treated as // fragment nodes. Recursion happens at the normal flow. // Handle object types var isObject = typeof newChild === 'object' && newChild !== null; if (isObject) { // Support only the subset of return types that Stack supports. Treat // everything else as empty, but log a warning. switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, priority)); case REACT_COROUTINE_TYPE: return placeSingleChild(reconcileSingleCoroutine(returnFiber, currentFirstChild, newChild, priority)); case REACT_YIELD_TYPE: return placeSingleChild(reconcileSingleYield(returnFiber, currentFirstChild, newChild, priority)); case REACT_PORTAL_TYPE: return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, priority)); } } if (typeof newChild === 'string' || typeof newChild === 'number') { return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, priority)); } if (isArray(newChild)) { return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, priority); } if (getIteratorFn(newChild)) { return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, priority); } if (isObject) { throwOnInvalidObjectType(returnFiber, newChild); } { if (typeof newChild === 'function') { warnOnFunctionType(); } } if (typeof newChild === 'undefined') { // If the new child is undefined, and the return fiber is a composite // component, throw an error. If Fiber return types are disabled, // we already threw above. switch (returnFiber.tag) { case ClassComponent$7: { { var instance = returnFiber.stateNode; if (instance.render._isMockFunction) { // We allow auto-mocks to proceed as if they're returning null. break; } } } // Intentionally fall through to the next case, which handles both // functions and classes // eslint-disable-next-lined no-fallthrough case FunctionalComponent$2: { var Component = returnFiber.type; invariant(false, '%s(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.', Component.displayName || Component.name || 'Component'); } } } // Remaining cases are all treated as empty. return deleteRemainingChildren(returnFiber, currentFirstChild); } return reconcileChildFibers; } var reconcileChildFibers$1 = ChildReconciler(true, true); var reconcileChildFibersInPlace$1 = ChildReconciler(false, true); var mountChildFibersInPlace$1 = ChildReconciler(false, false); var cloneChildFibers$1 = function (current, workInProgress) { !(current === null || workInProgress.child === current.child) ? invariant(false, 'Resuming work not yet implemented.') : void 0; if (workInProgress.child === null) { return; } var currentChild = workInProgress.child; var newChild = createWorkInProgress$2(currentChild, currentChild.pendingWorkPriority); // TODO: Pass this as an argument, since it's easy to forget. newChild.pendingProps = currentChild.pendingProps; workInProgress.child = newChild; newChild['return'] = workInProgress; while (currentChild.sibling !== null) { currentChild = currentChild.sibling; newChild = newChild.sibling = createWorkInProgress$2(currentChild, currentChild.pendingWorkPriority); newChild.pendingProps = currentChild.pendingProps; newChild['return'] = workInProgress; } newChild.sibling = null; }; var ReactChildFiber = { reconcileChildFibers: reconcileChildFibers$1, reconcileChildFibersInPlace: reconcileChildFibersInPlace$1, mountChildFibersInPlace: mountChildFibersInPlace$1, cloneChildFibers: cloneChildFibers$1 }; var Update$1 = ReactTypeOfSideEffect.Update; var AsyncUpdates$1 = ReactTypeOfInternalContext.AsyncUpdates; var cacheContext$1 = ReactFiberContext.cacheContext; var getMaskedContext$2 = ReactFiberContext.getMaskedContext; var getUnmaskedContext$2 = ReactFiberContext.getUnmaskedContext; var isContextConsumer$1 = ReactFiberContext.isContextConsumer; var addUpdate$1 = ReactFiberUpdateQueue.addUpdate; var addReplaceUpdate$1 = ReactFiberUpdateQueue.addReplaceUpdate; var addForceUpdate$1 = ReactFiberUpdateQueue.addForceUpdate; var beginUpdateQueue$2 = ReactFiberUpdateQueue.beginUpdateQueue; var _require5 = ReactFiberContext; var hasContextChanged$2 = _require5.hasContextChanged; var isMounted$1 = ReactFiberTreeReflection.isMounted; var fakeInternalInstance = {}; var isArray$1 = Array.isArray; { var _require7$1 = ReactDebugFiberPerf_1, startPhaseTimer$1 = _require7$1.startPhaseTimer, stopPhaseTimer$1 = _require7$1.stopPhaseTimer; var warning$25 = require$$0; var warnOnInvalidCallback = function (callback, callerName) { warning$25(callback === null || typeof callback === 'function', '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback); }; // This is so gross but it's at least non-critical and can be removed if // it causes problems. This is meant to give a nicer error message for // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component, // ...)) which otherwise throws a "_processChildContext is not a function" // exception. Object.defineProperty(fakeInternalInstance, '_processChildContext', { enumerable: false, value: function () { invariant(false, '_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn\'t supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal).'); } }); Object.freeze(fakeInternalInstance); } var ReactFiberClassComponent = function (scheduleUpdate, getPriorityContext, memoizeProps, memoizeState) { // Class component state updater var updater = { isMounted: isMounted$1, enqueueSetState: function (instance, partialState, callback) { var fiber = ReactInstanceMap_1.get(instance); var priorityLevel = getPriorityContext(fiber, false); callback = callback === undefined ? null : callback; { warnOnInvalidCallback(callback, 'setState'); } addUpdate$1(fiber, partialState, callback, priorityLevel); scheduleUpdate(fiber, priorityLevel); }, enqueueReplaceState: function (instance, state, callback) { var fiber = ReactInstanceMap_1.get(instance); var priorityLevel = getPriorityContext(fiber, false); callback = callback === undefined ? null : callback; { warnOnInvalidCallback(callback, 'replaceState'); } addReplaceUpdate$1(fiber, state, callback, priorityLevel); scheduleUpdate(fiber, priorityLevel); }, enqueueForceUpdate: function (instance, callback) { var fiber = ReactInstanceMap_1.get(instance); var priorityLevel = getPriorityContext(fiber, false); callback = callback === undefined ? null : callback; { warnOnInvalidCallback(callback, 'forceUpdate'); } addForceUpdate$1(fiber, callback, priorityLevel); scheduleUpdate(fiber, priorityLevel); } }; function checkShouldComponentUpdate(workInProgress, oldProps, newProps, oldState, newState, newContext) { if (oldProps === null || workInProgress.updateQueue !== null && workInProgress.updateQueue.hasForceUpdate) { // If the workInProgress already has an Update effect, return true return true; } var instance = workInProgress.stateNode; var type = workInProgress.type; if (typeof instance.shouldComponentUpdate === 'function') { { startPhaseTimer$1(workInProgress, 'shouldComponentUpdate'); } var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, newContext); { stopPhaseTimer$1(); } { warning$25(shouldUpdate !== undefined, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName_1(workInProgress) || 'Unknown'); } return shouldUpdate; } if (type.prototype && type.prototype.isPureReactComponent) { return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState); } return true; } function checkClassInstance(workInProgress) { var instance = workInProgress.stateNode; var type = workInProgress.type; { var name = getComponentName_1(workInProgress); var renderPresent = instance.render; warning$25(renderPresent, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name); var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state; warning$25(noGetInitialStateOnES6, 'getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', name); var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved; warning$25(noGetDefaultPropsOnES6, 'getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', name); var noInstancePropTypes = !instance.propTypes; warning$25(noInstancePropTypes, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name); var noInstanceContextTypes = !instance.contextTypes; warning$25(noInstanceContextTypes, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name); var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function'; warning$25(noComponentShouldUpdate, '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', name); if (type.prototype && type.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') { warning$25(false, '%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentName_1(workInProgress) || 'A pure component'); } var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function'; warning$25(noComponentDidUnmount, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name); var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function'; warning$25(noComponentWillRecieveProps, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name); var hasMutatedProps = instance.props !== workInProgress.pendingProps; warning$25(instance.props === undefined || !hasMutatedProps, '%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name); var noInstanceDefaultProps = !instance.defaultProps; warning$25(noInstanceDefaultProps, 'Setting defaultProps as an instance property on %s is not supported and will be ignored.' + ' Instead, define defaultProps as a static property on %s.', name, name); } var state = instance.state; if (state && (typeof state !== 'object' || isArray$1(state))) { invariant(false, '%s.state: must be set to an object or null', getComponentName_1(workInProgress)); } if (typeof instance.getChildContext === 'function') { !(typeof workInProgress.type.childContextTypes === 'object') ? invariant(false, '%s.getChildContext(): childContextTypes must be defined in order to use getChildContext().', getComponentName_1(workInProgress)) : void 0; } } function resetInputPointers(workInProgress, instance) { instance.props = workInProgress.memoizedProps; instance.state = workInProgress.memoizedState; } function adoptClassInstance(workInProgress, instance) { instance.updater = updater; workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates ReactInstanceMap_1.set(instance, workInProgress); { instance._reactInternalInstance = fakeInternalInstance; } } function constructClassInstance(workInProgress, props) { var ctor = workInProgress.type; var unmaskedContext = getUnmaskedContext$2(workInProgress); var needsContext = isContextConsumer$1(workInProgress); var context = needsContext ? getMaskedContext$2(workInProgress, unmaskedContext) : emptyObject; var instance = new ctor(props, context); adoptClassInstance(workInProgress, instance); // Cache unmasked context so we can avoid recreating masked context unless necessary. // ReactFiberContext usually updates this cache but can't for newly-created instances. if (needsContext) { cacheContext$1(workInProgress, unmaskedContext, context); } return instance; } function callComponentWillMount(workInProgress, instance) { { startPhaseTimer$1(workInProgress, 'componentWillMount'); } var oldState = instance.state; instance.componentWillMount(); { stopPhaseTimer$1(); } if (oldState !== instance.state) { { warning$25(false, '%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName_1(workInProgress)); } updater.enqueueReplaceState(instance, instance.state, null); } } function callComponentWillReceiveProps(workInProgress, instance, newProps, newContext) { { startPhaseTimer$1(workInProgress, 'componentWillReceiveProps'); } var oldState = instance.state; instance.componentWillReceiveProps(newProps, newContext); { stopPhaseTimer$1(); } if (instance.state !== oldState) { { warning$25(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName_1(workInProgress)); } updater.enqueueReplaceState(instance, instance.state, null); } } // Invokes the mount life-cycles on a previously never rendered instance. function mountClassInstance(workInProgress, priorityLevel) { var current = workInProgress.alternate; { checkClassInstance(workInProgress); } var instance = workInProgress.stateNode; var state = instance.state || null; var props = workInProgress.pendingProps; !props ? invariant(false, 'There must be pending props for an initial mount. This error is likely caused by a bug in React. Please file an issue.') : void 0; var unmaskedContext = getUnmaskedContext$2(workInProgress); instance.props = props; instance.state = state; instance.refs = emptyObject; instance.context = getMaskedContext$2(workInProgress, unmaskedContext); if (ReactFeatureFlags_1.enableAsyncSubtreeAPI && workInProgress.type != null && workInProgress.type.prototype != null && workInProgress.type.prototype.unstable_isAsyncReactComponent === true) { workInProgress.internalContextTag |= AsyncUpdates$1; } if (typeof instance.componentWillMount === 'function') { callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's // process them now. var updateQueue = workInProgress.updateQueue; if (updateQueue !== null) { instance.state = beginUpdateQueue$2(current, workInProgress, updateQueue, instance, state, props, priorityLevel); } } if (typeof instance.componentDidMount === 'function') { workInProgress.effectTag |= Update$1; } } // Called on a preexisting class instance. Returns false if a resumed render // could be reused. // function resumeMountClassInstance( // workInProgress: Fiber, // priorityLevel: PriorityLevel, // ): boolean { // const instance = workInProgress.stateNode; // resetInputPointers(workInProgress, instance); // let newState = workInProgress.memoizedState; // let newProps = workInProgress.pendingProps; // if (!newProps) { // // If there isn't any new props, then we'll reuse the memoized props. // // This could be from already completed work. // newProps = workInProgress.memoizedProps; // invariant( // newProps != null, // 'There should always be pending or memoized props. This error is ' + // 'likely caused by a bug in React. Please file an issue.', // ); // } // const newUnmaskedContext = getUnmaskedContext(workInProgress); // const newContext = getMaskedContext(workInProgress, newUnmaskedContext); // const oldContext = instance.context; // const oldProps = workInProgress.memoizedProps; // if ( // typeof instance.componentWillReceiveProps === 'function' && // (oldProps !== newProps || oldContext !== newContext) // ) { // callComponentWillReceiveProps( // workInProgress, // instance, // newProps, // newContext, // ); // } // // Process the update queue before calling shouldComponentUpdate // const updateQueue = workInProgress.updateQueue; // if (updateQueue !== null) { // newState = beginUpdateQueue( // workInProgress, // updateQueue, // instance, // newState, // newProps, // priorityLevel, // ); // } // // TODO: Should we deal with a setState that happened after the last // // componentWillMount and before this componentWillMount? Probably // // unsupported anyway. // if ( // !checkShouldComponentUpdate( // workInProgress, // workInProgress.memoizedProps, // newProps, // workInProgress.memoizedState, // newState, // newContext, // ) // ) { // // Update the existing instance's state, props, and context pointers even // // though we're bailing out. // instance.props = newProps; // instance.state = newState; // instance.context = newContext; // return false; // } // // Update the input pointers now so that they are correct when we call // // componentWillMount // instance.props = newProps; // instance.state = newState; // instance.context = newContext; // if (typeof instance.componentWillMount === 'function') { // callComponentWillMount(workInProgress, instance); // // componentWillMount may have called setState. Process the update queue. // const newUpdateQueue = workInProgress.updateQueue; // if (newUpdateQueue !== null) { // newState = beginUpdateQueue( // workInProgress, // newUpdateQueue, // instance, // newState, // newProps, // priorityLevel, // ); // } // } // if (typeof instance.componentDidMount === 'function') { // workInProgress.effectTag |= Update; // } // instance.state = newState; // return true; // } // Invokes the update life-cycles and returns false if it shouldn't rerender. function updateClassInstance(current, workInProgress, priorityLevel) { var instance = workInProgress.stateNode; resetInputPointers(workInProgress, instance); var oldProps = workInProgress.memoizedProps; var newProps = workInProgress.pendingProps; if (!newProps) { // If there aren't any new props, then we'll reuse the memoized props. // This could be from already completed work. newProps = oldProps; !(newProps != null) ? invariant(false, 'There should always be pending or memoized props. This error is likely caused by a bug in React. Please file an issue.') : void 0; } var oldContext = instance.context; var newUnmaskedContext = getUnmaskedContext$2(workInProgress); var newContext = getMaskedContext$2(workInProgress, newUnmaskedContext); // Note: During these life-cycles, instance.props/instance.state are what // ever the previously attempted to render - not the "current". However, // during componentDidUpdate we pass the "current" props. if (typeof instance.componentWillReceiveProps === 'function' && (oldProps !== newProps || oldContext !== newContext)) { callComponentWillReceiveProps(workInProgress, instance, newProps, newContext); } // Compute the next state using the memoized state and the update queue. var oldState = workInProgress.memoizedState; // TODO: Previous state can be null. var newState = void 0; if (workInProgress.updateQueue !== null) { newState = beginUpdateQueue$2(current, workInProgress, workInProgress.updateQueue, instance, oldState, newProps, priorityLevel); } else { newState = oldState; } if (oldProps === newProps && oldState === newState && !hasContextChanged$2() && !(workInProgress.updateQueue !== null && workInProgress.updateQueue.hasForceUpdate)) { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidUpdate === 'function') { if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) { workInProgress.effectTag |= Update$1; } } return false; } var shouldUpdate = checkShouldComponentUpdate(workInProgress, oldProps, newProps, oldState, newState, newContext); if (shouldUpdate) { if (typeof instance.componentWillUpdate === 'function') { { startPhaseTimer$1(workInProgress, 'componentWillUpdate'); } instance.componentWillUpdate(newProps, newState, newContext); { stopPhaseTimer$1(); } } if (typeof instance.componentDidUpdate === 'function') { workInProgress.effectTag |= Update$1; } } else { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidUpdate === 'function') { if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) { workInProgress.effectTag |= Update$1; } } // If shouldComponentUpdate returned false, we should still update the // memoized props/state to indicate that this work can be reused. memoizeProps(workInProgress, newProps); memoizeState(workInProgress, newState); } // Update the existing instance's state, props, and context pointers even // if shouldComponentUpdate returns false. instance.props = newProps; instance.state = newState; instance.context = newContext; return shouldUpdate; } return { adoptClassInstance: adoptClassInstance, constructClassInstance: constructClassInstance, mountClassInstance: mountClassInstance, // resumeMountClassInstance, updateClassInstance: updateClassInstance }; }; var mountChildFibersInPlace = ReactChildFiber.mountChildFibersInPlace; var reconcileChildFibers = ReactChildFiber.reconcileChildFibers; var reconcileChildFibersInPlace = ReactChildFiber.reconcileChildFibersInPlace; var cloneChildFibers = ReactChildFiber.cloneChildFibers; var beginUpdateQueue$1 = ReactFiberUpdateQueue.beginUpdateQueue; var getMaskedContext$1 = ReactFiberContext.getMaskedContext; var getUnmaskedContext$1 = ReactFiberContext.getUnmaskedContext; var hasContextChanged$1 = ReactFiberContext.hasContextChanged; var pushContextProvider$1 = ReactFiberContext.pushContextProvider; var pushTopLevelContextObject$1 = ReactFiberContext.pushTopLevelContextObject; var invalidateContextProvider$1 = ReactFiberContext.invalidateContextProvider; var IndeterminateComponent$2 = ReactTypeOfWork.IndeterminateComponent; var FunctionalComponent$1 = ReactTypeOfWork.FunctionalComponent; var ClassComponent$6 = ReactTypeOfWork.ClassComponent; var HostRoot$7 = ReactTypeOfWork.HostRoot; var HostComponent$7 = ReactTypeOfWork.HostComponent; var HostText$4 = ReactTypeOfWork.HostText; var HostPortal$4 = ReactTypeOfWork.HostPortal; var CoroutineComponent$1 = ReactTypeOfWork.CoroutineComponent; var CoroutineHandlerPhase = ReactTypeOfWork.CoroutineHandlerPhase; var YieldComponent$2 = ReactTypeOfWork.YieldComponent; var Fragment$2 = ReactTypeOfWork.Fragment; var NoWork$3 = ReactPriorityLevel.NoWork; var OffscreenPriority$1 = ReactPriorityLevel.OffscreenPriority; var PerformedWork$1 = ReactTypeOfSideEffect.PerformedWork; var Placement$2 = ReactTypeOfSideEffect.Placement; var ContentReset$1 = ReactTypeOfSideEffect.ContentReset; var Err$1 = ReactTypeOfSideEffect.Err; var Ref$1 = ReactTypeOfSideEffect.Ref; var ReactCurrentOwner$2 = ReactGlobalSharedState_1.ReactCurrentOwner; { var ReactDebugCurrentFiber$4 = ReactDebugCurrentFiber_1; var _require7 = ReactDebugFiberPerf_1, cancelWorkTimer = _require7.cancelWorkTimer; var warning$23 = require$$0; var warnedAboutStatelessRefs = {}; } var ReactFiberBeginWork = function (config, hostContext, hydrationContext, scheduleUpdate, getPriorityContext) { var shouldSetTextContent = config.shouldSetTextContent, useSyncScheduling = config.useSyncScheduling, shouldDeprioritizeSubtree = config.shouldDeprioritizeSubtree; var pushHostContext = hostContext.pushHostContext, pushHostContainer = hostContext.pushHostContainer; var enterHydrationState = hydrationContext.enterHydrationState, resetHydrationState = hydrationContext.resetHydrationState, tryToClaimNextHydratableInstance = hydrationContext.tryToClaimNextHydratableInstance; var _ReactFiberClassCompo = ReactFiberClassComponent(scheduleUpdate, getPriorityContext, memoizeProps, memoizeState), adoptClassInstance = _ReactFiberClassCompo.adoptClassInstance, constructClassInstance = _ReactFiberClassCompo.constructClassInstance, mountClassInstance = _ReactFiberClassCompo.mountClassInstance, updateClassInstance = _ReactFiberClassCompo.updateClassInstance; function reconcileChildren(current, workInProgress, nextChildren) { var priorityLevel = workInProgress.pendingWorkPriority; reconcileChildrenAtPriority(current, workInProgress, nextChildren, priorityLevel); } function reconcileChildrenAtPriority(current, workInProgress, nextChildren, priorityLevel) { if (current === null) { // If this is a fresh new component that hasn't been rendered yet, we // won't update its child set by applying minimal side-effects. Instead, // we will add them all to the child before it gets rendered. That means // we can optimize this reconciliation pass by not tracking side-effects. workInProgress.child = mountChildFibersInPlace(workInProgress, workInProgress.child, nextChildren, priorityLevel); } else if (current.child === workInProgress.child) { // If the current child is the same as the work in progress, it means that // we haven't yet started any work on these children. Therefore, we use // the clone algorithm to create a copy of all the current children. // If we had any progressed work already, that is invalid at this point so // let's throw it out. workInProgress.child = reconcileChildFibers(workInProgress, workInProgress.child, nextChildren, priorityLevel); } else { // If, on the other hand, it is already using a clone, that means we've // already begun some work on this tree and we can continue where we left // off by reconciling against the existing children. workInProgress.child = reconcileChildFibersInPlace(workInProgress, workInProgress.child, nextChildren, priorityLevel); } } function updateFragment(current, workInProgress) { var nextChildren = workInProgress.pendingProps; if (hasContextChanged$1()) { // Normally we can bail out on props equality but if context has changed // we don't do the bailout and we have to reuse existing props instead. if (nextChildren === null) { nextChildren = workInProgress.memoizedProps; } } else if (nextChildren === null || workInProgress.memoizedProps === nextChildren) { return bailoutOnAlreadyFinishedWork(current, workInProgress); } reconcileChildren(current, workInProgress, nextChildren); memoizeProps(workInProgress, nextChildren); return workInProgress.child; } function markRef(current, workInProgress) { var ref = workInProgress.ref; if (ref !== null && (!current || current.ref !== ref)) { // Schedule a Ref effect workInProgress.effectTag |= Ref$1; } } function updateFunctionalComponent(current, workInProgress) { var fn = workInProgress.type; var nextProps = workInProgress.pendingProps; var memoizedProps = workInProgress.memoizedProps; if (hasContextChanged$1()) { // Normally we can bail out on props equality but if context has changed // we don't do the bailout and we have to reuse existing props instead. if (nextProps === null) { nextProps = memoizedProps; } } else { if (nextProps === null || memoizedProps === nextProps) { return bailoutOnAlreadyFinishedWork(current, workInProgress); } // TODO: consider bringing fn.shouldComponentUpdate() back. // It used to be here. } var unmaskedContext = getUnmaskedContext$1(workInProgress); var context = getMaskedContext$1(workInProgress, unmaskedContext); var nextChildren; { ReactCurrentOwner$2.current = workInProgress; ReactDebugCurrentFiber$4.setCurrentFiber(workInProgress, 'render'); nextChildren = fn(nextProps, context); ReactDebugCurrentFiber$4.setCurrentFiber(workInProgress, null); } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork$1; reconcileChildren(current, workInProgress, nextChildren); memoizeProps(workInProgress, nextProps); return workInProgress.child; } function updateClassComponent(current, workInProgress, priorityLevel) { // Push context providers early to prevent context stack mismatches. // During mounting we don't know the child context yet as the instance doesn't exist. // We will invalidate the child context in finishClassComponent() right after rendering. var hasContext = pushContextProvider$1(workInProgress); var shouldUpdate = void 0; if (current === null) { if (!workInProgress.stateNode) { // In the initial pass we might need to construct the instance. constructClassInstance(workInProgress, workInProgress.pendingProps); mountClassInstance(workInProgress, priorityLevel); shouldUpdate = true; } else { invariant(false, 'Resuming work not yet implemented.'); // In a resume, we'll already have an instance we can reuse. // shouldUpdate = resumeMountClassInstance(workInProgress, priorityLevel); } } else { shouldUpdate = updateClassInstance(current, workInProgress, priorityLevel); } return finishClassComponent(current, workInProgress, shouldUpdate, hasContext); } function finishClassComponent(current, workInProgress, shouldUpdate, hasContext) { // Refs should update even if shouldComponentUpdate returns false markRef(current, workInProgress); if (!shouldUpdate) { // Context providers should defer to sCU for rendering if (hasContext) { invalidateContextProvider$1(workInProgress, false); } return bailoutOnAlreadyFinishedWork(current, workInProgress); } var instance = workInProgress.stateNode; // Rerender ReactCurrentOwner$2.current = workInProgress; var nextChildren = void 0; { ReactDebugCurrentFiber$4.setCurrentFiber(workInProgress, 'render'); nextChildren = instance.render(); ReactDebugCurrentFiber$4.setCurrentFiber(workInProgress, null); } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork$1; reconcileChildren(current, workInProgress, nextChildren); // Memoize props and state using the values we just used to render. // TODO: Restructure so we never read values from the instance. memoizeState(workInProgress, instance.state); memoizeProps(workInProgress, instance.props); // The context might have changed so we need to recalculate it. if (hasContext) { invalidateContextProvider$1(workInProgress, true); } return workInProgress.child; } function pushHostRootContext(workInProgress) { var root = workInProgress.stateNode; if (root.pendingContext) { pushTopLevelContextObject$1(workInProgress, root.pendingContext, root.pendingContext !== root.context); } else if (root.context) { // Should always be set pushTopLevelContextObject$1(workInProgress, root.context, false); } pushHostContainer(workInProgress, root.containerInfo); } function updateHostRoot(current, workInProgress, priorityLevel) { pushHostRootContext(workInProgress); var updateQueue = workInProgress.updateQueue; if (updateQueue !== null) { var prevState = workInProgress.memoizedState; var state = beginUpdateQueue$1(current, workInProgress, updateQueue, null, prevState, null, priorityLevel); if (prevState === state) { // If the state is the same as before, that's a bailout because we had // no work matching this priority. resetHydrationState(); return bailoutOnAlreadyFinishedWork(current, workInProgress); } var element = state.element; if ((current === null || current.child === null) && enterHydrationState(workInProgress)) { // If we don't have any current children this might be the first pass. // We always try to hydrate. If this isn't a hydration pass there won't // be any children to hydrate which is effectively the same thing as // not hydrating. // This is a bit of a hack. We track the host root as a placement to // know that we're currently in a mounting state. That way isMounted // works as expected. We must reset this before committing. // TODO: Delete this when we delete isMounted and findDOMNode. workInProgress.effectTag |= Placement$2; // Ensure that children mount into this root without tracking // side-effects. This ensures that we don't store Placement effects on // nodes that will be hydrated. workInProgress.child = mountChildFibersInPlace(workInProgress, workInProgress.child, element, priorityLevel); } else { // Otherwise reset hydration state in case we aborted and resumed another // root. resetHydrationState(); reconcileChildren(current, workInProgress, element); } memoizeState(workInProgress, state); return workInProgress.child; } resetHydrationState(); // If there is no update queue, that's a bailout because the root has no props. return bailoutOnAlreadyFinishedWork(current, workInProgress); } function updateHostComponent(current, workInProgress, renderPriority) { pushHostContext(workInProgress); if (current === null) { tryToClaimNextHydratableInstance(workInProgress); } var type = workInProgress.type; var memoizedProps = workInProgress.memoizedProps; var nextProps = workInProgress.pendingProps; if (nextProps === null) { nextProps = memoizedProps; !(nextProps !== null) ? invariant(false, 'We should always have pending or current props. This error is likely caused by a bug in React. Please file an issue.') : void 0; } var prevProps = current !== null ? current.memoizedProps : null; if (hasContextChanged$1()) { // Normally we can bail out on props equality but if context has changed // we don't do the bailout and we have to reuse existing props instead. } else if (nextProps === null || memoizedProps === nextProps) { return bailoutOnAlreadyFinishedWork(current, workInProgress); } var nextChildren = nextProps.children; var isDirectTextChild = shouldSetTextContent(type, nextProps); if (isDirectTextChild) { // We special case a direct text child of a host node. This is a common // case. We won't handle it as a reified child. We will instead handle // this in the host environment that also have access to this prop. That // avoids allocating another HostText fiber and traversing it. nextChildren = null; } else if (prevProps && shouldSetTextContent(type, prevProps)) { // If we're switching from a direct text child to a normal child, or to // empty, we need to schedule the text content to be reset. workInProgress.effectTag |= ContentReset$1; } markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden. if (renderPriority !== OffscreenPriority$1 && !useSyncScheduling && shouldDeprioritizeSubtree(type, nextProps)) { // Down-prioritize the children. workInProgress.pendingWorkPriority = OffscreenPriority$1; // Bailout and come back to this fiber later at OffscreenPriority. return null; } reconcileChildren(current, workInProgress, nextChildren); memoizeProps(workInProgress, nextProps); return workInProgress.child; } function updateHostText(current, workInProgress) { if (current === null) { tryToClaimNextHydratableInstance(workInProgress); } var nextProps = workInProgress.pendingProps; if (nextProps === null) { nextProps = workInProgress.memoizedProps; } memoizeProps(workInProgress, nextProps); // Nothing to do here. This is terminal. We'll do the completion step // immediately after. return null; } function mountIndeterminateComponent(current, workInProgress, priorityLevel) { !(current === null) ? invariant(false, 'An indeterminate component should never have mounted. This error is likely caused by a bug in React. Please file an issue.') : void 0; var fn = workInProgress.type; var props = workInProgress.pendingProps; var unmaskedContext = getUnmaskedContext$1(workInProgress); var context = getMaskedContext$1(workInProgress, unmaskedContext); var value; { ReactCurrentOwner$2.current = workInProgress; value = fn(props, context); } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork$1; if (typeof value === 'object' && value !== null && typeof value.render === 'function') { // Proceed under the assumption that this is a class instance workInProgress.tag = ClassComponent$6; // Push context providers early to prevent context stack mismatches. // During mounting we don't know the child context yet as the instance doesn't exist. // We will invalidate the child context in finishClassComponent() right after rendering. var hasContext = pushContextProvider$1(workInProgress); adoptClassInstance(workInProgress, value); mountClassInstance(workInProgress, priorityLevel); return finishClassComponent(current, workInProgress, true, hasContext); } else { // Proceed under the assumption that this is a functional component workInProgress.tag = FunctionalComponent$1; { var Component = workInProgress.type; if (Component) { warning$23(!Component.childContextTypes, '%s(...): childContextTypes cannot be defined on a functional component.', Component.displayName || Component.name || 'Component'); } if (workInProgress.ref !== null) { var info = ''; var ownerName = ReactDebugCurrentFiber$4.getCurrentFiberOwnerName(); if (ownerName) { info += '\n\nCheck the render method of `' + ownerName + '`.'; } var warningKey = ownerName || workInProgress._debugID || ''; var debugSource = workInProgress._debugSource; if (debugSource) { warningKey = debugSource.fileName + ':' + debugSource.lineNumber; } if (!warnedAboutStatelessRefs[warningKey]) { warnedAboutStatelessRefs[warningKey] = true; warning$23(false, 'Stateless function components cannot be given refs. ' + 'Attempts to access this ref will fail.%s%s', info, ReactDebugCurrentFiber$4.getCurrentFiberStackAddendum()); } } } reconcileChildren(current, workInProgress, value); memoizeProps(workInProgress, props); return workInProgress.child; } } function updateCoroutineComponent(current, workInProgress) { var nextCoroutine = workInProgress.pendingProps; if (hasContextChanged$1()) { // Normally we can bail out on props equality but if context has changed // we don't do the bailout and we have to reuse existing props instead. if (nextCoroutine === null) { nextCoroutine = current && current.memoizedProps; !(nextCoroutine !== null) ? invariant(false, 'We should always have pending or current props. This error is likely caused by a bug in React. Please file an issue.') : void 0; } } else if (nextCoroutine === null || workInProgress.memoizedProps === nextCoroutine) { nextCoroutine = workInProgress.memoizedProps; // TODO: When bailing out, we might need to return the stateNode instead // of the child. To check it for work. // return bailoutOnAlreadyFinishedWork(current, workInProgress); } var nextChildren = nextCoroutine.children; var priorityLevel = workInProgress.pendingWorkPriority; // The following is a fork of reconcileChildrenAtPriority but using // stateNode to store the child. if (current === null) { workInProgress.stateNode = mountChildFibersInPlace(workInProgress, workInProgress.stateNode, nextChildren, priorityLevel); } else if (current.child === workInProgress.child) { workInProgress.stateNode = reconcileChildFibers(workInProgress, workInProgress.stateNode, nextChildren, priorityLevel); } else { workInProgress.stateNode = reconcileChildFibersInPlace(workInProgress, workInProgress.stateNode, nextChildren, priorityLevel); } memoizeProps(workInProgress, nextCoroutine); // This doesn't take arbitrary time so we could synchronously just begin // eagerly do the work of workInProgress.child as an optimization. return workInProgress.stateNode; } function updatePortalComponent(current, workInProgress) { pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); var priorityLevel = workInProgress.pendingWorkPriority; var nextChildren = workInProgress.pendingProps; if (hasContextChanged$1()) { // Normally we can bail out on props equality but if context has changed // we don't do the bailout and we have to reuse existing props instead. if (nextChildren === null) { nextChildren = current && current.memoizedProps; !(nextChildren != null) ? invariant(false, 'We should always have pending or current props. This error is likely caused by a bug in React. Please file an issue.') : void 0; } } else if (nextChildren === null || workInProgress.memoizedProps === nextChildren) { return bailoutOnAlreadyFinishedWork(current, workInProgress); } if (current === null) { // Portals are special because we don't append the children during mount // but at commit. Therefore we need to track insertions which the normal // flow doesn't do during mount. This doesn't happen at the root because // the root always starts with a "current" with a null child. // TODO: Consider unifying this with how the root works. workInProgress.child = reconcileChildFibersInPlace(workInProgress, workInProgress.child, nextChildren, priorityLevel); memoizeProps(workInProgress, nextChildren); } else { reconcileChildren(current, workInProgress, nextChildren); memoizeProps(workInProgress, nextChildren); } return workInProgress.child; } /* function reuseChildrenEffects(returnFiber : Fiber, firstChild : Fiber) { let child = firstChild; do { // Ensure that the first and last effect of the parent corresponds // to the children's first and last effect. if (!returnFiber.firstEffect) { returnFiber.firstEffect = child.firstEffect; } if (child.lastEffect) { if (returnFiber.lastEffect) { returnFiber.lastEffect.nextEffect = child.firstEffect; } returnFiber.lastEffect = child.lastEffect; } } while (child = child.sibling); } */ function bailoutOnAlreadyFinishedWork(current, workInProgress) { { cancelWorkTimer(workInProgress); } // TODO: We should ideally be able to bail out early if the children have no // more work to do. However, since we don't have a separation of this // Fiber's priority and its children yet - we don't know without doing lots // of the same work we do anyway. Once we have that separation we can just // bail out here if the children has no more work at this priority level. // if (workInProgress.priorityOfChildren <= priorityLevel) { // // If there are side-effects in these children that have not yet been // // committed we need to ensure that they get properly transferred up. // if (current && current.child !== workInProgress.child) { // reuseChildrenEffects(workInProgress, child); // } // return null; // } cloneChildFibers(current, workInProgress); return workInProgress.child; } function bailoutOnLowPriority(current, workInProgress) { { cancelWorkTimer(workInProgress); } // TODO: Handle HostComponent tags here as well and call pushHostContext()? // See PR 8590 discussion for context switch (workInProgress.tag) { case HostRoot$7: pushHostRootContext(workInProgress); break; case ClassComponent$6: pushContextProvider$1(workInProgress); break; case HostPortal$4: pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); break; } // TODO: What if this is currently in progress? // How can that happen? How is this not being cloned? return null; } // TODO: Delete memoizeProps/State and move to reconcile/bailout instead function memoizeProps(workInProgress, nextProps) { workInProgress.memoizedProps = nextProps; } function memoizeState(workInProgress, nextState) { workInProgress.memoizedState = nextState; // Don't reset the updateQueue, in case there are pending updates. Resetting // is handled by beginUpdateQueue. } function beginWork(current, workInProgress, priorityLevel) { if (workInProgress.pendingWorkPriority === NoWork$3 || workInProgress.pendingWorkPriority > priorityLevel) { return bailoutOnLowPriority(current, workInProgress); } { ReactDebugCurrentFiber$4.setCurrentFiber(workInProgress, null); } switch (workInProgress.tag) { case IndeterminateComponent$2: return mountIndeterminateComponent(current, workInProgress, priorityLevel); case FunctionalComponent$1: return updateFunctionalComponent(current, workInProgress); case ClassComponent$6: return updateClassComponent(current, workInProgress, priorityLevel); case HostRoot$7: return updateHostRoot(current, workInProgress, priorityLevel); case HostComponent$7: return updateHostComponent(current, workInProgress, priorityLevel); case HostText$4: return updateHostText(current, workInProgress); case CoroutineHandlerPhase: // This is a restart. Reset the tag to the initial phase. workInProgress.tag = CoroutineComponent$1; // Intentionally fall through since this is now the same. case CoroutineComponent$1: return updateCoroutineComponent(current, workInProgress); case YieldComponent$2: // A yield component is just a placeholder, we can just run through the // next one immediately. return null; case HostPortal$4: return updatePortalComponent(current, workInProgress); case Fragment$2: return updateFragment(current, workInProgress); default: invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.'); } } function beginFailedWork(current, workInProgress, priorityLevel) { // Push context providers here to avoid a push/pop context mismatch. switch (workInProgress.tag) { case ClassComponent$6: pushContextProvider$1(workInProgress); break; case HostRoot$7: pushHostRootContext(workInProgress); break; default: invariant(false, 'Invalid type of work. This error is likely caused by a bug in React. Please file an issue.'); } // Add an error effect so we can handle the error during the commit phase workInProgress.effectTag |= Err$1; // This is a weird case where we do "resume" work — work that failed on // our first attempt. Because we no longer have a notion of "progressed // deletions," reset the child to the current child to make sure we delete // it again. TODO: Find a better way to handle this, perhaps during a more // general overhaul of error handling. if (current === null) { workInProgress.child = null; } else if (workInProgress.child !== current.child) { workInProgress.child = current.child; } if (workInProgress.pendingWorkPriority === NoWork$3 || workInProgress.pendingWorkPriority > priorityLevel) { return bailoutOnLowPriority(current, workInProgress); } // If we don't bail out, we're going be recomputing our children so we need // to drop our effect list. workInProgress.firstEffect = null; workInProgress.lastEffect = null; // Unmount the current children as if the component rendered null var nextChildren = null; reconcileChildrenAtPriority(current, workInProgress, nextChildren, priorityLevel); if (workInProgress.tag === ClassComponent$6) { var instance = workInProgress.stateNode; workInProgress.memoizedProps = instance.props; workInProgress.memoizedState = instance.state; } return workInProgress.child; } return { beginWork: beginWork, beginFailedWork: beginFailedWork }; }; var reconcileChildFibers$2 = ReactChildFiber.reconcileChildFibers; var popContextProvider$2 = ReactFiberContext.popContextProvider; var popTopLevelContextObject$1 = ReactFiberContext.popTopLevelContextObject; var IndeterminateComponent$3 = ReactTypeOfWork.IndeterminateComponent; var FunctionalComponent$3 = ReactTypeOfWork.FunctionalComponent; var ClassComponent$8 = ReactTypeOfWork.ClassComponent; var HostRoot$8 = ReactTypeOfWork.HostRoot; var HostComponent$8 = ReactTypeOfWork.HostComponent; var HostText$6 = ReactTypeOfWork.HostText; var HostPortal$6 = ReactTypeOfWork.HostPortal; var CoroutineComponent$3 = ReactTypeOfWork.CoroutineComponent; var CoroutineHandlerPhase$1 = ReactTypeOfWork.CoroutineHandlerPhase; var YieldComponent$4 = ReactTypeOfWork.YieldComponent; var Fragment$4 = ReactTypeOfWork.Fragment; var Placement$4 = ReactTypeOfSideEffect.Placement; var Ref$2 = ReactTypeOfSideEffect.Ref; var Update$2 = ReactTypeOfSideEffect.Update; var OffscreenPriority$2 = ReactPriorityLevel.OffscreenPriority; { var ReactDebugCurrentFiber$5 = ReactDebugCurrentFiber_1; } var ReactFiberCompleteWork = function (config, hostContext, hydrationContext) { var createInstance = config.createInstance, createTextInstance = config.createTextInstance, appendInitialChild = config.appendInitialChild, finalizeInitialChildren = config.finalizeInitialChildren, prepareUpdate = config.prepareUpdate; var getRootHostContainer = hostContext.getRootHostContainer, popHostContext = hostContext.popHostContext, getHostContext = hostContext.getHostContext, popHostContainer = hostContext.popHostContainer; var prepareToHydrateHostInstance = hydrationContext.prepareToHydrateHostInstance, prepareToHydrateHostTextInstance = hydrationContext.prepareToHydrateHostTextInstance, popHydrationState = hydrationContext.popHydrationState; function markUpdate(workInProgress) { // Tag the fiber with an update effect. This turns a Placement into // an UpdateAndPlacement. workInProgress.effectTag |= Update$2; } function markRef(workInProgress) { workInProgress.effectTag |= Ref$2; } function appendAllYields(yields, workInProgress) { var node = workInProgress.stateNode; if (node) { node['return'] = workInProgress; } while (node !== null) { if (node.tag === HostComponent$8 || node.tag === HostText$6 || node.tag === HostPortal$6) { invariant(false, 'A coroutine cannot have host component children.'); } else if (node.tag === YieldComponent$4) { yields.push(node.type); } else if (node.child !== null) { node.child['return'] = node; node = node.child; continue; } while (node.sibling === null) { if (node['return'] === null || node['return'] === workInProgress) { return; } node = node['return']; } node.sibling['return'] = node['return']; node = node.sibling; } } function moveCoroutineToHandlerPhase(current, workInProgress) { var coroutine = workInProgress.memoizedProps; !coroutine ? invariant(false, 'Should be resolved by now. This error is likely caused by a bug in React. Please file an issue.') : void 0; // First step of the coroutine has completed. Now we need to do the second. // TODO: It would be nice to have a multi stage coroutine represented by a // single component, or at least tail call optimize nested ones. Currently // that requires additional fields that we don't want to add to the fiber. // So this requires nested handlers. // Note: This doesn't mutate the alternate node. I don't think it needs to // since this stage is reset for every pass. workInProgress.tag = CoroutineHandlerPhase$1; // Build up the yields. // TODO: Compare this to a generator or opaque helpers like Children. var yields = []; appendAllYields(yields, workInProgress); var fn = coroutine.handler; var props = coroutine.props; var nextChildren = fn(props, yields); var currentFirstChild = current !== null ? current.child : null; // Inherit the priority of the returnFiber. var priority = workInProgress.pendingWorkPriority; workInProgress.child = reconcileChildFibers$2(workInProgress, currentFirstChild, nextChildren, priority); return workInProgress.child; } function appendAllChildren(parent, workInProgress) { // We only have the top Fiber that was created but we need recurse down its // children to find all the terminal nodes. var node = workInProgress.child; while (node !== null) { if (node.tag === HostComponent$8 || node.tag === HostText$6) { appendInitialChild(parent, node.stateNode); } else if (node.tag === HostPortal$6) { // If we have a portal child, then we don't want to traverse // down its children. Instead, we'll get insertions from each child in // the portal directly. } else if (node.child !== null) { node = node.child; continue; } if (node === workInProgress) { return; } while (node.sibling === null) { if (node['return'] === null || node['return'] === workInProgress) { return; } node = node['return']; } node = node.sibling; } } function completeWork(current, workInProgress, renderPriority) { { ReactDebugCurrentFiber$5.setCurrentFiber(workInProgress, null); } // Get the latest props. var newProps = workInProgress.pendingProps; if (newProps === null) { newProps = workInProgress.memoizedProps; } else if (workInProgress.pendingWorkPriority !== OffscreenPriority$2 || renderPriority === OffscreenPriority$2) { // Reset the pending props, unless this was a down-prioritization. workInProgress.pendingProps = null; } switch (workInProgress.tag) { case FunctionalComponent$3: return null; case ClassComponent$8: { // We are leaving this subtree, so pop context if any. popContextProvider$2(workInProgress); return null; } case HostRoot$8: { popHostContainer(workInProgress); popTopLevelContextObject$1(workInProgress); var fiberRoot = workInProgress.stateNode; if (fiberRoot.pendingContext) { fiberRoot.context = fiberRoot.pendingContext; fiberRoot.pendingContext = null; } if (current === null || current.child === null) { // If we hydrated, pop so that we can delete any remaining children // that weren't hydrated. popHydrationState(workInProgress); // This resets the hacky state to fix isMounted before committing. // TODO: Delete this when we delete isMounted and findDOMNode. workInProgress.effectTag &= ~Placement$4; } return null; } case HostComponent$8: { popHostContext(workInProgress); var rootContainerInstance = getRootHostContainer(); var type = workInProgress.type; if (current !== null && workInProgress.stateNode != null) { // If we have an alternate, that means this is an update and we need to // schedule a side-effect to do the updates. var oldProps = current.memoizedProps; // If we get updated because one of our children updated, we don't // have newProps so we'll have to reuse them. // TODO: Split the update API as separate for the props vs. children. // Even better would be if children weren't special cased at all tho. var instance = workInProgress.stateNode; var currentHostContext = getHostContext(); var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); // TODO: Type this specific to this type of component. workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there // is a new ref we mark this as an update. if (updatePayload) { markUpdate(workInProgress); } if (current.ref !== workInProgress.ref) { markRef(workInProgress); } } else { if (!newProps) { !(workInProgress.stateNode !== null) ? invariant(false, 'We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.') : void 0; // This can happen when we abort work. return null; } var _currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context // "stack" as the parent. Then append children as we go in beginWork // or completeWork depending on we want to add then top->down or // bottom->up. Top->down is faster in IE11. var wasHydrated = popHydrationState(workInProgress); if (wasHydrated) { // TOOD: Move this and createInstance step into the beginPhase // to consolidate. if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, _currentHostContext)) { // If changes to the hydrated node needs to be applied at the // commit-phase we mark this as such. markUpdate(workInProgress); } } else { var _instance = createInstance(type, newProps, rootContainerInstance, _currentHostContext, workInProgress); appendAllChildren(_instance, workInProgress); // Certain renderers require commit-time effects for initial mount. // (eg DOM renderer supports auto-focus for certain elements). // Make sure such renderers get scheduled for later work. if (finalizeInitialChildren(_instance, type, newProps, rootContainerInstance)) { markUpdate(workInProgress); } workInProgress.stateNode = _instance; } if (workInProgress.ref !== null) { // If there is a ref on a host node we need to schedule a callback markRef(workInProgress); } } return null; } case HostText$6: { var newText = newProps; if (current && workInProgress.stateNode != null) { var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need // to schedule a side-effect to do the updates. if (oldText !== newText) { markUpdate(workInProgress); } } else { if (typeof newText !== 'string') { !(workInProgress.stateNode !== null) ? invariant(false, 'We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.') : void 0; // This can happen when we abort work. return null; } var _rootContainerInstance = getRootHostContainer(); var _currentHostContext2 = getHostContext(); var _wasHydrated = popHydrationState(workInProgress); if (_wasHydrated) { if (prepareToHydrateHostTextInstance(workInProgress)) { markUpdate(workInProgress); } } else { workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext2, workInProgress); } } return null; } case CoroutineComponent$3: return moveCoroutineToHandlerPhase(current, workInProgress); case CoroutineHandlerPhase$1: // Reset the tag to now be a first phase coroutine. workInProgress.tag = CoroutineComponent$3; return null; case YieldComponent$4: // Does nothing. return null; case Fragment$4: return null; case HostPortal$6: // TODO: Only mark this as an update if we have any pending callbacks. markUpdate(workInProgress); popHostContainer(workInProgress); return null; // Error cases case IndeterminateComponent$3: invariant(false, 'An indeterminate component should have become determinate before completing. This error is likely caused by a bug in React. Please file an issue.'); // eslint-disable-next-line no-fallthrough default: invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.'); } } return { completeWork: completeWork }; }; { var warning$26 = require$$0; } var onCommitFiberRoot = null; var onCommitFiberUnmount = null; var hasLoggedError = false; function catchErrors(fn) { return function (arg) { try { return fn(arg); } catch (err) { if (true && !hasLoggedError) { hasLoggedError = true; warning$26(false, 'React DevTools encountered an error: %s', err); } } }; } function injectInternals$1(internals) { if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') { // No DevTools return false; } var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; if (!hook.supportsFiber) { { warning$26(false, 'The installed version of React DevTools is too old and will not work ' + 'with the current version of React. Please update React DevTools. ' + 'https://fb.me/react-devtools'); } // DevTools exists, even though it doesn't support Fiber. return true; } try { var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. onCommitFiberRoot = catchErrors(function (root) { return hook.onCommitFiberRoot(rendererID, root); }); onCommitFiberUnmount = catchErrors(function (fiber) { return hook.onCommitFiberUnmount(rendererID, fiber); }); } catch (err) { // Catch all errors because it is unsafe to throw during initialization. { warning$26(false, 'React DevTools encountered an error: %s.', err); } } // DevTools exists return true; } function onCommitRoot$1(root) { if (typeof onCommitFiberRoot === 'function') { onCommitFiberRoot(root); } } function onCommitUnmount$1(fiber) { if (typeof onCommitFiberUnmount === 'function') { onCommitFiberUnmount(fiber); } } var injectInternals_1 = injectInternals$1; var onCommitRoot_1 = onCommitRoot$1; var onCommitUnmount_1 = onCommitUnmount$1; var ReactFiberDevToolsHook = { injectInternals: injectInternals_1, onCommitRoot: onCommitRoot_1, onCommitUnmount: onCommitUnmount_1 }; var ClassComponent$9 = ReactTypeOfWork.ClassComponent; var HostRoot$9 = ReactTypeOfWork.HostRoot; var HostComponent$9 = ReactTypeOfWork.HostComponent; var HostText$7 = ReactTypeOfWork.HostText; var HostPortal$7 = ReactTypeOfWork.HostPortal; var CoroutineComponent$4 = ReactTypeOfWork.CoroutineComponent; var commitCallbacks$1 = ReactFiberUpdateQueue.commitCallbacks; var onCommitUnmount = ReactFiberDevToolsHook.onCommitUnmount; var invokeGuardedCallback$2 = ReactErrorUtils_1.invokeGuardedCallback; var hasCaughtError$1 = ReactErrorUtils_1.hasCaughtError; var clearCaughtError$1 = ReactErrorUtils_1.clearCaughtError; var Placement$5 = ReactTypeOfSideEffect.Placement; var Update$3 = ReactTypeOfSideEffect.Update; var Callback$1 = ReactTypeOfSideEffect.Callback; var ContentReset$2 = ReactTypeOfSideEffect.ContentReset; { var _require5$1 = ReactDebugFiberPerf_1, startPhaseTimer$2 = _require5$1.startPhaseTimer, stopPhaseTimer$2 = _require5$1.stopPhaseTimer; } var ReactFiberCommitWork = function (config, captureError) { var commitMount = config.commitMount, commitUpdate = config.commitUpdate, resetTextContent = config.resetTextContent, commitTextUpdate = config.commitTextUpdate, appendChild = config.appendChild, appendChildToContainer = config.appendChildToContainer, insertBefore = config.insertBefore, insertInContainerBefore = config.insertInContainerBefore, removeChild = config.removeChild, removeChildFromContainer = config.removeChildFromContainer, getPublicInstance = config.getPublicInstance; { var callComponentWillUnmountWithTimerInDev = function (current, instance) { startPhaseTimer$2(current, 'componentWillUnmount'); instance.props = current.memoizedProps; instance.state = current.memoizedState; instance.componentWillUnmount(); stopPhaseTimer$2(); }; } // Capture errors so they don't interrupt unmounting. function safelyCallComponentWillUnmount(current, instance) { { invokeGuardedCallback$2(null, callComponentWillUnmountWithTimerInDev, null, current, instance); if (hasCaughtError$1()) { var unmountError = clearCaughtError$1(); captureError(current, unmountError); } } } function safelyDetachRef(current) { var ref = current.ref; if (ref !== null) { { invokeGuardedCallback$2(null, ref, null, null); if (hasCaughtError$1()) { var refError = clearCaughtError$1(); captureError(current, refError); } } } } function getHostParentFiber(fiber) { var parent = fiber['return']; while (parent !== null) { if (isHostParent(parent)) { return parent; } parent = parent['return']; } invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.'); } function isHostParent(fiber) { return fiber.tag === HostComponent$9 || fiber.tag === HostRoot$9 || fiber.tag === HostPortal$7; } function getHostSibling(fiber) { // We're going to search forward into the tree until we find a sibling host // node. Unfortunately, if multiple insertions are done in a row we have to // search past them. This leads to exponential search for the next sibling. var node = fiber; siblings: while (true) { // If we didn't find anything, let's try the next sibling. while (node.sibling === null) { if (node['return'] === null || isHostParent(node['return'])) { // If we pop out of the root or hit the parent the fiber we are the // last sibling. return null; } node = node['return']; } node.sibling['return'] = node['return']; node = node.sibling; while (node.tag !== HostComponent$9 && node.tag !== HostText$7) { // If it is not host node and, we might have a host node inside it. // Try to search down until we find one. if (node.effectTag & Placement$5) { // If we don't have a child, try the siblings instead. continue siblings; } // If we don't have a child, try the siblings instead. // We also skip portals because they are not part of this host tree. if (node.child === null || node.tag === HostPortal$7) { continue siblings; } else { node.child['return'] = node; node = node.child; } } // Check if this host node is stable or about to be placed. if (!(node.effectTag & Placement$5)) { // Found it! return node.stateNode; } } } function commitPlacement(finishedWork) { // Recursively insert all host nodes into the parent. var parentFiber = getHostParentFiber(finishedWork); var parent = void 0; var isContainer = void 0; switch (parentFiber.tag) { case HostComponent$9: parent = parentFiber.stateNode; isContainer = false; break; case HostRoot$9: parent = parentFiber.stateNode.containerInfo; isContainer = true; break; case HostPortal$7: parent = parentFiber.stateNode.containerInfo; isContainer = true; break; default: invariant(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.'); } if (parentFiber.effectTag & ContentReset$2) { // Reset the text content of the parent before doing any insertions resetTextContent(parent); // Clear ContentReset from the effect tag parentFiber.effectTag &= ~ContentReset$2; } var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need recurse down its // children to find all the terminal nodes. var node = finishedWork; while (true) { if (node.tag === HostComponent$9 || node.tag === HostText$7) { if (before) { if (isContainer) { insertInContainerBefore(parent, node.stateNode, before); } else { insertBefore(parent, node.stateNode, before); } } else { if (isContainer) { appendChildToContainer(parent, node.stateNode); } else { appendChild(parent, node.stateNode); } } } else if (node.tag === HostPortal$7) { // If the insertion itself is a portal, then we don't want to traverse // down its children. Instead, we'll get insertions from each child in // the portal directly. } else if (node.child !== null) { node.child['return'] = node; node = node.child; continue; } if (node === finishedWork) { return; } while (node.sibling === null) { if (node['return'] === null || node['return'] === finishedWork) { return; } node = node['return']; } node.sibling['return'] = node['return']; node = node.sibling; } } function commitNestedUnmounts(root) { // While we're inside a removed host node we don't want to call // removeChild on the inner nodes because they're removed by the top // call anyway. We also want to call componentWillUnmount on all // composites before this host node is removed from the tree. Therefore var node = root; while (true) { commitUnmount(node); // Visit children because they may contain more composite or host nodes. // Skip portals because commitUnmount() currently visits them recursively. if (node.child !== null && node.tag !== HostPortal$7) { node.child['return'] = node; node = node.child; continue; } if (node === root) { return; } while (node.sibling === null) { if (node['return'] === null || node['return'] === root) { return; } node = node['return']; } node.sibling['return'] = node['return']; node = node.sibling; } } function unmountHostComponents(current) { // We only have the top Fiber that was inserted but we need recurse down its var node = current; // Each iteration, currentParent is populated with node's host parent if not // currentParentIsValid. var currentParentIsValid = false; var currentParent = void 0; var currentParentIsContainer = void 0; while (true) { if (!currentParentIsValid) { var parent = node['return']; findParent: while (true) { !(parent !== null) ? invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.') : void 0; switch (parent.tag) { case HostComponent$9: currentParent = parent.stateNode; currentParentIsContainer = false; break findParent; case HostRoot$9: currentParent = parent.stateNode.containerInfo; currentParentIsContainer = true; break findParent; case HostPortal$7: currentParent = parent.stateNode.containerInfo; currentParentIsContainer = true; break findParent; } parent = parent['return']; } currentParentIsValid = true; } if (node.tag === HostComponent$9 || node.tag === HostText$7) { commitNestedUnmounts(node); // After all the children have unmounted, it is now safe to remove the // node from the tree. if (currentParentIsContainer) { removeChildFromContainer(currentParent, node.stateNode); } else { removeChild(currentParent, node.stateNode); } // Don't visit children because we already visited them. } else if (node.tag === HostPortal$7) { // When we go into a portal, it becomes the parent to remove from. // We will reassign it back when we pop the portal on the way up. currentParent = node.stateNode.containerInfo; // Visit children because portals might contain host components. if (node.child !== null) { node.child['return'] = node; node = node.child; continue; } } else { commitUnmount(node); // Visit children because we may find more host components below. if (node.child !== null) { node.child['return'] = node; node = node.child; continue; } } if (node === current) { return; } while (node.sibling === null) { if (node['return'] === null || node['return'] === current) { return; } node = node['return']; if (node.tag === HostPortal$7) { // When we go out of the portal, we need to restore the parent. // Since we don't keep a stack of them, we will search for it. currentParentIsValid = false; } } node.sibling['return'] = node['return']; node = node.sibling; } } function commitDeletion(current) { // Recursively delete all host nodes from the parent. // Detach refs and call componentWillUnmount() on the whole subtree. unmountHostComponents(current); // Cut off the return pointers to disconnect it from the tree. Ideally, we // should clear the child pointer of the parent alternate to let this // get GC:ed but we don't know which for sure which parent is the current // one so we'll settle for GC:ing the subtree of this child. This child // itself will be GC:ed when the parent updates the next time. current['return'] = null; current.child = null; if (current.alternate) { current.alternate.child = null; current.alternate['return'] = null; } } // User-originating errors (lifecycles and refs) should not interrupt // deletion, so don't let them throw. Host-originating errors should // interrupt deletion, so it's okay function commitUnmount(current) { if (typeof onCommitUnmount === 'function') { onCommitUnmount(current); } switch (current.tag) { case ClassComponent$9: { safelyDetachRef(current); var instance = current.stateNode; if (typeof instance.componentWillUnmount === 'function') { safelyCallComponentWillUnmount(current, instance); } return; } case HostComponent$9: { safelyDetachRef(current); return; } case CoroutineComponent$4: { commitNestedUnmounts(current.stateNode); return; } case HostPortal$7: { // TODO: this is recursive. // We are also not using this parent because // the portal will get pushed immediately. unmountHostComponents(current); return; } } } function commitWork(current, finishedWork) { switch (finishedWork.tag) { case ClassComponent$9: { return; } case HostComponent$9: { var instance = finishedWork.stateNode; if (instance != null) { // Commit the work prepared earlier. var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps // as the newProps. The updatePayload will contain the real change in // this case. var oldProps = current !== null ? current.memoizedProps : newProps; var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. var updatePayload = finishedWork.updateQueue; finishedWork.updateQueue = null; if (updatePayload !== null) { commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork); } } return; } case HostText$7: { !(finishedWork.stateNode !== null) ? invariant(false, 'This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue.') : void 0; var textInstance = finishedWork.stateNode; var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps // as the newProps. The updatePayload will contain the real change in // this case. var oldText = current !== null ? current.memoizedProps : newText; commitTextUpdate(textInstance, oldText, newText); return; } case HostRoot$9: { return; } case HostPortal$7: { return; } default: { invariant(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.'); } } } function commitLifeCycles(current, finishedWork) { switch (finishedWork.tag) { case ClassComponent$9: { var instance = finishedWork.stateNode; if (finishedWork.effectTag & Update$3) { if (current === null) { { startPhaseTimer$2(finishedWork, 'componentDidMount'); } instance.props = finishedWork.memoizedProps; instance.state = finishedWork.memoizedState; instance.componentDidMount(); { stopPhaseTimer$2(); } } else { var prevProps = current.memoizedProps; var prevState = current.memoizedState; { startPhaseTimer$2(finishedWork, 'componentDidUpdate'); } instance.props = finishedWork.memoizedProps; instance.state = finishedWork.memoizedState; instance.componentDidUpdate(prevProps, prevState); { stopPhaseTimer$2(); } } } if (finishedWork.effectTag & Callback$1 && finishedWork.updateQueue !== null) { commitCallbacks$1(finishedWork, finishedWork.updateQueue, instance); } return; } case HostRoot$9: { var updateQueue = finishedWork.updateQueue; if (updateQueue !== null) { var _instance = finishedWork.child && finishedWork.child.stateNode; commitCallbacks$1(finishedWork, updateQueue, _instance); } return; } case HostComponent$9: { var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted // (eg DOM renderer may schedule auto-focus for inputs and form controls). // These effects should only be committed when components are first mounted, // aka when there is no current/alternate. if (current === null && finishedWork.effectTag & Update$3) { var type = finishedWork.type; var props = finishedWork.memoizedProps; commitMount(_instance2, type, props, finishedWork); } return; } case HostText$7: { // We have no life-cycles associated with text. return; } case HostPortal$7: { // We have no life-cycles associated with portals. return; } default: { invariant(false, 'This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.'); } } } function commitAttachRef(finishedWork) { var ref = finishedWork.ref; if (ref !== null) { var instance = finishedWork.stateNode; switch (finishedWork.tag) { case HostComponent$9: ref(getPublicInstance(instance)); break; default: ref(instance); } } } function commitDetachRef(current) { var currentRef = current.ref; if (currentRef !== null) { currentRef(null); } } return { commitPlacement: commitPlacement, commitDeletion: commitDeletion, commitWork: commitWork, commitLifeCycles: commitLifeCycles, commitAttachRef: commitAttachRef, commitDetachRef: commitDetachRef }; }; var createCursor$2 = ReactFiberStack.createCursor; var pop$2 = ReactFiberStack.pop; var push$2 = ReactFiberStack.push; var NO_CONTEXT = {}; var ReactFiberHostContext = function (config) { var getChildHostContext = config.getChildHostContext, getRootHostContext = config.getRootHostContext; var contextStackCursor = createCursor$2(NO_CONTEXT); var contextFiberStackCursor = createCursor$2(NO_CONTEXT); var rootInstanceStackCursor = createCursor$2(NO_CONTEXT); function requiredContext(c) { !(c !== NO_CONTEXT) ? invariant(false, 'Expected host context to exist. This error is likely caused by a bug in React. Please file an issue.') : void 0; return c; } function getRootHostContainer() { var rootInstance = requiredContext(rootInstanceStackCursor.current); return rootInstance; } function pushHostContainer(fiber, nextRootInstance) { // Push current root instance onto the stack; // This allows us to reset root when portals are popped. push$2(rootInstanceStackCursor, nextRootInstance, fiber); var nextRootContext = getRootHostContext(nextRootInstance); // Track the context and the Fiber that provided it. // This enables us to pop only Fibers that provide unique contexts. push$2(contextFiberStackCursor, fiber, fiber); push$2(contextStackCursor, nextRootContext, fiber); } function popHostContainer(fiber) { pop$2(contextStackCursor, fiber); pop$2(contextFiberStackCursor, fiber); pop$2(rootInstanceStackCursor, fiber); } function getHostContext() { var context = requiredContext(contextStackCursor.current); return context; } function pushHostContext(fiber) { var rootInstance = requiredContext(rootInstanceStackCursor.current); var context = requiredContext(contextStackCursor.current); var nextContext = getChildHostContext(context, fiber.type, rootInstance); // Don't push this Fiber's context unless it's unique. if (context === nextContext) { return; } // Track the context and the Fiber that provided it. // This enables us to pop only Fibers that provide unique contexts. push$2(contextFiberStackCursor, fiber, fiber); push$2(contextStackCursor, nextContext, fiber); } function popHostContext(fiber) { // Do not pop unless this Fiber provided the current context. // pushHostContext() only pushes Fibers that provide unique contexts. if (contextFiberStackCursor.current !== fiber) { return; } pop$2(contextStackCursor, fiber); pop$2(contextFiberStackCursor, fiber); } function resetHostContainer() { contextStackCursor.current = NO_CONTEXT; rootInstanceStackCursor.current = NO_CONTEXT; } return { getHostContext: getHostContext, getRootHostContainer: getRootHostContainer, popHostContainer: popHostContainer, popHostContext: popHostContext, pushHostContainer: pushHostContainer, pushHostContext: pushHostContext, resetHostContainer: resetHostContainer }; }; var HostComponent$10 = ReactTypeOfWork.HostComponent; var HostText$8 = ReactTypeOfWork.HostText; var HostRoot$10 = ReactTypeOfWork.HostRoot; var Deletion$2 = ReactTypeOfSideEffect.Deletion; var Placement$6 = ReactTypeOfSideEffect.Placement; var createFiberFromHostInstanceForDeletion$1 = ReactFiber.createFiberFromHostInstanceForDeletion; var ReactFiberHydrationContext = function (config) { var shouldSetTextContent = config.shouldSetTextContent, canHydrateInstance = config.canHydrateInstance, canHydrateTextInstance = config.canHydrateTextInstance, getNextHydratableSibling = config.getNextHydratableSibling, getFirstHydratableChild = config.getFirstHydratableChild, hydrateInstance = config.hydrateInstance, hydrateTextInstance = config.hydrateTextInstance, didNotHydrateInstance = config.didNotHydrateInstance, didNotFindHydratableInstance = config.didNotFindHydratableInstance, didNotFindHydratableTextInstance = config.didNotFindHydratableTextInstance; // If this doesn't have hydration mode. if (!(canHydrateInstance && canHydrateTextInstance && getNextHydratableSibling && getFirstHydratableChild && hydrateInstance && hydrateTextInstance && didNotHydrateInstance && didNotFindHydratableInstance && didNotFindHydratableTextInstance)) { return { enterHydrationState: function () { return false; }, resetHydrationState: function () {}, tryToClaimNextHydratableInstance: function () {}, prepareToHydrateHostInstance: function () { invariant(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'); }, prepareToHydrateHostTextInstance: function () { invariant(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'); }, popHydrationState: function (fiber) { return false; } }; } // The deepest Fiber on the stack involved in a hydration context. // This may have been an insertion or a hydration. var hydrationParentFiber = null; var nextHydratableInstance = null; var isHydrating = false; function enterHydrationState(fiber) { var parentInstance = fiber.stateNode.containerInfo; nextHydratableInstance = getFirstHydratableChild(parentInstance); hydrationParentFiber = fiber; isHydrating = true; return true; } function deleteHydratableInstance(returnFiber, instance) { { switch (returnFiber.tag) { case HostRoot$10: didNotHydrateInstance(returnFiber.stateNode.containerInfo, instance); break; case HostComponent$10: didNotHydrateInstance(returnFiber.stateNode, instance); break; } } var childToDelete = createFiberFromHostInstanceForDeletion$1(); childToDelete.stateNode = instance; childToDelete['return'] = returnFiber; childToDelete.effectTag = Deletion$2; // This might seem like it belongs on progressedFirstDeletion. However, // these children are not part of the reconciliation list of children. // Even if we abort and rereconcile the children, that will try to hydrate // again and the nodes are still in the host tree so these will be // recreated. if (returnFiber.lastEffect !== null) { returnFiber.lastEffect.nextEffect = childToDelete; returnFiber.lastEffect = childToDelete; } else { returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; } } function insertNonHydratedInstance(returnFiber, fiber) { fiber.effectTag |= Placement$6; { var parentInstance; switch (returnFiber.tag) { // TODO: Currently we don't warn for insertions into the root because // we always insert into the root in the non-hydrating case. We just // delete the existing content. Reenable this once we have a better // strategy for determining if we're hydrating or not. // case HostRoot: // parentInstance = returnFiber.stateNode.containerInfo; // break; case HostComponent$10: parentInstance = returnFiber.stateNode; break; default: return; } switch (fiber.tag) { case HostComponent$10: var type = fiber.type; var props = fiber.pendingProps; didNotFindHydratableInstance(parentInstance, type, props); break; case HostText$8: var text = fiber.pendingProps; didNotFindHydratableTextInstance(parentInstance, text); break; } } } function canHydrate(fiber, nextInstance) { switch (fiber.tag) { case HostComponent$10: { var type = fiber.type; var props = fiber.pendingProps; return canHydrateInstance(nextInstance, type, props); } case HostText$8: { var text = fiber.pendingProps; return canHydrateTextInstance(nextInstance, text); } default: return false; } } function tryToClaimNextHydratableInstance(fiber) { if (!isHydrating) { return; } var nextInstance = nextHydratableInstance; if (!nextInstance) { // Nothing to hydrate. Make it an insertion. insertNonHydratedInstance(hydrationParentFiber, fiber); isHydrating = false; hydrationParentFiber = fiber; return; } if (!canHydrate(fiber, nextInstance)) { // If we can't hydrate this instance let's try the next one. // We use this as a heuristic. It's based on intuition and not data so it // might be flawed or unnecessary. nextInstance = getNextHydratableSibling(nextInstance); if (!nextInstance || !canHydrate(fiber, nextInstance)) { // Nothing to hydrate. Make it an insertion. insertNonHydratedInstance(hydrationParentFiber, fiber); isHydrating = false; hydrationParentFiber = fiber; return; } // We matched the next one, we'll now assume that the first one was // superfluous and we'll delete it. Since we can't eagerly delete it // we'll have to schedule a deletion. To do that, this node needs a dummy // fiber associated with it. deleteHydratableInstance(hydrationParentFiber, nextHydratableInstance); } fiber.stateNode = nextInstance; hydrationParentFiber = fiber; nextHydratableInstance = getFirstHydratableChild(nextInstance); } function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) { var instance = fiber.stateNode; var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber); // TODO: Type this specific to this type of component. fiber.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there // is a new ref we mark this as an update. if (updatePayload !== null) { return true; } return false; } function prepareToHydrateHostTextInstance(fiber) { var textInstance = fiber.stateNode; var shouldUpdate = hydrateTextInstance(textInstance, fiber.memoizedProps, fiber); return shouldUpdate; } function popToNextHostParent(fiber) { var parent = fiber['return']; while (parent !== null && parent.tag !== HostComponent$10 && parent.tag !== HostRoot$10) { parent = parent['return']; } hydrationParentFiber = parent; } function popHydrationState(fiber) { if (fiber !== hydrationParentFiber) { // We're deeper than the current hydration context, inside an inserted // tree. return false; } if (!isHydrating) { // If we're not currently hydrating but we're in a hydration context, then // we were an insertion and now need to pop up reenter hydration of our // siblings. popToNextHostParent(fiber); isHydrating = true; return false; } var type = fiber.type; // If we have any remaining hydratable nodes, we need to delete them now. // We only do this deeper than head and body since they tend to have random // other nodes in them. We also ignore components with pure text content in // side of them. // TODO: Better heuristic. if (fiber.tag !== HostComponent$10 || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) { var nextInstance = nextHydratableInstance; while (nextInstance) { deleteHydratableInstance(fiber, nextInstance); nextInstance = getNextHydratableSibling(nextInstance); } } popToNextHostParent(fiber); nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null; return true; } function resetHydrationState() { hydrationParentFiber = null; nextHydratableInstance = null; isHydrating = false; } return { enterHydrationState: enterHydrationState, resetHydrationState: resetHydrationState, tryToClaimNextHydratableInstance: tryToClaimNextHydratableInstance, prepareToHydrateHostInstance: prepareToHydrateHostInstance, prepareToHydrateHostTextInstance: prepareToHydrateHostTextInstance, popHydrationState: popHydrationState }; }; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule ReactFiberInstrumentation * */ // This lets us hook into Fiber to debug what it's doing. // See https://github.com/facebook/react/pull/8033. // This is not part of the public API, not even for React DevTools. // You may only inject a debugTool if you work on React Fiber itself. var ReactFiberInstrumentation$2 = { debugTool: null }; var ReactFiberInstrumentation_1 = ReactFiberInstrumentation$2; var popContextProvider$1 = ReactFiberContext.popContextProvider; var reset$1 = ReactFiberStack.reset; var getStackAddendumByWorkInProgressFiber$2 = ReactFiberComponentTreeHook.getStackAddendumByWorkInProgressFiber; var logCapturedError = ReactFiberErrorLogger.logCapturedError; var invokeGuardedCallback$1 = ReactErrorUtils_1.invokeGuardedCallback; var hasCaughtError = ReactErrorUtils_1.hasCaughtError; var clearCaughtError = ReactErrorUtils_1.clearCaughtError; var ReactCurrentOwner$1 = ReactGlobalSharedState_1.ReactCurrentOwner; var createWorkInProgress$1 = ReactFiber.createWorkInProgress; var largerPriority$1 = ReactFiber.largerPriority; var onCommitRoot = ReactFiberDevToolsHook.onCommitRoot; var NoWork$2 = ReactPriorityLevel.NoWork; var SynchronousPriority$1 = ReactPriorityLevel.SynchronousPriority; var TaskPriority$1 = ReactPriorityLevel.TaskPriority; var HighPriority = ReactPriorityLevel.HighPriority; var LowPriority = ReactPriorityLevel.LowPriority; var OffscreenPriority = ReactPriorityLevel.OffscreenPriority; var AsyncUpdates = ReactTypeOfInternalContext.AsyncUpdates; var PerformedWork = ReactTypeOfSideEffect.PerformedWork; var Placement$1 = ReactTypeOfSideEffect.Placement; var Update = ReactTypeOfSideEffect.Update; var PlacementAndUpdate = ReactTypeOfSideEffect.PlacementAndUpdate; var Deletion = ReactTypeOfSideEffect.Deletion; var ContentReset = ReactTypeOfSideEffect.ContentReset; var Callback = ReactTypeOfSideEffect.Callback; var Err = ReactTypeOfSideEffect.Err; var Ref = ReactTypeOfSideEffect.Ref; var HostRoot$6 = ReactTypeOfWork.HostRoot; var HostComponent$6 = ReactTypeOfWork.HostComponent; var HostPortal$3 = ReactTypeOfWork.HostPortal; var ClassComponent$5 = ReactTypeOfWork.ClassComponent; var getUpdatePriority$1 = ReactFiberUpdateQueue.getUpdatePriority; var _require14 = ReactFiberContext; var resetContext$1 = _require14.resetContext; { var warning$22 = require$$0; var ReactFiberInstrumentation$1 = ReactFiberInstrumentation_1; var ReactDebugCurrentFiber$3 = ReactDebugCurrentFiber_1; var _require15 = ReactDebugFiberPerf_1, recordEffect = _require15.recordEffect, recordScheduleUpdate = _require15.recordScheduleUpdate, startWorkTimer = _require15.startWorkTimer, stopWorkTimer = _require15.stopWorkTimer, stopFailedWorkTimer = _require15.stopFailedWorkTimer, startWorkLoopTimer = _require15.startWorkLoopTimer, stopWorkLoopTimer = _require15.stopWorkLoopTimer, startCommitTimer = _require15.startCommitTimer, stopCommitTimer = _require15.stopCommitTimer, startCommitHostEffectsTimer = _require15.startCommitHostEffectsTimer, stopCommitHostEffectsTimer = _require15.stopCommitHostEffectsTimer, startCommitLifeCyclesTimer = _require15.startCommitLifeCyclesTimer, stopCommitLifeCyclesTimer = _require15.stopCommitLifeCyclesTimer; var warnAboutUpdateOnUnmounted = function (instance) { var ctor = instance.constructor; warning$22(false, 'Can only update a mounted or mounting component. This usually means ' + 'you called setState, replaceState, or forceUpdate on an unmounted ' + 'component. This is a no-op.\n\nPlease check the code for the ' + '%s component.', ctor && (ctor.displayName || ctor.name) || 'ReactClass'); }; var warnAboutInvalidUpdates = function (instance) { switch (ReactDebugCurrentFiber$3.phase) { case 'getChildContext': warning$22(false, 'setState(...): Cannot call setState() inside getChildContext()'); break; case 'render': warning$22(false, 'Cannot update during an existing state transition (such as within ' + "`render` or another component's constructor). Render methods should " + 'be a pure function of props and state; constructor side-effects are ' + 'an anti-pattern, but can be moved to `componentWillMount`.'); break; } }; } var timeHeuristicForUnitOfWork = 1; var ReactFiberScheduler = function (config) { var hostContext = ReactFiberHostContext(config); var hydrationContext = ReactFiberHydrationContext(config); var popHostContainer = hostContext.popHostContainer, popHostContext = hostContext.popHostContext, resetHostContainer = hostContext.resetHostContainer; var _ReactFiberBeginWork = ReactFiberBeginWork(config, hostContext, hydrationContext, scheduleUpdate, getPriorityContext), beginWork = _ReactFiberBeginWork.beginWork, beginFailedWork = _ReactFiberBeginWork.beginFailedWork; var _ReactFiberCompleteWo = ReactFiberCompleteWork(config, hostContext, hydrationContext), completeWork = _ReactFiberCompleteWo.completeWork; var _ReactFiberCommitWork = ReactFiberCommitWork(config, captureError), commitPlacement = _ReactFiberCommitWork.commitPlacement, commitDeletion = _ReactFiberCommitWork.commitDeletion, commitWork = _ReactFiberCommitWork.commitWork, commitLifeCycles = _ReactFiberCommitWork.commitLifeCycles, commitAttachRef = _ReactFiberCommitWork.commitAttachRef, commitDetachRef = _ReactFiberCommitWork.commitDetachRef; var scheduleDeferredCallback = config.scheduleDeferredCallback, useSyncScheduling = config.useSyncScheduling, prepareForCommit = config.prepareForCommit, resetAfterCommit = config.resetAfterCommit; // The priority level to use when scheduling an update. We use NoWork to // represent the default priority. // TODO: Should we change this to an array instead of using the call stack? // Might be less confusing. var priorityContext = NoWork$2; // Keeps track of whether we're currently in a work loop. var isPerformingWork = false; // Keeps track of whether the current deadline has expired. var deadlineHasExpired = false; // Keeps track of whether we should should batch sync updates. var isBatchingUpdates = false; // This is needed for the weird case where the initial mount is synchronous // even inside batchedUpdates :( var isUnbatchingUpdates = false; // The next work in progress fiber that we're currently working on. var nextUnitOfWork = null; var nextPriorityLevel = NoWork$2; // The next fiber with an effect that we're currently committing. var nextEffect = null; var pendingCommit = null; // Linked list of roots with scheduled work on them. var nextScheduledRoot = null; var lastScheduledRoot = null; // Keep track of which host environment callbacks are scheduled. var isCallbackScheduled = false; // Keep track of which fibers have captured an error that need to be handled. // Work is removed from this collection after componentDidCatch is called. var capturedErrors = null; // Keep track of which fibers have failed during the current batch of work. // This is a different set than capturedErrors, because it is not reset until // the end of the batch. This is needed to propagate errors correctly if a // subtree fails more than once. var failedBoundaries = null; // Error boundaries that captured an error during the current commit. var commitPhaseBoundaries = null; var firstUncaughtError = null; var didFatal = false; var isCommitting = false; var isUnmounting = false; // Use these to prevent an infinite loop of nested updates var NESTED_UPDATE_LIMIT = 1000; var nestedUpdateCount = 0; var nextRenderedTree = null; function resetContextStack() { // Reset the stack reset$1(); // Reset the cursors resetContext$1(); resetHostContainer(); } // resetNextUnitOfWork mutates the current priority context. It is reset after // after the workLoop exits, so never call resetNextUnitOfWork from outside // the work loop. function resetNextUnitOfWork() { // Clear out roots with no more work on them, or if they have uncaught errors while (nextScheduledRoot !== null && nextScheduledRoot.current.pendingWorkPriority === NoWork$2) { // Unschedule this root. nextScheduledRoot.isScheduled = false; // Read the next pointer now. // We need to clear it in case this root gets scheduled again later. var next = nextScheduledRoot.nextScheduledRoot; nextScheduledRoot.nextScheduledRoot = null; // Exit if we cleared all the roots and there's no work to do. if (nextScheduledRoot === lastScheduledRoot) { nextScheduledRoot = null; lastScheduledRoot = null; nextPriorityLevel = NoWork$2; return null; } // Continue with the next root. // If there's no work on it, it will get unscheduled too. nextScheduledRoot = next; } var root = nextScheduledRoot; var highestPriorityRoot = null; var highestPriorityLevel = NoWork$2; while (root !== null) { if (root.current.pendingWorkPriority !== NoWork$2 && (highestPriorityLevel === NoWork$2 || highestPriorityLevel > root.current.pendingWorkPriority)) { highestPriorityLevel = root.current.pendingWorkPriority; highestPriorityRoot = root; } // We didn't find anything to do in this root, so let's try the next one. root = root.nextScheduledRoot; } if (highestPriorityRoot !== null) { nextPriorityLevel = highestPriorityLevel; // Before we start any new work, let's make sure that we have a fresh // stack to work from. // TODO: This call is buried a bit too deep. It would be nice to have // a single point which happens right before any new work and // unfortunately this is it. resetContextStack(); nextUnitOfWork = createWorkInProgress$1(highestPriorityRoot.current, highestPriorityLevel); if (highestPriorityRoot !== nextRenderedTree) { // We've switched trees. Reset the nested update counter. nestedUpdateCount = 0; nextRenderedTree = highestPriorityRoot; } return; } nextPriorityLevel = NoWork$2; nextUnitOfWork = null; nextRenderedTree = null; return; } function commitAllHostEffects() { while (nextEffect !== null) { { ReactDebugCurrentFiber$3.setCurrentFiber(nextEffect, null); recordEffect(); } var effectTag = nextEffect.effectTag; if (effectTag & ContentReset) { config.resetTextContent(nextEffect.stateNode); } if (effectTag & Ref) { var current = nextEffect.alternate; if (current !== null) { commitDetachRef(current); } } // The following switch statement is only concerned about placement, // updates, and deletions. To avoid needing to add a case for every // possible bitmap value, we remove the secondary effects from the // effect tag and switch on that value. var primaryEffectTag = effectTag & ~(Callback | Err | ContentReset | Ref | PerformedWork); switch (primaryEffectTag) { case Placement$1: { commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is inserted, before // any life-cycles like componentDidMount gets called. // TODO: findDOMNode doesn't rely on this any more but isMounted // does and isMounted is deprecated anyway so we should be able // to kill this. nextEffect.effectTag &= ~Placement$1; break; } case PlacementAndUpdate: { // Placement commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is inserted, before // any life-cycles like componentDidMount gets called. nextEffect.effectTag &= ~Placement$1; // Update var _current = nextEffect.alternate; commitWork(_current, nextEffect); break; } case Update: { var _current2 = nextEffect.alternate; commitWork(_current2, nextEffect); break; } case Deletion: { isUnmounting = true; commitDeletion(nextEffect); isUnmounting = false; break; } } nextEffect = nextEffect.nextEffect; } { ReactDebugCurrentFiber$3.resetCurrentFiber(); } } function commitAllLifeCycles() { while (nextEffect !== null) { var effectTag = nextEffect.effectTag; // Use Task priority for lifecycle updates if (effectTag & (Update | Callback)) { { recordEffect(); } var current = nextEffect.alternate; commitLifeCycles(current, nextEffect); } if (effectTag & Ref) { { recordEffect(); } commitAttachRef(nextEffect); } if (effectTag & Err) { { recordEffect(); } commitErrorHandling(nextEffect); } var next = nextEffect.nextEffect; // Ensure that we clean these up so that we don't accidentally keep them. // I'm not actually sure this matters because we can't reset firstEffect // and lastEffect since they're on every node, not just the effectful // ones. So we have to clean everything as we reuse nodes anyway. nextEffect.nextEffect = null; // Ensure that we reset the effectTag here so that we can rely on effect // tags to reason about the current life-cycle. nextEffect = next; } } function commitAllWork(finishedWork) { // We keep track of this so that captureError can collect any boundaries // that capture an error during the commit phase. The reason these aren't // local to this function is because errors that occur during cWU are // captured elsewhere, to prevent the unmount from being interrupted. isCommitting = true; { startCommitTimer(); } pendingCommit = null; var root = finishedWork.stateNode; !(root.current !== finishedWork) ? invariant(false, 'Cannot commit the same tree as before. This is probably a bug related to the return field. This error is likely caused by a bug in React. Please file an issue.') : void 0; if (nextPriorityLevel === SynchronousPriority$1 || nextPriorityLevel === TaskPriority$1) { // Keep track of the number of iterations to prevent an infinite // update loop. nestedUpdateCount++; } // Reset this to null before calling lifecycles ReactCurrentOwner$1.current = null; var firstEffect = void 0; if (finishedWork.effectTag > PerformedWork) { // A fiber's effect list consists only of its children, not itself. So if // the root has an effect, we need to add it to the end of the list. The // resulting list is the set that would belong to the root's parent, if // it had one; that is, all the effects in the tree including the root. if (finishedWork.lastEffect !== null) { finishedWork.lastEffect.nextEffect = finishedWork; firstEffect = finishedWork.firstEffect; } else { firstEffect = finishedWork; } } else { // There is no effect on the root. firstEffect = finishedWork.firstEffect; } prepareForCommit(); // Commit all the side-effects within a tree. We'll do this in two passes. // The first pass performs all the host insertions, updates, deletions and // ref unmounts. nextEffect = firstEffect; { startCommitHostEffectsTimer(); } while (nextEffect !== null) { var didError = false; var _error = void 0; { invokeGuardedCallback$1(null, commitAllHostEffects, null); if (hasCaughtError()) { didError = true; _error = clearCaughtError(); } } if (didError) { !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0; captureError(nextEffect, _error); // Clean-up if (nextEffect !== null) { nextEffect = nextEffect.nextEffect; } } } { stopCommitHostEffectsTimer(); } resetAfterCommit(); // The work-in-progress tree is now the current tree. This must come after // the first pass of the commit phase, so that the previous tree is still // current during componentWillUnmount, but before the second pass, so that // the finished work is current during componentDidMount/Update. root.current = finishedWork; // In the second pass we'll perform all life-cycles and ref callbacks. // Life-cycles happen as a separate pass so that all placements, updates, // and deletions in the entire tree have already been invoked. // This pass also triggers any renderer-specific initial effects. nextEffect = firstEffect; { startCommitLifeCyclesTimer(); } while (nextEffect !== null) { var _didError = false; var _error2 = void 0; { invokeGuardedCallback$1(null, commitAllLifeCycles, null); if (hasCaughtError()) { _didError = true; _error2 = clearCaughtError(); } } if (_didError) { !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0; captureError(nextEffect, _error2); if (nextEffect !== null) { nextEffect = nextEffect.nextEffect; } } } isCommitting = false; { stopCommitLifeCyclesTimer(); stopCommitTimer(); } if (typeof onCommitRoot === 'function') { onCommitRoot(finishedWork.stateNode); } if (true && ReactFiberInstrumentation$1.debugTool) { ReactFiberInstrumentation$1.debugTool.onCommitWork(finishedWork); } // If we caught any errors during this commit, schedule their boundaries // to update. if (commitPhaseBoundaries) { commitPhaseBoundaries.forEach(scheduleErrorRecovery); commitPhaseBoundaries = null; } // This tree is done. Reset the unit of work pointer to the next highest // priority root. If there's no more work left, the pointer is set to null. resetNextUnitOfWork(); } function resetWorkPriority(workInProgress, renderPriority) { if (workInProgress.pendingWorkPriority !== NoWork$2 && workInProgress.pendingWorkPriority > renderPriority) { // This was a down-prioritization. Don't bubble priority from children. return; } // Check for pending update priority. var newPriority = getUpdatePriority$1(workInProgress); // TODO: Coroutines need to visit stateNode var child = workInProgress.child; while (child !== null) { // Ensure that remaining work priority bubbles up. newPriority = largerPriority$1(newPriority, child.pendingWorkPriority); child = child.sibling; } workInProgress.pendingWorkPriority = newPriority; } function completeUnitOfWork(workInProgress) { while (true) { // The current, flushed, state of this fiber is the alternate. // Ideally nothing should rely on this, but relying on it here // means that we don't need an additional field on the work in // progress. var current = workInProgress.alternate; var next = completeWork(current, workInProgress, nextPriorityLevel); var returnFiber = workInProgress['return']; var siblingFiber = workInProgress.sibling; resetWorkPriority(workInProgress, nextPriorityLevel); if (next !== null) { { stopWorkTimer(workInProgress); } if (true && ReactFiberInstrumentation$1.debugTool) { ReactFiberInstrumentation$1.debugTool.onCompleteWork(workInProgress); } // If completing this work spawned new work, do that next. We'll come // back here again. return next; } if (returnFiber !== null) { // Append all the effects of the subtree and this fiber onto the effect // list of the parent. The completion order of the children affects the // side-effect order. if (returnFiber.firstEffect === null) { returnFiber.firstEffect = workInProgress.firstEffect; } if (workInProgress.lastEffect !== null) { if (returnFiber.lastEffect !== null) { returnFiber.lastEffect.nextEffect = workInProgress.firstEffect; } returnFiber.lastEffect = workInProgress.lastEffect; } // If this fiber had side-effects, we append it AFTER the children's // side-effects. We can perform certain side-effects earlier if // needed, by doing multiple passes over the effect list. We don't want // to schedule our own side-effect on our own list because if end up // reusing children we'll schedule this effect onto itself since we're // at the end. var effectTag = workInProgress.effectTag; // Skip both NoWork and PerformedWork tags when creating the effect list. // PerformedWork effect is read by React DevTools but shouldn't be committed. if (effectTag > PerformedWork) { if (returnFiber.lastEffect !== null) { returnFiber.lastEffect.nextEffect = workInProgress; } else { returnFiber.firstEffect = workInProgress; } returnFiber.lastEffect = workInProgress; } } { stopWorkTimer(workInProgress); } if (true && ReactFiberInstrumentation$1.debugTool) { ReactFiberInstrumentation$1.debugTool.onCompleteWork(workInProgress); } if (siblingFiber !== null) { // If there is more work to do in this returnFiber, do that next. return siblingFiber; } else if (returnFiber !== null) { // If there's no more work in this returnFiber. Complete the returnFiber. workInProgress = returnFiber; continue; } else { // We've reached the root. Mark the root as pending commit. Depending // on how much time we have left, we'll either commit it now or in // the next frame. pendingCommit = workInProgress; return null; } } // Without this explicit null return Flow complains of invalid return type // TODO Remove the above while(true) loop // eslint-disable-next-line no-unreachable return null; } function performUnitOfWork(workInProgress) { // The current, flushed, state of this fiber is the alternate. // Ideally nothing should rely on this, but relying on it here // means that we don't need an additional field on the work in // progress. var current = workInProgress.alternate; // See if beginning this work spawns more work. { startWorkTimer(workInProgress); } var next = beginWork(current, workInProgress, nextPriorityLevel); if (true && ReactFiberInstrumentation$1.debugTool) { ReactFiberInstrumentation$1.debugTool.onBeginWork(workInProgress); } if (next === null) { // If this doesn't spawn new work, complete the current work. next = completeUnitOfWork(workInProgress); } ReactCurrentOwner$1.current = null; { ReactDebugCurrentFiber$3.resetCurrentFiber(); } return next; } function performFailedUnitOfWork(workInProgress) { // The current, flushed, state of this fiber is the alternate. // Ideally nothing should rely on this, but relying on it here // means that we don't need an additional field on the work in // progress. var current = workInProgress.alternate; // See if beginning this work spawns more work. { startWorkTimer(workInProgress); } var next = beginFailedWork(current, workInProgress, nextPriorityLevel); if (true && ReactFiberInstrumentation$1.debugTool) { ReactFiberInstrumentation$1.debugTool.onBeginWork(workInProgress); } if (next === null) { // If this doesn't spawn new work, complete the current work. next = completeUnitOfWork(workInProgress); } ReactCurrentOwner$1.current = null; { ReactDebugCurrentFiber$3.resetCurrentFiber(); } return next; } function performDeferredWork(deadline) { performWork(OffscreenPriority, deadline); } function handleCommitPhaseErrors() { // This is a special work loop for handling commit phase errors. It's // similar to the syncrhonous work loop, but does an additional check on // each fiber to see if it's an error boundary with an unhandled error. If // so, it uses a forked version of performUnitOfWork that unmounts the // failed subtree. // // The loop stops once the children have unmounted and error lifecycles are // called. Then we return to the regular flow. if (capturedErrors !== null && capturedErrors.size > 0 && nextPriorityLevel === TaskPriority$1) { while (nextUnitOfWork !== null) { if (hasCapturedError(nextUnitOfWork)) { // Use a forked version of performUnitOfWork nextUnitOfWork = performFailedUnitOfWork(nextUnitOfWork); } else { nextUnitOfWork = performUnitOfWork(nextUnitOfWork); } if (nextUnitOfWork === null) { !(pendingCommit !== null) ? invariant(false, 'Should have a pending commit. This error is likely caused by a bug in React. Please file an issue.') : void 0; // We just completed a root. Commit it now. priorityContext = TaskPriority$1; commitAllWork(pendingCommit); priorityContext = nextPriorityLevel; if (capturedErrors === null || capturedErrors.size === 0 || nextPriorityLevel !== TaskPriority$1) { // There are no more unhandled errors. We can exit this special // work loop. If there's still additional work, we'll perform it // using one of the normal work loops. break; } // The commit phase produced additional errors. Continue working. } } } } function workLoop(minPriorityLevel, deadline) { if (pendingCommit !== null) { priorityContext = TaskPriority$1; commitAllWork(pendingCommit); handleCommitPhaseErrors(); } else if (nextUnitOfWork === null) { resetNextUnitOfWork(); } if (nextPriorityLevel === NoWork$2 || nextPriorityLevel > minPriorityLevel) { return; } // During the render phase, updates should have the same priority at which // we're rendering. priorityContext = nextPriorityLevel; loop: do { if (nextPriorityLevel <= TaskPriority$1) { // Flush all synchronous and task work. while (nextUnitOfWork !== null) { nextUnitOfWork = performUnitOfWork(nextUnitOfWork); if (nextUnitOfWork === null) { !(pendingCommit !== null) ? invariant(false, 'Should have a pending commit. This error is likely caused by a bug in React. Please file an issue.') : void 0; // We just completed a root. Commit it now. priorityContext = TaskPriority$1; commitAllWork(pendingCommit); priorityContext = nextPriorityLevel; // Clear any errors that were scheduled during the commit phase. handleCommitPhaseErrors(); // The priority level may have changed. Check again. if (nextPriorityLevel === NoWork$2 || nextPriorityLevel > minPriorityLevel || nextPriorityLevel > TaskPriority$1) { // The priority level does not match. break; } } } } else if (deadline !== null) { // Flush asynchronous work until the deadline expires. while (nextUnitOfWork !== null && !deadlineHasExpired) { if (deadline.timeRemaining() > timeHeuristicForUnitOfWork) { nextUnitOfWork = performUnitOfWork(nextUnitOfWork); // In a deferred work batch, iff nextUnitOfWork returns null, we just // completed a root and a pendingCommit exists. Logically, we could // omit either of the checks in the following condition, but we need // both to satisfy Flow. if (nextUnitOfWork === null) { !(pendingCommit !== null) ? invariant(false, 'Should have a pending commit. This error is likely caused by a bug in React. Please file an issue.') : void 0; // We just completed a root. If we have time, commit it now. // Otherwise, we'll commit it in the next frame. if (deadline.timeRemaining() > timeHeuristicForUnitOfWork) { priorityContext = TaskPriority$1; commitAllWork(pendingCommit); priorityContext = nextPriorityLevel; // Clear any errors that were scheduled during the commit phase. handleCommitPhaseErrors(); // The priority level may have changed. Check again. if (nextPriorityLevel === NoWork$2 || nextPriorityLevel > minPriorityLevel || nextPriorityLevel < HighPriority) { // The priority level does not match. break; } } else { deadlineHasExpired = true; } } } else { deadlineHasExpired = true; } } } // There might be work left. Depending on the priority, we should // either perform it now or schedule a callback to perform it later. switch (nextPriorityLevel) { case SynchronousPriority$1: case TaskPriority$1: // We have remaining synchronous or task work. Keep performing it, // regardless of whether we're inside a callback. if (nextPriorityLevel <= minPriorityLevel) { continue loop; } break loop; case HighPriority: case LowPriority: case OffscreenPriority: // We have remaining async work. if (deadline === null) { // We're not inside a callback. Exit and perform the work during // the next callback. break loop; } // We are inside a callback. if (!deadlineHasExpired && nextPriorityLevel <= minPriorityLevel) { // We still have time. Keep working. continue loop; } // We've run out of time. Exit. break loop; case NoWork$2: // No work left. We can exit. break loop; default: invariant(false, 'Switch statement should be exhuastive. This error is likely caused by a bug in React. Please file an issue.'); } } while (true); } function performWorkCatchBlock(failedWork, boundary, minPriorityLevel, deadline) { // We're going to restart the error boundary that captured the error. // Conceptually, we're unwinding the stack. We need to unwind the // context stack, too. unwindContexts(failedWork, boundary); // Restart the error boundary using a forked version of // performUnitOfWork that deletes the boundary's children. The entire // failed subree will be unmounted. During the commit phase, a special // lifecycle method is called on the error boundary, which triggers // a re-render. nextUnitOfWork = performFailedUnitOfWork(boundary); // Continue working. workLoop(minPriorityLevel, deadline); } function performWork(minPriorityLevel, deadline) { { startWorkLoopTimer(); } !!isPerformingWork ? invariant(false, 'performWork was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0; isPerformingWork = true; // The priority context changes during the render phase. We'll need to // reset it at the end. var previousPriorityContext = priorityContext; var didError = false; var error = null; { invokeGuardedCallback$1(null, workLoop, null, minPriorityLevel, deadline); if (hasCaughtError()) { didError = true; error = clearCaughtError(); } } // An error was thrown during the render phase. while (didError) { if (didFatal) { // This was a fatal error. Don't attempt to recover from it. firstUncaughtError = error; break; } var failedWork = nextUnitOfWork; if (failedWork === null) { // An error was thrown but there's no current unit of work. This can // happen during the commit phase if there's a bug in the renderer. didFatal = true; continue; } // "Capture" the error by finding the nearest boundary. If there is no // error boundary, we use the root. var boundary = captureError(failedWork, error); !(boundary !== null) ? invariant(false, 'Should have found an error boundary. This error is likely caused by a bug in React. Please file an issue.') : void 0; if (didFatal) { // The error we just captured was a fatal error. This happens // when the error propagates to the root more than once. continue; } didError = false; error = null; { invokeGuardedCallback$1(null, performWorkCatchBlock, null, failedWork, boundary, minPriorityLevel, deadline); if (hasCaughtError()) { didError = true; error = clearCaughtError(); continue; } } // We're finished working. Exit the error loop. break; } // Reset the priority context to its previous value. priorityContext = previousPriorityContext; // If we're inside a callback, set this to false, since we just flushed it. if (deadline !== null) { isCallbackScheduled = false; } // If there's remaining async work, make sure we schedule another callback. if (nextPriorityLevel > TaskPriority$1 && !isCallbackScheduled) { scheduleDeferredCallback(performDeferredWork); isCallbackScheduled = true; } var errorToThrow = firstUncaughtError; // We're done performing work. Time to clean up. isPerformingWork = false; deadlineHasExpired = false; didFatal = false; firstUncaughtError = null; capturedErrors = null; failedBoundaries = null; nextRenderedTree = null; nestedUpdateCount = 0; { stopWorkLoopTimer(); } // It's safe to throw any unhandled errors. if (errorToThrow !== null) { throw errorToThrow; } } // Returns the boundary that captured the error, or null if the error is ignored function captureError(failedWork, error) { // It is no longer valid because we exited the user code. ReactCurrentOwner$1.current = null; { ReactDebugCurrentFiber$3.resetCurrentFiber(); } // Search for the nearest error boundary. var boundary = null; // Passed to logCapturedError() var errorBoundaryFound = false; var willRetry = false; var errorBoundaryName = null; // Host containers are a special case. If the failed work itself is a host // container, then it acts as its own boundary. In all other cases, we // ignore the work itself and only search through the parents. if (failedWork.tag === HostRoot$6) { boundary = failedWork; if (isFailedBoundary(failedWork)) { // If this root already failed, there must have been an error when // attempting to unmount it. This is a worst-case scenario and // should only be possible if there's a bug in the renderer. didFatal = true; } } else { var node = failedWork['return']; while (node !== null && boundary === null) { if (node.tag === ClassComponent$5) { var instance = node.stateNode; if (typeof instance.componentDidCatch === 'function') { errorBoundaryFound = true; errorBoundaryName = getComponentName_1(node); // Found an error boundary! boundary = node; willRetry = true; } } else if (node.tag === HostRoot$6) { // Treat the root like a no-op error boundary boundary = node; } if (isFailedBoundary(node)) { // This boundary is already in a failed state. // If we're currently unmounting, that means this error was // thrown while unmounting a failed subtree. We should ignore // the error. if (isUnmounting) { return null; } // If we're in the commit phase, we should check to see if // this boundary already captured an error during this commit. // This case exists because multiple errors can be thrown during // a single commit without interruption. if (commitPhaseBoundaries !== null && (commitPhaseBoundaries.has(node) || node.alternate !== null && commitPhaseBoundaries.has(node.alternate))) { // If so, we should ignore this error. return null; } // The error should propagate to the next boundary -— we keep looking. boundary = null; willRetry = false; } node = node['return']; } } if (boundary !== null) { // Add to the collection of failed boundaries. This lets us know that // subsequent errors in this subtree should propagate to the next boundary. if (failedBoundaries === null) { failedBoundaries = new Set(); } failedBoundaries.add(boundary); // This method is unsafe outside of the begin and complete phases. // We might be in the commit phase when an error is captured. // The risk is that the return path from this Fiber may not be accurate. // That risk is acceptable given the benefit of providing users more context. var _componentStack = getStackAddendumByWorkInProgressFiber$2(failedWork); var _componentName = getComponentName_1(failedWork); // Add to the collection of captured errors. This is stored as a global // map of errors and their component stack location keyed by the boundaries // that capture them. We mostly use this Map as a Set; it's a Map only to // avoid adding a field to Fiber to store the error. if (capturedErrors === null) { capturedErrors = new Map(); } var capturedError = { componentName: _componentName, componentStack: _componentStack, error: error, errorBoundary: errorBoundaryFound ? boundary.stateNode : null, errorBoundaryFound: errorBoundaryFound, errorBoundaryName: errorBoundaryName, willRetry: willRetry }; capturedErrors.set(boundary, capturedError); try { logCapturedError(capturedError); } catch (e) { // Prevent cycle if logCapturedError() throws. // A cycle may still occur if logCapturedError renders a component that throws. console.error(e); } // If we're in the commit phase, defer scheduling an update on the // boundary until after the commit is complete if (isCommitting) { if (commitPhaseBoundaries === null) { commitPhaseBoundaries = new Set(); } commitPhaseBoundaries.add(boundary); } else { // Otherwise, schedule an update now. // TODO: Is this actually necessary during the render phase? Is it // possible to unwind and continue rendering at the same priority, // without corrupting internal state? scheduleErrorRecovery(boundary); } return boundary; } else if (firstUncaughtError === null) { // If no boundary is found, we'll need to throw the error firstUncaughtError = error; } return null; } function hasCapturedError(fiber) { // TODO: capturedErrors should store the boundary instance, to avoid needing // to check the alternate. return capturedErrors !== null && (capturedErrors.has(fiber) || fiber.alternate !== null && capturedErrors.has(fiber.alternate)); } function isFailedBoundary(fiber) { // TODO: failedBoundaries should store the boundary instance, to avoid // needing to check the alternate. return failedBoundaries !== null && (failedBoundaries.has(fiber) || fiber.alternate !== null && failedBoundaries.has(fiber.alternate)); } function commitErrorHandling(effectfulFiber) { var capturedError = void 0; if (capturedErrors !== null) { capturedError = capturedErrors.get(effectfulFiber); capturedErrors['delete'](effectfulFiber); if (capturedError == null) { if (effectfulFiber.alternate !== null) { effectfulFiber = effectfulFiber.alternate; capturedError = capturedErrors.get(effectfulFiber); capturedErrors['delete'](effectfulFiber); } } } !(capturedError != null) ? invariant(false, 'No error for given unit of work. This error is likely caused by a bug in React. Please file an issue.') : void 0; switch (effectfulFiber.tag) { case ClassComponent$5: var instance = effectfulFiber.stateNode; var info = { componentStack: capturedError.componentStack }; // Allow the boundary to handle the error, usually by scheduling // an update to itself instance.componentDidCatch(capturedError.error, info); return; case HostRoot$6: if (firstUncaughtError === null) { // If this is the host container, we treat it as a no-op error // boundary. We'll throw the first uncaught error once it's safe to // do so, at the end of the batch. firstUncaughtError = capturedError.error; } return; default: invariant(false, 'Invalid type of work. This error is likely caused by a bug in React. Please file an issue.'); } } function unwindContexts(from, to) { var node = from; while (node !== null) { switch (node.tag) { case ClassComponent$5: popContextProvider$1(node); break; case HostComponent$6: popHostContext(node); break; case HostRoot$6: popHostContainer(node); break; case HostPortal$3: popHostContainer(node); break; } if (node === to || node.alternate === to) { { stopFailedWorkTimer(node); } break; } else { stopWorkTimer(node); } node = node['return']; } } function scheduleRoot(root, priorityLevel) { if (priorityLevel === NoWork$2) { return; } if (!root.isScheduled) { root.isScheduled = true; if (lastScheduledRoot) { // Schedule ourselves to the end. lastScheduledRoot.nextScheduledRoot = root; lastScheduledRoot = root; } else { // We're the only work scheduled. nextScheduledRoot = root; lastScheduledRoot = root; } } } function scheduleUpdate(fiber, priorityLevel) { return scheduleUpdateImpl(fiber, priorityLevel, false); } function scheduleUpdateImpl(fiber, priorityLevel, isErrorRecovery) { { recordScheduleUpdate(); } if (nestedUpdateCount > NESTED_UPDATE_LIMIT) { didFatal = true; invariant(false, 'Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.'); } if (!isPerformingWork && priorityLevel <= nextPriorityLevel) { // We must reset the current unit of work pointer so that we restart the // search from the root during the next tick, in case there is now higher // priority work somewhere earlier than before. nextUnitOfWork = null; } { if (!isErrorRecovery && fiber.tag === ClassComponent$5) { var instance = fiber.stateNode; warnAboutInvalidUpdates(instance); } } var node = fiber; var shouldContinue = true; while (node !== null && shouldContinue) { // Walk the parent path to the root and update each node's priority. Once // we reach a node whose priority matches (and whose alternate's priority // matches) we can exit safely knowing that the rest of the path is correct. shouldContinue = false; if (node.pendingWorkPriority === NoWork$2 || node.pendingWorkPriority > priorityLevel) { // Priority did not match. Update and keep going. shouldContinue = true; node.pendingWorkPriority = priorityLevel; } if (node.alternate !== null) { if (node.alternate.pendingWorkPriority === NoWork$2 || node.alternate.pendingWorkPriority > priorityLevel) { // Priority did not match. Update and keep going. shouldContinue = true; node.alternate.pendingWorkPriority = priorityLevel; } } if (node['return'] === null) { if (node.tag === HostRoot$6) { var root = node.stateNode; scheduleRoot(root, priorityLevel); if (!isPerformingWork) { switch (priorityLevel) { case SynchronousPriority$1: // Perform this update now. if (isUnbatchingUpdates) { // We're inside unbatchedUpdates, which is inside either // batchedUpdates or a lifecycle. We should only flush // synchronous work, not task work. performWork(SynchronousPriority$1, null); } else { // Flush both synchronous and task work. performWork(TaskPriority$1, null); } break; case TaskPriority$1: !isBatchingUpdates ? invariant(false, 'Task updates can only be scheduled as a nested update or inside batchedUpdates.') : void 0; break; default: // Schedule a callback to perform the work later. if (!isCallbackScheduled) { scheduleDeferredCallback(performDeferredWork); isCallbackScheduled = true; } } } } else { { if (!isErrorRecovery && fiber.tag === ClassComponent$5) { warnAboutUpdateOnUnmounted(fiber.stateNode); } } return; } } node = node['return']; } } function getPriorityContext(fiber, forceAsync) { var priorityLevel = priorityContext; if (priorityLevel === NoWork$2) { if (!useSyncScheduling || fiber.internalContextTag & AsyncUpdates || forceAsync) { priorityLevel = LowPriority; } else { priorityLevel = SynchronousPriority$1; } } // If we're in a batch, or if we're already performing work, downgrade sync // priority to task priority if (priorityLevel === SynchronousPriority$1 && (isPerformingWork || isBatchingUpdates)) { return TaskPriority$1; } return priorityLevel; } function scheduleErrorRecovery(fiber) { scheduleUpdateImpl(fiber, TaskPriority$1, true); } function batchedUpdates(fn, a) { var previousIsBatchingUpdates = isBatchingUpdates; isBatchingUpdates = true; try { return fn(a); } finally { isBatchingUpdates = previousIsBatchingUpdates; // If we're not already inside a batch, we need to flush any task work // that was created by the user-provided function. if (!isPerformingWork && !isBatchingUpdates) { performWork(TaskPriority$1, null); } } } function unbatchedUpdates(fn) { var previousIsUnbatchingUpdates = isUnbatchingUpdates; var previousIsBatchingUpdates = isBatchingUpdates; // This is only true if we're nested inside batchedUpdates. isUnbatchingUpdates = isBatchingUpdates; isBatchingUpdates = false; try { return fn(); } finally { isBatchingUpdates = previousIsBatchingUpdates; isUnbatchingUpdates = previousIsUnbatchingUpdates; } } function flushSync(batch) { var previousIsBatchingUpdates = isBatchingUpdates; var previousPriorityContext = priorityContext; isBatchingUpdates = true; priorityContext = SynchronousPriority$1; try { return batch(); } finally { isBatchingUpdates = previousIsBatchingUpdates; priorityContext = previousPriorityContext; !!isPerformingWork ? invariant(false, 'flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.') : void 0; performWork(TaskPriority$1, null); } } function deferredUpdates(fn) { var previousPriorityContext = priorityContext; priorityContext = LowPriority; try { return fn(); } finally { priorityContext = previousPriorityContext; } } return { scheduleUpdate: scheduleUpdate, getPriorityContext: getPriorityContext, batchedUpdates: batchedUpdates, unbatchedUpdates: unbatchedUpdates, flushSync: flushSync, deferredUpdates: deferredUpdates }; }; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule getContextForSubtree * */ var getContextFiber = function (arg) { invariant(false, 'Missing injection for fiber getContextForSubtree'); }; function getContextForSubtree(parentComponent) { if (!parentComponent) { return emptyObject; } var instance = ReactInstanceMap_1.get(parentComponent); if (typeof instance.tag === 'number') { return getContextFiber(instance); } else { return instance._processChildContext(instance._context); } } getContextForSubtree._injectFiber = function (fn) { getContextFiber = fn; }; var getContextForSubtree_1 = getContextForSubtree; var addTopLevelUpdate = ReactFiberUpdateQueue.addTopLevelUpdate; var findCurrentUnmaskedContext = ReactFiberContext.findCurrentUnmaskedContext; var isContextProvider = ReactFiberContext.isContextProvider; var processChildContext = ReactFiberContext.processChildContext; var createFiberRoot = ReactFiberRoot.createFiberRoot; var HostComponent$3 = ReactTypeOfWork.HostComponent; { var warning$18 = require$$0; var ReactFiberInstrumentation = ReactFiberInstrumentation_1; var ReactDebugCurrentFiber$1 = ReactDebugCurrentFiber_1; var getComponentName$4 = getComponentName_1; } var findCurrentHostFiber$1 = ReactFiberTreeReflection.findCurrentHostFiber; var findCurrentHostFiberWithNoPortals$1 = ReactFiberTreeReflection.findCurrentHostFiberWithNoPortals; getContextForSubtree_1._injectFiber(function (fiber) { var parentContext = findCurrentUnmaskedContext(fiber); return isContextProvider(fiber) ? processChildContext(fiber, parentContext, false) : parentContext; }); var ReactFiberReconciler = function (config) { var getPublicInstance = config.getPublicInstance; var _ReactFiberScheduler = ReactFiberScheduler(config), scheduleUpdate = _ReactFiberScheduler.scheduleUpdate, getPriorityContext = _ReactFiberScheduler.getPriorityContext, batchedUpdates = _ReactFiberScheduler.batchedUpdates, unbatchedUpdates = _ReactFiberScheduler.unbatchedUpdates, flushSync = _ReactFiberScheduler.flushSync, deferredUpdates = _ReactFiberScheduler.deferredUpdates; function scheduleTopLevelUpdate(current, element, callback) { { if (ReactDebugCurrentFiber$1.phase === 'render' && ReactDebugCurrentFiber$1.current !== null) { warning$18(false, 'Render methods should be a pure function of props and state; ' + 'triggering nested component updates from render is not allowed. ' + 'If necessary, trigger nested updates in componentDidUpdate.\n\n' + 'Check the render method of %s.', getComponentName$4(ReactDebugCurrentFiber$1.current) || 'Unknown'); } } // Check if the top-level element is an async wrapper component. If so, treat // updates to the root as async. This is a bit weird but lets us avoid a separate // `renderAsync` API. var forceAsync = ReactFeatureFlags_1.enableAsyncSubtreeAPI && element != null && element.type != null && element.type.prototype != null && element.type.prototype.unstable_isAsyncReactComponent === true; var priorityLevel = getPriorityContext(current, forceAsync); var nextState = { element: element }; callback = callback === undefined ? null : callback; { warning$18(callback === null || typeof callback === 'function', 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback); } addTopLevelUpdate(current, nextState, callback, priorityLevel); scheduleUpdate(current, priorityLevel); } return { createContainer: function (containerInfo) { return createFiberRoot(containerInfo); }, updateContainer: function (element, container, parentComponent, callback) { // TODO: If this is a nested container, this won't be the root. var current = container.current; { if (ReactFiberInstrumentation.debugTool) { if (current.alternate === null) { ReactFiberInstrumentation.debugTool.onMountContainer(container); } else if (element === null) { ReactFiberInstrumentation.debugTool.onUnmountContainer(container); } else { ReactFiberInstrumentation.debugTool.onUpdateContainer(container); } } } var context = getContextForSubtree_1(parentComponent); if (container.context === null) { container.context = context; } else { container.pendingContext = context; } scheduleTopLevelUpdate(current, element, callback); }, batchedUpdates: batchedUpdates, unbatchedUpdates: unbatchedUpdates, deferredUpdates: deferredUpdates, flushSync: flushSync, getPublicRootInstance: function (container) { var containerFiber = container.current; if (!containerFiber.child) { return null; } switch (containerFiber.child.tag) { case HostComponent$3: return getPublicInstance(containerFiber.child.stateNode); default: return containerFiber.child.stateNode; } }, findHostInstance: function (fiber) { var hostFiber = findCurrentHostFiber$1(fiber); if (hostFiber === null) { return null; } return hostFiber.stateNode; }, findHostInstanceWithNoPortals: function (fiber) { var hostFiber = findCurrentHostFiberWithNoPortals$1(fiber); if (hostFiber === null) { return null; } return hostFiber.stateNode; } }; }; var TEXT_NODE$3 = HTMLNodeType_1.TEXT_NODE; /** * Given any node return the first leaf node without children. * * @param {DOMElement|DOMTextNode} node * @return {DOMElement|DOMTextNode} */ function getLeafNode(node) { while (node && node.firstChild) { node = node.firstChild; } return node; } /** * Get the next sibling within a container. This will walk up the * DOM if a node's siblings have been exhausted. * * @param {DOMElement|DOMTextNode} node * @return {?DOMElement|DOMTextNode} */ function getSiblingNode(node) { while (node) { if (node.nextSibling) { return node.nextSibling; } node = node.parentNode; } } /** * Get object describing the nodes which contain characters at offset. * * @param {DOMElement|DOMTextNode} root * @param {number} offset * @return {?object} */ function getNodeForCharacterOffset(root, offset) { var node = getLeafNode(root); var nodeStart = 0; var nodeEnd = 0; while (node) { if (node.nodeType === TEXT_NODE$3) { nodeEnd = nodeStart + node.textContent.length; if (nodeStart <= offset && nodeEnd >= offset) { return { node: node, offset: offset - nodeStart }; } nodeStart = nodeEnd; } node = getLeafNode(getSiblingNode(node)); } } var getNodeForCharacterOffset_1 = getNodeForCharacterOffset; var contentKey = null; /** * Gets the key used to access text content on a DOM node. * * @return {?string} Key used to access text content. * @internal */ function getTextContentAccessor() { if (!contentKey && ExecutionEnvironment.canUseDOM) { // Prefer textContent to innerText because many browsers support both but // SVG <text> elements don't support innerText even when <div> does. contentKey = 'textContent' in document.documentElement ? 'textContent' : 'innerText'; } return contentKey; } var getTextContentAccessor_1 = getTextContentAccessor; /** * While `isCollapsed` is available on the Selection object and `collapsed` * is available on the Range object, IE11 sometimes gets them wrong. * If the anchor/focus nodes and offsets are the same, the range is collapsed. */ function isCollapsed(anchorNode, anchorOffset, focusNode$$1, focusOffset) { return anchorNode === focusNode$$1 && anchorOffset === focusOffset; } /** * @param {DOMElement} node * @return {?object} */ function getModernOffsets(node) { var selection = window.getSelection && window.getSelection(); if (!selection || selection.rangeCount === 0) { return null; } var anchorNode = selection.anchorNode; var anchorOffset = selection.anchorOffset; var focusNode$$1 = selection.focusNode; var focusOffset = selection.focusOffset; var currentRange = selection.getRangeAt(0); // In Firefox, range.startContainer and range.endContainer can be "anonymous // divs", e.g. the up/down buttons on an <input type="number">. Anonymous // divs do not seem to expose properties, triggering a "Permission denied // error" if any of its properties are accessed. The only seemingly possible // way to avoid erroring is to access a property that typically works for // non-anonymous divs and catch any error that may otherwise arise. See // https://bugzilla.mozilla.org/show_bug.cgi?id=208427 try { /* eslint-disable no-unused-expressions */ currentRange.startContainer.nodeType; currentRange.endContainer.nodeType; /* eslint-enable no-unused-expressions */ } catch (e) { return null; } // If the node and offset values are the same, the selection is collapsed. // `Selection.isCollapsed` is available natively, but IE sometimes gets // this value wrong. var isSelectionCollapsed = isCollapsed(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset); var rangeLength = isSelectionCollapsed ? 0 : currentRange.toString().length; var tempRange = currentRange.cloneRange(); tempRange.selectNodeContents(node); tempRange.setEnd(currentRange.startContainer, currentRange.startOffset); var isTempRangeCollapsed = isCollapsed(tempRange.startContainer, tempRange.startOffset, tempRange.endContainer, tempRange.endOffset); var start = isTempRangeCollapsed ? 0 : tempRange.toString().length; var end = start + rangeLength; // Detect whether the selection is backward. var detectionRange = document.createRange(); detectionRange.setStart(anchorNode, anchorOffset); detectionRange.setEnd(focusNode$$1, focusOffset); var isBackward = detectionRange.collapsed; return { start: isBackward ? end : start, end: isBackward ? start : end }; } /** * In modern non-IE browsers, we can support both forward and backward * selections. * * Note: IE10+ supports the Selection object, but it does not support * the `extend` method, which means that even in modern IE, it's not possible * to programmatically create a backward selection. Thus, for all IE * versions, we use the old IE API to create our selections. * * @param {DOMElement|DOMTextNode} node * @param {object} offsets */ function setModernOffsets(node, offsets) { if (!window.getSelection) { return; } var selection = window.getSelection(); var length = node[getTextContentAccessor_1()].length; var start = Math.min(offsets.start, length); var end = offsets.end === undefined ? start : Math.min(offsets.end, length); // IE 11 uses modern selection, but doesn't support the extend method. // Flip backward selections, so we can set with a single range. if (!selection.extend && start > end) { var temp = end; end = start; start = temp; } var startMarker = getNodeForCharacterOffset_1(node, start); var endMarker = getNodeForCharacterOffset_1(node, end); if (startMarker && endMarker) { var range = document.createRange(); range.setStart(startMarker.node, startMarker.offset); selection.removeAllRanges(); if (start > end) { selection.addRange(range); selection.extend(endMarker.node, endMarker.offset); } else { range.setEnd(endMarker.node, endMarker.offset); selection.addRange(range); } } } var ReactDOMSelection = { /** * @param {DOMElement} node */ getOffsets: getModernOffsets, /** * @param {DOMElement|DOMTextNode} node * @param {object} offsets */ setOffsets: setModernOffsets }; var ReactDOMSelection_1 = ReactDOMSelection; var ELEMENT_NODE$2 = HTMLNodeType_1.ELEMENT_NODE; function isInDocument(node) { return containsNode(document.documentElement, node); } /** * @ReactInputSelection: React input selection module. Based on Selection.js, * but modified to be suitable for react and has a couple of bug fixes (doesn't * assume buttons have range selections allowed). * Input selection module for React. */ var ReactInputSelection = { hasSelectionCapabilities: function (elem) { var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); return nodeName && (nodeName === 'input' && elem.type === 'text' || nodeName === 'textarea' || elem.contentEditable === 'true'); }, getSelectionInformation: function () { var focusedElem = getActiveElement(); return { focusedElem: focusedElem, selectionRange: ReactInputSelection.hasSelectionCapabilities(focusedElem) ? ReactInputSelection.getSelection(focusedElem) : null }; }, /** * @restoreSelection: If any selection information was potentially lost, * restore it. This is useful when performing operations that could remove dom * nodes and place them back in, resulting in focus being lost. */ restoreSelection: function (priorSelectionInformation) { var curFocusedElem = getActiveElement(); var priorFocusedElem = priorSelectionInformation.focusedElem; var priorSelectionRange = priorSelectionInformation.selectionRange; if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) { if (ReactInputSelection.hasSelectionCapabilities(priorFocusedElem)) { ReactInputSelection.setSelection(priorFocusedElem, priorSelectionRange); } // Focusing a node can change the scroll position, which is undesirable var ancestors = []; var ancestor = priorFocusedElem; while (ancestor = ancestor.parentNode) { if (ancestor.nodeType === ELEMENT_NODE$2) { ancestors.push({ element: ancestor, left: ancestor.scrollLeft, top: ancestor.scrollTop }); } } focusNode(priorFocusedElem); for (var i = 0; i < ancestors.length; i++) { var info = ancestors[i]; info.element.scrollLeft = info.left; info.element.scrollTop = info.top; } } }, /** * @getSelection: Gets the selection bounds of a focused textarea, input or * contentEditable node. * -@input: Look up selection bounds of this input * -@return {start: selectionStart, end: selectionEnd} */ getSelection: function (input) { var selection; if ('selectionStart' in input) { // Modern browser with input or textarea. selection = { start: input.selectionStart, end: input.selectionEnd }; } else { // Content editable or old IE textarea. selection = ReactDOMSelection_1.getOffsets(input); } return selection || { start: 0, end: 0 }; }, /** * @setSelection: Sets the selection bounds of a textarea or input and focuses * the input. * -@input Set selection bounds of this input or textarea * -@offsets Object of same form that is returned from get* */ setSelection: function (input, offsets) { var start = offsets.start; var end = offsets.end; if (end === undefined) { end = start; } if ('selectionStart' in input) { input.selectionStart = start; input.selectionEnd = Math.min(end, input.value.length); } else { ReactDOMSelection_1.setOffsets(input, offsets); } } }; var ReactInputSelection_1 = ReactInputSelection; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule ReactVersion */ var ReactVersion = '16.0.0'; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule findDOMNode * */ var ELEMENT_NODE$3 = HTMLNodeType_1.ELEMENT_NODE; var ReactCurrentOwner$3 = ReactGlobalSharedState_1.ReactCurrentOwner; { var warning$27 = require$$0; } var findFiber = function (arg) { invariant(false, 'Missing injection for fiber findDOMNode'); }; var findStack = function (arg) { invariant(false, 'Missing injection for stack findDOMNode'); }; var findDOMNode = function (componentOrElement) { { var owner = ReactCurrentOwner$3.current; if (owner !== null) { var isFiber = typeof owner.tag === 'number'; var warnedAboutRefsInRender = isFiber ? owner.stateNode._warnedAboutRefsInRender : owner._warnedAboutRefsInRender; warning$27(warnedAboutRefsInRender, '%s is accessing findDOMNode inside its render(). ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName_1(owner) || 'A component'); if (isFiber) { owner.stateNode._warnedAboutRefsInRender = true; } else { owner._warnedAboutRefsInRender = true; } } } if (componentOrElement == null) { return null; } if (componentOrElement.nodeType === ELEMENT_NODE$3) { return componentOrElement; } var inst = ReactInstanceMap_1.get(componentOrElement); if (inst) { if (typeof inst.tag === 'number') { return findFiber(inst); } else { return findStack(inst); } } if (typeof componentOrElement.render === 'function') { invariant(false, 'Unable to find node on an unmounted component.'); } else { invariant(false, 'Element appears to be neither ReactComponent nor DOMNode. Keys: %s', Object.keys(componentOrElement)); } }; findDOMNode._injectFiber = function (fn) { findFiber = fn; }; findDOMNode._injectStack = function (fn) { findStack = fn; }; var findDOMNode_1 = findDOMNode; /** * Copyright (c) 2014-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule lowPriorityWarning */ /** * Forked from fbjs/warning: * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js * * Only change is we use console.warn instead of console.error, * and do nothing when 'console' is not supported. * This really simplifies the code. * --- * Similar to invariant but only logs a warning if the condition is not met. * This can be used to log issues in development environments in critical * paths. Removing the logging code for production environments will keep the * same logic and follow the same code paths. */ var lowPriorityWarning$1 = function () {}; { var printWarning = function (format) { for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } var argIndex = 0; var message = 'Warning: ' + format.replace(/%s/g, function () { return args[argIndex++]; }); if (typeof console !== 'undefined') { console.warn(message); } try { // --- Welcome to debugging React --- // This error was thrown as a convenience so that you can use this stack // to find the callsite that caused this warning to fire. throw new Error(message); } catch (x) {} }; lowPriorityWarning$1 = function (condition, format) { if (format === undefined) { throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument'); } if (!condition) { for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { args[_key2 - 2] = arguments[_key2]; } printWarning.apply(undefined, [format].concat(args)); } }; } var lowPriorityWarning_1 = lowPriorityWarning$1; var validateDOMNesting$1 = emptyFunction; { var warning$28 = require$$0; var _require$13 = ReactDebugCurrentFiber_1, getCurrentFiberStackAddendum$6 = _require$13.getCurrentFiberStackAddendum; // This validation code was written based on the HTML5 parsing spec: // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope // // Note: this does not catch all invalid nesting, nor does it try to (as it's // not clear what practical benefit doing so provides); instead, we warn only // for cases where the parser will give a parse tree differing from what React // intended. For example, <b><div></div></b> is invalid but we don't warn // because it still parses correctly; we do warn for other cases like nested // <p> tags where the beginning of the second element implicitly closes the // first, causing a confusing mess. // https://html.spec.whatwg.org/multipage/syntax.html#special var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point // TODO: Distinguish by namespace here -- for <title>, including it here // errs on the side of fewer warnings 'foreignObject', 'desc', 'title']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope var buttonScopeTags = inScopeTags.concat(['button']); // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt']; var emptyAncestorInfo = { current: null, formTag: null, aTagInScope: null, buttonTagInScope: null, nobrTagInScope: null, pTagInButtonScope: null, listItemTagAutoclosing: null, dlItemTagAutoclosing: null }; var updatedAncestorInfo$1 = function (oldInfo, tag, instance) { var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo); var info = { tag: tag, instance: instance }; if (inScopeTags.indexOf(tag) !== -1) { ancestorInfo.aTagInScope = null; ancestorInfo.buttonTagInScope = null; ancestorInfo.nobrTagInScope = null; } if (buttonScopeTags.indexOf(tag) !== -1) { ancestorInfo.pTagInButtonScope = null; } // See rules for 'li', 'dd', 'dt' start tags in // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') { ancestorInfo.listItemTagAutoclosing = null; ancestorInfo.dlItemTagAutoclosing = null; } ancestorInfo.current = info; if (tag === 'form') { ancestorInfo.formTag = info; } if (tag === 'a') { ancestorInfo.aTagInScope = info; } if (tag === 'button') { ancestorInfo.buttonTagInScope = info; } if (tag === 'nobr') { ancestorInfo.nobrTagInScope = info; } if (tag === 'p') { ancestorInfo.pTagInButtonScope = info; } if (tag === 'li') { ancestorInfo.listItemTagAutoclosing = info; } if (tag === 'dd' || tag === 'dt') { ancestorInfo.dlItemTagAutoclosing = info; } return ancestorInfo; }; /** * Returns whether */ var isTagValidWithParent = function (tag, parentTag) { // First, let's check if we're in an unusual parsing mode... switch (parentTag) { // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect case 'select': return tag === 'option' || tag === 'optgroup' || tag === '#text'; case 'optgroup': return tag === 'option' || tag === '#text'; // Strictly speaking, seeing an <option> doesn't mean we're in a <select> // but case 'option': return tag === '#text'; // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption // No special behavior since these rules fall back to "in body" mode for // all except special table nodes which cause bad parsing behavior anyway. // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr case 'tr': return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template'; // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody case 'tbody': case 'thead': case 'tfoot': return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template'; // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup case 'colgroup': return tag === 'col' || tag === 'template'; // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable case 'table': return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template'; // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead case 'head': return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template'; // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element case 'html': return tag === 'head' || tag === 'body'; case '#document': return tag === 'html'; } // Probably in the "in body" parsing mode, so we outlaw only tag combos // where the parsing rules cause implicit opens or closes to be added. // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody switch (tag) { case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6'; case 'rp': case 'rt': return impliedEndTags.indexOf(parentTag) === -1; case 'body': case 'caption': case 'col': case 'colgroup': case 'frame': case 'head': case 'html': case 'tbody': case 'td': case 'tfoot': case 'th': case 'thead': case 'tr': // These tags are only valid with a few parents that have special child // parsing rules -- if we're down here, then none of those matched and // so we allow it only if we don't know what the parent is, as all other // cases are invalid. return parentTag == null; } return true; }; /** * Returns whether */ var findInvalidAncestorForTag = function (tag, ancestorInfo) { switch (tag) { case 'address': case 'article': case 'aside': case 'blockquote': case 'center': case 'details': case 'dialog': case 'dir': case 'div': case 'dl': case 'fieldset': case 'figcaption': case 'figure': case 'footer': case 'header': case 'hgroup': case 'main': case 'menu': case 'nav': case 'ol': case 'p': case 'section': case 'summary': case 'ul': case 'pre': case 'listing': case 'table': case 'hr': case 'xmp': case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': return ancestorInfo.pTagInButtonScope; case 'form': return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope; case 'li': return ancestorInfo.listItemTagAutoclosing; case 'dd': case 'dt': return ancestorInfo.dlItemTagAutoclosing; case 'button': return ancestorInfo.buttonTagInScope; case 'a': // Spec says something about storing a list of markers, but it sounds // equivalent to this check. return ancestorInfo.aTagInScope; case 'nobr': return ancestorInfo.nobrTagInScope; } return null; }; /** * Given a ReactCompositeComponent instance, return a list of its recursive * owners, starting at the root and ending with the instance itself. */ var findOwnerStack = function (instance) { if (!instance) { return []; } var stack = []; do { stack.push(instance); } while (instance = instance._currentElement._owner); stack.reverse(); return stack; }; var getOwnerInfo = function (childInstance, childTag, ancestorInstance, ancestorTag, isParent) { var childOwner = childInstance && childInstance._currentElement._owner; var ancestorOwner = ancestorInstance && ancestorInstance._currentElement._owner; var childOwners = findOwnerStack(childOwner); var ancestorOwners = findOwnerStack(ancestorOwner); var minStackLen = Math.min(childOwners.length, ancestorOwners.length); var i; var deepestCommon = -1; for (i = 0; i < minStackLen; i++) { if (childOwners[i] === ancestorOwners[i]) { deepestCommon = i; } else { break; } } var UNKNOWN = '(unknown)'; var childOwnerNames = childOwners.slice(deepestCommon + 1).map(function (inst) { return getComponentName_1(inst) || UNKNOWN; }); var ancestorOwnerNames = ancestorOwners.slice(deepestCommon + 1).map(function (inst) { return getComponentName_1(inst) || UNKNOWN; }); var ownerInfo = [].concat( // If the parent and child instances have a common owner ancestor, start // with that -- otherwise we just start with the parent's owners. deepestCommon !== -1 ? getComponentName_1(childOwners[deepestCommon]) || UNKNOWN : [], ancestorOwnerNames, ancestorTag, // If we're warning about an invalid (non-parent) ancestry, add '...' isParent ? [] : ['...'], childOwnerNames, childTag).join(' > '); return ownerInfo; }; var didWarn = {}; validateDOMNesting$1 = function (childTag, childText, childInstance, ancestorInfo) { ancestorInfo = ancestorInfo || emptyAncestorInfo; var parentInfo = ancestorInfo.current; var parentTag = parentInfo && parentInfo.tag; if (childText != null) { warning$28(childTag == null, 'validateDOMNesting: when childText is passed, childTag should be null'); childTag = '#text'; } var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo; var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo); var invalidParentOrAncestor = invalidParent || invalidAncestor; if (!invalidParentOrAncestor) { return; } var ancestorInstance = invalidParentOrAncestor.instance; var ancestorTag = invalidParentOrAncestor.tag; var addendum; if (childInstance != null) { addendum = ' See ' + getOwnerInfo(childInstance, childTag, ancestorInstance, ancestorTag, !!invalidParent) + '.'; } else { addendum = getCurrentFiberStackAddendum$6(); } var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum; if (didWarn[warnKey]) { return; } didWarn[warnKey] = true; var tagDisplayName = childTag; var whitespaceInfo = ''; if (childTag === '#text') { if (/\S/.test(childText)) { tagDisplayName = 'Text nodes'; } else { tagDisplayName = 'Whitespace text nodes'; whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.'; } } else { tagDisplayName = '<' + childTag + '>'; } if (invalidParent) { var info = ''; if (ancestorTag === 'table' && childTag === 'tr') { info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.'; } warning$28(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info, addendum); } else { warning$28(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.%s', tagDisplayName, ancestorTag, addendum); } }; validateDOMNesting$1.updatedAncestorInfo = updatedAncestorInfo$1; // For testing validateDOMNesting$1.isTagValidInContext = function (tag, ancestorInfo) { ancestorInfo = ancestorInfo || emptyAncestorInfo; var parentInfo = ancestorInfo.current; var parentTag = parentInfo && parentInfo.tag; return isTagValidWithParent(tag, parentTag) && !findInvalidAncestorForTag(tag, ancestorInfo); }; } var validateDOMNesting_1 = validateDOMNesting$1; var HostComponent$11 = ReactTypeOfWork.HostComponent; function getParent(inst) { if (inst._hostParent !== undefined) { return inst._hostParent; } if (typeof inst.tag === 'number') { do { inst = inst['return']; // TODO: If this is a HostRoot we might want to bail out. // That is depending on if we want nested subtrees (layers) to bubble // events to their parent. We could also go through parentNode on the // host node but that wouldn't work for React Native and doesn't let us // do the portal feature. } while (inst && inst.tag !== HostComponent$11); if (inst) { return inst; } } return null; } /** * Return the lowest common ancestor of A and B, or null if they are in * different trees. */ function getLowestCommonAncestor(instA, instB) { var depthA = 0; for (var tempA = instA; tempA; tempA = getParent(tempA)) { depthA++; } var depthB = 0; for (var tempB = instB; tempB; tempB = getParent(tempB)) { depthB++; } // If A is deeper, crawl up. while (depthA - depthB > 0) { instA = getParent(instA); depthA--; } // If B is deeper, crawl up. while (depthB - depthA > 0) { instB = getParent(instB); depthB--; } // Walk in lockstep until we find a match. var depth = depthA; while (depth--) { if (instA === instB || instA === instB.alternate) { return instA; } instA = getParent(instA); instB = getParent(instB); } return null; } /** * Return if A is an ancestor of B. */ function isAncestor(instA, instB) { while (instB) { if (instA === instB || instA === instB.alternate) { return true; } instB = getParent(instB); } return false; } /** * Return the parent instance of the passed-in instance. */ function getParentInstance(inst) { return getParent(inst); } /** * Simulates the traversal of a two-phase, capture/bubble event dispatch. */ function traverseTwoPhase(inst, fn, arg) { var path = []; while (inst) { path.push(inst); inst = getParent(inst); } var i; for (i = path.length; i-- > 0;) { fn(path[i], 'captured', arg); } for (i = 0; i < path.length; i++) { fn(path[i], 'bubbled', arg); } } /** * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that * should would receive a `mouseEnter` or `mouseLeave` event. * * Does not invoke the callback on the nearest common ancestor because nothing * "entered" or "left" that element. */ function traverseEnterLeave(from, to, fn, argFrom, argTo) { var common = from && to ? getLowestCommonAncestor(from, to) : null; var pathFrom = []; while (from && from !== common) { pathFrom.push(from); from = getParent(from); } var pathTo = []; while (to && to !== common) { pathTo.push(to); to = getParent(to); } var i; for (i = 0; i < pathFrom.length; i++) { fn(pathFrom[i], 'bubbled', argFrom); } for (i = pathTo.length; i-- > 0;) { fn(pathTo[i], 'captured', argTo); } } var ReactTreeTraversal = { isAncestor: isAncestor, getLowestCommonAncestor: getLowestCommonAncestor, getParentInstance: getParentInstance, traverseTwoPhase: traverseTwoPhase, traverseEnterLeave: traverseEnterLeave }; var getListener = EventPluginHub_1.getListener; { var warning$29 = require$$0; } /** * Some event types have a notion of different registration names for different * "phases" of propagation. This finds listeners by a given phase. */ function listenerAtPhase(inst, event, propagationPhase) { var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase]; return getListener(inst, registrationName); } /** * Tags a `SyntheticEvent` with dispatched listeners. Creating this function * here, allows us to not have to bind or create functions for each event. * Mutating the event's members allows us to not have to create a wrapping * "dispatch" object that pairs the event with the listener. */ function accumulateDirectionalDispatches(inst, phase, event) { { warning$29(inst, 'Dispatching inst must not be null'); } var listener = listenerAtPhase(inst, event, phase); if (listener) { event._dispatchListeners = accumulateInto_1(event._dispatchListeners, listener); event._dispatchInstances = accumulateInto_1(event._dispatchInstances, inst); } } /** * Collect dispatches (must be entirely collected before dispatching - see unit * tests). Lazily allocate the array to conserve memory. We must loop through * each event and perform the traversal for each one. We cannot perform a * single traversal for the entire collection of events because each event may * have a different target. */ function accumulateTwoPhaseDispatchesSingle(event) { if (event && event.dispatchConfig.phasedRegistrationNames) { ReactTreeTraversal.traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); } } /** * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. */ function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { if (event && event.dispatchConfig.phasedRegistrationNames) { var targetInst = event._targetInst; var parentInst = targetInst ? ReactTreeTraversal.getParentInstance(targetInst) : null; ReactTreeTraversal.traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event); } } /** * Accumulates without regard to direction, does not look for phased * registration names. Same as `accumulateDirectDispatchesSingle` but without * requiring that the `dispatchMarker` be the same as the dispatched ID. */ function accumulateDispatches(inst, ignoredDirection, event) { if (inst && event && event.dispatchConfig.registrationName) { var registrationName = event.dispatchConfig.registrationName; var listener = getListener(inst, registrationName); if (listener) { event._dispatchListeners = accumulateInto_1(event._dispatchListeners, listener); event._dispatchInstances = accumulateInto_1(event._dispatchInstances, inst); } } } /** * Accumulates dispatches on an `SyntheticEvent`, but only for the * `dispatchMarker`. * @param {SyntheticEvent} event */ function accumulateDirectDispatchesSingle(event) { if (event && event.dispatchConfig.registrationName) { accumulateDispatches(event._targetInst, null, event); } } function accumulateTwoPhaseDispatches(events) { forEachAccumulated_1(events, accumulateTwoPhaseDispatchesSingle); } function accumulateTwoPhaseDispatchesSkipTarget(events) { forEachAccumulated_1(events, accumulateTwoPhaseDispatchesSingleSkipTarget); } function accumulateEnterLeaveDispatches(leave, enter, from, to) { ReactTreeTraversal.traverseEnterLeave(from, to, accumulateDispatches, leave, enter); } function accumulateDirectDispatches(events) { forEachAccumulated_1(events, accumulateDirectDispatchesSingle); } /** * A small set of propagation patterns, each of which will accept a small amount * of information, and generate a set of "dispatch ready event objects" - which * are sets of events that have already been annotated with a set of dispatched * listener functions/ids. The API is designed this way to discourage these * propagation strategies from actually executing the dispatches, since we * always want to collect the entire set of dispatches before executing even a * single one. * * @constructor EventPropagators */ var EventPropagators = { accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches, accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget, accumulateDirectDispatches: accumulateDirectDispatches, accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches }; var EventPropagators_1 = EventPropagators; /** * This helper object stores information about text content of a target node, * allowing comparison of content before and after a given event. * * Identify the node where selection currently begins, then observe * both its text content and its current position in the DOM. Since the * browser may natively replace the target node during composition, we can * use its position to find its replacement. * * */ var compositionState = { _root: null, _startText: null, _fallbackText: null }; var FallbackCompositionState = { initialize: function (nativeEventTarget) { compositionState._root = nativeEventTarget; compositionState._startText = FallbackCompositionState.getText(); return true; }, reset: function () { compositionState._root = null; compositionState._startText = null; compositionState._fallbackText = null; }, getData: function () { if (compositionState._fallbackText) { return compositionState._fallbackText; } var start; var startValue = compositionState._startText; var startLength = startValue.length; var end; var endValue = FallbackCompositionState.getText(); var endLength = endValue.length; for (start = 0; start < startLength; start++) { if (startValue[start] !== endValue[start]) { break; } } var minEnd = startLength - start; for (end = 1; end <= minEnd; end++) { if (startValue[startLength - end] !== endValue[endLength - end]) { break; } } var sliceTail = end > 1 ? 1 - end : undefined; compositionState._fallbackText = endValue.slice(start, sliceTail); return compositionState._fallbackText; }, getText: function () { if ('value' in compositionState._root) { return compositionState._root.value; } return compositionState._root[getTextContentAccessor_1()]; } }; var FallbackCompositionState_1 = FallbackCompositionState; var didWarnForAddedNewProperty = false; var isProxySupported = typeof Proxy === 'function'; var EVENT_POOL_SIZE = 10; { var warning$30 = require$$0; } var shouldBeReleasedProperties = ['dispatchConfig', '_targetInst', 'nativeEvent', 'isDefaultPrevented', 'isPropagationStopped', '_dispatchListeners', '_dispatchInstances']; /** * @interface Event * @see http://www.w3.org/TR/DOM-Level-3-Events/ */ var EventInterface = { type: null, target: null, // currentTarget is set when dispatching; no use in copying it here currentTarget: emptyFunction.thatReturnsNull, eventPhase: null, bubbles: null, cancelable: null, timeStamp: function (event) { return event.timeStamp || Date.now(); }, defaultPrevented: null, isTrusted: null }; /** * Synthetic events are dispatched by event plugins, typically in response to a * top-level event delegation handler. * * These systems should generally use pooling to reduce the frequency of garbage * collection. The system should check `isPersistent` to determine whether the * event should be released into the pool after being dispatched. Users that * need a persisted event should invoke `persist`. * * Synthetic events (and subclasses) implement the DOM Level 3 Events API by * normalizing browser quirks. Subclasses do not necessarily have to implement a * DOM interface; custom application-specific events can also subclass this. * * @param {object} dispatchConfig Configuration used to dispatch this event. * @param {*} targetInst Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @param {DOMEventTarget} nativeEventTarget Target node. */ function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) { { // these have a getter/setter for warnings delete this.nativeEvent; delete this.preventDefault; delete this.stopPropagation; } this.dispatchConfig = dispatchConfig; this._targetInst = targetInst; this.nativeEvent = nativeEvent; var Interface = this.constructor.Interface; for (var propName in Interface) { if (!Interface.hasOwnProperty(propName)) { continue; } { delete this[propName]; // this has a getter/setter for warnings } var normalize = Interface[propName]; if (normalize) { this[propName] = normalize(nativeEvent); } else { if (propName === 'target') { this.target = nativeEventTarget; } else { this[propName] = nativeEvent[propName]; } } } var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false; if (defaultPrevented) { this.isDefaultPrevented = emptyFunction.thatReturnsTrue; } else { this.isDefaultPrevented = emptyFunction.thatReturnsFalse; } this.isPropagationStopped = emptyFunction.thatReturnsFalse; return this; } _assign(SyntheticEvent.prototype, { preventDefault: function () { this.defaultPrevented = true; var event = this.nativeEvent; if (!event) { return; } if (event.preventDefault) { event.preventDefault(); } else if (typeof event.returnValue !== 'unknown') { event.returnValue = false; } this.isDefaultPrevented = emptyFunction.thatReturnsTrue; }, stopPropagation: function () { var event = this.nativeEvent; if (!event) { return; } if (event.stopPropagation) { event.stopPropagation(); } else if (typeof event.cancelBubble !== 'unknown') { // The ChangeEventPlugin registers a "propertychange" event for // IE. This event does not support bubbling or cancelling, and // any references to cancelBubble throw "Member not found". A // typeof check of "unknown" circumvents this issue (and is also // IE specific). event.cancelBubble = true; } this.isPropagationStopped = emptyFunction.thatReturnsTrue; }, /** * We release all dispatched `SyntheticEvent`s after each event loop, adding * them back into the pool. This allows a way to hold onto a reference that * won't be added back into the pool. */ persist: function () { this.isPersistent = emptyFunction.thatReturnsTrue; }, /** * Checks if this event should be released back into the pool. * * @return {boolean} True if this should not be released, false otherwise. */ isPersistent: emptyFunction.thatReturnsFalse, /** * `PooledClass` looks for `destructor` on each instance it releases. */ destructor: function () { var Interface = this.constructor.Interface; for (var propName in Interface) { { Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName])); } } for (var i = 0; i < shouldBeReleasedProperties.length; i++) { this[shouldBeReleasedProperties[i]] = null; } { Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null)); Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', emptyFunction)); Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', emptyFunction)); } } }); SyntheticEvent.Interface = EventInterface; /** * Helper to reduce boilerplate when creating subclasses. * * @param {function} Class * @param {?object} Interface */ SyntheticEvent.augmentClass = function (Class, Interface) { var Super = this; var E = function () {}; E.prototype = Super.prototype; var prototype = new E(); _assign(prototype, Class.prototype); Class.prototype = prototype; Class.prototype.constructor = Class; Class.Interface = _assign({}, Super.Interface, Interface); Class.augmentClass = Super.augmentClass; addEventPoolingTo(Class); }; /** Proxying after everything set on SyntheticEvent * to resolve Proxy issue on some WebKit browsers * in which some Event properties are set to undefined (GH#10010) */ { if (isProxySupported) { /*eslint-disable no-func-assign */ SyntheticEvent = new Proxy(SyntheticEvent, { construct: function (target, args) { return this.apply(target, Object.create(target.prototype), args); }, apply: function (constructor, that, args) { return new Proxy(constructor.apply(that, args), { set: function (target, prop, value) { if (prop !== 'isPersistent' && !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1) { warning$30(didWarnForAddedNewProperty || target.isPersistent(), "This synthetic event is reused for performance reasons. If you're " + "seeing this, you're adding a new property in the synthetic event object. " + 'The property is never released. See ' + 'https://fb.me/react-event-pooling for more information.'); didWarnForAddedNewProperty = true; } target[prop] = value; return true; } }); } }); /*eslint-enable no-func-assign */ } } addEventPoolingTo(SyntheticEvent); var SyntheticEvent_1 = SyntheticEvent; /** * Helper to nullify syntheticEvent instance properties when destructing * * @param {String} propName * @param {?object} getVal * @return {object} defineProperty object */ function getPooledWarningPropertyDefinition(propName, getVal) { var isFunction = typeof getVal === 'function'; return { configurable: true, set: set, get: get }; function set(val) { var action = isFunction ? 'setting the method' : 'setting the property'; warn(action, 'This is effectively a no-op'); return val; } function get() { var action = isFunction ? 'accessing the method' : 'accessing the property'; var result = isFunction ? 'This is a no-op function' : 'This is set to null'; warn(action, result); return getVal; } function warn(action, result) { var warningCondition = false; warning$30(warningCondition, "This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result); } } function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { var EventConstructor = this; if (EventConstructor.eventPool.length) { var instance = EventConstructor.eventPool.pop(); EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst); return instance; } return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst); } function releasePooledEvent(event) { var EventConstructor = this; !(event instanceof EventConstructor) ? invariant(false, 'Trying to release an event instance into a pool of a different type.') : void 0; event.destructor(); if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { EventConstructor.eventPool.push(event); } } function addEventPoolingTo(EventConstructor) { EventConstructor.eventPool = []; EventConstructor.getPooled = getPooledEvent; EventConstructor.release = releasePooledEvent; } /** * @interface Event * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents */ var CompositionEventInterface = { data: null }; /** * @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */ function SyntheticCompositionEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { return SyntheticEvent_1.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticEvent_1.augmentClass(SyntheticCompositionEvent, CompositionEventInterface); var SyntheticCompositionEvent_1 = SyntheticCompositionEvent; /** * @interface Event * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105 * /#events-inputevents */ var InputEventInterface = { data: null }; /** * @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */ function SyntheticInputEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { return SyntheticEvent_1.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticEvent_1.augmentClass(SyntheticInputEvent, InputEventInterface); var SyntheticInputEvent_1 = SyntheticInputEvent; var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space var START_KEYCODE = 229; var canUseCompositionEvent = ExecutionEnvironment.canUseDOM && 'CompositionEvent' in window; var documentMode = null; if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) { documentMode = document.documentMode; } // Webkit offers a very useful `textInput` event that can be used to // directly represent `beforeInput`. The IE `textinput` event is not as // useful, so we don't use it. var canUseTextInputEvent = ExecutionEnvironment.canUseDOM && 'TextEvent' in window && !documentMode && !isPresto(); // In IE9+, we have access to composition events, but the data supplied // by the native compositionend event may be incorrect. Japanese ideographic // spaces, for instance (\u3000) are not recorded correctly. var useFallbackCompositionData = ExecutionEnvironment.canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11); /** * Opera <= 12 includes TextEvent in window, but does not fire * text input events. Rely on keypress instead. */ function isPresto() { var opera = window.opera; return typeof opera === 'object' && typeof opera.version === 'function' && parseInt(opera.version(), 10) <= 12; } var SPACEBAR_CODE = 32; var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); // Events and their corresponding property names. var eventTypes = { beforeInput: { phasedRegistrationNames: { bubbled: 'onBeforeInput', captured: 'onBeforeInputCapture' }, dependencies: ['topCompositionEnd', 'topKeyPress', 'topTextInput', 'topPaste'] }, compositionEnd: { phasedRegistrationNames: { bubbled: 'onCompositionEnd', captured: 'onCompositionEndCapture' }, dependencies: ['topBlur', 'topCompositionEnd', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown'] }, compositionStart: { phasedRegistrationNames: { bubbled: 'onCompositionStart', captured: 'onCompositionStartCapture' }, dependencies: ['topBlur', 'topCompositionStart', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown'] }, compositionUpdate: { phasedRegistrationNames: { bubbled: 'onCompositionUpdate', captured: 'onCompositionUpdateCapture' }, dependencies: ['topBlur', 'topCompositionUpdate', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown'] } }; // Track whether we've ever handled a keypress on the space key. var hasSpaceKeypress = false; /** * Return whether a native keypress event is assumed to be a command. * This is required because Firefox fires `keypress` events for key commands * (cut, copy, select-all, etc.) even though no character is inserted. */ function isKeypressCommand(nativeEvent) { return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && // ctrlKey && altKey is equivalent to AltGr, and is not a command. !(nativeEvent.ctrlKey && nativeEvent.altKey); } /** * Translate native top level events into event types. * * @param {string} topLevelType * @return {object} */ function getCompositionEventType(topLevelType) { switch (topLevelType) { case 'topCompositionStart': return eventTypes.compositionStart; case 'topCompositionEnd': return eventTypes.compositionEnd; case 'topCompositionUpdate': return eventTypes.compositionUpdate; } } /** * Does our fallback best-guess model think this event signifies that * composition has begun? * * @param {string} topLevelType * @param {object} nativeEvent * @return {boolean} */ function isFallbackCompositionStart(topLevelType, nativeEvent) { return topLevelType === 'topKeyDown' && nativeEvent.keyCode === START_KEYCODE; } /** * Does our fallback mode think that this event is the end of composition? * * @param {string} topLevelType * @param {object} nativeEvent * @return {boolean} */ function isFallbackCompositionEnd(topLevelType, nativeEvent) { switch (topLevelType) { case 'topKeyUp': // Command keys insert or clear IME input. return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1; case 'topKeyDown': // Expect IME keyCode on each keydown. If we get any other // code we must have exited earlier. return nativeEvent.keyCode !== START_KEYCODE; case 'topKeyPress': case 'topMouseDown': case 'topBlur': // Events are not possible without cancelling IME. return true; default: return false; } } /** * Google Input Tools provides composition data via a CustomEvent, * with the `data` property populated in the `detail` object. If this * is available on the event object, use it. If not, this is a plain * composition event and we have nothing special to extract. * * @param {object} nativeEvent * @return {?string} */ function getDataFromCustomEvent(nativeEvent) { var detail = nativeEvent.detail; if (typeof detail === 'object' && 'data' in detail) { return detail.data; } return null; } // Track the current IME composition status, if any. var isComposing = false; /** * @return {?object} A SyntheticCompositionEvent. */ function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) { var eventType; var fallbackData; if (canUseCompositionEvent) { eventType = getCompositionEventType(topLevelType); } else if (!isComposing) { if (isFallbackCompositionStart(topLevelType, nativeEvent)) { eventType = eventTypes.compositionStart; } } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) { eventType = eventTypes.compositionEnd; } if (!eventType) { return null; } if (useFallbackCompositionData) { // The current composition is stored statically and must not be // overwritten while composition continues. if (!isComposing && eventType === eventTypes.compositionStart) { isComposing = FallbackCompositionState_1.initialize(nativeEventTarget); } else if (eventType === eventTypes.compositionEnd) { if (isComposing) { fallbackData = FallbackCompositionState_1.getData(); } } } var event = SyntheticCompositionEvent_1.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget); if (fallbackData) { // Inject data generated from fallback path into the synthetic event. // This matches the property of native CompositionEventInterface. event.data = fallbackData; } else { var customData = getDataFromCustomEvent(nativeEvent); if (customData !== null) { event.data = customData; } } EventPropagators_1.accumulateTwoPhaseDispatches(event); return event; } /** * @param {TopLevelTypes} topLevelType Record from `BrowserEventConstants`. * @param {object} nativeEvent Native browser event. * @return {?string} The string corresponding to this `beforeInput` event. */ function getNativeBeforeInputChars(topLevelType, nativeEvent) { switch (topLevelType) { case 'topCompositionEnd': return getDataFromCustomEvent(nativeEvent); case 'topKeyPress': /** * If native `textInput` events are available, our goal is to make * use of them. However, there is a special case: the spacebar key. * In Webkit, preventing default on a spacebar `textInput` event * cancels character insertion, but it *also* causes the browser * to fall back to its default spacebar behavior of scrolling the * page. * * Tracking at: * https://code.google.com/p/chromium/issues/detail?id=355103 * * To avoid this issue, use the keypress event as if no `textInput` * event is available. */ var which = nativeEvent.which; if (which !== SPACEBAR_CODE) { return null; } hasSpaceKeypress = true; return SPACEBAR_CHAR; case 'topTextInput': // Record the characters to be added to the DOM. var chars = nativeEvent.data; // If it's a spacebar character, assume that we have already handled // it at the keypress level and bail immediately. Android Chrome // doesn't give us keycodes, so we need to blacklist it. if (chars === SPACEBAR_CHAR && hasSpaceKeypress) { return null; } return chars; default: // For other native event types, do nothing. return null; } } /** * For browsers that do not provide the `textInput` event, extract the * appropriate string to use for SyntheticInputEvent. * * @param {string} topLevelType Record from `BrowserEventConstants`. * @param {object} nativeEvent Native browser event. * @return {?string} The fallback string for this `beforeInput` event. */ function getFallbackBeforeInputChars(topLevelType, nativeEvent) { // If we are currently composing (IME) and using a fallback to do so, // try to extract the composed characters from the fallback object. // If composition event is available, we extract a string only at // compositionevent, otherwise extract it at fallback events. if (isComposing) { if (topLevelType === 'topCompositionEnd' || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) { var chars = FallbackCompositionState_1.getData(); FallbackCompositionState_1.reset(); isComposing = false; return chars; } return null; } switch (topLevelType) { case 'topPaste': // If a paste event occurs after a keypress, throw out the input // chars. Paste events should not lead to BeforeInput events. return null; case 'topKeyPress': /** * As of v27, Firefox may fire keypress events even when no character * will be inserted. A few possibilities: * * - `which` is `0`. Arrow keys, Esc key, etc. * * - `which` is the pressed key code, but no char is available. * Ex: 'AltGr + d` in Polish. There is no modified character for * this key combination and no character is inserted into the * document, but FF fires the keypress for char code `100` anyway. * No `input` event will occur. * * - `which` is the pressed key code, but a command combination is * being used. Ex: `Cmd+C`. No character is inserted, and no * `input` event will occur. */ if (!isKeypressCommand(nativeEvent)) { // IE fires the `keypress` event when a user types an emoji via // Touch keyboard of Windows. In such a case, the `char` property // holds an emoji character like `\uD83D\uDE0A`. Because its length // is 2, the property `which` does not represent an emoji correctly. // In such a case, we directly return the `char` property instead of // using `which`. if (nativeEvent.char && nativeEvent.char.length > 1) { return nativeEvent.char; } else if (nativeEvent.which) { return String.fromCharCode(nativeEvent.which); } } return null; case 'topCompositionEnd': return useFallbackCompositionData ? null : nativeEvent.data; default: return null; } } /** * Extract a SyntheticInputEvent for `beforeInput`, based on either native * `textInput` or fallback behavior. * * @return {?object} A SyntheticInputEvent. */ function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) { var chars; if (canUseTextInputEvent) { chars = getNativeBeforeInputChars(topLevelType, nativeEvent); } else { chars = getFallbackBeforeInputChars(topLevelType, nativeEvent); } // If no characters are being inserted, no BeforeInput event should // be fired. if (!chars) { return null; } var event = SyntheticInputEvent_1.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget); event.data = chars; EventPropagators_1.accumulateTwoPhaseDispatches(event); return event; } /** * Create an `onBeforeInput` event to match * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents. * * This event plugin is based on the native `textInput` event * available in Chrome, Safari, Opera, and IE. This event fires after * `onKeyPress` and `onCompositionEnd`, but before `onInput`. * * `beforeInput` is spec'd but not implemented in any browsers, and * the `input` event does not provide any useful information about what has * actually been added, contrary to the spec. Thus, `textInput` is the best * available event to identify the characters that have actually been inserted * into the target node. * * This plugin is also responsible for emitting `composition` events, thus * allowing us to share composition fallback code for both `beforeInput` and * `composition` event types. */ var BeforeInputEventPlugin = { eventTypes: eventTypes, extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { return [extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget), extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget)]; } }; var BeforeInputEventPlugin_1 = BeforeInputEventPlugin; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule isTextInputElement * */ /** * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary */ var supportedInputTypes = { color: true, date: true, datetime: true, 'datetime-local': true, email: true, month: true, number: true, password: true, range: true, search: true, tel: true, text: true, time: true, url: true, week: true }; function isTextInputElement(elem) { var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); if (nodeName === 'input') { return !!supportedInputTypes[elem.type]; } if (nodeName === 'textarea') { return true; } return false; } var isTextInputElement_1 = isTextInputElement; var eventTypes$1 = { change: { phasedRegistrationNames: { bubbled: 'onChange', captured: 'onChangeCapture' }, dependencies: ['topBlur', 'topChange', 'topClick', 'topFocus', 'topInput', 'topKeyDown', 'topKeyUp', 'topSelectionChange'] } }; function createAndAccumulateChangeEvent(inst, nativeEvent, target) { var event = SyntheticEvent_1.getPooled(eventTypes$1.change, inst, nativeEvent, target); event.type = 'change'; // Flag this event loop as needing state restore. ReactControlledComponent_1.enqueueStateRestore(target); EventPropagators_1.accumulateTwoPhaseDispatches(event); return event; } /** * For IE shims */ var activeElement = null; var activeElementInst = null; /** * SECTION: handle `change` event */ function shouldUseChangeEvent(elem) { var nodeName = elem.nodeName && elem.nodeName.toLowerCase(); return nodeName === 'select' || nodeName === 'input' && elem.type === 'file'; } function manualDispatchChangeEvent(nativeEvent) { var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget_1(nativeEvent)); // If change and propertychange bubbled, we'd just bind to it like all the // other events and have it go through ReactBrowserEventEmitter. Since it // doesn't, we manually listen for the events and so we have to enqueue and // process the abstract event manually. // // Batching is necessary here in order to ensure that all event handlers run // before the next rerender (including event handlers attached to ancestor // elements instead of directly on the input). Without this, controlled // components don't work properly in conjunction with event bubbling because // the component is rerendered and the value reverted before all the event // handlers can run. See https://github.com/facebook/react/issues/708. ReactGenericBatching_1.batchedUpdates(runEventInBatch, event); } function runEventInBatch(event) { EventPluginHub_1.enqueueEvents(event); EventPluginHub_1.processEventQueue(false); } function getInstIfValueChanged(targetInst) { var targetNode = ReactDOMComponentTree_1.getNodeFromInstance(targetInst); if (inputValueTracking_1.updateValueIfChanged(targetNode)) { return targetInst; } } function getTargetInstForChangeEvent(topLevelType, targetInst) { if (topLevelType === 'topChange') { return targetInst; } } /** * SECTION: handle `input` event */ var isInputEventSupported = false; if (ExecutionEnvironment.canUseDOM) { // IE9 claims to support the input event but fails to trigger it when // deleting text, so we ignore its input events. isInputEventSupported = isEventSupported_1('input') && (!document.documentMode || document.documentMode > 9); } /** * (For IE <=9) Starts tracking propertychange events on the passed-in element * and override the value property so that we can distinguish user events from * value changes in JS. */ function startWatchingForValueChange(target, targetInst) { activeElement = target; activeElementInst = targetInst; activeElement.attachEvent('onpropertychange', handlePropertyChange); } /** * (For IE <=9) Removes the event listeners from the currently-tracked element, * if any exists. */ function stopWatchingForValueChange() { if (!activeElement) { return; } activeElement.detachEvent('onpropertychange', handlePropertyChange); activeElement = null; activeElementInst = null; } /** * (For IE <=9) Handles a propertychange event, sending a `change` event if * the value of the active element has changed. */ function handlePropertyChange(nativeEvent) { if (nativeEvent.propertyName !== 'value') { return; } if (getInstIfValueChanged(activeElementInst)) { manualDispatchChangeEvent(nativeEvent); } } function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) { if (topLevelType === 'topFocus') { // In IE9, propertychange fires for most input events but is buggy and // doesn't fire when text is deleted, but conveniently, selectionchange // appears to fire in all of the remaining cases so we catch those and // forward the event if the value has changed // In either case, we don't want to call the event handler if the value // is changed from JS so we redefine a setter for `.value` that updates // our activeElementValue variable, allowing us to ignore those changes // // stopWatching() should be a noop here but we call it just in case we // missed a blur event somehow. stopWatchingForValueChange(); startWatchingForValueChange(target, targetInst); } else if (topLevelType === 'topBlur') { stopWatchingForValueChange(); } } // For IE8 and IE9. function getTargetInstForInputEventPolyfill(topLevelType, targetInst) { if (topLevelType === 'topSelectionChange' || topLevelType === 'topKeyUp' || topLevelType === 'topKeyDown') { // On the selectionchange event, the target is just document which isn't // helpful for us so just check activeElement instead. // // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire // propertychange on the first input event after setting `value` from a // script and fires only keydown, keypress, keyup. Catching keyup usually // gets it and catching keydown lets us fire an event for the first // keystroke if user does a key repeat (it'll be a little delayed: right // before the second keystroke). Other input methods (e.g., paste) seem to // fire selectionchange normally. return getInstIfValueChanged(activeElementInst); } } /** * SECTION: handle `click` event */ function shouldUseClickEvent(elem) { // Use the `click` event to detect changes to checkbox and radio inputs. // This approach works across all browsers, whereas `change` does not fire // until `blur` in IE8. var nodeName = elem.nodeName; return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio'); } function getTargetInstForClickEvent(topLevelType, targetInst) { if (topLevelType === 'topClick') { return getInstIfValueChanged(targetInst); } } function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) { if (topLevelType === 'topInput' || topLevelType === 'topChange') { return getInstIfValueChanged(targetInst); } } function handleControlledInputBlur(inst, node) { // TODO: In IE, inst is occasionally null. Why? if (inst == null) { return; } // Fiber and ReactDOM keep wrapper state in separate places var state = inst._wrapperState || node._wrapperState; if (!state || !state.controlled || node.type !== 'number') { return; } // If controlled, assign the value attribute to the current value on blur var value = '' + node.value; if (node.getAttribute('value') !== value) { node.setAttribute('value', value); } } /** * This plugin creates an `onChange` event that normalizes change events * across form elements. This event fires at a time when it's possible to * change the element's value without seeing a flicker. * * Supported elements are: * - input (see `isTextInputElement`) * - textarea * - select */ var ChangeEventPlugin = { eventTypes: eventTypes$1, _isInputEventSupported: isInputEventSupported, extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { var targetNode = targetInst ? ReactDOMComponentTree_1.getNodeFromInstance(targetInst) : window; var getTargetInstFunc, handleEventFunc; if (shouldUseChangeEvent(targetNode)) { getTargetInstFunc = getTargetInstForChangeEvent; } else if (isTextInputElement_1(targetNode)) { if (isInputEventSupported) { getTargetInstFunc = getTargetInstForInputOrChangeEvent; } else { getTargetInstFunc = getTargetInstForInputEventPolyfill; handleEventFunc = handleEventsForInputEventPolyfill; } } else if (shouldUseClickEvent(targetNode)) { getTargetInstFunc = getTargetInstForClickEvent; } if (getTargetInstFunc) { var inst = getTargetInstFunc(topLevelType, targetInst); if (inst) { var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget); return event; } } if (handleEventFunc) { handleEventFunc(topLevelType, targetNode, targetInst); } // When blurring, set the value attribute for number inputs if (topLevelType === 'topBlur') { handleControlledInputBlur(targetInst, targetNode); } } }; var ChangeEventPlugin_1 = ChangeEventPlugin; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule DOMEventPluginOrder */ /** * Module that is injectable into `EventPluginHub`, that specifies a * deterministic ordering of `EventPlugin`s. A convenient way to reason about * plugins, without having to package every one of them. This is better than * having plugins be ordered in the same order that they are injected because * that ordering would be influenced by the packaging order. * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that * preventing default on events is convenient in `SimpleEventPlugin` handlers. */ var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'TapEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin']; var DOMEventPluginOrder_1 = DOMEventPluginOrder; /** * @interface UIEvent * @see http://www.w3.org/TR/DOM-Level-3-Events/ */ var UIEventInterface = { view: function (event) { if (event.view) { return event.view; } var target = getEventTarget_1(event); if (target.window === target) { // target is a window object return target; } var doc = target.ownerDocument; // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. if (doc) { return doc.defaultView || doc.parentWindow; } else { return window; } }, detail: function (event) { return event.detail || 0; } }; /** * @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticEvent} */ function SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { return SyntheticEvent_1.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticEvent_1.augmentClass(SyntheticUIEvent, UIEventInterface); var SyntheticUIEvent_1 = SyntheticUIEvent; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule getEventModifierState */ /** * Translation from modifier key to the associated property in the event. * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers */ var modifierKeyToProp = { Alt: 'altKey', Control: 'ctrlKey', Meta: 'metaKey', Shift: 'shiftKey' }; // IE8 does not implement getModifierState so we simply map it to the only // modifier keys exposed by the event itself, does not support Lock-keys. // Currently, all major browsers except Chrome seems to support Lock-keys. function modifierStateGetter(keyArg) { var syntheticEvent = this; var nativeEvent = syntheticEvent.nativeEvent; if (nativeEvent.getModifierState) { return nativeEvent.getModifierState(keyArg); } var keyProp = modifierKeyToProp[keyArg]; return keyProp ? !!nativeEvent[keyProp] : false; } function getEventModifierState(nativeEvent) { return modifierStateGetter; } var getEventModifierState_1 = getEventModifierState; /** * @interface MouseEvent * @see http://www.w3.org/TR/DOM-Level-3-Events/ */ var MouseEventInterface = { screenX: null, screenY: null, clientX: null, clientY: null, pageX: null, pageY: null, ctrlKey: null, shiftKey: null, altKey: null, metaKey: null, getModifierState: getEventModifierState_1, button: null, buttons: null, relatedTarget: function (event) { return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement); } }; /** * @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */ function SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { return SyntheticUIEvent_1.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticUIEvent_1.augmentClass(SyntheticMouseEvent, MouseEventInterface); var SyntheticMouseEvent_1 = SyntheticMouseEvent; var eventTypes$2 = { mouseEnter: { registrationName: 'onMouseEnter', dependencies: ['topMouseOut', 'topMouseOver'] }, mouseLeave: { registrationName: 'onMouseLeave', dependencies: ['topMouseOut', 'topMouseOver'] } }; var EnterLeaveEventPlugin = { eventTypes: eventTypes$2, /** * For almost every interaction we care about, there will be both a top-level * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that * we do not extract duplicate events. However, moving the mouse into the * browser from outside will not fire a `mouseout` event. In this case, we use * the `mouseover` top-level event. */ extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { if (topLevelType === 'topMouseOver' && (nativeEvent.relatedTarget || nativeEvent.fromElement)) { return null; } if (topLevelType !== 'topMouseOut' && topLevelType !== 'topMouseOver') { // Must not be a mouse in or mouse out - ignoring. return null; } var win; if (nativeEventTarget.window === nativeEventTarget) { // `nativeEventTarget` is probably a window object. win = nativeEventTarget; } else { // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. var doc = nativeEventTarget.ownerDocument; if (doc) { win = doc.defaultView || doc.parentWindow; } else { win = window; } } var from; var to; if (topLevelType === 'topMouseOut') { from = targetInst; var related = nativeEvent.relatedTarget || nativeEvent.toElement; to = related ? ReactDOMComponentTree_1.getClosestInstanceFromNode(related) : null; } else { // Moving to a node from outside the window. from = null; to = targetInst; } if (from === to) { // Nothing pertains to our managed components. return null; } var fromNode = from == null ? win : ReactDOMComponentTree_1.getNodeFromInstance(from); var toNode = to == null ? win : ReactDOMComponentTree_1.getNodeFromInstance(to); var leave = SyntheticMouseEvent_1.getPooled(eventTypes$2.mouseLeave, from, nativeEvent, nativeEventTarget); leave.type = 'mouseleave'; leave.target = fromNode; leave.relatedTarget = toNode; var enter = SyntheticMouseEvent_1.getPooled(eventTypes$2.mouseEnter, to, nativeEvent, nativeEventTarget); enter.type = 'mouseenter'; enter.target = toNode; enter.relatedTarget = fromNode; EventPropagators_1.accumulateEnterLeaveDispatches(leave, enter, from, to); return [leave, enter]; } }; var EnterLeaveEventPlugin_1 = EnterLeaveEventPlugin; var DOCUMENT_NODE$2 = HTMLNodeType_1.DOCUMENT_NODE; var skipSelectionChangeEvent = ExecutionEnvironment.canUseDOM && 'documentMode' in document && document.documentMode <= 11; var eventTypes$3 = { select: { phasedRegistrationNames: { bubbled: 'onSelect', captured: 'onSelectCapture' }, dependencies: ['topBlur', 'topContextMenu', 'topFocus', 'topKeyDown', 'topKeyUp', 'topMouseDown', 'topMouseUp', 'topSelectionChange'] } }; var activeElement$1 = null; var activeElementInst$1 = null; var lastSelection = null; var mouseDown = false; // Track whether all listeners exists for this plugin. If none exist, we do // not extract events. See #3639. var isListeningToAllDependencies = ReactBrowserEventEmitter_1.isListeningToAllDependencies; /** * Get an object which is a unique representation of the current selection. * * The return value will not be consistent across nodes or browsers, but * two identical selections on the same node will return identical objects. * * @param {DOMElement} node * @return {object} */ function getSelection(node) { if ('selectionStart' in node && ReactInputSelection_1.hasSelectionCapabilities(node)) { return { start: node.selectionStart, end: node.selectionEnd }; } else if (window.getSelection) { var selection = window.getSelection(); return { anchorNode: selection.anchorNode, anchorOffset: selection.anchorOffset, focusNode: selection.focusNode, focusOffset: selection.focusOffset }; } } /** * Poll selection to see whether it's changed. * * @param {object} nativeEvent * @return {?SyntheticEvent} */ function constructSelectEvent(nativeEvent, nativeEventTarget) { // Ensure we have the right element, and that the user is not dragging a // selection (this matches native `select` event behavior). In HTML5, select // fires only on input and textarea thus if there's no focused element we // won't dispatch. if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement()) { return null; } // Only fire when selection has actually changed. var currentSelection = getSelection(activeElement$1); if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) { lastSelection = currentSelection; var syntheticEvent = SyntheticEvent_1.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget); syntheticEvent.type = 'select'; syntheticEvent.target = activeElement$1; EventPropagators_1.accumulateTwoPhaseDispatches(syntheticEvent); return syntheticEvent; } return null; } /** * This plugin creates an `onSelect` event that normalizes select events * across form elements. * * Supported elements are: * - input (see `isTextInputElement`) * - textarea * - contentEditable * * This differs from native browser implementations in the following ways: * - Fires on contentEditable fields as well as inputs. * - Fires for collapsed selection. * - Fires after user input. */ var SelectEventPlugin = { eventTypes: eventTypes$3, extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { var doc = nativeEventTarget.window === nativeEventTarget ? nativeEventTarget.document : nativeEventTarget.nodeType === DOCUMENT_NODE$2 ? nativeEventTarget : nativeEventTarget.ownerDocument; if (!doc || !isListeningToAllDependencies('onSelect', doc)) { return null; } var targetNode = targetInst ? ReactDOMComponentTree_1.getNodeFromInstance(targetInst) : window; switch (topLevelType) { // Track the input node that has focus. case 'topFocus': if (isTextInputElement_1(targetNode) || targetNode.contentEditable === 'true') { activeElement$1 = targetNode; activeElementInst$1 = targetInst; lastSelection = null; } break; case 'topBlur': activeElement$1 = null; activeElementInst$1 = null; lastSelection = null; break; // Don't fire the event while the user is dragging. This matches the // semantics of the native select event. case 'topMouseDown': mouseDown = true; break; case 'topContextMenu': case 'topMouseUp': mouseDown = false; return constructSelectEvent(nativeEvent, nativeEventTarget); // Chrome and IE fire non-standard event when selection is changed (and // sometimes when it hasn't). IE's event fires out of order with respect // to key and input events on deletion, so we discard it. // // Firefox doesn't support selectionchange, so check selection status // after each key entry. The selection changes after keydown and before // keyup, but we check on keydown as well in the case of holding down a // key, when multiple keydown events are fired but only one keyup is. // This is also our approach for IE handling, for the reason above. case 'topSelectionChange': if (skipSelectionChangeEvent) { break; } // falls through case 'topKeyDown': case 'topKeyUp': return constructSelectEvent(nativeEvent, nativeEventTarget); } return null; } }; var SelectEventPlugin_1 = SelectEventPlugin; /** * @interface Event * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent */ var AnimationEventInterface = { animationName: null, elapsedTime: null, pseudoElement: null }; /** * @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticEvent} */ function SyntheticAnimationEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { return SyntheticEvent_1.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticEvent_1.augmentClass(SyntheticAnimationEvent, AnimationEventInterface); var SyntheticAnimationEvent_1 = SyntheticAnimationEvent; /** * @interface Event * @see http://www.w3.org/TR/clipboard-apis/ */ var ClipboardEventInterface = { clipboardData: function (event) { return 'clipboardData' in event ? event.clipboardData : window.clipboardData; } }; /** * @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */ function SyntheticClipboardEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { return SyntheticEvent_1.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticEvent_1.augmentClass(SyntheticClipboardEvent, ClipboardEventInterface); var SyntheticClipboardEvent_1 = SyntheticClipboardEvent; /** * @interface FocusEvent * @see http://www.w3.org/TR/DOM-Level-3-Events/ */ var FocusEventInterface = { relatedTarget: null }; /** * @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */ function SyntheticFocusEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { return SyntheticUIEvent_1.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticUIEvent_1.augmentClass(SyntheticFocusEvent, FocusEventInterface); var SyntheticFocusEvent_1 = SyntheticFocusEvent; /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @providesModule getEventCharCode */ /** * `charCode` represents the actual "character code" and is safe to use with * `String.fromCharCode`. As such, only keys that correspond to printable * characters produce a valid `charCode`, the only exception to this is Enter. * The Tab-key is considered non-printable and does not have a `charCode`, * presumably because it does not produce a tab-character in browsers. * * @param {object} nativeEvent Native browser event. * @return {number} Normalized `charCode` property. */ function getEventCharCode(nativeEvent) { var charCode; var keyCode = nativeEvent.keyCode; if ('charCode' in nativeEvent) { charCode = nativeEvent.charCode; // FF does not set `charCode` for the Enter-key, check against `keyCode`. if (charCode === 0 && keyCode === 13) { charCode = 13; } } else { // IE8 does not implement `charCode`, but `keyCode` has the correct value. charCode = keyCode; } // Some non-printable keys are reported in `charCode`/`keyCode`, discard them. // Must not discard the (non-)printable Enter-key. if (charCode >= 32 || charCode === 13) { return charCode; } return 0; } var getEventCharCode_1 = getEventCharCode; /** * Normalization of deprecated HTML5 `key` values * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names */ var normalizeKey = { Esc: 'Escape', Spacebar: ' ', Left: 'ArrowLeft', Up: 'ArrowUp', Right: 'ArrowRight', Down: 'ArrowDown', Del: 'Delete', Win: 'OS', Menu: 'ContextMenu', Apps: 'ContextMenu', Scroll: 'ScrollLock', MozPrintableKey: 'Unidentified' }; /** * Translation from legacy `keyCode` to HTML5 `key` * Only special keys supported, all others depend on keyboard layout or browser * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names */ var translateToKey = { 8: 'Backspace', 9: 'Tab', 12: 'Clear', 13: 'Enter', 16: 'Shift', 17: 'Control', 18: 'Alt', 19: 'Pause', 20: 'CapsLock', 27: 'Escape', 32: ' ', 33: 'PageUp', 34: 'PageDown', 35: 'End', 36: 'Home', 37: 'ArrowLeft', 38: 'ArrowUp', 39: 'ArrowRight', 40: 'ArrowDown', 45: 'Insert', 46: 'Delete', 112: 'F1', 113: 'F2', 114: 'F3', 115: 'F4', 116: 'F5', 117: 'F6', 118: 'F7', 119: 'F8', 120: 'F9', 121: 'F10', 122: 'F11', 123: 'F12', 144: 'NumLock', 145: 'ScrollLock', 224: 'Meta' }; /** * @param {object} nativeEvent Native browser event. * @return {string} Normalized `key` property. */ function getEventKey(nativeEvent) { if (nativeEvent.key) { // Normalize inconsistent values reported by browsers due to // implementations of a working draft specification. // FireFox implements `key` but returns `MozPrintableKey` for all // printable characters (normalized to `Unidentified`), ignore it. var key = normalizeKey[nativeEvent.key] || nativeEvent.key; if (key !== 'Unidentified') { return key; } } // Browser does not implement `key`, polyfill as much of it as we can. if (nativeEvent.type === 'keypress') { var charCode = getEventCharCode_1(nativeEvent); // The enter-key is technically both printable and non-printable and can // thus be captured by `keypress`, no other non-printable key should. return charCode === 13 ? 'Enter' : String.fromCharCode(charCode); } if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') { // While user keyboard layout determines the actual meaning of each // `keyCode` value, almost all function keys have a universal value. return translateToKey[nativeEvent.keyCode] || 'Unidentified'; } return ''; } var getEventKey_1 = getEventKey; /** * @interface KeyboardEvent * @see http://www.w3.org/TR/DOM-Level-3-Events/ */ var KeyboardEventInterface = { key: getEventKey_1, location: null, ctrlKey: null, shiftKey: null, altKey: null, metaKey: null, repeat: null, locale: null, getModifierState: getEventModifierState_1, // Legacy Interface charCode: function (event) { // `charCode` is the result of a KeyPress event and represents the value of // the actual printable character. // KeyPress is deprecated, but its replacement is not yet final and not // implemented in any major browser. Only KeyPress has charCode. if (event.type === 'keypress') { return getEventCharCode_1(event); } return 0; }, keyCode: function (event) { // `keyCode` is the result of a KeyDown/Up event and represents the value of // physical keyboard key. // The actual meaning of the value depends on the users' keyboard layout // which cannot be detected. Assuming that it is a US keyboard layout // provides a surprisingly accurate mapping for US and European users. // Due to this, it is left to the user to implement at this time. if (event.type === 'keydown' || event.type === 'keyup') { return event.keyCode; } return 0; }, which: function (event) { // `which` is an alias for either `keyCode` or `charCode` depending on the // type of the event. if (event.type === 'keypress') { return getEventCharCode_1(event); } if (event.type === 'keydown' || event.type === 'keyup') { return event.keyCode; } return 0; } }; /** * @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */ function SyntheticKeyboardEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { return SyntheticUIEvent_1.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticUIEvent_1.augmentClass(SyntheticKeyboardEvent, KeyboardEventInterface); var SyntheticKeyboardEvent_1 = SyntheticKeyboardEvent; /** * @interface DragEvent * @see http://www.w3.org/TR/DOM-Level-3-Events/ */ var DragEventInterface = { dataTransfer: null }; /** * @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */ function SyntheticDragEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { return SyntheticMouseEvent_1.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticMouseEvent_1.augmentClass(SyntheticDragEvent, DragEventInterface); var SyntheticDragEvent_1 = SyntheticDragEvent; /** * @interface TouchEvent * @see http://www.w3.org/TR/touch-events/ */ var TouchEventInterface = { touches: null, targetTouches: null, changedTouches: null, altKey: null, metaKey: null, ctrlKey: null, shiftKey: null, getModifierState: getEventModifierState_1 }; /** * @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */ function SyntheticTouchEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { return SyntheticUIEvent_1.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticUIEvent_1.augmentClass(SyntheticTouchEvent, TouchEventInterface); var SyntheticTouchEvent_1 = SyntheticTouchEvent; /** * @interface Event * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events- * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent */ var TransitionEventInterface = { propertyName: null, elapsedTime: null, pseudoElement: null }; /** * @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticEvent} */ function SyntheticTransitionEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { return SyntheticEvent_1.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticEvent_1.augmentClass(SyntheticTransitionEvent, TransitionEventInterface); var SyntheticTransitionEvent_1 = SyntheticTransitionEvent; /** * @interface WheelEvent * @see http://www.w3.org/TR/DOM-Level-3-Events/ */ var WheelEventInterface = { deltaX: function (event) { return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive). 'wheelDeltaX' in event ? -event.wheelDeltaX : 0; }, deltaY: function (event) { return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive). 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive). 'wheelDelta' in event ? -event.wheelDelta : 0; }, deltaZ: null, // Browsers without "deltaMode" is reporting in raw wheel delta where one // notch on the scroll is always +/- 120, roughly equivalent to pixels. // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size. deltaMode: null }; /** * @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticMouseEvent} */ function SyntheticWheelEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { return SyntheticMouseEvent_1.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); } SyntheticMouseEvent_1.augmentClass(SyntheticWheelEvent, WheelEventInterface); var SyntheticWheelEvent_1 = SyntheticWheelEvent; /** * Turns * ['abort', ...] * into * eventTypes = { * 'abort': { * phasedRegistrationNames: { * bubbled: 'onAbort', * captured: 'onAbortCapture', * }, * dependencies: ['topAbort'], * }, * ... * }; * topLevelEventsToDispatchConfig = { * 'topAbort': { sameConfig } * }; */ var eventTypes$4 = {}; var topLevelEventsToDispatchConfig = {}; ['abort', 'animationEnd', 'animationIteration', 'animationStart', 'blur', 'cancel', 'canPlay', 'canPlayThrough', 'click', 'close', 'contextMenu', 'copy', 'cut', 'doubleClick', 'drag', 'dragEnd', 'dragEnter', 'dragExit', 'dragLeave', 'dragOver', 'dragStart', 'drop', 'durationChange', 'emptied', 'encrypted', 'ended', 'error', 'focus', 'input', 'invalid', 'keyDown', 'keyPress', 'keyUp', 'load', 'loadedData', 'loadedMetadata', 'loadStart', 'mouseDown', 'mouseMove', 'mouseOut', 'mouseOver', 'mouseUp', 'paste', 'pause', 'play', 'playing', 'progress', 'rateChange', 'reset', 'scroll', 'seeked', 'seeking', 'stalled', 'submit', 'suspend', 'timeUpdate', 'toggle', 'touchCancel', 'touchEnd', 'touchMove', 'touchStart', 'transitionEnd', 'volumeChange', 'waiting', 'wheel'].forEach(function (event) { var capitalizedEvent = event[0].toUpperCase() + event.slice(1); var onEvent = 'on' + capitalizedEvent; var topEvent = 'top' + capitalizedEvent; var type = { phasedRegistrationNames: { bubbled: onEvent, captured: onEvent + 'Capture' }, dependencies: [topEvent] }; eventTypes$4[event] = type; topLevelEventsToDispatchConfig[topEvent] = type; }); var SimpleEventPlugin = { eventTypes: eventTypes$4, extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType]; if (!dispatchConfig) { return null; } var EventConstructor; switch (topLevelType) { case 'topAbort': case 'topCancel': case 'topCanPlay': case 'topCanPlayThrough': case 'topClose': case 'topDurationChange': case 'topEmptied': case 'topEncrypted': case 'topEnded': case 'topError': case 'topInput': case 'topInvalid': case 'topLoad': case 'topLoadedData': case 'topLoadedMetadata': case 'topLoadStart': case 'topPause': case 'topPlay': case 'topPlaying': case 'topProgress': case 'topRateChange': case 'topReset': case 'topSeeked': case 'topSeeking': case 'topStalled': case 'topSubmit': case 'topSuspend': case 'topTimeUpdate': case 'topToggle': case 'topVolumeChange': case 'topWaiting': // HTML Events // @see http://www.w3.org/TR/html5/index.html#events-0 EventConstructor = SyntheticEvent_1; break; case 'topKeyPress': // Firefox creates a keypress event for function keys too. This removes // the unwanted keypress events. Enter is however both printable and // non-printable. One would expect Tab to be as well (but it isn't). if (getEventCharCode_1(nativeEvent) === 0) { return null; } /* falls through */ case 'topKeyDown': case 'topKeyUp': EventConstructor = SyntheticKeyboardEvent_1; break; case 'topBlur': case 'topFocus': EventConstructor = SyntheticFocusEvent_1; break; case 'topClick': // Firefox creates a click event on right mouse clicks. This removes the // unwanted click events. if (nativeEvent.button === 2) { return null; } /* falls through */ case 'topDoubleClick': case 'topMouseDown': case 'topMouseMove': case 'topMouseUp': // TODO: Disabled elements should not respond to mouse events /* falls through */ case 'topMouseOut': case 'topMouseOver': case 'topContextMenu': EventConstructor = SyntheticMouseEvent_1; break; case 'topDrag': case 'topDragEnd': case 'topDragEnter': case 'topDragExit': case 'topDragLeave': case 'topDragOver': case 'topDragStart': case 'topDrop': EventConstructor = SyntheticDragEvent_1; break; case 'topTouchCancel': case 'topTouchEnd': case 'topTouchMove': case 'topTouchStart': EventConstructor = SyntheticTouchEvent_1; break; case 'topAnimationEnd': case 'topAnimationIteration': case 'topAnimationStart': EventConstructor = SyntheticAnimationEvent_1; break; case 'topTransitionEnd': EventConstructor = SyntheticTransitionEvent_1; break; case 'topScroll': EventConstructor = SyntheticUIEvent_1; break; case 'topWheel': EventConstructor = SyntheticWheelEvent_1; break; case 'topCopy': case 'topCut': case 'topPaste': EventConstructor = SyntheticClipboardEvent_1; break; } !EventConstructor ? invariant(false, 'SimpleEventPlugin: Unhandled event type, `%s`.', topLevelType) : void 0; var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget); EventPropagators_1.accumulateTwoPhaseDispatches(event); return event; } }; var SimpleEventPlugin_1 = SimpleEventPlugin; ReactDOMEventListener_1.setHandleTopLevel(ReactBrowserEventEmitter_1.handleTopLevel); /** * Inject modules for resolving DOM hierarchy and plugin ordering. */ EventPluginHub_1.injection.injectEventPluginOrder(DOMEventPluginOrder_1); EventPluginUtils_1.injection.injectComponentTree(ReactDOMComponentTree_1); /** * Some important event plugins included by default (without having to require * them). */ EventPluginHub_1.injection.injectEventPluginsByName({ SimpleEventPlugin: SimpleEventPlugin_1, EnterLeaveEventPlugin: EnterLeaveEventPlugin_1, ChangeEventPlugin: ChangeEventPlugin_1, SelectEventPlugin: SelectEventPlugin_1, BeforeInputEventPlugin: BeforeInputEventPlugin_1 }); var MUST_USE_PROPERTY = DOMProperty_1.injection.MUST_USE_PROPERTY; var HAS_BOOLEAN_VALUE = DOMProperty_1.injection.HAS_BOOLEAN_VALUE; var HAS_NUMERIC_VALUE = DOMProperty_1.injection.HAS_NUMERIC_VALUE; var HAS_POSITIVE_NUMERIC_VALUE = DOMProperty_1.injection.HAS_POSITIVE_NUMERIC_VALUE; var HAS_OVERLOADED_BOOLEAN_VALUE = DOMProperty_1.injection.HAS_OVERLOADED_BOOLEAN_VALUE; var HAS_STRING_BOOLEAN_VALUE = DOMProperty_1.injection.HAS_STRING_BOOLEAN_VALUE; var HTMLDOMPropertyConfig = { // When adding attributes to this list, be sure to also add them to // the `possibleStandardNames` module to ensure casing and incorrect // name warnings. Properties: { allowFullScreen: HAS_BOOLEAN_VALUE, // IE only true/false iFrame attribute // https://msdn.microsoft.com/en-us/library/ms533072(v=vs.85).aspx allowTransparency: HAS_STRING_BOOLEAN_VALUE, // specifies target context for links with `preload` type async: HAS_BOOLEAN_VALUE, // autoFocus is polyfilled/normalized by AutoFocusUtils // autoFocus: HAS_BOOLEAN_VALUE, autoPlay: HAS_BOOLEAN_VALUE, capture: HAS_BOOLEAN_VALUE, checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, cols: HAS_POSITIVE_NUMERIC_VALUE, contentEditable: HAS_STRING_BOOLEAN_VALUE, controls: HAS_BOOLEAN_VALUE, 'default': HAS_BOOLEAN_VALUE, defer: HAS_BOOLEAN_VALUE, disabled: HAS_BOOLEAN_VALUE, download: HAS_OVERLOADED_BOOLEAN_VALUE, draggable: HAS_STRING_BOOLEAN_VALUE, formNoValidate: HAS_BOOLEAN_VALUE, hidden: HAS_BOOLEAN_VALUE, loop: HAS_BOOLEAN_VALUE, // Caution; `option.selected` is not updated if `select.multiple` is // disabled with `removeAttribute`. multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, noValidate: HAS_BOOLEAN_VALUE, open: HAS_BOOLEAN_VALUE, playsInline: HAS_BOOLEAN_VALUE, readOnly: HAS_BOOLEAN_VALUE, required: HAS_BOOLEAN_VALUE, reversed: HAS_BOOLEAN_VALUE, rows: HAS_POSITIVE_NUMERIC_VALUE, rowSpan: HAS_NUMERIC_VALUE, scoped: HAS_BOOLEAN_VALUE, seamless: HAS_BOOLEAN_VALUE, selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, size: HAS_POSITIVE_NUMERIC_VALUE, start: HAS_NUMERIC_VALUE, // support for projecting regular DOM Elements via V1 named slots ( shadow dom ) span: HAS_POSITIVE_NUMERIC_VALUE, spellCheck: HAS_STRING_BOOLEAN_VALUE, // Style must be explicitly set in the attribute list. React components // expect a style object style: 0, // itemScope is for for Microdata support. // See http://schema.org/docs/gs.html itemScope: HAS_BOOLEAN_VALUE, // These attributes must stay in the white-list because they have // different attribute names (see DOMAttributeNames below) acceptCharset: 0, className: 0, htmlFor: 0, httpEquiv: 0, // Attributes with mutation methods must be specified in the whitelist // Set the string boolean flag to allow the behavior value: HAS_STRING_BOOLEAN_VALUE }, DOMAttributeNames: { acceptCharset: 'accept-charset', className: 'class', htmlFor: 'for', httpEquiv: 'http-equiv' }, DOMMutationMethods: { value: function (node, value) { if (value == null) { return node.removeAttribute('value'); } // Number inputs get special treatment due to some edge cases in // Chrome. Let everything else assign the value attribute as normal. // https://github.com/facebook/react/issues/7253#issuecomment-236074326 if (node.type !== 'number' || node.hasAttribute('value') === false) { node.setAttribute('value', '' + value); } else if (node.validity && !node.validity.badInput && node.ownerDocument.activeElement !== node) { // Don't assign an attribute if validation reports bad // input. Chrome will clear the value. Additionally, don't // operate on inputs that have focus, otherwise Chrome might // strip off trailing decimal places and cause the user's // cursor position to jump to the beginning of the input. // // In ReactDOMInput, we have an onBlur event that will trigger // this function again when focus is lost. node.setAttribute('value', '' + value); } } } }; var HTMLDOMPropertyConfig_1 = HTMLDOMPropertyConfig; var HAS_STRING_BOOLEAN_VALUE$1 = DOMProperty_1.injection.HAS_STRING_BOOLEAN_VALUE; var NS = { xlink: 'http://www.w3.org/1999/xlink', xml: 'http://www.w3.org/XML/1998/namespace' }; /** * This is a list of all SVG attributes that need special casing, * namespacing, or boolean value assignment. * * When adding attributes to this list, be sure to also add them to * the `possibleStandardNames` module to ensure casing and incorrect * name warnings. * * SVG Attributes List: * https://www.w3.org/TR/SVG/attindex.html * SMIL Spec: * https://www.w3.org/TR/smil */ var ATTRS = ['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', 'x-height', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xmlns:xlink', 'xml:lang', 'xml:space']; var SVGDOMPropertyConfig = { Properties: { autoReverse: HAS_STRING_BOOLEAN_VALUE$1, externalResourcesRequired: HAS_STRING_BOOLEAN_VALUE$1, preserveAlpha: HAS_STRING_BOOLEAN_VALUE$1 }, DOMAttributeNames: { autoReverse: 'autoReverse', externalResourcesRequired: 'externalResourcesRequired', preserveAlpha: 'preserveAlpha' }, DOMAttributeNamespaces: { xlinkActuate: NS.xlink, xlinkArcrole: NS.xlink, xlinkHref: NS.xlink, xlinkRole: NS.xlink, xlinkShow: NS.xlink, xlinkTitle: NS.xlink, xlinkType: NS.xlink, xmlBase: NS.xml, xmlLang: NS.xml, xmlSpace: NS.xml } }; var CAMELIZE = /[\-\:]([a-z])/g; var capitalize = function (token) { return token[1].toUpperCase(); }; ATTRS.forEach(function (original) { var reactName = original.replace(CAMELIZE, capitalize); SVGDOMPropertyConfig.Properties[reactName] = 0; SVGDOMPropertyConfig.DOMAttributeNames[reactName] = original; }); var SVGDOMPropertyConfig_1 = SVGDOMPropertyConfig; DOMProperty_1.injection.injectDOMPropertyConfig(HTMLDOMPropertyConfig_1); DOMProperty_1.injection.injectDOMPropertyConfig(SVGDOMPropertyConfig_1); var injectInternals = ReactFiberDevToolsHook.injectInternals; var ELEMENT_NODE = HTMLNodeType_1.ELEMENT_NODE; var TEXT_NODE = HTMLNodeType_1.TEXT_NODE; var COMMENT_NODE = HTMLNodeType_1.COMMENT_NODE; var DOCUMENT_NODE = HTMLNodeType_1.DOCUMENT_NODE; var DOCUMENT_FRAGMENT_NODE = HTMLNodeType_1.DOCUMENT_FRAGMENT_NODE; var ROOT_ATTRIBUTE_NAME = DOMProperty_1.ROOT_ATTRIBUTE_NAME; var getChildNamespace = DOMNamespaces.getChildNamespace; var createElement = ReactDOMFiberComponent_1.createElement; var createTextNode = ReactDOMFiberComponent_1.createTextNode; var setInitialProperties = ReactDOMFiberComponent_1.setInitialProperties; var diffProperties = ReactDOMFiberComponent_1.diffProperties; var updateProperties = ReactDOMFiberComponent_1.updateProperties; var diffHydratedProperties = ReactDOMFiberComponent_1.diffHydratedProperties; var diffHydratedText = ReactDOMFiberComponent_1.diffHydratedText; var warnForDeletedHydratableElement = ReactDOMFiberComponent_1.warnForDeletedHydratableElement; var warnForDeletedHydratableText = ReactDOMFiberComponent_1.warnForDeletedHydratableText; var warnForInsertedHydratedElement = ReactDOMFiberComponent_1.warnForInsertedHydratedElement; var warnForInsertedHydratedText = ReactDOMFiberComponent_1.warnForInsertedHydratedText; var precacheFiberNode = ReactDOMComponentTree_1.precacheFiberNode; var updateFiberProps = ReactDOMComponentTree_1.updateFiberProps; { var lowPriorityWarning = lowPriorityWarning_1; var warning = require$$0; var validateDOMNesting = validateDOMNesting_1; var updatedAncestorInfo = validateDOMNesting.updatedAncestorInfo; if (typeof Map !== 'function' || Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') { warning(false, 'React depends on Map and Set built-in types. Make sure that you load a ' + 'polyfill in older browsers. http://fb.me/react-polyfills'); } } ReactControlledComponent_1.injection.injectFiberControlledHostComponent(ReactDOMFiberComponent_1); findDOMNode_1._injectFiber(function (fiber) { return DOMRenderer.findHostInstance(fiber); }); var eventsEnabled = null; var selectionInformation = null; /** * True if the supplied DOM node is a valid node element. * * @param {?DOMElement} node The candidate DOM node. * @return {boolean} True if the DOM is a valid DOM node. * @internal */ function isValidContainer(node) { return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || node.nodeType === COMMENT_NODE && node.nodeValue === ' react-mount-point-unstable ')); } function getReactRootElementInContainer(container) { if (!container) { return null; } if (container.nodeType === DOCUMENT_NODE) { return container.documentElement; } else { return container.firstChild; } } function shouldHydrateDueToLegacyHeuristic(container) { var rootElement = getReactRootElementInContainer(container); return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME)); } function shouldAutoFocusHostComponent(type, props) { switch (type) { case 'button': case 'input': case 'select': case 'textarea': return !!props.autoFocus; } return false; } var DOMRenderer = ReactFiberReconciler({ getRootHostContext: function (rootContainerInstance) { var type = void 0; var namespace = void 0; if (rootContainerInstance.nodeType === DOCUMENT_NODE) { type = '#document'; var root = rootContainerInstance.documentElement; namespace = root ? root.namespaceURI : getChildNamespace(null, ''); } else { var container = rootContainerInstance.nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance; var ownNamespace = container.namespaceURI || null; type = container.tagName; namespace = getChildNamespace(ownNamespace, type); } { var validatedTag = type.toLowerCase(); var _ancestorInfo = updatedAncestorInfo(null, validatedTag, null); return { namespace: namespace, ancestorInfo: _ancestorInfo }; } return namespace; }, getChildHostContext: function (parentHostContext, type) { { var parentHostContextDev = parentHostContext; var _namespace = getChildNamespace(parentHostContextDev.namespace, type); var _ancestorInfo2 = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type, null); return { namespace: _namespace, ancestorInfo: _ancestorInfo2 }; } var parentNamespace = parentHostContext; return getChildNamespace(parentNamespace, type); }, getPublicInstance: function (instance) { return instance; }, prepareForCommit: function () { eventsEnabled = ReactBrowserEventEmitter_1.isEnabled(); selectionInformation = ReactInputSelection_1.getSelectionInformation(); ReactBrowserEventEmitter_1.setEnabled(false); }, resetAfterCommit: function () { ReactInputSelection_1.restoreSelection(selectionInformation); selectionInformation = null; ReactBrowserEventEmitter_1.setEnabled(eventsEnabled); eventsEnabled = null; }, createInstance: function (type, props, rootContainerInstance, hostContext, internalInstanceHandle) { var parentNamespace = void 0; { // TODO: take namespace into account when validating. var hostContextDev = hostContext; validateDOMNesting(type, null, null, hostContextDev.ancestorInfo); if (typeof props.children === 'string' || typeof props.children === 'number') { var string = '' + props.children; var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type, null); validateDOMNesting(null, string, null, ownAncestorInfo); } parentNamespace = hostContextDev.namespace; } var domElement = createElement(type, props, rootContainerInstance, parentNamespace); precacheFiberNode(internalInstanceHandle, domElement); updateFiberProps(domElement, props); return domElement; }, appendInitialChild: function (parentInstance, child) { parentInstance.appendChild(child); }, finalizeInitialChildren: function (domElement, type, props, rootContainerInstance) { setInitialProperties(domElement, type, props, rootContainerInstance); return shouldAutoFocusHostComponent(type, props); }, prepareUpdate: function (domElement, type, oldProps, newProps, rootContainerInstance, hostContext) { { var hostContextDev = hostContext; if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) { var string = '' + newProps.children; var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type, null); validateDOMNesting(null, string, null, ownAncestorInfo); } } return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance); }, commitMount: function (domElement, type, newProps, internalInstanceHandle) { domElement.focus(); }, commitUpdate: function (domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) { // Update the props handle so that we know which props are the ones with // with current event handlers. updateFiberProps(domElement, newProps); // Apply the diff to the DOM node. updateProperties(domElement, updatePayload, type, oldProps, newProps); }, shouldSetTextContent: function (type, props) { return type === 'textarea' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && typeof props.dangerouslySetInnerHTML.__html === 'string'; }, resetTextContent: function (domElement) { domElement.textContent = ''; }, shouldDeprioritizeSubtree: function (type, props) { return !!props.hidden; }, createTextInstance: function (text, rootContainerInstance, hostContext, internalInstanceHandle) { { var hostContextDev = hostContext; validateDOMNesting(null, text, null, hostContextDev.ancestorInfo); } var textNode = createTextNode(text, rootContainerInstance); precacheFiberNode(internalInstanceHandle, textNode); return textNode; }, commitTextUpdate: function (textInstance, oldText, newText) { textInstance.nodeValue = newText; }, appendChild: function (parentInstance, child) { parentInstance.appendChild(child); }, appendChildToContainer: function (container, child) { if (container.nodeType === COMMENT_NODE) { container.parentNode.insertBefore(child, container); } else { container.appendChild(child); } }, insertBefore: function (parentInstance, child, beforeChild) { parentInstance.insertBefore(child, beforeChild); }, insertInContainerBefore: function (container, child, beforeChild) { if (container.nodeType === COMMENT_NODE) { container.parentNode.insertBefore(child, beforeChild); } else { container.insertBefore(child, beforeChild); } }, removeChild: function (parentInstance, child) { parentInstance.removeChild(child); }, removeChildFromContainer: function (container, child) { if (container.nodeType === COMMENT_NODE) { container.parentNode.removeChild(child); } else { container.removeChild(child); } }, canHydrateInstance: function (instance, type, props) { return instance.nodeType === ELEMENT_NODE && type === instance.nodeName.toLowerCase(); }, canHydrateTextInstance: function (instance, text) { if (text === '') { // Empty strings are not parsed by HTML so there won't be a correct match here. return false; } return instance.nodeType === TEXT_NODE; }, getNextHydratableSibling: function (instance) { var node = instance.nextSibling; // Skip non-hydratable nodes. while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE) { node = node.nextSibling; } return node; }, getFirstHydratableChild: function (parentInstance) { var next = parentInstance.firstChild; // Skip non-hydratable nodes. while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE) { next = next.nextSibling; } return next; }, hydrateInstance: function (instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) { precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events // get attached. updateFiberProps(instance, props); var parentNamespace = void 0; { var hostContextDev = hostContext; parentNamespace = hostContextDev.namespace; } return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance); }, hydrateTextInstance: function (textInstance, text, internalInstanceHandle) { precacheFiberNode(internalInstanceHandle, textInstance); return diffHydratedText(textInstance, text); }, didNotHydrateInstance: function (parentInstance, instance) { if (instance.nodeType === 1) { warnForDeletedHydratableElement(parentInstance, instance); } else { warnForDeletedHydratableText(parentInstance, instance); } }, didNotFindHydratableInstance: function (parentInstance, type, props) { warnForInsertedHydratedElement(parentInstance, type, props); }, didNotFindHydratableTextInstance: function (parentInstance, text) { warnForInsertedHydratedText(parentInstance, text); }, scheduleDeferredCallback: ReactDOMFrameScheduling.rIC, useSyncScheduling: !ReactDOMFeatureFlags_1.fiberAsyncScheduling }); ReactGenericBatching_1.injection.injectFiberBatchedUpdates(DOMRenderer.batchedUpdates); var warnedAboutHydrateAPI = false; function renderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) { !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0; { if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) { var hostInstance = DOMRenderer.findHostInstanceWithNoPortals(container._reactRootContainer.current); if (hostInstance) { warning(hostInstance.parentNode === container, 'render(...): It looks like the React-rendered content of this ' + 'container was removed without using React. This is not ' + 'supported and will cause errors. Instead, call ' + 'ReactDOM.unmountComponentAtNode to empty a container.'); } } var isRootRenderedBySomeReact = !!container._reactRootContainer; var rootEl = getReactRootElementInContainer(container); var hasNonRootReactChild = !!(rootEl && ReactDOMComponentTree_1.getInstanceFromNode(rootEl)); warning(!hasNonRootReactChild || isRootRenderedBySomeReact, 'render(...): Replacing React-rendered children with a new root ' + 'component. If you intended to update the children of this node, ' + 'you should instead have the existing children update their state ' + 'and render the new components instead of calling ReactDOM.render.'); warning(container.nodeType !== ELEMENT_NODE || !container.tagName || container.tagName.toUpperCase() !== 'BODY', 'render(): Rendering components directly into document.body is ' + 'discouraged, since its children are often manipulated by third-party ' + 'scripts and browser extensions. This may lead to subtle ' + 'reconciliation issues. Try rendering into a container element created ' + 'for your app.'); } var root = container._reactRootContainer; if (!root) { var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container); // First clear any existing content. if (!shouldHydrate) { var warned = false; var rootSibling = void 0; while (rootSibling = container.lastChild) { { if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) { warned = true; warning(false, 'render(): Target node has markup rendered by React, but there ' + 'are unrelated nodes as well. This is most commonly caused by ' + 'white-space inserted around server-rendered markup.'); } } container.removeChild(rootSibling); } } { if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) { warnedAboutHydrateAPI = true; lowPriorityWarning(false, 'render(): Calling ReactDOM.render() to hydrate server-rendered markup ' + 'will stop working in React v17. Replace the ReactDOM.render() call ' + 'with ReactDOM.hydrate() if you want React to attach to the server HTML.'); } } var newRoot = DOMRenderer.createContainer(container); root = container._reactRootContainer = newRoot; // Initial mount should not be batched. DOMRenderer.unbatchedUpdates(function () { DOMRenderer.updateContainer(children, newRoot, parentComponent, callback); }); } else { DOMRenderer.updateContainer(children, root, parentComponent, callback); } return DOMRenderer.getPublicRootInstance(root); } function createPortal(children, container) { var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0; // TODO: pass ReactDOM portal implementation as third argument return ReactPortal.createPortal(children, container, null, key); } var ReactDOMFiber = { createPortal: createPortal, hydrate: function (element, container, callback) { // TODO: throw or warn if we couldn't hydrate? return renderSubtreeIntoContainer(null, element, container, true, callback); }, render: function (element, container, callback) { return renderSubtreeIntoContainer(null, element, container, false, callback); }, unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) { !(parentComponent != null && ReactInstanceMap_1.has(parentComponent)) ? invariant(false, 'parentComponent must be a valid React Component') : void 0; return renderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback); }, unmountComponentAtNode: function (container) { !isValidContainer(container) ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : void 0; if (container._reactRootContainer) { { var rootEl = getReactRootElementInContainer(container); var renderedByDifferentReact = rootEl && !ReactDOMComponentTree_1.getInstanceFromNode(rootEl); warning(!renderedByDifferentReact, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.'); } // Unmount should not be batched. DOMRenderer.unbatchedUpdates(function () { renderSubtreeIntoContainer(null, null, container, false, function () { container._reactRootContainer = null; }); }); // If you call unmountComponentAtNode twice in quick succession, you'll // get `true` twice. That's probably fine? return true; } else { { var _rootEl = getReactRootElementInContainer(container); var hasNonRootReactChild = !!(_rootEl && ReactDOMComponentTree_1.getInstanceFromNode(_rootEl)); // Check if the container itself is a React root node. var isContainerReactRoot = container.nodeType === 1 && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer; warning(!hasNonRootReactChild, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by React and is not a top-level container. %s', isContainerReactRoot ? 'You may have accidentally passed in a React root node instead ' + 'of its container.' : 'Instead, have the parent component update its state and ' + 'rerender in order to remove this component.'); } return false; } }, findDOMNode: findDOMNode_1, // Temporary alias since we already shipped React 16 RC with it. // TODO: remove in React 17. unstable_createPortal: createPortal, unstable_batchedUpdates: ReactGenericBatching_1.batchedUpdates, unstable_deferredUpdates: DOMRenderer.deferredUpdates, flushSync: DOMRenderer.flushSync, __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { // For TapEventPlugin which is popular in open source EventPluginHub: EventPluginHub_1, // Used by test-utils EventPluginRegistry: EventPluginRegistry_1, EventPropagators: EventPropagators_1, ReactControlledComponent: ReactControlledComponent_1, ReactDOMComponentTree: ReactDOMComponentTree_1, ReactDOMEventListener: ReactDOMEventListener_1 } }; var foundDevTools = injectInternals({ findFiberByHostInstance: ReactDOMComponentTree_1.getClosestInstanceFromNode, findHostInstanceByFiber: DOMRenderer.findHostInstance, // This is an enum because we may add more (e.g. profiler build) bundleType: 1, version: ReactVersion, rendererPackageName: 'react-dom' }); { if (!foundDevTools && ExecutionEnvironment.canUseDOM && window.top === window.self) { // If we're in Chrome or Firefox, provide a download link if not installed. if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) { var protocol = window.location.protocol; // Don't warn in exotic cases like chrome-extension://. if (/^(https?|file):$/.test(protocol)) { console.info('%cDownload the React DevTools ' + 'for a better development experience: ' + 'https://fb.me/react-devtools' + (protocol === 'file:' ? '\nYou might need to use a local HTTP server (instead of file://): ' + 'https://fb.me/react-devtools-faq' : ''), 'font-weight:bold'); } } } } var ReactDOMFiberEntry = ReactDOMFiber; module.exports = ReactDOMFiberEntry; })(); }