[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 /** @license React v16.5.2 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 (function (global, factory) { 13 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react')) : 14 typeof define === 'function' && define.amd ? define(['react'], factory) : 15 (global.ReactDOM = factory(global.React)); 16 }(this, (function (React) { 'use strict'; 17 18 /** 19 * Use invariant() to assert state which your program assumes to be true. 20 * 21 * Provide sprintf-style format (only %s is supported) and arguments 22 * to provide information about what broke and what you were 23 * expecting. 24 * 25 * The invariant message will be stripped in production, but the invariant 26 * will remain to ensure logic does not differ in production. 27 */ 28 29 var validateFormat = function () {}; 30 31 { 32 validateFormat = function (format) { 33 if (format === undefined) { 34 throw new Error('invariant requires an error message argument'); 35 } 36 }; 37 } 38 39 function invariant(condition, format, a, b, c, d, e, f) { 40 validateFormat(format); 41 42 if (!condition) { 43 var error = void 0; 44 if (format === undefined) { 45 error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); 46 } else { 47 var args = [a, b, c, d, e, f]; 48 var argIndex = 0; 49 error = new Error(format.replace(/%s/g, function () { 50 return args[argIndex++]; 51 })); 52 error.name = 'Invariant Violation'; 53 } 54 55 error.framesToPop = 1; // we don't care about invariant's own frame 56 throw error; 57 } 58 } 59 60 // Relying on the `invariant()` implementation lets us 61 // preserve the format and params in the www builds. 62 63 !React ? invariant(false, 'ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.') : void 0; 64 65 var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) { 66 var funcArgs = Array.prototype.slice.call(arguments, 3); 67 try { 68 func.apply(context, funcArgs); 69 } catch (error) { 70 this.onError(error); 71 } 72 }; 73 74 { 75 // In DEV mode, we swap out invokeGuardedCallback for a special version 76 // that plays more nicely with the browser's DevTools. The idea is to preserve 77 // "Pause on exceptions" behavior. Because React wraps all user-provided 78 // functions in invokeGuardedCallback, and the production version of 79 // invokeGuardedCallback uses a try-catch, all user exceptions are treated 80 // like caught exceptions, and the DevTools won't pause unless the developer 81 // takes the extra step of enabling pause on caught exceptions. This is 82 // untintuitive, though, because even though React has caught the error, from 83 // the developer's perspective, the error is uncaught. 84 // 85 // To preserve the expected "Pause on exceptions" behavior, we don't use a 86 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake 87 // DOM node, and call the user-provided callback from inside an event handler 88 // for that fake event. If the callback throws, the error is "captured" using 89 // a global event handler. But because the error happens in a different 90 // event loop context, it does not interrupt the normal program flow. 91 // Effectively, this gives us try-catch behavior without actually using 92 // try-catch. Neat! 93 94 // Check that the browser supports the APIs we need to implement our special 95 // DEV version of invokeGuardedCallback 96 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') { 97 var fakeNode = document.createElement('react'); 98 99 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) { 100 // If document doesn't exist we know for sure we will crash in this method 101 // when we call document.createEvent(). However this can cause confusing 102 // errors: https://github.com/facebookincubator/create-react-app/issues/3482 103 // So we preemptively throw with a better message instead. 104 !(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; 105 var evt = document.createEvent('Event'); 106 107 // Keeps track of whether the user-provided callback threw an error. We 108 // set this to true at the beginning, then set it to false right after 109 // calling the function. If the function errors, `didError` will never be 110 // set to false. This strategy works even if the browser is flaky and 111 // fails to call our global error handler, because it doesn't rely on 112 // the error event at all. 113 var didError = true; 114 115 // Keeps track of the value of window.event so that we can reset it 116 // during the callback to let user code access window.event in the 117 // browsers that support it. 118 var windowEvent = 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 (didError) { 192 if (!didSetError) { 193 // The callback errored, but the error event never fired. 194 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.'); 195 } else if (isCrossOriginError) { 196 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.'); 197 } 198 this.onError(error); 199 } 200 201 // Remove our event listeners 202 window.removeEventListener('error', handleWindowError); 203 }; 204 205 invokeGuardedCallbackImpl = invokeGuardedCallbackDev; 206 } 207 } 208 209 var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl; 210 211 // Used by Fiber to simulate a try-catch. 212 var hasError = false; 213 var caughtError = null; 214 215 // Used by event system to capture/rethrow the first error. 216 var hasRethrowError = false; 217 var rethrowError = null; 218 219 var reporter = { 220 onError: function (error) { 221 hasError = true; 222 caughtError = error; 223 } 224 }; 225 226 /** 227 * Call a function while guarding against errors that happens within it. 228 * Returns an error if it throws, otherwise null. 229 * 230 * In production, this is implemented using a try-catch. The reason we don't 231 * use a try-catch directly is so that we can swap out a different 232 * implementation in DEV mode. 233 * 234 * @param {String} name of the guard to use for logging or debugging 235 * @param {Function} func The function to invoke 236 * @param {*} context The context to use when calling the function 237 * @param {...*} args Arguments for function 238 */ 239 function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) { 240 hasError = false; 241 caughtError = null; 242 invokeGuardedCallbackImpl$1.apply(reporter, arguments); 243 } 244 245 /** 246 * Same as invokeGuardedCallback, but instead of returning an error, it stores 247 * it in a global so it can be rethrown by `rethrowCaughtError` later. 248 * TODO: See if caughtError and rethrowError can be unified. 249 * 250 * @param {String} name of the guard to use for logging or debugging 251 * @param {Function} func The function to invoke 252 * @param {*} context The context to use when calling the function 253 * @param {...*} args Arguments for function 254 */ 255 function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) { 256 invokeGuardedCallback.apply(this, arguments); 257 if (hasError) { 258 var error = clearCaughtError(); 259 if (!hasRethrowError) { 260 hasRethrowError = true; 261 rethrowError = error; 262 } 263 } 264 } 265 266 /** 267 * During execution of guarded functions we will capture the first error which 268 * we will rethrow to be handled by the top level error handler. 269 */ 270 function rethrowCaughtError() { 271 if (hasRethrowError) { 272 var error = rethrowError; 273 hasRethrowError = false; 274 rethrowError = null; 275 throw error; 276 } 277 } 278 279 function hasCaughtError() { 280 return hasError; 281 } 282 283 function clearCaughtError() { 284 if (hasError) { 285 var error = caughtError; 286 hasError = false; 287 caughtError = null; 288 return error; 289 } else { 290 invariant(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.'); 291 } 292 } 293 294 /** 295 * Injectable ordering of event plugins. 296 */ 297 var eventPluginOrder = null; 298 299 /** 300 * Injectable mapping from names to event plugin modules. 301 */ 302 var namesToPlugins = {}; 303 304 /** 305 * Recomputes the plugin list using the injected plugins and plugin ordering. 306 * 307 * @private 308 */ 309 function recomputePluginOrdering() { 310 if (!eventPluginOrder) { 311 // Wait until an `eventPluginOrder` is injected. 312 return; 313 } 314 for (var pluginName in namesToPlugins) { 315 var pluginModule = namesToPlugins[pluginName]; 316 var pluginIndex = eventPluginOrder.indexOf(pluginName); 317 !(pluginIndex > -1) ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : void 0; 318 if (plugins[pluginIndex]) { 319 continue; 320 } 321 !pluginModule.extractEvents ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : void 0; 322 plugins[pluginIndex] = pluginModule; 323 var publishedEvents = pluginModule.eventTypes; 324 for (var eventName in publishedEvents) { 325 !publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : void 0; 326 } 327 } 328 } 329 330 /** 331 * Publishes an event so that it can be dispatched by the supplied plugin. 332 * 333 * @param {object} dispatchConfig Dispatch configuration for the event. 334 * @param {object} PluginModule Plugin publishing the event. 335 * @return {boolean} True if the event was successfully published. 336 * @private 337 */ 338 function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { 339 !!eventNameDispatchConfigs.hasOwnProperty(eventName) ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : void 0; 340 eventNameDispatchConfigs[eventName] = dispatchConfig; 341 342 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; 343 if (phasedRegistrationNames) { 344 for (var phaseName in phasedRegistrationNames) { 345 if (phasedRegistrationNames.hasOwnProperty(phaseName)) { 346 var phasedRegistrationName = phasedRegistrationNames[phaseName]; 347 publishRegistrationName(phasedRegistrationName, pluginModule, eventName); 348 } 349 } 350 return true; 351 } else if (dispatchConfig.registrationName) { 352 publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName); 353 return true; 354 } 355 return false; 356 } 357 358 /** 359 * Publishes a registration name that is used to identify dispatched events. 360 * 361 * @param {string} registrationName Registration name to add. 362 * @param {object} PluginModule Plugin publishing the event. 363 * @private 364 */ 365 function publishRegistrationName(registrationName, pluginModule, eventName) { 366 !!registrationNameModules[registrationName] ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : void 0; 367 registrationNameModules[registrationName] = pluginModule; 368 registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies; 369 370 { 371 var lowerCasedName = registrationName.toLowerCase(); 372 possibleRegistrationNames[lowerCasedName] = registrationName; 373 374 if (registrationName === 'onDoubleClick') { 375 possibleRegistrationNames.ondblclick = registrationName; 376 } 377 } 378 } 379 380 /** 381 * Registers plugins so that they can extract and dispatch events. 382 * 383 * @see {EventPluginHub} 384 */ 385 386 /** 387 * Ordered list of injected plugins. 388 */ 389 var plugins = []; 390 391 /** 392 * Mapping from event name to dispatch config 393 */ 394 var eventNameDispatchConfigs = {}; 395 396 /** 397 * Mapping from registration name to plugin module 398 */ 399 var registrationNameModules = {}; 400 401 /** 402 * Mapping from registration name to event name 403 */ 404 var registrationNameDependencies = {}; 405 406 /** 407 * Mapping from lowercase registration names to the properly cased version, 408 * used to warn in the case of missing event handlers. Available 409 * only in true. 410 * @type {Object} 411 */ 412 var possibleRegistrationNames = {}; 413 // Trust the developer to only use possibleRegistrationNames in true 414 415 /** 416 * Injects an ordering of plugins (by plugin name). This allows the ordering 417 * to be decoupled from injection of the actual plugins so that ordering is 418 * always deterministic regardless of packaging, on-the-fly injection, etc. 419 * 420 * @param {array} InjectedEventPluginOrder 421 * @internal 422 * @see {EventPluginHub.injection.injectEventPluginOrder} 423 */ 424 function injectEventPluginOrder(injectedEventPluginOrder) { 425 !!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; 426 // Clone the ordering so it cannot be dynamically mutated. 427 eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); 428 recomputePluginOrdering(); 429 } 430 431 /** 432 * Injects plugins to be used by `EventPluginHub`. The plugin names must be 433 * in the ordering injected by `injectEventPluginOrder`. 434 * 435 * Plugins can be injected as part of page initialization or on-the-fly. 436 * 437 * @param {object} injectedNamesToPlugins Map from names to plugin modules. 438 * @internal 439 * @see {EventPluginHub.injection.injectEventPluginsByName} 440 */ 441 function injectEventPluginsByName(injectedNamesToPlugins) { 442 var isOrderingDirty = false; 443 for (var pluginName in injectedNamesToPlugins) { 444 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { 445 continue; 446 } 447 var pluginModule = injectedNamesToPlugins[pluginName]; 448 if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) { 449 !!namesToPlugins[pluginName] ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : void 0; 450 namesToPlugins[pluginName] = pluginModule; 451 isOrderingDirty = true; 452 } 453 } 454 if (isOrderingDirty) { 455 recomputePluginOrdering(); 456 } 457 } 458 459 /** 460 * Similar to invariant but only logs a warning if the condition is not met. 461 * This can be used to log issues in development environments in critical 462 * paths. Removing the logging code for production environments will keep the 463 * same logic and follow the same code paths. 464 */ 465 466 var warningWithoutStack = function () {}; 467 468 { 469 warningWithoutStack = function (condition, format) { 470 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { 471 args[_key - 2] = arguments[_key]; 472 } 473 474 if (format === undefined) { 475 throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument'); 476 } 477 if (args.length > 8) { 478 // Check before the condition to catch violations early. 479 throw new Error('warningWithoutStack() currently supports at most 8 arguments.'); 480 } 481 if (condition) { 482 return; 483 } 484 if (typeof console !== 'undefined') { 485 var _args$map = args.map(function (item) { 486 return '' + item; 487 }), 488 a = _args$map[0], 489 b = _args$map[1], 490 c = _args$map[2], 491 d = _args$map[3], 492 e = _args$map[4], 493 f = _args$map[5], 494 g = _args$map[6], 495 h = _args$map[7]; 496 497 var message = 'Warning: ' + format; 498 499 // We intentionally don't use spread (or .apply) because it breaks IE9: 500 // https://github.com/facebook/react/issues/13610 501 switch (args.length) { 502 case 0: 503 console.error(message); 504 break; 505 case 1: 506 console.error(message, a); 507 break; 508 case 2: 509 console.error(message, a, b); 510 break; 511 case 3: 512 console.error(message, a, b, c); 513 break; 514 case 4: 515 console.error(message, a, b, c, d); 516 break; 517 case 5: 518 console.error(message, a, b, c, d, e); 519 break; 520 case 6: 521 console.error(message, a, b, c, d, e, f); 522 break; 523 case 7: 524 console.error(message, a, b, c, d, e, f, g); 525 break; 526 case 8: 527 console.error(message, a, b, c, d, e, f, g, h); 528 break; 529 default: 530 throw new Error('warningWithoutStack() currently supports at most 8 arguments.'); 531 } 532 } 533 try { 534 // --- Welcome to debugging React --- 535 // This error was thrown as a convenience so that you can use this stack 536 // to find the callsite that caused this warning to fire. 537 var argIndex = 0; 538 var _message = 'Warning: ' + format.replace(/%s/g, function () { 539 return args[argIndex++]; 540 }); 541 throw new Error(_message); 542 } catch (x) {} 543 }; 544 } 545 546 var warningWithoutStack$1 = warningWithoutStack; 547 548 var getFiberCurrentPropsFromNode = null; 549 var getInstanceFromNode = null; 550 var getNodeFromInstance = null; 551 552 function setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) { 553 getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl; 554 getInstanceFromNode = getInstanceFromNodeImpl; 555 getNodeFromInstance = getNodeFromInstanceImpl; 556 { 557 !(getNodeFromInstance && getInstanceFromNode) ? warningWithoutStack$1(false, 'EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0; 558 } 559 } 560 561 var validateEventDispatches = void 0; 562 { 563 validateEventDispatches = function (event) { 564 var dispatchListeners = event._dispatchListeners; 565 var dispatchInstances = event._dispatchInstances; 566 567 var listenersIsArr = Array.isArray(dispatchListeners); 568 var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0; 569 570 var instancesIsArr = Array.isArray(dispatchInstances); 571 var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0; 572 573 !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) ? warningWithoutStack$1(false, 'EventPluginUtils: Invalid `event`.') : void 0; 574 }; 575 } 576 577 /** 578 * Dispatch the event to the listener. 579 * @param {SyntheticEvent} event SyntheticEvent to handle 580 * @param {boolean} simulated If the event is simulated (changes exn behavior) 581 * @param {function} listener Application-level callback 582 * @param {*} inst Internal component instance 583 */ 584 function executeDispatch(event, simulated, listener, inst) { 585 var type = event.type || 'unknown-event'; 586 event.currentTarget = getNodeFromInstance(inst); 587 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event); 588 event.currentTarget = null; 589 } 590 591 /** 592 * Standard/simple iteration through an event's collected dispatches. 593 */ 594 function executeDispatchesInOrder(event, simulated) { 595 var dispatchListeners = event._dispatchListeners; 596 var dispatchInstances = event._dispatchInstances; 597 { 598 validateEventDispatches(event); 599 } 600 if (Array.isArray(dispatchListeners)) { 601 for (var i = 0; i < dispatchListeners.length; i++) { 602 if (event.isPropagationStopped()) { 603 break; 604 } 605 // Listeners and Instances are two parallel arrays that are always in sync. 606 executeDispatch(event, simulated, dispatchListeners[i], dispatchInstances[i]); 607 } 608 } else if (dispatchListeners) { 609 executeDispatch(event, simulated, dispatchListeners, dispatchInstances); 610 } 611 event._dispatchListeners = null; 612 event._dispatchInstances = null; 613 } 614 615 /** 616 * @see executeDispatchesInOrderStopAtTrueImpl 617 */ 618 619 620 /** 621 * Execution of a "direct" dispatch - there must be at most one dispatch 622 * accumulated on the event or it is considered an error. It doesn't really make 623 * sense for an event with multiple dispatches (bubbled) to keep track of the 624 * return values at each dispatch execution, but it does tend to make sense when 625 * dealing with "direct" dispatches. 626 * 627 * @return {*} The return value of executing the single dispatch. 628 */ 629 630 631 /** 632 * @param {SyntheticEvent} event 633 * @return {boolean} True iff number of dispatches accumulated is greater than 0. 634 */ 635 636 /** 637 * Accumulates items that must not be null or undefined into the first one. This 638 * is used to conserve memory by avoiding array allocations, and thus sacrifices 639 * API cleanness. Since `current` can be null before being passed in and not 640 * null after this function, make sure to assign it back to `current`: 641 * 642 * `a = accumulateInto(a, b);` 643 * 644 * This API should be sparingly used. Try `accumulate` for something cleaner. 645 * 646 * @return {*|array<*>} An accumulation of items. 647 */ 648 649 function accumulateInto(current, next) { 650 !(next != null) ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : void 0; 651 652 if (current == null) { 653 return next; 654 } 655 656 // Both are not empty. Warning: Never call x.concat(y) when you are not 657 // certain that x is an Array (x could be a string with concat method). 658 if (Array.isArray(current)) { 659 if (Array.isArray(next)) { 660 current.push.apply(current, next); 661 return current; 662 } 663 current.push(next); 664 return current; 665 } 666 667 if (Array.isArray(next)) { 668 // A bit too dangerous to mutate `next`. 669 return [current].concat(next); 670 } 671 672 return [current, next]; 673 } 674 675 /** 676 * @param {array} arr an "accumulation" of items which is either an Array or 677 * a single item. Useful when paired with the `accumulate` module. This is a 678 * simple utility that allows us to reason about a collection of items, but 679 * handling the case when there is exactly one item (and we do not need to 680 * allocate an array). 681 * @param {function} cb Callback invoked with each element or a collection. 682 * @param {?} [scope] Scope used as `this` in a callback. 683 */ 684 function forEachAccumulated(arr, cb, scope) { 685 if (Array.isArray(arr)) { 686 arr.forEach(cb, scope); 687 } else if (arr) { 688 cb.call(scope, arr); 689 } 690 } 691 692 /** 693 * Internal queue of events that have accumulated their dispatches and are 694 * waiting to have their dispatches executed. 695 */ 696 var eventQueue = null; 697 698 /** 699 * Dispatches an event and releases it back into the pool, unless persistent. 700 * 701 * @param {?object} event Synthetic event to be dispatched. 702 * @param {boolean} simulated If the event is simulated (changes exn behavior) 703 * @private 704 */ 705 var executeDispatchesAndRelease = function (event, simulated) { 706 if (event) { 707 executeDispatchesInOrder(event, simulated); 708 709 if (!event.isPersistent()) { 710 event.constructor.release(event); 711 } 712 } 713 }; 714 var executeDispatchesAndReleaseSimulated = function (e) { 715 return executeDispatchesAndRelease(e, true); 716 }; 717 var executeDispatchesAndReleaseTopLevel = function (e) { 718 return executeDispatchesAndRelease(e, false); 719 }; 720 721 function isInteractive(tag) { 722 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea'; 723 } 724 725 function shouldPreventMouseEvent(name, type, props) { 726 switch (name) { 727 case 'onClick': 728 case 'onClickCapture': 729 case 'onDoubleClick': 730 case 'onDoubleClickCapture': 731 case 'onMouseDown': 732 case 'onMouseDownCapture': 733 case 'onMouseMove': 734 case 'onMouseMoveCapture': 735 case 'onMouseUp': 736 case 'onMouseUpCapture': 737 return !!(props.disabled && isInteractive(type)); 738 default: 739 return false; 740 } 741 } 742 743 /** 744 * This is a unified interface for event plugins to be installed and configured. 745 * 746 * Event plugins can implement the following properties: 747 * 748 * `extractEvents` {function(string, DOMEventTarget, string, object): *} 749 * Required. When a top-level event is fired, this method is expected to 750 * extract synthetic events that will in turn be queued and dispatched. 751 * 752 * `eventTypes` {object} 753 * Optional, plugins that fire events must publish a mapping of registration 754 * names that are used to register listeners. Values of this mapping must 755 * be objects that contain `registrationName` or `phasedRegistrationNames`. 756 * 757 * `executeDispatch` {function(object, function, string)} 758 * Optional, allows plugins to override how an event gets dispatched. By 759 * default, the listener is simply invoked. 760 * 761 * Each plugin that is injected into `EventsPluginHub` is immediately operable. 762 * 763 * @public 764 */ 765 766 /** 767 * Methods for injecting dependencies. 768 */ 769 var injection = { 770 /** 771 * @param {array} InjectedEventPluginOrder 772 * @public 773 */ 774 injectEventPluginOrder: injectEventPluginOrder, 775 776 /** 777 * @param {object} injectedNamesToPlugins Map from names to plugin modules. 778 */ 779 injectEventPluginsByName: injectEventPluginsByName 780 }; 781 782 /** 783 * @param {object} inst The instance, which is the source of events. 784 * @param {string} registrationName Name of listener (e.g. `onClick`). 785 * @return {?function} The stored callback. 786 */ 787 function getListener(inst, registrationName) { 788 var listener = void 0; 789 790 // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not 791 // live here; needs to be moved to a better place soon 792 var stateNode = inst.stateNode; 793 if (!stateNode) { 794 // Work in progress (ex: onload events in incremental mode). 795 return null; 796 } 797 var props = getFiberCurrentPropsFromNode(stateNode); 798 if (!props) { 799 // Work in progress. 800 return null; 801 } 802 listener = props[registrationName]; 803 if (shouldPreventMouseEvent(registrationName, inst.type, props)) { 804 return null; 805 } 806 !(!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; 807 return listener; 808 } 809 810 /** 811 * Allows registered plugins an opportunity to extract events from top-level 812 * native browser events. 813 * 814 * @return {*} An accumulation of synthetic events. 815 * @internal 816 */ 817 function extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) { 818 var events = null; 819 for (var i = 0; i < plugins.length; i++) { 820 // Not every plugin in the ordering may be loaded at runtime. 821 var possiblePlugin = plugins[i]; 822 if (possiblePlugin) { 823 var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); 824 if (extractedEvents) { 825 events = accumulateInto(events, extractedEvents); 826 } 827 } 828 } 829 return events; 830 } 831 832 function runEventsInBatch(events, simulated) { 833 if (events !== null) { 834 eventQueue = accumulateInto(eventQueue, events); 835 } 836 837 // Set `eventQueue` to null before processing it so that we can tell if more 838 // events get enqueued while processing. 839 var processingEventQueue = eventQueue; 840 eventQueue = null; 841 842 if (!processingEventQueue) { 843 return; 844 } 845 846 if (simulated) { 847 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseSimulated); 848 } else { 849 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); 850 } 851 !!eventQueue ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : void 0; 852 // This would be a good time to rethrow if any of the event handlers threw. 853 rethrowCaughtError(); 854 } 855 856 function runExtractedEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) { 857 var events = extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); 858 runEventsInBatch(events, false); 859 } 860 861 var FunctionalComponent = 0; 862 var FunctionalComponentLazy = 1; 863 var ClassComponent = 2; 864 var ClassComponentLazy = 3; 865 var IndeterminateComponent = 4; // Before we know whether it is functional or class 866 var HostRoot = 5; // Root of a host tree. Could be nested inside another node. 867 var HostPortal = 6; // A subtree. Could be an entry point to a different renderer. 868 var HostComponent = 7; 869 var HostText = 8; 870 var Fragment = 9; 871 var Mode = 10; 872 var ContextConsumer = 11; 873 var ContextProvider = 12; 874 var ForwardRef = 13; 875 var ForwardRefLazy = 14; 876 var Profiler = 15; 877 var PlaceholderComponent = 16; 878 879 var randomKey = Math.random().toString(36).slice(2); 880 var internalInstanceKey = '__reactInternalInstance$' + randomKey; 881 var internalEventHandlersKey = '__reactEventHandlers$' + randomKey; 882 883 function precacheFiberNode(hostInst, node) { 884 node[internalInstanceKey] = hostInst; 885 } 886 887 /** 888 * Given a DOM node, return the closest ReactDOMComponent or 889 * ReactDOMTextComponent instance ancestor. 890 */ 891 function getClosestInstanceFromNode(node) { 892 if (node[internalInstanceKey]) { 893 return node[internalInstanceKey]; 894 } 895 896 while (!node[internalInstanceKey]) { 897 if (node.parentNode) { 898 node = node.parentNode; 899 } else { 900 // Top of the tree. This node must not be part of a React tree (or is 901 // unmounted, potentially). 902 return null; 903 } 904 } 905 906 var inst = node[internalInstanceKey]; 907 if (inst.tag === HostComponent || inst.tag === HostText) { 908 // In Fiber, this will always be the deepest root. 909 return inst; 910 } 911 912 return null; 913 } 914 915 /** 916 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent 917 * instance, or null if the node was not rendered by this React. 918 */ 919 function getInstanceFromNode$1(node) { 920 var inst = node[internalInstanceKey]; 921 if (inst) { 922 if (inst.tag === HostComponent || inst.tag === HostText) { 923 return inst; 924 } else { 925 return null; 926 } 927 } 928 return null; 929 } 930 931 /** 932 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding 933 * DOM node. 934 */ 935 function getNodeFromInstance$1(inst) { 936 if (inst.tag === HostComponent || inst.tag === HostText) { 937 // In Fiber this, is just the state node right now. We assume it will be 938 // a host component or host text. 939 return inst.stateNode; 940 } 941 942 // Without this first invariant, passing a non-DOM-component triggers the next 943 // invariant for a missing parent, which is super confusing. 944 invariant(false, 'getNodeFromInstance: Invalid argument.'); 945 } 946 947 function getFiberCurrentPropsFromNode$1(node) { 948 return node[internalEventHandlersKey] || null; 949 } 950 951 function updateFiberProps(node, props) { 952 node[internalEventHandlersKey] = props; 953 } 954 955 function getParent(inst) { 956 do { 957 inst = inst.return; 958 // TODO: If this is a HostRoot we might want to bail out. 959 // That is depending on if we want nested subtrees (layers) to bubble 960 // events to their parent. We could also go through parentNode on the 961 // host node but that wouldn't work for React Native and doesn't let us 962 // do the portal feature. 963 } while (inst && inst.tag !== HostComponent); 964 if (inst) { 965 return inst; 966 } 967 return null; 968 } 969 970 /** 971 * Return the lowest common ancestor of A and B, or null if they are in 972 * different trees. 973 */ 974 function getLowestCommonAncestor(instA, instB) { 975 var depthA = 0; 976 for (var tempA = instA; tempA; tempA = getParent(tempA)) { 977 depthA++; 978 } 979 var depthB = 0; 980 for (var tempB = instB; tempB; tempB = getParent(tempB)) { 981 depthB++; 982 } 983 984 // If A is deeper, crawl up. 985 while (depthA - depthB > 0) { 986 instA = getParent(instA); 987 depthA--; 988 } 989 990 // If B is deeper, crawl up. 991 while (depthB - depthA > 0) { 992 instB = getParent(instB); 993 depthB--; 994 } 995 996 // Walk in lockstep until we find a match. 997 var depth = depthA; 998 while (depth--) { 999 if (instA === instB || instA === instB.alternate) { 1000 return instA; 1001 } 1002 instA = getParent(instA); 1003 instB = getParent(instB); 1004 } 1005 return null; 1006 } 1007 1008 /** 1009 * Return if A is an ancestor of B. 1010 */ 1011 1012 1013 /** 1014 * Return the parent instance of the passed-in instance. 1015 */ 1016 1017 1018 /** 1019 * Simulates the traversal of a two-phase, capture/bubble event dispatch. 1020 */ 1021 function traverseTwoPhase(inst, fn, arg) { 1022 var path = []; 1023 while (inst) { 1024 path.push(inst); 1025 inst = getParent(inst); 1026 } 1027 var i = void 0; 1028 for (i = path.length; i-- > 0;) { 1029 fn(path[i], 'captured', arg); 1030 } 1031 for (i = 0; i < path.length; i++) { 1032 fn(path[i], 'bubbled', arg); 1033 } 1034 } 1035 1036 /** 1037 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that 1038 * should would receive a `mouseEnter` or `mouseLeave` event. 1039 * 1040 * Does not invoke the callback on the nearest common ancestor because nothing 1041 * "entered" or "left" that element. 1042 */ 1043 function traverseEnterLeave(from, to, fn, argFrom, argTo) { 1044 var common = from && to ? getLowestCommonAncestor(from, to) : null; 1045 var pathFrom = []; 1046 while (true) { 1047 if (!from) { 1048 break; 1049 } 1050 if (from === common) { 1051 break; 1052 } 1053 var alternate = from.alternate; 1054 if (alternate !== null && alternate === common) { 1055 break; 1056 } 1057 pathFrom.push(from); 1058 from = getParent(from); 1059 } 1060 var pathTo = []; 1061 while (true) { 1062 if (!to) { 1063 break; 1064 } 1065 if (to === common) { 1066 break; 1067 } 1068 var _alternate = to.alternate; 1069 if (_alternate !== null && _alternate === common) { 1070 break; 1071 } 1072 pathTo.push(to); 1073 to = getParent(to); 1074 } 1075 for (var i = 0; i < pathFrom.length; i++) { 1076 fn(pathFrom[i], 'bubbled', argFrom); 1077 } 1078 for (var _i = pathTo.length; _i-- > 0;) { 1079 fn(pathTo[_i], 'captured', argTo); 1080 } 1081 } 1082 1083 /** 1084 * Some event types have a notion of different registration names for different 1085 * "phases" of propagation. This finds listeners by a given phase. 1086 */ 1087 function listenerAtPhase(inst, event, propagationPhase) { 1088 var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase]; 1089 return getListener(inst, registrationName); 1090 } 1091 1092 /** 1093 * A small set of propagation patterns, each of which will accept a small amount 1094 * of information, and generate a set of "dispatch ready event objects" - which 1095 * are sets of events that have already been annotated with a set of dispatched 1096 * listener functions/ids. The API is designed this way to discourage these 1097 * propagation strategies from actually executing the dispatches, since we 1098 * always want to collect the entire set of dispatches before executing even a 1099 * single one. 1100 */ 1101 1102 /** 1103 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function 1104 * here, allows us to not have to bind or create functions for each event. 1105 * Mutating the event's members allows us to not have to create a wrapping 1106 * "dispatch" object that pairs the event with the listener. 1107 */ 1108 function accumulateDirectionalDispatches(inst, phase, event) { 1109 { 1110 !inst ? warningWithoutStack$1(false, 'Dispatching inst must not be null') : void 0; 1111 } 1112 var listener = listenerAtPhase(inst, event, phase); 1113 if (listener) { 1114 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener); 1115 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); 1116 } 1117 } 1118 1119 /** 1120 * Collect dispatches (must be entirely collected before dispatching - see unit 1121 * tests). Lazily allocate the array to conserve memory. We must loop through 1122 * each event and perform the traversal for each one. We cannot perform a 1123 * single traversal for the entire collection of events because each event may 1124 * have a different target. 1125 */ 1126 function accumulateTwoPhaseDispatchesSingle(event) { 1127 if (event && event.dispatchConfig.phasedRegistrationNames) { 1128 traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); 1129 } 1130 } 1131 1132 /** 1133 * Accumulates without regard to direction, does not look for phased 1134 * registration names. Same as `accumulateDirectDispatchesSingle` but without 1135 * requiring that the `dispatchMarker` be the same as the dispatched ID. 1136 */ 1137 function accumulateDispatches(inst, ignoredDirection, event) { 1138 if (inst && event && event.dispatchConfig.registrationName) { 1139 var registrationName = event.dispatchConfig.registrationName; 1140 var listener = getListener(inst, registrationName); 1141 if (listener) { 1142 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener); 1143 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); 1144 } 1145 } 1146 } 1147 1148 /** 1149 * Accumulates dispatches on an `SyntheticEvent`, but only for the 1150 * `dispatchMarker`. 1151 * @param {SyntheticEvent} event 1152 */ 1153 function accumulateDirectDispatchesSingle(event) { 1154 if (event && event.dispatchConfig.registrationName) { 1155 accumulateDispatches(event._targetInst, null, event); 1156 } 1157 } 1158 1159 function accumulateTwoPhaseDispatches(events) { 1160 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); 1161 } 1162 1163 1164 1165 function accumulateEnterLeaveDispatches(leave, enter, from, to) { 1166 traverseEnterLeave(from, to, accumulateDispatches, leave, enter); 1167 } 1168 1169 function accumulateDirectDispatches(events) { 1170 forEachAccumulated(events, accumulateDirectDispatchesSingle); 1171 } 1172 1173 var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); 1174 1175 // Do not uses the below two methods directly! 1176 // Instead use constants exported from DOMTopLevelEventTypes in ReactDOM. 1177 // (It is the only module that is allowed to access these methods.) 1178 1179 function unsafeCastStringToDOMTopLevelType(topLevelType) { 1180 return topLevelType; 1181 } 1182 1183 function unsafeCastDOMTopLevelTypeToString(topLevelType) { 1184 return topLevelType; 1185 } 1186 1187 /** 1188 * Generate a mapping of standard vendor prefixes using the defined style property and event name. 1189 * 1190 * @param {string} styleProp 1191 * @param {string} eventName 1192 * @returns {object} 1193 */ 1194 function makePrefixMap(styleProp, eventName) { 1195 var prefixes = {}; 1196 1197 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase(); 1198 prefixes['Webkit' + styleProp] = 'webkit' + eventName; 1199 prefixes['Moz' + styleProp] = 'moz' + eventName; 1200 1201 return prefixes; 1202 } 1203 1204 /** 1205 * A list of event names to a configurable list of vendor prefixes. 1206 */ 1207 var vendorPrefixes = { 1208 animationend: makePrefixMap('Animation', 'AnimationEnd'), 1209 animationiteration: makePrefixMap('Animation', 'AnimationIteration'), 1210 animationstart: makePrefixMap('Animation', 'AnimationStart'), 1211 transitionend: makePrefixMap('Transition', 'TransitionEnd') 1212 }; 1213 1214 /** 1215 * Event names that have already been detected and prefixed (if applicable). 1216 */ 1217 var prefixedEventNames = {}; 1218 1219 /** 1220 * Element to check for prefixes on. 1221 */ 1222 var style = {}; 1223 1224 /** 1225 * Bootstrap if a DOM exists. 1226 */ 1227 if (canUseDOM) { 1228 style = document.createElement('div').style; 1229 1230 // On some platforms, in particular some releases of Android 4.x, 1231 // the un-prefixed "animation" and "transition" properties are defined on the 1232 // style object but the events that fire will still be prefixed, so we need 1233 // to check if the un-prefixed events are usable, and if not remove them from the map. 1234 if (!('AnimationEvent' in window)) { 1235 delete vendorPrefixes.animationend.animation; 1236 delete vendorPrefixes.animationiteration.animation; 1237 delete vendorPrefixes.animationstart.animation; 1238 } 1239 1240 // Same as above 1241 if (!('TransitionEvent' in window)) { 1242 delete vendorPrefixes.transitionend.transition; 1243 } 1244 } 1245 1246 /** 1247 * Attempts to determine the correct vendor prefixed event name. 1248 * 1249 * @param {string} eventName 1250 * @returns {string} 1251 */ 1252 function getVendorPrefixedEventName(eventName) { 1253 if (prefixedEventNames[eventName]) { 1254 return prefixedEventNames[eventName]; 1255 } else if (!vendorPrefixes[eventName]) { 1256 return eventName; 1257 } 1258 1259 var prefixMap = vendorPrefixes[eventName]; 1260 1261 for (var styleProp in prefixMap) { 1262 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) { 1263 return prefixedEventNames[eventName] = prefixMap[styleProp]; 1264 } 1265 } 1266 1267 return eventName; 1268 } 1269 1270 /** 1271 * To identify top level events in ReactDOM, we use constants defined by this 1272 * module. This is the only module that uses the unsafe* methods to express 1273 * that the constants actually correspond to the browser event names. This lets 1274 * us save some bundle size by avoiding a top level type -> event name map. 1275 * The rest of ReactDOM code should import top level types from this file. 1276 */ 1277 var TOP_ABORT = unsafeCastStringToDOMTopLevelType('abort'); 1278 var TOP_ANIMATION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationend')); 1279 var TOP_ANIMATION_ITERATION = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationiteration')); 1280 var TOP_ANIMATION_START = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationstart')); 1281 var TOP_BLUR = unsafeCastStringToDOMTopLevelType('blur'); 1282 var TOP_CAN_PLAY = unsafeCastStringToDOMTopLevelType('canplay'); 1283 var TOP_CAN_PLAY_THROUGH = unsafeCastStringToDOMTopLevelType('canplaythrough'); 1284 var TOP_CANCEL = unsafeCastStringToDOMTopLevelType('cancel'); 1285 var TOP_CHANGE = unsafeCastStringToDOMTopLevelType('change'); 1286 var TOP_CLICK = unsafeCastStringToDOMTopLevelType('click'); 1287 var TOP_CLOSE = unsafeCastStringToDOMTopLevelType('close'); 1288 var TOP_COMPOSITION_END = unsafeCastStringToDOMTopLevelType('compositionend'); 1289 var TOP_COMPOSITION_START = unsafeCastStringToDOMTopLevelType('compositionstart'); 1290 var TOP_COMPOSITION_UPDATE = unsafeCastStringToDOMTopLevelType('compositionupdate'); 1291 var TOP_CONTEXT_MENU = unsafeCastStringToDOMTopLevelType('contextmenu'); 1292 var TOP_COPY = unsafeCastStringToDOMTopLevelType('copy'); 1293 var TOP_CUT = unsafeCastStringToDOMTopLevelType('cut'); 1294 var TOP_DOUBLE_CLICK = unsafeCastStringToDOMTopLevelType('dblclick'); 1295 var TOP_AUX_CLICK = unsafeCastStringToDOMTopLevelType('auxclick'); 1296 var TOP_DRAG = unsafeCastStringToDOMTopLevelType('drag'); 1297 var TOP_DRAG_END = unsafeCastStringToDOMTopLevelType('dragend'); 1298 var TOP_DRAG_ENTER = unsafeCastStringToDOMTopLevelType('dragenter'); 1299 var TOP_DRAG_EXIT = unsafeCastStringToDOMTopLevelType('dragexit'); 1300 var TOP_DRAG_LEAVE = unsafeCastStringToDOMTopLevelType('dragleave'); 1301 var TOP_DRAG_OVER = unsafeCastStringToDOMTopLevelType('dragover'); 1302 var TOP_DRAG_START = unsafeCastStringToDOMTopLevelType('dragstart'); 1303 var TOP_DROP = unsafeCastStringToDOMTopLevelType('drop'); 1304 var TOP_DURATION_CHANGE = unsafeCastStringToDOMTopLevelType('durationchange'); 1305 var TOP_EMPTIED = unsafeCastStringToDOMTopLevelType('emptied'); 1306 var TOP_ENCRYPTED = unsafeCastStringToDOMTopLevelType('encrypted'); 1307 var TOP_ENDED = unsafeCastStringToDOMTopLevelType('ended'); 1308 var TOP_ERROR = unsafeCastStringToDOMTopLevelType('error'); 1309 var TOP_FOCUS = unsafeCastStringToDOMTopLevelType('focus'); 1310 var TOP_GOT_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('gotpointercapture'); 1311 var TOP_INPUT = unsafeCastStringToDOMTopLevelType('input'); 1312 var TOP_INVALID = unsafeCastStringToDOMTopLevelType('invalid'); 1313 var TOP_KEY_DOWN = unsafeCastStringToDOMTopLevelType('keydown'); 1314 var TOP_KEY_PRESS = unsafeCastStringToDOMTopLevelType('keypress'); 1315 var TOP_KEY_UP = unsafeCastStringToDOMTopLevelType('keyup'); 1316 var TOP_LOAD = unsafeCastStringToDOMTopLevelType('load'); 1317 var TOP_LOAD_START = unsafeCastStringToDOMTopLevelType('loadstart'); 1318 var TOP_LOADED_DATA = unsafeCastStringToDOMTopLevelType('loadeddata'); 1319 var TOP_LOADED_METADATA = unsafeCastStringToDOMTopLevelType('loadedmetadata'); 1320 var TOP_LOST_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('lostpointercapture'); 1321 var TOP_MOUSE_DOWN = unsafeCastStringToDOMTopLevelType('mousedown'); 1322 var TOP_MOUSE_MOVE = unsafeCastStringToDOMTopLevelType('mousemove'); 1323 var TOP_MOUSE_OUT = unsafeCastStringToDOMTopLevelType('mouseout'); 1324 var TOP_MOUSE_OVER = unsafeCastStringToDOMTopLevelType('mouseover'); 1325 var TOP_MOUSE_UP = unsafeCastStringToDOMTopLevelType('mouseup'); 1326 var TOP_PASTE = unsafeCastStringToDOMTopLevelType('paste'); 1327 var TOP_PAUSE = unsafeCastStringToDOMTopLevelType('pause'); 1328 var TOP_PLAY = unsafeCastStringToDOMTopLevelType('play'); 1329 var TOP_PLAYING = unsafeCastStringToDOMTopLevelType('playing'); 1330 var TOP_POINTER_CANCEL = unsafeCastStringToDOMTopLevelType('pointercancel'); 1331 var TOP_POINTER_DOWN = unsafeCastStringToDOMTopLevelType('pointerdown'); 1332 1333 1334 var TOP_POINTER_MOVE = unsafeCastStringToDOMTopLevelType('pointermove'); 1335 var TOP_POINTER_OUT = unsafeCastStringToDOMTopLevelType('pointerout'); 1336 var TOP_POINTER_OVER = unsafeCastStringToDOMTopLevelType('pointerover'); 1337 var TOP_POINTER_UP = unsafeCastStringToDOMTopLevelType('pointerup'); 1338 var TOP_PROGRESS = unsafeCastStringToDOMTopLevelType('progress'); 1339 var TOP_RATE_CHANGE = unsafeCastStringToDOMTopLevelType('ratechange'); 1340 var TOP_RESET = unsafeCastStringToDOMTopLevelType('reset'); 1341 var TOP_SCROLL = unsafeCastStringToDOMTopLevelType('scroll'); 1342 var TOP_SEEKED = unsafeCastStringToDOMTopLevelType('seeked'); 1343 var TOP_SEEKING = unsafeCastStringToDOMTopLevelType('seeking'); 1344 var TOP_SELECTION_CHANGE = unsafeCastStringToDOMTopLevelType('selectionchange'); 1345 var TOP_STALLED = unsafeCastStringToDOMTopLevelType('stalled'); 1346 var TOP_SUBMIT = unsafeCastStringToDOMTopLevelType('submit'); 1347 var TOP_SUSPEND = unsafeCastStringToDOMTopLevelType('suspend'); 1348 var TOP_TEXT_INPUT = unsafeCastStringToDOMTopLevelType('textInput'); 1349 var TOP_TIME_UPDATE = unsafeCastStringToDOMTopLevelType('timeupdate'); 1350 var TOP_TOGGLE = unsafeCastStringToDOMTopLevelType('toggle'); 1351 var TOP_TOUCH_CANCEL = unsafeCastStringToDOMTopLevelType('touchcancel'); 1352 var TOP_TOUCH_END = unsafeCastStringToDOMTopLevelType('touchend'); 1353 var TOP_TOUCH_MOVE = unsafeCastStringToDOMTopLevelType('touchmove'); 1354 var TOP_TOUCH_START = unsafeCastStringToDOMTopLevelType('touchstart'); 1355 var TOP_TRANSITION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('transitionend')); 1356 var TOP_VOLUME_CHANGE = unsafeCastStringToDOMTopLevelType('volumechange'); 1357 var TOP_WAITING = unsafeCastStringToDOMTopLevelType('waiting'); 1358 var TOP_WHEEL = unsafeCastStringToDOMTopLevelType('wheel'); 1359 1360 // List of events that need to be individually attached to media elements. 1361 // Note that events in this list will *not* be listened to at the top level 1362 // unless they're explicitly whitelisted in `ReactBrowserEventEmitter.listenTo`. 1363 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]; 1364 1365 function getRawEventName(topLevelType) { 1366 return unsafeCastDOMTopLevelTypeToString(topLevelType); 1367 } 1368 1369 /** 1370 * These variables store information about text content of a target node, 1371 * allowing comparison of content before and after a given event. 1372 * 1373 * Identify the node where selection currently begins, then observe 1374 * both its text content and its current position in the DOM. Since the 1375 * browser may natively replace the target node during composition, we can 1376 * use its position to find its replacement. 1377 * 1378 * 1379 */ 1380 1381 var root = null; 1382 var startText = null; 1383 var fallbackText = null; 1384 1385 function initialize(nativeEventTarget) { 1386 root = nativeEventTarget; 1387 startText = getText(); 1388 return true; 1389 } 1390 1391 function reset() { 1392 root = null; 1393 startText = null; 1394 fallbackText = null; 1395 } 1396 1397 function getData() { 1398 if (fallbackText) { 1399 return fallbackText; 1400 } 1401 1402 var start = void 0; 1403 var startValue = startText; 1404 var startLength = startValue.length; 1405 var end = void 0; 1406 var endValue = getText(); 1407 var endLength = endValue.length; 1408 1409 for (start = 0; start < startLength; start++) { 1410 if (startValue[start] !== endValue[start]) { 1411 break; 1412 } 1413 } 1414 1415 var minEnd = startLength - start; 1416 for (end = 1; end <= minEnd; end++) { 1417 if (startValue[startLength - end] !== endValue[endLength - end]) { 1418 break; 1419 } 1420 } 1421 1422 var sliceTail = end > 1 ? 1 - end : undefined; 1423 fallbackText = endValue.slice(start, sliceTail); 1424 return fallbackText; 1425 } 1426 1427 function getText() { 1428 if ('value' in root) { 1429 return root.value; 1430 } 1431 return root.textContent; 1432 } 1433 1434 var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; 1435 1436 var _assign = ReactInternals.assign; 1437 1438 /* eslint valid-typeof: 0 */ 1439 1440 var EVENT_POOL_SIZE = 10; 1441 1442 /** 1443 * @interface Event 1444 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 1445 */ 1446 var EventInterface = { 1447 type: null, 1448 target: null, 1449 // currentTarget is set when dispatching; no use in copying it here 1450 currentTarget: function () { 1451 return null; 1452 }, 1453 eventPhase: null, 1454 bubbles: null, 1455 cancelable: null, 1456 timeStamp: function (event) { 1457 return event.timeStamp || Date.now(); 1458 }, 1459 defaultPrevented: null, 1460 isTrusted: null 1461 }; 1462 1463 function functionThatReturnsTrue() { 1464 return true; 1465 } 1466 1467 function functionThatReturnsFalse() { 1468 return false; 1469 } 1470 1471 /** 1472 * Synthetic events are dispatched by event plugins, typically in response to a 1473 * top-level event delegation handler. 1474 * 1475 * These systems should generally use pooling to reduce the frequency of garbage 1476 * collection. The system should check `isPersistent` to determine whether the 1477 * event should be released into the pool after being dispatched. Users that 1478 * need a persisted event should invoke `persist`. 1479 * 1480 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by 1481 * normalizing browser quirks. Subclasses do not necessarily have to implement a 1482 * DOM interface; custom application-specific events can also subclass this. 1483 * 1484 * @param {object} dispatchConfig Configuration used to dispatch this event. 1485 * @param {*} targetInst Marker identifying the event target. 1486 * @param {object} nativeEvent Native browser event. 1487 * @param {DOMEventTarget} nativeEventTarget Target node. 1488 */ 1489 function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) { 1490 { 1491 // these have a getter/setter for warnings 1492 delete this.nativeEvent; 1493 delete this.preventDefault; 1494 delete this.stopPropagation; 1495 delete this.isDefaultPrevented; 1496 delete this.isPropagationStopped; 1497 } 1498 1499 this.dispatchConfig = dispatchConfig; 1500 this._targetInst = targetInst; 1501 this.nativeEvent = nativeEvent; 1502 1503 var Interface = this.constructor.Interface; 1504 for (var propName in Interface) { 1505 if (!Interface.hasOwnProperty(propName)) { 1506 continue; 1507 } 1508 { 1509 delete this[propName]; // this has a getter/setter for warnings 1510 } 1511 var normalize = Interface[propName]; 1512 if (normalize) { 1513 this[propName] = normalize(nativeEvent); 1514 } else { 1515 if (propName === 'target') { 1516 this.target = nativeEventTarget; 1517 } else { 1518 this[propName] = nativeEvent[propName]; 1519 } 1520 } 1521 } 1522 1523 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false; 1524 if (defaultPrevented) { 1525 this.isDefaultPrevented = functionThatReturnsTrue; 1526 } else { 1527 this.isDefaultPrevented = functionThatReturnsFalse; 1528 } 1529 this.isPropagationStopped = functionThatReturnsFalse; 1530 return this; 1531 } 1532 1533 _assign(SyntheticEvent.prototype, { 1534 preventDefault: function () { 1535 this.defaultPrevented = true; 1536 var event = this.nativeEvent; 1537 if (!event) { 1538 return; 1539 } 1540 1541 if (event.preventDefault) { 1542 event.preventDefault(); 1543 } else if (typeof event.returnValue !== 'unknown') { 1544 event.returnValue = false; 1545 } 1546 this.isDefaultPrevented = functionThatReturnsTrue; 1547 }, 1548 1549 stopPropagation: function () { 1550 var event = this.nativeEvent; 1551 if (!event) { 1552 return; 1553 } 1554 1555 if (event.stopPropagation) { 1556 event.stopPropagation(); 1557 } else if (typeof event.cancelBubble !== 'unknown') { 1558 // The ChangeEventPlugin registers a "propertychange" event for 1559 // IE. This event does not support bubbling or cancelling, and 1560 // any references to cancelBubble throw "Member not found". A 1561 // typeof check of "unknown" circumvents this issue (and is also 1562 // IE specific). 1563 event.cancelBubble = true; 1564 } 1565 1566 this.isPropagationStopped = functionThatReturnsTrue; 1567 }, 1568 1569 /** 1570 * We release all dispatched `SyntheticEvent`s after each event loop, adding 1571 * them back into the pool. This allows a way to hold onto a reference that 1572 * won't be added back into the pool. 1573 */ 1574 persist: function () { 1575 this.isPersistent = functionThatReturnsTrue; 1576 }, 1577 1578 /** 1579 * Checks if this event should be released back into the pool. 1580 * 1581 * @return {boolean} True if this should not be released, false otherwise. 1582 */ 1583 isPersistent: functionThatReturnsFalse, 1584 1585 /** 1586 * `PooledClass` looks for `destructor` on each instance it releases. 1587 */ 1588 destructor: function () { 1589 var Interface = this.constructor.Interface; 1590 for (var propName in Interface) { 1591 { 1592 Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName])); 1593 } 1594 } 1595 this.dispatchConfig = null; 1596 this._targetInst = null; 1597 this.nativeEvent = null; 1598 this.isDefaultPrevented = functionThatReturnsFalse; 1599 this.isPropagationStopped = functionThatReturnsFalse; 1600 this._dispatchListeners = null; 1601 this._dispatchInstances = null; 1602 { 1603 Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null)); 1604 Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse)); 1605 Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse)); 1606 Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {})); 1607 Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {})); 1608 } 1609 } 1610 }); 1611 1612 SyntheticEvent.Interface = EventInterface; 1613 1614 /** 1615 * Helper to reduce boilerplate when creating subclasses. 1616 */ 1617 SyntheticEvent.extend = function (Interface) { 1618 var Super = this; 1619 1620 var E = function () {}; 1621 E.prototype = Super.prototype; 1622 var prototype = new E(); 1623 1624 function Class() { 1625 return Super.apply(this, arguments); 1626 } 1627 _assign(prototype, Class.prototype); 1628 Class.prototype = prototype; 1629 Class.prototype.constructor = Class; 1630 1631 Class.Interface = _assign({}, Super.Interface, Interface); 1632 Class.extend = Super.extend; 1633 addEventPoolingTo(Class); 1634 1635 return Class; 1636 }; 1637 1638 addEventPoolingTo(SyntheticEvent); 1639 1640 /** 1641 * Helper to nullify syntheticEvent instance properties when destructing 1642 * 1643 * @param {String} propName 1644 * @param {?object} getVal 1645 * @return {object} defineProperty object 1646 */ 1647 function getPooledWarningPropertyDefinition(propName, getVal) { 1648 var isFunction = typeof getVal === 'function'; 1649 return { 1650 configurable: true, 1651 set: set, 1652 get: get 1653 }; 1654 1655 function set(val) { 1656 var action = isFunction ? 'setting the method' : 'setting the property'; 1657 warn(action, 'This is effectively a no-op'); 1658 return val; 1659 } 1660 1661 function get() { 1662 var action = isFunction ? 'accessing the method' : 'accessing the property'; 1663 var result = isFunction ? 'This is a no-op function' : 'This is set to null'; 1664 warn(action, result); 1665 return getVal; 1666 } 1667 1668 function warn(action, result) { 1669 var warningCondition = false; 1670 !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; 1671 } 1672 } 1673 1674 function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { 1675 var EventConstructor = this; 1676 if (EventConstructor.eventPool.length) { 1677 var instance = EventConstructor.eventPool.pop(); 1678 EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst); 1679 return instance; 1680 } 1681 return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst); 1682 } 1683 1684 function releasePooledEvent(event) { 1685 var EventConstructor = this; 1686 !(event instanceof EventConstructor) ? invariant(false, 'Trying to release an event instance into a pool of a different type.') : void 0; 1687 event.destructor(); 1688 if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { 1689 EventConstructor.eventPool.push(event); 1690 } 1691 } 1692 1693 function addEventPoolingTo(EventConstructor) { 1694 EventConstructor.eventPool = []; 1695 EventConstructor.getPooled = getPooledEvent; 1696 EventConstructor.release = releasePooledEvent; 1697 } 1698 1699 /** 1700 * @interface Event 1701 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents 1702 */ 1703 var SyntheticCompositionEvent = SyntheticEvent.extend({ 1704 data: null 1705 }); 1706 1707 /** 1708 * @interface Event 1709 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105 1710 * /#events-inputevents 1711 */ 1712 var SyntheticInputEvent = SyntheticEvent.extend({ 1713 data: null 1714 }); 1715 1716 var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space 1717 var START_KEYCODE = 229; 1718 1719 var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window; 1720 1721 var documentMode = null; 1722 if (canUseDOM && 'documentMode' in document) { 1723 documentMode = document.documentMode; 1724 } 1725 1726 // Webkit offers a very useful `textInput` event that can be used to 1727 // directly represent `beforeInput`. The IE `textinput` event is not as 1728 // useful, so we don't use it. 1729 var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode; 1730 1731 // In IE9+, we have access to composition events, but the data supplied 1732 // by the native compositionend event may be incorrect. Japanese ideographic 1733 // spaces, for instance (\u3000) are not recorded correctly. 1734 var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11); 1735 1736 var SPACEBAR_CODE = 32; 1737 var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); 1738 1739 // Events and their corresponding property names. 1740 var eventTypes = { 1741 beforeInput: { 1742 phasedRegistrationNames: { 1743 bubbled: 'onBeforeInput', 1744 captured: 'onBeforeInputCapture' 1745 }, 1746 dependencies: [TOP_COMPOSITION_END, TOP_KEY_PRESS, TOP_TEXT_INPUT, TOP_PASTE] 1747 }, 1748 compositionEnd: { 1749 phasedRegistrationNames: { 1750 bubbled: 'onCompositionEnd', 1751 captured: 'onCompositionEndCapture' 1752 }, 1753 dependencies: [TOP_BLUR, TOP_COMPOSITION_END, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN] 1754 }, 1755 compositionStart: { 1756 phasedRegistrationNames: { 1757 bubbled: 'onCompositionStart', 1758 captured: 'onCompositionStartCapture' 1759 }, 1760 dependencies: [TOP_BLUR, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN] 1761 }, 1762 compositionUpdate: { 1763 phasedRegistrationNames: { 1764 bubbled: 'onCompositionUpdate', 1765 captured: 'onCompositionUpdateCapture' 1766 }, 1767 dependencies: [TOP_BLUR, TOP_COMPOSITION_UPDATE, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN] 1768 } 1769 }; 1770 1771 // Track whether we've ever handled a keypress on the space key. 1772 var hasSpaceKeypress = false; 1773 1774 /** 1775 * Return whether a native keypress event is assumed to be a command. 1776 * This is required because Firefox fires `keypress` events for key commands 1777 * (cut, copy, select-all, etc.) even though no character is inserted. 1778 */ 1779 function isKeypressCommand(nativeEvent) { 1780 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && 1781 // ctrlKey && altKey is equivalent to AltGr, and is not a command. 1782 !(nativeEvent.ctrlKey && nativeEvent.altKey); 1783 } 1784 1785 /** 1786 * Translate native top level events into event types. 1787 * 1788 * @param {string} topLevelType 1789 * @return {object} 1790 */ 1791 function getCompositionEventType(topLevelType) { 1792 switch (topLevelType) { 1793 case TOP_COMPOSITION_START: 1794 return eventTypes.compositionStart; 1795 case TOP_COMPOSITION_END: 1796 return eventTypes.compositionEnd; 1797 case TOP_COMPOSITION_UPDATE: 1798 return eventTypes.compositionUpdate; 1799 } 1800 } 1801 1802 /** 1803 * Does our fallback best-guess model think this event signifies that 1804 * composition has begun? 1805 * 1806 * @param {string} topLevelType 1807 * @param {object} nativeEvent 1808 * @return {boolean} 1809 */ 1810 function isFallbackCompositionStart(topLevelType, nativeEvent) { 1811 return topLevelType === TOP_KEY_DOWN && nativeEvent.keyCode === START_KEYCODE; 1812 } 1813 1814 /** 1815 * Does our fallback mode think that this event is the end of composition? 1816 * 1817 * @param {string} topLevelType 1818 * @param {object} nativeEvent 1819 * @return {boolean} 1820 */ 1821 function isFallbackCompositionEnd(topLevelType, nativeEvent) { 1822 switch (topLevelType) { 1823 case TOP_KEY_UP: 1824 // Command keys insert or clear IME input. 1825 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1; 1826 case TOP_KEY_DOWN: 1827 // Expect IME keyCode on each keydown. If we get any other 1828 // code we must have exited earlier. 1829 return nativeEvent.keyCode !== START_KEYCODE; 1830 case TOP_KEY_PRESS: 1831 case TOP_MOUSE_DOWN: 1832 case TOP_BLUR: 1833 // Events are not possible without cancelling IME. 1834 return true; 1835 default: 1836 return false; 1837 } 1838 } 1839 1840 /** 1841 * Google Input Tools provides composition data via a CustomEvent, 1842 * with the `data` property populated in the `detail` object. If this 1843 * is available on the event object, use it. If not, this is a plain 1844 * composition event and we have nothing special to extract. 1845 * 1846 * @param {object} nativeEvent 1847 * @return {?string} 1848 */ 1849 function getDataFromCustomEvent(nativeEvent) { 1850 var detail = nativeEvent.detail; 1851 if (typeof detail === 'object' && 'data' in detail) { 1852 return detail.data; 1853 } 1854 return null; 1855 } 1856 1857 /** 1858 * Check if a composition event was triggered by Korean IME. 1859 * Our fallback mode does not work well with IE's Korean IME, 1860 * so just use native composition events when Korean IME is used. 1861 * Although CompositionEvent.locale property is deprecated, 1862 * it is available in IE, where our fallback mode is enabled. 1863 * 1864 * @param {object} nativeEvent 1865 * @return {boolean} 1866 */ 1867 function isUsingKoreanIME(nativeEvent) { 1868 return nativeEvent.locale === 'ko'; 1869 } 1870 1871 // Track the current IME composition status, if any. 1872 var isComposing = false; 1873 1874 /** 1875 * @return {?object} A SyntheticCompositionEvent. 1876 */ 1877 function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) { 1878 var eventType = void 0; 1879 var fallbackData = void 0; 1880 1881 if (canUseCompositionEvent) { 1882 eventType = getCompositionEventType(topLevelType); 1883 } else if (!isComposing) { 1884 if (isFallbackCompositionStart(topLevelType, nativeEvent)) { 1885 eventType = eventTypes.compositionStart; 1886 } 1887 } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) { 1888 eventType = eventTypes.compositionEnd; 1889 } 1890 1891 if (!eventType) { 1892 return null; 1893 } 1894 1895 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) { 1896 // The current composition is stored statically and must not be 1897 // overwritten while composition continues. 1898 if (!isComposing && eventType === eventTypes.compositionStart) { 1899 isComposing = initialize(nativeEventTarget); 1900 } else if (eventType === eventTypes.compositionEnd) { 1901 if (isComposing) { 1902 fallbackData = getData(); 1903 } 1904 } 1905 } 1906 1907 var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget); 1908 1909 if (fallbackData) { 1910 // Inject data generated from fallback path into the synthetic event. 1911 // This matches the property of native CompositionEventInterface. 1912 event.data = fallbackData; 1913 } else { 1914 var customData = getDataFromCustomEvent(nativeEvent); 1915 if (customData !== null) { 1916 event.data = customData; 1917 } 1918 } 1919 1920 accumulateTwoPhaseDispatches(event); 1921 return event; 1922 } 1923 1924 /** 1925 * @param {TopLevelType} topLevelType Number from `TopLevelType`. 1926 * @param {object} nativeEvent Native browser event. 1927 * @return {?string} The string corresponding to this `beforeInput` event. 1928 */ 1929 function getNativeBeforeInputChars(topLevelType, nativeEvent) { 1930 switch (topLevelType) { 1931 case TOP_COMPOSITION_END: 1932 return getDataFromCustomEvent(nativeEvent); 1933 case TOP_KEY_PRESS: 1934 /** 1935 * If native `textInput` events are available, our goal is to make 1936 * use of them. However, there is a special case: the spacebar key. 1937 * In Webkit, preventing default on a spacebar `textInput` event 1938 * cancels character insertion, but it *also* causes the browser 1939 * to fall back to its default spacebar behavior of scrolling the 1940 * page. 1941 * 1942 * Tracking at: 1943 * https://code.google.com/p/chromium/issues/detail?id=355103 1944 * 1945 * To avoid this issue, use the keypress event as if no `textInput` 1946 * event is available. 1947 */ 1948 var which = nativeEvent.which; 1949 if (which !== SPACEBAR_CODE) { 1950 return null; 1951 } 1952 1953 hasSpaceKeypress = true; 1954 return SPACEBAR_CHAR; 1955 1956 case TOP_TEXT_INPUT: 1957 // Record the characters to be added to the DOM. 1958 var chars = nativeEvent.data; 1959 1960 // If it's a spacebar character, assume that we have already handled 1961 // it at the keypress level and bail immediately. Android Chrome 1962 // doesn't give us keycodes, so we need to ignore it. 1963 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) { 1964 return null; 1965 } 1966 1967 return chars; 1968 1969 default: 1970 // For other native event types, do nothing. 1971 return null; 1972 } 1973 } 1974 1975 /** 1976 * For browsers that do not provide the `textInput` event, extract the 1977 * appropriate string to use for SyntheticInputEvent. 1978 * 1979 * @param {number} topLevelType Number from `TopLevelEventTypes`. 1980 * @param {object} nativeEvent Native browser event. 1981 * @return {?string} The fallback string for this `beforeInput` event. 1982 */ 1983 function getFallbackBeforeInputChars(topLevelType, nativeEvent) { 1984 // If we are currently composing (IME) and using a fallback to do so, 1985 // try to extract the composed characters from the fallback object. 1986 // If composition event is available, we extract a string only at 1987 // compositionevent, otherwise extract it at fallback events. 1988 if (isComposing) { 1989 if (topLevelType === TOP_COMPOSITION_END || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) { 1990 var chars = getData(); 1991 reset(); 1992 isComposing = false; 1993 return chars; 1994 } 1995 return null; 1996 } 1997 1998 switch (topLevelType) { 1999 case TOP_PASTE: 2000 // If a paste event occurs after a keypress, throw out the input 2001 // chars. Paste events should not lead to BeforeInput events. 2002 return null; 2003 case TOP_KEY_PRESS: 2004 /** 2005 * As of v27, Firefox may fire keypress events even when no character 2006 * will be inserted. A few possibilities: 2007 * 2008 * - `which` is `0`. Arrow keys, Esc key, etc. 2009 * 2010 * - `which` is the pressed key code, but no char is available. 2011 * Ex: 'AltGr + d` in Polish. There is no modified character for 2012 * this key combination and no character is inserted into the 2013 * document, but FF fires the keypress for char code `100` anyway. 2014 * No `input` event will occur. 2015 * 2016 * - `which` is the pressed key code, but a command combination is 2017 * being used. Ex: `Cmd+C`. No character is inserted, and no 2018 * `input` event will occur. 2019 */ 2020 if (!isKeypressCommand(nativeEvent)) { 2021 // IE fires the `keypress` event when a user types an emoji via 2022 // Touch keyboard of Windows. In such a case, the `char` property 2023 // holds an emoji character like `\uD83D\uDE0A`. Because its length 2024 // is 2, the property `which` does not represent an emoji correctly. 2025 // In such a case, we directly return the `char` property instead of 2026 // using `which`. 2027 if (nativeEvent.char && nativeEvent.char.length > 1) { 2028 return nativeEvent.char; 2029 } else if (nativeEvent.which) { 2030 return String.fromCharCode(nativeEvent.which); 2031 } 2032 } 2033 return null; 2034 case TOP_COMPOSITION_END: 2035 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data; 2036 default: 2037 return null; 2038 } 2039 } 2040 2041 /** 2042 * Extract a SyntheticInputEvent for `beforeInput`, based on either native 2043 * `textInput` or fallback behavior. 2044 * 2045 * @return {?object} A SyntheticInputEvent. 2046 */ 2047 function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) { 2048 var chars = void 0; 2049 2050 if (canUseTextInputEvent) { 2051 chars = getNativeBeforeInputChars(topLevelType, nativeEvent); 2052 } else { 2053 chars = getFallbackBeforeInputChars(topLevelType, nativeEvent); 2054 } 2055 2056 // If no characters are being inserted, no BeforeInput event should 2057 // be fired. 2058 if (!chars) { 2059 return null; 2060 } 2061 2062 var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget); 2063 2064 event.data = chars; 2065 accumulateTwoPhaseDispatches(event); 2066 return event; 2067 } 2068 2069 /** 2070 * Create an `onBeforeInput` event to match 2071 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents. 2072 * 2073 * This event plugin is based on the native `textInput` event 2074 * available in Chrome, Safari, Opera, and IE. This event fires after 2075 * `onKeyPress` and `onCompositionEnd`, but before `onInput`. 2076 * 2077 * `beforeInput` is spec'd but not implemented in any browsers, and 2078 * the `input` event does not provide any useful information about what has 2079 * actually been added, contrary to the spec. Thus, `textInput` is the best 2080 * available event to identify the characters that have actually been inserted 2081 * into the target node. 2082 * 2083 * This plugin is also responsible for emitting `composition` events, thus 2084 * allowing us to share composition fallback code for both `beforeInput` and 2085 * `composition` event types. 2086 */ 2087 var BeforeInputEventPlugin = { 2088 eventTypes: eventTypes, 2089 2090 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { 2091 var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget); 2092 2093 var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget); 2094 2095 if (composition === null) { 2096 return beforeInput; 2097 } 2098 2099 if (beforeInput === null) { 2100 return composition; 2101 } 2102 2103 return [composition, beforeInput]; 2104 } 2105 }; 2106 2107 // Use to restore controlled state after a change event has fired. 2108 2109 var restoreImpl = null; 2110 var restoreTarget = null; 2111 var restoreQueue = null; 2112 2113 function restoreStateOfTarget(target) { 2114 // We perform this translation at the end of the event loop so that we 2115 // always receive the correct fiber here 2116 var internalInstance = getInstanceFromNode(target); 2117 if (!internalInstance) { 2118 // Unmounted 2119 return; 2120 } 2121 !(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; 2122 var props = getFiberCurrentPropsFromNode(internalInstance.stateNode); 2123 restoreImpl(internalInstance.stateNode, internalInstance.type, props); 2124 } 2125 2126 function setRestoreImplementation(impl) { 2127 restoreImpl = impl; 2128 } 2129 2130 function enqueueStateRestore(target) { 2131 if (restoreTarget) { 2132 if (restoreQueue) { 2133 restoreQueue.push(target); 2134 } else { 2135 restoreQueue = [target]; 2136 } 2137 } else { 2138 restoreTarget = target; 2139 } 2140 } 2141 2142 function needsStateRestore() { 2143 return restoreTarget !== null || restoreQueue !== null; 2144 } 2145 2146 function restoreStateIfNeeded() { 2147 if (!restoreTarget) { 2148 return; 2149 } 2150 var target = restoreTarget; 2151 var queuedTargets = restoreQueue; 2152 restoreTarget = null; 2153 restoreQueue = null; 2154 2155 restoreStateOfTarget(target); 2156 if (queuedTargets) { 2157 for (var i = 0; i < queuedTargets.length; i++) { 2158 restoreStateOfTarget(queuedTargets[i]); 2159 } 2160 } 2161 } 2162 2163 // Used as a way to call batchedUpdates when we don't have a reference to 2164 // the renderer. Such as when we're dispatching events or if third party 2165 // libraries need to call batchedUpdates. Eventually, this API will go away when 2166 // everything is batched by default. We'll then have a similar API to opt-out of 2167 // scheduled work and instead do synchronous work. 2168 2169 // Defaults 2170 var _batchedUpdatesImpl = function (fn, bookkeeping) { 2171 return fn(bookkeeping); 2172 }; 2173 var _interactiveUpdatesImpl = function (fn, a, b) { 2174 return fn(a, b); 2175 }; 2176 var _flushInteractiveUpdatesImpl = function () {}; 2177 2178 var isBatching = false; 2179 function batchedUpdates(fn, bookkeeping) { 2180 if (isBatching) { 2181 // If we are currently inside another batch, we need to wait until it 2182 // fully completes before restoring state. 2183 return fn(bookkeeping); 2184 } 2185 isBatching = true; 2186 try { 2187 return _batchedUpdatesImpl(fn, bookkeeping); 2188 } finally { 2189 // Here we wait until all updates have propagated, which is important 2190 // when using controlled components within layers: 2191 // https://github.com/facebook/react/issues/1698 2192 // Then we restore state of any controlled component. 2193 isBatching = false; 2194 var controlledComponentsHavePendingUpdates = needsStateRestore(); 2195 if (controlledComponentsHavePendingUpdates) { 2196 // If a controlled event was fired, we may need to restore the state of 2197 // the DOM node back to the controlled value. This is necessary when React 2198 // bails out of the update without touching the DOM. 2199 _flushInteractiveUpdatesImpl(); 2200 restoreStateIfNeeded(); 2201 } 2202 } 2203 } 2204 2205 function interactiveUpdates(fn, a, b) { 2206 return _interactiveUpdatesImpl(fn, a, b); 2207 } 2208 2209 2210 2211 function setBatchingImplementation(batchedUpdatesImpl, interactiveUpdatesImpl, flushInteractiveUpdatesImpl) { 2212 _batchedUpdatesImpl = batchedUpdatesImpl; 2213 _interactiveUpdatesImpl = interactiveUpdatesImpl; 2214 _flushInteractiveUpdatesImpl = flushInteractiveUpdatesImpl; 2215 } 2216 2217 /** 2218 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary 2219 */ 2220 var supportedInputTypes = { 2221 color: true, 2222 date: true, 2223 datetime: true, 2224 'datetime-local': true, 2225 email: true, 2226 month: true, 2227 number: true, 2228 password: true, 2229 range: true, 2230 search: true, 2231 tel: true, 2232 text: true, 2233 time: true, 2234 url: true, 2235 week: true 2236 }; 2237 2238 function isTextInputElement(elem) { 2239 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); 2240 2241 if (nodeName === 'input') { 2242 return !!supportedInputTypes[elem.type]; 2243 } 2244 2245 if (nodeName === 'textarea') { 2246 return true; 2247 } 2248 2249 return false; 2250 } 2251 2252 /** 2253 * HTML nodeType values that represent the type of the node 2254 */ 2255 2256 var ELEMENT_NODE = 1; 2257 var TEXT_NODE = 3; 2258 var COMMENT_NODE = 8; 2259 var DOCUMENT_NODE = 9; 2260 var DOCUMENT_FRAGMENT_NODE = 11; 2261 2262 /** 2263 * Gets the target node from a native browser event by accounting for 2264 * inconsistencies in browser DOM APIs. 2265 * 2266 * @param {object} nativeEvent Native browser event. 2267 * @return {DOMEventTarget} Target node. 2268 */ 2269 function getEventTarget(nativeEvent) { 2270 // Fallback to nativeEvent.srcElement for IE9 2271 // https://github.com/facebook/react/issues/12506 2272 var target = nativeEvent.target || nativeEvent.srcElement || window; 2273 2274 // Normalize SVG <use> element events #4963 2275 if (target.correspondingUseElement) { 2276 target = target.correspondingUseElement; 2277 } 2278 2279 // Safari may fire events on text nodes (Node.TEXT_NODE is 3). 2280 // @see http://www.quirksmode.org/js/events_properties.html 2281 return target.nodeType === TEXT_NODE ? target.parentNode : target; 2282 } 2283 2284 /** 2285 * Checks if an event is supported in the current execution environment. 2286 * 2287 * NOTE: This will not work correctly for non-generic events such as `change`, 2288 * `reset`, `load`, `error`, and `select`. 2289 * 2290 * Borrows from Modernizr. 2291 * 2292 * @param {string} eventNameSuffix Event name, e.g. "click". 2293 * @return {boolean} True if the event is supported. 2294 * @internal 2295 * @license Modernizr 3.0.0pre (Custom Build) | MIT 2296 */ 2297 function isEventSupported(eventNameSuffix) { 2298 if (!canUseDOM) { 2299 return false; 2300 } 2301 2302 var eventName = 'on' + eventNameSuffix; 2303 var isSupported = eventName in document; 2304 2305 if (!isSupported) { 2306 var element = document.createElement('div'); 2307 element.setAttribute(eventName, 'return;'); 2308 isSupported = typeof element[eventName] === 'function'; 2309 } 2310 2311 return isSupported; 2312 } 2313 2314 function isCheckable(elem) { 2315 var type = elem.type; 2316 var nodeName = elem.nodeName; 2317 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio'); 2318 } 2319 2320 function getTracker(node) { 2321 return node._valueTracker; 2322 } 2323 2324 function detachTracker(node) { 2325 node._valueTracker = null; 2326 } 2327 2328 function getValueFromNode(node) { 2329 var value = ''; 2330 if (!node) { 2331 return value; 2332 } 2333 2334 if (isCheckable(node)) { 2335 value = node.checked ? 'true' : 'false'; 2336 } else { 2337 value = node.value; 2338 } 2339 2340 return value; 2341 } 2342 2343 function trackValueOnNode(node) { 2344 var valueField = isCheckable(node) ? 'checked' : 'value'; 2345 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField); 2346 2347 var currentValue = '' + node[valueField]; 2348 2349 // if someone has already defined a value or Safari, then bail 2350 // and don't track value will cause over reporting of changes, 2351 // but it's better then a hard failure 2352 // (needed for certain tests that spyOn input values and Safari) 2353 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') { 2354 return; 2355 } 2356 var get = descriptor.get, 2357 set = descriptor.set; 2358 2359 Object.defineProperty(node, valueField, { 2360 configurable: true, 2361 get: function () { 2362 return get.call(this); 2363 }, 2364 set: function (value) { 2365 currentValue = '' + value; 2366 set.call(this, value); 2367 } 2368 }); 2369 // We could've passed this the first time 2370 // but it triggers a bug in IE11 and Edge 14/15. 2371 // Calling defineProperty() again should be equivalent. 2372 // https://github.com/facebook/react/issues/11768 2373 Object.defineProperty(node, valueField, { 2374 enumerable: descriptor.enumerable 2375 }); 2376 2377 var tracker = { 2378 getValue: function () { 2379 return currentValue; 2380 }, 2381 setValue: function (value) { 2382 currentValue = '' + value; 2383 }, 2384 stopTracking: function () { 2385 detachTracker(node); 2386 delete node[valueField]; 2387 } 2388 }; 2389 return tracker; 2390 } 2391 2392 function track(node) { 2393 if (getTracker(node)) { 2394 return; 2395 } 2396 2397 // TODO: Once it's just Fiber we can move this to node._wrapperState 2398 node._valueTracker = trackValueOnNode(node); 2399 } 2400 2401 function updateValueIfChanged(node) { 2402 if (!node) { 2403 return false; 2404 } 2405 2406 var tracker = getTracker(node); 2407 // if there is no tracker at this point it's unlikely 2408 // that trying again will succeed 2409 if (!tracker) { 2410 return true; 2411 } 2412 2413 var lastValue = tracker.getValue(); 2414 var nextValue = getValueFromNode(node); 2415 if (nextValue !== lastValue) { 2416 tracker.setValue(nextValue); 2417 return true; 2418 } 2419 return false; 2420 } 2421 2422 var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; 2423 2424 var BEFORE_SLASH_RE = /^(.*)[\\\/]/; 2425 2426 var describeComponentFrame = function (name, source, ownerName) { 2427 var sourceInfo = ''; 2428 if (source) { 2429 var path = source.fileName; 2430 var fileName = path.replace(BEFORE_SLASH_RE, ''); 2431 { 2432 // In DEV, include code for a common special case: 2433 // prefer "folder/index.js" instead of just "index.js". 2434 if (/^index\./.test(fileName)) { 2435 var match = path.match(BEFORE_SLASH_RE); 2436 if (match) { 2437 var pathBeforeSlash = match[1]; 2438 if (pathBeforeSlash) { 2439 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ''); 2440 fileName = folderName + '/' + fileName; 2441 } 2442 } 2443 } 2444 } 2445 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')'; 2446 } else if (ownerName) { 2447 sourceInfo = ' (created by ' + ownerName + ')'; 2448 } 2449 return '\n in ' + (name || 'Unknown') + sourceInfo; 2450 }; 2451 2452 // The Symbol used to tag the ReactElement-like types. If there is no native Symbol 2453 // nor polyfill, then a plain number is used for performance. 2454 var hasSymbol = typeof Symbol === 'function' && Symbol.for; 2455 2456 var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7; 2457 var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca; 2458 var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb; 2459 var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc; 2460 var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2; 2461 var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd; 2462 var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; 2463 var REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for('react.async_mode') : 0xeacf; 2464 var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0; 2465 var REACT_PLACEHOLDER_TYPE = hasSymbol ? Symbol.for('react.placeholder') : 0xead1; 2466 2467 var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; 2468 var FAUX_ITERATOR_SYMBOL = '@@iterator'; 2469 2470 function getIteratorFn(maybeIterable) { 2471 if (maybeIterable === null || typeof maybeIterable !== 'object') { 2472 return null; 2473 } 2474 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]; 2475 if (typeof maybeIterator === 'function') { 2476 return maybeIterator; 2477 } 2478 return null; 2479 } 2480 2481 var Pending = 0; 2482 var Resolved = 1; 2483 var Rejected = 2; 2484 2485 function getResultFromResolvedThenable(thenable) { 2486 return thenable._reactResult; 2487 } 2488 2489 function refineResolvedThenable(thenable) { 2490 return thenable._reactStatus === Resolved ? thenable._reactResult : null; 2491 } 2492 2493 function getComponentName(type) { 2494 if (type == null) { 2495 // Host root, text node or just invalid type. 2496 return null; 2497 } 2498 { 2499 if (typeof type.tag === 'number') { 2500 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.'); 2501 } 2502 } 2503 if (typeof type === 'function') { 2504 return type.displayName || type.name || null; 2505 } 2506 if (typeof type === 'string') { 2507 return type; 2508 } 2509 switch (type) { 2510 case REACT_ASYNC_MODE_TYPE: 2511 return 'AsyncMode'; 2512 case REACT_FRAGMENT_TYPE: 2513 return 'Fragment'; 2514 case REACT_PORTAL_TYPE: 2515 return 'Portal'; 2516 case REACT_PROFILER_TYPE: 2517 return 'Profiler'; 2518 case REACT_STRICT_MODE_TYPE: 2519 return 'StrictMode'; 2520 case REACT_PLACEHOLDER_TYPE: 2521 return 'Placeholder'; 2522 } 2523 if (typeof type === 'object') { 2524 switch (type.$$typeof) { 2525 case REACT_CONTEXT_TYPE: 2526 return 'Context.Consumer'; 2527 case REACT_PROVIDER_TYPE: 2528 return 'Context.Provider'; 2529 case REACT_FORWARD_REF_TYPE: 2530 var renderFn = type.render; 2531 var functionName = renderFn.displayName || renderFn.name || ''; 2532 return type.displayName || (functionName !== '' ? 'ForwardRef(' + functionName + ')' : 'ForwardRef'); 2533 } 2534 if (typeof type.then === 'function') { 2535 var thenable = type; 2536 var resolvedThenable = refineResolvedThenable(thenable); 2537 if (resolvedThenable) { 2538 return getComponentName(resolvedThenable); 2539 } 2540 } 2541 } 2542 return null; 2543 } 2544 2545 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; 2546 2547 function describeFiber(fiber) { 2548 switch (fiber.tag) { 2549 case IndeterminateComponent: 2550 case FunctionalComponent: 2551 case FunctionalComponentLazy: 2552 case ClassComponent: 2553 case ClassComponentLazy: 2554 case HostComponent: 2555 case Mode: 2556 var owner = fiber._debugOwner; 2557 var source = fiber._debugSource; 2558 var name = getComponentName(fiber.type); 2559 var ownerName = null; 2560 if (owner) { 2561 ownerName = getComponentName(owner.type); 2562 } 2563 return describeComponentFrame(name, source, ownerName); 2564 default: 2565 return ''; 2566 } 2567 } 2568 2569 function getStackByFiberInDevAndProd(workInProgress) { 2570 var info = ''; 2571 var node = workInProgress; 2572 do { 2573 info += describeFiber(node); 2574 node = node.return; 2575 } while (node); 2576 return info; 2577 } 2578 2579 var current = null; 2580 var phase = null; 2581 2582 function getCurrentFiberOwnerNameInDevOrNull() { 2583 { 2584 if (current === null) { 2585 return null; 2586 } 2587 var owner = current._debugOwner; 2588 if (owner !== null && typeof owner !== 'undefined') { 2589 return getComponentName(owner.type); 2590 } 2591 } 2592 return null; 2593 } 2594 2595 function getCurrentFiberStackInDev() { 2596 { 2597 if (current === null) { 2598 return ''; 2599 } 2600 // Safe because if current fiber exists, we are reconciling, 2601 // and it is guaranteed to be the work-in-progress version. 2602 return getStackByFiberInDevAndProd(current); 2603 } 2604 return ''; 2605 } 2606 2607 function resetCurrentFiber() { 2608 { 2609 ReactDebugCurrentFrame.getCurrentStack = null; 2610 current = null; 2611 phase = null; 2612 } 2613 } 2614 2615 function setCurrentFiber(fiber) { 2616 { 2617 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev; 2618 current = fiber; 2619 phase = null; 2620 } 2621 } 2622 2623 function setCurrentPhase(lifeCyclePhase) { 2624 { 2625 phase = lifeCyclePhase; 2626 } 2627 } 2628 2629 /** 2630 * Similar to invariant but only logs a warning if the condition is not met. 2631 * This can be used to log issues in development environments in critical 2632 * paths. Removing the logging code for production environments will keep the 2633 * same logic and follow the same code paths. 2634 */ 2635 2636 var warning = warningWithoutStack$1; 2637 2638 { 2639 warning = function (condition, format) { 2640 if (condition) { 2641 return; 2642 } 2643 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; 2644 var stack = ReactDebugCurrentFrame.getStackAddendum(); 2645 // eslint-disable-next-line react-internal/warning-and-invariant-args 2646 2647 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { 2648 args[_key - 2] = arguments[_key]; 2649 } 2650 2651 warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack])); 2652 }; 2653 } 2654 2655 var warning$1 = warning; 2656 2657 // A reserved attribute. 2658 // It is handled by React separately and shouldn't be written to the DOM. 2659 var RESERVED = 0; 2660 2661 // A simple string attribute. 2662 // Attributes that aren't in the whitelist are presumed to have this type. 2663 var STRING = 1; 2664 2665 // A string attribute that accepts booleans in React. In HTML, these are called 2666 // "enumerated" attributes with "true" and "false" as possible values. 2667 // When true, it should be set to a "true" string. 2668 // When false, it should be set to a "false" string. 2669 var BOOLEANISH_STRING = 2; 2670 2671 // A real boolean attribute. 2672 // When true, it should be present (set either to an empty string or its name). 2673 // When false, it should be omitted. 2674 var BOOLEAN = 3; 2675 2676 // An attribute that can be used as a flag as well as with a value. 2677 // When true, it should be present (set either to an empty string or its name). 2678 // When false, it should be omitted. 2679 // For any other value, should be present with that value. 2680 var OVERLOADED_BOOLEAN = 4; 2681 2682 // An attribute that must be numeric or parse as a numeric. 2683 // When falsy, it should be removed. 2684 var NUMERIC = 5; 2685 2686 // An attribute that must be positive numeric or parse as a positive numeric. 2687 // When falsy, it should be removed. 2688 var POSITIVE_NUMERIC = 6; 2689 2690 /* eslint-disable max-len */ 2691 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'; 2692 /* eslint-enable max-len */ 2693 var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040'; 2694 2695 2696 var ROOT_ATTRIBUTE_NAME = 'data-reactroot'; 2697 var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$'); 2698 2699 var hasOwnProperty = Object.prototype.hasOwnProperty; 2700 var illegalAttributeNameCache = {}; 2701 var validatedAttributeNameCache = {}; 2702 2703 function isAttributeNameSafe(attributeName) { 2704 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) { 2705 return true; 2706 } 2707 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) { 2708 return false; 2709 } 2710 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { 2711 validatedAttributeNameCache[attributeName] = true; 2712 return true; 2713 } 2714 illegalAttributeNameCache[attributeName] = true; 2715 { 2716 warning$1(false, 'Invalid attribute name: `%s`', attributeName); 2717 } 2718 return false; 2719 } 2720 2721 function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) { 2722 if (propertyInfo !== null) { 2723 return propertyInfo.type === RESERVED; 2724 } 2725 if (isCustomComponentTag) { 2726 return false; 2727 } 2728 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) { 2729 return true; 2730 } 2731 return false; 2732 } 2733 2734 function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) { 2735 if (propertyInfo !== null && propertyInfo.type === RESERVED) { 2736 return false; 2737 } 2738 switch (typeof value) { 2739 case 'function': 2740 // $FlowIssue symbol is perfectly valid here 2741 case 'symbol': 2742 // eslint-disable-line 2743 return true; 2744 case 'boolean': 2745 { 2746 if (isCustomComponentTag) { 2747 return false; 2748 } 2749 if (propertyInfo !== null) { 2750 return !propertyInfo.acceptsBooleans; 2751 } else { 2752 var prefix = name.toLowerCase().slice(0, 5); 2753 return prefix !== 'data-' && prefix !== 'aria-'; 2754 } 2755 } 2756 default: 2757 return false; 2758 } 2759 } 2760 2761 function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) { 2762 if (value === null || typeof value === 'undefined') { 2763 return true; 2764 } 2765 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) { 2766 return true; 2767 } 2768 if (isCustomComponentTag) { 2769 return false; 2770 } 2771 if (propertyInfo !== null) { 2772 switch (propertyInfo.type) { 2773 case BOOLEAN: 2774 return !value; 2775 case OVERLOADED_BOOLEAN: 2776 return value === false; 2777 case NUMERIC: 2778 return isNaN(value); 2779 case POSITIVE_NUMERIC: 2780 return isNaN(value) || value < 1; 2781 } 2782 } 2783 return false; 2784 } 2785 2786 function getPropertyInfo(name) { 2787 return properties.hasOwnProperty(name) ? properties[name] : null; 2788 } 2789 2790 function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace) { 2791 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN; 2792 this.attributeName = attributeName; 2793 this.attributeNamespace = attributeNamespace; 2794 this.mustUseProperty = mustUseProperty; 2795 this.propertyName = name; 2796 this.type = type; 2797 } 2798 2799 // When adding attributes to this list, be sure to also add them to 2800 // the `possibleStandardNames` module to ensure casing and incorrect 2801 // name warnings. 2802 var properties = {}; 2803 2804 // These props are reserved by React. They shouldn't be written to the DOM. 2805 ['children', 'dangerouslySetInnerHTML', 2806 // TODO: This prevents the assignment of defaultValue to regular 2807 // elements (not just inputs). Now that ReactDOMInput assigns to the 2808 // defaultValue property -- do we need this? 2809 'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) { 2810 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty 2811 name, // attributeName 2812 null); 2813 } // attributeNamespace 2814 ); 2815 2816 // A few React string attributes have a different name. 2817 // This is a mapping from React prop names to the attribute names. 2818 [['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) { 2819 var name = _ref[0], 2820 attributeName = _ref[1]; 2821 2822 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 2823 attributeName, // attributeName 2824 null); 2825 } // attributeNamespace 2826 ); 2827 2828 // These are "enumerated" HTML attributes that accept "true" and "false". 2829 // In React, we let users pass `true` and `false` even though technically 2830 // these aren't boolean attributes (they are coerced to strings). 2831 ['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) { 2832 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty 2833 name.toLowerCase(), // attributeName 2834 null); 2835 } // attributeNamespace 2836 ); 2837 2838 // These are "enumerated" SVG attributes that accept "true" and "false". 2839 // In React, we let users pass `true` and `false` even though technically 2840 // these aren't boolean attributes (they are coerced to strings). 2841 // Since these are SVG attributes, their attribute names are case-sensitive. 2842 ['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) { 2843 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty 2844 name, // attributeName 2845 null); 2846 } // attributeNamespace 2847 ); 2848 2849 // These are HTML boolean attributes. 2850 ['allowFullScreen', 'async', 2851 // Note: there is a special case that prevents it from being written to the DOM 2852 // on the client side because the browsers are inconsistent. Instead we call focus(). 2853 'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', 2854 // Microdata 2855 'itemScope'].forEach(function (name) { 2856 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty 2857 name.toLowerCase(), // attributeName 2858 null); 2859 } // attributeNamespace 2860 ); 2861 2862 // These are the few React props that we set as DOM properties 2863 // rather than attributes. These are all booleans. 2864 ['checked', 2865 // Note: `option.selected` is not updated if `select.multiple` is 2866 // disabled with `removeAttribute`. We have special logic for handling this. 2867 'multiple', 'muted', 'selected'].forEach(function (name) { 2868 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty 2869 name, // attributeName 2870 null); 2871 } // attributeNamespace 2872 ); 2873 2874 // These are HTML attributes that are "overloaded booleans": they behave like 2875 // booleans, but can also accept a string value. 2876 ['capture', 'download'].forEach(function (name) { 2877 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty 2878 name, // attributeName 2879 null); 2880 } // attributeNamespace 2881 ); 2882 2883 // These are HTML attributes that must be positive numbers. 2884 ['cols', 'rows', 'size', 'span'].forEach(function (name) { 2885 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty 2886 name, // attributeName 2887 null); 2888 } // attributeNamespace 2889 ); 2890 2891 // These are HTML attributes that must be numbers. 2892 ['rowSpan', 'start'].forEach(function (name) { 2893 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty 2894 name.toLowerCase(), // attributeName 2895 null); 2896 } // attributeNamespace 2897 ); 2898 2899 var CAMELIZE = /[\-\:]([a-z])/g; 2900 var capitalize = function (token) { 2901 return token[1].toUpperCase(); 2902 }; 2903 2904 // This is a list of all SVG attributes that need special casing, namespacing, 2905 // or boolean value assignment. Regular attributes that just accept strings 2906 // and have the same names are omitted, just like in the HTML whitelist. 2907 // Some of these attributes can be hard to find. This list was created by 2908 // scrapping the MDN documentation. 2909 ['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) { 2910 var name = attributeName.replace(CAMELIZE, capitalize); 2911 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 2912 attributeName, null); 2913 } // attributeNamespace 2914 ); 2915 2916 // String SVG attributes with the xlink namespace. 2917 ['xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) { 2918 var name = attributeName.replace(CAMELIZE, capitalize); 2919 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 2920 attributeName, 'http://www.w3.org/1999/xlink'); 2921 }); 2922 2923 // String SVG attributes with the xml namespace. 2924 ['xml:base', 'xml:lang', 'xml:space'].forEach(function (attributeName) { 2925 var name = attributeName.replace(CAMELIZE, capitalize); 2926 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 2927 attributeName, 'http://www.w3.org/XML/1998/namespace'); 2928 }); 2929 2930 // Special case: this attribute exists both in HTML and SVG. 2931 // Its "tabindex" attribute name is case-sensitive in SVG so we can't just use 2932 // its React `tabIndex` name, like we do for attributes that exist only in HTML. 2933 properties.tabIndex = new PropertyInfoRecord('tabIndex', STRING, false, // mustUseProperty 2934 'tabindex', // attributeName 2935 null); 2936 2937 /** 2938 * Get the value for a property on a node. Only used in DEV for SSR validation. 2939 * The "expected" argument is used as a hint of what the expected value is. 2940 * Some properties have multiple equivalent values. 2941 */ 2942 function getValueForProperty(node, name, expected, propertyInfo) { 2943 { 2944 if (propertyInfo.mustUseProperty) { 2945 var propertyName = propertyInfo.propertyName; 2946 2947 return node[propertyName]; 2948 } else { 2949 var attributeName = propertyInfo.attributeName; 2950 2951 var stringValue = null; 2952 2953 if (propertyInfo.type === OVERLOADED_BOOLEAN) { 2954 if (node.hasAttribute(attributeName)) { 2955 var value = node.getAttribute(attributeName); 2956 if (value === '') { 2957 return true; 2958 } 2959 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) { 2960 return value; 2961 } 2962 if (value === '' + expected) { 2963 return expected; 2964 } 2965 return value; 2966 } 2967 } else if (node.hasAttribute(attributeName)) { 2968 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) { 2969 // We had an attribute but shouldn't have had one, so read it 2970 // for the error message. 2971 return node.getAttribute(attributeName); 2972 } 2973 if (propertyInfo.type === BOOLEAN) { 2974 // If this was a boolean, it doesn't matter what the value is 2975 // the fact that we have it is the same as the expected. 2976 return expected; 2977 } 2978 // Even if this property uses a namespace we use getAttribute 2979 // because we assume its namespaced name is the same as our config. 2980 // To use getAttributeNS we need the local name which we don't have 2981 // in our config atm. 2982 stringValue = node.getAttribute(attributeName); 2983 } 2984 2985 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) { 2986 return stringValue === null ? expected : stringValue; 2987 } else if (stringValue === '' + expected) { 2988 return expected; 2989 } else { 2990 return stringValue; 2991 } 2992 } 2993 } 2994 } 2995 2996 /** 2997 * Get the value for a attribute on a node. Only used in DEV for SSR validation. 2998 * The third argument is used as a hint of what the expected value is. Some 2999 * attributes have multiple equivalent values. 3000 */ 3001 function getValueForAttribute(node, name, expected) { 3002 { 3003 if (!isAttributeNameSafe(name)) { 3004 return; 3005 } 3006 if (!node.hasAttribute(name)) { 3007 return expected === undefined ? undefined : null; 3008 } 3009 var value = node.getAttribute(name); 3010 if (value === '' + expected) { 3011 return expected; 3012 } 3013 return value; 3014 } 3015 } 3016 3017 /** 3018 * Sets the value for a property on a node. 3019 * 3020 * @param {DOMElement} node 3021 * @param {string} name 3022 * @param {*} value 3023 */ 3024 function setValueForProperty(node, name, value, isCustomComponentTag) { 3025 var propertyInfo = getPropertyInfo(name); 3026 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) { 3027 return; 3028 } 3029 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) { 3030 value = null; 3031 } 3032 // If the prop isn't in the special list, treat it as a simple attribute. 3033 if (isCustomComponentTag || propertyInfo === null) { 3034 if (isAttributeNameSafe(name)) { 3035 var _attributeName = name; 3036 if (value === null) { 3037 node.removeAttribute(_attributeName); 3038 } else { 3039 node.setAttribute(_attributeName, '' + value); 3040 } 3041 } 3042 return; 3043 } 3044 var mustUseProperty = propertyInfo.mustUseProperty; 3045 3046 if (mustUseProperty) { 3047 var propertyName = propertyInfo.propertyName; 3048 3049 if (value === null) { 3050 var type = propertyInfo.type; 3051 3052 node[propertyName] = type === BOOLEAN ? false : ''; 3053 } else { 3054 // Contrary to `setAttribute`, object properties are properly 3055 // `toString`ed by IE8/9. 3056 node[propertyName] = value; 3057 } 3058 return; 3059 } 3060 // The rest are treated as attributes with special cases. 3061 var attributeName = propertyInfo.attributeName, 3062 attributeNamespace = propertyInfo.attributeNamespace; 3063 3064 if (value === null) { 3065 node.removeAttribute(attributeName); 3066 } else { 3067 var _type = propertyInfo.type; 3068 3069 var attributeValue = void 0; 3070 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) { 3071 attributeValue = ''; 3072 } else { 3073 // `setAttribute` with objects becomes only `[object]` in IE8/9, 3074 // ('' + value) makes it output the correct toString()-value. 3075 attributeValue = '' + value; 3076 } 3077 if (attributeNamespace) { 3078 node.setAttributeNS(attributeNamespace, attributeName, attributeValue); 3079 } else { 3080 node.setAttribute(attributeName, attributeValue); 3081 } 3082 } 3083 } 3084 3085 // Flow does not allow string concatenation of most non-string types. To work 3086 // around this limitation, we use an opaque type that can only be obtained by 3087 // passing the value through getToStringValue first. 3088 function toString(value) { 3089 return '' + value; 3090 } 3091 3092 function getToStringValue(value) { 3093 switch (typeof value) { 3094 case 'boolean': 3095 case 'number': 3096 case 'object': 3097 case 'string': 3098 case 'undefined': 3099 return value; 3100 default: 3101 // function, symbol are assigned as empty strings 3102 return ''; 3103 } 3104 } 3105 3106 /** 3107 * Copyright (c) 2013-present, Facebook, Inc. 3108 * 3109 * This source code is licensed under the MIT license found in the 3110 * LICENSE file in the root directory of this source tree. 3111 */ 3112 3113 3114 3115 var ReactPropTypesSecret$1 = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; 3116 3117 var ReactPropTypesSecret_1 = ReactPropTypesSecret$1; 3118 3119 /** 3120 * Copyright (c) 2013-present, Facebook, Inc. 3121 * 3122 * This source code is licensed under the MIT license found in the 3123 * LICENSE file in the root directory of this source tree. 3124 */ 3125 3126 3127 3128 var printWarning = function() {}; 3129 3130 { 3131 var ReactPropTypesSecret = ReactPropTypesSecret_1; 3132 var loggedTypeFailures = {}; 3133 3134 printWarning = function(text) { 3135 var message = 'Warning: ' + text; 3136 if (typeof console !== 'undefined') { 3137 console.error(message); 3138 } 3139 try { 3140 // --- Welcome to debugging React --- 3141 // This error was thrown as a convenience so that you can use this stack 3142 // to find the callsite that caused this warning to fire. 3143 throw new Error(message); 3144 } catch (x) {} 3145 }; 3146 } 3147 3148 /** 3149 * Assert that the values match with the type specs. 3150 * Error messages are memorized and will only be shown once. 3151 * 3152 * @param {object} typeSpecs Map of name to a ReactPropType 3153 * @param {object} values Runtime values that need to be type-checked 3154 * @param {string} location e.g. "prop", "context", "child context" 3155 * @param {string} componentName Name of the component for error messages. 3156 * @param {?Function} getStack Returns the component stack. 3157 * @private 3158 */ 3159 function checkPropTypes(typeSpecs, values, location, componentName, getStack) { 3160 { 3161 for (var typeSpecName in typeSpecs) { 3162 if (typeSpecs.hasOwnProperty(typeSpecName)) { 3163 var error; 3164 // Prop type validation may throw. In case they do, we don't want to 3165 // fail the render phase where it didn't fail before. So we log it. 3166 // After these have been cleaned up, we'll let them throw. 3167 try { 3168 // This is intentionally an invariant that gets caught. It's the same 3169 // behavior as without this statement except with a better message. 3170 if (typeof typeSpecs[typeSpecName] !== 'function') { 3171 var err = Error( 3172 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + 3173 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' 3174 ); 3175 err.name = 'Invariant Violation'; 3176 throw err; 3177 } 3178 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret); 3179 } catch (ex) { 3180 error = ex; 3181 } 3182 if (error && !(error instanceof Error)) { 3183 printWarning( 3184 (componentName || 'React class') + ': type specification of ' + 3185 location + ' `' + typeSpecName + '` is invalid; the type checker ' + 3186 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' + 3187 'You may have forgotten to pass an argument to the type checker ' + 3188 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 3189 'shape all require an argument).' 3190 ); 3191 3192 } 3193 if (error instanceof Error && !(error.message in loggedTypeFailures)) { 3194 // Only monitor this failure once because there tends to be a lot of the 3195 // same error. 3196 loggedTypeFailures[error.message] = true; 3197 3198 var stack = getStack ? getStack() : ''; 3199 3200 printWarning( 3201 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '') 3202 ); 3203 } 3204 } 3205 } 3206 } 3207 } 3208 3209 var checkPropTypes_1 = checkPropTypes; 3210 3211 var ReactDebugCurrentFrame$1 = null; 3212 3213 var ReactControlledValuePropTypes = { 3214 checkPropTypes: null 3215 }; 3216 3217 { 3218 ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame; 3219 3220 var hasReadOnlyValue = { 3221 button: true, 3222 checkbox: true, 3223 image: true, 3224 hidden: true, 3225 radio: true, 3226 reset: true, 3227 submit: true 3228 }; 3229 3230 var propTypes = { 3231 value: function (props, propName, componentName) { 3232 if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null) { 3233 return null; 3234 } 3235 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`.'); 3236 }, 3237 checked: function (props, propName, componentName) { 3238 if (props.onChange || props.readOnly || props.disabled || props[propName] == null) { 3239 return null; 3240 } 3241 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`.'); 3242 } 3243 }; 3244 3245 /** 3246 * Provide a linked `value` attribute for controlled forms. You should not use 3247 * this outside of the ReactDOM controlled form components. 3248 */ 3249 ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) { 3250 checkPropTypes_1(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$1.getStackAddendum); 3251 }; 3252 } 3253 3254 // Exports ReactDOM.createRoot 3255 var enableUserTimingAPI = true; 3256 3257 // Experimental error-boundary API that can recover from errors within a single 3258 // render phase 3259 var enableGetDerivedStateFromCatch = false; 3260 // Suspense 3261 var enableSuspense = false; 3262 // Helps identify side effects in begin-phase lifecycle hooks and setState reducers: 3263 var debugRenderPhaseSideEffects = false; 3264 3265 // In some cases, StrictMode should also double-render lifecycles. 3266 // This can be confusing for tests though, 3267 // And it can be bad for performance in production. 3268 // This feature flag can be used to control the behavior: 3269 var debugRenderPhaseSideEffectsForStrictMode = true; 3270 3271 // To preserve the "Pause on caught exceptions" behavior of the debugger, we 3272 // replay the begin phase of a failed component inside invokeGuardedCallback. 3273 var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; 3274 3275 // Warn about deprecated, async-unsafe lifecycles; relates to RFC #6: 3276 var warnAboutDeprecatedLifecycles = false; 3277 3278 // Warn about legacy context API 3279 var warnAboutLegacyContextAPI = false; 3280 3281 // Gather advanced timing metrics for Profiler subtrees. 3282 var enableProfilerTimer = true; 3283 3284 // Trace which interactions trigger each commit. 3285 var enableSchedulerTracing = true; 3286 3287 // Only used in www builds. 3288 3289 3290 // Only used in www builds. 3291 3292 3293 // React Fire: prevent the value and checked attributes from syncing 3294 // with their related DOM properties 3295 var disableInputAttributeSyncing = false; 3296 3297 // TODO: direct imports like some-package/src/* are bad. Fix me. 3298 var didWarnValueDefaultValue = false; 3299 var didWarnCheckedDefaultChecked = false; 3300 var didWarnControlledToUncontrolled = false; 3301 var didWarnUncontrolledToControlled = false; 3302 3303 function isControlled(props) { 3304 var usesChecked = props.type === 'checkbox' || props.type === 'radio'; 3305 return usesChecked ? props.checked != null : props.value != null; 3306 } 3307 3308 /** 3309 * Implements an <input> host component that allows setting these optional 3310 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`. 3311 * 3312 * If `checked` or `value` are not supplied (or null/undefined), user actions 3313 * that affect the checked state or value will trigger updates to the element. 3314 * 3315 * If they are supplied (and not null/undefined), the rendered element will not 3316 * trigger updates to the element. Instead, the props must change in order for 3317 * the rendered element to be updated. 3318 * 3319 * The rendered element will be initialized as unchecked (or `defaultChecked`) 3320 * with an empty value (or `defaultValue`). 3321 * 3322 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html 3323 */ 3324 3325 function getHostProps(element, props) { 3326 var node = element; 3327 var checked = props.checked; 3328 3329 var hostProps = _assign({}, props, { 3330 defaultChecked: undefined, 3331 defaultValue: undefined, 3332 value: undefined, 3333 checked: checked != null ? checked : node._wrapperState.initialChecked 3334 }); 3335 3336 return hostProps; 3337 } 3338 3339 function initWrapperState(element, props) { 3340 { 3341 ReactControlledValuePropTypes.checkPropTypes('input', props); 3342 3343 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) { 3344 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); 3345 didWarnCheckedDefaultChecked = true; 3346 } 3347 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) { 3348 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); 3349 didWarnValueDefaultValue = true; 3350 } 3351 } 3352 3353 var node = element; 3354 var defaultValue = props.defaultValue == null ? '' : props.defaultValue; 3355 3356 node._wrapperState = { 3357 initialChecked: props.checked != null ? props.checked : props.defaultChecked, 3358 initialValue: getToStringValue(props.value != null ? props.value : defaultValue), 3359 controlled: isControlled(props) 3360 }; 3361 } 3362 3363 function updateChecked(element, props) { 3364 var node = element; 3365 var checked = props.checked; 3366 if (checked != null) { 3367 setValueForProperty(node, 'checked', checked, false); 3368 } 3369 } 3370 3371 function updateWrapper(element, props) { 3372 var node = element; 3373 { 3374 var _controlled = isControlled(props); 3375 3376 if (!node._wrapperState.controlled && _controlled && !didWarnUncontrolledToControlled) { 3377 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); 3378 didWarnUncontrolledToControlled = true; 3379 } 3380 if (node._wrapperState.controlled && !_controlled && !didWarnControlledToUncontrolled) { 3381 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); 3382 didWarnControlledToUncontrolled = true; 3383 } 3384 } 3385 3386 updateChecked(element, props); 3387 3388 var value = getToStringValue(props.value); 3389 var type = props.type; 3390 3391 if (value != null) { 3392 if (type === 'number') { 3393 if (value === 0 && node.value === '' || 3394 // We explicitly want to coerce to number here if possible. 3395 // eslint-disable-next-line 3396 node.value != value) { 3397 node.value = toString(value); 3398 } 3399 } else if (node.value !== toString(value)) { 3400 node.value = toString(value); 3401 } 3402 } else if (type === 'submit' || type === 'reset') { 3403 // Submit/reset inputs need the attribute removed completely to avoid 3404 // blank-text buttons. 3405 node.removeAttribute('value'); 3406 return; 3407 } 3408 3409 if (disableInputAttributeSyncing) { 3410 // When not syncing the value attribute, React only assigns a new value 3411 // whenever the defaultValue React prop has changed. When not present, 3412 // React does nothing 3413 if (props.hasOwnProperty('defaultValue')) { 3414 setDefaultValue(node, props.type, getToStringValue(props.defaultValue)); 3415 } 3416 } else { 3417 // When syncing the value attribute, the value comes from a cascade of 3418 // properties: 3419 // 1. The value React property 3420 // 2. The defaultValue React property 3421 // 3. Otherwise there should be no change 3422 if (props.hasOwnProperty('value')) { 3423 setDefaultValue(node, props.type, value); 3424 } else if (props.hasOwnProperty('defaultValue')) { 3425 setDefaultValue(node, props.type, getToStringValue(props.defaultValue)); 3426 } 3427 } 3428 3429 if (disableInputAttributeSyncing) { 3430 // When not syncing the checked attribute, the attribute is directly 3431 // controllable from the defaultValue React property. It needs to be 3432 // updated as new props come in. 3433 if (props.defaultChecked == null) { 3434 node.removeAttribute('checked'); 3435 } else { 3436 node.defaultChecked = !!props.defaultChecked; 3437 } 3438 } else { 3439 // When syncing the checked attribute, it only changes when it needs 3440 // to be removed, such as transitioning from a checkbox into a text input 3441 if (props.checked == null && props.defaultChecked != null) { 3442 node.defaultChecked = !!props.defaultChecked; 3443 } 3444 } 3445 } 3446 3447 function postMountWrapper(element, props, isHydrating) { 3448 var node = element; 3449 3450 // Do not assign value if it is already set. This prevents user text input 3451 // from being lost during SSR hydration. 3452 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) { 3453 var type = props.type; 3454 var isButton = type === 'submit' || type === 'reset'; 3455 3456 // Avoid setting value attribute on submit/reset inputs as it overrides the 3457 // default value provided by the browser. See: #12872 3458 if (isButton && (props.value === undefined || props.value === null)) { 3459 return; 3460 } 3461 3462 var _initialValue = toString(node._wrapperState.initialValue); 3463 3464 // Do not assign value if it is already set. This prevents user text input 3465 // from being lost during SSR hydration. 3466 if (!isHydrating) { 3467 if (disableInputAttributeSyncing) { 3468 var value = getToStringValue(props.value); 3469 3470 // When not syncing the value attribute, the value property points 3471 // directly to the React prop. Only assign it if it exists. 3472 if (value != null) { 3473 // Always assign on buttons so that it is possible to assign an 3474 // empty string to clear button text. 3475 // 3476 // Otherwise, do not re-assign the value property if is empty. This 3477 // potentially avoids a DOM write and prevents Firefox (~60.0.1) from 3478 // prematurely marking required inputs as invalid. Equality is compared 3479 // to the current value in case the browser provided value is not an 3480 // empty string. 3481 if (isButton || value !== node.value) { 3482 node.value = toString(value); 3483 } 3484 } 3485 } else { 3486 // When syncing the value attribute, the value property should use 3487 // the the wrapperState._initialValue property. This uses: 3488 // 3489 // 1. The value React property when present 3490 // 2. The defaultValue React property when present 3491 // 3. An empty string 3492 if (_initialValue !== node.value) { 3493 node.value = _initialValue; 3494 } 3495 } 3496 } 3497 3498 if (disableInputAttributeSyncing) { 3499 // When not syncing the value attribute, assign the value attribute 3500 // directly from the defaultValue React property (when present) 3501 var defaultValue = getToStringValue(props.defaultValue); 3502 if (defaultValue != null) { 3503 node.defaultValue = toString(defaultValue); 3504 } 3505 } else { 3506 // Otherwise, the value attribute is synchronized to the property, 3507 // so we assign defaultValue to the same thing as the value property 3508 // assignment step above. 3509 node.defaultValue = _initialValue; 3510 } 3511 } 3512 3513 // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug 3514 // this is needed to work around a chrome bug where setting defaultChecked 3515 // will sometimes influence the value of checked (even after detachment). 3516 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416 3517 // We need to temporarily unset name to avoid disrupting radio button groups. 3518 var name = node.name; 3519 if (name !== '') { 3520 node.name = ''; 3521 } 3522 3523 if (disableInputAttributeSyncing) { 3524 // When not syncing the checked attribute, the checked property 3525 // never gets assigned. It must be manually set. We don't want 3526 // to do this when hydrating so that existing user input isn't 3527 // modified 3528 if (!isHydrating) { 3529 updateChecked(element, props); 3530 } 3531 3532 // Only assign the checked attribute if it is defined. This saves 3533 // a DOM write when controlling the checked attribute isn't needed 3534 // (text inputs, submit/reset) 3535 if (props.hasOwnProperty('defaultChecked')) { 3536 node.defaultChecked = !node.defaultChecked; 3537 node.defaultChecked = !!props.defaultChecked; 3538 } 3539 } else { 3540 // When syncing the checked attribute, both the the checked property and 3541 // attribute are assigned at the same time using defaultChecked. This uses: 3542 // 3543 // 1. The checked React property when present 3544 // 2. The defaultChecked React property when present 3545 // 3. Otherwise, false 3546 node.defaultChecked = !node.defaultChecked; 3547 node.defaultChecked = !!node._wrapperState.initialChecked; 3548 } 3549 3550 if (name !== '') { 3551 node.name = name; 3552 } 3553 } 3554 3555 function restoreControlledState(element, props) { 3556 var node = element; 3557 updateWrapper(node, props); 3558 updateNamedCousins(node, props); 3559 } 3560 3561 function updateNamedCousins(rootNode, props) { 3562 var name = props.name; 3563 if (props.type === 'radio' && name != null) { 3564 var queryRoot = rootNode; 3565 3566 while (queryRoot.parentNode) { 3567 queryRoot = queryRoot.parentNode; 3568 } 3569 3570 // If `rootNode.form` was non-null, then we could try `form.elements`, 3571 // but that sometimes behaves strangely in IE8. We could also try using 3572 // `form.getElementsByName`, but that will only return direct children 3573 // and won't include inputs that use the HTML5 `form=` attribute. Since 3574 // the input might not even be in a form. It might not even be in the 3575 // document. Let's just use the local `querySelectorAll` to ensure we don't 3576 // miss anything. 3577 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]'); 3578 3579 for (var i = 0; i < group.length; i++) { 3580 var otherNode = group[i]; 3581 if (otherNode === rootNode || otherNode.form !== rootNode.form) { 3582 continue; 3583 } 3584 // This will throw if radio buttons rendered by different copies of React 3585 // and the same name are rendered into the same form (same as #1939). 3586 // That's probably okay; we don't support it just as we don't support 3587 // mixing React radio buttons with non-React ones. 3588 var otherProps = getFiberCurrentPropsFromNode$1(otherNode); 3589 !otherProps ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : void 0; 3590 3591 // We need update the tracked value on the named cousin since the value 3592 // was changed but the input saw no event or value set 3593 updateValueIfChanged(otherNode); 3594 3595 // If this is a controlled radio button group, forcing the input that 3596 // was previously checked to update will cause it to be come re-checked 3597 // as appropriate. 3598 updateWrapper(otherNode, otherProps); 3599 } 3600 } 3601 } 3602 3603 // In Chrome, assigning defaultValue to certain input types triggers input validation. 3604 // For number inputs, the display value loses trailing decimal points. For email inputs, 3605 // Chrome raises "The specified value <x> is not a valid email address". 3606 // 3607 // Here we check to see if the defaultValue has actually changed, avoiding these problems 3608 // when the user is inputting text 3609 // 3610 // https://github.com/facebook/react/issues/7253 3611 function setDefaultValue(node, type, value) { 3612 if ( 3613 // Focused number inputs synchronize on blur. See ChangeEventPlugin.js 3614 type !== 'number' || node.ownerDocument.activeElement !== node) { 3615 if (value == null) { 3616 node.defaultValue = toString(node._wrapperState.initialValue); 3617 } else if (node.defaultValue !== toString(value)) { 3618 node.defaultValue = toString(value); 3619 } 3620 } 3621 } 3622 3623 var eventTypes$1 = { 3624 change: { 3625 phasedRegistrationNames: { 3626 bubbled: 'onChange', 3627 captured: 'onChangeCapture' 3628 }, 3629 dependencies: [TOP_BLUR, TOP_CHANGE, TOP_CLICK, TOP_FOCUS, TOP_INPUT, TOP_KEY_DOWN, TOP_KEY_UP, TOP_SELECTION_CHANGE] 3630 } 3631 }; 3632 3633 function createAndAccumulateChangeEvent(inst, nativeEvent, target) { 3634 var event = SyntheticEvent.getPooled(eventTypes$1.change, inst, nativeEvent, target); 3635 event.type = 'change'; 3636 // Flag this event loop as needing state restore. 3637 enqueueStateRestore(target); 3638 accumulateTwoPhaseDispatches(event); 3639 return event; 3640 } 3641 /** 3642 * For IE shims 3643 */ 3644 var activeElement = null; 3645 var activeElementInst = null; 3646 3647 /** 3648 * SECTION: handle `change` event 3649 */ 3650 function shouldUseChangeEvent(elem) { 3651 var nodeName = elem.nodeName && elem.nodeName.toLowerCase(); 3652 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file'; 3653 } 3654 3655 function manualDispatchChangeEvent(nativeEvent) { 3656 var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent)); 3657 3658 // If change and propertychange bubbled, we'd just bind to it like all the 3659 // other events and have it go through ReactBrowserEventEmitter. Since it 3660 // doesn't, we manually listen for the events and so we have to enqueue and 3661 // process the abstract event manually. 3662 // 3663 // Batching is necessary here in order to ensure that all event handlers run 3664 // before the next rerender (including event handlers attached to ancestor 3665 // elements instead of directly on the input). Without this, controlled 3666 // components don't work properly in conjunction with event bubbling because 3667 // the component is rerendered and the value reverted before all the event 3668 // handlers can run. See https://github.com/facebook/react/issues/708. 3669 batchedUpdates(runEventInBatch, event); 3670 } 3671 3672 function runEventInBatch(event) { 3673 runEventsInBatch(event, false); 3674 } 3675 3676 function getInstIfValueChanged(targetInst) { 3677 var targetNode = getNodeFromInstance$1(targetInst); 3678 if (updateValueIfChanged(targetNode)) { 3679 return targetInst; 3680 } 3681 } 3682 3683 function getTargetInstForChangeEvent(topLevelType, targetInst) { 3684 if (topLevelType === TOP_CHANGE) { 3685 return targetInst; 3686 } 3687 } 3688 3689 /** 3690 * SECTION: handle `input` event 3691 */ 3692 var isInputEventSupported = false; 3693 if (canUseDOM) { 3694 // IE9 claims to support the input event but fails to trigger it when 3695 // deleting text, so we ignore its input events. 3696 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9); 3697 } 3698 3699 /** 3700 * (For IE <=9) Starts tracking propertychange events on the passed-in element 3701 * and override the value property so that we can distinguish user events from 3702 * value changes in JS. 3703 */ 3704 function startWatchingForValueChange(target, targetInst) { 3705 activeElement = target; 3706 activeElementInst = targetInst; 3707 activeElement.attachEvent('onpropertychange', handlePropertyChange); 3708 } 3709 3710 /** 3711 * (For IE <=9) Removes the event listeners from the currently-tracked element, 3712 * if any exists. 3713 */ 3714 function stopWatchingForValueChange() { 3715 if (!activeElement) { 3716 return; 3717 } 3718 activeElement.detachEvent('onpropertychange', handlePropertyChange); 3719 activeElement = null; 3720 activeElementInst = null; 3721 } 3722 3723 /** 3724 * (For IE <=9) Handles a propertychange event, sending a `change` event if 3725 * the value of the active element has changed. 3726 */ 3727 function handlePropertyChange(nativeEvent) { 3728 if (nativeEvent.propertyName !== 'value') { 3729 return; 3730 } 3731 if (getInstIfValueChanged(activeElementInst)) { 3732 manualDispatchChangeEvent(nativeEvent); 3733 } 3734 } 3735 3736 function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) { 3737 if (topLevelType === TOP_FOCUS) { 3738 // In IE9, propertychange fires for most input events but is buggy and 3739 // doesn't fire when text is deleted, but conveniently, selectionchange 3740 // appears to fire in all of the remaining cases so we catch those and 3741 // forward the event if the value has changed 3742 // In either case, we don't want to call the event handler if the value 3743 // is changed from JS so we redefine a setter for `.value` that updates 3744 // our activeElementValue variable, allowing us to ignore those changes 3745 // 3746 // stopWatching() should be a noop here but we call it just in case we 3747 // missed a blur event somehow. 3748 stopWatchingForValueChange(); 3749 startWatchingForValueChange(target, targetInst); 3750 } else if (topLevelType === TOP_BLUR) { 3751 stopWatchingForValueChange(); 3752 } 3753 } 3754 3755 // For IE8 and IE9. 3756 function getTargetInstForInputEventPolyfill(topLevelType, targetInst) { 3757 if (topLevelType === TOP_SELECTION_CHANGE || topLevelType === TOP_KEY_UP || topLevelType === TOP_KEY_DOWN) { 3758 // On the selectionchange event, the target is just document which isn't 3759 // helpful for us so just check activeElement instead. 3760 // 3761 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire 3762 // propertychange on the first input event after setting `value` from a 3763 // script and fires only keydown, keypress, keyup. Catching keyup usually 3764 // gets it and catching keydown lets us fire an event for the first 3765 // keystroke if user does a key repeat (it'll be a little delayed: right 3766 // before the second keystroke). Other input methods (e.g., paste) seem to 3767 // fire selectionchange normally. 3768 return getInstIfValueChanged(activeElementInst); 3769 } 3770 } 3771 3772 /** 3773 * SECTION: handle `click` event 3774 */ 3775 function shouldUseClickEvent(elem) { 3776 // Use the `click` event to detect changes to checkbox and radio inputs. 3777 // This approach works across all browsers, whereas `change` does not fire 3778 // until `blur` in IE8. 3779 var nodeName = elem.nodeName; 3780 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio'); 3781 } 3782 3783 function getTargetInstForClickEvent(topLevelType, targetInst) { 3784 if (topLevelType === TOP_CLICK) { 3785 return getInstIfValueChanged(targetInst); 3786 } 3787 } 3788 3789 function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) { 3790 if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) { 3791 return getInstIfValueChanged(targetInst); 3792 } 3793 } 3794 3795 function handleControlledInputBlur(node) { 3796 var state = node._wrapperState; 3797 3798 if (!state || !state.controlled || node.type !== 'number') { 3799 return; 3800 } 3801 3802 if (!disableInputAttributeSyncing) { 3803 // If controlled, assign the value attribute to the current value on blur 3804 setDefaultValue(node, 'number', node.value); 3805 } 3806 } 3807 3808 /** 3809 * This plugin creates an `onChange` event that normalizes change events 3810 * across form elements. This event fires at a time when it's possible to 3811 * change the element's value without seeing a flicker. 3812 * 3813 * Supported elements are: 3814 * - input (see `isTextInputElement`) 3815 * - textarea 3816 * - select 3817 */ 3818 var ChangeEventPlugin = { 3819 eventTypes: eventTypes$1, 3820 3821 _isInputEventSupported: isInputEventSupported, 3822 3823 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { 3824 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window; 3825 3826 var getTargetInstFunc = void 0, 3827 handleEventFunc = void 0; 3828 if (shouldUseChangeEvent(targetNode)) { 3829 getTargetInstFunc = getTargetInstForChangeEvent; 3830 } else if (isTextInputElement(targetNode)) { 3831 if (isInputEventSupported) { 3832 getTargetInstFunc = getTargetInstForInputOrChangeEvent; 3833 } else { 3834 getTargetInstFunc = getTargetInstForInputEventPolyfill; 3835 handleEventFunc = handleEventsForInputEventPolyfill; 3836 } 3837 } else if (shouldUseClickEvent(targetNode)) { 3838 getTargetInstFunc = getTargetInstForClickEvent; 3839 } 3840 3841 if (getTargetInstFunc) { 3842 var inst = getTargetInstFunc(topLevelType, targetInst); 3843 if (inst) { 3844 var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget); 3845 return event; 3846 } 3847 } 3848 3849 if (handleEventFunc) { 3850 handleEventFunc(topLevelType, targetNode, targetInst); 3851 } 3852 3853 // When blurring, set the value attribute for number inputs 3854 if (topLevelType === TOP_BLUR) { 3855 handleControlledInputBlur(targetNode); 3856 } 3857 } 3858 }; 3859 3860 /** 3861 * Module that is injectable into `EventPluginHub`, that specifies a 3862 * deterministic ordering of `EventPlugin`s. A convenient way to reason about 3863 * plugins, without having to package every one of them. This is better than 3864 * having plugins be ordered in the same order that they are injected because 3865 * that ordering would be influenced by the packaging order. 3866 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that 3867 * preventing default on events is convenient in `SimpleEventPlugin` handlers. 3868 */ 3869 var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin']; 3870 3871 var SyntheticUIEvent = SyntheticEvent.extend({ 3872 view: null, 3873 detail: null 3874 }); 3875 3876 /** 3877 * Translation from modifier key to the associated property in the event. 3878 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers 3879 */ 3880 3881 var modifierKeyToProp = { 3882 Alt: 'altKey', 3883 Control: 'ctrlKey', 3884 Meta: 'metaKey', 3885 Shift: 'shiftKey' 3886 }; 3887 3888 // IE8 does not implement getModifierState so we simply map it to the only 3889 // modifier keys exposed by the event itself, does not support Lock-keys. 3890 // Currently, all major browsers except Chrome seems to support Lock-keys. 3891 function modifierStateGetter(keyArg) { 3892 var syntheticEvent = this; 3893 var nativeEvent = syntheticEvent.nativeEvent; 3894 if (nativeEvent.getModifierState) { 3895 return nativeEvent.getModifierState(keyArg); 3896 } 3897 var keyProp = modifierKeyToProp[keyArg]; 3898 return keyProp ? !!nativeEvent[keyProp] : false; 3899 } 3900 3901 function getEventModifierState(nativeEvent) { 3902 return modifierStateGetter; 3903 } 3904 3905 var previousScreenX = 0; 3906 var previousScreenY = 0; 3907 // Use flags to signal movementX/Y has already been set 3908 var isMovementXSet = false; 3909 var isMovementYSet = false; 3910 3911 /** 3912 * @interface MouseEvent 3913 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 3914 */ 3915 var SyntheticMouseEvent = SyntheticUIEvent.extend({ 3916 screenX: null, 3917 screenY: null, 3918 clientX: null, 3919 clientY: null, 3920 pageX: null, 3921 pageY: null, 3922 ctrlKey: null, 3923 shiftKey: null, 3924 altKey: null, 3925 metaKey: null, 3926 getModifierState: getEventModifierState, 3927 button: null, 3928 buttons: null, 3929 relatedTarget: function (event) { 3930 return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement); 3931 }, 3932 movementX: function (event) { 3933 if ('movementX' in event) { 3934 return event.movementX; 3935 } 3936 3937 var screenX = previousScreenX; 3938 previousScreenX = event.screenX; 3939 3940 if (!isMovementXSet) { 3941 isMovementXSet = true; 3942 return 0; 3943 } 3944 3945 return event.type === 'mousemove' ? event.screenX - screenX : 0; 3946 }, 3947 movementY: function (event) { 3948 if ('movementY' in event) { 3949 return event.movementY; 3950 } 3951 3952 var screenY = previousScreenY; 3953 previousScreenY = event.screenY; 3954 3955 if (!isMovementYSet) { 3956 isMovementYSet = true; 3957 return 0; 3958 } 3959 3960 return event.type === 'mousemove' ? event.screenY - screenY : 0; 3961 } 3962 }); 3963 3964 /** 3965 * @interface PointerEvent 3966 * @see http://www.w3.org/TR/pointerevents/ 3967 */ 3968 var SyntheticPointerEvent = SyntheticMouseEvent.extend({ 3969 pointerId: null, 3970 width: null, 3971 height: null, 3972 pressure: null, 3973 tangentialPressure: null, 3974 tiltX: null, 3975 tiltY: null, 3976 twist: null, 3977 pointerType: null, 3978 isPrimary: null 3979 }); 3980 3981 var eventTypes$2 = { 3982 mouseEnter: { 3983 registrationName: 'onMouseEnter', 3984 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER] 3985 }, 3986 mouseLeave: { 3987 registrationName: 'onMouseLeave', 3988 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER] 3989 }, 3990 pointerEnter: { 3991 registrationName: 'onPointerEnter', 3992 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER] 3993 }, 3994 pointerLeave: { 3995 registrationName: 'onPointerLeave', 3996 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER] 3997 } 3998 }; 3999 4000 var EnterLeaveEventPlugin = { 4001 eventTypes: eventTypes$2, 4002 4003 /** 4004 * For almost every interaction we care about, there will be both a top-level 4005 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that 4006 * we do not extract duplicate events. However, moving the mouse into the 4007 * browser from outside will not fire a `mouseout` event. In this case, we use 4008 * the `mouseover` top-level event. 4009 */ 4010 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { 4011 var isOverEvent = topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER; 4012 var isOutEvent = topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT; 4013 4014 if (isOverEvent && (nativeEvent.relatedTarget || nativeEvent.fromElement)) { 4015 return null; 4016 } 4017 4018 if (!isOutEvent && !isOverEvent) { 4019 // Must not be a mouse or pointer in or out - ignoring. 4020 return null; 4021 } 4022 4023 var win = void 0; 4024 if (nativeEventTarget.window === nativeEventTarget) { 4025 // `nativeEventTarget` is probably a window object. 4026 win = nativeEventTarget; 4027 } else { 4028 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. 4029 var doc = nativeEventTarget.ownerDocument; 4030 if (doc) { 4031 win = doc.defaultView || doc.parentWindow; 4032 } else { 4033 win = window; 4034 } 4035 } 4036 4037 var from = void 0; 4038 var to = void 0; 4039 if (isOutEvent) { 4040 from = targetInst; 4041 var related = nativeEvent.relatedTarget || nativeEvent.toElement; 4042 to = related ? getClosestInstanceFromNode(related) : null; 4043 } else { 4044 // Moving to a node from outside the window. 4045 from = null; 4046 to = targetInst; 4047 } 4048 4049 if (from === to) { 4050 // Nothing pertains to our managed components. 4051 return null; 4052 } 4053 4054 var eventInterface = void 0, 4055 leaveEventType = void 0, 4056 enterEventType = void 0, 4057 eventTypePrefix = void 0; 4058 4059 if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) { 4060 eventInterface = SyntheticMouseEvent; 4061 leaveEventType = eventTypes$2.mouseLeave; 4062 enterEventType = eventTypes$2.mouseEnter; 4063 eventTypePrefix = 'mouse'; 4064 } else if (topLevelType === TOP_POINTER_OUT || topLevelType === TOP_POINTER_OVER) { 4065 eventInterface = SyntheticPointerEvent; 4066 leaveEventType = eventTypes$2.pointerLeave; 4067 enterEventType = eventTypes$2.pointerEnter; 4068 eventTypePrefix = 'pointer'; 4069 } 4070 4071 var fromNode = from == null ? win : getNodeFromInstance$1(from); 4072 var toNode = to == null ? win : getNodeFromInstance$1(to); 4073 4074 var leave = eventInterface.getPooled(leaveEventType, from, nativeEvent, nativeEventTarget); 4075 leave.type = eventTypePrefix + 'leave'; 4076 leave.target = fromNode; 4077 leave.relatedTarget = toNode; 4078 4079 var enter = eventInterface.getPooled(enterEventType, to, nativeEvent, nativeEventTarget); 4080 enter.type = eventTypePrefix + 'enter'; 4081 enter.target = toNode; 4082 enter.relatedTarget = fromNode; 4083 4084 accumulateEnterLeaveDispatches(leave, enter, from, to); 4085 4086 return [leave, enter]; 4087 } 4088 }; 4089 4090 /*eslint-disable no-self-compare */ 4091 4092 var hasOwnProperty$1 = Object.prototype.hasOwnProperty; 4093 4094 /** 4095 * inlined Object.is polyfill to avoid requiring consumers ship their own 4096 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is 4097 */ 4098 function is(x, y) { 4099 // SameValue algorithm 4100 if (x === y) { 4101 // Steps 1-5, 7-10 4102 // Steps 6.b-6.e: +0 != -0 4103 // Added the nonzero y check to make Flow happy, but it is redundant 4104 return x !== 0 || y !== 0 || 1 / x === 1 / y; 4105 } else { 4106 // Step 6.a: NaN == NaN 4107 return x !== x && y !== y; 4108 } 4109 } 4110 4111 /** 4112 * Performs equality by iterating through keys on an object and returning false 4113 * when any key has values which are not strictly equal between the arguments. 4114 * Returns true when the values of all keys are strictly equal. 4115 */ 4116 function shallowEqual(objA, objB) { 4117 if (is(objA, objB)) { 4118 return true; 4119 } 4120 4121 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { 4122 return false; 4123 } 4124 4125 var keysA = Object.keys(objA); 4126 var keysB = Object.keys(objB); 4127 4128 if (keysA.length !== keysB.length) { 4129 return false; 4130 } 4131 4132 // Test for A's keys different from B. 4133 for (var i = 0; i < keysA.length; i++) { 4134 if (!hasOwnProperty$1.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) { 4135 return false; 4136 } 4137 } 4138 4139 return true; 4140 } 4141 4142 /** 4143 * `ReactInstanceMap` maintains a mapping from a public facing stateful 4144 * instance (key) and the internal representation (value). This allows public 4145 * methods to accept the user facing instance as an argument and map them back 4146 * to internal methods. 4147 * 4148 * Note that this module is currently shared and assumed to be stateless. 4149 * If this becomes an actual Map, that will break. 4150 */ 4151 4152 /** 4153 * This API should be called `delete` but we'd have to make sure to always 4154 * transform these to strings for IE support. When this transform is fully 4155 * supported we can rename it. 4156 */ 4157 4158 4159 function get(key) { 4160 return key._reactInternalFiber; 4161 } 4162 4163 function has(key) { 4164 return key._reactInternalFiber !== undefined; 4165 } 4166 4167 function set(key, value) { 4168 key._reactInternalFiber = value; 4169 } 4170 4171 // Don't change these two values. They're used by React Dev Tools. 4172 var NoEffect = /* */0; 4173 var PerformedWork = /* */1; 4174 4175 // You can change the rest (and add more). 4176 var Placement = /* */2; 4177 var Update = /* */4; 4178 var PlacementAndUpdate = /* */6; 4179 var Deletion = /* */8; 4180 var ContentReset = /* */16; 4181 var Callback = /* */32; 4182 var DidCapture = /* */64; 4183 var Ref = /* */128; 4184 var Snapshot = /* */256; 4185 4186 // Update & Callback & Ref & Snapshot 4187 var LifecycleEffectMask = /* */420; 4188 4189 // Union of all host effects 4190 var HostEffectMask = /* */511; 4191 4192 var Incomplete = /* */512; 4193 var ShouldCapture = /* */1024; 4194 4195 var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; 4196 4197 var MOUNTING = 1; 4198 var MOUNTED = 2; 4199 var UNMOUNTED = 3; 4200 4201 function isFiberMountedImpl(fiber) { 4202 var node = fiber; 4203 if (!fiber.alternate) { 4204 // If there is no alternate, this might be a new tree that isn't inserted 4205 // yet. If it is, then it will have a pending insertion effect on it. 4206 if ((node.effectTag & Placement) !== NoEffect) { 4207 return MOUNTING; 4208 } 4209 while (node.return) { 4210 node = node.return; 4211 if ((node.effectTag & Placement) !== NoEffect) { 4212 return MOUNTING; 4213 } 4214 } 4215 } else { 4216 while (node.return) { 4217 node = node.return; 4218 } 4219 } 4220 if (node.tag === HostRoot) { 4221 // TODO: Check if this was a nested HostRoot when used with 4222 // renderContainerIntoSubtree. 4223 return MOUNTED; 4224 } 4225 // If we didn't hit the root, that means that we're in an disconnected tree 4226 // that has been unmounted. 4227 return UNMOUNTED; 4228 } 4229 4230 function isFiberMounted(fiber) { 4231 return isFiberMountedImpl(fiber) === MOUNTED; 4232 } 4233 4234 function isMounted(component) { 4235 { 4236 var owner = ReactCurrentOwner$1.current; 4237 if (owner !== null && (owner.tag === ClassComponent || owner.tag === ClassComponentLazy)) { 4238 var ownerFiber = owner; 4239 var instance = ownerFiber.stateNode; 4240 !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; 4241 instance._warnedAboutRefsInRender = true; 4242 } 4243 } 4244 4245 var fiber = get(component); 4246 if (!fiber) { 4247 return false; 4248 } 4249 return isFiberMountedImpl(fiber) === MOUNTED; 4250 } 4251 4252 function assertIsMounted(fiber) { 4253 !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0; 4254 } 4255 4256 function findCurrentFiberUsingSlowPath(fiber) { 4257 var alternate = fiber.alternate; 4258 if (!alternate) { 4259 // If there is no alternate, then we only need to check if it is mounted. 4260 var state = isFiberMountedImpl(fiber); 4261 !(state !== UNMOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0; 4262 if (state === MOUNTING) { 4263 return null; 4264 } 4265 return fiber; 4266 } 4267 // If we have two possible branches, we'll walk backwards up to the root 4268 // to see what path the root points to. On the way we may hit one of the 4269 // special cases and we'll deal with them. 4270 var a = fiber; 4271 var b = alternate; 4272 while (true) { 4273 var parentA = a.return; 4274 var parentB = parentA ? parentA.alternate : null; 4275 if (!parentA || !parentB) { 4276 // We're at the root. 4277 break; 4278 } 4279 4280 // If both copies of the parent fiber point to the same child, we can 4281 // assume that the child is current. This happens when we bailout on low 4282 // priority: the bailed out fiber's child reuses the current child. 4283 if (parentA.child === parentB.child) { 4284 var child = parentA.child; 4285 while (child) { 4286 if (child === a) { 4287 // We've determined that A is the current branch. 4288 assertIsMounted(parentA); 4289 return fiber; 4290 } 4291 if (child === b) { 4292 // We've determined that B is the current branch. 4293 assertIsMounted(parentA); 4294 return alternate; 4295 } 4296 child = child.sibling; 4297 } 4298 // We should never have an alternate for any mounting node. So the only 4299 // way this could possibly happen is if this was unmounted, if at all. 4300 invariant(false, 'Unable to find node on an unmounted component.'); 4301 } 4302 4303 if (a.return !== b.return) { 4304 // The return pointer of A and the return pointer of B point to different 4305 // fibers. We assume that return pointers never criss-cross, so A must 4306 // belong to the child set of A.return, and B must belong to the child 4307 // set of B.return. 4308 a = parentA; 4309 b = parentB; 4310 } else { 4311 // The return pointers point to the same fiber. We'll have to use the 4312 // default, slow path: scan the child sets of each parent alternate to see 4313 // which child belongs to which set. 4314 // 4315 // Search parent A's child set 4316 var didFindChild = false; 4317 var _child = parentA.child; 4318 while (_child) { 4319 if (_child === a) { 4320 didFindChild = true; 4321 a = parentA; 4322 b = parentB; 4323 break; 4324 } 4325 if (_child === b) { 4326 didFindChild = true; 4327 b = parentA; 4328 a = parentB; 4329 break; 4330 } 4331 _child = _child.sibling; 4332 } 4333 if (!didFindChild) { 4334 // Search parent B's child set 4335 _child = parentB.child; 4336 while (_child) { 4337 if (_child === a) { 4338 didFindChild = true; 4339 a = parentB; 4340 b = parentA; 4341 break; 4342 } 4343 if (_child === b) { 4344 didFindChild = true; 4345 b = parentB; 4346 a = parentA; 4347 break; 4348 } 4349 _child = _child.sibling; 4350 } 4351 !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; 4352 } 4353 } 4354 4355 !(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; 4356 } 4357 // If the root is not a host container, we're in a disconnected tree. I.e. 4358 // unmounted. 4359 !(a.tag === HostRoot) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0; 4360 if (a.stateNode.current === a) { 4361 // We've determined that A is the current branch. 4362 return fiber; 4363 } 4364 // Otherwise B has to be current branch. 4365 return alternate; 4366 } 4367 4368 function findCurrentHostFiber(parent) { 4369 var currentParent = findCurrentFiberUsingSlowPath(parent); 4370 if (!currentParent) { 4371 return null; 4372 } 4373 4374 // Next we'll drill down this component to find the first HostComponent/Text. 4375 var node = currentParent; 4376 while (true) { 4377 if (node.tag === HostComponent || node.tag === HostText) { 4378 return node; 4379 } else if (node.child) { 4380 node.child.return = node; 4381 node = node.child; 4382 continue; 4383 } 4384 if (node === currentParent) { 4385 return null; 4386 } 4387 while (!node.sibling) { 4388 if (!node.return || node.return === currentParent) { 4389 return null; 4390 } 4391 node = node.return; 4392 } 4393 node.sibling.return = node.return; 4394 node = node.sibling; 4395 } 4396 // Flow needs the return null here, but ESLint complains about it. 4397 // eslint-disable-next-line no-unreachable 4398 return null; 4399 } 4400 4401 function findCurrentHostFiberWithNoPortals(parent) { 4402 var currentParent = findCurrentFiberUsingSlowPath(parent); 4403 if (!currentParent) { 4404 return null; 4405 } 4406 4407 // Next we'll drill down this component to find the first HostComponent/Text. 4408 var node = currentParent; 4409 while (true) { 4410 if (node.tag === HostComponent || node.tag === HostText) { 4411 return node; 4412 } else if (node.child && node.tag !== HostPortal) { 4413 node.child.return = node; 4414 node = node.child; 4415 continue; 4416 } 4417 if (node === currentParent) { 4418 return null; 4419 } 4420 while (!node.sibling) { 4421 if (!node.return || node.return === currentParent) { 4422 return null; 4423 } 4424 node = node.return; 4425 } 4426 node.sibling.return = node.return; 4427 node = node.sibling; 4428 } 4429 // Flow needs the return null here, but ESLint complains about it. 4430 // eslint-disable-next-line no-unreachable 4431 return null; 4432 } 4433 4434 function addEventBubbleListener(element, eventType, listener) { 4435 element.addEventListener(eventType, listener, false); 4436 } 4437 4438 function addEventCaptureListener(element, eventType, listener) { 4439 element.addEventListener(eventType, listener, true); 4440 } 4441 4442 /** 4443 * @interface Event 4444 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface 4445 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent 4446 */ 4447 var SyntheticAnimationEvent = SyntheticEvent.extend({ 4448 animationName: null, 4449 elapsedTime: null, 4450 pseudoElement: null 4451 }); 4452 4453 /** 4454 * @interface Event 4455 * @see http://www.w3.org/TR/clipboard-apis/ 4456 */ 4457 var SyntheticClipboardEvent = SyntheticEvent.extend({ 4458 clipboardData: function (event) { 4459 return 'clipboardData' in event ? event.clipboardData : window.clipboardData; 4460 } 4461 }); 4462 4463 /** 4464 * @interface FocusEvent 4465 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 4466 */ 4467 var SyntheticFocusEvent = SyntheticUIEvent.extend({ 4468 relatedTarget: null 4469 }); 4470 4471 /** 4472 * `charCode` represents the actual "character code" and is safe to use with 4473 * `String.fromCharCode`. As such, only keys that correspond to printable 4474 * characters produce a valid `charCode`, the only exception to this is Enter. 4475 * The Tab-key is considered non-printable and does not have a `charCode`, 4476 * presumably because it does not produce a tab-character in browsers. 4477 * 4478 * @param {object} nativeEvent Native browser event. 4479 * @return {number} Normalized `charCode` property. 4480 */ 4481 function getEventCharCode(nativeEvent) { 4482 var charCode = void 0; 4483 var keyCode = nativeEvent.keyCode; 4484 4485 if ('charCode' in nativeEvent) { 4486 charCode = nativeEvent.charCode; 4487 4488 // FF does not set `charCode` for the Enter-key, check against `keyCode`. 4489 if (charCode === 0 && keyCode === 13) { 4490 charCode = 13; 4491 } 4492 } else { 4493 // IE8 does not implement `charCode`, but `keyCode` has the correct value. 4494 charCode = keyCode; 4495 } 4496 4497 // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux) 4498 // report Enter as charCode 10 when ctrl is pressed. 4499 if (charCode === 10) { 4500 charCode = 13; 4501 } 4502 4503 // Some non-printable keys are reported in `charCode`/`keyCode`, discard them. 4504 // Must not discard the (non-)printable Enter-key. 4505 if (charCode >= 32 || charCode === 13) { 4506 return charCode; 4507 } 4508 4509 return 0; 4510 } 4511 4512 /** 4513 * Normalization of deprecated HTML5 `key` values 4514 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names 4515 */ 4516 var normalizeKey = { 4517 Esc: 'Escape', 4518 Spacebar: ' ', 4519 Left: 'ArrowLeft', 4520 Up: 'ArrowUp', 4521 Right: 'ArrowRight', 4522 Down: 'ArrowDown', 4523 Del: 'Delete', 4524 Win: 'OS', 4525 Menu: 'ContextMenu', 4526 Apps: 'ContextMenu', 4527 Scroll: 'ScrollLock', 4528 MozPrintableKey: 'Unidentified' 4529 }; 4530 4531 /** 4532 * Translation from legacy `keyCode` to HTML5 `key` 4533 * Only special keys supported, all others depend on keyboard layout or browser 4534 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names 4535 */ 4536 var translateToKey = { 4537 '8': 'Backspace', 4538 '9': 'Tab', 4539 '12': 'Clear', 4540 '13': 'Enter', 4541 '16': 'Shift', 4542 '17': 'Control', 4543 '18': 'Alt', 4544 '19': 'Pause', 4545 '20': 'CapsLock', 4546 '27': 'Escape', 4547 '32': ' ', 4548 '33': 'PageUp', 4549 '34': 'PageDown', 4550 '35': 'End', 4551 '36': 'Home', 4552 '37': 'ArrowLeft', 4553 '38': 'ArrowUp', 4554 '39': 'ArrowRight', 4555 '40': 'ArrowDown', 4556 '45': 'Insert', 4557 '46': 'Delete', 4558 '112': 'F1', 4559 '113': 'F2', 4560 '114': 'F3', 4561 '115': 'F4', 4562 '116': 'F5', 4563 '117': 'F6', 4564 '118': 'F7', 4565 '119': 'F8', 4566 '120': 'F9', 4567 '121': 'F10', 4568 '122': 'F11', 4569 '123': 'F12', 4570 '144': 'NumLock', 4571 '145': 'ScrollLock', 4572 '224': 'Meta' 4573 }; 4574 4575 /** 4576 * @param {object} nativeEvent Native browser event. 4577 * @return {string} Normalized `key` property. 4578 */ 4579 function getEventKey(nativeEvent) { 4580 if (nativeEvent.key) { 4581 // Normalize inconsistent values reported by browsers due to 4582 // implementations of a working draft specification. 4583 4584 // FireFox implements `key` but returns `MozPrintableKey` for all 4585 // printable characters (normalized to `Unidentified`), ignore it. 4586 var key = normalizeKey[nativeEvent.key] || nativeEvent.key; 4587 if (key !== 'Unidentified') { 4588 return key; 4589 } 4590 } 4591 4592 // Browser does not implement `key`, polyfill as much of it as we can. 4593 if (nativeEvent.type === 'keypress') { 4594 var charCode = getEventCharCode(nativeEvent); 4595 4596 // The enter-key is technically both printable and non-printable and can 4597 // thus be captured by `keypress`, no other non-printable key should. 4598 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode); 4599 } 4600 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') { 4601 // While user keyboard layout determines the actual meaning of each 4602 // `keyCode` value, almost all function keys have a universal value. 4603 return translateToKey[nativeEvent.keyCode] || 'Unidentified'; 4604 } 4605 return ''; 4606 } 4607 4608 /** 4609 * @interface KeyboardEvent 4610 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 4611 */ 4612 var SyntheticKeyboardEvent = SyntheticUIEvent.extend({ 4613 key: getEventKey, 4614 location: null, 4615 ctrlKey: null, 4616 shiftKey: null, 4617 altKey: null, 4618 metaKey: null, 4619 repeat: null, 4620 locale: null, 4621 getModifierState: getEventModifierState, 4622 // Legacy Interface 4623 charCode: function (event) { 4624 // `charCode` is the result of a KeyPress event and represents the value of 4625 // the actual printable character. 4626 4627 // KeyPress is deprecated, but its replacement is not yet final and not 4628 // implemented in any major browser. Only KeyPress has charCode. 4629 if (event.type === 'keypress') { 4630 return getEventCharCode(event); 4631 } 4632 return 0; 4633 }, 4634 keyCode: function (event) { 4635 // `keyCode` is the result of a KeyDown/Up event and represents the value of 4636 // physical keyboard key. 4637 4638 // The actual meaning of the value depends on the users' keyboard layout 4639 // which cannot be detected. Assuming that it is a US keyboard layout 4640 // provides a surprisingly accurate mapping for US and European users. 4641 // Due to this, it is left to the user to implement at this time. 4642 if (event.type === 'keydown' || event.type === 'keyup') { 4643 return event.keyCode; 4644 } 4645 return 0; 4646 }, 4647 which: function (event) { 4648 // `which` is an alias for either `keyCode` or `charCode` depending on the 4649 // type of the event. 4650 if (event.type === 'keypress') { 4651 return getEventCharCode(event); 4652 } 4653 if (event.type === 'keydown' || event.type === 'keyup') { 4654 return event.keyCode; 4655 } 4656 return 0; 4657 } 4658 }); 4659 4660 /** 4661 * @interface DragEvent 4662 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 4663 */ 4664 var SyntheticDragEvent = SyntheticMouseEvent.extend({ 4665 dataTransfer: null 4666 }); 4667 4668 /** 4669 * @interface TouchEvent 4670 * @see http://www.w3.org/TR/touch-events/ 4671 */ 4672 var SyntheticTouchEvent = SyntheticUIEvent.extend({ 4673 touches: null, 4674 targetTouches: null, 4675 changedTouches: null, 4676 altKey: null, 4677 metaKey: null, 4678 ctrlKey: null, 4679 shiftKey: null, 4680 getModifierState: getEventModifierState 4681 }); 4682 4683 /** 4684 * @interface Event 4685 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events- 4686 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent 4687 */ 4688 var SyntheticTransitionEvent = SyntheticEvent.extend({ 4689 propertyName: null, 4690 elapsedTime: null, 4691 pseudoElement: null 4692 }); 4693 4694 /** 4695 * @interface WheelEvent 4696 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 4697 */ 4698 var SyntheticWheelEvent = SyntheticMouseEvent.extend({ 4699 deltaX: function (event) { 4700 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive). 4701 'wheelDeltaX' in event ? -event.wheelDeltaX : 0; 4702 }, 4703 deltaY: function (event) { 4704 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive). 4705 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive). 4706 'wheelDelta' in event ? -event.wheelDelta : 0; 4707 }, 4708 4709 deltaZ: null, 4710 4711 // Browsers without "deltaMode" is reporting in raw wheel delta where one 4712 // notch on the scroll is always +/- 120, roughly equivalent to pixels. 4713 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or 4714 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size. 4715 deltaMode: null 4716 }); 4717 4718 /** 4719 * Turns 4720 * ['abort', ...] 4721 * into 4722 * eventTypes = { 4723 * 'abort': { 4724 * phasedRegistrationNames: { 4725 * bubbled: 'onAbort', 4726 * captured: 'onAbortCapture', 4727 * }, 4728 * dependencies: [TOP_ABORT], 4729 * }, 4730 * ... 4731 * }; 4732 * topLevelEventsToDispatchConfig = new Map([ 4733 * [TOP_ABORT, { sameConfig }], 4734 * ]); 4735 */ 4736 4737 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']]; 4738 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']]; 4739 4740 var eventTypes$4 = {}; 4741 var topLevelEventsToDispatchConfig = {}; 4742 4743 function addEventTypeNameToConfig(_ref, isInteractive) { 4744 var topEvent = _ref[0], 4745 event = _ref[1]; 4746 4747 var capitalizedEvent = event[0].toUpperCase() + event.slice(1); 4748 var onEvent = 'on' + capitalizedEvent; 4749 4750 var type = { 4751 phasedRegistrationNames: { 4752 bubbled: onEvent, 4753 captured: onEvent + 'Capture' 4754 }, 4755 dependencies: [topEvent], 4756 isInteractive: isInteractive 4757 }; 4758 eventTypes$4[event] = type; 4759 topLevelEventsToDispatchConfig[topEvent] = type; 4760 } 4761 4762 interactiveEventTypeNames.forEach(function (eventTuple) { 4763 addEventTypeNameToConfig(eventTuple, true); 4764 }); 4765 nonInteractiveEventTypeNames.forEach(function (eventTuple) { 4766 addEventTypeNameToConfig(eventTuple, false); 4767 }); 4768 4769 // Only used in DEV for exhaustiveness validation. 4770 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]; 4771 4772 var SimpleEventPlugin = { 4773 eventTypes: eventTypes$4, 4774 4775 isInteractiveTopLevelEventType: function (topLevelType) { 4776 var config = topLevelEventsToDispatchConfig[topLevelType]; 4777 return config !== undefined && config.isInteractive === true; 4778 }, 4779 4780 4781 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { 4782 var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType]; 4783 if (!dispatchConfig) { 4784 return null; 4785 } 4786 var EventConstructor = void 0; 4787 switch (topLevelType) { 4788 case TOP_KEY_PRESS: 4789 // Firefox creates a keypress event for function keys too. This removes 4790 // the unwanted keypress events. Enter is however both printable and 4791 // non-printable. One would expect Tab to be as well (but it isn't). 4792 if (getEventCharCode(nativeEvent) === 0) { 4793 return null; 4794 } 4795 /* falls through */ 4796 case TOP_KEY_DOWN: 4797 case TOP_KEY_UP: 4798 EventConstructor = SyntheticKeyboardEvent; 4799 break; 4800 case TOP_BLUR: 4801 case TOP_FOCUS: 4802 EventConstructor = SyntheticFocusEvent; 4803 break; 4804 case TOP_CLICK: 4805 // Firefox creates a click event on right mouse clicks. This removes the 4806 // unwanted click events. 4807 if (nativeEvent.button === 2) { 4808 return null; 4809 } 4810 /* falls through */ 4811 case TOP_AUX_CLICK: 4812 case TOP_DOUBLE_CLICK: 4813 case TOP_MOUSE_DOWN: 4814 case TOP_MOUSE_MOVE: 4815 case TOP_MOUSE_UP: 4816 // TODO: Disabled elements should not respond to mouse events 4817 /* falls through */ 4818 case TOP_MOUSE_OUT: 4819 case TOP_MOUSE_OVER: 4820 case TOP_CONTEXT_MENU: 4821 EventConstructor = SyntheticMouseEvent; 4822 break; 4823 case TOP_DRAG: 4824 case TOP_DRAG_END: 4825 case TOP_DRAG_ENTER: 4826 case TOP_DRAG_EXIT: 4827 case TOP_DRAG_LEAVE: 4828 case TOP_DRAG_OVER: 4829 case TOP_DRAG_START: 4830 case TOP_DROP: 4831 EventConstructor = SyntheticDragEvent; 4832 break; 4833 case TOP_TOUCH_CANCEL: 4834 case TOP_TOUCH_END: 4835 case TOP_TOUCH_MOVE: 4836 case TOP_TOUCH_START: 4837 EventConstructor = SyntheticTouchEvent; 4838 break; 4839 case TOP_ANIMATION_END: 4840 case TOP_ANIMATION_ITERATION: 4841 case TOP_ANIMATION_START: 4842 EventConstructor = SyntheticAnimationEvent; 4843 break; 4844 case TOP_TRANSITION_END: 4845 EventConstructor = SyntheticTransitionEvent; 4846 break; 4847 case TOP_SCROLL: 4848 EventConstructor = SyntheticUIEvent; 4849 break; 4850 case TOP_WHEEL: 4851 EventConstructor = SyntheticWheelEvent; 4852 break; 4853 case TOP_COPY: 4854 case TOP_CUT: 4855 case TOP_PASTE: 4856 EventConstructor = SyntheticClipboardEvent; 4857 break; 4858 case TOP_GOT_POINTER_CAPTURE: 4859 case TOP_LOST_POINTER_CAPTURE: 4860 case TOP_POINTER_CANCEL: 4861 case TOP_POINTER_DOWN: 4862 case TOP_POINTER_MOVE: 4863 case TOP_POINTER_OUT: 4864 case TOP_POINTER_OVER: 4865 case TOP_POINTER_UP: 4866 EventConstructor = SyntheticPointerEvent; 4867 break; 4868 default: 4869 { 4870 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) { 4871 warningWithoutStack$1(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType); 4872 } 4873 } 4874 // HTML Events 4875 // @see http://www.w3.org/TR/html5/index.html#events-0 4876 EventConstructor = SyntheticEvent; 4877 break; 4878 } 4879 var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget); 4880 accumulateTwoPhaseDispatches(event); 4881 return event; 4882 } 4883 }; 4884 4885 var isInteractiveTopLevelEventType = SimpleEventPlugin.isInteractiveTopLevelEventType; 4886 4887 4888 var CALLBACK_BOOKKEEPING_POOL_SIZE = 10; 4889 var callbackBookkeepingPool = []; 4890 4891 /** 4892 * Find the deepest React component completely containing the root of the 4893 * passed-in instance (for use when entire React trees are nested within each 4894 * other). If React trees are not nested, returns null. 4895 */ 4896 function findRootContainerNode(inst) { 4897 // TODO: It may be a good idea to cache this to prevent unnecessary DOM 4898 // traversal, but caching is difficult to do correctly without using a 4899 // mutation observer to listen for all DOM changes. 4900 while (inst.return) { 4901 inst = inst.return; 4902 } 4903 if (inst.tag !== HostRoot) { 4904 // This can happen if we're in a detached tree. 4905 return null; 4906 } 4907 return inst.stateNode.containerInfo; 4908 } 4909 4910 // Used to store ancestor hierarchy in top level callback 4911 function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst) { 4912 if (callbackBookkeepingPool.length) { 4913 var instance = callbackBookkeepingPool.pop(); 4914 instance.topLevelType = topLevelType; 4915 instance.nativeEvent = nativeEvent; 4916 instance.targetInst = targetInst; 4917 return instance; 4918 } 4919 return { 4920 topLevelType: topLevelType, 4921 nativeEvent: nativeEvent, 4922 targetInst: targetInst, 4923 ancestors: [] 4924 }; 4925 } 4926 4927 function releaseTopLevelCallbackBookKeeping(instance) { 4928 instance.topLevelType = null; 4929 instance.nativeEvent = null; 4930 instance.targetInst = null; 4931 instance.ancestors.length = 0; 4932 if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) { 4933 callbackBookkeepingPool.push(instance); 4934 } 4935 } 4936 4937 function handleTopLevel(bookKeeping) { 4938 var targetInst = bookKeeping.targetInst; 4939 4940 // Loop through the hierarchy, in case there's any nested components. 4941 // It's important that we build the array of ancestors before calling any 4942 // event handlers, because event handlers can modify the DOM, leading to 4943 // inconsistencies with ReactMount's node cache. See #1105. 4944 var ancestor = targetInst; 4945 do { 4946 if (!ancestor) { 4947 bookKeeping.ancestors.push(ancestor); 4948 break; 4949 } 4950 var root = findRootContainerNode(ancestor); 4951 if (!root) { 4952 break; 4953 } 4954 bookKeeping.ancestors.push(ancestor); 4955 ancestor = getClosestInstanceFromNode(root); 4956 } while (ancestor); 4957 4958 for (var i = 0; i < bookKeeping.ancestors.length; i++) { 4959 targetInst = bookKeeping.ancestors[i]; 4960 runExtractedEventsInBatch(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent)); 4961 } 4962 } 4963 4964 // TODO: can we stop exporting these? 4965 var _enabled = true; 4966 4967 function setEnabled(enabled) { 4968 _enabled = !!enabled; 4969 } 4970 4971 function isEnabled() { 4972 return _enabled; 4973 } 4974 4975 /** 4976 * Traps top-level events by using event bubbling. 4977 * 4978 * @param {number} topLevelType Number from `TopLevelEventTypes`. 4979 * @param {object} element Element on which to attach listener. 4980 * @return {?object} An object with a remove function which will forcefully 4981 * remove the listener. 4982 * @internal 4983 */ 4984 function trapBubbledEvent(topLevelType, element) { 4985 if (!element) { 4986 return null; 4987 } 4988 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent; 4989 4990 addEventBubbleListener(element, getRawEventName(topLevelType), 4991 // Check if interactive and wrap in interactiveUpdates 4992 dispatch.bind(null, topLevelType)); 4993 } 4994 4995 /** 4996 * Traps a top-level event by using event capturing. 4997 * 4998 * @param {number} topLevelType Number from `TopLevelEventTypes`. 4999 * @param {object} element Element on which to attach listener. 5000 * @return {?object} An object with a remove function which will forcefully 5001 * remove the listener. 5002 * @internal 5003 */ 5004 function trapCapturedEvent(topLevelType, element) { 5005 if (!element) { 5006 return null; 5007 } 5008 var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent; 5009 5010 addEventCaptureListener(element, getRawEventName(topLevelType), 5011 // Check if interactive and wrap in interactiveUpdates 5012 dispatch.bind(null, topLevelType)); 5013 } 5014 5015 function dispatchInteractiveEvent(topLevelType, nativeEvent) { 5016 interactiveUpdates(dispatchEvent, topLevelType, nativeEvent); 5017 } 5018 5019 function dispatchEvent(topLevelType, nativeEvent) { 5020 if (!_enabled) { 5021 return; 5022 } 5023 5024 var nativeEventTarget = getEventTarget(nativeEvent); 5025 var targetInst = getClosestInstanceFromNode(nativeEventTarget); 5026 if (targetInst !== null && typeof targetInst.tag === 'number' && !isFiberMounted(targetInst)) { 5027 // If we get an event (ex: img onload) before committing that 5028 // component's mount, ignore it for now (that is, treat it as if it was an 5029 // event on a non-React tree). We might also consider queueing events and 5030 // dispatching them after the mount. 5031 targetInst = null; 5032 } 5033 5034 var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst); 5035 5036 try { 5037 // Event queue being processed in the same cycle allows 5038 // `preventDefault`. 5039 batchedUpdates(handleTopLevel, bookKeeping); 5040 } finally { 5041 releaseTopLevelCallbackBookKeeping(bookKeeping); 5042 } 5043 } 5044 5045 /** 5046 * Summary of `ReactBrowserEventEmitter` event handling: 5047 * 5048 * - Top-level delegation is used to trap most native browser events. This 5049 * may only occur in the main thread and is the responsibility of 5050 * ReactDOMEventListener, which is injected and can therefore support 5051 * pluggable event sources. This is the only work that occurs in the main 5052 * thread. 5053 * 5054 * - We normalize and de-duplicate events to account for browser quirks. This 5055 * may be done in the worker thread. 5056 * 5057 * - Forward these native events (with the associated top-level type used to 5058 * trap it) to `EventPluginHub`, which in turn will ask plugins if they want 5059 * to extract any synthetic events. 5060 * 5061 * - The `EventPluginHub` will then process each event by annotating them with 5062 * "dispatches", a sequence of listeners and IDs that care about that event. 5063 * 5064 * - The `EventPluginHub` then dispatches the events. 5065 * 5066 * Overview of React and the event system: 5067 * 5068 * +------------+ . 5069 * | DOM | . 5070 * +------------+ . 5071 * | . 5072 * v . 5073 * +------------+ . 5074 * | ReactEvent | . 5075 * | Listener | . 5076 * +------------+ . +-----------+ 5077 * | . +--------+|SimpleEvent| 5078 * | . | |Plugin | 5079 * +-----|------+ . v +-----------+ 5080 * | | | . +--------------+ +------------+ 5081 * | +-----------.--->|EventPluginHub| | Event | 5082 * | | . | | +-----------+ | Propagators| 5083 * | ReactEvent | . | | |TapEvent | |------------| 5084 * | Emitter | . | |<---+|Plugin | |other plugin| 5085 * | | . | | +-----------+ | utilities | 5086 * | +-----------.--->| | +------------+ 5087 * | | | . +--------------+ 5088 * +-----|------+ . ^ +-----------+ 5089 * | . | |Enter/Leave| 5090 * + . +-------+|Plugin | 5091 * +-------------+ . +-----------+ 5092 * | application | . 5093 * |-------------| . 5094 * | | . 5095 * | | . 5096 * +-------------+ . 5097 * . 5098 * React Core . General Purpose Event Plugin System 5099 */ 5100 5101 var alreadyListeningTo = {}; 5102 var reactTopListenersCounter = 0; 5103 5104 /** 5105 * To ensure no conflicts with other potential React instances on the page 5106 */ 5107 var topListenersIDKey = '_reactListenersID' + ('' + Math.random()).slice(2); 5108 5109 function getListeningForDocument(mountAt) { 5110 // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty` 5111 // directly. 5112 if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) { 5113 mountAt[topListenersIDKey] = reactTopListenersCounter++; 5114 alreadyListeningTo[mountAt[topListenersIDKey]] = {}; 5115 } 5116 return alreadyListeningTo[mountAt[topListenersIDKey]]; 5117 } 5118 5119 /** 5120 * We listen for bubbled touch events on the document object. 5121 * 5122 * Firefox v8.01 (and possibly others) exhibited strange behavior when 5123 * mounting `onmousemove` events at some node that was not the document 5124 * element. The symptoms were that if your mouse is not moving over something 5125 * contained within that mount point (for example on the background) the 5126 * top-level listeners for `onmousemove` won't be called. However, if you 5127 * register the `mousemove` on the document object, then it will of course 5128 * catch all `mousemove`s. This along with iOS quirks, justifies restricting 5129 * top-level listeners to the document object only, at least for these 5130 * movement types of events and possibly all events. 5131 * 5132 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html 5133 * 5134 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but 5135 * they bubble to document. 5136 * 5137 * @param {string} registrationName Name of listener (e.g. `onClick`). 5138 * @param {object} mountAt Container where to mount the listener 5139 */ 5140 function listenTo(registrationName, mountAt) { 5141 var isListening = getListeningForDocument(mountAt); 5142 var dependencies = registrationNameDependencies[registrationName]; 5143 5144 for (var i = 0; i < dependencies.length; i++) { 5145 var dependency = dependencies[i]; 5146 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) { 5147 switch (dependency) { 5148 case TOP_SCROLL: 5149 trapCapturedEvent(TOP_SCROLL, mountAt); 5150 break; 5151 case TOP_FOCUS: 5152 case TOP_BLUR: 5153 trapCapturedEvent(TOP_FOCUS, mountAt); 5154 trapCapturedEvent(TOP_BLUR, mountAt); 5155 // We set the flag for a single dependency later in this function, 5156 // but this ensures we mark both as attached rather than just one. 5157 isListening[TOP_BLUR] = true; 5158 isListening[TOP_FOCUS] = true; 5159 break; 5160 case TOP_CANCEL: 5161 case TOP_CLOSE: 5162 if (isEventSupported(getRawEventName(dependency))) { 5163 trapCapturedEvent(dependency, mountAt); 5164 } 5165 break; 5166 case TOP_INVALID: 5167 case TOP_SUBMIT: 5168 case TOP_RESET: 5169 // We listen to them on the target DOM elements. 5170 // Some of them bubble so we don't want them to fire twice. 5171 break; 5172 default: 5173 // By default, listen on the top level to all non-media events. 5174 // Media events don't bubble so adding the listener wouldn't do anything. 5175 var isMediaEvent = mediaEventTypes.indexOf(dependency) !== -1; 5176 if (!isMediaEvent) { 5177 trapBubbledEvent(dependency, mountAt); 5178 } 5179 break; 5180 } 5181 isListening[dependency] = true; 5182 } 5183 } 5184 } 5185 5186 function isListeningToAllDependencies(registrationName, mountAt) { 5187 var isListening = getListeningForDocument(mountAt); 5188 var dependencies = registrationNameDependencies[registrationName]; 5189 for (var i = 0; i < dependencies.length; i++) { 5190 var dependency = dependencies[i]; 5191 if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) { 5192 return false; 5193 } 5194 } 5195 return true; 5196 } 5197 5198 function getActiveElement(doc) { 5199 doc = doc || (typeof document !== 'undefined' ? document : undefined); 5200 if (typeof doc === 'undefined') { 5201 return null; 5202 } 5203 try { 5204 return doc.activeElement || doc.body; 5205 } catch (e) { 5206 return doc.body; 5207 } 5208 } 5209 5210 /** 5211 * Given any node return the first leaf node without children. 5212 * 5213 * @param {DOMElement|DOMTextNode} node 5214 * @return {DOMElement|DOMTextNode} 5215 */ 5216 function getLeafNode(node) { 5217 while (node && node.firstChild) { 5218 node = node.firstChild; 5219 } 5220 return node; 5221 } 5222 5223 /** 5224 * Get the next sibling within a container. This will walk up the 5225 * DOM if a node's siblings have been exhausted. 5226 * 5227 * @param {DOMElement|DOMTextNode} node 5228 * @return {?DOMElement|DOMTextNode} 5229 */ 5230 function getSiblingNode(node) { 5231 while (node) { 5232 if (node.nextSibling) { 5233 return node.nextSibling; 5234 } 5235 node = node.parentNode; 5236 } 5237 } 5238 5239 /** 5240 * Get object describing the nodes which contain characters at offset. 5241 * 5242 * @param {DOMElement|DOMTextNode} root 5243 * @param {number} offset 5244 * @return {?object} 5245 */ 5246 function getNodeForCharacterOffset(root, offset) { 5247 var node = getLeafNode(root); 5248 var nodeStart = 0; 5249 var nodeEnd = 0; 5250 5251 while (node) { 5252 if (node.nodeType === TEXT_NODE) { 5253 nodeEnd = nodeStart + node.textContent.length; 5254 5255 if (nodeStart <= offset && nodeEnd >= offset) { 5256 return { 5257 node: node, 5258 offset: offset - nodeStart 5259 }; 5260 } 5261 5262 nodeStart = nodeEnd; 5263 } 5264 5265 node = getLeafNode(getSiblingNode(node)); 5266 } 5267 } 5268 5269 /** 5270 * @param {DOMElement} outerNode 5271 * @return {?object} 5272 */ 5273 function getOffsets(outerNode) { 5274 var ownerDocument = outerNode.ownerDocument; 5275 5276 var win = ownerDocument && ownerDocument.defaultView || window; 5277 var selection = win.getSelection && win.getSelection(); 5278 5279 if (!selection || selection.rangeCount === 0) { 5280 return null; 5281 } 5282 5283 var anchorNode = selection.anchorNode, 5284 anchorOffset = selection.anchorOffset, 5285 focusNode = selection.focusNode, 5286 focusOffset = selection.focusOffset; 5287 5288 // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the 5289 // up/down buttons on an <input type="number">. Anonymous divs do not seem to 5290 // expose properties, triggering a "Permission denied error" if any of its 5291 // properties are accessed. The only seemingly possible way to avoid erroring 5292 // is to access a property that typically works for non-anonymous divs and 5293 // catch any error that may otherwise arise. See 5294 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427 5295 5296 try { 5297 /* eslint-disable no-unused-expressions */ 5298 anchorNode.nodeType; 5299 focusNode.nodeType; 5300 /* eslint-enable no-unused-expressions */ 5301 } catch (e) { 5302 return null; 5303 } 5304 5305 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset); 5306 } 5307 5308 /** 5309 * Returns {start, end} where `start` is the character/codepoint index of 5310 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and 5311 * `end` is the index of (focusNode, focusOffset). 5312 * 5313 * Returns null if you pass in garbage input but we should probably just crash. 5314 * 5315 * Exported only for testing. 5316 */ 5317 function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) { 5318 var length = 0; 5319 var start = -1; 5320 var end = -1; 5321 var indexWithinAnchor = 0; 5322 var indexWithinFocus = 0; 5323 var node = outerNode; 5324 var parentNode = null; 5325 5326 outer: while (true) { 5327 var next = null; 5328 5329 while (true) { 5330 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) { 5331 start = length + anchorOffset; 5332 } 5333 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) { 5334 end = length + focusOffset; 5335 } 5336 5337 if (node.nodeType === TEXT_NODE) { 5338 length += node.nodeValue.length; 5339 } 5340 5341 if ((next = node.firstChild) === null) { 5342 break; 5343 } 5344 // Moving from `node` to its first child `next`. 5345 parentNode = node; 5346 node = next; 5347 } 5348 5349 while (true) { 5350 if (node === outerNode) { 5351 // If `outerNode` has children, this is always the second time visiting 5352 // it. If it has no children, this is still the first loop, and the only 5353 // valid selection is anchorNode and focusNode both equal to this node 5354 // and both offsets 0, in which case we will have handled above. 5355 break outer; 5356 } 5357 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) { 5358 start = length; 5359 } 5360 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) { 5361 end = length; 5362 } 5363 if ((next = node.nextSibling) !== null) { 5364 break; 5365 } 5366 node = parentNode; 5367 parentNode = node.parentNode; 5368 } 5369 5370 // Moving from `node` to its next sibling `next`. 5371 node = next; 5372 } 5373 5374 if (start === -1 || end === -1) { 5375 // This should never happen. (Would happen if the anchor/focus nodes aren't 5376 // actually inside the passed-in node.) 5377 return null; 5378 } 5379 5380 return { 5381 start: start, 5382 end: end 5383 }; 5384 } 5385 5386 /** 5387 * In modern non-IE browsers, we can support both forward and backward 5388 * selections. 5389 * 5390 * Note: IE10+ supports the Selection object, but it does not support 5391 * the `extend` method, which means that even in modern IE, it's not possible 5392 * to programmatically create a backward selection. Thus, for all IE 5393 * versions, we use the old IE API to create our selections. 5394 * 5395 * @param {DOMElement|DOMTextNode} node 5396 * @param {object} offsets 5397 */ 5398 function setOffsets(node, offsets) { 5399 var doc = node.ownerDocument || document; 5400 var win = doc && doc.defaultView || window; 5401 var selection = win.getSelection(); 5402 var length = node.textContent.length; 5403 var start = Math.min(offsets.start, length); 5404 var end = offsets.end === undefined ? start : Math.min(offsets.end, length); 5405 5406 // IE 11 uses modern selection, but doesn't support the extend method. 5407 // Flip backward selections, so we can set with a single range. 5408 if (!selection.extend && start > end) { 5409 var temp = end; 5410 end = start; 5411 start = temp; 5412 } 5413 5414 var startMarker = getNodeForCharacterOffset(node, start); 5415 var endMarker = getNodeForCharacterOffset(node, end); 5416 5417 if (startMarker && endMarker) { 5418 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) { 5419 return; 5420 } 5421 var range = doc.createRange(); 5422 range.setStart(startMarker.node, startMarker.offset); 5423 selection.removeAllRanges(); 5424 5425 if (start > end) { 5426 selection.addRange(range); 5427 selection.extend(endMarker.node, endMarker.offset); 5428 } else { 5429 range.setEnd(endMarker.node, endMarker.offset); 5430 selection.addRange(range); 5431 } 5432 } 5433 } 5434 5435 function isTextNode(node) { 5436 return node && node.nodeType === TEXT_NODE; 5437 } 5438 5439 function containsNode(outerNode, innerNode) { 5440 if (!outerNode || !innerNode) { 5441 return false; 5442 } else if (outerNode === innerNode) { 5443 return true; 5444 } else if (isTextNode(outerNode)) { 5445 return false; 5446 } else if (isTextNode(innerNode)) { 5447 return containsNode(outerNode, innerNode.parentNode); 5448 } else if ('contains' in outerNode) { 5449 return outerNode.contains(innerNode); 5450 } else if (outerNode.compareDocumentPosition) { 5451 return !!(outerNode.compareDocumentPosition(innerNode) & 16); 5452 } else { 5453 return false; 5454 } 5455 } 5456 5457 function isInDocument(node) { 5458 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node); 5459 } 5460 5461 function getActiveElementDeep() { 5462 var win = window; 5463 var element = getActiveElement(); 5464 while (element instanceof win.HTMLIFrameElement) { 5465 // Accessing the contentDocument of a HTMLIframeElement can cause the browser 5466 // to throw, e.g. if it has a cross-origin src attribute 5467 try { 5468 win = element.contentDocument.defaultView; 5469 } catch (e) { 5470 return element; 5471 } 5472 element = getActiveElement(win.document); 5473 } 5474 return element; 5475 } 5476 5477 /** 5478 * @ReactInputSelection: React input selection module. Based on Selection.js, 5479 * but modified to be suitable for react and has a couple of bug fixes (doesn't 5480 * assume buttons have range selections allowed). 5481 * Input selection module for React. 5482 */ 5483 5484 /** 5485 * @hasSelectionCapabilities: we get the element types that support selection 5486 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart` 5487 * and `selectionEnd` rows. 5488 */ 5489 function hasSelectionCapabilities(elem) { 5490 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); 5491 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true'); 5492 } 5493 5494 function getSelectionInformation() { 5495 var focusedElem = getActiveElementDeep(); 5496 return { 5497 focusedElem: focusedElem, 5498 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection$1(focusedElem) : null 5499 }; 5500 } 5501 5502 /** 5503 * @restoreSelection: If any selection information was potentially lost, 5504 * restore it. This is useful when performing operations that could remove dom 5505 * nodes and place them back in, resulting in focus being lost. 5506 */ 5507 function restoreSelection(priorSelectionInformation) { 5508 var curFocusedElem = getActiveElementDeep(); 5509 var priorFocusedElem = priorSelectionInformation.focusedElem; 5510 var priorSelectionRange = priorSelectionInformation.selectionRange; 5511 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) { 5512 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) { 5513 setSelection(priorFocusedElem, priorSelectionRange); 5514 } 5515 5516 // Focusing a node can change the scroll position, which is undesirable 5517 var ancestors = []; 5518 var ancestor = priorFocusedElem; 5519 while (ancestor = ancestor.parentNode) { 5520 if (ancestor.nodeType === ELEMENT_NODE) { 5521 ancestors.push({ 5522 element: ancestor, 5523 left: ancestor.scrollLeft, 5524 top: ancestor.scrollTop 5525 }); 5526 } 5527 } 5528 5529 if (typeof priorFocusedElem.focus === 'function') { 5530 priorFocusedElem.focus(); 5531 } 5532 5533 for (var i = 0; i < ancestors.length; i++) { 5534 var info = ancestors[i]; 5535 info.element.scrollLeft = info.left; 5536 info.element.scrollTop = info.top; 5537 } 5538 } 5539 } 5540 5541 /** 5542 * @getSelection: Gets the selection bounds of a focused textarea, input or 5543 * contentEditable node. 5544 * -@input: Look up selection bounds of this input 5545 * -@return {start: selectionStart, end: selectionEnd} 5546 */ 5547 function getSelection$1(input) { 5548 var selection = void 0; 5549 5550 if ('selectionStart' in input) { 5551 // Modern browser with input or textarea. 5552 selection = { 5553 start: input.selectionStart, 5554 end: input.selectionEnd 5555 }; 5556 } else { 5557 // Content editable or old IE textarea. 5558 selection = getOffsets(input); 5559 } 5560 5561 return selection || { start: 0, end: 0 }; 5562 } 5563 5564 /** 5565 * @setSelection: Sets the selection bounds of a textarea or input and focuses 5566 * the input. 5567 * -@input Set selection bounds of this input or textarea 5568 * -@offsets Object of same form that is returned from get* 5569 */ 5570 function setSelection(input, offsets) { 5571 var start = offsets.start, 5572 end = offsets.end; 5573 5574 if (end === undefined) { 5575 end = start; 5576 } 5577 5578 if ('selectionStart' in input) { 5579 input.selectionStart = start; 5580 input.selectionEnd = Math.min(end, input.value.length); 5581 } else { 5582 setOffsets(input, offsets); 5583 } 5584 } 5585 5586 var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11; 5587 5588 var eventTypes$3 = { 5589 select: { 5590 phasedRegistrationNames: { 5591 bubbled: 'onSelect', 5592 captured: 'onSelectCapture' 5593 }, 5594 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] 5595 } 5596 }; 5597 5598 var activeElement$1 = null; 5599 var activeElementInst$1 = null; 5600 var lastSelection = null; 5601 var mouseDown = false; 5602 5603 /** 5604 * Get an object which is a unique representation of the current selection. 5605 * 5606 * The return value will not be consistent across nodes or browsers, but 5607 * two identical selections on the same node will return identical objects. 5608 * 5609 * @param {DOMElement} node 5610 * @return {object} 5611 */ 5612 function getSelection(node) { 5613 if ('selectionStart' in node && hasSelectionCapabilities(node)) { 5614 return { 5615 start: node.selectionStart, 5616 end: node.selectionEnd 5617 }; 5618 } else { 5619 var win = node.ownerDocument && node.ownerDocument.defaultView || window; 5620 var selection = win.getSelection(); 5621 return { 5622 anchorNode: selection.anchorNode, 5623 anchorOffset: selection.anchorOffset, 5624 focusNode: selection.focusNode, 5625 focusOffset: selection.focusOffset 5626 }; 5627 } 5628 } 5629 5630 /** 5631 * Get document associated with the event target. 5632 * 5633 * @param {object} nativeEventTarget 5634 * @return {Document} 5635 */ 5636 function getEventTargetDocument(eventTarget) { 5637 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument; 5638 } 5639 5640 /** 5641 * Poll selection to see whether it's changed. 5642 * 5643 * @param {object} nativeEvent 5644 * @param {object} nativeEventTarget 5645 * @return {?SyntheticEvent} 5646 */ 5647 function constructSelectEvent(nativeEvent, nativeEventTarget) { 5648 // Ensure we have the right element, and that the user is not dragging a 5649 // selection (this matches native `select` event behavior). In HTML5, select 5650 // fires only on input and textarea thus if there's no focused element we 5651 // won't dispatch. 5652 var doc = getEventTargetDocument(nativeEventTarget); 5653 5654 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) { 5655 return null; 5656 } 5657 5658 // Only fire when selection has actually changed. 5659 var currentSelection = getSelection(activeElement$1); 5660 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) { 5661 lastSelection = currentSelection; 5662 5663 var syntheticEvent = SyntheticEvent.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget); 5664 5665 syntheticEvent.type = 'select'; 5666 syntheticEvent.target = activeElement$1; 5667 5668 accumulateTwoPhaseDispatches(syntheticEvent); 5669 5670 return syntheticEvent; 5671 } 5672 5673 return null; 5674 } 5675 5676 /** 5677 * This plugin creates an `onSelect` event that normalizes select events 5678 * across form elements. 5679 * 5680 * Supported elements are: 5681 * - input (see `isTextInputElement`) 5682 * - textarea 5683 * - contentEditable 5684 * 5685 * This differs from native browser implementations in the following ways: 5686 * - Fires on contentEditable fields as well as inputs. 5687 * - Fires for collapsed selection. 5688 * - Fires after user input. 5689 */ 5690 var SelectEventPlugin = { 5691 eventTypes: eventTypes$3, 5692 5693 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { 5694 var doc = getEventTargetDocument(nativeEventTarget); 5695 // Track whether all listeners exists for this plugin. If none exist, we do 5696 // not extract events. See #3639. 5697 if (!doc || !isListeningToAllDependencies('onSelect', doc)) { 5698 return null; 5699 } 5700 5701 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window; 5702 5703 switch (topLevelType) { 5704 // Track the input node that has focus. 5705 case TOP_FOCUS: 5706 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') { 5707 activeElement$1 = targetNode; 5708 activeElementInst$1 = targetInst; 5709 lastSelection = null; 5710 } 5711 break; 5712 case TOP_BLUR: 5713 activeElement$1 = null; 5714 activeElementInst$1 = null; 5715 lastSelection = null; 5716 break; 5717 // Don't fire the event while the user is dragging. This matches the 5718 // semantics of the native select event. 5719 case TOP_MOUSE_DOWN: 5720 mouseDown = true; 5721 break; 5722 case TOP_CONTEXT_MENU: 5723 case TOP_MOUSE_UP: 5724 case TOP_DRAG_END: 5725 mouseDown = false; 5726 return constructSelectEvent(nativeEvent, nativeEventTarget); 5727 // Chrome and IE fire non-standard event when selection is changed (and 5728 // sometimes when it hasn't). IE's event fires out of order with respect 5729 // to key and input events on deletion, so we discard it. 5730 // 5731 // Firefox doesn't support selectionchange, so check selection status 5732 // after each key entry. The selection changes after keydown and before 5733 // keyup, but we check on keydown as well in the case of holding down a 5734 // key, when multiple keydown events are fired but only one keyup is. 5735 // This is also our approach for IE handling, for the reason above. 5736 case TOP_SELECTION_CHANGE: 5737 if (skipSelectionChangeEvent) { 5738 break; 5739 } 5740 // falls through 5741 case TOP_KEY_DOWN: 5742 case TOP_KEY_UP: 5743 return constructSelectEvent(nativeEvent, nativeEventTarget); 5744 } 5745 5746 return null; 5747 } 5748 }; 5749 5750 /** 5751 * Inject modules for resolving DOM hierarchy and plugin ordering. 5752 */ 5753 injection.injectEventPluginOrder(DOMEventPluginOrder); 5754 setComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1); 5755 5756 /** 5757 * Some important event plugins included by default (without having to require 5758 * them). 5759 */ 5760 injection.injectEventPluginsByName({ 5761 SimpleEventPlugin: SimpleEventPlugin, 5762 EnterLeaveEventPlugin: EnterLeaveEventPlugin, 5763 ChangeEventPlugin: ChangeEventPlugin, 5764 SelectEventPlugin: SelectEventPlugin, 5765 BeforeInputEventPlugin: BeforeInputEventPlugin 5766 }); 5767 5768 var didWarnSelectedSetOnOption = false; 5769 var didWarnInvalidChild = false; 5770 5771 function flattenChildren(children) { 5772 var content = ''; 5773 5774 // Flatten children. We'll warn if they are invalid 5775 // during validateProps() which runs for hydration too. 5776 // Note that this would throw on non-element objects. 5777 // Elements are stringified (which is normally irrelevant 5778 // but matters for <fbt>). 5779 React.Children.forEach(children, function (child) { 5780 if (child == null) { 5781 return; 5782 } 5783 content += child; 5784 // Note: we don't warn about invalid children here. 5785 // Instead, this is done separately below so that 5786 // it happens during the hydration codepath too. 5787 }); 5788 5789 return content; 5790 } 5791 5792 /** 5793 * Implements an <option> host component that warns when `selected` is set. 5794 */ 5795 5796 function validateProps(element, props) { 5797 { 5798 // This mirrors the codepath above, but runs for hydration too. 5799 // Warn about invalid children here so that client and hydration are consistent. 5800 // TODO: this seems like it could cause a DEV-only throw for hydration 5801 // if children contains a non-element object. We should try to avoid that. 5802 if (typeof props.children === 'object' && props.children !== null) { 5803 React.Children.forEach(props.children, function (child) { 5804 if (child == null) { 5805 return; 5806 } 5807 if (typeof child === 'string' || typeof child === 'number') { 5808 return; 5809 } 5810 if (typeof child.type !== 'string') { 5811 return; 5812 } 5813 if (!didWarnInvalidChild) { 5814 didWarnInvalidChild = true; 5815 warning$1(false, 'Only strings and numbers are supported as <option> children.'); 5816 } 5817 }); 5818 } 5819 5820 // TODO: Remove support for `selected` in <option>. 5821 if (props.selected != null && !didWarnSelectedSetOnOption) { 5822 warning$1(false, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.'); 5823 didWarnSelectedSetOnOption = true; 5824 } 5825 } 5826 } 5827 5828 function postMountWrapper$1(element, props) { 5829 // value="" should make a value attribute (#6219) 5830 if (props.value != null) { 5831 element.setAttribute('value', toString(getToStringValue(props.value))); 5832 } 5833 } 5834 5835 function getHostProps$1(element, props) { 5836 var hostProps = _assign({ children: undefined }, props); 5837 var content = flattenChildren(props.children); 5838 5839 if (content) { 5840 hostProps.children = content; 5841 } 5842 5843 return hostProps; 5844 } 5845 5846 // TODO: direct imports like some-package/src/* are bad. Fix me. 5847 var didWarnValueDefaultValue$1 = void 0; 5848 5849 { 5850 didWarnValueDefaultValue$1 = false; 5851 } 5852 5853 function getDeclarationErrorAddendum() { 5854 var ownerName = getCurrentFiberOwnerNameInDevOrNull(); 5855 if (ownerName) { 5856 return '\n\nCheck the render method of `' + ownerName + '`.'; 5857 } 5858 return ''; 5859 } 5860 5861 var valuePropNames = ['value', 'defaultValue']; 5862 5863 /** 5864 * Validation function for `value` and `defaultValue`. 5865 */ 5866 function checkSelectPropTypes(props) { 5867 ReactControlledValuePropTypes.checkPropTypes('select', props); 5868 5869 for (var i = 0; i < valuePropNames.length; i++) { 5870 var propName = valuePropNames[i]; 5871 if (props[propName] == null) { 5872 continue; 5873 } 5874 var isArray = Array.isArray(props[propName]); 5875 if (props.multiple && !isArray) { 5876 warning$1(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum()); 5877 } else if (!props.multiple && isArray) { 5878 warning$1(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum()); 5879 } 5880 } 5881 } 5882 5883 function updateOptions(node, multiple, propValue, setDefaultSelected) { 5884 var options = node.options; 5885 5886 if (multiple) { 5887 var selectedValues = propValue; 5888 var selectedValue = {}; 5889 for (var i = 0; i < selectedValues.length; i++) { 5890 // Prefix to avoid chaos with special keys. 5891 selectedValue['$' + selectedValues[i]] = true; 5892 } 5893 for (var _i = 0; _i < options.length; _i++) { 5894 var selected = selectedValue.hasOwnProperty('$' + options[_i].value); 5895 if (options[_i].selected !== selected) { 5896 options[_i].selected = selected; 5897 } 5898 if (selected && setDefaultSelected) { 5899 options[_i].defaultSelected = true; 5900 } 5901 } 5902 } else { 5903 // Do not set `select.value` as exact behavior isn't consistent across all 5904 // browsers for all cases. 5905 var _selectedValue = toString(getToStringValue(propValue)); 5906 var defaultSelected = null; 5907 for (var _i2 = 0; _i2 < options.length; _i2++) { 5908 if (options[_i2].value === _selectedValue) { 5909 options[_i2].selected = true; 5910 if (setDefaultSelected) { 5911 options[_i2].defaultSelected = true; 5912 } 5913 return; 5914 } 5915 if (defaultSelected === null && !options[_i2].disabled) { 5916 defaultSelected = options[_i2]; 5917 } 5918 } 5919 if (defaultSelected !== null) { 5920 defaultSelected.selected = true; 5921 } 5922 } 5923 } 5924 5925 /** 5926 * Implements a <select> host component that allows optionally setting the 5927 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a 5928 * stringable. If `multiple` is true, the prop must be an array of stringables. 5929 * 5930 * If `value` is not supplied (or null/undefined), user actions that change the 5931 * selected option will trigger updates to the rendered options. 5932 * 5933 * If it is supplied (and not null/undefined), the rendered options will not 5934 * update in response to user actions. Instead, the `value` prop must change in 5935 * order for the rendered options to update. 5936 * 5937 * If `defaultValue` is provided, any options with the supplied values will be 5938 * selected. 5939 */ 5940 5941 function getHostProps$2(element, props) { 5942 return _assign({}, props, { 5943 value: undefined 5944 }); 5945 } 5946 5947 function initWrapperState$1(element, props) { 5948 var node = element; 5949 { 5950 checkSelectPropTypes(props); 5951 } 5952 5953 node._wrapperState = { 5954 wasMultiple: !!props.multiple 5955 }; 5956 5957 { 5958 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) { 5959 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'); 5960 didWarnValueDefaultValue$1 = true; 5961 } 5962 } 5963 } 5964 5965 function postMountWrapper$2(element, props) { 5966 var node = element; 5967 node.multiple = !!props.multiple; 5968 var value = props.value; 5969 if (value != null) { 5970 updateOptions(node, !!props.multiple, value, false); 5971 } else if (props.defaultValue != null) { 5972 updateOptions(node, !!props.multiple, props.defaultValue, true); 5973 } 5974 } 5975 5976 function postUpdateWrapper(element, props) { 5977 var node = element; 5978 var wasMultiple = node._wrapperState.wasMultiple; 5979 node._wrapperState.wasMultiple = !!props.multiple; 5980 5981 var value = props.value; 5982 if (value != null) { 5983 updateOptions(node, !!props.multiple, value, false); 5984 } else if (wasMultiple !== !!props.multiple) { 5985 // For simplicity, reapply `defaultValue` if `multiple` is toggled. 5986 if (props.defaultValue != null) { 5987 updateOptions(node, !!props.multiple, props.defaultValue, true); 5988 } else { 5989 // Revert the select back to its default unselected state. 5990 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false); 5991 } 5992 } 5993 } 5994 5995 function restoreControlledState$2(element, props) { 5996 var node = element; 5997 var value = props.value; 5998 5999 if (value != null) { 6000 updateOptions(node, !!props.multiple, value, false); 6001 } 6002 } 6003 6004 var didWarnValDefaultVal = false; 6005 6006 /** 6007 * Implements a <textarea> host component that allows setting `value`, and 6008 * `defaultValue`. This differs from the traditional DOM API because value is 6009 * usually set as PCDATA children. 6010 * 6011 * If `value` is not supplied (or null/undefined), user actions that affect the 6012 * value will trigger updates to the element. 6013 * 6014 * If `value` is supplied (and not null/undefined), the rendered element will 6015 * not trigger updates to the element. Instead, the `value` prop must change in 6016 * order for the rendered element to be updated. 6017 * 6018 * The rendered element will be initialized with an empty value, the prop 6019 * `defaultValue` if specified, or the children content (deprecated). 6020 */ 6021 6022 function getHostProps$3(element, props) { 6023 var node = element; 6024 !(props.dangerouslySetInnerHTML == null) ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : void 0; 6025 6026 // Always set children to the same thing. In IE9, the selection range will 6027 // get reset if `textContent` is mutated. We could add a check in setTextContent 6028 // to only set the value if/when the value differs from the node value (which would 6029 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this 6030 // solution. The value can be a boolean or object so that's why it's forced 6031 // to be a string. 6032 var hostProps = _assign({}, props, { 6033 value: undefined, 6034 defaultValue: undefined, 6035 children: toString(node._wrapperState.initialValue) 6036 }); 6037 6038 return hostProps; 6039 } 6040 6041 function initWrapperState$2(element, props) { 6042 var node = element; 6043 { 6044 ReactControlledValuePropTypes.checkPropTypes('textarea', props); 6045 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) { 6046 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'); 6047 didWarnValDefaultVal = true; 6048 } 6049 } 6050 6051 var initialValue = props.value; 6052 6053 // Only bother fetching default value if we're going to use it 6054 if (initialValue == null) { 6055 var defaultValue = props.defaultValue; 6056 // TODO (yungsters): Remove support for children content in <textarea>. 6057 var children = props.children; 6058 if (children != null) { 6059 { 6060 warning$1(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.'); 6061 } 6062 !(defaultValue == null) ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : void 0; 6063 if (Array.isArray(children)) { 6064 !(children.length <= 1) ? invariant(false, '<textarea> can only have at most one child.') : void 0; 6065 children = children[0]; 6066 } 6067 6068 defaultValue = children; 6069 } 6070 if (defaultValue == null) { 6071 defaultValue = ''; 6072 } 6073 initialValue = defaultValue; 6074 } 6075 6076 node._wrapperState = { 6077 initialValue: getToStringValue(initialValue) 6078 }; 6079 } 6080 6081 function updateWrapper$1(element, props) { 6082 var node = element; 6083 var value = getToStringValue(props.value); 6084 var defaultValue = getToStringValue(props.defaultValue); 6085 if (value != null) { 6086 // Cast `value` to a string to ensure the value is set correctly. While 6087 // browsers typically do this as necessary, jsdom doesn't. 6088 var newValue = toString(value); 6089 // To avoid side effects (such as losing text selection), only set value if changed 6090 if (newValue !== node.value) { 6091 node.value = newValue; 6092 } 6093 if (props.defaultValue == null && node.defaultValue !== newValue) { 6094 node.defaultValue = newValue; 6095 } 6096 } 6097 if (defaultValue != null) { 6098 node.defaultValue = toString(defaultValue); 6099 } 6100 } 6101 6102 function postMountWrapper$3(element, props) { 6103 var node = element; 6104 // This is in postMount because we need access to the DOM node, which is not 6105 // available until after the component has mounted. 6106 var textContent = node.textContent; 6107 6108 // Only set node.value if textContent is equal to the expected 6109 // initial value. In IE10/IE11 there is a bug where the placeholder attribute 6110 // will populate textContent as well. 6111 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/ 6112 if (textContent === node._wrapperState.initialValue) { 6113 node.value = textContent; 6114 } 6115 } 6116 6117 function restoreControlledState$3(element, props) { 6118 // DOM component is still mounted; update 6119 updateWrapper$1(element, props); 6120 } 6121 6122 var HTML_NAMESPACE$1 = 'http://www.w3.org/1999/xhtml'; 6123 var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML'; 6124 var SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; 6125 6126 var Namespaces = { 6127 html: HTML_NAMESPACE$1, 6128 mathml: MATH_NAMESPACE, 6129 svg: SVG_NAMESPACE 6130 }; 6131 6132 // Assumes there is no parent namespace. 6133 function getIntrinsicNamespace(type) { 6134 switch (type) { 6135 case 'svg': 6136 return SVG_NAMESPACE; 6137 case 'math': 6138 return MATH_NAMESPACE; 6139 default: 6140 return HTML_NAMESPACE$1; 6141 } 6142 } 6143 6144 function getChildNamespace(parentNamespace, type) { 6145 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE$1) { 6146 // No (or default) parent namespace: potential entry point. 6147 return getIntrinsicNamespace(type); 6148 } 6149 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') { 6150 // We're leaving SVG. 6151 return HTML_NAMESPACE$1; 6152 } 6153 // By default, pass namespace below. 6154 return parentNamespace; 6155 } 6156 6157 /* globals MSApp */ 6158 6159 /** 6160 * Create a function which has 'unsafe' privileges (required by windows8 apps) 6161 */ 6162 var createMicrosoftUnsafeLocalFunction = function (func) { 6163 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) { 6164 return function (arg0, arg1, arg2, arg3) { 6165 MSApp.execUnsafeLocalFunction(function () { 6166 return func(arg0, arg1, arg2, arg3); 6167 }); 6168 }; 6169 } else { 6170 return func; 6171 } 6172 }; 6173 6174 // SVG temp container for IE lacking innerHTML 6175 var reusableSVGContainer = void 0; 6176 6177 /** 6178 * Set the innerHTML property of a node 6179 * 6180 * @param {DOMElement} node 6181 * @param {string} html 6182 * @internal 6183 */ 6184 var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) { 6185 // IE does not have innerHTML for SVG nodes, so instead we inject the 6186 // new markup in a temp node and then move the child nodes across into 6187 // the target node 6188 6189 if (node.namespaceURI === Namespaces.svg && !('innerHTML' in node)) { 6190 reusableSVGContainer = reusableSVGContainer || document.createElement('div'); 6191 reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>'; 6192 var svgNode = reusableSVGContainer.firstChild; 6193 while (node.firstChild) { 6194 node.removeChild(node.firstChild); 6195 } 6196 while (svgNode.firstChild) { 6197 node.appendChild(svgNode.firstChild); 6198 } 6199 } else { 6200 node.innerHTML = html; 6201 } 6202 }); 6203 6204 /** 6205 * Set the textContent property of a node. For text updates, it's faster 6206 * to set the `nodeValue` of the Text node directly instead of using 6207 * `.textContent` which will remove the existing node and create a new one. 6208 * 6209 * @param {DOMElement} node 6210 * @param {string} text 6211 * @internal 6212 */ 6213 var setTextContent = function (node, text) { 6214 if (text) { 6215 var firstChild = node.firstChild; 6216 6217 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) { 6218 firstChild.nodeValue = text; 6219 return; 6220 } 6221 } 6222 node.textContent = text; 6223 }; 6224 6225 /** 6226 * CSS properties which accept numbers but are not in units of "px". 6227 */ 6228 var isUnitlessNumber = { 6229 animationIterationCount: true, 6230 borderImageOutset: true, 6231 borderImageSlice: true, 6232 borderImageWidth: true, 6233 boxFlex: true, 6234 boxFlexGroup: true, 6235 boxOrdinalGroup: true, 6236 columnCount: true, 6237 columns: true, 6238 flex: true, 6239 flexGrow: true, 6240 flexPositive: true, 6241 flexShrink: true, 6242 flexNegative: true, 6243 flexOrder: true, 6244 gridArea: true, 6245 gridRow: true, 6246 gridRowEnd: true, 6247 gridRowSpan: true, 6248 gridRowStart: true, 6249 gridColumn: true, 6250 gridColumnEnd: true, 6251 gridColumnSpan: true, 6252 gridColumnStart: true, 6253 fontWeight: true, 6254 lineClamp: true, 6255 lineHeight: true, 6256 opacity: true, 6257 order: true, 6258 orphans: true, 6259 tabSize: true, 6260 widows: true, 6261 zIndex: true, 6262 zoom: true, 6263 6264 // SVG-related properties 6265 fillOpacity: true, 6266 floodOpacity: true, 6267 stopOpacity: true, 6268 strokeDasharray: true, 6269 strokeDashoffset: true, 6270 strokeMiterlimit: true, 6271 strokeOpacity: true, 6272 strokeWidth: true 6273 }; 6274 6275 /** 6276 * @param {string} prefix vendor-specific prefix, eg: Webkit 6277 * @param {string} key style name, eg: transitionDuration 6278 * @return {string} style name prefixed with `prefix`, properly camelCased, eg: 6279 * WebkitTransitionDuration 6280 */ 6281 function prefixKey(prefix, key) { 6282 return prefix + key.charAt(0).toUpperCase() + key.substring(1); 6283 } 6284 6285 /** 6286 * Support style names that may come passed in prefixed by adding permutations 6287 * of vendor prefixes. 6288 */ 6289 var prefixes = ['Webkit', 'ms', 'Moz', 'O']; 6290 6291 // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an 6292 // infinite loop, because it iterates over the newly added props too. 6293 Object.keys(isUnitlessNumber).forEach(function (prop) { 6294 prefixes.forEach(function (prefix) { 6295 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; 6296 }); 6297 }); 6298 6299 /** 6300 * Convert a value into the proper css writable value. The style name `name` 6301 * should be logical (no hyphens), as specified 6302 * in `CSSProperty.isUnitlessNumber`. 6303 * 6304 * @param {string} name CSS property name such as `topMargin`. 6305 * @param {*} value CSS property value such as `10px`. 6306 * @return {string} Normalized style value with dimensions applied. 6307 */ 6308 function dangerousStyleValue(name, value, isCustomProperty) { 6309 // Note that we've removed escapeTextForBrowser() calls here since the 6310 // whole string will be escaped when the attribute is injected into 6311 // the markup. If you provide unsafe user data here they can inject 6312 // arbitrary CSS which may be problematic (I couldn't repro this): 6313 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet 6314 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/ 6315 // This is not an XSS hole but instead a potential CSS injection issue 6316 // which has lead to a greater discussion about how we're going to 6317 // trust URLs moving forward. See #2115901 6318 6319 var isEmpty = value == null || typeof value === 'boolean' || value === ''; 6320 if (isEmpty) { 6321 return ''; 6322 } 6323 6324 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) { 6325 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers 6326 } 6327 6328 return ('' + value).trim(); 6329 } 6330 6331 var uppercasePattern = /([A-Z])/g; 6332 var msPattern = /^ms-/; 6333 6334 /** 6335 * Hyphenates a camelcased CSS property name, for example: 6336 * 6337 * > hyphenateStyleName('backgroundColor') 6338 * < "background-color" 6339 * > hyphenateStyleName('MozTransition') 6340 * < "-moz-transition" 6341 * > hyphenateStyleName('msTransition') 6342 * < "-ms-transition" 6343 * 6344 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix 6345 * is converted to `-ms-`. 6346 */ 6347 function hyphenateStyleName(name) { 6348 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-'); 6349 } 6350 6351 var warnValidStyle = function () {}; 6352 6353 { 6354 // 'msTransform' is correct, but the other prefixes should be capitalized 6355 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; 6356 var msPattern$1 = /^-ms-/; 6357 var hyphenPattern = /-(.)/g; 6358 6359 // style values shouldn't contain a semicolon 6360 var badStyleValueWithSemicolonPattern = /;\s*$/; 6361 6362 var warnedStyleNames = {}; 6363 var warnedStyleValues = {}; 6364 var warnedForNaNValue = false; 6365 var warnedForInfinityValue = false; 6366 6367 var camelize = function (string) { 6368 return string.replace(hyphenPattern, function (_, character) { 6369 return character.toUpperCase(); 6370 }); 6371 }; 6372 6373 var warnHyphenatedStyleName = function (name) { 6374 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { 6375 return; 6376 } 6377 6378 warnedStyleNames[name] = true; 6379 warning$1(false, 'Unsupported style property %s. Did you mean %s?', name, 6380 // As Andi Smith suggests 6381 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix 6382 // is converted to lowercase `ms`. 6383 camelize(name.replace(msPattern$1, 'ms-'))); 6384 }; 6385 6386 var warnBadVendoredStyleName = function (name) { 6387 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { 6388 return; 6389 } 6390 6391 warnedStyleNames[name] = true; 6392 warning$1(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1)); 6393 }; 6394 6395 var warnStyleValueWithSemicolon = function (name, value) { 6396 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { 6397 return; 6398 } 6399 6400 warnedStyleValues[value] = true; 6401 warning$1(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, '')); 6402 }; 6403 6404 var warnStyleValueIsNaN = function (name, value) { 6405 if (warnedForNaNValue) { 6406 return; 6407 } 6408 6409 warnedForNaNValue = true; 6410 warning$1(false, '`NaN` is an invalid value for the `%s` css style property.', name); 6411 }; 6412 6413 var warnStyleValueIsInfinity = function (name, value) { 6414 if (warnedForInfinityValue) { 6415 return; 6416 } 6417 6418 warnedForInfinityValue = true; 6419 warning$1(false, '`Infinity` is an invalid value for the `%s` css style property.', name); 6420 }; 6421 6422 warnValidStyle = function (name, value) { 6423 if (name.indexOf('-') > -1) { 6424 warnHyphenatedStyleName(name); 6425 } else if (badVendoredStyleNamePattern.test(name)) { 6426 warnBadVendoredStyleName(name); 6427 } else if (badStyleValueWithSemicolonPattern.test(value)) { 6428 warnStyleValueWithSemicolon(name, value); 6429 } 6430 6431 if (typeof value === 'number') { 6432 if (isNaN(value)) { 6433 warnStyleValueIsNaN(name, value); 6434 } else if (!isFinite(value)) { 6435 warnStyleValueIsInfinity(name, value); 6436 } 6437 } 6438 }; 6439 } 6440 6441 var warnValidStyle$1 = warnValidStyle; 6442 6443 /** 6444 * Operations for dealing with CSS properties. 6445 */ 6446 6447 /** 6448 * This creates a string that is expected to be equivalent to the style 6449 * attribute generated by server-side rendering. It by-passes warnings and 6450 * security checks so it's not safe to use this value for anything other than 6451 * comparison. It is only used in DEV for SSR validation. 6452 */ 6453 function createDangerousStringForStyles(styles) { 6454 { 6455 var serialized = ''; 6456 var delimiter = ''; 6457 for (var styleName in styles) { 6458 if (!styles.hasOwnProperty(styleName)) { 6459 continue; 6460 } 6461 var styleValue = styles[styleName]; 6462 if (styleValue != null) { 6463 var isCustomProperty = styleName.indexOf('--') === 0; 6464 serialized += delimiter + hyphenateStyleName(styleName) + ':'; 6465 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty); 6466 6467 delimiter = ';'; 6468 } 6469 } 6470 return serialized || null; 6471 } 6472 } 6473 6474 /** 6475 * Sets the value for multiple styles on a node. If a value is specified as 6476 * '' (empty string), the corresponding style property will be unset. 6477 * 6478 * @param {DOMElement} node 6479 * @param {object} styles 6480 */ 6481 function setValueForStyles(node, styles) { 6482 var style = node.style; 6483 for (var styleName in styles) { 6484 if (!styles.hasOwnProperty(styleName)) { 6485 continue; 6486 } 6487 var isCustomProperty = styleName.indexOf('--') === 0; 6488 { 6489 if (!isCustomProperty) { 6490 warnValidStyle$1(styleName, styles[styleName]); 6491 } 6492 } 6493 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty); 6494 if (styleName === 'float') { 6495 styleName = 'cssFloat'; 6496 } 6497 if (isCustomProperty) { 6498 style.setProperty(styleName, styleValue); 6499 } else { 6500 style[styleName] = styleValue; 6501 } 6502 } 6503 } 6504 6505 // For HTML, certain tags should omit their close tag. We keep a whitelist for 6506 // those special-case tags. 6507 6508 var omittedCloseTags = { 6509 area: true, 6510 base: true, 6511 br: true, 6512 col: true, 6513 embed: true, 6514 hr: true, 6515 img: true, 6516 input: true, 6517 keygen: true, 6518 link: true, 6519 meta: true, 6520 param: true, 6521 source: true, 6522 track: true, 6523 wbr: true 6524 // NOTE: menuitem's close tag should be omitted, but that causes problems. 6525 }; 6526 6527 // For HTML, certain tags cannot have children. This has the same purpose as 6528 // `omittedCloseTags` except that `menuitem` should still have its closing tag. 6529 6530 var voidElementTags = _assign({ 6531 menuitem: true 6532 }, omittedCloseTags); 6533 6534 // TODO: We can remove this if we add invariantWithStack() 6535 // or add stack by default to invariants where possible. 6536 var HTML$1 = '__html'; 6537 6538 var ReactDebugCurrentFrame$2 = null; 6539 { 6540 ReactDebugCurrentFrame$2 = ReactSharedInternals.ReactDebugCurrentFrame; 6541 } 6542 6543 function assertValidProps(tag, props) { 6544 if (!props) { 6545 return; 6546 } 6547 // Note the use of `==` which checks for null or undefined. 6548 if (voidElementTags[tag]) { 6549 !(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; 6550 } 6551 if (props.dangerouslySetInnerHTML != null) { 6552 !(props.children == null) ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : void 0; 6553 !(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; 6554 } 6555 { 6556 !(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; 6557 } 6558 !(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; 6559 } 6560 6561 function isCustomComponent(tagName, props) { 6562 if (tagName.indexOf('-') === -1) { 6563 return typeof props.is === 'string'; 6564 } 6565 switch (tagName) { 6566 // These are reserved SVG and MathML elements. 6567 // We don't mind this whitelist too much because we expect it to never grow. 6568 // The alternative is to track the namespace in a few places which is convoluted. 6569 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts 6570 case 'annotation-xml': 6571 case 'color-profile': 6572 case 'font-face': 6573 case 'font-face-src': 6574 case 'font-face-uri': 6575 case 'font-face-format': 6576 case 'font-face-name': 6577 case 'missing-glyph': 6578 return false; 6579 default: 6580 return true; 6581 } 6582 } 6583 6584 // When adding attributes to the HTML or SVG whitelist, be sure to 6585 // also add them to this module to ensure casing and incorrect name 6586 // warnings. 6587 var possibleStandardNames = { 6588 // HTML 6589 accept: 'accept', 6590 acceptcharset: 'acceptCharset', 6591 'accept-charset': 'acceptCharset', 6592 accesskey: 'accessKey', 6593 action: 'action', 6594 allowfullscreen: 'allowFullScreen', 6595 alt: 'alt', 6596 as: 'as', 6597 async: 'async', 6598 autocapitalize: 'autoCapitalize', 6599 autocomplete: 'autoComplete', 6600 autocorrect: 'autoCorrect', 6601 autofocus: 'autoFocus', 6602 autoplay: 'autoPlay', 6603 autosave: 'autoSave', 6604 capture: 'capture', 6605 cellpadding: 'cellPadding', 6606 cellspacing: 'cellSpacing', 6607 challenge: 'challenge', 6608 charset: 'charSet', 6609 checked: 'checked', 6610 children: 'children', 6611 cite: 'cite', 6612 class: 'className', 6613 classid: 'classID', 6614 classname: 'className', 6615 cols: 'cols', 6616 colspan: 'colSpan', 6617 content: 'content', 6618 contenteditable: 'contentEditable', 6619 contextmenu: 'contextMenu', 6620 controls: 'controls', 6621 controlslist: 'controlsList', 6622 coords: 'coords', 6623 crossorigin: 'crossOrigin', 6624 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML', 6625 data: 'data', 6626 datetime: 'dateTime', 6627 default: 'default', 6628 defaultchecked: 'defaultChecked', 6629 defaultvalue: 'defaultValue', 6630 defer: 'defer', 6631 dir: 'dir', 6632 disabled: 'disabled', 6633 download: 'download', 6634 draggable: 'draggable', 6635 enctype: 'encType', 6636 for: 'htmlFor', 6637 form: 'form', 6638 formmethod: 'formMethod', 6639 formaction: 'formAction', 6640 formenctype: 'formEncType', 6641 formnovalidate: 'formNoValidate', 6642 formtarget: 'formTarget', 6643 frameborder: 'frameBorder', 6644 headers: 'headers', 6645 height: 'height', 6646 hidden: 'hidden', 6647 high: 'high', 6648 href: 'href', 6649 hreflang: 'hrefLang', 6650 htmlfor: 'htmlFor', 6651 httpequiv: 'httpEquiv', 6652 'http-equiv': 'httpEquiv', 6653 icon: 'icon', 6654 id: 'id', 6655 innerhtml: 'innerHTML', 6656 inputmode: 'inputMode', 6657 integrity: 'integrity', 6658 is: 'is', 6659 itemid: 'itemID', 6660 itemprop: 'itemProp', 6661 itemref: 'itemRef', 6662 itemscope: 'itemScope', 6663 itemtype: 'itemType', 6664 keyparams: 'keyParams', 6665 keytype: 'keyType', 6666 kind: 'kind', 6667 label: 'label', 6668 lang: 'lang', 6669 list: 'list', 6670 loop: 'loop', 6671 low: 'low', 6672 manifest: 'manifest', 6673 marginwidth: 'marginWidth', 6674 marginheight: 'marginHeight', 6675 max: 'max', 6676 maxlength: 'maxLength', 6677 media: 'media', 6678 mediagroup: 'mediaGroup', 6679 method: 'method', 6680 min: 'min', 6681 minlength: 'minLength', 6682 multiple: 'multiple', 6683 muted: 'muted', 6684 name: 'name', 6685 nomodule: 'noModule', 6686 nonce: 'nonce', 6687 novalidate: 'noValidate', 6688 open: 'open', 6689 optimum: 'optimum', 6690 pattern: 'pattern', 6691 placeholder: 'placeholder', 6692 playsinline: 'playsInline', 6693 poster: 'poster', 6694 preload: 'preload', 6695 profile: 'profile', 6696 radiogroup: 'radioGroup', 6697 readonly: 'readOnly', 6698 referrerpolicy: 'referrerPolicy', 6699 rel: 'rel', 6700 required: 'required', 6701 reversed: 'reversed', 6702 role: 'role', 6703 rows: 'rows', 6704 rowspan: 'rowSpan', 6705 sandbox: 'sandbox', 6706 scope: 'scope', 6707 scoped: 'scoped', 6708 scrolling: 'scrolling', 6709 seamless: 'seamless', 6710 selected: 'selected', 6711 shape: 'shape', 6712 size: 'size', 6713 sizes: 'sizes', 6714 span: 'span', 6715 spellcheck: 'spellCheck', 6716 src: 'src', 6717 srcdoc: 'srcDoc', 6718 srclang: 'srcLang', 6719 srcset: 'srcSet', 6720 start: 'start', 6721 step: 'step', 6722 style: 'style', 6723 summary: 'summary', 6724 tabindex: 'tabIndex', 6725 target: 'target', 6726 title: 'title', 6727 type: 'type', 6728 usemap: 'useMap', 6729 value: 'value', 6730 width: 'width', 6731 wmode: 'wmode', 6732 wrap: 'wrap', 6733 6734 // SVG 6735 about: 'about', 6736 accentheight: 'accentHeight', 6737 'accent-height': 'accentHeight', 6738 accumulate: 'accumulate', 6739 additive: 'additive', 6740 alignmentbaseline: 'alignmentBaseline', 6741 'alignment-baseline': 'alignmentBaseline', 6742 allowreorder: 'allowReorder', 6743 alphabetic: 'alphabetic', 6744 amplitude: 'amplitude', 6745 arabicform: 'arabicForm', 6746 'arabic-form': 'arabicForm', 6747 ascent: 'ascent', 6748 attributename: 'attributeName', 6749 attributetype: 'attributeType', 6750 autoreverse: 'autoReverse', 6751 azimuth: 'azimuth', 6752 basefrequency: 'baseFrequency', 6753 baselineshift: 'baselineShift', 6754 'baseline-shift': 'baselineShift', 6755 baseprofile: 'baseProfile', 6756 bbox: 'bbox', 6757 begin: 'begin', 6758 bias: 'bias', 6759 by: 'by', 6760 calcmode: 'calcMode', 6761 capheight: 'capHeight', 6762 'cap-height': 'capHeight', 6763 clip: 'clip', 6764 clippath: 'clipPath', 6765 'clip-path': 'clipPath', 6766 clippathunits: 'clipPathUnits', 6767 cliprule: 'clipRule', 6768 'clip-rule': 'clipRule', 6769 color: 'color', 6770 colorinterpolation: 'colorInterpolation', 6771 'color-interpolation': 'colorInterpolation', 6772 colorinterpolationfilters: 'colorInterpolationFilters', 6773 'color-interpolation-filters': 'colorInterpolationFilters', 6774 colorprofile: 'colorProfile', 6775 'color-profile': 'colorProfile', 6776 colorrendering: 'colorRendering', 6777 'color-rendering': 'colorRendering', 6778 contentscripttype: 'contentScriptType', 6779 contentstyletype: 'contentStyleType', 6780 cursor: 'cursor', 6781 cx: 'cx', 6782 cy: 'cy', 6783 d: 'd', 6784 datatype: 'datatype', 6785 decelerate: 'decelerate', 6786 descent: 'descent', 6787 diffuseconstant: 'diffuseConstant', 6788 direction: 'direction', 6789 display: 'display', 6790 divisor: 'divisor', 6791 dominantbaseline: 'dominantBaseline', 6792 'dominant-baseline': 'dominantBaseline', 6793 dur: 'dur', 6794 dx: 'dx', 6795 dy: 'dy', 6796 edgemode: 'edgeMode', 6797 elevation: 'elevation', 6798 enablebackground: 'enableBackground', 6799 'enable-background': 'enableBackground', 6800 end: 'end', 6801 exponent: 'exponent', 6802 externalresourcesrequired: 'externalResourcesRequired', 6803 fill: 'fill', 6804 fillopacity: 'fillOpacity', 6805 'fill-opacity': 'fillOpacity', 6806 fillrule: 'fillRule', 6807 'fill-rule': 'fillRule', 6808 filter: 'filter', 6809 filterres: 'filterRes', 6810 filterunits: 'filterUnits', 6811 floodopacity: 'floodOpacity', 6812 'flood-opacity': 'floodOpacity', 6813 floodcolor: 'floodColor', 6814 'flood-color': 'floodColor', 6815 focusable: 'focusable', 6816 fontfamily: 'fontFamily', 6817 'font-family': 'fontFamily', 6818 fontsize: 'fontSize', 6819 'font-size': 'fontSize', 6820 fontsizeadjust: 'fontSizeAdjust', 6821 'font-size-adjust': 'fontSizeAdjust', 6822 fontstretch: 'fontStretch', 6823 'font-stretch': 'fontStretch', 6824 fontstyle: 'fontStyle', 6825 'font-style': 'fontStyle', 6826 fontvariant: 'fontVariant', 6827 'font-variant': 'fontVariant', 6828 fontweight: 'fontWeight', 6829 'font-weight': 'fontWeight', 6830 format: 'format', 6831 from: 'from', 6832 fx: 'fx', 6833 fy: 'fy', 6834 g1: 'g1', 6835 g2: 'g2', 6836 glyphname: 'glyphName', 6837 'glyph-name': 'glyphName', 6838 glyphorientationhorizontal: 'glyphOrientationHorizontal', 6839 'glyph-orientation-horizontal': 'glyphOrientationHorizontal', 6840 glyphorientationvertical: 'glyphOrientationVertical', 6841 'glyph-orientation-vertical': 'glyphOrientationVertical', 6842 glyphref: 'glyphRef', 6843 gradienttransform: 'gradientTransform', 6844 gradientunits: 'gradientUnits', 6845 hanging: 'hanging', 6846 horizadvx: 'horizAdvX', 6847 'horiz-adv-x': 'horizAdvX', 6848 horizoriginx: 'horizOriginX', 6849 'horiz-origin-x': 'horizOriginX', 6850 ideographic: 'ideographic', 6851 imagerendering: 'imageRendering', 6852 'image-rendering': 'imageRendering', 6853 in2: 'in2', 6854 in: 'in', 6855 inlist: 'inlist', 6856 intercept: 'intercept', 6857 k1: 'k1', 6858 k2: 'k2', 6859 k3: 'k3', 6860 k4: 'k4', 6861 k: 'k', 6862 kernelmatrix: 'kernelMatrix', 6863 kernelunitlength: 'kernelUnitLength', 6864 kerning: 'kerning', 6865 keypoints: 'keyPoints', 6866 keysplines: 'keySplines', 6867 keytimes: 'keyTimes', 6868 lengthadjust: 'lengthAdjust', 6869 letterspacing: 'letterSpacing', 6870 'letter-spacing': 'letterSpacing', 6871 lightingcolor: 'lightingColor', 6872 'lighting-color': 'lightingColor', 6873 limitingconeangle: 'limitingConeAngle', 6874 local: 'local', 6875 markerend: 'markerEnd', 6876 'marker-end': 'markerEnd', 6877 markerheight: 'markerHeight', 6878 markermid: 'markerMid', 6879 'marker-mid': 'markerMid', 6880 markerstart: 'markerStart', 6881 'marker-start': 'markerStart', 6882 markerunits: 'markerUnits', 6883 markerwidth: 'markerWidth', 6884 mask: 'mask', 6885 maskcontentunits: 'maskContentUnits', 6886 maskunits: 'maskUnits', 6887 mathematical: 'mathematical', 6888 mode: 'mode', 6889 numoctaves: 'numOctaves', 6890 offset: 'offset', 6891 opacity: 'opacity', 6892 operator: 'operator', 6893 order: 'order', 6894 orient: 'orient', 6895 orientation: 'orientation', 6896 origin: 'origin', 6897 overflow: 'overflow', 6898 overlineposition: 'overlinePosition', 6899 'overline-position': 'overlinePosition', 6900 overlinethickness: 'overlineThickness', 6901 'overline-thickness': 'overlineThickness', 6902 paintorder: 'paintOrder', 6903 'paint-order': 'paintOrder', 6904 panose1: 'panose1', 6905 'panose-1': 'panose1', 6906 pathlength: 'pathLength', 6907 patterncontentunits: 'patternContentUnits', 6908 patterntransform: 'patternTransform', 6909 patternunits: 'patternUnits', 6910 pointerevents: 'pointerEvents', 6911 'pointer-events': 'pointerEvents', 6912 points: 'points', 6913 pointsatx: 'pointsAtX', 6914 pointsaty: 'pointsAtY', 6915 pointsatz: 'pointsAtZ', 6916 prefix: 'prefix', 6917 preservealpha: 'preserveAlpha', 6918 preserveaspectratio: 'preserveAspectRatio', 6919 primitiveunits: 'primitiveUnits', 6920 property: 'property', 6921 r: 'r', 6922 radius: 'radius', 6923 refx: 'refX', 6924 refy: 'refY', 6925 renderingintent: 'renderingIntent', 6926 'rendering-intent': 'renderingIntent', 6927 repeatcount: 'repeatCount', 6928 repeatdur: 'repeatDur', 6929 requiredextensions: 'requiredExtensions', 6930 requiredfeatures: 'requiredFeatures', 6931 resource: 'resource', 6932 restart: 'restart', 6933 result: 'result', 6934 results: 'results', 6935 rotate: 'rotate', 6936 rx: 'rx', 6937 ry: 'ry', 6938 scale: 'scale', 6939 security: 'security', 6940 seed: 'seed', 6941 shaperendering: 'shapeRendering', 6942 'shape-rendering': 'shapeRendering', 6943 slope: 'slope', 6944 spacing: 'spacing', 6945 specularconstant: 'specularConstant', 6946 specularexponent: 'specularExponent', 6947 speed: 'speed', 6948 spreadmethod: 'spreadMethod', 6949 startoffset: 'startOffset', 6950 stddeviation: 'stdDeviation', 6951 stemh: 'stemh', 6952 stemv: 'stemv', 6953 stitchtiles: 'stitchTiles', 6954 stopcolor: 'stopColor', 6955 'stop-color': 'stopColor', 6956 stopopacity: 'stopOpacity', 6957 'stop-opacity': 'stopOpacity', 6958 strikethroughposition: 'strikethroughPosition', 6959 'strikethrough-position': 'strikethroughPosition', 6960 strikethroughthickness: 'strikethroughThickness', 6961 'strikethrough-thickness': 'strikethroughThickness', 6962 string: 'string', 6963 stroke: 'stroke', 6964 strokedasharray: 'strokeDasharray', 6965 'stroke-dasharray': 'strokeDasharray', 6966 strokedashoffset: 'strokeDashoffset', 6967 'stroke-dashoffset': 'strokeDashoffset', 6968 strokelinecap: 'strokeLinecap', 6969 'stroke-linecap': 'strokeLinecap', 6970 strokelinejoin: 'strokeLinejoin', 6971 'stroke-linejoin': 'strokeLinejoin', 6972 strokemiterlimit: 'strokeMiterlimit', 6973 'stroke-miterlimit': 'strokeMiterlimit', 6974 strokewidth: 'strokeWidth', 6975 'stroke-width': 'strokeWidth', 6976 strokeopacity: 'strokeOpacity', 6977 'stroke-opacity': 'strokeOpacity', 6978 suppresscontenteditablewarning: 'suppressContentEditableWarning', 6979 suppresshydrationwarning: 'suppressHydrationWarning', 6980 surfacescale: 'surfaceScale', 6981 systemlanguage: 'systemLanguage', 6982 tablevalues: 'tableValues', 6983 targetx: 'targetX', 6984 targety: 'targetY', 6985 textanchor: 'textAnchor', 6986 'text-anchor': 'textAnchor', 6987 textdecoration: 'textDecoration', 6988 'text-decoration': 'textDecoration', 6989 textlength: 'textLength', 6990 textrendering: 'textRendering', 6991 'text-rendering': 'textRendering', 6992 to: 'to', 6993 transform: 'transform', 6994 typeof: 'typeof', 6995 u1: 'u1', 6996 u2: 'u2', 6997 underlineposition: 'underlinePosition', 6998 'underline-position': 'underlinePosition', 6999 underlinethickness: 'underlineThickness', 7000 'underline-thickness': 'underlineThickness', 7001 unicode: 'unicode', 7002 unicodebidi: 'unicodeBidi', 7003 'unicode-bidi': 'unicodeBidi', 7004 unicoderange: 'unicodeRange', 7005 'unicode-range': 'unicodeRange', 7006 unitsperem: 'unitsPerEm', 7007 'units-per-em': 'unitsPerEm', 7008 unselectable: 'unselectable', 7009 valphabetic: 'vAlphabetic', 7010 'v-alphabetic': 'vAlphabetic', 7011 values: 'values', 7012 vectoreffect: 'vectorEffect', 7013 'vector-effect': 'vectorEffect', 7014 version: 'version', 7015 vertadvy: 'vertAdvY', 7016 'vert-adv-y': 'vertAdvY', 7017 vertoriginx: 'vertOriginX', 7018 'vert-origin-x': 'vertOriginX', 7019 vertoriginy: 'vertOriginY', 7020 'vert-origin-y': 'vertOriginY', 7021 vhanging: 'vHanging', 7022 'v-hanging': 'vHanging', 7023 videographic: 'vIdeographic', 7024 'v-ideographic': 'vIdeographic', 7025 viewbox: 'viewBox', 7026 viewtarget: 'viewTarget', 7027 visibility: 'visibility', 7028 vmathematical: 'vMathematical', 7029 'v-mathematical': 'vMathematical', 7030 vocab: 'vocab', 7031 widths: 'widths', 7032 wordspacing: 'wordSpacing', 7033 'word-spacing': 'wordSpacing', 7034 writingmode: 'writingMode', 7035 'writing-mode': 'writingMode', 7036 x1: 'x1', 7037 x2: 'x2', 7038 x: 'x', 7039 xchannelselector: 'xChannelSelector', 7040 xheight: 'xHeight', 7041 'x-height': 'xHeight', 7042 xlinkactuate: 'xlinkActuate', 7043 'xlink:actuate': 'xlinkActuate', 7044 xlinkarcrole: 'xlinkArcrole', 7045 'xlink:arcrole': 'xlinkArcrole', 7046 xlinkhref: 'xlinkHref', 7047 'xlink:href': 'xlinkHref', 7048 xlinkrole: 'xlinkRole', 7049 'xlink:role': 'xlinkRole', 7050 xlinkshow: 'xlinkShow', 7051 'xlink:show': 'xlinkShow', 7052 xlinktitle: 'xlinkTitle', 7053 'xlink:title': 'xlinkTitle', 7054 xlinktype: 'xlinkType', 7055 'xlink:type': 'xlinkType', 7056 xmlbase: 'xmlBase', 7057 'xml:base': 'xmlBase', 7058 xmllang: 'xmlLang', 7059 'xml:lang': 'xmlLang', 7060 xmlns: 'xmlns', 7061 'xml:space': 'xmlSpace', 7062 xmlnsxlink: 'xmlnsXlink', 7063 'xmlns:xlink': 'xmlnsXlink', 7064 xmlspace: 'xmlSpace', 7065 y1: 'y1', 7066 y2: 'y2', 7067 y: 'y', 7068 ychannelselector: 'yChannelSelector', 7069 z: 'z', 7070 zoomandpan: 'zoomAndPan' 7071 }; 7072 7073 var ariaProperties = { 7074 'aria-current': 0, // state 7075 'aria-details': 0, 7076 'aria-disabled': 0, // state 7077 'aria-hidden': 0, // state 7078 'aria-invalid': 0, // state 7079 'aria-keyshortcuts': 0, 7080 'aria-label': 0, 7081 'aria-roledescription': 0, 7082 // Widget Attributes 7083 'aria-autocomplete': 0, 7084 'aria-checked': 0, 7085 'aria-expanded': 0, 7086 'aria-haspopup': 0, 7087 'aria-level': 0, 7088 'aria-modal': 0, 7089 'aria-multiline': 0, 7090 'aria-multiselectable': 0, 7091 'aria-orientation': 0, 7092 'aria-placeholder': 0, 7093 'aria-pressed': 0, 7094 'aria-readonly': 0, 7095 'aria-required': 0, 7096 'aria-selected': 0, 7097 'aria-sort': 0, 7098 'aria-valuemax': 0, 7099 'aria-valuemin': 0, 7100 'aria-valuenow': 0, 7101 'aria-valuetext': 0, 7102 // Live Region Attributes 7103 'aria-atomic': 0, 7104 'aria-busy': 0, 7105 'aria-live': 0, 7106 'aria-relevant': 0, 7107 // Drag-and-Drop Attributes 7108 'aria-dropeffect': 0, 7109 'aria-grabbed': 0, 7110 // Relationship Attributes 7111 'aria-activedescendant': 0, 7112 'aria-colcount': 0, 7113 'aria-colindex': 0, 7114 'aria-colspan': 0, 7115 'aria-controls': 0, 7116 'aria-describedby': 0, 7117 'aria-errormessage': 0, 7118 'aria-flowto': 0, 7119 'aria-labelledby': 0, 7120 'aria-owns': 0, 7121 'aria-posinset': 0, 7122 'aria-rowcount': 0, 7123 'aria-rowindex': 0, 7124 'aria-rowspan': 0, 7125 'aria-setsize': 0 7126 }; 7127 7128 var warnedProperties = {}; 7129 var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$'); 7130 var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$'); 7131 7132 var hasOwnProperty$2 = Object.prototype.hasOwnProperty; 7133 7134 function validateProperty(tagName, name) { 7135 if (hasOwnProperty$2.call(warnedProperties, name) && warnedProperties[name]) { 7136 return true; 7137 } 7138 7139 if (rARIACamel.test(name)) { 7140 var ariaName = 'aria-' + name.slice(4).toLowerCase(); 7141 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; 7142 7143 // If this is an aria-* attribute, but is not listed in the known DOM 7144 // DOM properties, then it is an invalid aria-* attribute. 7145 if (correctName == null) { 7146 warning$1(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name); 7147 warnedProperties[name] = true; 7148 return true; 7149 } 7150 // aria-* attributes should be lowercase; suggest the lowercase version. 7151 if (name !== correctName) { 7152 warning$1(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName); 7153 warnedProperties[name] = true; 7154 return true; 7155 } 7156 } 7157 7158 if (rARIA.test(name)) { 7159 var lowerCasedName = name.toLowerCase(); 7160 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; 7161 7162 // If this is an aria-* attribute, but is not listed in the known DOM 7163 // DOM properties, then it is an invalid aria-* attribute. 7164 if (standardName == null) { 7165 warnedProperties[name] = true; 7166 return false; 7167 } 7168 // aria-* attributes should be lowercase; suggest the lowercase version. 7169 if (name !== standardName) { 7170 warning$1(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName); 7171 warnedProperties[name] = true; 7172 return true; 7173 } 7174 } 7175 7176 return true; 7177 } 7178 7179 function warnInvalidARIAProps(type, props) { 7180 var invalidProps = []; 7181 7182 for (var key in props) { 7183 var isValid = validateProperty(type, key); 7184 if (!isValid) { 7185 invalidProps.push(key); 7186 } 7187 } 7188 7189 var unknownPropString = invalidProps.map(function (prop) { 7190 return '`' + prop + '`'; 7191 }).join(', '); 7192 7193 if (invalidProps.length === 1) { 7194 warning$1(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type); 7195 } else if (invalidProps.length > 1) { 7196 warning$1(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type); 7197 } 7198 } 7199 7200 function validateProperties(type, props) { 7201 if (isCustomComponent(type, props)) { 7202 return; 7203 } 7204 warnInvalidARIAProps(type, props); 7205 } 7206 7207 var didWarnValueNull = false; 7208 7209 function validateProperties$1(type, props) { 7210 if (type !== 'input' && type !== 'textarea' && type !== 'select') { 7211 return; 7212 } 7213 7214 if (props != null && props.value === null && !didWarnValueNull) { 7215 didWarnValueNull = true; 7216 if (type === 'select' && props.multiple) { 7217 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); 7218 } else { 7219 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); 7220 } 7221 } 7222 } 7223 7224 var validateProperty$1 = function () {}; 7225 7226 { 7227 var warnedProperties$1 = {}; 7228 var _hasOwnProperty = Object.prototype.hasOwnProperty; 7229 var EVENT_NAME_REGEX = /^on./; 7230 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/; 7231 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$'); 7232 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$'); 7233 7234 validateProperty$1 = function (tagName, name, value, canUseEventSystem) { 7235 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) { 7236 return true; 7237 } 7238 7239 var lowerCasedName = name.toLowerCase(); 7240 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') { 7241 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.'); 7242 warnedProperties$1[name] = true; 7243 return true; 7244 } 7245 7246 // We can't rely on the event system being injected on the server. 7247 if (canUseEventSystem) { 7248 if (registrationNameModules.hasOwnProperty(name)) { 7249 return true; 7250 } 7251 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null; 7252 if (registrationName != null) { 7253 warning$1(false, 'Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName); 7254 warnedProperties$1[name] = true; 7255 return true; 7256 } 7257 if (EVENT_NAME_REGEX.test(name)) { 7258 warning$1(false, 'Unknown event handler property `%s`. It will be ignored.', name); 7259 warnedProperties$1[name] = true; 7260 return true; 7261 } 7262 } else if (EVENT_NAME_REGEX.test(name)) { 7263 // If no event plugins have been injected, we are in a server environment. 7264 // So we can't tell if the event name is correct for sure, but we can filter 7265 // out known bad ones like `onclick`. We can't suggest a specific replacement though. 7266 if (INVALID_EVENT_NAME_REGEX.test(name)) { 7267 warning$1(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name); 7268 } 7269 warnedProperties$1[name] = true; 7270 return true; 7271 } 7272 7273 // Let the ARIA attribute hook validate ARIA attributes 7274 if (rARIA$1.test(name) || rARIACamel$1.test(name)) { 7275 return true; 7276 } 7277 7278 if (lowerCasedName === 'innerhtml') { 7279 warning$1(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.'); 7280 warnedProperties$1[name] = true; 7281 return true; 7282 } 7283 7284 if (lowerCasedName === 'aria') { 7285 warning$1(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.'); 7286 warnedProperties$1[name] = true; 7287 return true; 7288 } 7289 7290 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') { 7291 warning$1(false, 'Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value); 7292 warnedProperties$1[name] = true; 7293 return true; 7294 } 7295 7296 if (typeof value === 'number' && isNaN(value)) { 7297 warning$1(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name); 7298 warnedProperties$1[name] = true; 7299 return true; 7300 } 7301 7302 var propertyInfo = getPropertyInfo(name); 7303 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED; 7304 7305 // Known attributes should match the casing specified in the property config. 7306 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) { 7307 var standardName = possibleStandardNames[lowerCasedName]; 7308 if (standardName !== name) { 7309 warning$1(false, 'Invalid DOM property `%s`. Did you mean `%s`?', name, standardName); 7310 warnedProperties$1[name] = true; 7311 return true; 7312 } 7313 } else if (!isReserved && name !== lowerCasedName) { 7314 // Unknown attributes should have lowercase casing since that's how they 7315 // will be cased anyway with server rendering. 7316 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); 7317 warnedProperties$1[name] = true; 7318 return true; 7319 } 7320 7321 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) { 7322 if (value) { 7323 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); 7324 } else { 7325 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); 7326 } 7327 warnedProperties$1[name] = true; 7328 return true; 7329 } 7330 7331 // Now that we've validated casing, do not validate 7332 // data types for reserved props 7333 if (isReserved) { 7334 return true; 7335 } 7336 7337 // Warn when a known attribute is a bad type 7338 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) { 7339 warnedProperties$1[name] = true; 7340 return false; 7341 } 7342 7343 // Warn when passing the strings 'false' or 'true' into a boolean prop 7344 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) { 7345 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); 7346 warnedProperties$1[name] = true; 7347 return true; 7348 } 7349 7350 return true; 7351 }; 7352 } 7353 7354 var warnUnknownProperties = function (type, props, canUseEventSystem) { 7355 var unknownProps = []; 7356 for (var key in props) { 7357 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem); 7358 if (!isValid) { 7359 unknownProps.push(key); 7360 } 7361 } 7362 7363 var unknownPropString = unknownProps.map(function (prop) { 7364 return '`' + prop + '`'; 7365 }).join(', '); 7366 if (unknownProps.length === 1) { 7367 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); 7368 } else if (unknownProps.length > 1) { 7369 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); 7370 } 7371 }; 7372 7373 function validateProperties$2(type, props, canUseEventSystem) { 7374 if (isCustomComponent(type, props)) { 7375 return; 7376 } 7377 warnUnknownProperties(type, props, canUseEventSystem); 7378 } 7379 7380 // TODO: direct imports like some-package/src/* are bad. Fix me. 7381 var didWarnInvalidHydration = false; 7382 var didWarnShadyDOM = false; 7383 7384 var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML'; 7385 var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning'; 7386 var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning'; 7387 var AUTOFOCUS = 'autoFocus'; 7388 var CHILDREN = 'children'; 7389 var STYLE = 'style'; 7390 var HTML = '__html'; 7391 7392 var HTML_NAMESPACE = Namespaces.html; 7393 7394 7395 var warnedUnknownTags = void 0; 7396 var suppressHydrationWarning = void 0; 7397 7398 var validatePropertiesInDevelopment = void 0; 7399 var warnForTextDifference = void 0; 7400 var warnForPropDifference = void 0; 7401 var warnForExtraAttributes = void 0; 7402 var warnForInvalidEventListener = void 0; 7403 var canDiffStyleForHydrationWarning = void 0; 7404 7405 var normalizeMarkupForTextOrAttribute = void 0; 7406 var normalizeHTML = void 0; 7407 7408 { 7409 warnedUnknownTags = { 7410 // Chrome is the only major browser not shipping <time>. But as of July 7411 // 2017 it intends to ship it due to widespread usage. We intentionally 7412 // *don't* warn for <time> even if it's unrecognized by Chrome because 7413 // it soon will be, and many apps have been using it anyway. 7414 time: true, 7415 // There are working polyfills for <dialog>. Let people use it. 7416 dialog: true, 7417 // Electron ships a custom <webview> tag to display external web content in 7418 // an isolated frame and process. 7419 // This tag is not present in non Electron environments such as JSDom which 7420 // is often used for testing purposes. 7421 // @see https://electronjs.org/docs/api/webview-tag 7422 webview: true 7423 }; 7424 7425 validatePropertiesInDevelopment = function (type, props) { 7426 validateProperties(type, props); 7427 validateProperties$1(type, props); 7428 validateProperties$2(type, props, /* canUseEventSystem */true); 7429 }; 7430 7431 // IE 11 parses & normalizes the style attribute as opposed to other 7432 // browsers. It adds spaces and sorts the properties in some 7433 // non-alphabetical order. Handling that would require sorting CSS 7434 // properties in the client & server versions or applying 7435 // `expectedStyle` to a temporary DOM node to read its `style` attribute 7436 // normalized. Since it only affects IE, we're skipping style warnings 7437 // in that browser completely in favor of doing all that work. 7438 // See https://github.com/facebook/react/issues/11807 7439 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode; 7440 7441 // HTML parsing normalizes CR and CRLF to LF. 7442 // It also can turn \u0000 into \uFFFD inside attributes. 7443 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream 7444 // If we have a mismatch, it might be caused by that. 7445 // We will still patch up in this case but not fire the warning. 7446 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g; 7447 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g; 7448 7449 normalizeMarkupForTextOrAttribute = function (markup) { 7450 var markupString = typeof markup === 'string' ? markup : '' + markup; 7451 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, ''); 7452 }; 7453 7454 warnForTextDifference = function (serverText, clientText) { 7455 if (didWarnInvalidHydration) { 7456 return; 7457 } 7458 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText); 7459 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText); 7460 if (normalizedServerText === normalizedClientText) { 7461 return; 7462 } 7463 didWarnInvalidHydration = true; 7464 warningWithoutStack$1(false, 'Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText); 7465 }; 7466 7467 warnForPropDifference = function (propName, serverValue, clientValue) { 7468 if (didWarnInvalidHydration) { 7469 return; 7470 } 7471 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue); 7472 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue); 7473 if (normalizedServerValue === normalizedClientValue) { 7474 return; 7475 } 7476 didWarnInvalidHydration = true; 7477 warningWithoutStack$1(false, 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue)); 7478 }; 7479 7480 warnForExtraAttributes = function (attributeNames) { 7481 if (didWarnInvalidHydration) { 7482 return; 7483 } 7484 didWarnInvalidHydration = true; 7485 var names = []; 7486 attributeNames.forEach(function (name) { 7487 names.push(name); 7488 }); 7489 warningWithoutStack$1(false, 'Extra attributes from the server: %s', names); 7490 }; 7491 7492 warnForInvalidEventListener = function (registrationName, listener) { 7493 if (listener === false) { 7494 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); 7495 } else { 7496 warning$1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener); 7497 } 7498 }; 7499 7500 // Parse the HTML and read it back to normalize the HTML string so that it 7501 // can be used for comparison. 7502 normalizeHTML = function (parent, html) { 7503 // We could have created a separate document here to avoid 7504 // re-initializing custom elements if they exist. But this breaks 7505 // how <noscript> is being handled. So we use the same document. 7506 // See the discussion in https://github.com/facebook/react/pull/11157. 7507 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName); 7508 testElement.innerHTML = html; 7509 return testElement.innerHTML; 7510 }; 7511 } 7512 7513 function ensureListeningTo(rootContainerElement, registrationName) { 7514 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE; 7515 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument; 7516 listenTo(registrationName, doc); 7517 } 7518 7519 function getOwnerDocumentFromRootContainer(rootContainerElement) { 7520 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument; 7521 } 7522 7523 function noop() {} 7524 7525 function trapClickOnNonInteractiveElement(node) { 7526 // Mobile Safari does not fire properly bubble click events on 7527 // non-interactive elements, which means delegated click listeners do not 7528 // fire. The workaround for this bug involves attaching an empty click 7529 // listener on the target node. 7530 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html 7531 // Just set it using the onclick property so that we don't have to manage any 7532 // bookkeeping for it. Not sure if we need to clear it when the listener is 7533 // removed. 7534 // TODO: Only do this for the relevant Safaris maybe? 7535 node.onclick = noop; 7536 } 7537 7538 function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) { 7539 for (var propKey in nextProps) { 7540 if (!nextProps.hasOwnProperty(propKey)) { 7541 continue; 7542 } 7543 var nextProp = nextProps[propKey]; 7544 if (propKey === STYLE) { 7545 { 7546 if (nextProp) { 7547 // Freeze the next style object so that we can assume it won't be 7548 // mutated. We have already warned for this in the past. 7549 Object.freeze(nextProp); 7550 } 7551 } 7552 // Relies on `updateStylesByID` not mutating `styleUpdates`. 7553 setValueForStyles(domElement, nextProp); 7554 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { 7555 var nextHtml = nextProp ? nextProp[HTML] : undefined; 7556 if (nextHtml != null) { 7557 setInnerHTML(domElement, nextHtml); 7558 } 7559 } else if (propKey === CHILDREN) { 7560 if (typeof nextProp === 'string') { 7561 // Avoid setting initial textContent when the text is empty. In IE11 setting 7562 // textContent on a <textarea> will cause the placeholder to not 7563 // show within the <textarea> until it has been focused and blurred again. 7564 // https://github.com/facebook/react/issues/6731#issuecomment-254874553 7565 var canSetTextContent = tag !== 'textarea' || nextProp !== ''; 7566 if (canSetTextContent) { 7567 setTextContent(domElement, nextProp); 7568 } 7569 } else if (typeof nextProp === 'number') { 7570 setTextContent(domElement, '' + nextProp); 7571 } 7572 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) { 7573 // Noop 7574 } else if (propKey === AUTOFOCUS) { 7575 // We polyfill it separately on the client during commit. 7576 // We could have excluded it in the property list instead of 7577 // adding a special case here, but then it wouldn't be emitted 7578 // on server rendering (but we *do* want to emit it in SSR). 7579 } else if (registrationNameModules.hasOwnProperty(propKey)) { 7580 if (nextProp != null) { 7581 if (true && typeof nextProp !== 'function') { 7582 warnForInvalidEventListener(propKey, nextProp); 7583 } 7584 ensureListeningTo(rootContainerElement, propKey); 7585 } 7586 } else if (nextProp != null) { 7587 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag); 7588 } 7589 } 7590 } 7591 7592 function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) { 7593 // TODO: Handle wasCustomComponentTag 7594 for (var i = 0; i < updatePayload.length; i += 2) { 7595 var propKey = updatePayload[i]; 7596 var propValue = updatePayload[i + 1]; 7597 if (propKey === STYLE) { 7598 setValueForStyles(domElement, propValue); 7599 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { 7600 setInnerHTML(domElement, propValue); 7601 } else if (propKey === CHILDREN) { 7602 setTextContent(domElement, propValue); 7603 } else { 7604 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag); 7605 } 7606 } 7607 } 7608 7609 function createElement(type, props, rootContainerElement, parentNamespace) { 7610 var isCustomComponentTag = void 0; 7611 7612 // We create tags in the namespace of their parent container, except HTML 7613 // tags get no namespace. 7614 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement); 7615 var domElement = void 0; 7616 var namespaceURI = parentNamespace; 7617 if (namespaceURI === HTML_NAMESPACE) { 7618 namespaceURI = getIntrinsicNamespace(type); 7619 } 7620 if (namespaceURI === HTML_NAMESPACE) { 7621 { 7622 isCustomComponentTag = isCustomComponent(type, props); 7623 // Should this check be gated by parent namespace? Not sure we want to 7624 // allow <SVG> or <mATH>. 7625 !(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; 7626 } 7627 7628 if (type === 'script') { 7629 // Create the script via .innerHTML so its "parser-inserted" flag is 7630 // set to true and it does not execute 7631 var div = ownerDocument.createElement('div'); 7632 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line 7633 // This is guaranteed to yield a script element. 7634 var firstChild = div.firstChild; 7635 domElement = div.removeChild(firstChild); 7636 } else if (typeof props.is === 'string') { 7637 // $FlowIssue `createElement` should be updated for Web Components 7638 domElement = ownerDocument.createElement(type, { is: props.is }); 7639 } else { 7640 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug. 7641 // See discussion in https://github.com/facebook/react/pull/6896 7642 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240 7643 domElement = ownerDocument.createElement(type); 7644 // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` 7645 // attribute on `select`s needs to be added before `option`s are inserted. This prevents 7646 // a bug where the `select` does not scroll to the correct option because singular 7647 // `select` elements automatically pick the first item. 7648 // See https://github.com/facebook/react/issues/13222 7649 if (type === 'select' && props.multiple) { 7650 var node = domElement; 7651 node.multiple = true; 7652 } 7653 } 7654 } else { 7655 domElement = ownerDocument.createElementNS(namespaceURI, type); 7656 } 7657 7658 { 7659 if (namespaceURI === HTML_NAMESPACE) { 7660 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) { 7661 warnedUnknownTags[type] = true; 7662 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); 7663 } 7664 } 7665 } 7666 7667 return domElement; 7668 } 7669 7670 function createTextNode(text, rootContainerElement) { 7671 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text); 7672 } 7673 7674 function setInitialProperties(domElement, tag, rawProps, rootContainerElement) { 7675 var isCustomComponentTag = isCustomComponent(tag, rawProps); 7676 { 7677 validatePropertiesInDevelopment(tag, rawProps); 7678 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) { 7679 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component'); 7680 didWarnShadyDOM = true; 7681 } 7682 } 7683 7684 // TODO: Make sure that we check isMounted before firing any of these events. 7685 var props = void 0; 7686 switch (tag) { 7687 case 'iframe': 7688 case 'object': 7689 trapBubbledEvent(TOP_LOAD, domElement); 7690 props = rawProps; 7691 break; 7692 case 'video': 7693 case 'audio': 7694 // Create listener for each media event 7695 for (var i = 0; i < mediaEventTypes.length; i++) { 7696 trapBubbledEvent(mediaEventTypes[i], domElement); 7697 } 7698 props = rawProps; 7699 break; 7700 case 'source': 7701 trapBubbledEvent(TOP_ERROR, domElement); 7702 props = rawProps; 7703 break; 7704 case 'img': 7705 case 'image': 7706 case 'link': 7707 trapBubbledEvent(TOP_ERROR, domElement); 7708 trapBubbledEvent(TOP_LOAD, domElement); 7709 props = rawProps; 7710 break; 7711 case 'form': 7712 trapBubbledEvent(TOP_RESET, domElement); 7713 trapBubbledEvent(TOP_SUBMIT, domElement); 7714 props = rawProps; 7715 break; 7716 case 'details': 7717 trapBubbledEvent(TOP_TOGGLE, domElement); 7718 props = rawProps; 7719 break; 7720 case 'input': 7721 initWrapperState(domElement, rawProps); 7722 props = getHostProps(domElement, rawProps); 7723 trapBubbledEvent(TOP_INVALID, domElement); 7724 // For controlled components we always need to ensure we're listening 7725 // to onChange. Even if there is no listener. 7726 ensureListeningTo(rootContainerElement, 'onChange'); 7727 break; 7728 case 'option': 7729 validateProps(domElement, rawProps); 7730 props = getHostProps$1(domElement, rawProps); 7731 break; 7732 case 'select': 7733 initWrapperState$1(domElement, rawProps); 7734 props = getHostProps$2(domElement, rawProps); 7735 trapBubbledEvent(TOP_INVALID, domElement); 7736 // For controlled components we always need to ensure we're listening 7737 // to onChange. Even if there is no listener. 7738 ensureListeningTo(rootContainerElement, 'onChange'); 7739 break; 7740 case 'textarea': 7741 initWrapperState$2(domElement, rawProps); 7742 props = getHostProps$3(domElement, rawProps); 7743 trapBubbledEvent(TOP_INVALID, domElement); 7744 // For controlled components we always need to ensure we're listening 7745 // to onChange. Even if there is no listener. 7746 ensureListeningTo(rootContainerElement, 'onChange'); 7747 break; 7748 default: 7749 props = rawProps; 7750 } 7751 7752 assertValidProps(tag, props); 7753 7754 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag); 7755 7756 switch (tag) { 7757 case 'input': 7758 // TODO: Make sure we check if this is still unmounted or do any clean 7759 // up necessary since we never stop tracking anymore. 7760 track(domElement); 7761 postMountWrapper(domElement, rawProps, false); 7762 break; 7763 case 'textarea': 7764 // TODO: Make sure we check if this is still unmounted or do any clean 7765 // up necessary since we never stop tracking anymore. 7766 track(domElement); 7767 postMountWrapper$3(domElement, rawProps); 7768 break; 7769 case 'option': 7770 postMountWrapper$1(domElement, rawProps); 7771 break; 7772 case 'select': 7773 postMountWrapper$2(domElement, rawProps); 7774 break; 7775 default: 7776 if (typeof props.onClick === 'function') { 7777 // TODO: This cast may not be sound for SVG, MathML or custom elements. 7778 trapClickOnNonInteractiveElement(domElement); 7779 } 7780 break; 7781 } 7782 } 7783 7784 // Calculate the diff between the two objects. 7785 function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) { 7786 { 7787 validatePropertiesInDevelopment(tag, nextRawProps); 7788 } 7789 7790 var updatePayload = null; 7791 7792 var lastProps = void 0; 7793 var nextProps = void 0; 7794 switch (tag) { 7795 case 'input': 7796 lastProps = getHostProps(domElement, lastRawProps); 7797 nextProps = getHostProps(domElement, nextRawProps); 7798 updatePayload = []; 7799 break; 7800 case 'option': 7801 lastProps = getHostProps$1(domElement, lastRawProps); 7802 nextProps = getHostProps$1(domElement, nextRawProps); 7803 updatePayload = []; 7804 break; 7805 case 'select': 7806 lastProps = getHostProps$2(domElement, lastRawProps); 7807 nextProps = getHostProps$2(domElement, nextRawProps); 7808 updatePayload = []; 7809 break; 7810 case 'textarea': 7811 lastProps = getHostProps$3(domElement, lastRawProps); 7812 nextProps = getHostProps$3(domElement, nextRawProps); 7813 updatePayload = []; 7814 break; 7815 default: 7816 lastProps = lastRawProps; 7817 nextProps = nextRawProps; 7818 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') { 7819 // TODO: This cast may not be sound for SVG, MathML or custom elements. 7820 trapClickOnNonInteractiveElement(domElement); 7821 } 7822 break; 7823 } 7824 7825 assertValidProps(tag, nextProps); 7826 7827 var propKey = void 0; 7828 var styleName = void 0; 7829 var styleUpdates = null; 7830 for (propKey in lastProps) { 7831 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) { 7832 continue; 7833 } 7834 if (propKey === STYLE) { 7835 var lastStyle = lastProps[propKey]; 7836 for (styleName in lastStyle) { 7837 if (lastStyle.hasOwnProperty(styleName)) { 7838 if (!styleUpdates) { 7839 styleUpdates = {}; 7840 } 7841 styleUpdates[styleName] = ''; 7842 } 7843 } 7844 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) { 7845 // Noop. This is handled by the clear text mechanism. 7846 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) { 7847 // Noop 7848 } else if (propKey === AUTOFOCUS) { 7849 // Noop. It doesn't work on updates anyway. 7850 } else if (registrationNameModules.hasOwnProperty(propKey)) { 7851 // This is a special case. If any listener updates we need to ensure 7852 // that the "current" fiber pointer gets updated so we need a commit 7853 // to update this element. 7854 if (!updatePayload) { 7855 updatePayload = []; 7856 } 7857 } else { 7858 // For all other deleted properties we add it to the queue. We use 7859 // the whitelist in the commit phase instead. 7860 (updatePayload = updatePayload || []).push(propKey, null); 7861 } 7862 } 7863 for (propKey in nextProps) { 7864 var nextProp = nextProps[propKey]; 7865 var lastProp = lastProps != null ? lastProps[propKey] : undefined; 7866 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) { 7867 continue; 7868 } 7869 if (propKey === STYLE) { 7870 { 7871 if (nextProp) { 7872 // Freeze the next style object so that we can assume it won't be 7873 // mutated. We have already warned for this in the past. 7874 Object.freeze(nextProp); 7875 } 7876 } 7877 if (lastProp) { 7878 // Unset styles on `lastProp` but not on `nextProp`. 7879 for (styleName in lastProp) { 7880 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) { 7881 if (!styleUpdates) { 7882 styleUpdates = {}; 7883 } 7884 styleUpdates[styleName] = ''; 7885 } 7886 } 7887 // Update styles that changed since `lastProp`. 7888 for (styleName in nextProp) { 7889 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) { 7890 if (!styleUpdates) { 7891 styleUpdates = {}; 7892 } 7893 styleUpdates[styleName] = nextProp[styleName]; 7894 } 7895 } 7896 } else { 7897 // Relies on `updateStylesByID` not mutating `styleUpdates`. 7898 if (!styleUpdates) { 7899 if (!updatePayload) { 7900 updatePayload = []; 7901 } 7902 updatePayload.push(propKey, styleUpdates); 7903 } 7904 styleUpdates = nextProp; 7905 } 7906 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { 7907 var nextHtml = nextProp ? nextProp[HTML] : undefined; 7908 var lastHtml = lastProp ? lastProp[HTML] : undefined; 7909 if (nextHtml != null) { 7910 if (lastHtml !== nextHtml) { 7911 (updatePayload = updatePayload || []).push(propKey, '' + nextHtml); 7912 } 7913 } else { 7914 // TODO: It might be too late to clear this if we have children 7915 // inserted already. 7916 } 7917 } else if (propKey === CHILDREN) { 7918 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) { 7919 (updatePayload = updatePayload || []).push(propKey, '' + nextProp); 7920 } 7921 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) { 7922 // Noop 7923 } else if (registrationNameModules.hasOwnProperty(propKey)) { 7924 if (nextProp != null) { 7925 // We eagerly listen to this even though we haven't committed yet. 7926 if (true && typeof nextProp !== 'function') { 7927 warnForInvalidEventListener(propKey, nextProp); 7928 } 7929 ensureListeningTo(rootContainerElement, propKey); 7930 } 7931 if (!updatePayload && lastProp !== nextProp) { 7932 // This is a special case. If any listener updates we need to ensure 7933 // that the "current" props pointer gets updated so we need a commit 7934 // to update this element. 7935 updatePayload = []; 7936 } 7937 } else { 7938 // For any other property we always add it to the queue and then we 7939 // filter it out using the whitelist during the commit. 7940 (updatePayload = updatePayload || []).push(propKey, nextProp); 7941 } 7942 } 7943 if (styleUpdates) { 7944 (updatePayload = updatePayload || []).push(STYLE, styleUpdates); 7945 } 7946 return updatePayload; 7947 } 7948 7949 // Apply the diff. 7950 function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) { 7951 // Update checked *before* name. 7952 // In the middle of an update, it is possible to have multiple checked. 7953 // When a checked radio tries to change name, browser makes another radio's checked false. 7954 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) { 7955 updateChecked(domElement, nextRawProps); 7956 } 7957 7958 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps); 7959 var isCustomComponentTag = isCustomComponent(tag, nextRawProps); 7960 // Apply the diff. 7961 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag); 7962 7963 // TODO: Ensure that an update gets scheduled if any of the special props 7964 // changed. 7965 switch (tag) { 7966 case 'input': 7967 // Update the wrapper around inputs *after* updating props. This has to 7968 // happen after `updateDOMProperties`. Otherwise HTML5 input validations 7969 // raise warnings and prevent the new value from being assigned. 7970 updateWrapper(domElement, nextRawProps); 7971 break; 7972 case 'textarea': 7973 updateWrapper$1(domElement, nextRawProps); 7974 break; 7975 case 'select': 7976 // <select> value update needs to occur after <option> children 7977 // reconciliation 7978 postUpdateWrapper(domElement, nextRawProps); 7979 break; 7980 } 7981 } 7982 7983 function getPossibleStandardName(propName) { 7984 { 7985 var lowerCasedName = propName.toLowerCase(); 7986 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) { 7987 return null; 7988 } 7989 return possibleStandardNames[lowerCasedName] || null; 7990 } 7991 return null; 7992 } 7993 7994 function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement) { 7995 var isCustomComponentTag = void 0; 7996 var extraAttributeNames = void 0; 7997 7998 { 7999 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING$1] === true; 8000 isCustomComponentTag = isCustomComponent(tag, rawProps); 8001 validatePropertiesInDevelopment(tag, rawProps); 8002 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) { 8003 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component'); 8004 didWarnShadyDOM = true; 8005 } 8006 } 8007 8008 // TODO: Make sure that we check isMounted before firing any of these events. 8009 switch (tag) { 8010 case 'iframe': 8011 case 'object': 8012 trapBubbledEvent(TOP_LOAD, domElement); 8013 break; 8014 case 'video': 8015 case 'audio': 8016 // Create listener for each media event 8017 for (var i = 0; i < mediaEventTypes.length; i++) { 8018 trapBubbledEvent(mediaEventTypes[i], domElement); 8019 } 8020 break; 8021 case 'source': 8022 trapBubbledEvent(TOP_ERROR, domElement); 8023 break; 8024 case 'img': 8025 case 'image': 8026 case 'link': 8027 trapBubbledEvent(TOP_ERROR, domElement); 8028 trapBubbledEvent(TOP_LOAD, domElement); 8029 break; 8030 case 'form': 8031 trapBubbledEvent(TOP_RESET, domElement); 8032 trapBubbledEvent(TOP_SUBMIT, domElement); 8033 break; 8034 case 'details': 8035 trapBubbledEvent(TOP_TOGGLE, domElement); 8036 break; 8037 case 'input': 8038 initWrapperState(domElement, rawProps); 8039 trapBubbledEvent(TOP_INVALID, domElement); 8040 // For controlled components we always need to ensure we're listening 8041 // to onChange. Even if there is no listener. 8042 ensureListeningTo(rootContainerElement, 'onChange'); 8043 break; 8044 case 'option': 8045 validateProps(domElement, rawProps); 8046 break; 8047 case 'select': 8048 initWrapperState$1(domElement, rawProps); 8049 trapBubbledEvent(TOP_INVALID, domElement); 8050 // For controlled components we always need to ensure we're listening 8051 // to onChange. Even if there is no listener. 8052 ensureListeningTo(rootContainerElement, 'onChange'); 8053 break; 8054 case 'textarea': 8055 initWrapperState$2(domElement, rawProps); 8056 trapBubbledEvent(TOP_INVALID, domElement); 8057 // For controlled components we always need to ensure we're listening 8058 // to onChange. Even if there is no listener. 8059 ensureListeningTo(rootContainerElement, 'onChange'); 8060 break; 8061 } 8062 8063 assertValidProps(tag, rawProps); 8064 8065 { 8066 extraAttributeNames = new Set(); 8067 var attributes = domElement.attributes; 8068 for (var _i = 0; _i < attributes.length; _i++) { 8069 var name = attributes[_i].name.toLowerCase(); 8070 switch (name) { 8071 // Built-in SSR attribute is whitelisted 8072 case 'data-reactroot': 8073 break; 8074 // Controlled attributes are not validated 8075 // TODO: Only ignore them on controlled tags. 8076 case 'value': 8077 break; 8078 case 'checked': 8079 break; 8080 case 'selected': 8081 break; 8082 default: 8083 // Intentionally use the original name. 8084 // See discussion in https://github.com/facebook/react/pull/10676. 8085 extraAttributeNames.add(attributes[_i].name); 8086 } 8087 } 8088 } 8089 8090 var updatePayload = null; 8091 for (var propKey in rawProps) { 8092 if (!rawProps.hasOwnProperty(propKey)) { 8093 continue; 8094 } 8095 var nextProp = rawProps[propKey]; 8096 if (propKey === CHILDREN) { 8097 // For text content children we compare against textContent. This 8098 // might match additional HTML that is hidden when we read it using 8099 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still 8100 // satisfies our requirement. Our requirement is not to produce perfect 8101 // HTML and attributes. Ideally we should preserve structure but it's 8102 // ok not to if the visible content is still enough to indicate what 8103 // even listeners these nodes might be wired up to. 8104 // TODO: Warn if there is more than a single textNode as a child. 8105 // TODO: Should we use domElement.firstChild.nodeValue to compare? 8106 if (typeof nextProp === 'string') { 8107 if (domElement.textContent !== nextProp) { 8108 if (true && !suppressHydrationWarning) { 8109 warnForTextDifference(domElement.textContent, nextProp); 8110 } 8111 updatePayload = [CHILDREN, nextProp]; 8112 } 8113 } else if (typeof nextProp === 'number') { 8114 if (domElement.textContent !== '' + nextProp) { 8115 if (true && !suppressHydrationWarning) { 8116 warnForTextDifference(domElement.textContent, nextProp); 8117 } 8118 updatePayload = [CHILDREN, '' + nextProp]; 8119 } 8120 } 8121 } else if (registrationNameModules.hasOwnProperty(propKey)) { 8122 if (nextProp != null) { 8123 if (true && typeof nextProp !== 'function') { 8124 warnForInvalidEventListener(propKey, nextProp); 8125 } 8126 ensureListeningTo(rootContainerElement, propKey); 8127 } 8128 } else if (true && 8129 // Convince Flow we've calculated it (it's DEV-only in this method.) 8130 typeof isCustomComponentTag === 'boolean') { 8131 // Validate that the properties correspond to their expected values. 8132 var serverValue = void 0; 8133 var propertyInfo = getPropertyInfo(propKey); 8134 if (suppressHydrationWarning) { 8135 // Don't bother comparing. We're ignoring all these warnings. 8136 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1 || 8137 // Controlled attributes are not validated 8138 // TODO: Only ignore them on controlled tags. 8139 propKey === 'value' || propKey === 'checked' || propKey === 'selected') { 8140 // Noop 8141 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { 8142 var serverHTML = domElement.innerHTML; 8143 var nextHtml = nextProp ? nextProp[HTML] : undefined; 8144 var expectedHTML = normalizeHTML(domElement, nextHtml != null ? nextHtml : ''); 8145 if (expectedHTML !== serverHTML) { 8146 warnForPropDifference(propKey, serverHTML, expectedHTML); 8147 } 8148 } else if (propKey === STYLE) { 8149 // $FlowFixMe - Should be inferred as not undefined. 8150 extraAttributeNames.delete(propKey); 8151 8152 if (canDiffStyleForHydrationWarning) { 8153 var expectedStyle = createDangerousStringForStyles(nextProp); 8154 serverValue = domElement.getAttribute('style'); 8155 if (expectedStyle !== serverValue) { 8156 warnForPropDifference(propKey, serverValue, expectedStyle); 8157 } 8158 } 8159 } else if (isCustomComponentTag) { 8160 // $FlowFixMe - Should be inferred as not undefined. 8161 extraAttributeNames.delete(propKey.toLowerCase()); 8162 serverValue = getValueForAttribute(domElement, propKey, nextProp); 8163 8164 if (nextProp !== serverValue) { 8165 warnForPropDifference(propKey, serverValue, nextProp); 8166 } 8167 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) { 8168 var isMismatchDueToBadCasing = false; 8169 if (propertyInfo !== null) { 8170 // $FlowFixMe - Should be inferred as not undefined. 8171 extraAttributeNames.delete(propertyInfo.attributeName); 8172 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo); 8173 } else { 8174 var ownNamespace = parentNamespace; 8175 if (ownNamespace === HTML_NAMESPACE) { 8176 ownNamespace = getIntrinsicNamespace(tag); 8177 } 8178 if (ownNamespace === HTML_NAMESPACE) { 8179 // $FlowFixMe - Should be inferred as not undefined. 8180 extraAttributeNames.delete(propKey.toLowerCase()); 8181 } else { 8182 var standardName = getPossibleStandardName(propKey); 8183 if (standardName !== null && standardName !== propKey) { 8184 // If an SVG prop is supplied with bad casing, it will 8185 // be successfully parsed from HTML, but will produce a mismatch 8186 // (and would be incorrectly rendered on the client). 8187 // However, we already warn about bad casing elsewhere. 8188 // So we'll skip the misleading extra mismatch warning in this case. 8189 isMismatchDueToBadCasing = true; 8190 // $FlowFixMe - Should be inferred as not undefined. 8191 extraAttributeNames.delete(standardName); 8192 } 8193 // $FlowFixMe - Should be inferred as not undefined. 8194 extraAttributeNames.delete(propKey); 8195 } 8196 serverValue = getValueForAttribute(domElement, propKey, nextProp); 8197 } 8198 8199 if (nextProp !== serverValue && !isMismatchDueToBadCasing) { 8200 warnForPropDifference(propKey, serverValue, nextProp); 8201 } 8202 } 8203 } 8204 } 8205 8206 { 8207 // $FlowFixMe - Should be inferred as not undefined. 8208 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) { 8209 // $FlowFixMe - Should be inferred as not undefined. 8210 warnForExtraAttributes(extraAttributeNames); 8211 } 8212 } 8213 8214 switch (tag) { 8215 case 'input': 8216 // TODO: Make sure we check if this is still unmounted or do any clean 8217 // up necessary since we never stop tracking anymore. 8218 track(domElement); 8219 postMountWrapper(domElement, rawProps, true); 8220 break; 8221 case 'textarea': 8222 // TODO: Make sure we check if this is still unmounted or do any clean 8223 // up necessary since we never stop tracking anymore. 8224 track(domElement); 8225 postMountWrapper$3(domElement, rawProps); 8226 break; 8227 case 'select': 8228 case 'option': 8229 // For input and textarea we current always set the value property at 8230 // post mount to force it to diverge from attributes. However, for 8231 // option and select we don't quite do the same thing and select 8232 // is not resilient to the DOM state changing so we don't do that here. 8233 // TODO: Consider not doing this for input and textarea. 8234 break; 8235 default: 8236 if (typeof rawProps.onClick === 'function') { 8237 // TODO: This cast may not be sound for SVG, MathML or custom elements. 8238 trapClickOnNonInteractiveElement(domElement); 8239 } 8240 break; 8241 } 8242 8243 return updatePayload; 8244 } 8245 8246 function diffHydratedText(textNode, text) { 8247 var isDifferent = textNode.nodeValue !== text; 8248 return isDifferent; 8249 } 8250 8251 function warnForUnmatchedText(textNode, text) { 8252 { 8253 warnForTextDifference(textNode.nodeValue, text); 8254 } 8255 } 8256 8257 function warnForDeletedHydratableElement(parentNode, child) { 8258 { 8259 if (didWarnInvalidHydration) { 8260 return; 8261 } 8262 didWarnInvalidHydration = true; 8263 warningWithoutStack$1(false, 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase()); 8264 } 8265 } 8266 8267 function warnForDeletedHydratableText(parentNode, child) { 8268 { 8269 if (didWarnInvalidHydration) { 8270 return; 8271 } 8272 didWarnInvalidHydration = true; 8273 warningWithoutStack$1(false, 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase()); 8274 } 8275 } 8276 8277 function warnForInsertedHydratedElement(parentNode, tag, props) { 8278 { 8279 if (didWarnInvalidHydration) { 8280 return; 8281 } 8282 didWarnInvalidHydration = true; 8283 warningWithoutStack$1(false, 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase()); 8284 } 8285 } 8286 8287 function warnForInsertedHydratedText(parentNode, text) { 8288 { 8289 if (text === '') { 8290 // We expect to insert empty text nodes since they're not represented in 8291 // the HTML. 8292 // TODO: Remove this special case if we can just avoid inserting empty 8293 // text nodes. 8294 return; 8295 } 8296 if (didWarnInvalidHydration) { 8297 return; 8298 } 8299 didWarnInvalidHydration = true; 8300 warningWithoutStack$1(false, 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase()); 8301 } 8302 } 8303 8304 function restoreControlledState$1(domElement, tag, props) { 8305 switch (tag) { 8306 case 'input': 8307 restoreControlledState(domElement, props); 8308 return; 8309 case 'textarea': 8310 restoreControlledState$3(domElement, props); 8311 return; 8312 case 'select': 8313 restoreControlledState$2(domElement, props); 8314 return; 8315 } 8316 } 8317 8318 // TODO: direct imports like some-package/src/* are bad. Fix me. 8319 var validateDOMNesting = function () {}; 8320 var updatedAncestorInfo = function () {}; 8321 8322 { 8323 // This validation code was written based on the HTML5 parsing spec: 8324 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope 8325 // 8326 // Note: this does not catch all invalid nesting, nor does it try to (as it's 8327 // not clear what practical benefit doing so provides); instead, we warn only 8328 // for cases where the parser will give a parse tree differing from what React 8329 // intended. For example, <b><div></div></b> is invalid but we don't warn 8330 // because it still parses correctly; we do warn for other cases like nested 8331 // <p> tags where the beginning of the second element implicitly closes the 8332 // first, causing a confusing mess. 8333 8334 // https://html.spec.whatwg.org/multipage/syntax.html#special 8335 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']; 8336 8337 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope 8338 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', 8339 8340 // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point 8341 // TODO: Distinguish by namespace here -- for <title>, including it here 8342 // errs on the side of fewer warnings 8343 'foreignObject', 'desc', 'title']; 8344 8345 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope 8346 var buttonScopeTags = inScopeTags.concat(['button']); 8347 8348 // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags 8349 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt']; 8350 8351 var emptyAncestorInfo = { 8352 current: null, 8353 8354 formTag: null, 8355 aTagInScope: null, 8356 buttonTagInScope: null, 8357 nobrTagInScope: null, 8358 pTagInButtonScope: null, 8359 8360 listItemTagAutoclosing: null, 8361 dlItemTagAutoclosing: null 8362 }; 8363 8364 updatedAncestorInfo = function (oldInfo, tag) { 8365 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo); 8366 var info = { tag: tag }; 8367 8368 if (inScopeTags.indexOf(tag) !== -1) { 8369 ancestorInfo.aTagInScope = null; 8370 ancestorInfo.buttonTagInScope = null; 8371 ancestorInfo.nobrTagInScope = null; 8372 } 8373 if (buttonScopeTags.indexOf(tag) !== -1) { 8374 ancestorInfo.pTagInButtonScope = null; 8375 } 8376 8377 // See rules for 'li', 'dd', 'dt' start tags in 8378 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody 8379 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') { 8380 ancestorInfo.listItemTagAutoclosing = null; 8381 ancestorInfo.dlItemTagAutoclosing = null; 8382 } 8383 8384 ancestorInfo.current = info; 8385 8386 if (tag === 'form') { 8387 ancestorInfo.formTag = info; 8388 } 8389 if (tag === 'a') { 8390 ancestorInfo.aTagInScope = info; 8391 } 8392 if (tag === 'button') { 8393 ancestorInfo.buttonTagInScope = info; 8394 } 8395 if (tag === 'nobr') { 8396 ancestorInfo.nobrTagInScope = info; 8397 } 8398 if (tag === 'p') { 8399 ancestorInfo.pTagInButtonScope = info; 8400 } 8401 if (tag === 'li') { 8402 ancestorInfo.listItemTagAutoclosing = info; 8403 } 8404 if (tag === 'dd' || tag === 'dt') { 8405 ancestorInfo.dlItemTagAutoclosing = info; 8406 } 8407 8408 return ancestorInfo; 8409 }; 8410 8411 /** 8412 * Returns whether 8413 */ 8414 var isTagValidWithParent = function (tag, parentTag) { 8415 // First, let's check if we're in an unusual parsing mode... 8416 switch (parentTag) { 8417 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect 8418 case 'select': 8419 return tag === 'option' || tag === 'optgroup' || tag === '#text'; 8420 case 'optgroup': 8421 return tag === 'option' || tag === '#text'; 8422 // Strictly speaking, seeing an <option> doesn't mean we're in a <select> 8423 // but 8424 case 'option': 8425 return tag === '#text'; 8426 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd 8427 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption 8428 // No special behavior since these rules fall back to "in body" mode for 8429 // all except special table nodes which cause bad parsing behavior anyway. 8430 8431 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr 8432 case 'tr': 8433 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template'; 8434 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody 8435 case 'tbody': 8436 case 'thead': 8437 case 'tfoot': 8438 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template'; 8439 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup 8440 case 'colgroup': 8441 return tag === 'col' || tag === 'template'; 8442 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable 8443 case 'table': 8444 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template'; 8445 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead 8446 case 'head': 8447 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template'; 8448 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element 8449 case 'html': 8450 return tag === 'head' || tag === 'body'; 8451 case '#document': 8452 return tag === 'html'; 8453 } 8454 8455 // Probably in the "in body" parsing mode, so we outlaw only tag combos 8456 // where the parsing rules cause implicit opens or closes to be added. 8457 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody 8458 switch (tag) { 8459 case 'h1': 8460 case 'h2': 8461 case 'h3': 8462 case 'h4': 8463 case 'h5': 8464 case 'h6': 8465 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6'; 8466 8467 case 'rp': 8468 case 'rt': 8469 return impliedEndTags.indexOf(parentTag) === -1; 8470 8471 case 'body': 8472 case 'caption': 8473 case 'col': 8474 case 'colgroup': 8475 case 'frame': 8476 case 'head': 8477 case 'html': 8478 case 'tbody': 8479 case 'td': 8480 case 'tfoot': 8481 case 'th': 8482 case 'thead': 8483 case 'tr': 8484 // These tags are only valid with a few parents that have special child 8485 // parsing rules -- if we're down here, then none of those matched and 8486 // so we allow it only if we don't know what the parent is, as all other 8487 // cases are invalid. 8488 return parentTag == null; 8489 } 8490 8491 return true; 8492 }; 8493 8494 /** 8495 * Returns whether 8496 */ 8497 var findInvalidAncestorForTag = function (tag, ancestorInfo) { 8498 switch (tag) { 8499 case 'address': 8500 case 'article': 8501 case 'aside': 8502 case 'blockquote': 8503 case 'center': 8504 case 'details': 8505 case 'dialog': 8506 case 'dir': 8507 case 'div': 8508 case 'dl': 8509 case 'fieldset': 8510 case 'figcaption': 8511 case 'figure': 8512 case 'footer': 8513 case 'header': 8514 case 'hgroup': 8515 case 'main': 8516 case 'menu': 8517 case 'nav': 8518 case 'ol': 8519 case 'p': 8520 case 'section': 8521 case 'summary': 8522 case 'ul': 8523 case 'pre': 8524 case 'listing': 8525 case 'table': 8526 case 'hr': 8527 case 'xmp': 8528 case 'h1': 8529 case 'h2': 8530 case 'h3': 8531 case 'h4': 8532 case 'h5': 8533 case 'h6': 8534 return ancestorInfo.pTagInButtonScope; 8535 8536 case 'form': 8537 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope; 8538 8539 case 'li': 8540 return ancestorInfo.listItemTagAutoclosing; 8541 8542 case 'dd': 8543 case 'dt': 8544 return ancestorInfo.dlItemTagAutoclosing; 8545 8546 case 'button': 8547 return ancestorInfo.buttonTagInScope; 8548 8549 case 'a': 8550 // Spec says something about storing a list of markers, but it sounds 8551 // equivalent to this check. 8552 return ancestorInfo.aTagInScope; 8553 8554 case 'nobr': 8555 return ancestorInfo.nobrTagInScope; 8556 } 8557 8558 return null; 8559 }; 8560 8561 var didWarn = {}; 8562 8563 validateDOMNesting = function (childTag, childText, ancestorInfo) { 8564 ancestorInfo = ancestorInfo || emptyAncestorInfo; 8565 var parentInfo = ancestorInfo.current; 8566 var parentTag = parentInfo && parentInfo.tag; 8567 8568 if (childText != null) { 8569 !(childTag == null) ? warningWithoutStack$1(false, 'validateDOMNesting: when childText is passed, childTag should be null') : void 0; 8570 childTag = '#text'; 8571 } 8572 8573 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo; 8574 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo); 8575 var invalidParentOrAncestor = invalidParent || invalidAncestor; 8576 if (!invalidParentOrAncestor) { 8577 return; 8578 } 8579 8580 var ancestorTag = invalidParentOrAncestor.tag; 8581 var addendum = getCurrentFiberStackInDev(); 8582 8583 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum; 8584 if (didWarn[warnKey]) { 8585 return; 8586 } 8587 didWarn[warnKey] = true; 8588 8589 var tagDisplayName = childTag; 8590 var whitespaceInfo = ''; 8591 if (childTag === '#text') { 8592 if (/\S/.test(childText)) { 8593 tagDisplayName = 'Text nodes'; 8594 } else { 8595 tagDisplayName = 'Whitespace text nodes'; 8596 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.'; 8597 } 8598 } else { 8599 tagDisplayName = '<' + childTag + '>'; 8600 } 8601 8602 if (invalidParent) { 8603 var info = ''; 8604 if (ancestorTag === 'table' && childTag === 'tr') { 8605 info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.'; 8606 } 8607 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info, addendum); 8608 } else { 8609 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.%s', tagDisplayName, ancestorTag, addendum); 8610 } 8611 }; 8612 } 8613 8614 var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; 8615 8616 var _ReactInternals$Sched = ReactInternals$1.Schedule; 8617 var unstable_cancelScheduledWork = _ReactInternals$Sched.unstable_cancelScheduledWork; 8618 var unstable_now = _ReactInternals$Sched.unstable_now; 8619 var unstable_scheduleWork = _ReactInternals$Sched.unstable_scheduleWork; 8620 8621 // Renderers that don't support persistence 8622 // can re-export everything from this module. 8623 8624 function shim() { 8625 invariant(false, 'The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue.'); 8626 } 8627 8628 // Persistence (when unsupported) 8629 var supportsPersistence = false; 8630 var cloneInstance = shim; 8631 var createContainerChildSet = shim; 8632 var appendChildToContainerChildSet = shim; 8633 var finalizeContainerChildren = shim; 8634 var replaceContainerChildren = shim; 8635 8636 var SUPPRESS_HYDRATION_WARNING = void 0; 8637 { 8638 SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning'; 8639 } 8640 8641 var eventsEnabled = null; 8642 var selectionInformation = null; 8643 8644 function shouldAutoFocusHostComponent(type, props) { 8645 switch (type) { 8646 case 'button': 8647 case 'input': 8648 case 'select': 8649 case 'textarea': 8650 return !!props.autoFocus; 8651 } 8652 return false; 8653 } 8654 8655 function getRootHostContext(rootContainerInstance) { 8656 var type = void 0; 8657 var namespace = void 0; 8658 var nodeType = rootContainerInstance.nodeType; 8659 switch (nodeType) { 8660 case DOCUMENT_NODE: 8661 case DOCUMENT_FRAGMENT_NODE: 8662 { 8663 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment'; 8664 var root = rootContainerInstance.documentElement; 8665 namespace = root ? root.namespaceURI : getChildNamespace(null, ''); 8666 break; 8667 } 8668 default: 8669 { 8670 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance; 8671 var ownNamespace = container.namespaceURI || null; 8672 type = container.tagName; 8673 namespace = getChildNamespace(ownNamespace, type); 8674 break; 8675 } 8676 } 8677 { 8678 var validatedTag = type.toLowerCase(); 8679 var _ancestorInfo = updatedAncestorInfo(null, validatedTag); 8680 return { namespace: namespace, ancestorInfo: _ancestorInfo }; 8681 } 8682 return namespace; 8683 } 8684 8685 function getChildHostContext(parentHostContext, type, rootContainerInstance) { 8686 { 8687 var parentHostContextDev = parentHostContext; 8688 var _namespace = getChildNamespace(parentHostContextDev.namespace, type); 8689 var _ancestorInfo2 = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type); 8690 return { namespace: _namespace, ancestorInfo: _ancestorInfo2 }; 8691 } 8692 var parentNamespace = parentHostContext; 8693 return getChildNamespace(parentNamespace, type); 8694 } 8695 8696 function getPublicInstance(instance) { 8697 return instance; 8698 } 8699 8700 function prepareForCommit(containerInfo) { 8701 eventsEnabled = isEnabled(); 8702 selectionInformation = getSelectionInformation(); 8703 setEnabled(false); 8704 } 8705 8706 function resetAfterCommit(containerInfo) { 8707 restoreSelection(selectionInformation); 8708 selectionInformation = null; 8709 setEnabled(eventsEnabled); 8710 eventsEnabled = null; 8711 } 8712 8713 function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) { 8714 var parentNamespace = void 0; 8715 { 8716 // TODO: take namespace into account when validating. 8717 var hostContextDev = hostContext; 8718 validateDOMNesting(type, null, hostContextDev.ancestorInfo); 8719 if (typeof props.children === 'string' || typeof props.children === 'number') { 8720 var string = '' + props.children; 8721 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type); 8722 validateDOMNesting(null, string, ownAncestorInfo); 8723 } 8724 parentNamespace = hostContextDev.namespace; 8725 } 8726 var domElement = createElement(type, props, rootContainerInstance, parentNamespace); 8727 precacheFiberNode(internalInstanceHandle, domElement); 8728 updateFiberProps(domElement, props); 8729 return domElement; 8730 } 8731 8732 function appendInitialChild(parentInstance, child) { 8733 parentInstance.appendChild(child); 8734 } 8735 8736 function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) { 8737 setInitialProperties(domElement, type, props, rootContainerInstance); 8738 return shouldAutoFocusHostComponent(type, props); 8739 } 8740 8741 function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) { 8742 { 8743 var hostContextDev = hostContext; 8744 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) { 8745 var string = '' + newProps.children; 8746 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type); 8747 validateDOMNesting(null, string, ownAncestorInfo); 8748 } 8749 } 8750 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance); 8751 } 8752 8753 function shouldSetTextContent(type, props) { 8754 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; 8755 } 8756 8757 function shouldDeprioritizeSubtree(type, props) { 8758 return !!props.hidden; 8759 } 8760 8761 function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) { 8762 { 8763 var hostContextDev = hostContext; 8764 validateDOMNesting(null, text, hostContextDev.ancestorInfo); 8765 } 8766 var textNode = createTextNode(text, rootContainerInstance); 8767 precacheFiberNode(internalInstanceHandle, textNode); 8768 return textNode; 8769 } 8770 8771 var isPrimaryRenderer = true; 8772 var scheduleTimeout = setTimeout; 8773 var cancelTimeout = clearTimeout; 8774 var noTimeout = -1; 8775 8776 // ------------------- 8777 // Mutation 8778 // ------------------- 8779 8780 var supportsMutation = true; 8781 8782 function commitMount(domElement, type, newProps, internalInstanceHandle) { 8783 // Despite the naming that might imply otherwise, this method only 8784 // fires if there is an `Update` effect scheduled during mounting. 8785 // This happens if `finalizeInitialChildren` returns `true` (which it 8786 // does to implement the `autoFocus` attribute on the client). But 8787 // there are also other cases when this might happen (such as patching 8788 // up text content during hydration mismatch). So we'll check this again. 8789 if (shouldAutoFocusHostComponent(type, newProps)) { 8790 domElement.focus(); 8791 } 8792 } 8793 8794 function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) { 8795 // Update the props handle so that we know which props are the ones with 8796 // with current event handlers. 8797 updateFiberProps(domElement, newProps); 8798 // Apply the diff to the DOM node. 8799 updateProperties(domElement, updatePayload, type, oldProps, newProps); 8800 } 8801 8802 function resetTextContent(domElement) { 8803 setTextContent(domElement, ''); 8804 } 8805 8806 function commitTextUpdate(textInstance, oldText, newText) { 8807 textInstance.nodeValue = newText; 8808 } 8809 8810 function appendChild(parentInstance, child) { 8811 parentInstance.appendChild(child); 8812 } 8813 8814 function appendChildToContainer(container, child) { 8815 var parentNode = void 0; 8816 if (container.nodeType === COMMENT_NODE) { 8817 parentNode = container.parentNode; 8818 parentNode.insertBefore(child, container); 8819 } else { 8820 parentNode = container; 8821 parentNode.appendChild(child); 8822 } 8823 // This container might be used for a portal. 8824 // If something inside a portal is clicked, that click should bubble 8825 // through the React tree. However, on Mobile Safari the click would 8826 // never bubble through the *DOM* tree unless an ancestor with onclick 8827 // event exists. So we wouldn't see it and dispatch it. 8828 // This is why we ensure that containers have inline onclick defined. 8829 // https://github.com/facebook/react/issues/11918 8830 if (parentNode.onclick === null) { 8831 // TODO: This cast may not be sound for SVG, MathML or custom elements. 8832 trapClickOnNonInteractiveElement(parentNode); 8833 } 8834 } 8835 8836 function insertBefore(parentInstance, child, beforeChild) { 8837 parentInstance.insertBefore(child, beforeChild); 8838 } 8839 8840 function insertInContainerBefore(container, child, beforeChild) { 8841 if (container.nodeType === COMMENT_NODE) { 8842 container.parentNode.insertBefore(child, beforeChild); 8843 } else { 8844 container.insertBefore(child, beforeChild); 8845 } 8846 } 8847 8848 function removeChild(parentInstance, child) { 8849 parentInstance.removeChild(child); 8850 } 8851 8852 function removeChildFromContainer(container, child) { 8853 if (container.nodeType === COMMENT_NODE) { 8854 container.parentNode.removeChild(child); 8855 } else { 8856 container.removeChild(child); 8857 } 8858 } 8859 8860 // ------------------- 8861 // Hydration 8862 // ------------------- 8863 8864 var supportsHydration = true; 8865 8866 function canHydrateInstance(instance, type, props) { 8867 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) { 8868 return null; 8869 } 8870 // This has now been refined to an element node. 8871 return instance; 8872 } 8873 8874 function canHydrateTextInstance(instance, text) { 8875 if (text === '' || instance.nodeType !== TEXT_NODE) { 8876 // Empty strings are not parsed by HTML so there won't be a correct match here. 8877 return null; 8878 } 8879 // This has now been refined to a text node. 8880 return instance; 8881 } 8882 8883 function getNextHydratableSibling(instance) { 8884 var node = instance.nextSibling; 8885 // Skip non-hydratable nodes. 8886 while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE) { 8887 node = node.nextSibling; 8888 } 8889 return node; 8890 } 8891 8892 function getFirstHydratableChild(parentInstance) { 8893 var next = parentInstance.firstChild; 8894 // Skip non-hydratable nodes. 8895 while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE) { 8896 next = next.nextSibling; 8897 } 8898 return next; 8899 } 8900 8901 function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) { 8902 precacheFiberNode(internalInstanceHandle, instance); 8903 // TODO: Possibly defer this until the commit phase where all the events 8904 // get attached. 8905 updateFiberProps(instance, props); 8906 var parentNamespace = void 0; 8907 { 8908 var hostContextDev = hostContext; 8909 parentNamespace = hostContextDev.namespace; 8910 } 8911 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance); 8912 } 8913 8914 function hydrateTextInstance(textInstance, text, internalInstanceHandle) { 8915 precacheFiberNode(internalInstanceHandle, textInstance); 8916 return diffHydratedText(textInstance, text); 8917 } 8918 8919 function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) { 8920 { 8921 warnForUnmatchedText(textInstance, text); 8922 } 8923 } 8924 8925 function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text) { 8926 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) { 8927 warnForUnmatchedText(textInstance, text); 8928 } 8929 } 8930 8931 function didNotHydrateContainerInstance(parentContainer, instance) { 8932 { 8933 if (instance.nodeType === ELEMENT_NODE) { 8934 warnForDeletedHydratableElement(parentContainer, instance); 8935 } else { 8936 warnForDeletedHydratableText(parentContainer, instance); 8937 } 8938 } 8939 } 8940 8941 function didNotHydrateInstance(parentType, parentProps, parentInstance, instance) { 8942 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) { 8943 if (instance.nodeType === ELEMENT_NODE) { 8944 warnForDeletedHydratableElement(parentInstance, instance); 8945 } else { 8946 warnForDeletedHydratableText(parentInstance, instance); 8947 } 8948 } 8949 } 8950 8951 function didNotFindHydratableContainerInstance(parentContainer, type, props) { 8952 { 8953 warnForInsertedHydratedElement(parentContainer, type, props); 8954 } 8955 } 8956 8957 function didNotFindHydratableContainerTextInstance(parentContainer, text) { 8958 { 8959 warnForInsertedHydratedText(parentContainer, text); 8960 } 8961 } 8962 8963 function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) { 8964 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) { 8965 warnForInsertedHydratedElement(parentInstance, type, props); 8966 } 8967 } 8968 8969 function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) { 8970 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) { 8971 warnForInsertedHydratedText(parentInstance, text); 8972 } 8973 } 8974 8975 // Prefix measurements so that it's possible to filter them. 8976 // Longer prefixes are hard to read in DevTools. 8977 var reactEmoji = '\u269B'; 8978 var warningEmoji = '\u26D4'; 8979 var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function'; 8980 8981 // Keep track of current fiber so that we know the path to unwind on pause. 8982 // TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them? 8983 var currentFiber = null; 8984 // If we're in the middle of user code, which fiber and method is it? 8985 // Reusing `currentFiber` would be confusing for this because user code fiber 8986 // can change during commit phase too, but we don't need to unwind it (since 8987 // lifecycles in the commit phase don't resemble a tree). 8988 var currentPhase = null; 8989 var currentPhaseFiber = null; 8990 // Did lifecycle hook schedule an update? This is often a performance problem, 8991 // so we will keep track of it, and include it in the report. 8992 // Track commits caused by cascading updates. 8993 var isCommitting = false; 8994 var hasScheduledUpdateInCurrentCommit = false; 8995 var hasScheduledUpdateInCurrentPhase = false; 8996 var commitCountInCurrentWorkLoop = 0; 8997 var effectCountInCurrentCommit = 0; 8998 var isWaitingForCallback = false; 8999 // During commits, we only show a measurement once per method name 9000 // to avoid stretch the commit phase with measurement overhead. 9001 var labelsInCurrentCommit = new Set(); 9002 9003 var formatMarkName = function (markName) { 9004 return reactEmoji + ' ' + markName; 9005 }; 9006 9007 var formatLabel = function (label, warning) { 9008 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' '; 9009 var suffix = warning ? ' Warning: ' + warning : ''; 9010 return '' + prefix + label + suffix; 9011 }; 9012 9013 var beginMark = function (markName) { 9014 performance.mark(formatMarkName(markName)); 9015 }; 9016 9017 var clearMark = function (markName) { 9018 performance.clearMarks(formatMarkName(markName)); 9019 }; 9020 9021 var endMark = function (label, markName, warning) { 9022 var formattedMarkName = formatMarkName(markName); 9023 var formattedLabel = formatLabel(label, warning); 9024 try { 9025 performance.measure(formattedLabel, formattedMarkName); 9026 } catch (err) {} 9027 // If previous mark was missing for some reason, this will throw. 9028 // This could only happen if React crashed in an unexpected place earlier. 9029 // Don't pile on with more errors. 9030 9031 // Clear marks immediately to avoid growing buffer. 9032 performance.clearMarks(formattedMarkName); 9033 performance.clearMeasures(formattedLabel); 9034 }; 9035 9036 var getFiberMarkName = function (label, debugID) { 9037 return label + ' (#' + debugID + ')'; 9038 }; 9039 9040 var getFiberLabel = function (componentName, isMounted, phase) { 9041 if (phase === null) { 9042 // These are composite component total time measurements. 9043 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']'; 9044 } else { 9045 // Composite component methods. 9046 return componentName + '.' + phase; 9047 } 9048 }; 9049 9050 var beginFiberMark = function (fiber, phase) { 9051 var componentName = getComponentName(fiber.type) || 'Unknown'; 9052 var debugID = fiber._debugID; 9053 var isMounted = fiber.alternate !== null; 9054 var label = getFiberLabel(componentName, isMounted, phase); 9055 9056 if (isCommitting && labelsInCurrentCommit.has(label)) { 9057 // During the commit phase, we don't show duplicate labels because 9058 // there is a fixed overhead for every measurement, and we don't 9059 // want to stretch the commit phase beyond necessary. 9060 return false; 9061 } 9062 labelsInCurrentCommit.add(label); 9063 9064 var markName = getFiberMarkName(label, debugID); 9065 beginMark(markName); 9066 return true; 9067 }; 9068 9069 var clearFiberMark = function (fiber, phase) { 9070 var componentName = getComponentName(fiber.type) || 'Unknown'; 9071 var debugID = fiber._debugID; 9072 var isMounted = fiber.alternate !== null; 9073 var label = getFiberLabel(componentName, isMounted, phase); 9074 var markName = getFiberMarkName(label, debugID); 9075 clearMark(markName); 9076 }; 9077 9078 var endFiberMark = function (fiber, phase, warning) { 9079 var componentName = getComponentName(fiber.type) || 'Unknown'; 9080 var debugID = fiber._debugID; 9081 var isMounted = fiber.alternate !== null; 9082 var label = getFiberLabel(componentName, isMounted, phase); 9083 var markName = getFiberMarkName(label, debugID); 9084 endMark(label, markName, warning); 9085 }; 9086 9087 var shouldIgnoreFiber = function (fiber) { 9088 // Host components should be skipped in the timeline. 9089 // We could check typeof fiber.type, but does this work with RN? 9090 switch (fiber.tag) { 9091 case HostRoot: 9092 case HostComponent: 9093 case HostText: 9094 case HostPortal: 9095 case Fragment: 9096 case ContextProvider: 9097 case ContextConsumer: 9098 case Mode: 9099 return true; 9100 default: 9101 return false; 9102 } 9103 }; 9104 9105 var clearPendingPhaseMeasurement = function () { 9106 if (currentPhase !== null && currentPhaseFiber !== null) { 9107 clearFiberMark(currentPhaseFiber, currentPhase); 9108 } 9109 currentPhaseFiber = null; 9110 currentPhase = null; 9111 hasScheduledUpdateInCurrentPhase = false; 9112 }; 9113 9114 var pauseTimers = function () { 9115 // Stops all currently active measurements so that they can be resumed 9116 // if we continue in a later deferred loop from the same unit of work. 9117 var fiber = currentFiber; 9118 while (fiber) { 9119 if (fiber._debugIsCurrentlyTiming) { 9120 endFiberMark(fiber, null, null); 9121 } 9122 fiber = fiber.return; 9123 } 9124 }; 9125 9126 var resumeTimersRecursively = function (fiber) { 9127 if (fiber.return !== null) { 9128 resumeTimersRecursively(fiber.return); 9129 } 9130 if (fiber._debugIsCurrentlyTiming) { 9131 beginFiberMark(fiber, null); 9132 } 9133 }; 9134 9135 var resumeTimers = function () { 9136 // Resumes all measurements that were active during the last deferred loop. 9137 if (currentFiber !== null) { 9138 resumeTimersRecursively(currentFiber); 9139 } 9140 }; 9141 9142 function recordEffect() { 9143 if (enableUserTimingAPI) { 9144 effectCountInCurrentCommit++; 9145 } 9146 } 9147 9148 function recordScheduleUpdate() { 9149 if (enableUserTimingAPI) { 9150 if (isCommitting) { 9151 hasScheduledUpdateInCurrentCommit = true; 9152 } 9153 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') { 9154 hasScheduledUpdateInCurrentPhase = true; 9155 } 9156 } 9157 } 9158 9159 function startRequestCallbackTimer() { 9160 if (enableUserTimingAPI) { 9161 if (supportsUserTiming && !isWaitingForCallback) { 9162 isWaitingForCallback = true; 9163 beginMark('(Waiting for async callback...)'); 9164 } 9165 } 9166 } 9167 9168 function stopRequestCallbackTimer(didExpire, expirationTime) { 9169 if (enableUserTimingAPI) { 9170 if (supportsUserTiming) { 9171 isWaitingForCallback = false; 9172 var warning = didExpire ? 'React was blocked by main thread' : null; 9173 endMark('(Waiting for async callback... will force flush in ' + expirationTime + ' ms)', '(Waiting for async callback...)', warning); 9174 } 9175 } 9176 } 9177 9178 function startWorkTimer(fiber) { 9179 if (enableUserTimingAPI) { 9180 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { 9181 return; 9182 } 9183 // If we pause, this is the fiber to unwind from. 9184 currentFiber = fiber; 9185 if (!beginFiberMark(fiber, null)) { 9186 return; 9187 } 9188 fiber._debugIsCurrentlyTiming = true; 9189 } 9190 } 9191 9192 function cancelWorkTimer(fiber) { 9193 if (enableUserTimingAPI) { 9194 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { 9195 return; 9196 } 9197 // Remember we shouldn't complete measurement for this fiber. 9198 // Otherwise flamechart will be deep even for small updates. 9199 fiber._debugIsCurrentlyTiming = false; 9200 clearFiberMark(fiber, null); 9201 } 9202 } 9203 9204 function stopWorkTimer(fiber) { 9205 if (enableUserTimingAPI) { 9206 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { 9207 return; 9208 } 9209 // If we pause, its parent is the fiber to unwind from. 9210 currentFiber = fiber.return; 9211 if (!fiber._debugIsCurrentlyTiming) { 9212 return; 9213 } 9214 fiber._debugIsCurrentlyTiming = false; 9215 endFiberMark(fiber, null, null); 9216 } 9217 } 9218 9219 function stopFailedWorkTimer(fiber) { 9220 if (enableUserTimingAPI) { 9221 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { 9222 return; 9223 } 9224 // If we pause, its parent is the fiber to unwind from. 9225 currentFiber = fiber.return; 9226 if (!fiber._debugIsCurrentlyTiming) { 9227 return; 9228 } 9229 fiber._debugIsCurrentlyTiming = false; 9230 var warning = 'An error was thrown inside this error boundary'; 9231 endFiberMark(fiber, null, warning); 9232 } 9233 } 9234 9235 function startPhaseTimer(fiber, phase) { 9236 if (enableUserTimingAPI) { 9237 if (!supportsUserTiming) { 9238 return; 9239 } 9240 clearPendingPhaseMeasurement(); 9241 if (!beginFiberMark(fiber, phase)) { 9242 return; 9243 } 9244 currentPhaseFiber = fiber; 9245 currentPhase = phase; 9246 } 9247 } 9248 9249 function stopPhaseTimer() { 9250 if (enableUserTimingAPI) { 9251 if (!supportsUserTiming) { 9252 return; 9253 } 9254 if (currentPhase !== null && currentPhaseFiber !== null) { 9255 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null; 9256 endFiberMark(currentPhaseFiber, currentPhase, warning); 9257 } 9258 currentPhase = null; 9259 currentPhaseFiber = null; 9260 } 9261 } 9262 9263 function startWorkLoopTimer(nextUnitOfWork) { 9264 if (enableUserTimingAPI) { 9265 currentFiber = nextUnitOfWork; 9266 if (!supportsUserTiming) { 9267 return; 9268 } 9269 commitCountInCurrentWorkLoop = 0; 9270 // This is top level call. 9271 // Any other measurements are performed within. 9272 beginMark('(React Tree Reconciliation)'); 9273 // Resume any measurements that were in progress during the last loop. 9274 resumeTimers(); 9275 } 9276 } 9277 9278 function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { 9279 if (enableUserTimingAPI) { 9280 if (!supportsUserTiming) { 9281 return; 9282 } 9283 var warning = null; 9284 if (interruptedBy !== null) { 9285 if (interruptedBy.tag === HostRoot) { 9286 warning = 'A top-level update interrupted the previous render'; 9287 } else { 9288 var componentName = getComponentName(interruptedBy.type) || 'Unknown'; 9289 warning = 'An update to ' + componentName + ' interrupted the previous render'; 9290 } 9291 } else if (commitCountInCurrentWorkLoop > 1) { 9292 warning = 'There were cascading updates'; 9293 } 9294 commitCountInCurrentWorkLoop = 0; 9295 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)'; 9296 // Pause any measurements until the next loop. 9297 pauseTimers(); 9298 endMark(label, '(React Tree Reconciliation)', warning); 9299 } 9300 } 9301 9302 function startCommitTimer() { 9303 if (enableUserTimingAPI) { 9304 if (!supportsUserTiming) { 9305 return; 9306 } 9307 isCommitting = true; 9308 hasScheduledUpdateInCurrentCommit = false; 9309 labelsInCurrentCommit.clear(); 9310 beginMark('(Committing Changes)'); 9311 } 9312 } 9313 9314 function stopCommitTimer() { 9315 if (enableUserTimingAPI) { 9316 if (!supportsUserTiming) { 9317 return; 9318 } 9319 9320 var warning = null; 9321 if (hasScheduledUpdateInCurrentCommit) { 9322 warning = 'Lifecycle hook scheduled a cascading update'; 9323 } else if (commitCountInCurrentWorkLoop > 0) { 9324 warning = 'Caused by a cascading update in earlier commit'; 9325 } 9326 hasScheduledUpdateInCurrentCommit = false; 9327 commitCountInCurrentWorkLoop++; 9328 isCommitting = false; 9329 labelsInCurrentCommit.clear(); 9330 9331 endMark('(Committing Changes)', '(Committing Changes)', warning); 9332 } 9333 } 9334 9335 function startCommitSnapshotEffectsTimer() { 9336 if (enableUserTimingAPI) { 9337 if (!supportsUserTiming) { 9338 return; 9339 } 9340 effectCountInCurrentCommit = 0; 9341 beginMark('(Committing Snapshot Effects)'); 9342 } 9343 } 9344 9345 function stopCommitSnapshotEffectsTimer() { 9346 if (enableUserTimingAPI) { 9347 if (!supportsUserTiming) { 9348 return; 9349 } 9350 var count = effectCountInCurrentCommit; 9351 effectCountInCurrentCommit = 0; 9352 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null); 9353 } 9354 } 9355 9356 function startCommitHostEffectsTimer() { 9357 if (enableUserTimingAPI) { 9358 if (!supportsUserTiming) { 9359 return; 9360 } 9361 effectCountInCurrentCommit = 0; 9362 beginMark('(Committing Host Effects)'); 9363 } 9364 } 9365 9366 function stopCommitHostEffectsTimer() { 9367 if (enableUserTimingAPI) { 9368 if (!supportsUserTiming) { 9369 return; 9370 } 9371 var count = effectCountInCurrentCommit; 9372 effectCountInCurrentCommit = 0; 9373 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null); 9374 } 9375 } 9376 9377 function startCommitLifeCyclesTimer() { 9378 if (enableUserTimingAPI) { 9379 if (!supportsUserTiming) { 9380 return; 9381 } 9382 effectCountInCurrentCommit = 0; 9383 beginMark('(Calling Lifecycle Methods)'); 9384 } 9385 } 9386 9387 function stopCommitLifeCyclesTimer() { 9388 if (enableUserTimingAPI) { 9389 if (!supportsUserTiming) { 9390 return; 9391 } 9392 var count = effectCountInCurrentCommit; 9393 effectCountInCurrentCommit = 0; 9394 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null); 9395 } 9396 } 9397 9398 var valueStack = []; 9399 9400 var fiberStack = void 0; 9401 9402 { 9403 fiberStack = []; 9404 } 9405 9406 var index = -1; 9407 9408 function createCursor(defaultValue) { 9409 return { 9410 current: defaultValue 9411 }; 9412 } 9413 9414 function pop(cursor, fiber) { 9415 if (index < 0) { 9416 { 9417 warningWithoutStack$1(false, 'Unexpected pop.'); 9418 } 9419 return; 9420 } 9421 9422 { 9423 if (fiber !== fiberStack[index]) { 9424 warningWithoutStack$1(false, 'Unexpected Fiber popped.'); 9425 } 9426 } 9427 9428 cursor.current = valueStack[index]; 9429 9430 valueStack[index] = null; 9431 9432 { 9433 fiberStack[index] = null; 9434 } 9435 9436 index--; 9437 } 9438 9439 function push(cursor, value, fiber) { 9440 index++; 9441 9442 valueStack[index] = cursor.current; 9443 9444 { 9445 fiberStack[index] = fiber; 9446 } 9447 9448 cursor.current = value; 9449 } 9450 9451 function checkThatStackIsEmpty() { 9452 { 9453 if (index !== -1) { 9454 warningWithoutStack$1(false, 'Expected an empty stack. Something was not reset properly.'); 9455 } 9456 } 9457 } 9458 9459 function resetStackAfterFatalErrorInDev() { 9460 { 9461 index = -1; 9462 valueStack.length = 0; 9463 fiberStack.length = 0; 9464 } 9465 } 9466 9467 var warnedAboutMissingGetChildContext = void 0; 9468 9469 { 9470 warnedAboutMissingGetChildContext = {}; 9471 } 9472 9473 var emptyContextObject = {}; 9474 { 9475 Object.freeze(emptyContextObject); 9476 } 9477 9478 // A cursor to the current merged context object on the stack. 9479 var contextStackCursor = createCursor(emptyContextObject); 9480 // A cursor to a boolean indicating whether the context has changed. 9481 var didPerformWorkStackCursor = createCursor(false); 9482 // Keep track of the previous context object that was on the stack. 9483 // We use this to get access to the parent context after we have already 9484 // pushed the next context provider, and now need to merge their contexts. 9485 var previousContext = emptyContextObject; 9486 9487 function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) { 9488 if (didPushOwnContextIfProvider && isContextProvider(Component)) { 9489 // If the fiber is a context provider itself, when we read its context 9490 // we may have already pushed its own child context on the stack. A context 9491 // provider should not "see" its own child context. Therefore we read the 9492 // previous (parent) context instead for a context provider. 9493 return previousContext; 9494 } 9495 return contextStackCursor.current; 9496 } 9497 9498 function cacheContext(workInProgress, unmaskedContext, maskedContext) { 9499 var instance = workInProgress.stateNode; 9500 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; 9501 instance.__reactInternalMemoizedMaskedChildContext = maskedContext; 9502 } 9503 9504 function getMaskedContext(workInProgress, unmaskedContext) { 9505 var type = workInProgress.type; 9506 var contextTypes = type.contextTypes; 9507 if (!contextTypes) { 9508 return emptyContextObject; 9509 } 9510 9511 // Avoid recreating masked context unless unmasked context has changed. 9512 // Failing to do this will result in unnecessary calls to componentWillReceiveProps. 9513 // This may trigger infinite loops if componentWillReceiveProps calls setState. 9514 var instance = workInProgress.stateNode; 9515 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) { 9516 return instance.__reactInternalMemoizedMaskedChildContext; 9517 } 9518 9519 var context = {}; 9520 for (var key in contextTypes) { 9521 context[key] = unmaskedContext[key]; 9522 } 9523 9524 { 9525 var name = getComponentName(type) || 'Unknown'; 9526 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev); 9527 } 9528 9529 // Cache unmasked context so we can avoid recreating masked context unless necessary. 9530 // Context is created before the class component is instantiated so check for instance. 9531 if (instance) { 9532 cacheContext(workInProgress, unmaskedContext, context); 9533 } 9534 9535 return context; 9536 } 9537 9538 function hasContextChanged() { 9539 return didPerformWorkStackCursor.current; 9540 } 9541 9542 function isContextProvider(type) { 9543 var childContextTypes = type.childContextTypes; 9544 return childContextTypes !== null && childContextTypes !== undefined; 9545 } 9546 9547 function popContext(fiber) { 9548 pop(didPerformWorkStackCursor, fiber); 9549 pop(contextStackCursor, fiber); 9550 } 9551 9552 function popTopLevelContextObject(fiber) { 9553 pop(didPerformWorkStackCursor, fiber); 9554 pop(contextStackCursor, fiber); 9555 } 9556 9557 function pushTopLevelContextObject(fiber, context, didChange) { 9558 !(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; 9559 9560 push(contextStackCursor, context, fiber); 9561 push(didPerformWorkStackCursor, didChange, fiber); 9562 } 9563 9564 function processChildContext(fiber, type, parentContext) { 9565 var instance = fiber.stateNode; 9566 var childContextTypes = type.childContextTypes; 9567 9568 // TODO (bvaughn) Replace this behavior with an invariant() in the future. 9569 // It has only been added in Fiber to match the (unintentional) behavior in Stack. 9570 if (typeof instance.getChildContext !== 'function') { 9571 { 9572 var componentName = getComponentName(type) || 'Unknown'; 9573 9574 if (!warnedAboutMissingGetChildContext[componentName]) { 9575 warnedAboutMissingGetChildContext[componentName] = true; 9576 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); 9577 } 9578 } 9579 return parentContext; 9580 } 9581 9582 var childContext = void 0; 9583 { 9584 setCurrentPhase('getChildContext'); 9585 } 9586 startPhaseTimer(fiber, 'getChildContext'); 9587 childContext = instance.getChildContext(); 9588 stopPhaseTimer(); 9589 { 9590 setCurrentPhase(null); 9591 } 9592 for (var contextKey in childContext) { 9593 !(contextKey in childContextTypes) ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(type) || 'Unknown', contextKey) : void 0; 9594 } 9595 { 9596 var name = getComponentName(type) || 'Unknown'; 9597 checkPropTypes_1(childContextTypes, childContext, 'child context', name, 9598 // In practice, there is one case in which we won't get a stack. It's when 9599 // somebody calls unstable_renderSubtreeIntoContainer() and we process 9600 // context from the parent component instance. The stack will be missing 9601 // because it's outside of the reconciliation, and so the pointer has not 9602 // been set. This is rare and doesn't matter. We'll also remove that API. 9603 getCurrentFiberStackInDev); 9604 } 9605 9606 return _assign({}, parentContext, childContext); 9607 } 9608 9609 function pushContextProvider(workInProgress) { 9610 var instance = workInProgress.stateNode; 9611 // We push the context as early as possible to ensure stack integrity. 9612 // If the instance does not exist yet, we will push null at first, 9613 // and replace it on the stack later when invalidating the context. 9614 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; 9615 9616 // Remember the parent context so we can merge with it later. 9617 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. 9618 previousContext = contextStackCursor.current; 9619 push(contextStackCursor, memoizedMergedChildContext, workInProgress); 9620 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress); 9621 9622 return true; 9623 } 9624 9625 function invalidateContextProvider(workInProgress, type, didChange) { 9626 var instance = workInProgress.stateNode; 9627 !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; 9628 9629 if (didChange) { 9630 // Merge parent and own context. 9631 // Skip this if we're not updating due to sCU. 9632 // This avoids unnecessarily recomputing memoized values. 9633 var mergedContext = processChildContext(workInProgress, type, previousContext); 9634 instance.__reactInternalMemoizedMergedChildContext = mergedContext; 9635 9636 // Replace the old (or empty) context with the new one. 9637 // It is important to unwind the context in the reverse order. 9638 pop(didPerformWorkStackCursor, workInProgress); 9639 pop(contextStackCursor, workInProgress); 9640 // Now push the new context and mark that it has changed. 9641 push(contextStackCursor, mergedContext, workInProgress); 9642 push(didPerformWorkStackCursor, didChange, workInProgress); 9643 } else { 9644 pop(didPerformWorkStackCursor, workInProgress); 9645 push(didPerformWorkStackCursor, didChange, workInProgress); 9646 } 9647 } 9648 9649 function findCurrentUnmaskedContext(fiber) { 9650 // Currently this is only used with renderSubtreeIntoContainer; not sure if it 9651 // makes sense elsewhere 9652 !(isFiberMounted(fiber) && (fiber.tag === ClassComponent || fiber.tag === ClassComponentLazy)) ? 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; 9653 9654 var node = fiber; 9655 do { 9656 switch (node.tag) { 9657 case HostRoot: 9658 return node.stateNode.context; 9659 case ClassComponent: 9660 { 9661 var Component = node.type; 9662 if (isContextProvider(Component)) { 9663 return node.stateNode.__reactInternalMemoizedMergedChildContext; 9664 } 9665 break; 9666 } 9667 case ClassComponentLazy: 9668 { 9669 var _Component = getResultFromResolvedThenable(node.type); 9670 if (isContextProvider(_Component)) { 9671 return node.stateNode.__reactInternalMemoizedMergedChildContext; 9672 } 9673 break; 9674 } 9675 } 9676 node = node.return; 9677 } while (node !== null); 9678 invariant(false, 'Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.'); 9679 } 9680 9681 var onCommitFiberRoot = null; 9682 var onCommitFiberUnmount = null; 9683 var hasLoggedError = false; 9684 9685 function catchErrors(fn) { 9686 return function (arg) { 9687 try { 9688 return fn(arg); 9689 } catch (err) { 9690 if (true && !hasLoggedError) { 9691 hasLoggedError = true; 9692 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err); 9693 } 9694 } 9695 }; 9696 } 9697 9698 var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined'; 9699 9700 function injectInternals(internals) { 9701 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') { 9702 // No DevTools 9703 return false; 9704 } 9705 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; 9706 if (hook.isDisabled) { 9707 // This isn't a real property on the hook, but it can be set to opt out 9708 // of DevTools integration and associated warnings and logs. 9709 // https://github.com/facebook/react/issues/3877 9710 return true; 9711 } 9712 if (!hook.supportsFiber) { 9713 { 9714 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'); 9715 } 9716 // DevTools exists, even though it doesn't support Fiber. 9717 return true; 9718 } 9719 try { 9720 var rendererID = hook.inject(internals); 9721 // We have successfully injected, so now it is safe to set up hooks. 9722 onCommitFiberRoot = catchErrors(function (root) { 9723 return hook.onCommitFiberRoot(rendererID, root); 9724 }); 9725 onCommitFiberUnmount = catchErrors(function (fiber) { 9726 return hook.onCommitFiberUnmount(rendererID, fiber); 9727 }); 9728 } catch (err) { 9729 // Catch all errors because it is unsafe to throw during initialization. 9730 { 9731 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err); 9732 } 9733 } 9734 // DevTools exists 9735 return true; 9736 } 9737 9738 function onCommitRoot(root) { 9739 if (typeof onCommitFiberRoot === 'function') { 9740 onCommitFiberRoot(root); 9741 } 9742 } 9743 9744 function onCommitUnmount(fiber) { 9745 if (typeof onCommitFiberUnmount === 'function') { 9746 onCommitFiberUnmount(fiber); 9747 } 9748 } 9749 9750 // Max 31 bit integer. The max integer size in V8 for 32-bit systems. 9751 // Math.pow(2, 30) - 1 9752 // 0b111111111111111111111111111111 9753 var maxSigned31BitInt = 1073741823; 9754 9755 var NoWork = 0; 9756 var Sync = 1; 9757 var Never = maxSigned31BitInt; 9758 9759 var UNIT_SIZE = 10; 9760 var MAGIC_NUMBER_OFFSET = 2; 9761 9762 // 1 unit of expiration time represents 10ms. 9763 function msToExpirationTime(ms) { 9764 // Always add an offset so that we don't clash with the magic number for NoWork. 9765 return (ms / UNIT_SIZE | 0) + MAGIC_NUMBER_OFFSET; 9766 } 9767 9768 function expirationTimeToMs(expirationTime) { 9769 return (expirationTime - MAGIC_NUMBER_OFFSET) * UNIT_SIZE; 9770 } 9771 9772 function ceiling(num, precision) { 9773 return ((num / precision | 0) + 1) * precision; 9774 } 9775 9776 function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) { 9777 return MAGIC_NUMBER_OFFSET + ceiling(currentTime - MAGIC_NUMBER_OFFSET + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE); 9778 } 9779 9780 var LOW_PRIORITY_EXPIRATION = 5000; 9781 var LOW_PRIORITY_BATCH_SIZE = 250; 9782 9783 function computeAsyncExpiration(currentTime) { 9784 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE); 9785 } 9786 9787 // We intentionally set a higher expiration time for interactive updates in 9788 // dev than in production. 9789 // 9790 // If the main thread is being blocked so long that you hit the expiration, 9791 // it's a problem that could be solved with better scheduling. 9792 // 9793 // People will be more likely to notice this and fix it with the long 9794 // expiration time in development. 9795 // 9796 // In production we opt for better UX at the risk of masking scheduling 9797 // problems, by expiring fast. 9798 var HIGH_PRIORITY_EXPIRATION = 500; 9799 var HIGH_PRIORITY_BATCH_SIZE = 100; 9800 9801 function computeInteractiveExpiration(currentTime) { 9802 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE); 9803 } 9804 9805 var NoContext = 0; 9806 var AsyncMode = 1; 9807 var StrictMode = 2; 9808 var ProfileMode = 4; 9809 9810 var hasBadMapPolyfill = void 0; 9811 9812 { 9813 hasBadMapPolyfill = false; 9814 try { 9815 var nonExtensibleObject = Object.preventExtensions({}); 9816 var testMap = new Map([[nonExtensibleObject, null]]); 9817 var testSet = new Set([nonExtensibleObject]); 9818 // This is necessary for Rollup to not consider these unused. 9819 // https://github.com/rollup/rollup/issues/1771 9820 // TODO: we can remove these if Rollup fixes the bug. 9821 testMap.set(0, 0); 9822 testSet.add(0); 9823 } catch (e) { 9824 // TODO: Consider warning about bad polyfills 9825 hasBadMapPolyfill = true; 9826 } 9827 } 9828 9829 // A Fiber is work on a Component that needs to be done or was done. There can 9830 // be more than one per component. 9831 9832 9833 var debugCounter = void 0; 9834 9835 { 9836 debugCounter = 1; 9837 } 9838 9839 function FiberNode(tag, pendingProps, key, mode) { 9840 // Instance 9841 this.tag = tag; 9842 this.key = key; 9843 this.type = null; 9844 this.stateNode = null; 9845 9846 // Fiber 9847 this.return = null; 9848 this.child = null; 9849 this.sibling = null; 9850 this.index = 0; 9851 9852 this.ref = null; 9853 9854 this.pendingProps = pendingProps; 9855 this.memoizedProps = null; 9856 this.updateQueue = null; 9857 this.memoizedState = null; 9858 this.firstContextDependency = null; 9859 9860 this.mode = mode; 9861 9862 // Effects 9863 this.effectTag = NoEffect; 9864 this.nextEffect = null; 9865 9866 this.firstEffect = null; 9867 this.lastEffect = null; 9868 9869 this.expirationTime = NoWork; 9870 this.childExpirationTime = NoWork; 9871 9872 this.alternate = null; 9873 9874 if (enableProfilerTimer) { 9875 this.actualDuration = 0; 9876 this.actualStartTime = -1; 9877 this.selfBaseDuration = 0; 9878 this.treeBaseDuration = 0; 9879 } 9880 9881 { 9882 this._debugID = debugCounter++; 9883 this._debugSource = null; 9884 this._debugOwner = null; 9885 this._debugIsCurrentlyTiming = false; 9886 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') { 9887 Object.preventExtensions(this); 9888 } 9889 } 9890 } 9891 9892 // This is a constructor function, rather than a POJO constructor, still 9893 // please ensure we do the following: 9894 // 1) Nobody should add any instance methods on this. Instance methods can be 9895 // more difficult to predict when they get optimized and they are almost 9896 // never inlined properly in static compilers. 9897 // 2) Nobody should rely on `instanceof Fiber` for type testing. We should 9898 // always know when it is a fiber. 9899 // 3) We might want to experiment with using numeric keys since they are easier 9900 // to optimize in a non-JIT environment. 9901 // 4) We can easily go from a constructor to a createFiber object literal if that 9902 // is faster. 9903 // 5) It should be easy to port this to a C struct and keep a C implementation 9904 // compatible. 9905 var createFiber = function (tag, pendingProps, key, mode) { 9906 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors 9907 return new FiberNode(tag, pendingProps, key, mode); 9908 }; 9909 9910 function shouldConstruct(Component) { 9911 var prototype = Component.prototype; 9912 return !!(prototype && prototype.isReactComponent); 9913 } 9914 9915 function resolveLazyComponentTag(fiber, Component) { 9916 if (typeof Component === 'function') { 9917 return shouldConstruct(Component) ? ClassComponentLazy : FunctionalComponentLazy; 9918 } else if (Component !== undefined && Component !== null && Component.$$typeof) { 9919 return ForwardRefLazy; 9920 } 9921 return IndeterminateComponent; 9922 } 9923 9924 // This is used to create an alternate fiber to do work on. 9925 function createWorkInProgress(current, pendingProps, expirationTime) { 9926 var workInProgress = current.alternate; 9927 if (workInProgress === null) { 9928 // We use a double buffering pooling technique because we know that we'll 9929 // only ever need at most two versions of a tree. We pool the "other" unused 9930 // node that we're free to reuse. This is lazily created to avoid allocating 9931 // extra objects for things that are never updated. It also allow us to 9932 // reclaim the extra memory if needed. 9933 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode); 9934 workInProgress.type = current.type; 9935 workInProgress.stateNode = current.stateNode; 9936 9937 { 9938 // DEV-only fields 9939 workInProgress._debugID = current._debugID; 9940 workInProgress._debugSource = current._debugSource; 9941 workInProgress._debugOwner = current._debugOwner; 9942 } 9943 9944 workInProgress.alternate = current; 9945 current.alternate = workInProgress; 9946 } else { 9947 workInProgress.pendingProps = pendingProps; 9948 9949 // We already have an alternate. 9950 // Reset the effect tag. 9951 workInProgress.effectTag = NoEffect; 9952 9953 // The effect list is no longer valid. 9954 workInProgress.nextEffect = null; 9955 workInProgress.firstEffect = null; 9956 workInProgress.lastEffect = null; 9957 9958 if (enableProfilerTimer) { 9959 // We intentionally reset, rather than copy, actualDuration & actualStartTime. 9960 // This prevents time from endlessly accumulating in new commits. 9961 // This has the downside of resetting values for different priority renders, 9962 // But works for yielding (the common case) and should support resuming. 9963 workInProgress.actualDuration = 0; 9964 workInProgress.actualStartTime = -1; 9965 } 9966 } 9967 9968 // Don't touching the subtree's expiration time, which has not changed. 9969 workInProgress.childExpirationTime = current.childExpirationTime; 9970 if (pendingProps !== current.pendingProps) { 9971 // This fiber has new props. 9972 workInProgress.expirationTime = expirationTime; 9973 } else { 9974 // This fiber's props have not changed. 9975 workInProgress.expirationTime = current.expirationTime; 9976 } 9977 9978 workInProgress.child = current.child; 9979 workInProgress.memoizedProps = current.memoizedProps; 9980 workInProgress.memoizedState = current.memoizedState; 9981 workInProgress.updateQueue = current.updateQueue; 9982 workInProgress.firstContextDependency = current.firstContextDependency; 9983 9984 // These will be overridden during the parent's reconciliation 9985 workInProgress.sibling = current.sibling; 9986 workInProgress.index = current.index; 9987 workInProgress.ref = current.ref; 9988 9989 if (enableProfilerTimer) { 9990 workInProgress.selfBaseDuration = current.selfBaseDuration; 9991 workInProgress.treeBaseDuration = current.treeBaseDuration; 9992 } 9993 9994 return workInProgress; 9995 } 9996 9997 function createHostRootFiber(isAsync) { 9998 var mode = isAsync ? AsyncMode | StrictMode : NoContext; 9999 10000 if (enableProfilerTimer && isDevToolsPresent) { 10001 // Always collect profile timings when DevTools are present. 10002 // This enables DevTools to start capturing timing at any point– 10003 // Without some nodes in the tree having empty base times. 10004 mode |= ProfileMode; 10005 } 10006 10007 return createFiber(HostRoot, null, null, mode); 10008 } 10009 10010 function createFiberFromElement(element, mode, expirationTime) { 10011 var owner = null; 10012 { 10013 owner = element._owner; 10014 } 10015 10016 var fiber = void 0; 10017 var type = element.type; 10018 var key = element.key; 10019 var pendingProps = element.props; 10020 10021 var fiberTag = void 0; 10022 if (typeof type === 'function') { 10023 fiberTag = shouldConstruct(type) ? ClassComponent : IndeterminateComponent; 10024 } else if (typeof type === 'string') { 10025 fiberTag = HostComponent; 10026 } else { 10027 getTag: switch (type) { 10028 case REACT_FRAGMENT_TYPE: 10029 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key); 10030 case REACT_ASYNC_MODE_TYPE: 10031 fiberTag = Mode; 10032 mode |= AsyncMode | StrictMode; 10033 break; 10034 case REACT_STRICT_MODE_TYPE: 10035 fiberTag = Mode; 10036 mode |= StrictMode; 10037 break; 10038 case REACT_PROFILER_TYPE: 10039 return createFiberFromProfiler(pendingProps, mode, expirationTime, key); 10040 case REACT_PLACEHOLDER_TYPE: 10041 fiberTag = PlaceholderComponent; 10042 break; 10043 default: 10044 { 10045 if (typeof type === 'object' && type !== null) { 10046 switch (type.$$typeof) { 10047 case REACT_PROVIDER_TYPE: 10048 fiberTag = ContextProvider; 10049 break getTag; 10050 case REACT_CONTEXT_TYPE: 10051 // This is a consumer 10052 fiberTag = ContextConsumer; 10053 break getTag; 10054 case REACT_FORWARD_REF_TYPE: 10055 fiberTag = ForwardRef; 10056 break getTag; 10057 default: 10058 { 10059 if (typeof type.then === 'function') { 10060 fiberTag = IndeterminateComponent; 10061 break getTag; 10062 } 10063 } 10064 } 10065 } 10066 var info = ''; 10067 { 10068 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) { 10069 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.'; 10070 } 10071 var ownerName = owner ? getComponentName(owner.type) : null; 10072 if (ownerName) { 10073 info += '\n\nCheck the render method of `' + ownerName + '`.'; 10074 } 10075 } 10076 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); 10077 } 10078 } 10079 } 10080 10081 fiber = createFiber(fiberTag, pendingProps, key, mode); 10082 fiber.type = type; 10083 fiber.expirationTime = expirationTime; 10084 10085 { 10086 fiber._debugSource = element._source; 10087 fiber._debugOwner = element._owner; 10088 } 10089 10090 return fiber; 10091 } 10092 10093 function createFiberFromFragment(elements, mode, expirationTime, key) { 10094 var fiber = createFiber(Fragment, elements, key, mode); 10095 fiber.expirationTime = expirationTime; 10096 return fiber; 10097 } 10098 10099 function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { 10100 { 10101 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') { 10102 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props'); 10103 } 10104 } 10105 10106 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); 10107 fiber.type = REACT_PROFILER_TYPE; 10108 fiber.expirationTime = expirationTime; 10109 10110 return fiber; 10111 } 10112 10113 function createFiberFromText(content, mode, expirationTime) { 10114 var fiber = createFiber(HostText, content, null, mode); 10115 fiber.expirationTime = expirationTime; 10116 return fiber; 10117 } 10118 10119 function createFiberFromHostInstanceForDeletion() { 10120 var fiber = createFiber(HostComponent, null, null, NoContext); 10121 fiber.type = 'DELETED'; 10122 return fiber; 10123 } 10124 10125 function createFiberFromPortal(portal, mode, expirationTime) { 10126 var pendingProps = portal.children !== null ? portal.children : []; 10127 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode); 10128 fiber.expirationTime = expirationTime; 10129 fiber.stateNode = { 10130 containerInfo: portal.containerInfo, 10131 pendingChildren: null, // Used by persistent updates 10132 implementation: portal.implementation 10133 }; 10134 return fiber; 10135 } 10136 10137 // Used for stashing WIP properties to replay failed work in DEV. 10138 function assignFiberPropertiesInDEV(target, source) { 10139 if (target === null) { 10140 // This Fiber's initial properties will always be overwritten. 10141 // We only use a Fiber to ensure the same hidden class so DEV isn't slow. 10142 target = createFiber(IndeterminateComponent, null, null, NoContext); 10143 } 10144 10145 // This is intentionally written as a list of all properties. 10146 // We tried to use Object.assign() instead but this is called in 10147 // the hottest path, and Object.assign() was too slow: 10148 // https://github.com/facebook/react/issues/12502 10149 // This code is DEV-only so size is not a concern. 10150 10151 target.tag = source.tag; 10152 target.key = source.key; 10153 target.type = source.type; 10154 target.stateNode = source.stateNode; 10155 target.return = source.return; 10156 target.child = source.child; 10157 target.sibling = source.sibling; 10158 target.index = source.index; 10159 target.ref = source.ref; 10160 target.pendingProps = source.pendingProps; 10161 target.memoizedProps = source.memoizedProps; 10162 target.updateQueue = source.updateQueue; 10163 target.memoizedState = source.memoizedState; 10164 target.firstContextDependency = source.firstContextDependency; 10165 target.mode = source.mode; 10166 target.effectTag = source.effectTag; 10167 target.nextEffect = source.nextEffect; 10168 target.firstEffect = source.firstEffect; 10169 target.lastEffect = source.lastEffect; 10170 target.expirationTime = source.expirationTime; 10171 target.childExpirationTime = source.childExpirationTime; 10172 target.alternate = source.alternate; 10173 if (enableProfilerTimer) { 10174 target.actualDuration = source.actualDuration; 10175 target.actualStartTime = source.actualStartTime; 10176 target.selfBaseDuration = source.selfBaseDuration; 10177 target.treeBaseDuration = source.treeBaseDuration; 10178 } 10179 target._debugID = source._debugID; 10180 target._debugSource = source._debugSource; 10181 target._debugOwner = source._debugOwner; 10182 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; 10183 return target; 10184 } 10185 10186 var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; 10187 10188 var _ReactInternals$Sched$1 = ReactInternals$2.ScheduleTracing; 10189 var __interactionsRef = _ReactInternals$Sched$1.__interactionsRef; 10190 var __subscriberRef = _ReactInternals$Sched$1.__subscriberRef; 10191 var unstable_clear = _ReactInternals$Sched$1.unstable_clear; 10192 var unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent; 10193 var unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID; 10194 var unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe; 10195 var unstable_trace = _ReactInternals$Sched$1.unstable_trace; 10196 var unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe; 10197 var unstable_wrap = _ReactInternals$Sched$1.unstable_wrap; 10198 10199 /* eslint-disable no-use-before-define */ 10200 // TODO: This should be lifted into the renderer. 10201 10202 10203 // The following attributes are only used by interaction tracing builds. 10204 // They enable interactions to be associated with their async work, 10205 // And expose interaction metadata to the React DevTools Profiler plugin. 10206 // Note that these attributes are only defined when the enableSchedulerTracing flag is enabled. 10207 10208 10209 // Exported FiberRoot type includes all properties, 10210 // To avoid requiring potentially error-prone :any casts throughout the project. 10211 // Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true). 10212 // The types are defined separately within this file to ensure they stay in sync. 10213 // (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.) 10214 10215 /* eslint-enable no-use-before-define */ 10216 10217 function createFiberRoot(containerInfo, isAsync, hydrate) { 10218 // Cyclic construction. This cheats the type system right now because 10219 // stateNode is any. 10220 var uninitializedFiber = createHostRootFiber(isAsync); 10221 10222 var root = void 0; 10223 if (enableSchedulerTracing) { 10224 root = { 10225 current: uninitializedFiber, 10226 containerInfo: containerInfo, 10227 pendingChildren: null, 10228 10229 earliestPendingTime: NoWork, 10230 latestPendingTime: NoWork, 10231 earliestSuspendedTime: NoWork, 10232 latestSuspendedTime: NoWork, 10233 latestPingedTime: NoWork, 10234 10235 didError: false, 10236 10237 pendingCommitExpirationTime: NoWork, 10238 finishedWork: null, 10239 timeoutHandle: noTimeout, 10240 context: null, 10241 pendingContext: null, 10242 hydrate: hydrate, 10243 nextExpirationTimeToWorkOn: NoWork, 10244 expirationTime: NoWork, 10245 firstBatch: null, 10246 nextScheduledRoot: null, 10247 10248 interactionThreadID: unstable_getThreadID(), 10249 memoizedInteractions: new Set(), 10250 pendingInteractionMap: new Map() 10251 }; 10252 } else { 10253 root = { 10254 current: uninitializedFiber, 10255 containerInfo: containerInfo, 10256 pendingChildren: null, 10257 10258 earliestPendingTime: NoWork, 10259 latestPendingTime: NoWork, 10260 earliestSuspendedTime: NoWork, 10261 latestSuspendedTime: NoWork, 10262 latestPingedTime: NoWork, 10263 10264 didError: false, 10265 10266 pendingCommitExpirationTime: NoWork, 10267 finishedWork: null, 10268 timeoutHandle: noTimeout, 10269 context: null, 10270 pendingContext: null, 10271 hydrate: hydrate, 10272 nextExpirationTimeToWorkOn: NoWork, 10273 expirationTime: NoWork, 10274 firstBatch: null, 10275 nextScheduledRoot: null 10276 }; 10277 } 10278 10279 uninitializedFiber.stateNode = root; 10280 10281 // The reason for the way the Flow types are structured in this file, 10282 // Is to avoid needing :any casts everywhere interaction tracing fields are used. 10283 // Unfortunately that requires an :any cast for non-interaction tracing capable builds. 10284 // $FlowFixMe Remove this :any cast and replace it with something better. 10285 return root; 10286 } 10287 10288 /** 10289 * Forked from fbjs/warning: 10290 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js 10291 * 10292 * Only change is we use console.warn instead of console.error, 10293 * and do nothing when 'console' is not supported. 10294 * This really simplifies the code. 10295 * --- 10296 * Similar to invariant but only logs a warning if the condition is not met. 10297 * This can be used to log issues in development environments in critical 10298 * paths. Removing the logging code for production environments will keep the 10299 * same logic and follow the same code paths. 10300 */ 10301 10302 var lowPriorityWarning = function () {}; 10303 10304 { 10305 var printWarning$1 = function (format) { 10306 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 10307 args[_key - 1] = arguments[_key]; 10308 } 10309 10310 var argIndex = 0; 10311 var message = 'Warning: ' + format.replace(/%s/g, function () { 10312 return args[argIndex++]; 10313 }); 10314 if (typeof console !== 'undefined') { 10315 console.warn(message); 10316 } 10317 try { 10318 // --- Welcome to debugging React --- 10319 // This error was thrown as a convenience so that you can use this stack 10320 // to find the callsite that caused this warning to fire. 10321 throw new Error(message); 10322 } catch (x) {} 10323 }; 10324 10325 lowPriorityWarning = function (condition, format) { 10326 if (format === undefined) { 10327 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument'); 10328 } 10329 if (!condition) { 10330 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { 10331 args[_key2 - 2] = arguments[_key2]; 10332 } 10333 10334 printWarning$1.apply(undefined, [format].concat(args)); 10335 } 10336 }; 10337 } 10338 10339 var lowPriorityWarning$1 = lowPriorityWarning; 10340 10341 var ReactStrictModeWarnings = { 10342 discardPendingWarnings: function () {}, 10343 flushPendingDeprecationWarnings: function () {}, 10344 flushPendingUnsafeLifecycleWarnings: function () {}, 10345 recordDeprecationWarnings: function (fiber, instance) {}, 10346 recordUnsafeLifecycleWarnings: function (fiber, instance) {}, 10347 recordLegacyContextWarning: function (fiber, instance) {}, 10348 flushLegacyContextWarning: function () {} 10349 }; 10350 10351 { 10352 var LIFECYCLE_SUGGESTIONS = { 10353 UNSAFE_componentWillMount: 'componentDidMount', 10354 UNSAFE_componentWillReceiveProps: 'static getDerivedStateFromProps', 10355 UNSAFE_componentWillUpdate: 'componentDidUpdate' 10356 }; 10357 10358 var pendingComponentWillMountWarnings = []; 10359 var pendingComponentWillReceivePropsWarnings = []; 10360 var pendingComponentWillUpdateWarnings = []; 10361 var pendingUnsafeLifecycleWarnings = new Map(); 10362 var pendingLegacyContextWarning = new Map(); 10363 10364 // Tracks components we have already warned about. 10365 var didWarnAboutDeprecatedLifecycles = new Set(); 10366 var didWarnAboutUnsafeLifecycles = new Set(); 10367 var didWarnAboutLegacyContext = new Set(); 10368 10369 var setToSortedString = function (set) { 10370 var array = []; 10371 set.forEach(function (value) { 10372 array.push(value); 10373 }); 10374 return array.sort().join(', '); 10375 }; 10376 10377 ReactStrictModeWarnings.discardPendingWarnings = function () { 10378 pendingComponentWillMountWarnings = []; 10379 pendingComponentWillReceivePropsWarnings = []; 10380 pendingComponentWillUpdateWarnings = []; 10381 pendingUnsafeLifecycleWarnings = new Map(); 10382 pendingLegacyContextWarning = new Map(); 10383 }; 10384 10385 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () { 10386 pendingUnsafeLifecycleWarnings.forEach(function (lifecycleWarningsMap, strictRoot) { 10387 var lifecyclesWarningMesages = []; 10388 10389 Object.keys(lifecycleWarningsMap).forEach(function (lifecycle) { 10390 var lifecycleWarnings = lifecycleWarningsMap[lifecycle]; 10391 if (lifecycleWarnings.length > 0) { 10392 var componentNames = new Set(); 10393 lifecycleWarnings.forEach(function (fiber) { 10394 componentNames.add(getComponentName(fiber.type) || 'Component'); 10395 didWarnAboutUnsafeLifecycles.add(fiber.type); 10396 }); 10397 10398 var formatted = lifecycle.replace('UNSAFE_', ''); 10399 var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle]; 10400 var sortedComponentNames = setToSortedString(componentNames); 10401 10402 lifecyclesWarningMesages.push(formatted + ': Please update the following components to use ' + (suggestion + ' instead: ' + sortedComponentNames)); 10403 } 10404 }); 10405 10406 if (lifecyclesWarningMesages.length > 0) { 10407 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); 10408 10409 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, lifecyclesWarningMesages.join('\n\n')); 10410 } 10411 }); 10412 10413 pendingUnsafeLifecycleWarnings = new Map(); 10414 }; 10415 10416 var findStrictRoot = function (fiber) { 10417 var maybeStrictRoot = null; 10418 10419 var node = fiber; 10420 while (node !== null) { 10421 if (node.mode & StrictMode) { 10422 maybeStrictRoot = node; 10423 } 10424 node = node.return; 10425 } 10426 10427 return maybeStrictRoot; 10428 }; 10429 10430 ReactStrictModeWarnings.flushPendingDeprecationWarnings = function () { 10431 if (pendingComponentWillMountWarnings.length > 0) { 10432 var uniqueNames = new Set(); 10433 pendingComponentWillMountWarnings.forEach(function (fiber) { 10434 uniqueNames.add(getComponentName(fiber.type) || 'Component'); 10435 didWarnAboutDeprecatedLifecycles.add(fiber.type); 10436 }); 10437 10438 var sortedNames = setToSortedString(uniqueNames); 10439 10440 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); 10441 10442 pendingComponentWillMountWarnings = []; 10443 } 10444 10445 if (pendingComponentWillReceivePropsWarnings.length > 0) { 10446 var _uniqueNames = new Set(); 10447 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) { 10448 _uniqueNames.add(getComponentName(fiber.type) || 'Component'); 10449 didWarnAboutDeprecatedLifecycles.add(fiber.type); 10450 }); 10451 10452 var _sortedNames = setToSortedString(_uniqueNames); 10453 10454 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); 10455 10456 pendingComponentWillReceivePropsWarnings = []; 10457 } 10458 10459 if (pendingComponentWillUpdateWarnings.length > 0) { 10460 var _uniqueNames2 = new Set(); 10461 pendingComponentWillUpdateWarnings.forEach(function (fiber) { 10462 _uniqueNames2.add(getComponentName(fiber.type) || 'Component'); 10463 didWarnAboutDeprecatedLifecycles.add(fiber.type); 10464 }); 10465 10466 var _sortedNames2 = setToSortedString(_uniqueNames2); 10467 10468 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); 10469 10470 pendingComponentWillUpdateWarnings = []; 10471 } 10472 }; 10473 10474 ReactStrictModeWarnings.recordDeprecationWarnings = function (fiber, instance) { 10475 // Dedup strategy: Warn once per component. 10476 if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) { 10477 return; 10478 } 10479 10480 // Don't warn about react-lifecycles-compat polyfilled components. 10481 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) { 10482 pendingComponentWillMountWarnings.push(fiber); 10483 } 10484 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) { 10485 pendingComponentWillReceivePropsWarnings.push(fiber); 10486 } 10487 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) { 10488 pendingComponentWillUpdateWarnings.push(fiber); 10489 } 10490 }; 10491 10492 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) { 10493 var strictRoot = findStrictRoot(fiber); 10494 if (strictRoot === null) { 10495 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.'); 10496 return; 10497 } 10498 10499 // Dedup strategy: Warn once per component. 10500 // This is difficult to track any other way since component names 10501 // are often vague and are likely to collide between 3rd party libraries. 10502 // An expand property is probably okay to use here since it's DEV-only, 10503 // and will only be set in the event of serious warnings. 10504 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { 10505 return; 10506 } 10507 10508 var warningsForRoot = void 0; 10509 if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) { 10510 warningsForRoot = { 10511 UNSAFE_componentWillMount: [], 10512 UNSAFE_componentWillReceiveProps: [], 10513 UNSAFE_componentWillUpdate: [] 10514 }; 10515 10516 pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot); 10517 } else { 10518 warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot); 10519 } 10520 10521 var unsafeLifecycles = []; 10522 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillMount === 'function') { 10523 unsafeLifecycles.push('UNSAFE_componentWillMount'); 10524 } 10525 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillReceiveProps === 'function') { 10526 unsafeLifecycles.push('UNSAFE_componentWillReceiveProps'); 10527 } 10528 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillUpdate === 'function') { 10529 unsafeLifecycles.push('UNSAFE_componentWillUpdate'); 10530 } 10531 10532 if (unsafeLifecycles.length > 0) { 10533 unsafeLifecycles.forEach(function (lifecycle) { 10534 warningsForRoot[lifecycle].push(fiber); 10535 }); 10536 } 10537 }; 10538 10539 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) { 10540 var strictRoot = findStrictRoot(fiber); 10541 if (strictRoot === null) { 10542 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.'); 10543 return; 10544 } 10545 10546 // Dedup strategy: Warn once per component. 10547 if (didWarnAboutLegacyContext.has(fiber.type)) { 10548 return; 10549 } 10550 10551 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot); 10552 10553 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') { 10554 if (warningsForRoot === undefined) { 10555 warningsForRoot = []; 10556 pendingLegacyContextWarning.set(strictRoot, warningsForRoot); 10557 } 10558 warningsForRoot.push(fiber); 10559 } 10560 }; 10561 10562 ReactStrictModeWarnings.flushLegacyContextWarning = function () { 10563 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) { 10564 var uniqueNames = new Set(); 10565 fiberArray.forEach(function (fiber) { 10566 uniqueNames.add(getComponentName(fiber.type) || 'Component'); 10567 didWarnAboutLegacyContext.add(fiber.type); 10568 }); 10569 10570 var sortedNames = setToSortedString(uniqueNames); 10571 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); 10572 10573 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); 10574 }); 10575 }; 10576 } 10577 10578 // This lets us hook into Fiber to debug what it's doing. 10579 // See https://github.com/facebook/react/pull/8033. 10580 // This is not part of the public API, not even for React DevTools. 10581 // You may only inject a debugTool if you work on React Fiber itself. 10582 var ReactFiberInstrumentation = { 10583 debugTool: null 10584 }; 10585 10586 var ReactFiberInstrumentation_1 = ReactFiberInstrumentation; 10587 10588 // TODO: Offscreen updates should never suspend. However, a promise that 10589 // suspended inside an offscreen subtree should be able to ping at the priority 10590 // of the outer render. 10591 10592 function markPendingPriorityLevel(root, expirationTime) { 10593 // If there's a gap between completing a failed root and retrying it, 10594 // additional updates may be scheduled. Clear `didError`, in case the update 10595 // is sufficient to fix the error. 10596 root.didError = false; 10597 10598 // Update the latest and earliest pending times 10599 var earliestPendingTime = root.earliestPendingTime; 10600 if (earliestPendingTime === NoWork) { 10601 // No other pending updates. 10602 root.earliestPendingTime = root.latestPendingTime = expirationTime; 10603 } else { 10604 if (earliestPendingTime > expirationTime) { 10605 // This is the earliest pending update. 10606 root.earliestPendingTime = expirationTime; 10607 } else { 10608 var latestPendingTime = root.latestPendingTime; 10609 if (latestPendingTime < expirationTime) { 10610 // This is the latest pending update 10611 root.latestPendingTime = expirationTime; 10612 } 10613 } 10614 } 10615 findNextExpirationTimeToWorkOn(expirationTime, root); 10616 } 10617 10618 function markCommittedPriorityLevels(root, earliestRemainingTime) { 10619 root.didError = false; 10620 10621 if (earliestRemainingTime === NoWork) { 10622 // Fast path. There's no remaining work. Clear everything. 10623 root.earliestPendingTime = NoWork; 10624 root.latestPendingTime = NoWork; 10625 root.earliestSuspendedTime = NoWork; 10626 root.latestSuspendedTime = NoWork; 10627 root.latestPingedTime = NoWork; 10628 findNextExpirationTimeToWorkOn(NoWork, root); 10629 return; 10630 } 10631 10632 // Let's see if the previous latest known pending level was just flushed. 10633 var latestPendingTime = root.latestPendingTime; 10634 if (latestPendingTime !== NoWork) { 10635 if (latestPendingTime < earliestRemainingTime) { 10636 // We've flushed all the known pending levels. 10637 root.earliestPendingTime = root.latestPendingTime = NoWork; 10638 } else { 10639 var earliestPendingTime = root.earliestPendingTime; 10640 if (earliestPendingTime < earliestRemainingTime) { 10641 // We've flushed the earliest known pending level. Set this to the 10642 // latest pending time. 10643 root.earliestPendingTime = root.latestPendingTime; 10644 } 10645 } 10646 } 10647 10648 // Now let's handle the earliest remaining level in the whole tree. We need to 10649 // decide whether to treat it as a pending level or as suspended. Check 10650 // it falls within the range of known suspended levels. 10651 10652 var earliestSuspendedTime = root.earliestSuspendedTime; 10653 if (earliestSuspendedTime === NoWork) { 10654 // There's no suspended work. Treat the earliest remaining level as a 10655 // pending level. 10656 markPendingPriorityLevel(root, earliestRemainingTime); 10657 findNextExpirationTimeToWorkOn(NoWork, root); 10658 return; 10659 } 10660 10661 var latestSuspendedTime = root.latestSuspendedTime; 10662 if (earliestRemainingTime > latestSuspendedTime) { 10663 // The earliest remaining level is later than all the suspended work. That 10664 // means we've flushed all the suspended work. 10665 root.earliestSuspendedTime = NoWork; 10666 root.latestSuspendedTime = NoWork; 10667 root.latestPingedTime = NoWork; 10668 10669 // There's no suspended work. Treat the earliest remaining level as a 10670 // pending level. 10671 markPendingPriorityLevel(root, earliestRemainingTime); 10672 findNextExpirationTimeToWorkOn(NoWork, root); 10673 return; 10674 } 10675 10676 if (earliestRemainingTime < earliestSuspendedTime) { 10677 // The earliest remaining time is earlier than all the suspended work. 10678 // Treat it as a pending update. 10679 markPendingPriorityLevel(root, earliestRemainingTime); 10680 findNextExpirationTimeToWorkOn(NoWork, root); 10681 return; 10682 } 10683 10684 // The earliest remaining time falls within the range of known suspended 10685 // levels. We should treat this as suspended work. 10686 findNextExpirationTimeToWorkOn(NoWork, root); 10687 } 10688 10689 function hasLowerPriorityWork(root, erroredExpirationTime) { 10690 var latestPendingTime = root.latestPendingTime; 10691 var latestSuspendedTime = root.latestSuspendedTime; 10692 var latestPingedTime = root.latestPingedTime; 10693 return latestPendingTime !== NoWork && latestPendingTime > erroredExpirationTime || latestSuspendedTime !== NoWork && latestSuspendedTime > erroredExpirationTime || latestPingedTime !== NoWork && latestPingedTime > erroredExpirationTime; 10694 } 10695 10696 function isPriorityLevelSuspended(root, expirationTime) { 10697 var earliestSuspendedTime = root.earliestSuspendedTime; 10698 var latestSuspendedTime = root.latestSuspendedTime; 10699 return earliestSuspendedTime !== NoWork && expirationTime >= earliestSuspendedTime && expirationTime <= latestSuspendedTime; 10700 } 10701 10702 function markSuspendedPriorityLevel(root, suspendedTime) { 10703 root.didError = false; 10704 clearPing(root, suspendedTime); 10705 10706 // First, check the known pending levels and update them if needed. 10707 var earliestPendingTime = root.earliestPendingTime; 10708 var latestPendingTime = root.latestPendingTime; 10709 if (earliestPendingTime === suspendedTime) { 10710 if (latestPendingTime === suspendedTime) { 10711 // Both known pending levels were suspended. Clear them. 10712 root.earliestPendingTime = root.latestPendingTime = NoWork; 10713 } else { 10714 // The earliest pending level was suspended. Clear by setting it to the 10715 // latest pending level. 10716 root.earliestPendingTime = latestPendingTime; 10717 } 10718 } else if (latestPendingTime === suspendedTime) { 10719 // The latest pending level was suspended. Clear by setting it to the 10720 // latest pending level. 10721 root.latestPendingTime = earliestPendingTime; 10722 } 10723 10724 // Finally, update the known suspended levels. 10725 var earliestSuspendedTime = root.earliestSuspendedTime; 10726 var latestSuspendedTime = root.latestSuspendedTime; 10727 if (earliestSuspendedTime === NoWork) { 10728 // No other suspended levels. 10729 root.earliestSuspendedTime = root.latestSuspendedTime = suspendedTime; 10730 } else { 10731 if (earliestSuspendedTime > suspendedTime) { 10732 // This is the earliest suspended level. 10733 root.earliestSuspendedTime = suspendedTime; 10734 } else if (latestSuspendedTime < suspendedTime) { 10735 // This is the latest suspended level 10736 root.latestSuspendedTime = suspendedTime; 10737 } 10738 } 10739 10740 findNextExpirationTimeToWorkOn(suspendedTime, root); 10741 } 10742 10743 function markPingedPriorityLevel(root, pingedTime) { 10744 root.didError = false; 10745 10746 // TODO: When we add back resuming, we need to ensure the progressed work 10747 // is thrown out and not reused during the restarted render. One way to 10748 // invalidate the progressed work is to restart at expirationTime + 1. 10749 var latestPingedTime = root.latestPingedTime; 10750 if (latestPingedTime === NoWork || latestPingedTime < pingedTime) { 10751 root.latestPingedTime = pingedTime; 10752 } 10753 findNextExpirationTimeToWorkOn(pingedTime, root); 10754 } 10755 10756 function clearPing(root, completedTime) { 10757 // TODO: Track whether the root was pinged during the render phase. If so, 10758 // we need to make sure we don't lose track of it. 10759 var latestPingedTime = root.latestPingedTime; 10760 if (latestPingedTime !== NoWork && latestPingedTime <= completedTime) { 10761 root.latestPingedTime = NoWork; 10762 } 10763 } 10764 10765 function findEarliestOutstandingPriorityLevel(root, renderExpirationTime) { 10766 var earliestExpirationTime = renderExpirationTime; 10767 10768 var earliestPendingTime = root.earliestPendingTime; 10769 var earliestSuspendedTime = root.earliestSuspendedTime; 10770 if (earliestExpirationTime === NoWork || earliestPendingTime !== NoWork && earliestPendingTime < earliestExpirationTime) { 10771 earliestExpirationTime = earliestPendingTime; 10772 } 10773 if (earliestExpirationTime === NoWork || earliestSuspendedTime !== NoWork && earliestSuspendedTime < earliestExpirationTime) { 10774 earliestExpirationTime = earliestSuspendedTime; 10775 } 10776 return earliestExpirationTime; 10777 } 10778 10779 function didExpireAtExpirationTime(root, currentTime) { 10780 var expirationTime = root.expirationTime; 10781 if (expirationTime !== NoWork && currentTime >= expirationTime) { 10782 // The root has expired. Flush all work up to the current time. 10783 root.nextExpirationTimeToWorkOn = currentTime; 10784 } 10785 } 10786 10787 function findNextExpirationTimeToWorkOn(completedExpirationTime, root) { 10788 var earliestSuspendedTime = root.earliestSuspendedTime; 10789 var latestSuspendedTime = root.latestSuspendedTime; 10790 var earliestPendingTime = root.earliestPendingTime; 10791 var latestPingedTime = root.latestPingedTime; 10792 10793 // Work on the earliest pending time. Failing that, work on the latest 10794 // pinged time. 10795 var nextExpirationTimeToWorkOn = earliestPendingTime !== NoWork ? earliestPendingTime : latestPingedTime; 10796 10797 // If there is no pending or pinged work, check if there's suspended work 10798 // that's lower priority than what we just completed. 10799 if (nextExpirationTimeToWorkOn === NoWork && (completedExpirationTime === NoWork || latestSuspendedTime > completedExpirationTime)) { 10800 // The lowest priority suspended work is the work most likely to be 10801 // committed next. Let's start rendering it again, so that if it times out, 10802 // it's ready to commit. 10803 nextExpirationTimeToWorkOn = latestSuspendedTime; 10804 } 10805 10806 var expirationTime = nextExpirationTimeToWorkOn; 10807 if (expirationTime !== NoWork && earliestSuspendedTime !== NoWork && earliestSuspendedTime < expirationTime) { 10808 // Expire using the earliest known expiration time. 10809 expirationTime = earliestSuspendedTime; 10810 } 10811 10812 root.nextExpirationTimeToWorkOn = nextExpirationTimeToWorkOn; 10813 root.expirationTime = expirationTime; 10814 } 10815 10816 // UpdateQueue is a linked list of prioritized updates. 10817 // 10818 // Like fibers, update queues come in pairs: a current queue, which represents 10819 // the visible state of the screen, and a work-in-progress queue, which is 10820 // can be mutated and processed asynchronously before it is committed — a form 10821 // of double buffering. If a work-in-progress render is discarded before 10822 // finishing, we create a new work-in-progress by cloning the current queue. 10823 // 10824 // Both queues share a persistent, singly-linked list structure. To schedule an 10825 // update, we append it to the end of both queues. Each queue maintains a 10826 // pointer to first update in the persistent list that hasn't been processed. 10827 // The work-in-progress pointer always has a position equal to or greater than 10828 // the current queue, since we always work on that one. The current queue's 10829 // pointer is only updated during the commit phase, when we swap in the 10830 // work-in-progress. 10831 // 10832 // For example: 10833 // 10834 // Current pointer: A - B - C - D - E - F 10835 // Work-in-progress pointer: D - E - F 10836 // ^ 10837 // The work-in-progress queue has 10838 // processed more updates than current. 10839 // 10840 // The reason we append to both queues is because otherwise we might drop 10841 // updates without ever processing them. For example, if we only add updates to 10842 // the work-in-progress queue, some updates could be lost whenever a work-in 10843 // -progress render restarts by cloning from current. Similarly, if we only add 10844 // updates to the current queue, the updates will be lost whenever an already 10845 // in-progress queue commits and swaps with the current queue. However, by 10846 // adding to both queues, we guarantee that the update will be part of the next 10847 // work-in-progress. (And because the work-in-progress queue becomes the 10848 // current queue once it commits, there's no danger of applying the same 10849 // update twice.) 10850 // 10851 // Prioritization 10852 // -------------- 10853 // 10854 // Updates are not sorted by priority, but by insertion; new updates are always 10855 // appended to the end of the list. 10856 // 10857 // The priority is still important, though. When processing the update queue 10858 // during the render phase, only the updates with sufficient priority are 10859 // included in the result. If we skip an update because it has insufficient 10860 // priority, it remains in the queue to be processed later, during a lower 10861 // priority render. Crucially, all updates subsequent to a skipped update also 10862 // remain in the queue *regardless of their priority*. That means high priority 10863 // updates are sometimes processed twice, at two separate priorities. We also 10864 // keep track of a base state, that represents the state before the first 10865 // update in the queue is applied. 10866 // 10867 // For example: 10868 // 10869 // Given a base state of '', and the following queue of updates 10870 // 10871 // A1 - B2 - C1 - D2 10872 // 10873 // where the number indicates the priority, and the update is applied to the 10874 // previous state by appending a letter, React will process these updates as 10875 // two separate renders, one per distinct priority level: 10876 // 10877 // First render, at priority 1: 10878 // Base state: '' 10879 // Updates: [A1, C1] 10880 // Result state: 'AC' 10881 // 10882 // Second render, at priority 2: 10883 // Base state: 'A' <- The base state does not include C1, 10884 // because B2 was skipped. 10885 // Updates: [B2, C1, D2] <- C1 was rebased on top of B2 10886 // Result state: 'ABCD' 10887 // 10888 // Because we process updates in insertion order, and rebase high priority 10889 // updates when preceding updates are skipped, the final result is deterministic 10890 // regardless of priority. Intermediate state may vary according to system 10891 // resources, but the final state is always the same. 10892 10893 var UpdateState = 0; 10894 var ReplaceState = 1; 10895 var ForceUpdate = 2; 10896 var CaptureUpdate = 3; 10897 10898 // Global state that is reset at the beginning of calling `processUpdateQueue`. 10899 // It should only be read right after calling `processUpdateQueue`, via 10900 // `checkHasForceUpdateAfterProcessing`. 10901 var hasForceUpdate = false; 10902 10903 var didWarnUpdateInsideUpdate = void 0; 10904 var currentlyProcessingQueue = void 0; 10905 var resetCurrentlyProcessingQueue = void 0; 10906 { 10907 didWarnUpdateInsideUpdate = false; 10908 currentlyProcessingQueue = null; 10909 resetCurrentlyProcessingQueue = function () { 10910 currentlyProcessingQueue = null; 10911 }; 10912 } 10913 10914 function createUpdateQueue(baseState) { 10915 var queue = { 10916 baseState: baseState, 10917 firstUpdate: null, 10918 lastUpdate: null, 10919 firstCapturedUpdate: null, 10920 lastCapturedUpdate: null, 10921 firstEffect: null, 10922 lastEffect: null, 10923 firstCapturedEffect: null, 10924 lastCapturedEffect: null 10925 }; 10926 return queue; 10927 } 10928 10929 function cloneUpdateQueue(currentQueue) { 10930 var queue = { 10931 baseState: currentQueue.baseState, 10932 firstUpdate: currentQueue.firstUpdate, 10933 lastUpdate: currentQueue.lastUpdate, 10934 10935 // TODO: With resuming, if we bail out and resuse the child tree, we should 10936 // keep these effects. 10937 firstCapturedUpdate: null, 10938 lastCapturedUpdate: null, 10939 10940 firstEffect: null, 10941 lastEffect: null, 10942 10943 firstCapturedEffect: null, 10944 lastCapturedEffect: null 10945 }; 10946 return queue; 10947 } 10948 10949 function createUpdate(expirationTime) { 10950 return { 10951 expirationTime: expirationTime, 10952 10953 tag: UpdateState, 10954 payload: null, 10955 callback: null, 10956 10957 next: null, 10958 nextEffect: null 10959 }; 10960 } 10961 10962 function appendUpdateToQueue(queue, update) { 10963 // Append the update to the end of the list. 10964 if (queue.lastUpdate === null) { 10965 // Queue is empty 10966 queue.firstUpdate = queue.lastUpdate = update; 10967 } else { 10968 queue.lastUpdate.next = update; 10969 queue.lastUpdate = update; 10970 } 10971 } 10972 10973 function enqueueUpdate(fiber, update) { 10974 // Update queues are created lazily. 10975 var alternate = fiber.alternate; 10976 var queue1 = void 0; 10977 var queue2 = void 0; 10978 if (alternate === null) { 10979 // There's only one fiber. 10980 queue1 = fiber.updateQueue; 10981 queue2 = null; 10982 if (queue1 === null) { 10983 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); 10984 } 10985 } else { 10986 // There are two owners. 10987 queue1 = fiber.updateQueue; 10988 queue2 = alternate.updateQueue; 10989 if (queue1 === null) { 10990 if (queue2 === null) { 10991 // Neither fiber has an update queue. Create new ones. 10992 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); 10993 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState); 10994 } else { 10995 // Only one fiber has an update queue. Clone to create a new one. 10996 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2); 10997 } 10998 } else { 10999 if (queue2 === null) { 11000 // Only one fiber has an update queue. Clone to create a new one. 11001 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1); 11002 } else { 11003 // Both owners have an update queue. 11004 } 11005 } 11006 } 11007 if (queue2 === null || queue1 === queue2) { 11008 // There's only a single queue. 11009 appendUpdateToQueue(queue1, update); 11010 } else { 11011 // There are two queues. We need to append the update to both queues, 11012 // while accounting for the persistent structure of the list — we don't 11013 // want the same update to be added multiple times. 11014 if (queue1.lastUpdate === null || queue2.lastUpdate === null) { 11015 // One of the queues is not empty. We must add the update to both queues. 11016 appendUpdateToQueue(queue1, update); 11017 appendUpdateToQueue(queue2, update); 11018 } else { 11019 // Both queues are non-empty. The last update is the same in both lists, 11020 // because of structural sharing. So, only append to one of the lists. 11021 appendUpdateToQueue(queue1, update); 11022 // But we still need to update the `lastUpdate` pointer of queue2. 11023 queue2.lastUpdate = update; 11024 } 11025 } 11026 11027 { 11028 if ((fiber.tag === ClassComponent || fiber.tag === ClassComponentLazy) && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) { 11029 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.'); 11030 didWarnUpdateInsideUpdate = true; 11031 } 11032 } 11033 } 11034 11035 function enqueueCapturedUpdate(workInProgress, update) { 11036 // Captured updates go into a separate list, and only on the work-in- 11037 // progress queue. 11038 var workInProgressQueue = workInProgress.updateQueue; 11039 if (workInProgressQueue === null) { 11040 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState); 11041 } else { 11042 // TODO: I put this here rather than createWorkInProgress so that we don't 11043 // clone the queue unnecessarily. There's probably a better way to 11044 // structure this. 11045 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); 11046 } 11047 11048 // Append the update to the end of the list. 11049 if (workInProgressQueue.lastCapturedUpdate === null) { 11050 // This is the first render phase update 11051 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update; 11052 } else { 11053 workInProgressQueue.lastCapturedUpdate.next = update; 11054 workInProgressQueue.lastCapturedUpdate = update; 11055 } 11056 } 11057 11058 function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { 11059 var current = workInProgress.alternate; 11060 if (current !== null) { 11061 // If the work-in-progress queue is equal to the current queue, 11062 // we need to clone it first. 11063 if (queue === current.updateQueue) { 11064 queue = workInProgress.updateQueue = cloneUpdateQueue(queue); 11065 } 11066 } 11067 return queue; 11068 } 11069 11070 function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) { 11071 switch (update.tag) { 11072 case ReplaceState: 11073 { 11074 var _payload = update.payload; 11075 if (typeof _payload === 'function') { 11076 // Updater function 11077 { 11078 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) { 11079 _payload.call(instance, prevState, nextProps); 11080 } 11081 } 11082 return _payload.call(instance, prevState, nextProps); 11083 } 11084 // State object 11085 return _payload; 11086 } 11087 case CaptureUpdate: 11088 { 11089 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture; 11090 } 11091 // Intentional fallthrough 11092 case UpdateState: 11093 { 11094 var _payload2 = update.payload; 11095 var partialState = void 0; 11096 if (typeof _payload2 === 'function') { 11097 // Updater function 11098 { 11099 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) { 11100 _payload2.call(instance, prevState, nextProps); 11101 } 11102 } 11103 partialState = _payload2.call(instance, prevState, nextProps); 11104 } else { 11105 // Partial state object 11106 partialState = _payload2; 11107 } 11108 if (partialState === null || partialState === undefined) { 11109 // Null and undefined are treated as no-ops. 11110 return prevState; 11111 } 11112 // Merge the partial state and the previous state. 11113 return _assign({}, prevState, partialState); 11114 } 11115 case ForceUpdate: 11116 { 11117 hasForceUpdate = true; 11118 return prevState; 11119 } 11120 } 11121 return prevState; 11122 } 11123 11124 function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) { 11125 hasForceUpdate = false; 11126 11127 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); 11128 11129 { 11130 currentlyProcessingQueue = queue; 11131 } 11132 11133 // These values may change as we process the queue. 11134 var newBaseState = queue.baseState; 11135 var newFirstUpdate = null; 11136 var newExpirationTime = NoWork; 11137 11138 // Iterate through the list of updates to compute the result. 11139 var update = queue.firstUpdate; 11140 var resultState = newBaseState; 11141 while (update !== null) { 11142 var updateExpirationTime = update.expirationTime; 11143 if (updateExpirationTime > renderExpirationTime) { 11144 // This update does not have sufficient priority. Skip it. 11145 if (newFirstUpdate === null) { 11146 // This is the first skipped update. It will be the first update in 11147 // the new list. 11148 newFirstUpdate = update; 11149 // Since this is the first update that was skipped, the current result 11150 // is the new base state. 11151 newBaseState = resultState; 11152 } 11153 // Since this update will remain in the list, update the remaining 11154 // expiration time. 11155 if (newExpirationTime === NoWork || newExpirationTime > updateExpirationTime) { 11156 newExpirationTime = updateExpirationTime; 11157 } 11158 } else { 11159 // This update does have sufficient priority. Process it and compute 11160 // a new result. 11161 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance); 11162 var _callback = update.callback; 11163 if (_callback !== null) { 11164 workInProgress.effectTag |= Callback; 11165 // Set this to null, in case it was mutated during an aborted render. 11166 update.nextEffect = null; 11167 if (queue.lastEffect === null) { 11168 queue.firstEffect = queue.lastEffect = update; 11169 } else { 11170 queue.lastEffect.nextEffect = update; 11171 queue.lastEffect = update; 11172 } 11173 } 11174 } 11175 // Continue to the next update. 11176 update = update.next; 11177 } 11178 11179 // Separately, iterate though the list of captured updates. 11180 var newFirstCapturedUpdate = null; 11181 update = queue.firstCapturedUpdate; 11182 while (update !== null) { 11183 var _updateExpirationTime = update.expirationTime; 11184 if (_updateExpirationTime > renderExpirationTime) { 11185 // This update does not have sufficient priority. Skip it. 11186 if (newFirstCapturedUpdate === null) { 11187 // This is the first skipped captured update. It will be the first 11188 // update in the new list. 11189 newFirstCapturedUpdate = update; 11190 // If this is the first update that was skipped, the current result is 11191 // the new base state. 11192 if (newFirstUpdate === null) { 11193 newBaseState = resultState; 11194 } 11195 } 11196 // Since this update will remain in the list, update the remaining 11197 // expiration time. 11198 if (newExpirationTime === NoWork || newExpirationTime > _updateExpirationTime) { 11199 newExpirationTime = _updateExpirationTime; 11200 } 11201 } else { 11202 // This update does have sufficient priority. Process it and compute 11203 // a new result. 11204 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance); 11205 var _callback2 = update.callback; 11206 if (_callback2 !== null) { 11207 workInProgress.effectTag |= Callback; 11208 // Set this to null, in case it was mutated during an aborted render. 11209 update.nextEffect = null; 11210 if (queue.lastCapturedEffect === null) { 11211 queue.firstCapturedEffect = queue.lastCapturedEffect = update; 11212 } else { 11213 queue.lastCapturedEffect.nextEffect = update; 11214 queue.lastCapturedEffect = update; 11215 } 11216 } 11217 } 11218 update = update.next; 11219 } 11220 11221 if (newFirstUpdate === null) { 11222 queue.lastUpdate = null; 11223 } 11224 if (newFirstCapturedUpdate === null) { 11225 queue.lastCapturedUpdate = null; 11226 } else { 11227 workInProgress.effectTag |= Callback; 11228 } 11229 if (newFirstUpdate === null && newFirstCapturedUpdate === null) { 11230 // We processed every update, without skipping. That means the new base 11231 // state is the same as the result state. 11232 newBaseState = resultState; 11233 } 11234 11235 queue.baseState = newBaseState; 11236 queue.firstUpdate = newFirstUpdate; 11237 queue.firstCapturedUpdate = newFirstCapturedUpdate; 11238 11239 // Set the remaining expiration time to be whatever is remaining in the queue. 11240 // This should be fine because the only two other things that contribute to 11241 // expiration time are props and context. We're already in the middle of the 11242 // begin phase by the time we start processing the queue, so we've already 11243 // dealt with the props. Context in components that specify 11244 // shouldComponentUpdate is tricky; but we'll have to account for 11245 // that regardless. 11246 workInProgress.expirationTime = newExpirationTime; 11247 workInProgress.memoizedState = resultState; 11248 11249 { 11250 currentlyProcessingQueue = null; 11251 } 11252 } 11253 11254 function callCallback(callback, context) { 11255 !(typeof callback === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', callback) : void 0; 11256 callback.call(context); 11257 } 11258 11259 function resetHasForceUpdateBeforeProcessing() { 11260 hasForceUpdate = false; 11261 } 11262 11263 function checkHasForceUpdateAfterProcessing() { 11264 return hasForceUpdate; 11265 } 11266 11267 function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) { 11268 // If the finished render included captured updates, and there are still 11269 // lower priority updates left over, we need to keep the captured updates 11270 // in the queue so that they are rebased and not dropped once we process the 11271 // queue again at the lower priority. 11272 if (finishedQueue.firstCapturedUpdate !== null) { 11273 // Join the captured update list to the end of the normal list. 11274 if (finishedQueue.lastUpdate !== null) { 11275 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate; 11276 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate; 11277 } 11278 // Clear the list of captured updates. 11279 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null; 11280 } 11281 11282 // Commit the effects 11283 commitUpdateEffects(finishedQueue.firstEffect, instance); 11284 finishedQueue.firstEffect = finishedQueue.lastEffect = null; 11285 11286 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); 11287 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; 11288 } 11289 11290 function commitUpdateEffects(effect, instance) { 11291 while (effect !== null) { 11292 var _callback3 = effect.callback; 11293 if (_callback3 !== null) { 11294 effect.callback = null; 11295 callCallback(_callback3, instance); 11296 } 11297 effect = effect.nextEffect; 11298 } 11299 } 11300 11301 function createCapturedValue(value, source) { 11302 // If the value is an error, call this function immediately after it is thrown 11303 // so the stack is accurate. 11304 return { 11305 value: value, 11306 source: source, 11307 stack: getStackByFiberInDevAndProd(source) 11308 }; 11309 } 11310 11311 var valueCursor = createCursor(null); 11312 11313 var rendererSigil = void 0; 11314 { 11315 // Use this to detect multiple renderers using the same context 11316 rendererSigil = {}; 11317 } 11318 11319 var currentlyRenderingFiber = null; 11320 var lastContextDependency = null; 11321 var lastContextWithAllBitsObserved = null; 11322 11323 function resetContextDependences() { 11324 // This is called right before React yields execution, to ensure `readContext` 11325 // cannot be called outside the render phase. 11326 currentlyRenderingFiber = null; 11327 lastContextDependency = null; 11328 lastContextWithAllBitsObserved = null; 11329 } 11330 11331 function pushProvider(providerFiber, nextValue) { 11332 var context = providerFiber.type._context; 11333 11334 if (isPrimaryRenderer) { 11335 push(valueCursor, context._currentValue, providerFiber); 11336 11337 context._currentValue = nextValue; 11338 { 11339 !(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; 11340 context._currentRenderer = rendererSigil; 11341 } 11342 } else { 11343 push(valueCursor, context._currentValue2, providerFiber); 11344 11345 context._currentValue2 = nextValue; 11346 { 11347 !(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; 11348 context._currentRenderer2 = rendererSigil; 11349 } 11350 } 11351 } 11352 11353 function popProvider(providerFiber) { 11354 var currentValue = valueCursor.current; 11355 11356 pop(valueCursor, providerFiber); 11357 11358 var context = providerFiber.type._context; 11359 if (isPrimaryRenderer) { 11360 context._currentValue = currentValue; 11361 } else { 11362 context._currentValue2 = currentValue; 11363 } 11364 } 11365 11366 function calculateChangedBits(context, newValue, oldValue) { 11367 // Use Object.is to compare the new context value to the old value. Inlined 11368 // Object.is polyfill. 11369 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is 11370 if (oldValue === newValue && (oldValue !== 0 || 1 / oldValue === 1 / newValue) || oldValue !== oldValue && newValue !== newValue // eslint-disable-line no-self-compare 11371 ) { 11372 // No change 11373 return 0; 11374 } else { 11375 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : maxSigned31BitInt; 11376 11377 { 11378 !((changedBits & maxSigned31BitInt) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0; 11379 } 11380 return changedBits | 0; 11381 } 11382 } 11383 11384 function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) { 11385 var fiber = workInProgress.child; 11386 if (fiber !== null) { 11387 // Set the return pointer of the child to the work-in-progress fiber. 11388 fiber.return = workInProgress; 11389 } 11390 while (fiber !== null) { 11391 var nextFiber = void 0; 11392 11393 // Visit this fiber. 11394 var dependency = fiber.firstContextDependency; 11395 if (dependency !== null) { 11396 do { 11397 // Check if the context matches. 11398 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) { 11399 // Match! Schedule an update on this fiber. 11400 11401 if (fiber.tag === ClassComponent || fiber.tag === ClassComponentLazy) { 11402 // Schedule a force update on the work-in-progress. 11403 var update = createUpdate(renderExpirationTime); 11404 update.tag = ForceUpdate; 11405 // TODO: Because we don't have a work-in-progress, this will add the 11406 // update to the current fiber, too, which means it will persist even if 11407 // this render is thrown away. Since it's a race condition, not sure it's 11408 // worth fixing. 11409 enqueueUpdate(fiber, update); 11410 } 11411 11412 if (fiber.expirationTime === NoWork || fiber.expirationTime > renderExpirationTime) { 11413 fiber.expirationTime = renderExpirationTime; 11414 } 11415 var alternate = fiber.alternate; 11416 if (alternate !== null && (alternate.expirationTime === NoWork || alternate.expirationTime > renderExpirationTime)) { 11417 alternate.expirationTime = renderExpirationTime; 11418 } 11419 // Update the child expiration time of all the ancestors, including 11420 // the alternates. 11421 var node = fiber.return; 11422 while (node !== null) { 11423 alternate = node.alternate; 11424 if (node.childExpirationTime === NoWork || node.childExpirationTime > renderExpirationTime) { 11425 node.childExpirationTime = renderExpirationTime; 11426 if (alternate !== null && (alternate.childExpirationTime === NoWork || alternate.childExpirationTime > renderExpirationTime)) { 11427 alternate.childExpirationTime = renderExpirationTime; 11428 } 11429 } else if (alternate !== null && (alternate.childExpirationTime === NoWork || alternate.childExpirationTime > renderExpirationTime)) { 11430 alternate.childExpirationTime = renderExpirationTime; 11431 } else { 11432 // Neither alternate was updated, which means the rest of the 11433 // ancestor path already has sufficient priority. 11434 break; 11435 } 11436 node = node.return; 11437 } 11438 } 11439 nextFiber = fiber.child; 11440 dependency = dependency.next; 11441 } while (dependency !== null); 11442 } else if (fiber.tag === ContextProvider) { 11443 // Don't scan deeper if this is a matching provider 11444 nextFiber = fiber.type === workInProgress.type ? null : fiber.child; 11445 } else { 11446 // Traverse down. 11447 nextFiber = fiber.child; 11448 } 11449 11450 if (nextFiber !== null) { 11451 // Set the return pointer of the child to the work-in-progress fiber. 11452 nextFiber.return = fiber; 11453 } else { 11454 // No child. Traverse to next sibling. 11455 nextFiber = fiber; 11456 while (nextFiber !== null) { 11457 if (nextFiber === workInProgress) { 11458 // We're back to the root of this subtree. Exit. 11459 nextFiber = null; 11460 break; 11461 } 11462 var sibling = nextFiber.sibling; 11463 if (sibling !== null) { 11464 // Set the return pointer of the sibling to the work-in-progress fiber. 11465 sibling.return = nextFiber.return; 11466 nextFiber = sibling; 11467 break; 11468 } 11469 // No more siblings. Traverse up. 11470 nextFiber = nextFiber.return; 11471 } 11472 } 11473 fiber = nextFiber; 11474 } 11475 } 11476 11477 function prepareToReadContext(workInProgress, renderExpirationTime) { 11478 currentlyRenderingFiber = workInProgress; 11479 lastContextDependency = null; 11480 lastContextWithAllBitsObserved = null; 11481 11482 // Reset the work-in-progress list 11483 workInProgress.firstContextDependency = null; 11484 } 11485 11486 function readContext(context, observedBits) { 11487 if (lastContextWithAllBitsObserved === context) { 11488 // Nothing to do. We already observe everything in this context. 11489 } else if (observedBits === false || observedBits === 0) { 11490 // Do not observe any updates. 11491 } else { 11492 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types. 11493 if (typeof observedBits !== 'number' || observedBits === maxSigned31BitInt) { 11494 // Observe all updates. 11495 lastContextWithAllBitsObserved = context; 11496 resolvedObservedBits = maxSigned31BitInt; 11497 } else { 11498 resolvedObservedBits = observedBits; 11499 } 11500 11501 var contextItem = { 11502 context: context, 11503 observedBits: resolvedObservedBits, 11504 next: null 11505 }; 11506 11507 if (lastContextDependency === null) { 11508 !(currentlyRenderingFiber !== null) ? invariant(false, 'Context.unstable_read(): Context can only be read while React is rendering, e.g. inside the render method or getDerivedStateFromProps.') : void 0; 11509 // This is the first dependency in the list 11510 currentlyRenderingFiber.firstContextDependency = lastContextDependency = contextItem; 11511 } else { 11512 // Append a new context item. 11513 lastContextDependency = lastContextDependency.next = contextItem; 11514 } 11515 } 11516 return isPrimaryRenderer ? context._currentValue : context._currentValue2; 11517 } 11518 11519 var NO_CONTEXT = {}; 11520 11521 var contextStackCursor$1 = createCursor(NO_CONTEXT); 11522 var contextFiberStackCursor = createCursor(NO_CONTEXT); 11523 var rootInstanceStackCursor = createCursor(NO_CONTEXT); 11524 11525 function requiredContext(c) { 11526 !(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; 11527 return c; 11528 } 11529 11530 function getRootHostContainer() { 11531 var rootInstance = requiredContext(rootInstanceStackCursor.current); 11532 return rootInstance; 11533 } 11534 11535 function pushHostContainer(fiber, nextRootInstance) { 11536 // Push current root instance onto the stack; 11537 // This allows us to reset root when portals are popped. 11538 push(rootInstanceStackCursor, nextRootInstance, fiber); 11539 // Track the context and the Fiber that provided it. 11540 // This enables us to pop only Fibers that provide unique contexts. 11541 push(contextFiberStackCursor, fiber, fiber); 11542 11543 // Finally, we need to push the host context to the stack. 11544 // However, we can't just call getRootHostContext() and push it because 11545 // we'd have a different number of entries on the stack depending on 11546 // whether getRootHostContext() throws somewhere in renderer code or not. 11547 // So we push an empty value first. This lets us safely unwind on errors. 11548 push(contextStackCursor$1, NO_CONTEXT, fiber); 11549 var nextRootContext = getRootHostContext(nextRootInstance); 11550 // Now that we know this function doesn't throw, replace it. 11551 pop(contextStackCursor$1, fiber); 11552 push(contextStackCursor$1, nextRootContext, fiber); 11553 } 11554 11555 function popHostContainer(fiber) { 11556 pop(contextStackCursor$1, fiber); 11557 pop(contextFiberStackCursor, fiber); 11558 pop(rootInstanceStackCursor, fiber); 11559 } 11560 11561 function getHostContext() { 11562 var context = requiredContext(contextStackCursor$1.current); 11563 return context; 11564 } 11565 11566 function pushHostContext(fiber) { 11567 var rootInstance = requiredContext(rootInstanceStackCursor.current); 11568 var context = requiredContext(contextStackCursor$1.current); 11569 var nextContext = getChildHostContext(context, fiber.type, rootInstance); 11570 11571 // Don't push this Fiber's context unless it's unique. 11572 if (context === nextContext) { 11573 return; 11574 } 11575 11576 // Track the context and the Fiber that provided it. 11577 // This enables us to pop only Fibers that provide unique contexts. 11578 push(contextFiberStackCursor, fiber, fiber); 11579 push(contextStackCursor$1, nextContext, fiber); 11580 } 11581 11582 function popHostContext(fiber) { 11583 // Do not pop unless this Fiber provided the current context. 11584 // pushHostContext() only pushes Fibers that provide unique contexts. 11585 if (contextFiberStackCursor.current !== fiber) { 11586 return; 11587 } 11588 11589 pop(contextStackCursor$1, fiber); 11590 pop(contextFiberStackCursor, fiber); 11591 } 11592 11593 var commitTime = 0; 11594 var profilerStartTime = -1; 11595 11596 function getCommitTime() { 11597 return commitTime; 11598 } 11599 11600 function recordCommitTime() { 11601 if (!enableProfilerTimer) { 11602 return; 11603 } 11604 commitTime = unstable_now(); 11605 } 11606 11607 function startProfilerTimer(fiber) { 11608 if (!enableProfilerTimer) { 11609 return; 11610 } 11611 11612 profilerStartTime = unstable_now(); 11613 11614 if (fiber.actualStartTime < 0) { 11615 fiber.actualStartTime = unstable_now(); 11616 } 11617 } 11618 11619 function stopProfilerTimerIfRunning(fiber) { 11620 if (!enableProfilerTimer) { 11621 return; 11622 } 11623 profilerStartTime = -1; 11624 } 11625 11626 function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { 11627 if (!enableProfilerTimer) { 11628 return; 11629 } 11630 11631 if (profilerStartTime >= 0) { 11632 var elapsedTime = unstable_now() - profilerStartTime; 11633 fiber.actualDuration += elapsedTime; 11634 if (overrideBaseTime) { 11635 fiber.selfBaseDuration = elapsedTime; 11636 } 11637 profilerStartTime = -1; 11638 } 11639 } 11640 11641 var fakeInternalInstance = {}; 11642 var isArray = Array.isArray; 11643 11644 // React.Component uses a shared frozen object by default. 11645 // We'll use it to determine whether we need to initialize legacy refs. 11646 var emptyRefsObject = new React.Component().refs; 11647 11648 var didWarnAboutStateAssignmentForComponent = void 0; 11649 var didWarnAboutUninitializedState = void 0; 11650 var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0; 11651 var didWarnAboutLegacyLifecyclesAndDerivedState = void 0; 11652 var didWarnAboutUndefinedDerivedState = void 0; 11653 var warnOnUndefinedDerivedState = void 0; 11654 var warnOnInvalidCallback$1 = void 0; 11655 var didWarnAboutDirectlyAssigningPropsToState = void 0; 11656 11657 { 11658 didWarnAboutStateAssignmentForComponent = new Set(); 11659 didWarnAboutUninitializedState = new Set(); 11660 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set(); 11661 didWarnAboutLegacyLifecyclesAndDerivedState = new Set(); 11662 didWarnAboutDirectlyAssigningPropsToState = new Set(); 11663 didWarnAboutUndefinedDerivedState = new Set(); 11664 11665 var didWarnOnInvalidCallback = new Set(); 11666 11667 warnOnInvalidCallback$1 = function (callback, callerName) { 11668 if (callback === null || typeof callback === 'function') { 11669 return; 11670 } 11671 var key = callerName + '_' + callback; 11672 if (!didWarnOnInvalidCallback.has(key)) { 11673 didWarnOnInvalidCallback.add(key); 11674 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback); 11675 } 11676 }; 11677 11678 warnOnUndefinedDerivedState = function (type, partialState) { 11679 if (partialState === undefined) { 11680 var componentName = getComponentName(type) || 'Component'; 11681 if (!didWarnAboutUndefinedDerivedState.has(componentName)) { 11682 didWarnAboutUndefinedDerivedState.add(componentName); 11683 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName); 11684 } 11685 } 11686 }; 11687 11688 // This is so gross but it's at least non-critical and can be removed if 11689 // it causes problems. This is meant to give a nicer error message for 11690 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component, 11691 // ...)) which otherwise throws a "_processChildContext is not a function" 11692 // exception. 11693 Object.defineProperty(fakeInternalInstance, '_processChildContext', { 11694 enumerable: false, 11695 value: function () { 11696 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).'); 11697 } 11698 }); 11699 Object.freeze(fakeInternalInstance); 11700 } 11701 11702 function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) { 11703 var prevState = workInProgress.memoizedState; 11704 11705 { 11706 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) { 11707 // Invoke the function an extra time to help detect side-effects. 11708 getDerivedStateFromProps(nextProps, prevState); 11709 } 11710 } 11711 11712 var partialState = getDerivedStateFromProps(nextProps, prevState); 11713 11714 { 11715 warnOnUndefinedDerivedState(ctor, partialState); 11716 } 11717 // Merge the partial state and the previous state. 11718 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState); 11719 workInProgress.memoizedState = memoizedState; 11720 11721 // Once the update queue is empty, persist the derived state onto the 11722 // base state. 11723 var updateQueue = workInProgress.updateQueue; 11724 if (updateQueue !== null && workInProgress.expirationTime === NoWork) { 11725 updateQueue.baseState = memoizedState; 11726 } 11727 } 11728 11729 var classComponentUpdater = { 11730 isMounted: isMounted, 11731 enqueueSetState: function (inst, payload, callback) { 11732 var fiber = get(inst); 11733 var currentTime = requestCurrentTime(); 11734 var expirationTime = computeExpirationForFiber(currentTime, fiber); 11735 11736 var update = createUpdate(expirationTime); 11737 update.payload = payload; 11738 if (callback !== undefined && callback !== null) { 11739 { 11740 warnOnInvalidCallback$1(callback, 'setState'); 11741 } 11742 update.callback = callback; 11743 } 11744 11745 enqueueUpdate(fiber, update); 11746 scheduleWork(fiber, expirationTime); 11747 }, 11748 enqueueReplaceState: function (inst, payload, callback) { 11749 var fiber = get(inst); 11750 var currentTime = requestCurrentTime(); 11751 var expirationTime = computeExpirationForFiber(currentTime, fiber); 11752 11753 var update = createUpdate(expirationTime); 11754 update.tag = ReplaceState; 11755 update.payload = payload; 11756 11757 if (callback !== undefined && callback !== null) { 11758 { 11759 warnOnInvalidCallback$1(callback, 'replaceState'); 11760 } 11761 update.callback = callback; 11762 } 11763 11764 enqueueUpdate(fiber, update); 11765 scheduleWork(fiber, expirationTime); 11766 }, 11767 enqueueForceUpdate: function (inst, callback) { 11768 var fiber = get(inst); 11769 var currentTime = requestCurrentTime(); 11770 var expirationTime = computeExpirationForFiber(currentTime, fiber); 11771 11772 var update = createUpdate(expirationTime); 11773 update.tag = ForceUpdate; 11774 11775 if (callback !== undefined && callback !== null) { 11776 { 11777 warnOnInvalidCallback$1(callback, 'forceUpdate'); 11778 } 11779 update.callback = callback; 11780 } 11781 11782 enqueueUpdate(fiber, update); 11783 scheduleWork(fiber, expirationTime); 11784 } 11785 }; 11786 11787 function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextLegacyContext) { 11788 var instance = workInProgress.stateNode; 11789 if (typeof instance.shouldComponentUpdate === 'function') { 11790 startPhaseTimer(workInProgress, 'shouldComponentUpdate'); 11791 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextLegacyContext); 11792 stopPhaseTimer(); 11793 11794 { 11795 !(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; 11796 } 11797 11798 return shouldUpdate; 11799 } 11800 11801 if (ctor.prototype && ctor.prototype.isPureReactComponent) { 11802 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState); 11803 } 11804 11805 return true; 11806 } 11807 11808 function checkClassInstance(workInProgress, ctor, newProps) { 11809 var instance = workInProgress.stateNode; 11810 { 11811 var name = getComponentName(ctor) || 'Component'; 11812 var renderPresent = instance.render; 11813 11814 if (!renderPresent) { 11815 if (ctor.prototype && typeof ctor.prototype.render === 'function') { 11816 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name); 11817 } else { 11818 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name); 11819 } 11820 } 11821 11822 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state; 11823 !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; 11824 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved; 11825 !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; 11826 var noInstancePropTypes = !instance.propTypes; 11827 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0; 11828 var noInstanceContextTypes = !instance.contextTypes; 11829 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0; 11830 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function'; 11831 !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; 11832 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') { 11833 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'); 11834 } 11835 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function'; 11836 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0; 11837 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function'; 11838 !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; 11839 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function'; 11840 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0; 11841 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function'; 11842 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0; 11843 var hasMutatedProps = instance.props !== newProps; 11844 !(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; 11845 var noInstanceDefaultProps = !instance.defaultProps; 11846 !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; 11847 11848 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) { 11849 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); 11850 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor)); 11851 } 11852 11853 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function'; 11854 !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; 11855 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromCatch !== 'function'; 11856 !noInstanceGetDerivedStateFromCatch ? warningWithoutStack$1(false, '%s: getDerivedStateFromCatch() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name) : void 0; 11857 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function'; 11858 !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; 11859 var _state = instance.state; 11860 if (_state && (typeof _state !== 'object' || isArray(_state))) { 11861 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name); 11862 } 11863 if (typeof instance.getChildContext === 'function') { 11864 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0; 11865 } 11866 } 11867 } 11868 11869 function adoptClassInstance(workInProgress, instance) { 11870 instance.updater = classComponentUpdater; 11871 workInProgress.stateNode = instance; 11872 // The instance needs access to the fiber so that it can schedule updates 11873 set(instance, workInProgress); 11874 { 11875 instance._reactInternalInstance = fakeInternalInstance; 11876 } 11877 } 11878 11879 function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) { 11880 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); 11881 var contextTypes = ctor.contextTypes; 11882 var isContextConsumer = contextTypes !== null && contextTypes !== undefined; 11883 var context = isContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject; 11884 11885 // Instantiate twice to help detect side-effects. 11886 { 11887 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) { 11888 new ctor(props, context); // eslint-disable-line no-new 11889 } 11890 } 11891 11892 var instance = new ctor(props, context); 11893 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null; 11894 adoptClassInstance(workInProgress, instance); 11895 11896 { 11897 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) { 11898 var componentName = getComponentName(ctor) || 'Component'; 11899 if (!didWarnAboutUninitializedState.has(componentName)) { 11900 didWarnAboutUninitializedState.add(componentName); 11901 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); 11902 } 11903 } 11904 11905 // If new component APIs are defined, "unsafe" lifecycles won't be called. 11906 // Warn about these lifecycles if they are present. 11907 // Don't warn about react-lifecycles-compat polyfilled methods though. 11908 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') { 11909 var foundWillMountName = null; 11910 var foundWillReceivePropsName = null; 11911 var foundWillUpdateName = null; 11912 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) { 11913 foundWillMountName = 'componentWillMount'; 11914 } else if (typeof instance.UNSAFE_componentWillMount === 'function') { 11915 foundWillMountName = 'UNSAFE_componentWillMount'; 11916 } 11917 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) { 11918 foundWillReceivePropsName = 'componentWillReceiveProps'; 11919 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') { 11920 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps'; 11921 } 11922 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) { 11923 foundWillUpdateName = 'componentWillUpdate'; 11924 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') { 11925 foundWillUpdateName = 'UNSAFE_componentWillUpdate'; 11926 } 11927 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) { 11928 var _componentName = getComponentName(ctor) || 'Component'; 11929 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()'; 11930 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) { 11931 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); 11932 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 : ''); 11933 } 11934 } 11935 } 11936 } 11937 11938 // Cache unmasked context so we can avoid recreating masked context unless necessary. 11939 // ReactFiberContext usually updates this cache but can't for newly-created instances. 11940 if (isContextConsumer) { 11941 cacheContext(workInProgress, unmaskedContext, context); 11942 } 11943 11944 return instance; 11945 } 11946 11947 function callComponentWillMount(workInProgress, instance) { 11948 startPhaseTimer(workInProgress, 'componentWillMount'); 11949 var oldState = instance.state; 11950 11951 if (typeof instance.componentWillMount === 'function') { 11952 instance.componentWillMount(); 11953 } 11954 if (typeof instance.UNSAFE_componentWillMount === 'function') { 11955 instance.UNSAFE_componentWillMount(); 11956 } 11957 11958 stopPhaseTimer(); 11959 11960 if (oldState !== instance.state) { 11961 { 11962 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'); 11963 } 11964 classComponentUpdater.enqueueReplaceState(instance, instance.state, null); 11965 } 11966 } 11967 11968 function callComponentWillReceiveProps(workInProgress, instance, newProps, nextLegacyContext) { 11969 var oldState = instance.state; 11970 startPhaseTimer(workInProgress, 'componentWillReceiveProps'); 11971 if (typeof instance.componentWillReceiveProps === 'function') { 11972 instance.componentWillReceiveProps(newProps, nextLegacyContext); 11973 } 11974 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') { 11975 instance.UNSAFE_componentWillReceiveProps(newProps, nextLegacyContext); 11976 } 11977 stopPhaseTimer(); 11978 11979 if (instance.state !== oldState) { 11980 { 11981 var componentName = getComponentName(workInProgress.type) || 'Component'; 11982 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { 11983 didWarnAboutStateAssignmentForComponent.add(componentName); 11984 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName); 11985 } 11986 } 11987 classComponentUpdater.enqueueReplaceState(instance, instance.state, null); 11988 } 11989 } 11990 11991 // Invokes the mount life-cycles on a previously never rendered instance. 11992 function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) { 11993 { 11994 checkClassInstance(workInProgress, ctor, newProps); 11995 } 11996 11997 var instance = workInProgress.stateNode; 11998 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); 11999 12000 instance.props = newProps; 12001 instance.state = workInProgress.memoizedState; 12002 instance.refs = emptyRefsObject; 12003 instance.context = getMaskedContext(workInProgress, unmaskedContext); 12004 12005 { 12006 if (instance.state === newProps) { 12007 var componentName = getComponentName(ctor) || 'Component'; 12008 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { 12009 didWarnAboutDirectlyAssigningPropsToState.add(componentName); 12010 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); 12011 } 12012 } 12013 12014 if (workInProgress.mode & StrictMode) { 12015 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance); 12016 12017 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance); 12018 } 12019 12020 if (warnAboutDeprecatedLifecycles) { 12021 ReactStrictModeWarnings.recordDeprecationWarnings(workInProgress, instance); 12022 } 12023 } 12024 12025 var updateQueue = workInProgress.updateQueue; 12026 if (updateQueue !== null) { 12027 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime); 12028 instance.state = workInProgress.memoizedState; 12029 } 12030 12031 var getDerivedStateFromProps = ctor.getDerivedStateFromProps; 12032 if (typeof getDerivedStateFromProps === 'function') { 12033 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps); 12034 instance.state = workInProgress.memoizedState; 12035 } 12036 12037 // In order to support react-lifecycles-compat polyfilled components, 12038 // Unsafe lifecycles should not be invoked for components using the new APIs. 12039 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) { 12040 callComponentWillMount(workInProgress, instance); 12041 // If we had additional state updates during this life-cycle, let's 12042 // process them now. 12043 updateQueue = workInProgress.updateQueue; 12044 if (updateQueue !== null) { 12045 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime); 12046 instance.state = workInProgress.memoizedState; 12047 } 12048 } 12049 12050 if (typeof instance.componentDidMount === 'function') { 12051 workInProgress.effectTag |= Update; 12052 } 12053 } 12054 12055 function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) { 12056 var instance = workInProgress.stateNode; 12057 12058 var oldProps = workInProgress.memoizedProps; 12059 instance.props = oldProps; 12060 12061 var oldContext = instance.context; 12062 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); 12063 var nextLegacyContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext); 12064 12065 var getDerivedStateFromProps = ctor.getDerivedStateFromProps; 12066 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; 12067 12068 // Note: During these life-cycles, instance.props/instance.state are what 12069 // ever the previously attempted to render - not the "current". However, 12070 // during componentDidUpdate we pass the "current" props. 12071 12072 // In order to support react-lifecycles-compat polyfilled components, 12073 // Unsafe lifecycles should not be invoked for components using the new APIs. 12074 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) { 12075 if (oldProps !== newProps || oldContext !== nextLegacyContext) { 12076 callComponentWillReceiveProps(workInProgress, instance, newProps, nextLegacyContext); 12077 } 12078 } 12079 12080 resetHasForceUpdateBeforeProcessing(); 12081 12082 var oldState = workInProgress.memoizedState; 12083 var newState = instance.state = oldState; 12084 var updateQueue = workInProgress.updateQueue; 12085 if (updateQueue !== null) { 12086 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime); 12087 newState = workInProgress.memoizedState; 12088 } 12089 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) { 12090 // If an update was already in progress, we should schedule an Update 12091 // effect even though we're bailing out, so that cWU/cDU are called. 12092 if (typeof instance.componentDidMount === 'function') { 12093 workInProgress.effectTag |= Update; 12094 } 12095 return false; 12096 } 12097 12098 if (typeof getDerivedStateFromProps === 'function') { 12099 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps); 12100 newState = workInProgress.memoizedState; 12101 } 12102 12103 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextLegacyContext); 12104 12105 if (shouldUpdate) { 12106 // In order to support react-lifecycles-compat polyfilled components, 12107 // Unsafe lifecycles should not be invoked for components using the new APIs. 12108 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) { 12109 startPhaseTimer(workInProgress, 'componentWillMount'); 12110 if (typeof instance.componentWillMount === 'function') { 12111 instance.componentWillMount(); 12112 } 12113 if (typeof instance.UNSAFE_componentWillMount === 'function') { 12114 instance.UNSAFE_componentWillMount(); 12115 } 12116 stopPhaseTimer(); 12117 } 12118 if (typeof instance.componentDidMount === 'function') { 12119 workInProgress.effectTag |= Update; 12120 } 12121 } else { 12122 // If an update was already in progress, we should schedule an Update 12123 // effect even though we're bailing out, so that cWU/cDU are called. 12124 if (typeof instance.componentDidMount === 'function') { 12125 workInProgress.effectTag |= Update; 12126 } 12127 12128 // If shouldComponentUpdate returned false, we should still update the 12129 // memoized state to indicate that this work can be reused. 12130 workInProgress.memoizedProps = newProps; 12131 workInProgress.memoizedState = newState; 12132 } 12133 12134 // Update the existing instance's state, props, and context pointers even 12135 // if shouldComponentUpdate returns false. 12136 instance.props = newProps; 12137 instance.state = newState; 12138 instance.context = nextLegacyContext; 12139 12140 return shouldUpdate; 12141 } 12142 12143 // Invokes the update life-cycles and returns false if it shouldn't rerender. 12144 function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) { 12145 var instance = workInProgress.stateNode; 12146 12147 var oldProps = workInProgress.memoizedProps; 12148 instance.props = oldProps; 12149 12150 var oldContext = instance.context; 12151 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); 12152 var nextLegacyContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext); 12153 12154 var getDerivedStateFromProps = ctor.getDerivedStateFromProps; 12155 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; 12156 12157 // Note: During these life-cycles, instance.props/instance.state are what 12158 // ever the previously attempted to render - not the "current". However, 12159 // during componentDidUpdate we pass the "current" props. 12160 12161 // In order to support react-lifecycles-compat polyfilled components, 12162 // Unsafe lifecycles should not be invoked for components using the new APIs. 12163 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) { 12164 if (oldProps !== newProps || oldContext !== nextLegacyContext) { 12165 callComponentWillReceiveProps(workInProgress, instance, newProps, nextLegacyContext); 12166 } 12167 } 12168 12169 resetHasForceUpdateBeforeProcessing(); 12170 12171 var oldState = workInProgress.memoizedState; 12172 var newState = instance.state = oldState; 12173 var updateQueue = workInProgress.updateQueue; 12174 if (updateQueue !== null) { 12175 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime); 12176 newState = workInProgress.memoizedState; 12177 } 12178 12179 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) { 12180 // If an update was already in progress, we should schedule an Update 12181 // effect even though we're bailing out, so that cWU/cDU are called. 12182 if (typeof instance.componentDidUpdate === 'function') { 12183 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) { 12184 workInProgress.effectTag |= Update; 12185 } 12186 } 12187 if (typeof instance.getSnapshotBeforeUpdate === 'function') { 12188 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) { 12189 workInProgress.effectTag |= Snapshot; 12190 } 12191 } 12192 return false; 12193 } 12194 12195 if (typeof getDerivedStateFromProps === 'function') { 12196 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps); 12197 newState = workInProgress.memoizedState; 12198 } 12199 12200 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextLegacyContext); 12201 12202 if (shouldUpdate) { 12203 // In order to support react-lifecycles-compat polyfilled components, 12204 // Unsafe lifecycles should not be invoked for components using the new APIs. 12205 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) { 12206 startPhaseTimer(workInProgress, 'componentWillUpdate'); 12207 if (typeof instance.componentWillUpdate === 'function') { 12208 instance.componentWillUpdate(newProps, newState, nextLegacyContext); 12209 } 12210 if (typeof instance.UNSAFE_componentWillUpdate === 'function') { 12211 instance.UNSAFE_componentWillUpdate(newProps, newState, nextLegacyContext); 12212 } 12213 stopPhaseTimer(); 12214 } 12215 if (typeof instance.componentDidUpdate === 'function') { 12216 workInProgress.effectTag |= Update; 12217 } 12218 if (typeof instance.getSnapshotBeforeUpdate === 'function') { 12219 workInProgress.effectTag |= Snapshot; 12220 } 12221 } else { 12222 // If an update was already in progress, we should schedule an Update 12223 // effect even though we're bailing out, so that cWU/cDU are called. 12224 if (typeof instance.componentDidUpdate === 'function') { 12225 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) { 12226 workInProgress.effectTag |= Update; 12227 } 12228 } 12229 if (typeof instance.getSnapshotBeforeUpdate === 'function') { 12230 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) { 12231 workInProgress.effectTag |= Snapshot; 12232 } 12233 } 12234 12235 // If shouldComponentUpdate returned false, we should still update the 12236 // memoized props/state to indicate that this work can be reused. 12237 workInProgress.memoizedProps = newProps; 12238 workInProgress.memoizedState = newState; 12239 } 12240 12241 // Update the existing instance's state, props, and context pointers even 12242 // if shouldComponentUpdate returns false. 12243 instance.props = newProps; 12244 instance.state = newState; 12245 instance.context = nextLegacyContext; 12246 12247 return shouldUpdate; 12248 } 12249 12250 var didWarnAboutMaps = void 0; 12251 var didWarnAboutGenerators = void 0; 12252 var didWarnAboutStringRefInStrictMode = void 0; 12253 var ownerHasKeyUseWarning = void 0; 12254 var ownerHasFunctionTypeWarning = void 0; 12255 var warnForMissingKey = function (child) {}; 12256 12257 { 12258 didWarnAboutMaps = false; 12259 didWarnAboutGenerators = false; 12260 didWarnAboutStringRefInStrictMode = {}; 12261 12262 /** 12263 * Warn if there's no key explicitly set on dynamic arrays of children or 12264 * object keys are not valid. This allows us to keep track of children between 12265 * updates. 12266 */ 12267 ownerHasKeyUseWarning = {}; 12268 ownerHasFunctionTypeWarning = {}; 12269 12270 warnForMissingKey = function (child) { 12271 if (child === null || typeof child !== 'object') { 12272 return; 12273 } 12274 if (!child._store || child._store.validated || child.key != null) { 12275 return; 12276 } 12277 !(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; 12278 child._store.validated = true; 12279 12280 var currentComponentErrorInfo = 'Each child in an array or iterator should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev(); 12281 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) { 12282 return; 12283 } 12284 ownerHasKeyUseWarning[currentComponentErrorInfo] = true; 12285 12286 warning$1(false, 'Each child in an array or iterator should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.'); 12287 }; 12288 } 12289 12290 var isArray$1 = Array.isArray; 12291 12292 function coerceRef(returnFiber, current$$1, element) { 12293 var mixedRef = element.ref; 12294 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') { 12295 { 12296 if (returnFiber.mode & StrictMode) { 12297 var componentName = getComponentName(returnFiber.type) || 'Component'; 12298 if (!didWarnAboutStringRefInStrictMode[componentName]) { 12299 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)); 12300 didWarnAboutStringRefInStrictMode[componentName] = true; 12301 } 12302 } 12303 } 12304 12305 if (element._owner) { 12306 var owner = element._owner; 12307 var inst = void 0; 12308 if (owner) { 12309 var ownerFiber = owner; 12310 !(ownerFiber.tag === ClassComponent || ownerFiber.tag === ClassComponentLazy) ? invariant(false, 'Stateless function components cannot have refs.') : void 0; 12311 inst = ownerFiber.stateNode; 12312 } 12313 !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; 12314 var stringRef = '' + mixedRef; 12315 // Check if previous string ref matches new string ref 12316 if (current$$1 !== null && current$$1.ref !== null && typeof current$$1.ref === 'function' && current$$1.ref._stringRef === stringRef) { 12317 return current$$1.ref; 12318 } 12319 var ref = function (value) { 12320 var refs = inst.refs; 12321 if (refs === emptyRefsObject) { 12322 // This is a lazy pooled frozen object, so we need to initialize. 12323 refs = inst.refs = {}; 12324 } 12325 if (value === null) { 12326 delete refs[stringRef]; 12327 } else { 12328 refs[stringRef] = value; 12329 } 12330 }; 12331 ref._stringRef = stringRef; 12332 return ref; 12333 } else { 12334 !(typeof mixedRef === 'string') ? invariant(false, 'Expected ref to be a function, a string, an object returned by React.createRef(), or null.') : void 0; 12335 !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 functional 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; 12336 } 12337 } 12338 return mixedRef; 12339 } 12340 12341 function throwOnInvalidObjectType(returnFiber, newChild) { 12342 if (returnFiber.type !== 'textarea') { 12343 var addendum = ''; 12344 { 12345 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev(); 12346 } 12347 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); 12348 } 12349 } 12350 12351 function warnOnFunctionType() { 12352 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(); 12353 12354 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { 12355 return; 12356 } 12357 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; 12358 12359 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.'); 12360 } 12361 12362 // This wrapper function exists because I expect to clone the code in each path 12363 // to be able to optimize each path individually by branching early. This needs 12364 // a compiler or we can do it manually. Helpers that don't need this branching 12365 // live outside of this function. 12366 function ChildReconciler(shouldTrackSideEffects) { 12367 function deleteChild(returnFiber, childToDelete) { 12368 if (!shouldTrackSideEffects) { 12369 // Noop. 12370 return; 12371 } 12372 // Deletions are added in reversed order so we add it to the front. 12373 // At this point, the return fiber's effect list is empty except for 12374 // deletions, so we can just append the deletion to the list. The remaining 12375 // effects aren't added until the complete phase. Once we implement 12376 // resuming, this may not be true. 12377 var last = returnFiber.lastEffect; 12378 if (last !== null) { 12379 last.nextEffect = childToDelete; 12380 returnFiber.lastEffect = childToDelete; 12381 } else { 12382 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; 12383 } 12384 childToDelete.nextEffect = null; 12385 childToDelete.effectTag = Deletion; 12386 } 12387 12388 function deleteRemainingChildren(returnFiber, currentFirstChild) { 12389 if (!shouldTrackSideEffects) { 12390 // Noop. 12391 return null; 12392 } 12393 12394 // TODO: For the shouldClone case, this could be micro-optimized a bit by 12395 // assuming that after the first child we've already added everything. 12396 var childToDelete = currentFirstChild; 12397 while (childToDelete !== null) { 12398 deleteChild(returnFiber, childToDelete); 12399 childToDelete = childToDelete.sibling; 12400 } 12401 return null; 12402 } 12403 12404 function mapRemainingChildren(returnFiber, currentFirstChild) { 12405 // Add the remaining children to a temporary map so that we can find them by 12406 // keys quickly. Implicit (null) keys get added to this set with their index 12407 var existingChildren = new Map(); 12408 12409 var existingChild = currentFirstChild; 12410 while (existingChild !== null) { 12411 if (existingChild.key !== null) { 12412 existingChildren.set(existingChild.key, existingChild); 12413 } else { 12414 existingChildren.set(existingChild.index, existingChild); 12415 } 12416 existingChild = existingChild.sibling; 12417 } 12418 return existingChildren; 12419 } 12420 12421 function useFiber(fiber, pendingProps, expirationTime) { 12422 // We currently set sibling to null and index to 0 here because it is easy 12423 // to forget to do before returning it. E.g. for the single child case. 12424 var clone = createWorkInProgress(fiber, pendingProps, expirationTime); 12425 clone.index = 0; 12426 clone.sibling = null; 12427 return clone; 12428 } 12429 12430 function placeChild(newFiber, lastPlacedIndex, newIndex) { 12431 newFiber.index = newIndex; 12432 if (!shouldTrackSideEffects) { 12433 // Noop. 12434 return lastPlacedIndex; 12435 } 12436 var current$$1 = newFiber.alternate; 12437 if (current$$1 !== null) { 12438 var oldIndex = current$$1.index; 12439 if (oldIndex < lastPlacedIndex) { 12440 // This is a move. 12441 newFiber.effectTag = Placement; 12442 return lastPlacedIndex; 12443 } else { 12444 // This item can stay in place. 12445 return oldIndex; 12446 } 12447 } else { 12448 // This is an insertion. 12449 newFiber.effectTag = Placement; 12450 return lastPlacedIndex; 12451 } 12452 } 12453 12454 function placeSingleChild(newFiber) { 12455 // This is simpler for the single child case. We only need to do a 12456 // placement for inserting new children. 12457 if (shouldTrackSideEffects && newFiber.alternate === null) { 12458 newFiber.effectTag = Placement; 12459 } 12460 return newFiber; 12461 } 12462 12463 function updateTextNode(returnFiber, current$$1, textContent, expirationTime) { 12464 if (current$$1 === null || current$$1.tag !== HostText) { 12465 // Insert 12466 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime); 12467 created.return = returnFiber; 12468 return created; 12469 } else { 12470 // Update 12471 var existing = useFiber(current$$1, textContent, expirationTime); 12472 existing.return = returnFiber; 12473 return existing; 12474 } 12475 } 12476 12477 function updateElement(returnFiber, current$$1, element, expirationTime) { 12478 if (current$$1 !== null && current$$1.type === element.type) { 12479 // Move based on index 12480 var existing = useFiber(current$$1, element.props, expirationTime); 12481 existing.ref = coerceRef(returnFiber, current$$1, element); 12482 existing.return = returnFiber; 12483 { 12484 existing._debugSource = element._source; 12485 existing._debugOwner = element._owner; 12486 } 12487 return existing; 12488 } else { 12489 // Insert 12490 var created = createFiberFromElement(element, returnFiber.mode, expirationTime); 12491 created.ref = coerceRef(returnFiber, current$$1, element); 12492 created.return = returnFiber; 12493 return created; 12494 } 12495 } 12496 12497 function updatePortal(returnFiber, current$$1, portal, expirationTime) { 12498 if (current$$1 === null || current$$1.tag !== HostPortal || current$$1.stateNode.containerInfo !== portal.containerInfo || current$$1.stateNode.implementation !== portal.implementation) { 12499 // Insert 12500 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime); 12501 created.return = returnFiber; 12502 return created; 12503 } else { 12504 // Update 12505 var existing = useFiber(current$$1, portal.children || [], expirationTime); 12506 existing.return = returnFiber; 12507 return existing; 12508 } 12509 } 12510 12511 function updateFragment(returnFiber, current$$1, fragment, expirationTime, key) { 12512 if (current$$1 === null || current$$1.tag !== Fragment) { 12513 // Insert 12514 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key); 12515 created.return = returnFiber; 12516 return created; 12517 } else { 12518 // Update 12519 var existing = useFiber(current$$1, fragment, expirationTime); 12520 existing.return = returnFiber; 12521 return existing; 12522 } 12523 } 12524 12525 function createChild(returnFiber, newChild, expirationTime) { 12526 if (typeof newChild === 'string' || typeof newChild === 'number') { 12527 // Text nodes don't have keys. If the previous node is implicitly keyed 12528 // we can continue to replace it without aborting even if it is not a text 12529 // node. 12530 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime); 12531 created.return = returnFiber; 12532 return created; 12533 } 12534 12535 if (typeof newChild === 'object' && newChild !== null) { 12536 switch (newChild.$$typeof) { 12537 case REACT_ELEMENT_TYPE: 12538 { 12539 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime); 12540 _created.ref = coerceRef(returnFiber, null, newChild); 12541 _created.return = returnFiber; 12542 return _created; 12543 } 12544 case REACT_PORTAL_TYPE: 12545 { 12546 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime); 12547 _created2.return = returnFiber; 12548 return _created2; 12549 } 12550 } 12551 12552 if (isArray$1(newChild) || getIteratorFn(newChild)) { 12553 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null); 12554 _created3.return = returnFiber; 12555 return _created3; 12556 } 12557 12558 throwOnInvalidObjectType(returnFiber, newChild); 12559 } 12560 12561 { 12562 if (typeof newChild === 'function') { 12563 warnOnFunctionType(); 12564 } 12565 } 12566 12567 return null; 12568 } 12569 12570 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) { 12571 // Update the fiber if the keys match, otherwise return null. 12572 12573 var key = oldFiber !== null ? oldFiber.key : null; 12574 12575 if (typeof newChild === 'string' || typeof newChild === 'number') { 12576 // Text nodes don't have keys. If the previous node is implicitly keyed 12577 // we can continue to replace it without aborting even if it is not a text 12578 // node. 12579 if (key !== null) { 12580 return null; 12581 } 12582 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime); 12583 } 12584 12585 if (typeof newChild === 'object' && newChild !== null) { 12586 switch (newChild.$$typeof) { 12587 case REACT_ELEMENT_TYPE: 12588 { 12589 if (newChild.key === key) { 12590 if (newChild.type === REACT_FRAGMENT_TYPE) { 12591 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key); 12592 } 12593 return updateElement(returnFiber, oldFiber, newChild, expirationTime); 12594 } else { 12595 return null; 12596 } 12597 } 12598 case REACT_PORTAL_TYPE: 12599 { 12600 if (newChild.key === key) { 12601 return updatePortal(returnFiber, oldFiber, newChild, expirationTime); 12602 } else { 12603 return null; 12604 } 12605 } 12606 } 12607 12608 if (isArray$1(newChild) || getIteratorFn(newChild)) { 12609 if (key !== null) { 12610 return null; 12611 } 12612 12613 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null); 12614 } 12615 12616 throwOnInvalidObjectType(returnFiber, newChild); 12617 } 12618 12619 { 12620 if (typeof newChild === 'function') { 12621 warnOnFunctionType(); 12622 } 12623 } 12624 12625 return null; 12626 } 12627 12628 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) { 12629 if (typeof newChild === 'string' || typeof newChild === 'number') { 12630 // Text nodes don't have keys, so we neither have to check the old nor 12631 // new node for the key. If both are text nodes, they match. 12632 var matchedFiber = existingChildren.get(newIdx) || null; 12633 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime); 12634 } 12635 12636 if (typeof newChild === 'object' && newChild !== null) { 12637 switch (newChild.$$typeof) { 12638 case REACT_ELEMENT_TYPE: 12639 { 12640 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null; 12641 if (newChild.type === REACT_FRAGMENT_TYPE) { 12642 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key); 12643 } 12644 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime); 12645 } 12646 case REACT_PORTAL_TYPE: 12647 { 12648 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null; 12649 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime); 12650 } 12651 } 12652 12653 if (isArray$1(newChild) || getIteratorFn(newChild)) { 12654 var _matchedFiber3 = existingChildren.get(newIdx) || null; 12655 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null); 12656 } 12657 12658 throwOnInvalidObjectType(returnFiber, newChild); 12659 } 12660 12661 { 12662 if (typeof newChild === 'function') { 12663 warnOnFunctionType(); 12664 } 12665 } 12666 12667 return null; 12668 } 12669 12670 /** 12671 * Warns if there is a duplicate or missing key 12672 */ 12673 function warnOnInvalidKey(child, knownKeys) { 12674 { 12675 if (typeof child !== 'object' || child === null) { 12676 return knownKeys; 12677 } 12678 switch (child.$$typeof) { 12679 case REACT_ELEMENT_TYPE: 12680 case REACT_PORTAL_TYPE: 12681 warnForMissingKey(child); 12682 var key = child.key; 12683 if (typeof key !== 'string') { 12684 break; 12685 } 12686 if (knownKeys === null) { 12687 knownKeys = new Set(); 12688 knownKeys.add(key); 12689 break; 12690 } 12691 if (!knownKeys.has(key)) { 12692 knownKeys.add(key); 12693 break; 12694 } 12695 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); 12696 break; 12697 default: 12698 break; 12699 } 12700 } 12701 return knownKeys; 12702 } 12703 12704 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) { 12705 // This algorithm can't optimize by searching from boths ends since we 12706 // don't have backpointers on fibers. I'm trying to see how far we can get 12707 // with that model. If it ends up not being worth the tradeoffs, we can 12708 // add it later. 12709 12710 // Even with a two ended optimization, we'd want to optimize for the case 12711 // where there are few changes and brute force the comparison instead of 12712 // going for the Map. It'd like to explore hitting that path first in 12713 // forward-only mode and only go for the Map once we notice that we need 12714 // lots of look ahead. This doesn't handle reversal as well as two ended 12715 // search but that's unusual. Besides, for the two ended optimization to 12716 // work on Iterables, we'd need to copy the whole set. 12717 12718 // In this first iteration, we'll just live with hitting the bad case 12719 // (adding everything to a Map) in for every insert/move. 12720 12721 // If you change this code, also update reconcileChildrenIterator() which 12722 // uses the same algorithm. 12723 12724 { 12725 // First, validate keys. 12726 var knownKeys = null; 12727 for (var i = 0; i < newChildren.length; i++) { 12728 var child = newChildren[i]; 12729 knownKeys = warnOnInvalidKey(child, knownKeys); 12730 } 12731 } 12732 12733 var resultingFirstChild = null; 12734 var previousNewFiber = null; 12735 12736 var oldFiber = currentFirstChild; 12737 var lastPlacedIndex = 0; 12738 var newIdx = 0; 12739 var nextOldFiber = null; 12740 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) { 12741 if (oldFiber.index > newIdx) { 12742 nextOldFiber = oldFiber; 12743 oldFiber = null; 12744 } else { 12745 nextOldFiber = oldFiber.sibling; 12746 } 12747 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime); 12748 if (newFiber === null) { 12749 // TODO: This breaks on empty slots like null children. That's 12750 // unfortunate because it triggers the slow path all the time. We need 12751 // a better way to communicate whether this was a miss or null, 12752 // boolean, undefined, etc. 12753 if (oldFiber === null) { 12754 oldFiber = nextOldFiber; 12755 } 12756 break; 12757 } 12758 if (shouldTrackSideEffects) { 12759 if (oldFiber && newFiber.alternate === null) { 12760 // We matched the slot, but we didn't reuse the existing fiber, so we 12761 // need to delete the existing child. 12762 deleteChild(returnFiber, oldFiber); 12763 } 12764 } 12765 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx); 12766 if (previousNewFiber === null) { 12767 // TODO: Move out of the loop. This only happens for the first run. 12768 resultingFirstChild = newFiber; 12769 } else { 12770 // TODO: Defer siblings if we're not at the right index for this slot. 12771 // I.e. if we had null values before, then we want to defer this 12772 // for each null value. However, we also don't want to call updateSlot 12773 // with the previous one. 12774 previousNewFiber.sibling = newFiber; 12775 } 12776 previousNewFiber = newFiber; 12777 oldFiber = nextOldFiber; 12778 } 12779 12780 if (newIdx === newChildren.length) { 12781 // We've reached the end of the new children. We can delete the rest. 12782 deleteRemainingChildren(returnFiber, oldFiber); 12783 return resultingFirstChild; 12784 } 12785 12786 if (oldFiber === null) { 12787 // If we don't have any more existing children we can choose a fast path 12788 // since the rest will all be insertions. 12789 for (; newIdx < newChildren.length; newIdx++) { 12790 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime); 12791 if (!_newFiber) { 12792 continue; 12793 } 12794 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx); 12795 if (previousNewFiber === null) { 12796 // TODO: Move out of the loop. This only happens for the first run. 12797 resultingFirstChild = _newFiber; 12798 } else { 12799 previousNewFiber.sibling = _newFiber; 12800 } 12801 previousNewFiber = _newFiber; 12802 } 12803 return resultingFirstChild; 12804 } 12805 12806 // Add all children to a key map for quick lookups. 12807 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); 12808 12809 // Keep scanning and use the map to restore deleted items as moves. 12810 for (; newIdx < newChildren.length; newIdx++) { 12811 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime); 12812 if (_newFiber2) { 12813 if (shouldTrackSideEffects) { 12814 if (_newFiber2.alternate !== null) { 12815 // The new fiber is a work in progress, but if there exists a 12816 // current, that means that we reused the fiber. We need to delete 12817 // it from the child list so that we don't add it to the deletion 12818 // list. 12819 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key); 12820 } 12821 } 12822 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx); 12823 if (previousNewFiber === null) { 12824 resultingFirstChild = _newFiber2; 12825 } else { 12826 previousNewFiber.sibling = _newFiber2; 12827 } 12828 previousNewFiber = _newFiber2; 12829 } 12830 } 12831 12832 if (shouldTrackSideEffects) { 12833 // Any existing children that weren't consumed above were deleted. We need 12834 // to add them to the deletion list. 12835 existingChildren.forEach(function (child) { 12836 return deleteChild(returnFiber, child); 12837 }); 12838 } 12839 12840 return resultingFirstChild; 12841 } 12842 12843 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) { 12844 // This is the same implementation as reconcileChildrenArray(), 12845 // but using the iterator instead. 12846 12847 var iteratorFn = getIteratorFn(newChildrenIterable); 12848 !(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; 12849 12850 { 12851 // We don't support rendering Generators because it's a mutation. 12852 // See https://github.com/facebook/react/issues/12995 12853 if (typeof Symbol === 'function' && 12854 // $FlowFixMe Flow doesn't know about toStringTag 12855 newChildrenIterable[Symbol.toStringTag] === 'Generator') { 12856 !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; 12857 didWarnAboutGenerators = true; 12858 } 12859 12860 // Warn about using Maps as children 12861 if (newChildrenIterable.entries === iteratorFn) { 12862 !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; 12863 didWarnAboutMaps = true; 12864 } 12865 12866 // First, validate keys. 12867 // We'll get a different iterator later for the main pass. 12868 var _newChildren = iteratorFn.call(newChildrenIterable); 12869 if (_newChildren) { 12870 var knownKeys = null; 12871 var _step = _newChildren.next(); 12872 for (; !_step.done; _step = _newChildren.next()) { 12873 var child = _step.value; 12874 knownKeys = warnOnInvalidKey(child, knownKeys); 12875 } 12876 } 12877 } 12878 12879 var newChildren = iteratorFn.call(newChildrenIterable); 12880 !(newChildren != null) ? invariant(false, 'An iterable object provided no iterator.') : void 0; 12881 12882 var resultingFirstChild = null; 12883 var previousNewFiber = null; 12884 12885 var oldFiber = currentFirstChild; 12886 var lastPlacedIndex = 0; 12887 var newIdx = 0; 12888 var nextOldFiber = null; 12889 12890 var step = newChildren.next(); 12891 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) { 12892 if (oldFiber.index > newIdx) { 12893 nextOldFiber = oldFiber; 12894 oldFiber = null; 12895 } else { 12896 nextOldFiber = oldFiber.sibling; 12897 } 12898 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime); 12899 if (newFiber === null) { 12900 // TODO: This breaks on empty slots like null children. That's 12901 // unfortunate because it triggers the slow path all the time. We need 12902 // a better way to communicate whether this was a miss or null, 12903 // boolean, undefined, etc. 12904 if (!oldFiber) { 12905 oldFiber = nextOldFiber; 12906 } 12907 break; 12908 } 12909 if (shouldTrackSideEffects) { 12910 if (oldFiber && newFiber.alternate === null) { 12911 // We matched the slot, but we didn't reuse the existing fiber, so we 12912 // need to delete the existing child. 12913 deleteChild(returnFiber, oldFiber); 12914 } 12915 } 12916 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx); 12917 if (previousNewFiber === null) { 12918 // TODO: Move out of the loop. This only happens for the first run. 12919 resultingFirstChild = newFiber; 12920 } else { 12921 // TODO: Defer siblings if we're not at the right index for this slot. 12922 // I.e. if we had null values before, then we want to defer this 12923 // for each null value. However, we also don't want to call updateSlot 12924 // with the previous one. 12925 previousNewFiber.sibling = newFiber; 12926 } 12927 previousNewFiber = newFiber; 12928 oldFiber = nextOldFiber; 12929 } 12930 12931 if (step.done) { 12932 // We've reached the end of the new children. We can delete the rest. 12933 deleteRemainingChildren(returnFiber, oldFiber); 12934 return resultingFirstChild; 12935 } 12936 12937 if (oldFiber === null) { 12938 // If we don't have any more existing children we can choose a fast path 12939 // since the rest will all be insertions. 12940 for (; !step.done; newIdx++, step = newChildren.next()) { 12941 var _newFiber3 = createChild(returnFiber, step.value, expirationTime); 12942 if (_newFiber3 === null) { 12943 continue; 12944 } 12945 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx); 12946 if (previousNewFiber === null) { 12947 // TODO: Move out of the loop. This only happens for the first run. 12948 resultingFirstChild = _newFiber3; 12949 } else { 12950 previousNewFiber.sibling = _newFiber3; 12951 } 12952 previousNewFiber = _newFiber3; 12953 } 12954 return resultingFirstChild; 12955 } 12956 12957 // Add all children to a key map for quick lookups. 12958 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); 12959 12960 // Keep scanning and use the map to restore deleted items as moves. 12961 for (; !step.done; newIdx++, step = newChildren.next()) { 12962 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime); 12963 if (_newFiber4 !== null) { 12964 if (shouldTrackSideEffects) { 12965 if (_newFiber4.alternate !== null) { 12966 // The new fiber is a work in progress, but if there exists a 12967 // current, that means that we reused the fiber. We need to delete 12968 // it from the child list so that we don't add it to the deletion 12969 // list. 12970 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key); 12971 } 12972 } 12973 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx); 12974 if (previousNewFiber === null) { 12975 resultingFirstChild = _newFiber4; 12976 } else { 12977 previousNewFiber.sibling = _newFiber4; 12978 } 12979 previousNewFiber = _newFiber4; 12980 } 12981 } 12982 12983 if (shouldTrackSideEffects) { 12984 // Any existing children that weren't consumed above were deleted. We need 12985 // to add them to the deletion list. 12986 existingChildren.forEach(function (child) { 12987 return deleteChild(returnFiber, child); 12988 }); 12989 } 12990 12991 return resultingFirstChild; 12992 } 12993 12994 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) { 12995 // There's no need to check for keys on text nodes since we don't have a 12996 // way to define them. 12997 if (currentFirstChild !== null && currentFirstChild.tag === HostText) { 12998 // We already have an existing node so let's just update it and delete 12999 // the rest. 13000 deleteRemainingChildren(returnFiber, currentFirstChild.sibling); 13001 var existing = useFiber(currentFirstChild, textContent, expirationTime); 13002 existing.return = returnFiber; 13003 return existing; 13004 } 13005 // The existing first child is not a text node so we need to create one 13006 // and delete the existing ones. 13007 deleteRemainingChildren(returnFiber, currentFirstChild); 13008 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime); 13009 created.return = returnFiber; 13010 return created; 13011 } 13012 13013 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) { 13014 var key = element.key; 13015 var child = currentFirstChild; 13016 while (child !== null) { 13017 // TODO: If key === null and child.key === null, then this only applies to 13018 // the first item in the list. 13019 if (child.key === key) { 13020 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.type === element.type) { 13021 deleteRemainingChildren(returnFiber, child.sibling); 13022 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime); 13023 existing.ref = coerceRef(returnFiber, child, element); 13024 existing.return = returnFiber; 13025 { 13026 existing._debugSource = element._source; 13027 existing._debugOwner = element._owner; 13028 } 13029 return existing; 13030 } else { 13031 deleteRemainingChildren(returnFiber, child); 13032 break; 13033 } 13034 } else { 13035 deleteChild(returnFiber, child); 13036 } 13037 child = child.sibling; 13038 } 13039 13040 if (element.type === REACT_FRAGMENT_TYPE) { 13041 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key); 13042 created.return = returnFiber; 13043 return created; 13044 } else { 13045 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime); 13046 _created4.ref = coerceRef(returnFiber, currentFirstChild, element); 13047 _created4.return = returnFiber; 13048 return _created4; 13049 } 13050 } 13051 13052 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) { 13053 var key = portal.key; 13054 var child = currentFirstChild; 13055 while (child !== null) { 13056 // TODO: If key === null and child.key === null, then this only applies to 13057 // the first item in the list. 13058 if (child.key === key) { 13059 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) { 13060 deleteRemainingChildren(returnFiber, child.sibling); 13061 var existing = useFiber(child, portal.children || [], expirationTime); 13062 existing.return = returnFiber; 13063 return existing; 13064 } else { 13065 deleteRemainingChildren(returnFiber, child); 13066 break; 13067 } 13068 } else { 13069 deleteChild(returnFiber, child); 13070 } 13071 child = child.sibling; 13072 } 13073 13074 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime); 13075 created.return = returnFiber; 13076 return created; 13077 } 13078 13079 // This API will tag the children with the side-effect of the reconciliation 13080 // itself. They will be added to the side-effect list as we pass through the 13081 // children and the parent. 13082 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) { 13083 // This function is not recursive. 13084 // If the top level item is an array, we treat it as a set of children, 13085 // not as a fragment. Nested arrays on the other hand will be treated as 13086 // fragment nodes. Recursion happens at the normal flow. 13087 13088 // Handle top level unkeyed fragments as if they were arrays. 13089 // This leads to an ambiguity between <>{[...]}</> and <>...</>. 13090 // We treat the ambiguous cases above the same. 13091 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null; 13092 if (isUnkeyedTopLevelFragment) { 13093 newChild = newChild.props.children; 13094 } 13095 13096 // Handle object types 13097 var isObject = typeof newChild === 'object' && newChild !== null; 13098 13099 if (isObject) { 13100 switch (newChild.$$typeof) { 13101 case REACT_ELEMENT_TYPE: 13102 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime)); 13103 case REACT_PORTAL_TYPE: 13104 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime)); 13105 } 13106 } 13107 13108 if (typeof newChild === 'string' || typeof newChild === 'number') { 13109 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime)); 13110 } 13111 13112 if (isArray$1(newChild)) { 13113 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime); 13114 } 13115 13116 if (getIteratorFn(newChild)) { 13117 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime); 13118 } 13119 13120 if (isObject) { 13121 throwOnInvalidObjectType(returnFiber, newChild); 13122 } 13123 13124 { 13125 if (typeof newChild === 'function') { 13126 warnOnFunctionType(); 13127 } 13128 } 13129 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) { 13130 // If the new child is undefined, and the return fiber is a composite 13131 // component, throw an error. If Fiber return types are disabled, 13132 // we already threw above. 13133 switch (returnFiber.tag) { 13134 case ClassComponent: 13135 case ClassComponentLazy: 13136 { 13137 { 13138 var instance = returnFiber.stateNode; 13139 if (instance.render._isMockFunction) { 13140 // We allow auto-mocks to proceed as if they're returning null. 13141 break; 13142 } 13143 } 13144 } 13145 // Intentionally fall through to the next case, which handles both 13146 // functions and classes 13147 // eslint-disable-next-lined no-fallthrough 13148 case FunctionalComponent: 13149 { 13150 var Component = returnFiber.type; 13151 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'); 13152 } 13153 } 13154 } 13155 13156 // Remaining cases are all treated as empty. 13157 return deleteRemainingChildren(returnFiber, currentFirstChild); 13158 } 13159 13160 return reconcileChildFibers; 13161 } 13162 13163 var reconcileChildFibers = ChildReconciler(true); 13164 var mountChildFibers = ChildReconciler(false); 13165 13166 function cloneChildFibers(current$$1, workInProgress) { 13167 !(current$$1 === null || workInProgress.child === current$$1.child) ? invariant(false, 'Resuming work not yet implemented.') : void 0; 13168 13169 if (workInProgress.child === null) { 13170 return; 13171 } 13172 13173 var currentChild = workInProgress.child; 13174 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime); 13175 workInProgress.child = newChild; 13176 13177 newChild.return = workInProgress; 13178 while (currentChild.sibling !== null) { 13179 currentChild = currentChild.sibling; 13180 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime); 13181 newChild.return = workInProgress; 13182 } 13183 newChild.sibling = null; 13184 } 13185 13186 // The deepest Fiber on the stack involved in a hydration context. 13187 // This may have been an insertion or a hydration. 13188 var hydrationParentFiber = null; 13189 var nextHydratableInstance = null; 13190 var isHydrating = false; 13191 13192 function enterHydrationState(fiber) { 13193 if (!supportsHydration) { 13194 return false; 13195 } 13196 13197 var parentInstance = fiber.stateNode.containerInfo; 13198 nextHydratableInstance = getFirstHydratableChild(parentInstance); 13199 hydrationParentFiber = fiber; 13200 isHydrating = true; 13201 return true; 13202 } 13203 13204 function deleteHydratableInstance(returnFiber, instance) { 13205 { 13206 switch (returnFiber.tag) { 13207 case HostRoot: 13208 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance); 13209 break; 13210 case HostComponent: 13211 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance); 13212 break; 13213 } 13214 } 13215 13216 var childToDelete = createFiberFromHostInstanceForDeletion(); 13217 childToDelete.stateNode = instance; 13218 childToDelete.return = returnFiber; 13219 childToDelete.effectTag = Deletion; 13220 13221 // This might seem like it belongs on progressedFirstDeletion. However, 13222 // these children are not part of the reconciliation list of children. 13223 // Even if we abort and rereconcile the children, that will try to hydrate 13224 // again and the nodes are still in the host tree so these will be 13225 // recreated. 13226 if (returnFiber.lastEffect !== null) { 13227 returnFiber.lastEffect.nextEffect = childToDelete; 13228 returnFiber.lastEffect = childToDelete; 13229 } else { 13230 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; 13231 } 13232 } 13233 13234 function insertNonHydratedInstance(returnFiber, fiber) { 13235 fiber.effectTag |= Placement; 13236 { 13237 switch (returnFiber.tag) { 13238 case HostRoot: 13239 { 13240 var parentContainer = returnFiber.stateNode.containerInfo; 13241 switch (fiber.tag) { 13242 case HostComponent: 13243 var type = fiber.type; 13244 var props = fiber.pendingProps; 13245 didNotFindHydratableContainerInstance(parentContainer, type, props); 13246 break; 13247 case HostText: 13248 var text = fiber.pendingProps; 13249 didNotFindHydratableContainerTextInstance(parentContainer, text); 13250 break; 13251 } 13252 break; 13253 } 13254 case HostComponent: 13255 { 13256 var parentType = returnFiber.type; 13257 var parentProps = returnFiber.memoizedProps; 13258 var parentInstance = returnFiber.stateNode; 13259 switch (fiber.tag) { 13260 case HostComponent: 13261 var _type = fiber.type; 13262 var _props = fiber.pendingProps; 13263 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props); 13264 break; 13265 case HostText: 13266 var _text = fiber.pendingProps; 13267 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text); 13268 break; 13269 } 13270 break; 13271 } 13272 default: 13273 return; 13274 } 13275 } 13276 } 13277 13278 function tryHydrate(fiber, nextInstance) { 13279 switch (fiber.tag) { 13280 case HostComponent: 13281 { 13282 var type = fiber.type; 13283 var props = fiber.pendingProps; 13284 var instance = canHydrateInstance(nextInstance, type, props); 13285 if (instance !== null) { 13286 fiber.stateNode = instance; 13287 return true; 13288 } 13289 return false; 13290 } 13291 case HostText: 13292 { 13293 var text = fiber.pendingProps; 13294 var textInstance = canHydrateTextInstance(nextInstance, text); 13295 if (textInstance !== null) { 13296 fiber.stateNode = textInstance; 13297 return true; 13298 } 13299 return false; 13300 } 13301 default: 13302 return false; 13303 } 13304 } 13305 13306 function tryToClaimNextHydratableInstance(fiber) { 13307 if (!isHydrating) { 13308 return; 13309 } 13310 var nextInstance = nextHydratableInstance; 13311 if (!nextInstance) { 13312 // Nothing to hydrate. Make it an insertion. 13313 insertNonHydratedInstance(hydrationParentFiber, fiber); 13314 isHydrating = false; 13315 hydrationParentFiber = fiber; 13316 return; 13317 } 13318 var firstAttemptedInstance = nextInstance; 13319 if (!tryHydrate(fiber, nextInstance)) { 13320 // If we can't hydrate this instance let's try the next one. 13321 // We use this as a heuristic. It's based on intuition and not data so it 13322 // might be flawed or unnecessary. 13323 nextInstance = getNextHydratableSibling(firstAttemptedInstance); 13324 if (!nextInstance || !tryHydrate(fiber, nextInstance)) { 13325 // Nothing to hydrate. Make it an insertion. 13326 insertNonHydratedInstance(hydrationParentFiber, fiber); 13327 isHydrating = false; 13328 hydrationParentFiber = fiber; 13329 return; 13330 } 13331 // We matched the next one, we'll now assume that the first one was 13332 // superfluous and we'll delete it. Since we can't eagerly delete it 13333 // we'll have to schedule a deletion. To do that, this node needs a dummy 13334 // fiber associated with it. 13335 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance); 13336 } 13337 hydrationParentFiber = fiber; 13338 nextHydratableInstance = getFirstHydratableChild(nextInstance); 13339 } 13340 13341 function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) { 13342 if (!supportsHydration) { 13343 invariant(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'); 13344 } 13345 13346 var instance = fiber.stateNode; 13347 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber); 13348 // TODO: Type this specific to this type of component. 13349 fiber.updateQueue = updatePayload; 13350 // If the update payload indicates that there is a change or if there 13351 // is a new ref we mark this as an update. 13352 if (updatePayload !== null) { 13353 return true; 13354 } 13355 return false; 13356 } 13357 13358 function prepareToHydrateHostTextInstance(fiber) { 13359 if (!supportsHydration) { 13360 invariant(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'); 13361 } 13362 13363 var textInstance = fiber.stateNode; 13364 var textContent = fiber.memoizedProps; 13365 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber); 13366 { 13367 if (shouldUpdate) { 13368 // We assume that prepareToHydrateHostTextInstance is called in a context where the 13369 // hydration parent is the parent host component of this host text. 13370 var returnFiber = hydrationParentFiber; 13371 if (returnFiber !== null) { 13372 switch (returnFiber.tag) { 13373 case HostRoot: 13374 { 13375 var parentContainer = returnFiber.stateNode.containerInfo; 13376 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent); 13377 break; 13378 } 13379 case HostComponent: 13380 { 13381 var parentType = returnFiber.type; 13382 var parentProps = returnFiber.memoizedProps; 13383 var parentInstance = returnFiber.stateNode; 13384 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent); 13385 break; 13386 } 13387 } 13388 } 13389 } 13390 } 13391 return shouldUpdate; 13392 } 13393 13394 function popToNextHostParent(fiber) { 13395 var parent = fiber.return; 13396 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot) { 13397 parent = parent.return; 13398 } 13399 hydrationParentFiber = parent; 13400 } 13401 13402 function popHydrationState(fiber) { 13403 if (!supportsHydration) { 13404 return false; 13405 } 13406 if (fiber !== hydrationParentFiber) { 13407 // We're deeper than the current hydration context, inside an inserted 13408 // tree. 13409 return false; 13410 } 13411 if (!isHydrating) { 13412 // If we're not currently hydrating but we're in a hydration context, then 13413 // we were an insertion and now need to pop up reenter hydration of our 13414 // siblings. 13415 popToNextHostParent(fiber); 13416 isHydrating = true; 13417 return false; 13418 } 13419 13420 var type = fiber.type; 13421 13422 // If we have any remaining hydratable nodes, we need to delete them now. 13423 // We only do this deeper than head and body since they tend to have random 13424 // other nodes in them. We also ignore components with pure text content in 13425 // side of them. 13426 // TODO: Better heuristic. 13427 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) { 13428 var nextInstance = nextHydratableInstance; 13429 while (nextInstance) { 13430 deleteHydratableInstance(fiber, nextInstance); 13431 nextInstance = getNextHydratableSibling(nextInstance); 13432 } 13433 } 13434 13435 popToNextHostParent(fiber); 13436 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null; 13437 return true; 13438 } 13439 13440 function resetHydrationState() { 13441 if (!supportsHydration) { 13442 return; 13443 } 13444 13445 hydrationParentFiber = null; 13446 nextHydratableInstance = null; 13447 isHydrating = false; 13448 } 13449 13450 function readLazyComponentType(thenable) { 13451 var status = thenable._reactStatus; 13452 switch (status) { 13453 case Resolved: 13454 var Component = thenable._reactResult; 13455 return Component; 13456 case Rejected: 13457 throw thenable._reactResult; 13458 case Pending: 13459 throw thenable; 13460 default: 13461 { 13462 thenable._reactStatus = Pending; 13463 thenable.then(function (resolvedValue) { 13464 if (thenable._reactStatus === Pending) { 13465 thenable._reactStatus = Resolved; 13466 if (typeof resolvedValue === 'object' && resolvedValue !== null) { 13467 // If the `default` property is not empty, assume it's the result 13468 // of an async import() and use that. Otherwise, use the 13469 // resolved value itself. 13470 var defaultExport = resolvedValue.default; 13471 resolvedValue = defaultExport !== undefined && defaultExport !== null ? defaultExport : resolvedValue; 13472 } else { 13473 resolvedValue = resolvedValue; 13474 } 13475 thenable._reactResult = resolvedValue; 13476 } 13477 }, function (error) { 13478 if (thenable._reactStatus === Pending) { 13479 thenable._reactStatus = Rejected; 13480 thenable._reactResult = error; 13481 } 13482 }); 13483 throw thenable; 13484 } 13485 } 13486 } 13487 13488 var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; 13489 13490 var didWarnAboutBadClass = void 0; 13491 var didWarnAboutGetDerivedStateOnFunctionalComponent = void 0; 13492 var didWarnAboutStatelessRefs = void 0; 13493 13494 { 13495 didWarnAboutBadClass = {}; 13496 didWarnAboutGetDerivedStateOnFunctionalComponent = {}; 13497 didWarnAboutStatelessRefs = {}; 13498 } 13499 13500 function reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime) { 13501 if (current$$1 === null) { 13502 // If this is a fresh new component that hasn't been rendered yet, we 13503 // won't update its child set by applying minimal side-effects. Instead, 13504 // we will add them all to the child before it gets rendered. That means 13505 // we can optimize this reconciliation pass by not tracking side-effects. 13506 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime); 13507 } else { 13508 // If the current child is the same as the work in progress, it means that 13509 // we haven't yet started any work on these children. Therefore, we use 13510 // the clone algorithm to create a copy of all the current children. 13511 13512 // If we had any progressed work already, that is invalid at this point so 13513 // let's throw it out. 13514 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, nextChildren, renderExpirationTime); 13515 } 13516 } 13517 13518 function updateForwardRef(current$$1, workInProgress, type, nextProps, renderExpirationTime) { 13519 var render = type.render; 13520 var ref = workInProgress.ref; 13521 if (hasContextChanged()) { 13522 // Normally we can bail out on props equality but if context has changed 13523 // we don't do the bailout and we have to reuse existing props instead. 13524 } else if (workInProgress.memoizedProps === nextProps) { 13525 var currentRef = current$$1 !== null ? current$$1.ref : null; 13526 if (ref === currentRef) { 13527 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime); 13528 } 13529 } 13530 13531 var nextChildren = void 0; 13532 { 13533 ReactCurrentOwner$3.current = workInProgress; 13534 setCurrentPhase('render'); 13535 nextChildren = render(nextProps, ref); 13536 setCurrentPhase(null); 13537 } 13538 13539 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 13540 memoizeProps(workInProgress, nextProps); 13541 return workInProgress.child; 13542 } 13543 13544 function updateFragment(current$$1, workInProgress, renderExpirationTime) { 13545 var nextChildren = workInProgress.pendingProps; 13546 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 13547 memoizeProps(workInProgress, nextChildren); 13548 return workInProgress.child; 13549 } 13550 13551 function updateMode(current$$1, workInProgress, renderExpirationTime) { 13552 var nextChildren = workInProgress.pendingProps.children; 13553 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 13554 memoizeProps(workInProgress, nextChildren); 13555 return workInProgress.child; 13556 } 13557 13558 function updateProfiler(current$$1, workInProgress, renderExpirationTime) { 13559 if (enableProfilerTimer) { 13560 workInProgress.effectTag |= Update; 13561 } 13562 var nextProps = workInProgress.pendingProps; 13563 var nextChildren = nextProps.children; 13564 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 13565 memoizeProps(workInProgress, nextProps); 13566 return workInProgress.child; 13567 } 13568 13569 function markRef(current$$1, workInProgress) { 13570 var ref = workInProgress.ref; 13571 if (current$$1 === null && ref !== null || current$$1 !== null && current$$1.ref !== ref) { 13572 // Schedule a Ref effect 13573 workInProgress.effectTag |= Ref; 13574 } 13575 } 13576 13577 function updateFunctionalComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) { 13578 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); 13579 var context = getMaskedContext(workInProgress, unmaskedContext); 13580 13581 var nextChildren = void 0; 13582 prepareToReadContext(workInProgress, renderExpirationTime); 13583 { 13584 ReactCurrentOwner$3.current = workInProgress; 13585 setCurrentPhase('render'); 13586 nextChildren = Component(nextProps, context); 13587 setCurrentPhase(null); 13588 } 13589 13590 // React DevTools reads this flag. 13591 workInProgress.effectTag |= PerformedWork; 13592 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 13593 memoizeProps(workInProgress, nextProps); 13594 return workInProgress.child; 13595 } 13596 13597 function updateClassComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) { 13598 // Push context providers early to prevent context stack mismatches. 13599 // During mounting we don't know the child context yet as the instance doesn't exist. 13600 // We will invalidate the child context in finishClassComponent() right after rendering. 13601 var hasContext = void 0; 13602 if (isContextProvider(Component)) { 13603 hasContext = true; 13604 pushContextProvider(workInProgress); 13605 } else { 13606 hasContext = false; 13607 } 13608 prepareToReadContext(workInProgress, renderExpirationTime); 13609 13610 var shouldUpdate = void 0; 13611 if (current$$1 === null) { 13612 if (workInProgress.stateNode === null) { 13613 // In the initial pass we might need to construct the instance. 13614 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime); 13615 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime); 13616 shouldUpdate = true; 13617 } else { 13618 // In a resume, we'll already have an instance we can reuse. 13619 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime); 13620 } 13621 } else { 13622 shouldUpdate = updateClassInstance(current$$1, workInProgress, Component, nextProps, renderExpirationTime); 13623 } 13624 return finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime); 13625 } 13626 13627 function finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) { 13628 // Refs should update even if shouldComponentUpdate returns false 13629 markRef(current$$1, workInProgress); 13630 13631 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect; 13632 13633 if (!shouldUpdate && !didCaptureError) { 13634 // Context providers should defer to sCU for rendering 13635 if (hasContext) { 13636 invalidateContextProvider(workInProgress, Component, false); 13637 } 13638 13639 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime); 13640 } 13641 13642 var instance = workInProgress.stateNode; 13643 13644 // Rerender 13645 ReactCurrentOwner$3.current = workInProgress; 13646 var nextChildren = void 0; 13647 if (didCaptureError && (!enableGetDerivedStateFromCatch || typeof Component.getDerivedStateFromCatch !== 'function')) { 13648 // If we captured an error, but getDerivedStateFrom catch is not defined, 13649 // unmount all the children. componentDidCatch will schedule an update to 13650 // re-render a fallback. This is temporary until we migrate everyone to 13651 // the new API. 13652 // TODO: Warn in a future release. 13653 nextChildren = null; 13654 13655 if (enableProfilerTimer) { 13656 stopProfilerTimerIfRunning(workInProgress); 13657 } 13658 } else { 13659 { 13660 setCurrentPhase('render'); 13661 nextChildren = instance.render(); 13662 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) { 13663 instance.render(); 13664 } 13665 setCurrentPhase(null); 13666 } 13667 } 13668 13669 // React DevTools reads this flag. 13670 workInProgress.effectTag |= PerformedWork; 13671 if (current$$1 !== null && didCaptureError) { 13672 // If we're recovering from an error, reconcile twice: first to delete 13673 // all the existing children. 13674 reconcileChildren(current$$1, workInProgress, null, renderExpirationTime); 13675 workInProgress.child = null; 13676 // Now we can continue reconciling like normal. This has the effect of 13677 // remounting all children regardless of whether their their 13678 // identity matches. 13679 } 13680 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 13681 // Memoize props and state using the values we just used to render. 13682 // TODO: Restructure so we never read values from the instance. 13683 memoizeState(workInProgress, instance.state); 13684 memoizeProps(workInProgress, instance.props); 13685 13686 // The context might have changed so we need to recalculate it. 13687 if (hasContext) { 13688 invalidateContextProvider(workInProgress, Component, true); 13689 } 13690 13691 return workInProgress.child; 13692 } 13693 13694 function pushHostRootContext(workInProgress) { 13695 var root = workInProgress.stateNode; 13696 if (root.pendingContext) { 13697 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context); 13698 } else if (root.context) { 13699 // Should always be set 13700 pushTopLevelContextObject(workInProgress, root.context, false); 13701 } 13702 pushHostContainer(workInProgress, root.containerInfo); 13703 } 13704 13705 function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { 13706 pushHostRootContext(workInProgress); 13707 var updateQueue = workInProgress.updateQueue; 13708 !(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; 13709 var nextProps = workInProgress.pendingProps; 13710 var prevState = workInProgress.memoizedState; 13711 var prevChildren = prevState !== null ? prevState.element : null; 13712 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime); 13713 var nextState = workInProgress.memoizedState; 13714 // Caution: React DevTools currently depends on this property 13715 // being called "element". 13716 var nextChildren = nextState.element; 13717 if (nextChildren === prevChildren) { 13718 // If the state is the same as before, that's a bailout because we had 13719 // no work that expires at this time. 13720 resetHydrationState(); 13721 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime); 13722 } 13723 var root = workInProgress.stateNode; 13724 if ((current$$1 === null || current$$1.child === null) && root.hydrate && enterHydrationState(workInProgress)) { 13725 // If we don't have any current children this might be the first pass. 13726 // We always try to hydrate. If this isn't a hydration pass there won't 13727 // be any children to hydrate which is effectively the same thing as 13728 // not hydrating. 13729 13730 // This is a bit of a hack. We track the host root as a placement to 13731 // know that we're currently in a mounting state. That way isMounted 13732 // works as expected. We must reset this before committing. 13733 // TODO: Delete this when we delete isMounted and findDOMNode. 13734 workInProgress.effectTag |= Placement; 13735 13736 // Ensure that children mount into this root without tracking 13737 // side-effects. This ensures that we don't store Placement effects on 13738 // nodes that will be hydrated. 13739 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime); 13740 } else { 13741 // Otherwise reset hydration state in case we aborted and resumed another 13742 // root. 13743 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 13744 resetHydrationState(); 13745 } 13746 return workInProgress.child; 13747 } 13748 13749 function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { 13750 pushHostContext(workInProgress); 13751 13752 if (current$$1 === null) { 13753 tryToClaimNextHydratableInstance(workInProgress); 13754 } 13755 13756 var type = workInProgress.type; 13757 var nextProps = workInProgress.pendingProps; 13758 var prevProps = current$$1 !== null ? current$$1.memoizedProps : null; 13759 13760 var nextChildren = nextProps.children; 13761 var isDirectTextChild = shouldSetTextContent(type, nextProps); 13762 13763 if (isDirectTextChild) { 13764 // We special case a direct text child of a host node. This is a common 13765 // case. We won't handle it as a reified child. We will instead handle 13766 // this in the host environment that also have access to this prop. That 13767 // avoids allocating another HostText fiber and traversing it. 13768 nextChildren = null; 13769 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) { 13770 // If we're switching from a direct text child to a normal child, or to 13771 // empty, we need to schedule the text content to be reset. 13772 workInProgress.effectTag |= ContentReset; 13773 } 13774 13775 markRef(current$$1, workInProgress); 13776 13777 // Check the host config to see if the children are offscreen/hidden. 13778 if (renderExpirationTime !== Never && workInProgress.mode & AsyncMode && shouldDeprioritizeSubtree(type, nextProps)) { 13779 // Schedule this fiber to re-render at offscreen priority. Then bailout. 13780 workInProgress.expirationTime = Never; 13781 workInProgress.memoizedProps = nextProps; 13782 return null; 13783 } 13784 13785 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 13786 memoizeProps(workInProgress, nextProps); 13787 return workInProgress.child; 13788 } 13789 13790 function updateHostText(current$$1, workInProgress) { 13791 if (current$$1 === null) { 13792 tryToClaimNextHydratableInstance(workInProgress); 13793 } 13794 var nextProps = workInProgress.pendingProps; 13795 memoizeProps(workInProgress, nextProps); 13796 // Nothing to do here. This is terminal. We'll do the completion step 13797 // immediately after. 13798 return null; 13799 } 13800 13801 function resolveDefaultProps(Component, baseProps) { 13802 if (Component && Component.defaultProps) { 13803 // Resolve default props. Taken from ReactElement 13804 var props = _assign({}, baseProps); 13805 var defaultProps = Component.defaultProps; 13806 for (var propName in defaultProps) { 13807 if (props[propName] === undefined) { 13808 props[propName] = defaultProps[propName]; 13809 } 13810 } 13811 return props; 13812 } 13813 return baseProps; 13814 } 13815 13816 function mountIndeterminateComponent(current$$1, workInProgress, Component, renderExpirationTime) { 13817 !(current$$1 === null) ? invariant(false, 'An indeterminate component should never have mounted. This error is likely caused by a bug in React. Please file an issue.') : void 0; 13818 13819 var props = workInProgress.pendingProps; 13820 if (typeof Component === 'object' && Component !== null && typeof Component.then === 'function') { 13821 Component = readLazyComponentType(Component); 13822 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(workInProgress, Component); 13823 var resolvedProps = resolveDefaultProps(Component, props); 13824 switch (resolvedTag) { 13825 case FunctionalComponentLazy: 13826 { 13827 return updateFunctionalComponent(current$$1, workInProgress, Component, resolvedProps, renderExpirationTime); 13828 } 13829 case ClassComponentLazy: 13830 { 13831 return updateClassComponent(current$$1, workInProgress, Component, resolvedProps, renderExpirationTime); 13832 } 13833 case ForwardRefLazy: 13834 { 13835 return updateForwardRef(current$$1, workInProgress, Component, resolvedProps, renderExpirationTime); 13836 } 13837 default: 13838 { 13839 // This message intentionally doesn't metion ForwardRef because the 13840 // fact that it's a separate type of work is an implementation detail. 13841 invariant(false, 'Element type is invalid. Received a promise that resolves to: %s. Promise elements must resolve to a class or function.', Component); 13842 } 13843 } 13844 } 13845 13846 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); 13847 var context = getMaskedContext(workInProgress, unmaskedContext); 13848 13849 prepareToReadContext(workInProgress, renderExpirationTime); 13850 13851 var value = void 0; 13852 13853 { 13854 if (Component.prototype && typeof Component.prototype.render === 'function') { 13855 var componentName = getComponentName(Component) || 'Unknown'; 13856 13857 if (!didWarnAboutBadClass[componentName]) { 13858 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); 13859 didWarnAboutBadClass[componentName] = true; 13860 } 13861 } 13862 13863 if (workInProgress.mode & StrictMode) { 13864 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); 13865 } 13866 13867 ReactCurrentOwner$3.current = workInProgress; 13868 value = Component(props, context); 13869 } 13870 // React DevTools reads this flag. 13871 workInProgress.effectTag |= PerformedWork; 13872 13873 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) { 13874 // Proceed under the assumption that this is a class instance 13875 workInProgress.tag = ClassComponent; 13876 13877 // Push context providers early to prevent context stack mismatches. 13878 // During mounting we don't know the child context yet as the instance doesn't exist. 13879 // We will invalidate the child context in finishClassComponent() right after rendering. 13880 var hasContext = false; 13881 if (isContextProvider(Component)) { 13882 hasContext = true; 13883 pushContextProvider(workInProgress); 13884 } else { 13885 hasContext = false; 13886 } 13887 13888 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; 13889 13890 var getDerivedStateFromProps = Component.getDerivedStateFromProps; 13891 if (typeof getDerivedStateFromProps === 'function') { 13892 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props); 13893 } 13894 13895 adoptClassInstance(workInProgress, value); 13896 mountClassInstance(workInProgress, Component, props, renderExpirationTime); 13897 return finishClassComponent(current$$1, workInProgress, Component, true, hasContext, renderExpirationTime); 13898 } else { 13899 // Proceed under the assumption that this is a functional component 13900 workInProgress.tag = FunctionalComponent; 13901 { 13902 if (Component) { 13903 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a functional component.', Component.displayName || Component.name || 'Component') : void 0; 13904 } 13905 if (workInProgress.ref !== null) { 13906 var info = ''; 13907 var ownerName = getCurrentFiberOwnerNameInDevOrNull(); 13908 if (ownerName) { 13909 info += '\n\nCheck the render method of `' + ownerName + '`.'; 13910 } 13911 13912 var warningKey = ownerName || workInProgress._debugID || ''; 13913 var debugSource = workInProgress._debugSource; 13914 if (debugSource) { 13915 warningKey = debugSource.fileName + ':' + debugSource.lineNumber; 13916 } 13917 if (!didWarnAboutStatelessRefs[warningKey]) { 13918 didWarnAboutStatelessRefs[warningKey] = true; 13919 warning$1(false, 'Stateless function components cannot be given refs. ' + 'Attempts to access this ref will fail.%s', info); 13920 } 13921 } 13922 13923 if (typeof Component.getDerivedStateFromProps === 'function') { 13924 var _componentName = getComponentName(Component) || 'Unknown'; 13925 13926 if (!didWarnAboutGetDerivedStateOnFunctionalComponent[_componentName]) { 13927 warningWithoutStack$1(false, '%s: Stateless functional components do not support getDerivedStateFromProps.', _componentName); 13928 didWarnAboutGetDerivedStateOnFunctionalComponent[_componentName] = true; 13929 } 13930 } 13931 } 13932 reconcileChildren(current$$1, workInProgress, value, renderExpirationTime); 13933 memoizeProps(workInProgress, props); 13934 return workInProgress.child; 13935 } 13936 } 13937 13938 function updatePlaceholderComponent(current$$1, workInProgress, renderExpirationTime) { 13939 if (enableSuspense) { 13940 var nextProps = workInProgress.pendingProps; 13941 13942 // Check if we already attempted to render the normal state. If we did, 13943 // and we timed out, render the placeholder state. 13944 var alreadyCaptured = (workInProgress.effectTag & DidCapture) === NoEffect; 13945 13946 var nextDidTimeout = void 0; 13947 if (current$$1 !== null && workInProgress.updateQueue !== null) { 13948 // We're outside strict mode. Something inside this Placeholder boundary 13949 // suspended during the last commit. Switch to the placholder. 13950 workInProgress.updateQueue = null; 13951 nextDidTimeout = true; 13952 // If we're recovering from an error, reconcile twice: first to delete 13953 // all the existing children. 13954 reconcileChildren(current$$1, workInProgress, null, renderExpirationTime); 13955 current$$1.child = null; 13956 // Now we can continue reconciling like normal. This has the effect of 13957 // remounting all children regardless of whether their their 13958 // identity matches. 13959 } else { 13960 nextDidTimeout = !alreadyCaptured; 13961 } 13962 13963 if ((workInProgress.mode & StrictMode) !== NoEffect) { 13964 if (nextDidTimeout) { 13965 // If the timed-out view commits, schedule an update effect to record 13966 // the committed time. 13967 workInProgress.effectTag |= Update; 13968 } else { 13969 // The state node points to the time at which placeholder timed out. 13970 // We can clear it once we switch back to the normal children. 13971 workInProgress.stateNode = null; 13972 } 13973 } 13974 13975 // If the `children` prop is a function, treat it like a render prop. 13976 // TODO: This is temporary until we finalize a lower level API. 13977 var children = nextProps.children; 13978 var nextChildren = void 0; 13979 if (typeof children === 'function') { 13980 nextChildren = children(nextDidTimeout); 13981 } else { 13982 nextChildren = nextDidTimeout ? nextProps.fallback : children; 13983 } 13984 13985 workInProgress.memoizedProps = nextProps; 13986 workInProgress.memoizedState = nextDidTimeout; 13987 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 13988 return workInProgress.child; 13989 } else { 13990 return null; 13991 } 13992 } 13993 13994 function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) { 13995 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); 13996 var nextChildren = workInProgress.pendingProps; 13997 if (current$$1 === null) { 13998 // Portals are special because we don't append the children during mount 13999 // but at commit. Therefore we need to track insertions which the normal 14000 // flow doesn't do during mount. This doesn't happen at the root because 14001 // the root always starts with a "current" with a null child. 14002 // TODO: Consider unifying this with how the root works. 14003 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime); 14004 memoizeProps(workInProgress, nextChildren); 14005 } else { 14006 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime); 14007 memoizeProps(workInProgress, nextChildren); 14008 } 14009 return workInProgress.child; 14010 } 14011 14012 function updateContextProvider(current$$1, workInProgress, renderExpirationTime) { 14013 var providerType = workInProgress.type; 14014 var context = providerType._context; 14015 14016 var newProps = workInProgress.pendingProps; 14017 var oldProps = workInProgress.memoizedProps; 14018 14019 var newValue = newProps.value; 14020 workInProgress.memoizedProps = newProps; 14021 14022 { 14023 var providerPropTypes = workInProgress.type.propTypes; 14024 14025 if (providerPropTypes) { 14026 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev); 14027 } 14028 } 14029 14030 pushProvider(workInProgress, newValue); 14031 14032 if (oldProps !== null) { 14033 var oldValue = oldProps.value; 14034 var changedBits = calculateChangedBits(context, newValue, oldValue); 14035 if (changedBits === 0) { 14036 // No change. Bailout early if children are the same. 14037 if (oldProps.children === newProps.children && !hasContextChanged()) { 14038 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime); 14039 } 14040 } else { 14041 // The context value changed. Search for matching consumers and schedule 14042 // them to update. 14043 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime); 14044 } 14045 } 14046 14047 var newChildren = newProps.children; 14048 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime); 14049 return workInProgress.child; 14050 } 14051 14052 function updateContextConsumer(current$$1, workInProgress, renderExpirationTime) { 14053 var context = workInProgress.type; 14054 var newProps = workInProgress.pendingProps; 14055 var render = newProps.children; 14056 14057 { 14058 !(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; 14059 } 14060 14061 prepareToReadContext(workInProgress, renderExpirationTime); 14062 var newValue = readContext(context, newProps.unstable_observedBits); 14063 var newChildren = void 0; 14064 { 14065 ReactCurrentOwner$3.current = workInProgress; 14066 setCurrentPhase('render'); 14067 newChildren = render(newValue); 14068 setCurrentPhase(null); 14069 } 14070 14071 // React DevTools reads this flag. 14072 workInProgress.effectTag |= PerformedWork; 14073 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime); 14074 workInProgress.memoizedProps = newProps; 14075 return workInProgress.child; 14076 } 14077 14078 /* 14079 function reuseChildrenEffects(returnFiber : Fiber, firstChild : Fiber) { 14080 let child = firstChild; 14081 do { 14082 // Ensure that the first and last effect of the parent corresponds 14083 // to the children's first and last effect. 14084 if (!returnFiber.firstEffect) { 14085 returnFiber.firstEffect = child.firstEffect; 14086 } 14087 if (child.lastEffect) { 14088 if (returnFiber.lastEffect) { 14089 returnFiber.lastEffect.nextEffect = child.firstEffect; 14090 } 14091 returnFiber.lastEffect = child.lastEffect; 14092 } 14093 } while (child = child.sibling); 14094 } 14095 */ 14096 14097 function bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime) { 14098 cancelWorkTimer(workInProgress); 14099 14100 if (current$$1 !== null) { 14101 // Reuse previous context list 14102 workInProgress.firstContextDependency = current$$1.firstContextDependency; 14103 } 14104 14105 if (enableProfilerTimer) { 14106 // Don't update "base" render times for bailouts. 14107 stopProfilerTimerIfRunning(workInProgress); 14108 } 14109 14110 // Check if the children have any pending work. 14111 var childExpirationTime = workInProgress.childExpirationTime; 14112 if (childExpirationTime === NoWork || childExpirationTime > renderExpirationTime) { 14113 // The children don't have any work either. We can skip them. 14114 // TODO: Once we add back resuming, we should check if the children are 14115 // a work-in-progress set. If so, we need to transfer their effects. 14116 return null; 14117 } else { 14118 // This fiber doesn't have work, but its subtree does. Clone the child 14119 // fibers and continue. 14120 cloneChildFibers(current$$1, workInProgress); 14121 return workInProgress.child; 14122 } 14123 } 14124 14125 // TODO: Delete memoizeProps/State and move to reconcile/bailout instead 14126 function memoizeProps(workInProgress, nextProps) { 14127 workInProgress.memoizedProps = nextProps; 14128 } 14129 14130 function memoizeState(workInProgress, nextState) { 14131 workInProgress.memoizedState = nextState; 14132 // Don't reset the updateQueue, in case there are pending updates. Resetting 14133 // is handled by processUpdateQueue. 14134 } 14135 14136 function beginWork(current$$1, workInProgress, renderExpirationTime) { 14137 var updateExpirationTime = workInProgress.expirationTime; 14138 if (!hasContextChanged() && (updateExpirationTime === NoWork || updateExpirationTime > renderExpirationTime)) { 14139 // This fiber does not have any pending work. Bailout without entering 14140 // the begin phase. There's still some bookkeeping we that needs to be done 14141 // in this optimized path, mostly pushing stuff onto the stack. 14142 switch (workInProgress.tag) { 14143 case HostRoot: 14144 pushHostRootContext(workInProgress); 14145 resetHydrationState(); 14146 break; 14147 case HostComponent: 14148 pushHostContext(workInProgress); 14149 break; 14150 case ClassComponent: 14151 { 14152 var Component = workInProgress.type; 14153 if (isContextProvider(Component)) { 14154 pushContextProvider(workInProgress); 14155 } 14156 break; 14157 } 14158 case ClassComponentLazy: 14159 { 14160 var thenable = workInProgress.type; 14161 var _Component = getResultFromResolvedThenable(thenable); 14162 if (isContextProvider(_Component)) { 14163 pushContextProvider(workInProgress); 14164 } 14165 break; 14166 } 14167 case HostPortal: 14168 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); 14169 break; 14170 case ContextProvider: 14171 { 14172 var newValue = workInProgress.memoizedProps.value; 14173 pushProvider(workInProgress, newValue); 14174 break; 14175 } 14176 case Profiler: 14177 if (enableProfilerTimer) { 14178 workInProgress.effectTag |= Update; 14179 } 14180 break; 14181 } 14182 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime); 14183 } 14184 14185 // Before entering the begin phase, clear the expiration time. 14186 workInProgress.expirationTime = NoWork; 14187 14188 switch (workInProgress.tag) { 14189 case IndeterminateComponent: 14190 { 14191 var _Component3 = workInProgress.type; 14192 return mountIndeterminateComponent(current$$1, workInProgress, _Component3, renderExpirationTime); 14193 } 14194 case FunctionalComponent: 14195 { 14196 var _Component4 = workInProgress.type; 14197 var _unresolvedProps = workInProgress.pendingProps; 14198 return updateFunctionalComponent(current$$1, workInProgress, _Component4, _unresolvedProps, renderExpirationTime); 14199 } 14200 case FunctionalComponentLazy: 14201 { 14202 var _thenable2 = workInProgress.type; 14203 var _Component5 = getResultFromResolvedThenable(_thenable2); 14204 var _unresolvedProps2 = workInProgress.pendingProps; 14205 var _child = updateFunctionalComponent(current$$1, workInProgress, _Component5, resolveDefaultProps(_Component5, _unresolvedProps2), renderExpirationTime); 14206 workInProgress.memoizedProps = _unresolvedProps2; 14207 return _child; 14208 } 14209 case ClassComponent: 14210 { 14211 var _Component6 = workInProgress.type; 14212 var _unresolvedProps3 = workInProgress.pendingProps; 14213 return updateClassComponent(current$$1, workInProgress, _Component6, _unresolvedProps3, renderExpirationTime); 14214 } 14215 case ClassComponentLazy: 14216 { 14217 var _thenable3 = workInProgress.type; 14218 var _Component7 = getResultFromResolvedThenable(_thenable3); 14219 var _unresolvedProps4 = workInProgress.pendingProps; 14220 var _child2 = updateClassComponent(current$$1, workInProgress, _Component7, resolveDefaultProps(_Component7, _unresolvedProps4), renderExpirationTime); 14221 workInProgress.memoizedProps = _unresolvedProps4; 14222 return _child2; 14223 } 14224 case HostRoot: 14225 return updateHostRoot(current$$1, workInProgress, renderExpirationTime); 14226 case HostComponent: 14227 return updateHostComponent(current$$1, workInProgress, renderExpirationTime); 14228 case HostText: 14229 return updateHostText(current$$1, workInProgress); 14230 case PlaceholderComponent: 14231 return updatePlaceholderComponent(current$$1, workInProgress, renderExpirationTime); 14232 case HostPortal: 14233 return updatePortalComponent(current$$1, workInProgress, renderExpirationTime); 14234 case ForwardRef: 14235 { 14236 var type = workInProgress.type; 14237 return updateForwardRef(current$$1, workInProgress, type, workInProgress.pendingProps, renderExpirationTime); 14238 } 14239 case ForwardRefLazy: 14240 var _thenable = workInProgress.type; 14241 var _Component2 = getResultFromResolvedThenable(_thenable); 14242 var unresolvedProps = workInProgress.pendingProps; 14243 var child = updateForwardRef(current$$1, workInProgress, _Component2, resolveDefaultProps(_Component2, unresolvedProps), renderExpirationTime); 14244 workInProgress.memoizedProps = unresolvedProps; 14245 return child; 14246 case Fragment: 14247 return updateFragment(current$$1, workInProgress, renderExpirationTime); 14248 case Mode: 14249 return updateMode(current$$1, workInProgress, renderExpirationTime); 14250 case Profiler: 14251 return updateProfiler(current$$1, workInProgress, renderExpirationTime); 14252 case ContextProvider: 14253 return updateContextProvider(current$$1, workInProgress, renderExpirationTime); 14254 case ContextConsumer: 14255 return updateContextConsumer(current$$1, workInProgress, renderExpirationTime); 14256 default: 14257 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.'); 14258 } 14259 } 14260 14261 function markUpdate(workInProgress) { 14262 // Tag the fiber with an update effect. This turns a Placement into 14263 // a PlacementAndUpdate. 14264 workInProgress.effectTag |= Update; 14265 } 14266 14267 function markRef$1(workInProgress) { 14268 workInProgress.effectTag |= Ref; 14269 } 14270 14271 function appendAllChildren(parent, workInProgress) { 14272 // We only have the top Fiber that was created but we need recurse down its 14273 // children to find all the terminal nodes. 14274 var node = workInProgress.child; 14275 while (node !== null) { 14276 if (node.tag === HostComponent || node.tag === HostText) { 14277 appendInitialChild(parent, node.stateNode); 14278 } else if (node.tag === HostPortal) { 14279 // If we have a portal child, then we don't want to traverse 14280 // down its children. Instead, we'll get insertions from each child in 14281 // the portal directly. 14282 } else if (node.child !== null) { 14283 node.child.return = node; 14284 node = node.child; 14285 continue; 14286 } 14287 if (node === workInProgress) { 14288 return; 14289 } 14290 while (node.sibling === null) { 14291 if (node.return === null || node.return === workInProgress) { 14292 return; 14293 } 14294 node = node.return; 14295 } 14296 node.sibling.return = node.return; 14297 node = node.sibling; 14298 } 14299 } 14300 14301 var updateHostContainer = void 0; 14302 var updateHostComponent$1 = void 0; 14303 var updateHostText$1 = void 0; 14304 if (supportsMutation) { 14305 // Mutation mode 14306 14307 updateHostContainer = function (workInProgress) { 14308 // Noop 14309 }; 14310 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) { 14311 // If we have an alternate, that means this is an update and we need to 14312 // schedule a side-effect to do the updates. 14313 var oldProps = current.memoizedProps; 14314 if (oldProps === newProps) { 14315 // In mutation mode, this is sufficient for a bailout because 14316 // we won't touch this node even if children changed. 14317 return; 14318 } 14319 14320 // If we get updated because one of our children updated, we don't 14321 // have newProps so we'll have to reuse them. 14322 // TODO: Split the update API as separate for the props vs. children. 14323 // Even better would be if children weren't special cased at all tho. 14324 var instance = workInProgress.stateNode; 14325 var currentHostContext = getHostContext(); 14326 // TODO: Experiencing an error where oldProps is null. Suggests a host 14327 // component is hitting the resume path. Figure out why. Possibly 14328 // related to `hidden`. 14329 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); 14330 // TODO: Type this specific to this type of component. 14331 workInProgress.updateQueue = updatePayload; 14332 // If the update payload indicates that there is a change or if there 14333 // is a new ref we mark this as an update. All the work is done in commitWork. 14334 if (updatePayload) { 14335 markUpdate(workInProgress); 14336 } 14337 }; 14338 updateHostText$1 = function (current, workInProgress, oldText, newText) { 14339 // If the text differs, mark it as an update. All the work in done in commitWork. 14340 if (oldText !== newText) { 14341 markUpdate(workInProgress); 14342 } 14343 }; 14344 } else if (supportsPersistence) { 14345 // Persistent host tree mode 14346 14347 // An unfortunate fork of appendAllChildren because we have two different parent types. 14348 var appendAllChildrenToContainer = function (containerChildSet, workInProgress) { 14349 // We only have the top Fiber that was created but we need recurse down its 14350 // children to find all the terminal nodes. 14351 var node = workInProgress.child; 14352 while (node !== null) { 14353 if (node.tag === HostComponent || node.tag === HostText) { 14354 appendChildToContainerChildSet(containerChildSet, node.stateNode); 14355 } else if (node.tag === HostPortal) { 14356 // If we have a portal child, then we don't want to traverse 14357 // down its children. Instead, we'll get insertions from each child in 14358 // the portal directly. 14359 } else if (node.child !== null) { 14360 node.child.return = node; 14361 node = node.child; 14362 continue; 14363 } 14364 if (node === workInProgress) { 14365 return; 14366 } 14367 while (node.sibling === null) { 14368 if (node.return === null || node.return === workInProgress) { 14369 return; 14370 } 14371 node = node.return; 14372 } 14373 node.sibling.return = node.return; 14374 node = node.sibling; 14375 } 14376 }; 14377 updateHostContainer = function (workInProgress) { 14378 var portalOrRoot = workInProgress.stateNode; 14379 var childrenUnchanged = workInProgress.firstEffect === null; 14380 if (childrenUnchanged) { 14381 // No changes, just reuse the existing instance. 14382 } else { 14383 var container = portalOrRoot.containerInfo; 14384 var newChildSet = createContainerChildSet(container); 14385 // If children might have changed, we have to add them all to the set. 14386 appendAllChildrenToContainer(newChildSet, workInProgress); 14387 portalOrRoot.pendingChildren = newChildSet; 14388 // Schedule an update on the container to swap out the container. 14389 markUpdate(workInProgress); 14390 finalizeContainerChildren(container, newChildSet); 14391 } 14392 }; 14393 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) { 14394 var currentInstance = current.stateNode; 14395 var oldProps = current.memoizedProps; 14396 // If there are no effects associated with this node, then none of our children had any updates. 14397 // This guarantees that we can reuse all of them. 14398 var childrenUnchanged = workInProgress.firstEffect === null; 14399 if (childrenUnchanged && oldProps === newProps) { 14400 // No changes, just reuse the existing instance. 14401 // Note that this might release a previous clone. 14402 workInProgress.stateNode = currentInstance; 14403 return; 14404 } 14405 var recyclableInstance = workInProgress.stateNode; 14406 var currentHostContext = getHostContext(); 14407 var updatePayload = null; 14408 if (oldProps !== newProps) { 14409 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext); 14410 } 14411 if (childrenUnchanged && updatePayload === null) { 14412 // No changes, just reuse the existing instance. 14413 // Note that this might release a previous clone. 14414 workInProgress.stateNode = currentInstance; 14415 return; 14416 } 14417 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance); 14418 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) { 14419 markUpdate(workInProgress); 14420 } 14421 workInProgress.stateNode = newInstance; 14422 if (childrenUnchanged) { 14423 // If there are no other effects in this tree, we need to flag this node as having one. 14424 // Even though we're not going to use it for anything. 14425 // Otherwise parents won't know that there are new children to propagate upwards. 14426 markUpdate(workInProgress); 14427 } else { 14428 // If children might have changed, we have to add them all to the set. 14429 appendAllChildren(newInstance, workInProgress); 14430 } 14431 }; 14432 updateHostText$1 = function (current, workInProgress, oldText, newText) { 14433 if (oldText !== newText) { 14434 // If the text content differs, we'll create a new text instance for it. 14435 var rootContainerInstance = getRootHostContainer(); 14436 var currentHostContext = getHostContext(); 14437 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress); 14438 // We'll have to mark it as having an effect, even though we won't use the effect for anything. 14439 // This lets the parents know that at least one of their children has changed. 14440 markUpdate(workInProgress); 14441 } 14442 }; 14443 } else { 14444 // No host operations 14445 updateHostContainer = function (workInProgress) { 14446 // Noop 14447 }; 14448 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) { 14449 // Noop 14450 }; 14451 updateHostText$1 = function (current, workInProgress, oldText, newText) { 14452 // Noop 14453 }; 14454 } 14455 14456 function completeWork(current, workInProgress, renderExpirationTime) { 14457 var newProps = workInProgress.pendingProps; 14458 14459 switch (workInProgress.tag) { 14460 case FunctionalComponent: 14461 case FunctionalComponentLazy: 14462 break; 14463 case ClassComponent: 14464 { 14465 var Component = workInProgress.type; 14466 if (isContextProvider(Component)) { 14467 popContext(workInProgress); 14468 } 14469 break; 14470 } 14471 case ClassComponentLazy: 14472 { 14473 var _Component = getResultFromResolvedThenable(workInProgress.type); 14474 if (isContextProvider(_Component)) { 14475 popContext(workInProgress); 14476 } 14477 break; 14478 } 14479 case HostRoot: 14480 { 14481 popHostContainer(workInProgress); 14482 popTopLevelContextObject(workInProgress); 14483 var fiberRoot = workInProgress.stateNode; 14484 if (fiberRoot.pendingContext) { 14485 fiberRoot.context = fiberRoot.pendingContext; 14486 fiberRoot.pendingContext = null; 14487 } 14488 if (current === null || current.child === null) { 14489 // If we hydrated, pop so that we can delete any remaining children 14490 // that weren't hydrated. 14491 popHydrationState(workInProgress); 14492 // This resets the hacky state to fix isMounted before committing. 14493 // TODO: Delete this when we delete isMounted and findDOMNode. 14494 workInProgress.effectTag &= ~Placement; 14495 } 14496 updateHostContainer(workInProgress); 14497 break; 14498 } 14499 case HostComponent: 14500 { 14501 popHostContext(workInProgress); 14502 var rootContainerInstance = getRootHostContainer(); 14503 var type = workInProgress.type; 14504 if (current !== null && workInProgress.stateNode != null) { 14505 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance); 14506 14507 if (current.ref !== workInProgress.ref) { 14508 markRef$1(workInProgress); 14509 } 14510 } else { 14511 if (!newProps) { 14512 !(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; 14513 // This can happen when we abort work. 14514 break; 14515 } 14516 14517 var currentHostContext = getHostContext(); 14518 // TODO: Move createInstance to beginWork and keep it on a context 14519 // "stack" as the parent. Then append children as we go in beginWork 14520 // or completeWork depending on we want to add then top->down or 14521 // bottom->up. Top->down is faster in IE11. 14522 var wasHydrated = popHydrationState(workInProgress); 14523 if (wasHydrated) { 14524 // TODO: Move this and createInstance step into the beginPhase 14525 // to consolidate. 14526 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) { 14527 // If changes to the hydrated node needs to be applied at the 14528 // commit-phase we mark this as such. 14529 markUpdate(workInProgress); 14530 } 14531 } else { 14532 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress); 14533 14534 appendAllChildren(instance, workInProgress); 14535 14536 // Certain renderers require commit-time effects for initial mount. 14537 // (eg DOM renderer supports auto-focus for certain elements). 14538 // Make sure such renderers get scheduled for later work. 14539 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance, currentHostContext)) { 14540 markUpdate(workInProgress); 14541 } 14542 workInProgress.stateNode = instance; 14543 } 14544 14545 if (workInProgress.ref !== null) { 14546 // If there is a ref on a host node we need to schedule a callback 14547 markRef$1(workInProgress); 14548 } 14549 } 14550 break; 14551 } 14552 case HostText: 14553 { 14554 var newText = newProps; 14555 if (current && workInProgress.stateNode != null) { 14556 var oldText = current.memoizedProps; 14557 // If we have an alternate, that means this is an update and we need 14558 // to schedule a side-effect to do the updates. 14559 updateHostText$1(current, workInProgress, oldText, newText); 14560 } else { 14561 if (typeof newText !== 'string') { 14562 !(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; 14563 // This can happen when we abort work. 14564 } 14565 var _rootContainerInstance = getRootHostContainer(); 14566 var _currentHostContext = getHostContext(); 14567 var _wasHydrated = popHydrationState(workInProgress); 14568 if (_wasHydrated) { 14569 if (prepareToHydrateHostTextInstance(workInProgress)) { 14570 markUpdate(workInProgress); 14571 } 14572 } else { 14573 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress); 14574 } 14575 } 14576 break; 14577 } 14578 case ForwardRef: 14579 case ForwardRefLazy: 14580 break; 14581 case PlaceholderComponent: 14582 break; 14583 case Fragment: 14584 break; 14585 case Mode: 14586 break; 14587 case Profiler: 14588 break; 14589 case HostPortal: 14590 popHostContainer(workInProgress); 14591 updateHostContainer(workInProgress); 14592 break; 14593 case ContextProvider: 14594 // Pop provider fiber 14595 popProvider(workInProgress); 14596 break; 14597 case ContextConsumer: 14598 break; 14599 // Error cases 14600 case IndeterminateComponent: 14601 invariant(false, 'An indeterminate component should have become determinate before completing. This error is likely caused by a bug in React. Please file an issue.'); 14602 // eslint-disable-next-line no-fallthrough 14603 default: 14604 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.'); 14605 } 14606 14607 return null; 14608 } 14609 14610 // This module is forked in different environments. 14611 // By default, return `true` to log errors to the console. 14612 // Forks can return `false` if this isn't desirable. 14613 function showErrorDialog(capturedError) { 14614 return true; 14615 } 14616 14617 function logCapturedError(capturedError) { 14618 var logError = showErrorDialog(capturedError); 14619 14620 // Allow injected showErrorDialog() to prevent default console.error logging. 14621 // This enables renderers like ReactNative to better manage redbox behavior. 14622 if (logError === false) { 14623 return; 14624 } 14625 14626 var error = capturedError.error; 14627 { 14628 var componentName = capturedError.componentName, 14629 componentStack = capturedError.componentStack, 14630 errorBoundaryName = capturedError.errorBoundaryName, 14631 errorBoundaryFound = capturedError.errorBoundaryFound, 14632 willRetry = capturedError.willRetry; 14633 14634 // Browsers support silencing uncaught errors by calling 14635 // `preventDefault()` in window `error` handler. 14636 // We record this information as an expando on the error. 14637 14638 if (error != null && error._suppressLogging) { 14639 if (errorBoundaryFound && willRetry) { 14640 // The error is recoverable and was silenced. 14641 // Ignore it and don't print the stack addendum. 14642 // This is handy for testing error boundaries without noise. 14643 return; 14644 } 14645 // The error is fatal. Since the silencing might have 14646 // been accidental, we'll surface it anyway. 14647 // However, the browser would have silenced the original error 14648 // so we'll print it first, and then print the stack addendum. 14649 console.error(error); 14650 // For a more detailed description of this block, see: 14651 // https://github.com/facebook/react/pull/13384 14652 } 14653 14654 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:'; 14655 14656 var errorBoundaryMessage = void 0; 14657 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow. 14658 if (errorBoundaryFound && errorBoundaryName) { 14659 if (willRetry) { 14660 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.'); 14661 } else { 14662 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.'; 14663 } 14664 } else { 14665 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.'; 14666 } 14667 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage); 14668 14669 // In development, we provide our own message with just the component stack. 14670 // We don't include the original error message and JS stack because the browser 14671 // has already printed it. Even if the application swallows the error, it is still 14672 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. 14673 console.error(combinedMessage); 14674 } 14675 } 14676 14677 var emptyObject = {}; 14678 14679 var didWarnAboutUndefinedSnapshotBeforeUpdate = null; 14680 { 14681 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); 14682 } 14683 14684 function logError(boundary, errorInfo) { 14685 var source = errorInfo.source; 14686 var stack = errorInfo.stack; 14687 if (stack === null && source !== null) { 14688 stack = getStackByFiberInDevAndProd(source); 14689 } 14690 14691 var capturedError = { 14692 componentName: source !== null ? getComponentName(source.type) : null, 14693 componentStack: stack !== null ? stack : '', 14694 error: errorInfo.value, 14695 errorBoundary: null, 14696 errorBoundaryName: null, 14697 errorBoundaryFound: false, 14698 willRetry: false 14699 }; 14700 14701 if (boundary !== null && boundary.tag === ClassComponent) { 14702 capturedError.errorBoundary = boundary.stateNode; 14703 capturedError.errorBoundaryName = getComponentName(boundary.type); 14704 capturedError.errorBoundaryFound = true; 14705 capturedError.willRetry = true; 14706 } 14707 14708 try { 14709 logCapturedError(capturedError); 14710 } catch (e) { 14711 // This method must not throw, or React internal state will get messed up. 14712 // If console.error is overridden, or logCapturedError() shows a dialog that throws, 14713 // we want to report this error outside of the normal stack as a last resort. 14714 // https://github.com/facebook/react/issues/13188 14715 setTimeout(function () { 14716 throw e; 14717 }); 14718 } 14719 } 14720 14721 var callComponentWillUnmountWithTimer = function (current$$1, instance) { 14722 startPhaseTimer(current$$1, 'componentWillUnmount'); 14723 instance.props = current$$1.memoizedProps; 14724 instance.state = current$$1.memoizedState; 14725 instance.componentWillUnmount(); 14726 stopPhaseTimer(); 14727 }; 14728 14729 // Capture errors so they don't interrupt unmounting. 14730 function safelyCallComponentWillUnmount(current$$1, instance) { 14731 { 14732 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current$$1, instance); 14733 if (hasCaughtError()) { 14734 var unmountError = clearCaughtError(); 14735 captureCommitPhaseError(current$$1, unmountError); 14736 } 14737 } 14738 } 14739 14740 function safelyDetachRef(current$$1) { 14741 var ref = current$$1.ref; 14742 if (ref !== null) { 14743 if (typeof ref === 'function') { 14744 { 14745 invokeGuardedCallback(null, ref, null, null); 14746 if (hasCaughtError()) { 14747 var refError = clearCaughtError(); 14748 captureCommitPhaseError(current$$1, refError); 14749 } 14750 } 14751 } else { 14752 ref.current = null; 14753 } 14754 } 14755 } 14756 14757 function commitBeforeMutationLifeCycles(current$$1, finishedWork) { 14758 switch (finishedWork.tag) { 14759 case ClassComponent: 14760 case ClassComponentLazy: 14761 { 14762 if (finishedWork.effectTag & Snapshot) { 14763 if (current$$1 !== null) { 14764 var prevProps = current$$1.memoizedProps; 14765 var prevState = current$$1.memoizedState; 14766 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate'); 14767 var instance = finishedWork.stateNode; 14768 instance.props = finishedWork.memoizedProps; 14769 instance.state = finishedWork.memoizedState; 14770 var snapshot = instance.getSnapshotBeforeUpdate(prevProps, prevState); 14771 { 14772 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; 14773 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { 14774 didWarnSet.add(finishedWork.type); 14775 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type)); 14776 } 14777 } 14778 instance.__reactInternalSnapshotBeforeUpdate = snapshot; 14779 stopPhaseTimer(); 14780 } 14781 } 14782 return; 14783 } 14784 case HostRoot: 14785 case HostComponent: 14786 case HostText: 14787 case HostPortal: 14788 // Nothing to do for these component types 14789 return; 14790 default: 14791 { 14792 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.'); 14793 } 14794 } 14795 } 14796 14797 function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpirationTime) { 14798 switch (finishedWork.tag) { 14799 case ClassComponent: 14800 case ClassComponentLazy: 14801 { 14802 var instance = finishedWork.stateNode; 14803 if (finishedWork.effectTag & Update) { 14804 if (current$$1 === null) { 14805 startPhaseTimer(finishedWork, 'componentDidMount'); 14806 instance.props = finishedWork.memoizedProps; 14807 instance.state = finishedWork.memoizedState; 14808 instance.componentDidMount(); 14809 stopPhaseTimer(); 14810 } else { 14811 var prevProps = current$$1.memoizedProps; 14812 var prevState = current$$1.memoizedState; 14813 startPhaseTimer(finishedWork, 'componentDidUpdate'); 14814 instance.props = finishedWork.memoizedProps; 14815 instance.state = finishedWork.memoizedState; 14816 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate); 14817 stopPhaseTimer(); 14818 } 14819 } 14820 var updateQueue = finishedWork.updateQueue; 14821 if (updateQueue !== null) { 14822 instance.props = finishedWork.memoizedProps; 14823 instance.state = finishedWork.memoizedState; 14824 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime); 14825 } 14826 return; 14827 } 14828 case HostRoot: 14829 { 14830 var _updateQueue = finishedWork.updateQueue; 14831 if (_updateQueue !== null) { 14832 var _instance = null; 14833 if (finishedWork.child !== null) { 14834 switch (finishedWork.child.tag) { 14835 case HostComponent: 14836 _instance = getPublicInstance(finishedWork.child.stateNode); 14837 break; 14838 case ClassComponent: 14839 case ClassComponentLazy: 14840 _instance = finishedWork.child.stateNode; 14841 break; 14842 } 14843 } 14844 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime); 14845 } 14846 return; 14847 } 14848 case HostComponent: 14849 { 14850 var _instance2 = finishedWork.stateNode; 14851 14852 // Renderers may schedule work to be done after host components are mounted 14853 // (eg DOM renderer may schedule auto-focus for inputs and form controls). 14854 // These effects should only be committed when components are first mounted, 14855 // aka when there is no current/alternate. 14856 if (current$$1 === null && finishedWork.effectTag & Update) { 14857 var type = finishedWork.type; 14858 var props = finishedWork.memoizedProps; 14859 commitMount(_instance2, type, props, finishedWork); 14860 } 14861 14862 return; 14863 } 14864 case HostText: 14865 { 14866 // We have no life-cycles associated with text. 14867 return; 14868 } 14869 case HostPortal: 14870 { 14871 // We have no life-cycles associated with portals. 14872 return; 14873 } 14874 case Profiler: 14875 { 14876 if (enableProfilerTimer) { 14877 var onRender = finishedWork.memoizedProps.onRender; 14878 14879 if (enableSchedulerTracing) { 14880 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions); 14881 } else { 14882 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime()); 14883 } 14884 } 14885 return; 14886 } 14887 case PlaceholderComponent: 14888 { 14889 if (enableSuspense) { 14890 if ((finishedWork.mode & StrictMode) === NoEffect) { 14891 // In loose mode, a placeholder times out by scheduling a synchronous 14892 // update in the commit phase. Use `updateQueue` field to signal that 14893 // the Timeout needs to switch to the placeholder. We don't need an 14894 // entire queue. Any non-null value works. 14895 // $FlowFixMe - Intentionally using a value other than an UpdateQueue. 14896 finishedWork.updateQueue = emptyObject; 14897 scheduleWork(finishedWork, Sync); 14898 } else { 14899 // In strict mode, the Update effect is used to record the time at 14900 // which the placeholder timed out. 14901 var currentTime = requestCurrentTime(); 14902 finishedWork.stateNode = { timedOutAt: currentTime }; 14903 } 14904 } 14905 return; 14906 } 14907 default: 14908 { 14909 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.'); 14910 } 14911 } 14912 } 14913 14914 function commitAttachRef(finishedWork) { 14915 var ref = finishedWork.ref; 14916 if (ref !== null) { 14917 var instance = finishedWork.stateNode; 14918 var instanceToUse = void 0; 14919 switch (finishedWork.tag) { 14920 case HostComponent: 14921 instanceToUse = getPublicInstance(instance); 14922 break; 14923 default: 14924 instanceToUse = instance; 14925 } 14926 if (typeof ref === 'function') { 14927 ref(instanceToUse); 14928 } else { 14929 { 14930 if (!ref.hasOwnProperty('current')) { 14931 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork)); 14932 } 14933 } 14934 14935 ref.current = instanceToUse; 14936 } 14937 } 14938 } 14939 14940 function commitDetachRef(current$$1) { 14941 var currentRef = current$$1.ref; 14942 if (currentRef !== null) { 14943 if (typeof currentRef === 'function') { 14944 currentRef(null); 14945 } else { 14946 currentRef.current = null; 14947 } 14948 } 14949 } 14950 14951 // User-originating errors (lifecycles and refs) should not interrupt 14952 // deletion, so don't let them throw. Host-originating errors should 14953 // interrupt deletion, so it's okay 14954 function commitUnmount(current$$1) { 14955 onCommitUnmount(current$$1); 14956 14957 switch (current$$1.tag) { 14958 case ClassComponent: 14959 case ClassComponentLazy: 14960 { 14961 safelyDetachRef(current$$1); 14962 var instance = current$$1.stateNode; 14963 if (typeof instance.componentWillUnmount === 'function') { 14964 safelyCallComponentWillUnmount(current$$1, instance); 14965 } 14966 return; 14967 } 14968 case HostComponent: 14969 { 14970 safelyDetachRef(current$$1); 14971 return; 14972 } 14973 case HostPortal: 14974 { 14975 // TODO: this is recursive. 14976 // We are also not using this parent because 14977 // the portal will get pushed immediately. 14978 if (supportsMutation) { 14979 unmountHostComponents(current$$1); 14980 } else if (supportsPersistence) { 14981 emptyPortalContainer(current$$1); 14982 } 14983 return; 14984 } 14985 } 14986 } 14987 14988 function commitNestedUnmounts(root) { 14989 // While we're inside a removed host node we don't want to call 14990 // removeChild on the inner nodes because they're removed by the top 14991 // call anyway. We also want to call componentWillUnmount on all 14992 // composites before this host node is removed from the tree. Therefore 14993 var node = root; 14994 while (true) { 14995 commitUnmount(node); 14996 // Visit children because they may contain more composite or host nodes. 14997 // Skip portals because commitUnmount() currently visits them recursively. 14998 if (node.child !== null && ( 14999 // If we use mutation we drill down into portals using commitUnmount above. 15000 // If we don't use mutation we drill down into portals here instead. 15001 !supportsMutation || node.tag !== HostPortal)) { 15002 node.child.return = node; 15003 node = node.child; 15004 continue; 15005 } 15006 if (node === root) { 15007 return; 15008 } 15009 while (node.sibling === null) { 15010 if (node.return === null || node.return === root) { 15011 return; 15012 } 15013 node = node.return; 15014 } 15015 node.sibling.return = node.return; 15016 node = node.sibling; 15017 } 15018 } 15019 15020 function detachFiber(current$$1) { 15021 // Cut off the return pointers to disconnect it from the tree. Ideally, we 15022 // should clear the child pointer of the parent alternate to let this 15023 // get GC:ed but we don't know which for sure which parent is the current 15024 // one so we'll settle for GC:ing the subtree of this child. This child 15025 // itself will be GC:ed when the parent updates the next time. 15026 current$$1.return = null; 15027 current$$1.child = null; 15028 if (current$$1.alternate) { 15029 current$$1.alternate.child = null; 15030 current$$1.alternate.return = null; 15031 } 15032 } 15033 15034 function emptyPortalContainer(current$$1) { 15035 if (!supportsPersistence) { 15036 return; 15037 } 15038 15039 var portal = current$$1.stateNode; 15040 var containerInfo = portal.containerInfo; 15041 15042 var emptyChildSet = createContainerChildSet(containerInfo); 15043 replaceContainerChildren(containerInfo, emptyChildSet); 15044 } 15045 15046 function commitContainer(finishedWork) { 15047 if (!supportsPersistence) { 15048 return; 15049 } 15050 15051 switch (finishedWork.tag) { 15052 case ClassComponent: 15053 case ClassComponentLazy: 15054 { 15055 return; 15056 } 15057 case HostComponent: 15058 { 15059 return; 15060 } 15061 case HostText: 15062 { 15063 return; 15064 } 15065 case HostRoot: 15066 case HostPortal: 15067 { 15068 var portalOrRoot = finishedWork.stateNode; 15069 var containerInfo = portalOrRoot.containerInfo, 15070 _pendingChildren = portalOrRoot.pendingChildren; 15071 15072 replaceContainerChildren(containerInfo, _pendingChildren); 15073 return; 15074 } 15075 default: 15076 { 15077 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.'); 15078 } 15079 } 15080 } 15081 15082 function getHostParentFiber(fiber) { 15083 var parent = fiber.return; 15084 while (parent !== null) { 15085 if (isHostParent(parent)) { 15086 return parent; 15087 } 15088 parent = parent.return; 15089 } 15090 invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.'); 15091 } 15092 15093 function isHostParent(fiber) { 15094 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal; 15095 } 15096 15097 function getHostSibling(fiber) { 15098 // We're going to search forward into the tree until we find a sibling host 15099 // node. Unfortunately, if multiple insertions are done in a row we have to 15100 // search past them. This leads to exponential search for the next sibling. 15101 var node = fiber; 15102 siblings: while (true) { 15103 // If we didn't find anything, let's try the next sibling. 15104 while (node.sibling === null) { 15105 if (node.return === null || isHostParent(node.return)) { 15106 // If we pop out of the root or hit the parent the fiber we are the 15107 // last sibling. 15108 return null; 15109 } 15110 node = node.return; 15111 } 15112 node.sibling.return = node.return; 15113 node = node.sibling; 15114 while (node.tag !== HostComponent && node.tag !== HostText) { 15115 // If it is not host node and, we might have a host node inside it. 15116 // Try to search down until we find one. 15117 if (node.effectTag & Placement) { 15118 // If we don't have a child, try the siblings instead. 15119 continue siblings; 15120 } 15121 // If we don't have a child, try the siblings instead. 15122 // We also skip portals because they are not part of this host tree. 15123 if (node.child === null || node.tag === HostPortal) { 15124 continue siblings; 15125 } else { 15126 node.child.return = node; 15127 node = node.child; 15128 } 15129 } 15130 // Check if this host node is stable or about to be placed. 15131 if (!(node.effectTag & Placement)) { 15132 // Found it! 15133 return node.stateNode; 15134 } 15135 } 15136 } 15137 15138 function commitPlacement(finishedWork) { 15139 if (!supportsMutation) { 15140 return; 15141 } 15142 15143 // Recursively insert all host nodes into the parent. 15144 var parentFiber = getHostParentFiber(finishedWork); 15145 15146 // Note: these two variables *must* always be updated together. 15147 var parent = void 0; 15148 var isContainer = void 0; 15149 15150 switch (parentFiber.tag) { 15151 case HostComponent: 15152 parent = parentFiber.stateNode; 15153 isContainer = false; 15154 break; 15155 case HostRoot: 15156 parent = parentFiber.stateNode.containerInfo; 15157 isContainer = true; 15158 break; 15159 case HostPortal: 15160 parent = parentFiber.stateNode.containerInfo; 15161 isContainer = true; 15162 break; 15163 default: 15164 invariant(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.'); 15165 } 15166 if (parentFiber.effectTag & ContentReset) { 15167 // Reset the text content of the parent before doing any insertions 15168 resetTextContent(parent); 15169 // Clear ContentReset from the effect tag 15170 parentFiber.effectTag &= ~ContentReset; 15171 } 15172 15173 var before = getHostSibling(finishedWork); 15174 // We only have the top Fiber that was inserted but we need recurse down its 15175 // children to find all the terminal nodes. 15176 var node = finishedWork; 15177 while (true) { 15178 if (node.tag === HostComponent || node.tag === HostText) { 15179 if (before) { 15180 if (isContainer) { 15181 insertInContainerBefore(parent, node.stateNode, before); 15182 } else { 15183 insertBefore(parent, node.stateNode, before); 15184 } 15185 } else { 15186 if (isContainer) { 15187 appendChildToContainer(parent, node.stateNode); 15188 } else { 15189 appendChild(parent, node.stateNode); 15190 } 15191 } 15192 } else if (node.tag === HostPortal) { 15193 // If the insertion itself is a portal, then we don't want to traverse 15194 // down its children. Instead, we'll get insertions from each child in 15195 // the portal directly. 15196 } else if (node.child !== null) { 15197 node.child.return = node; 15198 node = node.child; 15199 continue; 15200 } 15201 if (node === finishedWork) { 15202 return; 15203 } 15204 while (node.sibling === null) { 15205 if (node.return === null || node.return === finishedWork) { 15206 return; 15207 } 15208 node = node.return; 15209 } 15210 node.sibling.return = node.return; 15211 node = node.sibling; 15212 } 15213 } 15214 15215 function unmountHostComponents(current$$1) { 15216 // We only have the top Fiber that was deleted but we need recurse down its 15217 var node = current$$1; 15218 15219 // Each iteration, currentParent is populated with node's host parent if not 15220 // currentParentIsValid. 15221 var currentParentIsValid = false; 15222 15223 // Note: these two variables *must* always be updated together. 15224 var currentParent = void 0; 15225 var currentParentIsContainer = void 0; 15226 15227 while (true) { 15228 if (!currentParentIsValid) { 15229 var parent = node.return; 15230 findParent: while (true) { 15231 !(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; 15232 switch (parent.tag) { 15233 case HostComponent: 15234 currentParent = parent.stateNode; 15235 currentParentIsContainer = false; 15236 break findParent; 15237 case HostRoot: 15238 currentParent = parent.stateNode.containerInfo; 15239 currentParentIsContainer = true; 15240 break findParent; 15241 case HostPortal: 15242 currentParent = parent.stateNode.containerInfo; 15243 currentParentIsContainer = true; 15244 break findParent; 15245 } 15246 parent = parent.return; 15247 } 15248 currentParentIsValid = true; 15249 } 15250 15251 if (node.tag === HostComponent || node.tag === HostText) { 15252 commitNestedUnmounts(node); 15253 // After all the children have unmounted, it is now safe to remove the 15254 // node from the tree. 15255 if (currentParentIsContainer) { 15256 removeChildFromContainer(currentParent, node.stateNode); 15257 } else { 15258 removeChild(currentParent, node.stateNode); 15259 } 15260 // Don't visit children because we already visited them. 15261 } else if (node.tag === HostPortal) { 15262 // When we go into a portal, it becomes the parent to remove from. 15263 // We will reassign it back when we pop the portal on the way up. 15264 currentParent = node.stateNode.containerInfo; 15265 currentParentIsContainer = true; 15266 // Visit children because portals might contain host components. 15267 if (node.child !== null) { 15268 node.child.return = node; 15269 node = node.child; 15270 continue; 15271 } 15272 } else { 15273 commitUnmount(node); 15274 // Visit children because we may find more host components below. 15275 if (node.child !== null) { 15276 node.child.return = node; 15277 node = node.child; 15278 continue; 15279 } 15280 } 15281 if (node === current$$1) { 15282 return; 15283 } 15284 while (node.sibling === null) { 15285 if (node.return === null || node.return === current$$1) { 15286 return; 15287 } 15288 node = node.return; 15289 if (node.tag === HostPortal) { 15290 // When we go out of the portal, we need to restore the parent. 15291 // Since we don't keep a stack of them, we will search for it. 15292 currentParentIsValid = false; 15293 } 15294 } 15295 node.sibling.return = node.return; 15296 node = node.sibling; 15297 } 15298 } 15299 15300 function commitDeletion(current$$1) { 15301 if (supportsMutation) { 15302 // Recursively delete all host nodes from the parent. 15303 // Detach refs and call componentWillUnmount() on the whole subtree. 15304 unmountHostComponents(current$$1); 15305 } else { 15306 // Detach refs and call componentWillUnmount() on the whole subtree. 15307 commitNestedUnmounts(current$$1); 15308 } 15309 detachFiber(current$$1); 15310 } 15311 15312 function commitWork(current$$1, finishedWork) { 15313 if (!supportsMutation) { 15314 commitContainer(finishedWork); 15315 return; 15316 } 15317 15318 switch (finishedWork.tag) { 15319 case ClassComponent: 15320 case ClassComponentLazy: 15321 { 15322 return; 15323 } 15324 case HostComponent: 15325 { 15326 var instance = finishedWork.stateNode; 15327 if (instance != null) { 15328 // Commit the work prepared earlier. 15329 var newProps = finishedWork.memoizedProps; 15330 // For hydration we reuse the update path but we treat the oldProps 15331 // as the newProps. The updatePayload will contain the real change in 15332 // this case. 15333 var oldProps = current$$1 !== null ? current$$1.memoizedProps : newProps; 15334 var type = finishedWork.type; 15335 // TODO: Type the updateQueue to be specific to host components. 15336 var updatePayload = finishedWork.updateQueue; 15337 finishedWork.updateQueue = null; 15338 if (updatePayload !== null) { 15339 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork); 15340 } 15341 } 15342 return; 15343 } 15344 case HostText: 15345 { 15346 !(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; 15347 var textInstance = finishedWork.stateNode; 15348 var newText = finishedWork.memoizedProps; 15349 // For hydration we reuse the update path but we treat the oldProps 15350 // as the newProps. The updatePayload will contain the real change in 15351 // this case. 15352 var oldText = current$$1 !== null ? current$$1.memoizedProps : newText; 15353 commitTextUpdate(textInstance, oldText, newText); 15354 return; 15355 } 15356 case HostRoot: 15357 { 15358 return; 15359 } 15360 case Profiler: 15361 { 15362 return; 15363 } 15364 case PlaceholderComponent: 15365 { 15366 return; 15367 } 15368 default: 15369 { 15370 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.'); 15371 } 15372 } 15373 } 15374 15375 function commitResetTextContent(current$$1) { 15376 if (!supportsMutation) { 15377 return; 15378 } 15379 resetTextContent(current$$1.stateNode); 15380 } 15381 15382 function NoopComponent() { 15383 return null; 15384 } 15385 15386 function createRootErrorUpdate(fiber, errorInfo, expirationTime) { 15387 var update = createUpdate(expirationTime); 15388 // Unmount the root by rendering null. 15389 update.tag = CaptureUpdate; 15390 // Caution: React DevTools currently depends on this property 15391 // being called "element". 15392 update.payload = { element: null }; 15393 var error = errorInfo.value; 15394 update.callback = function () { 15395 onUncaughtError(error); 15396 logError(fiber, errorInfo); 15397 }; 15398 return update; 15399 } 15400 15401 function createClassErrorUpdate(fiber, errorInfo, expirationTime) { 15402 var update = createUpdate(expirationTime); 15403 update.tag = CaptureUpdate; 15404 var getDerivedStateFromCatch = fiber.type.getDerivedStateFromCatch; 15405 if (enableGetDerivedStateFromCatch && typeof getDerivedStateFromCatch === 'function') { 15406 var error = errorInfo.value; 15407 update.payload = function () { 15408 return getDerivedStateFromCatch(error); 15409 }; 15410 } 15411 15412 var inst = fiber.stateNode; 15413 if (inst !== null && typeof inst.componentDidCatch === 'function') { 15414 update.callback = function callback() { 15415 if (!enableGetDerivedStateFromCatch || getDerivedStateFromCatch !== 'function') { 15416 // To preserve the preexisting retry behavior of error boundaries, 15417 // we keep track of which ones already failed during this batch. 15418 // This gets reset before we yield back to the browser. 15419 // TODO: Warn in strict mode if getDerivedStateFromCatch is 15420 // not defined. 15421 markLegacyErrorBoundaryAsFailed(this); 15422 } 15423 var error = errorInfo.value; 15424 var stack = errorInfo.stack; 15425 logError(fiber, errorInfo); 15426 this.componentDidCatch(error, { 15427 componentStack: stack !== null ? stack : '' 15428 }); 15429 }; 15430 } 15431 return update; 15432 } 15433 15434 function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) { 15435 // The source fiber did not complete. 15436 sourceFiber.effectTag |= Incomplete; 15437 // Its effect list is no longer valid. 15438 sourceFiber.firstEffect = sourceFiber.lastEffect = null; 15439 15440 if (enableSuspense && value !== null && typeof value === 'object' && typeof value.then === 'function') { 15441 // This is a thenable. 15442 var thenable = value; 15443 15444 // Find the earliest timeout threshold of all the placeholders in the 15445 // ancestor path. We could avoid this traversal by storing the thresholds on 15446 // the stack, but we choose not to because we only hit this path if we're 15447 // IO-bound (i.e. if something suspends). Whereas the stack is used even in 15448 // the non-IO- bound case. 15449 var _workInProgress = returnFiber; 15450 var earliestTimeoutMs = -1; 15451 var startTimeMs = -1; 15452 do { 15453 if (_workInProgress.tag === PlaceholderComponent) { 15454 var current = _workInProgress.alternate; 15455 if (current !== null && current.memoizedState === true && current.stateNode !== null) { 15456 // Reached a placeholder that already timed out. Each timed out 15457 // placeholder acts as the root of a new suspense boundary. 15458 15459 // Use the time at which the placeholder timed out as the start time 15460 // for the current render. 15461 var timedOutAt = current.stateNode.timedOutAt; 15462 startTimeMs = expirationTimeToMs(timedOutAt); 15463 15464 // Do not search any further. 15465 break; 15466 } 15467 var timeoutPropMs = _workInProgress.pendingProps.delayMs; 15468 if (typeof timeoutPropMs === 'number') { 15469 if (timeoutPropMs <= 0) { 15470 earliestTimeoutMs = 0; 15471 } else if (earliestTimeoutMs === -1 || timeoutPropMs < earliestTimeoutMs) { 15472 earliestTimeoutMs = timeoutPropMs; 15473 } 15474 } 15475 } 15476 _workInProgress = _workInProgress.return; 15477 } while (_workInProgress !== null); 15478 15479 // Schedule the nearest Placeholder to re-render the timed out view. 15480 _workInProgress = returnFiber; 15481 do { 15482 if (_workInProgress.tag === PlaceholderComponent) { 15483 var didTimeout = _workInProgress.memoizedState; 15484 if (!didTimeout) { 15485 // Found the nearest boundary. 15486 15487 // If the boundary is not in async mode, we should not suspend, and 15488 // likewise, when the promise resolves, we should ping synchronously. 15489 var pingTime = (_workInProgress.mode & AsyncMode) === NoEffect ? Sync : renderExpirationTime; 15490 15491 // Attach a listener to the promise to "ping" the root and retry. 15492 var onResolveOrReject = retrySuspendedRoot.bind(null, root, _workInProgress, pingTime); 15493 thenable.then(onResolveOrReject, onResolveOrReject); 15494 15495 // If the boundary is outside of strict mode, we should *not* suspend 15496 // the commit. Pretend as if the suspended component rendered null and 15497 // keep rendering. In the commit phase, we'll schedule a subsequent 15498 // synchronous update to re-render the Placeholder. 15499 // 15500 // Note: It doesn't matter whether the component that suspended was 15501 // inside a strict mode tree. If the Placeholder is outside of it, we 15502 // should *not* suspend the commit. 15503 if ((_workInProgress.mode & StrictMode) === NoEffect) { 15504 _workInProgress.effectTag |= Update; 15505 15506 // Unmount the source fiber's children 15507 var nextChildren = null; 15508 reconcileChildren(sourceFiber.alternate, sourceFiber, nextChildren, renderExpirationTime); 15509 sourceFiber.effectTag &= ~Incomplete; 15510 if (sourceFiber.tag === IndeterminateComponent) { 15511 // Let's just assume it's a functional component. This fiber will 15512 // be unmounted in the immediate next commit, anyway. 15513 sourceFiber.tag = FunctionalComponent; 15514 } 15515 15516 if (sourceFiber.tag === ClassComponent || sourceFiber.tag === ClassComponentLazy) { 15517 // We're going to commit this fiber even though it didn't 15518 // complete. But we shouldn't call any lifecycle methods or 15519 // callbacks. Remove all lifecycle effect tags. 15520 sourceFiber.effectTag &= ~LifecycleEffectMask; 15521 if (sourceFiber.alternate === null) { 15522 // We're about to mount a class component that doesn't have an 15523 // instance. Turn this into a dummy functional component instead, 15524 // to prevent type errors. This is a bit weird but it's an edge 15525 // case and we're about to synchronously delete this 15526 // component, anyway. 15527 sourceFiber.tag = FunctionalComponent; 15528 sourceFiber.type = NoopComponent; 15529 } 15530 } 15531 15532 // Exit without suspending. 15533 return; 15534 } 15535 15536 // Confirmed that the boundary is in a strict mode tree. Continue with 15537 // the normal suspend path. 15538 15539 var absoluteTimeoutMs = void 0; 15540 if (earliestTimeoutMs === -1) { 15541 // If no explicit threshold is given, default to an abitrarily large 15542 // value. The actual size doesn't matter because the threshold for the 15543 // whole tree will be clamped to the expiration time. 15544 absoluteTimeoutMs = maxSigned31BitInt; 15545 } else { 15546 if (startTimeMs === -1) { 15547 // This suspend happened outside of any already timed-out 15548 // placeholders. We don't know exactly when the update was scheduled, 15549 // but we can infer an approximate start time from the expiration 15550 // time. First, find the earliest uncommitted expiration time in the 15551 // tree, including work that is suspended. Then subtract the offset 15552 // used to compute an async update's expiration time. This will cause 15553 // high priority (interactive) work to expire earlier than necessary, 15554 // but we can account for this by adjusting for the Just Noticeable 15555 // Difference. 15556 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, renderExpirationTime); 15557 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime); 15558 startTimeMs = earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION; 15559 } 15560 absoluteTimeoutMs = startTimeMs + earliestTimeoutMs; 15561 } 15562 15563 // Mark the earliest timeout in the suspended fiber's ancestor path. 15564 // After completing the root, we'll take the largest of all the 15565 // suspended fiber's timeouts and use it to compute a timeout for the 15566 // whole tree. 15567 renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime); 15568 15569 _workInProgress.effectTag |= ShouldCapture; 15570 _workInProgress.expirationTime = renderExpirationTime; 15571 return; 15572 } 15573 // This boundary already captured during this render. Continue to the 15574 // next boundary. 15575 } 15576 _workInProgress = _workInProgress.return; 15577 } while (_workInProgress !== null); 15578 // No boundary was found. Fallthrough to error mode. 15579 value = new Error('An update was suspended, but no placeholder UI was provided.'); 15580 } 15581 15582 // We didn't find a boundary that could handle this type of exception. Start 15583 // over and traverse parent path again, this time treating the exception 15584 // as an error. 15585 renderDidError(); 15586 value = createCapturedValue(value, sourceFiber); 15587 var workInProgress = returnFiber; 15588 do { 15589 switch (workInProgress.tag) { 15590 case HostRoot: 15591 { 15592 var _errorInfo = value; 15593 workInProgress.effectTag |= ShouldCapture; 15594 workInProgress.expirationTime = renderExpirationTime; 15595 var update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime); 15596 enqueueCapturedUpdate(workInProgress, update); 15597 return; 15598 } 15599 case ClassComponent: 15600 case ClassComponentLazy: 15601 // Capture and retry 15602 var errorInfo = value; 15603 var ctor = workInProgress.type; 15604 var instance = workInProgress.stateNode; 15605 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromCatch === 'function' && enableGetDerivedStateFromCatch || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) { 15606 workInProgress.effectTag |= ShouldCapture; 15607 workInProgress.expirationTime = renderExpirationTime; 15608 // Schedule the error boundary to re-render using updated state 15609 var _update = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime); 15610 enqueueCapturedUpdate(workInProgress, _update); 15611 return; 15612 } 15613 break; 15614 default: 15615 break; 15616 } 15617 workInProgress = workInProgress.return; 15618 } while (workInProgress !== null); 15619 } 15620 15621 function unwindWork(workInProgress, renderExpirationTime) { 15622 switch (workInProgress.tag) { 15623 case ClassComponent: 15624 { 15625 var Component = workInProgress.type; 15626 if (isContextProvider(Component)) { 15627 popContext(workInProgress); 15628 } 15629 var effectTag = workInProgress.effectTag; 15630 if (effectTag & ShouldCapture) { 15631 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture; 15632 return workInProgress; 15633 } 15634 return null; 15635 } 15636 case ClassComponentLazy: 15637 { 15638 var _Component = workInProgress.type._reactResult; 15639 if (isContextProvider(_Component)) { 15640 popContext(workInProgress); 15641 } 15642 var _effectTag = workInProgress.effectTag; 15643 if (_effectTag & ShouldCapture) { 15644 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture; 15645 return workInProgress; 15646 } 15647 return null; 15648 } 15649 case HostRoot: 15650 { 15651 popHostContainer(workInProgress); 15652 popTopLevelContextObject(workInProgress); 15653 var _effectTag2 = workInProgress.effectTag; 15654 !((_effectTag2 & 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; 15655 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture; 15656 return workInProgress; 15657 } 15658 case HostComponent: 15659 { 15660 popHostContext(workInProgress); 15661 return null; 15662 } 15663 case PlaceholderComponent: 15664 { 15665 var _effectTag3 = workInProgress.effectTag; 15666 if (_effectTag3 & ShouldCapture) { 15667 workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture; 15668 return workInProgress; 15669 } 15670 return null; 15671 } 15672 case HostPortal: 15673 popHostContainer(workInProgress); 15674 return null; 15675 case ContextProvider: 15676 popProvider(workInProgress); 15677 return null; 15678 default: 15679 return null; 15680 } 15681 } 15682 15683 function unwindInterruptedWork(interruptedWork) { 15684 switch (interruptedWork.tag) { 15685 case ClassComponent: 15686 { 15687 var childContextTypes = interruptedWork.type.childContextTypes; 15688 if (childContextTypes !== null && childContextTypes !== undefined) { 15689 popContext(interruptedWork); 15690 } 15691 break; 15692 } 15693 case ClassComponentLazy: 15694 { 15695 var _childContextTypes = interruptedWork.type._reactResult.childContextTypes; 15696 if (_childContextTypes !== null && _childContextTypes !== undefined) { 15697 popContext(interruptedWork); 15698 } 15699 break; 15700 } 15701 case HostRoot: 15702 { 15703 popHostContainer(interruptedWork); 15704 popTopLevelContextObject(interruptedWork); 15705 break; 15706 } 15707 case HostComponent: 15708 { 15709 popHostContext(interruptedWork); 15710 break; 15711 } 15712 case HostPortal: 15713 popHostContainer(interruptedWork); 15714 break; 15715 case ContextProvider: 15716 popProvider(interruptedWork); 15717 break; 15718 default: 15719 break; 15720 } 15721 } 15722 15723 var Dispatcher = { 15724 readContext: readContext 15725 }; 15726 15727 var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner; 15728 15729 15730 var didWarnAboutStateTransition = void 0; 15731 var didWarnSetStateChildContext = void 0; 15732 var warnAboutUpdateOnUnmounted = void 0; 15733 var warnAboutInvalidUpdates = void 0; 15734 15735 if (enableSchedulerTracing) { 15736 // Provide explicit error message when production+profiling bundle of e.g. react-dom 15737 // is used with production (non-profiling) bundle of schedule/tracing 15738 !(__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 `schedule/tracing` module with `schedule/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at http://fb.me/react-profiling') : void 0; 15739 } 15740 15741 { 15742 didWarnAboutStateTransition = false; 15743 didWarnSetStateChildContext = false; 15744 var didWarnStateUpdateForUnmountedComponent = {}; 15745 15746 warnAboutUpdateOnUnmounted = function (fiber) { 15747 // We show the whole stack but dedupe on the top component's name because 15748 // the problematic code almost always lies inside that component. 15749 var componentName = getComponentName(fiber.type) || 'ReactClass'; 15750 if (didWarnStateUpdateForUnmountedComponent[componentName]) { 15751 return; 15752 } 15753 warningWithoutStack$1(false, "Can't call setState (or forceUpdate) 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 the ' + 'componentWillUnmount method.%s', getStackByFiberInDevAndProd(fiber)); 15754 didWarnStateUpdateForUnmountedComponent[componentName] = true; 15755 }; 15756 15757 warnAboutInvalidUpdates = function (instance) { 15758 switch (phase) { 15759 case 'getChildContext': 15760 if (didWarnSetStateChildContext) { 15761 return; 15762 } 15763 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()'); 15764 didWarnSetStateChildContext = true; 15765 break; 15766 case 'render': 15767 if (didWarnAboutStateTransition) { 15768 return; 15769 } 15770 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.'); 15771 didWarnAboutStateTransition = true; 15772 break; 15773 } 15774 }; 15775 } 15776 15777 // Used to ensure computeUniqueAsyncExpiration is monotonically increasing. 15778 var lastUniqueAsyncExpiration = 0; 15779 15780 // Represents the expiration time that incoming updates should use. (If this 15781 // is NoWork, use the default strategy: async updates in async mode, sync 15782 // updates in sync mode.) 15783 var expirationContext = NoWork; 15784 15785 var isWorking = false; 15786 15787 // The next work in progress fiber that we're currently working on. 15788 var nextUnitOfWork = null; 15789 var nextRoot = null; 15790 // The time at which we're currently rendering work. 15791 var nextRenderExpirationTime = NoWork; 15792 var nextLatestAbsoluteTimeoutMs = -1; 15793 var nextRenderDidError = false; 15794 15795 // The next fiber with an effect that we're currently committing. 15796 var nextEffect = null; 15797 15798 var isCommitting$1 = false; 15799 15800 var legacyErrorBoundariesThatAlreadyFailed = null; 15801 15802 // Used for performance tracking. 15803 var interruptedBy = null; 15804 15805 // Do not decrement interaction counts in the event of suspense timeouts. 15806 // This would lead to prematurely calling the interaction-complete hook. 15807 var suspenseDidTimeout = false; 15808 15809 var stashedWorkInProgressProperties = void 0; 15810 var replayUnitOfWork = void 0; 15811 var isReplayingFailedUnitOfWork = void 0; 15812 var originalReplayError = void 0; 15813 var rethrowOriginalError = void 0; 15814 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { 15815 stashedWorkInProgressProperties = null; 15816 isReplayingFailedUnitOfWork = false; 15817 originalReplayError = null; 15818 replayUnitOfWork = function (failedUnitOfWork, thrownValue, isYieldy) { 15819 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') { 15820 // Don't replay promises. Treat everything else like an error. 15821 // TODO: Need to figure out a different strategy if/when we add 15822 // support for catching other types. 15823 return; 15824 } 15825 15826 // Restore the original state of the work-in-progress 15827 if (stashedWorkInProgressProperties === null) { 15828 // This should never happen. Don't throw because this code is DEV-only. 15829 warningWithoutStack$1(false, 'Could not replay rendering after an error. This is likely a bug in React. ' + 'Please file an issue.'); 15830 return; 15831 } 15832 assignFiberPropertiesInDEV(failedUnitOfWork, stashedWorkInProgressProperties); 15833 15834 switch (failedUnitOfWork.tag) { 15835 case HostRoot: 15836 popHostContainer(failedUnitOfWork); 15837 popTopLevelContextObject(failedUnitOfWork); 15838 break; 15839 case HostComponent: 15840 popHostContext(failedUnitOfWork); 15841 break; 15842 case ClassComponent: 15843 { 15844 var Component = failedUnitOfWork.type; 15845 if (isContextProvider(Component)) { 15846 popContext(failedUnitOfWork); 15847 } 15848 break; 15849 } 15850 case ClassComponentLazy: 15851 { 15852 var _Component = getResultFromResolvedThenable(failedUnitOfWork.type); 15853 if (isContextProvider(_Component)) { 15854 popContext(failedUnitOfWork); 15855 } 15856 break; 15857 } 15858 case HostPortal: 15859 popHostContainer(failedUnitOfWork); 15860 break; 15861 case ContextProvider: 15862 popProvider(failedUnitOfWork); 15863 break; 15864 } 15865 // Replay the begin phase. 15866 isReplayingFailedUnitOfWork = true; 15867 originalReplayError = thrownValue; 15868 invokeGuardedCallback(null, workLoop, null, isYieldy); 15869 isReplayingFailedUnitOfWork = false; 15870 originalReplayError = null; 15871 if (hasCaughtError()) { 15872 var replayError = clearCaughtError(); 15873 if (replayError != null && thrownValue != null) { 15874 try { 15875 // Reading the expando property is intentionally 15876 // inside `try` because it might be a getter or Proxy. 15877 if (replayError._suppressLogging) { 15878 // Also suppress logging for the original error. 15879 thrownValue._suppressLogging = true; 15880 } 15881 } catch (inner) { 15882 // Ignore. 15883 } 15884 } 15885 } else { 15886 // If the begin phase did not fail the second time, set this pointer 15887 // back to the original value. 15888 nextUnitOfWork = failedUnitOfWork; 15889 } 15890 }; 15891 rethrowOriginalError = function () { 15892 throw originalReplayError; 15893 }; 15894 } 15895 15896 function resetStack() { 15897 if (nextUnitOfWork !== null) { 15898 var interruptedWork = nextUnitOfWork.return; 15899 while (interruptedWork !== null) { 15900 unwindInterruptedWork(interruptedWork); 15901 interruptedWork = interruptedWork.return; 15902 } 15903 } 15904 15905 { 15906 ReactStrictModeWarnings.discardPendingWarnings(); 15907 checkThatStackIsEmpty(); 15908 } 15909 15910 nextRoot = null; 15911 nextRenderExpirationTime = NoWork; 15912 nextLatestAbsoluteTimeoutMs = -1; 15913 nextRenderDidError = false; 15914 nextUnitOfWork = null; 15915 } 15916 15917 function commitAllHostEffects() { 15918 while (nextEffect !== null) { 15919 { 15920 setCurrentFiber(nextEffect); 15921 } 15922 recordEffect(); 15923 15924 var effectTag = nextEffect.effectTag; 15925 15926 if (effectTag & ContentReset) { 15927 commitResetTextContent(nextEffect); 15928 } 15929 15930 if (effectTag & Ref) { 15931 var current$$1 = nextEffect.alternate; 15932 if (current$$1 !== null) { 15933 commitDetachRef(current$$1); 15934 } 15935 } 15936 15937 // The following switch statement is only concerned about placement, 15938 // updates, and deletions. To avoid needing to add a case for every 15939 // possible bitmap value, we remove the secondary effects from the 15940 // effect tag and switch on that value. 15941 var primaryEffectTag = effectTag & (Placement | Update | Deletion); 15942 switch (primaryEffectTag) { 15943 case Placement: 15944 { 15945 commitPlacement(nextEffect); 15946 // Clear the "placement" from effect tag so that we know that this is inserted, before 15947 // any life-cycles like componentDidMount gets called. 15948 // TODO: findDOMNode doesn't rely on this any more but isMounted 15949 // does and isMounted is deprecated anyway so we should be able 15950 // to kill this. 15951 nextEffect.effectTag &= ~Placement; 15952 break; 15953 } 15954 case PlacementAndUpdate: 15955 { 15956 // Placement 15957 commitPlacement(nextEffect); 15958 // Clear the "placement" from effect tag so that we know that this is inserted, before 15959 // any life-cycles like componentDidMount gets called. 15960 nextEffect.effectTag &= ~Placement; 15961 15962 // Update 15963 var _current = nextEffect.alternate; 15964 commitWork(_current, nextEffect); 15965 break; 15966 } 15967 case Update: 15968 { 15969 var _current2 = nextEffect.alternate; 15970 commitWork(_current2, nextEffect); 15971 break; 15972 } 15973 case Deletion: 15974 { 15975 commitDeletion(nextEffect); 15976 break; 15977 } 15978 } 15979 nextEffect = nextEffect.nextEffect; 15980 } 15981 15982 { 15983 resetCurrentFiber(); 15984 } 15985 } 15986 15987 function commitBeforeMutationLifecycles() { 15988 while (nextEffect !== null) { 15989 { 15990 setCurrentFiber(nextEffect); 15991 } 15992 15993 var effectTag = nextEffect.effectTag; 15994 if (effectTag & Snapshot) { 15995 recordEffect(); 15996 var current$$1 = nextEffect.alternate; 15997 commitBeforeMutationLifeCycles(current$$1, nextEffect); 15998 } 15999 16000 // Don't cleanup effects yet; 16001 // This will be done by commitAllLifeCycles() 16002 nextEffect = nextEffect.nextEffect; 16003 } 16004 16005 { 16006 resetCurrentFiber(); 16007 } 16008 } 16009 16010 function commitAllLifeCycles(finishedRoot, committedExpirationTime) { 16011 { 16012 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); 16013 16014 if (warnAboutDeprecatedLifecycles) { 16015 ReactStrictModeWarnings.flushPendingDeprecationWarnings(); 16016 } 16017 16018 if (warnAboutLegacyContextAPI) { 16019 ReactStrictModeWarnings.flushLegacyContextWarning(); 16020 } 16021 } 16022 while (nextEffect !== null) { 16023 var effectTag = nextEffect.effectTag; 16024 16025 if (effectTag & (Update | Callback)) { 16026 recordEffect(); 16027 var current$$1 = nextEffect.alternate; 16028 commitLifeCycles(finishedRoot, current$$1, nextEffect, committedExpirationTime); 16029 } 16030 16031 if (effectTag & Ref) { 16032 recordEffect(); 16033 commitAttachRef(nextEffect); 16034 } 16035 16036 var next = nextEffect.nextEffect; 16037 // Ensure that we clean these up so that we don't accidentally keep them. 16038 // I'm not actually sure this matters because we can't reset firstEffect 16039 // and lastEffect since they're on every node, not just the effectful 16040 // ones. So we have to clean everything as we reuse nodes anyway. 16041 nextEffect.nextEffect = null; 16042 // Ensure that we reset the effectTag here so that we can rely on effect 16043 // tags to reason about the current life-cycle. 16044 nextEffect = next; 16045 } 16046 } 16047 16048 function isAlreadyFailedLegacyErrorBoundary(instance) { 16049 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance); 16050 } 16051 16052 function markLegacyErrorBoundaryAsFailed(instance) { 16053 if (legacyErrorBoundariesThatAlreadyFailed === null) { 16054 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]); 16055 } else { 16056 legacyErrorBoundariesThatAlreadyFailed.add(instance); 16057 } 16058 } 16059 16060 function commitRoot(root, finishedWork) { 16061 isWorking = true; 16062 isCommitting$1 = true; 16063 startCommitTimer(); 16064 16065 !(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; 16066 var committedExpirationTime = root.pendingCommitExpirationTime; 16067 !(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; 16068 root.pendingCommitExpirationTime = NoWork; 16069 16070 // Update the pending priority levels to account for the work that we are 16071 // about to commit. This needs to happen before calling the lifecycles, since 16072 // they may schedule additional updates. 16073 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime; 16074 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime; 16075 var earliestRemainingTimeBeforeCommit = updateExpirationTimeBeforeCommit === NoWork || childExpirationTimeBeforeCommit !== NoWork && childExpirationTimeBeforeCommit < updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit; 16076 markCommittedPriorityLevels(root, earliestRemainingTimeBeforeCommit); 16077 16078 var prevInteractions = null; 16079 var committedInteractions = enableSchedulerTracing ? [] : null; 16080 if (enableSchedulerTracing) { 16081 // Restore any pending interactions at this point, 16082 // So that cascading work triggered during the render phase will be accounted for. 16083 prevInteractions = __interactionsRef.current; 16084 __interactionsRef.current = root.memoizedInteractions; 16085 16086 // We are potentially finished with the current batch of interactions. 16087 // So we should clear them out of the pending interaction map. 16088 // We do this at the start of commit in case cascading work is scheduled by commit phase lifecycles. 16089 // In that event, interaction data may be added back into the pending map for a future commit. 16090 // We also store the interactions we are about to commit so that we can notify subscribers after we're done. 16091 // These are stored as an Array rather than a Set, 16092 // Because the same interaction may be pending for multiple expiration times, 16093 // In which case it's important that we decrement the count the right number of times after finishing. 16094 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) { 16095 if (scheduledExpirationTime <= committedExpirationTime) { 16096 committedInteractions.push.apply(committedInteractions, Array.from(scheduledInteractions)); 16097 root.pendingInteractionMap.delete(scheduledExpirationTime); 16098 } 16099 }); 16100 } 16101 16102 // Reset this to null before calling lifecycles 16103 ReactCurrentOwner$2.current = null; 16104 16105 var firstEffect = void 0; 16106 if (finishedWork.effectTag > PerformedWork) { 16107 // A fiber's effect list consists only of its children, not itself. So if 16108 // the root has an effect, we need to add it to the end of the list. The 16109 // resulting list is the set that would belong to the root's parent, if 16110 // it had one; that is, all the effects in the tree including the root. 16111 if (finishedWork.lastEffect !== null) { 16112 finishedWork.lastEffect.nextEffect = finishedWork; 16113 firstEffect = finishedWork.firstEffect; 16114 } else { 16115 firstEffect = finishedWork; 16116 } 16117 } else { 16118 // There is no effect on the root. 16119 firstEffect = finishedWork.firstEffect; 16120 } 16121 16122 prepareForCommit(root.containerInfo); 16123 16124 // Invoke instances of getSnapshotBeforeUpdate before mutation. 16125 nextEffect = firstEffect; 16126 startCommitSnapshotEffectsTimer(); 16127 while (nextEffect !== null) { 16128 var didError = false; 16129 var error = void 0; 16130 { 16131 invokeGuardedCallback(null, commitBeforeMutationLifecycles, null); 16132 if (hasCaughtError()) { 16133 didError = true; 16134 error = clearCaughtError(); 16135 } 16136 } 16137 if (didError) { 16138 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0; 16139 captureCommitPhaseError(nextEffect, error); 16140 // Clean-up 16141 if (nextEffect !== null) { 16142 nextEffect = nextEffect.nextEffect; 16143 } 16144 } 16145 } 16146 stopCommitSnapshotEffectsTimer(); 16147 16148 if (enableProfilerTimer) { 16149 // Mark the current commit time to be shared by all Profilers in this batch. 16150 // This enables them to be grouped later. 16151 recordCommitTime(); 16152 } 16153 16154 // Commit all the side-effects within a tree. We'll do this in two passes. 16155 // The first pass performs all the host insertions, updates, deletions and 16156 // ref unmounts. 16157 nextEffect = firstEffect; 16158 startCommitHostEffectsTimer(); 16159 while (nextEffect !== null) { 16160 var _didError = false; 16161 var _error = void 0; 16162 { 16163 invokeGuardedCallback(null, commitAllHostEffects, null); 16164 if (hasCaughtError()) { 16165 _didError = true; 16166 _error = clearCaughtError(); 16167 } 16168 } 16169 if (_didError) { 16170 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0; 16171 captureCommitPhaseError(nextEffect, _error); 16172 // Clean-up 16173 if (nextEffect !== null) { 16174 nextEffect = nextEffect.nextEffect; 16175 } 16176 } 16177 } 16178 stopCommitHostEffectsTimer(); 16179 16180 resetAfterCommit(root.containerInfo); 16181 16182 // The work-in-progress tree is now the current tree. This must come after 16183 // the first pass of the commit phase, so that the previous tree is still 16184 // current during componentWillUnmount, but before the second pass, so that 16185 // the finished work is current during componentDidMount/Update. 16186 root.current = finishedWork; 16187 16188 // In the second pass we'll perform all life-cycles and ref callbacks. 16189 // Life-cycles happen as a separate pass so that all placements, updates, 16190 // and deletions in the entire tree have already been invoked. 16191 // This pass also triggers any renderer-specific initial effects. 16192 nextEffect = firstEffect; 16193 startCommitLifeCyclesTimer(); 16194 while (nextEffect !== null) { 16195 var _didError2 = false; 16196 var _error2 = void 0; 16197 { 16198 invokeGuardedCallback(null, commitAllLifeCycles, null, root, committedExpirationTime); 16199 if (hasCaughtError()) { 16200 _didError2 = true; 16201 _error2 = clearCaughtError(); 16202 } 16203 } 16204 if (_didError2) { 16205 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0; 16206 captureCommitPhaseError(nextEffect, _error2); 16207 if (nextEffect !== null) { 16208 nextEffect = nextEffect.nextEffect; 16209 } 16210 } 16211 } 16212 16213 isCommitting$1 = false; 16214 isWorking = false; 16215 stopCommitLifeCyclesTimer(); 16216 stopCommitTimer(); 16217 onCommitRoot(finishedWork.stateNode); 16218 if (true && ReactFiberInstrumentation_1.debugTool) { 16219 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork); 16220 } 16221 16222 var updateExpirationTimeAfterCommit = finishedWork.expirationTime; 16223 var childExpirationTimeAfterCommit = finishedWork.childExpirationTime; 16224 var earliestRemainingTimeAfterCommit = updateExpirationTimeAfterCommit === NoWork || childExpirationTimeAfterCommit !== NoWork && childExpirationTimeAfterCommit < updateExpirationTimeAfterCommit ? childExpirationTimeAfterCommit : updateExpirationTimeAfterCommit; 16225 if (earliestRemainingTimeAfterCommit === NoWork) { 16226 // If there's no remaining work, we can clear the set of already failed 16227 // error boundaries. 16228 legacyErrorBoundariesThatAlreadyFailed = null; 16229 } 16230 onCommit(root, earliestRemainingTimeAfterCommit); 16231 16232 if (enableSchedulerTracing) { 16233 __interactionsRef.current = prevInteractions; 16234 16235 var subscriber = void 0; 16236 16237 try { 16238 subscriber = __subscriberRef.current; 16239 if (subscriber !== null && root.memoizedInteractions.size > 0) { 16240 var threadID = computeThreadID(committedExpirationTime, root.interactionThreadID); 16241 subscriber.onWorkStopped(root.memoizedInteractions, threadID); 16242 } 16243 } catch (error) { 16244 // It's not safe for commitRoot() to throw. 16245 // Store the error for now and we'll re-throw in finishRendering(). 16246 if (!hasUnhandledError) { 16247 hasUnhandledError = true; 16248 unhandledError = error; 16249 } 16250 } finally { 16251 // Don't update interaction counts if we're frozen due to suspense. 16252 // In this case, we can skip the completed-work check entirely. 16253 if (!suspenseDidTimeout) { 16254 // Now that we're done, check the completed batch of interactions. 16255 // If no more work is outstanding for a given interaction, 16256 // We need to notify the subscribers that it's finished. 16257 committedInteractions.forEach(function (interaction) { 16258 interaction.__count--; 16259 if (subscriber !== null && interaction.__count === 0) { 16260 try { 16261 subscriber.onInteractionScheduledWorkCompleted(interaction); 16262 } catch (error) { 16263 // It's not safe for commitRoot() to throw. 16264 // Store the error for now and we'll re-throw in finishRendering(). 16265 if (!hasUnhandledError) { 16266 hasUnhandledError = true; 16267 unhandledError = error; 16268 } 16269 } 16270 } 16271 }); 16272 } 16273 } 16274 } 16275 } 16276 16277 function resetChildExpirationTime(workInProgress, renderTime) { 16278 if (renderTime !== Never && workInProgress.childExpirationTime === Never) { 16279 // The children of this component are hidden. Don't bubble their 16280 // expiration times. 16281 return; 16282 } 16283 16284 var newChildExpirationTime = NoWork; 16285 16286 // Bubble up the earliest expiration time. 16287 if (enableProfilerTimer && workInProgress.mode & ProfileMode) { 16288 // We're in profiling mode. 16289 // Let's use this same traversal to update the render durations. 16290 var actualDuration = workInProgress.actualDuration; 16291 var treeBaseDuration = workInProgress.selfBaseDuration; 16292 16293 // When a fiber is cloned, its actualDuration is reset to 0. 16294 // This value will only be updated if work is done on the fiber (i.e. it doesn't bailout). 16295 // When work is done, it should bubble to the parent's actualDuration. 16296 // If the fiber has not been cloned though, (meaning no work was done), 16297 // Then this value will reflect the amount of time spent working on a previous render. 16298 // In that case it should not bubble. 16299 // We determine whether it was cloned by comparing the child pointer. 16300 var shouldBubbleActualDurations = workInProgress.alternate === null || workInProgress.child !== workInProgress.alternate.child; 16301 16302 var child = workInProgress.child; 16303 while (child !== null) { 16304 var childUpdateExpirationTime = child.expirationTime; 16305 var childChildExpirationTime = child.childExpirationTime; 16306 if (newChildExpirationTime === NoWork || childUpdateExpirationTime !== NoWork && childUpdateExpirationTime < newChildExpirationTime) { 16307 newChildExpirationTime = childUpdateExpirationTime; 16308 } 16309 if (newChildExpirationTime === NoWork || childChildExpirationTime !== NoWork && childChildExpirationTime < newChildExpirationTime) { 16310 newChildExpirationTime = childChildExpirationTime; 16311 } 16312 if (shouldBubbleActualDurations) { 16313 actualDuration += child.actualDuration; 16314 } 16315 treeBaseDuration += child.treeBaseDuration; 16316 child = child.sibling; 16317 } 16318 workInProgress.actualDuration = actualDuration; 16319 workInProgress.treeBaseDuration = treeBaseDuration; 16320 } else { 16321 var _child = workInProgress.child; 16322 while (_child !== null) { 16323 var _childUpdateExpirationTime = _child.expirationTime; 16324 var _childChildExpirationTime = _child.childExpirationTime; 16325 if (newChildExpirationTime === NoWork || _childUpdateExpirationTime !== NoWork && _childUpdateExpirationTime < newChildExpirationTime) { 16326 newChildExpirationTime = _childUpdateExpirationTime; 16327 } 16328 if (newChildExpirationTime === NoWork || _childChildExpirationTime !== NoWork && _childChildExpirationTime < newChildExpirationTime) { 16329 newChildExpirationTime = _childChildExpirationTime; 16330 } 16331 _child = _child.sibling; 16332 } 16333 } 16334 16335 workInProgress.childExpirationTime = newChildExpirationTime; 16336 } 16337 16338 function completeUnitOfWork(workInProgress) { 16339 // Attempt to complete the current unit of work, then move to the 16340 // next sibling. If there are no more siblings, return to the 16341 // parent fiber. 16342 while (true) { 16343 // The current, flushed, state of this fiber is the alternate. 16344 // Ideally nothing should rely on this, but relying on it here 16345 // means that we don't need an additional field on the work in 16346 // progress. 16347 var current$$1 = workInProgress.alternate; 16348 { 16349 setCurrentFiber(workInProgress); 16350 } 16351 16352 var returnFiber = workInProgress.return; 16353 var siblingFiber = workInProgress.sibling; 16354 16355 if ((workInProgress.effectTag & Incomplete) === NoEffect) { 16356 // This fiber completed. 16357 if (enableProfilerTimer) { 16358 if (workInProgress.mode & ProfileMode) { 16359 startProfilerTimer(workInProgress); 16360 } 16361 16362 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime); 16363 16364 if (workInProgress.mode & ProfileMode) { 16365 // Update render duration assuming we didn't error. 16366 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); 16367 } 16368 } else { 16369 nextUnitOfWork = completeWork(current$$1, workInProgress, nextRenderExpirationTime); 16370 } 16371 var next = nextUnitOfWork; 16372 stopWorkTimer(workInProgress); 16373 resetChildExpirationTime(workInProgress, nextRenderExpirationTime); 16374 { 16375 resetCurrentFiber(); 16376 } 16377 16378 if (next !== null) { 16379 stopWorkTimer(workInProgress); 16380 if (true && ReactFiberInstrumentation_1.debugTool) { 16381 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress); 16382 } 16383 // If completing this work spawned new work, do that next. We'll come 16384 // back here again. 16385 return next; 16386 } 16387 16388 if (returnFiber !== null && 16389 // Do not append effects to parents if a sibling failed to complete 16390 (returnFiber.effectTag & Incomplete) === NoEffect) { 16391 // Append all the effects of the subtree and this fiber onto the effect 16392 // list of the parent. The completion order of the children affects the 16393 // side-effect order. 16394 if (returnFiber.firstEffect === null) { 16395 returnFiber.firstEffect = workInProgress.firstEffect; 16396 } 16397 if (workInProgress.lastEffect !== null) { 16398 if (returnFiber.lastEffect !== null) { 16399 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect; 16400 } 16401 returnFiber.lastEffect = workInProgress.lastEffect; 16402 } 16403 16404 // If this fiber had side-effects, we append it AFTER the children's 16405 // side-effects. We can perform certain side-effects earlier if 16406 // needed, by doing multiple passes over the effect list. We don't want 16407 // to schedule our own side-effect on our own list because if end up 16408 // reusing children we'll schedule this effect onto itself since we're 16409 // at the end. 16410 var effectTag = workInProgress.effectTag; 16411 // Skip both NoWork and PerformedWork tags when creating the effect list. 16412 // PerformedWork effect is read by React DevTools but shouldn't be committed. 16413 if (effectTag > PerformedWork) { 16414 if (returnFiber.lastEffect !== null) { 16415 returnFiber.lastEffect.nextEffect = workInProgress; 16416 } else { 16417 returnFiber.firstEffect = workInProgress; 16418 } 16419 returnFiber.lastEffect = workInProgress; 16420 } 16421 } 16422 16423 if (true && ReactFiberInstrumentation_1.debugTool) { 16424 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress); 16425 } 16426 16427 if (siblingFiber !== null) { 16428 // If there is more work to do in this returnFiber, do that next. 16429 return siblingFiber; 16430 } else if (returnFiber !== null) { 16431 // If there's no more work in this returnFiber. Complete the returnFiber. 16432 workInProgress = returnFiber; 16433 continue; 16434 } else { 16435 // We've reached the root. 16436 return null; 16437 } 16438 } else { 16439 if (workInProgress.mode & ProfileMode) { 16440 // Record the render duration for the fiber that errored. 16441 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); 16442 } 16443 16444 // This fiber did not complete because something threw. Pop values off 16445 // the stack without entering the complete phase. If this is a boundary, 16446 // capture values if possible. 16447 var _next = unwindWork(workInProgress, nextRenderExpirationTime); 16448 // Because this fiber did not complete, don't reset its expiration time. 16449 if (workInProgress.effectTag & DidCapture) { 16450 // Restarting an error boundary 16451 stopFailedWorkTimer(workInProgress); 16452 } else { 16453 stopWorkTimer(workInProgress); 16454 } 16455 16456 { 16457 resetCurrentFiber(); 16458 } 16459 16460 if (_next !== null) { 16461 stopWorkTimer(workInProgress); 16462 if (true && ReactFiberInstrumentation_1.debugTool) { 16463 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress); 16464 } 16465 16466 if (enableProfilerTimer) { 16467 // Include the time spent working on failed children before continuing. 16468 if (_next.mode & ProfileMode) { 16469 var actualDuration = _next.actualDuration; 16470 var child = _next.child; 16471 while (child !== null) { 16472 actualDuration += child.actualDuration; 16473 child = child.sibling; 16474 } 16475 _next.actualDuration = actualDuration; 16476 } 16477 } 16478 16479 // If completing this work spawned new work, do that next. We'll come 16480 // back here again. 16481 // Since we're restarting, remove anything that is not a host effect 16482 // from the effect tag. 16483 _next.effectTag &= HostEffectMask; 16484 return _next; 16485 } 16486 16487 if (returnFiber !== null) { 16488 // Mark the parent fiber as incomplete and clear its effect list. 16489 returnFiber.firstEffect = returnFiber.lastEffect = null; 16490 returnFiber.effectTag |= Incomplete; 16491 } 16492 16493 if (true && ReactFiberInstrumentation_1.debugTool) { 16494 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress); 16495 } 16496 16497 if (siblingFiber !== null) { 16498 // If there is more work to do in this returnFiber, do that next. 16499 return siblingFiber; 16500 } else if (returnFiber !== null) { 16501 // If there's no more work in this returnFiber. Complete the returnFiber. 16502 workInProgress = returnFiber; 16503 continue; 16504 } else { 16505 return null; 16506 } 16507 } 16508 } 16509 16510 // Without this explicit null return Flow complains of invalid return type 16511 // TODO Remove the above while(true) loop 16512 // eslint-disable-next-line no-unreachable 16513 return null; 16514 } 16515 16516 function performUnitOfWork(workInProgress) { 16517 // The current, flushed, state of this fiber is the alternate. 16518 // Ideally nothing should rely on this, but relying on it here 16519 // means that we don't need an additional field on the work in 16520 // progress. 16521 var current$$1 = workInProgress.alternate; 16522 16523 // See if beginning this work spawns more work. 16524 startWorkTimer(workInProgress); 16525 { 16526 setCurrentFiber(workInProgress); 16527 } 16528 16529 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { 16530 stashedWorkInProgressProperties = assignFiberPropertiesInDEV(stashedWorkInProgressProperties, workInProgress); 16531 } 16532 16533 var next = void 0; 16534 if (enableProfilerTimer) { 16535 if (workInProgress.mode & ProfileMode) { 16536 startProfilerTimer(workInProgress); 16537 } 16538 16539 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime); 16540 16541 if (workInProgress.mode & ProfileMode) { 16542 // Record the render duration assuming we didn't bailout (or error). 16543 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true); 16544 } 16545 } else { 16546 next = beginWork(current$$1, workInProgress, nextRenderExpirationTime); 16547 } 16548 16549 { 16550 resetCurrentFiber(); 16551 if (isReplayingFailedUnitOfWork) { 16552 // Currently replaying a failed unit of work. This should be unreachable, 16553 // because the render phase is meant to be idempotent, and it should 16554 // have thrown again. Since it didn't, rethrow the original error, so 16555 // React's internal stack is not misaligned. 16556 rethrowOriginalError(); 16557 } 16558 } 16559 if (true && ReactFiberInstrumentation_1.debugTool) { 16560 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress); 16561 } 16562 16563 if (next === null) { 16564 // If this doesn't spawn new work, complete the current work. 16565 next = completeUnitOfWork(workInProgress); 16566 } 16567 16568 ReactCurrentOwner$2.current = null; 16569 16570 return next; 16571 } 16572 16573 function workLoop(isYieldy) { 16574 if (!isYieldy) { 16575 // Flush work without yielding 16576 while (nextUnitOfWork !== null) { 16577 nextUnitOfWork = performUnitOfWork(nextUnitOfWork); 16578 } 16579 } else { 16580 // Flush asynchronous work until the deadline runs out of time. 16581 while (nextUnitOfWork !== null && !shouldYield()) { 16582 nextUnitOfWork = performUnitOfWork(nextUnitOfWork); 16583 } 16584 } 16585 } 16586 16587 function renderRoot(root, isYieldy, isExpired) { 16588 !!isWorking ? invariant(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0; 16589 isWorking = true; 16590 ReactCurrentOwner$2.currentDispatcher = Dispatcher; 16591 16592 var expirationTime = root.nextExpirationTimeToWorkOn; 16593 16594 var prevInteractions = null; 16595 if (enableSchedulerTracing) { 16596 // We're about to start new traced work. 16597 // Restore pending interactions so cascading work triggered during the render phase will be accounted for. 16598 prevInteractions = __interactionsRef.current; 16599 __interactionsRef.current = root.memoizedInteractions; 16600 } 16601 16602 // Check if we're starting from a fresh stack, or if we're resuming from 16603 // previously yielded work. 16604 if (expirationTime !== nextRenderExpirationTime || root !== nextRoot || nextUnitOfWork === null) { 16605 // Reset the stack and start working from the root. 16606 resetStack(); 16607 nextRoot = root; 16608 nextRenderExpirationTime = expirationTime; 16609 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, nextRenderExpirationTime); 16610 root.pendingCommitExpirationTime = NoWork; 16611 16612 if (enableSchedulerTracing) { 16613 // Determine which interactions this batch of work currently includes, 16614 // So that we can accurately attribute time spent working on it, 16615 var interactions = new Set(); 16616 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) { 16617 if (scheduledExpirationTime <= expirationTime) { 16618 scheduledInteractions.forEach(function (interaction) { 16619 return interactions.add(interaction); 16620 }); 16621 } 16622 }); 16623 16624 // Store the current set of interactions on the FiberRoot for a few reasons: 16625 // We can re-use it in hot functions like renderRoot() without having to recalculate it. 16626 // We will also use it in commitWork() to pass to any Profiler onRender() hooks. 16627 // This also provides DevTools with a way to access it when the onCommitRoot() hook is called. 16628 root.memoizedInteractions = interactions; 16629 16630 if (interactions.size > 0) { 16631 var subscriber = __subscriberRef.current; 16632 if (subscriber !== null) { 16633 var threadID = computeThreadID(expirationTime, root.interactionThreadID); 16634 try { 16635 subscriber.onWorkStarted(interactions, threadID); 16636 } catch (error) { 16637 // Work thrown by an interaction tracing subscriber should be rethrown, 16638 // But only once it's safe (to avoid leaveing the scheduler in an invalid state). 16639 // Store the error for now and we'll re-throw in finishRendering(). 16640 if (!hasUnhandledError) { 16641 hasUnhandledError = true; 16642 unhandledError = error; 16643 } 16644 } 16645 } 16646 } 16647 } 16648 } 16649 16650 var didFatal = false; 16651 16652 startWorkLoopTimer(nextUnitOfWork); 16653 16654 do { 16655 try { 16656 workLoop(isYieldy); 16657 } catch (thrownValue) { 16658 if (nextUnitOfWork === null) { 16659 // This is a fatal error. 16660 didFatal = true; 16661 onUncaughtError(thrownValue); 16662 } else { 16663 { 16664 // Reset global debug state 16665 // We assume this is defined in DEV 16666 resetCurrentlyProcessingQueue(); 16667 } 16668 16669 var failedUnitOfWork = nextUnitOfWork; 16670 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { 16671 replayUnitOfWork(failedUnitOfWork, thrownValue, isYieldy); 16672 } 16673 16674 // TODO: we already know this isn't true in some cases. 16675 // At least this shows a nicer error message until we figure out the cause. 16676 // https://github.com/facebook/react/issues/12449#issuecomment-386727431 16677 !(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; 16678 16679 var sourceFiber = nextUnitOfWork; 16680 var returnFiber = sourceFiber.return; 16681 if (returnFiber === null) { 16682 // This is the root. The root could capture its own errors. However, 16683 // we don't know if it errors before or after we pushed the host 16684 // context. This information is needed to avoid a stack mismatch. 16685 // Because we're not sure, treat this as a fatal error. We could track 16686 // which phase it fails in, but doesn't seem worth it. At least 16687 // for now. 16688 didFatal = true; 16689 onUncaughtError(thrownValue); 16690 } else { 16691 throwException(root, returnFiber, sourceFiber, thrownValue, nextRenderExpirationTime); 16692 nextUnitOfWork = completeUnitOfWork(sourceFiber); 16693 continue; 16694 } 16695 } 16696 } 16697 break; 16698 } while (true); 16699 16700 if (enableSchedulerTracing) { 16701 // Traced work is done for now; restore the previous interactions. 16702 __interactionsRef.current = prevInteractions; 16703 } 16704 16705 // We're done performing work. Time to clean up. 16706 isWorking = false; 16707 ReactCurrentOwner$2.currentDispatcher = null; 16708 resetContextDependences(); 16709 16710 // Yield back to main thread. 16711 if (didFatal) { 16712 var _didCompleteRoot = false; 16713 stopWorkLoopTimer(interruptedBy, _didCompleteRoot); 16714 interruptedBy = null; 16715 // There was a fatal error. 16716 { 16717 resetStackAfterFatalErrorInDev(); 16718 } 16719 // `nextRoot` points to the in-progress root. A non-null value indicates 16720 // that we're in the middle of an async render. Set it to null to indicate 16721 // there's no more work to be done in the current batch. 16722 nextRoot = null; 16723 onFatal(root); 16724 return; 16725 } 16726 16727 if (nextUnitOfWork !== null) { 16728 // There's still remaining async work in this tree, but we ran out of time 16729 // in the current frame. Yield back to the renderer. Unless we're 16730 // interrupted by a higher priority update, we'll continue later from where 16731 // we left off. 16732 var _didCompleteRoot2 = false; 16733 stopWorkLoopTimer(interruptedBy, _didCompleteRoot2); 16734 interruptedBy = null; 16735 onYield(root); 16736 return; 16737 } 16738 16739 // We completed the whole tree. 16740 var didCompleteRoot = true; 16741 stopWorkLoopTimer(interruptedBy, didCompleteRoot); 16742 var rootWorkInProgress = root.current.alternate; 16743 !(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; 16744 16745 // `nextRoot` points to the in-progress root. A non-null value indicates 16746 // that we're in the middle of an async render. Set it to null to indicate 16747 // there's no more work to be done in the current batch. 16748 nextRoot = null; 16749 interruptedBy = null; 16750 16751 if (nextRenderDidError) { 16752 // There was an error 16753 if (hasLowerPriorityWork(root, expirationTime)) { 16754 // There's lower priority work. If so, it may have the effect of fixing 16755 // the exception that was just thrown. Exit without committing. This is 16756 // similar to a suspend, but without a timeout because we're not waiting 16757 // for a promise to resolve. React will restart at the lower 16758 // priority level. 16759 markSuspendedPriorityLevel(root, expirationTime); 16760 var suspendedExpirationTime = expirationTime; 16761 var rootExpirationTime = root.expirationTime; 16762 onSuspend(root, rootWorkInProgress, suspendedExpirationTime, rootExpirationTime, -1 // Indicates no timeout 16763 ); 16764 return; 16765 } else if ( 16766 // There's no lower priority work, but we're rendering asynchronously. 16767 // Synchronsouly attempt to render the same level one more time. This is 16768 // similar to a suspend, but without a timeout because we're not waiting 16769 // for a promise to resolve. 16770 !root.didError && !isExpired) { 16771 root.didError = true; 16772 var _suspendedExpirationTime = root.nextExpirationTimeToWorkOn = expirationTime; 16773 var _rootExpirationTime = root.expirationTime = Sync; 16774 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime, _rootExpirationTime, -1 // Indicates no timeout 16775 ); 16776 return; 16777 } 16778 } 16779 16780 if (enableSuspense && !isExpired && nextLatestAbsoluteTimeoutMs !== -1) { 16781 // The tree was suspended. 16782 var _suspendedExpirationTime2 = expirationTime; 16783 markSuspendedPriorityLevel(root, _suspendedExpirationTime2); 16784 16785 // Find the earliest uncommitted expiration time in the tree, including 16786 // work that is suspended. The timeout threshold cannot be longer than 16787 // the overall expiration. 16788 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, expirationTime); 16789 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime); 16790 if (earliestExpirationTimeMs < nextLatestAbsoluteTimeoutMs) { 16791 nextLatestAbsoluteTimeoutMs = earliestExpirationTimeMs; 16792 } 16793 16794 // Subtract the current time from the absolute timeout to get the number 16795 // of milliseconds until the timeout. In other words, convert an absolute 16796 // timestamp to a relative time. This is the value that is passed 16797 // to `setTimeout`. 16798 var currentTimeMs = expirationTimeToMs(requestCurrentTime()); 16799 var msUntilTimeout = nextLatestAbsoluteTimeoutMs - currentTimeMs; 16800 msUntilTimeout = msUntilTimeout < 0 ? 0 : msUntilTimeout; 16801 16802 // TODO: Account for the Just Noticeable Difference 16803 16804 var _rootExpirationTime2 = root.expirationTime; 16805 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime2, _rootExpirationTime2, msUntilTimeout); 16806 return; 16807 } 16808 16809 // Ready to commit. 16810 onComplete(root, rootWorkInProgress, expirationTime); 16811 } 16812 16813 function dispatch(sourceFiber, value, expirationTime) { 16814 !(!isWorking || isCommitting$1) ? invariant(false, 'dispatch: Cannot dispatch during the render phase.') : void 0; 16815 16816 var fiber = sourceFiber.return; 16817 while (fiber !== null) { 16818 switch (fiber.tag) { 16819 case ClassComponent: 16820 case ClassComponentLazy: 16821 var ctor = fiber.type; 16822 var instance = fiber.stateNode; 16823 if (typeof ctor.getDerivedStateFromCatch === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) { 16824 var errorInfo = createCapturedValue(value, sourceFiber); 16825 var update = createClassErrorUpdate(fiber, errorInfo, expirationTime); 16826 enqueueUpdate(fiber, update); 16827 scheduleWork(fiber, expirationTime); 16828 return; 16829 } 16830 break; 16831 case HostRoot: 16832 { 16833 var _errorInfo = createCapturedValue(value, sourceFiber); 16834 var _update = createRootErrorUpdate(fiber, _errorInfo, expirationTime); 16835 enqueueUpdate(fiber, _update); 16836 scheduleWork(fiber, expirationTime); 16837 return; 16838 } 16839 } 16840 fiber = fiber.return; 16841 } 16842 16843 if (sourceFiber.tag === HostRoot) { 16844 // Error was thrown at the root. There is no parent, so the root 16845 // itself should capture it. 16846 var rootFiber = sourceFiber; 16847 var _errorInfo2 = createCapturedValue(value, rootFiber); 16848 var _update2 = createRootErrorUpdate(rootFiber, _errorInfo2, expirationTime); 16849 enqueueUpdate(rootFiber, _update2); 16850 scheduleWork(rootFiber, expirationTime); 16851 } 16852 } 16853 16854 function captureCommitPhaseError(fiber, error) { 16855 return dispatch(fiber, error, Sync); 16856 } 16857 16858 function computeThreadID(expirationTime, interactionThreadID) { 16859 // Interaction threads are unique per root and expiration time. 16860 return expirationTime * 1000 + interactionThreadID; 16861 } 16862 16863 // Creates a unique async expiration time. 16864 function computeUniqueAsyncExpiration() { 16865 var currentTime = requestCurrentTime(); 16866 var result = computeAsyncExpiration(currentTime); 16867 if (result <= lastUniqueAsyncExpiration) { 16868 // Since we assume the current time monotonically increases, we only hit 16869 // this branch when computeUniqueAsyncExpiration is fired multiple times 16870 // within a 200ms window (or whatever the async bucket size is). 16871 result = lastUniqueAsyncExpiration + 1; 16872 } 16873 lastUniqueAsyncExpiration = result; 16874 return lastUniqueAsyncExpiration; 16875 } 16876 16877 function computeExpirationForFiber(currentTime, fiber) { 16878 var expirationTime = void 0; 16879 if (expirationContext !== NoWork) { 16880 // An explicit expiration context was set; 16881 expirationTime = expirationContext; 16882 } else if (isWorking) { 16883 if (isCommitting$1) { 16884 // Updates that occur during the commit phase should have sync priority 16885 // by default. 16886 expirationTime = Sync; 16887 } else { 16888 // Updates during the render phase should expire at the same time as 16889 // the work that is being rendered. 16890 expirationTime = nextRenderExpirationTime; 16891 } 16892 } else { 16893 // No explicit expiration context was set, and we're not currently 16894 // performing work. Calculate a new expiration time. 16895 if (fiber.mode & AsyncMode) { 16896 if (isBatchingInteractiveUpdates) { 16897 // This is an interactive update 16898 expirationTime = computeInteractiveExpiration(currentTime); 16899 } else { 16900 // This is an async update 16901 expirationTime = computeAsyncExpiration(currentTime); 16902 } 16903 // If we're in the middle of rendering a tree, do not update at the same 16904 // expiration time that is already rendering. 16905 if (nextRoot !== null && expirationTime === nextRenderExpirationTime) { 16906 expirationTime += 1; 16907 } 16908 } else { 16909 // This is a sync update 16910 expirationTime = Sync; 16911 } 16912 } 16913 if (isBatchingInteractiveUpdates) { 16914 // This is an interactive update. Keep track of the lowest pending 16915 // interactive expiration time. This allows us to synchronously flush 16916 // all interactive updates when needed. 16917 if (lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime > lowestPriorityPendingInteractiveExpirationTime) { 16918 lowestPriorityPendingInteractiveExpirationTime = expirationTime; 16919 } 16920 } 16921 return expirationTime; 16922 } 16923 16924 function renderDidSuspend(root, absoluteTimeoutMs, suspendedTime) { 16925 // Schedule the timeout. 16926 if (absoluteTimeoutMs >= 0 && nextLatestAbsoluteTimeoutMs < absoluteTimeoutMs) { 16927 nextLatestAbsoluteTimeoutMs = absoluteTimeoutMs; 16928 } 16929 } 16930 16931 function renderDidError() { 16932 nextRenderDidError = true; 16933 } 16934 16935 function retrySuspendedRoot(root, fiber, suspendedTime) { 16936 if (enableSuspense) { 16937 var retryTime = void 0; 16938 16939 if (isPriorityLevelSuspended(root, suspendedTime)) { 16940 // Ping at the original level 16941 retryTime = suspendedTime; 16942 markPingedPriorityLevel(root, retryTime); 16943 } else { 16944 // Placeholder already timed out. Compute a new expiration time 16945 var currentTime = requestCurrentTime(); 16946 retryTime = computeExpirationForFiber(currentTime, fiber); 16947 markPendingPriorityLevel(root, retryTime); 16948 } 16949 16950 scheduleWorkToRoot(fiber, retryTime); 16951 var rootExpirationTime = root.expirationTime; 16952 if (rootExpirationTime !== NoWork) { 16953 if (enableSchedulerTracing) { 16954 // Restore previous interactions so that new work is associated with them. 16955 var prevInteractions = __interactionsRef.current; 16956 __interactionsRef.current = root.memoizedInteractions; 16957 // Because suspense timeouts do not decrement the interaction count, 16958 // Continued suspense work should also not increment the count. 16959 storeInteractionsForExpirationTime(root, rootExpirationTime, false); 16960 requestWork(root, rootExpirationTime); 16961 __interactionsRef.current = prevInteractions; 16962 } else { 16963 requestWork(root, rootExpirationTime); 16964 } 16965 } 16966 } 16967 } 16968 16969 function scheduleWorkToRoot(fiber, expirationTime) { 16970 // Update the source fiber's expiration time 16971 if (fiber.expirationTime === NoWork || fiber.expirationTime > expirationTime) { 16972 fiber.expirationTime = expirationTime; 16973 } 16974 var alternate = fiber.alternate; 16975 if (alternate !== null && (alternate.expirationTime === NoWork || alternate.expirationTime > expirationTime)) { 16976 alternate.expirationTime = expirationTime; 16977 } 16978 // Walk the parent path to the root and update the child expiration time. 16979 var node = fiber.return; 16980 if (node === null && fiber.tag === HostRoot) { 16981 return fiber.stateNode; 16982 } 16983 while (node !== null) { 16984 alternate = node.alternate; 16985 if (node.childExpirationTime === NoWork || node.childExpirationTime > expirationTime) { 16986 node.childExpirationTime = expirationTime; 16987 if (alternate !== null && (alternate.childExpirationTime === NoWork || alternate.childExpirationTime > expirationTime)) { 16988 alternate.childExpirationTime = expirationTime; 16989 } 16990 } else if (alternate !== null && (alternate.childExpirationTime === NoWork || alternate.childExpirationTime > expirationTime)) { 16991 alternate.childExpirationTime = expirationTime; 16992 } 16993 if (node.return === null && node.tag === HostRoot) { 16994 return node.stateNode; 16995 } 16996 node = node.return; 16997 } 16998 return null; 16999 } 17000 17001 function storeInteractionsForExpirationTime(root, expirationTime, updateInteractionCounts) { 17002 if (!enableSchedulerTracing) { 17003 return; 17004 } 17005 17006 var interactions = __interactionsRef.current; 17007 if (interactions.size > 0) { 17008 var pendingInteractions = root.pendingInteractionMap.get(expirationTime); 17009 if (pendingInteractions != null) { 17010 interactions.forEach(function (interaction) { 17011 if (updateInteractionCounts && !pendingInteractions.has(interaction)) { 17012 // Update the pending async work count for previously unscheduled interaction. 17013 interaction.__count++; 17014 } 17015 17016 pendingInteractions.add(interaction); 17017 }); 17018 } else { 17019 root.pendingInteractionMap.set(expirationTime, new Set(interactions)); 17020 17021 // Update the pending async work count for the current interactions. 17022 if (updateInteractionCounts) { 17023 interactions.forEach(function (interaction) { 17024 interaction.__count++; 17025 }); 17026 } 17027 } 17028 17029 var subscriber = __subscriberRef.current; 17030 if (subscriber !== null) { 17031 var threadID = computeThreadID(expirationTime, root.interactionThreadID); 17032 subscriber.onWorkScheduled(interactions, threadID); 17033 } 17034 } 17035 } 17036 17037 function scheduleWork(fiber, expirationTime) { 17038 recordScheduleUpdate(); 17039 17040 { 17041 if (fiber.tag === ClassComponent || fiber.tag === ClassComponentLazy) { 17042 var instance = fiber.stateNode; 17043 warnAboutInvalidUpdates(instance); 17044 } 17045 } 17046 17047 var root = scheduleWorkToRoot(fiber, expirationTime); 17048 if (root === null) { 17049 if (true && (fiber.tag === ClassComponent || fiber.tag === ClassComponentLazy)) { 17050 warnAboutUpdateOnUnmounted(fiber); 17051 } 17052 return; 17053 } 17054 17055 if (enableSchedulerTracing) { 17056 storeInteractionsForExpirationTime(root, expirationTime, true); 17057 } 17058 17059 if (!isWorking && nextRenderExpirationTime !== NoWork && expirationTime < nextRenderExpirationTime) { 17060 // This is an interruption. (Used for performance tracking.) 17061 interruptedBy = fiber; 17062 resetStack(); 17063 } 17064 markPendingPriorityLevel(root, expirationTime); 17065 if ( 17066 // If we're in the render phase, we don't need to schedule this root 17067 // for an update, because we'll do it before we exit... 17068 !isWorking || isCommitting$1 || 17069 // ...unless this is a different root than the one we're rendering. 17070 nextRoot !== root) { 17071 var rootExpirationTime = root.expirationTime; 17072 requestWork(root, rootExpirationTime); 17073 } 17074 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) { 17075 // Reset this back to zero so subsequent updates don't throw. 17076 nestedUpdateCount = 0; 17077 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.'); 17078 } 17079 } 17080 17081 function syncUpdates(fn, a, b, c, d) { 17082 var previousExpirationContext = expirationContext; 17083 expirationContext = Sync; 17084 try { 17085 return fn(a, b, c, d); 17086 } finally { 17087 expirationContext = previousExpirationContext; 17088 } 17089 } 17090 17091 // TODO: Everything below this is written as if it has been lifted to the 17092 // renderers. I'll do this in a follow-up. 17093 17094 // Linked-list of roots 17095 var firstScheduledRoot = null; 17096 var lastScheduledRoot = null; 17097 17098 var callbackExpirationTime = NoWork; 17099 var callbackID = void 0; 17100 var isRendering = false; 17101 var nextFlushedRoot = null; 17102 var nextFlushedExpirationTime = NoWork; 17103 var lowestPriorityPendingInteractiveExpirationTime = NoWork; 17104 var deadlineDidExpire = false; 17105 var hasUnhandledError = false; 17106 var unhandledError = null; 17107 var deadline = null; 17108 17109 var isBatchingUpdates = false; 17110 var isUnbatchingUpdates = false; 17111 var isBatchingInteractiveUpdates = false; 17112 17113 var completedBatches = null; 17114 17115 var originalStartTimeMs = unstable_now(); 17116 var currentRendererTime = msToExpirationTime(originalStartTimeMs); 17117 var currentSchedulerTime = currentRendererTime; 17118 17119 // Use these to prevent an infinite loop of nested updates 17120 var NESTED_UPDATE_LIMIT = 50; 17121 var nestedUpdateCount = 0; 17122 var lastCommittedRootDuringThisBatch = null; 17123 17124 var timeHeuristicForUnitOfWork = 1; 17125 17126 function recomputeCurrentRendererTime() { 17127 var currentTimeMs = unstable_now() - originalStartTimeMs; 17128 currentRendererTime = msToExpirationTime(currentTimeMs); 17129 } 17130 17131 function scheduleCallbackWithExpirationTime(root, expirationTime) { 17132 if (callbackExpirationTime !== NoWork) { 17133 // A callback is already scheduled. Check its expiration time (timeout). 17134 if (expirationTime > callbackExpirationTime) { 17135 // Existing callback has sufficient timeout. Exit. 17136 return; 17137 } else { 17138 if (callbackID !== null) { 17139 // Existing callback has insufficient timeout. Cancel and schedule a 17140 // new one. 17141 unstable_cancelScheduledWork(callbackID); 17142 } 17143 } 17144 // The request callback timer is already running. Don't start a new one. 17145 } else { 17146 startRequestCallbackTimer(); 17147 } 17148 17149 callbackExpirationTime = expirationTime; 17150 var currentMs = unstable_now() - originalStartTimeMs; 17151 var expirationTimeMs = expirationTimeToMs(expirationTime); 17152 var timeout = expirationTimeMs - currentMs; 17153 callbackID = unstable_scheduleWork(performAsyncWork, { timeout: timeout }); 17154 } 17155 17156 // For every call to renderRoot, one of onFatal, onComplete, onSuspend, and 17157 // onYield is called upon exiting. We use these in lieu of returning a tuple. 17158 // I've also chosen not to inline them into renderRoot because these will 17159 // eventually be lifted into the renderer. 17160 function onFatal(root) { 17161 root.finishedWork = null; 17162 } 17163 17164 function onComplete(root, finishedWork, expirationTime) { 17165 root.pendingCommitExpirationTime = expirationTime; 17166 root.finishedWork = finishedWork; 17167 } 17168 17169 function onSuspend(root, finishedWork, suspendedExpirationTime, rootExpirationTime, msUntilTimeout) { 17170 root.expirationTime = rootExpirationTime; 17171 if (enableSuspense && msUntilTimeout === 0 && !shouldYield()) { 17172 // Don't wait an additional tick. Commit the tree immediately. 17173 root.pendingCommitExpirationTime = suspendedExpirationTime; 17174 root.finishedWork = finishedWork; 17175 } else if (msUntilTimeout > 0) { 17176 // Wait `msUntilTimeout` milliseconds before committing. 17177 root.timeoutHandle = scheduleTimeout(onTimeout.bind(null, root, finishedWork, suspendedExpirationTime), msUntilTimeout); 17178 } 17179 } 17180 17181 function onYield(root) { 17182 root.finishedWork = null; 17183 } 17184 17185 function onTimeout(root, finishedWork, suspendedExpirationTime) { 17186 if (enableSuspense) { 17187 // The root timed out. Commit it. 17188 root.pendingCommitExpirationTime = suspendedExpirationTime; 17189 root.finishedWork = finishedWork; 17190 // Read the current time before entering the commit phase. We can be 17191 // certain this won't cause tearing related to batching of event updates 17192 // because we're at the top of a timer event. 17193 recomputeCurrentRendererTime(); 17194 currentSchedulerTime = currentRendererTime; 17195 17196 if (enableSchedulerTracing) { 17197 // Don't update pending interaction counts for suspense timeouts, 17198 // Because we know we still need to do more work in this case. 17199 suspenseDidTimeout = true; 17200 flushRoot(root, suspendedExpirationTime); 17201 suspenseDidTimeout = false; 17202 } else { 17203 flushRoot(root, suspendedExpirationTime); 17204 } 17205 } 17206 } 17207 17208 function onCommit(root, expirationTime) { 17209 root.expirationTime = expirationTime; 17210 root.finishedWork = null; 17211 } 17212 17213 function requestCurrentTime() { 17214 // requestCurrentTime is called by the scheduler to compute an expiration 17215 // time. 17216 // 17217 // Expiration times are computed by adding to the current time (the start 17218 // time). However, if two updates are scheduled within the same event, we 17219 // should treat their start times as simultaneous, even if the actual clock 17220 // time has advanced between the first and second call. 17221 17222 // In other words, because expiration times determine how updates are batched, 17223 // we want all updates of like priority that occur within the same event to 17224 // receive the same expiration time. Otherwise we get tearing. 17225 // 17226 // We keep track of two separate times: the current "renderer" time and the 17227 // current "scheduler" time. The renderer time can be updated whenever; it 17228 // only exists to minimize the calls performance.now. 17229 // 17230 // But the scheduler time can only be updated if there's no pending work, or 17231 // if we know for certain that we're not in the middle of an event. 17232 17233 if (isRendering) { 17234 // We're already rendering. Return the most recently read time. 17235 return currentSchedulerTime; 17236 } 17237 // Check if there's pending work. 17238 findHighestPriorityRoot(); 17239 if (nextFlushedExpirationTime === NoWork || nextFlushedExpirationTime === Never) { 17240 // If there's no pending work, or if the pending work is offscreen, we can 17241 // read the current time without risk of tearing. 17242 recomputeCurrentRendererTime(); 17243 currentSchedulerTime = currentRendererTime; 17244 return currentSchedulerTime; 17245 } 17246 // There's already pending work. We might be in the middle of a browser 17247 // event. If we were to read the current time, it could cause multiple updates 17248 // within the same event to receive different expiration times, leading to 17249 // tearing. Return the last read time. During the next idle callback, the 17250 // time will be updated. 17251 return currentSchedulerTime; 17252 } 17253 17254 // requestWork is called by the scheduler whenever a root receives an update. 17255 // It's up to the renderer to call renderRoot at some point in the future. 17256 function requestWork(root, expirationTime) { 17257 addRootToSchedule(root, expirationTime); 17258 if (isRendering) { 17259 // Prevent reentrancy. Remaining work will be scheduled at the end of 17260 // the currently rendering batch. 17261 return; 17262 } 17263 17264 if (isBatchingUpdates) { 17265 // Flush work at the end of the batch. 17266 if (isUnbatchingUpdates) { 17267 // ...unless we're inside unbatchedUpdates, in which case we should 17268 // flush it now. 17269 nextFlushedRoot = root; 17270 nextFlushedExpirationTime = Sync; 17271 performWorkOnRoot(root, Sync, true); 17272 } 17273 return; 17274 } 17275 17276 // TODO: Get rid of Sync and use current time? 17277 if (expirationTime === Sync) { 17278 performSyncWork(); 17279 } else { 17280 scheduleCallbackWithExpirationTime(root, expirationTime); 17281 } 17282 } 17283 17284 function addRootToSchedule(root, expirationTime) { 17285 // Add the root to the schedule. 17286 // Check if this root is already part of the schedule. 17287 if (root.nextScheduledRoot === null) { 17288 // This root is not already scheduled. Add it. 17289 root.expirationTime = expirationTime; 17290 if (lastScheduledRoot === null) { 17291 firstScheduledRoot = lastScheduledRoot = root; 17292 root.nextScheduledRoot = root; 17293 } else { 17294 lastScheduledRoot.nextScheduledRoot = root; 17295 lastScheduledRoot = root; 17296 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot; 17297 } 17298 } else { 17299 // This root is already scheduled, but its priority may have increased. 17300 var remainingExpirationTime = root.expirationTime; 17301 if (remainingExpirationTime === NoWork || expirationTime < remainingExpirationTime) { 17302 // Update the priority. 17303 root.expirationTime = expirationTime; 17304 } 17305 } 17306 } 17307 17308 function findHighestPriorityRoot() { 17309 var highestPriorityWork = NoWork; 17310 var highestPriorityRoot = null; 17311 if (lastScheduledRoot !== null) { 17312 var previousScheduledRoot = lastScheduledRoot; 17313 var root = firstScheduledRoot; 17314 while (root !== null) { 17315 var remainingExpirationTime = root.expirationTime; 17316 if (remainingExpirationTime === NoWork) { 17317 // This root no longer has work. Remove it from the scheduler. 17318 17319 // TODO: This check is redudant, but Flow is confused by the branch 17320 // below where we set lastScheduledRoot to null, even though we break 17321 // from the loop right after. 17322 !(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; 17323 if (root === root.nextScheduledRoot) { 17324 // This is the only root in the list. 17325 root.nextScheduledRoot = null; 17326 firstScheduledRoot = lastScheduledRoot = null; 17327 break; 17328 } else if (root === firstScheduledRoot) { 17329 // This is the first root in the list. 17330 var next = root.nextScheduledRoot; 17331 firstScheduledRoot = next; 17332 lastScheduledRoot.nextScheduledRoot = next; 17333 root.nextScheduledRoot = null; 17334 } else if (root === lastScheduledRoot) { 17335 // This is the last root in the list. 17336 lastScheduledRoot = previousScheduledRoot; 17337 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot; 17338 root.nextScheduledRoot = null; 17339 break; 17340 } else { 17341 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot; 17342 root.nextScheduledRoot = null; 17343 } 17344 root = previousScheduledRoot.nextScheduledRoot; 17345 } else { 17346 if (highestPriorityWork === NoWork || remainingExpirationTime < highestPriorityWork) { 17347 // Update the priority, if it's higher 17348 highestPriorityWork = remainingExpirationTime; 17349 highestPriorityRoot = root; 17350 } 17351 if (root === lastScheduledRoot) { 17352 break; 17353 } 17354 if (highestPriorityWork === Sync) { 17355 // Sync is highest priority by definition so 17356 // we can stop searching. 17357 break; 17358 } 17359 previousScheduledRoot = root; 17360 root = root.nextScheduledRoot; 17361 } 17362 } 17363 } 17364 17365 nextFlushedRoot = highestPriorityRoot; 17366 nextFlushedExpirationTime = highestPriorityWork; 17367 } 17368 17369 function performAsyncWork(dl) { 17370 if (dl.didTimeout) { 17371 // The callback timed out. That means at least one update has expired. 17372 // Iterate through the root schedule. If they contain expired work, set 17373 // the next render expiration time to the current time. This has the effect 17374 // of flushing all expired work in a single batch, instead of flushing each 17375 // level one at a time. 17376 if (firstScheduledRoot !== null) { 17377 recomputeCurrentRendererTime(); 17378 var root = firstScheduledRoot; 17379 do { 17380 didExpireAtExpirationTime(root, currentRendererTime); 17381 // The root schedule is circular, so this is never null. 17382 root = root.nextScheduledRoot; 17383 } while (root !== firstScheduledRoot); 17384 } 17385 } 17386 performWork(NoWork, dl); 17387 } 17388 17389 function performSyncWork() { 17390 performWork(Sync, null); 17391 } 17392 17393 function performWork(minExpirationTime, dl) { 17394 deadline = dl; 17395 17396 // Keep working on roots until there's no more work, or until we reach 17397 // the deadline. 17398 findHighestPriorityRoot(); 17399 17400 if (deadline !== null) { 17401 recomputeCurrentRendererTime(); 17402 currentSchedulerTime = currentRendererTime; 17403 17404 if (enableUserTimingAPI) { 17405 var didExpire = nextFlushedExpirationTime < currentRendererTime; 17406 var timeout = expirationTimeToMs(nextFlushedExpirationTime); 17407 stopRequestCallbackTimer(didExpire, timeout); 17408 } 17409 17410 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && (minExpirationTime === NoWork || minExpirationTime >= nextFlushedExpirationTime) && (!deadlineDidExpire || currentRendererTime >= nextFlushedExpirationTime)) { 17411 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, currentRendererTime >= nextFlushedExpirationTime); 17412 findHighestPriorityRoot(); 17413 recomputeCurrentRendererTime(); 17414 currentSchedulerTime = currentRendererTime; 17415 } 17416 } else { 17417 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && (minExpirationTime === NoWork || minExpirationTime >= nextFlushedExpirationTime)) { 17418 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, true); 17419 findHighestPriorityRoot(); 17420 } 17421 } 17422 17423 // We're done flushing work. Either we ran out of time in this callback, 17424 // or there's no more work left with sufficient priority. 17425 17426 // If we're inside a callback, set this to false since we just completed it. 17427 if (deadline !== null) { 17428 callbackExpirationTime = NoWork; 17429 callbackID = null; 17430 } 17431 // If there's work left over, schedule a new callback. 17432 if (nextFlushedExpirationTime !== NoWork) { 17433 scheduleCallbackWithExpirationTime(nextFlushedRoot, nextFlushedExpirationTime); 17434 } 17435 17436 // Clean-up. 17437 deadline = null; 17438 deadlineDidExpire = false; 17439 17440 finishRendering(); 17441 } 17442 17443 function flushRoot(root, expirationTime) { 17444 !!isRendering ? invariant(false, 'work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method.') : void 0; 17445 // Perform work on root as if the given expiration time is the current time. 17446 // This has the effect of synchronously flushing all work up to and 17447 // including the given time. 17448 nextFlushedRoot = root; 17449 nextFlushedExpirationTime = expirationTime; 17450 performWorkOnRoot(root, expirationTime, true); 17451 // Flush any sync work that was scheduled by lifecycles 17452 performSyncWork(); 17453 } 17454 17455 function finishRendering() { 17456 nestedUpdateCount = 0; 17457 lastCommittedRootDuringThisBatch = null; 17458 17459 if (completedBatches !== null) { 17460 var batches = completedBatches; 17461 completedBatches = null; 17462 for (var i = 0; i < batches.length; i++) { 17463 var batch = batches[i]; 17464 try { 17465 batch._onComplete(); 17466 } catch (error) { 17467 if (!hasUnhandledError) { 17468 hasUnhandledError = true; 17469 unhandledError = error; 17470 } 17471 } 17472 } 17473 } 17474 17475 if (hasUnhandledError) { 17476 var error = unhandledError; 17477 unhandledError = null; 17478 hasUnhandledError = false; 17479 throw error; 17480 } 17481 } 17482 17483 function performWorkOnRoot(root, expirationTime, isExpired) { 17484 !!isRendering ? invariant(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0; 17485 17486 isRendering = true; 17487 17488 // Check if this is async work or sync/expired work. 17489 if (deadline === null || isExpired) { 17490 // Flush work without yielding. 17491 // TODO: Non-yieldy work does not necessarily imply expired work. A renderer 17492 // may want to perform some work without yielding, but also without 17493 // requiring the root to complete (by triggering placeholders). 17494 17495 var finishedWork = root.finishedWork; 17496 if (finishedWork !== null) { 17497 // This root is already complete. We can commit it. 17498 completeRoot(root, finishedWork, expirationTime); 17499 } else { 17500 root.finishedWork = null; 17501 // If this root previously suspended, clear its existing timeout, since 17502 // we're about to try rendering again. 17503 var timeoutHandle = root.timeoutHandle; 17504 if (enableSuspense && timeoutHandle !== noTimeout) { 17505 root.timeoutHandle = noTimeout; 17506 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above 17507 cancelTimeout(timeoutHandle); 17508 } 17509 var isYieldy = false; 17510 renderRoot(root, isYieldy, isExpired); 17511 finishedWork = root.finishedWork; 17512 if (finishedWork !== null) { 17513 // We've completed the root. Commit it. 17514 completeRoot(root, finishedWork, expirationTime); 17515 } 17516 } 17517 } else { 17518 // Flush async work. 17519 var _finishedWork = root.finishedWork; 17520 if (_finishedWork !== null) { 17521 // This root is already complete. We can commit it. 17522 completeRoot(root, _finishedWork, expirationTime); 17523 } else { 17524 root.finishedWork = null; 17525 // If this root previously suspended, clear its existing timeout, since 17526 // we're about to try rendering again. 17527 var _timeoutHandle = root.timeoutHandle; 17528 if (enableSuspense && _timeoutHandle !== noTimeout) { 17529 root.timeoutHandle = noTimeout; 17530 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above 17531 cancelTimeout(_timeoutHandle); 17532 } 17533 var _isYieldy = true; 17534 renderRoot(root, _isYieldy, isExpired); 17535 _finishedWork = root.finishedWork; 17536 if (_finishedWork !== null) { 17537 // We've completed the root. Check the deadline one more time 17538 // before committing. 17539 if (!shouldYield()) { 17540 // Still time left. Commit the root. 17541 completeRoot(root, _finishedWork, expirationTime); 17542 } else { 17543 // There's no time left. Mark this root as complete. We'll come 17544 // back and commit it later. 17545 root.finishedWork = _finishedWork; 17546 } 17547 } 17548 } 17549 } 17550 17551 isRendering = false; 17552 } 17553 17554 function completeRoot(root, finishedWork, expirationTime) { 17555 // Check if there's a batch that matches this expiration time. 17556 var firstBatch = root.firstBatch; 17557 if (firstBatch !== null && firstBatch._expirationTime <= expirationTime) { 17558 if (completedBatches === null) { 17559 completedBatches = [firstBatch]; 17560 } else { 17561 completedBatches.push(firstBatch); 17562 } 17563 if (firstBatch._defer) { 17564 // This root is blocked from committing by a batch. Unschedule it until 17565 // we receive another update. 17566 root.finishedWork = finishedWork; 17567 root.expirationTime = NoWork; 17568 return; 17569 } 17570 } 17571 17572 // Commit the root. 17573 root.finishedWork = null; 17574 17575 // Check if this is a nested update (a sync update scheduled during the 17576 // commit phase). 17577 if (root === lastCommittedRootDuringThisBatch) { 17578 // If the next root is the same as the previous root, this is a nested 17579 // update. To prevent an infinite loop, increment the nested update count. 17580 nestedUpdateCount++; 17581 } else { 17582 // Reset whenever we switch roots. 17583 lastCommittedRootDuringThisBatch = root; 17584 nestedUpdateCount = 0; 17585 } 17586 commitRoot(root, finishedWork); 17587 } 17588 17589 // When working on async work, the reconciler asks the renderer if it should 17590 // yield execution. For DOM, we implement this with requestIdleCallback. 17591 function shouldYield() { 17592 if (deadlineDidExpire) { 17593 return true; 17594 } 17595 if (deadline === null || deadline.timeRemaining() > timeHeuristicForUnitOfWork) { 17596 // Disregard deadline.didTimeout. Only expired work should be flushed 17597 // during a timeout. This path is only hit for non-expired work. 17598 return false; 17599 } 17600 deadlineDidExpire = true; 17601 return true; 17602 } 17603 17604 function onUncaughtError(error) { 17605 !(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; 17606 // Unschedule this root so we don't work on it again until there's 17607 // another update. 17608 nextFlushedRoot.expirationTime = NoWork; 17609 if (!hasUnhandledError) { 17610 hasUnhandledError = true; 17611 unhandledError = error; 17612 } 17613 } 17614 17615 // TODO: Batching should be implemented at the renderer level, not inside 17616 // the reconciler. 17617 function batchedUpdates$1(fn, a) { 17618 var previousIsBatchingUpdates = isBatchingUpdates; 17619 isBatchingUpdates = true; 17620 try { 17621 return fn(a); 17622 } finally { 17623 isBatchingUpdates = previousIsBatchingUpdates; 17624 if (!isBatchingUpdates && !isRendering) { 17625 performSyncWork(); 17626 } 17627 } 17628 } 17629 17630 // TODO: Batching should be implemented at the renderer level, not inside 17631 // the reconciler. 17632 function unbatchedUpdates(fn, a) { 17633 if (isBatchingUpdates && !isUnbatchingUpdates) { 17634 isUnbatchingUpdates = true; 17635 try { 17636 return fn(a); 17637 } finally { 17638 isUnbatchingUpdates = false; 17639 } 17640 } 17641 return fn(a); 17642 } 17643 17644 // TODO: Batching should be implemented at the renderer level, not within 17645 // the reconciler. 17646 function flushSync(fn, a) { 17647 !!isRendering ? invariant(false, 'flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.') : void 0; 17648 var previousIsBatchingUpdates = isBatchingUpdates; 17649 isBatchingUpdates = true; 17650 try { 17651 return syncUpdates(fn, a); 17652 } finally { 17653 isBatchingUpdates = previousIsBatchingUpdates; 17654 performSyncWork(); 17655 } 17656 } 17657 17658 function interactiveUpdates$1(fn, a, b) { 17659 if (isBatchingInteractiveUpdates) { 17660 return fn(a, b); 17661 } 17662 // If there are any pending interactive updates, synchronously flush them. 17663 // This needs to happen before we read any handlers, because the effect of 17664 // the previous event may influence which handlers are called during 17665 // this event. 17666 if (!isBatchingUpdates && !isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) { 17667 // Synchronously flush pending interactive updates. 17668 performWork(lowestPriorityPendingInteractiveExpirationTime, null); 17669 lowestPriorityPendingInteractiveExpirationTime = NoWork; 17670 } 17671 var previousIsBatchingInteractiveUpdates = isBatchingInteractiveUpdates; 17672 var previousIsBatchingUpdates = isBatchingUpdates; 17673 isBatchingInteractiveUpdates = true; 17674 isBatchingUpdates = true; 17675 try { 17676 return fn(a, b); 17677 } finally { 17678 isBatchingInteractiveUpdates = previousIsBatchingInteractiveUpdates; 17679 isBatchingUpdates = previousIsBatchingUpdates; 17680 if (!isBatchingUpdates && !isRendering) { 17681 performSyncWork(); 17682 } 17683 } 17684 } 17685 17686 function flushInteractiveUpdates$1() { 17687 if (!isRendering && lowestPriorityPendingInteractiveExpirationTime !== NoWork) { 17688 // Synchronously flush pending interactive updates. 17689 performWork(lowestPriorityPendingInteractiveExpirationTime, null); 17690 lowestPriorityPendingInteractiveExpirationTime = NoWork; 17691 } 17692 } 17693 17694 function flushControlled(fn) { 17695 var previousIsBatchingUpdates = isBatchingUpdates; 17696 isBatchingUpdates = true; 17697 try { 17698 syncUpdates(fn); 17699 } finally { 17700 isBatchingUpdates = previousIsBatchingUpdates; 17701 if (!isBatchingUpdates && !isRendering) { 17702 performSyncWork(); 17703 } 17704 } 17705 } 17706 17707 // 0 is PROD, 1 is DEV. 17708 // Might add PROFILE later. 17709 17710 17711 var didWarnAboutNestedUpdates = void 0; 17712 17713 { 17714 didWarnAboutNestedUpdates = false; 17715 } 17716 17717 function getContextForSubtree(parentComponent) { 17718 if (!parentComponent) { 17719 return emptyContextObject; 17720 } 17721 17722 var fiber = get(parentComponent); 17723 var parentContext = findCurrentUnmaskedContext(fiber); 17724 17725 if (fiber.tag === ClassComponent) { 17726 var Component = fiber.type; 17727 if (isContextProvider(Component)) { 17728 return processChildContext(fiber, Component, parentContext); 17729 } 17730 } else if (fiber.tag === ClassComponentLazy) { 17731 var _Component = getResultFromResolvedThenable(fiber.type); 17732 if (isContextProvider(_Component)) { 17733 return processChildContext(fiber, _Component, parentContext); 17734 } 17735 } 17736 17737 return parentContext; 17738 } 17739 17740 function scheduleRootUpdate(current$$1, element, expirationTime, callback) { 17741 { 17742 if (phase === 'render' && current !== null && !didWarnAboutNestedUpdates) { 17743 didWarnAboutNestedUpdates = true; 17744 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'); 17745 } 17746 } 17747 17748 var update = createUpdate(expirationTime); 17749 // Caution: React DevTools currently depends on this property 17750 // being called "element". 17751 update.payload = { element: element }; 17752 17753 callback = callback === undefined ? null : callback; 17754 if (callback !== null) { 17755 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0; 17756 update.callback = callback; 17757 } 17758 enqueueUpdate(current$$1, update); 17759 17760 scheduleWork(current$$1, expirationTime); 17761 return expirationTime; 17762 } 17763 17764 function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) { 17765 // TODO: If this is a nested container, this won't be the root. 17766 var current$$1 = container.current; 17767 17768 { 17769 if (ReactFiberInstrumentation_1.debugTool) { 17770 if (current$$1.alternate === null) { 17771 ReactFiberInstrumentation_1.debugTool.onMountContainer(container); 17772 } else if (element === null) { 17773 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container); 17774 } else { 17775 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container); 17776 } 17777 } 17778 } 17779 17780 var context = getContextForSubtree(parentComponent); 17781 if (container.context === null) { 17782 container.context = context; 17783 } else { 17784 container.pendingContext = context; 17785 } 17786 17787 return scheduleRootUpdate(current$$1, element, expirationTime, callback); 17788 } 17789 17790 function findHostInstance(component) { 17791 var fiber = get(component); 17792 if (fiber === undefined) { 17793 if (typeof component.render === 'function') { 17794 invariant(false, 'Unable to find node on an unmounted component.'); 17795 } else { 17796 invariant(false, 'Argument appears to not be a ReactComponent. Keys: %s', Object.keys(component)); 17797 } 17798 } 17799 var hostFiber = findCurrentHostFiber(fiber); 17800 if (hostFiber === null) { 17801 return null; 17802 } 17803 return hostFiber.stateNode; 17804 } 17805 17806 function createContainer(containerInfo, isAsync, hydrate) { 17807 return createFiberRoot(containerInfo, isAsync, hydrate); 17808 } 17809 17810 function updateContainer(element, container, parentComponent, callback) { 17811 var current$$1 = container.current; 17812 var currentTime = requestCurrentTime(); 17813 var expirationTime = computeExpirationForFiber(currentTime, current$$1); 17814 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback); 17815 } 17816 17817 function getPublicRootInstance(container) { 17818 var containerFiber = container.current; 17819 if (!containerFiber.child) { 17820 return null; 17821 } 17822 switch (containerFiber.child.tag) { 17823 case HostComponent: 17824 return getPublicInstance(containerFiber.child.stateNode); 17825 default: 17826 return containerFiber.child.stateNode; 17827 } 17828 } 17829 17830 function findHostInstanceWithNoPortals(fiber) { 17831 var hostFiber = findCurrentHostFiberWithNoPortals(fiber); 17832 if (hostFiber === null) { 17833 return null; 17834 } 17835 return hostFiber.stateNode; 17836 } 17837 17838 function injectIntoDevTools(devToolsConfig) { 17839 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; 17840 17841 return injectInternals(_assign({}, devToolsConfig, { 17842 findHostInstanceByFiber: function (fiber) { 17843 var hostFiber = findCurrentHostFiber(fiber); 17844 if (hostFiber === null) { 17845 return null; 17846 } 17847 return hostFiber.stateNode; 17848 }, 17849 findFiberByHostInstance: function (instance) { 17850 if (!findFiberByHostInstance) { 17851 // Might not be implemented by the renderer. 17852 return null; 17853 } 17854 return findFiberByHostInstance(instance); 17855 } 17856 })); 17857 } 17858 17859 // This file intentionally does *not* have the Flow annotation. 17860 // Don't add it. See `./inline-typed.js` for an explanation. 17861 17862 function createPortal$1(children, containerInfo, 17863 // TODO: figure out the API for cross-renderer implementation. 17864 implementation) { 17865 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; 17866 17867 return { 17868 // This tag allow us to uniquely identify this as a React Portal 17869 $$typeof: REACT_PORTAL_TYPE, 17870 key: key == null ? null : '' + key, 17871 children: children, 17872 containerInfo: containerInfo, 17873 implementation: implementation 17874 }; 17875 } 17876 17877 // TODO: this is special because it gets imported during build. 17878 17879 var ReactVersion = '16.5.2'; 17880 17881 // TODO: This type is shared between the reconciler and ReactDOM, but will 17882 // eventually be lifted out to the renderer. 17883 var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; 17884 17885 var topLevelUpdateWarnings = void 0; 17886 var warnOnInvalidCallback = void 0; 17887 var didWarnAboutUnstableCreatePortal = false; 17888 17889 { 17890 if (typeof Map !== 'function' || 17891 // $FlowIssue Flow incorrectly thinks Map has no prototype 17892 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || 17893 // $FlowIssue Flow incorrectly thinks Set has no prototype 17894 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') { 17895 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'); 17896 } 17897 17898 topLevelUpdateWarnings = function (container) { 17899 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) { 17900 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current); 17901 if (hostInstance) { 17902 !(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; 17903 } 17904 } 17905 17906 var isRootRenderedBySomeReact = !!container._reactRootContainer; 17907 var rootEl = getReactRootElementInContainer(container); 17908 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl)); 17909 17910 !(!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; 17911 17912 !(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; 17913 }; 17914 17915 warnOnInvalidCallback = function (callback, callerName) { 17916 !(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; 17917 }; 17918 } 17919 17920 setRestoreImplementation(restoreControlledState$1); 17921 17922 /* eslint-disable no-use-before-define */ 17923 17924 /* eslint-enable no-use-before-define */ 17925 17926 function ReactBatch(root) { 17927 var expirationTime = computeUniqueAsyncExpiration(); 17928 this._expirationTime = expirationTime; 17929 this._root = root; 17930 this._next = null; 17931 this._callbacks = null; 17932 this._didComplete = false; 17933 this._hasChildren = false; 17934 this._children = null; 17935 this._defer = true; 17936 } 17937 ReactBatch.prototype.render = function (children) { 17938 !this._defer ? invariant(false, 'batch.render: Cannot render a batch that already committed.') : void 0; 17939 this._hasChildren = true; 17940 this._children = children; 17941 var internalRoot = this._root._internalRoot; 17942 var expirationTime = this._expirationTime; 17943 var work = new ReactWork(); 17944 updateContainerAtExpirationTime(children, internalRoot, null, expirationTime, work._onCommit); 17945 return work; 17946 }; 17947 ReactBatch.prototype.then = function (onComplete) { 17948 if (this._didComplete) { 17949 onComplete(); 17950 return; 17951 } 17952 var callbacks = this._callbacks; 17953 if (callbacks === null) { 17954 callbacks = this._callbacks = []; 17955 } 17956 callbacks.push(onComplete); 17957 }; 17958 ReactBatch.prototype.commit = function () { 17959 var internalRoot = this._root._internalRoot; 17960 var firstBatch = internalRoot.firstBatch; 17961 !(this._defer && firstBatch !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0; 17962 17963 if (!this._hasChildren) { 17964 // This batch is empty. Return. 17965 this._next = null; 17966 this._defer = false; 17967 return; 17968 } 17969 17970 var expirationTime = this._expirationTime; 17971 17972 // Ensure this is the first batch in the list. 17973 if (firstBatch !== this) { 17974 // This batch is not the earliest batch. We need to move it to the front. 17975 // Update its expiration time to be the expiration time of the earliest 17976 // batch, so that we can flush it without flushing the other batches. 17977 if (this._hasChildren) { 17978 expirationTime = this._expirationTime = firstBatch._expirationTime; 17979 // Rendering this batch again ensures its children will be the final state 17980 // when we flush (updates are processed in insertion order: last 17981 // update wins). 17982 // TODO: This forces a restart. Should we print a warning? 17983 this.render(this._children); 17984 } 17985 17986 // Remove the batch from the list. 17987 var previous = null; 17988 var batch = firstBatch; 17989 while (batch !== this) { 17990 previous = batch; 17991 batch = batch._next; 17992 } 17993 !(previous !== null) ? invariant(false, 'batch.commit: Cannot commit a batch multiple times.') : void 0; 17994 previous._next = batch._next; 17995 17996 // Add it to the front. 17997 this._next = firstBatch; 17998 firstBatch = internalRoot.firstBatch = this; 17999 } 18000 18001 // Synchronously flush all the work up to this batch's expiration time. 18002 this._defer = false; 18003 flushRoot(internalRoot, expirationTime); 18004 18005 // Pop the batch from the list. 18006 var next = this._next; 18007 this._next = null; 18008 firstBatch = internalRoot.firstBatch = next; 18009 18010 // Append the next earliest batch's children to the update queue. 18011 if (firstBatch !== null && firstBatch._hasChildren) { 18012 firstBatch.render(firstBatch._children); 18013 } 18014 }; 18015 ReactBatch.prototype._onComplete = function () { 18016 if (this._didComplete) { 18017 return; 18018 } 18019 this._didComplete = true; 18020 var callbacks = this._callbacks; 18021 if (callbacks === null) { 18022 return; 18023 } 18024 // TODO: Error handling. 18025 for (var i = 0; i < callbacks.length; i++) { 18026 var _callback = callbacks[i]; 18027 _callback(); 18028 } 18029 }; 18030 18031 function ReactWork() { 18032 this._callbacks = null; 18033 this._didCommit = false; 18034 // TODO: Avoid need to bind by replacing callbacks in the update queue with 18035 // list of Work objects. 18036 this._onCommit = this._onCommit.bind(this); 18037 } 18038 ReactWork.prototype.then = function (onCommit) { 18039 if (this._didCommit) { 18040 onCommit(); 18041 return; 18042 } 18043 var callbacks = this._callbacks; 18044 if (callbacks === null) { 18045 callbacks = this._callbacks = []; 18046 } 18047 callbacks.push(onCommit); 18048 }; 18049 ReactWork.prototype._onCommit = function () { 18050 if (this._didCommit) { 18051 return; 18052 } 18053 this._didCommit = true; 18054 var callbacks = this._callbacks; 18055 if (callbacks === null) { 18056 return; 18057 } 18058 // TODO: Error handling. 18059 for (var i = 0; i < callbacks.length; i++) { 18060 var _callback2 = callbacks[i]; 18061 !(typeof _callback2 === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', _callback2) : void 0; 18062 _callback2(); 18063 } 18064 }; 18065 18066 function ReactRoot(container, isAsync, hydrate) { 18067 var root = createContainer(container, isAsync, hydrate); 18068 this._internalRoot = root; 18069 } 18070 ReactRoot.prototype.render = function (children, callback) { 18071 var root = this._internalRoot; 18072 var work = new ReactWork(); 18073 callback = callback === undefined ? null : callback; 18074 { 18075 warnOnInvalidCallback(callback, 'render'); 18076 } 18077 if (callback !== null) { 18078 work.then(callback); 18079 } 18080 updateContainer(children, root, null, work._onCommit); 18081 return work; 18082 }; 18083 ReactRoot.prototype.unmount = function (callback) { 18084 var root = this._internalRoot; 18085 var work = new ReactWork(); 18086 callback = callback === undefined ? null : callback; 18087 { 18088 warnOnInvalidCallback(callback, 'render'); 18089 } 18090 if (callback !== null) { 18091 work.then(callback); 18092 } 18093 updateContainer(null, root, null, work._onCommit); 18094 return work; 18095 }; 18096 ReactRoot.prototype.legacy_renderSubtreeIntoContainer = function (parentComponent, children, callback) { 18097 var root = this._internalRoot; 18098 var work = new ReactWork(); 18099 callback = callback === undefined ? null : callback; 18100 { 18101 warnOnInvalidCallback(callback, 'render'); 18102 } 18103 if (callback !== null) { 18104 work.then(callback); 18105 } 18106 updateContainer(children, root, parentComponent, work._onCommit); 18107 return work; 18108 }; 18109 ReactRoot.prototype.createBatch = function () { 18110 var batch = new ReactBatch(this); 18111 var expirationTime = batch._expirationTime; 18112 18113 var internalRoot = this._internalRoot; 18114 var firstBatch = internalRoot.firstBatch; 18115 if (firstBatch === null) { 18116 internalRoot.firstBatch = batch; 18117 batch._next = null; 18118 } else { 18119 // Insert sorted by expiration time then insertion order 18120 var insertAfter = null; 18121 var insertBefore = firstBatch; 18122 while (insertBefore !== null && insertBefore._expirationTime <= expirationTime) { 18123 insertAfter = insertBefore; 18124 insertBefore = insertBefore._next; 18125 } 18126 batch._next = insertBefore; 18127 if (insertAfter !== null) { 18128 insertAfter._next = batch; 18129 } 18130 } 18131 18132 return batch; 18133 }; 18134 18135 /** 18136 * True if the supplied DOM node is a valid node element. 18137 * 18138 * @param {?DOMElement} node The candidate DOM node. 18139 * @return {boolean} True if the DOM is a valid DOM node. 18140 * @internal 18141 */ 18142 function isValidContainer(node) { 18143 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 ')); 18144 } 18145 18146 function getReactRootElementInContainer(container) { 18147 if (!container) { 18148 return null; 18149 } 18150 18151 if (container.nodeType === DOCUMENT_NODE) { 18152 return container.documentElement; 18153 } else { 18154 return container.firstChild; 18155 } 18156 } 18157 18158 function shouldHydrateDueToLegacyHeuristic(container) { 18159 var rootElement = getReactRootElementInContainer(container); 18160 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME)); 18161 } 18162 18163 setBatchingImplementation(batchedUpdates$1, interactiveUpdates$1, flushInteractiveUpdates$1); 18164 18165 var warnedAboutHydrateAPI = false; 18166 18167 function legacyCreateRootFromDOMContainer(container, forceHydrate) { 18168 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container); 18169 // First clear any existing content. 18170 if (!shouldHydrate) { 18171 var warned = false; 18172 var rootSibling = void 0; 18173 while (rootSibling = container.lastChild) { 18174 { 18175 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) { 18176 warned = true; 18177 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.'); 18178 } 18179 } 18180 container.removeChild(rootSibling); 18181 } 18182 } 18183 { 18184 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) { 18185 warnedAboutHydrateAPI = true; 18186 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.'); 18187 } 18188 } 18189 // Legacy roots are not async by default. 18190 var isAsync = false; 18191 return new ReactRoot(container, isAsync, shouldHydrate); 18192 } 18193 18194 function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) { 18195 // TODO: Ensure all entry points contain this check 18196 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0; 18197 18198 { 18199 topLevelUpdateWarnings(container); 18200 } 18201 18202 // TODO: Without `any` type, Flow says "Property cannot be accessed on any 18203 // member of intersection type." Whyyyyyy. 18204 var root = container._reactRootContainer; 18205 if (!root) { 18206 // Initial mount 18207 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate); 18208 if (typeof callback === 'function') { 18209 var originalCallback = callback; 18210 callback = function () { 18211 var instance = getPublicRootInstance(root._internalRoot); 18212 originalCallback.call(instance); 18213 }; 18214 } 18215 // Initial mount should not be batched. 18216 unbatchedUpdates(function () { 18217 if (parentComponent != null) { 18218 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback); 18219 } else { 18220 root.render(children, callback); 18221 } 18222 }); 18223 } else { 18224 if (typeof callback === 'function') { 18225 var _originalCallback = callback; 18226 callback = function () { 18227 var instance = getPublicRootInstance(root._internalRoot); 18228 _originalCallback.call(instance); 18229 }; 18230 } 18231 // Update 18232 if (parentComponent != null) { 18233 root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback); 18234 } else { 18235 root.render(children, callback); 18236 } 18237 } 18238 return getPublicRootInstance(root._internalRoot); 18239 } 18240 18241 function createPortal(children, container) { 18242 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; 18243 18244 !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0; 18245 // TODO: pass ReactDOM portal implementation as third argument 18246 return createPortal$1(children, container, null, key); 18247 } 18248 18249 var ReactDOM = { 18250 createPortal: createPortal, 18251 18252 findDOMNode: function (componentOrElement) { 18253 { 18254 var owner = ReactCurrentOwner.current; 18255 if (owner !== null && owner.stateNode !== null) { 18256 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender; 18257 !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; 18258 owner.stateNode._warnedAboutRefsInRender = true; 18259 } 18260 } 18261 if (componentOrElement == null) { 18262 return null; 18263 } 18264 if (componentOrElement.nodeType === ELEMENT_NODE) { 18265 return componentOrElement; 18266 } 18267 18268 return findHostInstance(componentOrElement); 18269 }, 18270 hydrate: function (element, container, callback) { 18271 // TODO: throw or warn if we couldn't hydrate? 18272 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback); 18273 }, 18274 render: function (element, container, callback) { 18275 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback); 18276 }, 18277 unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) { 18278 !(parentComponent != null && has(parentComponent)) ? invariant(false, 'parentComponent must be a valid React Component') : void 0; 18279 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback); 18280 }, 18281 unmountComponentAtNode: function (container) { 18282 !isValidContainer(container) ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : void 0; 18283 18284 if (container._reactRootContainer) { 18285 { 18286 var rootEl = getReactRootElementInContainer(container); 18287 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl); 18288 !!renderedByDifferentReact ? warningWithoutStack$1(false, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.') : void 0; 18289 } 18290 18291 // Unmount should not be batched. 18292 unbatchedUpdates(function () { 18293 legacyRenderSubtreeIntoContainer(null, null, container, false, function () { 18294 container._reactRootContainer = null; 18295 }); 18296 }); 18297 // If you call unmountComponentAtNode twice in quick succession, you'll 18298 // get `true` twice. That's probably fine? 18299 return true; 18300 } else { 18301 { 18302 var _rootEl = getReactRootElementInContainer(container); 18303 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl)); 18304 18305 // Check if the container itself is a React root node. 18306 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer; 18307 18308 !!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; 18309 } 18310 18311 return false; 18312 } 18313 }, 18314 18315 18316 // Temporary alias since we already shipped React 16 RC with it. 18317 // TODO: remove in React 17. 18318 unstable_createPortal: function () { 18319 if (!didWarnAboutUnstableCreatePortal) { 18320 didWarnAboutUnstableCreatePortal = true; 18321 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.'); 18322 } 18323 return createPortal.apply(undefined, arguments); 18324 }, 18325 18326 18327 unstable_batchedUpdates: batchedUpdates$1, 18328 18329 unstable_interactiveUpdates: interactiveUpdates$1, 18330 18331 flushSync: flushSync, 18332 18333 unstable_flushControlled: flushControlled, 18334 18335 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { 18336 // Keep in sync with ReactDOMUnstableNativeDependencies.js 18337 // and ReactTestUtils.js. This is an array for better minification. 18338 Events: [getInstanceFromNode$1, getNodeFromInstance$1, getFiberCurrentPropsFromNode$1, injection.injectEventPluginsByName, eventNameDispatchConfigs, accumulateTwoPhaseDispatches, accumulateDirectDispatches, enqueueStateRestore, restoreStateIfNeeded, dispatchEvent, runEventsInBatch] 18339 } 18340 }; 18341 18342 ReactDOM.unstable_createRoot = function createRoot(container, options) { 18343 !isValidContainer(container) ? invariant(false, 'unstable_createRoot(...): Target container is not a DOM element.') : void 0; 18344 var hydrate = options != null && options.hydrate === true; 18345 return new ReactRoot(container, true, hydrate); 18346 }; 18347 18348 var foundDevTools = injectIntoDevTools({ 18349 findFiberByHostInstance: getClosestInstanceFromNode, 18350 bundleType: 1, 18351 version: ReactVersion, 18352 rendererPackageName: 'react-dom' 18353 }); 18354 18355 { 18356 if (!foundDevTools && canUseDOM && window.top === window.self) { 18357 // If we're in Chrome or Firefox, provide a download link if not installed. 18358 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) { 18359 var protocol = window.location.protocol; 18360 // Don't warn in exotic cases like chrome-extension://. 18361 if (/^(https?|file):$/.test(protocol)) { 18362 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'); 18363 } 18364 } 18365 } 18366 } 18367 18368 18369 18370 var ReactDOM$2 = Object.freeze({ 18371 default: ReactDOM 18372 }); 18373 18374 var ReactDOM$3 = ( ReactDOM$2 && ReactDOM ) || ReactDOM$2; 18375 18376 // TODO: decide on the top-level export form. 18377 // This is hacky but makes it work with both Rollup and Jest. 18378 var reactDom = ReactDOM$3.default || ReactDOM$3; 18379 18380 return reactDom; 18381 18382 })));
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Jan 7 01:00:05 2019 | Cross-referenced by PHPXref 0.7.1 |