react-dom-dev.mjs (792090B)
1 /** @license React v16.8.6 2 * react-dom.development.js 3 * 4 * Copyright (c) Facebook, Inc. and its affiliates. 5 * 6 * This source code is licensed under the MIT license found in the 7 * LICENSE file in the root directory of this source tree. 8 */ 9 10 'use strict'; 11 12 import React from 'resource://devtools/client/shared/vendor/react.mjs'; 13 14 /** 15 * Use invariant() to assert state which your program assumes to be true. 16 * 17 * Provide sprintf-style format (only %s is supported) and arguments 18 * to provide information about what broke and what you were 19 * expecting. 20 * 21 * The invariant message will be stripped in production, but the invariant 22 * will remain to ensure logic does not differ in production. 23 */ 24 25 var validateFormat = function () {}; 26 27 { 28 validateFormat = function (format) { 29 if (format === undefined) { 30 throw new Error('invariant requires an error message argument'); 31 } 32 }; 33 } 34 35 function invariant(condition, format, a, b, c, d, e, f) { 36 validateFormat(format); 37 38 if (!condition) { 39 var error = void 0; 40 if (format === undefined) { 41 error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); 42 } else { 43 var args = [a, b, c, d, e, f]; 44 var argIndex = 0; 45 error = new Error(format.replace(/%s/g, function () { 46 return args[argIndex++]; 47 })); 48 error.name = 'Invariant Violation'; 49 } 50 51 error.framesToPop = 1; // we don't care about invariant's own frame 52 throw error; 53 } 54 } 55 56 // Relying on the `invariant()` implementation lets us 57 // preserve the format and params in the www builds. 58 59 !React ? invariant(false, 'ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.') : void 0; 60 61 var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) { 62 var funcArgs = Array.prototype.slice.call(arguments, 3); 63 try { 64 func.apply(context, funcArgs); 65 } catch (error) { 66 this.onError(error); 67 } 68 }; 69 70 { 71 // In DEV mode, we swap out invokeGuardedCallback for a special version 72 // that plays more nicely with the browser's DevTools. The idea is to preserve 73 // "Pause on exceptions" behavior. Because React wraps all user-provided 74 // functions in invokeGuardedCallback, and the production version of 75 // invokeGuardedCallback uses a try-catch, all user exceptions are treated 76 // like caught exceptions, and the DevTools won't pause unless the developer 77 // takes the extra step of enabling pause on caught exceptions. This is 78 // unintuitive, though, because even though React has caught the error, from 79 // the developer's perspective, the error is uncaught. 80 // 81 // To preserve the expected "Pause on exceptions" behavior, we don't use a 82 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake 83 // DOM node, and call the user-provided callback from inside an event handler 84 // for that fake event. If the callback throws, the error is "captured" using 85 // a global event handler. But because the error happens in a different 86 // event loop context, it does not interrupt the normal program flow. 87 // Effectively, this gives us try-catch behavior without actually using 88 // try-catch. Neat! 89 90 // Check that the browser supports the APIs we need to implement our special 91 // DEV version of invokeGuardedCallback 92 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') { 93 var fakeNode = document.createElementNS('http://www.w3.org/1999/xhtml', 'react'); 94 95 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) { 96 // If document doesn't exist we know for sure we will crash in this method 97 // when we call document.createEvent(). However this can cause confusing 98 // errors: https://github.com/facebookincubator/create-react-app/issues/3482 99 // So we preemptively throw with a better message instead. 100 !(typeof document !== 'undefined') ? invariant(false, 'The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous.') : void 0; 101 var evt = document.createEvent('Event'); 102 103 // Keeps track of whether the user-provided callback threw an error. We 104 // set this to true at the beginning, then set it to false right after 105 // calling the function. If the function errors, `didError` will never be 106 // set to false. This strategy works even if the browser is flaky and 107 // fails to call our global error handler, because it doesn't rely on 108 // the error event at all. 109 var didError = true; 110 111 // Keeps track of the value of window.event so that we can reset it 112 // during the callback to let user code access window.event in the 113 // browsers that support it. 114 var windowEvent = window.event; 115 116 // Keeps track of the descriptor of window.event to restore it after event 117 // dispatching: https://github.com/facebook/react/issues/13688 118 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event'); 119 120 // Create an event handler for our fake event. We will synchronously 121 // dispatch our fake event using `dispatchEvent`. Inside the handler, we 122 // call the user-provided callback. 123 var funcArgs = Array.prototype.slice.call(arguments, 3); 124 function callCallback() { 125 // We immediately remove the callback from event listeners so that 126 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a 127 // nested call would trigger the fake event handlers of any call higher 128 // in the stack. 129 fakeNode.removeEventListener(evtType, callCallback, false); 130 131 // We check for window.hasOwnProperty('event') to prevent the 132 // window.event assignment in both IE <= 10 as they throw an error 133 // "Member not found" in strict mode, and in Firefox which does not 134 // support window.event. 135 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) { 136 window.event = windowEvent; 137 } 138 139 func.apply(context, funcArgs); 140 didError = false; 141 } 142 143 // Create a global error event handler. We use this to capture the value 144 // that was thrown. It's possible that this error handler will fire more 145 // than once; for example, if non-React code also calls `dispatchEvent` 146 // and a handler for that event throws. We should be resilient to most of 147 // those cases. Even if our error event handler fires more than once, the 148 // last error event is always used. If the callback actually does error, 149 // we know that the last error event is the correct one, because it's not 150 // possible for anything else to have happened in between our callback 151 // erroring and the code that follows the `dispatchEvent` call below. If 152 // the callback doesn't error, but the error event was fired, we know to 153 // ignore it because `didError` will be false, as described above. 154 var error = void 0; 155 // Use this to track whether the error event is ever called. 156 var didSetError = false; 157 var isCrossOriginError = false; 158 159 function handleWindowError(event) { 160 error = event.error; 161 didSetError = true; 162 if (error === null && event.colno === 0 && event.lineno === 0) { 163 isCrossOriginError = true; 164 } 165 if (event.defaultPrevented) { 166 // Some other error handler has prevented default. 167 // Browsers silence the error report if this happens. 168 // We'll remember this to later decide whether to log it or not. 169 if (error != null && typeof error === 'object') { 170 try { 171 error._suppressLogging = true; 172 } catch (inner) { 173 // Ignore. 174 } 175 } 176 } 177 } 178 179 // Create a fake event type. 180 var evtType = 'react-' + (name ? name : 'invokeguardedcallback'); 181 182 // Attach our event handlers 183 window.addEventListener('error', handleWindowError); 184 fakeNode.addEventListener(evtType, callCallback, false); 185 186 // Synchronously dispatch our fake event. If the user-provided function 187 // errors, it will trigger our global error handler. 188 evt.initEvent(evtType, false, false); 189 fakeNode.dispatchEvent(evt); 190 191 if (windowEventDescriptor) { 192 Object.defineProperty(window, 'event', windowEventDescriptor); 193 } 194 195 if (didError) { 196 if (!didSetError) { 197 // The callback errored, but the error event never fired. 198 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.'); 199 } else if (isCrossOriginError) { 200 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.'); 201 } 202 this.onError(error); 203 } 204 205 // Remove our event listeners 206 window.removeEventListener('error', handleWindowError); 207 }; 208 209 invokeGuardedCallbackImpl = invokeGuardedCallbackDev; 210 } 211 } 212 213 var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl; 214 215 // Used by Fiber to simulate a try-catch. 216 var hasError = false; 217 var caughtError = null; 218 219 // Used by event system to capture/rethrow the first error. 220 var hasRethrowError = false; 221 var rethrowError = null; 222 223 var reporter = { 224 onError: function (error) { 225 hasError = true; 226 caughtError = error; 227 } 228 }; 229 230 /** 231 * Call a function while guarding against errors that happens within it. 232 * Returns an error if it throws, otherwise null. 233 * 234 * In production, this is implemented using a try-catch. The reason we don't 235 * use a try-catch directly is so that we can swap out a different 236 * implementation in DEV mode. 237 * 238 * @param {String} name of the guard to use for logging or debugging 239 * @param {Function} func The function to invoke 240 * @param {*} context The context to use when calling the function 241 * @param {...*} args Arguments for function 242 */ 243 function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) { 244 hasError = false; 245 caughtError = null; 246 invokeGuardedCallbackImpl$1.apply(reporter, arguments); 247 } 248 249 /** 250 * Same as invokeGuardedCallback, but instead of returning an error, it stores 251 * it in a global so it can be rethrown by `rethrowCaughtError` later. 252 * TODO: See if caughtError and rethrowError can be unified. 253 * 254 * @param {String} name of the guard to use for logging or debugging 255 * @param {Function} func The function to invoke 256 * @param {*} context The context to use when calling the function 257 * @param {...*} args Arguments for function 258 */ 259 function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) { 260 invokeGuardedCallback.apply(this, arguments); 261 if (hasError) { 262 var error = clearCaughtError(); 263 if (!hasRethrowError) { 264 hasRethrowError = true; 265 rethrowError = error; 266 } 267 } 268 } 269 270 /** 271 * During execution of guarded functions we will capture the first error which 272 * we will rethrow to be handled by the top level error handler. 273 */ 274 function rethrowCaughtError() { 275 if (hasRethrowError) { 276 var error = rethrowError; 277 hasRethrowError = false; 278 rethrowError = null; 279 throw error; 280 } 281 } 282 283 function hasCaughtError() { 284 return hasError; 285 } 286 287 function clearCaughtError() { 288 if (hasError) { 289 var error = caughtError; 290 hasError = false; 291 caughtError = null; 292 return error; 293 } else { 294 invariant(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.'); 295 } 296 } 297 298 /** 299 * Injectable ordering of event plugins. 300 */ 301 var eventPluginOrder = null; 302 303 /** 304 * Injectable mapping from names to event plugin modules. 305 */ 306 var namesToPlugins = {}; 307 308 /** 309 * Recomputes the plugin list using the injected plugins and plugin ordering. 310 * 311 * @private 312 */ 313 function recomputePluginOrdering() { 314 if (!eventPluginOrder) { 315 // Wait until an `eventPluginOrder` is injected. 316 return; 317 } 318 for (var pluginName in namesToPlugins) { 319 var pluginModule = namesToPlugins[pluginName]; 320 var pluginIndex = eventPluginOrder.indexOf(pluginName); 321 !(pluginIndex > -1) ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : void 0; 322 if (plugins[pluginIndex]) { 323 continue; 324 } 325 !pluginModule.extractEvents ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : void 0; 326 plugins[pluginIndex] = pluginModule; 327 var publishedEvents = pluginModule.eventTypes; 328 for (var eventName in publishedEvents) { 329 !publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : void 0; 330 } 331 } 332 } 333 334 /** 335 * Publishes an event so that it can be dispatched by the supplied plugin. 336 * 337 * @param {object} dispatchConfig Dispatch configuration for the event. 338 * @param {object} PluginModule Plugin publishing the event. 339 * @return {boolean} True if the event was successfully published. 340 * @private 341 */ 342 function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { 343 !!eventNameDispatchConfigs.hasOwnProperty(eventName) ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : void 0; 344 eventNameDispatchConfigs[eventName] = dispatchConfig; 345 346 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; 347 if (phasedRegistrationNames) { 348 for (var phaseName in phasedRegistrationNames) { 349 if (phasedRegistrationNames.hasOwnProperty(phaseName)) { 350 var phasedRegistrationName = phasedRegistrationNames[phaseName]; 351 publishRegistrationName(phasedRegistrationName, pluginModule, eventName); 352 } 353 } 354 return true; 355 } else if (dispatchConfig.registrationName) { 356 publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName); 357 return true; 358 } 359 return false; 360 } 361 362 /** 363 * Publishes a registration name that is used to identify dispatched events. 364 * 365 * @param {string} registrationName Registration name to add. 366 * @param {object} PluginModule Plugin publishing the event. 367 * @private 368 */ 369 function publishRegistrationName(registrationName, pluginModule, eventName) { 370 !!registrationNameModules[registrationName] ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : void 0; 371 registrationNameModules[registrationName] = pluginModule; 372 registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies; 373 374 { 375 var lowerCasedName = registrationName.toLowerCase(); 376 possibleRegistrationNames[lowerCasedName] = registrationName; 377 378 if (registrationName === 'onDoubleClick') { 379 possibleRegistrationNames.ondblclick = registrationName; 380 } 381 } 382 } 383 384 /** 385 * Registers plugins so that they can extract and dispatch events. 386 * 387 * @see {EventPluginHub} 388 */ 389 390 /** 391 * Ordered list of injected plugins. 392 */ 393 var plugins = []; 394 395 /** 396 * Mapping from event name to dispatch config 397 */ 398 var eventNameDispatchConfigs = {}; 399 400 /** 401 * Mapping from registration name to plugin module 402 */ 403 var registrationNameModules = {}; 404 405 /** 406 * Mapping from registration name to event name 407 */ 408 var registrationNameDependencies = {}; 409 410 /** 411 * Mapping from lowercase registration names to the properly cased version, 412 * used to warn in the case of missing event handlers. Available 413 * only in true. 414 * @type {Object} 415 */ 416 var possibleRegistrationNames = {}; 417 // Trust the developer to only use possibleRegistrationNames in true 418 419 /** 420 * Injects an ordering of plugins (by plugin name). This allows the ordering 421 * to be decoupled from injection of the actual plugins so that ordering is 422 * always deterministic regardless of packaging, on-the-fly injection, etc. 423 * 424 * @param {array} InjectedEventPluginOrder 425 * @internal 426 * @see {EventPluginHub.injection.injectEventPluginOrder} 427 */ 428 function injectEventPluginOrder(injectedEventPluginOrder) { 429 !!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; 430 // Clone the ordering so it cannot be dynamically mutated. 431 eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); 432 recomputePluginOrdering(); 433 } 434 435 /** 436 * Injects plugins to be used by `EventPluginHub`. The plugin names must be 437 * in the ordering injected by `injectEventPluginOrder`. 438 * 439 * Plugins can be injected as part of page initialization or on-the-fly. 440 * 441 * @param {object} injectedNamesToPlugins Map from names to plugin modules. 442 * @internal 443 * @see {EventPluginHub.injection.injectEventPluginsByName} 444 */ 445 function injectEventPluginsByName(injectedNamesToPlugins) { 446 var isOrderingDirty = false; 447 for (var pluginName in injectedNamesToPlugins) { 448 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { 449 continue; 450 } 451 var pluginModule = injectedNamesToPlugins[pluginName]; 452 if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) { 453 !!namesToPlugins[pluginName] ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : void 0; 454 namesToPlugins[pluginName] = pluginModule; 455 isOrderingDirty = true; 456 } 457 } 458 if (isOrderingDirty) { 459 recomputePluginOrdering(); 460 } 461 } 462 463 /** 464 * Similar to invariant but only logs a warning if the condition is not met. 465 * This can be used to log issues in development environments in critical 466 * paths. Removing the logging code for production environments will keep the 467 * same logic and follow the same code paths. 468 */ 469 470 var warningWithoutStack = function () {}; 471 472 { 473 warningWithoutStack = function (condition, format) { 474 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { 475 args[_key - 2] = arguments[_key]; 476 } 477 478 if (format === undefined) { 479 throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument'); 480 } 481 if (args.length > 8) { 482 // Check before the condition to catch violations early. 483 throw new Error('warningWithoutStack() currently supports at most 8 arguments.'); 484 } 485 if (condition) { 486 return; 487 } 488 if (typeof console !== 'undefined') { 489 var argsWithFormat = args.map(function (item) { 490 return '' + item; 491 }); 492 argsWithFormat.unshift('Warning: ' + format); 493 494 // We intentionally don't use spread (or .apply) directly because it 495 // breaks IE9: https://github.com/facebook/react/issues/13610 496 Function.prototype.apply.call(console.error, console, argsWithFormat); 497 } 498 try { 499 // --- Welcome to debugging React --- 500 // This error was thrown as a convenience so that you can use this stack 501 // to find the callsite that caused this warning to fire. 502 var argIndex = 0; 503 var message = 'Warning: ' + format.replace(/%s/g, function () { 504 return args[argIndex++]; 505 }); 506 throw new Error(message); 507 } catch (x) {} 508 }; 509 } 510 511 var warningWithoutStack$1 = warningWithoutStack; 512 513 var getFiberCurrentPropsFromNode = null; 514 var getInstanceFromNode = null; 515 var getNodeFromInstance = null; 516 517 function setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) { 518 getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl; 519 getInstanceFromNode = getInstanceFromNodeImpl; 520 getNodeFromInstance = getNodeFromInstanceImpl; 521 { 522 !(getNodeFromInstance && getInstanceFromNode) ? warningWithoutStack$1(false, 'EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0; 523 } 524 } 525 526 var validateEventDispatches = void 0; 527 { 528 validateEventDispatches = function (event) { 529 var dispatchListeners = event._dispatchListeners; 530 var dispatchInstances = event._dispatchInstances; 531 532 var listenersIsArr = Array.isArray(dispatchListeners); 533 var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0; 534 535 var instancesIsArr = Array.isArray(dispatchInstances); 536 var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0; 537 538 !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) ? warningWithoutStack$1(false, 'EventPluginUtils: Invalid `event`.') : void 0; 539 }; 540 } 541 542 /** 543 * Dispatch the event to the listener. 544 * @param {SyntheticEvent} event SyntheticEvent to handle 545 * @param {function} listener Application-level callback 546 * @param {*} inst Internal component instance 547 */ 548 function executeDispatch(event, listener, inst) { 549 var type = event.type || 'unknown-event'; 550 event.currentTarget = getNodeFromInstance(inst); 551 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event); 552 event.currentTarget = null; 553 } 554 555 /** 556 * Standard/simple iteration through an event's collected dispatches. 557 */ 558 function executeDispatchesInOrder(event) { 559 var dispatchListeners = event._dispatchListeners; 560 var dispatchInstances = event._dispatchInstances; 561 { 562 validateEventDispatches(event); 563 } 564 if (Array.isArray(dispatchListeners)) { 565 for (var i = 0; i < dispatchListeners.length; i++) { 566 if (event.isPropagationStopped()) { 567 break; 568 } 569 // Listeners and Instances are two parallel arrays that are always in sync. 570 executeDispatch(event, dispatchListeners[i], dispatchInstances[i]); 571 } 572 } else if (dispatchListeners) { 573 executeDispatch(event, dispatchListeners, dispatchInstances); 574 } 575 event._dispatchListeners = null; 576 event._dispatchInstances = null; 577 } 578 579 /** 580 * @see executeDispatchesInOrderStopAtTrueImpl 581 */ 582 583 584 /** 585 * Execution of a "direct" dispatch - there must be at most one dispatch 586 * accumulated on the event or it is considered an error. It doesn't really make 587 * sense for an event with multiple dispatches (bubbled) to keep track of the 588 * return values at each dispatch execution, but it does tend to make sense when 589 * dealing with "direct" dispatches. 590 * 591 * @return {*} The return value of executing the single dispatch. 592 */ 593 594 595 /** 596 * @param {SyntheticEvent} event 597 * @return {boolean} True iff number of dispatches accumulated is greater than 0. 598 */ 599 600 /** 601 * Accumulates items that must not be null or undefined into the first one. This 602 * is used to conserve memory by avoiding array allocations, and thus sacrifices 603 * API cleanness. Since `current` can be null before being passed in and not 604 * null after this function, make sure to assign it back to `current`: 605 * 606 * `a = accumulateInto(a, b);` 607 * 608 * This API should be sparingly used. Try `accumulate` for something cleaner. 609 * 610 * @return {*|array<*>} An accumulation of items. 611 */ 612 613 function accumulateInto(current, next) { 614 !(next != null) ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : void 0; 615 616 if (current == null) { 617 return next; 618 } 619 620 // Both are not empty. Warning: Never call x.concat(y) when you are not 621 // certain that x is an Array (x could be a string with concat method). 622 if (Array.isArray(current)) { 623 if (Array.isArray(next)) { 624 current.push.apply(current, next); 625 return current; 626 } 627 current.push(next); 628 return current; 629 } 630 631 if (Array.isArray(next)) { 632 // A bit too dangerous to mutate `next`. 633 return [current].concat(next); 634 } 635 636 return [current, next]; 637 } 638 639 /** 640 * @param {array} arr an "accumulation" of items which is either an Array or 641 * a single item. Useful when paired with the `accumulate` module. This is a 642 * simple utility that allows us to reason about a collection of items, but 643 * handling the case when there is exactly one item (and we do not need to 644 * allocate an array). 645 * @param {function} cb Callback invoked with each element or a collection. 646 * @param {?} [scope] Scope used as `this` in a callback. 647 */ 648 function forEachAccumulated(arr, cb, scope) { 649 if (Array.isArray(arr)) { 650 arr.forEach(cb, scope); 651 } else if (arr) { 652 cb.call(scope, arr); 653 } 654 } 655 656 /** 657 * Internal queue of events that have accumulated their dispatches and are 658 * waiting to have their dispatches executed. 659 */ 660 var eventQueue = null; 661 662 /** 663 * Dispatches an event and releases it back into the pool, unless persistent. 664 * 665 * @param {?object} event Synthetic event to be dispatched. 666 * @private 667 */ 668 var executeDispatchesAndRelease = function (event) { 669 if (event) { 670 executeDispatchesInOrder(event); 671 672 if (!event.isPersistent()) { 673 event.constructor.release(event); 674 } 675 } 676 }; 677 var executeDispatchesAndReleaseTopLevel = function (e) { 678 return executeDispatchesAndRelease(e); 679 }; 680 681 function isInteractive(tag) { 682 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea'; 683 } 684 685 function shouldPreventMouseEvent(name, type, props) { 686 switch (name) { 687 case 'onClick': 688 case 'onClickCapture': 689 case 'onDoubleClick': 690 case 'onDoubleClickCapture': 691 case 'onMouseDown': 692 case 'onMouseDownCapture': 693 case 'onMouseMove': 694 case 'onMouseMoveCapture': 695 case 'onMouseUp': 696 case 'onMouseUpCapture': 697 return !!(props.disabled && isInteractive(type)); 698 default: 699 return false; 700 } 701 } 702 703 /** 704 * This is a unified interface for event plugins to be installed and configured. 705 * 706 * Event plugins can implement the following properties: 707 * 708 * `extractEvents` {function(string, DOMEventTarget, string, object): *} 709 * Required. When a top-level event is fired, this method is expected to 710 * extract synthetic events that will in turn be queued and dispatched. 711 * 712 * `eventTypes` {object} 713 * Optional, plugins that fire events must publish a mapping of registration 714 * names that are used to register listeners. Values of this mapping must 715 * be objects that contain `registrationName` or `phasedRegistrationNames`. 716 * 717 * `executeDispatch` {function(object, function, string)} 718 * Optional, allows plugins to override how an event gets dispatched. By 719 * default, the listener is simply invoked. 720 * 721 * Each plugin that is injected into `EventsPluginHub` is immediately operable. 722 * 723 * @public 724 */ 725 726 /** 727 * Methods for injecting dependencies. 728 */ 729 var injection = { 730 /** 731 * @param {array} InjectedEventPluginOrder 732 * @public 733 */ 734 injectEventPluginOrder: injectEventPluginOrder, 735 736 /** 737 * @param {object} injectedNamesToPlugins Map from names to plugin modules. 738 */ 739 injectEventPluginsByName: injectEventPluginsByName 740 }; 741 742 /** 743 * @param {object} inst The instance, which is the source of events. 744 * @param {string} registrationName Name of listener (e.g. `onClick`). 745 * @return {?function} The stored callback. 746 */ 747 function getListener(inst, registrationName) { 748 var listener = void 0; 749 750 // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not 751 // live here; needs to be moved to a better place soon 752 var stateNode = inst.stateNode; 753 if (!stateNode) { 754 // Work in progress (ex: onload events in incremental mode). 755 return null; 756 } 757 var props = getFiberCurrentPropsFromNode(stateNode); 758 if (!props) { 759 // Work in progress. 760 return null; 761 } 762 listener = props[registrationName]; 763 if (shouldPreventMouseEvent(registrationName, inst.type, props)) { 764 return null; 765 } 766 !(!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; 767 return listener; 768 } 769 770 /** 771 * Allows registered plugins an opportunity to extract events from top-level 772 * native browser events. 773 * 774 * @return {*} An accumulation of synthetic events. 775 * @internal 776 */ 777 function extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) { 778 var events = null; 779 for (var i = 0; i < plugins.length; i++) { 780 // Not every plugin in the ordering may be loaded at runtime. 781 var possiblePlugin = plugins[i]; 782 if (possiblePlugin) { 783 var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); 784 if (extractedEvents) { 785 events = accumulateInto(events, extractedEvents); 786 } 787 } 788 } 789 return events; 790 } 791 792 function runEventsInBatch(events) { 793 if (events !== null) { 794 eventQueue = accumulateInto(eventQueue, events); 795 } 796 797 // Set `eventQueue` to null before processing it so that we can tell if more 798 // events get enqueued while processing. 799 var processingEventQueue = eventQueue; 800 eventQueue = null; 801 802 if (!processingEventQueue) { 803 return; 804 } 805 806 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); 807 !!eventQueue ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : void 0; 808 // This would be a good time to rethrow if any of the event handlers threw. 809 rethrowCaughtError(); 810 } 811 812 function runExtractedEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) { 813 var events = extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); 814 runEventsInBatch(events); 815 } 816 817 var FunctionComponent = 0; 818 var ClassComponent = 1; 819 var IndeterminateComponent = 2; // Before we know whether it is function or class 820 var HostRoot = 3; // Root of a host tree. Could be nested inside another node. 821 var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. 822 var HostComponent = 5; 823 var HostText = 6; 824 var Fragment = 7; 825 var Mode = 8; 826 var ContextConsumer = 9; 827 var ContextProvider = 10; 828 var ForwardRef = 11; 829 var Profiler = 12; 830 var SuspenseComponent = 13; 831 var MemoComponent = 14; 832 var SimpleMemoComponent = 15; 833 var LazyComponent = 16; 834 var IncompleteClassComponent = 17; 835 var DehydratedSuspenseComponent = 18; 836 837 var randomKey = Math.random().toString(36).slice(2); 838 var internalInstanceKey = '__reactInternalInstance$' + randomKey; 839 var internalEventHandlersKey = '__reactEventHandlers$' + randomKey; 840 841 function precacheFiberNode(hostInst, node) { 842 node[internalInstanceKey] = hostInst; 843 } 844 845 /** 846 * Given a DOM node, return the closest ReactDOMComponent or 847 * ReactDOMTextComponent instance ancestor. 848 */ 849 function getClosestInstanceFromNode(node) { 850 if (node[internalInstanceKey]) { 851 return node[internalInstanceKey]; 852 } 853 854 while (!node[internalInstanceKey]) { 855 if (node.parentNode) { 856 node = node.parentNode; 857 } else { 858 // Top of the tree. This node must not be part of a React tree (or is 859 // unmounted, potentially). 860 return null; 861 } 862 } 863 864 var inst = node[internalInstanceKey]; 865 if (inst.tag === HostComponent || inst.tag === HostText) { 866 // In Fiber, this will always be the deepest root. 867 return inst; 868 } 869 870 return null; 871 } 872 873 /** 874 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent 875 * instance, or null if the node was not rendered by this React. 876 */ 877 function getInstanceFromNode$1(node) { 878 var inst = node[internalInstanceKey]; 879 if (inst) { 880 if (inst.tag === HostComponent || inst.tag === HostText) { 881 return inst; 882 } else { 883 return null; 884 } 885 } 886 return null; 887 } 888 889 /** 890 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding 891 * DOM node. 892 */ 893 function getNodeFromInstance$1(inst) { 894 if (inst.tag === HostComponent || inst.tag === HostText) { 895 // In Fiber this, is just the state node right now. We assume it will be 896 // a host component or host text. 897 return inst.stateNode; 898 } 899 900 // Without this first invariant, passing a non-DOM-component triggers the next 901 // invariant for a missing parent, which is super confusing. 902 invariant(false, 'getNodeFromInstance: Invalid argument.'); 903 } 904 905 function getFiberCurrentPropsFromNode$1(node) { 906 return node[internalEventHandlersKey] || null; 907 } 908 909 function updateFiberProps(node, props) { 910 node[internalEventHandlersKey] = props; 911 } 912 913 function getParent(inst) { 914 do { 915 inst = inst.return; 916 // TODO: If this is a HostRoot we might want to bail out. 917 // That is depending on if we want nested subtrees (layers) to bubble 918 // events to their parent. We could also go through parentNode on the 919 // host node but that wouldn't work for React Native and doesn't let us 920 // do the portal feature. 921 } while (inst && inst.tag !== HostComponent); 922 if (inst) { 923 return inst; 924 } 925 return null; 926 } 927 928 /** 929 * Return the lowest common ancestor of A and B, or null if they are in 930 * different trees. 931 */ 932 function getLowestCommonAncestor(instA, instB) { 933 var depthA = 0; 934 for (var tempA = instA; tempA; tempA = getParent(tempA)) { 935 depthA++; 936 } 937 var depthB = 0; 938 for (var tempB = instB; tempB; tempB = getParent(tempB)) { 939 depthB++; 940 } 941 942 // If A is deeper, crawl up. 943 while (depthA - depthB > 0) { 944 instA = getParent(instA); 945 depthA--; 946 } 947 948 // If B is deeper, crawl up. 949 while (depthB - depthA > 0) { 950 instB = getParent(instB); 951 depthB--; 952 } 953 954 // Walk in lockstep until we find a match. 955 var depth = depthA; 956 while (depth--) { 957 if (instA === instB || instA === instB.alternate) { 958 return instA; 959 } 960 instA = getParent(instA); 961 instB = getParent(instB); 962 } 963 return null; 964 } 965 966 /** 967 * Return if A is an ancestor of B. 968 */ 969 970 971 /** 972 * Return the parent instance of the passed-in instance. 973 */ 974 975 976 /** 977 * Simulates the traversal of a two-phase, capture/bubble event dispatch. 978 */ 979 function traverseTwoPhase(inst, fn, arg) { 980 var path = []; 981 while (inst) { 982 path.push(inst); 983 inst = getParent(inst); 984 } 985 var i = void 0; 986 for (i = path.length; i-- > 0;) { 987 fn(path[i], 'captured', arg); 988 } 989 for (i = 0; i < path.length; i++) { 990 fn(path[i], 'bubbled', arg); 991 } 992 } 993 994 /** 995 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that 996 * should would receive a `mouseEnter` or `mouseLeave` event. 997 * 998 * Does not invoke the callback on the nearest common ancestor because nothing 999 * "entered" or "left" that element. 1000 */ 1001 function traverseEnterLeave(from, to, fn, argFrom, argTo) { 1002 var common = from && to ? getLowestCommonAncestor(from, to) : null; 1003 var pathFrom = []; 1004 while (true) { 1005 if (!from) { 1006 break; 1007 } 1008 if (from === common) { 1009 break; 1010 } 1011 var alternate = from.alternate; 1012 if (alternate !== null && alternate === common) { 1013 break; 1014 } 1015 pathFrom.push(from); 1016 from = getParent(from); 1017 } 1018 var pathTo = []; 1019 while (true) { 1020 if (!to) { 1021 break; 1022 } 1023 if (to === common) { 1024 break; 1025 } 1026 var _alternate = to.alternate; 1027 if (_alternate !== null && _alternate === common) { 1028 break; 1029 } 1030 pathTo.push(to); 1031 to = getParent(to); 1032 } 1033 for (var i = 0; i < pathFrom.length; i++) { 1034 fn(pathFrom[i], 'bubbled', argFrom); 1035 } 1036 for (var _i = pathTo.length; _i-- > 0;) { 1037 fn(pathTo[_i], 'captured', argTo); 1038 } 1039 } 1040 1041 /** 1042 * Some event types have a notion of different registration names for different 1043 * "phases" of propagation. This finds listeners by a given phase. 1044 */ 1045 function listenerAtPhase(inst, event, propagationPhase) { 1046 var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase]; 1047 return getListener(inst, registrationName); 1048 } 1049 1050 /** 1051 * A small set of propagation patterns, each of which will accept a small amount 1052 * of information, and generate a set of "dispatch ready event objects" - which 1053 * are sets of events that have already been annotated with a set of dispatched 1054 * listener functions/ids. The API is designed this way to discourage these 1055 * propagation strategies from actually executing the dispatches, since we 1056 * always want to collect the entire set of dispatches before executing even a 1057 * single one. 1058 */ 1059 1060 /** 1061 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function 1062 * here, allows us to not have to bind or create functions for each event. 1063 * Mutating the event's members allows us to not have to create a wrapping 1064 * "dispatch" object that pairs the event with the listener. 1065 */ 1066 function accumulateDirectionalDispatches(inst, phase, event) { 1067 { 1068 !inst ? warningWithoutStack$1(false, 'Dispatching inst must not be null') : void 0; 1069 } 1070 var listener = listenerAtPhase(inst, event, phase); 1071 if (listener) { 1072 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener); 1073 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); 1074 } 1075 } 1076 1077 /** 1078 * Collect dispatches (must be entirely collected before dispatching - see unit 1079 * tests). Lazily allocate the array to conserve memory. We must loop through 1080 * each event and perform the traversal for each one. We cannot perform a 1081 * single traversal for the entire collection of events because each event may 1082 * have a different target. 1083 */ 1084 function accumulateTwoPhaseDispatchesSingle(event) { 1085 if (event && event.dispatchConfig.phasedRegistrationNames) { 1086 traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); 1087 } 1088 } 1089 1090 /** 1091 * Accumulates without regard to direction, does not look for phased 1092 * registration names. Same as `accumulateDirectDispatchesSingle` but without 1093 * requiring that the `dispatchMarker` be the same as the dispatched ID. 1094 */ 1095 function accumulateDispatches(inst, ignoredDirection, event) { 1096 if (inst && event && event.dispatchConfig.registrationName) { 1097 var registrationName = event.dispatchConfig.registrationName; 1098 var listener = getListener(inst, registrationName); 1099 if (listener) { 1100 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener); 1101 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); 1102 } 1103 } 1104 } 1105 1106 /** 1107 * Accumulates dispatches on an `SyntheticEvent`, but only for the 1108 * `dispatchMarker`. 1109 * @param {SyntheticEvent} event 1110 */ 1111 function accumulateDirectDispatchesSingle(event) { 1112 if (event && event.dispatchConfig.registrationName) { 1113 accumulateDispatches(event._targetInst, null, event); 1114 } 1115 } 1116 1117 function accumulateTwoPhaseDispatches(events) { 1118 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); 1119 } 1120 1121 1122 1123 function accumulateEnterLeaveDispatches(leave, enter, from, to) { 1124 traverseEnterLeave(from, to, accumulateDispatches, leave, enter); 1125 } 1126 1127 function accumulateDirectDispatches(events) { 1128 forEachAccumulated(events, accumulateDirectDispatchesSingle); 1129 } 1130 1131 var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); 1132 1133 // Do not uses the below two methods directly! 1134 // Instead use constants exported from DOMTopLevelEventTypes in ReactDOM. 1135 // (It is the only module that is allowed to access these methods.) 1136 1137 function unsafeCastStringToDOMTopLevelType(topLevelType) { 1138 return topLevelType; 1139 } 1140 1141 function unsafeCastDOMTopLevelTypeToString(topLevelType) { 1142 return topLevelType; 1143 } 1144 1145 /** 1146 * Generate a mapping of standard vendor prefixes using the defined style property and event name. 1147 * 1148 * @param {string} styleProp 1149 * @param {string} eventName 1150 * @returns {object} 1151 */ 1152 function makePrefixMap(styleProp, eventName) { 1153 var prefixes = {}; 1154 1155 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase(); 1156 prefixes['Webkit' + styleProp] = 'webkit' + eventName; 1157 prefixes['Moz' + styleProp] = 'moz' + eventName; 1158 1159 return prefixes; 1160 } 1161 1162 /** 1163 * A list of event names to a configurable list of vendor prefixes. 1164 */ 1165 var vendorPrefixes = { 1166 animationend: makePrefixMap('Animation', 'AnimationEnd'), 1167 animationiteration: makePrefixMap('Animation', 'AnimationIteration'), 1168 animationstart: makePrefixMap('Animation', 'AnimationStart'), 1169 transitionend: makePrefixMap('Transition', 'TransitionEnd') 1170 }; 1171 1172 /** 1173 * Event names that have already been detected and prefixed (if applicable). 1174 */ 1175 var prefixedEventNames = {}; 1176 1177 /** 1178 * Element to check for prefixes on. 1179 */ 1180 var style = {}; 1181 1182 /** 1183 * Bootstrap if a DOM exists. 1184 */ 1185 if (canUseDOM) { 1186 style = document.createElementNS('http://www.w3.org/1999/xhtml', 'div').style; 1187 1188 // On some platforms, in particular some releases of Android 4.x, 1189 // the un-prefixed "animation" and "transition" properties are defined on the 1190 // style object but the events that fire will still be prefixed, so we need 1191 // to check if the un-prefixed events are usable, and if not remove them from the map. 1192 if (!('AnimationEvent' in window)) { 1193 delete vendorPrefixes.animationend.animation; 1194 delete vendorPrefixes.animationiteration.animation; 1195 delete vendorPrefixes.animationstart.animation; 1196 } 1197 1198 // Same as above 1199 if (!('TransitionEvent' in window)) { 1200 delete vendorPrefixes.transitionend.transition; 1201 } 1202 } 1203 1204 /** 1205 * Attempts to determine the correct vendor prefixed event name. 1206 * 1207 * @param {string} eventName 1208 * @returns {string} 1209 */ 1210 function getVendorPrefixedEventName(eventName) { 1211 if (prefixedEventNames[eventName]) { 1212 return prefixedEventNames[eventName]; 1213 } else if (!vendorPrefixes[eventName]) { 1214 return eventName; 1215 } 1216 1217 var prefixMap = vendorPrefixes[eventName]; 1218 1219 for (var styleProp in prefixMap) { 1220 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) { 1221 return prefixedEventNames[eventName] = prefixMap[styleProp]; 1222 } 1223 } 1224 1225 return eventName; 1226 } 1227 1228 /** 1229 * To identify top level events in ReactDOM, we use constants defined by this 1230 * module. This is the only module that uses the unsafe* methods to express 1231 * that the constants actually correspond to the browser event names. This lets 1232 * us save some bundle size by avoiding a top level type -> event name map. 1233 * The rest of ReactDOM code should import top level types from this file. 1234 */ 1235 var TOP_ABORT = unsafeCastStringToDOMTopLevelType('abort'); 1236 var TOP_ANIMATION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationend')); 1237 var TOP_ANIMATION_ITERATION = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationiteration')); 1238 var TOP_ANIMATION_START = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationstart')); 1239 var TOP_BLUR = unsafeCastStringToDOMTopLevelType('blur'); 1240 var TOP_CAN_PLAY = unsafeCastStringToDOMTopLevelType('canplay'); 1241 var TOP_CAN_PLAY_THROUGH = unsafeCastStringToDOMTopLevelType('canplaythrough'); 1242 var TOP_CANCEL = unsafeCastStringToDOMTopLevelType('cancel'); 1243 var TOP_CHANGE = unsafeCastStringToDOMTopLevelType('change'); 1244 var TOP_CLICK = unsafeCastStringToDOMTopLevelType('click'); 1245 var TOP_CLOSE = unsafeCastStringToDOMTopLevelType('close'); 1246 var TOP_COMPOSITION_END = unsafeCastStringToDOMTopLevelType('compositionend'); 1247 var TOP_COMPOSITION_START = unsafeCastStringToDOMTopLevelType('compositionstart'); 1248 var TOP_COMPOSITION_UPDATE = unsafeCastStringToDOMTopLevelType('compositionupdate'); 1249 var TOP_CONTEXT_MENU = unsafeCastStringToDOMTopLevelType('contextmenu'); 1250 var TOP_COPY = unsafeCastStringToDOMTopLevelType('copy'); 1251 var TOP_CUT = unsafeCastStringToDOMTopLevelType('cut'); 1252 var TOP_DOUBLE_CLICK = unsafeCastStringToDOMTopLevelType('dblclick'); 1253 var TOP_AUX_CLICK = unsafeCastStringToDOMTopLevelType('auxclick'); 1254 var TOP_DRAG = unsafeCastStringToDOMTopLevelType('drag'); 1255 var TOP_DRAG_END = unsafeCastStringToDOMTopLevelType('dragend'); 1256 var TOP_DRAG_ENTER = unsafeCastStringToDOMTopLevelType('dragenter'); 1257 var TOP_DRAG_EXIT = unsafeCastStringToDOMTopLevelType('dragexit'); 1258 var TOP_DRAG_LEAVE = unsafeCastStringToDOMTopLevelType('dragleave'); 1259 var TOP_DRAG_OVER = unsafeCastStringToDOMTopLevelType('dragover'); 1260 var TOP_DRAG_START = unsafeCastStringToDOMTopLevelType('dragstart'); 1261 var TOP_DROP = unsafeCastStringToDOMTopLevelType('drop'); 1262 var TOP_DURATION_CHANGE = unsafeCastStringToDOMTopLevelType('durationchange'); 1263 var TOP_EMPTIED = unsafeCastStringToDOMTopLevelType('emptied'); 1264 var TOP_ENCRYPTED = unsafeCastStringToDOMTopLevelType('encrypted'); 1265 var TOP_ENDED = unsafeCastStringToDOMTopLevelType('ended'); 1266 var TOP_ERROR = unsafeCastStringToDOMTopLevelType('error'); 1267 var TOP_FOCUS = unsafeCastStringToDOMTopLevelType('focus'); 1268 var TOP_GOT_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('gotpointercapture'); 1269 var TOP_INPUT = unsafeCastStringToDOMTopLevelType('input'); 1270 var TOP_INVALID = unsafeCastStringToDOMTopLevelType('invalid'); 1271 var TOP_KEY_DOWN = unsafeCastStringToDOMTopLevelType('keydown'); 1272 var TOP_KEY_PRESS = unsafeCastStringToDOMTopLevelType('keypress'); 1273 var TOP_KEY_UP = unsafeCastStringToDOMTopLevelType('keyup'); 1274 var TOP_LOAD = unsafeCastStringToDOMTopLevelType('load'); 1275 var TOP_LOAD_START = unsafeCastStringToDOMTopLevelType('loadstart'); 1276 var TOP_LOADED_DATA = unsafeCastStringToDOMTopLevelType('loadeddata'); 1277 var TOP_LOADED_METADATA = unsafeCastStringToDOMTopLevelType('loadedmetadata'); 1278 var TOP_LOST_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('lostpointercapture'); 1279 var TOP_MOUSE_DOWN = unsafeCastStringToDOMTopLevelType('mousedown'); 1280 var TOP_MOUSE_MOVE = unsafeCastStringToDOMTopLevelType('mousemove'); 1281 var TOP_MOUSE_OUT = unsafeCastStringToDOMTopLevelType('mouseout'); 1282 var TOP_MOUSE_OVER = unsafeCastStringToDOMTopLevelType('mouseover'); 1283 var TOP_MOUSE_UP = unsafeCastStringToDOMTopLevelType('mouseup'); 1284 var TOP_PASTE = unsafeCastStringToDOMTopLevelType('paste'); 1285 var TOP_PAUSE = unsafeCastStringToDOMTopLevelType('pause'); 1286 var TOP_PLAY = unsafeCastStringToDOMTopLevelType('play'); 1287 var TOP_PLAYING = unsafeCastStringToDOMTopLevelType('playing'); 1288 var TOP_POINTER_CANCEL = unsafeCastStringToDOMTopLevelType('pointercancel'); 1289 var TOP_POINTER_DOWN = unsafeCastStringToDOMTopLevelType('pointerdown'); 1290 1291 1292 var TOP_POINTER_MOVE = unsafeCastStringToDOMTopLevelType('pointermove'); 1293 var TOP_POINTER_OUT = unsafeCastStringToDOMTopLevelType('pointerout'); 1294 var TOP_POINTER_OVER = unsafeCastStringToDOMTopLevelType('pointerover'); 1295 var TOP_POINTER_UP = unsafeCastStringToDOMTopLevelType('pointerup'); 1296 var TOP_PROGRESS = unsafeCastStringToDOMTopLevelType('progress'); 1297 var TOP_RATE_CHANGE = unsafeCastStringToDOMTopLevelType('ratechange'); 1298 var TOP_RESET = unsafeCastStringToDOMTopLevelType('reset'); 1299 var TOP_SCROLL = unsafeCastStringToDOMTopLevelType('scroll'); 1300 var TOP_SEEKED = unsafeCastStringToDOMTopLevelType('seeked'); 1301 var TOP_SEEKING = unsafeCastStringToDOMTopLevelType('seeking'); 1302 var TOP_SELECTION_CHANGE = unsafeCastStringToDOMTopLevelType('selectionchange'); 1303 var TOP_STALLED = unsafeCastStringToDOMTopLevelType('stalled'); 1304 var TOP_SUBMIT = unsafeCastStringToDOMTopLevelType('submit'); 1305 var TOP_SUSPEND = unsafeCastStringToDOMTopLevelType('suspend'); 1306 var TOP_TEXT_INPUT = unsafeCastStringToDOMTopLevelType('textInput'); 1307 var TOP_TIME_UPDATE = unsafeCastStringToDOMTopLevelType('timeupdate'); 1308 var TOP_TOGGLE = unsafeCastStringToDOMTopLevelType('toggle'); 1309 var TOP_TOUCH_CANCEL = unsafeCastStringToDOMTopLevelType('touchcancel'); 1310 var TOP_TOUCH_END = unsafeCastStringToDOMTopLevelType('touchend'); 1311 var TOP_TOUCH_MOVE = unsafeCastStringToDOMTopLevelType('touchmove'); 1312 var TOP_TOUCH_START = unsafeCastStringToDOMTopLevelType('touchstart'); 1313 var TOP_TRANSITION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('transitionend')); 1314 var TOP_VOLUME_CHANGE = unsafeCastStringToDOMTopLevelType('volumechange'); 1315 var TOP_WAITING = unsafeCastStringToDOMTopLevelType('waiting'); 1316 var TOP_WHEEL = unsafeCastStringToDOMTopLevelType('wheel'); 1317 1318 // List of events that need to be individually attached to media elements. 1319 // Note that events in this list will *not* be listened to at the top level 1320 // unless they're explicitly whitelisted in `ReactBrowserEventEmitter.listenTo`. 1321 var mediaEventTypes = [TOP_ABORT, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, TOP_DURATION_CHANGE, TOP_EMPTIED, TOP_ENCRYPTED, TOP_ENDED, TOP_ERROR, TOP_LOADED_DATA, TOP_LOADED_METADATA, TOP_LOAD_START, TOP_PAUSE, TOP_PLAY, TOP_PLAYING, TOP_PROGRESS, TOP_RATE_CHANGE, TOP_SEEKED, TOP_SEEKING, TOP_STALLED, TOP_SUSPEND, TOP_TIME_UPDATE, TOP_VOLUME_CHANGE, TOP_WAITING]; 1322 1323 function getRawEventName(topLevelType) { 1324 return unsafeCastDOMTopLevelTypeToString(topLevelType); 1325 } 1326 1327 /** 1328 * These variables store information about text content of a target node, 1329 * allowing comparison of content before and after a given event. 1330 * 1331 * Identify the node where selection currently begins, then observe 1332 * both its text content and its current position in the DOM. Since the 1333 * browser may natively replace the target node during composition, we can 1334 * use its position to find its replacement. 1335 * 1336 * 1337 */ 1338 1339 var root = null; 1340 var startText = null; 1341 var fallbackText = null; 1342 1343 function initialize(nativeEventTarget) { 1344 root = nativeEventTarget; 1345 startText = getText(); 1346 return true; 1347 } 1348 1349 function reset() { 1350 root = null; 1351 startText = null; 1352 fallbackText = null; 1353 } 1354 1355 function getData() { 1356 if (fallbackText) { 1357 return fallbackText; 1358 } 1359 1360 var start = void 0; 1361 var startValue = startText; 1362 var startLength = startValue.length; 1363 var end = void 0; 1364 var endValue = getText(); 1365 var endLength = endValue.length; 1366 1367 for (start = 0; start < startLength; start++) { 1368 if (startValue[start] !== endValue[start]) { 1369 break; 1370 } 1371 } 1372 1373 var minEnd = startLength - start; 1374 for (end = 1; end <= minEnd; end++) { 1375 if (startValue[startLength - end] !== endValue[endLength - end]) { 1376 break; 1377 } 1378 } 1379 1380 var sliceTail = end > 1 ? 1 - end : undefined; 1381 fallbackText = endValue.slice(start, sliceTail); 1382 return fallbackText; 1383 } 1384 1385 function getText() { 1386 if ('value' in root) { 1387 return root.value; 1388 } 1389 return root.textContent; 1390 } 1391 1392 var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; 1393 1394 var _assign = ReactInternals.assign; 1395 1396 /* eslint valid-typeof: 0 */ 1397 1398 var EVENT_POOL_SIZE = 10; 1399 1400 /** 1401 * @interface Event 1402 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 1403 */ 1404 var EventInterface = { 1405 type: null, 1406 target: null, 1407 // currentTarget is set when dispatching; no use in copying it here 1408 currentTarget: function () { 1409 return null; 1410 }, 1411 eventPhase: null, 1412 bubbles: null, 1413 cancelable: null, 1414 timeStamp: function (event) { 1415 return event.timeStamp || Date.now(); 1416 }, 1417 defaultPrevented: null, 1418 isTrusted: null 1419 }; 1420 1421 function functionThatReturnsTrue() { 1422 return true; 1423 } 1424 1425 function functionThatReturnsFalse() { 1426 return false; 1427 } 1428 1429 /** 1430 * Synthetic events are dispatched by event plugins, typically in response to a 1431 * top-level event delegation handler. 1432 * 1433 * These systems should generally use pooling to reduce the frequency of garbage 1434 * collection. The system should check `isPersistent` to determine whether the 1435 * event should be released into the pool after being dispatched. Users that 1436 * need a persisted event should invoke `persist`. 1437 * 1438 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by 1439 * normalizing browser quirks. Subclasses do not necessarily have to implement a 1440 * DOM interface; custom application-specific events can also subclass this. 1441 * 1442 * @param {object} dispatchConfig Configuration used to dispatch this event. 1443 * @param {*} targetInst Marker identifying the event target. 1444 * @param {object} nativeEvent Native browser event. 1445 * @param {DOMEventTarget} nativeEventTarget Target node. 1446 */ 1447 function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) { 1448 { 1449 // these have a getter/setter for warnings 1450 delete this.nativeEvent; 1451 delete this.preventDefault; 1452 delete this.stopPropagation; 1453 delete this.isDefaultPrevented; 1454 delete this.isPropagationStopped; 1455 } 1456 1457 this.dispatchConfig = dispatchConfig; 1458 this._targetInst = targetInst; 1459 this.nativeEvent = nativeEvent; 1460 1461 var Interface = this.constructor.Interface; 1462 for (var propName in Interface) { 1463 if (!Interface.hasOwnProperty(propName)) { 1464 continue; 1465 } 1466 { 1467 delete this[propName]; // this has a getter/setter for warnings 1468 } 1469 var normalize = Interface[propName]; 1470 if (normalize) { 1471 this[propName] = normalize(nativeEvent); 1472 } else { 1473 if (propName === 'target') { 1474 this.target = nativeEventTarget; 1475 } else { 1476 this[propName] = nativeEvent[propName]; 1477 } 1478 } 1479 } 1480 1481 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false; 1482 if (defaultPrevented) { 1483 this.isDefaultPrevented = functionThatReturnsTrue; 1484 } else { 1485 this.isDefaultPrevented = functionThatReturnsFalse; 1486 } 1487 this.isPropagationStopped = functionThatReturnsFalse; 1488 return this; 1489 } 1490 1491 _assign(SyntheticEvent.prototype, { 1492 preventDefault: function () { 1493 this.defaultPrevented = true; 1494 var event = this.nativeEvent; 1495 if (!event) { 1496 return; 1497 } 1498 1499 if (event.preventDefault) { 1500 event.preventDefault(); 1501 } else if (typeof event.returnValue !== 'unknown') { 1502 event.returnValue = false; 1503 } 1504 this.isDefaultPrevented = functionThatReturnsTrue; 1505 }, 1506 1507 stopPropagation: function () { 1508 var event = this.nativeEvent; 1509 if (!event) { 1510 return; 1511 } 1512 1513 if (event.stopPropagation) { 1514 event.stopPropagation(); 1515 } else if (typeof event.cancelBubble !== 'unknown') { 1516 // The ChangeEventPlugin registers a "propertychange" event for 1517 // IE. This event does not support bubbling or cancelling, and 1518 // any references to cancelBubble throw "Member not found". A 1519 // typeof check of "unknown" circumvents this issue (and is also 1520 // IE specific). 1521 event.cancelBubble = true; 1522 } 1523 1524 this.isPropagationStopped = functionThatReturnsTrue; 1525 }, 1526 1527 /** 1528 * We release all dispatched `SyntheticEvent`s after each event loop, adding 1529 * them back into the pool. This allows a way to hold onto a reference that 1530 * won't be added back into the pool. 1531 */ 1532 persist: function () { 1533 this.isPersistent = functionThatReturnsTrue; 1534 }, 1535 1536 /** 1537 * Checks if this event should be released back into the pool. 1538 * 1539 * @return {boolean} True if this should not be released, false otherwise. 1540 */ 1541 isPersistent: functionThatReturnsFalse, 1542 1543 /** 1544 * `PooledClass` looks for `destructor` on each instance it releases. 1545 */ 1546 destructor: function () { 1547 var Interface = this.constructor.Interface; 1548 for (var propName in Interface) { 1549 { 1550 Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName])); 1551 } 1552 } 1553 this.dispatchConfig = null; 1554 this._targetInst = null; 1555 this.nativeEvent = null; 1556 this.isDefaultPrevented = functionThatReturnsFalse; 1557 this.isPropagationStopped = functionThatReturnsFalse; 1558 this._dispatchListeners = null; 1559 this._dispatchInstances = null; 1560 { 1561 Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null)); 1562 Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse)); 1563 Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse)); 1564 Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {})); 1565 Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {})); 1566 } 1567 } 1568 }); 1569 1570 SyntheticEvent.Interface = EventInterface; 1571 1572 /** 1573 * Helper to reduce boilerplate when creating subclasses. 1574 */ 1575 SyntheticEvent.extend = function (Interface) { 1576 var Super = this; 1577 1578 var E = function () {}; 1579 E.prototype = Super.prototype; 1580 var prototype = new E(); 1581 1582 function Class() { 1583 return Super.apply(this, arguments); 1584 } 1585 _assign(prototype, Class.prototype); 1586 Class.prototype = prototype; 1587 Class.prototype.constructor = Class; 1588 1589 Class.Interface = _assign({}, Super.Interface, Interface); 1590 Class.extend = Super.extend; 1591 addEventPoolingTo(Class); 1592 1593 return Class; 1594 }; 1595 1596 addEventPoolingTo(SyntheticEvent); 1597 1598 /** 1599 * Helper to nullify syntheticEvent instance properties when destructing 1600 * 1601 * @param {String} propName 1602 * @param {?object} getVal 1603 * @return {object} defineProperty object 1604 */ 1605 function getPooledWarningPropertyDefinition(propName, getVal) { 1606 var isFunction = typeof getVal === 'function'; 1607 return { 1608 configurable: true, 1609 set: set, 1610 get: get 1611 }; 1612 1613 function set(val) { 1614 var action = isFunction ? 'setting the method' : 'setting the property'; 1615 warn(action, 'This is effectively a no-op'); 1616 return val; 1617 } 1618 1619 function get() { 1620 var action = isFunction ? 'accessing the method' : 'accessing the property'; 1621 var result = isFunction ? 'This is a no-op function' : 'This is set to null'; 1622 warn(action, result); 1623 return getVal; 1624 } 1625 1626 function warn(action, result) { 1627 var warningCondition = false; 1628 !warningCondition ? warningWithoutStack$1(false, "This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0; 1629 } 1630 } 1631 1632 function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { 1633 var EventConstructor = this; 1634 if (EventConstructor.eventPool.length) { 1635 var instance = EventConstructor.eventPool.pop(); 1636 EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst); 1637 return instance; 1638 } 1639 return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst); 1640 } 1641 1642 function releasePooledEvent(event) { 1643 var EventConstructor = this; 1644 !(event instanceof EventConstructor) ? invariant(false, 'Trying to release an event instance into a pool of a different type.') : void 0; 1645 event.destructor(); 1646 if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { 1647 EventConstructor.eventPool.push(event); 1648 } 1649 } 1650 1651 function addEventPoolingTo(EventConstructor) { 1652 EventConstructor.eventPool = []; 1653 EventConstructor.getPooled = getPooledEvent; 1654 EventConstructor.release = releasePooledEvent; 1655 } 1656 1657 /** 1658 * @interface Event 1659 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents 1660 */ 1661 var SyntheticCompositionEvent = SyntheticEvent.extend({ 1662 data: null 1663 }); 1664 1665 /** 1666 * @interface Event 1667 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105 1668 * /#events-inputevents 1669 */ 1670 var SyntheticInputEvent = SyntheticEvent.extend({ 1671 data: null 1672 }); 1673 1674 var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space 1675 var START_KEYCODE = 229; 1676 1677 var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window; 1678 1679 var documentMode = null; 1680 if (canUseDOM && 'documentMode' in document) { 1681 documentMode = document.documentMode; 1682 } 1683 1684 // Webkit offers a very useful `textInput` event that can be used to 1685 // directly represent `beforeInput`. The IE `textinput` event is not as 1686 // useful, so we don't use it. 1687 var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode; 1688 1689 // In IE9+, we have access to composition events, but the data supplied 1690 // by the native compositionend event may be incorrect. Japanese ideographic 1691 // spaces, for instance (\u3000) are not recorded correctly. 1692 var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11); 1693 1694 var SPACEBAR_CODE = 32; 1695 var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); 1696 1697 // Events and their corresponding property names. 1698 var eventTypes = { 1699 beforeInput: { 1700 phasedRegistrationNames: { 1701 bubbled: 'onBeforeInput', 1702 captured: 'onBeforeInputCapture' 1703 }, 1704 dependencies: [TOP_COMPOSITION_END, TOP_KEY_PRESS, TOP_TEXT_INPUT, TOP_PASTE] 1705 }, 1706 compositionEnd: { 1707 phasedRegistrationNames: { 1708 bubbled: 'onCompositionEnd', 1709 captured: 'onCompositionEndCapture' 1710 }, 1711 dependencies: [TOP_BLUR, TOP_COMPOSITION_END, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN] 1712 }, 1713 compositionStart: { 1714 phasedRegistrationNames: { 1715 bubbled: 'onCompositionStart', 1716 captured: 'onCompositionStartCapture' 1717 }, 1718 dependencies: [TOP_BLUR, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN] 1719 }, 1720 compositionUpdate: { 1721 phasedRegistrationNames: { 1722 bubbled: 'onCompositionUpdate', 1723 captured: 'onCompositionUpdateCapture' 1724 }, 1725 dependencies: [TOP_BLUR, TOP_COMPOSITION_UPDATE, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN] 1726 } 1727 }; 1728 1729 // Track whether we've ever handled a keypress on the space key. 1730 var hasSpaceKeypress = false; 1731 1732 /** 1733 * Return whether a native keypress event is assumed to be a command. 1734 * This is required because Firefox fires `keypress` events for key commands 1735 * (cut, copy, select-all, etc.) even though no character is inserted. 1736 */ 1737 function isKeypressCommand(nativeEvent) { 1738 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && 1739 // ctrlKey && altKey is equivalent to AltGr, and is not a command. 1740 !(nativeEvent.ctrlKey && nativeEvent.altKey); 1741 } 1742 1743 /** 1744 * Translate native top level events into event types. 1745 * 1746 * @param {string} topLevelType 1747 * @return {object} 1748 */ 1749 function getCompositionEventType(topLevelType) { 1750 switch (topLevelType) { 1751 case TOP_COMPOSITION_START: 1752 return eventTypes.compositionStart; 1753 case TOP_COMPOSITION_END: 1754 return eventTypes.compositionEnd; 1755 case TOP_COMPOSITION_UPDATE: 1756 return eventTypes.compositionUpdate; 1757 } 1758 } 1759 1760 /** 1761 * Does our fallback best-guess model think this event signifies that 1762 * composition has begun? 1763 * 1764 * @param {string} topLevelType 1765 * @param {object} nativeEvent 1766 * @return {boolean} 1767 */ 1768 function isFallbackCompositionStart(topLevelType, nativeEvent) { 1769 return topLevelType === TOP_KEY_DOWN && nativeEvent.keyCode === START_KEYCODE; 1770 } 1771 1772 /** 1773 * Does our fallback mode think that this event is the end of composition? 1774 * 1775 * @param {string} topLevelType 1776 * @param {object} nativeEvent 1777 * @return {boolean} 1778 */ 1779 function isFallbackCompositionEnd(topLevelType, nativeEvent) { 1780 switch (topLevelType) { 1781 case TOP_KEY_UP: 1782 // Command keys insert or clear IME input. 1783 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1; 1784 case TOP_KEY_DOWN: 1785 // Expect IME keyCode on each keydown. If we get any other 1786 // code we must have exited earlier. 1787 return nativeEvent.keyCode !== START_KEYCODE; 1788 case TOP_KEY_PRESS: 1789 case TOP_MOUSE_DOWN: 1790 case TOP_BLUR: 1791 // Events are not possible without cancelling IME. 1792 return true; 1793 default: 1794 return false; 1795 } 1796 } 1797 1798 /** 1799 * Google Input Tools provides composition data via a CustomEvent, 1800 * with the `data` property populated in the `detail` object. If this 1801 * is available on the event object, use it. If not, this is a plain 1802 * composition event and we have nothing special to extract. 1803 * 1804 * @param {object} nativeEvent 1805 * @return {?string} 1806 */ 1807 function getDataFromCustomEvent(nativeEvent) { 1808 var detail = nativeEvent.detail; 1809 if (typeof detail === 'object' && 'data' in detail) { 1810 return detail.data; 1811 } 1812 return null; 1813 } 1814 1815 /** 1816 * Check if a composition event was triggered by Korean IME. 1817 * Our fallback mode does not work well with IE's Korean IME, 1818 * so just use native composition events when Korean IME is used. 1819 * Although CompositionEvent.locale property is deprecated, 1820 * it is available in IE, where our fallback mode is enabled. 1821 * 1822 * @param {object} nativeEvent 1823 * @return {boolean} 1824 */ 1825 function isUsingKoreanIME(nativeEvent) { 1826 return nativeEvent.locale === 'ko'; 1827 } 1828 1829 // Track the current IME composition status, if any. 1830 var isComposing = false; 1831 1832 /** 1833 * @return {?object} A SyntheticCompositionEvent. 1834 */ 1835 function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) { 1836 var eventType = void 0; 1837 var fallbackData = void 0; 1838 1839 if (canUseCompositionEvent) { 1840 eventType = getCompositionEventType(topLevelType); 1841 } else if (!isComposing) { 1842 if (isFallbackCompositionStart(topLevelType, nativeEvent)) { 1843 eventType = eventTypes.compositionStart; 1844 } 1845 } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) { 1846 eventType = eventTypes.compositionEnd; 1847 } 1848 1849 if (!eventType) { 1850 return null; 1851 } 1852 1853 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) { 1854 // The current composition is stored statically and must not be 1855 // overwritten while composition continues. 1856 if (!isComposing && eventType === eventTypes.compositionStart) { 1857 isComposing = initialize(nativeEventTarget); 1858 } else if (eventType === eventTypes.compositionEnd) { 1859 if (isComposing) { 1860 fallbackData = getData(); 1861 } 1862 } 1863 } 1864 1865 var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget); 1866 1867 if (fallbackData) { 1868 // Inject data generated from fallback path into the synthetic event. 1869 // This matches the property of native CompositionEventInterface. 1870 event.data = fallbackData; 1871 } else { 1872 var customData = getDataFromCustomEvent(nativeEvent); 1873 if (customData !== null) { 1874 event.data = customData; 1875 } 1876 } 1877 1878 accumulateTwoPhaseDispatches(event); 1879 return event; 1880 } 1881 1882 /** 1883 * @param {TopLevelType} topLevelType Number from `TopLevelType`. 1884 * @param {object} nativeEvent Native browser event. 1885 * @return {?string} The string corresponding to this `beforeInput` event. 1886 */ 1887 function getNativeBeforeInputChars(topLevelType, nativeEvent) { 1888 switch (topLevelType) { 1889 case TOP_COMPOSITION_END: 1890 return getDataFromCustomEvent(nativeEvent); 1891 case TOP_KEY_PRESS: 1892 /** 1893 * If native `textInput` events are available, our goal is to make 1894 * use of them. However, there is a special case: the spacebar key. 1895 * In Webkit, preventing default on a spacebar `textInput` event 1896 * cancels character insertion, but it *also* causes the browser 1897 * to fall back to its default spacebar behavior of scrolling the 1898 * page. 1899 * 1900 * Tracking at: 1901 * https://code.google.com/p/chromium/issues/detail?id=355103 1902 * 1903 * To avoid this issue, use the keypress event as if no `textInput` 1904 * event is available. 1905 */ 1906 var which = nativeEvent.which; 1907 if (which !== SPACEBAR_CODE) { 1908 return null; 1909 } 1910 1911 hasSpaceKeypress = true; 1912 return SPACEBAR_CHAR; 1913 1914 case TOP_TEXT_INPUT: 1915 // Record the characters to be added to the DOM. 1916 var chars = nativeEvent.data; 1917 1918 // If it's a spacebar character, assume that we have already handled 1919 // it at the keypress level and bail immediately. Android Chrome 1920 // doesn't give us keycodes, so we need to ignore it. 1921 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) { 1922 return null; 1923 } 1924 1925 return chars; 1926 1927 default: 1928 // For other native event types, do nothing. 1929 return null; 1930 } 1931 } 1932 1933 /** 1934 * For browsers that do not provide the `textInput` event, extract the 1935 * appropriate string to use for SyntheticInputEvent. 1936 * 1937 * @param {number} topLevelType Number from `TopLevelEventTypes`. 1938 * @param {object} nativeEvent Native browser event. 1939 * @return {?string} The fallback string for this `beforeInput` event. 1940 */ 1941 function getFallbackBeforeInputChars(topLevelType, nativeEvent) { 1942 // If we are currently composing (IME) and using a fallback to do so, 1943 // try to extract the composed characters from the fallback object. 1944 // If composition event is available, we extract a string only at 1945 // compositionevent, otherwise extract it at fallback events. 1946 if (isComposing) { 1947 if (topLevelType === TOP_COMPOSITION_END || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) { 1948 var chars = getData(); 1949 reset(); 1950 isComposing = false; 1951 return chars; 1952 } 1953 return null; 1954 } 1955 1956 switch (topLevelType) { 1957 case TOP_PASTE: 1958 // If a paste event occurs after a keypress, throw out the input 1959 // chars. Paste events should not lead to BeforeInput events. 1960 return null; 1961 case TOP_KEY_PRESS: 1962 /** 1963 * As of v27, Firefox may fire keypress events even when no character 1964 * will be inserted. A few possibilities: 1965 * 1966 * - `which` is `0`. Arrow keys, Esc key, etc. 1967 * 1968 * - `which` is the pressed key code, but no char is available. 1969 * Ex: 'AltGr + d` in Polish. There is no modified character for 1970 * this key combination and no character is inserted into the 1971 * document, but FF fires the keypress for char code `100` anyway. 1972 * No `input` event will occur. 1973 * 1974 * - `which` is the pressed key code, but a command combination is 1975 * being used. Ex: `Cmd+C`. No character is inserted, and no 1976 * `input` event will occur. 1977 */ 1978 if (!isKeypressCommand(nativeEvent)) { 1979 // IE fires the `keypress` event when a user types an emoji via 1980 // Touch keyboard of Windows. In such a case, the `char` property 1981 // holds an emoji character like `\uD83D\uDE0A`. Because its length 1982 // is 2, the property `which` does not represent an emoji correctly. 1983 // In such a case, we directly return the `char` property instead of 1984 // using `which`. 1985 if (nativeEvent.char && nativeEvent.char.length > 1) { 1986 return nativeEvent.char; 1987 } else if (nativeEvent.which) { 1988 return String.fromCharCode(nativeEvent.which); 1989 } 1990 } 1991 return null; 1992 case TOP_COMPOSITION_END: 1993 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data; 1994 default: 1995 return null; 1996 } 1997 } 1998 1999 /** 2000 * Extract a SyntheticInputEvent for `beforeInput`, based on either native 2001 * `textInput` or fallback behavior. 2002 * 2003 * @return {?object} A SyntheticInputEvent. 2004 */ 2005 function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) { 2006 var chars = void 0; 2007 2008 if (canUseTextInputEvent) { 2009 chars = getNativeBeforeInputChars(topLevelType, nativeEvent); 2010 } else { 2011 chars = getFallbackBeforeInputChars(topLevelType, nativeEvent); 2012 } 2013 2014 // If no characters are being inserted, no BeforeInput event should 2015 // be fired. 2016 if (!chars) { 2017 return null; 2018 } 2019 2020 var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget); 2021 2022 event.data = chars; 2023 accumulateTwoPhaseDispatches(event); 2024 return event; 2025 } 2026 2027 /** 2028 * Create an `onBeforeInput` event to match 2029 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents. 2030 * 2031 * This event plugin is based on the native `textInput` event 2032 * available in Chrome, Safari, Opera, and IE. This event fires after 2033 * `onKeyPress` and `onCompositionEnd`, but before `onInput`. 2034 * 2035 * `beforeInput` is spec'd but not implemented in any browsers, and 2036 * the `input` event does not provide any useful information about what has 2037 * actually been added, contrary to the spec. Thus, `textInput` is the best 2038 * available event to identify the characters that have actually been inserted 2039 * into the target node. 2040 * 2041 * This plugin is also responsible for emitting `composition` events, thus 2042 * allowing us to share composition fallback code for both `beforeInput` and 2043 * `composition` event types. 2044 */ 2045 var BeforeInputEventPlugin = { 2046 eventTypes: eventTypes, 2047 2048 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { 2049 var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget); 2050 2051 var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget); 2052 2053 if (composition === null) { 2054 return beforeInput; 2055 } 2056 2057 if (beforeInput === null) { 2058 return composition; 2059 } 2060 2061 return [composition, beforeInput]; 2062 } 2063 }; 2064 2065 // Use to restore controlled state after a change event has fired. 2066 2067 var restoreImpl = null; 2068 var restoreTarget = null; 2069 var restoreQueue = null; 2070 2071 function restoreStateOfTarget(target) { 2072 // We perform this translation at the end of the event loop so that we 2073 // always receive the correct fiber here 2074 var internalInstance = getInstanceFromNode(target); 2075 if (!internalInstance) { 2076 // Unmounted 2077 return; 2078 } 2079 !(typeof restoreImpl === 'function') ? invariant(false, 'setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue.') : void 0; 2080 var props = getFiberCurrentPropsFromNode(internalInstance.stateNode); 2081 restoreImpl(internalInstance.stateNode, internalInstance.type, props); 2082 } 2083 2084 function setRestoreImplementation(impl) { 2085 restoreImpl = impl; 2086 } 2087 2088 function enqueueStateRestore(target) { 2089 if (restoreTarget) { 2090 if (restoreQueue) { 2091 restoreQueue.push(target); 2092 } else { 2093 restoreQueue = [target]; 2094 } 2095 } else { 2096 restoreTarget = target; 2097 } 2098 } 2099 2100 function needsStateRestore() { 2101 return restoreTarget !== null || restoreQueue !== null; 2102 } 2103 2104 function restoreStateIfNeeded() { 2105 if (!restoreTarget) { 2106 return; 2107 } 2108 var target = restoreTarget; 2109 var queuedTargets = restoreQueue; 2110 restoreTarget = null; 2111 restoreQueue = null; 2112 2113 restoreStateOfTarget(target); 2114 if (queuedTargets) { 2115 for (var i = 0; i < queuedTargets.length; i++) { 2116 restoreStateOfTarget(queuedTargets[i]); 2117 } 2118 } 2119 } 2120 2121 // Used as a way to call batchedUpdates when we don't have a reference to 2122 // the renderer. Such as when we're dispatching events or if third party 2123 // libraries need to call batchedUpdates. Eventually, this API will go away when 2124 // everything is batched by default. We'll then have a similar API to opt-out of 2125 // scheduled work and instead do synchronous work. 2126 2127 // Defaults 2128 var _batchedUpdatesImpl = function (fn, bookkeeping) { 2129 return fn(bookkeeping); 2130 }; 2131 var _interactiveUpdatesImpl = function (fn, a, b) { 2132 return fn(a, b); 2133 }; 2134 var _flushInteractiveUpdatesImpl = function () {}; 2135 2136 var isBatching = false; 2137 function batchedUpdates(fn, bookkeeping) { 2138 if (isBatching) { 2139 // If we are currently inside another batch, we need to wait until it 2140 // fully completes before restoring state. 2141 return fn(bookkeeping); 2142 } 2143 isBatching = true; 2144 try { 2145 return _batchedUpdatesImpl(fn, bookkeeping); 2146 } finally { 2147 // Here we wait until all updates have propagated, which is important 2148 // when using controlled components within layers: 2149 // https://github.com/facebook/react/issues/1698 2150 // Then we restore state of any controlled component. 2151 isBatching = false; 2152 var controlledComponentsHavePendingUpdates = needsStateRestore(); 2153 if (controlledComponentsHavePendingUpdates) { 2154 // If a controlled event was fired, we may need to restore the state of 2155 // the DOM node back to the controlled value. This is necessary when React 2156 // bails out of the update without touching the DOM. 2157 _flushInteractiveUpdatesImpl(); 2158 restoreStateIfNeeded(); 2159 } 2160 } 2161 } 2162 2163 function interactiveUpdates(fn, a, b) { 2164 return _interactiveUpdatesImpl(fn, a, b); 2165 } 2166 2167 2168 2169 function setBatchingImplementation(batchedUpdatesImpl, interactiveUpdatesImpl, flushInteractiveUpdatesImpl) { 2170 _batchedUpdatesImpl = batchedUpdatesImpl; 2171 _interactiveUpdatesImpl = interactiveUpdatesImpl; 2172 _flushInteractiveUpdatesImpl = flushInteractiveUpdatesImpl; 2173 } 2174 2175 /** 2176 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary 2177 */ 2178 var supportedInputTypes = { 2179 color: true, 2180 date: true, 2181 datetime: true, 2182 'datetime-local': true, 2183 email: true, 2184 month: true, 2185 number: true, 2186 password: true, 2187 range: true, 2188 search: true, 2189 tel: true, 2190 text: true, 2191 time: true, 2192 url: true, 2193 week: true 2194 }; 2195 2196 function isTextInputElement(elem) { 2197 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); 2198 2199 if (nodeName === 'input') { 2200 return !!supportedInputTypes[elem.type]; 2201 } 2202 2203 if (nodeName === 'textarea') { 2204 return true; 2205 } 2206 2207 return false; 2208 } 2209 2210 /** 2211 * HTML nodeType values that represent the type of the node 2212 */ 2213 2214 var ELEMENT_NODE = 1; 2215 var TEXT_NODE = 3; 2216 var COMMENT_NODE = 8; 2217 var DOCUMENT_NODE = 9; 2218 var DOCUMENT_FRAGMENT_NODE = 11; 2219 2220 /** 2221 * Gets the target node from a native browser event by accounting for 2222 * inconsistencies in browser DOM APIs. 2223 * 2224 * @param {object} nativeEvent Native browser event. 2225 * @return {DOMEventTarget} Target node. 2226 */ 2227 function getEventTarget(nativeEvent) { 2228 // Fallback to nativeEvent.srcElement for IE9 2229 // https://github.com/facebook/react/issues/12506 2230 var target = nativeEvent.target || nativeEvent.srcElement || window; 2231 2232 // Normalize SVG <use> element events #4963 2233 if (target.correspondingUseElement) { 2234 target = target.correspondingUseElement; 2235 } 2236 2237 // Safari may fire events on text nodes (Node.TEXT_NODE is 3). 2238 // @see http://www.quirksmode.org/js/events_properties.html 2239 return target.nodeType === TEXT_NODE ? target.parentNode : target; 2240 } 2241 2242 /** 2243 * Checks if an event is supported in the current execution environment. 2244 * 2245 * NOTE: This will not work correctly for non-generic events such as `change`, 2246 * `reset`, `load`, `error`, and `select`. 2247 * 2248 * Borrows from Modernizr. 2249 * 2250 * @param {string} eventNameSuffix Event name, e.g. "click". 2251 * @return {boolean} True if the event is supported. 2252 * @internal 2253 * @license Modernizr 3.0.0pre (Custom Build) | MIT 2254 */ 2255 function isEventSupported(eventNameSuffix) { 2256 if (!canUseDOM) { 2257 return false; 2258 } 2259 2260 var eventName = 'on' + eventNameSuffix; 2261 var isSupported = eventName in document; 2262 2263 if (!isSupported) { 2264 var element = document.createElementNS('http://www.w3.org/1999/xhtml', 'div'); 2265 element.setAttribute(eventName, 'return;'); 2266 isSupported = typeof element[eventName] === 'function'; 2267 } 2268 2269 return isSupported; 2270 } 2271 2272 function isCheckable(elem) { 2273 var type = elem.type; 2274 var nodeName = elem.nodeName; 2275 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio'); 2276 } 2277 2278 function getTracker(node) { 2279 return node._valueTracker; 2280 } 2281 2282 function detachTracker(node) { 2283 node._valueTracker = null; 2284 } 2285 2286 function getValueFromNode(node) { 2287 var value = ''; 2288 if (!node) { 2289 return value; 2290 } 2291 2292 if (isCheckable(node)) { 2293 value = node.checked ? 'true' : 'false'; 2294 } else { 2295 value = node.value; 2296 } 2297 2298 return value; 2299 } 2300 2301 function trackValueOnNode(node) { 2302 var valueField = isCheckable(node) ? 'checked' : 'value'; 2303 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField); 2304 2305 var currentValue = '' + node[valueField]; 2306 2307 // if someone has already defined a value or Safari, then bail 2308 // and don't track value will cause over reporting of changes, 2309 // but it's better then a hard failure 2310 // (needed for certain tests that spyOn input values and Safari) 2311 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') { 2312 return; 2313 } 2314 var get = descriptor.get, 2315 set = descriptor.set; 2316 2317 Object.defineProperty(node, valueField, { 2318 configurable: true, 2319 get: function () { 2320 return get.call(this); 2321 }, 2322 set: function (value) { 2323 currentValue = '' + value; 2324 set.call(this, value); 2325 } 2326 }); 2327 // We could've passed this the first time 2328 // but it triggers a bug in IE11 and Edge 14/15. 2329 // Calling defineProperty() again should be equivalent. 2330 // https://github.com/facebook/react/issues/11768 2331 Object.defineProperty(node, valueField, { 2332 enumerable: descriptor.enumerable 2333 }); 2334 2335 var tracker = { 2336 getValue: function () { 2337 return currentValue; 2338 }, 2339 setValue: function (value) { 2340 currentValue = '' + value; 2341 }, 2342 stopTracking: function () { 2343 detachTracker(node); 2344 delete node[valueField]; 2345 } 2346 }; 2347 return tracker; 2348 } 2349 2350 function track(node) { 2351 if (getTracker(node)) { 2352 return; 2353 } 2354 2355 // TODO: Once it's just Fiber we can move this to node._wrapperState 2356 node._valueTracker = trackValueOnNode(node); 2357 } 2358 2359 function updateValueIfChanged(node) { 2360 if (!node) { 2361 return false; 2362 } 2363 2364 var tracker = getTracker(node); 2365 // if there is no tracker at this point it's unlikely 2366 // that trying again will succeed 2367 if (!tracker) { 2368 return true; 2369 } 2370 2371 var lastValue = tracker.getValue(); 2372 var nextValue = getValueFromNode(node); 2373 if (nextValue !== lastValue) { 2374 tracker.setValue(nextValue); 2375 return true; 2376 } 2377 return false; 2378 } 2379 2380 var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; 2381 2382 // Prevent newer renderers from RTE when used with older react package versions. 2383 // Current owner and dispatcher used to share the same ref, 2384 // but PR #14548 split them out to better support the react-debug-tools package. 2385 if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) { 2386 ReactSharedInternals.ReactCurrentDispatcher = { 2387 current: null 2388 }; 2389 } 2390 2391 var BEFORE_SLASH_RE = /^(.*)[\\\/]/; 2392 2393 var describeComponentFrame = function (name, source, ownerName) { 2394 var sourceInfo = ''; 2395 if (source) { 2396 var path = source.fileName; 2397 var fileName = path.replace(BEFORE_SLASH_RE, ''); 2398 { 2399 // In DEV, include code for a common special case: 2400 // prefer "folder/index.js" instead of just "index.js". 2401 if (/^index\./.test(fileName)) { 2402 var match = path.match(BEFORE_SLASH_RE); 2403 if (match) { 2404 var pathBeforeSlash = match[1]; 2405 if (pathBeforeSlash) { 2406 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ''); 2407 fileName = folderName + '/' + fileName; 2408 } 2409 } 2410 } 2411 } 2412 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')'; 2413 } else if (ownerName) { 2414 sourceInfo = ' (created by ' + ownerName + ')'; 2415 } 2416 return '\n in ' + (name || 'Unknown') + sourceInfo; 2417 }; 2418 2419 // The Symbol used to tag the ReactElement-like types. If there is no native Symbol 2420 // nor polyfill, then a plain number is used for performance. 2421 var hasSymbol = typeof Symbol === 'function' && Symbol.for; 2422 2423 var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7; 2424 var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca; 2425 var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb; 2426 var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc; 2427 var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2; 2428 var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd; 2429 var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; 2430 2431 var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf; 2432 var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0; 2433 var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1; 2434 var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3; 2435 var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4; 2436 2437 var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; 2438 var FAUX_ITERATOR_SYMBOL = '@@iterator'; 2439 2440 function getIteratorFn(maybeIterable) { 2441 if (maybeIterable === null || typeof maybeIterable !== 'object') { 2442 return null; 2443 } 2444 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]; 2445 if (typeof maybeIterator === 'function') { 2446 return maybeIterator; 2447 } 2448 return null; 2449 } 2450 2451 var Pending = 0; 2452 var Resolved = 1; 2453 var Rejected = 2; 2454 2455 function refineResolvedLazyComponent(lazyComponent) { 2456 return lazyComponent._status === Resolved ? lazyComponent._result : null; 2457 } 2458 2459 function getWrappedName(outerType, innerType, wrapperName) { 2460 var functionName = innerType.displayName || innerType.name || ''; 2461 return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName); 2462 } 2463 2464 function getComponentName(type) { 2465 if (type == null) { 2466 // Host root, text node or just invalid type. 2467 return null; 2468 } 2469 { 2470 if (typeof type.tag === 'number') { 2471 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.'); 2472 } 2473 } 2474 if (typeof type === 'function') { 2475 return type.displayName || type.name || null; 2476 } 2477 if (typeof type === 'string') { 2478 return type; 2479 } 2480 switch (type) { 2481 case REACT_CONCURRENT_MODE_TYPE: 2482 return 'ConcurrentMode'; 2483 case REACT_FRAGMENT_TYPE: 2484 return 'Fragment'; 2485 case REACT_PORTAL_TYPE: 2486 return 'Portal'; 2487 case REACT_PROFILER_TYPE: 2488 return 'Profiler'; 2489 case REACT_STRICT_MODE_TYPE: 2490 return 'StrictMode'; 2491 case REACT_SUSPENSE_TYPE: 2492 return 'Suspense'; 2493 } 2494 if (typeof type === 'object') { 2495 switch (type.$$typeof) { 2496 case REACT_CONTEXT_TYPE: 2497 return 'Context.Consumer'; 2498 case REACT_PROVIDER_TYPE: 2499 return 'Context.Provider'; 2500 case REACT_FORWARD_REF_TYPE: 2501 return getWrappedName(type, type.render, 'ForwardRef'); 2502 case REACT_MEMO_TYPE: 2503 return getComponentName(type.type); 2504 case REACT_LAZY_TYPE: 2505 { 2506 var thenable = type; 2507 var resolvedThenable = refineResolvedLazyComponent(thenable); 2508 if (resolvedThenable) { 2509 return getComponentName(resolvedThenable); 2510 } 2511 } 2512 } 2513 } 2514 return null; 2515 } 2516 2517 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; 2518 2519 function describeFiber(fiber) { 2520 switch (fiber.tag) { 2521 case HostRoot: 2522 case HostPortal: 2523 case HostText: 2524 case Fragment: 2525 case ContextProvider: 2526 case ContextConsumer: 2527 return ''; 2528 default: 2529 var owner = fiber._debugOwner; 2530 var source = fiber._debugSource; 2531 var name = getComponentName(fiber.type); 2532 var ownerName = null; 2533 if (owner) { 2534 ownerName = getComponentName(owner.type); 2535 } 2536 return describeComponentFrame(name, source, ownerName); 2537 } 2538 } 2539 2540 function getStackByFiberInDevAndProd(workInProgress) { 2541 var info = ''; 2542 var node = workInProgress; 2543 do { 2544 info += describeFiber(node); 2545 node = node.return; 2546 } while (node); 2547 return info; 2548 } 2549 2550 var current = null; 2551 var phase = null; 2552 2553 function getCurrentFiberOwnerNameInDevOrNull() { 2554 { 2555 if (current === null) { 2556 return null; 2557 } 2558 var owner = current._debugOwner; 2559 if (owner !== null && typeof owner !== 'undefined') { 2560 return getComponentName(owner.type); 2561 } 2562 } 2563 return null; 2564 } 2565 2566 function getCurrentFiberStackInDev() { 2567 { 2568 if (current === null) { 2569 return ''; 2570 } 2571 // Safe because if current fiber exists, we are reconciling, 2572 // and it is guaranteed to be the work-in-progress version. 2573 return getStackByFiberInDevAndProd(current); 2574 } 2575 return ''; 2576 } 2577 2578 function resetCurrentFiber() { 2579 { 2580 ReactDebugCurrentFrame.getCurrentStack = null; 2581 current = null; 2582 phase = null; 2583 } 2584 } 2585 2586 function setCurrentFiber(fiber) { 2587 { 2588 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev; 2589 current = fiber; 2590 phase = null; 2591 } 2592 } 2593 2594 function setCurrentPhase(lifeCyclePhase) { 2595 { 2596 phase = lifeCyclePhase; 2597 } 2598 } 2599 2600 /** 2601 * Similar to invariant but only logs a warning if the condition is not met. 2602 * This can be used to log issues in development environments in critical 2603 * paths. Removing the logging code for production environments will keep the 2604 * same logic and follow the same code paths. 2605 */ 2606 2607 var warning = warningWithoutStack$1; 2608 2609 { 2610 warning = function (condition, format) { 2611 if (condition) { 2612 return; 2613 } 2614 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; 2615 var stack = ReactDebugCurrentFrame.getStackAddendum(); 2616 // eslint-disable-next-line react-internal/warning-and-invariant-args 2617 2618 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { 2619 args[_key - 2] = arguments[_key]; 2620 } 2621 2622 warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack])); 2623 }; 2624 } 2625 2626 var warning$1 = warning; 2627 2628 // A reserved attribute. 2629 // It is handled by React separately and shouldn't be written to the DOM. 2630 var RESERVED = 0; 2631 2632 // A simple string attribute. 2633 // Attributes that aren't in the whitelist are presumed to have this type. 2634 var STRING = 1; 2635 2636 // A string attribute that accepts booleans in React. In HTML, these are called 2637 // "enumerated" attributes with "true" and "false" as possible values. 2638 // When true, it should be set to a "true" string. 2639 // When false, it should be set to a "false" string. 2640 var BOOLEANISH_STRING = 2; 2641 2642 // A real boolean attribute. 2643 // When true, it should be present (set either to an empty string or its name). 2644 // When false, it should be omitted. 2645 var BOOLEAN = 3; 2646 2647 // An attribute that can be used as a flag as well as with a value. 2648 // When true, it should be present (set either to an empty string or its name). 2649 // When false, it should be omitted. 2650 // For any other value, should be present with that value. 2651 var OVERLOADED_BOOLEAN = 4; 2652 2653 // An attribute that must be numeric or parse as a numeric. 2654 // When falsy, it should be removed. 2655 var NUMERIC = 5; 2656 2657 // An attribute that must be positive numeric or parse as a positive numeric. 2658 // When falsy, it should be removed. 2659 var POSITIVE_NUMERIC = 6; 2660 2661 /* eslint-disable max-len */ 2662 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'; 2663 /* eslint-enable max-len */ 2664 var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040'; 2665 2666 2667 var ROOT_ATTRIBUTE_NAME = 'data-reactroot'; 2668 var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$'); 2669 2670 var hasOwnProperty = Object.prototype.hasOwnProperty; 2671 var illegalAttributeNameCache = {}; 2672 var validatedAttributeNameCache = {}; 2673 2674 function isAttributeNameSafe(attributeName) { 2675 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) { 2676 return true; 2677 } 2678 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) { 2679 return false; 2680 } 2681 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { 2682 validatedAttributeNameCache[attributeName] = true; 2683 return true; 2684 } 2685 illegalAttributeNameCache[attributeName] = true; 2686 { 2687 warning$1(false, 'Invalid attribute name: `%s`', attributeName); 2688 } 2689 return false; 2690 } 2691 2692 function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) { 2693 if (propertyInfo !== null) { 2694 return propertyInfo.type === RESERVED; 2695 } 2696 if (isCustomComponentTag) { 2697 return false; 2698 } 2699 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) { 2700 return true; 2701 } 2702 return false; 2703 } 2704 2705 function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) { 2706 if (propertyInfo !== null && propertyInfo.type === RESERVED) { 2707 return false; 2708 } 2709 switch (typeof value) { 2710 case 'function': 2711 // $FlowIssue symbol is perfectly valid here 2712 case 'symbol': 2713 // eslint-disable-line 2714 return true; 2715 case 'boolean': 2716 { 2717 if (isCustomComponentTag) { 2718 return false; 2719 } 2720 if (propertyInfo !== null) { 2721 return !propertyInfo.acceptsBooleans; 2722 } else { 2723 var prefix = name.toLowerCase().slice(0, 5); 2724 return prefix !== 'data-' && prefix !== 'aria-'; 2725 } 2726 } 2727 default: 2728 return false; 2729 } 2730 } 2731 2732 function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) { 2733 if (value === null || typeof value === 'undefined') { 2734 return true; 2735 } 2736 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) { 2737 return true; 2738 } 2739 if (isCustomComponentTag) { 2740 return false; 2741 } 2742 if (propertyInfo !== null) { 2743 switch (propertyInfo.type) { 2744 case BOOLEAN: 2745 return !value; 2746 case OVERLOADED_BOOLEAN: 2747 return value === false; 2748 case NUMERIC: 2749 return isNaN(value); 2750 case POSITIVE_NUMERIC: 2751 return isNaN(value) || value < 1; 2752 } 2753 } 2754 return false; 2755 } 2756 2757 function getPropertyInfo(name) { 2758 return properties.hasOwnProperty(name) ? properties[name] : null; 2759 } 2760 2761 function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace) { 2762 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN; 2763 this.attributeName = attributeName; 2764 this.attributeNamespace = attributeNamespace; 2765 this.mustUseProperty = mustUseProperty; 2766 this.propertyName = name; 2767 this.type = type; 2768 } 2769 2770 // When adding attributes to this list, be sure to also add them to 2771 // the `possibleStandardNames` module to ensure casing and incorrect 2772 // name warnings. 2773 var properties = {}; 2774 2775 // These props are reserved by React. They shouldn't be written to the DOM. 2776 ['children', 'dangerouslySetInnerHTML', 2777 // TODO: This prevents the assignment of defaultValue to regular 2778 // elements (not just inputs). Now that ReactDOMInput assigns to the 2779 // defaultValue property -- do we need this? 2780 'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) { 2781 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty 2782 name, // attributeName 2783 null); 2784 } // attributeNamespace 2785 ); 2786 2787 // A few React string attributes have a different name. 2788 // This is a mapping from React prop names to the attribute names. 2789 [['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) { 2790 var name = _ref[0], 2791 attributeName = _ref[1]; 2792 2793 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 2794 attributeName, // attributeName 2795 null); 2796 } // attributeNamespace 2797 ); 2798 2799 // These are "enumerated" HTML attributes that accept "true" and "false". 2800 // In React, we let users pass `true` and `false` even though technically 2801 // these aren't boolean attributes (they are coerced to strings). 2802 ['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) { 2803 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty 2804 name.toLowerCase(), // attributeName 2805 null); 2806 } // attributeNamespace 2807 ); 2808 2809 // These are "enumerated" SVG attributes that accept "true" and "false". 2810 // In React, we let users pass `true` and `false` even though technically 2811 // these aren't boolean attributes (they are coerced to strings). 2812 // Since these are SVG attributes, their attribute names are case-sensitive. 2813 ['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) { 2814 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty 2815 name, // attributeName 2816 null); 2817 } // attributeNamespace 2818 ); 2819 2820 // These are HTML boolean attributes. 2821 ['allowFullScreen', 'async', 2822 // Note: there is a special case that prevents it from being written to the DOM 2823 // on the client side because the browsers are inconsistent. Instead we call focus(). 2824 'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', 2825 // Microdata 2826 'itemScope'].forEach(function (name) { 2827 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty 2828 name.toLowerCase(), // attributeName 2829 null); 2830 } // attributeNamespace 2831 ); 2832 2833 // These are the few React props that we set as DOM properties 2834 // rather than attributes. These are all booleans. 2835 ['checked', 2836 // Note: `option.selected` is not updated if `select.multiple` is 2837 // disabled with `removeAttribute`. We have special logic for handling this. 2838 'multiple', 'muted', 'selected'].forEach(function (name) { 2839 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty 2840 name, // attributeName 2841 null); 2842 } // attributeNamespace 2843 ); 2844 2845 // These are HTML attributes that are "overloaded booleans": they behave like 2846 // booleans, but can also accept a string value. 2847 ['capture', 'download'].forEach(function (name) { 2848 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty 2849 name, // attributeName 2850 null); 2851 } // attributeNamespace 2852 ); 2853 2854 // These are HTML attributes that must be positive numbers. 2855 ['cols', 'rows', 'size', 'span'].forEach(function (name) { 2856 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty 2857 name, // attributeName 2858 null); 2859 } // attributeNamespace 2860 ); 2861 2862 // These are HTML attributes that must be numbers. 2863 ['rowSpan', 'start'].forEach(function (name) { 2864 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty 2865 name.toLowerCase(), // attributeName 2866 null); 2867 } // attributeNamespace 2868 ); 2869 2870 var CAMELIZE = /[\-\:]([a-z])/g; 2871 var capitalize = function (token) { 2872 return token[1].toUpperCase(); 2873 }; 2874 2875 // This is a list of all SVG attributes that need special casing, namespacing, 2876 // or boolean value assignment. Regular attributes that just accept strings 2877 // and have the same names are omitted, just like in the HTML whitelist. 2878 // Some of these attributes can be hard to find. This list was created by 2879 // scrapping the MDN documentation. 2880 ['accent-height', 'alignment-baseline', 'arabic-form', 'baseline-shift', 'cap-height', 'clip-path', 'clip-rule', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'dominant-baseline', 'enable-background', 'fill-opacity', 'fill-rule', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-name', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'horiz-adv-x', 'horiz-origin-x', 'image-rendering', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start', 'overline-position', 'overline-thickness', 'paint-order', 'panose-1', 'pointer-events', 'rendering-intent', 'shape-rendering', 'stop-color', 'stop-opacity', 'strikethrough-position', 'strikethrough-thickness', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-decoration', 'text-rendering', 'underline-position', 'underline-thickness', 'unicode-bidi', 'unicode-range', 'units-per-em', 'v-alphabetic', 'v-hanging', 'v-ideographic', 'v-mathematical', 'vector-effect', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'word-spacing', 'writing-mode', 'xmlns:xlink', 'x-height'].forEach(function (attributeName) { 2881 var name = attributeName.replace(CAMELIZE, capitalize); 2882 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 2883 attributeName, null); 2884 } // attributeNamespace 2885 ); 2886 2887 // String SVG attributes with the xlink namespace. 2888 ['xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) { 2889 var name = attributeName.replace(CAMELIZE, capitalize); 2890 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 2891 attributeName, 'http://www.w3.org/1999/xlink'); 2892 }); 2893 2894 // String SVG attributes with the xml namespace. 2895 ['xml:base', 'xml:lang', 'xml:space'].forEach(function (attributeName) { 2896 var name = attributeName.replace(CAMELIZE, capitalize); 2897 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 2898 attributeName, 'http://www.w3.org/XML/1998/namespace'); 2899 }); 2900 2901 // These attribute exists both in HTML and SVG. 2902 // The attribute name is case-sensitive in SVG so we can't just use 2903 // the React name like we do for attributes that exist only in HTML. 2904 ['tabIndex', 'crossOrigin'].forEach(function (attributeName) { 2905 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty 2906 attributeName.toLowerCase(), // attributeName 2907 null); 2908 } // attributeNamespace 2909 ); 2910 2911 /** 2912 * Get the value for a property on a node. Only used in DEV for SSR validation. 2913 * The "expected" argument is used as a hint of what the expected value is. 2914 * Some properties have multiple equivalent values. 2915 */ 2916 function getValueForProperty(node, name, expected, propertyInfo) { 2917 { 2918 if (propertyInfo.mustUseProperty) { 2919 var propertyName = propertyInfo.propertyName; 2920 2921 return node[propertyName]; 2922 } else { 2923 var attributeName = propertyInfo.attributeName; 2924 2925 var stringValue = null; 2926 2927 if (propertyInfo.type === OVERLOADED_BOOLEAN) { 2928 if (node.hasAttribute(attributeName)) { 2929 var value = node.getAttribute(attributeName); 2930 if (value === '') { 2931 return true; 2932 } 2933 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) { 2934 return value; 2935 } 2936 if (value === '' + expected) { 2937 return expected; 2938 } 2939 return value; 2940 } 2941 } else if (node.hasAttribute(attributeName)) { 2942 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) { 2943 // We had an attribute but shouldn't have had one, so read it 2944 // for the error message. 2945 return node.getAttribute(attributeName); 2946 } 2947 if (propertyInfo.type === BOOLEAN) { 2948 // If this was a boolean, it doesn't matter what the value is 2949 // the fact that we have it is the same as the expected. 2950 return expected; 2951 } 2952 // Even if this property uses a namespace we use getAttribute 2953 // because we assume its namespaced name is the same as our config. 2954 // To use getAttributeNS we need the local name which we don't have 2955 // in our config atm. 2956 stringValue = node.getAttribute(attributeName); 2957 } 2958 2959 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) { 2960 return stringValue === null ? expected : stringValue; 2961 } else if (stringValue === '' + expected) { 2962 return expected; 2963 } else { 2964 return stringValue; 2965 } 2966 } 2967 } 2968 } 2969 2970 /** 2971 * Get the value for a attribute on a node. Only used in DEV for SSR validation. 2972 * The third argument is used as a hint of what the expected value is. Some 2973 * attributes have multiple equivalent values. 2974 */ 2975 function getValueForAttribute(node, name, expected) { 2976 { 2977 if (!isAttributeNameSafe(name)) { 2978 return; 2979 } 2980 if (!node.hasAttribute(name)) { 2981 return expected === undefined ? undefined : null; 2982 } 2983 var value = node.getAttribute(name); 2984 if (value === '' + expected) { 2985 return expected; 2986 } 2987 return value; 2988 } 2989 } 2990 2991 /** 2992 * Sets the value for a property on a node. 2993 * 2994 * @param {DOMElement} node 2995 * @param {string} name 2996 * @param {*} value 2997 */ 2998 function setValueForProperty(node, name, value, isCustomComponentTag) { 2999 var propertyInfo = getPropertyInfo(name); 3000 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) { 3001 return; 3002 } 3003 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) { 3004 value = null; 3005 } 3006 // If the prop isn't in the special list, treat it as a simple attribute. 3007 if (isCustomComponentTag || propertyInfo === null) { 3008 if (isAttributeNameSafe(name)) { 3009 var _attributeName = name; 3010 if (value === null) { 3011 node.removeAttribute(_attributeName); 3012 } else { 3013 node.setAttribute(_attributeName, '' + value); 3014 } 3015 } 3016 return; 3017 } 3018 var mustUseProperty = propertyInfo.mustUseProperty; 3019 3020 if (mustUseProperty) { 3021 var propertyName = propertyInfo.propertyName; 3022 3023 if (value === null) { 3024 var type = propertyInfo.type; 3025 3026 node[propertyName] = type === BOOLEAN ? false : ''; 3027 } else { 3028 // Contrary to `setAttribute`, object properties are properly 3029 // `toString`ed by IE8/9. 3030 node[propertyName] = value; 3031 } 3032 return; 3033 } 3034 // The rest are treated as attributes with special cases. 3035 var attributeName = propertyInfo.attributeName, 3036 attributeNamespace = propertyInfo.attributeNamespace; 3037 3038 if (value === null) { 3039 node.removeAttribute(attributeName); 3040 } else { 3041 var _type = propertyInfo.type; 3042 3043 var attributeValue = void 0; 3044 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) { 3045 attributeValue = ''; 3046 } else { 3047 // `setAttribute` with objects becomes only `[object]` in IE8/9, 3048 // ('' + value) makes it output the correct toString()-value. 3049 attributeValue = '' + value; 3050 } 3051 if (attributeNamespace) { 3052 node.setAttributeNS(attributeNamespace, attributeName, attributeValue); 3053 } else { 3054 node.setAttribute(attributeName, attributeValue); 3055 } 3056 } 3057 } 3058 3059 // Flow does not allow string concatenation of most non-string types. To work 3060 // around this limitation, we use an opaque type that can only be obtained by 3061 // passing the value through getToStringValue first. 3062 function toString(value) { 3063 return '' + value; 3064 } 3065 3066 function getToStringValue(value) { 3067 switch (typeof value) { 3068 case 'boolean': 3069 case 'number': 3070 case 'object': 3071 case 'string': 3072 case 'undefined': 3073 return value; 3074 default: 3075 // function, symbol are assigned as empty strings 3076 return ''; 3077 } 3078 } 3079 3080 /** 3081 * Copyright (c) 2013-present, Facebook, Inc. 3082 * 3083 * This source code is licensed under the MIT license found in the 3084 * LICENSE file in the root directory of this source tree. 3085 */ 3086 3087 3088 3089 var ReactPropTypesSecret$1 = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; 3090 3091 var ReactPropTypesSecret_1 = ReactPropTypesSecret$1; 3092 3093 /** 3094 * Copyright (c) 2013-present, Facebook, Inc. 3095 * 3096 * This source code is licensed under the MIT license found in the 3097 * LICENSE file in the root directory of this source tree. 3098 */ 3099 3100 3101 3102 var printWarning = function() {}; 3103 3104 { 3105 var ReactPropTypesSecret = ReactPropTypesSecret_1; 3106 var loggedTypeFailures = {}; 3107 3108 printWarning = function(text) { 3109 var message = 'Warning: ' + text; 3110 if (typeof console !== 'undefined') { 3111 console.error(message); 3112 } 3113 try { 3114 // --- Welcome to debugging React --- 3115 // This error was thrown as a convenience so that you can use this stack 3116 // to find the callsite that caused this warning to fire. 3117 throw new Error(message); 3118 } catch (x) {} 3119 }; 3120 } 3121 3122 /** 3123 * Assert that the values match with the type specs. 3124 * Error messages are memorized and will only be shown once. 3125 * 3126 * @param {object} typeSpecs Map of name to a ReactPropType 3127 * @param {object} values Runtime values that need to be type-checked 3128 * @param {string} location e.g. "prop", "context", "child context" 3129 * @param {string} componentName Name of the component for error messages. 3130 * @param {?Function} getStack Returns the component stack. 3131 * @private 3132 */ 3133 function checkPropTypes(typeSpecs, values, location, componentName, getStack) { 3134 { 3135 for (var typeSpecName in typeSpecs) { 3136 if (typeSpecs.hasOwnProperty(typeSpecName)) { 3137 var error; 3138 // Prop type validation may throw. In case they do, we don't want to 3139 // fail the render phase where it didn't fail before. So we log it. 3140 // After these have been cleaned up, we'll let them throw. 3141 try { 3142 // This is intentionally an invariant that gets caught. It's the same 3143 // behavior as without this statement except with a better message. 3144 if (typeof typeSpecs[typeSpecName] !== 'function') { 3145 var err = Error( 3146 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + 3147 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' 3148 ); 3149 err.name = 'Invariant Violation'; 3150 throw err; 3151 } 3152 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret); 3153 } catch (ex) { 3154 error = ex; 3155 } 3156 if (error && !(error instanceof Error)) { 3157 printWarning( 3158 (componentName || 'React class') + ': type specification of ' + 3159 location + ' `' + typeSpecName + '` is invalid; the type checker ' + 3160 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' + 3161 'You may have forgotten to pass an argument to the type checker ' + 3162 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 3163 'shape all require an argument).' 3164 ); 3165 3166 } 3167 if (error instanceof Error && !(error.message in loggedTypeFailures)) { 3168 // Only monitor this failure once because there tends to be a lot of the 3169 // same error. 3170 loggedTypeFailures[error.message] = true; 3171 3172 var stack = getStack ? getStack() : ''; 3173 3174 printWarning( 3175 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '') 3176 ); 3177 } 3178 } 3179 } 3180 } 3181 } 3182 3183 var checkPropTypes_1 = checkPropTypes; 3184 3185 var ReactDebugCurrentFrame$1 = null; 3186 3187 var ReactControlledValuePropTypes = { 3188 checkPropTypes: null 3189 }; 3190 3191 { 3192 ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame; 3193 3194 var hasReadOnlyValue = { 3195 button: true, 3196 checkbox: true, 3197 image: true, 3198 hidden: true, 3199 radio: true, 3200 reset: true, 3201 submit: true 3202 }; 3203 3204 var propTypes = { 3205 value: function (props, propName, componentName) { 3206 if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null) { 3207 return null; 3208 } 3209 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`.'); 3210 }, 3211 checked: function (props, propName, componentName) { 3212 if (props.onChange || props.readOnly || props.disabled || props[propName] == null) { 3213 return null; 3214 } 3215 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`.'); 3216 } 3217 }; 3218 3219 /** 3220 * Provide a linked `value` attribute for controlled forms. You should not use 3221 * this outside of the ReactDOM controlled form components. 3222 */ 3223 ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) { 3224 checkPropTypes_1(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$1.getStackAddendum); 3225 }; 3226 } 3227 3228 var enableUserTimingAPI = true; 3229 3230 // Helps identify side effects in begin-phase lifecycle hooks and setState reducers: 3231 var debugRenderPhaseSideEffects = false; 3232 3233 // In some cases, StrictMode should also double-render lifecycles. 3234 // This can be confusing for tests though, 3235 // And it can be bad for performance in production. 3236 // This feature flag can be used to control the behavior: 3237 var debugRenderPhaseSideEffectsForStrictMode = true; 3238 3239 // To preserve the "Pause on caught exceptions" behavior of the debugger, we 3240 // replay the begin phase of a failed component inside invokeGuardedCallback. 3241 var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; 3242 3243 // Warn about deprecated, async-unsafe lifecycles; relates to RFC #6: 3244 var warnAboutDeprecatedLifecycles = false; 3245 3246 // Gather advanced timing metrics for Profiler subtrees. 3247 var enableProfilerTimer = true; 3248 3249 // Trace which interactions trigger each commit. 3250 var enableSchedulerTracing = true; 3251 3252 // Only used in www builds. 3253 var enableSuspenseServerRenderer = false; // TODO: true? Here it might just be false. 3254 3255 // Only used in www builds. 3256 3257 3258 // Only used in www builds. 3259 3260 3261 // React Fire: prevent the value and checked attributes from syncing 3262 // with their related DOM properties 3263 var disableInputAttributeSyncing = false; 3264 3265 // These APIs will no longer be "unstable" in the upcoming 16.7 release, 3266 // Control this behavior with a flag to support 16.6 minor releases in the meanwhile. 3267 var enableStableConcurrentModeAPIs = false; 3268 3269 var warnAboutShorthandPropertyCollision = false; 3270 3271 // TODO: direct imports like some-package/src/* are bad. Fix me. 3272 var didWarnValueDefaultValue = false; 3273 var didWarnCheckedDefaultChecked = false; 3274 var didWarnControlledToUncontrolled = false; 3275 var didWarnUncontrolledToControlled = false; 3276 3277 function isControlled(props) { 3278 var usesChecked = props.type === 'checkbox' || props.type === 'radio'; 3279 return usesChecked ? props.checked != null : props.value != null; 3280 } 3281 3282 /** 3283 * Implements an <input> host component that allows setting these optional 3284 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`. 3285 * 3286 * If `checked` or `value` are not supplied (or null/undefined), user actions 3287 * that affect the checked state or value will trigger updates to the element. 3288 * 3289 * If they are supplied (and not null/undefined), the rendered element will not 3290 * trigger updates to the element. Instead, the props must change in order for 3291 * the rendered element to be updated. 3292 * 3293 * The rendered element will be initialized as unchecked (or `defaultChecked`) 3294 * with an empty value (or `defaultValue`). 3295 * 3296 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html 3297 */ 3298 3299 function getHostProps(element, props) { 3300 var node = element; 3301 var checked = props.checked; 3302 3303 var hostProps = _assign({}, props, { 3304 defaultChecked: undefined, 3305 defaultValue: undefined, 3306 value: undefined, 3307 checked: checked != null ? checked : node._wrapperState.initialChecked 3308 }); 3309 3310 return hostProps; 3311 } 3312 3313 function initWrapperState(element, props) { 3314 { 3315 ReactControlledValuePropTypes.checkPropTypes('input', props); 3316 3317 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) { 3318 warning$1(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', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type); 3319 didWarnCheckedDefaultChecked = true; 3320 } 3321 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) { 3322 warning$1(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', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type); 3323 didWarnValueDefaultValue = true; 3324 } 3325 } 3326 3327 var node = element; 3328 var defaultValue = props.defaultValue == null ? '' : props.defaultValue; 3329 3330 node._wrapperState = { 3331 initialChecked: props.checked != null ? props.checked : props.defaultChecked, 3332 initialValue: getToStringValue(props.value != null ? props.value : defaultValue), 3333 controlled: isControlled(props) 3334 }; 3335 } 3336 3337 function updateChecked(element, props) { 3338 var node = element; 3339 var checked = props.checked; 3340 if (checked != null) { 3341 setValueForProperty(node, 'checked', checked, false); 3342 } 3343 } 3344 3345 function updateWrapper(element, props) { 3346 var node = element; 3347 { 3348 var _controlled = isControlled(props); 3349 3350 if (!node._wrapperState.controlled && _controlled && !didWarnUncontrolledToControlled) { 3351 warning$1(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', props.type); 3352 didWarnUncontrolledToControlled = true; 3353 } 3354 if (node._wrapperState.controlled && !_controlled && !didWarnControlledToUncontrolled) { 3355 warning$1(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', props.type); 3356 didWarnControlledToUncontrolled = true; 3357 } 3358 } 3359 3360 updateChecked(element, props); 3361 3362 var value = getToStringValue(props.value); 3363 var type = props.type; 3364 3365 if (value != null) { 3366 if (type === 'number') { 3367 if (value === 0 && node.value === '' || 3368 // We explicitly want to coerce to number here if possible. 3369 // eslint-disable-next-line 3370 node.value != value) { 3371 node.value = toString(value); 3372 } 3373 } else if (node.value !== toString(value)) { 3374 node.value = toString(value); 3375 } 3376 } else if (type === 'submit' || type === 'reset') { 3377 // Submit/reset inputs need the attribute removed completely to avoid 3378 // blank-text buttons. 3379 node.removeAttribute('value'); 3380 return; 3381 } 3382 3383 if (disableInputAttributeSyncing) { 3384 // When not syncing the value attribute, React only assigns a new value 3385 // whenever the defaultValue React prop has changed. When not present, 3386 // React does nothing 3387 if (props.hasOwnProperty('defaultValue')) { 3388 setDefaultValue(node, props.type, getToStringValue(props.defaultValue)); 3389 } 3390 } else { 3391 // When syncing the value attribute, the value comes from a cascade of 3392 // properties: 3393 // 1. The value React property 3394 // 2. The defaultValue React property 3395 // 3. Otherwise there should be no change 3396 if (props.hasOwnProperty('value')) { 3397 setDefaultValue(node, props.type, value); 3398 } else if (props.hasOwnProperty('defaultValue')) { 3399 setDefaultValue(node, props.type, getToStringValue(props.defaultValue)); 3400 } 3401 } 3402 3403 if (disableInputAttributeSyncing) { 3404 // When not syncing the checked attribute, the attribute is directly 3405 // controllable from the defaultValue React property. It needs to be 3406 // updated as new props come in. 3407 if (props.defaultChecked == null) { 3408 node.removeAttribute('checked'); 3409 } else { 3410 node.defaultChecked = !!props.defaultChecked; 3411 } 3412 } else { 3413 // When syncing the checked attribute, it only changes when it needs 3414 // to be removed, such as transitioning from a checkbox into a text input 3415 if (props.checked == null && props.defaultChecked != null) { 3416 node.defaultChecked = !!props.defaultChecked; 3417 } 3418 } 3419 } 3420 3421 function postMountWrapper(element, props, isHydrating) { 3422 var node = element; 3423 3424 // Do not assign value if it is already set. This prevents user text input 3425 // from being lost during SSR hydration. 3426 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) { 3427 var type = props.type; 3428 var isButton = type === 'submit' || type === 'reset'; 3429 3430 // Avoid setting value attribute on submit/reset inputs as it overrides the 3431 // default value provided by the browser. See: #12872 3432 if (isButton && (props.value === undefined || props.value === null)) { 3433 return; 3434 } 3435 3436 var _initialValue = toString(node._wrapperState.initialValue); 3437 3438 // Do not assign value if it is already set. This prevents user text input 3439 // from being lost during SSR hydration. 3440 if (!isHydrating) { 3441 if (disableInputAttributeSyncing) { 3442 var value = getToStringValue(props.value); 3443 3444 // When not syncing the value attribute, the value property points 3445 // directly to the React prop. Only assign it if it exists. 3446 if (value != null) { 3447 // Always assign on buttons so that it is possible to assign an 3448 // empty string to clear button text. 3449 // 3450 // Otherwise, do not re-assign the value property if is empty. This 3451 // potentially avoids a DOM write and prevents Firefox (~60.0.1) from 3452 // prematurely marking required inputs as invalid. Equality is compared 3453 // to the current value in case the browser provided value is not an 3454 // empty string. 3455 if (isButton || value !== node.value) { 3456 node.value = toString(value); 3457 } 3458 } 3459 } else { 3460 // When syncing the value attribute, the value property should use 3461 // the wrapperState._initialValue property. This uses: 3462 // 3463 // 1. The value React property when present 3464 // 2. The defaultValue React property when present 3465 // 3. An empty string 3466 if (_initialValue !== node.value) { 3467 node.value = _initialValue; 3468 } 3469 } 3470 } 3471 3472 if (disableInputAttributeSyncing) { 3473 // When not syncing the value attribute, assign the value attribute 3474 // directly from the defaultValue React property (when present) 3475 var defaultValue = getToStringValue(props.defaultValue); 3476 if (defaultValue != null) { 3477 node.defaultValue = toString(defaultValue); 3478 } 3479 } else { 3480 // Otherwise, the value attribute is synchronized to the property, 3481 // so we assign defaultValue to the same thing as the value property 3482 // assignment step above. 3483 node.defaultValue = _initialValue; 3484 } 3485 } 3486 3487 // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug 3488 // this is needed to work around a chrome bug where setting defaultChecked 3489 // will sometimes influence the value of checked (even after detachment). 3490 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416 3491 // We need to temporarily unset name to avoid disrupting radio button groups. 3492 var name = node.name; 3493 if (name !== '') { 3494 node.name = ''; 3495 } 3496 3497 if (disableInputAttributeSyncing) { 3498 // When not syncing the checked attribute, the checked property 3499 // never gets assigned. It must be manually set. We don't want 3500 // to do this when hydrating so that existing user input isn't 3501 // modified 3502 if (!isHydrating) { 3503 updateChecked(element, props); 3504 } 3505 3506 // Only assign the checked attribute if it is defined. This saves 3507 // a DOM write when controlling the checked attribute isn't needed 3508 // (text inputs, submit/reset) 3509 if (props.hasOwnProperty('defaultChecked')) { 3510 node.defaultChecked = !node.defaultChecked; 3511 node.defaultChecked = !!props.defaultChecked; 3512 } 3513 } else { 3514 // When syncing the checked attribute, both the checked property and 3515 // attribute are assigned at the same time using defaultChecked. This uses: 3516 // 3517 // 1. The checked React property when present 3518 // 2. The defaultChecked React property when present 3519 // 3. Otherwise, false 3520 node.defaultChecked = !node.defaultChecked; 3521 node.defaultChecked = !!node._wrapperState.initialChecked; 3522 } 3523 3524 if (name !== '') { 3525 node.name = name; 3526 } 3527 } 3528 3529 function restoreControlledState(element, props) { 3530 var node = element; 3531 updateWrapper(node, props); 3532 updateNamedCousins(node, props); 3533 } 3534 3535 function updateNamedCousins(rootNode, props) { 3536 var name = props.name; 3537 if (props.type === 'radio' && name != null) { 3538 var queryRoot = rootNode; 3539 3540 while (queryRoot.parentNode) { 3541 queryRoot = queryRoot.parentNode; 3542 } 3543 3544 // If `rootNode.form` was non-null, then we could try `form.elements`, 3545 // but that sometimes behaves strangely in IE8. We could also try using 3546 // `form.getElementsByName`, but that will only return direct children 3547 // and won't include inputs that use the HTML5 `form=` attribute. Since 3548 // the input might not even be in a form. It might not even be in the 3549 // document. Let's just use the local `querySelectorAll` to ensure we don't 3550 // miss anything. 3551 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]'); 3552 3553 for (var i = 0; i < group.length; i++) { 3554 var otherNode = group[i]; 3555 if (otherNode === rootNode || otherNode.form !== rootNode.form) { 3556 continue; 3557 } 3558 // This will throw if radio buttons rendered by different copies of React 3559 // and the same name are rendered into the same form (same as #1939). 3560 // That's probably okay; we don't support it just as we don't support 3561 // mixing React radio buttons with non-React ones. 3562 var otherProps = getFiberCurrentPropsFromNode$1(otherNode); 3563 !otherProps ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : void 0; 3564 3565 // We need update the tracked value on the named cousin since the value 3566 // was changed but the input saw no event or value set 3567 updateValueIfChanged(otherNode); 3568 3569 // If this is a controlled radio button group, forcing the input that 3570 // was previously checked to update will cause it to be come re-checked 3571 // as appropriate. 3572 updateWrapper(otherNode, otherProps); 3573 } 3574 } 3575 } 3576 3577 // In Chrome, assigning defaultValue to certain input types triggers input validation. 3578 // For number inputs, the display value loses trailing decimal points. For email inputs, 3579 // Chrome raises "The specified value <x> is not a valid email address". 3580 // 3581 // Here we check to see if the defaultValue has actually changed, avoiding these problems 3582 // when the user is inputting text 3583 // 3584 // https://github.com/facebook/react/issues/7253 3585 function setDefaultValue(node, type, value) { 3586 if ( 3587 // Focused number inputs synchronize on blur. See ChangeEventPlugin.js 3588 type !== 'number' || node.ownerDocument.activeElement !== node) { 3589 if (value == null) { 3590 node.defaultValue = toString(node._wrapperState.initialValue); 3591 } else if (node.defaultValue !== toString(value)) { 3592 node.defaultValue = toString(value); 3593 } 3594 } 3595 } 3596 3597 var eventTypes$1 = { 3598 change: { 3599 phasedRegistrationNames: { 3600 bubbled: 'onChange', 3601 captured: 'onChangeCapture' 3602 }, 3603 dependencies: [TOP_BLUR, TOP_CHANGE, TOP_CLICK, TOP_FOCUS, TOP_INPUT, TOP_KEY_DOWN, TOP_KEY_UP, TOP_SELECTION_CHANGE] 3604 } 3605 }; 3606 3607 function createAndAccumulateChangeEvent(inst, nativeEvent, target) { 3608 var event = SyntheticEvent.getPooled(eventTypes$1.change, inst, nativeEvent, target); 3609 event.type = 'change'; 3610 // Flag this event loop as needing state restore. 3611 enqueueStateRestore(target); 3612 accumulateTwoPhaseDispatches(event); 3613 return event; 3614 } 3615 /** 3616 * For IE shims 3617 */ 3618 var activeElement = null; 3619 var activeElementInst = null; 3620 3621 /** 3622 * SECTION: handle `change` event 3623 */ 3624 function shouldUseChangeEvent(elem) { 3625 var nodeName = elem.nodeName && elem.nodeName.toLowerCase(); 3626 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file'; 3627 } 3628 3629 function manualDispatchChangeEvent(nativeEvent) { 3630 var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent)); 3631 3632 // If change and propertychange bubbled, we'd just bind to it like all the 3633 // other events and have it go through ReactBrowserEventEmitter. Since it 3634 // doesn't, we manually listen for the events and so we have to enqueue and 3635 // process the abstract event manually. 3636 // 3637 // Batching is necessary here in order to ensure that all event handlers run 3638 // before the next rerender (including event handlers attached to ancestor 3639 // elements instead of directly on the input). Without this, controlled 3640 // components don't work properly in conjunction with event bubbling because 3641 // the component is rerendered and the value reverted before all the event 3642 // handlers can run. See https://github.com/facebook/react/issues/708. 3643 batchedUpdates(runEventInBatch, event); 3644 } 3645 3646 function runEventInBatch(event) { 3647 runEventsInBatch(event); 3648 } 3649 3650 function getInstIfValueChanged(targetInst) { 3651 var targetNode = getNodeFromInstance$1(targetInst); 3652 if (updateValueIfChanged(targetNode)) { 3653 return targetInst; 3654 } 3655 } 3656 3657 function getTargetInstForChangeEvent(topLevelType, targetInst) { 3658 if (topLevelType === TOP_CHANGE) { 3659 return targetInst; 3660 } 3661 } 3662 3663 /** 3664 * SECTION: handle `input` event 3665 */ 3666 var isInputEventSupported = false; 3667 if (canUseDOM) { 3668 // IE9 claims to support the input event but fails to trigger it when 3669 // deleting text, so we ignore its input events. 3670 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9); 3671 } 3672 3673 /** 3674 * (For IE <=9) Starts tracking propertychange events on the passed-in element 3675 * and override the value property so that we can distinguish user events from 3676 * value changes in JS. 3677 */ 3678 function startWatchingForValueChange(target, targetInst) { 3679 activeElement = target; 3680 activeElementInst = targetInst; 3681 activeElement.attachEvent('onpropertychange', handlePropertyChange); 3682 } 3683 3684 /** 3685 * (For IE <=9) Removes the event listeners from the currently-tracked element, 3686 * if any exists. 3687 */ 3688 function stopWatchingForValueChange() { 3689 if (!activeElement) { 3690 return; 3691 } 3692 activeElement.detachEvent('onpropertychange', handlePropertyChange); 3693 activeElement = null; 3694 activeElementInst = null; 3695 } 3696 3697 /** 3698 * (For IE <=9) Handles a propertychange event, sending a `change` event if 3699 * the value of the active element has changed. 3700 */ 3701 function handlePropertyChange(nativeEvent) { 3702 if (nativeEvent.propertyName !== 'value') { 3703 return; 3704 } 3705 if (getInstIfValueChanged(activeElementInst)) { 3706 manualDispatchChangeEvent(nativeEvent); 3707 } 3708 } 3709 3710 function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) { 3711 if (topLevelType === TOP_FOCUS) { 3712 // In IE9, propertychange fires for most input events but is buggy and 3713 // doesn't fire when text is deleted, but conveniently, selectionchange 3714 // appears to fire in all of the remaining cases so we catch those and 3715 // forward the event if the value has changed 3716 // In either case, we don't want to call the event handler if the value 3717 // is changed from JS so we redefine a setter for `.value` that updates 3718 // our activeElementValue variable, allowing us to ignore those changes 3719 // 3720 // stopWatching() should be a noop here but we call it just in case we 3721 // missed a blur event somehow. 3722 stopWatchingForValueChange(); 3723 startWatchingForValueChange(target, targetInst); 3724 } else if (topLevelType === TOP_BLUR) { 3725 stopWatchingForValueChange(); 3726 } 3727 } 3728 3729 // For IE8 and IE9. 3730 function getTargetInstForInputEventPolyfill(topLevelType, targetInst) { 3731 if (topLevelType === TOP_SELECTION_CHANGE || topLevelType === TOP_KEY_UP || topLevelType === TOP_KEY_DOWN) { 3732 // On the selectionchange event, the target is just document which isn't 3733 // helpful for us so just check activeElement instead. 3734 // 3735 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire 3736 // propertychange on the first input event after setting `value` from a 3737 // script and fires only keydown, keypress, keyup. Catching keyup usually 3738 // gets it and catching keydown lets us fire an event for the first 3739 // keystroke if user does a key repeat (it'll be a little delayed: right 3740 // before the second keystroke). Other input methods (e.g., paste) seem to 3741 // fire selectionchange normally. 3742 return getInstIfValueChanged(activeElementInst); 3743 } 3744 } 3745 3746 /** 3747 * SECTION: handle `click` event 3748 */ 3749 function shouldUseClickEvent(elem) { 3750 // Use the `click` event to detect changes to checkbox and radio inputs. 3751 // This approach works across all browsers, whereas `change` does not fire 3752 // until `blur` in IE8. 3753 var nodeName = elem.nodeName; 3754 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio'); 3755 } 3756 3757 function getTargetInstForClickEvent(topLevelType, targetInst) { 3758 if (topLevelType === TOP_CLICK) { 3759 return getInstIfValueChanged(targetInst); 3760 } 3761 } 3762 3763 function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) { 3764 if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) { 3765 return getInstIfValueChanged(targetInst); 3766 } 3767 } 3768 3769 function handleControlledInputBlur(node) { 3770 var state = node._wrapperState; 3771 3772 if (!state || !state.controlled || node.type !== 'number') { 3773 return; 3774 } 3775 3776 if (!disableInputAttributeSyncing) { 3777 // If controlled, assign the value attribute to the current value on blur 3778 setDefaultValue(node, 'number', node.value); 3779 } 3780 } 3781 3782 /** 3783 * This plugin creates an `onChange` event that normalizes change events 3784 * across form elements. This event fires at a time when it's possible to 3785 * change the element's value without seeing a flicker. 3786 * 3787 * Supported elements are: 3788 * - input (see `isTextInputElement`) 3789 * - textarea 3790 * - select 3791 */ 3792 var ChangeEventPlugin = { 3793 eventTypes: eventTypes$1, 3794 3795 _isInputEventSupported: isInputEventSupported, 3796 3797 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { 3798 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window; 3799 3800 var getTargetInstFunc = void 0, 3801 handleEventFunc = void 0; 3802 if (shouldUseChangeEvent(targetNode)) { 3803 getTargetInstFunc = getTargetInstForChangeEvent; 3804 } else if (isTextInputElement(targetNode)) { 3805 if (isInputEventSupported) { 3806 getTargetInstFunc = getTargetInstForInputOrChangeEvent; 3807 } else { 3808 getTargetInstFunc = getTargetInstForInputEventPolyfill; 3809 handleEventFunc = handleEventsForInputEventPolyfill; 3810 } 3811 } else if (shouldUseClickEvent(targetNode)) { 3812 getTargetInstFunc = getTargetInstForClickEvent; 3813 } 3814 3815 if (getTargetInstFunc) { 3816 var inst = getTargetInstFunc(topLevelType, targetInst); 3817 if (inst) { 3818 var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget); 3819 return event; 3820 } 3821 } 3822 3823 if (handleEventFunc) { 3824 handleEventFunc(topLevelType, targetNode, targetInst); 3825 } 3826 3827 // When blurring, set the value attribute for number inputs 3828 if (topLevelType === TOP_BLUR) { 3829 handleControlledInputBlur(targetNode); 3830 } 3831 } 3832 }; 3833 3834 /** 3835 * Module that is injectable into `EventPluginHub`, that specifies a 3836 * deterministic ordering of `EventPlugin`s. A convenient way to reason about 3837 * plugins, without having to package every one of them. This is better than 3838 * having plugins be ordered in the same order that they are injected because 3839 * that ordering would be influenced by the packaging order. 3840 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that 3841 * preventing default on events is convenient in `SimpleEventPlugin` handlers. 3842 */ 3843 var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin']; 3844 3845 var SyntheticUIEvent = SyntheticEvent.extend({ 3846 view: null, 3847 detail: null 3848 }); 3849 3850 var modifierKeyToProp = { 3851 Alt: 'altKey', 3852 Control: 'ctrlKey', 3853 Meta: 'metaKey', 3854 Shift: 'shiftKey' 3855 }; 3856 3857 // Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support 3858 // getModifierState. If getModifierState is not supported, we map it to a set of 3859 // modifier keys exposed by the event. In this case, Lock-keys are not supported. 3860 /** 3861 * Translation from modifier key to the associated property in the event. 3862 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers 3863 */ 3864 3865 function modifierStateGetter(keyArg) { 3866 var syntheticEvent = this; 3867 var nativeEvent = syntheticEvent.nativeEvent; 3868 if (nativeEvent.getModifierState) { 3869 return nativeEvent.getModifierState(keyArg); 3870 } 3871 var keyProp = modifierKeyToProp[keyArg]; 3872 return keyProp ? !!nativeEvent[keyProp] : false; 3873 } 3874 3875 function getEventModifierState(nativeEvent) { 3876 return modifierStateGetter; 3877 } 3878 3879 var previousScreenX = 0; 3880 var previousScreenY = 0; 3881 // Use flags to signal movementX/Y has already been set 3882 var isMovementXSet = false; 3883 var isMovementYSet = false; 3884 3885 /** 3886 * @interface MouseEvent 3887 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 3888 */ 3889 var SyntheticMouseEvent = SyntheticUIEvent.extend({ 3890 screenX: null, 3891 screenY: null, 3892 clientX: null, 3893 clientY: null, 3894 pageX: null, 3895 pageY: null, 3896 ctrlKey: null, 3897 shiftKey: null, 3898 altKey: null, 3899 metaKey: null, 3900 getModifierState: getEventModifierState, 3901 button: null, 3902 buttons: null, 3903 relatedTarget: function (event) { 3904 return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement); 3905 }, 3906 movementX: function (event) { 3907 if ('movementX' in event) { 3908 return event.movementX; 3909 } 3910 3911 var screenX = previousScreenX; 3912 previousScreenX = event.screenX; 3913 3914 if (!isMovementXSet) { 3915 isMovementXSet = true; 3916 return 0; 3917 } 3918 3919 return event.type === 'mousemove' ? event.screenX - screenX : 0; 3920 }, 3921 movementY: function (event) { 3922 if ('movementY' in event) { 3923 return event.movementY; 3924 } 3925 3926 var screenY = previousScreenY; 3927 previousScreenY = event.screenY; 3928 3929 if (!isMovementYSet) { 3930 isMovementYSet = true; 3931 return 0; 3932 } 3933 3934 return event.type === 'mousemove' ? event.screenY - screenY : 0; 3935 } 3936 }); 3937 3938 /** 3939 * @interface PointerEvent 3940 * @see http://www.w3.org/TR/pointerevents/ 3941 */ 3942 var SyntheticPointerEvent = SyntheticMouseEvent.extend({ 3943 pointerId: null, 3944 width: null, 3945 height: null, 3946 pressure: null, 3947 tangentialPressure: null, 3948 tiltX: null, 3949 tiltY: null, 3950 twist: null, 3951 pointerType: null, 3952 isPrimary: null 3953 }); 3954 3955 var eventTypes$2 = { 3956 mouseEnter: { 3957 registrationName: 'onMouseEnter', 3958 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER] 3959 }, 3960 mouseLeave: { 3961 registrationName: 'onMouseLeave', 3962 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER] 3963 }, 3964 pointerEnter: { 3965 registrationName: 'onPointerEnter', 3966 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER] 3967 }, 3968 pointerLeave: { 3969 registrationName: 'onPointerLeave', 3970 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER] 3971 } 3972 }; 3973 3974 var EnterLeaveEventPlugin = { 3975 eventTypes: eventTypes$2, 3976 3977 /** 3978 * For almost every interaction we care about, there will be both a top-level 3979 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that 3980 * we do not extract duplicate events. However, moving the mouse into the 3981 * browser from outside will not fire a `mouseout` event. In this case, we use 3982 * the `mouseover` top-level event. 3983 */ 3984 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { 3985 var isOverEvent = topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER; 3986 var isOutEvent = topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT; 3987 3988 if (isOverEvent && (nativeEvent.relatedTarget || nativeEvent.fromElement)) { 3989 return null; 3990 } 3991 3992 if (!isOutEvent && !isOverEvent) { 3993 // Must not be a mouse or pointer in or out - ignoring. 3994 return null; 3995 } 3996 3997 var win = void 0; 3998 if (nativeEventTarget.window === nativeEventTarget) { 3999 // `nativeEventTarget` is probably a window object. 4000 win = nativeEventTarget; 4001 } else { 4002 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. 4003 var doc = nativeEventTarget.ownerDocument; 4004 if (doc) { 4005 win = doc.defaultView || doc.parentWindow; 4006 } else { 4007 win = window; 4008 } 4009 } 4010 4011 var from = void 0; 4012 var to = void 0; 4013 if (isOutEvent) { 4014 from = targetInst; 4015 var related = nativeEvent.relatedTarget || nativeEvent.toElement; 4016 to = related ? getClosestInstanceFromNode(related) : null; 4017 } else { 4018 // Moving to a node from outside the window. 4019 from = null; 4020 to = targetInst; 4021 } 4022 4023 if (from === to) { 4024 // Nothing pertains to our managed components. 4025 return null; 4026 } 4027 4028 var eventInterface = void 0, 4029 leaveEventType = void 0, 4030 enterEventType = void 0, 4031 eventTypePrefix = void 0; 4032 4033 if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) { 4034 eventInterface = SyntheticMouseEvent; 4035 leaveEventType = eventTypes$2.mouseLeave; 4036 enterEventType = eventTypes$2.mouseEnter; 4037 eventTypePrefix = 'mouse'; 4038 } else if (topLevelType === TOP_POINTER_OUT || topLevelType === TOP_POINTER_OVER) { 4039 eventInterface = SyntheticPointerEvent; 4040 leaveEventType = eventTypes$2.pointerLeave; 4041 enterEventType = eventTypes$2.pointerEnter; 4042 eventTypePrefix = 'pointer'; 4043 } 4044 4045 var fromNode = from == null ? win : getNodeFromInstance$1(from); 4046 var toNode = to == null ? win : getNodeFromInstance$1(to); 4047 4048 var leave = eventInterface.getPooled(leaveEventType, from, nativeEvent, nativeEventTarget); 4049 leave.type = eventTypePrefix + 'leave'; 4050 leave.target = fromNode; 4051 leave.relatedTarget = toNode; 4052 4053 var enter = eventInterface.getPooled(enterEventType, to, nativeEvent, nativeEventTarget); 4054 enter.type = eventTypePrefix + 'enter'; 4055 enter.target = toNode; 4056 enter.relatedTarget = fromNode; 4057 4058 accumulateEnterLeaveDispatches(leave, enter, from, to); 4059 4060 return [leave, enter]; 4061 } 4062 }; 4063 4064 /** 4065 * inlined Object.is polyfill to avoid requiring consumers ship their own 4066 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is 4067 */ 4068 function is(x, y) { 4069 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare 4070 ; 4071 } 4072 4073 var hasOwnProperty$1 = Object.prototype.hasOwnProperty; 4074 4075 /** 4076 * Performs equality by iterating through keys on an object and returning false 4077 * when any key has values which are not strictly equal between the arguments. 4078 * Returns true when the values of all keys are strictly equal. 4079 */ 4080 function shallowEqual(objA, objB) { 4081 if (is(objA, objB)) { 4082 return true; 4083 } 4084 4085 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { 4086 return false; 4087 } 4088 4089 var keysA = Object.keys(objA); 4090 var keysB = Object.keys(objB); 4091 4092 if (keysA.length !== keysB.length) { 4093 return false; 4094 } 4095 4096 // Test for A's keys different from B. 4097 for (var i = 0; i < keysA.length; i++) { 4098 if (!hasOwnProperty$1.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) { 4099 return false; 4100 } 4101 } 4102 4103 return true; 4104 } 4105 4106 /** 4107 * `ReactInstanceMap` maintains a mapping from a public facing stateful 4108 * instance (key) and the internal representation (value). This allows public 4109 * methods to accept the user facing instance as an argument and map them back 4110 * to internal methods. 4111 * 4112 * Note that this module is currently shared and assumed to be stateless. 4113 * If this becomes an actual Map, that will break. 4114 */ 4115 4116 /** 4117 * This API should be called `delete` but we'd have to make sure to always 4118 * transform these to strings for IE support. When this transform is fully 4119 * supported we can rename it. 4120 */ 4121 4122 4123 function get(key) { 4124 return key._reactInternalFiber; 4125 } 4126 4127 function has(key) { 4128 return key._reactInternalFiber !== undefined; 4129 } 4130 4131 function set(key, value) { 4132 key._reactInternalFiber = value; 4133 } 4134 4135 // Don't change these two values. They're used by React Dev Tools. 4136 var NoEffect = /* */0; 4137 var PerformedWork = /* */1; 4138 4139 // You can change the rest (and add more). 4140 var Placement = /* */2; 4141 var Update = /* */4; 4142 var PlacementAndUpdate = /* */6; 4143 var Deletion = /* */8; 4144 var ContentReset = /* */16; 4145 var Callback = /* */32; 4146 var DidCapture = /* */64; 4147 var Ref = /* */128; 4148 var Snapshot = /* */256; 4149 var Passive = /* */512; 4150 4151 // Passive & Update & Callback & Ref & Snapshot 4152 var LifecycleEffectMask = /* */932; 4153 4154 // Union of all host effects 4155 var HostEffectMask = /* */1023; 4156 4157 var Incomplete = /* */1024; 4158 var ShouldCapture = /* */2048; 4159 4160 var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; 4161 4162 var MOUNTING = 1; 4163 var MOUNTED = 2; 4164 var UNMOUNTED = 3; 4165 4166 function isFiberMountedImpl(fiber) { 4167 var node = fiber; 4168 if (!fiber.alternate) { 4169 // If there is no alternate, this might be a new tree that isn't inserted 4170 // yet. If it is, then it will have a pending insertion effect on it. 4171 if ((node.effectTag & Placement) !== NoEffect) { 4172 return MOUNTING; 4173 } 4174 while (node.return) { 4175 node = node.return; 4176 if ((node.effectTag & Placement) !== NoEffect) { 4177 return MOUNTING; 4178 } 4179 } 4180 } else { 4181 while (node.return) { 4182 node = node.return; 4183 } 4184 } 4185 if (node.tag === HostRoot) { 4186 // TODO: Check if this was a nested HostRoot when used with 4187 // renderContainerIntoSubtree. 4188 return MOUNTED; 4189 } 4190 // If we didn't hit the root, that means that we're in an disconnected tree 4191 // that has been unmounted. 4192 return UNMOUNTED; 4193 } 4194 4195 function isFiberMounted(fiber) { 4196 return isFiberMountedImpl(fiber) === MOUNTED; 4197 } 4198 4199 function isMounted(component) { 4200 { 4201 var owner = ReactCurrentOwner$1.current; 4202 if (owner !== null && owner.tag === ClassComponent) { 4203 var ownerFiber = owner; 4204 var instance = ownerFiber.stateNode; 4205 !instance._warnedAboutRefsInRender ? warningWithoutStack$1(false, '%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(ownerFiber.type) || 'A component') : void 0; 4206 instance._warnedAboutRefsInRender = true; 4207 } 4208 } 4209 4210 var fiber = get(component); 4211 if (!fiber) { 4212 return false; 4213 } 4214 return isFiberMountedImpl(fiber) === MOUNTED; 4215 } 4216 4217 function assertIsMounted(fiber) { 4218 !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0; 4219 } 4220 4221 function findCurrentFiberUsingSlowPath(fiber) { 4222 var alternate = fiber.alternate; 4223 if (!alternate) { 4224 // If there is no alternate, then we only need to check if it is mounted. 4225 var state = isFiberMountedImpl(fiber); 4226 !(state !== UNMOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0; 4227 if (state === MOUNTING) { 4228 return null; 4229 } 4230 return fiber; 4231 } 4232 // If we have two possible branches, we'll walk backwards up to the root 4233 // to see what path the root points to. On the way we may hit one of the 4234 // special cases and we'll deal with them. 4235 var a = fiber; 4236 var b = alternate; 4237 while (true) { 4238 var parentA = a.return; 4239 var parentB = parentA ? parentA.alternate : null; 4240 if (!parentA || !parentB) { 4241 // We're at the root. 4242 break; 4243 } 4244 4245 // If both copies of the parent fiber point to the same child, we can 4246 // assume that the child is current. This happens when we bailout on low 4247 // priority: the bailed out fiber's child reuses the current child. 4248 if (parentA.child === parentB.child) { 4249 var child = parentA.child; 4250 while (child) { 4251 if (child === a) { 4252 // We've determined that A is the current branch. 4253 assertIsMounted(parentA); 4254 return fiber; 4255 } 4256 if (child === b) { 4257 // We've determined that B is the current branch. 4258 assertIsMounted(parentA); 4259 return alternate; 4260 } 4261 child = child.sibling; 4262 } 4263 // We should never have an alternate for any mounting node. So the only 4264 // way this could possibly happen is if this was unmounted, if at all. 4265 invariant(false, 'Unable to find node on an unmounted component.'); 4266 } 4267 4268 if (a.return !== b.return) { 4269 // The return pointer of A and the return pointer of B point to different 4270 // fibers. We assume that return pointers never criss-cross, so A must 4271 // belong to the child set of A.return, and B must belong to the child 4272 // set of B.return. 4273 a = parentA; 4274 b = parentB; 4275 } else { 4276 // The return pointers point to the same fiber. We'll have to use the 4277 // default, slow path: scan the child sets of each parent alternate to see 4278 // which child belongs to which set. 4279 // 4280 // Search parent A's child set 4281 var didFindChild = false; 4282 var _child = parentA.child; 4283 while (_child) { 4284 if (_child === a) { 4285 didFindChild = true; 4286 a = parentA; 4287 b = parentB; 4288 break; 4289 } 4290 if (_child === b) { 4291 didFindChild = true; 4292 b = parentA; 4293 a = parentB; 4294 break; 4295 } 4296 _child = _child.sibling; 4297 } 4298 if (!didFindChild) { 4299 // Search parent B's child set 4300 _child = parentB.child; 4301 while (_child) { 4302 if (_child === a) { 4303 didFindChild = true; 4304 a = parentB; 4305 b = parentA; 4306 break; 4307 } 4308 if (_child === b) { 4309 didFindChild = true; 4310 b = parentB; 4311 a = parentA; 4312 break; 4313 } 4314 _child = _child.sibling; 4315 } 4316 !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; 4317 } 4318 } 4319 4320 !(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; 4321 } 4322 // If the root is not a host container, we're in a disconnected tree. I.e. 4323 // unmounted. 4324 !(a.tag === HostRoot) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0; 4325 if (a.stateNode.current === a) { 4326 // We've determined that A is the current branch. 4327 return fiber; 4328 } 4329 // Otherwise B has to be current branch. 4330 return alternate; 4331 } 4332 4333 function findCurrentHostFiber(parent) { 4334 var currentParent = findCurrentFiberUsingSlowPath(parent); 4335 if (!currentParent) { 4336 return null; 4337 } 4338 4339 // Next we'll drill down this component to find the first HostComponent/Text. 4340 var node = currentParent; 4341 while (true) { 4342 if (node.tag === HostComponent || node.tag === HostText) { 4343 return node; 4344 } else if (node.child) { 4345 node.child.return = node; 4346 node = node.child; 4347 continue; 4348 } 4349 if (node === currentParent) { 4350 return null; 4351 } 4352 while (!node.sibling) { 4353 if (!node.return || node.return === currentParent) { 4354 return null; 4355 } 4356 node = node.return; 4357 } 4358 node.sibling.return = node.return; 4359 node = node.sibling; 4360 } 4361 // Flow needs the return null here, but ESLint complains about it. 4362 // eslint-disable-next-line no-unreachable 4363 return null; 4364 } 4365 4366 function findCurrentHostFiberWithNoPortals(parent) { 4367 var currentParent = findCurrentFiberUsingSlowPath(parent); 4368 if (!currentParent) { 4369 return null; 4370 } 4371 4372 // Next we'll drill down this component to find the first HostComponent/Text. 4373 var node = currentParent; 4374 while (true) { 4375 if (node.tag === HostComponent || node.tag === HostText) { 4376 return node; 4377 } else if (node.child && node.tag !== HostPortal) { 4378 node.child.return = node; 4379 node = node.child; 4380 continue; 4381 } 4382 if (node === currentParent) { 4383 return null; 4384 } 4385 while (!node.sibling) { 4386 if (!node.return || node.return === currentParent) { 4387 return null; 4388 } 4389 node = node.return; 4390 } 4391 node.sibling.return = node.return; 4392 node = node.sibling; 4393 } 4394 // Flow needs the return null here, but ESLint complains about it. 4395 // eslint-disable-next-line no-unreachable 4396 return null; 4397 } 4398 4399 function addEventBubbleListener(element, eventType, listener) { 4400 element.addEventListener(eventType, listener, false); 4401 } 4402 4403 function addEventCaptureListener(element, eventType, listener) { 4404 element.addEventListener(eventType, listener, true); 4405 } 4406 4407 /** 4408 * @interface Event 4409 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface 4410 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent 4411 */ 4412 var SyntheticAnimationEvent = SyntheticEvent.extend({ 4413 animationName: null, 4414 elapsedTime: null, 4415 pseudoElement: null 4416 }); 4417 4418 /** 4419 * @interface Event 4420 * @see http://www.w3.org/TR/clipboard-apis/ 4421 */ 4422 var SyntheticClipboardEvent = SyntheticEvent.extend({ 4423 clipboardData: function (event) { 4424 return 'clipboardData' in event ? event.clipboardData : window.clipboardData; 4425 } 4426 }); 4427 4428 /** 4429 * @interface FocusEvent 4430 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 4431 */ 4432 var SyntheticFocusEvent = SyntheticUIEvent.extend({ 4433 relatedTarget: null 4434 }); 4435 4436 /** 4437 * `charCode` represents the actual "character code" and is safe to use with 4438 * `String.fromCharCode`. As such, only keys that correspond to printable 4439 * characters produce a valid `charCode`, the only exception to this is Enter. 4440 * The Tab-key is considered non-printable and does not have a `charCode`, 4441 * presumably because it does not produce a tab-character in browsers. 4442 * 4443 * @param {object} nativeEvent Native browser event. 4444 * @return {number} Normalized `charCode` property. 4445 */ 4446 function getEventCharCode(nativeEvent) { 4447 var charCode = void 0; 4448 var keyCode = nativeEvent.keyCode; 4449 4450 if ('charCode' in nativeEvent) { 4451 charCode = nativeEvent.charCode; 4452 4453 // FF does not set `charCode` for the Enter-key, check against `keyCode`. 4454 if (charCode === 0 && keyCode === 13) { 4455 charCode = 13; 4456 } 4457 } else { 4458 // IE8 does not implement `charCode`, but `keyCode` has the correct value. 4459 charCode = keyCode; 4460 } 4461 4462 // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux) 4463 // report Enter as charCode 10 when ctrl is pressed. 4464 if (charCode === 10) { 4465 charCode = 13; 4466 } 4467 4468 // Some non-printable keys are reported in `charCode`/`keyCode`, discard them. 4469 // Must not discard the (non-)printable Enter-key. 4470 if (charCode >= 32 || charCode === 13) { 4471 return charCode; 4472 } 4473 4474 return 0; 4475 } 4476 4477 /** 4478 * Normalization of deprecated HTML5 `key` values 4479 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names 4480 */ 4481 var normalizeKey = { 4482 Esc: 'Escape', 4483 Spacebar: ' ', 4484 Left: 'ArrowLeft', 4485 Up: 'ArrowUp', 4486 Right: 'ArrowRight', 4487 Down: 'ArrowDown', 4488 Del: 'Delete', 4489 Win: 'OS', 4490 Menu: 'ContextMenu', 4491 Apps: 'ContextMenu', 4492 Scroll: 'ScrollLock', 4493 MozPrintableKey: 'Unidentified' 4494 }; 4495 4496 /** 4497 * Translation from legacy `keyCode` to HTML5 `key` 4498 * Only special keys supported, all others depend on keyboard layout or browser 4499 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names 4500 */ 4501 var translateToKey = { 4502 '8': 'Backspace', 4503 '9': 'Tab', 4504 '12': 'Clear', 4505 '13': 'Enter', 4506 '16': 'Shift', 4507 '17': 'Control', 4508 '18': 'Alt', 4509 '19': 'Pause', 4510 '20': 'CapsLock', 4511 '27': 'Escape', 4512 '32': ' ', 4513 '33': 'PageUp', 4514 '34': 'PageDown', 4515 '35': 'End', 4516 '36': 'Home', 4517 '37': 'ArrowLeft', 4518 '38': 'ArrowUp', 4519 '39': 'ArrowRight', 4520 '40': 'ArrowDown', 4521 '45': 'Insert', 4522 '46': 'Delete', 4523 '112': 'F1', 4524 '113': 'F2', 4525 '114': 'F3', 4526 '115': 'F4', 4527 '116': 'F5', 4528 '117': 'F6', 4529 '118': 'F7', 4530 '119': 'F8', 4531 '120': 'F9', 4532 '121': 'F10', 4533 '122': 'F11', 4534 '123': 'F12', 4535 '144': 'NumLock', 4536 '145': 'ScrollLock', 4537 '224': 'Meta' 4538 }; 4539 4540 /** 4541 * @param {object} nativeEvent Native browser event. 4542 * @return {string} Normalized `key` property. 4543 */ 4544 function getEventKey(nativeEvent) { 4545 if (nativeEvent.key) { 4546 // Normalize inconsistent values reported by browsers due to 4547 // implementations of a working draft specification. 4548 4549 // FireFox implements `key` but returns `MozPrintableKey` for all 4550 // printable characters (normalized to `Unidentified`), ignore it. 4551 var key = normalizeKey[nativeEvent.key] || nativeEvent.key; 4552 if (key !== 'Unidentified') { 4553 return key; 4554 } 4555 } 4556 4557 // Browser does not implement `key`, polyfill as much of it as we can. 4558 if (nativeEvent.type === 'keypress') { 4559 var charCode = getEventCharCode(nativeEvent); 4560 4561 // The enter-key is technically both printable and non-printable and can 4562 // thus be captured by `keypress`, no other non-printable key should. 4563 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode); 4564 } 4565 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') { 4566 // While user keyboard layout determines the actual meaning of each 4567 // `keyCode` value, almost all function keys have a universal value. 4568 return translateToKey[nativeEvent.keyCode] || 'Unidentified'; 4569 } 4570 return ''; 4571 } 4572 4573 /** 4574 * @interface KeyboardEvent 4575 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 4576 */ 4577 var SyntheticKeyboardEvent = SyntheticUIEvent.extend({ 4578 key: getEventKey, 4579 location: null, 4580 ctrlKey: null, 4581 shiftKey: null, 4582 altKey: null, 4583 metaKey: null, 4584 repeat: null, 4585 locale: null, 4586 getModifierState: getEventModifierState, 4587 // Legacy Interface 4588 charCode: function (event) { 4589 // `charCode` is the result of a KeyPress event and represents the value of 4590 // the actual printable character. 4591 4592 // KeyPress is deprecated, but its replacement is not yet final and not 4593 // implemented in any major browser. Only KeyPress has charCode. 4594 if (event.type === 'keypress') { 4595 return getEventCharCode(event); 4596 } 4597 return 0; 4598 }, 4599 keyCode: function (event) { 4600 // `keyCode` is the result of a KeyDown/Up event and represents the value of 4601 // physical keyboard key. 4602 4603 // The actual meaning of the value depends on the users' keyboard layout 4604 // which cannot be detected. Assuming that it is a US keyboard layout 4605 // provides a surprisingly accurate mapping for US and European users. 4606 // Due to this, it is left to the user to implement at this time. 4607 if (event.type === 'keydown' || event.type === 'keyup') { 4608 return event.keyCode; 4609 } 4610 return 0; 4611 }, 4612 which: function (event) { 4613 // `which` is an alias for either `keyCode` or `charCode` depending on the 4614 // type of the event. 4615 if (event.type === 'keypress') { 4616 return getEventCharCode(event); 4617 } 4618 if (event.type === 'keydown' || event.type === 'keyup') { 4619 return event.keyCode; 4620 } 4621 return 0; 4622 } 4623 }); 4624 4625 /** 4626 * @interface DragEvent 4627 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 4628 */ 4629 var SyntheticDragEvent = SyntheticMouseEvent.extend({ 4630 dataTransfer: null 4631 }); 4632 4633 /** 4634 * @interface TouchEvent 4635 * @see http://www.w3.org/TR/touch-events/ 4636 */ 4637 var SyntheticTouchEvent = SyntheticUIEvent.extend({ 4638 touches: null, 4639 targetTouches: null, 4640 changedTouches: null, 4641 altKey: null, 4642 metaKey: null, 4643 ctrlKey: null, 4644 shiftKey: null, 4645 getModifierState: getEventModifierState 4646 }); 4647 4648 /** 4649 * @interface Event 4650 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events- 4651 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent 4652 */ 4653 var SyntheticTransitionEvent = SyntheticEvent.extend({ 4654 propertyName: null, 4655 elapsedTime: null, 4656 pseudoElement: null 4657 }); 4658 4659 /** 4660 * @interface WheelEvent 4661 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 4662 */ 4663 var SyntheticWheelEvent = SyntheticMouseEvent.extend({ 4664 deltaX: function (event) { 4665 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive). 4666 'wheelDeltaX' in event ? -event.wheelDeltaX : 0; 4667 }, 4668 deltaY: function (event) { 4669 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive). 4670 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive). 4671 'wheelDelta' in event ? -event.wheelDelta : 0; 4672 }, 4673 4674 deltaZ: null, 4675 4676 // Browsers without "deltaMode" is reporting in raw wheel delta where one 4677 // notch on the scroll is always +/- 120, roughly equivalent to pixels. 4678 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or 4679 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size. 4680 deltaMode: null 4681 }); 4682 4683 /** 4684 * Turns 4685 * ['abort', ...] 4686 * into 4687 * eventTypes = { 4688 * 'abort': { 4689 * phasedRegistrationNames: { 4690 * bubbled: 'onAbort', 4691 * captured: 'onAbortCapture', 4692 * }, 4693 * dependencies: [TOP_ABORT], 4694 * }, 4695 * ... 4696 * }; 4697 * topLevelEventsToDispatchConfig = new Map([ 4698 * [TOP_ABORT, { sameConfig }], 4699 * ]); 4700 */ 4701 4702 var interactiveEventTypeNames = [[TOP_BLUR, 'blur'], [TOP_CANCEL, 'cancel'], [TOP_CLICK, 'click'], [TOP_CLOSE, 'close'], [TOP_CONTEXT_MENU, 'contextMenu'], [TOP_COPY, 'copy'], [TOP_CUT, 'cut'], [TOP_AUX_CLICK, 'auxClick'], [TOP_DOUBLE_CLICK, 'doubleClick'], [TOP_DRAG_END, 'dragEnd'], [TOP_DRAG_START, 'dragStart'], [TOP_DROP, 'drop'], [TOP_FOCUS, 'focus'], [TOP_INPUT, 'input'], [TOP_INVALID, 'invalid'], [TOP_KEY_DOWN, 'keyDown'], [TOP_KEY_PRESS, 'keyPress'], [TOP_KEY_UP, 'keyUp'], [TOP_MOUSE_DOWN, 'mouseDown'], [TOP_MOUSE_UP, 'mouseUp'], [TOP_PASTE, 'paste'], [TOP_PAUSE, 'pause'], [TOP_PLAY, 'play'], [TOP_POINTER_CANCEL, 'pointerCancel'], [TOP_POINTER_DOWN, 'pointerDown'], [TOP_POINTER_UP, 'pointerUp'], [TOP_RATE_CHANGE, 'rateChange'], [TOP_RESET, 'reset'], [TOP_SEEKED, 'seeked'], [TOP_SUBMIT, 'submit'], [TOP_TOUCH_CANCEL, 'touchCancel'], [TOP_TOUCH_END, 'touchEnd'], [TOP_TOUCH_START, 'touchStart'], [TOP_VOLUME_CHANGE, 'volumeChange']]; 4703 var nonInteractiveEventTypeNames = [[TOP_ABORT, 'abort'], [TOP_ANIMATION_END, 'animationEnd'], [TOP_ANIMATION_ITERATION, 'animationIteration'], [TOP_ANIMATION_START, 'animationStart'], [TOP_CAN_PLAY, 'canPlay'], [TOP_CAN_PLAY_THROUGH, 'canPlayThrough'], [TOP_DRAG, 'drag'], [TOP_DRAG_ENTER, 'dragEnter'], [TOP_DRAG_EXIT, 'dragExit'], [TOP_DRAG_LEAVE, 'dragLeave'], [TOP_DRAG_OVER, 'dragOver'], [TOP_DURATION_CHANGE, 'durationChange'], [TOP_EMPTIED, 'emptied'], [TOP_ENCRYPTED, 'encrypted'], [TOP_ENDED, 'ended'], [TOP_ERROR, 'error'], [TOP_GOT_POINTER_CAPTURE, 'gotPointerCapture'], [TOP_LOAD, 'load'], [TOP_LOADED_DATA, 'loadedData'], [TOP_LOADED_METADATA, 'loadedMetadata'], [TOP_LOAD_START, 'loadStart'], [TOP_LOST_POINTER_CAPTURE, 'lostPointerCapture'], [TOP_MOUSE_MOVE, 'mouseMove'], [TOP_MOUSE_OUT, 'mouseOut'], [TOP_MOUSE_OVER, 'mouseOver'], [TOP_PLAYING, 'playing'], [TOP_POINTER_MOVE, 'pointerMove'], [TOP_POINTER_OUT, 'pointerOut'], [TOP_POINTER_OVER, 'pointerOver'], [TOP_PROGRESS, 'progress'], [TOP_SCROLL, 'scroll'], [TOP_SEEKING, 'seeking'], [TOP_STALLED, 'stalled'], [TOP_SUSPEND, 'suspend'], [TOP_TIME_UPDATE, 'timeUpdate'], [TOP_TOGGLE, 'toggle'], [TOP_TOUCH_MOVE, 'touchMove'], [TOP_TRANSITION_END, 'transitionEnd'], [TOP_WAITING, 'waiting'], [TOP_WHEEL, 'wheel']]; 4704 4705 var eventTypes$4 = {}; 4706 var topLevelEventsToDispatchConfig = {}; 4707 4708 function addEventTypeNameToConfig(_ref, isInteractive) { 4709 var topEvent = _ref[0], 4710 event = _ref[1]; 4711 4712 var capitalizedEvent = event[0].toUpperCase() + event.slice(1); 4713 var onEvent = 'on' + capitalizedEvent; 4714 4715 var type = { 4716 phasedRegistrationNames: { 4717 bubbled: onEvent, 4718 captured: onEvent + 'Capture' 4719 }, 4720 dependencies: [topEvent], 4721 isInteractive: isInteractive 4722 }; 4723 eventTypes$4[event] = type; 4724 topLevelEventsToDispatchConfig[topEvent] = type; 4725 } 4726 4727 interactiveEventTypeNames.forEach(function (eventTuple) { 4728 addEventTypeNameToConfig(eventTuple, true); 4729 }); 4730 nonInteractiveEventTypeNames.forEach(function (eventTuple) { 4731 addEventTypeNameToConfig(eventTuple, false); 4732 }); 4733 4734 // Only used in DEV for exhaustiveness validation. 4735 var knownHTMLTopLevelTypes = [TOP_ABORT, TOP_CANCEL, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, TOP_CLOSE, TOP_DURATION_CHANGE, TOP_EMPTIED, TOP_ENCRYPTED, TOP_ENDED, TOP_ERROR, TOP_INPUT, TOP_INVALID, TOP_LOAD, TOP_LOADED_DATA, TOP_LOADED_METADATA, TOP_LOAD_START, TOP_PAUSE, TOP_PLAY, TOP_PLAYING, TOP_PROGRESS, TOP_RATE_CHANGE, TOP_RESET, TOP_SEEKED, TOP_SEEKING, TOP_STALLED, TOP_SUBMIT, TOP_SUSPEND, TOP_TIME_UPDATE, TOP_TOGGLE, TOP_VOLUME_CHANGE, TOP_WAITING]; 4736 4737 var SimpleEventPlugin = { 4738 eventTypes: eventTypes$4, 4739 4740 isInteractiveTopLevelEventType: function (topLevelType) { 4741 var config = topLevelEventsToDispatchConfig[topLevelType]; 4742 return config !== undefined && config.isInteractive === true; 4743 }, 4744 4745 4746 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { 4747 var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType]; 4748 if (!dispatchConfig) { 4749 return null; 4750 } 4751 var EventConstructor = void 0; 4752 switch (topLevelType) { 4753 case TOP_KEY_PRESS: 4754 // Firefox creates a keypress event for function keys too. This removes 4755 // the unwanted keypress events. Enter is however both printable and 4756 // non-printable. One would expect Tab to be as well (but it isn't). 4757 if (getEventCharCode(nativeEvent) === 0) { 4758 return null; 4759 } 4760 /* falls through */ 4761 case TOP_KEY_DOWN: 4762 case TOP_KEY_UP: 4763 EventConstructor = SyntheticKeyboardEvent; 4764 break; 4765 case TOP_BLUR: 4766 case TOP_FOCUS: 4767 EventConstructor = SyntheticFocusEvent; 4768 break; 4769 case TOP_CLICK: 4770 // Firefox creates a click event on right mouse clicks. This removes the 4771 // unwanted click events. 4772 if (nativeEvent.button === 2) { 4773 return null; 4774 } 4775 /* falls through */ 4776 case TOP_AUX_CLICK: 4777 case TOP_DOUBLE_CLICK: 4778 case TOP_MOUSE_DOWN: 4779 case TOP_MOUSE_MOVE: 4780 case TOP_MOUSE_UP: 4781 // TODO: Disabled elements should not respond to mouse events 4782 /* falls through */ 4783 case TOP_MOUSE_OUT: 4784 case TOP_MOUSE_OVER: 4785 case TOP_CONTEXT_MENU: 4786 EventConstructor = SyntheticMouseEvent; 4787 break; 4788 case TOP_DRAG: 4789 case TOP_DRAG_END: 4790 case TOP_DRAG_ENTER: 4791 case TOP_DRAG_EXIT: 4792 case TOP_DRAG_LEAVE: 4793 case TOP_DRAG_OVER: 4794 case TOP_DRAG_START: 4795 case TOP_DROP: 4796 EventConstructor = SyntheticDragEvent; 4797 break; 4798 case TOP_TOUCH_CANCEL: 4799 case TOP_TOUCH_END: 4800 case TOP_TOUCH_MOVE: 4801 case TOP_TOUCH_START: 4802 EventConstructor = SyntheticTouchEvent; 4803 break; 4804 case TOP_ANIMATION_END: 4805 case TOP_ANIMATION_ITERATION: 4806 case TOP_ANIMATION_START: 4807 EventConstructor = SyntheticAnimationEvent; 4808 break; 4809 case TOP_TRANSITION_END: 4810 EventConstructor = SyntheticTransitionEvent; 4811 break; 4812 case TOP_SCROLL: 4813 EventConstructor = SyntheticUIEvent; 4814 break; 4815 case TOP_WHEEL: 4816 EventConstructor = SyntheticWheelEvent; 4817 break; 4818 case TOP_COPY: 4819 case TOP_CUT: 4820 case TOP_PASTE: 4821 EventConstructor = SyntheticClipboardEvent; 4822 break; 4823 case TOP_GOT_POINTER_CAPTURE: 4824 case TOP_LOST_POINTER_CAPTURE: 4825 case TOP_POINTER_CANCEL: 4826 case TOP_POINTER_DOWN: 4827 case TOP_POINTER_MOVE: 4828 case TOP_POINTER_OUT: 4829 case TOP_POINTER_OVER: 4830 case TOP_POINTER_UP: 4831 EventConstructor = SyntheticPointerEvent; 4832 break; 4833 default: 4834 { 4835 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) { 4836 warningWithoutStack$1(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType); 4837 } 4838 } 4839 // HTML Events 4840 // @see http://www.w3.org/TR/html5/index.html#events-0 4841 EventConstructor = SyntheticEvent; 4842 break; 4843 } 4844 var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget); 4845 accumulateTwoPhaseDispatches(event); 4846 return event; 4847 } 4848 }; 4849 4850 var isInteractiveTopLevelEventType = SimpleEventPlugin.isInteractiveTopLevelEventType; 4851 4852 4853 var CALLBACK_BOOKKEEPING_POOL_SIZE = 10; 4854 var callbackBookkeepingPool = []; 4855 4856 /** 4857 * Find the deepest React component completely containing the root of the 4858 * passed-in instance (for use when entire React trees are nested within each 4859 * other). If React trees are not nested, returns null. 4860 */ 4861 function findRootContainerNode(inst) { 4862 // TODO: It may be a good idea to cache this to prevent unnecessary DOM 4863 // traversal, but caching is difficult to do correctly without using a 4864 // mutation observer to listen for all DOM changes. 4865 while (inst.return) { 4866 inst = inst.return; 4867 } 4868 if (inst.tag !== HostRoot) { 4869 // This can happen if we're in a detached tree. 4870 return null; 4871 } 4872 return inst.stateNode.containerInfo; 4873 } 4874 4875 // Used to store ancestor hierarchy in top level callback 4876 function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst) { 4877 if (callbackBookkeepingPool.length) { 4878 var instance = callbackBookkeepingPool.pop(); 4879 instance.topLevelType = topLevelType; 4880 instance.nativeEvent = nativeEvent; 4881 instance.targetInst = targetInst; 4882 return instance; 4883 } 4884 return { 4885 topLevelType: topLevelType, 4886 nativeEvent: nativeEvent, 4887 targetInst: targetInst, 4888 ancestors: [] 4889 }; 4890 } 4891 4892 function releaseTopLevelCallbackBookKeeping(instance) { 4893 instance.topLevelType = null; 4894 instance.nativeEvent = null; 4895 instance.targetInst = null; 4896 instance.ancestors.length = 0; 4897 if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) { 4898 callbackBookkeepingPool.push(instance); 4899 } 4900 } 4901 4902 function handleTopLevel(bookKeeping) { 4903 var targetInst = bookKeeping.targetInst; 4904 4905 // Loop through the hierarchy, in case there's any nested components. 4906 // It's important that we build the array of ancestors before calling any 4907 // event handlers, because event handlers can modify the DOM, leading to 4908 // inconsistencies with ReactMount's node cache. See #1105. 4909 var ancestor = targetInst; 4910 do { 4911 if (!ancestor) { 4912 bookKeeping.ancestors.push(ancestor); 4913 break; 4914 } 4915 var root = findRootContainerNode(ancestor); 4916 if (!root) { 4917 break; 4918 } 4919 bookKeeping.ancestors.push(ancestor); 4920 ancestor = getClosestInstanceFromNode(root); 4921 } while (ancestor); 4922 4923 for (var i = 0; i < bookKeeping.ancestors.length; i++) { 4924 targetInst = bookKeeping.ancestors[i]; 4925 runExtractedEventsInBatch(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent)); 4926 } 4927 } 4928 4929 // TODO: can we stop exporting these? 4930 var _enabled = true; 4931 4932 function setEnabled(enabled) { 4933 _enabled = !!enabled; 4934 } 4935 4936 function isEnabled() { 4937 return _enabled; 4938 } 4939 4940 /** 4941 * Traps top-level events by using event bubbling. 4942 * 4943 * @param {number} topLevelType Number from `TopLevelEventTypes`. 4944 * @param {object} element Element on which to attach listener. 4945 * @return {?object} An object with a remove function which will forcefully 4946 * remove the listener. 4947 * @internal 4948 */ 4949 function trapBubbledEvent(topLevelType, element) { 4950 if (!element) { 4951 return null; 4952 } 4953 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent; 4954 4955 addEventBubbleListener(element, getRawEventName(topLevelType), 4956 // Check if interactive and wrap in interactiveUpdates 4957 dispatch.bind(null, topLevelType)); 4958 } 4959 4960 /** 4961 * Traps a top-level event by using event capturing. 4962 * 4963 * @param {number} topLevelType Number from `TopLevelEventTypes`. 4964 * @param {object} element Element on which to attach listener. 4965 * @return {?object} An object with a remove function which will forcefully 4966 * remove the listener. 4967 * @internal 4968 */ 4969 function trapCapturedEvent(topLevelType, element) { 4970 if (!element) { 4971 return null; 4972 } 4973 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent; 4974 4975 addEventCaptureListener(element, getRawEventName(topLevelType), 4976 // Check if interactive and wrap in interactiveUpdates 4977 dispatch.bind(null, topLevelType)); 4978 } 4979 4980 function dispatchInteractiveEvent(topLevelType, nativeEvent) { 4981 interactiveUpdates(dispatchEvent, topLevelType, nativeEvent); 4982 } 4983 4984 function dispatchEvent(topLevelType, nativeEvent) { 4985 if (!_enabled) { 4986 return; 4987 } 4988 4989 var nativeEventTarget = getEventTarget(nativeEvent); 4990 var targetInst = getClosestInstanceFromNode(nativeEventTarget); 4991 if (targetInst !== null && typeof targetInst.tag === 'number' && !isFiberMounted(targetInst)) { 4992 // If we get an event (ex: img onload) before committing that 4993 // component's mount, ignore it for now (that is, treat it as if it was an 4994 // event on a non-React tree). We might also consider queueing events and 4995 // dispatching them after the mount. 4996 targetInst = null; 4997 } 4998 4999 var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst); 5000 5001 try { 5002 // Event queue being processed in the same cycle allows 5003 // `preventDefault`. 5004 batchedUpdates(handleTopLevel, bookKeeping); 5005 } finally { 5006 releaseTopLevelCallbackBookKeeping(bookKeeping); 5007 } 5008 } 5009 5010 /** 5011 * Summary of `ReactBrowserEventEmitter` event handling: 5012 * 5013 * - Top-level delegation is used to trap most native browser events. This 5014 * may only occur in the main thread and is the responsibility of 5015 * ReactDOMEventListener, which is injected and can therefore support 5016 * pluggable event sources. This is the only work that occurs in the main 5017 * thread. 5018 * 5019 * - We normalize and de-duplicate events to account for browser quirks. This 5020 * may be done in the worker thread. 5021 * 5022 * - Forward these native events (with the associated top-level type used to 5023 * trap it) to `EventPluginHub`, which in turn will ask plugins if they want 5024 * to extract any synthetic events. 5025 * 5026 * - The `EventPluginHub` will then process each event by annotating them with 5027 * "dispatches", a sequence of listeners and IDs that care about that event. 5028 * 5029 * - The `EventPluginHub` then dispatches the events. 5030 * 5031 * Overview of React and the event system: 5032 * 5033 * +------------+ . 5034 * | DOM | . 5035 * +------------+ . 5036 * | . 5037 * v . 5038 * +------------+ . 5039 * | ReactEvent | . 5040 * | Listener | . 5041 * +------------+ . +-----------+ 5042 * | . +--------+|SimpleEvent| 5043 * | . | |Plugin | 5044 * +-----|------+ . v +-----------+ 5045 * | | | . +--------------+ +------------+ 5046 * | +-----------.--->|EventPluginHub| | Event | 5047 * | | . | | +-----------+ | Propagators| 5048 * | ReactEvent | . | | |TapEvent | |------------| 5049 * | Emitter | . | |<---+|Plugin | |other plugin| 5050 * | | . | | +-----------+ | utilities | 5051 * | +-----------.--->| | +------------+ 5052 * | | | . +--------------+ 5053 * +-----|------+ . ^ +-----------+ 5054 * | . | |Enter/Leave| 5055 * + . +-------+|Plugin | 5056 * +-------------+ . +-----------+ 5057 * | application | . 5058 * |-------------| . 5059 * | | . 5060 * | | . 5061 * +-------------+ . 5062 * . 5063 * React Core . General Purpose Event Plugin System 5064 */ 5065 5066 var alreadyListeningTo = {}; 5067 var reactTopListenersCounter = 0; 5068 5069 /** 5070 * To ensure no conflicts with other potential React instances on the page 5071 */ 5072 var topListenersIDKey = '_reactListenersID' + ('' + Math.random()).slice(2); 5073 5074 function getListeningForDocument(mountAt) { 5075 // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty` 5076 // directly. 5077 if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) { 5078 mountAt[topListenersIDKey] = reactTopListenersCounter++; 5079 alreadyListeningTo[mountAt[topListenersIDKey]] = {}; 5080 } 5081 return alreadyListeningTo[mountAt[topListenersIDKey]]; 5082 } 5083 5084 /** 5085 * We listen for bubbled touch events on the document object. 5086 * 5087 * Firefox v8.01 (and possibly others) exhibited strange behavior when 5088 * mounting `onmousemove` events at some node that was not the document 5089 * element. The symptoms were that if your mouse is not moving over something 5090 * contained within that mount point (for example on the background) the 5091 * top-level listeners for `onmousemove` won't be called. However, if you 5092 * register the `mousemove` on the document object, then it will of course 5093 * catch all `mousemove`s. This along with iOS quirks, justifies restricting 5094 * top-level listeners to the document object only, at least for these 5095 * movement types of events and possibly all events. 5096 * 5097 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html 5098 * 5099 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but 5100 * they bubble to document. 5101 * 5102 * @param {string} registrationName Name of listener (e.g. `onClick`). 5103 * @param {object} mountAt Container where to mount the listener 5104 */ 5105 function listenTo(registrationName, mountAt) { 5106 var isListening = getListeningForDocument(mountAt); 5107 var dependencies = registrationNameDependencies[registrationName]; 5108 5109 for (var i = 0; i < dependencies.length; i++) { 5110 var dependency = dependencies[i]; 5111 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) { 5112 switch (dependency) { 5113 case TOP_SCROLL: 5114 trapCapturedEvent(TOP_SCROLL, mountAt); 5115 break; 5116 case TOP_FOCUS: 5117 case TOP_BLUR: 5118 trapCapturedEvent(TOP_FOCUS, mountAt); 5119 trapCapturedEvent(TOP_BLUR, mountAt); 5120 // We set the flag for a single dependency later in this function, 5121 // but this ensures we mark both as attached rather than just one. 5122 isListening[TOP_BLUR] = true; 5123 isListening[TOP_FOCUS] = true; 5124 break; 5125 case TOP_CANCEL: 5126 case TOP_CLOSE: 5127 if (isEventSupported(getRawEventName(dependency))) { 5128 trapCapturedEvent(dependency, mountAt); 5129 } 5130 break; 5131 case TOP_INVALID: 5132 case TOP_SUBMIT: 5133 case TOP_RESET: 5134 // We listen to them on the target DOM elements. 5135 // Some of them bubble so we don't want them to fire twice. 5136 break; 5137 default: 5138 // By default, listen on the top level to all non-media events. 5139 // Media events don't bubble so adding the listener wouldn't do anything. 5140 var isMediaEvent = mediaEventTypes.indexOf(dependency) !== -1; 5141 if (!isMediaEvent) { 5142 trapBubbledEvent(dependency, mountAt); 5143 } 5144 break; 5145 } 5146 isListening[dependency] = true; 5147 } 5148 } 5149 } 5150 5151 function isListeningToAllDependencies(registrationName, mountAt) { 5152 var isListening = getListeningForDocument(mountAt); 5153 var dependencies = registrationNameDependencies[registrationName]; 5154 for (var i = 0; i < dependencies.length; i++) { 5155 var dependency = dependencies[i]; 5156 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) { 5157 return false; 5158 } 5159 } 5160 return true; 5161 } 5162 5163 function getActiveElement(doc) { 5164 doc = doc || (typeof document !== 'undefined' ? document : undefined); 5165 if (typeof doc === 'undefined') { 5166 return null; 5167 } 5168 try { 5169 return doc.activeElement || doc.body; 5170 } catch (e) { 5171 return doc.body; 5172 } 5173 } 5174 5175 /** 5176 * Given any node return the first leaf node without children. 5177 * 5178 * @param {DOMElement|DOMTextNode} node 5179 * @return {DOMElement|DOMTextNode} 5180 */ 5181 function getLeafNode(node) { 5182 while (node && node.firstChild) { 5183 node = node.firstChild; 5184 } 5185 return node; 5186 } 5187 5188 /** 5189 * Get the next sibling within a container. This will walk up the 5190 * DOM if a node's siblings have been exhausted. 5191 * 5192 * @param {DOMElement|DOMTextNode} node 5193 * @return {?DOMElement|DOMTextNode} 5194 */ 5195 function getSiblingNode(node) { 5196 while (node) { 5197 if (node.nextSibling) { 5198 return node.nextSibling; 5199 } 5200 node = node.parentNode; 5201 } 5202 } 5203 5204 /** 5205 * Get object describing the nodes which contain characters at offset. 5206 * 5207 * @param {DOMElement|DOMTextNode} root 5208 * @param {number} offset 5209 * @return {?object} 5210 */ 5211 function getNodeForCharacterOffset(root, offset) { 5212 var node = getLeafNode(root); 5213 var nodeStart = 0; 5214 var nodeEnd = 0; 5215 5216 while (node) { 5217 if (node.nodeType === TEXT_NODE) { 5218 nodeEnd = nodeStart + node.textContent.length; 5219 5220 if (nodeStart <= offset && nodeEnd >= offset) { 5221 return { 5222 node: node, 5223 offset: offset - nodeStart 5224 }; 5225 } 5226 5227 nodeStart = nodeEnd; 5228 } 5229 5230 node = getLeafNode(getSiblingNode(node)); 5231 } 5232 } 5233 5234 /** 5235 * @param {DOMElement} outerNode 5236 * @return {?object} 5237 */ 5238 function getOffsets(outerNode) { 5239 var ownerDocument = outerNode.ownerDocument; 5240 5241 var win = ownerDocument && ownerDocument.defaultView || window; 5242 var selection = win.getSelection && win.getSelection(); 5243 5244 if (!selection || selection.rangeCount === 0) { 5245 return null; 5246 } 5247 5248 var anchorNode = selection.anchorNode, 5249 anchorOffset = selection.anchorOffset, 5250 focusNode = selection.focusNode, 5251 focusOffset = selection.focusOffset; 5252 5253 // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the 5254 // up/down buttons on an <input type="number">. Anonymous divs do not seem to 5255 // expose properties, triggering a "Permission denied error" if any of its 5256 // properties are accessed. The only seemingly possible way to avoid erroring 5257 // is to access a property that typically works for non-anonymous divs and 5258 // catch any error that may otherwise arise. See 5259 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427 5260 5261 try { 5262 /* eslint-disable no-unused-expressions */ 5263 anchorNode.nodeType; 5264 focusNode.nodeType; 5265 /* eslint-enable no-unused-expressions */ 5266 } catch (e) { 5267 return null; 5268 } 5269 5270 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset); 5271 } 5272 5273 /** 5274 * Returns {start, end} where `start` is the character/codepoint index of 5275 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and 5276 * `end` is the index of (focusNode, focusOffset). 5277 * 5278 * Returns null if you pass in garbage input but we should probably just crash. 5279 * 5280 * Exported only for testing. 5281 */ 5282 function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) { 5283 var length = 0; 5284 var start = -1; 5285 var end = -1; 5286 var indexWithinAnchor = 0; 5287 var indexWithinFocus = 0; 5288 var node = outerNode; 5289 var parentNode = null; 5290 5291 outer: while (true) { 5292 var next = null; 5293 5294 while (true) { 5295 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) { 5296 start = length + anchorOffset; 5297 } 5298 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) { 5299 end = length + focusOffset; 5300 } 5301 5302 if (node.nodeType === TEXT_NODE) { 5303 length += node.nodeValue.length; 5304 } 5305 5306 if ((next = node.firstChild) === null) { 5307 break; 5308 } 5309 // Moving from `node` to its first child `next`. 5310 parentNode = node; 5311 node = next; 5312 } 5313 5314 while (true) { 5315 if (node === outerNode) { 5316 // If `outerNode` has children, this is always the second time visiting 5317 // it. If it has no children, this is still the first loop, and the only 5318 // valid selection is anchorNode and focusNode both equal to this node 5319 // and both offsets 0, in which case we will have handled above. 5320 break outer; 5321 } 5322 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) { 5323 start = length; 5324 } 5325 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) { 5326 end = length; 5327 } 5328 if ((next = node.nextSibling) !== null) { 5329 break; 5330 } 5331 node = parentNode; 5332 parentNode = node.parentNode; 5333 } 5334 5335 // Moving from `node` to its next sibling `next`. 5336 node = next; 5337 } 5338 5339 if (start === -1 || end === -1) { 5340 // This should never happen. (Would happen if the anchor/focus nodes aren't 5341 // actually inside the passed-in node.) 5342 return null; 5343 } 5344 5345 return { 5346 start: start, 5347 end: end 5348 }; 5349 } 5350 5351 /** 5352 * In modern non-IE browsers, we can support both forward and backward 5353 * selections. 5354 * 5355 * Note: IE10+ supports the Selection object, but it does not support 5356 * the `extend` method, which means that even in modern IE, it's not possible 5357 * to programmatically create a backward selection. Thus, for all IE 5358 * versions, we use the old IE API to create our selections. 5359 * 5360 * @param {DOMElement|DOMTextNode} node 5361 * @param {object} offsets 5362 */ 5363 function setOffsets(node, offsets) { 5364 var doc = node.ownerDocument || document; 5365 var win = doc && doc.defaultView || window; 5366 5367 // Edge fails with "Object expected" in some scenarios. 5368 // (For instance: TinyMCE editor used in a list component that supports pasting to add more, 5369 // fails when pasting 100+ items) 5370 if (!win.getSelection) { 5371 return; 5372 } 5373 5374 var selection = win.getSelection(); 5375 var length = node.textContent.length; 5376 var start = Math.min(offsets.start, length); 5377 var end = offsets.end === undefined ? start : Math.min(offsets.end, length); 5378 5379 // IE 11 uses modern selection, but doesn't support the extend method. 5380 // Flip backward selections, so we can set with a single range. 5381 if (!selection.extend && start > end) { 5382 var temp = end; 5383 end = start; 5384 start = temp; 5385 } 5386 5387 var startMarker = getNodeForCharacterOffset(node, start); 5388 var endMarker = getNodeForCharacterOffset(node, end); 5389 5390 if (startMarker && endMarker) { 5391 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) { 5392 return; 5393 } 5394 var range = doc.createRange(); 5395 range.setStart(startMarker.node, startMarker.offset); 5396 selection.removeAllRanges(); 5397 5398 if (start > end) { 5399 selection.addRange(range); 5400 selection.extend(endMarker.node, endMarker.offset); 5401 } else { 5402 range.setEnd(endMarker.node, endMarker.offset); 5403 selection.addRange(range); 5404 } 5405 } 5406 } 5407 5408 function isTextNode(node) { 5409 return node && node.nodeType === TEXT_NODE; 5410 } 5411 5412 function containsNode(outerNode, innerNode) { 5413 if (!outerNode || !innerNode) { 5414 return false; 5415 } else if (outerNode === innerNode) { 5416 return true; 5417 } else if (isTextNode(outerNode)) { 5418 return false; 5419 } else if (isTextNode(innerNode)) { 5420 return containsNode(outerNode, innerNode.parentNode); 5421 } else if ('contains' in outerNode) { 5422 return outerNode.contains(innerNode); 5423 } else if (outerNode.compareDocumentPosition) { 5424 return !!(outerNode.compareDocumentPosition(innerNode) & 16); 5425 } else { 5426 return false; 5427 } 5428 } 5429 5430 function isInDocument(node) { 5431 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node); 5432 } 5433 5434 function isSameOriginFrame(iframe) { 5435 try { 5436 // Accessing the contentDocument of a HTMLIframeElement can cause the browser 5437 // to throw, e.g. if it has a cross-origin src attribute. 5438 // Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g: 5439 // iframe.contentDocument.defaultView; 5440 // A safety way is to access one of the cross origin properties: Window or Location 5441 // Which might result in "SecurityError" DOM Exception and it is compatible to Safari. 5442 // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl 5443 5444 return typeof iframe.contentWindow.location.href === 'string'; 5445 } catch (err) { 5446 return false; 5447 } 5448 } 5449 5450 function getActiveElementDeep() { 5451 var win = window; 5452 var element = getActiveElement(); 5453 while (element instanceof win.HTMLIFrameElement) { 5454 if (isSameOriginFrame(element)) { 5455 win = element.contentWindow; 5456 } else { 5457 return element; 5458 } 5459 element = getActiveElement(win.document); 5460 } 5461 return element; 5462 } 5463 5464 /** 5465 * @ReactInputSelection: React input selection module. Based on Selection.js, 5466 * but modified to be suitable for react and has a couple of bug fixes (doesn't 5467 * assume buttons have range selections allowed). 5468 * Input selection module for React. 5469 */ 5470 5471 /** 5472 * @hasSelectionCapabilities: we get the element types that support selection 5473 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart` 5474 * and `selectionEnd` rows. 5475 */ 5476 function hasSelectionCapabilities(elem) { 5477 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); 5478 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true'); 5479 } 5480 5481 function getSelectionInformation() { 5482 var focusedElem = getActiveElementDeep(); 5483 return { 5484 focusedElem: focusedElem, 5485 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection$1(focusedElem) : null 5486 }; 5487 } 5488 5489 /** 5490 * @restoreSelection: If any selection information was potentially lost, 5491 * restore it. This is useful when performing operations that could remove dom 5492 * nodes and place them back in, resulting in focus being lost. 5493 */ 5494 function restoreSelection(priorSelectionInformation) { 5495 var curFocusedElem = getActiveElementDeep(); 5496 var priorFocusedElem = priorSelectionInformation.focusedElem; 5497 var priorSelectionRange = priorSelectionInformation.selectionRange; 5498 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) { 5499 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) { 5500 setSelection(priorFocusedElem, priorSelectionRange); 5501 } 5502 5503 // Focusing a node can change the scroll position, which is undesirable 5504 var ancestors = []; 5505 var ancestor = priorFocusedElem; 5506 while (ancestor = ancestor.parentNode) { 5507 if (ancestor.nodeType === ELEMENT_NODE) { 5508 ancestors.push({ 5509 element: ancestor, 5510 left: ancestor.scrollLeft, 5511 top: ancestor.scrollTop 5512 }); 5513 } 5514 } 5515 5516 if (typeof priorFocusedElem.focus === 'function') { 5517 priorFocusedElem.focus(); 5518 } 5519 5520 for (var i = 0; i < ancestors.length; i++) { 5521 var info = ancestors[i]; 5522 info.element.scrollLeft = info.left; 5523 info.element.scrollTop = info.top; 5524 } 5525 } 5526 } 5527 5528 /** 5529 * @getSelection: Gets the selection bounds of a focused textarea, input or 5530 * contentEditable node. 5531 * -@input: Look up selection bounds of this input 5532 * -@return {start: selectionStart, end: selectionEnd} 5533 */ 5534 function getSelection$1(input) { 5535 var selection = void 0; 5536 5537 if ('selectionStart' in input) { 5538 // Modern browser with input or textarea. 5539 selection = { 5540 start: input.selectionStart, 5541 end: input.selectionEnd 5542 }; 5543 } else { 5544 // Content editable or old IE textarea. 5545 selection = getOffsets(input); 5546 } 5547 5548 return selection || { start: 0, end: 0 }; 5549 } 5550 5551 /** 5552 * @setSelection: Sets the selection bounds of a textarea or input and focuses 5553 * the input. 5554 * -@input Set selection bounds of this input or textarea 5555 * -@offsets Object of same form that is returned from get* 5556 */ 5557 function setSelection(input, offsets) { 5558 var start = offsets.start, 5559 end = offsets.end; 5560 5561 if (end === undefined) { 5562 end = start; 5563 } 5564 5565 if ('selectionStart' in input) { 5566 input.selectionStart = start; 5567 input.selectionEnd = Math.min(end, input.value.length); 5568 } else { 5569 setOffsets(input, offsets); 5570 } 5571 } 5572 5573 var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11; 5574 5575 var eventTypes$3 = { 5576 select: { 5577 phasedRegistrationNames: { 5578 bubbled: 'onSelect', 5579 captured: 'onSelectCapture' 5580 }, 5581 dependencies: [TOP_BLUR, TOP_CONTEXT_MENU, TOP_DRAG_END, TOP_FOCUS, TOP_KEY_DOWN, TOP_KEY_UP, TOP_MOUSE_DOWN, TOP_MOUSE_UP, TOP_SELECTION_CHANGE] 5582 } 5583 }; 5584 5585 var activeElement$1 = null; 5586 var activeElementInst$1 = null; 5587 var lastSelection = null; 5588 var mouseDown = false; 5589 5590 /** 5591 * Get an object which is a unique representation of the current selection. 5592 * 5593 * The return value will not be consistent across nodes or browsers, but 5594 * two identical selections on the same node will return identical objects. 5595 * 5596 * @param {DOMElement} node 5597 * @return {object} 5598 */ 5599 function getSelection(node) { 5600 if ('selectionStart' in node && hasSelectionCapabilities(node)) { 5601 return { 5602 start: node.selectionStart, 5603 end: node.selectionEnd 5604 }; 5605 } else { 5606 var win = node.ownerDocument && node.ownerDocument.defaultView || window; 5607 var selection = win.getSelection(); 5608 return { 5609 anchorNode: selection.anchorNode, 5610 anchorOffset: selection.anchorOffset, 5611 focusNode: selection.focusNode, 5612 focusOffset: selection.focusOffset 5613 }; 5614 } 5615 } 5616 5617 /** 5618 * Get document associated with the event target. 5619 * 5620 * @param {object} nativeEventTarget 5621 * @return {Document} 5622 */ 5623 function getEventTargetDocument(eventTarget) { 5624 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument; 5625 } 5626 5627 /** 5628 * Poll selection to see whether it's changed. 5629 * 5630 * @param {object} nativeEvent 5631 * @param {object} nativeEventTarget 5632 * @return {?SyntheticEvent} 5633 */ 5634 function constructSelectEvent(nativeEvent, nativeEventTarget) { 5635 // Ensure we have the right element, and that the user is not dragging a 5636 // selection (this matches native `select` event behavior). In HTML5, select 5637 // fires only on input and textarea thus if there's no focused element we 5638 // won't dispatch. 5639 var doc = getEventTargetDocument(nativeEventTarget); 5640 5641 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) { 5642 return null; 5643 } 5644 5645 // Only fire when selection has actually changed. 5646 var currentSelection = getSelection(activeElement$1); 5647 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) { 5648 lastSelection = currentSelection; 5649 5650 var syntheticEvent = SyntheticEvent.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget); 5651 5652 syntheticEvent.type = 'select'; 5653 syntheticEvent.target = activeElement$1; 5654 5655 accumulateTwoPhaseDispatches(syntheticEvent); 5656 5657 return syntheticEvent; 5658 } 5659 5660 return null; 5661 } 5662 5663 /** 5664 * This plugin creates an `onSelect` event that normalizes select events 5665 * across form elements. 5666 * 5667 * Supported elements are: 5668 * - input (see `isTextInputElement`) 5669 * - textarea 5670 * - contentEditable 5671 * 5672 * This differs from native browser implementations in the following ways: 5673 * - Fires on contentEditable fields as well as inputs. 5674 * - Fires for collapsed selection. 5675 * - Fires after user input. 5676 */ 5677 var SelectEventPlugin = { 5678 eventTypes: eventTypes$3, 5679 5680 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { 5681 var doc = getEventTargetDocument(nativeEventTarget); 5682 // Track whether all listeners exists for this plugin. If none exist, we do 5683 // not extract events. See #3639. 5684 if (!doc || !isListeningToAllDependencies('onSelect', doc)) { 5685 return null; 5686 } 5687 5688 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window; 5689 5690 switch (topLevelType) { 5691 // Track the input node that has focus. 5692 case TOP_FOCUS: 5693 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') { 5694 activeElement$1 = targetNode; 5695 activeElementInst$1 = targetInst; 5696 lastSelection = null; 5697 } 5698 break; 5699 case TOP_BLUR: 5700 activeElement$1 = null; 5701 activeElementInst$1 = null; 5702 lastSelection = null; 5703 break; 5704 // Don't fire the event while the user is dragging. This matches the 5705 // semantics of the native select event. 5706 case TOP_MOUSE_DOWN: 5707 mouseDown = true; 5708 break; 5709 case TOP_CONTEXT_MENU: 5710 case TOP_MOUSE_UP: 5711 case TOP_DRAG_END: 5712 mouseDown = false; 5713 return constructSelectEvent(nativeEvent, nativeEventTarget); 5714 // Chrome and IE fire non-standard event when selection is changed (and 5715 // sometimes when it hasn't). IE's event fires out of order with respect 5716 // to key and input events on deletion, so we discard it. 5717 // 5718 // Firefox doesn't support selectionchange, so check selection status 5719 // after each key entry. The selection changes after keydown and before 5720 // keyup, but we check on keydown as well in the case of holding down a 5721 // key, when multiple keydown events are fired but only one keyup is. 5722 // This is also our approach for IE handling, for the reason above. 5723 case TOP_SELECTION_CHANGE: 5724 if (skipSelectionChangeEvent) { 5725 break; 5726 } 5727 // falls through 5728 case TOP_KEY_DOWN: 5729 case TOP_KEY_UP: 5730 return constructSelectEvent(nativeEvent, nativeEventTarget); 5731 } 5732 5733 return null; 5734 } 5735 }; 5736 5737 /** 5738 * Inject modules for resolving DOM hierarchy and plugin ordering. 5739 */ 5740 injection.injectEventPluginOrder(DOMEventPluginOrder); 5741 setComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1); 5742 5743 /** 5744 * Some important event plugins included by default (without having to require 5745 * them). 5746 */ 5747 injection.injectEventPluginsByName({ 5748 SimpleEventPlugin: SimpleEventPlugin, 5749 EnterLeaveEventPlugin: EnterLeaveEventPlugin, 5750 ChangeEventPlugin: ChangeEventPlugin, 5751 SelectEventPlugin: SelectEventPlugin, 5752 BeforeInputEventPlugin: BeforeInputEventPlugin 5753 }); 5754 5755 var didWarnSelectedSetOnOption = false; 5756 var didWarnInvalidChild = false; 5757 5758 function flattenChildren(children) { 5759 var content = ''; 5760 5761 // Flatten children. We'll warn if they are invalid 5762 // during validateProps() which runs for hydration too. 5763 // Note that this would throw on non-element objects. 5764 // Elements are stringified (which is normally irrelevant 5765 // but matters for <fbt>). 5766 React.Children.forEach(children, function (child) { 5767 if (child == null) { 5768 return; 5769 } 5770 content += child; 5771 // Note: we don't warn about invalid children here. 5772 // Instead, this is done separately below so that 5773 // it happens during the hydration codepath too. 5774 }); 5775 5776 return content; 5777 } 5778 5779 /** 5780 * Implements an <option> host component that warns when `selected` is set. 5781 */ 5782 5783 function validateProps(element, props) { 5784 { 5785 // This mirrors the codepath above, but runs for hydration too. 5786 // Warn about invalid children here so that client and hydration are consistent. 5787 // TODO: this seems like it could cause a DEV-only throw for hydration 5788 // if children contains a non-element object. We should try to avoid that. 5789 if (typeof props.children === 'object' && props.children !== null) { 5790 React.Children.forEach(props.children, function (child) { 5791 if (child == null) { 5792 return; 5793 } 5794 if (typeof child === 'string' || typeof child === 'number') { 5795 return; 5796 } 5797 if (typeof child.type !== 'string') { 5798 return; 5799 } 5800 if (!didWarnInvalidChild) { 5801 didWarnInvalidChild = true; 5802 warning$1(false, 'Only strings and numbers are supported as <option> children.'); 5803 } 5804 }); 5805 } 5806 5807 // TODO: Remove support for `selected` in <option>. 5808 if (props.selected != null && !didWarnSelectedSetOnOption) { 5809 warning$1(false, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.'); 5810 didWarnSelectedSetOnOption = true; 5811 } 5812 } 5813 } 5814 5815 function postMountWrapper$1(element, props) { 5816 // value="" should make a value attribute (#6219) 5817 if (props.value != null) { 5818 element.setAttribute('value', toString(getToStringValue(props.value))); 5819 } 5820 } 5821 5822 function getHostProps$1(element, props) { 5823 var hostProps = _assign({ children: undefined }, props); 5824 var content = flattenChildren(props.children); 5825 5826 if (content) { 5827 hostProps.children = content; 5828 } 5829 5830 return hostProps; 5831 } 5832 5833 // TODO: direct imports like some-package/src/* are bad. Fix me. 5834 var didWarnValueDefaultValue$1 = void 0; 5835 5836 { 5837 didWarnValueDefaultValue$1 = false; 5838 } 5839 5840 function getDeclarationErrorAddendum() { 5841 var ownerName = getCurrentFiberOwnerNameInDevOrNull(); 5842 if (ownerName) { 5843 return '\n\nCheck the render method of `' + ownerName + '`.'; 5844 } 5845 return ''; 5846 } 5847 5848 var valuePropNames = ['value', 'defaultValue']; 5849 5850 /** 5851 * Validation function for `value` and `defaultValue`. 5852 */ 5853 function checkSelectPropTypes(props) { 5854 ReactControlledValuePropTypes.checkPropTypes('select', props); 5855 5856 for (var i = 0; i < valuePropNames.length; i++) { 5857 var propName = valuePropNames[i]; 5858 if (props[propName] == null) { 5859 continue; 5860 } 5861 var isArray = Array.isArray(props[propName]); 5862 if (props.multiple && !isArray) { 5863 warning$1(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum()); 5864 } else if (!props.multiple && isArray) { 5865 warning$1(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum()); 5866 } 5867 } 5868 } 5869 5870 function updateOptions(node, multiple, propValue, setDefaultSelected) { 5871 var options = node.options; 5872 5873 if (multiple) { 5874 var selectedValues = propValue; 5875 var selectedValue = {}; 5876 for (var i = 0; i < selectedValues.length; i++) { 5877 // Prefix to avoid chaos with special keys. 5878 selectedValue['$' + selectedValues[i]] = true; 5879 } 5880 for (var _i = 0; _i < options.length; _i++) { 5881 var selected = selectedValue.hasOwnProperty('$' + options[_i].value); 5882 if (options[_i].selected !== selected) { 5883 options[_i].selected = selected; 5884 } 5885 if (selected && setDefaultSelected) { 5886 options[_i].defaultSelected = true; 5887 } 5888 } 5889 } else { 5890 // Do not set `select.value` as exact behavior isn't consistent across all 5891 // browsers for all cases. 5892 var _selectedValue = toString(getToStringValue(propValue)); 5893 var defaultSelected = null; 5894 for (var _i2 = 0; _i2 < options.length; _i2++) { 5895 if (options[_i2].value === _selectedValue) { 5896 options[_i2].selected = true; 5897 if (setDefaultSelected) { 5898 options[_i2].defaultSelected = true; 5899 } 5900 return; 5901 } 5902 if (defaultSelected === null && !options[_i2].disabled) { 5903 defaultSelected = options[_i2]; 5904 } 5905 } 5906 if (defaultSelected !== null) { 5907 defaultSelected.selected = true; 5908 } 5909 } 5910 } 5911 5912 /** 5913 * Implements a <select> host component that allows optionally setting the 5914 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a 5915 * stringable. If `multiple` is true, the prop must be an array of stringables. 5916 * 5917 * If `value` is not supplied (or null/undefined), user actions that change the 5918 * selected option will trigger updates to the rendered options. 5919 * 5920 * If it is supplied (and not null/undefined), the rendered options will not 5921 * update in response to user actions. Instead, the `value` prop must change in 5922 * order for the rendered options to update. 5923 * 5924 * If `defaultValue` is provided, any options with the supplied values will be 5925 * selected. 5926 */ 5927 5928 function getHostProps$2(element, props) { 5929 return _assign({}, props, { 5930 value: undefined 5931 }); 5932 } 5933 5934 function initWrapperState$1(element, props) { 5935 var node = element; 5936 { 5937 checkSelectPropTypes(props); 5938 } 5939 5940 node._wrapperState = { 5941 wasMultiple: !!props.multiple 5942 }; 5943 5944 { 5945 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) { 5946 warning$1(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'); 5947 didWarnValueDefaultValue$1 = true; 5948 } 5949 } 5950 } 5951 5952 function postMountWrapper$2(element, props) { 5953 var node = element; 5954 node.multiple = !!props.multiple; 5955 var value = props.value; 5956 if (value != null) { 5957 updateOptions(node, !!props.multiple, value, false); 5958 } else if (props.defaultValue != null) { 5959 updateOptions(node, !!props.multiple, props.defaultValue, true); 5960 } 5961 } 5962 5963 function postUpdateWrapper(element, props) { 5964 var node = element; 5965 var wasMultiple = node._wrapperState.wasMultiple; 5966 node._wrapperState.wasMultiple = !!props.multiple; 5967 5968 var value = props.value; 5969 if (value != null) { 5970 updateOptions(node, !!props.multiple, value, false); 5971 } else if (wasMultiple !== !!props.multiple) { 5972 // For simplicity, reapply `defaultValue` if `multiple` is toggled. 5973 if (props.defaultValue != null) { 5974 updateOptions(node, !!props.multiple, props.defaultValue, true); 5975 } else { 5976 // Revert the select back to its default unselected state. 5977 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false); 5978 } 5979 } 5980 } 5981 5982 function restoreControlledState$2(element, props) { 5983 var node = element; 5984 var value = props.value; 5985 5986 if (value != null) { 5987 updateOptions(node, !!props.multiple, value, false); 5988 } 5989 } 5990 5991 var didWarnValDefaultVal = false; 5992 5993 /** 5994 * Implements a <textarea> host component that allows setting `value`, and 5995 * `defaultValue`. This differs from the traditional DOM API because value is 5996 * usually set as PCDATA children. 5997 * 5998 * If `value` is not supplied (or null/undefined), user actions that affect the 5999 * value will trigger updates to the element. 6000 * 6001 * If `value` is supplied (and not null/undefined), the rendered element will 6002 * not trigger updates to the element. Instead, the `value` prop must change in 6003 * order for the rendered element to be updated. 6004 * 6005 * The rendered element will be initialized with an empty value, the prop 6006 * `defaultValue` if specified, or the children content (deprecated). 6007 */ 6008 6009 function getHostProps$3(element, props) { 6010 var node = element; 6011 !(props.dangerouslySetInnerHTML == null) ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : void 0; 6012 6013 // Always set children to the same thing. In IE9, the selection range will 6014 // get reset if `textContent` is mutated. We could add a check in setTextContent 6015 // to only set the value if/when the value differs from the node value (which would 6016 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this 6017 // solution. The value can be a boolean or object so that's why it's forced 6018 // to be a string. 6019 var hostProps = _assign({}, props, { 6020 value: undefined, 6021 defaultValue: undefined, 6022 children: toString(node._wrapperState.initialValue) 6023 }); 6024 6025 return hostProps; 6026 } 6027 6028 function initWrapperState$2(element, props) { 6029 var node = element; 6030 { 6031 ReactControlledValuePropTypes.checkPropTypes('textarea', props); 6032 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) { 6033 warning$1(false, '%s contains a textarea with both value and defaultValue props. ' + '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', getCurrentFiberOwnerNameInDevOrNull() || 'A component'); 6034 didWarnValDefaultVal = true; 6035 } 6036 } 6037 6038 var initialValue = props.value; 6039 6040 // Only bother fetching default value if we're going to use it 6041 if (initialValue == null) { 6042 var defaultValue = props.defaultValue; 6043 // TODO (yungsters): Remove support for children content in <textarea>. 6044 var children = props.children; 6045 if (children != null) { 6046 { 6047 warning$1(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.'); 6048 } 6049 !(defaultValue == null) ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : void 0; 6050 if (Array.isArray(children)) { 6051 !(children.length <= 1) ? invariant(false, '<textarea> can only have at most one child.') : void 0; 6052 children = children[0]; 6053 } 6054 6055 defaultValue = children; 6056 } 6057 if (defaultValue == null) { 6058 defaultValue = ''; 6059 } 6060 initialValue = defaultValue; 6061 } 6062 6063 node._wrapperState = { 6064 initialValue: getToStringValue(initialValue) 6065 }; 6066 } 6067 6068 function updateWrapper$1(element, props) { 6069 var node = element; 6070 var value = getToStringValue(props.value); 6071 var defaultValue = getToStringValue(props.defaultValue); 6072 if (value != null) { 6073 // Cast `value` to a string to ensure the value is set correctly. While 6074 // browsers typically do this as necessary, jsdom doesn't. 6075 var newValue = toString(value); 6076 // To avoid side effects (such as losing text selection), only set value if changed 6077 if (newValue !== node.value) { 6078 node.value = newValue; 6079 } 6080 if (props.defaultValue == null && node.defaultValue !== newValue) { 6081 node.defaultValue = newValue; 6082 } 6083 } 6084 if (defaultValue != null) { 6085 node.defaultValue = toString(defaultValue); 6086 } 6087 } 6088 6089 function postMountWrapper$3(element, props) { 6090 var node = element; 6091 // This is in postMount because we need access to the DOM node, which is not 6092 // available until after the component has mounted. 6093 var textContent = node.textContent; 6094 6095 // Only set node.value if textContent is equal to the expected 6096 // initial value. In IE10/IE11 there is a bug where the placeholder attribute 6097 // will populate textContent as well. 6098 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/ 6099 if (textContent === node._wrapperState.initialValue) { 6100 node.value = textContent; 6101 } 6102 } 6103 6104 function restoreControlledState$3(element, props) { 6105 // DOM component is still mounted; update 6106 updateWrapper$1(element, props); 6107 } 6108 6109 var HTML_NAMESPACE$1 = 'http://www.w3.org/1999/xhtml'; 6110 var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML'; 6111 var SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; 6112 6113 var Namespaces = { 6114 html: HTML_NAMESPACE$1, 6115 mathml: MATH_NAMESPACE, 6116 svg: SVG_NAMESPACE 6117 }; 6118 6119 // Assumes there is no parent namespace. 6120 function getIntrinsicNamespace(type) { 6121 switch (type) { 6122 case 'svg': 6123 return SVG_NAMESPACE; 6124 case 'math': 6125 return MATH_NAMESPACE; 6126 default: 6127 return HTML_NAMESPACE$1; 6128 } 6129 } 6130 6131 function getChildNamespace(parentNamespace, type) { 6132 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE$1) { 6133 // No (or default) parent namespace: potential entry point. 6134 return getIntrinsicNamespace(type); 6135 } 6136 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') { 6137 // We're leaving SVG. 6138 return HTML_NAMESPACE$1; 6139 } 6140 // By default, pass namespace below. 6141 return parentNamespace; 6142 } 6143 6144 /* globals MSApp */ 6145 6146 /** 6147 * Create a function which has 'unsafe' privileges (required by windows8 apps) 6148 */ 6149 var createMicrosoftUnsafeLocalFunction = function (func) { 6150 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) { 6151 return function (arg0, arg1, arg2, arg3) { 6152 MSApp.execUnsafeLocalFunction(function () { 6153 return func(arg0, arg1, arg2, arg3); 6154 }); 6155 }; 6156 } else { 6157 return func; 6158 } 6159 }; 6160 6161 // SVG temp container for IE lacking innerHTML 6162 var reusableSVGContainer = void 0; 6163 6164 /** 6165 * Set the innerHTML property of a node 6166 * 6167 * @param {DOMElement} node 6168 * @param {string} html 6169 * @internal 6170 */ 6171 var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) { 6172 // IE does not have innerHTML for SVG nodes, so instead we inject the 6173 // new markup in a temp node and then move the child nodes across into 6174 // the target node 6175 6176 if (node.namespaceURI === Namespaces.svg && !('innerHTML' in node)) { 6177 reusableSVGContainer = reusableSVGContainer || document.createElementNS('http://www.w3.org/1999/xhtml', 'div'); 6178 reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>'; 6179 var svgNode = reusableSVGContainer.firstChild; 6180 while (node.firstChild) { 6181 node.removeChild(node.firstChild); 6182 } 6183 while (svgNode.firstChild) { 6184 node.appendChild(svgNode.firstChild); 6185 } 6186 } else { 6187 node.innerHTML = html; 6188 } 6189 }); 6190 6191 /** 6192 * Set the textContent property of a node. For text updates, it's faster 6193 * to set the `nodeValue` of the Text node directly instead of using 6194 * `.textContent` which will remove the existing node and create a new one. 6195 * 6196 * @param {DOMElement} node 6197 * @param {string} text 6198 * @internal 6199 */ 6200 var setTextContent = function (node, text) { 6201 if (text) { 6202 var firstChild = node.firstChild; 6203 6204 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) { 6205 firstChild.nodeValue = text; 6206 return; 6207 } 6208 } 6209 node.textContent = text; 6210 }; 6211 6212 // List derived from Gecko source code: 6213 // https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js 6214 var shorthandToLonghand = { 6215 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'], 6216 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'], 6217 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'], 6218 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'], 6219 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'], 6220 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'], 6221 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'], 6222 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'], 6223 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'], 6224 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'], 6225 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'], 6226 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'], 6227 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'], 6228 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'], 6229 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'], 6230 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'], 6231 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'], 6232 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'], 6233 columns: ['columnCount', 'columnWidth'], 6234 flex: ['flexBasis', 'flexGrow', 'flexShrink'], 6235 flexFlow: ['flexDirection', 'flexWrap'], 6236 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'], 6237 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'], 6238 gap: ['columnGap', 'rowGap'], 6239 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'], 6240 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'], 6241 gridColumn: ['gridColumnEnd', 'gridColumnStart'], 6242 gridColumnGap: ['columnGap'], 6243 gridGap: ['columnGap', 'rowGap'], 6244 gridRow: ['gridRowEnd', 'gridRowStart'], 6245 gridRowGap: ['rowGap'], 6246 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'], 6247 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'], 6248 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'], 6249 marker: ['markerEnd', 'markerMid', 'markerStart'], 6250 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'], 6251 maskPosition: ['maskPositionX', 'maskPositionY'], 6252 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'], 6253 overflow: ['overflowX', 'overflowY'], 6254 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'], 6255 placeContent: ['alignContent', 'justifyContent'], 6256 placeItems: ['alignItems', 'justifyItems'], 6257 placeSelf: ['alignSelf', 'justifySelf'], 6258 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'], 6259 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'], 6260 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'], 6261 wordWrap: ['overflowWrap'] 6262 }; 6263 6264 /** 6265 * CSS properties which accept numbers but are not in units of "px". 6266 */ 6267 var isUnitlessNumber = { 6268 animationIterationCount: true, 6269 borderImageOutset: true, 6270 borderImageSlice: true, 6271 borderImageWidth: true, 6272 boxFlex: true, 6273 boxFlexGroup: true, 6274 boxOrdinalGroup: true, 6275 columnCount: true, 6276 columns: true, 6277 flex: true, 6278 flexGrow: true, 6279 flexPositive: true, 6280 flexShrink: true, 6281 flexNegative: true, 6282 flexOrder: true, 6283 gridArea: true, 6284 gridRow: true, 6285 gridRowEnd: true, 6286 gridRowSpan: true, 6287 gridRowStart: true, 6288 gridColumn: true, 6289 gridColumnEnd: true, 6290 gridColumnSpan: true, 6291 gridColumnStart: true, 6292 fontWeight: true, 6293 lineClamp: true, 6294 lineHeight: true, 6295 opacity: true, 6296 order: true, 6297 orphans: true, 6298 tabSize: true, 6299 widows: true, 6300 zIndex: true, 6301 zoom: true, 6302 6303 // SVG-related properties 6304 fillOpacity: true, 6305 floodOpacity: true, 6306 stopOpacity: true, 6307 strokeDasharray: true, 6308 strokeDashoffset: true, 6309 strokeMiterlimit: true, 6310 strokeOpacity: true, 6311 strokeWidth: true 6312 }; 6313 6314 /** 6315 * @param {string} prefix vendor-specific prefix, eg: Webkit 6316 * @param {string} key style name, eg: transitionDuration 6317 * @return {string} style name prefixed with `prefix`, properly camelCased, eg: 6318 * WebkitTransitionDuration 6319 */ 6320 function prefixKey(prefix, key) { 6321 return prefix + key.charAt(0).toUpperCase() + key.substring(1); 6322 } 6323 6324 /** 6325 * Support style names that may come passed in prefixed by adding permutations 6326 * of vendor prefixes. 6327 */ 6328 var prefixes = ['Webkit', 'ms', 'Moz', 'O']; 6329 6330 // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an 6331 // infinite loop, because it iterates over the newly added props too. 6332 Object.keys(isUnitlessNumber).forEach(function (prop) { 6333 prefixes.forEach(function (prefix) { 6334 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; 6335 }); 6336 }); 6337 6338 /** 6339 * Convert a value into the proper css writable value. The style name `name` 6340 * should be logical (no hyphens), as specified 6341 * in `CSSProperty.isUnitlessNumber`. 6342 * 6343 * @param {string} name CSS property name such as `topMargin`. 6344 * @param {*} value CSS property value such as `10px`. 6345 * @return {string} Normalized style value with dimensions applied. 6346 */ 6347 function dangerousStyleValue(name, value, isCustomProperty) { 6348 // Note that we've removed escapeTextForBrowser() calls here since the 6349 // whole string will be escaped when the attribute is injected into 6350 // the markup. If you provide unsafe user data here they can inject 6351 // arbitrary CSS which may be problematic (I couldn't repro this): 6352 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet 6353 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/ 6354 // This is not an XSS hole but instead a potential CSS injection issue 6355 // which has lead to a greater discussion about how we're going to 6356 // trust URLs moving forward. See #2115901 6357 6358 var isEmpty = value == null || typeof value === 'boolean' || value === ''; 6359 if (isEmpty) { 6360 return ''; 6361 } 6362 6363 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) { 6364 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers 6365 } 6366 6367 return ('' + value).trim(); 6368 } 6369 6370 var uppercasePattern = /([A-Z])/g; 6371 var msPattern = /^ms-/; 6372 6373 /** 6374 * Hyphenates a camelcased CSS property name, for example: 6375 * 6376 * > hyphenateStyleName('backgroundColor') 6377 * < "background-color" 6378 * > hyphenateStyleName('MozTransition') 6379 * < "-moz-transition" 6380 * > hyphenateStyleName('msTransition') 6381 * < "-ms-transition" 6382 * 6383 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix 6384 * is converted to `-ms-`. 6385 */ 6386 function hyphenateStyleName(name) { 6387 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-'); 6388 } 6389 6390 var warnValidStyle = function () {}; 6391 6392 { 6393 // 'msTransform' is correct, but the other prefixes should be capitalized 6394 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; 6395 var msPattern$1 = /^-ms-/; 6396 var hyphenPattern = /-(.)/g; 6397 6398 // style values shouldn't contain a semicolon 6399 var badStyleValueWithSemicolonPattern = /;\s*$/; 6400 6401 var warnedStyleNames = {}; 6402 var warnedStyleValues = {}; 6403 var warnedForNaNValue = false; 6404 var warnedForInfinityValue = false; 6405 6406 var camelize = function (string) { 6407 return string.replace(hyphenPattern, function (_, character) { 6408 return character.toUpperCase(); 6409 }); 6410 }; 6411 6412 var warnHyphenatedStyleName = function (name) { 6413 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { 6414 return; 6415 } 6416 6417 warnedStyleNames[name] = true; 6418 warning$1(false, 'Unsupported style property %s. Did you mean %s?', name, 6419 // As Andi Smith suggests 6420 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix 6421 // is converted to lowercase `ms`. 6422 camelize(name.replace(msPattern$1, 'ms-'))); 6423 }; 6424 6425 var warnBadVendoredStyleName = function (name) { 6426 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { 6427 return; 6428 } 6429 6430 warnedStyleNames[name] = true; 6431 warning$1(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1)); 6432 }; 6433 6434 var warnStyleValueWithSemicolon = function (name, value) { 6435 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { 6436 return; 6437 } 6438 6439 warnedStyleValues[value] = true; 6440 warning$1(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, '')); 6441 }; 6442 6443 var warnStyleValueIsNaN = function (name, value) { 6444 if (warnedForNaNValue) { 6445 return; 6446 } 6447 6448 warnedForNaNValue = true; 6449 warning$1(false, '`NaN` is an invalid value for the `%s` css style property.', name); 6450 }; 6451 6452 var warnStyleValueIsInfinity = function (name, value) { 6453 if (warnedForInfinityValue) { 6454 return; 6455 } 6456 6457 warnedForInfinityValue = true; 6458 warning$1(false, '`Infinity` is an invalid value for the `%s` css style property.', name); 6459 }; 6460 6461 warnValidStyle = function (name, value) { 6462 if (name.indexOf('-') > -1) { 6463 warnHyphenatedStyleName(name); 6464 } else if (badVendoredStyleNamePattern.test(name)) { 6465 warnBadVendoredStyleName(name); 6466 } else if (badStyleValueWithSemicolonPattern.test(value)) { 6467 warnStyleValueWithSemicolon(name, value); 6468 } 6469 6470 if (typeof value === 'number') { 6471 if (isNaN(value)) { 6472 warnStyleValueIsNaN(name, value); 6473 } else if (!isFinite(value)) { 6474 warnStyleValueIsInfinity(name, value); 6475 } 6476 } 6477 }; 6478 } 6479 6480 var warnValidStyle$1 = warnValidStyle; 6481 6482 /** 6483 * Operations for dealing with CSS properties. 6484 */ 6485 6486 /** 6487 * This creates a string that is expected to be equivalent to the style 6488 * attribute generated by server-side rendering. It by-passes warnings and 6489 * security checks so it's not safe to use this value for anything other than 6490 * comparison. It is only used in DEV for SSR validation. 6491 */ 6492 function createDangerousStringForStyles(styles) { 6493 { 6494 var serialized = ''; 6495 var delimiter = ''; 6496 for (var styleName in styles) { 6497 if (!styles.hasOwnProperty(styleName)) { 6498 continue; 6499 } 6500 var styleValue = styles[styleName]; 6501 if (styleValue != null) { 6502 var isCustomProperty = styleName.indexOf('--') === 0; 6503 serialized += delimiter + hyphenateStyleName(styleName) + ':'; 6504 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty); 6505 6506 delimiter = ';'; 6507 } 6508 } 6509 return serialized || null; 6510 } 6511 } 6512 6513 /** 6514 * Sets the value for multiple styles on a node. If a value is specified as 6515 * '' (empty string), the corresponding style property will be unset. 6516 * 6517 * @param {DOMElement} node 6518 * @param {object} styles 6519 */ 6520 function setValueForStyles(node, styles) { 6521 var style = node.style; 6522 for (var styleName in styles) { 6523 if (!styles.hasOwnProperty(styleName)) { 6524 continue; 6525 } 6526 var isCustomProperty = styleName.indexOf('--') === 0; 6527 { 6528 if (!isCustomProperty) { 6529 warnValidStyle$1(styleName, styles[styleName]); 6530 } 6531 } 6532 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty); 6533 if (styleName === 'float') { 6534 styleName = 'cssFloat'; 6535 } 6536 if (isCustomProperty) { 6537 style.setProperty(styleName, styleValue); 6538 } else { 6539 style[styleName] = styleValue; 6540 } 6541 } 6542 } 6543 6544 function isValueEmpty(value) { 6545 return value == null || typeof value === 'boolean' || value === ''; 6546 } 6547 6548 /** 6549 * Given {color: 'red', overflow: 'hidden'} returns { 6550 * color: 'color', 6551 * overflowX: 'overflow', 6552 * overflowY: 'overflow', 6553 * }. This can be read as "the overflowY property was set by the overflow 6554 * shorthand". That is, the values are the property that each was derived from. 6555 */ 6556 function expandShorthandMap(styles) { 6557 var expanded = {}; 6558 for (var key in styles) { 6559 var longhands = shorthandToLonghand[key] || [key]; 6560 for (var i = 0; i < longhands.length; i++) { 6561 expanded[longhands[i]] = key; 6562 } 6563 } 6564 return expanded; 6565 } 6566 6567 /** 6568 * When mixing shorthand and longhand property names, we warn during updates if 6569 * we expect an incorrect result to occur. In particular, we warn for: 6570 * 6571 * Updating a shorthand property (longhand gets overwritten): 6572 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'} 6573 * becomes .style.font = 'baz' 6574 * Removing a shorthand property (longhand gets lost too): 6575 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'} 6576 * becomes .style.font = '' 6577 * Removing a longhand property (should revert to shorthand; doesn't): 6578 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'} 6579 * becomes .style.fontVariant = '' 6580 */ 6581 function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) { 6582 if (!warnAboutShorthandPropertyCollision) { 6583 return; 6584 } 6585 6586 if (!nextStyles) { 6587 return; 6588 } 6589 6590 var expandedUpdates = expandShorthandMap(styleUpdates); 6591 var expandedStyles = expandShorthandMap(nextStyles); 6592 var warnedAbout = {}; 6593 for (var key in expandedUpdates) { 6594 var originalKey = expandedUpdates[key]; 6595 var correctOriginalKey = expandedStyles[key]; 6596 if (correctOriginalKey && originalKey !== correctOriginalKey) { 6597 var warningKey = originalKey + ',' + correctOriginalKey; 6598 if (warnedAbout[warningKey]) { 6599 continue; 6600 } 6601 warnedAbout[warningKey] = true; 6602 warning$1(false, '%s a style property during rerender (%s) when a ' + 'conflicting property is set (%s) can lead to styling bugs. To ' + "avoid this, don't mix shorthand and non-shorthand properties " + 'for the same value; instead, replace the shorthand with ' + 'separate values.', isValueEmpty(styleUpdates[originalKey]) ? 'Removing' : 'Updating', originalKey, correctOriginalKey); 6603 } 6604 } 6605 } 6606 6607 // For HTML, certain tags should omit their close tag. We keep a whitelist for 6608 // those special-case tags. 6609 6610 var omittedCloseTags = { 6611 area: true, 6612 base: true, 6613 br: true, 6614 col: true, 6615 embed: true, 6616 hr: true, 6617 img: true, 6618 input: true, 6619 keygen: true, 6620 link: true, 6621 meta: true, 6622 param: true, 6623 source: true, 6624 track: true, 6625 wbr: true 6626 // NOTE: menuitem's close tag should be omitted, but that causes problems. 6627 }; 6628 6629 // For HTML, certain tags cannot have children. This has the same purpose as 6630 // `omittedCloseTags` except that `menuitem` should still have its closing tag. 6631 6632 var voidElementTags = _assign({ 6633 menuitem: true 6634 }, omittedCloseTags); 6635 6636 // TODO: We can remove this if we add invariantWithStack() 6637 // or add stack by default to invariants where possible. 6638 var HTML$1 = '__html'; 6639 6640 var ReactDebugCurrentFrame$2 = null; 6641 { 6642 ReactDebugCurrentFrame$2 = ReactSharedInternals.ReactDebugCurrentFrame; 6643 } 6644 6645 function assertValidProps(tag, props) { 6646 if (!props) { 6647 return; 6648 } 6649 // Note the use of `==` which checks for null or undefined. 6650 if (voidElementTags[tag]) { 6651 !(props.children == null && props.dangerouslySetInnerHTML == null) ? invariant(false, '%s is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.%s', tag, ReactDebugCurrentFrame$2.getStackAddendum()) : void 0; 6652 } 6653 if (props.dangerouslySetInnerHTML != null) { 6654 !(props.children == null) ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : void 0; 6655 !(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; 6656 } 6657 { 6658 !(props.suppressContentEditableWarning || !props.contentEditable || props.children == null) ? warning$1(false, '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.') : void 0; 6659 } 6660 !(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', ReactDebugCurrentFrame$2.getStackAddendum()) : void 0; 6661 } 6662 6663 function isCustomComponent(tagName, props) { 6664 if (tagName.indexOf('-') === -1) { 6665 return typeof props.is === 'string'; 6666 } 6667 switch (tagName) { 6668 // These are reserved SVG and MathML elements. 6669 // We don't mind this whitelist too much because we expect it to never grow. 6670 // The alternative is to track the namespace in a few places which is convoluted. 6671 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts 6672 case 'annotation-xml': 6673 case 'color-profile': 6674 case 'font-face': 6675 case 'font-face-src': 6676 case 'font-face-uri': 6677 case 'font-face-format': 6678 case 'font-face-name': 6679 case 'missing-glyph': 6680 return false; 6681 default: 6682 return true; 6683 } 6684 } 6685 6686 // When adding attributes to the HTML or SVG whitelist, be sure to 6687 // also add them to this module to ensure casing and incorrect name 6688 // warnings. 6689 var possibleStandardNames = { 6690 // HTML 6691 accept: 'accept', 6692 acceptcharset: 'acceptCharset', 6693 'accept-charset': 'acceptCharset', 6694 accesskey: 'accessKey', 6695 action: 'action', 6696 allowfullscreen: 'allowFullScreen', 6697 alt: 'alt', 6698 as: 'as', 6699 async: 'async', 6700 autocapitalize: 'autoCapitalize', 6701 autocomplete: 'autoComplete', 6702 autocorrect: 'autoCorrect', 6703 autofocus: 'autoFocus', 6704 autoplay: 'autoPlay', 6705 autosave: 'autoSave', 6706 capture: 'capture', 6707 cellpadding: 'cellPadding', 6708 cellspacing: 'cellSpacing', 6709 challenge: 'challenge', 6710 charset: 'charSet', 6711 checked: 'checked', 6712 children: 'children', 6713 cite: 'cite', 6714 class: 'className', 6715 classid: 'classID', 6716 classname: 'className', 6717 cols: 'cols', 6718 colspan: 'colSpan', 6719 content: 'content', 6720 contenteditable: 'contentEditable', 6721 contextmenu: 'contextMenu', 6722 controls: 'controls', 6723 controlslist: 'controlsList', 6724 coords: 'coords', 6725 crossorigin: 'crossOrigin', 6726 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML', 6727 data: 'data', 6728 datetime: 'dateTime', 6729 default: 'default', 6730 defaultchecked: 'defaultChecked', 6731 defaultvalue: 'defaultValue', 6732 defer: 'defer', 6733 dir: 'dir', 6734 disabled: 'disabled', 6735 download: 'download', 6736 draggable: 'draggable', 6737 enctype: 'encType', 6738 for: 'htmlFor', 6739 form: 'form', 6740 formmethod: 'formMethod', 6741 formaction: 'formAction', 6742 formenctype: 'formEncType', 6743 formnovalidate: 'formNoValidate', 6744 formtarget: 'formTarget', 6745 frameborder: 'frameBorder', 6746 headers: 'headers', 6747 height: 'height', 6748 hidden: 'hidden', 6749 high: 'high', 6750 href: 'href', 6751 hreflang: 'hrefLang', 6752 htmlfor: 'htmlFor', 6753 httpequiv: 'httpEquiv', 6754 'http-equiv': 'httpEquiv', 6755 icon: 'icon', 6756 id: 'id', 6757 innerhtml: 'innerHTML', 6758 inputmode: 'inputMode', 6759 integrity: 'integrity', 6760 is: 'is', 6761 itemid: 'itemID', 6762 itemprop: 'itemProp', 6763 itemref: 'itemRef', 6764 itemscope: 'itemScope', 6765 itemtype: 'itemType', 6766 keyparams: 'keyParams', 6767 keytype: 'keyType', 6768 kind: 'kind', 6769 label: 'label', 6770 lang: 'lang', 6771 list: 'list', 6772 loop: 'loop', 6773 low: 'low', 6774 manifest: 'manifest', 6775 marginwidth: 'marginWidth', 6776 marginheight: 'marginHeight', 6777 max: 'max', 6778 maxlength: 'maxLength', 6779 media: 'media', 6780 mediagroup: 'mediaGroup', 6781 method: 'method', 6782 min: 'min', 6783 minlength: 'minLength', 6784 multiple: 'multiple', 6785 muted: 'muted', 6786 name: 'name', 6787 nomodule: 'noModule', 6788 nonce: 'nonce', 6789 novalidate: 'noValidate', 6790 open: 'open', 6791 optimum: 'optimum', 6792 pattern: 'pattern', 6793 placeholder: 'placeholder', 6794 playsinline: 'playsInline', 6795 poster: 'poster', 6796 preload: 'preload', 6797 profile: 'profile', 6798 radiogroup: 'radioGroup', 6799 readonly: 'readOnly', 6800 referrerpolicy: 'referrerPolicy', 6801 rel: 'rel', 6802 required: 'required', 6803 reversed: 'reversed', 6804 role: 'role', 6805 rows: 'rows', 6806 rowspan: 'rowSpan', 6807 sandbox: 'sandbox', 6808 scope: 'scope', 6809 scoped: 'scoped', 6810 scrolling: 'scrolling', 6811 seamless: 'seamless', 6812 selected: 'selected', 6813 shape: 'shape', 6814 size: 'size', 6815 sizes: 'sizes', 6816 span: 'span', 6817 spellcheck: 'spellCheck', 6818 src: 'src', 6819 srcdoc: 'srcDoc', 6820 srclang: 'srcLang', 6821 srcset: 'srcSet', 6822 start: 'start', 6823 step: 'step', 6824 style: 'style', 6825 summary: 'summary', 6826 tabindex: 'tabIndex', 6827 target: 'target', 6828 title: 'title', 6829 type: 'type', 6830 usemap: 'useMap', 6831 value: 'value', 6832 width: 'width', 6833 wmode: 'wmode', 6834 wrap: 'wrap', 6835 6836 // SVG 6837 about: 'about', 6838 accentheight: 'accentHeight', 6839 'accent-height': 'accentHeight', 6840 accumulate: 'accumulate', 6841 additive: 'additive', 6842 alignmentbaseline: 'alignmentBaseline', 6843 'alignment-baseline': 'alignmentBaseline', 6844 allowreorder: 'allowReorder', 6845 alphabetic: 'alphabetic', 6846 amplitude: 'amplitude', 6847 arabicform: 'arabicForm', 6848 'arabic-form': 'arabicForm', 6849 ascent: 'ascent', 6850 attributename: 'attributeName', 6851 attributetype: 'attributeType', 6852 autoreverse: 'autoReverse', 6853 azimuth: 'azimuth', 6854 basefrequency: 'baseFrequency', 6855 baselineshift: 'baselineShift', 6856 'baseline-shift': 'baselineShift', 6857 baseprofile: 'baseProfile', 6858 bbox: 'bbox', 6859 begin: 'begin', 6860 bias: 'bias', 6861 by: 'by', 6862 calcmode: 'calcMode', 6863 capheight: 'capHeight', 6864 'cap-height': 'capHeight', 6865 clip: 'clip', 6866 clippath: 'clipPath', 6867 'clip-path': 'clipPath', 6868 clippathunits: 'clipPathUnits', 6869 cliprule: 'clipRule', 6870 'clip-rule': 'clipRule', 6871 color: 'color', 6872 colorinterpolation: 'colorInterpolation', 6873 'color-interpolation': 'colorInterpolation', 6874 colorinterpolationfilters: 'colorInterpolationFilters', 6875 'color-interpolation-filters': 'colorInterpolationFilters', 6876 colorprofile: 'colorProfile', 6877 'color-profile': 'colorProfile', 6878 colorrendering: 'colorRendering', 6879 'color-rendering': 'colorRendering', 6880 contentscripttype: 'contentScriptType', 6881 contentstyletype: 'contentStyleType', 6882 cursor: 'cursor', 6883 cx: 'cx', 6884 cy: 'cy', 6885 d: 'd', 6886 datatype: 'datatype', 6887 decelerate: 'decelerate', 6888 descent: 'descent', 6889 diffuseconstant: 'diffuseConstant', 6890 direction: 'direction', 6891 display: 'display', 6892 divisor: 'divisor', 6893 dominantbaseline: 'dominantBaseline', 6894 'dominant-baseline': 'dominantBaseline', 6895 dur: 'dur', 6896 dx: 'dx', 6897 dy: 'dy', 6898 edgemode: 'edgeMode', 6899 elevation: 'elevation', 6900 enablebackground: 'enableBackground', 6901 'enable-background': 'enableBackground', 6902 end: 'end', 6903 exponent: 'exponent', 6904 externalresourcesrequired: 'externalResourcesRequired', 6905 fill: 'fill', 6906 fillopacity: 'fillOpacity', 6907 'fill-opacity': 'fillOpacity', 6908 fillrule: 'fillRule', 6909 'fill-rule': 'fillRule', 6910 filter: 'filter', 6911 filterres: 'filterRes', 6912 filterunits: 'filterUnits', 6913 floodopacity: 'floodOpacity', 6914 'flood-opacity': 'floodOpacity', 6915 floodcolor: 'floodColor', 6916 'flood-color': 'floodColor', 6917 focusable: 'focusable', 6918 fontfamily: 'fontFamily', 6919 'font-family': 'fontFamily', 6920 fontsize: 'fontSize', 6921 'font-size': 'fontSize', 6922 fontsizeadjust: 'fontSizeAdjust', 6923 'font-size-adjust': 'fontSizeAdjust', 6924 fontstretch: 'fontStretch', 6925 'font-stretch': 'fontStretch', 6926 fontstyle: 'fontStyle', 6927 'font-style': 'fontStyle', 6928 fontvariant: 'fontVariant', 6929 'font-variant': 'fontVariant', 6930 fontweight: 'fontWeight', 6931 'font-weight': 'fontWeight', 6932 format: 'format', 6933 from: 'from', 6934 fx: 'fx', 6935 fy: 'fy', 6936 g1: 'g1', 6937 g2: 'g2', 6938 glyphname: 'glyphName', 6939 'glyph-name': 'glyphName', 6940 glyphorientationhorizontal: 'glyphOrientationHorizontal', 6941 'glyph-orientation-horizontal': 'glyphOrientationHorizontal', 6942 glyphorientationvertical: 'glyphOrientationVertical', 6943 'glyph-orientation-vertical': 'glyphOrientationVertical', 6944 glyphref: 'glyphRef', 6945 gradienttransform: 'gradientTransform', 6946 gradientunits: 'gradientUnits', 6947 hanging: 'hanging', 6948 horizadvx: 'horizAdvX', 6949 'horiz-adv-x': 'horizAdvX', 6950 horizoriginx: 'horizOriginX', 6951 'horiz-origin-x': 'horizOriginX', 6952 ideographic: 'ideographic', 6953 imagerendering: 'imageRendering', 6954 'image-rendering': 'imageRendering', 6955 in2: 'in2', 6956 in: 'in', 6957 inlist: 'inlist', 6958 intercept: 'intercept', 6959 k1: 'k1', 6960 k2: 'k2', 6961 k3: 'k3', 6962 k4: 'k4', 6963 k: 'k', 6964 kernelmatrix: 'kernelMatrix', 6965 kernelunitlength: 'kernelUnitLength', 6966 kerning: 'kerning', 6967 keypoints: 'keyPoints', 6968 keysplines: 'keySplines', 6969 keytimes: 'keyTimes', 6970 lengthadjust: 'lengthAdjust', 6971 letterspacing: 'letterSpacing', 6972 'letter-spacing': 'letterSpacing', 6973 lightingcolor: 'lightingColor', 6974 'lighting-color': 'lightingColor', 6975 limitingconeangle: 'limitingConeAngle', 6976 local: 'local', 6977 markerend: 'markerEnd', 6978 'marker-end': 'markerEnd', 6979 markerheight: 'markerHeight', 6980 markermid: 'markerMid', 6981 'marker-mid': 'markerMid', 6982 markerstart: 'markerStart', 6983 'marker-start': 'markerStart', 6984 markerunits: 'markerUnits', 6985 markerwidth: 'markerWidth', 6986 mask: 'mask', 6987 maskcontentunits: 'maskContentUnits', 6988 maskunits: 'maskUnits', 6989 mathematical: 'mathematical', 6990 mode: 'mode', 6991 numoctaves: 'numOctaves', 6992 offset: 'offset', 6993 opacity: 'opacity', 6994 operator: 'operator', 6995 order: 'order', 6996 orient: 'orient', 6997 orientation: 'orientation', 6998 origin: 'origin', 6999 overflow: 'overflow', 7000 overlineposition: 'overlinePosition', 7001 'overline-position': 'overlinePosition', 7002 overlinethickness: 'overlineThickness', 7003 'overline-thickness': 'overlineThickness', 7004 paintorder: 'paintOrder', 7005 'paint-order': 'paintOrder', 7006 panose1: 'panose1', 7007 'panose-1': 'panose1', 7008 pathlength: 'pathLength', 7009 patterncontentunits: 'patternContentUnits', 7010 patterntransform: 'patternTransform', 7011 patternunits: 'patternUnits', 7012 pointerevents: 'pointerEvents', 7013 'pointer-events': 'pointerEvents', 7014 points: 'points', 7015 pointsatx: 'pointsAtX', 7016 pointsaty: 'pointsAtY', 7017 pointsatz: 'pointsAtZ', 7018 prefix: 'prefix', 7019 preservealpha: 'preserveAlpha', 7020 preserveaspectratio: 'preserveAspectRatio', 7021 primitiveunits: 'primitiveUnits', 7022 property: 'property', 7023 r: 'r', 7024 radius: 'radius', 7025 refx: 'refX', 7026 refy: 'refY', 7027 renderingintent: 'renderingIntent', 7028 'rendering-intent': 'renderingIntent', 7029 repeatcount: 'repeatCount', 7030 repeatdur: 'repeatDur', 7031 requiredextensions: 'requiredExtensions', 7032 requiredfeatures: 'requiredFeatures', 7033 resource: 'resource', 7034 restart: 'restart', 7035 result: 'result', 7036 results: 'results', 7037 rotate: 'rotate', 7038 rx: 'rx', 7039 ry: 'ry', 7040 scale: 'scale', 7041 security: 'security', 7042 seed: 'seed', 7043 shaperendering: 'shapeRendering', 7044 'shape-rendering': 'shapeRendering', 7045 slope: 'slope', 7046 spacing: 'spacing', 7047 specularconstant: 'specularConstant', 7048 specularexponent: 'specularExponent', 7049 speed: 'speed', 7050 spreadmethod: 'spreadMethod', 7051 startoffset: 'startOffset', 7052 stddeviation: 'stdDeviation', 7053 stemh: 'stemh', 7054 stemv: 'stemv', 7055 stitchtiles: 'stitchTiles', 7056 stopcolor: 'stopColor', 7057 'stop-color': 'stopColor', 7058 stopopacity: 'stopOpacity', 7059 'stop-opacity': 'stopOpacity', 7060 strikethroughposition: 'strikethroughPosition', 7061 'strikethrough-position': 'strikethroughPosition', 7062 strikethroughthickness: 'strikethroughThickness', 7063 'strikethrough-thickness': 'strikethroughThickness', 7064 string: 'string', 7065 stroke: 'stroke', 7066 strokedasharray: 'strokeDasharray', 7067 'stroke-dasharray': 'strokeDasharray', 7068 strokedashoffset: 'strokeDashoffset', 7069 'stroke-dashoffset': 'strokeDashoffset', 7070 strokelinecap: 'strokeLinecap', 7071 'stroke-linecap': 'strokeLinecap', 7072 strokelinejoin: 'strokeLinejoin', 7073 'stroke-linejoin': 'strokeLinejoin', 7074 strokemiterlimit: 'strokeMiterlimit', 7075 'stroke-miterlimit': 'strokeMiterlimit', 7076 strokewidth: 'strokeWidth', 7077 'stroke-width': 'strokeWidth', 7078 strokeopacity: 'strokeOpacity', 7079 'stroke-opacity': 'strokeOpacity', 7080 suppresscontenteditablewarning: 'suppressContentEditableWarning', 7081 suppresshydrationwarning: 'suppressHydrationWarning', 7082 surfacescale: 'surfaceScale', 7083 systemlanguage: 'systemLanguage', 7084 tablevalues: 'tableValues', 7085 targetx: 'targetX', 7086 targety: 'targetY', 7087 textanchor: 'textAnchor', 7088 'text-anchor': 'textAnchor', 7089 textdecoration: 'textDecoration', 7090 'text-decoration': 'textDecoration', 7091 textlength: 'textLength', 7092 textrendering: 'textRendering', 7093 'text-rendering': 'textRendering', 7094 to: 'to', 7095 transform: 'transform', 7096 typeof: 'typeof', 7097 u1: 'u1', 7098 u2: 'u2', 7099 underlineposition: 'underlinePosition', 7100 'underline-position': 'underlinePosition', 7101 underlinethickness: 'underlineThickness', 7102 'underline-thickness': 'underlineThickness', 7103 unicode: 'unicode', 7104 unicodebidi: 'unicodeBidi', 7105 'unicode-bidi': 'unicodeBidi', 7106 unicoderange: 'unicodeRange', 7107 'unicode-range': 'unicodeRange', 7108 unitsperem: 'unitsPerEm', 7109 'units-per-em': 'unitsPerEm', 7110 unselectable: 'unselectable', 7111 valphabetic: 'vAlphabetic', 7112 'v-alphabetic': 'vAlphabetic', 7113 values: 'values', 7114 vectoreffect: 'vectorEffect', 7115 'vector-effect': 'vectorEffect', 7116 version: 'version', 7117 vertadvy: 'vertAdvY', 7118 'vert-adv-y': 'vertAdvY', 7119 vertoriginx: 'vertOriginX', 7120 'vert-origin-x': 'vertOriginX', 7121 vertoriginy: 'vertOriginY', 7122 'vert-origin-y': 'vertOriginY', 7123 vhanging: 'vHanging', 7124 'v-hanging': 'vHanging', 7125 videographic: 'vIdeographic', 7126 'v-ideographic': 'vIdeographic', 7127 viewbox: 'viewBox', 7128 viewtarget: 'viewTarget', 7129 visibility: 'visibility', 7130 vmathematical: 'vMathematical', 7131 'v-mathematical': 'vMathematical', 7132 vocab: 'vocab', 7133 widths: 'widths', 7134 wordspacing: 'wordSpacing', 7135 'word-spacing': 'wordSpacing', 7136 writingmode: 'writingMode', 7137 'writing-mode': 'writingMode', 7138 x1: 'x1', 7139 x2: 'x2', 7140 x: 'x', 7141 xchannelselector: 'xChannelSelector', 7142 xheight: 'xHeight', 7143 'x-height': 'xHeight', 7144 xlinkactuate: 'xlinkActuate', 7145 'xlink:actuate': 'xlinkActuate', 7146 xlinkarcrole: 'xlinkArcrole', 7147 'xlink:arcrole': 'xlinkArcrole', 7148 xlinkhref: 'xlinkHref', 7149 'xlink:href': 'xlinkHref', 7150 xlinkrole: 'xlinkRole', 7151 'xlink:role': 'xlinkRole', 7152 xlinkshow: 'xlinkShow', 7153 'xlink:show': 'xlinkShow', 7154 xlinktitle: 'xlinkTitle', 7155 'xlink:title': 'xlinkTitle', 7156 xlinktype: 'xlinkType', 7157 'xlink:type': 'xlinkType', 7158 xmlbase: 'xmlBase', 7159 'xml:base': 'xmlBase', 7160 xmllang: 'xmlLang', 7161 'xml:lang': 'xmlLang', 7162 xmlns: 'xmlns', 7163 'xml:space': 'xmlSpace', 7164 xmlnsxlink: 'xmlnsXlink', 7165 'xmlns:xlink': 'xmlnsXlink', 7166 xmlspace: 'xmlSpace', 7167 y1: 'y1', 7168 y2: 'y2', 7169 y: 'y', 7170 ychannelselector: 'yChannelSelector', 7171 z: 'z', 7172 zoomandpan: 'zoomAndPan' 7173 }; 7174 7175 var ariaProperties = { 7176 'aria-current': 0, // state 7177 'aria-details': 0, 7178 'aria-disabled': 0, // state 7179 'aria-hidden': 0, // state 7180 'aria-invalid': 0, // state 7181 'aria-keyshortcuts': 0, 7182 'aria-label': 0, 7183 'aria-roledescription': 0, 7184 // Widget Attributes 7185 'aria-autocomplete': 0, 7186 'aria-checked': 0, 7187 'aria-expanded': 0, 7188 'aria-haspopup': 0, 7189 'aria-level': 0, 7190 'aria-modal': 0, 7191 'aria-multiline': 0, 7192 'aria-multiselectable': 0, 7193 'aria-orientation': 0, 7194 'aria-placeholder': 0, 7195 'aria-pressed': 0, 7196 'aria-readonly': 0, 7197 'aria-required': 0, 7198 'aria-selected': 0, 7199 'aria-sort': 0, 7200 'aria-valuemax': 0, 7201 'aria-valuemin': 0, 7202 'aria-valuenow': 0, 7203 'aria-valuetext': 0, 7204 // Live Region Attributes 7205 'aria-atomic': 0, 7206 'aria-busy': 0, 7207 'aria-live': 0, 7208 'aria-relevant': 0, 7209 // Drag-and-Drop Attributes 7210 'aria-dropeffect': 0, 7211 'aria-grabbed': 0, 7212 // Relationship Attributes 7213 'aria-activedescendant': 0, 7214 'aria-colcount': 0, 7215 'aria-colindex': 0, 7216 'aria-colspan': 0, 7217 'aria-controls': 0, 7218 'aria-describedby': 0, 7219 'aria-errormessage': 0, 7220 'aria-flowto': 0, 7221 'aria-labelledby': 0, 7222 'aria-owns': 0, 7223 'aria-posinset': 0, 7224 'aria-rowcount': 0, 7225 'aria-rowindex': 0, 7226 'aria-rowspan': 0, 7227 'aria-setsize': 0 7228 }; 7229 7230 var warnedProperties = {}; 7231 var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$'); 7232 var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$'); 7233 7234 var hasOwnProperty$2 = Object.prototype.hasOwnProperty; 7235 7236 function validateProperty(tagName, name) { 7237 if (hasOwnProperty$2.call(warnedProperties, name) && warnedProperties[name]) { 7238 return true; 7239 } 7240 7241 if (rARIACamel.test(name)) { 7242 var ariaName = 'aria-' + name.slice(4).toLowerCase(); 7243 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; 7244 7245 // If this is an aria-* attribute, but is not listed in the known DOM 7246 // DOM properties, then it is an invalid aria-* attribute. 7247 if (correctName == null) { 7248 warning$1(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name); 7249 warnedProperties[name] = true; 7250 return true; 7251 } 7252 // aria-* attributes should be lowercase; suggest the lowercase version. 7253 if (name !== correctName) { 7254 warning$1(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName); 7255 warnedProperties[name] = true; 7256 return true; 7257 } 7258 } 7259 7260 if (rARIA.test(name)) { 7261 var lowerCasedName = name.toLowerCase(); 7262 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; 7263 7264 // If this is an aria-* attribute, but is not listed in the known DOM 7265 // DOM properties, then it is an invalid aria-* attribute. 7266 if (standardName == null) { 7267 warnedProperties[name] = true; 7268 return false; 7269 } 7270 // aria-* attributes should be lowercase; suggest the lowercase version. 7271 if (name !== standardName) { 7272 warning$1(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName); 7273 warnedProperties[name] = true; 7274 return true; 7275 } 7276 } 7277 7278 return true; 7279 } 7280 7281 function warnInvalidARIAProps(type, props) { 7282 var invalidProps = []; 7283 7284 for (var key in props) { 7285 var isValid = validateProperty(type, key); 7286 if (!isValid) { 7287 invalidProps.push(key); 7288 } 7289 } 7290 7291 var unknownPropString = invalidProps.map(function (prop) { 7292 return '`' + prop + '`'; 7293 }).join(', '); 7294 7295 if (invalidProps.length === 1) { 7296 warning$1(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type); 7297 } else if (invalidProps.length > 1) { 7298 warning$1(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type); 7299 } 7300 } 7301 7302 function validateProperties(type, props) { 7303 if (isCustomComponent(type, props)) { 7304 return; 7305 } 7306 warnInvalidARIAProps(type, props); 7307 } 7308 7309 var didWarnValueNull = false; 7310 7311 function validateProperties$1(type, props) { 7312 if (type !== 'input' && type !== 'textarea' && type !== 'select') { 7313 return; 7314 } 7315 7316 if (props != null && props.value === null && !didWarnValueNull) { 7317 didWarnValueNull = true; 7318 if (type === 'select' && props.multiple) { 7319 warning$1(false, '`value` prop on `%s` should not be null. ' + 'Consider using an empty array when `multiple` is set to `true` ' + 'to clear the component or `undefined` for uncontrolled components.', type); 7320 } else { 7321 warning$1(false, '`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type); 7322 } 7323 } 7324 } 7325 7326 var validateProperty$1 = function () {}; 7327 7328 { 7329 var warnedProperties$1 = {}; 7330 var _hasOwnProperty = Object.prototype.hasOwnProperty; 7331 var EVENT_NAME_REGEX = /^on./; 7332 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/; 7333 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$'); 7334 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$'); 7335 7336 validateProperty$1 = function (tagName, name, value, canUseEventSystem) { 7337 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) { 7338 return true; 7339 } 7340 7341 var lowerCasedName = name.toLowerCase(); 7342 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') { 7343 warning$1(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.'); 7344 warnedProperties$1[name] = true; 7345 return true; 7346 } 7347 7348 // We can't rely on the event system being injected on the server. 7349 if (canUseEventSystem) { 7350 if (registrationNameModules.hasOwnProperty(name)) { 7351 return true; 7352 } 7353 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null; 7354 if (registrationName != null) { 7355 warning$1(false, 'Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName); 7356 warnedProperties$1[name] = true; 7357 return true; 7358 } 7359 if (EVENT_NAME_REGEX.test(name)) { 7360 warning$1(false, 'Unknown event handler property `%s`. It will be ignored.', name); 7361 warnedProperties$1[name] = true; 7362 return true; 7363 } 7364 } else if (EVENT_NAME_REGEX.test(name)) { 7365 // If no event plugins have been injected, we are in a server environment. 7366 // So we can't tell if the event name is correct for sure, but we can filter 7367 // out known bad ones like `onclick`. We can't suggest a specific replacement though. 7368 if (INVALID_EVENT_NAME_REGEX.test(name)) { 7369 warning$1(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name); 7370 } 7371 warnedProperties$1[name] = true; 7372 return true; 7373 } 7374 7375 // Let the ARIA attribute hook validate ARIA attributes 7376 if (rARIA$1.test(name) || rARIACamel$1.test(name)) { 7377 return true; 7378 } 7379 7380 if (lowerCasedName === 'innerhtml') { 7381 warning$1(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.'); 7382 warnedProperties$1[name] = true; 7383 return true; 7384 } 7385 7386 if (lowerCasedName === 'aria') { 7387 warning$1(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.'); 7388 warnedProperties$1[name] = true; 7389 return true; 7390 } 7391 7392 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') { 7393 warning$1(false, 'Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value); 7394 warnedProperties$1[name] = true; 7395 return true; 7396 } 7397 7398 if (typeof value === 'number' && isNaN(value)) { 7399 warning$1(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name); 7400 warnedProperties$1[name] = true; 7401 return true; 7402 } 7403 7404 var propertyInfo = getPropertyInfo(name); 7405 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED; 7406 7407 // Known attributes should match the casing specified in the property config. 7408 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) { 7409 var standardName = possibleStandardNames[lowerCasedName]; 7410 if (standardName !== name) { 7411 warning$1(false, 'Invalid DOM property `%s`. Did you mean `%s`?', name, standardName); 7412 warnedProperties$1[name] = true; 7413 return true; 7414 } 7415 } else if (!isReserved && name !== lowerCasedName) { 7416 // Unknown attributes should have lowercase casing since that's how they 7417 // will be cased anyway with server rendering. 7418 warning$1(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.', name, lowerCasedName); 7419 warnedProperties$1[name] = true; 7420 return true; 7421 } 7422 7423 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) { 7424 if (value) { 7425 warning$1(false, 'Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.', value, name, name, value, name); 7426 } else { 7427 warning$1(false, 'Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.\n\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.', value, name, name, value, name, name, name); 7428 } 7429 warnedProperties$1[name] = true; 7430 return true; 7431 } 7432 7433 // Now that we've validated casing, do not validate 7434 // data types for reserved props 7435 if (isReserved) { 7436 return true; 7437 } 7438 7439 // Warn when a known attribute is a bad type 7440 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) { 7441 warnedProperties$1[name] = true; 7442 return false; 7443 } 7444 7445 // Warn when passing the strings 'false' or 'true' into a boolean prop 7446 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) { 7447 warning$1(false, 'Received the string `%s` for the boolean attribute `%s`. ' + '%s ' + 'Did you mean %s={%s}?', value, name, value === 'false' ? 'The browser will interpret it as a truthy value.' : 'Although this works, it will not work as expected if you pass the string "false".', name, value); 7448 warnedProperties$1[name] = true; 7449 return true; 7450 } 7451 7452 return true; 7453 }; 7454 } 7455 7456 var warnUnknownProperties = function (type, props, canUseEventSystem) { 7457 var unknownProps = []; 7458 for (var key in props) { 7459 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem); 7460 if (!isValid) { 7461 unknownProps.push(key); 7462 } 7463 } 7464 7465 var unknownPropString = unknownProps.map(function (prop) { 7466 return '`' + prop + '`'; 7467 }).join(', '); 7468 if (unknownProps.length === 1) { 7469 warning$1(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', unknownPropString, type); 7470 } else if (unknownProps.length > 1) { 7471 warning$1(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', unknownPropString, type); 7472 } 7473 }; 7474 7475 function validateProperties$2(type, props, canUseEventSystem) { 7476 if (isCustomComponent(type, props)) { 7477 return; 7478 } 7479 warnUnknownProperties(type, props, canUseEventSystem); 7480 } 7481 7482 // TODO: direct imports like some-package/src/* are bad. Fix me. 7483 var didWarnInvalidHydration = false; 7484 var didWarnShadyDOM = false; 7485 7486 var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML'; 7487 var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning'; 7488 var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning'; 7489 var AUTOFOCUS = 'autoFocus'; 7490 var CHILDREN = 'children'; 7491 var STYLE$1 = 'style'; 7492 var HTML = '__html'; 7493 7494 var HTML_NAMESPACE = Namespaces.html; 7495 7496 7497 var warnedUnknownTags = void 0; 7498 var suppressHydrationWarning = void 0; 7499 7500 var validatePropertiesInDevelopment = void 0; 7501 var warnForTextDifference = void 0; 7502 var warnForPropDifference = void 0; 7503 var warnForExtraAttributes = void 0; 7504 var warnForInvalidEventListener = void 0; 7505 var canDiffStyleForHydrationWarning = void 0; 7506 7507 var normalizeMarkupForTextOrAttribute = void 0; 7508 var normalizeHTML = void 0; 7509 7510 { 7511 warnedUnknownTags = { 7512 // Chrome is the only major browser not shipping <time>. But as of July 7513 // 2017 it intends to ship it due to widespread usage. We intentionally 7514 // *don't* warn for <time> even if it's unrecognized by Chrome because 7515 // it soon will be, and many apps have been using it anyway. 7516 time: true, 7517 // There are working polyfills for <dialog>. Let people use it. 7518 dialog: true, 7519 // Electron ships a custom <webview> tag to display external web content in 7520 // an isolated frame and process. 7521 // This tag is not present in non Electron environments such as JSDom which 7522 // is often used for testing purposes. 7523 // @see https://electronjs.org/docs/api/webview-tag 7524 webview: true 7525 }; 7526 7527 validatePropertiesInDevelopment = function (type, props) { 7528 validateProperties(type, props); 7529 validateProperties$1(type, props); 7530 validateProperties$2(type, props, /* canUseEventSystem */true); 7531 }; 7532 7533 // IE 11 parses & normalizes the style attribute as opposed to other 7534 // browsers. It adds spaces and sorts the properties in some 7535 // non-alphabetical order. Handling that would require sorting CSS 7536 // properties in the client & server versions or applying 7537 // `expectedStyle` to a temporary DOM node to read its `style` attribute 7538 // normalized. Since it only affects IE, we're skipping style warnings 7539 // in that browser completely in favor of doing all that work. 7540 // See https://github.com/facebook/react/issues/11807 7541 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode; 7542 7543 // HTML parsing normalizes CR and CRLF to LF. 7544 // It also can turn \u0000 into \uFFFD inside attributes. 7545 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream 7546 // If we have a mismatch, it might be caused by that. 7547 // We will still patch up in this case but not fire the warning. 7548 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g; 7549 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g; 7550 7551 normalizeMarkupForTextOrAttribute = function (markup) { 7552 var markupString = typeof markup === 'string' ? markup : '' + markup; 7553 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, ''); 7554 }; 7555 7556 warnForTextDifference = function (serverText, clientText) { 7557 if (didWarnInvalidHydration) { 7558 return; 7559 } 7560 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText); 7561 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText); 7562 if (normalizedServerText === normalizedClientText) { 7563 return; 7564 } 7565 didWarnInvalidHydration = true; 7566 warningWithoutStack$1(false, 'Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText); 7567 }; 7568 7569 warnForPropDifference = function (propName, serverValue, clientValue) { 7570 if (didWarnInvalidHydration) { 7571 return; 7572 } 7573 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue); 7574 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue); 7575 if (normalizedServerValue === normalizedClientValue) { 7576 return; 7577 } 7578 didWarnInvalidHydration = true; 7579 warningWithoutStack$1(false, 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue)); 7580 }; 7581 7582 warnForExtraAttributes = function (attributeNames) { 7583 if (didWarnInvalidHydration) { 7584 return; 7585 } 7586 didWarnInvalidHydration = true; 7587 var names = []; 7588 attributeNames.forEach(function (name) { 7589 names.push(name); 7590 }); 7591 warningWithoutStack$1(false, 'Extra attributes from the server: %s', names); 7592 }; 7593 7594 warnForInvalidEventListener = function (registrationName, listener) { 7595 if (listener === false) { 7596 warning$1(false, 'Expected `%s` listener to be a function, instead got `false`.\n\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.', registrationName, registrationName, registrationName); 7597 } else { 7598 warning$1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener); 7599 } 7600 }; 7601 7602 // Parse the HTML and read it back to normalize the HTML string so that it 7603 // can be used for comparison. 7604 normalizeHTML = function (parent, html) { 7605 // We could have created a separate document here to avoid 7606 // re-initializing custom elements if they exist. But this breaks 7607 // how <noscript> is being handled. So we use the same document. 7608 // See the discussion in https://github.com/facebook/react/pull/11157. 7609 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElementNS('http://www.w3.org/1999/xhtml', parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName); 7610 testElement.innerHTML = html; 7611 return testElement.innerHTML; 7612 }; 7613 } 7614 7615 function ensureListeningTo(rootContainerElement, registrationName) { 7616 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE; 7617 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument; 7618 listenTo(registrationName, doc); 7619 } 7620 7621 function getOwnerDocumentFromRootContainer(rootContainerElement) { 7622 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument; 7623 } 7624 7625 function noop() {} 7626 7627 function trapClickOnNonInteractiveElement(node) { 7628 // Mobile Safari does not fire properly bubble click events on 7629 // non-interactive elements, which means delegated click listeners do not 7630 // fire. The workaround for this bug involves attaching an empty click 7631 // listener on the target node. 7632 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html 7633 // Just set it using the onclick property so that we don't have to manage any 7634 // bookkeeping for it. Not sure if we need to clear it when the listener is 7635 // removed. 7636 // TODO: Only do this for the relevant Safaris maybe? 7637 node.onclick = noop; 7638 } 7639 7640 function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) { 7641 for (var propKey in nextProps) { 7642 if (!nextProps.hasOwnProperty(propKey)) { 7643 continue; 7644 } 7645 var nextProp = nextProps[propKey]; 7646 if (propKey === STYLE$1) { 7647 { 7648 if (nextProp) { 7649 // Freeze the next style object so that we can assume it won't be 7650 // mutated. We have already warned for this in the past. 7651 Object.freeze(nextProp); 7652 } 7653 } 7654 // Relies on `updateStylesByID` not mutating `styleUpdates`. 7655 setValueForStyles(domElement, nextProp); 7656 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { 7657 var nextHtml = nextProp ? nextProp[HTML] : undefined; 7658 if (nextHtml != null) { 7659 setInnerHTML(domElement, nextHtml); 7660 } 7661 } else if (propKey === CHILDREN) { 7662 if (typeof nextProp === 'string') { 7663 // Avoid setting initial textContent when the text is empty. In IE11 setting 7664 // textContent on a <textarea> will cause the placeholder to not 7665 // show within the <textarea> until it has been focused and blurred again. 7666 // https://github.com/facebook/react/issues/6731#issuecomment-254874553 7667 var canSetTextContent = tag !== 'textarea' || nextProp !== ''; 7668 if (canSetTextContent) { 7669 setTextContent(domElement, nextProp); 7670 } 7671 } else if (typeof nextProp === 'number') { 7672 setTextContent(domElement, '' + nextProp); 7673 } 7674 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) { 7675 // Noop 7676 } else if (propKey === AUTOFOCUS) { 7677 // We polyfill it separately on the client during commit. 7678 // We could have excluded it in the property list instead of 7679 // adding a special case here, but then it wouldn't be emitted 7680 // on server rendering (but we *do* want to emit it in SSR). 7681 } else if (registrationNameModules.hasOwnProperty(propKey)) { 7682 if (nextProp != null) { 7683 if (true && typeof nextProp !== 'function') { 7684 warnForInvalidEventListener(propKey, nextProp); 7685 } 7686 ensureListeningTo(rootContainerElement, propKey); 7687 } 7688 } else if (nextProp != null) { 7689 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag); 7690 } 7691 } 7692 } 7693 7694 function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) { 7695 // TODO: Handle wasCustomComponentTag 7696 for (var i = 0; i < updatePayload.length; i += 2) { 7697 var propKey = updatePayload[i]; 7698 var propValue = updatePayload[i + 1]; 7699 if (propKey === STYLE$1) { 7700 setValueForStyles(domElement, propValue); 7701 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { 7702 setInnerHTML(domElement, propValue); 7703 } else if (propKey === CHILDREN) { 7704 setTextContent(domElement, propValue); 7705 } else { 7706 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag); 7707 } 7708 } 7709 } 7710 7711 function createElement(type, props, rootContainerElement, parentNamespace) { 7712 var isCustomComponentTag = void 0; 7713 7714 // We create tags in the namespace of their parent container, except HTML 7715 // tags get no namespace. 7716 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement); 7717 var domElement = void 0; 7718 var namespaceURI = parentNamespace; 7719 if (namespaceURI === HTML_NAMESPACE) { 7720 namespaceURI = getIntrinsicNamespace(type); 7721 } 7722 if (namespaceURI === HTML_NAMESPACE) { 7723 { 7724 isCustomComponentTag = isCustomComponent(type, props); 7725 // Should this check be gated by parent namespace? Not sure we want to 7726 // allow <SVG> or <mATH>. 7727 !(isCustomComponentTag || type === type.toLowerCase()) ? warning$1(false, '<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type) : void 0; 7728 } 7729 7730 if (type === 'script') { 7731 // Create the script via .innerHTML so its "parser-inserted" flag is 7732 // set to true and it does not execute 7733 var div = ownerDocument.createElementNS('http://www.w3.org/1999/xhtml', 'div'); 7734 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line 7735 // This is guaranteed to yield a script element. 7736 var firstChild = div.firstChild; 7737 domElement = div.removeChild(firstChild); 7738 } else if (typeof props.is === 'string') { 7739 // $FlowIssue `createElement` should be updated for Web Components 7740 domElement = ownerDocument.createElementNS('http://www.w3.org/1999/xhtml', type, { is: props.is }); 7741 } else { 7742 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug. 7743 // See discussion in https://github.com/facebook/react/pull/6896 7744 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240 7745 domElement = ownerDocument.createElementNS('http://www.w3.org/1999/xhtml', type); 7746 // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size` 7747 // attributes on `select`s needs to be added before `option`s are inserted. 7748 // This prevents: 7749 // - a bug where the `select` does not scroll to the correct option because singular 7750 // `select` elements automatically pick the first item #13222 7751 // - a bug where the `select` set the first item as selected despite the `size` attribute #14239 7752 // See https://github.com/facebook/react/issues/13222 7753 // and https://github.com/facebook/react/issues/14239 7754 if (type === 'select') { 7755 var node = domElement; 7756 if (props.multiple) { 7757 node.multiple = true; 7758 } else if (props.size) { 7759 // Setting a size greater than 1 causes a select to behave like `multiple=true`, where 7760 // it is possible that no option is selected. 7761 // 7762 // This is only necessary when a select in "single selection mode". 7763 node.size = props.size; 7764 } 7765 } 7766 } 7767 } else { 7768 domElement = ownerDocument.createElementNS(namespaceURI, type); 7769 } 7770 7771 { 7772 if (namespaceURI === HTML_NAMESPACE) { 7773 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) { 7774 warnedUnknownTags[type] = true; 7775 warning$1(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); 7776 } 7777 } 7778 } 7779 7780 return domElement; 7781 } 7782 7783 function createTextNode(text, rootContainerElement) { 7784 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text); 7785 } 7786 7787 function setInitialProperties(domElement, tag, rawProps, rootContainerElement) { 7788 var isCustomComponentTag = isCustomComponent(tag, rawProps); 7789 { 7790 validatePropertiesInDevelopment(tag, rawProps); 7791 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) { 7792 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component'); 7793 didWarnShadyDOM = true; 7794 } 7795 } 7796 7797 // TODO: Make sure that we check isMounted before firing any of these events. 7798 var props = void 0; 7799 switch (tag) { 7800 case 'iframe': 7801 case 'object': 7802 trapBubbledEvent(TOP_LOAD, domElement); 7803 props = rawProps; 7804 break; 7805 case 'video': 7806 case 'audio': 7807 // Create listener for each media event 7808 for (var i = 0; i < mediaEventTypes.length; i++) { 7809 trapBubbledEvent(mediaEventTypes[i], domElement); 7810 } 7811 props = rawProps; 7812 break; 7813 case 'source': 7814 trapBubbledEvent(TOP_ERROR, domElement); 7815 props = rawProps; 7816 break; 7817 case 'img': 7818 case 'image': 7819 case 'link': 7820 trapBubbledEvent(TOP_ERROR, domElement); 7821 trapBubbledEvent(TOP_LOAD, domElement); 7822 props = rawProps; 7823 break; 7824 case 'form': 7825 trapBubbledEvent(TOP_RESET, domElement); 7826 trapBubbledEvent(TOP_SUBMIT, domElement); 7827 props = rawProps; 7828 break; 7829 case 'details': 7830 trapBubbledEvent(TOP_TOGGLE, domElement); 7831 props = rawProps; 7832 break; 7833 case 'input': 7834 initWrapperState(domElement, rawProps); 7835 props = getHostProps(domElement, rawProps); 7836 trapBubbledEvent(TOP_INVALID, domElement); 7837 // For controlled components we always need to ensure we're listening 7838 // to onChange. Even if there is no listener. 7839 ensureListeningTo(rootContainerElement, 'onChange'); 7840 break; 7841 case 'option': 7842 validateProps(domElement, rawProps); 7843 props = getHostProps$1(domElement, rawProps); 7844 break; 7845 case 'select': 7846 initWrapperState$1(domElement, rawProps); 7847 props = getHostProps$2(domElement, rawProps); 7848 trapBubbledEvent(TOP_INVALID, domElement); 7849 // For controlled components we always need to ensure we're listening 7850 // to onChange. Even if there is no listener. 7851 ensureListeningTo(rootContainerElement, 'onChange'); 7852 break; 7853 case 'textarea': 7854 initWrapperState$2(domElement, rawProps); 7855 props = getHostProps$3(domElement, rawProps); 7856 trapBubbledEvent(TOP_INVALID, domElement); 7857 // For controlled components we always need to ensure we're listening 7858 // to onChange. Even if there is no listener. 7859 ensureListeningTo(rootContainerElement, 'onChange'); 7860 break; 7861 default: 7862 props = rawProps; 7863 } 7864 7865 assertValidProps(tag, props); 7866 7867 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag); 7868 7869 switch (tag) { 7870 case 'input': 7871 // TODO: Make sure we check if this is still unmounted or do any clean 7872 // up necessary since we never stop tracking anymore. 7873 track(domElement); 7874 postMountWrapper(domElement, rawProps, false); 7875 break; 7876 case 'textarea': 7877 // TODO: Make sure we check if this is still unmounted or do any clean 7878 // up necessary since we never stop tracking anymore. 7879 track(domElement); 7880 postMountWrapper$3(domElement, rawProps); 7881 break; 7882 case 'option': 7883 postMountWrapper$1(domElement, rawProps); 7884 break; 7885 case 'select': 7886 postMountWrapper$2(domElement, rawProps); 7887 break; 7888 default: 7889 if (typeof props.onClick === 'function') { 7890 // TODO: This cast may not be sound for SVG, MathML or custom elements. 7891 trapClickOnNonInteractiveElement(domElement); 7892 } 7893 break; 7894 } 7895 } 7896 7897 // Calculate the diff between the two objects. 7898 function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) { 7899 { 7900 validatePropertiesInDevelopment(tag, nextRawProps); 7901 } 7902 7903 var updatePayload = null; 7904 7905 var lastProps = void 0; 7906 var nextProps = void 0; 7907 switch (tag) { 7908 case 'input': 7909 lastProps = getHostProps(domElement, lastRawProps); 7910 nextProps = getHostProps(domElement, nextRawProps); 7911 updatePayload = []; 7912 break; 7913 case 'option': 7914 lastProps = getHostProps$1(domElement, lastRawProps); 7915 nextProps = getHostProps$1(domElement, nextRawProps); 7916 updatePayload = []; 7917 break; 7918 case 'select': 7919 lastProps = getHostProps$2(domElement, lastRawProps); 7920 nextProps = getHostProps$2(domElement, nextRawProps); 7921 updatePayload = []; 7922 break; 7923 case 'textarea': 7924 lastProps = getHostProps$3(domElement, lastRawProps); 7925 nextProps = getHostProps$3(domElement, nextRawProps); 7926 updatePayload = []; 7927 break; 7928 default: 7929 lastProps = lastRawProps; 7930 nextProps = nextRawProps; 7931 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') { 7932 // TODO: This cast may not be sound for SVG, MathML or custom elements. 7933 trapClickOnNonInteractiveElement(domElement); 7934 } 7935 break; 7936 } 7937 7938 assertValidProps(tag, nextProps); 7939 7940 var propKey = void 0; 7941 var styleName = void 0; 7942 var styleUpdates = null; 7943 for (propKey in lastProps) { 7944 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) { 7945 continue; 7946 } 7947 if (propKey === STYLE$1) { 7948 var lastStyle = lastProps[propKey]; 7949 for (styleName in lastStyle) { 7950 if (lastStyle.hasOwnProperty(styleName)) { 7951 if (!styleUpdates) { 7952 styleUpdates = {}; 7953 } 7954 styleUpdates[styleName] = ''; 7955 } 7956 } 7957 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) { 7958 // Noop. This is handled by the clear text mechanism. 7959 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) { 7960 // Noop 7961 } else if (propKey === AUTOFOCUS) { 7962 // Noop. It doesn't work on updates anyway. 7963 } else if (registrationNameModules.hasOwnProperty(propKey)) { 7964 // This is a special case. If any listener updates we need to ensure 7965 // that the "current" fiber pointer gets updated so we need a commit 7966 // to update this element. 7967 if (!updatePayload) { 7968 updatePayload = []; 7969 } 7970 } else { 7971 // For all other deleted properties we add it to the queue. We use 7972 // the whitelist in the commit phase instead. 7973 (updatePayload = updatePayload || []).push(propKey, null); 7974 } 7975 } 7976 for (propKey in nextProps) { 7977 var nextProp = nextProps[propKey]; 7978 var lastProp = lastProps != null ? lastProps[propKey] : undefined; 7979 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) { 7980 continue; 7981 } 7982 if (propKey === STYLE$1) { 7983 { 7984 if (nextProp) { 7985 // Freeze the next style object so that we can assume it won't be 7986 // mutated. We have already warned for this in the past. 7987 Object.freeze(nextProp); 7988 } 7989 } 7990 if (lastProp) { 7991 // Unset styles on `lastProp` but not on `nextProp`. 7992 for (styleName in lastProp) { 7993 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) { 7994 if (!styleUpdates) { 7995 styleUpdates = {}; 7996 } 7997 styleUpdates[styleName] = ''; 7998 } 7999 } 8000 // Update styles that changed since `lastProp`. 8001 for (styleName in nextProp) { 8002 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) { 8003 if (!styleUpdates) { 8004 styleUpdates = {}; 8005 } 8006 styleUpdates[styleName] = nextProp[styleName]; 8007 } 8008 } 8009 } else { 8010 // Relies on `updateStylesByID` not mutating `styleUpdates`. 8011 if (!styleUpdates) { 8012 if (!updatePayload) { 8013 updatePayload = []; 8014 } 8015 updatePayload.push(propKey, styleUpdates); 8016 } 8017 styleUpdates = nextProp; 8018 } 8019 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { 8020 var nextHtml = nextProp ? nextProp[HTML] : undefined; 8021 var lastHtml = lastProp ? lastProp[HTML] : undefined; 8022 if (nextHtml != null) { 8023 if (lastHtml !== nextHtml) { 8024 (updatePayload = updatePayload || []).push(propKey, '' + nextHtml); 8025 } 8026 } else { 8027 // TODO: It might be too late to clear this if we have children 8028 // inserted already. 8029 } 8030 } else if (propKey === CHILDREN) { 8031 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) { 8032 (updatePayload = updatePayload || []).push(propKey, '' + nextProp); 8033 } 8034 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) { 8035 // Noop 8036 } else if (registrationNameModules.hasOwnProperty(propKey)) { 8037 if (nextProp != null) { 8038 // We eagerly listen to this even though we haven't committed yet. 8039 if (true && typeof nextProp !== 'function') { 8040 warnForInvalidEventListener(propKey, nextProp); 8041 } 8042 ensureListeningTo(rootContainerElement, propKey); 8043 } 8044 if (!updatePayload && lastProp !== nextProp) { 8045 // This is a special case. If any listener updates we need to ensure 8046 // that the "current" props pointer gets updated so we need a commit 8047 // to update this element. 8048 updatePayload = []; 8049 } 8050 } else { 8051 // For any other property we always add it to the queue and then we 8052 // filter it out using the whitelist during the commit. 8053 (updatePayload = updatePayload || []).push(propKey, nextProp); 8054 } 8055 } 8056 if (styleUpdates) { 8057 { 8058 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE$1]); 8059 } 8060 (updatePayload = updatePayload || []).push(STYLE$1, styleUpdates); 8061 } 8062 return updatePayload; 8063 } 8064 8065 // Apply the diff. 8066 function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) { 8067 // Update checked *before* name. 8068 // In the middle of an update, it is possible to have multiple checked. 8069 // When a checked radio tries to change name, browser makes another radio's checked false. 8070 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) { 8071 updateChecked(domElement, nextRawProps); 8072 } 8073 8074 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps); 8075 var isCustomComponentTag = isCustomComponent(tag, nextRawProps); 8076 // Apply the diff. 8077 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag); 8078 8079 // TODO: Ensure that an update gets scheduled if any of the special props 8080 // changed. 8081 switch (tag) { 8082 case 'input': 8083 // Update the wrapper around inputs *after* updating props. This has to 8084 // happen after `updateDOMProperties`. Otherwise HTML5 input validations 8085 // raise warnings and prevent the new value from being assigned. 8086 updateWrapper(domElement, nextRawProps); 8087 break; 8088 case 'textarea': 8089 updateWrapper$1(domElement, nextRawProps); 8090 break; 8091 case 'select': 8092 // <select> value update needs to occur after <option> children 8093 // reconciliation 8094 postUpdateWrapper(domElement, nextRawProps); 8095 break; 8096 } 8097 } 8098 8099 function getPossibleStandardName(propName) { 8100 { 8101 var lowerCasedName = propName.toLowerCase(); 8102 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) { 8103 return null; 8104 } 8105 return possibleStandardNames[lowerCasedName] || null; 8106 } 8107 return null; 8108 } 8109 8110 function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement) { 8111 var isCustomComponentTag = void 0; 8112 var extraAttributeNames = void 0; 8113 8114 { 8115 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING$1] === true; 8116 isCustomComponentTag = isCustomComponent(tag, rawProps); 8117 validatePropertiesInDevelopment(tag, rawProps); 8118 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) { 8119 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component'); 8120 didWarnShadyDOM = true; 8121 } 8122 } 8123 8124 // TODO: Make sure that we check isMounted before firing any of these events. 8125 switch (tag) { 8126 case 'iframe': 8127 case 'object': 8128 trapBubbledEvent(TOP_LOAD, domElement); 8129 break; 8130 case 'video': 8131 case 'audio': 8132 // Create listener for each media event 8133 for (var i = 0; i < mediaEventTypes.length; i++) { 8134 trapBubbledEvent(mediaEventTypes[i], domElement); 8135 } 8136 break; 8137 case 'source': 8138 trapBubbledEvent(TOP_ERROR, domElement); 8139 break; 8140 case 'img': 8141 case 'image': 8142 case 'link': 8143 trapBubbledEvent(TOP_ERROR, domElement); 8144 trapBubbledEvent(TOP_LOAD, domElement); 8145 break; 8146 case 'form': 8147 trapBubbledEvent(TOP_RESET, domElement); 8148 trapBubbledEvent(TOP_SUBMIT, domElement); 8149 break; 8150 case 'details': 8151 trapBubbledEvent(TOP_TOGGLE, domElement); 8152 break; 8153 case 'input': 8154 initWrapperState(domElement, rawProps); 8155 trapBubbledEvent(TOP_INVALID, domElement); 8156 // For controlled components we always need to ensure we're listening 8157 // to onChange. Even if there is no listener. 8158 ensureListeningTo(rootContainerElement, 'onChange'); 8159 break; 8160 case 'option': 8161 validateProps(domElement, rawProps); 8162 break; 8163 case 'select': 8164 initWrapperState$1(domElement, rawProps); 8165 trapBubbledEvent(TOP_INVALID, domElement); 8166 // For controlled components we always need to ensure we're listening 8167 // to onChange. Even if there is no listener. 8168 ensureListeningTo(rootContainerElement, 'onChange'); 8169 break; 8170 case 'textarea': 8171 initWrapperState$2(domElement, rawProps); 8172 trapBubbledEvent(TOP_INVALID, domElement); 8173 // For controlled components we always need to ensure we're listening 8174 // to onChange. Even if there is no listener. 8175 ensureListeningTo(rootContainerElement, 'onChange'); 8176 break; 8177 } 8178 8179 assertValidProps(tag, rawProps); 8180 8181 { 8182 extraAttributeNames = new Set(); 8183 var attributes = domElement.attributes; 8184 for (var _i = 0; _i < attributes.length; _i++) { 8185 var name = attributes[_i].name.toLowerCase(); 8186 switch (name) { 8187 // Built-in SSR attribute is whitelisted 8188 case 'data-reactroot': 8189 break; 8190 // Controlled attributes are not validated 8191 // TODO: Only ignore them on controlled tags. 8192 case 'value': 8193 break; 8194 case 'checked': 8195 break; 8196 case 'selected': 8197 break; 8198 default: 8199 // Intentionally use the original name. 8200 // See discussion in https://github.com/facebook/react/pull/10676. 8201 extraAttributeNames.add(attributes[_i].name); 8202 } 8203 } 8204 } 8205 8206 var updatePayload = null; 8207 for (var propKey in rawProps) { 8208 if (!rawProps.hasOwnProperty(propKey)) { 8209 continue; 8210 } 8211 var nextProp = rawProps[propKey]; 8212 if (propKey === CHILDREN) { 8213 // For text content children we compare against textContent. This 8214 // might match additional HTML that is hidden when we read it using 8215 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still 8216 // satisfies our requirement. Our requirement is not to produce perfect 8217 // HTML and attributes. Ideally we should preserve structure but it's 8218 // ok not to if the visible content is still enough to indicate what 8219 // even listeners these nodes might be wired up to. 8220 // TODO: Warn if there is more than a single textNode as a child. 8221 // TODO: Should we use domElement.firstChild.nodeValue to compare? 8222 if (typeof nextProp === 'string') { 8223 if (domElement.textContent !== nextProp) { 8224 if (true && !suppressHydrationWarning) { 8225 warnForTextDifference(domElement.textContent, nextProp); 8226 } 8227 updatePayload = [CHILDREN, nextProp]; 8228 } 8229 } else if (typeof nextProp === 'number') { 8230 if (domElement.textContent !== '' + nextProp) { 8231 if (true && !suppressHydrationWarning) { 8232 warnForTextDifference(domElement.textContent, nextProp); 8233 } 8234 updatePayload = [CHILDREN, '' + nextProp]; 8235 } 8236 } 8237 } else if (registrationNameModules.hasOwnProperty(propKey)) { 8238 if (nextProp != null) { 8239 if (true && typeof nextProp !== 'function') { 8240 warnForInvalidEventListener(propKey, nextProp); 8241 } 8242 ensureListeningTo(rootContainerElement, propKey); 8243 } 8244 } else if (true && 8245 // Convince Flow we've calculated it (it's DEV-only in this method.) 8246 typeof isCustomComponentTag === 'boolean') { 8247 // Validate that the properties correspond to their expected values. 8248 var serverValue = void 0; 8249 var propertyInfo = getPropertyInfo(propKey); 8250 if (suppressHydrationWarning) { 8251 // Don't bother comparing. We're ignoring all these warnings. 8252 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1 || 8253 // Controlled attributes are not validated 8254 // TODO: Only ignore them on controlled tags. 8255 propKey === 'value' || propKey === 'checked' || propKey === 'selected') { 8256 // Noop 8257 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { 8258 var serverHTML = domElement.innerHTML; 8259 var nextHtml = nextProp ? nextProp[HTML] : undefined; 8260 var expectedHTML = normalizeHTML(domElement, nextHtml != null ? nextHtml : ''); 8261 if (expectedHTML !== serverHTML) { 8262 warnForPropDifference(propKey, serverHTML, expectedHTML); 8263 } 8264 } else if (propKey === STYLE$1) { 8265 // $FlowFixMe - Should be inferred as not undefined. 8266 extraAttributeNames.delete(propKey); 8267 8268 if (canDiffStyleForHydrationWarning) { 8269 var expectedStyle = createDangerousStringForStyles(nextProp); 8270 serverValue = domElement.getAttribute('style'); 8271 if (expectedStyle !== serverValue) { 8272 warnForPropDifference(propKey, serverValue, expectedStyle); 8273 } 8274 } 8275 } else if (isCustomComponentTag) { 8276 // $FlowFixMe - Should be inferred as not undefined. 8277 extraAttributeNames.delete(propKey.toLowerCase()); 8278 serverValue = getValueForAttribute(domElement, propKey, nextProp); 8279 8280 if (nextProp !== serverValue) { 8281 warnForPropDifference(propKey, serverValue, nextProp); 8282 } 8283 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) { 8284 var isMismatchDueToBadCasing = false; 8285 if (propertyInfo !== null) { 8286 // $FlowFixMe - Should be inferred as not undefined. 8287 extraAttributeNames.delete(propertyInfo.attributeName); 8288 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo); 8289 } else { 8290 var ownNamespace = parentNamespace; 8291 if (ownNamespace === HTML_NAMESPACE) { 8292 ownNamespace = getIntrinsicNamespace(tag); 8293 } 8294 if (ownNamespace === HTML_NAMESPACE) { 8295 // $FlowFixMe - Should be inferred as not undefined. 8296 extraAttributeNames.delete(propKey.toLowerCase()); 8297 } else { 8298 var standardName = getPossibleStandardName(propKey); 8299 if (standardName !== null && standardName !== propKey) { 8300 // If an SVG prop is supplied with bad casing, it will 8301 // be successfully parsed from HTML, but will produce a mismatch 8302 // (and would be incorrectly rendered on the client). 8303 // However, we already warn about bad casing elsewhere. 8304 // So we'll skip the misleading extra mismatch warning in this case. 8305 isMismatchDueToBadCasing = true; 8306 // $FlowFixMe - Should be inferred as not undefined. 8307 extraAttributeNames.delete(standardName); 8308 } 8309 // $FlowFixMe - Should be inferred as not undefined. 8310 extraAttributeNames.delete(propKey); 8311 } 8312 serverValue = getValueForAttribute(domElement, propKey, nextProp); 8313 } 8314 8315 if (nextProp !== serverValue && !isMismatchDueToBadCasing) { 8316 warnForPropDifference(propKey, serverValue, nextProp); 8317 } 8318 } 8319 } 8320 } 8321 8322 { 8323 // $FlowFixMe - Should be inferred as not undefined. 8324 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) { 8325 // $FlowFixMe - Should be inferred as not undefined. 8326 warnForExtraAttributes(extraAttributeNames); 8327 } 8328 } 8329 8330 switch (tag) { 8331 case 'input': 8332 // TODO: Make sure we check if this is still unmounted or do any clean 8333 // up necessary since we never stop tracking anymore. 8334 track(domElement); 8335 postMountWrapper(domElement, rawProps, true); 8336 break; 8337 case 'textarea': 8338 // TODO: Make sure we check if this is still unmounted or do any clean 8339 // up necessary since we never stop tracking anymore. 8340 track(domElement); 8341 postMountWrapper$3(domElement, rawProps); 8342 break; 8343 case 'select': 8344 case 'option': 8345 // For input and textarea we current always set the value property at 8346 // post mount to force it to diverge from attributes. However, for 8347 // option and select we don't quite do the same thing and select 8348 // is not resilient to the DOM state changing so we don't do that here. 8349 // TODO: Consider not doing this for input and textarea. 8350 break; 8351 default: 8352 if (typeof rawProps.onClick === 'function') { 8353 // TODO: This cast may not be sound for SVG, MathML or custom elements. 8354 trapClickOnNonInteractiveElement(domElement); 8355 } 8356 break; 8357 } 8358 8359 return updatePayload; 8360 } 8361 8362 function diffHydratedText(textNode, text) { 8363 var isDifferent = textNode.nodeValue !== text; 8364 return isDifferent; 8365 } 8366 8367 function warnForUnmatchedText(textNode, text) { 8368 { 8369 warnForTextDifference(textNode.nodeValue, text); 8370 } 8371 } 8372 8373 function warnForDeletedHydratableElement(parentNode, child) { 8374 { 8375 if (didWarnInvalidHydration) { 8376 return; 8377 } 8378 didWarnInvalidHydration = true; 8379 warningWithoutStack$1(false, 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase()); 8380 } 8381 } 8382 8383 function warnForDeletedHydratableText(parentNode, child) { 8384 { 8385 if (didWarnInvalidHydration) { 8386 return; 8387 } 8388 didWarnInvalidHydration = true; 8389 warningWithoutStack$1(false, 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase()); 8390 } 8391 } 8392 8393 function warnForInsertedHydratedElement(parentNode, tag, props) { 8394 { 8395 if (didWarnInvalidHydration) { 8396 return; 8397 } 8398 didWarnInvalidHydration = true; 8399 warningWithoutStack$1(false, 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase()); 8400 } 8401 } 8402 8403 function warnForInsertedHydratedText(parentNode, text) { 8404 { 8405 if (text === '') { 8406 // We expect to insert empty text nodes since they're not represented in 8407 // the HTML. 8408 // TODO: Remove this special case if we can just avoid inserting empty 8409 // text nodes. 8410 return; 8411 } 8412 if (didWarnInvalidHydration) { 8413 return; 8414 } 8415 didWarnInvalidHydration = true; 8416 warningWithoutStack$1(false, 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase()); 8417 } 8418 } 8419 8420 function restoreControlledState$1(domElement, tag, props) { 8421 switch (tag) { 8422 case 'input': 8423 restoreControlledState(domElement, props); 8424 return; 8425 case 'textarea': 8426 restoreControlledState$3(domElement, props); 8427 return; 8428 case 'select': 8429 restoreControlledState$2(domElement, props); 8430 return; 8431 } 8432 } 8433 8434 // TODO: direct imports like some-package/src/* are bad. Fix me. 8435 var validateDOMNesting = function () {}; 8436 var updatedAncestorInfo = function () {}; 8437 8438 { 8439 // This validation code was written based on the HTML5 parsing spec: 8440 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope 8441 // 8442 // Note: this does not catch all invalid nesting, nor does it try to (as it's 8443 // not clear what practical benefit doing so provides); instead, we warn only 8444 // for cases where the parser will give a parse tree differing from what React 8445 // intended. For example, <b><div></div></b> is invalid but we don't warn 8446 // because it still parses correctly; we do warn for other cases like nested 8447 // <p> tags where the beginning of the second element implicitly closes the 8448 // first, causing a confusing mess. 8449 8450 // https://html.spec.whatwg.org/multipage/syntax.html#special 8451 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']; 8452 8453 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope 8454 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', 8455 8456 // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point 8457 // TODO: Distinguish by namespace here -- for <title>, including it here 8458 // errs on the side of fewer warnings 8459 'foreignObject', 'desc', 'title']; 8460 8461 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope 8462 var buttonScopeTags = inScopeTags.concat(['button']); 8463 8464 // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags 8465 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt']; 8466 8467 var emptyAncestorInfo = { 8468 current: null, 8469 8470 formTag: null, 8471 aTagInScope: null, 8472 buttonTagInScope: null, 8473 nobrTagInScope: null, 8474 pTagInButtonScope: null, 8475 8476 listItemTagAutoclosing: null, 8477 dlItemTagAutoclosing: null 8478 }; 8479 8480 updatedAncestorInfo = function (oldInfo, tag) { 8481 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo); 8482 var info = { tag: tag }; 8483 8484 if (inScopeTags.indexOf(tag) !== -1) { 8485 ancestorInfo.aTagInScope = null; 8486 ancestorInfo.buttonTagInScope = null; 8487 ancestorInfo.nobrTagInScope = null; 8488 } 8489 if (buttonScopeTags.indexOf(tag) !== -1) { 8490 ancestorInfo.pTagInButtonScope = null; 8491 } 8492 8493 // See rules for 'li', 'dd', 'dt' start tags in 8494 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody 8495 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') { 8496 ancestorInfo.listItemTagAutoclosing = null; 8497 ancestorInfo.dlItemTagAutoclosing = null; 8498 } 8499 8500 ancestorInfo.current = info; 8501 8502 if (tag === 'form') { 8503 ancestorInfo.formTag = info; 8504 } 8505 if (tag === 'a') { 8506 ancestorInfo.aTagInScope = info; 8507 } 8508 if (tag === 'button') { 8509 ancestorInfo.buttonTagInScope = info; 8510 } 8511 if (tag === 'nobr') { 8512 ancestorInfo.nobrTagInScope = info; 8513 } 8514 if (tag === 'p') { 8515 ancestorInfo.pTagInButtonScope = info; 8516 } 8517 if (tag === 'li') { 8518 ancestorInfo.listItemTagAutoclosing = info; 8519 } 8520 if (tag === 'dd' || tag === 'dt') { 8521 ancestorInfo.dlItemTagAutoclosing = info; 8522 } 8523 8524 return ancestorInfo; 8525 }; 8526 8527 /** 8528 * Returns whether 8529 */ 8530 var isTagValidWithParent = function (tag, parentTag) { 8531 // First, let's check if we're in an unusual parsing mode... 8532 switch (parentTag) { 8533 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect 8534 case 'select': 8535 return tag === 'option' || tag === 'optgroup' || tag === '#text'; 8536 case 'optgroup': 8537 return tag === 'option' || tag === '#text'; 8538 // Strictly speaking, seeing an <option> doesn't mean we're in a <select> 8539 // but 8540 case 'option': 8541 return tag === '#text'; 8542 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd 8543 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption 8544 // No special behavior since these rules fall back to "in body" mode for 8545 // all except special table nodes which cause bad parsing behavior anyway. 8546 8547 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr 8548 case 'tr': 8549 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template'; 8550 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody 8551 case 'tbody': 8552 case 'thead': 8553 case 'tfoot': 8554 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template'; 8555 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup 8556 case 'colgroup': 8557 return tag === 'col' || tag === 'template'; 8558 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable 8559 case 'table': 8560 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template'; 8561 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead 8562 case 'head': 8563 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template'; 8564 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element 8565 case 'html': 8566 return tag === 'head' || tag === 'body'; 8567 case '#document': 8568 return tag === 'html'; 8569 } 8570 8571 // Probably in the "in body" parsing mode, so we outlaw only tag combos 8572 // where the parsing rules cause implicit opens or closes to be added. 8573 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody 8574 switch (tag) { 8575 case 'h1': 8576 case 'h2': 8577 case 'h3': 8578 case 'h4': 8579 case 'h5': 8580 case 'h6': 8581 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6'; 8582 8583 case 'rp': 8584 case 'rt': 8585 return impliedEndTags.indexOf(parentTag) === -1; 8586 8587 case 'body': 8588 case 'caption': 8589 case 'col': 8590 case 'colgroup': 8591 case 'frame': 8592 case 'head': 8593 case 'html': 8594 case 'tbody': 8595 case 'td': 8596 case 'tfoot': 8597 case 'th': 8598 case 'thead': 8599 case 'tr': 8600 // These tags are only valid with a few parents that have special child 8601 // parsing rules -- if we're down here, then none of those matched and 8602 // so we allow it only if we don't know what the parent is, as all other 8603 // cases are invalid. 8604 return parentTag == null; 8605 } 8606 8607 return true; 8608 }; 8609 8610 /** 8611 * Returns whether 8612 */ 8613 var findInvalidAncestorForTag = function (tag, ancestorInfo) { 8614 switch (tag) { 8615 case 'address': 8616 case 'article': 8617 case 'aside': 8618 case 'blockquote': 8619 case 'center': 8620 case 'details': 8621 case 'dialog': 8622 case 'dir': 8623 case 'div': 8624 case 'dl': 8625 case 'fieldset': 8626 case 'figcaption': 8627 case 'figure': 8628 case 'footer': 8629 case 'header': 8630 case 'hgroup': 8631 case 'main': 8632 case 'menu': 8633 case 'nav': 8634 case 'ol': 8635 case 'p': 8636 case 'section': 8637 case 'summary': 8638 case 'ul': 8639 case 'pre': 8640 case 'listing': 8641 case 'table': 8642 case 'hr': 8643 case 'xmp': 8644 case 'h1': 8645 case 'h2': 8646 case 'h3': 8647 case 'h4': 8648 case 'h5': 8649 case 'h6': 8650 return ancestorInfo.pTagInButtonScope; 8651 8652 case 'form': 8653 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope; 8654 8655 case 'li': 8656 return ancestorInfo.listItemTagAutoclosing; 8657 8658 case 'dd': 8659 case 'dt': 8660 return ancestorInfo.dlItemTagAutoclosing; 8661 8662 case 'button': 8663 return ancestorInfo.buttonTagInScope; 8664 8665 case 'a': 8666 // Spec says something about storing a list of markers, but it sounds 8667 // equivalent to this check. 8668 return ancestorInfo.aTagInScope; 8669 8670 case 'nobr': 8671 return ancestorInfo.nobrTagInScope; 8672 } 8673 8674 return null; 8675 }; 8676 8677 var didWarn = {}; 8678 8679 validateDOMNesting = function (childTag, childText, ancestorInfo) { 8680 ancestorInfo = ancestorInfo || emptyAncestorInfo; 8681 var parentInfo = ancestorInfo.current; 8682 var parentTag = parentInfo && parentInfo.tag; 8683 8684 if (childText != null) { 8685 !(childTag == null) ? warningWithoutStack$1(false, 'validateDOMNesting: when childText is passed, childTag should be null') : void 0; 8686 childTag = '#text'; 8687 } 8688 8689 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo; 8690 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo); 8691 var invalidParentOrAncestor = invalidParent || invalidAncestor; 8692 if (!invalidParentOrAncestor) { 8693 return; 8694 } 8695 8696 var ancestorTag = invalidParentOrAncestor.tag; 8697 var addendum = getCurrentFiberStackInDev(); 8698 8699 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum; 8700 if (didWarn[warnKey]) { 8701 return; 8702 } 8703 didWarn[warnKey] = true; 8704 8705 var tagDisplayName = childTag; 8706 var whitespaceInfo = ''; 8707 if (childTag === '#text') { 8708 if (/\S/.test(childText)) { 8709 tagDisplayName = 'Text nodes'; 8710 } else { 8711 tagDisplayName = 'Whitespace text nodes'; 8712 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.'; 8713 } 8714 } else { 8715 tagDisplayName = '<' + childTag + '>'; 8716 } 8717 8718 if (invalidParent) { 8719 var info = ''; 8720 if (ancestorTag === 'table' && childTag === 'tr') { 8721 info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.'; 8722 } 8723 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info, addendum); 8724 } else { 8725 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.%s', tagDisplayName, ancestorTag, addendum); 8726 } 8727 }; 8728 } 8729 8730 var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; 8731 8732 var _ReactInternals$Sched = ReactInternals$1.Scheduler; 8733 var unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback; 8734 var unstable_now = _ReactInternals$Sched.unstable_now; 8735 var unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback; 8736 var unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield; 8737 var unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode; 8738 var unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority; 8739 var unstable_next = _ReactInternals$Sched.unstable_next; 8740 var unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution; 8741 var unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution; 8742 var unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel; 8743 var unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority; 8744 var unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority; 8745 var unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority; 8746 var unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority; 8747 var unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority; 8748 8749 // Renderers that don't support persistence 8750 // can re-export everything from this module. 8751 8752 function shim() { 8753 invariant(false, 'The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue.'); 8754 } 8755 8756 // Persistence (when unsupported) 8757 var supportsPersistence = false; 8758 var cloneInstance = shim; 8759 var createContainerChildSet = shim; 8760 var appendChildToContainerChildSet = shim; 8761 var finalizeContainerChildren = shim; 8762 var replaceContainerChildren = shim; 8763 var cloneHiddenInstance = shim; 8764 var cloneUnhiddenInstance = shim; 8765 var createHiddenTextInstance = shim; 8766 8767 var SUPPRESS_HYDRATION_WARNING = void 0; 8768 { 8769 SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning'; 8770 } 8771 8772 var SUSPENSE_START_DATA = '$'; 8773 var SUSPENSE_END_DATA = '/$'; 8774 8775 var STYLE = 'style'; 8776 8777 var eventsEnabled = null; 8778 var selectionInformation = null; 8779 8780 function shouldAutoFocusHostComponent(type, props) { 8781 switch (type) { 8782 case 'button': 8783 case 'input': 8784 case 'select': 8785 case 'textarea': 8786 return !!props.autoFocus; 8787 } 8788 return false; 8789 } 8790 8791 function getRootHostContext(rootContainerInstance) { 8792 var type = void 0; 8793 var namespace = void 0; 8794 var nodeType = rootContainerInstance.nodeType; 8795 switch (nodeType) { 8796 case DOCUMENT_NODE: 8797 case DOCUMENT_FRAGMENT_NODE: 8798 { 8799 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment'; 8800 var root = rootContainerInstance.documentElement; 8801 namespace = root ? root.namespaceURI : getChildNamespace(null, ''); 8802 break; 8803 } 8804 default: 8805 { 8806 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance; 8807 var ownNamespace = container.namespaceURI || null; 8808 type = container.tagName; 8809 namespace = getChildNamespace(ownNamespace, type); 8810 break; 8811 } 8812 } 8813 { 8814 var validatedTag = type.toLowerCase(); 8815 var _ancestorInfo = updatedAncestorInfo(null, validatedTag); 8816 return { namespace: namespace, ancestorInfo: _ancestorInfo }; 8817 } 8818 return namespace; 8819 } 8820 8821 function getChildHostContext(parentHostContext, type, rootContainerInstance) { 8822 { 8823 var parentHostContextDev = parentHostContext; 8824 var _namespace = getChildNamespace(parentHostContextDev.namespace, type); 8825 var _ancestorInfo2 = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type); 8826 return { namespace: _namespace, ancestorInfo: _ancestorInfo2 }; 8827 } 8828 var parentNamespace = parentHostContext; 8829 return getChildNamespace(parentNamespace, type); 8830 } 8831 8832 function getPublicInstance(instance) { 8833 return instance; 8834 } 8835 8836 function prepareForCommit(containerInfo) { 8837 eventsEnabled = isEnabled(); 8838 selectionInformation = getSelectionInformation(); 8839 setEnabled(false); 8840 } 8841 8842 function resetAfterCommit(containerInfo) { 8843 restoreSelection(selectionInformation); 8844 selectionInformation = null; 8845 setEnabled(eventsEnabled); 8846 eventsEnabled = null; 8847 } 8848 8849 function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) { 8850 var parentNamespace = void 0; 8851 { 8852 // TODO: take namespace into account when validating. 8853 var hostContextDev = hostContext; 8854 validateDOMNesting(type, null, hostContextDev.ancestorInfo); 8855 if (typeof props.children === 'string' || typeof props.children === 'number') { 8856 var string = '' + props.children; 8857 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type); 8858 validateDOMNesting(null, string, ownAncestorInfo); 8859 } 8860 parentNamespace = hostContextDev.namespace; 8861 } 8862 var domElement = createElement(type, props, rootContainerInstance, parentNamespace); 8863 precacheFiberNode(internalInstanceHandle, domElement); 8864 updateFiberProps(domElement, props); 8865 return domElement; 8866 } 8867 8868 function appendInitialChild(parentInstance, child) { 8869 parentInstance.appendChild(child); 8870 } 8871 8872 function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) { 8873 setInitialProperties(domElement, type, props, rootContainerInstance); 8874 return shouldAutoFocusHostComponent(type, props); 8875 } 8876 8877 function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) { 8878 { 8879 var hostContextDev = hostContext; 8880 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) { 8881 var string = '' + newProps.children; 8882 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type); 8883 validateDOMNesting(null, string, ownAncestorInfo); 8884 } 8885 } 8886 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance); 8887 } 8888 8889 function shouldSetTextContent(type, props) { 8890 return type === 'textarea' || type === 'option' || type === 'noscript' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && props.dangerouslySetInnerHTML.__html != null; 8891 } 8892 8893 function shouldDeprioritizeSubtree(type, props) { 8894 return !!props.hidden; 8895 } 8896 8897 function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) { 8898 { 8899 var hostContextDev = hostContext; 8900 validateDOMNesting(null, text, hostContextDev.ancestorInfo); 8901 } 8902 var textNode = createTextNode(text, rootContainerInstance); 8903 precacheFiberNode(internalInstanceHandle, textNode); 8904 return textNode; 8905 } 8906 8907 var isPrimaryRenderer = true; 8908 // This initialization code may run even on server environments 8909 // if a component just imports ReactDOM (e.g. for findDOMNode). 8910 // Some environments might not have setTimeout or clearTimeout. 8911 var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined; 8912 var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined; 8913 var noTimeout = -1; 8914 var schedulePassiveEffects = unstable_scheduleCallback; 8915 var cancelPassiveEffects = unstable_cancelCallback; 8916 8917 // ------------------- 8918 // Mutation 8919 // ------------------- 8920 8921 var supportsMutation = true; 8922 8923 function commitMount(domElement, type, newProps, internalInstanceHandle) { 8924 // Despite the naming that might imply otherwise, this method only 8925 // fires if there is an `Update` effect scheduled during mounting. 8926 // This happens if `finalizeInitialChildren` returns `true` (which it 8927 // does to implement the `autoFocus` attribute on the client). But 8928 // there are also other cases when this might happen (such as patching 8929 // up text content during hydration mismatch). So we'll check this again. 8930 if (shouldAutoFocusHostComponent(type, newProps)) { 8931 domElement.focus(); 8932 } 8933 } 8934 8935 function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) { 8936 // Update the props handle so that we know which props are the ones with 8937 // with current event handlers. 8938 updateFiberProps(domElement, newProps); 8939 // Apply the diff to the DOM node. 8940 updateProperties(domElement, updatePayload, type, oldProps, newProps); 8941 } 8942 8943 function resetTextContent(domElement) { 8944 setTextContent(domElement, ''); 8945 } 8946 8947 function commitTextUpdate(textInstance, oldText, newText) { 8948 textInstance.nodeValue = newText; 8949 } 8950 8951 function appendChild(parentInstance, child) { 8952 parentInstance.appendChild(child); 8953 } 8954 8955 function appendChildToContainer(container, child) { 8956 var parentNode = void 0; 8957 if (container.nodeType === COMMENT_NODE) { 8958 parentNode = container.parentNode; 8959 parentNode.insertBefore(child, container); 8960 } else { 8961 parentNode = container; 8962 parentNode.appendChild(child); 8963 } 8964 // This container might be used for a portal. 8965 // If something inside a portal is clicked, that click should bubble 8966 // through the React tree. However, on Mobile Safari the click would 8967 // never bubble through the *DOM* tree unless an ancestor with onclick 8968 // event exists. So we wouldn't see it and dispatch it. 8969 // This is why we ensure that non React root containers have inline onclick 8970 // defined. 8971 // https://github.com/facebook/react/issues/11918 8972 var reactRootContainer = container._reactRootContainer; 8973 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) { 8974 // TODO: This cast may not be sound for SVG, MathML or custom elements. 8975 trapClickOnNonInteractiveElement(parentNode); 8976 } 8977 } 8978 8979 function insertBefore(parentInstance, child, beforeChild) { 8980 parentInstance.insertBefore(child, beforeChild); 8981 } 8982 8983 function insertInContainerBefore(container, child, beforeChild) { 8984 if (container.nodeType === COMMENT_NODE) { 8985 container.parentNode.insertBefore(child, beforeChild); 8986 } else { 8987 container.insertBefore(child, beforeChild); 8988 } 8989 } 8990 8991 function removeChild(parentInstance, child) { 8992 parentInstance.removeChild(child); 8993 } 8994 8995 function removeChildFromContainer(container, child) { 8996 if (container.nodeType === COMMENT_NODE) { 8997 container.parentNode.removeChild(child); 8998 } else { 8999 container.removeChild(child); 9000 } 9001 } 9002 9003 function clearSuspenseBoundary(parentInstance, suspenseInstance) { 9004 var node = suspenseInstance; 9005 // Delete all nodes within this suspense boundary. 9006 // There might be nested nodes so we need to keep track of how 9007 // deep we are and only break out when we're back on top. 9008 var depth = 0; 9009 do { 9010 var nextNode = node.nextSibling; 9011 parentInstance.removeChild(node); 9012 if (nextNode && nextNode.nodeType === COMMENT_NODE) { 9013 var data = nextNode.data; 9014 if (data === SUSPENSE_END_DATA) { 9015 if (depth === 0) { 9016 parentInstance.removeChild(nextNode); 9017 return; 9018 } else { 9019 depth--; 9020 } 9021 } else if (data === SUSPENSE_START_DATA) { 9022 depth++; 9023 } 9024 } 9025 node = nextNode; 9026 } while (node); 9027 // TODO: Warn, we didn't find the end comment boundary. 9028 } 9029 9030 function clearSuspenseBoundaryFromContainer(container, suspenseInstance) { 9031 if (container.nodeType === COMMENT_NODE) { 9032 clearSuspenseBoundary(container.parentNode, suspenseInstance); 9033 } else if (container.nodeType === ELEMENT_NODE) { 9034 clearSuspenseBoundary(container, suspenseInstance); 9035 } else { 9036 // Document nodes should never contain suspense boundaries. 9037 } 9038 } 9039 9040 function hideInstance(instance) { 9041 // TODO: Does this work for all element types? What about MathML? Should we 9042 // pass host context to this method? 9043 instance = instance; 9044 instance.style.display = 'none'; 9045 } 9046 9047 function hideTextInstance(textInstance) { 9048 textInstance.nodeValue = ''; 9049 } 9050 9051 function unhideInstance(instance, props) { 9052 instance = instance; 9053 var styleProp = props[STYLE]; 9054 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null; 9055 instance.style.display = dangerousStyleValue('display', display); 9056 } 9057 9058 function unhideTextInstance(textInstance, text) { 9059 textInstance.nodeValue = text; 9060 } 9061 9062 // ------------------- 9063 // Hydration 9064 // ------------------- 9065 9066 var supportsHydration = true; 9067 9068 function canHydrateInstance(instance, type, props) { 9069 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) { 9070 return null; 9071 } 9072 // This has now been refined to an element node. 9073 return instance; 9074 } 9075 9076 function canHydrateTextInstance(instance, text) { 9077 if (text === '' || instance.nodeType !== TEXT_NODE) { 9078 // Empty strings are not parsed by HTML so there won't be a correct match here. 9079 return null; 9080 } 9081 // This has now been refined to a text node. 9082 return instance; 9083 } 9084 9085 function canHydrateSuspenseInstance(instance) { 9086 if (instance.nodeType !== COMMENT_NODE) { 9087 // Empty strings are not parsed by HTML so there won't be a correct match here. 9088 return null; 9089 } 9090 // This has now been refined to a suspense node. 9091 return instance; 9092 } 9093 9094 function getNextHydratableSibling(instance) { 9095 var node = instance.nextSibling; 9096 // Skip non-hydratable nodes. 9097 while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE && (!enableSuspenseServerRenderer || node.nodeType !== COMMENT_NODE || node.data !== SUSPENSE_START_DATA)) { 9098 node = node.nextSibling; 9099 } 9100 return node; 9101 } 9102 9103 function getFirstHydratableChild(parentInstance) { 9104 var next = parentInstance.firstChild; 9105 // Skip non-hydratable nodes. 9106 while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE && (!enableSuspenseServerRenderer || next.nodeType !== COMMENT_NODE || next.data !== SUSPENSE_START_DATA)) { 9107 next = next.nextSibling; 9108 } 9109 return next; 9110 } 9111 9112 function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) { 9113 precacheFiberNode(internalInstanceHandle, instance); 9114 // TODO: Possibly defer this until the commit phase where all the events 9115 // get attached. 9116 updateFiberProps(instance, props); 9117 var parentNamespace = void 0; 9118 { 9119 var hostContextDev = hostContext; 9120 parentNamespace = hostContextDev.namespace; 9121 } 9122 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance); 9123 } 9124 9125 function hydrateTextInstance(textInstance, text, internalInstanceHandle) { 9126 precacheFiberNode(internalInstanceHandle, textInstance); 9127 return diffHydratedText(textInstance, text); 9128 } 9129 9130 function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) { 9131 var node = suspenseInstance.nextSibling; 9132 // Skip past all nodes within this suspense boundary. 9133 // There might be nested nodes so we need to keep track of how 9134 // deep we are and only break out when we're back on top. 9135 var depth = 0; 9136 while (node) { 9137 if (node.nodeType === COMMENT_NODE) { 9138 var data = node.data; 9139 if (data === SUSPENSE_END_DATA) { 9140 if (depth === 0) { 9141 return getNextHydratableSibling(node); 9142 } else { 9143 depth--; 9144 } 9145 } else if (data === SUSPENSE_START_DATA) { 9146 depth++; 9147 } 9148 } 9149 node = node.nextSibling; 9150 } 9151 // TODO: Warn, we didn't find the end comment boundary. 9152 return null; 9153 } 9154 9155 function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) { 9156 { 9157 warnForUnmatchedText(textInstance, text); 9158 } 9159 } 9160 9161 function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text) { 9162 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) { 9163 warnForUnmatchedText(textInstance, text); 9164 } 9165 } 9166 9167 function didNotHydrateContainerInstance(parentContainer, instance) { 9168 { 9169 if (instance.nodeType === ELEMENT_NODE) { 9170 warnForDeletedHydratableElement(parentContainer, instance); 9171 } else if (instance.nodeType === COMMENT_NODE) { 9172 // TODO: warnForDeletedHydratableSuspenseBoundary 9173 } else { 9174 warnForDeletedHydratableText(parentContainer, instance); 9175 } 9176 } 9177 } 9178 9179 function didNotHydrateInstance(parentType, parentProps, parentInstance, instance) { 9180 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) { 9181 if (instance.nodeType === ELEMENT_NODE) { 9182 warnForDeletedHydratableElement(parentInstance, instance); 9183 } else if (instance.nodeType === COMMENT_NODE) { 9184 // TODO: warnForDeletedHydratableSuspenseBoundary 9185 } else { 9186 warnForDeletedHydratableText(parentInstance, instance); 9187 } 9188 } 9189 } 9190 9191 function didNotFindHydratableContainerInstance(parentContainer, type, props) { 9192 { 9193 warnForInsertedHydratedElement(parentContainer, type, props); 9194 } 9195 } 9196 9197 function didNotFindHydratableContainerTextInstance(parentContainer, text) { 9198 { 9199 warnForInsertedHydratedText(parentContainer, text); 9200 } 9201 } 9202 9203 9204 9205 function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) { 9206 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) { 9207 warnForInsertedHydratedElement(parentInstance, type, props); 9208 } 9209 } 9210 9211 function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) { 9212 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) { 9213 warnForInsertedHydratedText(parentInstance, text); 9214 } 9215 } 9216 9217 function didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) { 9218 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) { 9219 // TODO: warnForInsertedHydratedSuspense(parentInstance); 9220 } 9221 } 9222 9223 // Prefix measurements so that it's possible to filter them. 9224 // Longer prefixes are hard to read in DevTools. 9225 var reactEmoji = '\u269B'; 9226 var warningEmoji = '\u26D4'; 9227 var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function'; 9228 9229 // Keep track of current fiber so that we know the path to unwind on pause. 9230 // TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them? 9231 var currentFiber = null; 9232 // If we're in the middle of user code, which fiber and method is it? 9233 // Reusing `currentFiber` would be confusing for this because user code fiber 9234 // can change during commit phase too, but we don't need to unwind it (since 9235 // lifecycles in the commit phase don't resemble a tree). 9236 var currentPhase = null; 9237 var currentPhaseFiber = null; 9238 // Did lifecycle hook schedule an update? This is often a performance problem, 9239 // so we will keep track of it, and include it in the report. 9240 // Track commits caused by cascading updates. 9241 var isCommitting = false; 9242 var hasScheduledUpdateInCurrentCommit = false; 9243 var hasScheduledUpdateInCurrentPhase = false; 9244 var commitCountInCurrentWorkLoop = 0; 9245 var effectCountInCurrentCommit = 0; 9246 var isWaitingForCallback = false; 9247 // During commits, we only show a measurement once per method name 9248 // to avoid stretch the commit phase with measurement overhead. 9249 var labelsInCurrentCommit = new Set(); 9250 9251 var formatMarkName = function (markName) { 9252 return reactEmoji + ' ' + markName; 9253 }; 9254 9255 var formatLabel = function (label, warning) { 9256 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' '; 9257 var suffix = warning ? ' Warning: ' + warning : ''; 9258 return '' + prefix + label + suffix; 9259 }; 9260 9261 var beginMark = function (markName) { 9262 performance.mark(formatMarkName(markName)); 9263 }; 9264 9265 var clearMark = function (markName) { 9266 performance.clearMarks(formatMarkName(markName)); 9267 }; 9268 9269 var endMark = function (label, markName, warning) { 9270 var formattedMarkName = formatMarkName(markName); 9271 var formattedLabel = formatLabel(label, warning); 9272 try { 9273 performance.measure(formattedLabel, formattedMarkName); 9274 } catch (err) {} 9275 // If previous mark was missing for some reason, this will throw. 9276 // This could only happen if React crashed in an unexpected place earlier. 9277 // Don't pile on with more errors. 9278 9279 // Clear marks immediately to avoid growing buffer. 9280 performance.clearMarks(formattedMarkName); 9281 performance.clearMeasures(formattedLabel); 9282 }; 9283 9284 var getFiberMarkName = function (label, debugID) { 9285 return label + ' (#' + debugID + ')'; 9286 }; 9287 9288 var getFiberLabel = function (componentName, isMounted, phase) { 9289 if (phase === null) { 9290 // These are composite component total time measurements. 9291 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']'; 9292 } else { 9293 // Composite component methods. 9294 return componentName + '.' + phase; 9295 } 9296 }; 9297 9298 var beginFiberMark = function (fiber, phase) { 9299 var componentName = getComponentName(fiber.type) || 'Unknown'; 9300 var debugID = fiber._debugID; 9301 var isMounted = fiber.alternate !== null; 9302 var label = getFiberLabel(componentName, isMounted, phase); 9303 9304 if (isCommitting && labelsInCurrentCommit.has(label)) { 9305 // During the commit phase, we don't show duplicate labels because 9306 // there is a fixed overhead for every measurement, and we don't 9307 // want to stretch the commit phase beyond necessary. 9308 return false; 9309 } 9310 labelsInCurrentCommit.add(label); 9311 9312 var markName = getFiberMarkName(label, debugID); 9313 beginMark(markName); 9314 return true; 9315 }; 9316 9317 var clearFiberMark = function (fiber, phase) { 9318 var componentName = getComponentName(fiber.type) || 'Unknown'; 9319 var debugID = fiber._debugID; 9320 var isMounted = fiber.alternate !== null; 9321 var label = getFiberLabel(componentName, isMounted, phase); 9322 var markName = getFiberMarkName(label, debugID); 9323 clearMark(markName); 9324 }; 9325 9326 var endFiberMark = function (fiber, phase, warning) { 9327 var componentName = getComponentName(fiber.type) || 'Unknown'; 9328 var debugID = fiber._debugID; 9329 var isMounted = fiber.alternate !== null; 9330 var label = getFiberLabel(componentName, isMounted, phase); 9331 var markName = getFiberMarkName(label, debugID); 9332 endMark(label, markName, warning); 9333 }; 9334 9335 var shouldIgnoreFiber = function (fiber) { 9336 // Host components should be skipped in the timeline. 9337 // We could check typeof fiber.type, but does this work with RN? 9338 switch (fiber.tag) { 9339 case HostRoot: 9340 case HostComponent: 9341 case HostText: 9342 case HostPortal: 9343 case Fragment: 9344 case ContextProvider: 9345 case ContextConsumer: 9346 case Mode: 9347 return true; 9348 default: 9349 return false; 9350 } 9351 }; 9352 9353 var clearPendingPhaseMeasurement = function () { 9354 if (currentPhase !== null && currentPhaseFiber !== null) { 9355 clearFiberMark(currentPhaseFiber, currentPhase); 9356 } 9357 currentPhaseFiber = null; 9358 currentPhase = null; 9359 hasScheduledUpdateInCurrentPhase = false; 9360 }; 9361 9362 var pauseTimers = function () { 9363 // Stops all currently active measurements so that they can be resumed 9364 // if we continue in a later deferred loop from the same unit of work. 9365 var fiber = currentFiber; 9366 while (fiber) { 9367 if (fiber._debugIsCurrentlyTiming) { 9368 endFiberMark(fiber, null, null); 9369 } 9370 fiber = fiber.return; 9371 } 9372 }; 9373 9374 var resumeTimersRecursively = function (fiber) { 9375 if (fiber.return !== null) { 9376 resumeTimersRecursively(fiber.return); 9377 } 9378 if (fiber._debugIsCurrentlyTiming) { 9379 beginFiberMark(fiber, null); 9380 } 9381 }; 9382 9383 var resumeTimers = function () { 9384 // Resumes all measurements that were active during the last deferred loop. 9385 if (currentFiber !== null) { 9386 resumeTimersRecursively(currentFiber); 9387 } 9388 }; 9389 9390 function recordEffect() { 9391 if (enableUserTimingAPI) { 9392 effectCountInCurrentCommit++; 9393 } 9394 } 9395 9396 function recordScheduleUpdate() { 9397 if (enableUserTimingAPI) { 9398 if (isCommitting) { 9399 hasScheduledUpdateInCurrentCommit = true; 9400 } 9401 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') { 9402 hasScheduledUpdateInCurrentPhase = true; 9403 } 9404 } 9405 } 9406 9407 function startRequestCallbackTimer() { 9408 if (enableUserTimingAPI) { 9409 if (supportsUserTiming && !isWaitingForCallback) { 9410 isWaitingForCallback = true; 9411 beginMark('(Waiting for async callback...)'); 9412 } 9413 } 9414 } 9415 9416 function stopRequestCallbackTimer(didExpire, expirationTime) { 9417 if (enableUserTimingAPI) { 9418 if (supportsUserTiming) { 9419 isWaitingForCallback = false; 9420 var warning = didExpire ? 'React was blocked by main thread' : null; 9421 endMark('(Waiting for async callback... will force flush in ' + expirationTime + ' ms)', '(Waiting for async callback...)', warning); 9422 } 9423 } 9424 } 9425 9426 function startWorkTimer(fiber) { 9427 if (enableUserTimingAPI) { 9428 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { 9429 return; 9430 } 9431 // If we pause, this is the fiber to unwind from. 9432 currentFiber = fiber; 9433 if (!beginFiberMark(fiber, null)) { 9434 return; 9435 } 9436 fiber._debugIsCurrentlyTiming = true; 9437 } 9438 } 9439 9440 function cancelWorkTimer(fiber) { 9441 if (enableUserTimingAPI) { 9442 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { 9443 return; 9444 } 9445 // Remember we shouldn't complete measurement for this fiber. 9446 // Otherwise flamechart will be deep even for small updates. 9447 fiber._debugIsCurrentlyTiming = false; 9448 clearFiberMark(fiber, null); 9449 } 9450 } 9451 9452 function stopWorkTimer(fiber) { 9453 if (enableUserTimingAPI) { 9454 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { 9455 return; 9456 } 9457 // If we pause, its parent is the fiber to unwind from. 9458 currentFiber = fiber.return; 9459 if (!fiber._debugIsCurrentlyTiming) { 9460 return; 9461 } 9462 fiber._debugIsCurrentlyTiming = false; 9463 endFiberMark(fiber, null, null); 9464 } 9465 } 9466 9467 function stopFailedWorkTimer(fiber) { 9468 if (enableUserTimingAPI) { 9469 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { 9470 return; 9471 } 9472 // If we pause, its parent is the fiber to unwind from. 9473 currentFiber = fiber.return; 9474 if (!fiber._debugIsCurrentlyTiming) { 9475 return; 9476 } 9477 fiber._debugIsCurrentlyTiming = false; 9478 var warning = fiber.tag === SuspenseComponent || fiber.tag === DehydratedSuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary'; 9479 endFiberMark(fiber, null, warning); 9480 } 9481 } 9482 9483 function startPhaseTimer(fiber, phase) { 9484 if (enableUserTimingAPI) { 9485 if (!supportsUserTiming) { 9486 return; 9487 } 9488 clearPendingPhaseMeasurement(); 9489 if (!beginFiberMark(fiber, phase)) { 9490 return; 9491 } 9492 currentPhaseFiber = fiber; 9493 currentPhase = phase; 9494 } 9495 } 9496 9497 function stopPhaseTimer() { 9498 if (enableUserTimingAPI) { 9499 if (!supportsUserTiming) { 9500 return; 9501 } 9502 if (currentPhase !== null && currentPhaseFiber !== null) { 9503 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null; 9504 endFiberMark(currentPhaseFiber, currentPhase, warning); 9505 } 9506 currentPhase = null; 9507 currentPhaseFiber = null; 9508 } 9509 } 9510 9511 function startWorkLoopTimer(nextUnitOfWork) { 9512 if (enableUserTimingAPI) { 9513 currentFiber = nextUnitOfWork; 9514 if (!supportsUserTiming) { 9515 return; 9516 } 9517 commitCountInCurrentWorkLoop = 0; 9518 // This is top level call. 9519 // Any other measurements are performed within. 9520 beginMark('(React Tree Reconciliation)'); 9521 // Resume any measurements that were in progress during the last loop. 9522 resumeTimers(); 9523 } 9524 } 9525 9526 function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { 9527 if (enableUserTimingAPI) { 9528 if (!supportsUserTiming) { 9529 return; 9530 } 9531 var warning = null; 9532 if (interruptedBy !== null) { 9533 if (interruptedBy.tag === HostRoot) { 9534 warning = 'A top-level update interrupted the previous render'; 9535 } else { 9536 var componentName = getComponentName(interruptedBy.type) || 'Unknown'; 9537 warning = 'An update to ' + componentName + ' interrupted the previous render'; 9538 } 9539 } else if (commitCountInCurrentWorkLoop > 1) { 9540 warning = 'There were cascading updates'; 9541 } 9542 commitCountInCurrentWorkLoop = 0; 9543 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)'; 9544 // Pause any measurements until the next loop. 9545 pauseTimers(); 9546 endMark(label, '(React Tree Reconciliation)', warning); 9547 } 9548 } 9549 9550 function startCommitTimer() { 9551 if (enableUserTimingAPI) { 9552 if (!supportsUserTiming) { 9553 return; 9554 } 9555 isCommitting = true; 9556 hasScheduledUpdateInCurrentCommit = false; 9557 labelsInCurrentCommit.clear(); 9558 beginMark('(Committing Changes)'); 9559 } 9560 } 9561 9562 function stopCommitTimer() { 9563 if (enableUserTimingAPI) { 9564 if (!supportsUserTiming) { 9565 return; 9566 } 9567 9568 var warning = null; 9569 if (hasScheduledUpdateInCurrentCommit) { 9570 warning = 'Lifecycle hook scheduled a cascading update'; 9571 } else if (commitCountInCurrentWorkLoop > 0) { 9572 warning = 'Caused by a cascading update in earlier commit'; 9573 } 9574 hasScheduledUpdateInCurrentCommit = false; 9575 commitCountInCurrentWorkLoop++; 9576 isCommitting = false; 9577 labelsInCurrentCommit.clear(); 9578 9579 endMark('(Committing Changes)', '(Committing Changes)', warning); 9580 } 9581 } 9582 9583 function startCommitSnapshotEffectsTimer() { 9584 if (enableUserTimingAPI) { 9585 if (!supportsUserTiming) { 9586 return; 9587 } 9588 effectCountInCurrentCommit = 0; 9589 beginMark('(Committing Snapshot Effects)'); 9590 } 9591 } 9592 9593 function stopCommitSnapshotEffectsTimer() { 9594 if (enableUserTimingAPI) { 9595 if (!supportsUserTiming) { 9596 return; 9597 } 9598 var count = effectCountInCurrentCommit; 9599 effectCountInCurrentCommit = 0; 9600 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null); 9601 } 9602 } 9603 9604 function startCommitHostEffectsTimer() { 9605 if (enableUserTimingAPI) { 9606 if (!supportsUserTiming) { 9607 return; 9608 } 9609 effectCountInCurrentCommit = 0; 9610 beginMark('(Committing Host Effects)'); 9611 } 9612 } 9613 9614 function stopCommitHostEffectsTimer() { 9615 if (enableUserTimingAPI) { 9616 if (!supportsUserTiming) { 9617 return; 9618 } 9619 var count = effectCountInCurrentCommit; 9620 effectCountInCurrentCommit = 0; 9621 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null); 9622 } 9623 } 9624 9625 function startCommitLifeCyclesTimer() { 9626 if (enableUserTimingAPI) { 9627 if (!supportsUserTiming) { 9628 return; 9629 } 9630 effectCountInCurrentCommit = 0; 9631 beginMark('(Calling Lifecycle Methods)'); 9632 } 9633 } 9634 9635 function stopCommitLifeCyclesTimer() { 9636 if (enableUserTimingAPI) { 9637 if (!supportsUserTiming) { 9638 return; 9639 } 9640 var count = effectCountInCurrentCommit; 9641 effectCountInCurrentCommit = 0; 9642 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null); 9643 } 9644 } 9645 9646 var valueStack = []; 9647 9648 var fiberStack = void 0; 9649 9650 { 9651 fiberStack = []; 9652 } 9653 9654 var index = -1; 9655 9656 function createCursor(defaultValue) { 9657 return { 9658 current: defaultValue 9659 }; 9660 } 9661 9662 function pop(cursor, fiber) { 9663 if (index < 0) { 9664 { 9665 warningWithoutStack$1(false, 'Unexpected pop.'); 9666 } 9667 return; 9668 } 9669 9670 { 9671 if (fiber !== fiberStack[index]) { 9672 warningWithoutStack$1(false, 'Unexpected Fiber popped.'); 9673 } 9674 } 9675 9676 cursor.current = valueStack[index]; 9677 9678 valueStack[index] = null; 9679 9680 { 9681 fiberStack[index] = null; 9682 } 9683 9684 index--; 9685 } 9686 9687 function push(cursor, value, fiber) { 9688 index++; 9689 9690 valueStack[index] = cursor.current; 9691 9692 { 9693 fiberStack[index] = fiber; 9694 } 9695 9696 cursor.current = value; 9697 } 9698 9699 function checkThatStackIsEmpty() { 9700 { 9701 if (index !== -1) { 9702 warningWithoutStack$1(false, 'Expected an empty stack. Something was not reset properly.'); 9703 } 9704 } 9705 } 9706 9707 function resetStackAfterFatalErrorInDev() { 9708 { 9709 index = -1; 9710 valueStack.length = 0; 9711 fiberStack.length = 0; 9712 } 9713 } 9714 9715 var warnedAboutMissingGetChildContext = void 0; 9716 9717 { 9718 warnedAboutMissingGetChildContext = {}; 9719 } 9720 9721 var emptyContextObject = {}; 9722 { 9723 Object.freeze(emptyContextObject); 9724 } 9725 9726 // A cursor to the current merged context object on the stack. 9727 var contextStackCursor = createCursor(emptyContextObject); 9728 // A cursor to a boolean indicating whether the context has changed. 9729 var didPerformWorkStackCursor = createCursor(false); 9730 // Keep track of the previous context object that was on the stack. 9731 // We use this to get access to the parent context after we have already 9732 // pushed the next context provider, and now need to merge their contexts. 9733 var previousContext = emptyContextObject; 9734 9735 function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) { 9736 if (didPushOwnContextIfProvider && isContextProvider(Component)) { 9737 // If the fiber is a context provider itself, when we read its context 9738 // we may have already pushed its own child context on the stack. A context 9739 // provider should not "see" its own child context. Therefore we read the 9740 // previous (parent) context instead for a context provider. 9741 return previousContext; 9742 } 9743 return contextStackCursor.current; 9744 } 9745 9746 function cacheContext(workInProgress, unmaskedContext, maskedContext) { 9747 var instance = workInProgress.stateNode; 9748 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; 9749 instance.__reactInternalMemoizedMaskedChildContext = maskedContext; 9750 } 9751 9752 function getMaskedContext(workInProgress, unmaskedContext) { 9753 var type = workInProgress.type; 9754 var contextTypes = type.contextTypes; 9755 if (!contextTypes) { 9756 return emptyContextObject; 9757 } 9758 9759 // Avoid recreating masked context unless unmasked context has changed. 9760 // Failing to do this will result in unnecessary calls to componentWillReceiveProps. 9761 // This may trigger infinite loops if componentWillReceiveProps calls setState. 9762 var instance = workInProgress.stateNode; 9763 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) { 9764 return instance.__reactInternalMemoizedMaskedChildContext; 9765 } 9766 9767 var context = {}; 9768 for (var key in contextTypes) { 9769 context[key] = unmaskedContext[key]; 9770 } 9771 9772 { 9773 var name = getComponentName(type) || 'Unknown'; 9774 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev); 9775 } 9776 9777 // Cache unmasked context so we can avoid recreating masked context unless necessary. 9778 // Context is created before the class component is instantiated so check for instance. 9779 if (instance) { 9780 cacheContext(workInProgress, unmaskedContext, context); 9781 } 9782 9783 return context; 9784 } 9785 9786 function hasContextChanged() { 9787 return didPerformWorkStackCursor.current; 9788 } 9789 9790 function isContextProvider(type) { 9791 var childContextTypes = type.childContextTypes; 9792 return childContextTypes !== null && childContextTypes !== undefined; 9793 } 9794 9795 function popContext(fiber) { 9796 pop(didPerformWorkStackCursor, fiber); 9797 pop(contextStackCursor, fiber); 9798 } 9799 9800 function popTopLevelContextObject(fiber) { 9801 pop(didPerformWorkStackCursor, fiber); 9802 pop(contextStackCursor, fiber); 9803 } 9804 9805 function pushTopLevelContextObject(fiber, context, didChange) { 9806 !(contextStackCursor.current === emptyContextObject) ? invariant(false, 'Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.') : void 0; 9807 9808 push(contextStackCursor, context, fiber); 9809 push(didPerformWorkStackCursor, didChange, fiber); 9810 } 9811 9812 function processChildContext(fiber, type, parentContext) { 9813 var instance = fiber.stateNode; 9814 var childContextTypes = type.childContextTypes; 9815 9816 // TODO (bvaughn) Replace this behavior with an invariant() in the future. 9817 // It has only been added in Fiber to match the (unintentional) behavior in Stack. 9818 if (typeof instance.getChildContext !== 'function') { 9819 { 9820 var componentName = getComponentName(type) || 'Unknown'; 9821 9822 if (!warnedAboutMissingGetChildContext[componentName]) { 9823 warnedAboutMissingGetChildContext[componentName] = true; 9824 warningWithoutStack$1(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); 9825 } 9826 } 9827 return parentContext; 9828 } 9829 9830 var childContext = void 0; 9831 { 9832 setCurrentPhase('getChildContext'); 9833 } 9834 startPhaseTimer(fiber, 'getChildContext'); 9835 childContext = instance.getChildContext(); 9836 stopPhaseTimer(); 9837 { 9838 setCurrentPhase(null); 9839 } 9840 for (var contextKey in childContext) { 9841 !(contextKey in childContextTypes) ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(type) || 'Unknown', contextKey) : void 0; 9842 } 9843 { 9844 var name = getComponentName(type) || 'Unknown'; 9845 checkPropTypes_1(childContextTypes, childContext, 'child context', name, 9846 // In practice, there is one case in which we won't get a stack. It's when 9847 // somebody calls unstable_renderSubtreeIntoContainer() and we process 9848 // context from the parent component instance. The stack will be missing 9849 // because it's outside of the reconciliation, and so the pointer has not 9850 // been set. This is rare and doesn't matter. We'll also remove that API. 9851 getCurrentFiberStackInDev); 9852 } 9853 9854 return _assign({}, parentContext, childContext); 9855 } 9856 9857 function pushContextProvider(workInProgress) { 9858 var instance = workInProgress.stateNode; 9859 // We push the context as early as possible to ensure stack integrity. 9860 // If the instance does not exist yet, we will push null at first, 9861 // and replace it on the stack later when invalidating the context. 9862 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; 9863 9864 // Remember the parent context so we can merge with it later. 9865 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. 9866 previousContext = contextStackCursor.current; 9867 push(contextStackCursor, memoizedMergedChildContext, workInProgress); 9868 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress); 9869 9870 return true; 9871 } 9872 9873 function invalidateContextProvider(workInProgress, type, didChange) { 9874 var instance = workInProgress.stateNode; 9875 !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; 9876 9877 if (didChange) { 9878 // Merge parent and own context. 9879 // Skip this if we're not updating due to sCU. 9880 // This avoids unnecessarily recomputing memoized values. 9881 var mergedContext = processChildContext(workInProgress, type, previousContext); 9882 instance.__reactInternalMemoizedMergedChildContext = mergedContext; 9883 9884 // Replace the old (or empty) context with the new one. 9885 // It is important to unwind the context in the reverse order. 9886 pop(didPerformWorkStackCursor, workInProgress); 9887 pop(contextStackCursor, workInProgress); 9888 // Now push the new context and mark that it has changed. 9889 push(contextStackCursor, mergedContext, workInProgress); 9890 push(didPerformWorkStackCursor, didChange, workInProgress); 9891 } else { 9892 pop(didPerformWorkStackCursor, workInProgress); 9893 push(didPerformWorkStackCursor, didChange, workInProgress); 9894 } 9895 } 9896 9897 function findCurrentUnmaskedContext(fiber) { 9898 // Currently this is only used with renderSubtreeIntoContainer; not sure if it 9899 // makes sense elsewhere 9900 !(isFiberMounted(fiber) && fiber.tag === ClassComponent) ? 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; 9901 9902 var node = fiber; 9903 do { 9904 switch (node.tag) { 9905 case HostRoot: 9906 return node.stateNode.context; 9907 case ClassComponent: 9908 { 9909 var Component = node.type; 9910 if (isContextProvider(Component)) { 9911 return node.stateNode.__reactInternalMemoizedMergedChildContext; 9912 } 9913 break; 9914 } 9915 } 9916 node = node.return; 9917 } while (node !== null); 9918 invariant(false, 'Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.'); 9919 } 9920 9921 var onCommitFiberRoot = null; 9922 var onCommitFiberUnmount = null; 9923 var hasLoggedError = false; 9924 9925 function catchErrors(fn) { 9926 return function (arg) { 9927 try { 9928 return fn(arg); 9929 } catch (err) { 9930 if (true && !hasLoggedError) { 9931 hasLoggedError = true; 9932 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err); 9933 } 9934 } 9935 }; 9936 } 9937 9938 var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined'; 9939 9940 function injectInternals(internals) { 9941 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') { 9942 // No DevTools 9943 return false; 9944 } 9945 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; 9946 if (hook.isDisabled) { 9947 // This isn't a real property on the hook, but it can be set to opt out 9948 // of DevTools integration and associated warnings and logs. 9949 // https://github.com/facebook/react/issues/3877 9950 return true; 9951 } 9952 if (!hook.supportsFiber) { 9953 { 9954 warningWithoutStack$1(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'); 9955 } 9956 // DevTools exists, even though it doesn't support Fiber. 9957 return true; 9958 } 9959 try { 9960 var rendererID = hook.inject(internals); 9961 // We have successfully injected, so now it is safe to set up hooks. 9962 onCommitFiberRoot = catchErrors(function (root) { 9963 return hook.onCommitFiberRoot(rendererID, root); 9964 }); 9965 onCommitFiberUnmount = catchErrors(function (fiber) { 9966 return hook.onCommitFiberUnmount(rendererID, fiber); 9967 }); 9968 } catch (err) { 9969 // Catch all errors because it is unsafe to throw during initialization. 9970 { 9971 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err); 9972 } 9973 } 9974 // DevTools exists 9975 return true; 9976 } 9977 9978 function onCommitRoot(root) { 9979 if (typeof onCommitFiberRoot === 'function') { 9980 onCommitFiberRoot(root); 9981 } 9982 } 9983 9984 function onCommitUnmount(fiber) { 9985 if (typeof onCommitFiberUnmount === 'function') { 9986 onCommitFiberUnmount(fiber); 9987 } 9988 } 9989 9990 // Max 31 bit integer. The max integer size in V8 for 32-bit systems. 9991 // Math.pow(2, 30) - 1 9992 // 0b111111111111111111111111111111 9993 var maxSigned31BitInt = 1073741823; 9994 9995 var NoWork = 0; 9996 var Never = 1; 9997 var Sync = maxSigned31BitInt; 9998 9999 var UNIT_SIZE = 10; 10000 var MAGIC_NUMBER_OFFSET = maxSigned31BitInt - 1; 10001 10002 // 1 unit of expiration time represents 10ms. 10003 function msToExpirationTime(ms) { 10004 // Always add an offset so that we don't clash with the magic number for NoWork. 10005 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0); 10006 } 10007 10008 function expirationTimeToMs(expirationTime) { 10009 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE; 10010 } 10011 10012 function ceiling(num, precision) { 10013 return ((num / precision | 0) + 1) * precision; 10014 } 10015 10016 function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) { 10017 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE); 10018 } 10019 10020 var LOW_PRIORITY_EXPIRATION = 5000; 10021 var LOW_PRIORITY_BATCH_SIZE = 250; 10022 10023 function computeAsyncExpiration(currentTime) { 10024 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE); 10025 } 10026 10027 // We intentionally set a higher expiration time for interactive updates in 10028 // dev than in production. 10029 // 10030 // If the main thread is being blocked so long that you hit the expiration, 10031 // it's a problem that could be solved with better scheduling. 10032 // 10033 // People will be more likely to notice this and fix it with the long 10034 // expiration time in development. 10035 // 10036 // In production we opt for better UX at the risk of masking scheduling 10037 // problems, by expiring fast. 10038 var HIGH_PRIORITY_EXPIRATION = 500; 10039 var HIGH_PRIORITY_BATCH_SIZE = 100; 10040 10041 function computeInteractiveExpiration(currentTime) { 10042 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE); 10043 } 10044 10045 var NoContext = 0; 10046 var ConcurrentMode = 1; 10047 var StrictMode = 2; 10048 var ProfileMode = 4; 10049 10050 var hasBadMapPolyfill = void 0; 10051 10052 { 10053 hasBadMapPolyfill = false; 10054 try { 10055 var nonExtensibleObject = Object.preventExtensions({}); 10056 var testMap = new Map([[nonExtensibleObject, null]]); 10057 var testSet = new Set([nonExtensibleObject]); 10058 // This is necessary for Rollup to not consider these unused. 10059 // https://github.com/rollup/rollup/issues/1771 10060 // TODO: we can remove these if Rollup fixes the bug. 10061 testMap.set(0, 0); 10062 testSet.add(0); 10063 } catch (e) { 10064 // TODO: Consider warning about bad polyfills 10065 hasBadMapPolyfill = true; 10066 } 10067 } 10068 10069 // A Fiber is work on a Component that needs to be done or was done. There can 10070 // be more than one per component. 10071 10072 10073 var debugCounter = void 0; 10074 10075 { 10076 debugCounter = 1; 10077 } 10078 10079 function FiberNode(tag, pendingProps, key, mode) { 10080 // Instance 10081 this.tag = tag; 10082 this.key = key; 10083 this.elementType = null; 10084 this.type = null; 10085 this.stateNode = null; 10086 10087 // Fiber 10088 this.return = null; 10089 this.child = null; 10090 this.sibling = null; 10091 this.index = 0; 10092 10093 this.ref = null; 10094 10095 this.pendingProps = pendingProps; 10096 this.memoizedProps = null; 10097 this.updateQueue = null; 10098 this.memoizedState = null; 10099 this.contextDependencies = null; 10100 10101 this.mode = mode; 10102 10103 // Effects 10104 this.effectTag = NoEffect; 10105 this.nextEffect = null; 10106 10107 this.firstEffect = null; 10108 this.lastEffect = null; 10109 10110 this.expirationTime = NoWork; 10111 this.childExpirationTime = NoWork; 10112 10113 this.alternate = null; 10114 10115 if (enableProfilerTimer) { 10116 // Note: The following is done to avoid a v8 performance cliff. 10117 // 10118 // Initializing the fields below to smis and later updating them with 10119 // double values will cause Fibers to end up having separate shapes. 10120 // This behavior/bug has something to do with Object.preventExtension(). 10121 // Fortunately this only impacts DEV builds. 10122 // Unfortunately it makes React unusably slow for some applications. 10123 // To work around this, initialize the fields below with doubles. 10124 // 10125 // Learn more about this here: 10126 // https://github.com/facebook/react/issues/14365 10127 // https://bugs.chromium.org/p/v8/issues/detail?id=8538 10128 this.actualDuration = Number.NaN; 10129 this.actualStartTime = Number.NaN; 10130 this.selfBaseDuration = Number.NaN; 10131 this.treeBaseDuration = Number.NaN; 10132 10133 // It's okay to replace the initial doubles with smis after initialization. 10134 // This won't trigger the performance cliff mentioned above, 10135 // and it simplifies other profiler code (including DevTools). 10136 this.actualDuration = 0; 10137 this.actualStartTime = -1; 10138 this.selfBaseDuration = 0; 10139 this.treeBaseDuration = 0; 10140 } 10141 10142 { 10143 this._debugID = debugCounter++; 10144 this._debugSource = null; 10145 this._debugOwner = null; 10146 this._debugIsCurrentlyTiming = false; 10147 this._debugHookTypes = null; 10148 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') { 10149 Object.preventExtensions(this); 10150 } 10151 } 10152 } 10153 10154 // This is a constructor function, rather than a POJO constructor, still 10155 // please ensure we do the following: 10156 // 1) Nobody should add any instance methods on this. Instance methods can be 10157 // more difficult to predict when they get optimized and they are almost 10158 // never inlined properly in static compilers. 10159 // 2) Nobody should rely on `instanceof Fiber` for type testing. We should 10160 // always know when it is a fiber. 10161 // 3) We might want to experiment with using numeric keys since they are easier 10162 // to optimize in a non-JIT environment. 10163 // 4) We can easily go from a constructor to a createFiber object literal if that 10164 // is faster. 10165 // 5) It should be easy to port this to a C struct and keep a C implementation 10166 // compatible. 10167 var createFiber = function (tag, pendingProps, key, mode) { 10168 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors 10169 return new FiberNode(tag, pendingProps, key, mode); 10170 }; 10171 10172 function shouldConstruct(Component) { 10173 var prototype = Component.prototype; 10174 return !!(prototype && prototype.isReactComponent); 10175 } 10176 10177 function isSimpleFunctionComponent(type) { 10178 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined; 10179 } 10180 10181 function resolveLazyComponentTag(Component) { 10182 if (typeof Component === 'function') { 10183 return shouldConstruct(Component) ? ClassComponent : FunctionComponent; 10184 } else if (Component !== undefined && Component !== null) { 10185 var $$typeof = Component.$$typeof; 10186 if ($$typeof === REACT_FORWARD_REF_TYPE) { 10187 return ForwardRef; 10188 } 10189 if ($$typeof === REACT_MEMO_TYPE) { 10190 return MemoComponent; 10191 } 10192 } 10193 return IndeterminateComponent; 10194 } 10195 10196 // This is used to create an alternate fiber to do work on. 10197 function createWorkInProgress(current, pendingProps, expirationTime) { 10198 var workInProgress = current.alternate; 10199 if (workInProgress === null) { 10200 // We use a double buffering pooling technique because we know that we'll 10201 // only ever need at most two versions of a tree. We pool the "other" unused 10202 // node that we're free to reuse. This is lazily created to avoid allocating 10203 // extra objects for things that are never updated. It also allow us to 10204 // reclaim the extra memory if needed. 10205 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode); 10206 workInProgress.elementType = current.elementType; 10207 workInProgress.type = current.type; 10208 workInProgress.stateNode = current.stateNode; 10209 10210 { 10211 // DEV-only fields 10212 workInProgress._debugID = current._debugID; 10213 workInProgress._debugSource = current._debugSource; 10214 workInProgress._debugOwner = current._debugOwner; 10215 workInProgress._debugHookTypes = current._debugHookTypes; 10216 } 10217 10218 workInProgress.alternate = current; 10219 current.alternate = workInProgress; 10220 } else { 10221 workInProgress.pendingProps = pendingProps; 10222 10223 // We already have an alternate. 10224 // Reset the effect tag. 10225 workInProgress.effectTag = NoEffect; 10226 10227 // The effect list is no longer valid. 10228 workInProgress.nextEffect = null; 10229 workInProgress.firstEffect = null; 10230 workInProgress.lastEffect = null; 10231 10232 if (enableProfilerTimer) { 10233 // We intentionally reset, rather than copy, actualDuration & actualStartTime. 10234 // This prevents time from endlessly accumulating in new commits. 10235 // This has the downside of resetting values for different priority renders, 10236 // But works for yielding (the common case) and should support resuming. 10237 workInProgress.actualDuration = 0; 10238 workInProgress.actualStartTime = -1; 10239 } 10240 } 10241 10242 workInProgress.childExpirationTime = current.childExpirationTime; 10243 workInProgress.expirationTime = current.expirationTime; 10244 10245 workInProgress.child = current.child; 10246 workInProgress.memoizedProps = current.memoizedProps; 10247 workInProgress.memoizedState = current.memoizedState; 10248 workInProgress.updateQueue = current.updateQueue; 10249 workInProgress.contextDependencies = current.contextDependencies; 10250 10251 // These will be overridden during the parent's reconciliation 10252 workInProgress.sibling = current.sibling; 10253 workInProgress.index = current.index; 10254 workInProgress.ref = current.ref; 10255 10256 if (enableProfilerTimer) { 10257 workInProgress.selfBaseDuration = current.selfBaseDuration; 10258 workInProgress.treeBaseDuration = current.treeBaseDuration; 10259 } 10260 10261 return workInProgress; 10262 } 10263 10264 function createHostRootFiber(isConcurrent) { 10265 var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext; 10266 10267 if (enableProfilerTimer && isDevToolsPresent) { 10268 // Always collect profile timings when DevTools are present. 10269 // This enables DevTools to start capturing timing at any point– 10270 // Without some nodes in the tree having empty base times. 10271 mode |= ProfileMode; 10272 } 10273 10274 return createFiber(HostRoot, null, null, mode); 10275 } 10276 10277 function createFiberFromTypeAndProps(type, // React$ElementType 10278 key, pendingProps, owner, mode, expirationTime) { 10279 var fiber = void 0; 10280 10281 var fiberTag = IndeterminateComponent; 10282 // The resolved type is set if we know what the final type will be. I.e. it's not lazy. 10283 var resolvedType = type; 10284 if (typeof type === 'function') { 10285 if (shouldConstruct(type)) { 10286 fiberTag = ClassComponent; 10287 } 10288 } else if (typeof type === 'string') { 10289 fiberTag = HostComponent; 10290 } else { 10291 getTag: switch (type) { 10292 case REACT_FRAGMENT_TYPE: 10293 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key); 10294 case REACT_CONCURRENT_MODE_TYPE: 10295 return createFiberFromMode(pendingProps, mode | ConcurrentMode | StrictMode, expirationTime, key); 10296 case REACT_STRICT_MODE_TYPE: 10297 return createFiberFromMode(pendingProps, mode | StrictMode, expirationTime, key); 10298 case REACT_PROFILER_TYPE: 10299 return createFiberFromProfiler(pendingProps, mode, expirationTime, key); 10300 case REACT_SUSPENSE_TYPE: 10301 return createFiberFromSuspense(pendingProps, mode, expirationTime, key); 10302 default: 10303 { 10304 if (typeof type === 'object' && type !== null) { 10305 switch (type.$$typeof) { 10306 case REACT_PROVIDER_TYPE: 10307 fiberTag = ContextProvider; 10308 break getTag; 10309 case REACT_CONTEXT_TYPE: 10310 // This is a consumer 10311 fiberTag = ContextConsumer; 10312 break getTag; 10313 case REACT_FORWARD_REF_TYPE: 10314 fiberTag = ForwardRef; 10315 break getTag; 10316 case REACT_MEMO_TYPE: 10317 fiberTag = MemoComponent; 10318 break getTag; 10319 case REACT_LAZY_TYPE: 10320 fiberTag = LazyComponent; 10321 resolvedType = null; 10322 break getTag; 10323 } 10324 } 10325 var info = ''; 10326 { 10327 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) { 10328 info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and " + 'named imports.'; 10329 } 10330 var ownerName = owner ? getComponentName(owner.type) : null; 10331 if (ownerName) { 10332 info += '\n\nCheck the render method of `' + ownerName + '`.'; 10333 } 10334 } 10335 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); 10336 } 10337 } 10338 } 10339 10340 fiber = createFiber(fiberTag, pendingProps, key, mode); 10341 fiber.elementType = type; 10342 fiber.type = resolvedType; 10343 fiber.expirationTime = expirationTime; 10344 10345 return fiber; 10346 } 10347 10348 function createFiberFromElement(element, mode, expirationTime) { 10349 var owner = null; 10350 { 10351 owner = element._owner; 10352 } 10353 var type = element.type; 10354 var key = element.key; 10355 var pendingProps = element.props; 10356 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime); 10357 { 10358 fiber._debugSource = element._source; 10359 fiber._debugOwner = element._owner; 10360 } 10361 return fiber; 10362 } 10363 10364 function createFiberFromFragment(elements, mode, expirationTime, key) { 10365 var fiber = createFiber(Fragment, elements, key, mode); 10366 fiber.expirationTime = expirationTime; 10367 return fiber; 10368 } 10369 10370 function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { 10371 { 10372 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') { 10373 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props'); 10374 } 10375 } 10376 10377 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); 10378 // TODO: The Profiler fiber shouldn't have a type. It has a tag. 10379 fiber.elementType = REACT_PROFILER_TYPE; 10380 fiber.type = REACT_PROFILER_TYPE; 10381 fiber.expirationTime = expirationTime; 10382 10383 return fiber; 10384 } 10385 10386 function createFiberFromMode(pendingProps, mode, expirationTime, key) { 10387 var fiber = createFiber(Mode, pendingProps, key, mode); 10388 10389 // TODO: The Mode fiber shouldn't have a type. It has a tag. 10390 var type = (mode & ConcurrentMode) === NoContext ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE; 10391 fiber.elementType = type; 10392 fiber.type = type; 10393 10394 fiber.expirationTime = expirationTime; 10395 return fiber; 10396 } 10397 10398 function createFiberFromSuspense(pendingProps, mode, expirationTime, key) { 10399 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); 10400 10401 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag. 10402 var type = REACT_SUSPENSE_TYPE; 10403 fiber.elementType = type; 10404 fiber.type = type; 10405 10406 fiber.expirationTime = expirationTime; 10407 return fiber; 10408 } 10409 10410 function createFiberFromText(content, mode, expirationTime) { 10411 var fiber = createFiber(HostText, content, null, mode); 10412 fiber.expirationTime = expirationTime; 10413 return fiber; 10414 } 10415 10416 function createFiberFromHostInstanceForDeletion() { 10417 var fiber = createFiber(HostComponent, null, null, NoContext); 10418 // TODO: These should not need a type. 10419 fiber.elementType = 'DELETED'; 10420 fiber.type = 'DELETED'; 10421 return fiber; 10422 } 10423 10424 function createFiberFromPortal(portal, mode, expirationTime) { 10425 var pendingProps = portal.children !== null ? portal.children : []; 10426 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode); 10427 fiber.expirationTime = expirationTime; 10428 fiber.stateNode = { 10429 containerInfo: portal.containerInfo, 10430 pendingChildren: null, // Used by persistent updates 10431 implementation: portal.implementation 10432 }; 10433 return fiber; 10434 } 10435 10436 // Used for stashing WIP properties to replay failed work in DEV. 10437 function assignFiberPropertiesInDEV(target, source) { 10438 if (target === null) { 10439 // This Fiber's initial properties will always be overwritten. 10440 // We only use a Fiber to ensure the same hidden class so DEV isn't slow. 10441 target = createFiber(IndeterminateComponent, null, null, NoContext); 10442 } 10443 10444 // This is intentionally written as a list of all properties. 10445 // We tried to use Object.assign() instead but this is called in 10446 // the hottest path, and Object.assign() was too slow: 10447 // https://github.com/facebook/react/issues/12502 10448 // This code is DEV-only so size is not a concern. 10449 10450 target.tag = source.tag; 10451 target.key = source.key; 10452 target.elementType = source.elementType; 10453 target.type = source.type; 10454 target.stateNode = source.stateNode; 10455 target.return = source.return; 10456 target.child = source.child; 10457 target.sibling = source.sibling; 10458 target.index = source.index; 10459 target.ref = source.ref; 10460 target.pendingProps = source.pendingProps; 10461 target.memoizedProps = source.memoizedProps; 10462 target.updateQueue = source.updateQueue; 10463 target.memoizedState = source.memoizedState; 10464 target.contextDependencies = source.contextDependencies; 10465 target.mode = source.mode; 10466 target.effectTag = source.effectTag; 10467 target.nextEffect = source.nextEffect; 10468 target.firstEffect = source.firstEffect; 10469 target.lastEffect = source.lastEffect; 10470 target.expirationTime = source.expirationTime; 10471 target.childExpirationTime = source.childExpirationTime; 10472 target.alternate = source.alternate; 10473 if (enableProfilerTimer) { 10474 target.actualDuration = source.actualDuration; 10475 target.actualStartTime = source.actualStartTime; 10476 target.selfBaseDuration = source.selfBaseDuration; 10477 target.treeBaseDuration = source.treeBaseDuration; 10478 } 10479 target._debugID = source._debugID; 10480 target._debugSource = source._debugSource; 10481 target._debugOwner = source._debugOwner; 10482 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; 10483 target._debugHookTypes = source._debugHookTypes; 10484 return target; 10485 } 10486 10487 var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; 10488 10489 var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing; 10490 var __interactionsRef = _ReactInternals$Sched$1.__interactionsRef; 10491 var __subscriberRef = _ReactInternals$Sched$1.__subscriberRef; 10492 var unstable_clear = _ReactInternals$Sched$1.unstable_clear; 10493 var unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent; 10494 var unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID; 10495 var unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe; 10496 var unstable_trace = _ReactInternals$Sched$1.unstable_trace; 10497 var unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe; 10498 var unstable_wrap = _ReactInternals$Sched$1.unstable_wrap; 10499 10500 // TODO: This should be lifted into the renderer. 10501 10502 10503 // The following attributes are only used by interaction tracing builds. 10504 // They enable interactions to be associated with their async work, 10505 // And expose interaction metadata to the React DevTools Profiler plugin. 10506 // Note that these attributes are only defined when the enableSchedulerTracing flag is enabled. 10507 10508 10509 // Exported FiberRoot type includes all properties, 10510 // To avoid requiring potentially error-prone :any casts throughout the project. 10511 // Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true). 10512 // The types are defined separately within this file to ensure they stay in sync. 10513 // (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.) 10514 10515 10516 function createFiberRoot(containerInfo, isConcurrent, hydrate) { 10517 // Cyclic construction. This cheats the type system right now because 10518 // stateNode is any. 10519 var uninitializedFiber = createHostRootFiber(isConcurrent); 10520 10521 var root = void 0; 10522 if (enableSchedulerTracing) { 10523 root = { 10524 current: uninitializedFiber, 10525 containerInfo: containerInfo, 10526 pendingChildren: null, 10527 10528 earliestPendingTime: NoWork, 10529 latestPendingTime: NoWork, 10530 earliestSuspendedTime: NoWork, 10531 latestSuspendedTime: NoWork, 10532 latestPingedTime: NoWork, 10533 10534 pingCache: null, 10535 10536 didError: false, 10537 10538 pendingCommitExpirationTime: NoWork, 10539 finishedWork: null, 10540 timeoutHandle: noTimeout, 10541 context: null, 10542 pendingContext: null, 10543 hydrate: hydrate, 10544 nextExpirationTimeToWorkOn: NoWork, 10545 expirationTime: NoWork, 10546 firstBatch: null, 10547 nextScheduledRoot: null, 10548 10549 interactionThreadID: unstable_getThreadID(), 10550 memoizedInteractions: new Set(), 10551 pendingInteractionMap: new Map() 10552 }; 10553 } else { 10554 root = { 10555 current: uninitializedFiber, 10556 containerInfo: containerInfo, 10557 pendingChildren: null, 10558 10559 pingCache: null, 10560 10561 earliestPendingTime: NoWork, 10562 latestPendingTime: NoWork, 10563 earliestSuspendedTime: NoWork, 10564 latestSuspendedTime: NoWork, 10565 latestPingedTime: NoWork, 10566 10567 didError: false, 10568 10569 pendingCommitExpirationTime: NoWork, 10570 finishedWork: null, 10571 timeoutHandle: noTimeout, 10572 context: null, 10573 pendingContext: null, 10574 hydrate: hydrate, 10575 nextExpirationTimeToWorkOn: NoWork, 10576 expirationTime: NoWork, 10577 firstBatch: null, 10578 nextScheduledRoot: null 10579 }; 10580 } 10581 10582 uninitializedFiber.stateNode = root; 10583 10584 // The reason for the way the Flow types are structured in this file, 10585 // Is to avoid needing :any casts everywhere interaction tracing fields are used. 10586 // Unfortunately that requires an :any cast for non-interaction tracing capable builds. 10587 // $FlowFixMe Remove this :any cast and replace it with something better. 10588 return root; 10589 } 10590 10591 /** 10592 * Forked from fbjs/warning: 10593 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js 10594 * 10595 * Only change is we use console.warn instead of console.error, 10596 * and do nothing when 'console' is not supported. 10597 * This really simplifies the code. 10598 * --- 10599 * Similar to invariant but only logs a warning if the condition is not met. 10600 * This can be used to log issues in development environments in critical 10601 * paths. Removing the logging code for production environments will keep the 10602 * same logic and follow the same code paths. 10603 */ 10604 10605 var lowPriorityWarning = function () {}; 10606 10607 { 10608 var printWarning$1 = function (format) { 10609 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 10610 args[_key - 1] = arguments[_key]; 10611 } 10612 10613 var argIndex = 0; 10614 var message = 'Warning: ' + format.replace(/%s/g, function () { 10615 return args[argIndex++]; 10616 }); 10617 if (typeof console !== 'undefined') { 10618 console.warn(message); 10619 } 10620 try { 10621 // --- Welcome to debugging React --- 10622 // This error was thrown as a convenience so that you can use this stack 10623 // to find the callsite that caused this warning to fire. 10624 throw new Error(message); 10625 } catch (x) {} 10626 }; 10627 10628 lowPriorityWarning = function (condition, format) { 10629 if (format === undefined) { 10630 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument'); 10631 } 10632 if (!condition) { 10633 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { 10634 args[_key2 - 2] = arguments[_key2]; 10635 } 10636 10637 printWarning$1.apply(undefined, [format].concat(args)); 10638 } 10639 }; 10640 } 10641 10642 var lowPriorityWarning$1 = lowPriorityWarning; 10643 10644 var ReactStrictModeWarnings = { 10645 discardPendingWarnings: function () {}, 10646 flushPendingDeprecationWarnings: function () {}, 10647 flushPendingUnsafeLifecycleWarnings: function () {}, 10648 recordDeprecationWarnings: function (fiber, instance) {}, 10649 recordUnsafeLifecycleWarnings: function (fiber, instance) {}, 10650 recordLegacyContextWarning: function (fiber, instance) {}, 10651 flushLegacyContextWarning: function () {} 10652 }; 10653 10654 { 10655 var LIFECYCLE_SUGGESTIONS = { 10656 UNSAFE_componentWillMount: 'componentDidMount', 10657 UNSAFE_componentWillReceiveProps: 'static getDerivedStateFromProps', 10658 UNSAFE_componentWillUpdate: 'componentDidUpdate' 10659 }; 10660 10661 var pendingComponentWillMountWarnings = []; 10662 var pendingComponentWillReceivePropsWarnings = []; 10663 var pendingComponentWillUpdateWarnings = []; 10664 var pendingUnsafeLifecycleWarnings = new Map(); 10665 var pendingLegacyContextWarning = new Map(); 10666 10667 // Tracks components we have already warned about. 10668 var didWarnAboutDeprecatedLifecycles = new Set(); 10669 var didWarnAboutUnsafeLifecycles = new Set(); 10670 var didWarnAboutLegacyContext = new Set(); 10671 10672 var setToSortedString = function (set) { 10673 var array = []; 10674 set.forEach(function (value) { 10675 array.push(value); 10676 }); 10677 return array.sort().join(', '); 10678 }; 10679 10680 ReactStrictModeWarnings.discardPendingWarnings = function () { 10681 pendingComponentWillMountWarnings = []; 10682 pendingComponentWillReceivePropsWarnings = []; 10683 pendingComponentWillUpdateWarnings = []; 10684 pendingUnsafeLifecycleWarnings = new Map(); 10685 pendingLegacyContextWarning = new Map(); 10686 }; 10687 10688 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () { 10689 pendingUnsafeLifecycleWarnings.forEach(function (lifecycleWarningsMap, strictRoot) { 10690 var lifecyclesWarningMessages = []; 10691 10692 Object.keys(lifecycleWarningsMap).forEach(function (lifecycle) { 10693 var lifecycleWarnings = lifecycleWarningsMap[lifecycle]; 10694 if (lifecycleWarnings.length > 0) { 10695 var componentNames = new Set(); 10696 lifecycleWarnings.forEach(function (fiber) { 10697 componentNames.add(getComponentName(fiber.type) || 'Component'); 10698 didWarnAboutUnsafeLifecycles.add(fiber.type); 10699 }); 10700 10701 var formatted = lifecycle.replace('UNSAFE_', ''); 10702 var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle]; 10703 var sortedComponentNames = setToSortedString(componentNames); 10704 10705 lifecyclesWarningMessages.push(formatted + ': Please update the following components to use ' + (suggestion + ' instead: ' + sortedComponentNames)); 10706 } 10707 }); 10708 10709 if (lifecyclesWarningMessages.length > 0) { 10710 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); 10711 10712 warningWithoutStack$1(false, 'Unsafe lifecycle methods were found within a strict-mode tree:%s' + '\n\n%s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-strict-mode-warnings', strictRootComponentStack, lifecyclesWarningMessages.join('\n\n')); 10713 } 10714 }); 10715 10716 pendingUnsafeLifecycleWarnings = new Map(); 10717 }; 10718 10719 var findStrictRoot = function (fiber) { 10720 var maybeStrictRoot = null; 10721 10722 var node = fiber; 10723 while (node !== null) { 10724 if (node.mode & StrictMode) { 10725 maybeStrictRoot = node; 10726 } 10727 node = node.return; 10728 } 10729 10730 return maybeStrictRoot; 10731 }; 10732 10733 ReactStrictModeWarnings.flushPendingDeprecationWarnings = function () { 10734 if (pendingComponentWillMountWarnings.length > 0) { 10735 var uniqueNames = new Set(); 10736 pendingComponentWillMountWarnings.forEach(function (fiber) { 10737 uniqueNames.add(getComponentName(fiber.type) || 'Component'); 10738 didWarnAboutDeprecatedLifecycles.add(fiber.type); 10739 }); 10740 10741 var sortedNames = setToSortedString(uniqueNames); 10742 10743 lowPriorityWarning$1(false, 'componentWillMount is deprecated and will be removed in the next major version. ' + 'Use componentDidMount instead. As a temporary workaround, ' + 'you can rename to UNSAFE_componentWillMount.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', sortedNames); 10744 10745 pendingComponentWillMountWarnings = []; 10746 } 10747 10748 if (pendingComponentWillReceivePropsWarnings.length > 0) { 10749 var _uniqueNames = new Set(); 10750 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) { 10751 _uniqueNames.add(getComponentName(fiber.type) || 'Component'); 10752 didWarnAboutDeprecatedLifecycles.add(fiber.type); 10753 }); 10754 10755 var _sortedNames = setToSortedString(_uniqueNames); 10756 10757 lowPriorityWarning$1(false, 'componentWillReceiveProps is deprecated and will be removed in the next major version. ' + 'Use static getDerivedStateFromProps instead.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', _sortedNames); 10758 10759 pendingComponentWillReceivePropsWarnings = []; 10760 } 10761 10762 if (pendingComponentWillUpdateWarnings.length > 0) { 10763 var _uniqueNames2 = new Set(); 10764 pendingComponentWillUpdateWarnings.forEach(function (fiber) { 10765 _uniqueNames2.add(getComponentName(fiber.type) || 'Component'); 10766 didWarnAboutDeprecatedLifecycles.add(fiber.type); 10767 }); 10768 10769 var _sortedNames2 = setToSortedString(_uniqueNames2); 10770 10771 lowPriorityWarning$1(false, 'componentWillUpdate is deprecated and will be removed in the next major version. ' + 'Use componentDidUpdate instead. As a temporary workaround, ' + 'you can rename to UNSAFE_componentWillUpdate.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-async-component-lifecycle-hooks', _sortedNames2); 10772 10773 pendingComponentWillUpdateWarnings = []; 10774 } 10775 }; 10776 10777 ReactStrictModeWarnings.recordDeprecationWarnings = function (fiber, instance) { 10778 // Dedup strategy: Warn once per component. 10779 if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) { 10780 return; 10781 } 10782 10783 // Don't warn about react-lifecycles-compat polyfilled components. 10784 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) { 10785 pendingComponentWillMountWarnings.push(fiber); 10786 } 10787 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) { 10788 pendingComponentWillReceivePropsWarnings.push(fiber); 10789 } 10790 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) { 10791 pendingComponentWillUpdateWarnings.push(fiber); 10792 } 10793 }; 10794 10795 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) { 10796 var strictRoot = findStrictRoot(fiber); 10797 if (strictRoot === null) { 10798 warningWithoutStack$1(false, 'Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.'); 10799 return; 10800 } 10801 10802 // Dedup strategy: Warn once per component. 10803 // This is difficult to track any other way since component names 10804 // are often vague and are likely to collide between 3rd party libraries. 10805 // An expand property is probably okay to use here since it's DEV-only, 10806 // and will only be set in the event of serious warnings. 10807 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { 10808 return; 10809 } 10810 10811 var warningsForRoot = void 0; 10812 if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) { 10813 warningsForRoot = { 10814 UNSAFE_componentWillMount: [], 10815 UNSAFE_componentWillReceiveProps: [], 10816 UNSAFE_componentWillUpdate: [] 10817 }; 10818 10819 pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot); 10820 } else { 10821 warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot); 10822 } 10823 10824 var unsafeLifecycles = []; 10825 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillMount === 'function') { 10826 unsafeLifecycles.push('UNSAFE_componentWillMount'); 10827 } 10828 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillReceiveProps === 'function') { 10829 unsafeLifecycles.push('UNSAFE_componentWillReceiveProps'); 10830 } 10831 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillUpdate === 'function') { 10832 unsafeLifecycles.push('UNSAFE_componentWillUpdate'); 10833 } 10834 10835 if (unsafeLifecycles.length > 0) { 10836 unsafeLifecycles.forEach(function (lifecycle) { 10837 warningsForRoot[lifecycle].push(fiber); 10838 }); 10839 } 10840 }; 10841 10842 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) { 10843 var strictRoot = findStrictRoot(fiber); 10844 if (strictRoot === null) { 10845 warningWithoutStack$1(false, 'Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.'); 10846 return; 10847 } 10848 10849 // Dedup strategy: Warn once per component. 10850 if (didWarnAboutLegacyContext.has(fiber.type)) { 10851 return; 10852 } 10853 10854 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot); 10855 10856 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') { 10857 if (warningsForRoot === undefined) { 10858 warningsForRoot = []; 10859 pendingLegacyContextWarning.set(strictRoot, warningsForRoot); 10860 } 10861 warningsForRoot.push(fiber); 10862 } 10863 }; 10864 10865 ReactStrictModeWarnings.flushLegacyContextWarning = function () { 10866 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) { 10867 var uniqueNames = new Set(); 10868 fiberArray.forEach(function (fiber) { 10869 uniqueNames.add(getComponentName(fiber.type) || 'Component'); 10870 didWarnAboutLegacyContext.add(fiber.type); 10871 }); 10872 10873 var sortedNames = setToSortedString(uniqueNames); 10874 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); 10875 10876 warningWithoutStack$1(false, 'Legacy context API has been detected within a strict-mode tree: %s' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-strict-mode-warnings', strictRootComponentStack, sortedNames); 10877 }); 10878 }; 10879 } 10880 10881 // This lets us hook into Fiber to debug what it's doing. 10882 // See https://github.com/facebook/react/pull/8033. 10883 // This is not part of the public API, not even for React DevTools. 10884 // You may only inject a debugTool if you work on React Fiber itself. 10885 var ReactFiberInstrumentation = { 10886 debugTool: null 10887 }; 10888 10889 var ReactFiberInstrumentation_1 = ReactFiberInstrumentation; 10890 10891 // TODO: Offscreen updates should never suspend. However, a promise that 10892 // suspended inside an offscreen subtree should be able to ping at the priority 10893 // of the outer render. 10894 10895 function markPendingPriorityLevel(root, expirationTime) { 10896 // If there's a gap between completing a failed root and retrying it, 10897 // additional updates may be scheduled. Clear `didError`, in case the update 10898 // is sufficient to fix the error. 10899 root.didError = false; 10900 10901 // Update the latest and earliest pending times 10902 var earliestPendingTime = root.earliestPendingTime; 10903 if (earliestPendingTime === NoWork) { 10904 // No other pending updates. 10905 root.earliestPendingTime = root.latestPendingTime = expirationTime; 10906 } else { 10907 if (earliestPendingTime < expirationTime) { 10908 // This is the earliest pending update. 10909 root.earliestPendingTime = expirationTime; 10910 } else { 10911 var latestPendingTime = root.latestPendingTime; 10912 if (latestPendingTime > expirationTime) { 10913 // This is the latest pending update 10914 root.latestPendingTime = expirationTime; 10915 } 10916 } 10917 } 10918 findNextExpirationTimeToWorkOn(expirationTime, root); 10919 } 10920 10921 function markCommittedPriorityLevels(root, earliestRemainingTime) { 10922 root.didError = false; 10923 10924 if (earliestRemainingTime === NoWork) { 10925 // Fast path. There's no remaining work. Clear everything. 10926 root.earliestPendingTime = NoWork; 10927 root.latestPendingTime = NoWork; 10928 root.earliestSuspendedTime = NoWork; 10929 root.latestSuspendedTime = NoWork; 10930 root.latestPingedTime = NoWork; 10931 findNextExpirationTimeToWorkOn(NoWork, root); 10932 return; 10933 } 10934 10935 if (earliestRemainingTime < root.latestPingedTime) { 10936 root.latestPingedTime = NoWork; 10937 } 10938 10939 // Let's see if the previous latest known pending level was just flushed. 10940 var latestPendingTime = root.latestPendingTime; 10941 if (latestPendingTime !== NoWork) { 10942 if (latestPendingTime > earliestRemainingTime) { 10943 // We've flushed all the known pending levels. 10944 root.earliestPendingTime = root.latestPendingTime = NoWork; 10945 } else { 10946 var earliestPendingTime = root.earliestPendingTime; 10947 if (earliestPendingTime > earliestRemainingTime) { 10948 // We've flushed the earliest known pending level. Set this to the 10949 // latest pending time. 10950 root.earliestPendingTime = root.latestPendingTime; 10951 } 10952 } 10953 } 10954 10955 // Now let's handle the earliest remaining level in the whole tree. We need to 10956 // decide whether to treat it as a pending level or as suspended. Check 10957 // it falls within the range of known suspended levels. 10958 10959 var earliestSuspendedTime = root.earliestSuspendedTime; 10960 if (earliestSuspendedTime === NoWork) { 10961 // There's no suspended work. Treat the earliest remaining level as a 10962 // pending level. 10963 markPendingPriorityLevel(root, earliestRemainingTime); 10964 findNextExpirationTimeToWorkOn(NoWork, root); 10965 return; 10966 } 10967 10968 var latestSuspendedTime = root.latestSuspendedTime; 10969 if (earliestRemainingTime < latestSuspendedTime) { 10970 // The earliest remaining level is later than all the suspended work. That 10971 // means we've flushed all the suspended work. 10972 root.earliestSuspendedTime = NoWork; 10973 root.latestSuspendedTime = NoWork; 10974 root.latestPingedTime = NoWork; 10975 10976 // There's no suspended work. Treat the earliest remaining level as a 10977 // pending level. 10978 markPendingPriorityLevel(root, earliestRemainingTime); 10979 findNextExpirationTimeToWorkOn(NoWork, root); 10980 return; 10981 } 10982 10983 if (earliestRemainingTime > earliestSuspendedTime) { 10984 // The earliest remaining time is earlier than all the suspended work. 10985 // Treat it as a pending update. 10986 markPendingPriorityLevel(root, earliestRemainingTime); 10987 findNextExpirationTimeToWorkOn(NoWork, root); 10988 return; 10989 } 10990 10991 // The earliest remaining time falls within the range of known suspended 10992 // levels. We should treat this as suspended work. 10993 findNextExpirationTimeToWorkOn(NoWork, root); 10994 } 10995 10996 function hasLowerPriorityWork(root, erroredExpirationTime) { 10997 var latestPendingTime = root.latestPendingTime; 10998 var latestSuspendedTime = root.latestSuspendedTime; 10999 var latestPingedTime = root.latestPingedTime; 11000 return latestPendingTime !== NoWork && latestPendingTime < erroredExpirationTime || latestSuspendedTime !== NoWork && latestSuspendedTime < erroredExpirationTime || latestPingedTime !== NoWork && latestPingedTime < erroredExpirationTime; 11001 } 11002 11003 function isPriorityLevelSuspended(root, expirationTime) { 11004 var earliestSuspendedTime = root.earliestSuspendedTime; 11005 var latestSuspendedTime = root.latestSuspendedTime; 11006 return earliestSuspendedTime !== NoWork && expirationTime <= earliestSuspendedTime && expirationTime >= latestSuspendedTime; 11007 } 11008 11009 function markSuspendedPriorityLevel(root, suspendedTime) { 11010 root.didError = false; 11011 clearPing(root, suspendedTime); 11012 11013 // First, check the known pending levels and update them if needed. 11014 var earliestPendingTime = root.earliestPendingTime; 11015 var latestPendingTime = root.latestPendingTime; 11016 if (earliestPendingTime === suspendedTime) { 11017 if (latestPendingTime === suspendedTime) { 11018 // Both known pending levels were suspended. Clear them. 11019 root.earliestPendingTime = root.latestPendingTime = NoWork; 11020 } else { 11021 // The earliest pending level was suspended. Clear by setting it to the 11022 // latest pending level. 11023 root.earliestPendingTime = latestPendingTime; 11024 } 11025 } else if (latestPendingTime === suspendedTime) { 11026 // The latest pending level was suspended. Clear by setting it to the 11027 // latest pending level. 11028 root.latestPendingTime = earliestPendingTime; 11029 } 11030 11031 // Finally, update the known suspended levels. 11032 var earliestSuspendedTime = root.earliestSuspendedTime; 11033 var latestSuspendedTime = root.latestSuspendedTime; 11034 if (earliestSuspendedTime === NoWork) { 11035 // No other suspended levels. 11036 root.earliestSuspendedTime = root.latestSuspendedTime = suspendedTime; 11037 } else { 11038 if (earliestSuspendedTime < suspendedTime) { 11039 // This is the earliest suspended level. 11040 root.earliestSuspendedTime = suspendedTime; 11041 } else if (latestSuspendedTime > suspendedTime) { 11042 // This is the latest suspended level 11043 root.latestSuspendedTime = suspendedTime; 11044 } 11045 } 11046 11047 findNextExpirationTimeToWorkOn(suspendedTime, root); 11048 } 11049 11050 function markPingedPriorityLevel(root, pingedTime) { 11051 root.didError = false; 11052 11053 // TODO: When we add back resuming, we need to ensure the progressed work 11054 // is thrown out and not reused during the restarted render. One way to 11055 // invalidate the progressed work is to restart at expirationTime + 1. 11056 var latestPingedTime = root.latestPingedTime; 11057 if (latestPingedTime === NoWork || latestPingedTime > pingedTime) { 11058 root.latestPingedTime = pingedTime; 11059 } 11060 findNextExpirationTimeToWorkOn(pingedTime, root); 11061 } 11062 11063 function clearPing(root, completedTime) { 11064 var latestPingedTime = root.latestPingedTime; 11065 if (latestPingedTime >= completedTime) { 11066 root.latestPingedTime = NoWork; 11067 } 11068 } 11069 11070 function findEarliestOutstandingPriorityLevel(root, renderExpirationTime) { 11071 var earliestExpirationTime = renderExpirationTime; 11072 11073 var earliestPendingTime = root.earliestPendingTime; 11074 var earliestSuspendedTime = root.earliestSuspendedTime; 11075 if (earliestPendingTime > earliestExpirationTime) { 11076 earliestExpirationTime = earliestPendingTime; 11077 } 11078 if (earliestSuspendedTime > earliestExpirationTime) { 11079 earliestExpirationTime = earliestSuspendedTime; 11080 } 11081 return earliestExpirationTime; 11082 } 11083 11084 function didExpireAtExpirationTime(root, currentTime) { 11085 var expirationTime = root.expirationTime; 11086 if (expirationTime !== NoWork && currentTime <= expirationTime) { 11087 // The root has expired. Flush all work up to the current time. 11088 root.nextExpirationTimeToWorkOn = currentTime; 11089 } 11090 } 11091 11092 function findNextExpirationTimeToWorkOn(completedExpirationTime, root) { 11093 var earliestSuspendedTime = root.earliestSuspendedTime; 11094 var latestSuspendedTime = root.latestSuspendedTime; 11095 var earliestPendingTime = root.earliestPendingTime; 11096 var latestPingedTime = root.latestPingedTime; 11097 11098 // Work on the earliest pending time. Failing that, work on the latest 11099 // pinged time. 11100 var nextExpirationTimeToWorkOn = earliestPendingTime !== NoWork ? earliestPendingTime : latestPingedTime; 11101 11102 // If there is no pending or pinged work, check if there's suspended work 11103 // that's lower priority than what we just completed. 11104 if (nextExpirationTimeToWorkOn === NoWork && (completedExpirationTime === NoWork || latestSuspendedTime < completedExpirationTime)) { 11105 // The lowest priority suspended work is the work most likely to be 11106 // committed next. Let's start rendering it again, so that if it times out, 11107 // it's ready to commit. 11108 nextExpirationTimeToWorkOn = latestSuspendedTime; 11109 } 11110 11111 var expirationTime = nextExpirationTimeToWorkOn; 11112 if (expirationTime !== NoWork && earliestSuspendedTime > expirationTime) { 11113 // Expire using the earliest known expiration time. 11114 expirationTime = earliestSuspendedTime; 11115 } 11116 11117 root.nextExpirationTimeToWorkOn = nextExpirationTimeToWorkOn; 11118 root.expirationTime = expirationTime; 11119 } 11120 11121 function resolveDefaultProps(Component, baseProps) { 11122 if (Component && Component.defaultProps) { 11123 // Resolve default props. Taken from ReactElement 11124 var props = _assign({}, baseProps); 11125 var defaultProps = Component.defaultProps; 11126 for (var propName in defaultProps) { 11127 if (props[propName] === undefined) { 11128 props[propName] = defaultProps[propName]; 11129 } 11130 } 11131 return props; 11132 } 11133 return baseProps; 11134 } 11135 11136 function readLazyComponentType(lazyComponent) { 11137 var status = lazyComponent._status; 11138 var result = lazyComponent._result; 11139 switch (status) { 11140 case Resolved: 11141 { 11142 var Component = result; 11143 return Component; 11144 } 11145 case Rejected: 11146 { 11147 var error = result; 11148 throw error; 11149 } 11150 case Pending: 11151 { 11152 var thenable = result; 11153 throw thenable; 11154 } 11155 default: 11156 { 11157 lazyComponent._status = Pending; 11158 var ctor = lazyComponent._ctor; 11159 var _thenable = ctor(); 11160 _thenable.then(function (moduleObject) { 11161 if (lazyComponent._status === Pending) { 11162 var defaultExport = moduleObject.default; 11163 { 11164 if (defaultExport === undefined) { 11165 warning$1(false, 'lazy: Expected the result of a dynamic import() call. ' + 'Instead received: %s\n\nYour code should look like: \n ' + "const MyComponent = lazy(() => import('./MyComponent'))", moduleObject); 11166 } 11167 } 11168 lazyComponent._status = Resolved; 11169 lazyComponent._result = defaultExport; 11170 } 11171 }, function (error) { 11172 if (lazyComponent._status === Pending) { 11173 lazyComponent._status = Rejected; 11174 lazyComponent._result = error; 11175 } 11176 }); 11177 // Handle synchronous thenables. 11178 switch (lazyComponent._status) { 11179 case Resolved: 11180 return lazyComponent._result; 11181 case Rejected: 11182 throw lazyComponent._result; 11183 } 11184 lazyComponent._result = _thenable; 11185 throw _thenable; 11186 } 11187 } 11188 } 11189 11190 var fakeInternalInstance = {}; 11191 var isArray$1 = Array.isArray; 11192 11193 // React.Component uses a shared frozen object by default. 11194 // We'll use it to determine whether we need to initialize legacy refs. 11195 var emptyRefsObject = new React.Component().refs; 11196 11197 var didWarnAboutStateAssignmentForComponent = void 0; 11198 var didWarnAboutUninitializedState = void 0; 11199 var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0; 11200 var didWarnAboutLegacyLifecyclesAndDerivedState = void 0; 11201 var didWarnAboutUndefinedDerivedState = void 0; 11202 var warnOnUndefinedDerivedState = void 0; 11203 var warnOnInvalidCallback$1 = void 0; 11204 var didWarnAboutDirectlyAssigningPropsToState = void 0; 11205 var didWarnAboutContextTypeAndContextTypes = void 0; 11206 var didWarnAboutInvalidateContextType = void 0; 11207 11208 { 11209 didWarnAboutStateAssignmentForComponent = new Set(); 11210 didWarnAboutUninitializedState = new Set(); 11211 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set(); 11212 didWarnAboutLegacyLifecyclesAndDerivedState = new Set(); 11213 didWarnAboutDirectlyAssigningPropsToState = new Set(); 11214 didWarnAboutUndefinedDerivedState = new Set(); 11215 didWarnAboutContextTypeAndContextTypes = new Set(); 11216 didWarnAboutInvalidateContextType = new Set(); 11217 11218 var didWarnOnInvalidCallback = new Set(); 11219 11220 warnOnInvalidCallback$1 = function (callback, callerName) { 11221 if (callback === null || typeof callback === 'function') { 11222 return; 11223 } 11224 var key = callerName + '_' + callback; 11225 if (!didWarnOnInvalidCallback.has(key)) { 11226 didWarnOnInvalidCallback.add(key); 11227 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback); 11228 } 11229 }; 11230 11231 warnOnUndefinedDerivedState = function (type, partialState) { 11232 if (partialState === undefined) { 11233 var componentName = getComponentName(type) || 'Component'; 11234 if (!didWarnAboutUndefinedDerivedState.has(componentName)) { 11235 didWarnAboutUndefinedDerivedState.add(componentName); 11236 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName); 11237 } 11238 } 11239 }; 11240 11241 // This is so gross but it's at least non-critical and can be removed if 11242 // it causes problems. This is meant to give a nicer error message for 11243 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component, 11244 // ...)) which otherwise throws a "_processChildContext is not a function" 11245 // exception. 11246 Object.defineProperty(fakeInternalInstance, '_processChildContext', { 11247 enumerable: false, 11248 value: function () { 11249 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).'); 11250 } 11251 }); 11252 Object.freeze(fakeInternalInstance); 11253 } 11254 11255 function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) { 11256 var prevState = workInProgress.memoizedState; 11257 11258 { 11259 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) { 11260 // Invoke the function an extra time to help detect side-effects. 11261 getDerivedStateFromProps(nextProps, prevState); 11262 } 11263 } 11264 11265 var partialState = getDerivedStateFromProps(nextProps, prevState); 11266 11267 { 11268 warnOnUndefinedDerivedState(ctor, partialState); 11269 } 11270 // Merge the partial state and the previous state. 11271 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState); 11272 workInProgress.memoizedState = memoizedState; 11273 11274 // Once the update queue is empty, persist the derived state onto the 11275 // base state. 11276 var updateQueue = workInProgress.updateQueue; 11277 if (updateQueue !== null && workInProgress.expirationTime === NoWork) { 11278 updateQueue.baseState = memoizedState; 11279 } 11280 } 11281 11282 var classComponentUpdater = { 11283 isMounted: isMounted, 11284 enqueueSetState: function (inst, payload, callback) { 11285 var fiber = get(inst); 11286 var currentTime = requestCurrentTime(); 11287 var expirationTime = computeExpirationForFiber(currentTime, fiber); 11288 11289 var update = createUpdate(expirationTime); 11290 update.payload = payload; 11291 if (callback !== undefined && callback !== null) { 11292 { 11293 warnOnInvalidCallback$1(callback, 'setState'); 11294 } 11295 update.callback = callback; 11296 } 11297 11298 flushPassiveEffects(); 11299 enqueueUpdate(fiber, update); 11300 scheduleWork(fiber, expirationTime); 11301 }, 11302 enqueueReplaceState: function (inst, payload, callback) { 11303 var fiber = get(inst); 11304 var currentTime = requestCurrentTime(); 11305 var expirationTime = computeExpirationForFiber(currentTime, fiber); 11306 11307 var update = createUpdate(expirationTime); 11308 update.tag = ReplaceState; 11309 update.payload = payload; 11310 11311 if (callback !== undefined && callback !== null) { 11312 { 11313 warnOnInvalidCallback$1(callback, 'replaceState'); 11314 } 11315 update.callback = callback; 11316 } 11317 11318 flushPassiveEffects(); 11319 enqueueUpdate(fiber, update); 11320 scheduleWork(fiber, expirationTime); 11321 }, 11322 enqueueForceUpdate: function (inst, callback) { 11323 var fiber = get(inst); 11324 var currentTime = requestCurrentTime(); 11325 var expirationTime = computeExpirationForFiber(currentTime, fiber); 11326 11327 var update = createUpdate(expirationTime); 11328 update.tag = ForceUpdate; 11329 11330 if (callback !== undefined && callback !== null) { 11331 { 11332 warnOnInvalidCallback$1(callback, 'forceUpdate'); 11333 } 11334 update.callback = callback; 11335 } 11336 11337 flushPassiveEffects(); 11338 enqueueUpdate(fiber, update); 11339 scheduleWork(fiber, expirationTime); 11340 } 11341 }; 11342 11343 function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) { 11344 var instance = workInProgress.stateNode; 11345 if (typeof instance.shouldComponentUpdate === 'function') { 11346 startPhaseTimer(workInProgress, 'shouldComponentUpdate'); 11347 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext); 11348 stopPhaseTimer(); 11349 11350 { 11351 !(shouldUpdate !== undefined) ? warningWithoutStack$1(false, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component') : void 0; 11352 } 11353 11354 return shouldUpdate; 11355 } 11356 11357 if (ctor.prototype && ctor.prototype.isPureReactComponent) { 11358 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState); 11359 } 11360 11361 return true; 11362 } 11363 11364 function checkClassInstance(workInProgress, ctor, newProps) { 11365 var instance = workInProgress.stateNode; 11366 { 11367 var name = getComponentName(ctor) || 'Component'; 11368 var renderPresent = instance.render; 11369 11370 if (!renderPresent) { 11371 if (ctor.prototype && typeof ctor.prototype.render === 'function') { 11372 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name); 11373 } else { 11374 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name); 11375 } 11376 } 11377 11378 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state; 11379 !noGetInitialStateOnES6 ? warningWithoutStack$1(false, '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) : void 0; 11380 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved; 11381 !noGetDefaultPropsOnES6 ? warningWithoutStack$1(false, '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) : void 0; 11382 var noInstancePropTypes = !instance.propTypes; 11383 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0; 11384 var noInstanceContextType = !instance.contextType; 11385 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0; 11386 var noInstanceContextTypes = !instance.contextTypes; 11387 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0; 11388 11389 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) { 11390 didWarnAboutContextTypeAndContextTypes.add(ctor); 11391 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name); 11392 } 11393 11394 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function'; 11395 !noComponentShouldUpdate ? warningWithoutStack$1(false, '%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) : void 0; 11396 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') { 11397 warningWithoutStack$1(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(ctor) || 'A pure component'); 11398 } 11399 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function'; 11400 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0; 11401 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function'; 11402 !noComponentDidReceiveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidReceiveProps(). But there is no such lifecycle method. ' + 'If you meant to update the state in response to changing props, ' + 'use componentWillReceiveProps(). If you meant to fetch data or ' + 'run side-effects or mutations after React has updated the UI, use componentDidUpdate().', name) : void 0; 11403 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function'; 11404 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0; 11405 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function'; 11406 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0; 11407 var hasMutatedProps = instance.props !== newProps; 11408 !(instance.props === undefined || !hasMutatedProps) ? warningWithoutStack$1(false, '%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name) : void 0; 11409 var noInstanceDefaultProps = !instance.defaultProps; 11410 !noInstanceDefaultProps ? warningWithoutStack$1(false, '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) : void 0; 11411 11412 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) { 11413 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); 11414 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor)); 11415 } 11416 11417 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function'; 11418 !noInstanceGetDerivedStateFromProps ? warningWithoutStack$1(false, '%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name) : void 0; 11419 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function'; 11420 !noInstanceGetDerivedStateFromCatch ? warningWithoutStack$1(false, '%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name) : void 0; 11421 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function'; 11422 !noStaticGetSnapshotBeforeUpdate ? warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name) : void 0; 11423 var _state = instance.state; 11424 if (_state && (typeof _state !== 'object' || isArray$1(_state))) { 11425 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name); 11426 } 11427 if (typeof instance.getChildContext === 'function') { 11428 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0; 11429 } 11430 } 11431 } 11432 11433 function adoptClassInstance(workInProgress, instance) { 11434 instance.updater = classComponentUpdater; 11435 workInProgress.stateNode = instance; 11436 // The instance needs access to the fiber so that it can schedule updates 11437 set(instance, workInProgress); 11438 { 11439 instance._reactInternalInstance = fakeInternalInstance; 11440 } 11441 } 11442 11443 function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) { 11444 var isLegacyContextConsumer = false; 11445 var unmaskedContext = emptyContextObject; 11446 var context = null; 11447 var contextType = ctor.contextType; 11448 11449 { 11450 if ('contextType' in ctor) { 11451 var isValid = 11452 // Allow null for conditional declaration 11453 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer> 11454 11455 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) { 11456 didWarnAboutInvalidateContextType.add(ctor); 11457 11458 var addendum = ''; 11459 if (contextType === undefined) { 11460 addendum = ' However, it is set to undefined. ' + 'This can be caused by a typo or by mixing up named and default imports. ' + 'This can also happen due to a circular dependency, so ' + 'try moving the createContext() call to a separate file.'; 11461 } else if (typeof contextType !== 'object') { 11462 addendum = ' However, it is set to a ' + typeof contextType + '.'; 11463 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) { 11464 addendum = ' Did you accidentally pass the Context.Provider instead?'; 11465 } else if (contextType._context !== undefined) { 11466 // <Context.Consumer> 11467 addendum = ' Did you accidentally pass the Context.Consumer instead?'; 11468 } else { 11469 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.'; 11470 } 11471 warningWithoutStack$1(false, '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum); 11472 } 11473 } 11474 } 11475 11476 if (typeof contextType === 'object' && contextType !== null) { 11477 context = readContext(contextType); 11478 } else { 11479 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); 11480 var contextTypes = ctor.contextTypes; 11481 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined; 11482 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject; 11483 } 11484 11485 // Instantiate twice to help detect side-effects. 11486 { 11487 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) { 11488 new ctor(props, context); // eslint-disable-line no-new 11489 } 11490 } 11491 11492 var instance = new ctor(props, context); 11493 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null; 11494 adoptClassInstance(workInProgress, instance); 11495 11496 { 11497 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) { 11498 var componentName = getComponentName(ctor) || 'Component'; 11499 if (!didWarnAboutUninitializedState.has(componentName)) { 11500 didWarnAboutUninitializedState.add(componentName); 11501 warningWithoutStack$1(false, '`%s` uses `getDerivedStateFromProps` but its initial state is ' + '%s. This is not recommended. Instead, define the initial state by ' + 'assigning an object to `this.state` in the constructor of `%s`. ' + 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.', componentName, instance.state === null ? 'null' : 'undefined', componentName); 11502 } 11503 } 11504 11505 // If new component APIs are defined, "unsafe" lifecycles won't be called. 11506 // Warn about these lifecycles if they are present. 11507 // Don't warn about react-lifecycles-compat polyfilled methods though. 11508 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') { 11509 var foundWillMountName = null; 11510 var foundWillReceivePropsName = null; 11511 var foundWillUpdateName = null; 11512 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) { 11513 foundWillMountName = 'componentWillMount'; 11514 } else if (typeof instance.UNSAFE_componentWillMount === 'function') { 11515 foundWillMountName = 'UNSAFE_componentWillMount'; 11516 } 11517 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) { 11518 foundWillReceivePropsName = 'componentWillReceiveProps'; 11519 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') { 11520 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps'; 11521 } 11522 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) { 11523 foundWillUpdateName = 'componentWillUpdate'; 11524 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') { 11525 foundWillUpdateName = 'UNSAFE_componentWillUpdate'; 11526 } 11527 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) { 11528 var _componentName = getComponentName(ctor) || 'Component'; 11529 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()'; 11530 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) { 11531 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); 11532 warningWithoutStack$1(false, 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' + '%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n' + 'The above lifecycles should be removed. Learn more about this warning here:\n' + 'https://fb.me/react-async-component-lifecycle-hooks', _componentName, newApiName, foundWillMountName !== null ? '\n ' + foundWillMountName : '', foundWillReceivePropsName !== null ? '\n ' + foundWillReceivePropsName : '', foundWillUpdateName !== null ? '\n ' + foundWillUpdateName : ''); 11533 } 11534 } 11535 } 11536 } 11537 11538 // Cache unmasked context so we can avoid recreating masked context unless necessary. 11539 // ReactFiberContext usually updates this cache but can't for newly-created instances. 11540 if (isLegacyContextConsumer) { 11541 cacheContext(workInProgress, unmaskedContext, context); 11542 } 11543 11544 return instance; 11545 } 11546 11547 function callComponentWillMount(workInProgress, instance) { 11548 startPhaseTimer(workInProgress, 'componentWillMount'); 11549 var oldState = instance.state; 11550 11551 if (typeof instance.componentWillMount === 'function') { 11552 instance.componentWillMount(); 11553 } 11554 if (typeof instance.UNSAFE_componentWillMount === 'function') { 11555 instance.UNSAFE_componentWillMount(); 11556 } 11557 11558 stopPhaseTimer(); 11559 11560 if (oldState !== instance.state) { 11561 { 11562 warningWithoutStack$1(false, '%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component'); 11563 } 11564 classComponentUpdater.enqueueReplaceState(instance, instance.state, null); 11565 } 11566 } 11567 11568 function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) { 11569 var oldState = instance.state; 11570 startPhaseTimer(workInProgress, 'componentWillReceiveProps'); 11571 if (typeof instance.componentWillReceiveProps === 'function') { 11572 instance.componentWillReceiveProps(newProps, nextContext); 11573 } 11574 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') { 11575 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext); 11576 } 11577 stopPhaseTimer(); 11578 11579 if (instance.state !== oldState) { 11580 { 11581 var componentName = getComponentName(workInProgress.type) || 'Component'; 11582 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { 11583 didWarnAboutStateAssignmentForComponent.add(componentName); 11584 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName); 11585 } 11586 } 11587 classComponentUpdater.enqueueReplaceState(instance, instance.state, null); 11588 } 11589 } 11590 11591 // Invokes the mount life-cycles on a previously never rendered instance. 11592 function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) { 11593 { 11594 checkClassInstance(workInProgress, ctor, newProps); 11595 } 11596 11597 var instance = workInProgress.stateNode; 11598 instance.props = newProps; 11599 instance.state = workInProgress.memoizedState; 11600 instance.refs = emptyRefsObject; 11601 11602 var contextType = ctor.contextType; 11603 if (typeof contextType === 'object' && contextType !== null) { 11604 instance.context = readContext(contextType); 11605 } else { 11606 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); 11607 instance.context = getMaskedContext(workInProgress, unmaskedContext); 11608 } 11609 11610 { 11611 if (instance.state === newProps) { 11612 var componentName = getComponentName(ctor) || 'Component'; 11613 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { 11614 didWarnAboutDirectlyAssigningPropsToState.add(componentName); 11615 warningWithoutStack$1(false, '%s: It is not recommended to assign props directly to state ' + "because updates to props won't be reflected in state. " + 'In most cases, it is better to use props directly.', componentName); 11616 } 11617 } 11618 11619 if (workInProgress.mode & StrictMode) { 11620 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance); 11621 11622 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance); 11623 } 11624 11625 if (warnAboutDeprecatedLifecycles) { 11626 ReactStrictModeWarnings.recordDeprecationWarnings(workInProgress, instance); 11627 } 11628 } 11629 11630 var updateQueue = workInProgress.updateQueue; 11631 if (updateQueue !== null) { 11632 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime); 11633 instance.state = workInProgress.memoizedState; 11634 } 11635 11636 var getDerivedStateFromProps = ctor.getDerivedStateFromProps; 11637 if (typeof getDerivedStateFromProps === 'function') { 11638 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps); 11639 instance.state = workInProgress.memoizedState; 11640 } 11641 11642 // In order to support react-lifecycles-compat polyfilled components, 11643 // Unsafe lifecycles should not be invoked for components using the new APIs. 11644 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) { 11645 callComponentWillMount(workInProgress, instance); 11646 // If we had additional state updates during this life-cycle, let's 11647 // process them now. 11648 updateQueue = workInProgress.updateQueue; 11649 if (updateQueue !== null) { 11650 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime); 11651 instance.state = workInProgress.memoizedState; 11652 } 11653 } 11654 11655 if (typeof instance.componentDidMount === 'function') { 11656 workInProgress.effectTag |= Update; 11657 } 11658 } 11659 11660 function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) { 11661 var instance = workInProgress.stateNode; 11662 11663 var oldProps = workInProgress.memoizedProps; 11664 instance.props = oldProps; 11665 11666 var oldContext = instance.context; 11667 var contextType = ctor.contextType; 11668 var nextContext = void 0; 11669 if (typeof contextType === 'object' && contextType !== null) { 11670 nextContext = readContext(contextType); 11671 } else { 11672 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); 11673 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext); 11674 } 11675 11676 var getDerivedStateFromProps = ctor.getDerivedStateFromProps; 11677 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; 11678 11679 // Note: During these life-cycles, instance.props/instance.state are what 11680 // ever the previously attempted to render - not the "current". However, 11681 // during componentDidUpdate we pass the "current" props. 11682 11683 // In order to support react-lifecycles-compat polyfilled components, 11684 // Unsafe lifecycles should not be invoked for components using the new APIs. 11685 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) { 11686 if (oldProps !== newProps || oldContext !== nextContext) { 11687 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext); 11688 } 11689 } 11690 11691 resetHasForceUpdateBeforeProcessing(); 11692 11693 var oldState = workInProgress.memoizedState; 11694 var newState = instance.state = oldState; 11695 var updateQueue = workInProgress.updateQueue; 11696 if (updateQueue !== null) { 11697 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime); 11698 newState = workInProgress.memoizedState; 11699 } 11700 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) { 11701 // If an update was already in progress, we should schedule an Update 11702 // effect even though we're bailing out, so that cWU/cDU are called. 11703 if (typeof instance.componentDidMount === 'function') { 11704 workInProgress.effectTag |= Update; 11705 } 11706 return false; 11707 } 11708 11709 if (typeof getDerivedStateFromProps === 'function') { 11710 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps); 11711 newState = workInProgress.memoizedState; 11712 } 11713 11714 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext); 11715 11716 if (shouldUpdate) { 11717 // In order to support react-lifecycles-compat polyfilled components, 11718 // Unsafe lifecycles should not be invoked for components using the new APIs. 11719 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) { 11720 startPhaseTimer(workInProgress, 'componentWillMount'); 11721 if (typeof instance.componentWillMount === 'function') { 11722 instance.componentWillMount(); 11723 } 11724 if (typeof instance.UNSAFE_componentWillMount === 'function') { 11725 instance.UNSAFE_componentWillMount(); 11726 } 11727 stopPhaseTimer(); 11728 } 11729 if (typeof instance.componentDidMount === 'function') { 11730 workInProgress.effectTag |= Update; 11731 } 11732 } else { 11733 // If an update was already in progress, we should schedule an Update 11734 // effect even though we're bailing out, so that cWU/cDU are called. 11735 if (typeof instance.componentDidMount === 'function') { 11736 workInProgress.effectTag |= Update; 11737 } 11738 11739 // If shouldComponentUpdate returned false, we should still update the 11740 // memoized state to indicate that this work can be reused. 11741 workInProgress.memoizedProps = newProps; 11742 workInProgress.memoizedState = newState; 11743 } 11744 11745 // Update the existing instance's state, props, and context pointers even 11746 // if shouldComponentUpdate returns false. 11747 instance.props = newProps; 11748 instance.state = newState; 11749 instance.context = nextContext; 11750 11751 return shouldUpdate; 11752 } 11753 11754 // Invokes the update life-cycles and returns false if it shouldn't rerender. 11755 function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) { 11756 var instance = workInProgress.stateNode; 11757 11758 var oldProps = workInProgress.memoizedProps; 11759 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps); 11760 11761 var oldContext = instance.context; 11762 var contextType = ctor.contextType; 11763 var nextContext = void 0; 11764 if (typeof contextType === 'object' && contextType !== null) { 11765 nextContext = readContext(contextType); 11766 } else { 11767 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); 11768 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext); 11769 } 11770 11771 var getDerivedStateFromProps = ctor.getDerivedStateFromProps; 11772 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; 11773 11774 // Note: During these life-cycles, instance.props/instance.state are what 11775 // ever the previously attempted to render - not the "current". However, 11776 // during componentDidUpdate we pass the "current" props. 11777 11778 // In order to support react-lifecycles-compat polyfilled components, 11779 // Unsafe lifecycles should not be invoked for components using the new APIs. 11780 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) { 11781 if (oldProps !== newProps || oldContext !== nextContext) { 11782 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext); 11783 } 11784 } 11785 11786 resetHasForceUpdateBeforeProcessing(); 11787 11788 var oldState = workInProgress.memoizedState; 11789 var newState = instance.state = oldState; 11790 var updateQueue = workInProgress.updateQueue; 11791 if (updateQueue !== null) { 11792 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime); 11793 newState = workInProgress.memoizedState; 11794 } 11795 11796 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) { 11797 // If an update was already in progress, we should schedule an Update 11798 // effect even though we're bailing out, so that cWU/cDU are called. 11799 if (typeof instance.componentDidUpdate === 'function') { 11800 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) { 11801 workInProgress.effectTag |= Update; 11802 } 11803 } 11804 if (typeof instance.getSnapshotBeforeUpdate === 'function') { 11805 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) { 11806 workInProgress.effectTag |= Snapshot; 11807 } 11808 } 11809 return false; 11810 } 11811 11812 if (typeof getDerivedStateFromProps === 'function') { 11813 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps); 11814 newState = workInProgress.memoizedState; 11815 } 11816 11817 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext); 11818 11819 if (shouldUpdate) { 11820 // In order to support react-lifecycles-compat polyfilled components, 11821 // Unsafe lifecycles should not be invoked for components using the new APIs. 11822 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) { 11823 startPhaseTimer(workInProgress, 'componentWillUpdate'); 11824 if (typeof instance.componentWillUpdate === 'function') { 11825 instance.componentWillUpdate(newProps, newState, nextContext); 11826 } 11827 if (typeof instance.UNSAFE_componentWillUpdate === 'function') { 11828 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext); 11829 } 11830 stopPhaseTimer(); 11831 } 11832 if (typeof instance.componentDidUpdate === 'function') { 11833 workInProgress.effectTag |= Update; 11834 } 11835 if (typeof instance.getSnapshotBeforeUpdate === 'function') { 11836 workInProgress.effectTag |= Snapshot; 11837 } 11838 } else { 11839 // If an update was already in progress, we should schedule an Update 11840 // effect even though we're bailing out, so that cWU/cDU are called. 11841 if (typeof instance.componentDidUpdate === 'function') { 11842 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) { 11843 workInProgress.effectTag |= Update; 11844 } 11845 } 11846 if (typeof instance.getSnapshotBeforeUpdate === 'function') { 11847 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) { 11848 workInProgress.effectTag |= Snapshot; 11849 } 11850 } 11851 11852 // If shouldComponentUpdate returned false, we should still update the 11853 // memoized props/state to indicate that this work can be reused. 11854 workInProgress.memoizedProps = newProps; 11855 workInProgress.memoizedState = newState; 11856 } 11857 11858 // Update the existing instance's state, props, and context pointers even 11859 // if shouldComponentUpdate returns false. 11860 instance.props = newProps; 11861 instance.state = newState; 11862 instance.context = nextContext; 11863 11864 return shouldUpdate; 11865 } 11866 11867 var didWarnAboutMaps = void 0; 11868 var didWarnAboutGenerators = void 0; 11869 var didWarnAboutStringRefInStrictMode = void 0; 11870 var ownerHasKeyUseWarning = void 0; 11871 var ownerHasFunctionTypeWarning = void 0; 11872 var warnForMissingKey = function (child) {}; 11873 11874 { 11875 didWarnAboutMaps = false; 11876 didWarnAboutGenerators = false; 11877 didWarnAboutStringRefInStrictMode = {}; 11878 11879 /** 11880 * Warn if there's no key explicitly set on dynamic arrays of children or 11881 * object keys are not valid. This allows us to keep track of children between 11882 * updates. 11883 */ 11884 ownerHasKeyUseWarning = {}; 11885 ownerHasFunctionTypeWarning = {}; 11886 11887 warnForMissingKey = function (child) { 11888 if (child === null || typeof child !== 'object') { 11889 return; 11890 } 11891 if (!child._store || child._store.validated || child.key != null) { 11892 return; 11893 } 11894 !(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; 11895 child._store.validated = true; 11896 11897 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev(); 11898 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) { 11899 return; 11900 } 11901 ownerHasKeyUseWarning[currentComponentErrorInfo] = true; 11902 11903 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.'); 11904 }; 11905 } 11906 11907 var isArray = Array.isArray; 11908 11909 function coerceRef(returnFiber, current$$1, element) { 11910 var mixedRef = element.ref; 11911 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') { 11912 { 11913 if (returnFiber.mode & StrictMode) { 11914 var componentName = getComponentName(returnFiber.type) || 'Component'; 11915 if (!didWarnAboutStringRefInStrictMode[componentName]) { 11916 warningWithoutStack$1(false, 'A string ref, "%s", has been found within a strict mode tree. ' + 'String refs are a source of potential bugs and should be avoided. ' + 'We recommend using createRef() instead.' + '\n%s' + '\n\nLearn more about using refs safely here:' + '\nhttps://fb.me/react-strict-mode-string-ref', mixedRef, getStackByFiberInDevAndProd(returnFiber)); 11917 didWarnAboutStringRefInStrictMode[componentName] = true; 11918 } 11919 } 11920 } 11921 11922 if (element._owner) { 11923 var owner = element._owner; 11924 var inst = void 0; 11925 if (owner) { 11926 var ownerFiber = owner; 11927 !(ownerFiber.tag === ClassComponent) ? invariant(false, 'Function components cannot have refs. Did you mean to use React.forwardRef()?') : void 0; 11928 inst = ownerFiber.stateNode; 11929 } 11930 !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; 11931 var stringRef = '' + mixedRef; 11932 // Check if previous string ref matches new string ref 11933 if (current$$1 !== null && current$$1.ref !== null && typeof current$$1.ref === 'function' && current$$1.ref._stringRef === stringRef) { 11934 return current$$1.ref; 11935 } 11936 var ref = function (value) { 11937 var refs = inst.refs; 11938 if (refs === emptyRefsObject) { 11939 // This is a lazy pooled frozen object, so we need to initialize. 11940 refs = inst.refs = {}; 11941 } 11942 if (value === null) { 11943 delete refs[stringRef]; 11944 } else { 11945 refs[stringRef] = value; 11946 } 11947 }; 11948 ref._stringRef = stringRef; 11949 return ref; 11950 } else { 11951 !(typeof mixedRef === 'string') ? invariant(false, 'Expected ref to be a function, a string, an object returned by React.createRef(), or null.') : void 0; 11952 !element._owner ? invariant(false, 'Element ref was specified as a string (%s) but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component\'s render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information.', mixedRef) : void 0; 11953 } 11954 } 11955 return mixedRef; 11956 } 11957 11958 function throwOnInvalidObjectType(returnFiber, newChild) { 11959 if (returnFiber.type !== 'textarea') { 11960 var addendum = ''; 11961 { 11962 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev(); 11963 } 11964 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); 11965 } 11966 } 11967 11968 function warnOnFunctionType() { 11969 var currentComponentErrorInfo = '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.' + getCurrentFiberStackInDev(); 11970 11971 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { 11972 return; 11973 } 11974 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; 11975 11976 warning$1(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.'); 11977 } 11978 11979 // This wrapper function exists because I expect to clone the code in each path 11980 // to be able to optimize each path individually by branching early. This needs 11981 // a compiler or we can do it manually. Helpers that don't need this branching 11982 // live outside of this function. 11983 function ChildReconciler(shouldTrackSideEffects) { 11984 function deleteChild(returnFiber, childToDelete) { 11985 if (!shouldTrackSideEffects) { 11986 // Noop. 11987 return; 11988 } 11989 // Deletions are added in reversed order so we add it to the front. 11990 // At this point, the return fiber's effect list is empty except for 11991 // deletions, so we can just append the deletion to the list. The remaining 11992 // effects aren't added until the complete phase. Once we implement 11993 // resuming, this may not be true. 11994 var last = returnFiber.lastEffect; 11995 if (last !== null) { 11996 last.nextEffect = childToDelete; 11997 returnFiber.lastEffect = childToDelete; 11998 } else { 11999 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; 12000 } 12001 childToDelete.nextEffect = null; 12002 childToDelete.effectTag = Deletion; 12003 } 12004 12005 function deleteRemainingChildren(returnFiber, currentFirstChild) { 12006 if (!shouldTrackSideEffects) { 12007 // Noop. 12008 return null; 12009 } 12010 12011 // TODO: For the shouldClone case, this could be micro-optimized a bit by 12012 // assuming that after the first child we've already added everything. 12013 var childToDelete = currentFirstChild; 12014 while (childToDelete !== null) { 12015 deleteChild(returnFiber, childToDelete); 12016 childToDelete = childToDelete.sibling; 12017 } 12018 return null; 12019 } 12020 12021 function mapRemainingChildren(returnFiber, currentFirstChild) { 12022 // Add the remaining children to a temporary map so that we can find them by 12023 // keys quickly. Implicit (null) keys get added to this set with their index 12024 var existingChildren = new Map(); 12025 12026 var existingChild = currentFirstChild; 12027 while (existingChild !== null) { 12028 if (existingChild.key !== null) { 12029 existingChildren.set(existingChild.key, existingChild); 12030 } else { 12031 existingChildren.set(existingChild.index, existingChild); 12032 } 12033 existingChild = existingChild.sibling; 12034 } 12035 return existingChildren; 12036 } 12037 12038 function useFiber(fiber, pendingProps, expirationTime) { 12039 // We currently set sibling to null and index to 0 here because it is easy 12040 // to forget to do before returning it. E.g. for the single child case. 12041 var clone = createWorkInProgress(fiber, pendingProps, expirationTime); 12042 clone.index = 0; 12043 clone.sibling = null; 12044 return clone; 12045 } 12046 12047 function placeChild(newFiber, lastPlacedIndex, newIndex) { 12048 newFiber.index = newIndex; 12049 if (!shouldTrackSideEffects) { 12050 // Noop. 12051 return lastPlacedIndex; 12052 } 12053 var current$$1 = newFiber.alternate; 12054 if (current$$1 !== null) { 12055 var oldIndex = current$$1.index; 12056 if (oldIndex < lastPlacedIndex) { 12057 // This is a move. 12058 newFiber.effectTag = Placement; 12059 return lastPlacedIndex; 12060 } else { 12061 // This item can stay in place. 12062 return oldIndex; 12063 } 12064 } else { 12065 // This is an insertion. 12066 newFiber.effectTag = Placement; 12067 return lastPlacedIndex; 12068 } 12069 } 12070 12071 function placeSingleChild(newFiber) { 12072 // This is simpler for the single child case. We only need to do a 12073 // placement for inserting new children. 12074 if (shouldTrackSideEffects && newFiber.alternate === null) { 12075 newFiber.effectTag = Placement; 12076 } 12077 return newFiber; 12078 } 12079 12080 function updateTextNode(returnFiber, current$$1, textContent, expirationTime) { 12081 if (current$$1 === null || current$$1.tag !== HostText) { 12082 // Insert 12083 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime); 12084 created.return = returnFiber; 12085 return created; 12086 } else { 12087 // Update 12088 var existing = useFiber(current$$1, textContent, expirationTime); 12089 existing.return = returnFiber; 12090 return existing; 12091 } 12092 } 12093 12094 function updateElement(returnFiber, current$$1, element, expirationTime) { 12095 if (current$$1 !== null && current$$1.elementType === element.type) { 12096 // Move based on index 12097 var existing = useFiber(current$$1, element.props, expirationTime); 12098 existing.ref = coerceRef(returnFiber, current$$1, element); 12099 existing.return = returnFiber; 12100 { 12101 existing._debugSource = element._source; 12102 existing._debugOwner = element._owner; 12103 } 12104 return existing; 12105 } else { 12106 // Insert 12107 var created = createFiberFromElement(element, returnFiber.mode, expirationTime); 12108 created.ref = coerceRef(returnFiber, current$$1, element); 12109 created.return = returnFiber; 12110 return created; 12111 } 12112 } 12113 12114 function updatePortal(returnFiber, current$$1, portal, expirationTime) { 12115 if (current$$1 === null || current$$1.tag !== HostPortal || current$$1.stateNode.containerInfo !== portal.containerInfo || current$$1.stateNode.implementation !== portal.implementation) { 12116 // Insert 12117 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime); 12118 created.return = returnFiber; 12119 return created; 12120 } else { 12121 // Update 12122 var existing = useFiber(current$$1, portal.children || [], expirationTime); 12123 existing.return = returnFiber; 12124 return existing; 12125 } 12126 } 12127 12128 function updateFragment(returnFiber, current$$1, fragment, expirationTime, key) { 12129 if (current$$1 === null || current$$1.tag !== Fragment) { 12130 // Insert 12131 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key); 12132 created.return = returnFiber; 12133 return created; 12134 } else { 12135 // Update 12136 var existing = useFiber(current$$1, fragment, expirationTime); 12137 existing.return = returnFiber; 12138 return existing; 12139 } 12140 } 12141 12142 function createChild(returnFiber, newChild, expirationTime) { 12143 if (typeof newChild === 'string' || typeof newChild === 'number') { 12144 // Text nodes don't have keys. If the previous node is implicitly keyed 12145 // we can continue to replace it without aborting even if it is not a text 12146 // node. 12147 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime); 12148 created.return = returnFiber; 12149 return created; 12150 } 12151 12152 if (typeof newChild === 'object' && newChild !== null) { 12153 switch (newChild.$$typeof) { 12154 case REACT_ELEMENT_TYPE: 12155 { 12156 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime); 12157 _created.ref = coerceRef(returnFiber, null, newChild); 12158 _created.return = returnFiber; 12159 return _created; 12160 } 12161 case REACT_PORTAL_TYPE: 12162 { 12163 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime); 12164 _created2.return = returnFiber; 12165 return _created2; 12166 } 12167 } 12168 12169 if (isArray(newChild) || getIteratorFn(newChild)) { 12170 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null); 12171 _created3.return = returnFiber; 12172 return _created3; 12173 } 12174 12175 throwOnInvalidObjectType(returnFiber, newChild); 12176 } 12177 12178 { 12179 if (typeof newChild === 'function') { 12180 warnOnFunctionType(); 12181 } 12182 } 12183 12184 return null; 12185 } 12186 12187 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) { 12188 // Update the fiber if the keys match, otherwise return null. 12189 12190 var key = oldFiber !== null ? oldFiber.key : null; 12191 12192 if (typeof newChild === 'string' || typeof newChild === 'number') { 12193 // Text nodes don't have keys. If the previous node is implicitly keyed 12194 // we can continue to replace it without aborting even if it is not a text 12195 // node. 12196 if (key !== null) { 12197 return null; 12198 } 12199 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime); 12200 } 12201 12202 if (typeof newChild === 'object' && newChild !== null) { 12203 switch (newChild.$$typeof) { 12204 case REACT_ELEMENT_TYPE: 12205 { 12206 if (newChild.key === key) { 12207 if (newChild.type === REACT_FRAGMENT_TYPE) { 12208 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key); 12209 } 12210 return updateElement(returnFiber, oldFiber, newChild, expirationTime); 12211 } else { 12212 return null; 12213 } 12214 } 12215 case REACT_PORTAL_TYPE: 12216 { 12217 if (newChild.key === key) { 12218 return updatePortal(returnFiber, oldFiber, newChild, expirationTime); 12219 } else { 12220 return null; 12221 } 12222 } 12223 } 12224 12225 if (isArray(newChild) || getIteratorFn(newChild)) { 12226 if (key !== null) { 12227 return null; 12228 } 12229 12230 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null); 12231 } 12232 12233 throwOnInvalidObjectType(returnFiber, newChild); 12234 } 12235 12236 { 12237 if (typeof newChild === 'function') { 12238 warnOnFunctionType(); 12239 } 12240 } 12241 12242 return null; 12243 } 12244 12245 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) { 12246 if (typeof newChild === 'string' || typeof newChild === 'number') { 12247 // Text nodes don't have keys, so we neither have to check the old nor 12248 // new node for the key. If both are text nodes, they match. 12249 var matchedFiber = existingChildren.get(newIdx) || null; 12250 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime); 12251 } 12252 12253 if (typeof newChild === 'object' && newChild !== null) { 12254 switch (newChild.$$typeof) { 12255 case REACT_ELEMENT_TYPE: 12256 { 12257 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null; 12258 if (newChild.type === REACT_FRAGMENT_TYPE) { 12259 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key); 12260 } 12261 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime); 12262 } 12263 case REACT_PORTAL_TYPE: 12264 { 12265 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null; 12266 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime); 12267 } 12268 } 12269 12270 if (isArray(newChild) || getIteratorFn(newChild)) { 12271 var _matchedFiber3 = existingChildren.get(newIdx) || null; 12272 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null); 12273 } 12274 12275 throwOnInvalidObjectType(returnFiber, newChild); 12276 } 12277 12278 { 12279 if (typeof newChild === 'function') { 12280 warnOnFunctionType(); 12281 } 12282 } 12283 12284 return null; 12285 } 12286 12287 /** 12288 * Warns if there is a duplicate or missing key 12289 */ 12290 function warnOnInvalidKey(child, knownKeys) { 12291 { 12292 if (typeof child !== 'object' || child === null) { 12293 return knownKeys; 12294 } 12295 switch (child.$$typeof) { 12296 case REACT_ELEMENT_TYPE: 12297 case REACT_PORTAL_TYPE: 12298 warnForMissingKey(child); 12299 var key = child.key; 12300 if (typeof key !== 'string') { 12301 break; 12302 } 12303 if (knownKeys === null) { 12304 knownKeys = new Set(); 12305 knownKeys.add(key); 12306 break; 12307 } 12308 if (!knownKeys.has(key)) { 12309 knownKeys.add(key); 12310 break; 12311 } 12312 warning$1(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.', key); 12313 break; 12314 default: 12315 break; 12316 } 12317 } 12318 return knownKeys; 12319 } 12320 12321 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) { 12322 // This algorithm can't optimize by searching from both ends since we 12323 // don't have backpointers on fibers. I'm trying to see how far we can get 12324 // with that model. If it ends up not being worth the tradeoffs, we can 12325 // add it later. 12326 12327 // Even with a two ended optimization, we'd want to optimize for the case 12328 // where there are few changes and brute force the comparison instead of 12329 // going for the Map. It'd like to explore hitting that path first in 12330 // forward-only mode and only go for the Map once we notice that we need 12331 // lots of look ahead. This doesn't handle reversal as well as two ended 12332 // search but that's unusual. Besides, for the two ended optimization to 12333 // work on Iterables, we'd need to copy the whole set. 12334 12335 // In this first iteration, we'll just live with hitting the bad case 12336 // (adding everything to a Map) in for every insert/move. 12337 12338 // If you change this code, also update reconcileChildrenIterator() which 12339 // uses the same algorithm. 12340 12341 { 12342 // First, validate keys. 12343 var knownKeys = null; 12344 for (var i = 0; i < newChildren.length; i++) { 12345 var child = newChildren[i]; 12346 knownKeys = warnOnInvalidKey(child, knownKeys); 12347 } 12348 } 12349 12350 var resultingFirstChild = null; 12351 var previousNewFiber = null; 12352 12353 var oldFiber = currentFirstChild; 12354 var lastPlacedIndex = 0; 12355 var newIdx = 0; 12356 var nextOldFiber = null; 12357 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) { 12358 if (oldFiber.index > newIdx) { 12359 nextOldFiber = oldFiber; 12360 oldFiber = null; 12361 } else { 12362 nextOldFiber = oldFiber.sibling; 12363 } 12364 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime); 12365 if (newFiber === null) { 12366 // TODO: This breaks on empty slots like null children. That's 12367 // unfortunate because it triggers the slow path all the time. We need 12368 // a better way to communicate whether this was a miss or null, 12369 // boolean, undefined, etc. 12370 if (oldFiber === null) { 12371 oldFiber = nextOldFiber; 12372 } 12373 break; 12374 } 12375 if (shouldTrackSideEffects) { 12376 if (oldFiber && newFiber.alternate === null) { 12377 // We matched the slot, but we didn't reuse the existing fiber, so we 12378 // need to delete the existing child. 12379 deleteChild(returnFiber, oldFiber); 12380 } 12381 } 12382 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx); 12383 if (previousNewFiber === null) { 12384 // TODO: Move out of the loop. This only happens for the first run. 12385 resultingFirstChild = newFiber; 12386 } else { 12387 // TODO: Defer siblings if we're not at the right index for this slot. 12388 // I.e. if we had null values before, then we want to defer this 12389 // for each null value. However, we also don't want to call updateSlot 12390 // with the previous one. 12391 previousNewFiber.sibling = newFiber; 12392 } 12393 previousNewFiber = newFiber; 12394 oldFiber = nextOldFiber; 12395 } 12396 12397 if (newIdx === newChildren.length) { 12398 // We've reached the end of the new children. We can delete the rest. 12399 deleteRemainingChildren(returnFiber, oldFiber); 12400 return resultingFirstChild; 12401 } 12402 12403 if (oldFiber === null) { 12404 // If we don't have any more existing children we can choose a fast path 12405 // since the rest will all be insertions. 12406 for (; newIdx < newChildren.length; newIdx++) { 12407 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime); 12408 if (!_newFiber) { 12409 continue; 12410 } 12411 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx); 12412 if (previousNewFiber === null) { 12413 // TODO: Move out of the loop. This only happens for the first run. 12414 resultingFirstChild = _newFiber; 12415 } else { 12416 previousNewFiber.sibling = _newFiber; 12417 } 12418 previousNewFiber = _newFiber; 12419 } 12420 return resultingFirstChild; 12421 } 12422 12423 // Add all children to a key map for quick lookups. 12424 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); 12425 12426 // Keep scanning and use the map to restore deleted items as moves. 12427 for (; newIdx < newChildren.length; newIdx++) { 12428 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime); 12429 if (_newFiber2) { 12430 if (shouldTrackSideEffects) { 12431 if (_newFiber2.alternate !== null) { 12432 // The new fiber is a work in progress, but if there exists a 12433 // current, that means that we reused the fiber. We need to delete 12434 // it from the child list so that we don't add it to the deletion 12435 // list. 12436 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key); 12437 } 12438 } 12439 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx); 12440 if (previousNewFiber === null) { 12441 resultingFirstChild = _newFiber2; 12442 } else { 12443 previousNewFiber.sibling = _newFiber2; 12444 } 12445 previousNewFiber = _newFiber2; 12446 } 12447 } 12448 12449 if (shouldTrackSideEffects) { 12450 // Any existing children that weren't consumed above were deleted. We need 12451 // to add them to the deletion list. 12452 existingChildren.forEach(function (child) { 12453 return deleteChild(returnFiber, child); 12454 }); 12455 } 12456 12457 return resultingFirstChild; 12458 } 12459 12460 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) { 12461 // This is the same implementation as reconcileChildrenArray(), 12462 // but using the iterator instead. 12463 12464 var iteratorFn = getIteratorFn(newChildrenIterable); 12465 !(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; 12466 12467 { 12468 // We don't support rendering Generators because it's a mutation. 12469 // See https://github.com/facebook/react/issues/12995 12470 if (typeof Symbol === 'function' && 12471 // $FlowFixMe Flow doesn't know about toStringTag 12472 newChildrenIterable[Symbol.toStringTag] === 'Generator') { 12473 !didWarnAboutGenerators ? warning$1(false, 'Using Generators as children is unsupported and will likely yield ' + 'unexpected results because enumerating a generator mutates it. ' + 'You may convert it to an array with `Array.from()` or the ' + '`[...spread]` operator before rendering. Keep in mind ' + 'you might need to polyfill these features for older browsers.') : void 0; 12474 didWarnAboutGenerators = true; 12475 } 12476 12477 // Warn about using Maps as children 12478 if (newChildrenIterable.entries === iteratorFn) { 12479 !didWarnAboutMaps ? warning$1(false, 'Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.') : void 0; 12480 didWarnAboutMaps = true; 12481 } 12482 12483 // First, validate keys. 12484 // We'll get a different iterator later for the main pass. 12485 var _newChildren = iteratorFn.call(newChildrenIterable); 12486 if (_newChildren) { 12487 var knownKeys = null; 12488 var _step = _newChildren.next(); 12489 for (; !_step.done; _step = _newChildren.next()) { 12490 var child = _step.value; 12491 knownKeys = warnOnInvalidKey(child, knownKeys); 12492 } 12493 } 12494 } 12495 12496 var newChildren = iteratorFn.call(newChildrenIterable); 12497 !(newChildren != null) ? invariant(false, 'An iterable object provided no iterator.') : void 0; 12498 12499 var resultingFirstChild = null; 12500 var previousNewFiber = null; 12501 12502 var oldFiber = currentFirstChild; 12503 var lastPlacedIndex = 0; 12504 var newIdx = 0; 12505 var nextOldFiber = null; 12506 12507 var step = newChildren.next(); 12508 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) { 12509 if (oldFiber.index > newIdx) { 12510 nextOldFiber = oldFiber; 12511 oldFiber = null; 12512 } else { 12513 nextOldFiber = oldFiber.sibling; 12514 } 12515 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime); 12516 if (newFiber === null) { 12517 // TODO: This breaks on empty slots like null children. That's 12518 // unfortunate because it triggers the slow path all the time. We need 12519 // a better way to communicate whether this was a miss or null, 12520 // boolean, undefined, etc. 12521 if (!oldFiber) { 12522 oldFiber = nextOldFiber; 12523 } 12524 break; 12525 } 12526 if (shouldTrackSideEffects) { 12527 if (oldFiber && newFiber.alternate === null) { 12528 // We matched the slot, but we didn't reuse the existing fiber, so we 12529 // need to delete the existing child. 12530 deleteChild(returnFiber, oldFiber); 12531 } 12532 } 12533 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx); 12534 if (previousNewFiber === null) { 12535 // TODO: Move out of the loop. This only happens for the first run. 12536 resultingFirstChild = newFiber; 12537 } else { 12538 // TODO: Defer siblings if we're not at the right index for this slot. 12539 // I.e. if we had null values before, then we want to defer this 12540 // for each null value. However, we also don't want to call updateSlot 12541 // with the previous one. 12542 previousNewFiber.sibling = newFiber; 12543 } 12544 previousNewFiber = newFiber; 12545 oldFiber = nextOldFiber; 12546 } 12547 12548 if (step.done) { 12549 // We've reached the end of the new children. We can delete the rest. 12550 deleteRemainingChildren(returnFiber, oldFiber); 12551 return resultingFirstChild; 12552 } 12553 12554 if (oldFiber === null) { 12555 // If we don't have any more existing children we can choose a fast path 12556 // since the rest will all be insertions. 12557 for (; !step.done; newIdx++, step = newChildren.next()) { 12558 var _newFiber3 = createChild(returnFiber, step.value, expirationTime); 12559 if (_newFiber3 === null) { 12560 continue; 12561 } 12562 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx); 12563 if (previousNewFiber === null) { 12564 // TODO: Move out of the loop. This only happens for the first run. 12565 resultingFirstChild = _newFiber3; 12566 } else { 12567 previousNewFiber.sibling = _newFiber3; 12568 } 12569 previousNewFiber = _newFiber3; 12570 } 12571 return resultingFirstChild; 12572 } 12573 12574 // Add all children to a key map for quick lookups. 12575 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); 12576 12577 // Keep scanning and use the map to restore deleted items as moves. 12578 for (; !step.done; newIdx++, step = newChildren.next()) { 12579 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime); 12580 if (_newFiber4 !== null) { 12581 if (shouldTrackSideEffects) { 12582 if (_newFiber4.alternate !== null) { 12583 // The new fiber is a work in progress, but if there exists a 12584 // current, that means that we reused the fiber. We need to delete 12585 // it from the child list so that we don't add it to the deletion 12586 // list. 12587 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key); 12588 } 12589 } 12590 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx); 12591 if (previousNewFiber === null) { 12592 resultingFirstChild = _newFiber4; 12593 } else { 12594 previousNewFiber.sibling = _newFiber4; 12595 } 12596 previousNewFiber = _newFiber4; 12597 } 12598 } 12599 12600 if (shouldTrackSideEffects) { 12601 // Any existing children that weren't consumed above were deleted. We need 12602 // to add them to the deletion list. 12603 existingChildren.forEach(function (child) { 12604 return deleteChild(returnFiber, child); 12605 }); 12606 } 12607 12608 return resultingFirstChild; 12609 } 12610 12611 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) { 12612 // There's no need to check for keys on text nodes since we don't have a 12613 // way to define them. 12614 if (currentFirstChild !== null && currentFirstChild.tag === HostText) { 12615 // We already have an existing node so let's just update it and delete 12616 // the rest. 12617 deleteRemainingChildren(returnFiber, currentFirstChild.sibling); 12618 var existing = useFiber(currentFirstChild, textContent, expirationTime); 12619 existing.return = returnFiber; 12620 return existing; 12621 } 12622 // The existing first child is not a text node so we need to create one 12623 // and delete the existing ones. 12624 deleteRemainingChildren(returnFiber, currentFirstChild); 12625 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime); 12626 created.return = returnFiber; 12627 return created; 12628 } 12629 12630 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) { 12631 var key = element.key; 12632 var child = currentFirstChild; 12633 while (child !== null) { 12634 // TODO: If key === null and child.key === null, then this only applies to 12635 // the first item in the list. 12636 if (child.key === key) { 12637 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type) { 12638 deleteRemainingChildren(returnFiber, child.sibling); 12639 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime); 12640 existing.ref = coerceRef(returnFiber, child, element); 12641 existing.return = returnFiber; 12642 { 12643 existing._debugSource = element._source; 12644 existing._debugOwner = element._owner; 12645 } 12646 return existing; 12647 } else { 12648 deleteRemainingChildren(returnFiber, child); 12649 break; 12650 } 12651 } else { 12652 deleteChild(returnFiber, child); 12653 } 12654 child = child.sibling; 12655 } 12656 12657 if (element.type === REACT_FRAGMENT_TYPE) { 12658 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key); 12659 created.return = returnFiber; 12660 return created; 12661 } else { 12662 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime); 12663 _created4.ref = coerceRef(returnFiber, currentFirstChild, element); 12664 _created4.return = returnFiber; 12665 return _created4; 12666 } 12667 } 12668 12669 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) { 12670 var key = portal.key; 12671 var child = currentFirstChild; 12672 while (child !== null) { 12673 // TODO: If key === null and child.key === null, then this only applies to 12674 // the first item in the list. 12675 if (child.key === key) { 12676 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) { 12677 deleteRemainingChildren(returnFiber, child.sibling); 12678 var existing = useFiber(child, portal.children || [], expirationTime); 12679 existing.return = returnFiber; 12680 return existing; 12681 } else { 12682 deleteRemainingChildren(returnFiber, child); 12683 break; 12684 } 12685 } else { 12686 deleteChild(returnFiber, child); 12687 } 12688 child = child.sibling; 12689 } 12690 12691 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime); 12692 created.return = returnFiber; 12693 return created; 12694 } 12695 12696 // This API will tag the children with the side-effect of the reconciliation 12697 // itself. They will be added to the side-effect list as we pass through the 12698 // children and the parent. 12699 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) { 12700 // This function is not recursive. 12701 // If the top level item is an array, we treat it as a set of children, 12702 // not as a fragment. Nested arrays on the other hand will be treated as 12703 // fragment nodes. Recursion happens at the normal flow. 12704 12705 // Handle top level unkeyed fragments as if they were arrays. 12706 // This leads to an ambiguity between <>{[...]}</> and <>...</>. 12707 // We treat the ambiguous cases above the same. 12708 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null; 12709 if (isUnkeyedTopLevelFragment) { 12710 newChild = newChild.props.children; 12711 } 12712 12713 // Handle object types 12714 var isObject = typeof newChild === 'object' && newChild !== null; 12715 12716 if (isObject) { 12717 switch (newChild.$$typeof) { 12718 case REACT_ELEMENT_TYPE: 12719 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime)); 12720 case REACT_PORTAL_TYPE: 12721 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime)); 12722 } 12723 } 12724 12725 if (typeof newChild === 'string' || typeof newChild === 'number') { 12726 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime)); 12727 } 12728 12729 if (isArray(newChild)) { 12730 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime); 12731 } 12732 12733 if (getIteratorFn(newChild)) { 12734 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime); 12735 } 12736 12737 if (isObject) { 12738 throwOnInvalidObjectType(returnFiber, newChild); 12739 } 12740 12741 { 12742 if (typeof newChild === 'function') { 12743 warnOnFunctionType(); 12744 } 12745 } 12746 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) { 12747 // If the new child is undefined, and the return fiber is a composite 12748 // component, throw an error. If Fiber return types are disabled, 12749 // we already threw above. 12750 switch (returnFiber.tag) { 12751 case ClassComponent: 12752 { 12753 { 12754 var instance = returnFiber.stateNode; 12755 if (instance.render._isMockFunction) { 12756 // We allow auto-mocks to proceed as if they're returning null. 12757 break; 12758 } 12759 } 12760 } 12761 // Intentionally fall through to the next case, which handles both 12762 // functions and classes 12763 // eslint-disable-next-lined no-fallthrough 12764 case FunctionComponent: 12765 { 12766 var Component = returnFiber.type; 12767 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'); 12768 } 12769 } 12770 } 12771 12772 // Remaining cases are all treated as empty. 12773 return deleteRemainingChildren(returnFiber, currentFirstChild); 12774 } 12775 12776 return reconcileChildFibers; 12777 } 12778 12779 var reconcileChildFibers = ChildReconciler(true); 12780 var mountChildFibers = ChildReconciler(false); 12781 12782 function cloneChildFibers(current$$1, workInProgress) { 12783 !(current$$1 === null || workInProgress.child === current$$1.child) ? invariant(false, 'Resuming work not yet implemented.') : void 0; 12784 12785 if (workInProgress.child === null) { 12786 return; 12787 } 12788 12789 var currentChild = workInProgress.child; 12790 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime); 12791 workInProgress.child = newChild; 12792 12793 newChild.return = workInProgress; 12794 while (currentChild.sibling !== null) { 12795 currentChild = currentChild.sibling; 12796 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime); 12797 newChild.return = workInProgress; 12798 } 12799 newChild.sibling = null; 12800 } 12801 12802 var NO_CONTEXT = {}; 12803 12804 var contextStackCursor$1 = createCursor(NO_CONTEXT); 12805 var contextFiberStackCursor = createCursor(NO_CONTEXT); 12806 var rootInstanceStackCursor = createCursor(NO_CONTEXT); 12807 12808 function requiredContext(c) { 12809 !(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; 12810 return c; 12811 } 12812 12813 function getRootHostContainer() { 12814 var rootInstance = requiredContext(rootInstanceStackCursor.current); 12815 return rootInstance; 12816 } 12817 12818 function pushHostContainer(fiber, nextRootInstance) { 12819 // Push current root instance onto the stack; 12820 // This allows us to reset root when portals are popped. 12821 push(rootInstanceStackCursor, nextRootInstance, fiber); 12822 // Track the context and the Fiber that provided it. 12823 // This enables us to pop only Fibers that provide unique contexts. 12824 push(contextFiberStackCursor, fiber, fiber); 12825 12826 // Finally, we need to push the host context to the stack. 12827 // However, we can't just call getRootHostContext() and push it because 12828 // we'd have a different number of entries on the stack depending on 12829 // whether getRootHostContext() throws somewhere in renderer code or not. 12830 // So we push an empty value first. This lets us safely unwind on errors. 12831 push(contextStackCursor$1, NO_CONTEXT, fiber); 12832 var nextRootContext = getRootHostContext(nextRootInstance); 12833 // Now that we know this function doesn't throw, replace it. 12834 pop(contextStackCursor$1, fiber); 12835 push(contextStackCursor$1, nextRootContext, fiber); 12836 } 12837 12838 function popHostContainer(fiber) { 12839 pop(contextStackCursor$1, fiber); 12840 pop(contextFiberStackCursor, fiber); 12841 pop(rootInstanceStackCursor, fiber); 12842 } 12843 12844 function getHostContext() { 12845 var context = requiredContext(contextStackCursor$1.current); 12846 return context; 12847 } 12848 12849 function pushHostContext(fiber) { 12850 var rootInstance = requiredContext(rootInstanceStackCursor.current); 12851 var context = requiredContext(contextStackCursor$1.current); 12852 var nextContext = getChildHostContext(context, fiber.type, rootInstance); 12853 12854 // Don't push this Fiber's context unless it's unique. 12855 if (context === nextContext) { 12856 return; 12857 } 12858 12859 // Track the context and the Fiber that provided it. 12860 // This enables us to pop only Fibers that provide unique contexts. 12861 push(contextFiberStackCursor, fiber, fiber); 12862 push(contextStackCursor$1, nextContext, fiber); 12863 } 12864 12865 function popHostContext(fiber) { 12866 // Do not pop unless this Fiber provided the current context. 12867 // pushHostContext() only pushes Fibers that provide unique contexts. 12868 if (contextFiberStackCursor.current !== fiber) { 12869 return; 12870 } 12871 12872 pop(contextStackCursor$1, fiber); 12873 pop(contextFiberStackCursor, fiber); 12874 } 12875 12876 var NoEffect$1 = /* */0; 12877 var UnmountSnapshot = /* */2; 12878 var UnmountMutation = /* */4; 12879 var MountMutation = /* */8; 12880 var UnmountLayout = /* */16; 12881 var MountLayout = /* */32; 12882 var MountPassive = /* */64; 12883 var UnmountPassive = /* */128; 12884 12885 var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher; 12886 12887 12888 var didWarnAboutMismatchedHooksForComponent = void 0; 12889 { 12890 didWarnAboutMismatchedHooksForComponent = new Set(); 12891 } 12892 12893 // These are set right before calling the component. 12894 var renderExpirationTime = NoWork; 12895 // The work-in-progress fiber. I've named it differently to distinguish it from 12896 // the work-in-progress hook. 12897 var currentlyRenderingFiber$1 = null; 12898 12899 // Hooks are stored as a linked list on the fiber's memoizedState field. The 12900 // current hook list is the list that belongs to the current fiber. The 12901 // work-in-progress hook list is a new list that will be added to the 12902 // work-in-progress fiber. 12903 var currentHook = null; 12904 var nextCurrentHook = null; 12905 var firstWorkInProgressHook = null; 12906 var workInProgressHook = null; 12907 var nextWorkInProgressHook = null; 12908 12909 var remainingExpirationTime = NoWork; 12910 var componentUpdateQueue = null; 12911 var sideEffectTag = 0; 12912 12913 // Updates scheduled during render will trigger an immediate re-render at the 12914 // end of the current pass. We can't store these updates on the normal queue, 12915 // because if the work is aborted, they should be discarded. Because this is 12916 // a relatively rare case, we also don't want to add an additional field to 12917 // either the hook or queue object types. So we store them in a lazily create 12918 // map of queue -> render-phase updates, which are discarded once the component 12919 // completes without re-rendering. 12920 12921 // Whether an update was scheduled during the currently executing render pass. 12922 var didScheduleRenderPhaseUpdate = false; 12923 // Lazily created map of render-phase updates 12924 var renderPhaseUpdates = null; 12925 // Counter to prevent infinite loops. 12926 var numberOfReRenders = 0; 12927 var RE_RENDER_LIMIT = 25; 12928 12929 // In DEV, this is the name of the currently executing primitive hook 12930 var currentHookNameInDev = null; 12931 12932 // In DEV, this list ensures that hooks are called in the same order between renders. 12933 // The list stores the order of hooks used during the initial render (mount). 12934 // Subsequent renders (updates) reference this list. 12935 var hookTypesDev = null; 12936 var hookTypesUpdateIndexDev = -1; 12937 12938 function mountHookTypesDev() { 12939 { 12940 var hookName = currentHookNameInDev; 12941 12942 if (hookTypesDev === null) { 12943 hookTypesDev = [hookName]; 12944 } else { 12945 hookTypesDev.push(hookName); 12946 } 12947 } 12948 } 12949 12950 function updateHookTypesDev() { 12951 { 12952 var hookName = currentHookNameInDev; 12953 12954 if (hookTypesDev !== null) { 12955 hookTypesUpdateIndexDev++; 12956 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) { 12957 warnOnHookMismatchInDev(hookName); 12958 } 12959 } 12960 } 12961 } 12962 12963 function warnOnHookMismatchInDev(currentHookName) { 12964 { 12965 var componentName = getComponentName(currentlyRenderingFiber$1.type); 12966 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) { 12967 didWarnAboutMismatchedHooksForComponent.add(componentName); 12968 12969 if (hookTypesDev !== null) { 12970 var table = ''; 12971 12972 var secondColumnStart = 30; 12973 12974 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) { 12975 var oldHookName = hookTypesDev[i]; 12976 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName; 12977 12978 var row = i + 1 + '. ' + oldHookName; 12979 12980 // Extra space so second column lines up 12981 // lol @ IE not supporting String#repeat 12982 while (row.length < secondColumnStart) { 12983 row += ' '; 12984 } 12985 12986 row += newHookName + '\n'; 12987 12988 table += row; 12989 } 12990 12991 warning$1(false, 'React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table); 12992 } 12993 } 12994 } 12995 } 12996 12997 function throwInvalidHookError() { 12998 invariant(false, 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.'); 12999 } 13000 13001 function areHookInputsEqual(nextDeps, prevDeps) { 13002 if (prevDeps === null) { 13003 { 13004 warning$1(false, '%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev); 13005 } 13006 return false; 13007 } 13008 13009 { 13010 // Don't bother comparing lengths in prod because these arrays should be 13011 // passed inline. 13012 if (nextDeps.length !== prevDeps.length) { 13013 warning$1(false, 'The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, '[' + nextDeps.join(', ') + ']', '[' + prevDeps.join(', ') + ']'); 13014 } 13015 } 13016 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { 13017 if (is(nextDeps[i], prevDeps[i])) { 13018 continue; 13019 } 13020 return false; 13021 } 13022 return true; 13023 } 13024 13025 function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) { 13026 renderExpirationTime = nextRenderExpirationTime; 13027 currentlyRenderingFiber$1 = workInProgress; 13028 nextCurrentHook = current !== null ? current.memoizedState : null; 13029 13030 { 13031 hookTypesDev = current !== null ? current._debugHookTypes : null; 13032 hookTypesUpdateIndexDev = -1; 13033 } 13034 13035 // The following should have already been reset 13036 // currentHook = null; 13037 // workInProgressHook = null; 13038 13039 // remainingExpirationTime = NoWork; 13040 // componentUpdateQueue = null; 13041 13042 // didScheduleRenderPhaseUpdate = false; 13043 // renderPhaseUpdates = null; 13044 // numberOfReRenders = 0; 13045 // sideEffectTag = 0; 13046 13047 // TODO Warn if no hooks are used at all during mount, then some are used during update. 13048 // Currently we will identify the update render as a mount because nextCurrentHook === null. 13049 // This is tricky because it's valid for certain types of components (e.g. React.lazy) 13050 13051 // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used. 13052 // Non-stateful hooks (e.g. context) don't get added to memoizedState, 13053 // so nextCurrentHook would be null during updates and mounts. 13054 { 13055 if (nextCurrentHook !== null) { 13056 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; 13057 } else if (hookTypesDev !== null) { 13058 // This dispatcher handles an edge case where a component is updating, 13059 // but no stateful hooks have been used. 13060 // We want to match the production code behavior (which will use HooksDispatcherOnMount), 13061 // but with the extra DEV validation to ensure hooks ordering hasn't changed. 13062 // This dispatcher does that. 13063 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV; 13064 } else { 13065 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV; 13066 } 13067 } 13068 13069 var children = Component(props, refOrContext); 13070 13071 if (didScheduleRenderPhaseUpdate) { 13072 do { 13073 didScheduleRenderPhaseUpdate = false; 13074 numberOfReRenders += 1; 13075 13076 // Start over from the beginning of the list 13077 nextCurrentHook = current !== null ? current.memoizedState : null; 13078 nextWorkInProgressHook = firstWorkInProgressHook; 13079 13080 currentHook = null; 13081 workInProgressHook = null; 13082 componentUpdateQueue = null; 13083 13084 { 13085 // Also validate hook order for cascading updates. 13086 hookTypesUpdateIndexDev = -1; 13087 } 13088 13089 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; 13090 13091 children = Component(props, refOrContext); 13092 } while (didScheduleRenderPhaseUpdate); 13093 13094 renderPhaseUpdates = null; 13095 numberOfReRenders = 0; 13096 } 13097 13098 // We can assume the previous dispatcher is always this one, since we set it 13099 // at the beginning of the render phase and there's no re-entrancy. 13100 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; 13101 13102 var renderedWork = currentlyRenderingFiber$1; 13103 13104 renderedWork.memoizedState = firstWorkInProgressHook; 13105 renderedWork.expirationTime = remainingExpirationTime; 13106 renderedWork.updateQueue = componentUpdateQueue; 13107 renderedWork.effectTag |= sideEffectTag; 13108 13109 { 13110 renderedWork._debugHookTypes = hookTypesDev; 13111 } 13112 13113 // This check uses currentHook so that it works the same in DEV and prod bundles. 13114 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles. 13115 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null; 13116 13117 renderExpirationTime = NoWork; 13118 currentlyRenderingFiber$1 = null; 13119 13120 currentHook = null; 13121 nextCurrentHook = null; 13122 firstWorkInProgressHook = null; 13123 workInProgressHook = null; 13124 nextWorkInProgressHook = null; 13125 13126 { 13127 currentHookNameInDev = null; 13128 hookTypesDev = null; 13129 hookTypesUpdateIndexDev = -1; 13130 } 13131 13132 remainingExpirationTime = NoWork; 13133 componentUpdateQueue = null; 13134 sideEffectTag = 0; 13135 13136 // These were reset above 13137 // didScheduleRenderPhaseUpdate = false; 13138 // renderPhaseUpdates = null; 13139 // numberOfReRenders = 0; 13140 13141 !!didRenderTooFewHooks ? invariant(false, 'Rendered fewer hooks than expected. This may be caused by an accidental early return statement.') : void 0; 13142 13143 return children; 13144 } 13145 13146 function bailoutHooks(current, workInProgress, expirationTime) { 13147 workInProgress.updateQueue = current.updateQueue; 13148 workInProgress.effectTag &= ~(Passive | Update); 13149 if (current.expirationTime <= expirationTime) { 13150 current.expirationTime = NoWork; 13151 } 13152 } 13153 13154 function resetHooks() { 13155 // We can assume the previous dispatcher is always this one, since we set it 13156 // at the beginning of the render phase and there's no re-entrancy. 13157 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; 13158 13159 // This is used to reset the state of this module when a component throws. 13160 // It's also called inside mountIndeterminateComponent if we determine the 13161 // component is a module-style component. 13162 renderExpirationTime = NoWork; 13163 currentlyRenderingFiber$1 = null; 13164 13165 currentHook = null; 13166 nextCurrentHook = null; 13167 firstWorkInProgressHook = null; 13168 workInProgressHook = null; 13169 nextWorkInProgressHook = null; 13170 13171 { 13172 hookTypesDev = null; 13173 hookTypesUpdateIndexDev = -1; 13174 13175 currentHookNameInDev = null; 13176 } 13177 13178 remainingExpirationTime = NoWork; 13179 componentUpdateQueue = null; 13180 sideEffectTag = 0; 13181 13182 didScheduleRenderPhaseUpdate = false; 13183 renderPhaseUpdates = null; 13184 numberOfReRenders = 0; 13185 } 13186 13187 function mountWorkInProgressHook() { 13188 var hook = { 13189 memoizedState: null, 13190 13191 baseState: null, 13192 queue: null, 13193 baseUpdate: null, 13194 13195 next: null 13196 }; 13197 13198 if (workInProgressHook === null) { 13199 // This is the first hook in the list 13200 firstWorkInProgressHook = workInProgressHook = hook; 13201 } else { 13202 // Append to the end of the list 13203 workInProgressHook = workInProgressHook.next = hook; 13204 } 13205 return workInProgressHook; 13206 } 13207 13208 function updateWorkInProgressHook() { 13209 // This function is used both for updates and for re-renders triggered by a 13210 // render phase update. It assumes there is either a current hook we can 13211 // clone, or a work-in-progress hook from a previous render pass that we can 13212 // use as a base. When we reach the end of the base list, we must switch to 13213 // the dispatcher used for mounts. 13214 if (nextWorkInProgressHook !== null) { 13215 // There's already a work-in-progress. Reuse it. 13216 workInProgressHook = nextWorkInProgressHook; 13217 nextWorkInProgressHook = workInProgressHook.next; 13218 13219 currentHook = nextCurrentHook; 13220 nextCurrentHook = currentHook !== null ? currentHook.next : null; 13221 } else { 13222 // Clone from the current hook. 13223 !(nextCurrentHook !== null) ? invariant(false, 'Rendered more hooks than during the previous render.') : void 0; 13224 currentHook = nextCurrentHook; 13225 13226 var newHook = { 13227 memoizedState: currentHook.memoizedState, 13228 13229 baseState: currentHook.baseState, 13230 queue: currentHook.queue, 13231 baseUpdate: currentHook.baseUpdate, 13232 13233 next: null 13234 }; 13235 13236 if (workInProgressHook === null) { 13237 // This is the first hook in the list. 13238 workInProgressHook = firstWorkInProgressHook = newHook; 13239 } else { 13240 // Append to the end of the list. 13241 workInProgressHook = workInProgressHook.next = newHook; 13242 } 13243 nextCurrentHook = currentHook.next; 13244 } 13245 return workInProgressHook; 13246 } 13247 13248 function createFunctionComponentUpdateQueue() { 13249 return { 13250 lastEffect: null 13251 }; 13252 } 13253 13254 function basicStateReducer(state, action) { 13255 return typeof action === 'function' ? action(state) : action; 13256 } 13257 13258 function mountReducer(reducer, initialArg, init) { 13259 var hook = mountWorkInProgressHook(); 13260 var initialState = void 0; 13261 if (init !== undefined) { 13262 initialState = init(initialArg); 13263 } else { 13264 initialState = initialArg; 13265 } 13266 hook.memoizedState = hook.baseState = initialState; 13267 var queue = hook.queue = { 13268 last: null, 13269 dispatch: null, 13270 lastRenderedReducer: reducer, 13271 lastRenderedState: initialState 13272 }; 13273 var dispatch = queue.dispatch = dispatchAction.bind(null, 13274 // Flow doesn't know this is non-null, but we do. 13275 currentlyRenderingFiber$1, queue); 13276 return [hook.memoizedState, dispatch]; 13277 } 13278 13279 function updateReducer(reducer, initialArg, init) { 13280 var hook = updateWorkInProgressHook(); 13281 var queue = hook.queue; 13282 !(queue !== null) ? invariant(false, 'Should have a queue. This is likely a bug in React. Please file an issue.') : void 0; 13283 13284 queue.lastRenderedReducer = reducer; 13285 13286 if (numberOfReRenders > 0) { 13287 // This is a re-render. Apply the new render phase updates to the previous 13288 var _dispatch = queue.dispatch; 13289 if (renderPhaseUpdates !== null) { 13290 // Render phase updates are stored in a map of queue -> linked list 13291 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); 13292 if (firstRenderPhaseUpdate !== undefined) { 13293 renderPhaseUpdates.delete(queue); 13294 var newState = hook.memoizedState; 13295 var update = firstRenderPhaseUpdate; 13296 do { 13297 // Process this render phase update. We don't have to check the 13298 // priority because it will always be the same as the current 13299 // render's. 13300 var _action = update.action; 13301 newState = reducer(newState, _action); 13302 update = update.next; 13303 } while (update !== null); 13304 13305 // Mark that the fiber performed work, but only if the new state is 13306 // different from the current state. 13307 if (!is(newState, hook.memoizedState)) { 13308 markWorkInProgressReceivedUpdate(); 13309 } 13310 13311 hook.memoizedState = newState; 13312 // Don't persist the state accumlated from the render phase updates to 13313 // the base state unless the queue is empty. 13314 // TODO: Not sure if this is the desired semantics, but it's what we 13315 // do for gDSFP. I can't remember why. 13316 if (hook.baseUpdate === queue.last) { 13317 hook.baseState = newState; 13318 } 13319 13320 queue.lastRenderedState = newState; 13321 13322 return [newState, _dispatch]; 13323 } 13324 } 13325 return [hook.memoizedState, _dispatch]; 13326 } 13327 13328 // The last update in the entire queue 13329 var last = queue.last; 13330 // The last update that is part of the base state. 13331 var baseUpdate = hook.baseUpdate; 13332 var baseState = hook.baseState; 13333 13334 // Find the first unprocessed update. 13335 var first = void 0; 13336 if (baseUpdate !== null) { 13337 if (last !== null) { 13338 // For the first update, the queue is a circular linked list where 13339 // `queue.last.next = queue.first`. Once the first update commits, and 13340 // the `baseUpdate` is no longer empty, we can unravel the list. 13341 last.next = null; 13342 } 13343 first = baseUpdate.next; 13344 } else { 13345 first = last !== null ? last.next : null; 13346 } 13347 if (first !== null) { 13348 var _newState = baseState; 13349 var newBaseState = null; 13350 var newBaseUpdate = null; 13351 var prevUpdate = baseUpdate; 13352 var _update = first; 13353 var didSkip = false; 13354 do { 13355 var updateExpirationTime = _update.expirationTime; 13356 if (updateExpirationTime < renderExpirationTime) { 13357 // Priority is insufficient. Skip this update. If this is the first 13358 // skipped update, the previous update/state is the new base 13359 // update/state. 13360 if (!didSkip) { 13361 didSkip = true; 13362 newBaseUpdate = prevUpdate; 13363 newBaseState = _newState; 13364 } 13365 // Update the remaining priority in the queue. 13366 if (updateExpirationTime > remainingExpirationTime) { 13367 remainingExpirationTime = updateExpirationTime; 13368 } 13369 } else { 13370 // Process this update. 13371 if (_update.eagerReducer === reducer) { 13372 // If this update was processed eagerly, and its reducer matches the 13373 // current reducer, we can use the eagerly computed state. 13374 _newState = _update.eagerState; 13375 } else { 13376 var _action2 = _update.action; 13377 _newState = reducer(_newState, _action2); 13378 } 13379 } 13380 prevUpdate = _update; 13381 _update = _update.next; 13382 } while (_update !== null && _update !== first); 13383 13384 if (!didSkip) { 13385 newBaseUpdate = prevUpdate; 13386 newBaseState = _newState; 13387 } 13388 13389 // Mark that the fiber performed work, but only if the new state is 13390 // different from the current state. 13391 if (!is(_newState, hook.memoizedState)) { 13392 markWorkInProgressReceivedUpdate(); 13393 } 13394 13395 hook.memoizedState = _newState; 13396 hook.baseUpdate = newBaseUpdate; 13397 hook.baseState = newBaseState; 13398 13399 queue.lastRenderedState = _newState; 13400 } 13401 13402 var dispatch = queue.dispatch; 13403 return [hook.memoizedState, dispatch]; 13404 } 13405 13406 function mountState(initialState) { 13407 var hook = mountWorkInProgressHook(); 13408 if (typeof initialState === 'function') { 13409 initialState = initialState(); 13410 } 13411 hook.memoizedState = hook.baseState = initialState; 13412 var queue = hook.queue = { 13413 last: null, 13414 dispatch: null, 13415 lastRenderedReducer: basicStateReducer, 13416 lastRenderedState: initialState 13417 }; 13418 var dispatch = queue.dispatch = dispatchAction.bind(null, 13419 // Flow doesn't know this is non-null, but we do. 13420 currentlyRenderingFiber$1, queue); 13421 return [hook.memoizedState, dispatch]; 13422 } 13423 13424 function updateState(initialState) { 13425 return updateReducer(basicStateReducer, initialState); 13426 } 13427 13428 function pushEffect(tag, create, destroy, deps) { 13429 var effect = { 13430 tag: tag, 13431 create: create, 13432 destroy: destroy, 13433 deps: deps, 13434 // Circular 13435 next: null 13436 }; 13437 if (componentUpdateQueue === null) { 13438 componentUpdateQueue = createFunctionComponentUpdateQueue(); 13439 componentUpdateQueue.lastEffect = effect.next = effect; 13440 } else { 13441 var _lastEffect = componentUpdateQueue.lastEffect; 13442 if (_lastEffect === null) { 13443 componentUpdateQueue.lastEffect = effect.next = effect; 13444 } else { 13445 var firstEffect = _lastEffect.next; 13446 _lastEffect.next = effect; 13447 effect.next = firstEffect; 13448 componentUpdateQueue.lastEffect = effect; 13449 } 13450 } 13451 return effect; 13452 } 13453 13454 function mountRef(initialValue) { 13455 var hook = mountWorkInProgressHook(); 13456 var ref = { current: initialValue }; 13457 { 13458 Object.seal(ref); 13459 } 13460 hook.memoizedState = ref; 13461 return ref; 13462 } 13463 13464 function updateRef(initialValue) { 13465 var hook = updateWorkInProgressHook(); 13466 return hook.memoizedState; 13467 } 13468 13469 function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { 13470 var hook = mountWorkInProgressHook(); 13471 var nextDeps = deps === undefined ? null : deps; 13472 sideEffectTag |= fiberEffectTag; 13473 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps); 13474 } 13475 13476 function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { 13477 var hook = updateWorkInProgressHook(); 13478 var nextDeps = deps === undefined ? null : deps; 13479 var destroy = undefined; 13480 13481 if (currentHook !== null) { 13482 var prevEffect = currentHook.memoizedState; 13483 destroy = prevEffect.destroy; 13484 if (nextDeps !== null) { 13485 var prevDeps = prevEffect.deps; 13486 if (areHookInputsEqual(nextDeps, prevDeps)) { 13487 pushEffect(NoEffect$1, create, destroy, nextDeps); 13488 return; 13489 } 13490 } 13491 } 13492 13493 sideEffectTag |= fiberEffectTag; 13494 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps); 13495 } 13496 13497 function mountEffect(create, deps) { 13498 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps); 13499 } 13500 13501 function updateEffect(create, deps) { 13502 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps); 13503 } 13504 13505 function mountLayoutEffect(create, deps) { 13506 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps); 13507 } 13508 13509 function updateLayoutEffect(create, deps) { 13510 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps); 13511 } 13512 13513 function imperativeHandleEffect(create, ref) { 13514 if (typeof ref === 'function') { 13515 var refCallback = ref; 13516 var _inst = create(); 13517 refCallback(_inst); 13518 return function () { 13519 refCallback(null); 13520 }; 13521 } else if (ref !== null && ref !== undefined) { 13522 var refObject = ref; 13523 { 13524 !refObject.hasOwnProperty('current') ? warning$1(false, 'Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}') : void 0; 13525 } 13526 var _inst2 = create(); 13527 refObject.current = _inst2; 13528 return function () { 13529 refObject.current = null; 13530 }; 13531 } 13532 } 13533 13534 function mountImperativeHandle(ref, create, deps) { 13535 { 13536 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0; 13537 } 13538 13539 // TODO: If deps are provided, should we skip comparing the ref itself? 13540 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; 13541 13542 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps); 13543 } 13544 13545 function updateImperativeHandle(ref, create, deps) { 13546 { 13547 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0; 13548 } 13549 13550 // TODO: If deps are provided, should we skip comparing the ref itself? 13551 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; 13552 13553 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps); 13554 } 13555 13556 function mountDebugValue(value, formatterFn) { 13557 // This hook is normally a no-op. 13558 // The react-debug-hooks package injects its own implementation 13559 // so that e.g. DevTools can display custom hook values. 13560 } 13561 13562 var updateDebugValue = mountDebugValue; 13563 13564 function mountCallback(callback, deps) { 13565 var hook = mountWorkInProgressHook(); 13566 var nextDeps = deps === undefined ? null : deps; 13567 hook.memoizedState = [callback, nextDeps]; 13568 return callback; 13569 } 13570 13571 function updateCallback(callback, deps) { 13572 var hook = updateWorkInProgressHook(); 13573 var nextDeps = deps === undefined ? null : deps; 13574 var prevState = hook.memoizedState; 13575 if (prevState !== null) { 13576 if (nextDeps !== null) { 13577 var prevDeps = prevState[1]; 13578 if (areHookInputsEqual(nextDeps, prevDeps)) { 13579 return prevState[0]; 13580 } 13581 } 13582 } 13583 hook.memoizedState = [callback, nextDeps]; 13584 return callback; 13585 } 13586 13587 function mountMemo(nextCreate, deps) { 13588 var hook = mountWorkInProgressHook(); 13589 var nextDeps = deps === undefined ? null : deps; 13590 var nextValue = nextCreate(); 13591 hook.memoizedState = [nextValue, nextDeps]; 13592 return nextValue; 13593 } 13594 13595 function updateMemo(nextCreate, deps) { 13596 var hook = updateWorkInProgressHook(); 13597 var nextDeps = deps === undefined ? null : deps; 13598 var prevState = hook.memoizedState; 13599 if (prevState !== null) { 13600 // Assume these are defined. If they're not, areHookInputsEqual will warn. 13601 if (nextDeps !== null) { 13602 var prevDeps = prevState[1]; 13603 if (areHookInputsEqual(nextDeps, prevDeps)) { 13604 return prevState[0]; 13605 } 13606 } 13607 } 13608 var nextValue = nextCreate(); 13609 hook.memoizedState = [nextValue, nextDeps]; 13610 return nextValue; 13611 } 13612 13613 // in a test-like environment, we want to warn if dispatchAction() 13614 // is called outside of a batchedUpdates/TestUtils.act(...) call. 13615 var shouldWarnForUnbatchedSetState = false; 13616 13617 { 13618 // jest isn't a 'global', it's just exposed to tests via a wrapped function 13619 // further, this isn't a test file, so flow doesn't recognize the symbol. So... 13620 // $FlowExpectedError - because requirements don't give a damn about your type sigs. 13621 if ('undefined' !== typeof jest) { 13622 shouldWarnForUnbatchedSetState = true; 13623 } 13624 } 13625 13626 function dispatchAction(fiber, queue, action) { 13627 !(numberOfReRenders < RE_RENDER_LIMIT) ? invariant(false, 'Too many re-renders. React limits the number of renders to prevent an infinite loop.') : void 0; 13628 13629 { 13630 !(arguments.length <= 3) ? warning$1(false, "State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().') : void 0; 13631 } 13632 13633 var alternate = fiber.alternate; 13634 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) { 13635 // This is a render phase update. Stash it in a lazily-created map of 13636 // queue -> linked list of updates. After this render pass, we'll restart 13637 // and apply the stashed updates on top of the work-in-progress hook. 13638 didScheduleRenderPhaseUpdate = true; 13639 var update = { 13640 expirationTime: renderExpirationTime, 13641 action: action, 13642 eagerReducer: null, 13643 eagerState: null, 13644 next: null 13645 }; 13646 if (renderPhaseUpdates === null) { 13647 renderPhaseUpdates = new Map(); 13648 } 13649 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); 13650 if (firstRenderPhaseUpdate === undefined) { 13651 renderPhaseUpdates.set(queue, update); 13652 } else { 13653 // Append the update to the end of the list. 13654 var lastRenderPhaseUpdate = firstRenderPhaseUpdate; 13655 while (lastRenderPhaseUpdate.next !== null) { 13656 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next; 13657 } 13658 lastRenderPhaseUpdate.next = update; 13659 } 13660 } else { 13661 flushPassiveEffects(); 13662 13663 var currentTime = requestCurrentTime(); 13664 var _expirationTime = computeExpirationForFiber(currentTime, fiber); 13665 13666 var _update2 = { 13667 expirationTime: _expirationTime, 13668 action: action, 13669 eagerReducer: null, 13670 eagerState: null, 13671 next: null 13672 }; 13673 13674 // Append the update to the end of the list. 13675 var _last = queue.last; 13676 if (_last === null) { 13677 // This is the first update. Create a circular list. 13678 _update2.next = _update2; 13679 } else { 13680 var first = _last.next; 13681 if (first !== null) { 13682 // Still circular. 13683 _update2.next = first; 13684 } 13685 _last.next = _update2; 13686 } 13687 queue.last = _update2; 13688 13689 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) { 13690 // The queue is currently empty, which means we can eagerly compute the 13691 // next state before entering the render phase. If the new state is the 13692 // same as the current state, we may be able to bail out entirely. 13693 var _lastRenderedReducer = queue.lastRenderedReducer; 13694 if (_lastRenderedReducer !== null) { 13695 var prevDispatcher = void 0; 13696 { 13697 prevDispatcher = ReactCurrentDispatcher$1.current; 13698 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 13699 } 13700 try { 13701 var currentState = queue.lastRenderedState; 13702 var _eagerState = _lastRenderedReducer(currentState, action); 13703 // Stash the eagerly computed state, and the reducer used to compute 13704 // it, on the update object. If the reducer hasn't changed by the 13705 // time we enter the render phase, then the eager state can be used 13706 // without calling the reducer again. 13707 _update2.eagerReducer = _lastRenderedReducer; 13708 _update2.eagerState = _eagerState; 13709 if (is(_eagerState, currentState)) { 13710 // Fast path. We can bail out without scheduling React to re-render. 13711 // It's still possible that we'll need to rebase this update later, 13712 // if the component re-renders for a different reason and by that 13713 // time the reducer has changed. 13714 return; 13715 } 13716 } catch (error) { 13717 // Suppress the error. It will throw again in the render phase. 13718 } finally { 13719 { 13720 ReactCurrentDispatcher$1.current = prevDispatcher; 13721 } 13722 } 13723 } 13724 } 13725 { 13726 if (shouldWarnForUnbatchedSetState === true) { 13727 warnIfNotCurrentlyBatchingInDev(fiber); 13728 } 13729 } 13730 scheduleWork(fiber, _expirationTime); 13731 } 13732 } 13733 13734 var ContextOnlyDispatcher = { 13735 readContext: readContext, 13736 13737 useCallback: throwInvalidHookError, 13738 useContext: throwInvalidHookError, 13739 useEffect: throwInvalidHookError, 13740 useImperativeHandle: throwInvalidHookError, 13741 useLayoutEffect: throwInvalidHookError, 13742 useMemo: throwInvalidHookError, 13743 useReducer: throwInvalidHookError, 13744 useRef: throwInvalidHookError, 13745 useState: throwInvalidHookError, 13746 useDebugValue: throwInvalidHookError 13747 }; 13748 13749 var HooksDispatcherOnMountInDEV = null; 13750 var HooksDispatcherOnMountWithHookTypesInDEV = null; 13751 var HooksDispatcherOnUpdateInDEV = null; 13752 var InvalidNestedHooksDispatcherOnMountInDEV = null; 13753 var InvalidNestedHooksDispatcherOnUpdateInDEV = null; 13754 13755 { 13756 var warnInvalidContextAccess = function () { 13757 warning$1(false, 'Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().'); 13758 }; 13759 13760 var warnInvalidHookAccess = function () { 13761 warning$1(false, 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + 'https://fb.me/rules-of-hooks'); 13762 }; 13763 13764 HooksDispatcherOnMountInDEV = { 13765 readContext: function (context, observedBits) { 13766 return readContext(context, observedBits); 13767 }, 13768 useCallback: function (callback, deps) { 13769 currentHookNameInDev = 'useCallback'; 13770 mountHookTypesDev(); 13771 return mountCallback(callback, deps); 13772 }, 13773 useContext: function (context, observedBits) { 13774 currentHookNameInDev = 'useContext'; 13775 mountHookTypesDev(); 13776 return readContext(context, observedBits); 13777 }, 13778 useEffect: function (create, deps) { 13779 currentHookNameInDev = 'useEffect'; 13780 mountHookTypesDev(); 13781 return mountEffect(create, deps); 13782 }, 13783 useImperativeHandle: function (ref, create, deps) { 13784 currentHookNameInDev = 'useImperativeHandle'; 13785 mountHookTypesDev(); 13786 return mountImperativeHandle(ref, create, deps); 13787 }, 13788 useLayoutEffect: function (create, deps) { 13789 currentHookNameInDev = 'useLayoutEffect'; 13790 mountHookTypesDev(); 13791 return mountLayoutEffect(create, deps); 13792 }, 13793 useMemo: function (create, deps) { 13794 currentHookNameInDev = 'useMemo'; 13795 mountHookTypesDev(); 13796 var prevDispatcher = ReactCurrentDispatcher$1.current; 13797 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 13798 try { 13799 return mountMemo(create, deps); 13800 } finally { 13801 ReactCurrentDispatcher$1.current = prevDispatcher; 13802 } 13803 }, 13804 useReducer: function (reducer, initialArg, init) { 13805 currentHookNameInDev = 'useReducer'; 13806 mountHookTypesDev(); 13807 var prevDispatcher = ReactCurrentDispatcher$1.current; 13808 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 13809 try { 13810 return mountReducer(reducer, initialArg, init); 13811 } finally { 13812 ReactCurrentDispatcher$1.current = prevDispatcher; 13813 } 13814 }, 13815 useRef: function (initialValue) { 13816 currentHookNameInDev = 'useRef'; 13817 mountHookTypesDev(); 13818 return mountRef(initialValue); 13819 }, 13820 useState: function (initialState) { 13821 currentHookNameInDev = 'useState'; 13822 mountHookTypesDev(); 13823 var prevDispatcher = ReactCurrentDispatcher$1.current; 13824 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 13825 try { 13826 return mountState(initialState); 13827 } finally { 13828 ReactCurrentDispatcher$1.current = prevDispatcher; 13829 } 13830 }, 13831 useDebugValue: function (value, formatterFn) { 13832 currentHookNameInDev = 'useDebugValue'; 13833 mountHookTypesDev(); 13834 return mountDebugValue(value, formatterFn); 13835 } 13836 }; 13837 13838 HooksDispatcherOnMountWithHookTypesInDEV = { 13839 readContext: function (context, observedBits) { 13840 return readContext(context, observedBits); 13841 }, 13842 useCallback: function (callback, deps) { 13843 currentHookNameInDev = 'useCallback'; 13844 updateHookTypesDev(); 13845 return mountCallback(callback, deps); 13846 }, 13847 useContext: function (context, observedBits) { 13848 currentHookNameInDev = 'useContext'; 13849 updateHookTypesDev(); 13850 return readContext(context, observedBits); 13851 }, 13852 useEffect: function (create, deps) { 13853 currentHookNameInDev = 'useEffect'; 13854 updateHookTypesDev(); 13855 return mountEffect(create, deps); 13856 }, 13857 useImperativeHandle: function (ref, create, deps) { 13858 currentHookNameInDev = 'useImperativeHandle'; 13859 updateHookTypesDev(); 13860 return mountImperativeHandle(ref, create, deps); 13861 }, 13862 useLayoutEffect: function (create, deps) { 13863 currentHookNameInDev = 'useLayoutEffect'; 13864 updateHookTypesDev(); 13865 return mountLayoutEffect(create, deps); 13866 }, 13867 useMemo: function (create, deps) { 13868 currentHookNameInDev = 'useMemo'; 13869 updateHookTypesDev(); 13870 var prevDispatcher = ReactCurrentDispatcher$1.current; 13871 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 13872 try { 13873 return mountMemo(create, deps); 13874 } finally { 13875 ReactCurrentDispatcher$1.current = prevDispatcher; 13876 } 13877 }, 13878 useReducer: function (reducer, initialArg, init) { 13879 currentHookNameInDev = 'useReducer'; 13880 updateHookTypesDev(); 13881 var prevDispatcher = ReactCurrentDispatcher$1.current; 13882 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 13883 try { 13884 return mountReducer(reducer, initialArg, init); 13885 } finally { 13886 ReactCurrentDispatcher$1.current = prevDispatcher; 13887 } 13888 }, 13889 useRef: function (initialValue) { 13890 currentHookNameInDev = 'useRef'; 13891 updateHookTypesDev(); 13892 return mountRef(initialValue); 13893 }, 13894 useState: function (initialState) { 13895 currentHookNameInDev = 'useState'; 13896 updateHookTypesDev(); 13897 var prevDispatcher = ReactCurrentDispatcher$1.current; 13898 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 13899 try { 13900 return mountState(initialState); 13901 } finally { 13902 ReactCurrentDispatcher$1.current = prevDispatcher; 13903 } 13904 }, 13905 useDebugValue: function (value, formatterFn) { 13906 currentHookNameInDev = 'useDebugValue'; 13907 updateHookTypesDev(); 13908 return mountDebugValue(value, formatterFn); 13909 } 13910 }; 13911 13912 HooksDispatcherOnUpdateInDEV = { 13913 readContext: function (context, observedBits) { 13914 return readContext(context, observedBits); 13915 }, 13916 useCallback: function (callback, deps) { 13917 currentHookNameInDev = 'useCallback'; 13918 updateHookTypesDev(); 13919 return updateCallback(callback, deps); 13920 }, 13921 useContext: function (context, observedBits) { 13922 currentHookNameInDev = 'useContext'; 13923 updateHookTypesDev(); 13924 return readContext(context, observedBits); 13925 }, 13926 useEffect: function (create, deps) { 13927 currentHookNameInDev = 'useEffect'; 13928 updateHookTypesDev(); 13929 return updateEffect(create, deps); 13930 }, 13931 useImperativeHandle: function (ref, create, deps) { 13932 currentHookNameInDev = 'useImperativeHandle'; 13933 updateHookTypesDev(); 13934 return updateImperativeHandle(ref, create, deps); 13935 }, 13936 useLayoutEffect: function (create, deps) { 13937 currentHookNameInDev = 'useLayoutEffect'; 13938 updateHookTypesDev(); 13939 return updateLayoutEffect(create, deps); 13940 }, 13941 useMemo: function (create, deps) { 13942 currentHookNameInDev = 'useMemo'; 13943 updateHookTypesDev(); 13944 var prevDispatcher = ReactCurrentDispatcher$1.current; 13945 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 13946 try { 13947 return updateMemo(create, deps); 13948 } finally { 13949 ReactCurrentDispatcher$1.current = prevDispatcher; 13950 } 13951 }, 13952 useReducer: function (reducer, initialArg, init) { 13953 currentHookNameInDev = 'useReducer'; 13954 updateHookTypesDev(); 13955 var prevDispatcher = ReactCurrentDispatcher$1.current; 13956 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 13957 try { 13958 return updateReducer(reducer, initialArg, init); 13959 } finally { 13960 ReactCurrentDispatcher$1.current = prevDispatcher; 13961 } 13962 }, 13963 useRef: function (initialValue) { 13964 currentHookNameInDev = 'useRef'; 13965 updateHookTypesDev(); 13966 return updateRef(initialValue); 13967 }, 13968 useState: function (initialState) { 13969 currentHookNameInDev = 'useState'; 13970 updateHookTypesDev(); 13971 var prevDispatcher = ReactCurrentDispatcher$1.current; 13972 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 13973 try { 13974 return updateState(initialState); 13975 } finally { 13976 ReactCurrentDispatcher$1.current = prevDispatcher; 13977 } 13978 }, 13979 useDebugValue: function (value, formatterFn) { 13980 currentHookNameInDev = 'useDebugValue'; 13981 updateHookTypesDev(); 13982 return updateDebugValue(value, formatterFn); 13983 } 13984 }; 13985 13986 InvalidNestedHooksDispatcherOnMountInDEV = { 13987 readContext: function (context, observedBits) { 13988 warnInvalidContextAccess(); 13989 return readContext(context, observedBits); 13990 }, 13991 useCallback: function (callback, deps) { 13992 currentHookNameInDev = 'useCallback'; 13993 warnInvalidHookAccess(); 13994 mountHookTypesDev(); 13995 return mountCallback(callback, deps); 13996 }, 13997 useContext: function (context, observedBits) { 13998 currentHookNameInDev = 'useContext'; 13999 warnInvalidHookAccess(); 14000 mountHookTypesDev(); 14001 return readContext(context, observedBits); 14002 }, 14003 useEffect: function (create, deps) { 14004 currentHookNameInDev = 'useEffect'; 14005 warnInvalidHookAccess(); 14006 mountHookTypesDev(); 14007 return mountEffect(create, deps); 14008 }, 14009 useImperativeHandle: function (ref, create, deps) { 14010 currentHookNameInDev = 'useImperativeHandle'; 14011 warnInvalidHookAccess(); 14012 mountHookTypesDev(); 14013 return mountImperativeHandle(ref, create, deps); 14014 }, 14015 useLayoutEffect: function (create, deps) { 14016 currentHookNameInDev = 'useLayoutEffect'; 14017 warnInvalidHookAccess(); 14018 mountHookTypesDev(); 14019 return mountLayoutEffect(create, deps); 14020 }, 14021 useMemo: function (create, deps) { 14022 currentHookNameInDev = 'useMemo'; 14023 warnInvalidHookAccess(); 14024 mountHookTypesDev(); 14025 var prevDispatcher = ReactCurrentDispatcher$1.current; 14026 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 14027 try { 14028 return mountMemo(create, deps); 14029 } finally { 14030 ReactCurrentDispatcher$1.current = prevDispatcher; 14031 } 14032 }, 14033 useReducer: function (reducer, initialArg, init) { 14034 currentHookNameInDev = 'useReducer'; 14035 warnInvalidHookAccess(); 14036 mountHookTypesDev(); 14037 var prevDispatcher = ReactCurrentDispatcher$1.current; 14038 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 14039 try { 14040 return mountReducer(reducer, initialArg, init); 14041 } finally { 14042 ReactCurrentDispatcher$1.current = prevDispatcher; 14043 } 14044 }, 14045 useRef: function (initialValue) { 14046 currentHookNameInDev = 'useRef'; 14047 warnInvalidHookAccess(); 14048 mountHookTypesDev(); 14049 return mountRef(initialValue); 14050 }, 14051 useState: function (initialState) { 14052 currentHookNameInDev = 'useState'; 14053 warnInvalidHookAccess(); 14054 mountHookTypesDev(); 14055 var prevDispatcher = ReactCurrentDispatcher$1.current; 14056 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 14057 try { 14058 return mountState(initialState); 14059 } finally { 14060 ReactCurrentDispatcher$1.current = prevDispatcher; 14061 } 14062 }, 14063 useDebugValue: function (value, formatterFn) { 14064 currentHookNameInDev = 'useDebugValue'; 14065 warnInvalidHookAccess(); 14066 mountHookTypesDev(); 14067 return mountDebugValue(value, formatterFn); 14068 } 14069 }; 14070 14071 InvalidNestedHooksDispatcherOnUpdateInDEV = { 14072 readContext: function (context, observedBits) { 14073 warnInvalidContextAccess(); 14074 return readContext(context, observedBits); 14075 }, 14076 useCallback: function (callback, deps) { 14077 currentHookNameInDev = 'useCallback'; 14078 warnInvalidHookAccess(); 14079 updateHookTypesDev(); 14080 return updateCallback(callback, deps); 14081 }, 14082 useContext: function (context, observedBits) { 14083 currentHookNameInDev = 'useContext'; 14084 warnInvalidHookAccess(); 14085 updateHookTypesDev(); 14086 return readContext(context, observedBits); 14087 }, 14088 useEffect: function (create, deps) { 14089 currentHookNameInDev = 'useEffect'; 14090 warnInvalidHookAccess(); 14091 updateHookTypesDev(); 14092 return updateEffect(create, deps); 14093 }, 14094 useImperativeHandle: function (ref, create, deps) { 14095 currentHookNameInDev = 'useImperativeHandle'; 14096 warnInvalidHookAccess(); 14097 updateHookTypesDev(); 14098 return updateImperativeHandle(ref, create, deps); 14099 }, 14100 useLayoutEffect: function (create, deps) { 14101 currentHookNameInDev = 'useLayoutEffect'; 14102 warnInvalidHookAccess(); 14103 updateHookTypesDev(); 14104 return updateLayoutEffect(create, deps); 14105 }, 14106 useMemo: function (create, deps) { 14107 currentHookNameInDev = 'useMemo'; 14108 warnInvalidHookAccess(); 14109 updateHookTypesDev(); 14110 var prevDispatcher = ReactCurrentDispatcher$1.current; 14111 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 14112 try { 14113 return updateMemo(create, deps); 14114 } finally { 14115 ReactCurrentDispatcher$1.current = prevDispatcher; 14116 } 14117 }, 14118 useReducer: function (reducer, initialArg, init) { 14119 currentHookNameInDev = 'useReducer'; 14120 warnInvalidHookAccess(); 14121 updateHookTypesDev(); 14122 var prevDispatcher = ReactCurrentDispatcher$1.current; 14123 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 14124 try { 14125 return updateReducer(reducer, initialArg, init); 14126 } finally { 14127 ReactCurrentDispatcher$1.current = prevDispatcher; 14128 } 14129 }, 14130 useRef: function (initialValue) { 14131 currentHookNameInDev = 'useRef'; 14132 warnInvalidHookAccess(); 14133 updateHookTypesDev(); 14134 return updateRef(initialValue); 14135 }, 14136 useState: function (initialState) { 14137 currentHookNameInDev = 'useState'; 14138 warnInvalidHookAccess(); 14139 updateHookTypesDev(); 14140 var prevDispatcher = ReactCurrentDispatcher$1.current; 14141 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 14142 try { 14143 return updateState(initialState); 14144 } finally { 14145 ReactCurrentDispatcher$1.current = prevDispatcher; 14146 } 14147 }, 14148 useDebugValue: function (value, formatterFn) { 14149 currentHookNameInDev = 'useDebugValue'; 14150 warnInvalidHookAccess(); 14151 updateHookTypesDev(); 14152 return updateDebugValue(value, formatterFn); 14153 } 14154 }; 14155 } 14156 14157 var commitTime = 0; 14158 var profilerStartTime = -1; 14159 14160 function getCommitTime() { 14161 return commitTime; 14162 } 14163 14164 function recordCommitTime() { 14165 if (!enableProfilerTimer) { 14166 return; 14167 } 14168 commitTime = unstable_now(); 14169 } 14170 14171 function startProfilerTimer(fiber) { 14172 if (!enableProfilerTimer) { 14173 return; 14174 } 14175 14176 profilerStartTime = unstable_now(); 14177 14178 if (fiber.actualStartTime < 0) { 14179 fiber.actualStartTime = unstable_now(); 14180 } 14181 } 14182 14183 function stopProfilerTimerIfRunning(fiber) { 14184 if (!enableProfilerTimer) { 14185 return; 14186 } 14187 profilerStartTime = -1; 14188 } 14189 14190 function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { 14191 if (!enableProfilerTimer) { 14192 return; 14193 } 14194 14195 if (profilerStartTime >= 0) { 14196 var elapsedTime = unstable_now() - profilerStartTime; 14197 fiber.actualDuration += elapsedTime; 14198 if (overrideBaseTime) { 14199 fiber.selfBaseDuration = elapsedTime; 14200 } 14201 profilerStartTime = -1; 14202 } 14203 } 14204 14205 // The deepest Fiber on the stack involved in a hydration context. 14206 // This may have been an insertion or a hydration. 14207 var hydrationParentFiber = null; 14208 var nextHydratableInstance = null; 14209 var isHydrating = false; 14210 14211 function enterHydrationState(fiber) { 14212 if (!supportsHydration) { 14213 return false; 14214 } 14215 14216 var parentInstance = fiber.stateNode.containerInfo; 14217 nextHydratableInstance = getFirstHydratableChild(parentInstance); 14218 hydrationParentFiber = fiber; 14219 isHydrating = true; 14220 return true; 14221 } 14222 14223 function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) { 14224 if (!supportsHydration) { 14225 return false; 14226 } 14227 14228 var suspenseInstance = fiber.stateNode; 14229 nextHydratableInstance = getNextHydratableSibling(suspenseInstance); 14230 popToNextHostParent(fiber); 14231 isHydrating = true; 14232 return true; 14233 } 14234 14235 function deleteHydratableInstance(returnFiber, instance) { 14236 { 14237 switch (returnFiber.tag) { 14238 case HostRoot: 14239 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance); 14240 break; 14241 case HostComponent: 14242 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance); 14243 break; 14244 } 14245 } 14246 14247 var childToDelete = createFiberFromHostInstanceForDeletion(); 14248 childToDelete.stateNode = instance; 14249 childToDelete.return = returnFiber; 14250 childToDelete.effectTag = Deletion; 14251 14252 // This might seem like it belongs on progressedFirstDeletion. However, 14253 // these children are not part of the reconciliation list of children. 14254 // Even if we abort and rereconcile the children, that will try to hydrate 14255 // again and the nodes are still in the host tree so these will be 14256 // recreated. 14257 if (returnFiber.lastEffect !== null) { 14258 returnFiber.lastEffect.nextEffect = childToDelete; 14259 returnFiber.lastEffect = childToDelete; 14260 } else { 14261 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; 14262 } 14263 } 14264 14265 function insertNonHydratedInstance(returnFiber, fiber) { 14266 fiber.effectTag |= Placement; 14267 { 14268 switch (returnFiber.tag) { 14269 case HostRoot: 14270 { 14271 var parentContainer = returnFiber.stateNode.containerInfo; 14272 switch (fiber.tag) { 14273 case HostComponent: 14274 var type = fiber.type; 14275 var props = fiber.pendingProps; 14276 didNotFindHydratableContainerInstance(parentContainer, type, props); 14277 break; 14278 case HostText: 14279 var text = fiber.pendingProps; 14280 didNotFindHydratableContainerTextInstance(parentContainer, text); 14281 break; 14282 case SuspenseComponent: 14283 14284 break; 14285 } 14286 break; 14287 } 14288 case HostComponent: 14289 { 14290 var parentType = returnFiber.type; 14291 var parentProps = returnFiber.memoizedProps; 14292 var parentInstance = returnFiber.stateNode; 14293 switch (fiber.tag) { 14294 case HostComponent: 14295 var _type = fiber.type; 14296 var _props = fiber.pendingProps; 14297 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props); 14298 break; 14299 case HostText: 14300 var _text = fiber.pendingProps; 14301 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text); 14302 break; 14303 case SuspenseComponent: 14304 didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance); 14305 break; 14306 } 14307 break; 14308 } 14309 default: 14310 return; 14311 } 14312 } 14313 } 14314 14315 function tryHydrate(fiber, nextInstance) { 14316 switch (fiber.tag) { 14317 case HostComponent: 14318 { 14319 var type = fiber.type; 14320 var props = fiber.pendingProps; 14321 var instance = canHydrateInstance(nextInstance, type, props); 14322 if (instance !== null) { 14323 fiber.stateNode = instance; 14324 return true; 14325 } 14326 return false; 14327 } 14328 case HostText: 14329 { 14330 var text = fiber.pendingProps; 14331 var textInstance = canHydrateTextInstance(nextInstance, text); 14332 if (textInstance !== null) { 14333 fiber.stateNode = textInstance; 14334 return true; 14335 } 14336 return false; 14337 } 14338 case SuspenseComponent: 14339 { 14340 if (enableSuspenseServerRenderer) { 14341 var suspenseInstance = canHydrateSuspenseInstance(nextInstance); 14342 if (suspenseInstance !== null) { 14343 // Downgrade the tag to a dehydrated component until we've hydrated it. 14344 fiber.tag = DehydratedSuspenseComponent; 14345 fiber.stateNode = suspenseInstance; 14346 return true; 14347 } 14348 } 14349 return false; 14350 } 14351 default: 14352 return false; 14353 } 14354 } 14355 14356 function tryToClaimNextHydratableInstance(fiber) { 14357 if (!isHydrating) { 14358 return; 14359 } 14360 var nextInstance = nextHydratableInstance; 14361 if (!nextInstance) { 14362 // Nothing to hydrate. Make it an insertion. 14363 insertNonHydratedInstance(hydrationParentFiber, fiber); 14364 isHydrating = false; 14365 hydrationParentFiber = fiber; 14366 return; 14367 } 14368 var firstAttemptedInstance = nextInstance; 14369 if (!tryHydrate(fiber, nextInstance)) { 14370 // If we can't hydrate this instance let's try the next one. 14371 // We use this as a heuristic. It's based on intuition and not data so it 14372 // might be flawed or unnecessary. 14373 nextInstance = getNextHydratableSibling(firstAttemptedInstance); 14374 if (!nextInstance || !tryHydrate(fiber, nextInstance)) { 14375 // Nothing to hydrate. Make it an insertion. 14376 insertNonHydratedInstance(hydrationParentFiber, fiber); 14377 isHydrating = false; 14378 hydrationParentFiber = fiber; 14379 return; 14380 } 14381 // We matched the next one, we'll now assume that the first one was 14382 // superfluous and we'll delete it. Since we can't eagerly delete it 14383 // we'll have to schedule a deletion. To do that, this node needs a dummy 14384 // fiber associated with it. 14385 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance); 14386 } 14387 hydrationParentFiber = fiber; 14388 nextHydratableInstance = getFirstHydratableChild(nextInstance); 14389 } 14390 14391 function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) { 14392 if (!supportsHydration) { 14393 invariant(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'); 14394 } 14395 14396 var instance = fiber.stateNode; 14397 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber); 14398 // TODO: Type this specific to this type of component. 14399 fiber.updateQueue = updatePayload; 14400 // If the update payload indicates that there is a change or if there 14401 // is a new ref we mark this as an update. 14402 if (updatePayload !== null) { 14403 return true; 14404 } 14405 return false; 14406 } 14407 14408 function prepareToHydrateHostTextInstance(fiber) { 14409 if (!supportsHydration) { 14410 invariant(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'); 14411 } 14412 14413 var textInstance = fiber.stateNode; 14414 var textContent = fiber.memoizedProps; 14415 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber); 14416 { 14417 if (shouldUpdate) { 14418 // We assume that prepareToHydrateHostTextInstance is called in a context where the 14419 // hydration parent is the parent host component of this host text. 14420 var returnFiber = hydrationParentFiber; 14421 if (returnFiber !== null) { 14422 switch (returnFiber.tag) { 14423 case HostRoot: 14424 { 14425 var parentContainer = returnFiber.stateNode.containerInfo; 14426 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent); 14427 break; 14428 } 14429 case HostComponent: 14430 { 14431 var parentType = returnFiber.type; 14432 var parentProps = returnFiber.memoizedProps; 14433 var parentInstance = returnFiber.stateNode; 14434 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent); 14435 break; 14436 } 14437 } 14438 } 14439 } 14440 } 14441 return shouldUpdate; 14442 } 14443 14444 function skipPastDehydratedSuspenseInstance(fiber) { 14445 if (!supportsHydration) { 14446 invariant(false, 'Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'); 14447 } 14448 var suspenseInstance = fiber.stateNode; 14449 !suspenseInstance ? invariant(false, 'Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.') : void 0; 14450 nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance); 14451 } 14452 14453 function popToNextHostParent(fiber) { 14454 var parent = fiber.return; 14455 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== DehydratedSuspenseComponent) { 14456 parent = parent.return; 14457 } 14458 hydrationParentFiber = parent; 14459 } 14460 14461 function popHydrationState(fiber) { 14462 if (!supportsHydration) { 14463 return false; 14464 } 14465 if (fiber !== hydrationParentFiber) { 14466 // We're deeper than the current hydration context, inside an inserted 14467 // tree. 14468 return false; 14469 } 14470 if (!isHydrating) { 14471 // If we're not currently hydrating but we're in a hydration context, then 14472 // we were an insertion and now need to pop up reenter hydration of our 14473 // siblings. 14474 popToNextHostParent(fiber); 14475 isHydrating = true; 14476 return false; 14477 } 14478 14479 var type = fiber.type; 14480 14481 // If we have any remaining hydratable nodes, we need to delete them now. 14482 // We only do this deeper than head and body since they tend to have random 14483 // other nodes in them. We also ignore components with pure text content in 14484 // side of them. 14485 // TODO: Better heuristic. 14486 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) { 14487 var nextInstance = nextHydratableInstance; 14488 while (nextInstance) { 14489 deleteHydratableInstance(fiber, nextInstance); 14490 nextInstance = getNextHydratableSibling(nextInstance); 14491 } 14492 } 14493 14494 popToNextHostParent(fiber); 14495 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null; 14496 return true; 14497 } 14498 14499 function resetHydrationState() { 14500 if (!supportsHydration) { 14501 return; 14502 } 14503 14504 hydrationParentFiber = null; 14505 nextHydratableInstance = null; 14506 isHydrating = false; 14507 } 14508 14509 var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; 14510 14511 var didReceiveUpdate = false; 14512 14513 var didWarnAboutBadClass = void 0; 14514 var didWarnAboutContextTypeOnFunctionComponent = void 0; 14515 var didWarnAboutGetDerivedStateOnFunctionComponent = void 0; 14516 var didWarnAboutFunctionRefs = void 0; 14517 var didWarnAboutReassigningProps = void 0; 14518 14519 { 14520 didWarnAboutBadClass = {}; 14521 didWarnAboutContextTypeOnFunctionComponent = {}; 14522 didWarnAboutGetDerivedStateOnFunctionComponent = {}; 14523 didWarnAboutFunctionRefs = {}; 14524 didWarnAboutReassigningProps = false; 14525 } 14526 14527 function reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime) { 14528 if (current$$1 === null) { 14529 // If this is a fresh new component that hasn't been rendered yet, we 14530 // won't update its child set by applying minimal side-effects. Instead, 14531 // we will add them all to the child before it gets rendered. That means 14532 // we can optimize this reconciliation pass by not tracking side-effects. 14533 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime); 14534 } else { 14535 // If the current child is the same as the work in progress, it means that 14536 // we haven't yet started any work on these children. Therefore, we use 14537 // the clone algorithm to create a copy of all the current children. 14538 14539 // If we had any progressed work already, that is invalid at this point so 14540 // let's throw it out. 14541 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, nextChildren, renderExpirationTime); 14542 } 14543 } 14544 14545 function forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime) { 14546 // This function is fork of reconcileChildren. It's used in cases where we 14547 // want to reconcile without matching against the existing set. This has the 14548 // effect of all current children being unmounted; even if the type and key 14549 // are the same, the old child is unmounted and a new child is created. 14550 // 14551 // To do this, we're going to go through the reconcile algorithm twice. In 14552 // the first pass, we schedule a deletion for all the current children by 14553 // passing null. 14554 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, null, renderExpirationTime); 14555 // In the second pass, we mount the new children. The trick here is that we 14556 // pass null in place of where we usually pass the current child set. This has 14557 // the effect of remounting all children regardless of whether their their 14558 // identity matches. 14559 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime); 14560 } 14561 14562 function updateForwardRef(current$$1, workInProgress, Component, nextProps, renderExpirationTime) { 14563 // TODO: current can be non-null here even if the component 14564 // hasn't yet mounted. This happens after the first render suspends. 14565 // We'll need to figure out if this is fine or can cause issues. 14566 14567 { 14568 if (workInProgress.type !== workInProgress.elementType) { 14569 // Lazy component props can't be validated in createElement 14570 // because they're only guaranteed to be resolved here. 14571 var innerPropTypes = Component.propTypes; 14572 if (innerPropTypes) { 14573 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props 14574 'prop', getComponentName(Component), getCurrentFiberStackInDev); 14575 } 14576 } 14577 } 14578 14579 var render = Component.render; 14580 var ref = workInProgress.ref; 14581 14582 // The rest is a fork of updateFunctionComponent 14583 var nextChildren = void 0; 14584 prepareToReadContext(workInProgress, renderExpirationTime); 14585 { 14586 ReactCurrentOwner$3.current = workInProgress; 14587 setCurrentPhase('render'); 14588 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime); 14589 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) { 14590 // Only double-render components with Hooks 14591 if (workInProgress.memoizedState !== null) { 14592 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime); 14593 } 14594 } 14595 setCurrentPhase(null); 14596 } 14597 14598 if (current$$1 !== null && !didReceiveUpdate) { 14599 bailoutHooks(current$$1, workInProgress, renderExpirationTime); 14600 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime); 14601 } 14602 14603 // React DevTools reads this flag. 14604 workInProgress.effectTag |= PerformedWork; 14605 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 14606 return workInProgress.child; 14607 } 14608 14609 function updateMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) { 14610 if (current$$1 === null) { 14611 var type = Component.type; 14612 if (isSimpleFunctionComponent(type) && Component.compare === null && 14613 // SimpleMemoComponent codepath doesn't resolve outer props either. 14614 Component.defaultProps === undefined) { 14615 // If this is a plain function component without default props, 14616 // and with only the default shallow comparison, we upgrade it 14617 // to a SimpleMemoComponent to allow fast path updates. 14618 workInProgress.tag = SimpleMemoComponent; 14619 workInProgress.type = type; 14620 { 14621 validateFunctionComponentInDev(workInProgress, type); 14622 } 14623 return updateSimpleMemoComponent(current$$1, workInProgress, type, nextProps, updateExpirationTime, renderExpirationTime); 14624 } 14625 { 14626 var innerPropTypes = type.propTypes; 14627 if (innerPropTypes) { 14628 // Inner memo component props aren't currently validated in createElement. 14629 // We could move it there, but we'd still need this for lazy code path. 14630 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props 14631 'prop', getComponentName(type), getCurrentFiberStackInDev); 14632 } 14633 } 14634 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime); 14635 child.ref = workInProgress.ref; 14636 child.return = workInProgress; 14637 workInProgress.child = child; 14638 return child; 14639 } 14640 { 14641 var _type = Component.type; 14642 var _innerPropTypes = _type.propTypes; 14643 if (_innerPropTypes) { 14644 // Inner memo component props aren't currently validated in createElement. 14645 // We could move it there, but we'd still need this for lazy code path. 14646 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props 14647 'prop', getComponentName(_type), getCurrentFiberStackInDev); 14648 } 14649 } 14650 var currentChild = current$$1.child; // This is always exactly one child 14651 if (updateExpirationTime < renderExpirationTime) { 14652 // This will be the props with resolved defaultProps, 14653 // unlike current.memoizedProps which will be the unresolved ones. 14654 var prevProps = currentChild.memoizedProps; 14655 // Default to shallow comparison 14656 var compare = Component.compare; 14657 compare = compare !== null ? compare : shallowEqual; 14658 if (compare(prevProps, nextProps) && current$$1.ref === workInProgress.ref) { 14659 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime); 14660 } 14661 } 14662 // React DevTools reads this flag. 14663 workInProgress.effectTag |= PerformedWork; 14664 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime); 14665 newChild.ref = workInProgress.ref; 14666 newChild.return = workInProgress; 14667 workInProgress.child = newChild; 14668 return newChild; 14669 } 14670 14671 function updateSimpleMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) { 14672 // TODO: current can be non-null here even if the component 14673 // hasn't yet mounted. This happens when the inner render suspends. 14674 // We'll need to figure out if this is fine or can cause issues. 14675 14676 { 14677 if (workInProgress.type !== workInProgress.elementType) { 14678 // Lazy component props can't be validated in createElement 14679 // because they're only guaranteed to be resolved here. 14680 var outerMemoType = workInProgress.elementType; 14681 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) { 14682 // We warn when you define propTypes on lazy() 14683 // so let's just skip over it to find memo() outer wrapper. 14684 // Inner props for memo are validated later. 14685 outerMemoType = refineResolvedLazyComponent(outerMemoType); 14686 } 14687 var outerPropTypes = outerMemoType && outerMemoType.propTypes; 14688 if (outerPropTypes) { 14689 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps) 14690 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev); 14691 } 14692 // Inner propTypes will be validated in the function component path. 14693 } 14694 } 14695 if (current$$1 !== null) { 14696 var prevProps = current$$1.memoizedProps; 14697 if (shallowEqual(prevProps, nextProps) && current$$1.ref === workInProgress.ref) { 14698 didReceiveUpdate = false; 14699 if (updateExpirationTime < renderExpirationTime) { 14700 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime); 14701 } 14702 } 14703 } 14704 return updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime); 14705 } 14706 14707 function updateFragment(current$$1, workInProgress, renderExpirationTime) { 14708 var nextChildren = workInProgress.pendingProps; 14709 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 14710 return workInProgress.child; 14711 } 14712 14713 function updateMode(current$$1, workInProgress, renderExpirationTime) { 14714 var nextChildren = workInProgress.pendingProps.children; 14715 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 14716 return workInProgress.child; 14717 } 14718 14719 function updateProfiler(current$$1, workInProgress, renderExpirationTime) { 14720 if (enableProfilerTimer) { 14721 workInProgress.effectTag |= Update; 14722 } 14723 var nextProps = workInProgress.pendingProps; 14724 var nextChildren = nextProps.children; 14725 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 14726 return workInProgress.child; 14727 } 14728 14729 function markRef(current$$1, workInProgress) { 14730 var ref = workInProgress.ref; 14731 if (current$$1 === null && ref !== null || current$$1 !== null && current$$1.ref !== ref) { 14732 // Schedule a Ref effect 14733 workInProgress.effectTag |= Ref; 14734 } 14735 } 14736 14737 function updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) { 14738 { 14739 if (workInProgress.type !== workInProgress.elementType) { 14740 // Lazy component props can't be validated in createElement 14741 // because they're only guaranteed to be resolved here. 14742 var innerPropTypes = Component.propTypes; 14743 if (innerPropTypes) { 14744 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props 14745 'prop', getComponentName(Component), getCurrentFiberStackInDev); 14746 } 14747 } 14748 } 14749 14750 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); 14751 var context = getMaskedContext(workInProgress, unmaskedContext); 14752 14753 var nextChildren = void 0; 14754 prepareToReadContext(workInProgress, renderExpirationTime); 14755 { 14756 ReactCurrentOwner$3.current = workInProgress; 14757 setCurrentPhase('render'); 14758 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime); 14759 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) { 14760 // Only double-render components with Hooks 14761 if (workInProgress.memoizedState !== null) { 14762 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime); 14763 } 14764 } 14765 setCurrentPhase(null); 14766 } 14767 14768 if (current$$1 !== null && !didReceiveUpdate) { 14769 bailoutHooks(current$$1, workInProgress, renderExpirationTime); 14770 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime); 14771 } 14772 14773 // React DevTools reads this flag. 14774 workInProgress.effectTag |= PerformedWork; 14775 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 14776 return workInProgress.child; 14777 } 14778 14779 function updateClassComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) { 14780 { 14781 if (workInProgress.type !== workInProgress.elementType) { 14782 // Lazy component props can't be validated in createElement 14783 // because they're only guaranteed to be resolved here. 14784 var innerPropTypes = Component.propTypes; 14785 if (innerPropTypes) { 14786 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props 14787 'prop', getComponentName(Component), getCurrentFiberStackInDev); 14788 } 14789 } 14790 } 14791 14792 // Push context providers early to prevent context stack mismatches. 14793 // During mounting we don't know the child context yet as the instance doesn't exist. 14794 // We will invalidate the child context in finishClassComponent() right after rendering. 14795 var hasContext = void 0; 14796 if (isContextProvider(Component)) { 14797 hasContext = true; 14798 pushContextProvider(workInProgress); 14799 } else { 14800 hasContext = false; 14801 } 14802 prepareToReadContext(workInProgress, renderExpirationTime); 14803 14804 var instance = workInProgress.stateNode; 14805 var shouldUpdate = void 0; 14806 if (instance === null) { 14807 if (current$$1 !== null) { 14808 // An class component without an instance only mounts if it suspended 14809 // inside a non- concurrent tree, in an inconsistent state. We want to 14810 // tree it like a new mount, even though an empty version of it already 14811 // committed. Disconnect the alternate pointers. 14812 current$$1.alternate = null; 14813 workInProgress.alternate = null; 14814 // Since this is conceptually a new fiber, schedule a Placement effect 14815 workInProgress.effectTag |= Placement; 14816 } 14817 // In the initial pass we might need to construct the instance. 14818 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime); 14819 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime); 14820 shouldUpdate = true; 14821 } else if (current$$1 === null) { 14822 // In a resume, we'll already have an instance we can reuse. 14823 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime); 14824 } else { 14825 shouldUpdate = updateClassInstance(current$$1, workInProgress, Component, nextProps, renderExpirationTime); 14826 } 14827 var nextUnitOfWork = finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime); 14828 { 14829 var inst = workInProgress.stateNode; 14830 if (inst.props !== nextProps) { 14831 !didWarnAboutReassigningProps ? warning$1(false, 'It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentName(workInProgress.type) || 'a component') : void 0; 14832 didWarnAboutReassigningProps = true; 14833 } 14834 } 14835 return nextUnitOfWork; 14836 } 14837 14838 function finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) { 14839 // Refs should update even if shouldComponentUpdate returns false 14840 markRef(current$$1, workInProgress); 14841 14842 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect; 14843 14844 if (!shouldUpdate && !didCaptureError) { 14845 // Context providers should defer to sCU for rendering 14846 if (hasContext) { 14847 invalidateContextProvider(workInProgress, Component, false); 14848 } 14849 14850 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime); 14851 } 14852 14853 var instance = workInProgress.stateNode; 14854 14855 // Rerender 14856 ReactCurrentOwner$3.current = workInProgress; 14857 var nextChildren = void 0; 14858 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') { 14859 // If we captured an error, but getDerivedStateFrom catch is not defined, 14860 // unmount all the children. componentDidCatch will schedule an update to 14861 // re-render a fallback. This is temporary until we migrate everyone to 14862 // the new API. 14863 // TODO: Warn in a future release. 14864 nextChildren = null; 14865 14866 if (enableProfilerTimer) { 14867 stopProfilerTimerIfRunning(workInProgress); 14868 } 14869 } else { 14870 { 14871 setCurrentPhase('render'); 14872 nextChildren = instance.render(); 14873 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) { 14874 instance.render(); 14875 } 14876 setCurrentPhase(null); 14877 } 14878 } 14879 14880 // React DevTools reads this flag. 14881 workInProgress.effectTag |= PerformedWork; 14882 if (current$$1 !== null && didCaptureError) { 14883 // If we're recovering from an error, reconcile without reusing any of 14884 // the existing children. Conceptually, the normal children and the children 14885 // that are shown on error are two different sets, so we shouldn't reuse 14886 // normal children even if their identities match. 14887 forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime); 14888 } else { 14889 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 14890 } 14891 14892 // Memoize state using the values we just used to render. 14893 // TODO: Restructure so we never read values from the instance. 14894 workInProgress.memoizedState = instance.state; 14895 14896 // The context might have changed so we need to recalculate it. 14897 if (hasContext) { 14898 invalidateContextProvider(workInProgress, Component, true); 14899 } 14900 14901 return workInProgress.child; 14902 } 14903 14904 function pushHostRootContext(workInProgress) { 14905 var root = workInProgress.stateNode; 14906 if (root.pendingContext) { 14907 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context); 14908 } else if (root.context) { 14909 // Should always be set 14910 pushTopLevelContextObject(workInProgress, root.context, false); 14911 } 14912 pushHostContainer(workInProgress, root.containerInfo); 14913 } 14914 14915 function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { 14916 pushHostRootContext(workInProgress); 14917 var updateQueue = workInProgress.updateQueue; 14918 !(updateQueue !== null) ? invariant(false, 'If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue.') : void 0; 14919 var nextProps = workInProgress.pendingProps; 14920 var prevState = workInProgress.memoizedState; 14921 var prevChildren = prevState !== null ? prevState.element : null; 14922 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime); 14923 var nextState = workInProgress.memoizedState; 14924 // Caution: React DevTools currently depends on this property 14925 // being called "element". 14926 var nextChildren = nextState.element; 14927 if (nextChildren === prevChildren) { 14928 // If the state is the same as before, that's a bailout because we had 14929 // no work that expires at this time. 14930 resetHydrationState(); 14931 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime); 14932 } 14933 var root = workInProgress.stateNode; 14934 if ((current$$1 === null || current$$1.child === null) && root.hydrate && enterHydrationState(workInProgress)) { 14935 // If we don't have any current children this might be the first pass. 14936 // We always try to hydrate. If this isn't a hydration pass there won't 14937 // be any children to hydrate which is effectively the same thing as 14938 // not hydrating. 14939 14940 // This is a bit of a hack. We track the host root as a placement to 14941 // know that we're currently in a mounting state. That way isMounted 14942 // works as expected. We must reset this before committing. 14943 // TODO: Delete this when we delete isMounted and findDOMNode. 14944 workInProgress.effectTag |= Placement; 14945 14946 // Ensure that children mount into this root without tracking 14947 // side-effects. This ensures that we don't store Placement effects on 14948 // nodes that will be hydrated. 14949 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime); 14950 } else { 14951 // Otherwise reset hydration state in case we aborted and resumed another 14952 // root. 14953 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 14954 resetHydrationState(); 14955 } 14956 return workInProgress.child; 14957 } 14958 14959 function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { 14960 pushHostContext(workInProgress); 14961 14962 if (current$$1 === null) { 14963 tryToClaimNextHydratableInstance(workInProgress); 14964 } 14965 14966 var type = workInProgress.type; 14967 var nextProps = workInProgress.pendingProps; 14968 var prevProps = current$$1 !== null ? current$$1.memoizedProps : null; 14969 14970 var nextChildren = nextProps.children; 14971 var isDirectTextChild = shouldSetTextContent(type, nextProps); 14972 14973 if (isDirectTextChild) { 14974 // We special case a direct text child of a host node. This is a common 14975 // case. We won't handle it as a reified child. We will instead handle 14976 // this in the host environment that also have access to this prop. That 14977 // avoids allocating another HostText fiber and traversing it. 14978 nextChildren = null; 14979 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) { 14980 // If we're switching from a direct text child to a normal child, or to 14981 // empty, we need to schedule the text content to be reset. 14982 workInProgress.effectTag |= ContentReset; 14983 } 14984 14985 markRef(current$$1, workInProgress); 14986 14987 // Check the host config to see if the children are offscreen/hidden. 14988 if (renderExpirationTime !== Never && workInProgress.mode & ConcurrentMode && shouldDeprioritizeSubtree(type, nextProps)) { 14989 // Schedule this fiber to re-render at offscreen priority. Then bailout. 14990 workInProgress.expirationTime = workInProgress.childExpirationTime = Never; 14991 return null; 14992 } 14993 14994 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 14995 return workInProgress.child; 14996 } 14997 14998 function updateHostText(current$$1, workInProgress) { 14999 if (current$$1 === null) { 15000 tryToClaimNextHydratableInstance(workInProgress); 15001 } 15002 // Nothing to do here. This is terminal. We'll do the completion step 15003 // immediately after. 15004 return null; 15005 } 15006 15007 function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) { 15008 if (_current !== null) { 15009 // An lazy component only mounts if it suspended inside a non- 15010 // concurrent tree, in an inconsistent state. We want to treat it like 15011 // a new mount, even though an empty version of it already committed. 15012 // Disconnect the alternate pointers. 15013 _current.alternate = null; 15014 workInProgress.alternate = null; 15015 // Since this is conceptually a new fiber, schedule a Placement effect 15016 workInProgress.effectTag |= Placement; 15017 } 15018 15019 var props = workInProgress.pendingProps; 15020 // We can't start a User Timing measurement with correct label yet. 15021 // Cancel and resume right after we know the tag. 15022 cancelWorkTimer(workInProgress); 15023 var Component = readLazyComponentType(elementType); 15024 // Store the unwrapped component in the type. 15025 workInProgress.type = Component; 15026 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component); 15027 startWorkTimer(workInProgress); 15028 var resolvedProps = resolveDefaultProps(Component, props); 15029 var child = void 0; 15030 switch (resolvedTag) { 15031 case FunctionComponent: 15032 { 15033 { 15034 validateFunctionComponentInDev(workInProgress, Component); 15035 } 15036 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime); 15037 break; 15038 } 15039 case ClassComponent: 15040 { 15041 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime); 15042 break; 15043 } 15044 case ForwardRef: 15045 { 15046 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime); 15047 break; 15048 } 15049 case MemoComponent: 15050 { 15051 { 15052 if (workInProgress.type !== workInProgress.elementType) { 15053 var outerPropTypes = Component.propTypes; 15054 if (outerPropTypes) { 15055 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only 15056 'prop', getComponentName(Component), getCurrentFiberStackInDev); 15057 } 15058 } 15059 } 15060 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too 15061 updateExpirationTime, renderExpirationTime); 15062 break; 15063 } 15064 default: 15065 { 15066 var hint = ''; 15067 { 15068 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) { 15069 hint = ' Did you wrap a component in React.lazy() more than once?'; 15070 } 15071 } 15072 // This message intentionally doesn't mention ForwardRef or MemoComponent 15073 // because the fact that it's a separate type of work is an 15074 // implementation detail. 15075 invariant(false, 'Element type is invalid. Received a promise that resolves to: %s. Lazy element type must resolve to a class or function.%s', Component, hint); 15076 } 15077 } 15078 return child; 15079 } 15080 15081 function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) { 15082 if (_current !== null) { 15083 // An incomplete component only mounts if it suspended inside a non- 15084 // concurrent tree, in an inconsistent state. We want to treat it like 15085 // a new mount, even though an empty version of it already committed. 15086 // Disconnect the alternate pointers. 15087 _current.alternate = null; 15088 workInProgress.alternate = null; 15089 // Since this is conceptually a new fiber, schedule a Placement effect 15090 workInProgress.effectTag |= Placement; 15091 } 15092 15093 // Promote the fiber to a class and try rendering again. 15094 workInProgress.tag = ClassComponent; 15095 15096 // The rest of this function is a fork of `updateClassComponent` 15097 15098 // Push context providers early to prevent context stack mismatches. 15099 // During mounting we don't know the child context yet as the instance doesn't exist. 15100 // We will invalidate the child context in finishClassComponent() right after rendering. 15101 var hasContext = void 0; 15102 if (isContextProvider(Component)) { 15103 hasContext = true; 15104 pushContextProvider(workInProgress); 15105 } else { 15106 hasContext = false; 15107 } 15108 prepareToReadContext(workInProgress, renderExpirationTime); 15109 15110 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime); 15111 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime); 15112 15113 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime); 15114 } 15115 15116 function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) { 15117 if (_current !== null) { 15118 // An indeterminate component only mounts if it suspended inside a non- 15119 // concurrent tree, in an inconsistent state. We want to treat it like 15120 // a new mount, even though an empty version of it already committed. 15121 // Disconnect the alternate pointers. 15122 _current.alternate = null; 15123 workInProgress.alternate = null; 15124 // Since this is conceptually a new fiber, schedule a Placement effect 15125 workInProgress.effectTag |= Placement; 15126 } 15127 15128 var props = workInProgress.pendingProps; 15129 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); 15130 var context = getMaskedContext(workInProgress, unmaskedContext); 15131 15132 prepareToReadContext(workInProgress, renderExpirationTime); 15133 15134 var value = void 0; 15135 15136 { 15137 if (Component.prototype && typeof Component.prototype.render === 'function') { 15138 var componentName = getComponentName(Component) || 'Unknown'; 15139 15140 if (!didWarnAboutBadClass[componentName]) { 15141 warningWithoutStack$1(false, "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + 'This is likely to cause errors. Change %s to extend React.Component instead.', componentName, componentName); 15142 didWarnAboutBadClass[componentName] = true; 15143 } 15144 } 15145 15146 if (workInProgress.mode & StrictMode) { 15147 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); 15148 } 15149 15150 ReactCurrentOwner$3.current = workInProgress; 15151 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime); 15152 } 15153 // React DevTools reads this flag. 15154 workInProgress.effectTag |= PerformedWork; 15155 15156 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) { 15157 // Proceed under the assumption that this is a class instance 15158 workInProgress.tag = ClassComponent; 15159 15160 // Throw out any hooks that were used. 15161 resetHooks(); 15162 15163 // Push context providers early to prevent context stack mismatches. 15164 // During mounting we don't know the child context yet as the instance doesn't exist. 15165 // We will invalidate the child context in finishClassComponent() right after rendering. 15166 var hasContext = false; 15167 if (isContextProvider(Component)) { 15168 hasContext = true; 15169 pushContextProvider(workInProgress); 15170 } else { 15171 hasContext = false; 15172 } 15173 15174 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; 15175 15176 var getDerivedStateFromProps = Component.getDerivedStateFromProps; 15177 if (typeof getDerivedStateFromProps === 'function') { 15178 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props); 15179 } 15180 15181 adoptClassInstance(workInProgress, value); 15182 mountClassInstance(workInProgress, Component, props, renderExpirationTime); 15183 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime); 15184 } else { 15185 // Proceed under the assumption that this is a function component 15186 workInProgress.tag = FunctionComponent; 15187 { 15188 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) { 15189 // Only double-render components with Hooks 15190 if (workInProgress.memoizedState !== null) { 15191 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime); 15192 } 15193 } 15194 } 15195 reconcileChildren(null, workInProgress, value, renderExpirationTime); 15196 { 15197 validateFunctionComponentInDev(workInProgress, Component); 15198 } 15199 return workInProgress.child; 15200 } 15201 } 15202 15203 function validateFunctionComponentInDev(workInProgress, Component) { 15204 if (Component) { 15205 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0; 15206 } 15207 if (workInProgress.ref !== null) { 15208 var info = ''; 15209 var ownerName = getCurrentFiberOwnerNameInDevOrNull(); 15210 if (ownerName) { 15211 info += '\n\nCheck the render method of `' + ownerName + '`.'; 15212 } 15213 15214 var warningKey = ownerName || workInProgress._debugID || ''; 15215 var debugSource = workInProgress._debugSource; 15216 if (debugSource) { 15217 warningKey = debugSource.fileName + ':' + debugSource.lineNumber; 15218 } 15219 if (!didWarnAboutFunctionRefs[warningKey]) { 15220 didWarnAboutFunctionRefs[warningKey] = true; 15221 warning$1(false, 'Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info); 15222 } 15223 } 15224 15225 if (typeof Component.getDerivedStateFromProps === 'function') { 15226 var componentName = getComponentName(Component) || 'Unknown'; 15227 15228 if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) { 15229 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', componentName); 15230 didWarnAboutGetDerivedStateOnFunctionComponent[componentName] = true; 15231 } 15232 } 15233 15234 if (typeof Component.contextType === 'object' && Component.contextType !== null) { 15235 var _componentName = getComponentName(Component) || 'Unknown'; 15236 15237 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName]) { 15238 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName); 15239 didWarnAboutContextTypeOnFunctionComponent[_componentName] = true; 15240 } 15241 } 15242 } 15243 15244 function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime) { 15245 var mode = workInProgress.mode; 15246 var nextProps = workInProgress.pendingProps; 15247 15248 // We should attempt to render the primary children unless this boundary 15249 // already suspended during this render (`alreadyCaptured` is true). 15250 var nextState = workInProgress.memoizedState; 15251 15252 var nextDidTimeout = void 0; 15253 if ((workInProgress.effectTag & DidCapture) === NoEffect) { 15254 // This is the first attempt. 15255 nextState = null; 15256 nextDidTimeout = false; 15257 } else { 15258 // Something in this boundary's subtree already suspended. Switch to 15259 // rendering the fallback children. 15260 nextState = { 15261 timedOutAt: nextState !== null ? nextState.timedOutAt : NoWork 15262 }; 15263 nextDidTimeout = true; 15264 workInProgress.effectTag &= ~DidCapture; 15265 } 15266 15267 // This next part is a bit confusing. If the children timeout, we switch to 15268 // showing the fallback children in place of the "primary" children. 15269 // However, we don't want to delete the primary children because then their 15270 // state will be lost (both the React state and the host state, e.g. 15271 // uncontrolled form inputs). Instead we keep them mounted and hide them. 15272 // Both the fallback children AND the primary children are rendered at the 15273 // same time. Once the primary children are un-suspended, we can delete 15274 // the fallback children — don't need to preserve their state. 15275 // 15276 // The two sets of children are siblings in the host environment, but 15277 // semantically, for purposes of reconciliation, they are two separate sets. 15278 // So we store them using two fragment fibers. 15279 // 15280 // However, we want to avoid allocating extra fibers for every placeholder. 15281 // They're only necessary when the children time out, because that's the 15282 // only time when both sets are mounted. 15283 // 15284 // So, the extra fragment fibers are only used if the children time out. 15285 // Otherwise, we render the primary children directly. This requires some 15286 // custom reconciliation logic to preserve the state of the primary 15287 // children. It's essentially a very basic form of re-parenting. 15288 15289 // `child` points to the child fiber. In the normal case, this is the first 15290 // fiber of the primary children set. In the timed-out case, it's a 15291 // a fragment fiber containing the primary children. 15292 var child = void 0; 15293 // `next` points to the next fiber React should render. In the normal case, 15294 // it's the same as `child`: the first fiber of the primary children set. 15295 // In the timed-out case, it's a fragment fiber containing the *fallback* 15296 // children -- we skip over the primary children entirely. 15297 var next = void 0; 15298 if (current$$1 === null) { 15299 if (enableSuspenseServerRenderer) { 15300 // If we're currently hydrating, try to hydrate this boundary. 15301 // But only if this has a fallback. 15302 if (nextProps.fallback !== undefined) { 15303 tryToClaimNextHydratableInstance(workInProgress); 15304 // This could've changed the tag if this was a dehydrated suspense component. 15305 if (workInProgress.tag === DehydratedSuspenseComponent) { 15306 return updateDehydratedSuspenseComponent(null, workInProgress, renderExpirationTime); 15307 } 15308 } 15309 } 15310 15311 // This is the initial mount. This branch is pretty simple because there's 15312 // no previous state that needs to be preserved. 15313 if (nextDidTimeout) { 15314 // Mount separate fragments for primary and fallback children. 15315 var nextFallbackChildren = nextProps.fallback; 15316 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null); 15317 15318 if ((workInProgress.mode & ConcurrentMode) === NoContext) { 15319 // Outside of concurrent mode, we commit the effects from the 15320 var progressedState = workInProgress.memoizedState; 15321 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child; 15322 primaryChildFragment.child = progressedPrimaryChild; 15323 } 15324 15325 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null); 15326 primaryChildFragment.sibling = fallbackChildFragment; 15327 child = primaryChildFragment; 15328 // Skip the primary children, and continue working on the 15329 // fallback children. 15330 next = fallbackChildFragment; 15331 child.return = next.return = workInProgress; 15332 } else { 15333 // Mount the primary children without an intermediate fragment fiber. 15334 var nextPrimaryChildren = nextProps.children; 15335 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime); 15336 } 15337 } else { 15338 // This is an update. This branch is more complicated because we need to 15339 // ensure the state of the primary children is preserved. 15340 var prevState = current$$1.memoizedState; 15341 var prevDidTimeout = prevState !== null; 15342 if (prevDidTimeout) { 15343 // The current tree already timed out. That means each child set is 15344 var currentPrimaryChildFragment = current$$1.child; 15345 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; 15346 if (nextDidTimeout) { 15347 // Still timed out. Reuse the current primary children by cloning 15348 // its fragment. We're going to skip over these entirely. 15349 var _nextFallbackChildren = nextProps.fallback; 15350 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork); 15351 15352 if ((workInProgress.mode & ConcurrentMode) === NoContext) { 15353 // Outside of concurrent mode, we commit the effects from the 15354 var _progressedState = workInProgress.memoizedState; 15355 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child; 15356 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) { 15357 _primaryChildFragment.child = _progressedPrimaryChild; 15358 } 15359 } 15360 15361 // Because primaryChildFragment is a new fiber that we're inserting as the 15362 // parent of a new tree, we need to set its treeBaseDuration. 15363 if (enableProfilerTimer && workInProgress.mode & ProfileMode) { 15364 // treeBaseDuration is the sum of all the child tree base durations. 15365 var treeBaseDuration = 0; 15366 var hiddenChild = _primaryChildFragment.child; 15367 while (hiddenChild !== null) { 15368 treeBaseDuration += hiddenChild.treeBaseDuration; 15369 hiddenChild = hiddenChild.sibling; 15370 } 15371 _primaryChildFragment.treeBaseDuration = treeBaseDuration; 15372 } 15373 15374 // Clone the fallback child fragment, too. These we'll continue 15375 // working on. 15376 var _fallbackChildFragment = _primaryChildFragment.sibling = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime); 15377 child = _primaryChildFragment; 15378 _primaryChildFragment.childExpirationTime = NoWork; 15379 // Skip the primary children, and continue working on the 15380 // fallback children. 15381 next = _fallbackChildFragment; 15382 child.return = next.return = workInProgress; 15383 } else { 15384 // No longer suspended. Switch back to showing the primary children, 15385 // and remove the intermediate fragment fiber. 15386 var _nextPrimaryChildren = nextProps.children; 15387 var currentPrimaryChild = currentPrimaryChildFragment.child; 15388 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime); 15389 15390 // If this render doesn't suspend, we need to delete the fallback 15391 // children. Wait until the complete phase, after we've confirmed the 15392 // fallback is no longer needed. 15393 // TODO: Would it be better to store the fallback fragment on 15394 // the stateNode? 15395 15396 // Continue rendering the children, like we normally do. 15397 child = next = primaryChild; 15398 } 15399 } else { 15400 // The current tree has not already timed out. That means the primary 15401 // children are not wrapped in a fragment fiber. 15402 var _currentPrimaryChild = current$$1.child; 15403 if (nextDidTimeout) { 15404 // Timed out. Wrap the children in a fragment fiber to keep them 15405 // separate from the fallback children. 15406 var _nextFallbackChildren2 = nextProps.fallback; 15407 var _primaryChildFragment2 = createFiberFromFragment( 15408 // It shouldn't matter what the pending props are because we aren't 15409 // going to render this fragment. 15410 null, mode, NoWork, null); 15411 _primaryChildFragment2.child = _currentPrimaryChild; 15412 15413 // Even though we're creating a new fiber, there are no new children, 15414 // because we're reusing an already mounted tree. So we don't need to 15415 // schedule a placement. 15416 // primaryChildFragment.effectTag |= Placement; 15417 15418 if ((workInProgress.mode & ConcurrentMode) === NoContext) { 15419 // Outside of concurrent mode, we commit the effects from the 15420 var _progressedState2 = workInProgress.memoizedState; 15421 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child; 15422 _primaryChildFragment2.child = _progressedPrimaryChild2; 15423 } 15424 15425 // Because primaryChildFragment is a new fiber that we're inserting as the 15426 // parent of a new tree, we need to set its treeBaseDuration. 15427 if (enableProfilerTimer && workInProgress.mode & ProfileMode) { 15428 // treeBaseDuration is the sum of all the child tree base durations. 15429 var _treeBaseDuration = 0; 15430 var _hiddenChild = _primaryChildFragment2.child; 15431 while (_hiddenChild !== null) { 15432 _treeBaseDuration += _hiddenChild.treeBaseDuration; 15433 _hiddenChild = _hiddenChild.sibling; 15434 } 15435 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration; 15436 } 15437 15438 // Create a fragment from the fallback children, too. 15439 var _fallbackChildFragment2 = _primaryChildFragment2.sibling = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null); 15440 _fallbackChildFragment2.effectTag |= Placement; 15441 child = _primaryChildFragment2; 15442 _primaryChildFragment2.childExpirationTime = NoWork; 15443 // Skip the primary children, and continue working on the 15444 // fallback children. 15445 next = _fallbackChildFragment2; 15446 child.return = next.return = workInProgress; 15447 } else { 15448 // Still haven't timed out. Continue rendering the children, like we 15449 // normally do. 15450 var _nextPrimaryChildren2 = nextProps.children; 15451 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime); 15452 } 15453 } 15454 workInProgress.stateNode = current$$1.stateNode; 15455 } 15456 15457 workInProgress.memoizedState = nextState; 15458 workInProgress.child = child; 15459 return next; 15460 } 15461 15462 function updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime) { 15463 if (current$$1 === null) { 15464 // During the first pass, we'll bail out and not drill into the children. 15465 // Instead, we'll leave the content in place and try to hydrate it later. 15466 workInProgress.expirationTime = Never; 15467 return null; 15468 } 15469 // We use childExpirationTime to indicate that a child might depend on context, so if 15470 // any context has changed, we need to treat is as if the input might have changed. 15471 var hasContextChanged$$1 = current$$1.childExpirationTime >= renderExpirationTime; 15472 if (didReceiveUpdate || hasContextChanged$$1) { 15473 // This boundary has changed since the first render. This means that we are now unable to 15474 // hydrate it. We might still be able to hydrate it using an earlier expiration time but 15475 // during this render we can't. Instead, we're going to delete the whole subtree and 15476 // instead inject a new real Suspense boundary to take its place, which may render content 15477 // or fallback. The real Suspense boundary will suspend for a while so we have some time 15478 // to ensure it can produce real content, but all state and pending events will be lost. 15479 15480 // Detach from the current dehydrated boundary. 15481 current$$1.alternate = null; 15482 workInProgress.alternate = null; 15483 15484 // Insert a deletion in the effect list. 15485 var returnFiber = workInProgress.return; 15486 !(returnFiber !== null) ? invariant(false, 'Suspense boundaries are never on the root. This is probably a bug in React.') : void 0; 15487 var last = returnFiber.lastEffect; 15488 if (last !== null) { 15489 last.nextEffect = current$$1; 15490 returnFiber.lastEffect = current$$1; 15491 } else { 15492 returnFiber.firstEffect = returnFiber.lastEffect = current$$1; 15493 } 15494 current$$1.nextEffect = null; 15495 current$$1.effectTag = Deletion; 15496 15497 // Upgrade this work in progress to a real Suspense component. 15498 workInProgress.tag = SuspenseComponent; 15499 workInProgress.stateNode = null; 15500 workInProgress.memoizedState = null; 15501 // This is now an insertion. 15502 workInProgress.effectTag |= Placement; 15503 // Retry as a real Suspense component. 15504 return updateSuspenseComponent(null, workInProgress, renderExpirationTime); 15505 } 15506 if ((workInProgress.effectTag & DidCapture) === NoEffect) { 15507 // This is the first attempt. 15508 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress); 15509 var nextProps = workInProgress.pendingProps; 15510 var nextChildren = nextProps.children; 15511 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime); 15512 return workInProgress.child; 15513 } else { 15514 // Something suspended. Leave the existing children in place. 15515 // TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far? 15516 workInProgress.child = null; 15517 return null; 15518 } 15519 } 15520 15521 function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) { 15522 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); 15523 var nextChildren = workInProgress.pendingProps; 15524 if (current$$1 === null) { 15525 // Portals are special because we don't append the children during mount 15526 // but at commit. Therefore we need to track insertions which the normal 15527 // flow doesn't do during mount. This doesn't happen at the root because 15528 // the root always starts with a "current" with a null child. 15529 // TODO: Consider unifying this with how the root works. 15530 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime); 15531 } else { 15532 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 15533 } 15534 return workInProgress.child; 15535 } 15536 15537 function updateContextProvider(current$$1, workInProgress, renderExpirationTime) { 15538 var providerType = workInProgress.type; 15539 var context = providerType._context; 15540 15541 var newProps = workInProgress.pendingProps; 15542 var oldProps = workInProgress.memoizedProps; 15543 15544 var newValue = newProps.value; 15545 15546 { 15547 var providerPropTypes = workInProgress.type.propTypes; 15548 15549 if (providerPropTypes) { 15550 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev); 15551 } 15552 } 15553 15554 pushProvider(workInProgress, newValue); 15555 15556 if (oldProps !== null) { 15557 var oldValue = oldProps.value; 15558 var changedBits = calculateChangedBits(context, newValue, oldValue); 15559 if (changedBits === 0) { 15560 // No change. Bailout early if children are the same. 15561 if (oldProps.children === newProps.children && !hasContextChanged()) { 15562 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime); 15563 } 15564 } else { 15565 // The context value changed. Search for matching consumers and schedule 15566 // them to update. 15567 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime); 15568 } 15569 } 15570 15571 var newChildren = newProps.children; 15572 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime); 15573 return workInProgress.child; 15574 } 15575 15576 var hasWarnedAboutUsingContextAsConsumer = false; 15577 15578 function updateContextConsumer(current$$1, workInProgress, renderExpirationTime) { 15579 var context = workInProgress.type; 15580 // The logic below for Context differs depending on PROD or DEV mode. In 15581 // DEV mode, we create a separate object for Context.Consumer that acts 15582 // like a proxy to Context. This proxy object adds unnecessary code in PROD 15583 // so we use the old behaviour (Context.Consumer references Context) to 15584 // reduce size and overhead. The separate object references context via 15585 // a property called "_context", which also gives us the ability to check 15586 // in DEV mode if this property exists or not and warn if it does not. 15587 { 15588 if (context._context === undefined) { 15589 // This may be because it's a Context (rather than a Consumer). 15590 // Or it may be because it's older React where they're the same thing. 15591 // We only want to warn if we're sure it's a new React. 15592 if (context !== context.Consumer) { 15593 if (!hasWarnedAboutUsingContextAsConsumer) { 15594 hasWarnedAboutUsingContextAsConsumer = true; 15595 warning$1(false, 'Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?'); 15596 } 15597 } 15598 } else { 15599 context = context._context; 15600 } 15601 } 15602 var newProps = workInProgress.pendingProps; 15603 var render = newProps.children; 15604 15605 { 15606 !(typeof render === 'function') ? warningWithoutStack$1(false, 'A context consumer was rendered with multiple children, or a child ' + "that isn't a function. A context consumer expects a single child " + 'that is a function. If you did pass a function, make sure there ' + 'is no trailing or leading whitespace around it.') : void 0; 15607 } 15608 15609 prepareToReadContext(workInProgress, renderExpirationTime); 15610 var newValue = readContext(context, newProps.unstable_observedBits); 15611 var newChildren = void 0; 15612 { 15613 ReactCurrentOwner$3.current = workInProgress; 15614 setCurrentPhase('render'); 15615 newChildren = render(newValue); 15616 setCurrentPhase(null); 15617 } 15618 15619 // React DevTools reads this flag. 15620 workInProgress.effectTag |= PerformedWork; 15621 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime); 15622 return workInProgress.child; 15623 } 15624 15625 function markWorkInProgressReceivedUpdate() { 15626 didReceiveUpdate = true; 15627 } 15628 15629 function bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime) { 15630 cancelWorkTimer(workInProgress); 15631 15632 if (current$$1 !== null) { 15633 // Reuse previous context list 15634 workInProgress.contextDependencies = current$$1.contextDependencies; 15635 } 15636 15637 if (enableProfilerTimer) { 15638 // Don't update "base" render times for bailouts. 15639 stopProfilerTimerIfRunning(workInProgress); 15640 } 15641 15642 // Check if the children have any pending work. 15643 var childExpirationTime = workInProgress.childExpirationTime; 15644 if (childExpirationTime < renderExpirationTime) { 15645 // The children don't have any work either. We can skip them. 15646 // TODO: Once we add back resuming, we should check if the children are 15647 // a work-in-progress set. If so, we need to transfer their effects. 15648 return null; 15649 } else { 15650 // This fiber doesn't have work, but its subtree does. Clone the child 15651 // fibers and continue. 15652 cloneChildFibers(current$$1, workInProgress); 15653 return workInProgress.child; 15654 } 15655 } 15656 15657 function beginWork(current$$1, workInProgress, renderExpirationTime) { 15658 var updateExpirationTime = workInProgress.expirationTime; 15659 15660 if (current$$1 !== null) { 15661 var oldProps = current$$1.memoizedProps; 15662 var newProps = workInProgress.pendingProps; 15663 15664 if (oldProps !== newProps || hasContextChanged()) { 15665 // If props or context changed, mark the fiber as having performed work. 15666 // This may be unset if the props are determined to be equal later (memo). 15667 didReceiveUpdate = true; 15668 } else if (updateExpirationTime < renderExpirationTime) { 15669 didReceiveUpdate = false; 15670 // This fiber does not have any pending work. Bailout without entering 15671 // the begin phase. There's still some bookkeeping we that needs to be done 15672 // in this optimized path, mostly pushing stuff onto the stack. 15673 switch (workInProgress.tag) { 15674 case HostRoot: 15675 pushHostRootContext(workInProgress); 15676 resetHydrationState(); 15677 break; 15678 case HostComponent: 15679 pushHostContext(workInProgress); 15680 break; 15681 case ClassComponent: 15682 { 15683 var Component = workInProgress.type; 15684 if (isContextProvider(Component)) { 15685 pushContextProvider(workInProgress); 15686 } 15687 break; 15688 } 15689 case HostPortal: 15690 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); 15691 break; 15692 case ContextProvider: 15693 { 15694 var newValue = workInProgress.memoizedProps.value; 15695 pushProvider(workInProgress, newValue); 15696 break; 15697 } 15698 case Profiler: 15699 if (enableProfilerTimer) { 15700 workInProgress.effectTag |= Update; 15701 } 15702 break; 15703 case SuspenseComponent: 15704 { 15705 var state = workInProgress.memoizedState; 15706 var didTimeout = state !== null; 15707 if (didTimeout) { 15708 // If this boundary is currently timed out, we need to decide 15709 // whether to retry the primary children, or to skip over it and 15710 // go straight to the fallback. Check the priority of the primary 15711 var primaryChildFragment = workInProgress.child; 15712 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime; 15713 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) { 15714 // The primary children have pending work. Use the normal path 15715 // to attempt to render the primary children again. 15716 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime); 15717 } else { 15718 // The primary children do not have pending work with sufficient 15719 // priority. Bailout. 15720 var child = bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime); 15721 if (child !== null) { 15722 // The fallback children have pending work. Skip over the 15723 // primary children and work on the fallback. 15724 return child.sibling; 15725 } else { 15726 return null; 15727 } 15728 } 15729 } 15730 break; 15731 } 15732 case DehydratedSuspenseComponent: 15733 { 15734 if (enableSuspenseServerRenderer) { 15735 // We know that this component will suspend again because if it has 15736 // been unsuspended it has committed as a regular Suspense component. 15737 // If it needs to be retried, it should have work scheduled on it. 15738 workInProgress.effectTag |= DidCapture; 15739 break; 15740 } 15741 } 15742 } 15743 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime); 15744 } 15745 } else { 15746 didReceiveUpdate = false; 15747 } 15748 15749 // Before entering the begin phase, clear the expiration time. 15750 workInProgress.expirationTime = NoWork; 15751 15752 switch (workInProgress.tag) { 15753 case IndeterminateComponent: 15754 { 15755 var elementType = workInProgress.elementType; 15756 return mountIndeterminateComponent(current$$1, workInProgress, elementType, renderExpirationTime); 15757 } 15758 case LazyComponent: 15759 { 15760 var _elementType = workInProgress.elementType; 15761 return mountLazyComponent(current$$1, workInProgress, _elementType, updateExpirationTime, renderExpirationTime); 15762 } 15763 case FunctionComponent: 15764 { 15765 var _Component = workInProgress.type; 15766 var unresolvedProps = workInProgress.pendingProps; 15767 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps); 15768 return updateFunctionComponent(current$$1, workInProgress, _Component, resolvedProps, renderExpirationTime); 15769 } 15770 case ClassComponent: 15771 { 15772 var _Component2 = workInProgress.type; 15773 var _unresolvedProps = workInProgress.pendingProps; 15774 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps); 15775 return updateClassComponent(current$$1, workInProgress, _Component2, _resolvedProps, renderExpirationTime); 15776 } 15777 case HostRoot: 15778 return updateHostRoot(current$$1, workInProgress, renderExpirationTime); 15779 case HostComponent: 15780 return updateHostComponent(current$$1, workInProgress, renderExpirationTime); 15781 case HostText: 15782 return updateHostText(current$$1, workInProgress); 15783 case SuspenseComponent: 15784 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime); 15785 case HostPortal: 15786 return updatePortalComponent(current$$1, workInProgress, renderExpirationTime); 15787 case ForwardRef: 15788 { 15789 var type = workInProgress.type; 15790 var _unresolvedProps2 = workInProgress.pendingProps; 15791 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2); 15792 return updateForwardRef(current$$1, workInProgress, type, _resolvedProps2, renderExpirationTime); 15793 } 15794 case Fragment: 15795 return updateFragment(current$$1, workInProgress, renderExpirationTime); 15796 case Mode: 15797 return updateMode(current$$1, workInProgress, renderExpirationTime); 15798 case Profiler: 15799 return updateProfiler(current$$1, workInProgress, renderExpirationTime); 15800 case ContextProvider: 15801 return updateContextProvider(current$$1, workInProgress, renderExpirationTime); 15802 case ContextConsumer: 15803 return updateContextConsumer(current$$1, workInProgress, renderExpirationTime); 15804 case MemoComponent: 15805 { 15806 var _type2 = workInProgress.type; 15807 var _unresolvedProps3 = workInProgress.pendingProps; 15808 // Resolve outer props first, then resolve inner props. 15809 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); 15810 { 15811 if (workInProgress.type !== workInProgress.elementType) { 15812 var outerPropTypes = _type2.propTypes; 15813 if (outerPropTypes) { 15814 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only 15815 'prop', getComponentName(_type2), getCurrentFiberStackInDev); 15816 } 15817 } 15818 } 15819 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); 15820 return updateMemoComponent(current$$1, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime); 15821 } 15822 case SimpleMemoComponent: 15823 { 15824 return updateSimpleMemoComponent(current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime); 15825 } 15826 case IncompleteClassComponent: 15827 { 15828 var _Component3 = workInProgress.type; 15829 var _unresolvedProps4 = workInProgress.pendingProps; 15830 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4); 15831 return mountIncompleteClassComponent(current$$1, workInProgress, _Component3, _resolvedProps4, renderExpirationTime); 15832 } 15833 case DehydratedSuspenseComponent: 15834 { 15835 if (enableSuspenseServerRenderer) { 15836 return updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime); 15837 } 15838 break; 15839 } 15840 } 15841 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.'); 15842 } 15843 15844 var valueCursor = createCursor(null); 15845 15846 var rendererSigil = void 0; 15847 { 15848 // Use this to detect multiple renderers using the same context 15849 rendererSigil = {}; 15850 } 15851 15852 var currentlyRenderingFiber = null; 15853 var lastContextDependency = null; 15854 var lastContextWithAllBitsObserved = null; 15855 15856 var isDisallowedContextReadInDEV = false; 15857 15858 function resetContextDependences() { 15859 // This is called right before React yields execution, to ensure `readContext` 15860 // cannot be called outside the render phase. 15861 currentlyRenderingFiber = null; 15862 lastContextDependency = null; 15863 lastContextWithAllBitsObserved = null; 15864 { 15865 isDisallowedContextReadInDEV = false; 15866 } 15867 } 15868 15869 function enterDisallowedContextReadInDEV() { 15870 { 15871 isDisallowedContextReadInDEV = true; 15872 } 15873 } 15874 15875 function exitDisallowedContextReadInDEV() { 15876 { 15877 isDisallowedContextReadInDEV = false; 15878 } 15879 } 15880 15881 function pushProvider(providerFiber, nextValue) { 15882 var context = providerFiber.type._context; 15883 15884 if (isPrimaryRenderer) { 15885 push(valueCursor, context._currentValue, providerFiber); 15886 15887 context._currentValue = nextValue; 15888 { 15889 !(context._currentRenderer === undefined || context._currentRenderer === null || context._currentRenderer === rendererSigil) ? warningWithoutStack$1(false, 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.') : void 0; 15890 context._currentRenderer = rendererSigil; 15891 } 15892 } else { 15893 push(valueCursor, context._currentValue2, providerFiber); 15894 15895 context._currentValue2 = nextValue; 15896 { 15897 !(context._currentRenderer2 === undefined || context._currentRenderer2 === null || context._currentRenderer2 === rendererSigil) ? warningWithoutStack$1(false, 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.') : void 0; 15898 context._currentRenderer2 = rendererSigil; 15899 } 15900 } 15901 } 15902 15903 function popProvider(providerFiber) { 15904 var currentValue = valueCursor.current; 15905 15906 pop(valueCursor, providerFiber); 15907 15908 var context = providerFiber.type._context; 15909 if (isPrimaryRenderer) { 15910 context._currentValue = currentValue; 15911 } else { 15912 context._currentValue2 = currentValue; 15913 } 15914 } 15915 15916 function calculateChangedBits(context, newValue, oldValue) { 15917 if (is(oldValue, newValue)) { 15918 // No change 15919 return 0; 15920 } else { 15921 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : maxSigned31BitInt; 15922 15923 { 15924 !((changedBits & maxSigned31BitInt) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0; 15925 } 15926 return changedBits | 0; 15927 } 15928 } 15929 15930 function scheduleWorkOnParentPath(parent, renderExpirationTime) { 15931 // Update the child expiration time of all the ancestors, including 15932 // the alternates. 15933 var node = parent; 15934 while (node !== null) { 15935 var alternate = node.alternate; 15936 if (node.childExpirationTime < renderExpirationTime) { 15937 node.childExpirationTime = renderExpirationTime; 15938 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) { 15939 alternate.childExpirationTime = renderExpirationTime; 15940 } 15941 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) { 15942 alternate.childExpirationTime = renderExpirationTime; 15943 } else { 15944 // Neither alternate was updated, which means the rest of the 15945 // ancestor path already has sufficient priority. 15946 break; 15947 } 15948 node = node.return; 15949 } 15950 } 15951 15952 function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) { 15953 var fiber = workInProgress.child; 15954 if (fiber !== null) { 15955 // Set the return pointer of the child to the work-in-progress fiber. 15956 fiber.return = workInProgress; 15957 } 15958 while (fiber !== null) { 15959 var nextFiber = void 0; 15960 15961 // Visit this fiber. 15962 var list = fiber.contextDependencies; 15963 if (list !== null) { 15964 nextFiber = fiber.child; 15965 15966 var dependency = list.first; 15967 while (dependency !== null) { 15968 // Check if the context matches. 15969 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) { 15970 // Match! Schedule an update on this fiber. 15971 15972 if (fiber.tag === ClassComponent) { 15973 // Schedule a force update on the work-in-progress. 15974 var update = createUpdate(renderExpirationTime); 15975 update.tag = ForceUpdate; 15976 // TODO: Because we don't have a work-in-progress, this will add the 15977 // update to the current fiber, too, which means it will persist even if 15978 // this render is thrown away. Since it's a race condition, not sure it's 15979 // worth fixing. 15980 enqueueUpdate(fiber, update); 15981 } 15982 15983 if (fiber.expirationTime < renderExpirationTime) { 15984 fiber.expirationTime = renderExpirationTime; 15985 } 15986 var alternate = fiber.alternate; 15987 if (alternate !== null && alternate.expirationTime < renderExpirationTime) { 15988 alternate.expirationTime = renderExpirationTime; 15989 } 15990 15991 scheduleWorkOnParentPath(fiber.return, renderExpirationTime); 15992 15993 // Mark the expiration time on the list, too. 15994 if (list.expirationTime < renderExpirationTime) { 15995 list.expirationTime = renderExpirationTime; 15996 } 15997 15998 // Since we already found a match, we can stop traversing the 15999 // dependency list. 16000 break; 16001 } 16002 dependency = dependency.next; 16003 } 16004 } else if (fiber.tag === ContextProvider) { 16005 // Don't scan deeper if this is a matching provider 16006 nextFiber = fiber.type === workInProgress.type ? null : fiber.child; 16007 } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedSuspenseComponent) { 16008 // If a dehydrated suspense component is in this subtree, we don't know 16009 // if it will have any context consumers in it. The best we can do is 16010 // mark it as having updates on its children. 16011 if (fiber.expirationTime < renderExpirationTime) { 16012 fiber.expirationTime = renderExpirationTime; 16013 } 16014 var _alternate = fiber.alternate; 16015 if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) { 16016 _alternate.expirationTime = renderExpirationTime; 16017 } 16018 // This is intentionally passing this fiber as the parent 16019 // because we want to schedule this fiber as having work 16020 // on its children. We'll use the childExpirationTime on 16021 // this fiber to indicate that a context has changed. 16022 scheduleWorkOnParentPath(fiber, renderExpirationTime); 16023 nextFiber = fiber.sibling; 16024 } else { 16025 // Traverse down. 16026 nextFiber = fiber.child; 16027 } 16028 16029 if (nextFiber !== null) { 16030 // Set the return pointer of the child to the work-in-progress fiber. 16031 nextFiber.return = fiber; 16032 } else { 16033 // No child. Traverse to next sibling. 16034 nextFiber = fiber; 16035 while (nextFiber !== null) { 16036 if (nextFiber === workInProgress) { 16037 // We're back to the root of this subtree. Exit. 16038 nextFiber = null; 16039 break; 16040 } 16041 var sibling = nextFiber.sibling; 16042 if (sibling !== null) { 16043 // Set the return pointer of the sibling to the work-in-progress fiber. 16044 sibling.return = nextFiber.return; 16045 nextFiber = sibling; 16046 break; 16047 } 16048 // No more siblings. Traverse up. 16049 nextFiber = nextFiber.return; 16050 } 16051 } 16052 fiber = nextFiber; 16053 } 16054 } 16055 16056 function prepareToReadContext(workInProgress, renderExpirationTime) { 16057 currentlyRenderingFiber = workInProgress; 16058 lastContextDependency = null; 16059 lastContextWithAllBitsObserved = null; 16060 16061 var currentDependencies = workInProgress.contextDependencies; 16062 if (currentDependencies !== null && currentDependencies.expirationTime >= renderExpirationTime) { 16063 // Context list has a pending update. Mark that this fiber performed work. 16064 markWorkInProgressReceivedUpdate(); 16065 } 16066 16067 // Reset the work-in-progress list 16068 workInProgress.contextDependencies = null; 16069 } 16070 16071 function readContext(context, observedBits) { 16072 { 16073 // This warning would fire if you read context inside a Hook like useMemo. 16074 // Unlike the class check below, it's not enforced in production for perf. 16075 !!isDisallowedContextReadInDEV ? warning$1(false, 'Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().') : void 0; 16076 } 16077 16078 if (lastContextWithAllBitsObserved === context) { 16079 // Nothing to do. We already observe everything in this context. 16080 } else if (observedBits === false || observedBits === 0) { 16081 // Do not observe any updates. 16082 } else { 16083 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types. 16084 if (typeof observedBits !== 'number' || observedBits === maxSigned31BitInt) { 16085 // Observe all updates. 16086 lastContextWithAllBitsObserved = context; 16087 resolvedObservedBits = maxSigned31BitInt; 16088 } else { 16089 resolvedObservedBits = observedBits; 16090 } 16091 16092 var contextItem = { 16093 context: context, 16094 observedBits: resolvedObservedBits, 16095 next: null 16096 }; 16097 16098 if (lastContextDependency === null) { 16099 !(currentlyRenderingFiber !== null) ? invariant(false, 'Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo().') : void 0; 16100 16101 // This is the first dependency for this component. Create a new list. 16102 lastContextDependency = contextItem; 16103 currentlyRenderingFiber.contextDependencies = { 16104 first: contextItem, 16105 expirationTime: NoWork 16106 }; 16107 } else { 16108 // Append a new context item. 16109 lastContextDependency = lastContextDependency.next = contextItem; 16110 } 16111 } 16112 return isPrimaryRenderer ? context._currentValue : context._currentValue2; 16113 } 16114 16115 // UpdateQueue is a linked list of prioritized updates. 16116 // 16117 // Like fibers, update queues come in pairs: a current queue, which represents 16118 // the visible state of the screen, and a work-in-progress queue, which can be 16119 // mutated and processed asynchronously before it is committed — a form of 16120 // double buffering. If a work-in-progress render is discarded before finishing, 16121 // we create a new work-in-progress by cloning the current queue. 16122 // 16123 // Both queues share a persistent, singly-linked list structure. To schedule an 16124 // update, we append it to the end of both queues. Each queue maintains a 16125 // pointer to first update in the persistent list that hasn't been processed. 16126 // The work-in-progress pointer always has a position equal to or greater than 16127 // the current queue, since we always work on that one. The current queue's 16128 // pointer is only updated during the commit phase, when we swap in the 16129 // work-in-progress. 16130 // 16131 // For example: 16132 // 16133 // Current pointer: A - B - C - D - E - F 16134 // Work-in-progress pointer: D - E - F 16135 // ^ 16136 // The work-in-progress queue has 16137 // processed more updates than current. 16138 // 16139 // The reason we append to both queues is because otherwise we might drop 16140 // updates without ever processing them. For example, if we only add updates to 16141 // the work-in-progress queue, some updates could be lost whenever a work-in 16142 // -progress render restarts by cloning from current. Similarly, if we only add 16143 // updates to the current queue, the updates will be lost whenever an already 16144 // in-progress queue commits and swaps with the current queue. However, by 16145 // adding to both queues, we guarantee that the update will be part of the next 16146 // work-in-progress. (And because the work-in-progress queue becomes the 16147 // current queue once it commits, there's no danger of applying the same 16148 // update twice.) 16149 // 16150 // Prioritization 16151 // -------------- 16152 // 16153 // Updates are not sorted by priority, but by insertion; new updates are always 16154 // appended to the end of the list. 16155 // 16156 // The priority is still important, though. When processing the update queue 16157 // during the render phase, only the updates with sufficient priority are 16158 // included in the result. If we skip an update because it has insufficient 16159 // priority, it remains in the queue to be processed later, during a lower 16160 // priority render. Crucially, all updates subsequent to a skipped update also 16161 // remain in the queue *regardless of their priority*. That means high priority 16162 // updates are sometimes processed twice, at two separate priorities. We also 16163 // keep track of a base state, that represents the state before the first 16164 // update in the queue is applied. 16165 // 16166 // For example: 16167 // 16168 // Given a base state of '', and the following queue of updates 16169 // 16170 // A1 - B2 - C1 - D2 16171 // 16172 // where the number indicates the priority, and the update is applied to the 16173 // previous state by appending a letter, React will process these updates as 16174 // two separate renders, one per distinct priority level: 16175 // 16176 // First render, at priority 1: 16177 // Base state: '' 16178 // Updates: [A1, C1] 16179 // Result state: 'AC' 16180 // 16181 // Second render, at priority 2: 16182 // Base state: 'A' <- The base state does not include C1, 16183 // because B2 was skipped. 16184 // Updates: [B2, C1, D2] <- C1 was rebased on top of B2 16185 // Result state: 'ABCD' 16186 // 16187 // Because we process updates in insertion order, and rebase high priority 16188 // updates when preceding updates are skipped, the final result is deterministic 16189 // regardless of priority. Intermediate state may vary according to system 16190 // resources, but the final state is always the same. 16191 16192 var UpdateState = 0; 16193 var ReplaceState = 1; 16194 var ForceUpdate = 2; 16195 var CaptureUpdate = 3; 16196 16197 // Global state that is reset at the beginning of calling `processUpdateQueue`. 16198 // It should only be read right after calling `processUpdateQueue`, via 16199 // `checkHasForceUpdateAfterProcessing`. 16200 var hasForceUpdate = false; 16201 16202 var didWarnUpdateInsideUpdate = void 0; 16203 var currentlyProcessingQueue = void 0; 16204 var resetCurrentlyProcessingQueue = void 0; 16205 { 16206 didWarnUpdateInsideUpdate = false; 16207 currentlyProcessingQueue = null; 16208 resetCurrentlyProcessingQueue = function () { 16209 currentlyProcessingQueue = null; 16210 }; 16211 } 16212 16213 function createUpdateQueue(baseState) { 16214 var queue = { 16215 baseState: baseState, 16216 firstUpdate: null, 16217 lastUpdate: null, 16218 firstCapturedUpdate: null, 16219 lastCapturedUpdate: null, 16220 firstEffect: null, 16221 lastEffect: null, 16222 firstCapturedEffect: null, 16223 lastCapturedEffect: null 16224 }; 16225 return queue; 16226 } 16227 16228 function cloneUpdateQueue(currentQueue) { 16229 var queue = { 16230 baseState: currentQueue.baseState, 16231 firstUpdate: currentQueue.firstUpdate, 16232 lastUpdate: currentQueue.lastUpdate, 16233 16234 // TODO: With resuming, if we bail out and resuse the child tree, we should 16235 // keep these effects. 16236 firstCapturedUpdate: null, 16237 lastCapturedUpdate: null, 16238 16239 firstEffect: null, 16240 lastEffect: null, 16241 16242 firstCapturedEffect: null, 16243 lastCapturedEffect: null 16244 }; 16245 return queue; 16246 } 16247 16248 function createUpdate(expirationTime) { 16249 return { 16250 expirationTime: expirationTime, 16251 16252 tag: UpdateState, 16253 payload: null, 16254 callback: null, 16255 16256 next: null, 16257 nextEffect: null 16258 }; 16259 } 16260 16261 function appendUpdateToQueue(queue, update) { 16262 // Append the update to the end of the list. 16263 if (queue.lastUpdate === null) { 16264 // Queue is empty 16265 queue.firstUpdate = queue.lastUpdate = update; 16266 } else { 16267 queue.lastUpdate.next = update; 16268 queue.lastUpdate = update; 16269 } 16270 } 16271 16272 function enqueueUpdate(fiber, update) { 16273 // Update queues are created lazily. 16274 var alternate = fiber.alternate; 16275 var queue1 = void 0; 16276 var queue2 = void 0; 16277 if (alternate === null) { 16278 // There's only one fiber. 16279 queue1 = fiber.updateQueue; 16280 queue2 = null; 16281 if (queue1 === null) { 16282 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); 16283 } 16284 } else { 16285 // There are two owners. 16286 queue1 = fiber.updateQueue; 16287 queue2 = alternate.updateQueue; 16288 if (queue1 === null) { 16289 if (queue2 === null) { 16290 // Neither fiber has an update queue. Create new ones. 16291 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); 16292 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState); 16293 } else { 16294 // Only one fiber has an update queue. Clone to create a new one. 16295 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2); 16296 } 16297 } else { 16298 if (queue2 === null) { 16299 // Only one fiber has an update queue. Clone to create a new one. 16300 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1); 16301 } else { 16302 // Both owners have an update queue. 16303 } 16304 } 16305 } 16306 if (queue2 === null || queue1 === queue2) { 16307 // There's only a single queue. 16308 appendUpdateToQueue(queue1, update); 16309 } else { 16310 // There are two queues. We need to append the update to both queues, 16311 // while accounting for the persistent structure of the list — we don't 16312 // want the same update to be added multiple times. 16313 if (queue1.lastUpdate === null || queue2.lastUpdate === null) { 16314 // One of the queues is not empty. We must add the update to both queues. 16315 appendUpdateToQueue(queue1, update); 16316 appendUpdateToQueue(queue2, update); 16317 } else { 16318 // Both queues are non-empty. The last update is the same in both lists, 16319 // because of structural sharing. So, only append to one of the lists. 16320 appendUpdateToQueue(queue1, update); 16321 // But we still need to update the `lastUpdate` pointer of queue2. 16322 queue2.lastUpdate = update; 16323 } 16324 } 16325 16326 { 16327 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) { 16328 warningWithoutStack$1(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.'); 16329 didWarnUpdateInsideUpdate = true; 16330 } 16331 } 16332 } 16333 16334 function enqueueCapturedUpdate(workInProgress, update) { 16335 // Captured updates go into a separate list, and only on the work-in- 16336 // progress queue. 16337 var workInProgressQueue = workInProgress.updateQueue; 16338 if (workInProgressQueue === null) { 16339 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState); 16340 } else { 16341 // TODO: I put this here rather than createWorkInProgress so that we don't 16342 // clone the queue unnecessarily. There's probably a better way to 16343 // structure this. 16344 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); 16345 } 16346 16347 // Append the update to the end of the list. 16348 if (workInProgressQueue.lastCapturedUpdate === null) { 16349 // This is the first render phase update 16350 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update; 16351 } else { 16352 workInProgressQueue.lastCapturedUpdate.next = update; 16353 workInProgressQueue.lastCapturedUpdate = update; 16354 } 16355 } 16356 16357 function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { 16358 var current = workInProgress.alternate; 16359 if (current !== null) { 16360 // If the work-in-progress queue is equal to the current queue, 16361 // we need to clone it first. 16362 if (queue === current.updateQueue) { 16363 queue = workInProgress.updateQueue = cloneUpdateQueue(queue); 16364 } 16365 } 16366 return queue; 16367 } 16368 16369 function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) { 16370 switch (update.tag) { 16371 case ReplaceState: 16372 { 16373 var _payload = update.payload; 16374 if (typeof _payload === 'function') { 16375 // Updater function 16376 { 16377 enterDisallowedContextReadInDEV(); 16378 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) { 16379 _payload.call(instance, prevState, nextProps); 16380 } 16381 } 16382 var nextState = _payload.call(instance, prevState, nextProps); 16383 { 16384 exitDisallowedContextReadInDEV(); 16385 } 16386 return nextState; 16387 } 16388 // State object 16389 return _payload; 16390 } 16391 case CaptureUpdate: 16392 { 16393 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture; 16394 } 16395 // Intentional fallthrough 16396 case UpdateState: 16397 { 16398 var _payload2 = update.payload; 16399 var partialState = void 0; 16400 if (typeof _payload2 === 'function') { 16401 // Updater function 16402 { 16403 enterDisallowedContextReadInDEV(); 16404 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) { 16405 _payload2.call(instance, prevState, nextProps); 16406 } 16407 } 16408 partialState = _payload2.call(instance, prevState, nextProps); 16409 { 16410 exitDisallowedContextReadInDEV(); 16411 } 16412 } else { 16413 // Partial state object 16414 partialState = _payload2; 16415 } 16416 if (partialState === null || partialState === undefined) { 16417 // Null and undefined are treated as no-ops. 16418 return prevState; 16419 } 16420 // Merge the partial state and the previous state. 16421 return _assign({}, prevState, partialState); 16422 } 16423 case ForceUpdate: 16424 { 16425 hasForceUpdate = true; 16426 return prevState; 16427 } 16428 } 16429 return prevState; 16430 } 16431 16432 function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) { 16433 hasForceUpdate = false; 16434 16435 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); 16436 16437 { 16438 currentlyProcessingQueue = queue; 16439 } 16440 16441 // These values may change as we process the queue. 16442 var newBaseState = queue.baseState; 16443 var newFirstUpdate = null; 16444 var newExpirationTime = NoWork; 16445 16446 // Iterate through the list of updates to compute the result. 16447 var update = queue.firstUpdate; 16448 var resultState = newBaseState; 16449 while (update !== null) { 16450 var updateExpirationTime = update.expirationTime; 16451 if (updateExpirationTime < renderExpirationTime) { 16452 // This update does not have sufficient priority. Skip it. 16453 if (newFirstUpdate === null) { 16454 // This is the first skipped update. It will be the first update in 16455 // the new list. 16456 newFirstUpdate = update; 16457 // Since this is the first update that was skipped, the current result 16458 // is the new base state. 16459 newBaseState = resultState; 16460 } 16461 // Since this update will remain in the list, update the remaining 16462 // expiration time. 16463 if (newExpirationTime < updateExpirationTime) { 16464 newExpirationTime = updateExpirationTime; 16465 } 16466 } else { 16467 // This update does have sufficient priority. Process it and compute 16468 // a new result. 16469 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance); 16470 var _callback = update.callback; 16471 if (_callback !== null) { 16472 workInProgress.effectTag |= Callback; 16473 // Set this to null, in case it was mutated during an aborted render. 16474 update.nextEffect = null; 16475 if (queue.lastEffect === null) { 16476 queue.firstEffect = queue.lastEffect = update; 16477 } else { 16478 queue.lastEffect.nextEffect = update; 16479 queue.lastEffect = update; 16480 } 16481 } 16482 } 16483 // Continue to the next update. 16484 update = update.next; 16485 } 16486 16487 // Separately, iterate though the list of captured updates. 16488 var newFirstCapturedUpdate = null; 16489 update = queue.firstCapturedUpdate; 16490 while (update !== null) { 16491 var _updateExpirationTime = update.expirationTime; 16492 if (_updateExpirationTime < renderExpirationTime) { 16493 // This update does not have sufficient priority. Skip it. 16494 if (newFirstCapturedUpdate === null) { 16495 // This is the first skipped captured update. It will be the first 16496 // update in the new list. 16497 newFirstCapturedUpdate = update; 16498 // If this is the first update that was skipped, the current result is 16499 // the new base state. 16500 if (newFirstUpdate === null) { 16501 newBaseState = resultState; 16502 } 16503 } 16504 // Since this update will remain in the list, update the remaining 16505 // expiration time. 16506 if (newExpirationTime < _updateExpirationTime) { 16507 newExpirationTime = _updateExpirationTime; 16508 } 16509 } else { 16510 // This update does have sufficient priority. Process it and compute 16511 // a new result. 16512 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance); 16513 var _callback2 = update.callback; 16514 if (_callback2 !== null) { 16515 workInProgress.effectTag |= Callback; 16516 // Set this to null, in case it was mutated during an aborted render. 16517 update.nextEffect = null; 16518 if (queue.lastCapturedEffect === null) { 16519 queue.firstCapturedEffect = queue.lastCapturedEffect = update; 16520 } else { 16521 queue.lastCapturedEffect.nextEffect = update; 16522 queue.lastCapturedEffect = update; 16523 } 16524 } 16525 } 16526 update = update.next; 16527 } 16528 16529 if (newFirstUpdate === null) { 16530 queue.lastUpdate = null; 16531 } 16532 if (newFirstCapturedUpdate === null) { 16533 queue.lastCapturedUpdate = null; 16534 } else { 16535 workInProgress.effectTag |= Callback; 16536 } 16537 if (newFirstUpdate === null && newFirstCapturedUpdate === null) { 16538 // We processed every update, without skipping. That means the new base 16539 // state is the same as the result state. 16540 newBaseState = resultState; 16541 } 16542 16543 queue.baseState = newBaseState; 16544 queue.firstUpdate = newFirstUpdate; 16545 queue.firstCapturedUpdate = newFirstCapturedUpdate; 16546 16547 // Set the remaining expiration time to be whatever is remaining in the queue. 16548 // This should be fine because the only two other things that contribute to 16549 // expiration time are props and context. We're already in the middle of the 16550 // begin phase by the time we start processing the queue, so we've already 16551 // dealt with the props. Context in components that specify 16552 // shouldComponentUpdate is tricky; but we'll have to account for 16553 // that regardless. 16554 workInProgress.expirationTime = newExpirationTime; 16555 workInProgress.memoizedState = resultState; 16556 16557 { 16558 currentlyProcessingQueue = null; 16559 } 16560 } 16561 16562 function callCallback(callback, context) { 16563 !(typeof callback === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', callback) : void 0; 16564 callback.call(context); 16565 } 16566 16567 function resetHasForceUpdateBeforeProcessing() { 16568 hasForceUpdate = false; 16569 } 16570 16571 function checkHasForceUpdateAfterProcessing() { 16572 return hasForceUpdate; 16573 } 16574 16575 function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) { 16576 // If the finished render included captured updates, and there are still 16577 // lower priority updates left over, we need to keep the captured updates 16578 // in the queue so that they are rebased and not dropped once we process the 16579 // queue again at the lower priority. 16580 if (finishedQueue.firstCapturedUpdate !== null) { 16581 // Join the captured update list to the end of the normal list. 16582 if (finishedQueue.lastUpdate !== null) { 16583 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate; 16584 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate; 16585 } 16586 // Clear the list of captured updates. 16587 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null; 16588 } 16589 16590 // Commit the effects 16591 commitUpdateEffects(finishedQueue.firstEffect, instance); 16592 finishedQueue.firstEffect = finishedQueue.lastEffect = null; 16593 16594 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); 16595 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; 16596 } 16597 16598 function commitUpdateEffects(effect, instance) { 16599 while (effect !== null) { 16600 var _callback3 = effect.callback; 16601 if (_callback3 !== null) { 16602 effect.callback = null; 16603 callCallback(_callback3, instance); 16604 } 16605 effect = effect.nextEffect; 16606 } 16607 } 16608 16609 function createCapturedValue(value, source) { 16610 // If the value is an error, call this function immediately after it is thrown 16611 // so the stack is accurate. 16612 return { 16613 value: value, 16614 source: source, 16615 stack: getStackByFiberInDevAndProd(source) 16616 }; 16617 } 16618 16619 function markUpdate(workInProgress) { 16620 // Tag the fiber with an update effect. This turns a Placement into 16621 // a PlacementAndUpdate. 16622 workInProgress.effectTag |= Update; 16623 } 16624 16625 function markRef$1(workInProgress) { 16626 workInProgress.effectTag |= Ref; 16627 } 16628 16629 var appendAllChildren = void 0; 16630 var updateHostContainer = void 0; 16631 var updateHostComponent$1 = void 0; 16632 var updateHostText$1 = void 0; 16633 if (supportsMutation) { 16634 // Mutation mode 16635 16636 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) { 16637 // We only have the top Fiber that was created but we need recurse down its 16638 // children to find all the terminal nodes. 16639 var node = workInProgress.child; 16640 while (node !== null) { 16641 if (node.tag === HostComponent || node.tag === HostText) { 16642 appendInitialChild(parent, node.stateNode); 16643 } else if (node.tag === HostPortal) { 16644 // If we have a portal child, then we don't want to traverse 16645 // down its children. Instead, we'll get insertions from each child in 16646 // the portal directly. 16647 } else if (node.child !== null) { 16648 node.child.return = node; 16649 node = node.child; 16650 continue; 16651 } 16652 if (node === workInProgress) { 16653 return; 16654 } 16655 while (node.sibling === null) { 16656 if (node.return === null || node.return === workInProgress) { 16657 return; 16658 } 16659 node = node.return; 16660 } 16661 node.sibling.return = node.return; 16662 node = node.sibling; 16663 } 16664 }; 16665 16666 updateHostContainer = function (workInProgress) { 16667 // Noop 16668 }; 16669 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) { 16670 // If we have an alternate, that means this is an update and we need to 16671 // schedule a side-effect to do the updates. 16672 var oldProps = current.memoizedProps; 16673 if (oldProps === newProps) { 16674 // In mutation mode, this is sufficient for a bailout because 16675 // we won't touch this node even if children changed. 16676 return; 16677 } 16678 16679 // If we get updated because one of our children updated, we don't 16680 // have newProps so we'll have to reuse them. 16681 // TODO: Split the update API as separate for the props vs. children. 16682 // Even better would be if children weren't special cased at all tho. 16683 var instance = workInProgress.stateNode; 16684 var currentHostContext = getHostContext(); 16685 // TODO: Experiencing an error where oldProps is null. Suggests a host 16686 // component is hitting the resume path. Figure out why. Possibly 16687 // related to `hidden`. 16688 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); 16689 // TODO: Type this specific to this type of component. 16690 workInProgress.updateQueue = updatePayload; 16691 // If the update payload indicates that there is a change or if there 16692 // is a new ref we mark this as an update. All the work is done in commitWork. 16693 if (updatePayload) { 16694 markUpdate(workInProgress); 16695 } 16696 }; 16697 updateHostText$1 = function (current, workInProgress, oldText, newText) { 16698 // If the text differs, mark it as an update. All the work in done in commitWork. 16699 if (oldText !== newText) { 16700 markUpdate(workInProgress); 16701 } 16702 }; 16703 } else if (supportsPersistence) { 16704 // Persistent host tree mode 16705 16706 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) { 16707 // We only have the top Fiber that was created but we need recurse down its 16708 // children to find all the terminal nodes. 16709 var node = workInProgress.child; 16710 while (node !== null) { 16711 // eslint-disable-next-line no-labels 16712 branches: if (node.tag === HostComponent) { 16713 var instance = node.stateNode; 16714 if (needsVisibilityToggle) { 16715 var props = node.memoizedProps; 16716 var type = node.type; 16717 if (isHidden) { 16718 // This child is inside a timed out tree. Hide it. 16719 instance = cloneHiddenInstance(instance, type, props, node); 16720 } else { 16721 // This child was previously inside a timed out tree. If it was not 16722 // updated during this render, it may need to be unhidden. Clone 16723 // again to be sure. 16724 instance = cloneUnhiddenInstance(instance, type, props, node); 16725 } 16726 node.stateNode = instance; 16727 } 16728 appendInitialChild(parent, instance); 16729 } else if (node.tag === HostText) { 16730 var _instance = node.stateNode; 16731 if (needsVisibilityToggle) { 16732 var text = node.memoizedProps; 16733 var rootContainerInstance = getRootHostContainer(); 16734 var currentHostContext = getHostContext(); 16735 if (isHidden) { 16736 _instance = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress); 16737 } else { 16738 _instance = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress); 16739 } 16740 node.stateNode = _instance; 16741 } 16742 appendInitialChild(parent, _instance); 16743 } else if (node.tag === HostPortal) { 16744 // If we have a portal child, then we don't want to traverse 16745 // down its children. Instead, we'll get insertions from each child in 16746 // the portal directly. 16747 } else if (node.tag === SuspenseComponent) { 16748 var current = node.alternate; 16749 if (current !== null) { 16750 var oldState = current.memoizedState; 16751 var newState = node.memoizedState; 16752 var oldIsHidden = oldState !== null; 16753 var newIsHidden = newState !== null; 16754 if (oldIsHidden !== newIsHidden) { 16755 // The placeholder either just timed out or switched back to the normal 16756 // children after having previously timed out. Toggle the visibility of 16757 // the direct host children. 16758 var primaryChildParent = newIsHidden ? node.child : node; 16759 if (primaryChildParent !== null) { 16760 appendAllChildren(parent, primaryChildParent, true, newIsHidden); 16761 } 16762 // eslint-disable-next-line no-labels 16763 break branches; 16764 } 16765 } 16766 if (node.child !== null) { 16767 // Continue traversing like normal 16768 node.child.return = node; 16769 node = node.child; 16770 continue; 16771 } 16772 } else if (node.child !== null) { 16773 node.child.return = node; 16774 node = node.child; 16775 continue; 16776 } 16777 // $FlowFixMe This is correct but Flow is confused by the labeled break. 16778 node = node; 16779 if (node === workInProgress) { 16780 return; 16781 } 16782 while (node.sibling === null) { 16783 if (node.return === null || node.return === workInProgress) { 16784 return; 16785 } 16786 node = node.return; 16787 } 16788 node.sibling.return = node.return; 16789 node = node.sibling; 16790 } 16791 }; 16792 16793 // An unfortunate fork of appendAllChildren because we have two different parent types. 16794 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) { 16795 // We only have the top Fiber that was created but we need recurse down its 16796 // children to find all the terminal nodes. 16797 var node = workInProgress.child; 16798 while (node !== null) { 16799 // eslint-disable-next-line no-labels 16800 branches: if (node.tag === HostComponent) { 16801 var instance = node.stateNode; 16802 if (needsVisibilityToggle) { 16803 var props = node.memoizedProps; 16804 var type = node.type; 16805 if (isHidden) { 16806 // This child is inside a timed out tree. Hide it. 16807 instance = cloneHiddenInstance(instance, type, props, node); 16808 } else { 16809 // This child was previously inside a timed out tree. If it was not 16810 // updated during this render, it may need to be unhidden. Clone 16811 // again to be sure. 16812 instance = cloneUnhiddenInstance(instance, type, props, node); 16813 } 16814 node.stateNode = instance; 16815 } 16816 appendChildToContainerChildSet(containerChildSet, instance); 16817 } else if (node.tag === HostText) { 16818 var _instance2 = node.stateNode; 16819 if (needsVisibilityToggle) { 16820 var text = node.memoizedProps; 16821 var rootContainerInstance = getRootHostContainer(); 16822 var currentHostContext = getHostContext(); 16823 if (isHidden) { 16824 _instance2 = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress); 16825 } else { 16826 _instance2 = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress); 16827 } 16828 node.stateNode = _instance2; 16829 } 16830 appendChildToContainerChildSet(containerChildSet, _instance2); 16831 } else if (node.tag === HostPortal) { 16832 // If we have a portal child, then we don't want to traverse 16833 // down its children. Instead, we'll get insertions from each child in 16834 // the portal directly. 16835 } else if (node.tag === SuspenseComponent) { 16836 var current = node.alternate; 16837 if (current !== null) { 16838 var oldState = current.memoizedState; 16839 var newState = node.memoizedState; 16840 var oldIsHidden = oldState !== null; 16841 var newIsHidden = newState !== null; 16842 if (oldIsHidden !== newIsHidden) { 16843 // The placeholder either just timed out or switched back to the normal 16844 // children after having previously timed out. Toggle the visibility of 16845 // the direct host children. 16846 var primaryChildParent = newIsHidden ? node.child : node; 16847 if (primaryChildParent !== null) { 16848 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden); 16849 } 16850 // eslint-disable-next-line no-labels 16851 break branches; 16852 } 16853 } 16854 if (node.child !== null) { 16855 // Continue traversing like normal 16856 node.child.return = node; 16857 node = node.child; 16858 continue; 16859 } 16860 } else if (node.child !== null) { 16861 node.child.return = node; 16862 node = node.child; 16863 continue; 16864 } 16865 // $FlowFixMe This is correct but Flow is confused by the labeled break. 16866 node = node; 16867 if (node === workInProgress) { 16868 return; 16869 } 16870 while (node.sibling === null) { 16871 if (node.return === null || node.return === workInProgress) { 16872 return; 16873 } 16874 node = node.return; 16875 } 16876 node.sibling.return = node.return; 16877 node = node.sibling; 16878 } 16879 }; 16880 updateHostContainer = function (workInProgress) { 16881 var portalOrRoot = workInProgress.stateNode; 16882 var childrenUnchanged = workInProgress.firstEffect === null; 16883 if (childrenUnchanged) { 16884 // No changes, just reuse the existing instance. 16885 } else { 16886 var container = portalOrRoot.containerInfo; 16887 var newChildSet = createContainerChildSet(container); 16888 // If children might have changed, we have to add them all to the set. 16889 appendAllChildrenToContainer(newChildSet, workInProgress, false, false); 16890 portalOrRoot.pendingChildren = newChildSet; 16891 // Schedule an update on the container to swap out the container. 16892 markUpdate(workInProgress); 16893 finalizeContainerChildren(container, newChildSet); 16894 } 16895 }; 16896 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) { 16897 var currentInstance = current.stateNode; 16898 var oldProps = current.memoizedProps; 16899 // If there are no effects associated with this node, then none of our children had any updates. 16900 // This guarantees that we can reuse all of them. 16901 var childrenUnchanged = workInProgress.firstEffect === null; 16902 if (childrenUnchanged && oldProps === newProps) { 16903 // No changes, just reuse the existing instance. 16904 // Note that this might release a previous clone. 16905 workInProgress.stateNode = currentInstance; 16906 return; 16907 } 16908 var recyclableInstance = workInProgress.stateNode; 16909 var currentHostContext = getHostContext(); 16910 var updatePayload = null; 16911 if (oldProps !== newProps) { 16912 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext); 16913 } 16914 if (childrenUnchanged && updatePayload === null) { 16915 // No changes, just reuse the existing instance. 16916 // Note that this might release a previous clone. 16917 workInProgress.stateNode = currentInstance; 16918 return; 16919 } 16920 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance); 16921 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) { 16922 markUpdate(workInProgress); 16923 } 16924 workInProgress.stateNode = newInstance; 16925 if (childrenUnchanged) { 16926 // If there are no other effects in this tree, we need to flag this node as having one. 16927 // Even though we're not going to use it for anything. 16928 // Otherwise parents won't know that there are new children to propagate upwards. 16929 markUpdate(workInProgress); 16930 } else { 16931 // If children might have changed, we have to add them all to the set. 16932 appendAllChildren(newInstance, workInProgress, false, false); 16933 } 16934 }; 16935 updateHostText$1 = function (current, workInProgress, oldText, newText) { 16936 if (oldText !== newText) { 16937 // If the text content differs, we'll create a new text instance for it. 16938 var rootContainerInstance = getRootHostContainer(); 16939 var currentHostContext = getHostContext(); 16940 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress); 16941 // We'll have to mark it as having an effect, even though we won't use the effect for anything. 16942 // This lets the parents know that at least one of their children has changed. 16943 markUpdate(workInProgress); 16944 } 16945 }; 16946 } else { 16947 // No host operations 16948 updateHostContainer = function (workInProgress) { 16949 // Noop 16950 }; 16951 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) { 16952 // Noop 16953 }; 16954 updateHostText$1 = function (current, workInProgress, oldText, newText) { 16955 // Noop 16956 }; 16957 } 16958 16959 function completeWork(current, workInProgress, renderExpirationTime) { 16960 var newProps = workInProgress.pendingProps; 16961 16962 switch (workInProgress.tag) { 16963 case IndeterminateComponent: 16964 break; 16965 case LazyComponent: 16966 break; 16967 case SimpleMemoComponent: 16968 case FunctionComponent: 16969 break; 16970 case ClassComponent: 16971 { 16972 var Component = workInProgress.type; 16973 if (isContextProvider(Component)) { 16974 popContext(workInProgress); 16975 } 16976 break; 16977 } 16978 case HostRoot: 16979 { 16980 popHostContainer(workInProgress); 16981 popTopLevelContextObject(workInProgress); 16982 var fiberRoot = workInProgress.stateNode; 16983 if (fiberRoot.pendingContext) { 16984 fiberRoot.context = fiberRoot.pendingContext; 16985 fiberRoot.pendingContext = null; 16986 } 16987 if (current === null || current.child === null) { 16988 // If we hydrated, pop so that we can delete any remaining children 16989 // that weren't hydrated. 16990 popHydrationState(workInProgress); 16991 // This resets the hacky state to fix isMounted before committing. 16992 // TODO: Delete this when we delete isMounted and findDOMNode. 16993 workInProgress.effectTag &= ~Placement; 16994 } 16995 updateHostContainer(workInProgress); 16996 break; 16997 } 16998 case HostComponent: 16999 { 17000 popHostContext(workInProgress); 17001 var rootContainerInstance = getRootHostContainer(); 17002 var type = workInProgress.type; 17003 if (current !== null && workInProgress.stateNode != null) { 17004 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance); 17005 17006 if (current.ref !== workInProgress.ref) { 17007 markRef$1(workInProgress); 17008 } 17009 } else { 17010 if (!newProps) { 17011 !(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; 17012 // This can happen when we abort work. 17013 break; 17014 } 17015 17016 var currentHostContext = getHostContext(); 17017 // TODO: Move createInstance to beginWork and keep it on a context 17018 // "stack" as the parent. Then append children as we go in beginWork 17019 // or completeWork depending on we want to add then top->down or 17020 // bottom->up. Top->down is faster in IE11. 17021 var wasHydrated = popHydrationState(workInProgress); 17022 if (wasHydrated) { 17023 // TODO: Move this and createInstance step into the beginPhase 17024 // to consolidate. 17025 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) { 17026 // If changes to the hydrated node needs to be applied at the 17027 // commit-phase we mark this as such. 17028 markUpdate(workInProgress); 17029 } 17030 } else { 17031 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress); 17032 17033 appendAllChildren(instance, workInProgress, false, false); 17034 17035 // Certain renderers require commit-time effects for initial mount. 17036 // (eg DOM renderer supports auto-focus for certain elements). 17037 // Make sure such renderers get scheduled for later work. 17038 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance, currentHostContext)) { 17039 markUpdate(workInProgress); 17040 } 17041 workInProgress.stateNode = instance; 17042 } 17043 17044 if (workInProgress.ref !== null) { 17045 // If there is a ref on a host node we need to schedule a callback 17046 markRef$1(workInProgress); 17047 } 17048 } 17049 break; 17050 } 17051 case HostText: 17052 { 17053 var newText = newProps; 17054 if (current && workInProgress.stateNode != null) { 17055 var oldText = current.memoizedProps; 17056 // If we have an alternate, that means this is an update and we need 17057 // to schedule a side-effect to do the updates. 17058 updateHostText$1(current, workInProgress, oldText, newText); 17059 } else { 17060 if (typeof newText !== 'string') { 17061 !(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; 17062 // This can happen when we abort work. 17063 } 17064 var _rootContainerInstance = getRootHostContainer(); 17065 var _currentHostContext = getHostContext(); 17066 var _wasHydrated = popHydrationState(workInProgress); 17067 if (_wasHydrated) { 17068 if (prepareToHydrateHostTextInstance(workInProgress)) { 17069 markUpdate(workInProgress); 17070 } 17071 } else { 17072 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress); 17073 } 17074 } 17075 break; 17076 } 17077 case ForwardRef: 17078 break; 17079 case SuspenseComponent: 17080 { 17081 var nextState = workInProgress.memoizedState; 17082 if ((workInProgress.effectTag & DidCapture) !== NoEffect) { 17083 // Something suspended. Re-render with the fallback children. 17084 workInProgress.expirationTime = renderExpirationTime; 17085 // Do not reset the effect list. 17086 return workInProgress; 17087 } 17088 17089 var nextDidTimeout = nextState !== null; 17090 var prevDidTimeout = current !== null && current.memoizedState !== null; 17091 17092 if (current !== null && !nextDidTimeout && prevDidTimeout) { 17093 // We just switched from the fallback to the normal children. Delete 17094 // the fallback. 17095 // TODO: Would it be better to store the fallback fragment on 17096 var currentFallbackChild = current.child.sibling; 17097 if (currentFallbackChild !== null) { 17098 // Deletions go at the beginning of the return fiber's effect list 17099 var first = workInProgress.firstEffect; 17100 if (first !== null) { 17101 workInProgress.firstEffect = currentFallbackChild; 17102 currentFallbackChild.nextEffect = first; 17103 } else { 17104 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild; 17105 currentFallbackChild.nextEffect = null; 17106 } 17107 currentFallbackChild.effectTag = Deletion; 17108 } 17109 } 17110 17111 if (nextDidTimeout || prevDidTimeout) { 17112 // If the children are hidden, or if they were previous hidden, schedule 17113 // an effect to toggle their visibility. This is also used to attach a 17114 // retry listener to the promise. 17115 workInProgress.effectTag |= Update; 17116 } 17117 break; 17118 } 17119 case Fragment: 17120 break; 17121 case Mode: 17122 break; 17123 case Profiler: 17124 break; 17125 case HostPortal: 17126 popHostContainer(workInProgress); 17127 updateHostContainer(workInProgress); 17128 break; 17129 case ContextProvider: 17130 // Pop provider fiber 17131 popProvider(workInProgress); 17132 break; 17133 case ContextConsumer: 17134 break; 17135 case MemoComponent: 17136 break; 17137 case IncompleteClassComponent: 17138 { 17139 // Same as class component case. I put it down here so that the tags are 17140 // sequential to ensure this switch is compiled to a jump table. 17141 var _Component = workInProgress.type; 17142 if (isContextProvider(_Component)) { 17143 popContext(workInProgress); 17144 } 17145 break; 17146 } 17147 case DehydratedSuspenseComponent: 17148 { 17149 if (enableSuspenseServerRenderer) { 17150 if (current === null) { 17151 var _wasHydrated2 = popHydrationState(workInProgress); 17152 !_wasHydrated2 ? invariant(false, 'A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.') : void 0; 17153 skipPastDehydratedSuspenseInstance(workInProgress); 17154 } else if ((workInProgress.effectTag & DidCapture) === NoEffect) { 17155 // This boundary did not suspend so it's now hydrated. 17156 // To handle any future suspense cases, we're going to now upgrade it 17157 // to a Suspense component. We detach it from the existing current fiber. 17158 current.alternate = null; 17159 workInProgress.alternate = null; 17160 workInProgress.tag = SuspenseComponent; 17161 workInProgress.memoizedState = null; 17162 workInProgress.stateNode = null; 17163 } 17164 } 17165 break; 17166 } 17167 default: 17168 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.'); 17169 } 17170 17171 return null; 17172 } 17173 17174 function shouldCaptureSuspense(workInProgress) { 17175 // In order to capture, the Suspense component must have a fallback prop. 17176 if (workInProgress.memoizedProps.fallback === undefined) { 17177 return false; 17178 } 17179 // If it was the primary children that just suspended, capture and render the 17180 // fallback. Otherwise, don't capture and bubble to the next boundary. 17181 var nextState = workInProgress.memoizedState; 17182 return nextState === null; 17183 } 17184 17185 // This module is forked in different environments. 17186 // By default, return `true` to log errors to the console. 17187 // Forks can return `false` if this isn't desirable. 17188 function showErrorDialog(capturedError) { 17189 return true; 17190 } 17191 17192 function logCapturedError(capturedError) { 17193 var logError = showErrorDialog(capturedError); 17194 17195 // Allow injected showErrorDialog() to prevent default console.error logging. 17196 // This enables renderers like ReactNative to better manage redbox behavior. 17197 if (logError === false) { 17198 return; 17199 } 17200 17201 var error = capturedError.error; 17202 { 17203 var componentName = capturedError.componentName, 17204 componentStack = capturedError.componentStack, 17205 errorBoundaryName = capturedError.errorBoundaryName, 17206 errorBoundaryFound = capturedError.errorBoundaryFound, 17207 willRetry = capturedError.willRetry; 17208 17209 // Browsers support silencing uncaught errors by calling 17210 // `preventDefault()` in window `error` handler. 17211 // We record this information as an expando on the error. 17212 17213 if (error != null && error._suppressLogging) { 17214 if (errorBoundaryFound && willRetry) { 17215 // The error is recoverable and was silenced. 17216 // Ignore it and don't print the stack addendum. 17217 // This is handy for testing error boundaries without noise. 17218 return; 17219 } 17220 // The error is fatal. Since the silencing might have 17221 // been accidental, we'll surface it anyway. 17222 // However, the browser would have silenced the original error 17223 // so we'll print it first, and then print the stack addendum. 17224 console.error(error); 17225 // For a more detailed description of this block, see: 17226 // https://github.com/facebook/react/pull/13384 17227 } 17228 17229 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:'; 17230 17231 var errorBoundaryMessage = void 0; 17232 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow. 17233 if (errorBoundaryFound && errorBoundaryName) { 17234 if (willRetry) { 17235 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.'); 17236 } else { 17237 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.'; 17238 } 17239 } else { 17240 errorBoundaryMessage = 'Consider adding an error boundary to your tree to customize error handling behavior.\n' + 'Visit https://fb.me/react-error-boundaries to learn more about error boundaries.'; 17241 } 17242 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage); 17243 17244 // In development, we provide our own message with just the component stack. 17245 // We don't include the original error message and JS stack because the browser 17246 // has already printed it. Even if the application swallows the error, it is still 17247 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. 17248 console.error(combinedMessage); 17249 } 17250 } 17251 17252 var didWarnAboutUndefinedSnapshotBeforeUpdate = null; 17253 { 17254 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); 17255 } 17256 17257 var PossiblyWeakSet$1 = typeof WeakSet === 'function' ? WeakSet : Set; 17258 17259 function logError(boundary, errorInfo) { 17260 var source = errorInfo.source; 17261 var stack = errorInfo.stack; 17262 if (stack === null && source !== null) { 17263 stack = getStackByFiberInDevAndProd(source); 17264 } 17265 17266 var capturedError = { 17267 componentName: source !== null ? getComponentName(source.type) : null, 17268 componentStack: stack !== null ? stack : '', 17269 error: errorInfo.value, 17270 errorBoundary: null, 17271 errorBoundaryName: null, 17272 errorBoundaryFound: false, 17273 willRetry: false 17274 }; 17275 17276 if (boundary !== null && boundary.tag === ClassComponent) { 17277 capturedError.errorBoundary = boundary.stateNode; 17278 capturedError.errorBoundaryName = getComponentName(boundary.type); 17279 capturedError.errorBoundaryFound = true; 17280 capturedError.willRetry = true; 17281 } 17282 17283 try { 17284 logCapturedError(capturedError); 17285 } catch (e) { 17286 // This method must not throw, or React internal state will get messed up. 17287 // If console.error is overridden, or logCapturedError() shows a dialog that throws, 17288 // we want to report this error outside of the normal stack as a last resort. 17289 // https://github.com/facebook/react/issues/13188 17290 setTimeout(function () { 17291 throw e; 17292 }); 17293 } 17294 } 17295 17296 var callComponentWillUnmountWithTimer = function (current$$1, instance) { 17297 startPhaseTimer(current$$1, 'componentWillUnmount'); 17298 instance.props = current$$1.memoizedProps; 17299 instance.state = current$$1.memoizedState; 17300 instance.componentWillUnmount(); 17301 stopPhaseTimer(); 17302 }; 17303 17304 // Capture errors so they don't interrupt unmounting. 17305 function safelyCallComponentWillUnmount(current$$1, instance) { 17306 { 17307 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current$$1, instance); 17308 if (hasCaughtError()) { 17309 var unmountError = clearCaughtError(); 17310 captureCommitPhaseError(current$$1, unmountError); 17311 } 17312 } 17313 } 17314 17315 function safelyDetachRef(current$$1) { 17316 var ref = current$$1.ref; 17317 if (ref !== null) { 17318 if (typeof ref === 'function') { 17319 { 17320 invokeGuardedCallback(null, ref, null, null); 17321 if (hasCaughtError()) { 17322 var refError = clearCaughtError(); 17323 captureCommitPhaseError(current$$1, refError); 17324 } 17325 } 17326 } else { 17327 ref.current = null; 17328 } 17329 } 17330 } 17331 17332 function safelyCallDestroy(current$$1, destroy) { 17333 { 17334 invokeGuardedCallback(null, destroy, null); 17335 if (hasCaughtError()) { 17336 var error = clearCaughtError(); 17337 captureCommitPhaseError(current$$1, error); 17338 } 17339 } 17340 } 17341 17342 function commitBeforeMutationLifeCycles(current$$1, finishedWork) { 17343 switch (finishedWork.tag) { 17344 case FunctionComponent: 17345 case ForwardRef: 17346 case SimpleMemoComponent: 17347 { 17348 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork); 17349 return; 17350 } 17351 case ClassComponent: 17352 { 17353 if (finishedWork.effectTag & Snapshot) { 17354 if (current$$1 !== null) { 17355 var prevProps = current$$1.memoizedProps; 17356 var prevState = current$$1.memoizedState; 17357 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate'); 17358 var instance = finishedWork.stateNode; 17359 // We could update instance props and state here, 17360 // but instead we rely on them being set during last render. 17361 // TODO: revisit this when we implement resuming. 17362 { 17363 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) { 17364 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0; 17365 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0; 17366 } 17367 } 17368 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState); 17369 { 17370 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; 17371 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { 17372 didWarnSet.add(finishedWork.type); 17373 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type)); 17374 } 17375 } 17376 instance.__reactInternalSnapshotBeforeUpdate = snapshot; 17377 stopPhaseTimer(); 17378 } 17379 } 17380 return; 17381 } 17382 case HostRoot: 17383 case HostComponent: 17384 case HostText: 17385 case HostPortal: 17386 case IncompleteClassComponent: 17387 // Nothing to do for these component types 17388 return; 17389 default: 17390 { 17391 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.'); 17392 } 17393 } 17394 } 17395 17396 function commitHookEffectList(unmountTag, mountTag, finishedWork) { 17397 var updateQueue = finishedWork.updateQueue; 17398 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; 17399 if (lastEffect !== null) { 17400 var firstEffect = lastEffect.next; 17401 var effect = firstEffect; 17402 do { 17403 if ((effect.tag & unmountTag) !== NoEffect$1) { 17404 // Unmount 17405 var destroy = effect.destroy; 17406 effect.destroy = undefined; 17407 if (destroy !== undefined) { 17408 destroy(); 17409 } 17410 } 17411 if ((effect.tag & mountTag) !== NoEffect$1) { 17412 // Mount 17413 var create = effect.create; 17414 effect.destroy = create(); 17415 17416 { 17417 var _destroy = effect.destroy; 17418 if (_destroy !== undefined && typeof _destroy !== 'function') { 17419 var addendum = void 0; 17420 if (_destroy === null) { 17421 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).'; 17422 } else if (typeof _destroy.then === 'function') { 17423 addendum = '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, write the async function inside your effect ' + 'and call it immediately:\n\n' + 'useEffect(() => {\n' + ' async function fetchData() {\n' + ' // You can await here\n' + ' const response = await MyAPI.getData(someId);\n' + ' // ...\n' + ' }\n' + ' fetchData();\n' + '}, [someId]); // Or [] if effect doesn\'t need props or state\n\n' + 'Learn more about data fetching with Hooks: https://fb.me/react-hooks-data-fetching'; 17424 } else { 17425 addendum = ' You returned: ' + _destroy; 17426 } 17427 warningWithoutStack$1(false, 'An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork)); 17428 } 17429 } 17430 } 17431 effect = effect.next; 17432 } while (effect !== firstEffect); 17433 } 17434 } 17435 17436 function commitPassiveHookEffects(finishedWork) { 17437 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); 17438 commitHookEffectList(NoEffect$1, MountPassive, finishedWork); 17439 } 17440 17441 function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpirationTime) { 17442 switch (finishedWork.tag) { 17443 case FunctionComponent: 17444 case ForwardRef: 17445 case SimpleMemoComponent: 17446 { 17447 commitHookEffectList(UnmountLayout, MountLayout, finishedWork); 17448 break; 17449 } 17450 case ClassComponent: 17451 { 17452 var instance = finishedWork.stateNode; 17453 if (finishedWork.effectTag & Update) { 17454 if (current$$1 === null) { 17455 startPhaseTimer(finishedWork, 'componentDidMount'); 17456 // We could update instance props and state here, 17457 // but instead we rely on them being set during last render. 17458 // TODO: revisit this when we implement resuming. 17459 { 17460 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) { 17461 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0; 17462 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0; 17463 } 17464 } 17465 instance.componentDidMount(); 17466 stopPhaseTimer(); 17467 } else { 17468 var prevProps = finishedWork.elementType === finishedWork.type ? current$$1.memoizedProps : resolveDefaultProps(finishedWork.type, current$$1.memoizedProps); 17469 var prevState = current$$1.memoizedState; 17470 startPhaseTimer(finishedWork, 'componentDidUpdate'); 17471 // We could update instance props and state here, 17472 // but instead we rely on them being set during last render. 17473 // TODO: revisit this when we implement resuming. 17474 { 17475 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) { 17476 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0; 17477 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0; 17478 } 17479 } 17480 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate); 17481 stopPhaseTimer(); 17482 } 17483 } 17484 var updateQueue = finishedWork.updateQueue; 17485 if (updateQueue !== null) { 17486 { 17487 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) { 17488 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0; 17489 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0; 17490 } 17491 } 17492 // We could update instance props and state here, 17493 // but instead we rely on them being set during last render. 17494 // TODO: revisit this when we implement resuming. 17495 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime); 17496 } 17497 return; 17498 } 17499 case HostRoot: 17500 { 17501 var _updateQueue = finishedWork.updateQueue; 17502 if (_updateQueue !== null) { 17503 var _instance = null; 17504 if (finishedWork.child !== null) { 17505 switch (finishedWork.child.tag) { 17506 case HostComponent: 17507 _instance = getPublicInstance(finishedWork.child.stateNode); 17508 break; 17509 case ClassComponent: 17510 _instance = finishedWork.child.stateNode; 17511 break; 17512 } 17513 } 17514 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime); 17515 } 17516 return; 17517 } 17518 case HostComponent: 17519 { 17520 var _instance2 = finishedWork.stateNode; 17521 17522 // Renderers may schedule work to be done after host components are mounted 17523 // (eg DOM renderer may schedule auto-focus for inputs and form controls). 17524 // These effects should only be committed when components are first mounted, 17525 // aka when there is no current/alternate. 17526 if (current$$1 === null && finishedWork.effectTag & Update) { 17527 var type = finishedWork.type; 17528 var props = finishedWork.memoizedProps; 17529 commitMount(_instance2, type, props, finishedWork); 17530 } 17531 17532 return; 17533 } 17534 case HostText: 17535 { 17536 // We have no life-cycles associated with text. 17537 return; 17538 } 17539 case HostPortal: 17540 { 17541 // We have no life-cycles associated with portals. 17542 return; 17543 } 17544 case Profiler: 17545 { 17546 if (enableProfilerTimer) { 17547 var onRender = finishedWork.memoizedProps.onRender; 17548 17549 if (enableSchedulerTracing) { 17550 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions); 17551 } else { 17552 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime()); 17553 } 17554 } 17555 return; 17556 } 17557 case SuspenseComponent: 17558 break; 17559 case IncompleteClassComponent: 17560 break; 17561 default: 17562 { 17563 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.'); 17564 } 17565 } 17566 } 17567 17568 function hideOrUnhideAllChildren(finishedWork, isHidden) { 17569 if (supportsMutation) { 17570 // We only have the top Fiber that was inserted but we need to recurse down its 17571 var node = finishedWork; 17572 while (true) { 17573 if (node.tag === HostComponent) { 17574 var instance = node.stateNode; 17575 if (isHidden) { 17576 hideInstance(instance); 17577 } else { 17578 unhideInstance(node.stateNode, node.memoizedProps); 17579 } 17580 } else if (node.tag === HostText) { 17581 var _instance3 = node.stateNode; 17582 if (isHidden) { 17583 hideTextInstance(_instance3); 17584 } else { 17585 unhideTextInstance(_instance3, node.memoizedProps); 17586 } 17587 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) { 17588 // Found a nested Suspense component that timed out. Skip over the 17589 var fallbackChildFragment = node.child.sibling; 17590 fallbackChildFragment.return = node; 17591 node = fallbackChildFragment; 17592 continue; 17593 } else if (node.child !== null) { 17594 node.child.return = node; 17595 node = node.child; 17596 continue; 17597 } 17598 if (node === finishedWork) { 17599 return; 17600 } 17601 while (node.sibling === null) { 17602 if (node.return === null || node.return === finishedWork) { 17603 return; 17604 } 17605 node = node.return; 17606 } 17607 node.sibling.return = node.return; 17608 node = node.sibling; 17609 } 17610 } 17611 } 17612 17613 function commitAttachRef(finishedWork) { 17614 var ref = finishedWork.ref; 17615 if (ref !== null) { 17616 var instance = finishedWork.stateNode; 17617 var instanceToUse = void 0; 17618 switch (finishedWork.tag) { 17619 case HostComponent: 17620 instanceToUse = getPublicInstance(instance); 17621 break; 17622 default: 17623 instanceToUse = instance; 17624 } 17625 if (typeof ref === 'function') { 17626 ref(instanceToUse); 17627 } else { 17628 { 17629 if (!ref.hasOwnProperty('current')) { 17630 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork)); 17631 } 17632 } 17633 17634 ref.current = instanceToUse; 17635 } 17636 } 17637 } 17638 17639 function commitDetachRef(current$$1) { 17640 var currentRef = current$$1.ref; 17641 if (currentRef !== null) { 17642 if (typeof currentRef === 'function') { 17643 currentRef(null); 17644 } else { 17645 currentRef.current = null; 17646 } 17647 } 17648 } 17649 17650 // User-originating errors (lifecycles and refs) should not interrupt 17651 // deletion, so don't let them throw. Host-originating errors should 17652 // interrupt deletion, so it's okay 17653 function commitUnmount(current$$1) { 17654 onCommitUnmount(current$$1); 17655 17656 switch (current$$1.tag) { 17657 case FunctionComponent: 17658 case ForwardRef: 17659 case MemoComponent: 17660 case SimpleMemoComponent: 17661 { 17662 var updateQueue = current$$1.updateQueue; 17663 if (updateQueue !== null) { 17664 var lastEffect = updateQueue.lastEffect; 17665 if (lastEffect !== null) { 17666 var firstEffect = lastEffect.next; 17667 var effect = firstEffect; 17668 do { 17669 var destroy = effect.destroy; 17670 if (destroy !== undefined) { 17671 safelyCallDestroy(current$$1, destroy); 17672 } 17673 effect = effect.next; 17674 } while (effect !== firstEffect); 17675 } 17676 } 17677 break; 17678 } 17679 case ClassComponent: 17680 { 17681 safelyDetachRef(current$$1); 17682 var instance = current$$1.stateNode; 17683 if (typeof instance.componentWillUnmount === 'function') { 17684 safelyCallComponentWillUnmount(current$$1, instance); 17685 } 17686 return; 17687 } 17688 case HostComponent: 17689 { 17690 safelyDetachRef(current$$1); 17691 return; 17692 } 17693 case HostPortal: 17694 { 17695 // TODO: this is recursive. 17696 // We are also not using this parent because 17697 // the portal will get pushed immediately. 17698 if (supportsMutation) { 17699 unmountHostComponents(current$$1); 17700 } else if (supportsPersistence) { 17701 emptyPortalContainer(current$$1); 17702 } 17703 return; 17704 } 17705 } 17706 } 17707 17708 function commitNestedUnmounts(root) { 17709 // While we're inside a removed host node we don't want to call 17710 // removeChild on the inner nodes because they're removed by the top 17711 // call anyway. We also want to call componentWillUnmount on all 17712 // composites before this host node is removed from the tree. Therefore 17713 var node = root; 17714 while (true) { 17715 commitUnmount(node); 17716 // Visit children because they may contain more composite or host nodes. 17717 // Skip portals because commitUnmount() currently visits them recursively. 17718 if (node.child !== null && ( 17719 // If we use mutation we drill down into portals using commitUnmount above. 17720 // If we don't use mutation we drill down into portals here instead. 17721 !supportsMutation || node.tag !== HostPortal)) { 17722 node.child.return = node; 17723 node = node.child; 17724 continue; 17725 } 17726 if (node === root) { 17727 return; 17728 } 17729 while (node.sibling === null) { 17730 if (node.return === null || node.return === root) { 17731 return; 17732 } 17733 node = node.return; 17734 } 17735 node.sibling.return = node.return; 17736 node = node.sibling; 17737 } 17738 } 17739 17740 function detachFiber(current$$1) { 17741 // Cut off the return pointers to disconnect it from the tree. Ideally, we 17742 // should clear the child pointer of the parent alternate to let this 17743 // get GC:ed but we don't know which for sure which parent is the current 17744 // one so we'll settle for GC:ing the subtree of this child. This child 17745 // itself will be GC:ed when the parent updates the next time. 17746 current$$1.return = null; 17747 current$$1.child = null; 17748 current$$1.memoizedState = null; 17749 current$$1.updateQueue = null; 17750 var alternate = current$$1.alternate; 17751 if (alternate !== null) { 17752 alternate.return = null; 17753 alternate.child = null; 17754 alternate.memoizedState = null; 17755 alternate.updateQueue = null; 17756 } 17757 } 17758 17759 function emptyPortalContainer(current$$1) { 17760 if (!supportsPersistence) { 17761 return; 17762 } 17763 17764 var portal = current$$1.stateNode; 17765 var containerInfo = portal.containerInfo; 17766 17767 var emptyChildSet = createContainerChildSet(containerInfo); 17768 replaceContainerChildren(containerInfo, emptyChildSet); 17769 } 17770 17771 function commitContainer(finishedWork) { 17772 if (!supportsPersistence) { 17773 return; 17774 } 17775 17776 switch (finishedWork.tag) { 17777 case ClassComponent: 17778 { 17779 return; 17780 } 17781 case HostComponent: 17782 { 17783 return; 17784 } 17785 case HostText: 17786 { 17787 return; 17788 } 17789 case HostRoot: 17790 case HostPortal: 17791 { 17792 var portalOrRoot = finishedWork.stateNode; 17793 var containerInfo = portalOrRoot.containerInfo, 17794 _pendingChildren = portalOrRoot.pendingChildren; 17795 17796 replaceContainerChildren(containerInfo, _pendingChildren); 17797 return; 17798 } 17799 default: 17800 { 17801 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.'); 17802 } 17803 } 17804 } 17805 17806 function getHostParentFiber(fiber) { 17807 var parent = fiber.return; 17808 while (parent !== null) { 17809 if (isHostParent(parent)) { 17810 return parent; 17811 } 17812 parent = parent.return; 17813 } 17814 invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.'); 17815 } 17816 17817 function isHostParent(fiber) { 17818 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal; 17819 } 17820 17821 function getHostSibling(fiber) { 17822 // We're going to search forward into the tree until we find a sibling host 17823 // node. Unfortunately, if multiple insertions are done in a row we have to 17824 // search past them. This leads to exponential search for the next sibling. 17825 var node = fiber; 17826 siblings: while (true) { 17827 // If we didn't find anything, let's try the next sibling. 17828 while (node.sibling === null) { 17829 if (node.return === null || isHostParent(node.return)) { 17830 // If we pop out of the root or hit the parent the fiber we are the 17831 // last sibling. 17832 return null; 17833 } 17834 node = node.return; 17835 } 17836 node.sibling.return = node.return; 17837 node = node.sibling; 17838 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedSuspenseComponent) { 17839 // If it is not host node and, we might have a host node inside it. 17840 // Try to search down until we find one. 17841 if (node.effectTag & Placement) { 17842 // If we don't have a child, try the siblings instead. 17843 continue siblings; 17844 } 17845 // If we don't have a child, try the siblings instead. 17846 // We also skip portals because they are not part of this host tree. 17847 if (node.child === null || node.tag === HostPortal) { 17848 continue siblings; 17849 } else { 17850 node.child.return = node; 17851 node = node.child; 17852 } 17853 } 17854 // Check if this host node is stable or about to be placed. 17855 if (!(node.effectTag & Placement)) { 17856 // Found it! 17857 return node.stateNode; 17858 } 17859 } 17860 } 17861 17862 function commitPlacement(finishedWork) { 17863 if (!supportsMutation) { 17864 return; 17865 } 17866 17867 // Recursively insert all host nodes into the parent. 17868 var parentFiber = getHostParentFiber(finishedWork); 17869 17870 // Note: these two variables *must* always be updated together. 17871 var parent = void 0; 17872 var isContainer = void 0; 17873 17874 switch (parentFiber.tag) { 17875 case HostComponent: 17876 parent = parentFiber.stateNode; 17877 isContainer = false; 17878 break; 17879 case HostRoot: 17880 parent = parentFiber.stateNode.containerInfo; 17881 isContainer = true; 17882 break; 17883 case HostPortal: 17884 parent = parentFiber.stateNode.containerInfo; 17885 isContainer = true; 17886 break; 17887 default: 17888 invariant(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.'); 17889 } 17890 if (parentFiber.effectTag & ContentReset) { 17891 // Reset the text content of the parent before doing any insertions 17892 resetTextContent(parent); 17893 // Clear ContentReset from the effect tag 17894 parentFiber.effectTag &= ~ContentReset; 17895 } 17896 17897 var before = getHostSibling(finishedWork); 17898 // We only have the top Fiber that was inserted but we need to recurse down its 17899 // children to find all the terminal nodes. 17900 var node = finishedWork; 17901 while (true) { 17902 if (node.tag === HostComponent || node.tag === HostText) { 17903 if (before) { 17904 if (isContainer) { 17905 insertInContainerBefore(parent, node.stateNode, before); 17906 } else { 17907 insertBefore(parent, node.stateNode, before); 17908 } 17909 } else { 17910 if (isContainer) { 17911 appendChildToContainer(parent, node.stateNode); 17912 } else { 17913 appendChild(parent, node.stateNode); 17914 } 17915 } 17916 } else if (node.tag === HostPortal) { 17917 // If the insertion itself is a portal, then we don't want to traverse 17918 // down its children. Instead, we'll get insertions from each child in 17919 // the portal directly. 17920 } else if (node.child !== null) { 17921 node.child.return = node; 17922 node = node.child; 17923 continue; 17924 } 17925 if (node === finishedWork) { 17926 return; 17927 } 17928 while (node.sibling === null) { 17929 if (node.return === null || node.return === finishedWork) { 17930 return; 17931 } 17932 node = node.return; 17933 } 17934 node.sibling.return = node.return; 17935 node = node.sibling; 17936 } 17937 } 17938 17939 function unmountHostComponents(current$$1) { 17940 // We only have the top Fiber that was deleted but we need to recurse down its 17941 var node = current$$1; 17942 17943 // Each iteration, currentParent is populated with node's host parent if not 17944 // currentParentIsValid. 17945 var currentParentIsValid = false; 17946 17947 // Note: these two variables *must* always be updated together. 17948 var currentParent = void 0; 17949 var currentParentIsContainer = void 0; 17950 17951 while (true) { 17952 if (!currentParentIsValid) { 17953 var parent = node.return; 17954 findParent: while (true) { 17955 !(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; 17956 switch (parent.tag) { 17957 case HostComponent: 17958 currentParent = parent.stateNode; 17959 currentParentIsContainer = false; 17960 break findParent; 17961 case HostRoot: 17962 currentParent = parent.stateNode.containerInfo; 17963 currentParentIsContainer = true; 17964 break findParent; 17965 case HostPortal: 17966 currentParent = parent.stateNode.containerInfo; 17967 currentParentIsContainer = true; 17968 break findParent; 17969 } 17970 parent = parent.return; 17971 } 17972 currentParentIsValid = true; 17973 } 17974 17975 if (node.tag === HostComponent || node.tag === HostText) { 17976 commitNestedUnmounts(node); 17977 // After all the children have unmounted, it is now safe to remove the 17978 // node from the tree. 17979 if (currentParentIsContainer) { 17980 removeChildFromContainer(currentParent, node.stateNode); 17981 } else { 17982 removeChild(currentParent, node.stateNode); 17983 } 17984 // Don't visit children because we already visited them. 17985 } else if (enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent) { 17986 // Delete the dehydrated suspense boundary and all of its content. 17987 if (currentParentIsContainer) { 17988 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode); 17989 } else { 17990 clearSuspenseBoundary(currentParent, node.stateNode); 17991 } 17992 } else if (node.tag === HostPortal) { 17993 if (node.child !== null) { 17994 // When we go into a portal, it becomes the parent to remove from. 17995 // We will reassign it back when we pop the portal on the way up. 17996 currentParent = node.stateNode.containerInfo; 17997 currentParentIsContainer = true; 17998 // Visit children because portals might contain host components. 17999 node.child.return = node; 18000 node = node.child; 18001 continue; 18002 } 18003 } else { 18004 commitUnmount(node); 18005 // Visit children because we may find more host components below. 18006 if (node.child !== null) { 18007 node.child.return = node; 18008 node = node.child; 18009 continue; 18010 } 18011 } 18012 if (node === current$$1) { 18013 return; 18014 } 18015 while (node.sibling === null) { 18016 if (node.return === null || node.return === current$$1) { 18017 return; 18018 } 18019 node = node.return; 18020 if (node.tag === HostPortal) { 18021 // When we go out of the portal, we need to restore the parent. 18022 // Since we don't keep a stack of them, we will search for it. 18023 currentParentIsValid = false; 18024 } 18025 } 18026 node.sibling.return = node.return; 18027 node = node.sibling; 18028 } 18029 } 18030 18031 function commitDeletion(current$$1) { 18032 if (supportsMutation) { 18033 // Recursively delete all host nodes from the parent. 18034 // Detach refs and call componentWillUnmount() on the whole subtree. 18035 unmountHostComponents(current$$1); 18036 } else { 18037 // Detach refs and call componentWillUnmount() on the whole subtree. 18038 commitNestedUnmounts(current$$1); 18039 } 18040 detachFiber(current$$1); 18041 } 18042 18043 function commitWork(current$$1, finishedWork) { 18044 if (!supportsMutation) { 18045 switch (finishedWork.tag) { 18046 case FunctionComponent: 18047 case ForwardRef: 18048 case MemoComponent: 18049 case SimpleMemoComponent: 18050 { 18051 // Note: We currently never use MountMutation, but useLayout uses 18052 // UnmountMutation. 18053 commitHookEffectList(UnmountMutation, MountMutation, finishedWork); 18054 return; 18055 } 18056 } 18057 18058 commitContainer(finishedWork); 18059 return; 18060 } 18061 18062 switch (finishedWork.tag) { 18063 case FunctionComponent: 18064 case ForwardRef: 18065 case MemoComponent: 18066 case SimpleMemoComponent: 18067 { 18068 // Note: We currently never use MountMutation, but useLayout uses 18069 // UnmountMutation. 18070 commitHookEffectList(UnmountMutation, MountMutation, finishedWork); 18071 return; 18072 } 18073 case ClassComponent: 18074 { 18075 return; 18076 } 18077 case HostComponent: 18078 { 18079 var instance = finishedWork.stateNode; 18080 if (instance != null) { 18081 // Commit the work prepared earlier. 18082 var newProps = finishedWork.memoizedProps; 18083 // For hydration we reuse the update path but we treat the oldProps 18084 // as the newProps. The updatePayload will contain the real change in 18085 // this case. 18086 var oldProps = current$$1 !== null ? current$$1.memoizedProps : newProps; 18087 var type = finishedWork.type; 18088 // TODO: Type the updateQueue to be specific to host components. 18089 var updatePayload = finishedWork.updateQueue; 18090 finishedWork.updateQueue = null; 18091 if (updatePayload !== null) { 18092 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork); 18093 } 18094 } 18095 return; 18096 } 18097 case HostText: 18098 { 18099 !(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; 18100 var textInstance = finishedWork.stateNode; 18101 var newText = finishedWork.memoizedProps; 18102 // For hydration we reuse the update path but we treat the oldProps 18103 // as the newProps. The updatePayload will contain the real change in 18104 // this case. 18105 var oldText = current$$1 !== null ? current$$1.memoizedProps : newText; 18106 commitTextUpdate(textInstance, oldText, newText); 18107 return; 18108 } 18109 case HostRoot: 18110 { 18111 return; 18112 } 18113 case Profiler: 18114 { 18115 return; 18116 } 18117 case SuspenseComponent: 18118 { 18119 var newState = finishedWork.memoizedState; 18120 18121 var newDidTimeout = void 0; 18122 var primaryChildParent = finishedWork; 18123 if (newState === null) { 18124 newDidTimeout = false; 18125 } else { 18126 newDidTimeout = true; 18127 primaryChildParent = finishedWork.child; 18128 if (newState.timedOutAt === NoWork) { 18129 // If the children had not already timed out, record the time. 18130 // This is used to compute the elapsed time during subsequent 18131 // attempts to render the children. 18132 newState.timedOutAt = requestCurrentTime(); 18133 } 18134 } 18135 18136 if (primaryChildParent !== null) { 18137 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout); 18138 } 18139 18140 // If this boundary just timed out, then it will have a set of thenables. 18141 // For each thenable, attach a listener so that when it resolves, React 18142 // attempts to re-render the boundary in the primary (pre-timeout) state. 18143 var thenables = finishedWork.updateQueue; 18144 if (thenables !== null) { 18145 finishedWork.updateQueue = null; 18146 var retryCache = finishedWork.stateNode; 18147 if (retryCache === null) { 18148 retryCache = finishedWork.stateNode = new PossiblyWeakSet$1(); 18149 } 18150 thenables.forEach(function (thenable) { 18151 // Memoize using the boundary fiber to prevent redundant listeners. 18152 var retry = retryTimedOutBoundary.bind(null, finishedWork, thenable); 18153 if (enableSchedulerTracing) { 18154 retry = unstable_wrap(retry); 18155 } 18156 if (!retryCache.has(thenable)) { 18157 retryCache.add(thenable); 18158 thenable.then(retry, retry); 18159 } 18160 }); 18161 } 18162 18163 return; 18164 } 18165 case IncompleteClassComponent: 18166 { 18167 return; 18168 } 18169 default: 18170 { 18171 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.'); 18172 } 18173 } 18174 } 18175 18176 function commitResetTextContent(current$$1) { 18177 if (!supportsMutation) { 18178 return; 18179 } 18180 resetTextContent(current$$1.stateNode); 18181 } 18182 18183 var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set; 18184 var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map; 18185 18186 function createRootErrorUpdate(fiber, errorInfo, expirationTime) { 18187 var update = createUpdate(expirationTime); 18188 // Unmount the root by rendering null. 18189 update.tag = CaptureUpdate; 18190 // Caution: React DevTools currently depends on this property 18191 // being called "element". 18192 update.payload = { element: null }; 18193 var error = errorInfo.value; 18194 update.callback = function () { 18195 onUncaughtError(error); 18196 logError(fiber, errorInfo); 18197 }; 18198 return update; 18199 } 18200 18201 function createClassErrorUpdate(fiber, errorInfo, expirationTime) { 18202 var update = createUpdate(expirationTime); 18203 update.tag = CaptureUpdate; 18204 var getDerivedStateFromError = fiber.type.getDerivedStateFromError; 18205 if (typeof getDerivedStateFromError === 'function') { 18206 var error = errorInfo.value; 18207 update.payload = function () { 18208 return getDerivedStateFromError(error); 18209 }; 18210 } 18211 18212 var inst = fiber.stateNode; 18213 if (inst !== null && typeof inst.componentDidCatch === 'function') { 18214 update.callback = function callback() { 18215 if (typeof getDerivedStateFromError !== 'function') { 18216 // To preserve the preexisting retry behavior of error boundaries, 18217 // we keep track of which ones already failed during this batch. 18218 // This gets reset before we yield back to the browser. 18219 // TODO: Warn in strict mode if getDerivedStateFromError is 18220 // not defined. 18221 markLegacyErrorBoundaryAsFailed(this); 18222 } 18223 var error = errorInfo.value; 18224 var stack = errorInfo.stack; 18225 logError(fiber, errorInfo); 18226 this.componentDidCatch(error, { 18227 componentStack: stack !== null ? stack : '' 18228 }); 18229 { 18230 if (typeof getDerivedStateFromError !== 'function') { 18231 // If componentDidCatch is the only error boundary method defined, 18232 // then it needs to call setState to recover from errors. 18233 // If no state update is scheduled then the boundary will swallow the error. 18234 !(fiber.expirationTime === Sync) ? warningWithoutStack$1(false, '%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentName(fiber.type) || 'Unknown') : void 0; 18235 } 18236 } 18237 }; 18238 } 18239 return update; 18240 } 18241 18242 function attachPingListener(root, renderExpirationTime, thenable) { 18243 // Attach a listener to the promise to "ping" the root and retry. But 18244 // only if one does not already exist for the current render expiration 18245 // time (which acts like a "thread ID" here). 18246 var pingCache = root.pingCache; 18247 var threadIDs = void 0; 18248 if (pingCache === null) { 18249 pingCache = root.pingCache = new PossiblyWeakMap(); 18250 threadIDs = new Set(); 18251 pingCache.set(thenable, threadIDs); 18252 } else { 18253 threadIDs = pingCache.get(thenable); 18254 if (threadIDs === undefined) { 18255 threadIDs = new Set(); 18256 pingCache.set(thenable, threadIDs); 18257 } 18258 } 18259 if (!threadIDs.has(renderExpirationTime)) { 18260 // Memoize using the thread ID to prevent redundant listeners. 18261 threadIDs.add(renderExpirationTime); 18262 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime); 18263 if (enableSchedulerTracing) { 18264 ping = unstable_wrap(ping); 18265 } 18266 thenable.then(ping, ping); 18267 } 18268 } 18269 18270 function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) { 18271 // The source fiber did not complete. 18272 sourceFiber.effectTag |= Incomplete; 18273 // Its effect list is no longer valid. 18274 sourceFiber.firstEffect = sourceFiber.lastEffect = null; 18275 18276 if (value !== null && typeof value === 'object' && typeof value.then === 'function') { 18277 // This is a thenable. 18278 var thenable = value; 18279 18280 // Find the earliest timeout threshold of all the placeholders in the 18281 // ancestor path. We could avoid this traversal by storing the thresholds on 18282 // the stack, but we choose not to because we only hit this path if we're 18283 // IO-bound (i.e. if something suspends). Whereas the stack is used even in 18284 // the non-IO- bound case. 18285 var _workInProgress = returnFiber; 18286 var earliestTimeoutMs = -1; 18287 var startTimeMs = -1; 18288 do { 18289 if (_workInProgress.tag === SuspenseComponent) { 18290 var current$$1 = _workInProgress.alternate; 18291 if (current$$1 !== null) { 18292 var currentState = current$$1.memoizedState; 18293 if (currentState !== null) { 18294 // Reached a boundary that already timed out. Do not search 18295 // any further. 18296 var timedOutAt = currentState.timedOutAt; 18297 startTimeMs = expirationTimeToMs(timedOutAt); 18298 // Do not search any further. 18299 break; 18300 } 18301 } 18302 var timeoutPropMs = _workInProgress.pendingProps.maxDuration; 18303 if (typeof timeoutPropMs === 'number') { 18304 if (timeoutPropMs <= 0) { 18305 earliestTimeoutMs = 0; 18306 } else if (earliestTimeoutMs === -1 || timeoutPropMs < earliestTimeoutMs) { 18307 earliestTimeoutMs = timeoutPropMs; 18308 } 18309 } 18310 } 18311 // If there is a DehydratedSuspenseComponent we don't have to do anything because 18312 // if something suspends inside it, we will simply leave that as dehydrated. It 18313 // will never timeout. 18314 _workInProgress = _workInProgress.return; 18315 } while (_workInProgress !== null); 18316 18317 // Schedule the nearest Suspense to re-render the timed out view. 18318 _workInProgress = returnFiber; 18319 do { 18320 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress)) { 18321 // Found the nearest boundary. 18322 18323 // Stash the promise on the boundary fiber. If the boundary times out, we'll 18324 var thenables = _workInProgress.updateQueue; 18325 if (thenables === null) { 18326 var updateQueue = new Set(); 18327 updateQueue.add(thenable); 18328 _workInProgress.updateQueue = updateQueue; 18329 } else { 18330 thenables.add(thenable); 18331 } 18332 18333 // If the boundary is outside of concurrent mode, we should *not* 18334 // suspend the commit. Pretend as if the suspended component rendered 18335 // null and keep rendering. In the commit phase, we'll schedule a 18336 // subsequent synchronous update to re-render the Suspense. 18337 // 18338 // Note: It doesn't matter whether the component that suspended was 18339 // inside a concurrent mode tree. If the Suspense is outside of it, we 18340 // should *not* suspend the commit. 18341 if ((_workInProgress.mode & ConcurrentMode) === NoEffect) { 18342 _workInProgress.effectTag |= DidCapture; 18343 18344 // We're going to commit this fiber even though it didn't complete. 18345 // But we shouldn't call any lifecycle methods or callbacks. Remove 18346 // all lifecycle effect tags. 18347 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete); 18348 18349 if (sourceFiber.tag === ClassComponent) { 18350 var currentSourceFiber = sourceFiber.alternate; 18351 if (currentSourceFiber === null) { 18352 // This is a new mount. Change the tag so it's not mistaken for a 18353 // completed class component. For example, we should not call 18354 // componentWillUnmount if it is deleted. 18355 sourceFiber.tag = IncompleteClassComponent; 18356 } else { 18357 // When we try rendering again, we should not reuse the current fiber, 18358 // since it's known to be in an inconsistent state. Use a force updte to 18359 // prevent a bail out. 18360 var update = createUpdate(Sync); 18361 update.tag = ForceUpdate; 18362 enqueueUpdate(sourceFiber, update); 18363 } 18364 } 18365 18366 // The source fiber did not complete. Mark it with Sync priority to 18367 // indicate that it still has pending work. 18368 sourceFiber.expirationTime = Sync; 18369 18370 // Exit without suspending. 18371 return; 18372 } 18373 18374 // Confirmed that the boundary is in a concurrent mode tree. Continue 18375 // with the normal suspend path. 18376 18377 attachPingListener(root, renderExpirationTime, thenable); 18378 18379 var absoluteTimeoutMs = void 0; 18380 if (earliestTimeoutMs === -1) { 18381 // If no explicit threshold is given, default to an arbitrarily large 18382 // value. The actual size doesn't matter because the threshold for the 18383 // whole tree will be clamped to the expiration time. 18384 absoluteTimeoutMs = maxSigned31BitInt; 18385 } else { 18386 if (startTimeMs === -1) { 18387 // This suspend happened outside of any already timed-out 18388 // placeholders. We don't know exactly when the update was 18389 // scheduled, but we can infer an approximate start time from the 18390 // expiration time. First, find the earliest uncommitted expiration 18391 // time in the tree, including work that is suspended. Then subtract 18392 // the offset used to compute an async update's expiration time. 18393 // This will cause high priority (interactive) work to expire 18394 // earlier than necessary, but we can account for this by adjusting 18395 // for the Just Noticeable Difference. 18396 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, renderExpirationTime); 18397 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime); 18398 startTimeMs = earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION; 18399 } 18400 absoluteTimeoutMs = startTimeMs + earliestTimeoutMs; 18401 } 18402 18403 // Mark the earliest timeout in the suspended fiber's ancestor path. 18404 // After completing the root, we'll take the largest of all the 18405 // suspended fiber's timeouts and use it to compute a timeout for the 18406 // whole tree. 18407 renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime); 18408 18409 _workInProgress.effectTag |= ShouldCapture; 18410 _workInProgress.expirationTime = renderExpirationTime; 18411 return; 18412 } else if (enableSuspenseServerRenderer && _workInProgress.tag === DehydratedSuspenseComponent) { 18413 attachPingListener(root, renderExpirationTime, thenable); 18414 18415 // Since we already have a current fiber, we can eagerly add a retry listener. 18416 var retryCache = _workInProgress.memoizedState; 18417 if (retryCache === null) { 18418 retryCache = _workInProgress.memoizedState = new PossiblyWeakSet(); 18419 var _current = _workInProgress.alternate; 18420 !_current ? invariant(false, 'A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React.') : void 0; 18421 _current.memoizedState = retryCache; 18422 } 18423 // Memoize using the boundary fiber to prevent redundant listeners. 18424 if (!retryCache.has(thenable)) { 18425 retryCache.add(thenable); 18426 var retry = retryTimedOutBoundary.bind(null, _workInProgress, thenable); 18427 if (enableSchedulerTracing) { 18428 retry = unstable_wrap(retry); 18429 } 18430 thenable.then(retry, retry); 18431 } 18432 _workInProgress.effectTag |= ShouldCapture; 18433 _workInProgress.expirationTime = renderExpirationTime; 18434 return; 18435 } 18436 // This boundary already captured during this render. Continue to the next 18437 // boundary. 18438 _workInProgress = _workInProgress.return; 18439 } while (_workInProgress !== null); 18440 // No boundary was found. Fallthrough to error mode. 18441 // TODO: Use invariant so the message is stripped in prod? 18442 value = new Error((getComponentName(sourceFiber.type) || 'A React component') + ' suspended while rendering, but no fallback UI was specified.\n' + '\n' + 'Add a <Suspense fallback=...> component higher in the tree to ' + 'provide a loading indicator or placeholder to display.' + getStackByFiberInDevAndProd(sourceFiber)); 18443 } 18444 18445 // We didn't find a boundary that could handle this type of exception. Start 18446 // over and traverse parent path again, this time treating the exception 18447 // as an error. 18448 renderDidError(); 18449 value = createCapturedValue(value, sourceFiber); 18450 var workInProgress = returnFiber; 18451 do { 18452 switch (workInProgress.tag) { 18453 case HostRoot: 18454 { 18455 var _errorInfo = value; 18456 workInProgress.effectTag |= ShouldCapture; 18457 workInProgress.expirationTime = renderExpirationTime; 18458 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime); 18459 enqueueCapturedUpdate(workInProgress, _update); 18460 return; 18461 } 18462 case ClassComponent: 18463 // Capture and retry 18464 var errorInfo = value; 18465 var ctor = workInProgress.type; 18466 var instance = workInProgress.stateNode; 18467 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) { 18468 workInProgress.effectTag |= ShouldCapture; 18469 workInProgress.expirationTime = renderExpirationTime; 18470 // Schedule the error boundary to re-render using updated state 18471 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime); 18472 enqueueCapturedUpdate(workInProgress, _update2); 18473 return; 18474 } 18475 break; 18476 default: 18477 break; 18478 } 18479 workInProgress = workInProgress.return; 18480 } while (workInProgress !== null); 18481 } 18482 18483 function unwindWork(workInProgress, renderExpirationTime) { 18484 switch (workInProgress.tag) { 18485 case ClassComponent: 18486 { 18487 var Component = workInProgress.type; 18488 if (isContextProvider(Component)) { 18489 popContext(workInProgress); 18490 } 18491 var effectTag = workInProgress.effectTag; 18492 if (effectTag & ShouldCapture) { 18493 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture; 18494 return workInProgress; 18495 } 18496 return null; 18497 } 18498 case HostRoot: 18499 { 18500 popHostContainer(workInProgress); 18501 popTopLevelContextObject(workInProgress); 18502 var _effectTag = workInProgress.effectTag; 18503 !((_effectTag & DidCapture) === NoEffect) ? invariant(false, 'The root failed to unmount after an error. This is likely a bug in React. Please file an issue.') : void 0; 18504 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture; 18505 return workInProgress; 18506 } 18507 case HostComponent: 18508 { 18509 // TODO: popHydrationState 18510 popHostContext(workInProgress); 18511 return null; 18512 } 18513 case SuspenseComponent: 18514 { 18515 var _effectTag2 = workInProgress.effectTag; 18516 if (_effectTag2 & ShouldCapture) { 18517 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture; 18518 // Captured a suspense effect. Re-render the boundary. 18519 return workInProgress; 18520 } 18521 return null; 18522 } 18523 case DehydratedSuspenseComponent: 18524 { 18525 if (enableSuspenseServerRenderer) { 18526 // TODO: popHydrationState 18527 var _effectTag3 = workInProgress.effectTag; 18528 if (_effectTag3 & ShouldCapture) { 18529 workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture; 18530 // Captured a suspense effect. Re-render the boundary. 18531 return workInProgress; 18532 } 18533 } 18534 return null; 18535 } 18536 case HostPortal: 18537 popHostContainer(workInProgress); 18538 return null; 18539 case ContextProvider: 18540 popProvider(workInProgress); 18541 return null; 18542 default: 18543 return null; 18544 } 18545 } 18546 18547 function unwindInterruptedWork(interruptedWork) { 18548 switch (interruptedWork.tag) { 18549 case ClassComponent: 18550 { 18551 var childContextTypes = interruptedWork.type.childContextTypes; 18552 if (childContextTypes !== null && childContextTypes !== undefined) { 18553 popContext(interruptedWork); 18554 } 18555 break; 18556 } 18557 case HostRoot: 18558 { 18559 popHostContainer(interruptedWork); 18560 popTopLevelContextObject(interruptedWork); 18561 break; 18562 } 18563 case HostComponent: 18564 { 18565 popHostContext(interruptedWork); 18566 break; 18567 } 18568 case HostPortal: 18569 popHostContainer(interruptedWork); 18570 break; 18571 case ContextProvider: 18572 popProvider(interruptedWork); 18573 break; 18574 default: 18575 break; 18576 } 18577 } 18578 18579 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; 18580 var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner; 18581 18582 18583 var didWarnAboutStateTransition = void 0; 18584 var didWarnSetStateChildContext = void 0; 18585 var warnAboutUpdateOnUnmounted = void 0; 18586 var warnAboutInvalidUpdates = void 0; 18587 18588 if (enableSchedulerTracing) { 18589 // Provide explicit error message when production+profiling bundle of e.g. react-dom 18590 // is used with production (non-profiling) bundle of scheduler/tracing 18591 !(__interactionsRef != null && __interactionsRef.current != null) ? invariant(false, 'It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at http://fb.me/react-profiling') : void 0; 18592 } 18593 18594 { 18595 didWarnAboutStateTransition = false; 18596 didWarnSetStateChildContext = false; 18597 var didWarnStateUpdateForUnmountedComponent = {}; 18598 18599 warnAboutUpdateOnUnmounted = function (fiber, isClass) { 18600 // We show the whole stack but dedupe on the top component's name because 18601 // the problematic code almost always lies inside that component. 18602 var componentName = getComponentName(fiber.type) || 'ReactComponent'; 18603 if (didWarnStateUpdateForUnmountedComponent[componentName]) { 18604 return; 18605 } 18606 warningWithoutStack$1(false, "Can't perform a React state update on an unmounted component. This " + 'is a no-op, but it indicates a memory leak in your application. To ' + 'fix, cancel all subscriptions and asynchronous tasks in %s.%s', isClass ? 'the componentWillUnmount method' : 'a useEffect cleanup function', getStackByFiberInDevAndProd(fiber)); 18607 didWarnStateUpdateForUnmountedComponent[componentName] = true; 18608 }; 18609 18610 warnAboutInvalidUpdates = function (instance) { 18611 switch (phase) { 18612 case 'getChildContext': 18613 if (didWarnSetStateChildContext) { 18614 return; 18615 } 18616 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()'); 18617 didWarnSetStateChildContext = true; 18618 break; 18619 case 'render': 18620 if (didWarnAboutStateTransition) { 18621 return; 18622 } 18623 warningWithoutStack$1(false, 'Cannot update during an existing state transition (such as within ' + '`render`). Render methods should be a pure function of props and state.'); 18624 didWarnAboutStateTransition = true; 18625 break; 18626 } 18627 }; 18628 } 18629 18630 // Used to ensure computeUniqueAsyncExpiration is monotonically decreasing. 18631 var lastUniqueAsyncExpiration = Sync - 1; 18632 18633 var isWorking = false; 18634 18635 // The next work in progress fiber that we're currently working on. 18636 var nextUnitOfWork = null; 18637 var nextRoot = null; 18638 // The time at which we're currently rendering work. 18639 var nextRenderExpirationTime = NoWork; 18640 var nextLatestAbsoluteTimeoutMs = -1; 18641 var nextRenderDidError = false; 18642 18643 // The next fiber with an effect that we're currently committing. 18644 var nextEffect = null; 18645 18646 var isCommitting$1 = false; 18647 var rootWithPendingPassiveEffects = null; 18648 var passiveEffectCallbackHandle = null; 18649 var passiveEffectCallback = null; 18650 18651 var legacyErrorBoundariesThatAlreadyFailed = null; 18652 18653 // Used for performance tracking. 18654 var interruptedBy = null; 18655 18656 var stashedWorkInProgressProperties = void 0; 18657 var replayUnitOfWork = void 0; 18658 var mayReplayFailedUnitOfWork = void 0; 18659 var isReplayingFailedUnitOfWork = void 0; 18660 var originalReplayError = void 0; 18661 var rethrowOriginalError = void 0; 18662 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { 18663 stashedWorkInProgressProperties = null; 18664 mayReplayFailedUnitOfWork = true; 18665 isReplayingFailedUnitOfWork = false; 18666 originalReplayError = null; 18667 replayUnitOfWork = function (failedUnitOfWork, thrownValue, isYieldy) { 18668 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') { 18669 // Don't replay promises. Treat everything else like an error. 18670 // TODO: Need to figure out a different strategy if/when we add 18671 // support for catching other types. 18672 return; 18673 } 18674 18675 // Restore the original state of the work-in-progress 18676 if (stashedWorkInProgressProperties === null) { 18677 // This should never happen. Don't throw because this code is DEV-only. 18678 warningWithoutStack$1(false, 'Could not replay rendering after an error. This is likely a bug in React. ' + 'Please file an issue.'); 18679 return; 18680 } 18681 assignFiberPropertiesInDEV(failedUnitOfWork, stashedWorkInProgressProperties); 18682 18683 switch (failedUnitOfWork.tag) { 18684 case HostRoot: 18685 popHostContainer(failedUnitOfWork); 18686 popTopLevelContextObject(failedUnitOfWork); 18687 break; 18688 case HostComponent: 18689 popHostContext(failedUnitOfWork); 18690 break; 18691 case ClassComponent: 18692 { 18693 var Component = failedUnitOfWork.type; 18694 if (isContextProvider(Component)) { 18695 popContext(failedUnitOfWork); 18696 } 18697 break; 18698 } 18699 case HostPortal: 18700 popHostContainer(failedUnitOfWork); 18701 break; 18702 case ContextProvider: 18703 popProvider(failedUnitOfWork); 18704 break; 18705 } 18706 // Replay the begin phase. 18707 isReplayingFailedUnitOfWork = true; 18708 originalReplayError = thrownValue; 18709 invokeGuardedCallback(null, workLoop, null, isYieldy); 18710 isReplayingFailedUnitOfWork = false; 18711 originalReplayError = null; 18712 if (hasCaughtError()) { 18713 var replayError = clearCaughtError(); 18714 if (replayError != null && thrownValue != null) { 18715 try { 18716 // Reading the expando property is intentionally 18717 // inside `try` because it might be a getter or Proxy. 18718 if (replayError._suppressLogging) { 18719 // Also suppress logging for the original error. 18720 thrownValue._suppressLogging = true; 18721 } 18722 } catch (inner) { 18723 // Ignore. 18724 } 18725 } 18726 } else { 18727 // If the begin phase did not fail the second time, set this pointer 18728 // back to the original value. 18729 nextUnitOfWork = failedUnitOfWork; 18730 } 18731 }; 18732 rethrowOriginalError = function () { 18733 throw originalReplayError; 18734 }; 18735 } 18736 18737 function resetStack() { 18738 if (nextUnitOfWork !== null) { 18739 var interruptedWork = nextUnitOfWork.return; 18740 while (interruptedWork !== null) { 18741 unwindInterruptedWork(interruptedWork); 18742 interruptedWork = interruptedWork.return; 18743 } 18744 } 18745 18746 { 18747 ReactStrictModeWarnings.discardPendingWarnings(); 18748 checkThatStackIsEmpty(); 18749 } 18750 18751 nextRoot = null; 18752 nextRenderExpirationTime = NoWork; 18753 nextLatestAbsoluteTimeoutMs = -1; 18754 nextRenderDidError = false; 18755 nextUnitOfWork = null; 18756 } 18757 18758 function commitAllHostEffects() { 18759 while (nextEffect !== null) { 18760 { 18761 setCurrentFiber(nextEffect); 18762 } 18763 recordEffect(); 18764 18765 var effectTag = nextEffect.effectTag; 18766 18767 if (effectTag & ContentReset) { 18768 commitResetTextContent(nextEffect); 18769 } 18770 18771 if (effectTag & Ref) { 18772 var current$$1 = nextEffect.alternate; 18773 if (current$$1 !== null) { 18774 commitDetachRef(current$$1); 18775 } 18776 } 18777 18778 // The following switch statement is only concerned about placement, 18779 // updates, and deletions. To avoid needing to add a case for every 18780 // possible bitmap value, we remove the secondary effects from the 18781 // effect tag and switch on that value. 18782 var primaryEffectTag = effectTag & (Placement | Update | Deletion); 18783 switch (primaryEffectTag) { 18784 case Placement: 18785 { 18786 commitPlacement(nextEffect); 18787 // Clear the "placement" from effect tag so that we know that this is inserted, before 18788 // any life-cycles like componentDidMount gets called. 18789 // TODO: findDOMNode doesn't rely on this any more but isMounted 18790 // does and isMounted is deprecated anyway so we should be able 18791 // to kill this. 18792 nextEffect.effectTag &= ~Placement; 18793 break; 18794 } 18795 case PlacementAndUpdate: 18796 { 18797 // Placement 18798 commitPlacement(nextEffect); 18799 // Clear the "placement" from effect tag so that we know that this is inserted, before 18800 // any life-cycles like componentDidMount gets called. 18801 nextEffect.effectTag &= ~Placement; 18802 18803 // Update 18804 var _current = nextEffect.alternate; 18805 commitWork(_current, nextEffect); 18806 break; 18807 } 18808 case Update: 18809 { 18810 var _current2 = nextEffect.alternate; 18811 commitWork(_current2, nextEffect); 18812 break; 18813 } 18814 case Deletion: 18815 { 18816 commitDeletion(nextEffect); 18817 break; 18818 } 18819 } 18820 nextEffect = nextEffect.nextEffect; 18821 } 18822 18823 { 18824 resetCurrentFiber(); 18825 } 18826 } 18827 18828 function commitBeforeMutationLifecycles() { 18829 while (nextEffect !== null) { 18830 { 18831 setCurrentFiber(nextEffect); 18832 } 18833 18834 var effectTag = nextEffect.effectTag; 18835 if (effectTag & Snapshot) { 18836 recordEffect(); 18837 var current$$1 = nextEffect.alternate; 18838 commitBeforeMutationLifeCycles(current$$1, nextEffect); 18839 } 18840 18841 nextEffect = nextEffect.nextEffect; 18842 } 18843 18844 { 18845 resetCurrentFiber(); 18846 } 18847 } 18848 18849 function commitAllLifeCycles(finishedRoot, committedExpirationTime) { 18850 { 18851 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); 18852 ReactStrictModeWarnings.flushLegacyContextWarning(); 18853 18854 if (warnAboutDeprecatedLifecycles) { 18855 ReactStrictModeWarnings.flushPendingDeprecationWarnings(); 18856 } 18857 } 18858 while (nextEffect !== null) { 18859 { 18860 setCurrentFiber(nextEffect); 18861 } 18862 var effectTag = nextEffect.effectTag; 18863 18864 if (effectTag & (Update | Callback)) { 18865 recordEffect(); 18866 var current$$1 = nextEffect.alternate; 18867 commitLifeCycles(finishedRoot, current$$1, nextEffect, committedExpirationTime); 18868 } 18869 18870 if (effectTag & Ref) { 18871 recordEffect(); 18872 commitAttachRef(nextEffect); 18873 } 18874 18875 if (effectTag & Passive) { 18876 rootWithPendingPassiveEffects = finishedRoot; 18877 } 18878 18879 nextEffect = nextEffect.nextEffect; 18880 } 18881 { 18882 resetCurrentFiber(); 18883 } 18884 } 18885 18886 function commitPassiveEffects(root, firstEffect) { 18887 rootWithPendingPassiveEffects = null; 18888 passiveEffectCallbackHandle = null; 18889 passiveEffectCallback = null; 18890 18891 // Set this to true to prevent re-entrancy 18892 var previousIsRendering = isRendering; 18893 isRendering = true; 18894 18895 var effect = firstEffect; 18896 do { 18897 { 18898 setCurrentFiber(effect); 18899 } 18900 18901 if (effect.effectTag & Passive) { 18902 var didError = false; 18903 var error = void 0; 18904 { 18905 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect); 18906 if (hasCaughtError()) { 18907 didError = true; 18908 error = clearCaughtError(); 18909 } 18910 } 18911 if (didError) { 18912 captureCommitPhaseError(effect, error); 18913 } 18914 } 18915 effect = effect.nextEffect; 18916 } while (effect !== null); 18917 { 18918 resetCurrentFiber(); 18919 } 18920 18921 isRendering = previousIsRendering; 18922 18923 // Check if work was scheduled by one of the effects 18924 var rootExpirationTime = root.expirationTime; 18925 if (rootExpirationTime !== NoWork) { 18926 requestWork(root, rootExpirationTime); 18927 } 18928 // Flush any sync work that was scheduled by effects 18929 if (!isBatchingUpdates && !isRendering) { 18930 performSyncWork(); 18931 } 18932 } 18933 18934 function isAlreadyFailedLegacyErrorBoundary(instance) { 18935 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance); 18936 } 18937 18938 function markLegacyErrorBoundaryAsFailed(instance) { 18939 if (legacyErrorBoundariesThatAlreadyFailed === null) { 18940 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]); 18941 } else { 18942 legacyErrorBoundariesThatAlreadyFailed.add(instance); 18943 } 18944 } 18945 18946 function flushPassiveEffects() { 18947 if (passiveEffectCallbackHandle !== null) { 18948 cancelPassiveEffects(passiveEffectCallbackHandle); 18949 } 18950 if (passiveEffectCallback !== null) { 18951 // We call the scheduled callback instead of commitPassiveEffects directly 18952 // to ensure tracing works correctly. 18953 passiveEffectCallback(); 18954 } 18955 } 18956 18957 function commitRoot(root, finishedWork) { 18958 isWorking = true; 18959 isCommitting$1 = true; 18960 startCommitTimer(); 18961 18962 !(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; 18963 var committedExpirationTime = root.pendingCommitExpirationTime; 18964 !(committedExpirationTime !== NoWork) ? invariant(false, 'Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue.') : void 0; 18965 root.pendingCommitExpirationTime = NoWork; 18966 18967 // Update the pending priority levels to account for the work that we are 18968 // about to commit. This needs to happen before calling the lifecycles, since 18969 // they may schedule additional updates. 18970 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime; 18971 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime; 18972 var earliestRemainingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit; 18973 markCommittedPriorityLevels(root, earliestRemainingTimeBeforeCommit); 18974 18975 var prevInteractions = null; 18976 if (enableSchedulerTracing) { 18977 // Restore any pending interactions at this point, 18978 // So that cascading work triggered during the render phase will be accounted for. 18979 prevInteractions = __interactionsRef.current; 18980 __interactionsRef.current = root.memoizedInteractions; 18981 } 18982 18983 // Reset this to null before calling lifecycles 18984 ReactCurrentOwner$2.current = null; 18985 18986 var firstEffect = void 0; 18987 if (finishedWork.effectTag > PerformedWork) { 18988 // A fiber's effect list consists only of its children, not itself. So if 18989 // the root has an effect, we need to add it to the end of the list. The 18990 // resulting list is the set that would belong to the root's parent, if 18991 // it had one; that is, all the effects in the tree including the root. 18992 if (finishedWork.lastEffect !== null) { 18993 finishedWork.lastEffect.nextEffect = finishedWork; 18994 firstEffect = finishedWork.firstEffect; 18995 } else { 18996 firstEffect = finishedWork; 18997 } 18998 } else { 18999 // There is no effect on the root. 19000 firstEffect = finishedWork.firstEffect; 19001 } 19002 19003 prepareForCommit(root.containerInfo); 19004 19005 // Invoke instances of getSnapshotBeforeUpdate before mutation. 19006 nextEffect = firstEffect; 19007 startCommitSnapshotEffectsTimer(); 19008 while (nextEffect !== null) { 19009 var didError = false; 19010 var error = void 0; 19011 { 19012 invokeGuardedCallback(null, commitBeforeMutationLifecycles, null); 19013 if (hasCaughtError()) { 19014 didError = true; 19015 error = clearCaughtError(); 19016 } 19017 } 19018 if (didError) { 19019 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0; 19020 captureCommitPhaseError(nextEffect, error); 19021 // Clean-up 19022 if (nextEffect !== null) { 19023 nextEffect = nextEffect.nextEffect; 19024 } 19025 } 19026 } 19027 stopCommitSnapshotEffectsTimer(); 19028 19029 if (enableProfilerTimer) { 19030 // Mark the current commit time to be shared by all Profilers in this batch. 19031 // This enables them to be grouped later. 19032 recordCommitTime(); 19033 } 19034 19035 // Commit all the side-effects within a tree. We'll do this in two passes. 19036 // The first pass performs all the host insertions, updates, deletions and 19037 // ref unmounts. 19038 nextEffect = firstEffect; 19039 startCommitHostEffectsTimer(); 19040 while (nextEffect !== null) { 19041 var _didError = false; 19042 var _error = void 0; 19043 { 19044 invokeGuardedCallback(null, commitAllHostEffects, null); 19045 if (hasCaughtError()) { 19046 _didError = true; 19047 _error = clearCaughtError(); 19048 } 19049 } 19050 if (_didError) { 19051 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0; 19052 captureCommitPhaseError(nextEffect, _error); 19053 // Clean-up 19054 if (nextEffect !== null) { 19055 nextEffect = nextEffect.nextEffect; 19056 } 19057 } 19058 } 19059 stopCommitHostEffectsTimer(); 19060 19061 resetAfterCommit(root.containerInfo); 19062 19063 // The work-in-progress tree is now the current tree. This must come after 19064 // the first pass of the commit phase, so that the previous tree is still 19065 // current during componentWillUnmount, but before the second pass, so that 19066 // the finished work is current during componentDidMount/Update. 19067 root.current = finishedWork; 19068 19069 // In the second pass we'll perform all life-cycles and ref callbacks. 19070 // Life-cycles happen as a separate pass so that all placements, updates, 19071 // and deletions in the entire tree have already been invoked. 19072 // This pass also triggers any renderer-specific initial effects. 19073 nextEffect = firstEffect; 19074 startCommitLifeCyclesTimer(); 19075 while (nextEffect !== null) { 19076 var _didError2 = false; 19077 var _error2 = void 0; 19078 { 19079 invokeGuardedCallback(null, commitAllLifeCycles, null, root, committedExpirationTime); 19080 if (hasCaughtError()) { 19081 _didError2 = true; 19082 _error2 = clearCaughtError(); 19083 } 19084 } 19085 if (_didError2) { 19086 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0; 19087 captureCommitPhaseError(nextEffect, _error2); 19088 if (nextEffect !== null) { 19089 nextEffect = nextEffect.nextEffect; 19090 } 19091 } 19092 } 19093 19094 if (firstEffect !== null && rootWithPendingPassiveEffects !== null) { 19095 // This commit included a passive effect. These do not need to fire until 19096 // after the next paint. Schedule an callback to fire them in an async 19097 // event. To ensure serial execution, the callback will be flushed early if 19098 // we enter rootWithPendingPassiveEffects commit phase before then. 19099 var callback = commitPassiveEffects.bind(null, root, firstEffect); 19100 if (enableSchedulerTracing) { 19101 // TODO: Avoid this extra callback by mutating the tracing ref directly, 19102 // like we do at the beginning of commitRoot. I've opted not to do that 19103 // here because that code is still in flux. 19104 callback = unstable_wrap(callback); 19105 } 19106 passiveEffectCallbackHandle = unstable_runWithPriority(unstable_NormalPriority, function () { 19107 return schedulePassiveEffects(callback); 19108 }); 19109 passiveEffectCallback = callback; 19110 } 19111 19112 isCommitting$1 = false; 19113 isWorking = false; 19114 stopCommitLifeCyclesTimer(); 19115 stopCommitTimer(); 19116 onCommitRoot(finishedWork.stateNode); 19117 if (true && ReactFiberInstrumentation_1.debugTool) { 19118 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork); 19119 } 19120 19121 var updateExpirationTimeAfterCommit = finishedWork.expirationTime; 19122 var childExpirationTimeAfterCommit = finishedWork.childExpirationTime; 19123 var earliestRemainingTimeAfterCommit = childExpirationTimeAfterCommit > updateExpirationTimeAfterCommit ? childExpirationTimeAfterCommit : updateExpirationTimeAfterCommit; 19124 if (earliestRemainingTimeAfterCommit === NoWork) { 19125 // If there's no remaining work, we can clear the set of already failed 19126 // error boundaries. 19127 legacyErrorBoundariesThatAlreadyFailed = null; 19128 } 19129 onCommit(root, earliestRemainingTimeAfterCommit); 19130 19131 if (enableSchedulerTracing) { 19132 __interactionsRef.current = prevInteractions; 19133 19134 var subscriber = void 0; 19135 19136 try { 19137 subscriber = __subscriberRef.current; 19138 if (subscriber !== null && root.memoizedInteractions.size > 0) { 19139 var threadID = computeThreadID(committedExpirationTime, root.interactionThreadID); 19140 subscriber.onWorkStopped(root.memoizedInteractions, threadID); 19141 } 19142 } catch (error) { 19143 // It's not safe for commitRoot() to throw. 19144 // Store the error for now and we'll re-throw in finishRendering(). 19145 if (!hasUnhandledError) { 19146 hasUnhandledError = true; 19147 unhandledError = error; 19148 } 19149 } finally { 19150 // Clear completed interactions from the pending Map. 19151 // Unless the render was suspended or cascading work was scheduled, 19152 // In which case– leave pending interactions until the subsequent render. 19153 var pendingInteractionMap = root.pendingInteractionMap; 19154 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) { 19155 // Only decrement the pending interaction count if we're done. 19156 // If there's still work at the current priority, 19157 // That indicates that we are waiting for suspense data. 19158 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) { 19159 pendingInteractionMap.delete(scheduledExpirationTime); 19160 19161 scheduledInteractions.forEach(function (interaction) { 19162 interaction.__count--; 19163 19164 if (subscriber !== null && interaction.__count === 0) { 19165 try { 19166 subscriber.onInteractionScheduledWorkCompleted(interaction); 19167 } catch (error) { 19168 // It's not safe for commitRoot() to throw. 19169 // Store the error for now and we'll re-throw in finishRendering(). 19170 if (!hasUnhandledError) { 19171 hasUnhandledError = true; 19172 unhandledError = error; 19173 } 19174 } 19175 } 19176 }); 19177 } 19178 }); 19179 } 19180 } 19181 } 19182 19183 function resetChildExpirationTime(workInProgress, renderTime) { 19184 if (renderTime !== Never && workInProgress.childExpirationTime === Never) { 19185 // The children of this component are hidden. Don't bubble their 19186 // expiration times. 19187 return; 19188 } 19189 19190 var newChildExpirationTime = NoWork; 19191 19192 // Bubble up the earliest expiration time. 19193 if (enableProfilerTimer && workInProgress.mode & ProfileMode) { 19194 // We're in profiling mode. 19195 // Let's use this same traversal to update the render durations. 19196 var actualDuration = workInProgress.actualDuration; 19197 var treeBaseDuration = workInProgress.selfBaseDuration; 19198 19199 // When a fiber is cloned, its actualDuration is reset to 0. 19200 // This value will only be updated if work is done on the fiber (i.e. it doesn't bailout). 19201 // When work is done, it should bubble to the parent's actualDuration. 19202 // If the fiber has not been cloned though, (meaning no work was done), 19203 // Then this value will reflect the amount of time spent working on a previous render. 19204 // In that case it should not bubble. 19205 // We determine whether it was cloned by comparing the child pointer. 19206 var shouldBubbleActualDurations = workInProgress.alternate === null || workInProgress.child !== workInProgress.alternate.child; 19207 19208 var child = workInProgress.child; 19209 while (child !== null) { 19210 var childUpdateExpirationTime = child.expirationTime; 19211 var childChildExpirationTime = child.childExpirationTime; 19212 if (childUpdateExpirationTime > newChildExpirationTime) { 19213 newChildExpirationTime = childUpdateExpirationTime; 19214 } 19215 if (childChildExpirationTime > newChildExpirationTime) { 19216 newChildExpirationTime = childChildExpirationTime; 19217 } 19218 if (shouldBubbleActualDurations) { 19219 actualDuration += child.actualDuration; 19220 } 19221 treeBaseDuration += child.treeBaseDuration; 19222 child = child.sibling; 19223 } 19224 workInProgress.actualDuration = actualDuration; 19225 workInProgress.treeBaseDuration = treeBaseDuration; 19226 } else { 19227 var _child = workInProgress.child; 19228 while (_child !== null) { 19229 var _childUpdateExpirationTime = _child.expirationTime; 19230 var _childChildExpirationTime = _child.childExpirationTime; 19231 if (_childUpdateExpirationTime > newChildExpirationTime) { 19232 newChildExpirationTime = _childUpdateExpirationTime; 19233 } 19234 if (_childChildExpirationTime > newChildExpirationTime) { 19235 newChildExpirationTime = _childChildExpirationTime; 19236 } 19237 _child = _child.sibling; 19238 } 19239 } 19240 19241 workInProgress.childExpirationTime = newChildExpirationTime; 19242 } 19243 19244 function completeUnitOfWork(workInProgress) { 19245 // Attempt to complete the current unit of work, then move to the 19246 // next sibling. If there are no more siblings, return to the 19247 // parent fiber. 19248 while (true) { 19249 // The current, flushed, state of this fiber is the alternate. 19250 // Ideally nothing should rely on this, but relying on it here 19251 // means that we don't need an additional field on the work in 19252 // progress. 19253 var current$$1 = workInProgress.alternate; 19254 { 19255 setCurrentFiber(workInProgress); 19256 } 19257 19258 var returnFiber = workInProgress.return; 19259 var siblingFiber = workInProgress.sibling; 19260 19261 if ((workInProgress.effectTag & Incomplete) === NoEffect) { 19262 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { 19263 // Don't replay if it fails during completion phase. 19264 mayReplayFailedUnitOfWork = false; 19265 } 19266 // This fiber completed. 19267 // Remember we're completing this unit so we can find a boundary if it fails. 19268 nextUnitOfWork = workInProgress; 19269 if (enableProfilerTimer) { 19270 if (workInProgress.mode & ProfileMode) { 19271 startProfilerTimer(workInProgress); 19272 } 19273 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime); 19274 if (workInProgress.mode & ProfileMode) { 19275 // Update render duration assuming we didn't error. 19276 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); 19277 } 19278 } else { 19279 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime); 19280 } 19281 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { 19282 // We're out of completion phase so replaying is fine now. 19283 mayReplayFailedUnitOfWork = true; 19284 } 19285 stopWorkTimer(workInProgress); 19286 resetChildExpirationTime(workInProgress, nextRenderExpirationTime); 19287 { 19288 resetCurrentFiber(); 19289 } 19290 19291 if (nextUnitOfWork !== null) { 19292 // Completing this fiber spawned new work. Work on that next. 19293 return nextUnitOfWork; 19294 } 19295 19296 if (returnFiber !== null && 19297 // Do not append effects to parents if a sibling failed to complete 19298 (returnFiber.effectTag & Incomplete) === NoEffect) { 19299 // Append all the effects of the subtree and this fiber onto the effect 19300 // list of the parent. The completion order of the children affects the 19301 // side-effect order. 19302 if (returnFiber.firstEffect === null) { 19303 returnFiber.firstEffect = workInProgress.firstEffect; 19304 } 19305 if (workInProgress.lastEffect !== null) { 19306 if (returnFiber.lastEffect !== null) { 19307 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect; 19308 } 19309 returnFiber.lastEffect = workInProgress.lastEffect; 19310 } 19311 19312 // If this fiber had side-effects, we append it AFTER the children's 19313 // side-effects. We can perform certain side-effects earlier if 19314 // needed, by doing multiple passes over the effect list. We don't want 19315 // to schedule our own side-effect on our own list because if end up 19316 // reusing children we'll schedule this effect onto itself since we're 19317 // at the end. 19318 var effectTag = workInProgress.effectTag; 19319 // Skip both NoWork and PerformedWork tags when creating the effect list. 19320 // PerformedWork effect is read by React DevTools but shouldn't be committed. 19321 if (effectTag > PerformedWork) { 19322 if (returnFiber.lastEffect !== null) { 19323 returnFiber.lastEffect.nextEffect = workInProgress; 19324 } else { 19325 returnFiber.firstEffect = workInProgress; 19326 } 19327 returnFiber.lastEffect = workInProgress; 19328 } 19329 } 19330 19331 if (true && ReactFiberInstrumentation_1.debugTool) { 19332 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress); 19333 } 19334 19335 if (siblingFiber !== null) { 19336 // If there is more work to do in this returnFiber, do that next. 19337 return siblingFiber; 19338 } else if (returnFiber !== null) { 19339 // If there's no more work in this returnFiber. Complete the returnFiber. 19340 workInProgress = returnFiber; 19341 continue; 19342 } else { 19343 // We've reached the root. 19344 return null; 19345 } 19346 } else { 19347 if (enableProfilerTimer && workInProgress.mode & ProfileMode) { 19348 // Record the render duration for the fiber that errored. 19349 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); 19350 19351 // Include the time spent working on failed children before continuing. 19352 var actualDuration = workInProgress.actualDuration; 19353 var child = workInProgress.child; 19354 while (child !== null) { 19355 actualDuration += child.actualDuration; 19356 child = child.sibling; 19357 } 19358 workInProgress.actualDuration = actualDuration; 19359 } 19360 19361 // This fiber did not complete because something threw. Pop values off 19362 // the stack without entering the complete phase. If this is a boundary, 19363 // capture values if possible. 19364 var next = unwindWork(workInProgress, nextRenderExpirationTime); 19365 // Because this fiber did not complete, don't reset its expiration time. 19366 if (workInProgress.effectTag & DidCapture) { 19367 // Restarting an error boundary 19368 stopFailedWorkTimer(workInProgress); 19369 } else { 19370 stopWorkTimer(workInProgress); 19371 } 19372 19373 { 19374 resetCurrentFiber(); 19375 } 19376 19377 if (next !== null) { 19378 stopWorkTimer(workInProgress); 19379 if (true && ReactFiberInstrumentation_1.debugTool) { 19380 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress); 19381 } 19382 19383 // If completing this work spawned new work, do that next. We'll come 19384 // back here again. 19385 // Since we're restarting, remove anything that is not a host effect 19386 // from the effect tag. 19387 next.effectTag &= HostEffectMask; 19388 return next; 19389 } 19390 19391 if (returnFiber !== null) { 19392 // Mark the parent fiber as incomplete and clear its effect list. 19393 returnFiber.firstEffect = returnFiber.lastEffect = null; 19394 returnFiber.effectTag |= Incomplete; 19395 } 19396 19397 if (true && ReactFiberInstrumentation_1.debugTool) { 19398 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress); 19399 } 19400 19401 if (siblingFiber !== null) { 19402 // If there is more work to do in this returnFiber, do that next. 19403 return siblingFiber; 19404 } else if (returnFiber !== null) { 19405 // If there's no more work in this returnFiber. Complete the returnFiber. 19406 workInProgress = returnFiber; 19407 continue; 19408 } else { 19409 return null; 19410 } 19411 } 19412 } 19413 19414 // Without this explicit null return Flow complains of invalid return type 19415 // TODO Remove the above while(true) loop 19416 // eslint-disable-next-line no-unreachable 19417 return null; 19418 } 19419 19420 function performUnitOfWork(workInProgress) { 19421 // The current, flushed, state of this fiber is the alternate. 19422 // Ideally nothing should rely on this, but relying on it here 19423 // means that we don't need an additional field on the work in 19424 // progress. 19425 var current$$1 = workInProgress.alternate; 19426 19427 // See if beginning this work spawns more work. 19428 startWorkTimer(workInProgress); 19429 { 19430 setCurrentFiber(workInProgress); 19431 } 19432 19433 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { 19434 stashedWorkInProgressProperties = assignFiberPropertiesInDEV(stashedWorkInProgressProperties, workInProgress); 19435 } 19436 19437 var next = void 0; 19438 if (enableProfilerTimer) { 19439 if (workInProgress.mode & ProfileMode) { 19440 startProfilerTimer(workInProgress); 19441 } 19442 19443 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime); 19444 workInProgress.memoizedProps = workInProgress.pendingProps; 19445 19446 if (workInProgress.mode & ProfileMode) { 19447 // Record the render duration assuming we didn't bailout (or error). 19448 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true); 19449 } 19450 } else { 19451 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime); 19452 workInProgress.memoizedProps = workInProgress.pendingProps; 19453 } 19454 19455 { 19456 resetCurrentFiber(); 19457 if (isReplayingFailedUnitOfWork) { 19458 // Currently replaying a failed unit of work. This should be unreachable, 19459 // because the render phase is meant to be idempotent, and it should 19460 // have thrown again. Since it didn't, rethrow the original error, so 19461 // React's internal stack is not misaligned. 19462 rethrowOriginalError(); 19463 } 19464 } 19465 if (true && ReactFiberInstrumentation_1.debugTool) { 19466 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress); 19467 } 19468 19469 if (next === null) { 19470 // If this doesn't spawn new work, complete the current work. 19471 next = completeUnitOfWork(workInProgress); 19472 } 19473 19474 ReactCurrentOwner$2.current = null; 19475 19476 return next; 19477 } 19478 19479 function workLoop(isYieldy) { 19480 if (!isYieldy) { 19481 // Flush work without yielding 19482 while (nextUnitOfWork !== null) { 19483 nextUnitOfWork = performUnitOfWork(nextUnitOfWork); 19484 } 19485 } else { 19486 // Flush asynchronous work until there's a higher priority event 19487 while (nextUnitOfWork !== null && !shouldYieldToRenderer()) { 19488 nextUnitOfWork = performUnitOfWork(nextUnitOfWork); 19489 } 19490 } 19491 } 19492 19493 function renderRoot(root, isYieldy) { 19494 !!isWorking ? invariant(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0; 19495 19496 flushPassiveEffects(); 19497 19498 isWorking = true; 19499 var previousDispatcher = ReactCurrentDispatcher.current; 19500 ReactCurrentDispatcher.current = ContextOnlyDispatcher; 19501 19502 var expirationTime = root.nextExpirationTimeToWorkOn; 19503 19504 // Check if we're starting from a fresh stack, or if we're resuming from 19505 // previously yielded work. 19506 if (expirationTime !== nextRenderExpirationTime || root !== nextRoot || nextUnitOfWork === null) { 19507 // Reset the stack and start working from the root. 19508 resetStack(); 19509 nextRoot = root; 19510 nextRenderExpirationTime = expirationTime; 19511 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, nextRenderExpirationTime); 19512 root.pendingCommitExpirationTime = NoWork; 19513 19514 if (enableSchedulerTracing) { 19515 // Determine which interactions this batch of work currently includes, 19516 // So that we can accurately attribute time spent working on it, 19517 var interactions = new Set(); 19518 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) { 19519 if (scheduledExpirationTime >= expirationTime) { 19520 scheduledInteractions.forEach(function (interaction) { 19521 return interactions.add(interaction); 19522 }); 19523 } 19524 }); 19525 19526 // Store the current set of interactions on the FiberRoot for a few reasons: 19527 // We can re-use it in hot functions like renderRoot() without having to recalculate it. 19528 // We will also use it in commitWork() to pass to any Profiler onRender() hooks. 19529 // This also provides DevTools with a way to access it when the onCommitRoot() hook is called. 19530 root.memoizedInteractions = interactions; 19531 19532 if (interactions.size > 0) { 19533 var subscriber = __subscriberRef.current; 19534 if (subscriber !== null) { 19535 var threadID = computeThreadID(expirationTime, root.interactionThreadID); 19536 try { 19537 subscriber.onWorkStarted(interactions, threadID); 19538 } catch (error) { 19539 // Work thrown by an interaction tracing subscriber should be rethrown, 19540 // But only once it's safe (to avoid leaving the scheduler in an invalid state). 19541 // Store the error for now and we'll re-throw in finishRendering(). 19542 if (!hasUnhandledError) { 19543 hasUnhandledError = true; 19544 unhandledError = error; 19545 } 19546 } 19547 } 19548 } 19549 } 19550 } 19551 19552 var prevInteractions = null; 19553 if (enableSchedulerTracing) { 19554 // We're about to start new traced work. 19555 // Restore pending interactions so cascading work triggered during the render phase will be accounted for. 19556 prevInteractions = __interactionsRef.current; 19557 __interactionsRef.current = root.memoizedInteractions; 19558 } 19559 19560 var didFatal = false; 19561 19562 startWorkLoopTimer(nextUnitOfWork); 19563 19564 do { 19565 try { 19566 workLoop(isYieldy); 19567 } catch (thrownValue) { 19568 resetContextDependences(); 19569 resetHooks(); 19570 19571 // Reset in case completion throws. 19572 // This is only used in DEV and when replaying is on. 19573 var mayReplay = void 0; 19574 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { 19575 mayReplay = mayReplayFailedUnitOfWork; 19576 mayReplayFailedUnitOfWork = true; 19577 } 19578 19579 if (nextUnitOfWork === null) { 19580 // This is a fatal error. 19581 didFatal = true; 19582 onUncaughtError(thrownValue); 19583 } else { 19584 if (enableProfilerTimer && nextUnitOfWork.mode & ProfileMode) { 19585 // Record the time spent rendering before an error was thrown. 19586 // This avoids inaccurate Profiler durations in the case of a suspended render. 19587 stopProfilerTimerIfRunningAndRecordDelta(nextUnitOfWork, true); 19588 } 19589 19590 { 19591 // Reset global debug state 19592 // We assume this is defined in DEV 19593 resetCurrentlyProcessingQueue(); 19594 } 19595 19596 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { 19597 if (mayReplay) { 19598 var failedUnitOfWork = nextUnitOfWork; 19599 replayUnitOfWork(failedUnitOfWork, thrownValue, isYieldy); 19600 } 19601 } 19602 19603 // TODO: we already know this isn't true in some cases. 19604 // At least this shows a nicer error message until we figure out the cause. 19605 // https://github.com/facebook/react/issues/12449#issuecomment-386727431 19606 !(nextUnitOfWork !== null) ? invariant(false, 'Failed to replay rendering after an error. This is likely caused by a bug in React. Please file an issue with a reproducing case to help us find it.') : void 0; 19607 19608 var sourceFiber = nextUnitOfWork; 19609 var returnFiber = sourceFiber.return; 19610 if (returnFiber === null) { 19611 // This is the root. The root could capture its own errors. However, 19612 // we don't know if it errors before or after we pushed the host 19613 // context. This information is needed to avoid a stack mismatch. 19614 // Because we're not sure, treat this as a fatal error. We could track 19615 // which phase it fails in, but doesn't seem worth it. At least 19616 // for now. 19617 didFatal = true; 19618 onUncaughtError(thrownValue); 19619 } else { 19620 throwException(root, returnFiber, sourceFiber, thrownValue, nextRenderExpirationTime); 19621 nextUnitOfWork = completeUnitOfWork(sourceFiber); 19622 continue; 19623 } 19624 } 19625 } 19626 break; 19627 } while (true); 19628 19629 if (enableSchedulerTracing) { 19630 // Traced work is done for now; restore the previous interactions. 19631 __interactionsRef.current = prevInteractions; 19632 } 19633 19634 // We're done performing work. Time to clean up. 19635 isWorking = false; 19636 ReactCurrentDispatcher.current = previousDispatcher; 19637 resetContextDependences(); 19638 resetHooks(); 19639 19640 // Yield back to main thread. 19641 if (didFatal) { 19642 var _didCompleteRoot = false; 19643 stopWorkLoopTimer(interruptedBy, _didCompleteRoot); 19644 interruptedBy = null; 19645 // There was a fatal error. 19646 { 19647 resetStackAfterFatalErrorInDev(); 19648 } 19649 // `nextRoot` points to the in-progress root. A non-null value indicates 19650 // that we're in the middle of an async render. Set it to null to indicate 19651 // there's no more work to be done in the current batch. 19652 nextRoot = null; 19653 onFatal(root); 19654 return; 19655 } 19656 19657 if (nextUnitOfWork !== null) { 19658 // There's still remaining async work in this tree, but we ran out of time 19659 // in the current frame. Yield back to the renderer. Unless we're 19660 // interrupted by a higher priority update, we'll continue later from where 19661 // we left off. 19662 var _didCompleteRoot2 = false; 19663 stopWorkLoopTimer(interruptedBy, _didCompleteRoot2); 19664 interruptedBy = null; 19665 onYield(root); 19666 return; 19667 } 19668 19669 // We completed the whole tree. 19670 var didCompleteRoot = true; 19671 stopWorkLoopTimer(interruptedBy, didCompleteRoot); 19672 var rootWorkInProgress = root.current.alternate; 19673 !(rootWorkInProgress !== null) ? invariant(false, 'Finished root should have a work-in-progress. This error is likely caused by a bug in React. Please file an issue.') : void 0; 19674 19675 // `nextRoot` points to the in-progress root. A non-null value indicates 19676 // that we're in the middle of an async render. Set it to null to indicate 19677 // there's no more work to be done in the current batch. 19678 nextRoot = null; 19679 interruptedBy = null; 19680 19681 if (nextRenderDidError) { 19682 // There was an error 19683 if (hasLowerPriorityWork(root, expirationTime)) { 19684 // There's lower priority work. If so, it may have the effect of fixing 19685 // the exception that was just thrown. Exit without committing. This is 19686 // similar to a suspend, but without a timeout because we're not waiting 19687 // for a promise to resolve. React will restart at the lower 19688 // priority level. 19689 markSuspendedPriorityLevel(root, expirationTime); 19690 var suspendedExpirationTime = expirationTime; 19691 var rootExpirationTime = root.expirationTime; 19692 onSuspend(root, rootWorkInProgress, suspendedExpirationTime, rootExpirationTime, -1 // Indicates no timeout 19693 ); 19694 return; 19695 } else if ( 19696 // There's no lower priority work, but we're rendering asynchronously. 19697 // Synchronously attempt to render the same level one more time. This is 19698 // similar to a suspend, but without a timeout because we're not waiting 19699 // for a promise to resolve. 19700 !root.didError && isYieldy) { 19701 root.didError = true; 19702 var _suspendedExpirationTime = root.nextExpirationTimeToWorkOn = expirationTime; 19703 var _rootExpirationTime = root.expirationTime = Sync; 19704 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime, _rootExpirationTime, -1 // Indicates no timeout 19705 ); 19706 return; 19707 } 19708 } 19709 19710 if (isYieldy && nextLatestAbsoluteTimeoutMs !== -1) { 19711 // The tree was suspended. 19712 var _suspendedExpirationTime2 = expirationTime; 19713 markSuspendedPriorityLevel(root, _suspendedExpirationTime2); 19714 19715 // Find the earliest uncommitted expiration time in the tree, including 19716 // work that is suspended. The timeout threshold cannot be longer than 19717 // the overall expiration. 19718 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, expirationTime); 19719 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime); 19720 if (earliestExpirationTimeMs < nextLatestAbsoluteTimeoutMs) { 19721 nextLatestAbsoluteTimeoutMs = earliestExpirationTimeMs; 19722 } 19723 19724 // Subtract the current time from the absolute timeout to get the number 19725 // of milliseconds until the timeout. In other words, convert an absolute 19726 // timestamp to a relative time. This is the value that is passed 19727 // to `setTimeout`. 19728 var currentTimeMs = expirationTimeToMs(requestCurrentTime()); 19729 var msUntilTimeout = nextLatestAbsoluteTimeoutMs - currentTimeMs; 19730 msUntilTimeout = msUntilTimeout < 0 ? 0 : msUntilTimeout; 19731 19732 // TODO: Account for the Just Noticeable Difference 19733 19734 var _rootExpirationTime2 = root.expirationTime; 19735 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime2, _rootExpirationTime2, msUntilTimeout); 19736 return; 19737 } 19738 19739 // Ready to commit. 19740 onComplete(root, rootWorkInProgress, expirationTime); 19741 } 19742 19743 function captureCommitPhaseError(sourceFiber, value) { 19744 var expirationTime = Sync; 19745 var fiber = sourceFiber.return; 19746 while (fiber !== null) { 19747 switch (fiber.tag) { 19748 case ClassComponent: 19749 var ctor = fiber.type; 19750 var instance = fiber.stateNode; 19751 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) { 19752 var errorInfo = createCapturedValue(value, sourceFiber); 19753 var update = createClassErrorUpdate(fiber, errorInfo, expirationTime); 19754 enqueueUpdate(fiber, update); 19755 scheduleWork(fiber, expirationTime); 19756 return; 19757 } 19758 break; 19759 case HostRoot: 19760 { 19761 var _errorInfo = createCapturedValue(value, sourceFiber); 19762 var _update = createRootErrorUpdate(fiber, _errorInfo, expirationTime); 19763 enqueueUpdate(fiber, _update); 19764 scheduleWork(fiber, expirationTime); 19765 return; 19766 } 19767 } 19768 fiber = fiber.return; 19769 } 19770 19771 if (sourceFiber.tag === HostRoot) { 19772 // Error was thrown at the root. There is no parent, so the root 19773 // itself should capture it. 19774 var rootFiber = sourceFiber; 19775 var _errorInfo2 = createCapturedValue(value, rootFiber); 19776 var _update2 = createRootErrorUpdate(rootFiber, _errorInfo2, expirationTime); 19777 enqueueUpdate(rootFiber, _update2); 19778 scheduleWork(rootFiber, expirationTime); 19779 } 19780 } 19781 19782 function computeThreadID(expirationTime, interactionThreadID) { 19783 // Interaction threads are unique per root and expiration time. 19784 return expirationTime * 1000 + interactionThreadID; 19785 } 19786 19787 // Creates a unique async expiration time. 19788 function computeUniqueAsyncExpiration() { 19789 var currentTime = requestCurrentTime(); 19790 var result = computeAsyncExpiration(currentTime); 19791 if (result >= lastUniqueAsyncExpiration) { 19792 // Since we assume the current time monotonically increases, we only hit 19793 // this branch when computeUniqueAsyncExpiration is fired multiple times 19794 // within a 200ms window (or whatever the async bucket size is). 19795 result = lastUniqueAsyncExpiration - 1; 19796 } 19797 lastUniqueAsyncExpiration = result; 19798 return lastUniqueAsyncExpiration; 19799 } 19800 19801 function computeExpirationForFiber(currentTime, fiber) { 19802 var priorityLevel = unstable_getCurrentPriorityLevel(); 19803 19804 var expirationTime = void 0; 19805 if ((fiber.mode & ConcurrentMode) === NoContext) { 19806 // Outside of concurrent mode, updates are always synchronous. 19807 expirationTime = Sync; 19808 } else if (isWorking && !isCommitting$1) { 19809 // During render phase, updates expire during as the current render. 19810 expirationTime = nextRenderExpirationTime; 19811 } else { 19812 switch (priorityLevel) { 19813 case unstable_ImmediatePriority: 19814 expirationTime = Sync; 19815 break; 19816 case unstable_UserBlockingPriority: 19817 expirationTime = computeInteractiveExpiration(currentTime); 19818 break; 19819 case unstable_NormalPriority: 19820 // This is a normal, concurrent update 19821 expirationTime = computeAsyncExpiration(currentTime); 19822 break; 19823 case unstable_LowPriority: 19824 case unstable_IdlePriority: 19825 expirationTime = Never; 19826 break; 19827 default: 19828 invariant(false, 'Unknown priority level. This error is likely caused by a bug in React. Please file an issue.'); 19829 } 19830 19831 // If we're in the middle of rendering a tree, do not update at the same 19832 // expiration time that is already rendering. 19833 if (nextRoot !== null && expirationTime === nextRenderExpirationTime) { 19834 expirationTime -= 1; 19835 } 19836 } 19837 19838 // Keep track of the lowest pending interactive expiration time. This 19839 // allows us to synchronously flush all interactive updates 19840 // when needed. 19841 // TODO: Move this to renderer? 19842 if (priorityLevel === unstable_UserBlockingPriority && (lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime < lowestPriorityPendingInteractiveExpirationTime)) { 19843 lowestPriorityPendingInteractiveExpirationTime = expirationTime; 19844 } 19845 19846 return expirationTime; 19847 } 19848 19849 function renderDidSuspend(root, absoluteTimeoutMs, suspendedTime) { 19850 // Schedule the timeout. 19851 if (absoluteTimeoutMs >= 0 && nextLatestAbsoluteTimeoutMs < absoluteTimeoutMs) { 19852 nextLatestAbsoluteTimeoutMs = absoluteTimeoutMs; 19853 } 19854 } 19855 19856 function renderDidError() { 19857 nextRenderDidError = true; 19858 } 19859 19860 function pingSuspendedRoot(root, thenable, pingTime) { 19861 // A promise that previously suspended React from committing has resolved. 19862 // If React is still suspended, try again at the previous level (pingTime). 19863 19864 var pingCache = root.pingCache; 19865 if (pingCache !== null) { 19866 // The thenable resolved, so we no longer need to memoize, because it will 19867 // never be thrown again. 19868 pingCache.delete(thenable); 19869 } 19870 19871 if (nextRoot !== null && nextRenderExpirationTime === pingTime) { 19872 // Received a ping at the same priority level at which we're currently 19873 // rendering. Restart from the root. 19874 nextRoot = null; 19875 } else { 19876 // Confirm that the root is still suspended at this level. Otherwise exit. 19877 if (isPriorityLevelSuspended(root, pingTime)) { 19878 // Ping at the original level 19879 markPingedPriorityLevel(root, pingTime); 19880 var rootExpirationTime = root.expirationTime; 19881 if (rootExpirationTime !== NoWork) { 19882 requestWork(root, rootExpirationTime); 19883 } 19884 } 19885 } 19886 } 19887 19888 function retryTimedOutBoundary(boundaryFiber, thenable) { 19889 // The boundary fiber (a Suspense component) previously timed out and was 19890 // rendered in its fallback state. One of the promises that suspended it has 19891 // resolved, which means at least part of the tree was likely unblocked. Try 19892 var retryCache = void 0; 19893 if (enableSuspenseServerRenderer) { 19894 switch (boundaryFiber.tag) { 19895 case SuspenseComponent: 19896 retryCache = boundaryFiber.stateNode; 19897 break; 19898 case DehydratedSuspenseComponent: 19899 retryCache = boundaryFiber.memoizedState; 19900 break; 19901 default: 19902 invariant(false, 'Pinged unknown suspense boundary type. This is probably a bug in React.'); 19903 } 19904 } else { 19905 retryCache = boundaryFiber.stateNode; 19906 } 19907 if (retryCache !== null) { 19908 // The thenable resolved, so we no longer need to memoize, because it will 19909 // never be thrown again. 19910 retryCache.delete(thenable); 19911 } 19912 19913 var currentTime = requestCurrentTime(); 19914 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber); 19915 var root = scheduleWorkToRoot(boundaryFiber, retryTime); 19916 if (root !== null) { 19917 markPendingPriorityLevel(root, retryTime); 19918 var rootExpirationTime = root.expirationTime; 19919 if (rootExpirationTime !== NoWork) { 19920 requestWork(root, rootExpirationTime); 19921 } 19922 } 19923 } 19924 19925 function scheduleWorkToRoot(fiber, expirationTime) { 19926 recordScheduleUpdate(); 19927 19928 { 19929 if (fiber.tag === ClassComponent) { 19930 var instance = fiber.stateNode; 19931 warnAboutInvalidUpdates(instance); 19932 } 19933 } 19934 19935 // Update the source fiber's expiration time 19936 if (fiber.expirationTime < expirationTime) { 19937 fiber.expirationTime = expirationTime; 19938 } 19939 var alternate = fiber.alternate; 19940 if (alternate !== null && alternate.expirationTime < expirationTime) { 19941 alternate.expirationTime = expirationTime; 19942 } 19943 // Walk the parent path to the root and update the child expiration time. 19944 var node = fiber.return; 19945 var root = null; 19946 if (node === null && fiber.tag === HostRoot) { 19947 root = fiber.stateNode; 19948 } else { 19949 while (node !== null) { 19950 alternate = node.alternate; 19951 if (node.childExpirationTime < expirationTime) { 19952 node.childExpirationTime = expirationTime; 19953 if (alternate !== null && alternate.childExpirationTime < expirationTime) { 19954 alternate.childExpirationTime = expirationTime; 19955 } 19956 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) { 19957 alternate.childExpirationTime = expirationTime; 19958 } 19959 if (node.return === null && node.tag === HostRoot) { 19960 root = node.stateNode; 19961 break; 19962 } 19963 node = node.return; 19964 } 19965 } 19966 19967 if (enableSchedulerTracing) { 19968 if (root !== null) { 19969 var interactions = __interactionsRef.current; 19970 if (interactions.size > 0) { 19971 var pendingInteractionMap = root.pendingInteractionMap; 19972 var pendingInteractions = pendingInteractionMap.get(expirationTime); 19973 if (pendingInteractions != null) { 19974 interactions.forEach(function (interaction) { 19975 if (!pendingInteractions.has(interaction)) { 19976 // Update the pending async work count for previously unscheduled interaction. 19977 interaction.__count++; 19978 } 19979 19980 pendingInteractions.add(interaction); 19981 }); 19982 } else { 19983 pendingInteractionMap.set(expirationTime, new Set(interactions)); 19984 19985 // Update the pending async work count for the current interactions. 19986 interactions.forEach(function (interaction) { 19987 interaction.__count++; 19988 }); 19989 } 19990 19991 var subscriber = __subscriberRef.current; 19992 if (subscriber !== null) { 19993 var threadID = computeThreadID(expirationTime, root.interactionThreadID); 19994 subscriber.onWorkScheduled(interactions, threadID); 19995 } 19996 } 19997 } 19998 } 19999 return root; 20000 } 20001 20002 function warnIfNotCurrentlyBatchingInDev(fiber) { 20003 { 20004 if (isRendering === false && isBatchingUpdates === false) { 20005 warningWithoutStack$1(false, 'An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see in the browser." + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber)); 20006 } 20007 } 20008 } 20009 20010 function scheduleWork(fiber, expirationTime) { 20011 var root = scheduleWorkToRoot(fiber, expirationTime); 20012 if (root === null) { 20013 { 20014 switch (fiber.tag) { 20015 case ClassComponent: 20016 warnAboutUpdateOnUnmounted(fiber, true); 20017 break; 20018 case FunctionComponent: 20019 case ForwardRef: 20020 case MemoComponent: 20021 case SimpleMemoComponent: 20022 warnAboutUpdateOnUnmounted(fiber, false); 20023 break; 20024 } 20025 } 20026 return; 20027 } 20028 20029 if (!isWorking && nextRenderExpirationTime !== NoWork && expirationTime > nextRenderExpirationTime) { 20030 // This is an interruption. (Used for performance tracking.) 20031 interruptedBy = fiber; 20032 resetStack(); 20033 } 20034 markPendingPriorityLevel(root, expirationTime); 20035 if ( 20036 // If we're in the render phase, we don't need to schedule this root 20037 // for an update, because we'll do it before we exit... 20038 !isWorking || isCommitting$1 || 20039 // ...unless this is a different root than the one we're rendering. 20040 nextRoot !== root) { 20041 var rootExpirationTime = root.expirationTime; 20042 requestWork(root, rootExpirationTime); 20043 } 20044 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) { 20045 // Reset this back to zero so subsequent updates don't throw. 20046 nestedUpdateCount = 0; 20047 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.'); 20048 } 20049 } 20050 20051 function syncUpdates(fn, a, b, c, d) { 20052 return unstable_runWithPriority(unstable_ImmediatePriority, function () { 20053 return fn(a, b, c, d); 20054 }); 20055 } 20056 20057 // TODO: Everything below this is written as if it has been lifted to the 20058 // renderers. I'll do this in a follow-up. 20059 20060 // Linked-list of roots 20061 var firstScheduledRoot = null; 20062 var lastScheduledRoot = null; 20063 20064 var callbackExpirationTime = NoWork; 20065 var callbackID = void 0; 20066 var isRendering = false; 20067 var nextFlushedRoot = null; 20068 var nextFlushedExpirationTime = NoWork; 20069 var lowestPriorityPendingInteractiveExpirationTime = NoWork; 20070 var hasUnhandledError = false; 20071 var unhandledError = null; 20072 20073 var isBatchingUpdates = false; 20074 var isUnbatchingUpdates = false; 20075 20076 var completedBatches = null; 20077 20078 var originalStartTimeMs = unstable_now(); 20079 var currentRendererTime = msToExpirationTime(originalStartTimeMs); 20080 var currentSchedulerTime = currentRendererTime; 20081 20082 // Use these to prevent an infinite loop of nested updates 20083 var NESTED_UPDATE_LIMIT = 50; 20084 var nestedUpdateCount = 0; 20085 var lastCommittedRootDuringThisBatch = null; 20086 20087 function recomputeCurrentRendererTime() { 20088 var currentTimeMs = unstable_now() - originalStartTimeMs; 20089 currentRendererTime = msToExpirationTime(currentTimeMs); 20090 } 20091 20092 function scheduleCallbackWithExpirationTime(root, expirationTime) { 20093 if (callbackExpirationTime !== NoWork) { 20094 // A callback is already scheduled. Check its expiration time (timeout). 20095 if (expirationTime < callbackExpirationTime) { 20096 // Existing callback has sufficient timeout. Exit. 20097 return; 20098 } else { 20099 if (callbackID !== null) { 20100 // Existing callback has insufficient timeout. Cancel and schedule a 20101 // new one. 20102 unstable_cancelCallback(callbackID); 20103 } 20104 } 20105 // The request callback timer is already running. Don't start a new one. 20106 } else { 20107 startRequestCallbackTimer(); 20108 } 20109 20110 callbackExpirationTime = expirationTime; 20111 var currentMs = unstable_now() - originalStartTimeMs; 20112 var expirationTimeMs = expirationTimeToMs(expirationTime); 20113 var timeout = expirationTimeMs - currentMs; 20114 callbackID = unstable_scheduleCallback(performAsyncWork, { timeout: timeout }); 20115 } 20116 20117 // For every call to renderRoot, one of onFatal, onComplete, onSuspend, and 20118 // onYield is called upon exiting. We use these in lieu of returning a tuple. 20119 // I've also chosen not to inline them into renderRoot because these will 20120 // eventually be lifted into the renderer. 20121 function onFatal(root) { 20122 root.finishedWork = null; 20123 } 20124 20125 function onComplete(root, finishedWork, expirationTime) { 20126 root.pendingCommitExpirationTime = expirationTime; 20127 root.finishedWork = finishedWork; 20128 } 20129 20130 function onSuspend(root, finishedWork, suspendedExpirationTime, rootExpirationTime, msUntilTimeout) { 20131 root.expirationTime = rootExpirationTime; 20132 if (msUntilTimeout === 0 && !shouldYieldToRenderer()) { 20133 // Don't wait an additional tick. Commit the tree immediately. 20134 root.pendingCommitExpirationTime = suspendedExpirationTime; 20135 root.finishedWork = finishedWork; 20136 } else if (msUntilTimeout > 0) { 20137 // Wait `msUntilTimeout` milliseconds before committing. 20138 root.timeoutHandle = scheduleTimeout(onTimeout.bind(null, root, finishedWork, suspendedExpirationTime), msUntilTimeout); 20139 } 20140 } 20141 20142 function onYield(root) { 20143 root.finishedWork = null; 20144 } 20145 20146 function onTimeout(root, finishedWork, suspendedExpirationTime) { 20147 // The root timed out. Commit it. 20148 root.pendingCommitExpirationTime = suspendedExpirationTime; 20149 root.finishedWork = finishedWork; 20150 // Read the current time before entering the commit phase. We can be 20151 // certain this won't cause tearing related to batching of event updates 20152 // because we're at the top of a timer event. 20153 recomputeCurrentRendererTime(); 20154 currentSchedulerTime = currentRendererTime; 20155 flushRoot(root, suspendedExpirationTime); 20156 } 20157 20158 function onCommit(root, expirationTime) { 20159 root.expirationTime = expirationTime; 20160 root.finishedWork = null; 20161 } 20162 20163 function requestCurrentTime() { 20164 // requestCurrentTime is called by the scheduler to compute an expiration 20165 // time. 20166 // 20167 // Expiration times are computed by adding to the current time (the start 20168 // time). However, if two updates are scheduled within the same event, we 20169 // should treat their start times as simultaneous, even if the actual clock 20170 // time has advanced between the first and second call. 20171 20172 // In other words, because expiration times determine how updates are batched, 20173 // we want all updates of like priority that occur within the same event to 20174 // receive the same expiration time. Otherwise we get tearing. 20175 // 20176 // We keep track of two separate times: the current "renderer" time and the 20177 // current "scheduler" time. The renderer time can be updated whenever; it 20178 // only exists to minimize the calls performance.now. 20179 // 20180 // But the scheduler time can only be updated if there's no pending work, or 20181 // if we know for certain that we're not in the middle of an event. 20182 20183 if (isRendering) { 20184 // We're already rendering. Return the most recently read time. 20185 return currentSchedulerTime; 20186 } 20187 // Check if there's pending work. 20188 findHighestPriorityRoot(); 20189 if (nextFlushedExpirationTime === NoWork || nextFlushedExpirationTime === Never) { 20190 // If there's no pending work, or if the pending work is offscreen, we can 20191 // read the current time without risk of tearing. 20192 recomputeCurrentRendererTime(); 20193 currentSchedulerTime = currentRendererTime; 20194 return currentSchedulerTime; 20195 } 20196 // There's already pending work. We might be in the middle of a browser 20197 // event. If we were to read the current time, it could cause multiple updates 20198 // within the same event to receive different expiration times, leading to 20199 // tearing. Return the last read time. During the next idle callback, the 20200 // time will be updated. 20201 return currentSchedulerTime; 20202 } 20203 20204 // requestWork is called by the scheduler whenever a root receives an update. 20205 // It's up to the renderer to call renderRoot at some point in the future. 20206 function requestWork(root, expirationTime) { 20207 addRootToSchedule(root, expirationTime); 20208 if (isRendering) { 20209 // Prevent reentrancy. Remaining work will be scheduled at the end of 20210 // the currently rendering batch. 20211 return; 20212 } 20213 20214 if (isBatchingUpdates) { 20215 // Flush work at the end of the batch. 20216 if (isUnbatchingUpdates) { 20217 // ...unless we're inside unbatchedUpdates, in which case we should 20218 // flush it now. 20219 nextFlushedRoot = root; 20220 nextFlushedExpirationTime = Sync; 20221 performWorkOnRoot(root, Sync, false); 20222 } 20223 return; 20224 } 20225 20226 // TODO: Get rid of Sync and use current time? 20227 if (expirationTime === Sync) { 20228 performSyncWork(); 20229 } else { 20230 scheduleCallbackWithExpirationTime(root, expirationTime); 20231 } 20232 } 20233 20234 function addRootToSchedule(root, expirationTime) { 20235 // Add the root to the schedule. 20236 // Check if this root is already part of the schedule. 20237 if (root.nextScheduledRoot === null) { 20238 // This root is not already scheduled. Add it. 20239 root.expirationTime = expirationTime; 20240 if (lastScheduledRoot === null) { 20241 firstScheduledRoot = lastScheduledRoot = root; 20242 root.nextScheduledRoot = root; 20243 } else { 20244 lastScheduledRoot.nextScheduledRoot = root; 20245 lastScheduledRoot = root; 20246 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot; 20247 } 20248 } else { 20249 // This root is already scheduled, but its priority may have increased. 20250 var remainingExpirationTime = root.expirationTime; 20251 if (expirationTime > remainingExpirationTime) { 20252 // Update the priority. 20253 root.expirationTime = expirationTime; 20254 } 20255 } 20256 } 20257 20258 function findHighestPriorityRoot() { 20259 var highestPriorityWork = NoWork; 20260 var highestPriorityRoot = null; 20261 if (lastScheduledRoot !== null) { 20262 var previousScheduledRoot = lastScheduledRoot; 20263 var root = firstScheduledRoot; 20264 while (root !== null) { 20265 var remainingExpirationTime = root.expirationTime; 20266 if (remainingExpirationTime === NoWork) { 20267 // This root no longer has work. Remove it from the scheduler. 20268 20269 // TODO: This check is redudant, but Flow is confused by the branch 20270 // below where we set lastScheduledRoot to null, even though we break 20271 // from the loop right after. 20272 !(previousScheduledRoot !== null && lastScheduledRoot !== null) ? invariant(false, 'Should have a previous and last root. This error is likely caused by a bug in React. Please file an issue.') : void 0; 20273 if (root === root.nextScheduledRoot) { 20274 // This is the only root in the list. 20275 root.nextScheduledRoot = null; 20276 firstScheduledRoot = lastScheduledRoot = null; 20277 break; 20278 } else if (root === firstScheduledRoot) { 20279 // This is the first root in the list. 20280 var next = root.nextScheduledRoot; 20281 firstScheduledRoot = next; 20282 lastScheduledRoot.nextScheduledRoot = next; 20283 root.nextScheduledRoot = null; 20284 } else if (root === lastScheduledRoot) { 20285 // This is the last root in the list. 20286 lastScheduledRoot = previousScheduledRoot; 20287 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot; 20288 root.nextScheduledRoot = null; 20289 break; 20290 } else { 20291 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot; 20292 root.nextScheduledRoot = null; 20293 } 20294 root = previousScheduledRoot.nextScheduledRoot; 20295 } else { 20296 if (remainingExpirationTime > highestPriorityWork) { 20297 // Update the priority, if it's higher 20298 highestPriorityWork = remainingExpirationTime; 20299 highestPriorityRoot = root; 20300 } 20301 if (root === lastScheduledRoot) { 20302 break; 20303 } 20304 if (highestPriorityWork === Sync) { 20305 // Sync is highest priority by definition so 20306 // we can stop searching. 20307 break; 20308 } 20309 previousScheduledRoot = root; 20310 root = root.nextScheduledRoot; 20311 } 20312 } 20313 } 20314 20315 nextFlushedRoot = highestPriorityRoot; 20316 nextFlushedExpirationTime = highestPriorityWork; 20317 } 20318 20319 // TODO: This wrapper exists because many of the older tests (the ones that use 20320 // flushDeferredPri) rely on the number of times `shouldYield` is called. We 20321 // should get rid of it. 20322 var didYield = false; 20323 function shouldYieldToRenderer() { 20324 if (didYield) { 20325 return true; 20326 } 20327 if (unstable_shouldYield()) { 20328 didYield = true; 20329 return true; 20330 } 20331 return false; 20332 } 20333 20334 function performAsyncWork() { 20335 try { 20336 if (!shouldYieldToRenderer()) { 20337 // The callback timed out. That means at least one update has expired. 20338 // Iterate through the root schedule. If they contain expired work, set 20339 // the next render expiration time to the current time. This has the effect 20340 // of flushing all expired work in a single batch, instead of flushing each 20341 // level one at a time. 20342 if (firstScheduledRoot !== null) { 20343 recomputeCurrentRendererTime(); 20344 var root = firstScheduledRoot; 20345 do { 20346 didExpireAtExpirationTime(root, currentRendererTime); 20347 // The root schedule is circular, so this is never null. 20348 root = root.nextScheduledRoot; 20349 } while (root !== firstScheduledRoot); 20350 } 20351 } 20352 performWork(NoWork, true); 20353 } finally { 20354 didYield = false; 20355 } 20356 } 20357 20358 function performSyncWork() { 20359 performWork(Sync, false); 20360 } 20361 20362 function performWork(minExpirationTime, isYieldy) { 20363 // Keep working on roots until there's no more work, or until there's a higher 20364 // priority event. 20365 findHighestPriorityRoot(); 20366 20367 if (isYieldy) { 20368 recomputeCurrentRendererTime(); 20369 currentSchedulerTime = currentRendererTime; 20370 20371 if (enableUserTimingAPI) { 20372 var didExpire = nextFlushedExpirationTime > currentRendererTime; 20373 var timeout = expirationTimeToMs(nextFlushedExpirationTime); 20374 stopRequestCallbackTimer(didExpire, timeout); 20375 } 20376 20377 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime && !(didYield && currentRendererTime > nextFlushedExpirationTime)) { 20378 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, currentRendererTime > nextFlushedExpirationTime); 20379 findHighestPriorityRoot(); 20380 recomputeCurrentRendererTime(); 20381 currentSchedulerTime = currentRendererTime; 20382 } 20383 } else { 20384 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime) { 20385 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, false); 20386 findHighestPriorityRoot(); 20387 } 20388 } 20389 20390 // We're done flushing work. Either we ran out of time in this callback, 20391 // or there's no more work left with sufficient priority. 20392 20393 // If we're inside a callback, set this to false since we just completed it. 20394 if (isYieldy) { 20395 callbackExpirationTime = NoWork; 20396 callbackID = null; 20397 } 20398 // If there's work left over, schedule a new callback. 20399 if (nextFlushedExpirationTime !== NoWork) { 20400 scheduleCallbackWithExpirationTime(nextFlushedRoot, nextFlushedExpirationTime); 20401 } 20402 20403 // Clean-up. 20404 finishRendering(); 20405 } 20406 20407 function flushRoot(root, expirationTime) { 20408 !!isRendering ? invariant(false, 'work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method.') : void 0; 20409 // Perform work on root as if the given expiration time is the current time. 20410 // This has the effect of synchronously flushing all work up to and 20411 // including the given time. 20412 nextFlushedRoot = root; 20413 nextFlushedExpirationTime = expirationTime; 20414 performWorkOnRoot(root, expirationTime, false); 20415 // Flush any sync work that was scheduled by lifecycles 20416 performSyncWork(); 20417 } 20418 20419 function finishRendering() { 20420 nestedUpdateCount = 0; 20421 lastCommittedRootDuringThisBatch = null; 20422 20423 if (completedBatches !== null) { 20424 var batches = completedBatches; 20425 completedBatches = null; 20426 for (var i = 0; i < batches.length; i++) { 20427 var batch = batches[i]; 20428 try { 20429 batch._onComplete(); 20430 } catch (error) { 20431 if (!hasUnhandledError) { 20432 hasUnhandledError = true; 20433 unhandledError = error; 20434 } 20435 } 20436 } 20437 } 20438 20439 if (hasUnhandledError) { 20440 var error = unhandledError; 20441 unhandledError = null; 20442 hasUnhandledError = false; 20443 throw error; 20444 } 20445 } 20446 20447 function performWorkOnRoot(root, expirationTime, isYieldy) { 20448 !!isRendering ? invariant(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0; 20449 20450 isRendering = true; 20451 20452 // Check if this is async work or sync/expired work. 20453 if (!isYieldy) { 20454 // Flush work without yielding. 20455 // TODO: Non-yieldy work does not necessarily imply expired work. A renderer 20456 // may want to perform some work without yielding, but also without 20457 // requiring the root to complete (by triggering placeholders). 20458 20459 var finishedWork = root.finishedWork; 20460 if (finishedWork !== null) { 20461 // This root is already complete. We can commit it. 20462 completeRoot(root, finishedWork, expirationTime); 20463 } else { 20464 root.finishedWork = null; 20465 // If this root previously suspended, clear its existing timeout, since 20466 // we're about to try rendering again. 20467 var timeoutHandle = root.timeoutHandle; 20468 if (timeoutHandle !== noTimeout) { 20469 root.timeoutHandle = noTimeout; 20470 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above 20471 cancelTimeout(timeoutHandle); 20472 } 20473 renderRoot(root, isYieldy); 20474 finishedWork = root.finishedWork; 20475 if (finishedWork !== null) { 20476 // We've completed the root. Commit it. 20477 completeRoot(root, finishedWork, expirationTime); 20478 } 20479 } 20480 } else { 20481 // Flush async work. 20482 var _finishedWork = root.finishedWork; 20483 if (_finishedWork !== null) { 20484 // This root is already complete. We can commit it. 20485 completeRoot(root, _finishedWork, expirationTime); 20486 } else { 20487 root.finishedWork = null; 20488 // If this root previously suspended, clear its existing timeout, since 20489 // we're about to try rendering again. 20490 var _timeoutHandle = root.timeoutHandle; 20491 if (_timeoutHandle !== noTimeout) { 20492 root.timeoutHandle = noTimeout; 20493 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above 20494 cancelTimeout(_timeoutHandle); 20495 } 20496 renderRoot(root, isYieldy); 20497 _finishedWork = root.finishedWork; 20498 if (_finishedWork !== null) { 20499 // We've completed the root. Check the if we should yield one more time 20500 // before committing. 20501 if (!shouldYieldToRenderer()) { 20502 // Still time left. Commit the root. 20503 completeRoot(root, _finishedWork, expirationTime); 20504 } else { 20505 // There's no time left. Mark this root as complete. We'll come 20506 // back and commit it later. 20507 root.finishedWork = _finishedWork; 20508 } 20509 } 20510 } 20511 } 20512 20513 isRendering = false; 20514 } 20515 20516 function completeRoot(root, finishedWork, expirationTime) { 20517 // Check if there's a batch that matches this expiration time. 20518 var firstBatch = root.firstBatch; 20519 if (firstBatch !== null && firstBatch._expirationTime >= expirationTime) { 20520 if (completedBatches === null) { 20521 completedBatches = [firstBatch]; 20522 } else { 20523 completedBatches.push(firstBatch); 20524 } 20525 if (firstBatch._defer) { 20526 // This root is blocked from committing by a batch. Unschedule it until 20527 // we receive another update. 20528 root.finishedWork = finishedWork; 20529 root.expirationTime = NoWork; 20530 return; 20531 } 20532 } 20533 20534 // Commit the root. 20535 root.finishedWork = null; 20536 20537 // Check if this is a nested update (a sync update scheduled during the 20538 // commit phase). 20539 if (root === lastCommittedRootDuringThisBatch) { 20540 // If the next root is the same as the previous root, this is a nested 20541 // update. To prevent an infinite loop, increment the nested update count. 20542 nestedUpdateCount++; 20543 } else { 20544 // Reset whenever we switch roots. 20545 lastCommittedRootDuringThisBatch = root; 20546 nestedUpdateCount = 0; 20547 } 20548 unstable_runWithPriority(unstable_ImmediatePriority, function () { 20549 commitRoot(root, finishedWork); 20550 }); 20551 } 20552 20553 function onUncaughtError(error) { 20554 !(nextFlushedRoot !== null) ? invariant(false, 'Should be working on a root. This error is likely caused by a bug in React. Please file an issue.') : void 0; 20555 // Unschedule this root so we don't work on it again until there's 20556 // another update. 20557 nextFlushedRoot.expirationTime = NoWork; 20558 if (!hasUnhandledError) { 20559 hasUnhandledError = true; 20560 unhandledError = error; 20561 } 20562 } 20563 20564 // TODO: Batching should be implemented at the renderer level, not inside 20565 // the reconciler. 20566 function batchedUpdates$1(fn, a) { 20567 var previousIsBatchingUpdates = isBatchingUpdates; 20568 isBatchingUpdates = true; 20569 try { 20570 return fn(a); 20571 } finally { 20572 isBatchingUpdates = previousIsBatchingUpdates; 20573 if (!isBatchingUpdates && !isRendering) { 20574 performSyncWork(); 20575 } 20576 } 20577 } 20578 20579 // TODO: Batching should be implemented at the renderer level, not inside 20580 // the reconciler. 20581 function unbatchedUpdates(fn, a) { 20582 if (isBatchingUpdates && !isUnbatchingUpdates) { 20583 isUnbatchingUpdates = true; 20584 try { 20585 return fn(a); 20586 } finally { 20587 isUnbatchingUpdates = false; 20588 } 20589 } 20590 return fn(a); 20591 } 20592 20593 // TODO: Batching should be implemented at the renderer level, not within 20594 // the reconciler. 20595 function flushSync(fn, a) { 20596 !!isRendering ? invariant(false, 'flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.') : void 0; 20597 var previousIsBatchingUpdates = isBatchingUpdates; 20598 isBatchingUpdates = true; 20599 try { 20600 return syncUpdates(fn, a); 20601 } finally { 20602 isBatchingUpdates = previousIsBatchingUpdates; 20603 performSyncWork(); 20604 } 20605 } 20606 20607 function interactiveUpdates$1(fn, a, b) { 20608 // If there are any pending interactive updates, synchronously flush them. 20609 // This needs to happen before we read any handlers, because the effect of 20610 // the previous event may influence which handlers are called during 20611 // this event. 20612 if (!isBatchingUpdates && !isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) { 20613 // Synchronously flush pending interactive updates. 20614 performWork(lowestPriorityPendingInteractiveExpirationTime, false); 20615 lowestPriorityPendingInteractiveExpirationTime = NoWork; 20616 } 20617 var previousIsBatchingUpdates = isBatchingUpdates; 20618 isBatchingUpdates = true; 20619 try { 20620 return unstable_runWithPriority(unstable_UserBlockingPriority, function () { 20621 return fn(a, b); 20622 }); 20623 } finally { 20624 isBatchingUpdates = previousIsBatchingUpdates; 20625 if (!isBatchingUpdates && !isRendering) { 20626 performSyncWork(); 20627 } 20628 } 20629 } 20630 20631 function flushInteractiveUpdates$1() { 20632 if (!isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) { 20633 // Synchronously flush pending interactive updates. 20634 performWork(lowestPriorityPendingInteractiveExpirationTime, false); 20635 lowestPriorityPendingInteractiveExpirationTime = NoWork; 20636 } 20637 } 20638 20639 function flushControlled(fn) { 20640 var previousIsBatchingUpdates = isBatchingUpdates; 20641 isBatchingUpdates = true; 20642 try { 20643 syncUpdates(fn); 20644 } finally { 20645 isBatchingUpdates = previousIsBatchingUpdates; 20646 if (!isBatchingUpdates && !isRendering) { 20647 performSyncWork(); 20648 } 20649 } 20650 } 20651 20652 // 0 is PROD, 1 is DEV. 20653 // Might add PROFILE later. 20654 20655 20656 var didWarnAboutNestedUpdates = void 0; 20657 var didWarnAboutFindNodeInStrictMode = void 0; 20658 20659 { 20660 didWarnAboutNestedUpdates = false; 20661 didWarnAboutFindNodeInStrictMode = {}; 20662 } 20663 20664 function getContextForSubtree(parentComponent) { 20665 if (!parentComponent) { 20666 return emptyContextObject; 20667 } 20668 20669 var fiber = get(parentComponent); 20670 var parentContext = findCurrentUnmaskedContext(fiber); 20671 20672 if (fiber.tag === ClassComponent) { 20673 var Component = fiber.type; 20674 if (isContextProvider(Component)) { 20675 return processChildContext(fiber, Component, parentContext); 20676 } 20677 } 20678 20679 return parentContext; 20680 } 20681 20682 function scheduleRootUpdate(current$$1, element, expirationTime, callback) { 20683 { 20684 if (phase === 'render' && current !== null && !didWarnAboutNestedUpdates) { 20685 didWarnAboutNestedUpdates = true; 20686 warningWithoutStack$1(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(current.type) || 'Unknown'); 20687 } 20688 } 20689 20690 var update = createUpdate(expirationTime); 20691 // Caution: React DevTools currently depends on this property 20692 // being called "element". 20693 update.payload = { element: element }; 20694 20695 callback = callback === undefined ? null : callback; 20696 if (callback !== null) { 20697 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0; 20698 update.callback = callback; 20699 } 20700 20701 flushPassiveEffects(); 20702 enqueueUpdate(current$$1, update); 20703 scheduleWork(current$$1, expirationTime); 20704 20705 return expirationTime; 20706 } 20707 20708 function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) { 20709 // TODO: If this is a nested container, this won't be the root. 20710 var current$$1 = container.current; 20711 20712 { 20713 if (ReactFiberInstrumentation_1.debugTool) { 20714 if (current$$1.alternate === null) { 20715 ReactFiberInstrumentation_1.debugTool.onMountContainer(container); 20716 } else if (element === null) { 20717 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container); 20718 } else { 20719 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container); 20720 } 20721 } 20722 } 20723 20724 var context = getContextForSubtree(parentComponent); 20725 if (container.context === null) { 20726 container.context = context; 20727 } else { 20728 container.pendingContext = context; 20729 } 20730 20731 return scheduleRootUpdate(current$$1, element, expirationTime, callback); 20732 } 20733 20734 function findHostInstance(component) { 20735 var fiber = get(component); 20736 if (fiber === undefined) { 20737 if (typeof component.render === 'function') { 20738 invariant(false, 'Unable to find node on an unmounted component.'); 20739 } else { 20740 invariant(false, 'Argument appears to not be a ReactComponent. Keys: %s', Object.keys(component)); 20741 } 20742 } 20743 var hostFiber = findCurrentHostFiber(fiber); 20744 if (hostFiber === null) { 20745 return null; 20746 } 20747 return hostFiber.stateNode; 20748 } 20749 20750 function findHostInstanceWithWarning(component, methodName) { 20751 { 20752 var fiber = get(component); 20753 if (fiber === undefined) { 20754 if (typeof component.render === 'function') { 20755 invariant(false, 'Unable to find node on an unmounted component.'); 20756 } else { 20757 invariant(false, 'Argument appears to not be a ReactComponent. Keys: %s', Object.keys(component)); 20758 } 20759 } 20760 var hostFiber = findCurrentHostFiber(fiber); 20761 if (hostFiber === null) { 20762 return null; 20763 } 20764 if (hostFiber.mode & StrictMode) { 20765 var componentName = getComponentName(fiber.type) || 'Component'; 20766 if (!didWarnAboutFindNodeInStrictMode[componentName]) { 20767 didWarnAboutFindNodeInStrictMode[componentName] = true; 20768 if (fiber.mode & StrictMode) { 20769 warningWithoutStack$1(false, '%s is deprecated in StrictMode. ' + '%s was passed an instance of %s which is inside StrictMode. ' + 'Instead, add a ref directly to the element you want to reference.' + '\n%s' + '\n\nLearn more about using refs safely here:' + '\nhttps://fb.me/react-strict-mode-find-node', methodName, methodName, componentName, getStackByFiberInDevAndProd(hostFiber)); 20770 } else { 20771 warningWithoutStack$1(false, '%s is deprecated in StrictMode. ' + '%s was passed an instance of %s which renders StrictMode children. ' + 'Instead, add a ref directly to the element you want to reference.' + '\n%s' + '\n\nLearn more about using refs safely here:' + '\nhttps://fb.me/react-strict-mode-find-node', methodName, methodName, componentName, getStackByFiberInDevAndProd(hostFiber)); 20772 } 20773 } 20774 } 20775 return hostFiber.stateNode; 20776 } 20777 return findHostInstance(component); 20778 } 20779 20780 function createContainer(containerInfo, isConcurrent, hydrate) { 20781 return createFiberRoot(containerInfo, isConcurrent, hydrate); 20782 } 20783 20784 function updateContainer(element, container, parentComponent, callback) { 20785 var current$$1 = container.current; 20786 var currentTime = requestCurrentTime(); 20787 var expirationTime = computeExpirationForFiber(currentTime, current$$1); 20788 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback); 20789 } 20790 20791 function getPublicRootInstance(container) { 20792 var containerFiber = container.current; 20793 if (!containerFiber.child) { 20794 return null; 20795 } 20796 switch (containerFiber.child.tag) { 20797 case HostComponent: 20798 return getPublicInstance(containerFiber.child.stateNode); 20799 default: 20800 return containerFiber.child.stateNode; 20801 } 20802 } 20803 20804 function findHostInstanceWithNoPortals(fiber) { 20805 var hostFiber = findCurrentHostFiberWithNoPortals(fiber); 20806 if (hostFiber === null) { 20807 return null; 20808 } 20809 return hostFiber.stateNode; 20810 } 20811 20812 var overrideProps = null; 20813 20814 { 20815 var copyWithSetImpl = function (obj, path, idx, value) { 20816 if (idx >= path.length) { 20817 return value; 20818 } 20819 var key = path[idx]; 20820 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); 20821 // $FlowFixMe number or string is fine here 20822 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value); 20823 return updated; 20824 }; 20825 20826 var copyWithSet = function (obj, path, value) { 20827 return copyWithSetImpl(obj, path, 0, value); 20828 }; 20829 20830 // Support DevTools props for function components, forwardRef, memo, host components, etc. 20831 overrideProps = function (fiber, path, value) { 20832 flushPassiveEffects(); 20833 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); 20834 if (fiber.alternate) { 20835 fiber.alternate.pendingProps = fiber.pendingProps; 20836 } 20837 scheduleWork(fiber, Sync); 20838 }; 20839 } 20840 20841 function injectIntoDevTools(devToolsConfig) { 20842 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; 20843 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; 20844 20845 20846 return injectInternals(_assign({}, devToolsConfig, { 20847 overrideProps: overrideProps, 20848 currentDispatcherRef: ReactCurrentDispatcher, 20849 findHostInstanceByFiber: function (fiber) { 20850 var hostFiber = findCurrentHostFiber(fiber); 20851 if (hostFiber === null) { 20852 return null; 20853 } 20854 return hostFiber.stateNode; 20855 }, 20856 findFiberByHostInstance: function (instance) { 20857 if (!findFiberByHostInstance) { 20858 // Might not be implemented by the renderer. 20859 return null; 20860 } 20861 return findFiberByHostInstance(instance); 20862 } 20863 })); 20864 } 20865 20866 // This file intentionally does *not* have the Flow annotation. 20867 // Don't add it. See `./inline-typed.js` for an explanation. 20868 20869 function createPortal$1(children, containerInfo, 20870 // TODO: figure out the API for cross-renderer implementation. 20871 implementation) { 20872 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; 20873 20874 return { 20875 // This tag allow us to uniquely identify this as a React Portal 20876 $$typeof: REACT_PORTAL_TYPE, 20877 key: key == null ? null : '' + key, 20878 children: children, 20879 containerInfo: containerInfo, 20880 implementation: implementation 20881 }; 20882 } 20883 20884 // TODO: this is special because it gets imported during build. 20885 20886 var ReactVersion = '16.8.6'; 20887 20888 // TODO: This type is shared between the reconciler and ReactDOM, but will 20889 // eventually be lifted out to the renderer. 20890 20891 var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; 20892 20893 var topLevelUpdateWarnings = void 0; 20894 var warnOnInvalidCallback = void 0; 20895 var didWarnAboutUnstableCreatePortal = false; 20896 20897 { 20898 if (typeof Map !== 'function' || 20899 // $FlowIssue Flow incorrectly thinks Map has no prototype 20900 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || 20901 // $FlowIssue Flow incorrectly thinks Set has no prototype 20902 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') { 20903 warningWithoutStack$1(false, 'React depends on Map and Set built-in types. Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills'); 20904 } 20905 20906 topLevelUpdateWarnings = function (container) { 20907 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) { 20908 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current); 20909 if (hostInstance) { 20910 !(hostInstance.parentNode === container) ? warningWithoutStack$1(false, '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.') : void 0; 20911 } 20912 } 20913 20914 var isRootRenderedBySomeReact = !!container._reactRootContainer; 20915 var rootEl = getReactRootElementInContainer(container); 20916 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl)); 20917 20918 !(!hasNonRootReactChild || isRootRenderedBySomeReact) ? warningWithoutStack$1(false, '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.') : void 0; 20919 20920 !(container.nodeType !== ELEMENT_NODE || !container.tagName || container.tagName.toUpperCase() !== 'BODY') ? warningWithoutStack$1(false, '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.') : void 0; 20921 }; 20922 20923 warnOnInvalidCallback = function (callback, callerName) { 20924 !(callback === null || typeof callback === 'function') ? warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback) : void 0; 20925 }; 20926 } 20927 20928 setRestoreImplementation(restoreControlledState$1); 20929 20930 function ReactBatch(root) { 20931 var expirationTime = computeUniqueAsyncExpiration(); 20932 this._expirationTime = expirationTime; 20933 this._root = root; 20934 this._next = null; 20935 this._callbacks = null; 20936 this._didComplete = false; 20937 this._hasChildren = false; 20938 this._children = null; 20939 this._defer = true; 20940 } 20941 ReactBatch.prototype.render = function (children) { 20942 !this._defer ? invariant(false, 'batch.render: Cannot render a batch that already committed.') : void 0; 20943 this._hasChildren = true; 20944 this._children = children; 20945 var internalRoot = this._root._internalRoot; 20946 var expirationTime = this._expirationTime; 20947 var work = new ReactWork(); 20948 updateContainerAtExpirationTime(children, internalRoot, null, expirationTime, work._onCommit); 20949 return work; 20950 }; 20951 ReactBatch.prototype.then = function (onComplete) { 20952 if (this._didComplete) { 20953 onComplete(); 20954 return; 20955 } 20956 var callbacks = this._callbacks; 20957 if (callbacks === null) { 20958 callbacks = this._callbacks = []; 20959 } 20960 callbacks.push(onComplete); 20961 }; 20962 ReactBatch.prototype.commit = function () { 20963 var internalRoot = this._root._internalRoot; 20964 var firstBatch = internalRoot.firstBatch; 20965 !(this._defer && firstBatch !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0; 20966 20967 if (!this._hasChildren) { 20968 // This batch is empty. Return. 20969 this._next = null; 20970 this._defer = false; 20971 return; 20972 } 20973 20974 var expirationTime = this._expirationTime; 20975 20976 // Ensure this is the first batch in the list. 20977 if (firstBatch !== this) { 20978 // This batch is not the earliest batch. We need to move it to the front. 20979 // Update its expiration time to be the expiration time of the earliest 20980 // batch, so that we can flush it without flushing the other batches. 20981 if (this._hasChildren) { 20982 expirationTime = this._expirationTime = firstBatch._expirationTime; 20983 // Rendering this batch again ensures its children will be the final state 20984 // when we flush (updates are processed in insertion order: last 20985 // update wins). 20986 // TODO: This forces a restart. Should we print a warning? 20987 this.render(this._children); 20988 } 20989 20990 // Remove the batch from the list. 20991 var previous = null; 20992 var batch = firstBatch; 20993 while (batch !== this) { 20994 previous = batch; 20995 batch = batch._next; 20996 } 20997 !(previous !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0; 20998 previous._next = batch._next; 20999 21000 // Add it to the front. 21001 this._next = firstBatch; 21002 firstBatch = internalRoot.firstBatch = this; 21003 } 21004 21005 // Synchronously flush all the work up to this batch's expiration time. 21006 this._defer = false; 21007 flushRoot(internalRoot, expirationTime); 21008 21009 // Pop the batch from the list. 21010 var next = this._next; 21011 this._next = null; 21012 firstBatch = internalRoot.firstBatch = next; 21013 21014 // Append the next earliest batch's children to the update queue. 21015 if (firstBatch !== null && firstBatch._hasChildren) { 21016 firstBatch.render(firstBatch._children); 21017 } 21018 }; 21019 ReactBatch.prototype._onComplete = function () { 21020 if (this._didComplete) { 21021 return; 21022 } 21023 this._didComplete = true; 21024 var callbacks = this._callbacks; 21025 if (callbacks === null) { 21026 return; 21027 } 21028 // TODO: Error handling. 21029 for (var i = 0; i < callbacks.length; i++) { 21030 var _callback = callbacks[i]; 21031 _callback(); 21032 } 21033 }; 21034 21035 function ReactWork() { 21036 this._callbacks = null; 21037 this._didCommit = false; 21038 // TODO: Avoid need to bind by replacing callbacks in the update queue with 21039 // list of Work objects. 21040 this._onCommit = this._onCommit.bind(this); 21041 } 21042 ReactWork.prototype.then = function (onCommit) { 21043 if (this._didCommit) { 21044 onCommit(); 21045 return; 21046 } 21047 var callbacks = this._callbacks; 21048 if (callbacks === null) { 21049 callbacks = this._callbacks = []; 21050 } 21051 callbacks.push(onCommit); 21052 }; 21053 ReactWork.prototype._onCommit = function () { 21054 if (this._didCommit) { 21055 return; 21056 } 21057 this._didCommit = true; 21058 var callbacks = this._callbacks; 21059 if (callbacks === null) { 21060 return; 21061 } 21062 // TODO: Error handling. 21063 for (var i = 0; i < callbacks.length; i++) { 21064 var _callback2 = callbacks[i]; 21065 !(typeof _callback2 === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback2) : void 0; 21066 _callback2(); 21067 } 21068 }; 21069 21070 function ReactRoot(container, isConcurrent, hydrate) { 21071 var root = createContainer(container, isConcurrent, hydrate); 21072 this._internalRoot = root; 21073 } 21074 ReactRoot.prototype.render = function (children, callback) { 21075 var root = this._internalRoot; 21076 var work = new ReactWork(); 21077 callback = callback === undefined ? null : callback; 21078 { 21079 warnOnInvalidCallback(callback, 'render'); 21080 } 21081 if (callback !== null) { 21082 work.then(callback); 21083 } 21084 updateContainer(children, root, null, work._onCommit); 21085 return work; 21086 }; 21087 ReactRoot.prototype.unmount = function (callback) { 21088 var root = this._internalRoot; 21089 var work = new ReactWork(); 21090 callback = callback === undefined ? null : callback; 21091 { 21092 warnOnInvalidCallback(callback, 'render'); 21093 } 21094 if (callback !== null) { 21095 work.then(callback); 21096 } 21097 updateContainer(null, root, null, work._onCommit); 21098 return work; 21099 }; 21100 ReactRoot.prototype.legacy_renderSubtreeIntoContainer = function (parentComponent, children, callback) { 21101 var root = this._internalRoot; 21102 var work = new ReactWork(); 21103 callback = callback === undefined ? null : callback; 21104 { 21105 warnOnInvalidCallback(callback, 'render'); 21106 } 21107 if (callback !== null) { 21108 work.then(callback); 21109 } 21110 updateContainer(children, root, parentComponent, work._onCommit); 21111 return work; 21112 }; 21113 ReactRoot.prototype.createBatch = function () { 21114 var batch = new ReactBatch(this); 21115 var expirationTime = batch._expirationTime; 21116 21117 var internalRoot = this._internalRoot; 21118 var firstBatch = internalRoot.firstBatch; 21119 if (firstBatch === null) { 21120 internalRoot.firstBatch = batch; 21121 batch._next = null; 21122 } else { 21123 // Insert sorted by expiration time then insertion order 21124 var insertAfter = null; 21125 var insertBefore = firstBatch; 21126 while (insertBefore !== null && insertBefore._expirationTime >= expirationTime) { 21127 insertAfter = insertBefore; 21128 insertBefore = insertBefore._next; 21129 } 21130 batch._next = insertBefore; 21131 if (insertAfter !== null) { 21132 insertAfter._next = batch; 21133 } 21134 } 21135 21136 return batch; 21137 }; 21138 21139 /** 21140 * True if the supplied DOM node is a valid node element. 21141 * 21142 * @param {?DOMElement} node The candidate DOM node. 21143 * @return {boolean} True if the DOM is a valid DOM node. 21144 * @internal 21145 */ 21146 function isValidContainer(node) { 21147 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 ')); 21148 } 21149 21150 function getReactRootElementInContainer(container) { 21151 if (!container) { 21152 return null; 21153 } 21154 21155 if (container.nodeType === DOCUMENT_NODE) { 21156 return container.documentElement; 21157 } else { 21158 return container.firstChild; 21159 } 21160 } 21161 21162 function shouldHydrateDueToLegacyHeuristic(container) { 21163 var rootElement = getReactRootElementInContainer(container); 21164 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME)); 21165 } 21166 21167 setBatchingImplementation(batchedUpdates$1, interactiveUpdates$1, flushInteractiveUpdates$1); 21168 21169 var warnedAboutHydrateAPI = false; 21170 21171 function legacyCreateRootFromDOMContainer(container, forceHydrate) { 21172 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container); 21173 // First clear any existing content. 21174 if (!shouldHydrate) { 21175 var warned = false; 21176 var rootSibling = void 0; 21177 while (rootSibling = container.lastChild) { 21178 { 21179 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) { 21180 warned = true; 21181 warningWithoutStack$1(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.'); 21182 } 21183 } 21184 container.removeChild(rootSibling); 21185 } 21186 } 21187 { 21188 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) { 21189 warnedAboutHydrateAPI = true; 21190 lowPriorityWarning$1(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.'); 21191 } 21192 } 21193 // Legacy roots are not async by default. 21194 var isConcurrent = false; 21195 return new ReactRoot(container, isConcurrent, shouldHydrate); 21196 } 21197 21198 function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) { 21199 { 21200 topLevelUpdateWarnings(container); 21201 } 21202 21203 // TODO: Without `any` type, Flow says "Property cannot be accessed on any 21204 // member of intersection type." Whyyyyyy. 21205 var root = container._reactRootContainer; 21206 if (!root) { 21207 // Initial mount 21208 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate); 21209 if (typeof callback === 'function') { 21210 var originalCallback = callback; 21211 callback = function () { 21212 var instance = getPublicRootInstance(root._internalRoot); 21213 originalCallback.call(instance); 21214 }; 21215 } 21216 // Initial mount should not be batched. 21217 unbatchedUpdates(function () { 21218 if (parentComponent != null) { 21219 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback); 21220 } else { 21221 root.render(children, callback); 21222 } 21223 }); 21224 } else { 21225 if (typeof callback === 'function') { 21226 var _originalCallback = callback; 21227 callback = function () { 21228 var instance = getPublicRootInstance(root._internalRoot); 21229 _originalCallback.call(instance); 21230 }; 21231 } 21232 // Update 21233 if (parentComponent != null) { 21234 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback); 21235 } else { 21236 root.render(children, callback); 21237 } 21238 } 21239 return getPublicRootInstance(root._internalRoot); 21240 } 21241 21242 function createPortal$$1(children, container) { 21243 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; 21244 21245 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0; 21246 // TODO: pass ReactDOM portal implementation as third argument 21247 return createPortal$1(children, container, null, key); 21248 } 21249 21250 var ReactDOM = { 21251 createPortal: createPortal$$1, 21252 21253 findDOMNode: function (componentOrElement) { 21254 { 21255 var owner = ReactCurrentOwner.current; 21256 if (owner !== null && owner.stateNode !== null) { 21257 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender; 21258 !warnedAboutRefsInRender ? warningWithoutStack$1(false, '%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(owner.type) || 'A component') : void 0; 21259 owner.stateNode._warnedAboutRefsInRender = true; 21260 } 21261 } 21262 if (componentOrElement == null) { 21263 return null; 21264 } 21265 if (componentOrElement.nodeType === ELEMENT_NODE) { 21266 return componentOrElement; 21267 } 21268 { 21269 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode'); 21270 } 21271 return findHostInstance(componentOrElement); 21272 }, 21273 hydrate: function (element, container, callback) { 21274 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0; 21275 { 21276 !!container._reactHasBeenPassedToCreateRootDEV ? warningWithoutStack$1(false, 'You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOM.%s(). This is not supported. ' + 'Did you mean to call createRoot(container, {hydrate: true}).render(element)?', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0; 21277 } 21278 // TODO: throw or warn if we couldn't hydrate? 21279 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback); 21280 }, 21281 render: function (element, container, callback) { 21282 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0; 21283 { 21284 !!container._reactHasBeenPassedToCreateRootDEV ? warningWithoutStack$1(false, 'You are calling ReactDOM.render() on a container that was previously ' + 'passed to ReactDOM.%s(). This is not supported. ' + 'Did you mean to call root.render(element)?', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0; 21285 } 21286 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback); 21287 }, 21288 unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) { 21289 !isValidContainer(containerNode) ? invariant(false, 'Target container is not a DOM element.') : void 0; 21290 !(parentComponent != null && has(parentComponent)) ? invariant(false, 'parentComponent must be a valid React Component') : void 0; 21291 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback); 21292 }, 21293 unmountComponentAtNode: function (container) { 21294 !isValidContainer(container) ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : void 0; 21295 21296 { 21297 !!container._reactHasBeenPassedToCreateRootDEV ? warningWithoutStack$1(false, 'You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' + 'passed to ReactDOM.%s(). This is not supported. Did you mean to call root.unmount()?', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0; 21298 } 21299 21300 if (container._reactRootContainer) { 21301 { 21302 var rootEl = getReactRootElementInContainer(container); 21303 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl); 21304 !!renderedByDifferentReact ? warningWithoutStack$1(false, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.') : void 0; 21305 } 21306 21307 // Unmount should not be batched. 21308 unbatchedUpdates(function () { 21309 legacyRenderSubtreeIntoContainer(null, null, container, false, function () { 21310 container._reactRootContainer = null; 21311 }); 21312 }); 21313 // If you call unmountComponentAtNode twice in quick succession, you'll 21314 // get `true` twice. That's probably fine? 21315 return true; 21316 } else { 21317 { 21318 var _rootEl = getReactRootElementInContainer(container); 21319 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl)); 21320 21321 // Check if the container itself is a React root node. 21322 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer; 21323 21324 !!hasNonRootReactChild ? warningWithoutStack$1(false, "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.') : void 0; 21325 } 21326 21327 return false; 21328 } 21329 }, 21330 21331 21332 // Temporary alias since we already shipped React 16 RC with it. 21333 // TODO: remove in React 17. 21334 unstable_createPortal: function () { 21335 if (!didWarnAboutUnstableCreatePortal) { 21336 didWarnAboutUnstableCreatePortal = true; 21337 lowPriorityWarning$1(false, 'The ReactDOM.unstable_createPortal() alias has been deprecated, ' + 'and will be removed in React 17+. Update your code to use ' + 'ReactDOM.createPortal() instead. It has the exact same API, ' + 'but without the "unstable_" prefix.'); 21338 } 21339 return createPortal$$1.apply(undefined, arguments); 21340 }, 21341 21342 21343 unstable_batchedUpdates: batchedUpdates$1, 21344 21345 unstable_interactiveUpdates: interactiveUpdates$1, 21346 21347 flushSync: flushSync, 21348 21349 unstable_createRoot: createRoot, 21350 unstable_flushControlled: flushControlled, 21351 21352 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { 21353 // Keep in sync with ReactDOMUnstableNativeDependencies.js 21354 // and ReactTestUtils.js. This is an array for better minification. 21355 Events: [getInstanceFromNode$1, getNodeFromInstance$1, getFiberCurrentPropsFromNode$1, injection.injectEventPluginsByName, eventNameDispatchConfigs, accumulateTwoPhaseDispatches, accumulateDirectDispatches, enqueueStateRestore, restoreStateIfNeeded, dispatchEvent, runEventsInBatch] 21356 } 21357 }; 21358 21359 function createRoot(container, options) { 21360 var functionName = enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot'; 21361 !isValidContainer(container) ? invariant(false, '%s(...): Target container is not a DOM element.', functionName) : void 0; 21362 { 21363 !!container._reactRootContainer ? warningWithoutStack$1(false, 'You are calling ReactDOM.%s() on a container that was previously ' + 'passed to ReactDOM.render(). This is not supported.', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0; 21364 container._reactHasBeenPassedToCreateRootDEV = true; 21365 } 21366 var hydrate = options != null && options.hydrate === true; 21367 return new ReactRoot(container, true, hydrate); 21368 } 21369 21370 if (enableStableConcurrentModeAPIs) { 21371 ReactDOM.createRoot = createRoot; 21372 ReactDOM.unstable_createRoot = undefined; 21373 } 21374 21375 var foundDevTools = injectIntoDevTools({ 21376 findFiberByHostInstance: getClosestInstanceFromNode, 21377 bundleType: 1, 21378 version: ReactVersion, 21379 rendererPackageName: 'react-dom' 21380 }); 21381 21382 { 21383 if (!foundDevTools && canUseDOM && window.top === window.self) { 21384 // If we're in Chrome or Firefox, provide a download link if not installed. 21385 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) { 21386 var protocol = window.location.protocol; 21387 // Don't warn in exotic cases like chrome-extension://. 21388 if (/^(https?|file):$/.test(protocol)) { 21389 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'); 21390 } 21391 } 21392 } 21393 } 21394 21395 21396 21397 var ReactDOM$2 = ({ 21398 default: ReactDOM 21399 }); 21400 21401 var ReactDOM$3 = ( ReactDOM$2 && ReactDOM ) || ReactDOM$2; 21402 21403 // TODO: decide on the top-level export form. 21404 // This is hacky but makes it work with both Rollup and Jest. 21405 var reactDom = ReactDOM$3.default || ReactDOM$3; 21406 21407 export default reactDom;