react-dom.development.js (1026501B)
1/** 2 * @license React 3 * react-dom.development.js 4 * 5 * Copyright (c) Facebook, Inc. and its affiliates. 6 * 7 * This source code is licensed under the MIT license found in the 8 * LICENSE file in the root directory of this source tree. 9 */ 10 11'use strict'; 12 13if (process.env.NODE_ENV !== "production") { 14 (function() { 15 16 'use strict'; 17 18/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ 19if ( 20 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && 21 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === 22 'function' 23) { 24 __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error()); 25} 26 var React = require('react'); 27var Scheduler = require('scheduler'); 28 29var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; 30 31var suppressWarning = false; 32function setSuppressWarning(newSuppressWarning) { 33 { 34 suppressWarning = newSuppressWarning; 35 } 36} // In DEV, calls to console.warn and console.error get replaced 37// by calls to these methods by a Babel plugin. 38// 39// In PROD (or in packages without access to React internals), 40// they are left as they are instead. 41 42function warn(format) { 43 { 44 if (!suppressWarning) { 45 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 46 args[_key - 1] = arguments[_key]; 47 } 48 49 printWarning('warn', format, args); 50 } 51 } 52} 53function error(format) { 54 { 55 if (!suppressWarning) { 56 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { 57 args[_key2 - 1] = arguments[_key2]; 58 } 59 60 printWarning('error', format, args); 61 } 62 } 63} 64 65function printWarning(level, format, args) { 66 // When changing this logic, you might want to also 67 // update consoleWithStackDev.www.js as well. 68 { 69 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; 70 var stack = ReactDebugCurrentFrame.getStackAddendum(); 71 72 if (stack !== '') { 73 format += '%s'; 74 args = args.concat([stack]); 75 } // eslint-disable-next-line react-internal/safe-string-coercion 76 77 78 var argsWithFormat = args.map(function (item) { 79 return String(item); 80 }); // Careful: RN currently depends on this prefix 81 82 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it 83 // breaks IE9: https://github.com/facebook/react/issues/13610 84 // eslint-disable-next-line react-internal/no-production-logging 85 86 Function.prototype.apply.call(console[level], console, argsWithFormat); 87 } 88} 89 90var FunctionComponent = 0; 91var ClassComponent = 1; 92var IndeterminateComponent = 2; // Before we know whether it is function or class 93 94var HostRoot = 3; // Root of a host tree. Could be nested inside another node. 95 96var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. 97 98var HostComponent = 5; 99var HostText = 6; 100var Fragment = 7; 101var Mode = 8; 102var ContextConsumer = 9; 103var ContextProvider = 10; 104var ForwardRef = 11; 105var Profiler = 12; 106var SuspenseComponent = 13; 107var MemoComponent = 14; 108var SimpleMemoComponent = 15; 109var LazyComponent = 16; 110var IncompleteClassComponent = 17; 111var DehydratedFragment = 18; 112var SuspenseListComponent = 19; 113var ScopeComponent = 21; 114var OffscreenComponent = 22; 115var LegacyHiddenComponent = 23; 116var CacheComponent = 24; 117var TracingMarkerComponent = 25; 118 119// ----------------------------------------------------------------------------- 120 121var enableClientRenderFallbackOnTextMismatch = true; // TODO: Need to review this code one more time before landing 122// the react-reconciler package. 123 124var enableNewReconciler = false; // Support legacy Primer support on internal FB www 125 126var enableLazyContextPropagation = false; // FB-only usage. The new API has different semantics. 127 128var enableLegacyHidden = false; // Enables unstable_avoidThisFallback feature in Fiber 129 130var enableSuspenseAvoidThisFallback = false; // Enables unstable_avoidThisFallback feature in Fizz 131// React DOM Chopping Block 132// 133// Similar to main Chopping Block but only flags related to React DOM. These are 134// grouped because we will likely batch all of them into a single major release. 135// ----------------------------------------------------------------------------- 136// Disable support for comment nodes as React DOM containers. Already disabled 137// in open source, but www codebase still relies on it. Need to remove. 138 139var disableCommentsAsDOMContainers = true; // Disable javascript: URL strings in href for XSS protection. 140// and client rendering, mostly to allow JSX attributes to apply to the custom 141// element's object properties instead of only HTML attributes. 142// https://github.com/facebook/react/issues/11347 143 144var enableCustomElementPropertySupport = false; // Disables children for <textarea> elements 145var warnAboutStringRefs = false; // ----------------------------------------------------------------------------- 146// Debugging and DevTools 147// ----------------------------------------------------------------------------- 148// Adds user timing marks for e.g. state updates, suspense, and work loop stuff, 149// for an experimental timeline tool. 150 151var enableSchedulingProfiler = true; // Helps identify side effects in render-phase lifecycle hooks and setState 152 153var enableProfilerTimer = true; // Record durations for commit and passive effects phases. 154 155var enableProfilerCommitHooks = true; // Phase param passed to onRender callback differentiates between an "update" and a "cascading-update". 156 157var allNativeEvents = new Set(); 158/** 159 * Mapping from registration name to event name 160 */ 161 162 163var registrationNameDependencies = {}; 164/** 165 * Mapping from lowercase registration names to the properly cased version, 166 * used to warn in the case of missing event handlers. Available 167 * only in true. 168 * @type {Object} 169 */ 170 171var possibleRegistrationNames = {} ; // Trust the developer to only use possibleRegistrationNames in true 172 173function registerTwoPhaseEvent(registrationName, dependencies) { 174 registerDirectEvent(registrationName, dependencies); 175 registerDirectEvent(registrationName + 'Capture', dependencies); 176} 177function registerDirectEvent(registrationName, dependencies) { 178 { 179 if (registrationNameDependencies[registrationName]) { 180 error('EventRegistry: More than one plugin attempted to publish the same ' + 'registration name, `%s`.', registrationName); 181 } 182 } 183 184 registrationNameDependencies[registrationName] = dependencies; 185 186 { 187 var lowerCasedName = registrationName.toLowerCase(); 188 possibleRegistrationNames[lowerCasedName] = registrationName; 189 190 if (registrationName === 'onDoubleClick') { 191 possibleRegistrationNames.ondblclick = registrationName; 192 } 193 } 194 195 for (var i = 0; i < dependencies.length; i++) { 196 allNativeEvents.add(dependencies[i]); 197 } 198} 199 200var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined'); 201 202var hasOwnProperty = Object.prototype.hasOwnProperty; 203 204/* 205 * The `'' + value` pattern (used in in perf-sensitive code) throws for Symbol 206 * and Temporal.* types. See https://github.com/facebook/react/pull/22064. 207 * 208 * The functions in this module will throw an easier-to-understand, 209 * easier-to-debug exception with a clear errors message message explaining the 210 * problem. (Instead of a confusing exception thrown inside the implementation 211 * of the `value` object). 212 */ 213// $FlowFixMe only called in DEV, so void return is not possible. 214function typeName(value) { 215 { 216 // toStringTag is needed for namespaced types like Temporal.Instant 217 var hasToStringTag = typeof Symbol === 'function' && Symbol.toStringTag; 218 var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || 'Object'; 219 return type; 220 } 221} // $FlowFixMe only called in DEV, so void return is not possible. 222 223 224function willCoercionThrow(value) { 225 { 226 try { 227 testStringCoercion(value); 228 return false; 229 } catch (e) { 230 return true; 231 } 232 } 233} 234 235function testStringCoercion(value) { 236 // If you ended up here by following an exception call stack, here's what's 237 // happened: you supplied an object or symbol value to React (as a prop, key, 238 // DOM attribute, CSS property, string ref, etc.) and when React tried to 239 // coerce it to a string using `'' + value`, an exception was thrown. 240 // 241 // The most common types that will cause this exception are `Symbol` instances 242 // and Temporal objects like `Temporal.Instant`. But any object that has a 243 // `valueOf` or `[Symbol.toPrimitive]` method that throws will also cause this 244 // exception. (Library authors do this to prevent users from using built-in 245 // numeric operators like `+` or comparison operators like `>=` because custom 246 // methods are needed to perform accurate arithmetic or comparison.) 247 // 248 // To fix the problem, coerce this object or symbol value to a string before 249 // passing it to React. The most reliable way is usually `String(value)`. 250 // 251 // To find which value is throwing, check the browser or debugger console. 252 // Before this exception was thrown, there should be `console.error` output 253 // that shows the type (Symbol, Temporal.PlainDate, etc.) that caused the 254 // problem and how that type was used: key, atrribute, input value prop, etc. 255 // In most cases, this console output also shows the component and its 256 // ancestor components where the exception happened. 257 // 258 // eslint-disable-next-line react-internal/safe-string-coercion 259 return '' + value; 260} 261 262function checkAttributeStringCoercion(value, attributeName) { 263 { 264 if (willCoercionThrow(value)) { 265 error('The provided `%s` attribute is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', attributeName, typeName(value)); 266 267 return testStringCoercion(value); // throw (to help callers find troubleshooting comments) 268 } 269 } 270} 271function checkKeyStringCoercion(value) { 272 { 273 if (willCoercionThrow(value)) { 274 error('The provided key is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', typeName(value)); 275 276 return testStringCoercion(value); // throw (to help callers find troubleshooting comments) 277 } 278 } 279} 280function checkPropStringCoercion(value, propName) { 281 { 282 if (willCoercionThrow(value)) { 283 error('The provided `%s` prop is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', propName, typeName(value)); 284 285 return testStringCoercion(value); // throw (to help callers find troubleshooting comments) 286 } 287 } 288} 289function checkCSSPropertyStringCoercion(value, propName) { 290 { 291 if (willCoercionThrow(value)) { 292 error('The provided `%s` CSS property is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', propName, typeName(value)); 293 294 return testStringCoercion(value); // throw (to help callers find troubleshooting comments) 295 } 296 } 297} 298function checkHtmlStringCoercion(value) { 299 { 300 if (willCoercionThrow(value)) { 301 error('The provided HTML markup uses a value of unsupported type %s.' + ' This value must be coerced to a string before before using it here.', typeName(value)); 302 303 return testStringCoercion(value); // throw (to help callers find troubleshooting comments) 304 } 305 } 306} 307function checkFormFieldValueStringCoercion(value) { 308 { 309 if (willCoercionThrow(value)) { 310 error('Form field values (value, checked, defaultValue, or defaultChecked props)' + ' must be strings, not %s.' + ' This value must be coerced to a string before before using it here.', typeName(value)); 311 312 return testStringCoercion(value); // throw (to help callers find troubleshooting comments) 313 } 314 } 315} 316 317// A reserved attribute. 318// It is handled by React separately and shouldn't be written to the DOM. 319var RESERVED = 0; // A simple string attribute. 320// Attributes that aren't in the filter are presumed to have this type. 321 322var STRING = 1; // A string attribute that accepts booleans in React. In HTML, these are called 323// "enumerated" attributes with "true" and "false" as possible values. 324// When true, it should be set to a "true" string. 325// When false, it should be set to a "false" string. 326 327var BOOLEANISH_STRING = 2; // A real boolean attribute. 328// When true, it should be present (set either to an empty string or its name). 329// When false, it should be omitted. 330 331var BOOLEAN = 3; // An attribute that can be used as a flag as well as with a value. 332// When true, it should be present (set either to an empty string or its name). 333// When false, it should be omitted. 334// For any other value, should be present with that value. 335 336var OVERLOADED_BOOLEAN = 4; // An attribute that must be numeric or parse as a numeric. 337// When falsy, it should be removed. 338 339var NUMERIC = 5; // An attribute that must be positive numeric or parse as a positive numeric. 340// When falsy, it should be removed. 341 342var POSITIVE_NUMERIC = 6; 343 344/* eslint-disable max-len */ 345var 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"; 346/* eslint-enable max-len */ 347 348var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040"; 349var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$'); 350var illegalAttributeNameCache = {}; 351var validatedAttributeNameCache = {}; 352function isAttributeNameSafe(attributeName) { 353 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) { 354 return true; 355 } 356 357 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) { 358 return false; 359 } 360 361 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { 362 validatedAttributeNameCache[attributeName] = true; 363 return true; 364 } 365 366 illegalAttributeNameCache[attributeName] = true; 367 368 { 369 error('Invalid attribute name: `%s`', attributeName); 370 } 371 372 return false; 373} 374function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) { 375 if (propertyInfo !== null) { 376 return propertyInfo.type === RESERVED; 377 } 378 379 if (isCustomComponentTag) { 380 return false; 381 } 382 383 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) { 384 return true; 385 } 386 387 return false; 388} 389function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) { 390 if (propertyInfo !== null && propertyInfo.type === RESERVED) { 391 return false; 392 } 393 394 switch (typeof value) { 395 case 'function': // $FlowIssue symbol is perfectly valid here 396 397 case 'symbol': 398 // eslint-disable-line 399 return true; 400 401 case 'boolean': 402 { 403 if (isCustomComponentTag) { 404 return false; 405 } 406 407 if (propertyInfo !== null) { 408 return !propertyInfo.acceptsBooleans; 409 } else { 410 var prefix = name.toLowerCase().slice(0, 5); 411 return prefix !== 'data-' && prefix !== 'aria-'; 412 } 413 } 414 415 default: 416 return false; 417 } 418} 419function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) { 420 if (value === null || typeof value === 'undefined') { 421 return true; 422 } 423 424 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) { 425 return true; 426 } 427 428 if (isCustomComponentTag) { 429 430 return false; 431 } 432 433 if (propertyInfo !== null) { 434 435 switch (propertyInfo.type) { 436 case BOOLEAN: 437 return !value; 438 439 case OVERLOADED_BOOLEAN: 440 return value === false; 441 442 case NUMERIC: 443 return isNaN(value); 444 445 case POSITIVE_NUMERIC: 446 return isNaN(value) || value < 1; 447 } 448 } 449 450 return false; 451} 452function getPropertyInfo(name) { 453 return properties.hasOwnProperty(name) ? properties[name] : null; 454} 455 456function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL, removeEmptyString) { 457 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN; 458 this.attributeName = attributeName; 459 this.attributeNamespace = attributeNamespace; 460 this.mustUseProperty = mustUseProperty; 461 this.propertyName = name; 462 this.type = type; 463 this.sanitizeURL = sanitizeURL; 464 this.removeEmptyString = removeEmptyString; 465} // When adding attributes to this list, be sure to also add them to 466// the `possibleStandardNames` module to ensure casing and incorrect 467// name warnings. 468 469 470var properties = {}; // These props are reserved by React. They shouldn't be written to the DOM. 471 472var reservedProps = ['children', 'dangerouslySetInnerHTML', // TODO: This prevents the assignment of defaultValue to regular 473// elements (not just inputs). Now that ReactDOMInput assigns to the 474// defaultValue property -- do we need this? 475'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style']; 476 477reservedProps.forEach(function (name) { 478 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty 479 name, // attributeName 480 null, // attributeNamespace 481 false, // sanitizeURL 482 false); 483}); // A few React string attributes have a different name. 484// This is a mapping from React prop names to the attribute names. 485 486[['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) { 487 var name = _ref[0], 488 attributeName = _ref[1]; 489 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 490 attributeName, // attributeName 491 null, // attributeNamespace 492 false, // sanitizeURL 493 false); 494}); // These are "enumerated" HTML attributes that accept "true" and "false". 495// In React, we let users pass `true` and `false` even though technically 496// these aren't boolean attributes (they are coerced to strings). 497 498['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) { 499 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty 500 name.toLowerCase(), // attributeName 501 null, // attributeNamespace 502 false, // sanitizeURL 503 false); 504}); // These are "enumerated" SVG attributes that accept "true" and "false". 505// In React, we let users pass `true` and `false` even though technically 506// these aren't boolean attributes (they are coerced to strings). 507// Since these are SVG attributes, their attribute names are case-sensitive. 508 509['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) { 510 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty 511 name, // attributeName 512 null, // attributeNamespace 513 false, // sanitizeURL 514 false); 515}); // These are HTML boolean attributes. 516 517['allowFullScreen', 'async', // Note: there is a special case that prevents it from being written to the DOM 518// on the client side because the browsers are inconsistent. Instead we call focus(). 519'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'disableRemotePlayback', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', // Microdata 520'itemScope'].forEach(function (name) { 521 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty 522 name.toLowerCase(), // attributeName 523 null, // attributeNamespace 524 false, // sanitizeURL 525 false); 526}); // These are the few React props that we set as DOM properties 527// rather than attributes. These are all booleans. 528 529['checked', // Note: `option.selected` is not updated if `select.multiple` is 530// disabled with `removeAttribute`. We have special logic for handling this. 531'multiple', 'muted', 'selected' // NOTE: if you add a camelCased prop to this list, 532// you'll need to set attributeName to name.toLowerCase() 533// instead in the assignment below. 534].forEach(function (name) { 535 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty 536 name, // attributeName 537 null, // attributeNamespace 538 false, // sanitizeURL 539 false); 540}); // These are HTML attributes that are "overloaded booleans": they behave like 541// booleans, but can also accept a string value. 542 543['capture', 'download' // NOTE: if you add a camelCased prop to this list, 544// you'll need to set attributeName to name.toLowerCase() 545// instead in the assignment below. 546].forEach(function (name) { 547 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty 548 name, // attributeName 549 null, // attributeNamespace 550 false, // sanitizeURL 551 false); 552}); // These are HTML attributes that must be positive numbers. 553 554['cols', 'rows', 'size', 'span' // NOTE: if you add a camelCased prop to this list, 555// you'll need to set attributeName to name.toLowerCase() 556// instead in the assignment below. 557].forEach(function (name) { 558 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty 559 name, // attributeName 560 null, // attributeNamespace 561 false, // sanitizeURL 562 false); 563}); // These are HTML attributes that must be numbers. 564 565['rowSpan', 'start'].forEach(function (name) { 566 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty 567 name.toLowerCase(), // attributeName 568 null, // attributeNamespace 569 false, // sanitizeURL 570 false); 571}); 572var CAMELIZE = /[\-\:]([a-z])/g; 573 574var capitalize = function (token) { 575 return token[1].toUpperCase(); 576}; // This is a list of all SVG attributes that need special casing, namespacing, 577// or boolean value assignment. Regular attributes that just accept strings 578// and have the same names are omitted, just like in the HTML attribute filter. 579// Some of these attributes can be hard to find. This list was created by 580// scraping the MDN documentation. 581 582 583['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' // NOTE: if you add a camelCased prop to this list, 584// you'll need to set attributeName to name.toLowerCase() 585// instead in the assignment below. 586].forEach(function (attributeName) { 587 var name = attributeName.replace(CAMELIZE, capitalize); 588 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 589 attributeName, null, // attributeNamespace 590 false, // sanitizeURL 591 false); 592}); // String SVG attributes with the xlink namespace. 593 594['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type' // NOTE: if you add a camelCased prop to this list, 595// you'll need to set attributeName to name.toLowerCase() 596// instead in the assignment below. 597].forEach(function (attributeName) { 598 var name = attributeName.replace(CAMELIZE, capitalize); 599 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 600 attributeName, 'http://www.w3.org/1999/xlink', false, // sanitizeURL 601 false); 602}); // String SVG attributes with the xml namespace. 603 604['xml:base', 'xml:lang', 'xml:space' // NOTE: if you add a camelCased prop to this list, 605// you'll need to set attributeName to name.toLowerCase() 606// instead in the assignment below. 607].forEach(function (attributeName) { 608 var name = attributeName.replace(CAMELIZE, capitalize); 609 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty 610 attributeName, 'http://www.w3.org/XML/1998/namespace', false, // sanitizeURL 611 false); 612}); // These attribute exists both in HTML and SVG. 613// The attribute name is case-sensitive in SVG so we can't just use 614// the React name like we do for attributes that exist only in HTML. 615 616['tabIndex', 'crossOrigin'].forEach(function (attributeName) { 617 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty 618 attributeName.toLowerCase(), // attributeName 619 null, // attributeNamespace 620 false, // sanitizeURL 621 false); 622}); // These attributes accept URLs. These must not allow javascript: URLS. 623// These will also need to accept Trusted Types object in the future. 624 625var xlinkHref = 'xlinkHref'; 626properties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty 627'xlink:href', 'http://www.w3.org/1999/xlink', true, // sanitizeURL 628false); 629['src', 'href', 'action', 'formAction'].forEach(function (attributeName) { 630 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty 631 attributeName.toLowerCase(), // attributeName 632 null, // attributeNamespace 633 true, // sanitizeURL 634 true); 635}); 636 637// and any newline or tab are filtered out as if they're not part of the URL. 638// https://url.spec.whatwg.org/#url-parsing 639// Tab or newline are defined as \r\n\t: 640// https://infra.spec.whatwg.org/#ascii-tab-or-newline 641// A C0 control is a code point in the range \u0000 NULL to \u001F 642// INFORMATION SEPARATOR ONE, inclusive: 643// https://infra.spec.whatwg.org/#c0-control-or-space 644 645/* eslint-disable max-len */ 646 647var isJavaScriptProtocol = /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i; 648var didWarn = false; 649 650function sanitizeURL(url) { 651 { 652 if (!didWarn && isJavaScriptProtocol.test(url)) { 653 didWarn = true; 654 655 error('A future version of React will block javascript: URLs as a security precaution. ' + 'Use event handlers instead if you can. If you need to generate unsafe HTML try ' + 'using dangerouslySetInnerHTML instead. React was passed %s.', JSON.stringify(url)); 656 } 657 } 658} 659 660/** 661 * Get the value for a property on a node. Only used in DEV for SSR validation. 662 * The "expected" argument is used as a hint of what the expected value is. 663 * Some properties have multiple equivalent values. 664 */ 665function getValueForProperty(node, name, expected, propertyInfo) { 666 { 667 if (propertyInfo.mustUseProperty) { 668 var propertyName = propertyInfo.propertyName; 669 return node[propertyName]; 670 } else { 671 // This check protects multiple uses of `expected`, which is why the 672 // react-internal/safe-string-coercion rule is disabled in several spots 673 // below. 674 { 675 checkAttributeStringCoercion(expected, name); 676 } 677 678 if ( propertyInfo.sanitizeURL) { 679 // If we haven't fully disabled javascript: URLs, and if 680 // the hydration is successful of a javascript: URL, we 681 // still want to warn on the client. 682 // eslint-disable-next-line react-internal/safe-string-coercion 683 sanitizeURL('' + expected); 684 } 685 686 var attributeName = propertyInfo.attributeName; 687 var stringValue = null; 688 689 if (propertyInfo.type === OVERLOADED_BOOLEAN) { 690 if (node.hasAttribute(attributeName)) { 691 var value = node.getAttribute(attributeName); 692 693 if (value === '') { 694 return true; 695 } 696 697 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) { 698 return value; 699 } // eslint-disable-next-line react-internal/safe-string-coercion 700 701 702 if (value === '' + expected) { 703 return expected; 704 } 705 706 return value; 707 } 708 } else if (node.hasAttribute(attributeName)) { 709 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) { 710 // We had an attribute but shouldn't have had one, so read it 711 // for the error message. 712 return node.getAttribute(attributeName); 713 } 714 715 if (propertyInfo.type === BOOLEAN) { 716 // If this was a boolean, it doesn't matter what the value is 717 // the fact that we have it is the same as the expected. 718 return expected; 719 } // Even if this property uses a namespace we use getAttribute 720 // because we assume its namespaced name is the same as our config. 721 // To use getAttributeNS we need the local name which we don't have 722 // in our config atm. 723 724 725 stringValue = node.getAttribute(attributeName); 726 } 727 728 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) { 729 return stringValue === null ? expected : stringValue; // eslint-disable-next-line react-internal/safe-string-coercion 730 } else if (stringValue === '' + expected) { 731 return expected; 732 } else { 733 return stringValue; 734 } 735 } 736 } 737} 738/** 739 * Get the value for a attribute on a node. Only used in DEV for SSR validation. 740 * The third argument is used as a hint of what the expected value is. Some 741 * attributes have multiple equivalent values. 742 */ 743 744function getValueForAttribute(node, name, expected, isCustomComponentTag) { 745 { 746 if (!isAttributeNameSafe(name)) { 747 return; 748 } 749 750 if (!node.hasAttribute(name)) { 751 return expected === undefined ? undefined : null; 752 } 753 754 var value = node.getAttribute(name); 755 756 { 757 checkAttributeStringCoercion(expected, name); 758 } 759 760 if (value === '' + expected) { 761 return expected; 762 } 763 764 return value; 765 } 766} 767/** 768 * Sets the value for a property on a node. 769 * 770 * @param {DOMElement} node 771 * @param {string} name 772 * @param {*} value 773 */ 774 775function setValueForProperty(node, name, value, isCustomComponentTag) { 776 var propertyInfo = getPropertyInfo(name); 777 778 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) { 779 return; 780 } 781 782 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) { 783 value = null; 784 } 785 786 787 if (isCustomComponentTag || propertyInfo === null) { 788 if (isAttributeNameSafe(name)) { 789 var _attributeName = name; 790 791 if (value === null) { 792 node.removeAttribute(_attributeName); 793 } else { 794 { 795 checkAttributeStringCoercion(value, name); 796 } 797 798 node.setAttribute(_attributeName, '' + value); 799 } 800 } 801 802 return; 803 } 804 805 var mustUseProperty = propertyInfo.mustUseProperty; 806 807 if (mustUseProperty) { 808 var propertyName = propertyInfo.propertyName; 809 810 if (value === null) { 811 var type = propertyInfo.type; 812 node[propertyName] = type === BOOLEAN ? false : ''; 813 } else { 814 // Contrary to `setAttribute`, object properties are properly 815 // `toString`ed by IE8/9. 816 node[propertyName] = value; 817 } 818 819 return; 820 } // The rest are treated as attributes with special cases. 821 822 823 var attributeName = propertyInfo.attributeName, 824 attributeNamespace = propertyInfo.attributeNamespace; 825 826 if (value === null) { 827 node.removeAttribute(attributeName); 828 } else { 829 var _type = propertyInfo.type; 830 var attributeValue; 831 832 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) { 833 // If attribute type is boolean, we know for sure it won't be an execution sink 834 // and we won't require Trusted Type here. 835 attributeValue = ''; 836 } else { 837 // `setAttribute` with objects becomes only `[object]` in IE8/9, 838 // ('' + value) makes it output the correct toString()-value. 839 { 840 { 841 checkAttributeStringCoercion(value, attributeName); 842 } 843 844 attributeValue = '' + value; 845 } 846 847 if (propertyInfo.sanitizeURL) { 848 sanitizeURL(attributeValue.toString()); 849 } 850 } 851 852 if (attributeNamespace) { 853 node.setAttributeNS(attributeNamespace, attributeName, attributeValue); 854 } else { 855 node.setAttribute(attributeName, attributeValue); 856 } 857 } 858} 859 860// ATTENTION 861// When adding new symbols to this file, 862// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols' 863// The Symbol used to tag the ReactElement-like types. 864var REACT_ELEMENT_TYPE = Symbol.for('react.element'); 865var REACT_PORTAL_TYPE = Symbol.for('react.portal'); 866var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment'); 867var REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode'); 868var REACT_PROFILER_TYPE = Symbol.for('react.profiler'); 869var REACT_PROVIDER_TYPE = Symbol.for('react.provider'); 870var REACT_CONTEXT_TYPE = Symbol.for('react.context'); 871var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref'); 872var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense'); 873var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list'); 874var REACT_MEMO_TYPE = Symbol.for('react.memo'); 875var REACT_LAZY_TYPE = Symbol.for('react.lazy'); 876var REACT_SCOPE_TYPE = Symbol.for('react.scope'); 877var REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for('react.debug_trace_mode'); 878var REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen'); 879var REACT_LEGACY_HIDDEN_TYPE = Symbol.for('react.legacy_hidden'); 880var REACT_CACHE_TYPE = Symbol.for('react.cache'); 881var REACT_TRACING_MARKER_TYPE = Symbol.for('react.tracing_marker'); 882var MAYBE_ITERATOR_SYMBOL = Symbol.iterator; 883var FAUX_ITERATOR_SYMBOL = '@@iterator'; 884function getIteratorFn(maybeIterable) { 885 if (maybeIterable === null || typeof maybeIterable !== 'object') { 886 return null; 887 } 888 889 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]; 890 891 if (typeof maybeIterator === 'function') { 892 return maybeIterator; 893 } 894 895 return null; 896} 897 898var assign = Object.assign; 899 900// Helpers to patch console.logs to avoid logging during side-effect free 901// replaying on render function. This currently only patches the object 902// lazily which won't cover if the log function was extracted eagerly. 903// We could also eagerly patch the method. 904var disabledDepth = 0; 905var prevLog; 906var prevInfo; 907var prevWarn; 908var prevError; 909var prevGroup; 910var prevGroupCollapsed; 911var prevGroupEnd; 912 913function disabledLog() {} 914 915disabledLog.__reactDisabledLog = true; 916function disableLogs() { 917 { 918 if (disabledDepth === 0) { 919 /* eslint-disable react-internal/no-production-logging */ 920 prevLog = console.log; 921 prevInfo = console.info; 922 prevWarn = console.warn; 923 prevError = console.error; 924 prevGroup = console.group; 925 prevGroupCollapsed = console.groupCollapsed; 926 prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 927 928 var props = { 929 configurable: true, 930 enumerable: true, 931 value: disabledLog, 932 writable: true 933 }; // $FlowFixMe Flow thinks console is immutable. 934 935 Object.defineProperties(console, { 936 info: props, 937 log: props, 938 warn: props, 939 error: props, 940 group: props, 941 groupCollapsed: props, 942 groupEnd: props 943 }); 944 /* eslint-enable react-internal/no-production-logging */ 945 } 946 947 disabledDepth++; 948 } 949} 950function reenableLogs() { 951 { 952 disabledDepth--; 953 954 if (disabledDepth === 0) { 955 /* eslint-disable react-internal/no-production-logging */ 956 var props = { 957 configurable: true, 958 enumerable: true, 959 writable: true 960 }; // $FlowFixMe Flow thinks console is immutable. 961 962 Object.defineProperties(console, { 963 log: assign({}, props, { 964 value: prevLog 965 }), 966 info: assign({}, props, { 967 value: prevInfo 968 }), 969 warn: assign({}, props, { 970 value: prevWarn 971 }), 972 error: assign({}, props, { 973 value: prevError 974 }), 975 group: assign({}, props, { 976 value: prevGroup 977 }), 978 groupCollapsed: assign({}, props, { 979 value: prevGroupCollapsed 980 }), 981 groupEnd: assign({}, props, { 982 value: prevGroupEnd 983 }) 984 }); 985 /* eslint-enable react-internal/no-production-logging */ 986 } 987 988 if (disabledDepth < 0) { 989 error('disabledDepth fell below zero. ' + 'This is a bug in React. Please file an issue.'); 990 } 991 } 992} 993 994var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; 995var prefix; 996function describeBuiltInComponentFrame(name, source, ownerFn) { 997 { 998 if (prefix === undefined) { 999 // Extract the VM specific prefix used by each line. 1000 try { 1001 throw Error(); 1002 } catch (x) { 1003 var match = x.stack.trim().match(/\n( *(at )?)/); 1004 prefix = match && match[1] || ''; 1005 } 1006 } // We use the prefix to ensure our stacks line up with native stack frames. 1007 1008 1009 return '\n' + prefix + name; 1010 } 1011} 1012var reentry = false; 1013var componentFrameCache; 1014 1015{ 1016 var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map; 1017 componentFrameCache = new PossiblyWeakMap(); 1018} 1019 1020function describeNativeComponentFrame(fn, construct) { 1021 // If something asked for a stack inside a fake render, it should get ignored. 1022 if ( !fn || reentry) { 1023 return ''; 1024 } 1025 1026 { 1027 var frame = componentFrameCache.get(fn); 1028 1029 if (frame !== undefined) { 1030 return frame; 1031 } 1032 } 1033 1034 var control; 1035 reentry = true; 1036 var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe It does accept undefined. 1037 1038 Error.prepareStackTrace = undefined; 1039 var previousDispatcher; 1040 1041 { 1042 previousDispatcher = ReactCurrentDispatcher.current; // Set the dispatcher in DEV because this might be call in the render function 1043 // for warnings. 1044 1045 ReactCurrentDispatcher.current = null; 1046 disableLogs(); 1047 } 1048 1049 try { 1050 // This should throw. 1051 if (construct) { 1052 // Something should be setting the props in the constructor. 1053 var Fake = function () { 1054 throw Error(); 1055 }; // $FlowFixMe 1056 1057 1058 Object.defineProperty(Fake.prototype, 'props', { 1059 set: function () { 1060 // We use a throwing setter instead of frozen or non-writable props 1061 // because that won't throw in a non-strict mode function. 1062 throw Error(); 1063 } 1064 }); 1065 1066 if (typeof Reflect === 'object' && Reflect.construct) { 1067 // We construct a different control for this case to include any extra 1068 // frames added by the construct call. 1069 try { 1070 Reflect.construct(Fake, []); 1071 } catch (x) { 1072 control = x; 1073 } 1074 1075 Reflect.construct(fn, [], Fake); 1076 } else { 1077 try { 1078 Fake.call(); 1079 } catch (x) { 1080 control = x; 1081 } 1082 1083 fn.call(Fake.prototype); 1084 } 1085 } else { 1086 try { 1087 throw Error(); 1088 } catch (x) { 1089 control = x; 1090 } 1091 1092 fn(); 1093 } 1094 } catch (sample) { 1095 // This is inlined manually because closure doesn't do it for us. 1096 if (sample && control && typeof sample.stack === 'string') { 1097 // This extracts the first frame from the sample that isn't also in the control. 1098 // Skipping one frame that we assume is the frame that calls the two. 1099 var sampleLines = sample.stack.split('\n'); 1100 var controlLines = control.stack.split('\n'); 1101 var s = sampleLines.length - 1; 1102 var c = controlLines.length - 1; 1103 1104 while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) { 1105 // We expect at least one stack frame to be shared. 1106 // Typically this will be the root most one. However, stack frames may be 1107 // cut off due to maximum stack limits. In this case, one maybe cut off 1108 // earlier than the other. We assume that the sample is longer or the same 1109 // and there for cut off earlier. So we should find the root most frame in 1110 // the sample somewhere in the control. 1111 c--; 1112 } 1113 1114 for (; s >= 1 && c >= 0; s--, c--) { 1115 // Next we find the first one that isn't the same which should be the 1116 // frame that called our sample function and the control. 1117 if (sampleLines[s] !== controlLines[c]) { 1118 // In V8, the first line is describing the message but other VMs don't. 1119 // If we're about to return the first line, and the control is also on the same 1120 // line, that's a pretty good indicator that our sample threw at same line as 1121 // the control. I.e. before we entered the sample frame. So we ignore this result. 1122 // This can happen if you passed a class to function component, or non-function. 1123 if (s !== 1 || c !== 1) { 1124 do { 1125 s--; 1126 c--; // We may still have similar intermediate frames from the construct call. 1127 // The next one that isn't the same should be our match though. 1128 1129 if (c < 0 || sampleLines[s] !== controlLines[c]) { 1130 // V8 adds a "new" prefix for native classes. Let's remove it to make it prettier. 1131 var _frame = '\n' + sampleLines[s].replace(' at new ', ' at '); // If our component frame is labeled "<anonymous>" 1132 // but we have a user-provided "displayName" 1133 // splice it in to make the stack more readable. 1134 1135 1136 if (fn.displayName && _frame.includes('<anonymous>')) { 1137 _frame = _frame.replace('<anonymous>', fn.displayName); 1138 } 1139 1140 { 1141 if (typeof fn === 'function') { 1142 componentFrameCache.set(fn, _frame); 1143 } 1144 } // Return the line we found. 1145 1146 1147 return _frame; 1148 } 1149 } while (s >= 1 && c >= 0); 1150 } 1151 1152 break; 1153 } 1154 } 1155 } 1156 } finally { 1157 reentry = false; 1158 1159 { 1160 ReactCurrentDispatcher.current = previousDispatcher; 1161 reenableLogs(); 1162 } 1163 1164 Error.prepareStackTrace = previousPrepareStackTrace; 1165 } // Fallback to just using the name if we couldn't make it throw. 1166 1167 1168 var name = fn ? fn.displayName || fn.name : ''; 1169 var syntheticFrame = name ? describeBuiltInComponentFrame(name) : ''; 1170 1171 { 1172 if (typeof fn === 'function') { 1173 componentFrameCache.set(fn, syntheticFrame); 1174 } 1175 } 1176 1177 return syntheticFrame; 1178} 1179 1180function describeClassComponentFrame(ctor, source, ownerFn) { 1181 { 1182 return describeNativeComponentFrame(ctor, true); 1183 } 1184} 1185function describeFunctionComponentFrame(fn, source, ownerFn) { 1186 { 1187 return describeNativeComponentFrame(fn, false); 1188 } 1189} 1190 1191function shouldConstruct(Component) { 1192 var prototype = Component.prototype; 1193 return !!(prototype && prototype.isReactComponent); 1194} 1195 1196function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { 1197 1198 if (type == null) { 1199 return ''; 1200 } 1201 1202 if (typeof type === 'function') { 1203 { 1204 return describeNativeComponentFrame(type, shouldConstruct(type)); 1205 } 1206 } 1207 1208 if (typeof type === 'string') { 1209 return describeBuiltInComponentFrame(type); 1210 } 1211 1212 switch (type) { 1213 case REACT_SUSPENSE_TYPE: 1214 return describeBuiltInComponentFrame('Suspense'); 1215 1216 case REACT_SUSPENSE_LIST_TYPE: 1217 return describeBuiltInComponentFrame('SuspenseList'); 1218 } 1219 1220 if (typeof type === 'object') { 1221 switch (type.$$typeof) { 1222 case REACT_FORWARD_REF_TYPE: 1223 return describeFunctionComponentFrame(type.render); 1224 1225 case REACT_MEMO_TYPE: 1226 // Memo may contain any component type so we recursively resolve it. 1227 return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); 1228 1229 case REACT_LAZY_TYPE: 1230 { 1231 var lazyComponent = type; 1232 var payload = lazyComponent._payload; 1233 var init = lazyComponent._init; 1234 1235 try { 1236 // Lazy may contain any component type so we recursively resolve it. 1237 return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn); 1238 } catch (x) {} 1239 } 1240 } 1241 } 1242 1243 return ''; 1244} 1245 1246function describeFiber(fiber) { 1247 var owner = fiber._debugOwner ? fiber._debugOwner.type : null ; 1248 var source = fiber._debugSource ; 1249 1250 switch (fiber.tag) { 1251 case HostComponent: 1252 return describeBuiltInComponentFrame(fiber.type); 1253 1254 case LazyComponent: 1255 return describeBuiltInComponentFrame('Lazy'); 1256 1257 case SuspenseComponent: 1258 return describeBuiltInComponentFrame('Suspense'); 1259 1260 case SuspenseListComponent: 1261 return describeBuiltInComponentFrame('SuspenseList'); 1262 1263 case FunctionComponent: 1264 case IndeterminateComponent: 1265 case SimpleMemoComponent: 1266 return describeFunctionComponentFrame(fiber.type); 1267 1268 case ForwardRef: 1269 return describeFunctionComponentFrame(fiber.type.render); 1270 1271 case ClassComponent: 1272 return describeClassComponentFrame(fiber.type); 1273 1274 default: 1275 return ''; 1276 } 1277} 1278 1279function getStackByFiberInDevAndProd(workInProgress) { 1280 try { 1281 var info = ''; 1282 var node = workInProgress; 1283 1284 do { 1285 info += describeFiber(node); 1286 node = node.return; 1287 } while (node); 1288 1289 return info; 1290 } catch (x) { 1291 return '\nError generating stack: ' + x.message + '\n' + x.stack; 1292 } 1293} 1294 1295function getWrappedName(outerType, innerType, wrapperName) { 1296 var displayName = outerType.displayName; 1297 1298 if (displayName) { 1299 return displayName; 1300 } 1301 1302 var functionName = innerType.displayName || innerType.name || ''; 1303 return functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName; 1304} // Keep in sync with react-reconciler/getComponentNameFromFiber 1305 1306 1307function getContextName(type) { 1308 return type.displayName || 'Context'; 1309} // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead. 1310 1311 1312function getComponentNameFromType(type) { 1313 if (type == null) { 1314 // Host root, text node or just invalid type. 1315 return null; 1316 } 1317 1318 { 1319 if (typeof type.tag === 'number') { 1320 error('Received an unexpected object in getComponentNameFromType(). ' + 'This is likely a bug in React. Please file an issue.'); 1321 } 1322 } 1323 1324 if (typeof type === 'function') { 1325 return type.displayName || type.name || null; 1326 } 1327 1328 if (typeof type === 'string') { 1329 return type; 1330 } 1331 1332 switch (type) { 1333 case REACT_FRAGMENT_TYPE: 1334 return 'Fragment'; 1335 1336 case REACT_PORTAL_TYPE: 1337 return 'Portal'; 1338 1339 case REACT_PROFILER_TYPE: 1340 return 'Profiler'; 1341 1342 case REACT_STRICT_MODE_TYPE: 1343 return 'StrictMode'; 1344 1345 case REACT_SUSPENSE_TYPE: 1346 return 'Suspense'; 1347 1348 case REACT_SUSPENSE_LIST_TYPE: 1349 return 'SuspenseList'; 1350 1351 } 1352 1353 if (typeof type === 'object') { 1354 switch (type.$$typeof) { 1355 case REACT_CONTEXT_TYPE: 1356 var context = type; 1357 return getContextName(context) + '.Consumer'; 1358 1359 case REACT_PROVIDER_TYPE: 1360 var provider = type; 1361 return getContextName(provider._context) + '.Provider'; 1362 1363 case REACT_FORWARD_REF_TYPE: 1364 return getWrappedName(type, type.render, 'ForwardRef'); 1365 1366 case REACT_MEMO_TYPE: 1367 var outerName = type.displayName || null; 1368 1369 if (outerName !== null) { 1370 return outerName; 1371 } 1372 1373 return getComponentNameFromType(type.type) || 'Memo'; 1374 1375 case REACT_LAZY_TYPE: 1376 { 1377 var lazyComponent = type; 1378 var payload = lazyComponent._payload; 1379 var init = lazyComponent._init; 1380 1381 try { 1382 return getComponentNameFromType(init(payload)); 1383 } catch (x) { 1384 return null; 1385 } 1386 } 1387 1388 // eslint-disable-next-line no-fallthrough 1389 } 1390 } 1391 1392 return null; 1393} 1394 1395function getWrappedName$1(outerType, innerType, wrapperName) { 1396 var functionName = innerType.displayName || innerType.name || ''; 1397 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName); 1398} // Keep in sync with shared/getComponentNameFromType 1399 1400 1401function getContextName$1(type) { 1402 return type.displayName || 'Context'; 1403} 1404 1405function getComponentNameFromFiber(fiber) { 1406 var tag = fiber.tag, 1407 type = fiber.type; 1408 1409 switch (tag) { 1410 case CacheComponent: 1411 return 'Cache'; 1412 1413 case ContextConsumer: 1414 var context = type; 1415 return getContextName$1(context) + '.Consumer'; 1416 1417 case ContextProvider: 1418 var provider = type; 1419 return getContextName$1(provider._context) + '.Provider'; 1420 1421 case DehydratedFragment: 1422 return 'DehydratedFragment'; 1423 1424 case ForwardRef: 1425 return getWrappedName$1(type, type.render, 'ForwardRef'); 1426 1427 case Fragment: 1428 return 'Fragment'; 1429 1430 case HostComponent: 1431 // Host component type is the display name (e.g. "div", "View") 1432 return type; 1433 1434 case HostPortal: 1435 return 'Portal'; 1436 1437 case HostRoot: 1438 return 'Root'; 1439 1440 case HostText: 1441 return 'Text'; 1442 1443 case LazyComponent: 1444 // Name comes from the type in this case; we don't have a tag. 1445 return getComponentNameFromType(type); 1446 1447 case Mode: 1448 if (type === REACT_STRICT_MODE_TYPE) { 1449 // Don't be less specific than shared/getComponentNameFromType 1450 return 'StrictMode'; 1451 } 1452 1453 return 'Mode'; 1454 1455 case OffscreenComponent: 1456 return 'Offscreen'; 1457 1458 case Profiler: 1459 return 'Profiler'; 1460 1461 case ScopeComponent: 1462 return 'Scope'; 1463 1464 case SuspenseComponent: 1465 return 'Suspense'; 1466 1467 case SuspenseListComponent: 1468 return 'SuspenseList'; 1469 1470 case TracingMarkerComponent: 1471 return 'TracingMarker'; 1472 // The display name for this tags come from the user-provided type: 1473 1474 case ClassComponent: 1475 case FunctionComponent: 1476 case IncompleteClassComponent: 1477 case IndeterminateComponent: 1478 case MemoComponent: 1479 case SimpleMemoComponent: 1480 if (typeof type === 'function') { 1481 return type.displayName || type.name || null; 1482 } 1483 1484 if (typeof type === 'string') { 1485 return type; 1486 } 1487 1488 break; 1489 1490 } 1491 1492 return null; 1493} 1494 1495var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; 1496var current = null; 1497var isRendering = false; 1498function getCurrentFiberOwnerNameInDevOrNull() { 1499 { 1500 if (current === null) { 1501 return null; 1502 } 1503 1504 var owner = current._debugOwner; 1505 1506 if (owner !== null && typeof owner !== 'undefined') { 1507 return getComponentNameFromFiber(owner); 1508 } 1509 } 1510 1511 return null; 1512} 1513 1514function getCurrentFiberStackInDev() { 1515 { 1516 if (current === null) { 1517 return ''; 1518 } // Safe because if current fiber exists, we are reconciling, 1519 // and it is guaranteed to be the work-in-progress version. 1520 1521 1522 return getStackByFiberInDevAndProd(current); 1523 } 1524} 1525 1526function resetCurrentFiber() { 1527 { 1528 ReactDebugCurrentFrame.getCurrentStack = null; 1529 current = null; 1530 isRendering = false; 1531 } 1532} 1533function setCurrentFiber(fiber) { 1534 { 1535 ReactDebugCurrentFrame.getCurrentStack = fiber === null ? null : getCurrentFiberStackInDev; 1536 current = fiber; 1537 isRendering = false; 1538 } 1539} 1540function getCurrentFiber() { 1541 { 1542 return current; 1543 } 1544} 1545function setIsRendering(rendering) { 1546 { 1547 isRendering = rendering; 1548 } 1549} 1550 1551// Flow does not allow string concatenation of most non-string types. To work 1552// around this limitation, we use an opaque type that can only be obtained by 1553// passing the value through getToStringValue first. 1554function toString(value) { 1555 // The coercion safety check is performed in getToStringValue(). 1556 // eslint-disable-next-line react-internal/safe-string-coercion 1557 return '' + value; 1558} 1559function getToStringValue(value) { 1560 switch (typeof value) { 1561 case 'boolean': 1562 case 'number': 1563 case 'string': 1564 case 'undefined': 1565 return value; 1566 1567 case 'object': 1568 { 1569 checkFormFieldValueStringCoercion(value); 1570 } 1571 1572 return value; 1573 1574 default: 1575 // function, symbol are assigned as empty strings 1576 return ''; 1577 } 1578} 1579 1580var hasReadOnlyValue = { 1581 button: true, 1582 checkbox: true, 1583 image: true, 1584 hidden: true, 1585 radio: true, 1586 reset: true, 1587 submit: true 1588}; 1589function checkControlledValueProps(tagName, props) { 1590 { 1591 if (!(hasReadOnlyValue[props.type] || props.onChange || props.onInput || props.readOnly || props.disabled || props.value == null)) { 1592 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`.'); 1593 } 1594 1595 if (!(props.onChange || props.readOnly || props.disabled || props.checked == null)) { 1596 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`.'); 1597 } 1598 } 1599} 1600 1601function isCheckable(elem) { 1602 var type = elem.type; 1603 var nodeName = elem.nodeName; 1604 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio'); 1605} 1606 1607function getTracker(node) { 1608 return node._valueTracker; 1609} 1610 1611function detachTracker(node) { 1612 node._valueTracker = null; 1613} 1614 1615function getValueFromNode(node) { 1616 var value = ''; 1617 1618 if (!node) { 1619 return value; 1620 } 1621 1622 if (isCheckable(node)) { 1623 value = node.checked ? 'true' : 'false'; 1624 } else { 1625 value = node.value; 1626 } 1627 1628 return value; 1629} 1630 1631function trackValueOnNode(node) { 1632 var valueField = isCheckable(node) ? 'checked' : 'value'; 1633 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField); 1634 1635 { 1636 checkFormFieldValueStringCoercion(node[valueField]); 1637 } 1638 1639 var currentValue = '' + node[valueField]; // if someone has already defined a value or Safari, then bail 1640 // and don't track value will cause over reporting of changes, 1641 // but it's better then a hard failure 1642 // (needed for certain tests that spyOn input values and Safari) 1643 1644 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') { 1645 return; 1646 } 1647 1648 var get = descriptor.get, 1649 set = descriptor.set; 1650 Object.defineProperty(node, valueField, { 1651 configurable: true, 1652 get: function () { 1653 return get.call(this); 1654 }, 1655 set: function (value) { 1656 { 1657 checkFormFieldValueStringCoercion(value); 1658 } 1659 1660 currentValue = '' + value; 1661 set.call(this, value); 1662 } 1663 }); // We could've passed this the first time 1664 // but it triggers a bug in IE11 and Edge 14/15. 1665 // Calling defineProperty() again should be equivalent. 1666 // https://github.com/facebook/react/issues/11768 1667 1668 Object.defineProperty(node, valueField, { 1669 enumerable: descriptor.enumerable 1670 }); 1671 var tracker = { 1672 getValue: function () { 1673 return currentValue; 1674 }, 1675 setValue: function (value) { 1676 { 1677 checkFormFieldValueStringCoercion(value); 1678 } 1679 1680 currentValue = '' + value; 1681 }, 1682 stopTracking: function () { 1683 detachTracker(node); 1684 delete node[valueField]; 1685 } 1686 }; 1687 return tracker; 1688} 1689 1690function track(node) { 1691 if (getTracker(node)) { 1692 return; 1693 } // TODO: Once it's just Fiber we can move this to node._wrapperState 1694 1695 1696 node._valueTracker = trackValueOnNode(node); 1697} 1698function updateValueIfChanged(node) { 1699 if (!node) { 1700 return false; 1701 } 1702 1703 var tracker = getTracker(node); // if there is no tracker at this point it's unlikely 1704 // that trying again will succeed 1705 1706 if (!tracker) { 1707 return true; 1708 } 1709 1710 var lastValue = tracker.getValue(); 1711 var nextValue = getValueFromNode(node); 1712 1713 if (nextValue !== lastValue) { 1714 tracker.setValue(nextValue); 1715 return true; 1716 } 1717 1718 return false; 1719} 1720 1721function getActiveElement(doc) { 1722 doc = doc || (typeof document !== 'undefined' ? document : undefined); 1723 1724 if (typeof doc === 'undefined') { 1725 return null; 1726 } 1727 1728 try { 1729 return doc.activeElement || doc.body; 1730 } catch (e) { 1731 return doc.body; 1732 } 1733} 1734 1735var didWarnValueDefaultValue = false; 1736var didWarnCheckedDefaultChecked = false; 1737var didWarnControlledToUncontrolled = false; 1738var didWarnUncontrolledToControlled = false; 1739 1740function isControlled(props) { 1741 var usesChecked = props.type === 'checkbox' || props.type === 'radio'; 1742 return usesChecked ? props.checked != null : props.value != null; 1743} 1744/** 1745 * Implements an <input> host component that allows setting these optional 1746 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`. 1747 * 1748 * If `checked` or `value` are not supplied (or null/undefined), user actions 1749 * that affect the checked state or value will trigger updates to the element. 1750 * 1751 * If they are supplied (and not null/undefined), the rendered element will not 1752 * trigger updates to the element. Instead, the props must change in order for 1753 * the rendered element to be updated. 1754 * 1755 * The rendered element will be initialized as unchecked (or `defaultChecked`) 1756 * with an empty value (or `defaultValue`). 1757 * 1758 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html 1759 */ 1760 1761 1762function getHostProps(element, props) { 1763 var node = element; 1764 var checked = props.checked; 1765 var hostProps = assign({}, props, { 1766 defaultChecked: undefined, 1767 defaultValue: undefined, 1768 value: undefined, 1769 checked: checked != null ? checked : node._wrapperState.initialChecked 1770 }); 1771 return hostProps; 1772} 1773function initWrapperState(element, props) { 1774 { 1775 checkControlledValueProps('input', props); 1776 1777 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) { 1778 error('%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://reactjs.org/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type); 1779 1780 didWarnCheckedDefaultChecked = true; 1781 } 1782 1783 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) { 1784 error('%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://reactjs.org/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type); 1785 1786 didWarnValueDefaultValue = true; 1787 } 1788 } 1789 1790 var node = element; 1791 var defaultValue = props.defaultValue == null ? '' : props.defaultValue; 1792 node._wrapperState = { 1793 initialChecked: props.checked != null ? props.checked : props.defaultChecked, 1794 initialValue: getToStringValue(props.value != null ? props.value : defaultValue), 1795 controlled: isControlled(props) 1796 }; 1797} 1798function updateChecked(element, props) { 1799 var node = element; 1800 var checked = props.checked; 1801 1802 if (checked != null) { 1803 setValueForProperty(node, 'checked', checked, false); 1804 } 1805} 1806function updateWrapper(element, props) { 1807 var node = element; 1808 1809 { 1810 var controlled = isControlled(props); 1811 1812 if (!node._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) { 1813 error('A component is changing an uncontrolled input to be controlled. ' + 'This is likely caused by the value changing from undefined to ' + 'a defined value, which should not happen. ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components'); 1814 1815 didWarnUncontrolledToControlled = true; 1816 } 1817 1818 if (node._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) { 1819 error('A component is changing a controlled input to be uncontrolled. ' + 'This is likely caused by the value changing from a defined to ' + 'undefined, which should not happen. ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components'); 1820 1821 didWarnControlledToUncontrolled = true; 1822 } 1823 } 1824 1825 updateChecked(element, props); 1826 var value = getToStringValue(props.value); 1827 var type = props.type; 1828 1829 if (value != null) { 1830 if (type === 'number') { 1831 if (value === 0 && node.value === '' || // We explicitly want to coerce to number here if possible. 1832 // eslint-disable-next-line 1833 node.value != value) { 1834 node.value = toString(value); 1835 } 1836 } else if (node.value !== toString(value)) { 1837 node.value = toString(value); 1838 } 1839 } else if (type === 'submit' || type === 'reset') { 1840 // Submit/reset inputs need the attribute removed completely to avoid 1841 // blank-text buttons. 1842 node.removeAttribute('value'); 1843 return; 1844 } 1845 1846 { 1847 // When syncing the value attribute, the value comes from a cascade of 1848 // properties: 1849 // 1. The value React property 1850 // 2. The defaultValue React property 1851 // 3. Otherwise there should be no change 1852 if (props.hasOwnProperty('value')) { 1853 setDefaultValue(node, props.type, value); 1854 } else if (props.hasOwnProperty('defaultValue')) { 1855 setDefaultValue(node, props.type, getToStringValue(props.defaultValue)); 1856 } 1857 } 1858 1859 { 1860 // When syncing the checked attribute, it only changes when it needs 1861 // to be removed, such as transitioning from a checkbox into a text input 1862 if (props.checked == null && props.defaultChecked != null) { 1863 node.defaultChecked = !!props.defaultChecked; 1864 } 1865 } 1866} 1867function postMountWrapper(element, props, isHydrating) { 1868 var node = element; // Do not assign value if it is already set. This prevents user text input 1869 // from being lost during SSR hydration. 1870 1871 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) { 1872 var type = props.type; 1873 var isButton = type === 'submit' || type === 'reset'; // Avoid setting value attribute on submit/reset inputs as it overrides the 1874 // default value provided by the browser. See: #12872 1875 1876 if (isButton && (props.value === undefined || props.value === null)) { 1877 return; 1878 } 1879 1880 var initialValue = toString(node._wrapperState.initialValue); // Do not assign value if it is already set. This prevents user text input 1881 // from being lost during SSR hydration. 1882 1883 if (!isHydrating) { 1884 { 1885 // When syncing the value attribute, the value property should use 1886 // the wrapperState._initialValue property. This uses: 1887 // 1888 // 1. The value React property when present 1889 // 2. The defaultValue React property when present 1890 // 3. An empty string 1891 if (initialValue !== node.value) { 1892 node.value = initialValue; 1893 } 1894 } 1895 } 1896 1897 { 1898 // Otherwise, the value attribute is synchronized to the property, 1899 // so we assign defaultValue to the same thing as the value property 1900 // assignment step above. 1901 node.defaultValue = initialValue; 1902 } 1903 } // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug 1904 // this is needed to work around a chrome bug where setting defaultChecked 1905 // will sometimes influence the value of checked (even after detachment). 1906 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416 1907 // We need to temporarily unset name to avoid disrupting radio button groups. 1908 1909 1910 var name = node.name; 1911 1912 if (name !== '') { 1913 node.name = ''; 1914 } 1915 1916 { 1917 // When syncing the checked attribute, both the checked property and 1918 // attribute are assigned at the same time using defaultChecked. This uses: 1919 // 1920 // 1. The checked React property when present 1921 // 2. The defaultChecked React property when present 1922 // 3. Otherwise, false 1923 node.defaultChecked = !node.defaultChecked; 1924 node.defaultChecked = !!node._wrapperState.initialChecked; 1925 } 1926 1927 if (name !== '') { 1928 node.name = name; 1929 } 1930} 1931function restoreControlledState(element, props) { 1932 var node = element; 1933 updateWrapper(node, props); 1934 updateNamedCousins(node, props); 1935} 1936 1937function updateNamedCousins(rootNode, props) { 1938 var name = props.name; 1939 1940 if (props.type === 'radio' && name != null) { 1941 var queryRoot = rootNode; 1942 1943 while (queryRoot.parentNode) { 1944 queryRoot = queryRoot.parentNode; 1945 } // If `rootNode.form` was non-null, then we could try `form.elements`, 1946 // but that sometimes behaves strangely in IE8. We could also try using 1947 // `form.getElementsByName`, but that will only return direct children 1948 // and won't include inputs that use the HTML5 `form=` attribute. Since 1949 // the input might not even be in a form. It might not even be in the 1950 // document. Let's just use the local `querySelectorAll` to ensure we don't 1951 // miss anything. 1952 1953 1954 { 1955 checkAttributeStringCoercion(name, 'name'); 1956 } 1957 1958 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]'); 1959 1960 for (var i = 0; i < group.length; i++) { 1961 var otherNode = group[i]; 1962 1963 if (otherNode === rootNode || otherNode.form !== rootNode.form) { 1964 continue; 1965 } // This will throw if radio buttons rendered by different copies of React 1966 // and the same name are rendered into the same form (same as #1939). 1967 // That's probably okay; we don't support it just as we don't support 1968 // mixing React radio buttons with non-React ones. 1969 1970 1971 var otherProps = getFiberCurrentPropsFromNode(otherNode); 1972 1973 if (!otherProps) { 1974 throw new Error('ReactDOMInput: Mixing React and non-React radio inputs with the ' + 'same `name` is not supported.'); 1975 } // We need update the tracked value on the named cousin since the value 1976 // was changed but the input saw no event or value set 1977 1978 1979 updateValueIfChanged(otherNode); // If this is a controlled radio button group, forcing the input that 1980 // was previously checked to update will cause it to be come re-checked 1981 // as appropriate. 1982 1983 updateWrapper(otherNode, otherProps); 1984 } 1985 } 1986} // In Chrome, assigning defaultValue to certain input types triggers input validation. 1987// For number inputs, the display value loses trailing decimal points. For email inputs, 1988// Chrome raises "The specified value <x> is not a valid email address". 1989// 1990// Here we check to see if the defaultValue has actually changed, avoiding these problems 1991// when the user is inputting text 1992// 1993// https://github.com/facebook/react/issues/7253 1994 1995 1996function setDefaultValue(node, type, value) { 1997 if ( // Focused number inputs synchronize on blur. See ChangeEventPlugin.js 1998 type !== 'number' || getActiveElement(node.ownerDocument) !== node) { 1999 if (value == null) { 2000 node.defaultValue = toString(node._wrapperState.initialValue); 2001 } else if (node.defaultValue !== toString(value)) { 2002 node.defaultValue = toString(value); 2003 } 2004 } 2005} 2006 2007var didWarnSelectedSetOnOption = false; 2008var didWarnInvalidChild = false; 2009var didWarnInvalidInnerHTML = false; 2010/** 2011 * Implements an <option> host component that warns when `selected` is set. 2012 */ 2013 2014function validateProps(element, props) { 2015 { 2016 // If a value is not provided, then the children must be simple. 2017 if (props.value == null) { 2018 if (typeof props.children === 'object' && props.children !== null) { 2019 React.Children.forEach(props.children, function (child) { 2020 if (child == null) { 2021 return; 2022 } 2023 2024 if (typeof child === 'string' || typeof child === 'number') { 2025 return; 2026 } 2027 2028 if (!didWarnInvalidChild) { 2029 didWarnInvalidChild = true; 2030 2031 error('Cannot infer the option value of complex children. ' + 'Pass a `value` prop or use a plain string as children to <option>.'); 2032 } 2033 }); 2034 } else if (props.dangerouslySetInnerHTML != null) { 2035 if (!didWarnInvalidInnerHTML) { 2036 didWarnInvalidInnerHTML = true; 2037 2038 error('Pass a `value` prop if you set dangerouslyInnerHTML so React knows ' + 'which value should be selected.'); 2039 } 2040 } 2041 } // TODO: Remove support for `selected` in <option>. 2042 2043 2044 if (props.selected != null && !didWarnSelectedSetOnOption) { 2045 error('Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.'); 2046 2047 didWarnSelectedSetOnOption = true; 2048 } 2049 } 2050} 2051function postMountWrapper$1(element, props) { 2052 // value="" should make a value attribute (#6219) 2053 if (props.value != null) { 2054 element.setAttribute('value', toString(getToStringValue(props.value))); 2055 } 2056} 2057 2058var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare 2059 2060function isArray(a) { 2061 return isArrayImpl(a); 2062} 2063 2064var didWarnValueDefaultValue$1; 2065 2066{ 2067 didWarnValueDefaultValue$1 = false; 2068} 2069 2070function getDeclarationErrorAddendum() { 2071 var ownerName = getCurrentFiberOwnerNameInDevOrNull(); 2072 2073 if (ownerName) { 2074 return '\n\nCheck the render method of `' + ownerName + '`.'; 2075 } 2076 2077 return ''; 2078} 2079 2080var valuePropNames = ['value', 'defaultValue']; 2081/** 2082 * Validation function for `value` and `defaultValue`. 2083 */ 2084 2085function checkSelectPropTypes(props) { 2086 { 2087 checkControlledValueProps('select', props); 2088 2089 for (var i = 0; i < valuePropNames.length; i++) { 2090 var propName = valuePropNames[i]; 2091 2092 if (props[propName] == null) { 2093 continue; 2094 } 2095 2096 var propNameIsArray = isArray(props[propName]); 2097 2098 if (props.multiple && !propNameIsArray) { 2099 error('The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum()); 2100 } else if (!props.multiple && propNameIsArray) { 2101 error('The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum()); 2102 } 2103 } 2104 } 2105} 2106 2107function updateOptions(node, multiple, propValue, setDefaultSelected) { 2108 var options = node.options; 2109 2110 if (multiple) { 2111 var selectedValues = propValue; 2112 var selectedValue = {}; 2113 2114 for (var i = 0; i < selectedValues.length; i++) { 2115 // Prefix to avoid chaos with special keys. 2116 selectedValue['$' + selectedValues[i]] = true; 2117 } 2118 2119 for (var _i = 0; _i < options.length; _i++) { 2120 var selected = selectedValue.hasOwnProperty('$' + options[_i].value); 2121 2122 if (options[_i].selected !== selected) { 2123 options[_i].selected = selected; 2124 } 2125 2126 if (selected && setDefaultSelected) { 2127 options[_i].defaultSelected = true; 2128 } 2129 } 2130 } else { 2131 // Do not set `select.value` as exact behavior isn't consistent across all 2132 // browsers for all cases. 2133 var _selectedValue = toString(getToStringValue(propValue)); 2134 2135 var defaultSelected = null; 2136 2137 for (var _i2 = 0; _i2 < options.length; _i2++) { 2138 if (options[_i2].value === _selectedValue) { 2139 options[_i2].selected = true; 2140 2141 if (setDefaultSelected) { 2142 options[_i2].defaultSelected = true; 2143 } 2144 2145 return; 2146 } 2147 2148 if (defaultSelected === null && !options[_i2].disabled) { 2149 defaultSelected = options[_i2]; 2150 } 2151 } 2152 2153 if (defaultSelected !== null) { 2154 defaultSelected.selected = true; 2155 } 2156 } 2157} 2158/** 2159 * Implements a <select> host component that allows optionally setting the 2160 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a 2161 * stringable. If `multiple` is true, the prop must be an array of stringables. 2162 * 2163 * If `value` is not supplied (or null/undefined), user actions that change the 2164 * selected option will trigger updates to the rendered options. 2165 * 2166 * If it is supplied (and not null/undefined), the rendered options will not 2167 * update in response to user actions. Instead, the `value` prop must change in 2168 * order for the rendered options to update. 2169 * 2170 * If `defaultValue` is provided, any options with the supplied values will be 2171 * selected. 2172 */ 2173 2174 2175function getHostProps$1(element, props) { 2176 return assign({}, props, { 2177 value: undefined 2178 }); 2179} 2180function initWrapperState$1(element, props) { 2181 var node = element; 2182 2183 { 2184 checkSelectPropTypes(props); 2185 } 2186 2187 node._wrapperState = { 2188 wasMultiple: !!props.multiple 2189 }; 2190 2191 { 2192 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) { 2193 error('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://reactjs.org/link/controlled-components'); 2194 2195 didWarnValueDefaultValue$1 = true; 2196 } 2197 } 2198} 2199function postMountWrapper$2(element, props) { 2200 var node = element; 2201 node.multiple = !!props.multiple; 2202 var value = props.value; 2203 2204 if (value != null) { 2205 updateOptions(node, !!props.multiple, value, false); 2206 } else if (props.defaultValue != null) { 2207 updateOptions(node, !!props.multiple, props.defaultValue, true); 2208 } 2209} 2210function postUpdateWrapper(element, props) { 2211 var node = element; 2212 var wasMultiple = node._wrapperState.wasMultiple; 2213 node._wrapperState.wasMultiple = !!props.multiple; 2214 var value = props.value; 2215 2216 if (value != null) { 2217 updateOptions(node, !!props.multiple, value, false); 2218 } else if (wasMultiple !== !!props.multiple) { 2219 // For simplicity, reapply `defaultValue` if `multiple` is toggled. 2220 if (props.defaultValue != null) { 2221 updateOptions(node, !!props.multiple, props.defaultValue, true); 2222 } else { 2223 // Revert the select back to its default unselected state. 2224 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false); 2225 } 2226 } 2227} 2228function restoreControlledState$1(element, props) { 2229 var node = element; 2230 var value = props.value; 2231 2232 if (value != null) { 2233 updateOptions(node, !!props.multiple, value, false); 2234 } 2235} 2236 2237var didWarnValDefaultVal = false; 2238 2239/** 2240 * Implements a <textarea> host component that allows setting `value`, and 2241 * `defaultValue`. This differs from the traditional DOM API because value is 2242 * usually set as PCDATA children. 2243 * 2244 * If `value` is not supplied (or null/undefined), user actions that affect the 2245 * value will trigger updates to the element. 2246 * 2247 * If `value` is supplied (and not null/undefined), the rendered element will 2248 * not trigger updates to the element. Instead, the `value` prop must change in 2249 * order for the rendered element to be updated. 2250 * 2251 * The rendered element will be initialized with an empty value, the prop 2252 * `defaultValue` if specified, or the children content (deprecated). 2253 */ 2254function getHostProps$2(element, props) { 2255 var node = element; 2256 2257 if (props.dangerouslySetInnerHTML != null) { 2258 throw new Error('`dangerouslySetInnerHTML` does not make sense on <textarea>.'); 2259 } // Always set children to the same thing. In IE9, the selection range will 2260 // get reset if `textContent` is mutated. We could add a check in setTextContent 2261 // to only set the value if/when the value differs from the node value (which would 2262 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this 2263 // solution. The value can be a boolean or object so that's why it's forced 2264 // to be a string. 2265 2266 2267 var hostProps = assign({}, props, { 2268 value: undefined, 2269 defaultValue: undefined, 2270 children: toString(node._wrapperState.initialValue) 2271 }); 2272 2273 return hostProps; 2274} 2275function initWrapperState$2(element, props) { 2276 var node = element; 2277 2278 { 2279 checkControlledValueProps('textarea', props); 2280 2281 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) { 2282 error('%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://reactjs.org/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component'); 2283 2284 didWarnValDefaultVal = true; 2285 } 2286 } 2287 2288 var initialValue = props.value; // Only bother fetching default value if we're going to use it 2289 2290 if (initialValue == null) { 2291 var children = props.children, 2292 defaultValue = props.defaultValue; 2293 2294 if (children != null) { 2295 { 2296 error('Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.'); 2297 } 2298 2299 { 2300 if (defaultValue != null) { 2301 throw new Error('If you supply `defaultValue` on a <textarea>, do not pass children.'); 2302 } 2303 2304 if (isArray(children)) { 2305 if (children.length > 1) { 2306 throw new Error('<textarea> can only have at most one child.'); 2307 } 2308 2309 children = children[0]; 2310 } 2311 2312 defaultValue = children; 2313 } 2314 } 2315 2316 if (defaultValue == null) { 2317 defaultValue = ''; 2318 } 2319 2320 initialValue = defaultValue; 2321 } 2322 2323 node._wrapperState = { 2324 initialValue: getToStringValue(initialValue) 2325 }; 2326} 2327function updateWrapper$1(element, props) { 2328 var node = element; 2329 var value = getToStringValue(props.value); 2330 var defaultValue = getToStringValue(props.defaultValue); 2331 2332 if (value != null) { 2333 // Cast `value` to a string to ensure the value is set correctly. While 2334 // browsers typically do this as necessary, jsdom doesn't. 2335 var newValue = toString(value); // To avoid side effects (such as losing text selection), only set value if changed 2336 2337 if (newValue !== node.value) { 2338 node.value = newValue; 2339 } 2340 2341 if (props.defaultValue == null && node.defaultValue !== newValue) { 2342 node.defaultValue = newValue; 2343 } 2344 } 2345 2346 if (defaultValue != null) { 2347 node.defaultValue = toString(defaultValue); 2348 } 2349} 2350function postMountWrapper$3(element, props) { 2351 var node = element; // This is in postMount because we need access to the DOM node, which is not 2352 // available until after the component has mounted. 2353 2354 var textContent = node.textContent; // Only set node.value if textContent is equal to the expected 2355 // initial value. In IE10/IE11 there is a bug where the placeholder attribute 2356 // will populate textContent as well. 2357 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/ 2358 2359 if (textContent === node._wrapperState.initialValue) { 2360 if (textContent !== '' && textContent !== null) { 2361 node.value = textContent; 2362 } 2363 } 2364} 2365function restoreControlledState$2(element, props) { 2366 // DOM component is still mounted; update 2367 updateWrapper$1(element, props); 2368} 2369 2370var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'; 2371var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML'; 2372var SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; // Assumes there is no parent namespace. 2373 2374function getIntrinsicNamespace(type) { 2375 switch (type) { 2376 case 'svg': 2377 return SVG_NAMESPACE; 2378 2379 case 'math': 2380 return MATH_NAMESPACE; 2381 2382 default: 2383 return HTML_NAMESPACE; 2384 } 2385} 2386function getChildNamespace(parentNamespace, type) { 2387 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE) { 2388 // No (or default) parent namespace: potential entry point. 2389 return getIntrinsicNamespace(type); 2390 } 2391 2392 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') { 2393 // We're leaving SVG. 2394 return HTML_NAMESPACE; 2395 } // By default, pass namespace below. 2396 2397 2398 return parentNamespace; 2399} 2400 2401/* globals MSApp */ 2402 2403/** 2404 * Create a function which has 'unsafe' privileges (required by windows8 apps) 2405 */ 2406var createMicrosoftUnsafeLocalFunction = function (func) { 2407 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) { 2408 return function (arg0, arg1, arg2, arg3) { 2409 MSApp.execUnsafeLocalFunction(function () { 2410 return func(arg0, arg1, arg2, arg3); 2411 }); 2412 }; 2413 } else { 2414 return func; 2415 } 2416}; 2417 2418var reusableSVGContainer; 2419/** 2420 * Set the innerHTML property of a node 2421 * 2422 * @param {DOMElement} node 2423 * @param {string} html 2424 * @internal 2425 */ 2426 2427var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) { 2428 if (node.namespaceURI === SVG_NAMESPACE) { 2429 2430 if (!('innerHTML' in node)) { 2431 // IE does not have innerHTML for SVG nodes, so instead we inject the 2432 // new markup in a temp node and then move the child nodes across into 2433 // the target node 2434 reusableSVGContainer = reusableSVGContainer || document.createElement('div'); 2435 reusableSVGContainer.innerHTML = '<svg>' + html.valueOf().toString() + '</svg>'; 2436 var svgNode = reusableSVGContainer.firstChild; 2437 2438 while (node.firstChild) { 2439 node.removeChild(node.firstChild); 2440 } 2441 2442 while (svgNode.firstChild) { 2443 node.appendChild(svgNode.firstChild); 2444 } 2445 2446 return; 2447 } 2448 } 2449 2450 node.innerHTML = html; 2451}); 2452 2453/** 2454 * HTML nodeType values that represent the type of the node 2455 */ 2456var ELEMENT_NODE = 1; 2457var TEXT_NODE = 3; 2458var COMMENT_NODE = 8; 2459var DOCUMENT_NODE = 9; 2460var DOCUMENT_FRAGMENT_NODE = 11; 2461 2462/** 2463 * Set the textContent property of a node. For text updates, it's faster 2464 * to set the `nodeValue` of the Text node directly instead of using 2465 * `.textContent` which will remove the existing node and create a new one. 2466 * 2467 * @param {DOMElement} node 2468 * @param {string} text 2469 * @internal 2470 */ 2471 2472var setTextContent = function (node, text) { 2473 if (text) { 2474 var firstChild = node.firstChild; 2475 2476 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) { 2477 firstChild.nodeValue = text; 2478 return; 2479 } 2480 } 2481 2482 node.textContent = text; 2483}; 2484 2485// List derived from Gecko source code: 2486// https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js 2487var shorthandToLonghand = { 2488 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'], 2489 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'], 2490 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'], 2491 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'], 2492 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'], 2493 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'], 2494 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'], 2495 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'], 2496 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'], 2497 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'], 2498 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'], 2499 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'], 2500 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'], 2501 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'], 2502 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'], 2503 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'], 2504 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'], 2505 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'], 2506 columns: ['columnCount', 'columnWidth'], 2507 flex: ['flexBasis', 'flexGrow', 'flexShrink'], 2508 flexFlow: ['flexDirection', 'flexWrap'], 2509 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'], 2510 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'], 2511 gap: ['columnGap', 'rowGap'], 2512 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'], 2513 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'], 2514 gridColumn: ['gridColumnEnd', 'gridColumnStart'], 2515 gridColumnGap: ['columnGap'], 2516 gridGap: ['columnGap', 'rowGap'], 2517 gridRow: ['gridRowEnd', 'gridRowStart'], 2518 gridRowGap: ['rowGap'], 2519 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'], 2520 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'], 2521 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'], 2522 marker: ['markerEnd', 'markerMid', 'markerStart'], 2523 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'], 2524 maskPosition: ['maskPositionX', 'maskPositionY'], 2525 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'], 2526 overflow: ['overflowX', 'overflowY'], 2527 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'], 2528 placeContent: ['alignContent', 'justifyContent'], 2529 placeItems: ['alignItems', 'justifyItems'], 2530 placeSelf: ['alignSelf', 'justifySelf'], 2531 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'], 2532 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'], 2533 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'], 2534 wordWrap: ['overflowWrap'] 2535}; 2536 2537/** 2538 * CSS properties which accept numbers but are not in units of "px". 2539 */ 2540var isUnitlessNumber = { 2541 animationIterationCount: true, 2542 aspectRatio: true, 2543 borderImageOutset: true, 2544 borderImageSlice: true, 2545 borderImageWidth: true, 2546 boxFlex: true, 2547 boxFlexGroup: true, 2548 boxOrdinalGroup: true, 2549 columnCount: true, 2550 columns: true, 2551 flex: true, 2552 flexGrow: true, 2553 flexPositive: true, 2554 flexShrink: true, 2555 flexNegative: true, 2556 flexOrder: true, 2557 gridArea: true, 2558 gridRow: true, 2559 gridRowEnd: true, 2560 gridRowSpan: true, 2561 gridRowStart: true, 2562 gridColumn: true, 2563 gridColumnEnd: true, 2564 gridColumnSpan: true, 2565 gridColumnStart: true, 2566 fontWeight: true, 2567 lineClamp: true, 2568 lineHeight: true, 2569 opacity: true, 2570 order: true, 2571 orphans: true, 2572 tabSize: true, 2573 widows: true, 2574 zIndex: true, 2575 zoom: true, 2576 // SVG-related properties 2577 fillOpacity: true, 2578 floodOpacity: true, 2579 stopOpacity: true, 2580 strokeDasharray: true, 2581 strokeDashoffset: true, 2582 strokeMiterlimit: true, 2583 strokeOpacity: true, 2584 strokeWidth: true 2585}; 2586/** 2587 * @param {string} prefix vendor-specific prefix, eg: Webkit 2588 * @param {string} key style name, eg: transitionDuration 2589 * @return {string} style name prefixed with `prefix`, properly camelCased, eg: 2590 * WebkitTransitionDuration 2591 */ 2592 2593function prefixKey(prefix, key) { 2594 return prefix + key.charAt(0).toUpperCase() + key.substring(1); 2595} 2596/** 2597 * Support style names that may come passed in prefixed by adding permutations 2598 * of vendor prefixes. 2599 */ 2600 2601 2602var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an 2603// infinite loop, because it iterates over the newly added props too. 2604 2605Object.keys(isUnitlessNumber).forEach(function (prop) { 2606 prefixes.forEach(function (prefix) { 2607 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; 2608 }); 2609}); 2610 2611/** 2612 * Convert a value into the proper css writable value. The style name `name` 2613 * should be logical (no hyphens), as specified 2614 * in `CSSProperty.isUnitlessNumber`. 2615 * 2616 * @param {string} name CSS property name such as `topMargin`. 2617 * @param {*} value CSS property value such as `10px`. 2618 * @return {string} Normalized style value with dimensions applied. 2619 */ 2620 2621function dangerousStyleValue(name, value, isCustomProperty) { 2622 // Note that we've removed escapeTextForBrowser() calls here since the 2623 // whole string will be escaped when the attribute is injected into 2624 // the markup. If you provide unsafe user data here they can inject 2625 // arbitrary CSS which may be problematic (I couldn't repro this): 2626 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet 2627 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/ 2628 // This is not an XSS hole but instead a potential CSS injection issue 2629 // which has lead to a greater discussion about how we're going to 2630 // trust URLs moving forward. See #2115901 2631 var isEmpty = value == null || typeof value === 'boolean' || value === ''; 2632 2633 if (isEmpty) { 2634 return ''; 2635 } 2636 2637 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) { 2638 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers 2639 } 2640 2641 { 2642 checkCSSPropertyStringCoercion(value, name); 2643 } 2644 2645 return ('' + value).trim(); 2646} 2647 2648var uppercasePattern = /([A-Z])/g; 2649var msPattern = /^ms-/; 2650/** 2651 * Hyphenates a camelcased CSS property name, for example: 2652 * 2653 * > hyphenateStyleName('backgroundColor') 2654 * < "background-color" 2655 * > hyphenateStyleName('MozTransition') 2656 * < "-moz-transition" 2657 * > hyphenateStyleName('msTransition') 2658 * < "-ms-transition" 2659 * 2660 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix 2661 * is converted to `-ms-`. 2662 */ 2663 2664function hyphenateStyleName(name) { 2665 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-'); 2666} 2667 2668var warnValidStyle = function () {}; 2669 2670{ 2671 // 'msTransform' is correct, but the other prefixes should be capitalized 2672 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; 2673 var msPattern$1 = /^-ms-/; 2674 var hyphenPattern = /-(.)/g; // style values shouldn't contain a semicolon 2675 2676 var badStyleValueWithSemicolonPattern = /;\s*$/; 2677 var warnedStyleNames = {}; 2678 var warnedStyleValues = {}; 2679 var warnedForNaNValue = false; 2680 var warnedForInfinityValue = false; 2681 2682 var camelize = function (string) { 2683 return string.replace(hyphenPattern, function (_, character) { 2684 return character.toUpperCase(); 2685 }); 2686 }; 2687 2688 var warnHyphenatedStyleName = function (name) { 2689 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { 2690 return; 2691 } 2692 2693 warnedStyleNames[name] = true; 2694 2695 error('Unsupported style property %s. Did you mean %s?', name, // As Andi Smith suggests 2696 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix 2697 // is converted to lowercase `ms`. 2698 camelize(name.replace(msPattern$1, 'ms-'))); 2699 }; 2700 2701 var warnBadVendoredStyleName = function (name) { 2702 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { 2703 return; 2704 } 2705 2706 warnedStyleNames[name] = true; 2707 2708 error('Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1)); 2709 }; 2710 2711 var warnStyleValueWithSemicolon = function (name, value) { 2712 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { 2713 return; 2714 } 2715 2716 warnedStyleValues[value] = true; 2717 2718 error("Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, '')); 2719 }; 2720 2721 var warnStyleValueIsNaN = function (name, value) { 2722 if (warnedForNaNValue) { 2723 return; 2724 } 2725 2726 warnedForNaNValue = true; 2727 2728 error('`NaN` is an invalid value for the `%s` css style property.', name); 2729 }; 2730 2731 var warnStyleValueIsInfinity = function (name, value) { 2732 if (warnedForInfinityValue) { 2733 return; 2734 } 2735 2736 warnedForInfinityValue = true; 2737 2738 error('`Infinity` is an invalid value for the `%s` css style property.', name); 2739 }; 2740 2741 warnValidStyle = function (name, value) { 2742 if (name.indexOf('-') > -1) { 2743 warnHyphenatedStyleName(name); 2744 } else if (badVendoredStyleNamePattern.test(name)) { 2745 warnBadVendoredStyleName(name); 2746 } else if (badStyleValueWithSemicolonPattern.test(value)) { 2747 warnStyleValueWithSemicolon(name, value); 2748 } 2749 2750 if (typeof value === 'number') { 2751 if (isNaN(value)) { 2752 warnStyleValueIsNaN(name, value); 2753 } else if (!isFinite(value)) { 2754 warnStyleValueIsInfinity(name, value); 2755 } 2756 } 2757 }; 2758} 2759 2760var warnValidStyle$1 = warnValidStyle; 2761 2762/** 2763 * Operations for dealing with CSS properties. 2764 */ 2765 2766/** 2767 * This creates a string that is expected to be equivalent to the style 2768 * attribute generated by server-side rendering. It by-passes warnings and 2769 * security checks so it's not safe to use this value for anything other than 2770 * comparison. It is only used in DEV for SSR validation. 2771 */ 2772 2773function createDangerousStringForStyles(styles) { 2774 { 2775 var serialized = ''; 2776 var delimiter = ''; 2777 2778 for (var styleName in styles) { 2779 if (!styles.hasOwnProperty(styleName)) { 2780 continue; 2781 } 2782 2783 var styleValue = styles[styleName]; 2784 2785 if (styleValue != null) { 2786 var isCustomProperty = styleName.indexOf('--') === 0; 2787 serialized += delimiter + (isCustomProperty ? styleName : hyphenateStyleName(styleName)) + ':'; 2788 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty); 2789 delimiter = ';'; 2790 } 2791 } 2792 2793 return serialized || null; 2794 } 2795} 2796/** 2797 * Sets the value for multiple styles on a node. If a value is specified as 2798 * '' (empty string), the corresponding style property will be unset. 2799 * 2800 * @param {DOMElement} node 2801 * @param {object} styles 2802 */ 2803 2804function setValueForStyles(node, styles) { 2805 var style = node.style; 2806 2807 for (var styleName in styles) { 2808 if (!styles.hasOwnProperty(styleName)) { 2809 continue; 2810 } 2811 2812 var isCustomProperty = styleName.indexOf('--') === 0; 2813 2814 { 2815 if (!isCustomProperty) { 2816 warnValidStyle$1(styleName, styles[styleName]); 2817 } 2818 } 2819 2820 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty); 2821 2822 if (styleName === 'float') { 2823 styleName = 'cssFloat'; 2824 } 2825 2826 if (isCustomProperty) { 2827 style.setProperty(styleName, styleValue); 2828 } else { 2829 style[styleName] = styleValue; 2830 } 2831 } 2832} 2833 2834function isValueEmpty(value) { 2835 return value == null || typeof value === 'boolean' || value === ''; 2836} 2837/** 2838 * Given {color: 'red', overflow: 'hidden'} returns { 2839 * color: 'color', 2840 * overflowX: 'overflow', 2841 * overflowY: 'overflow', 2842 * }. This can be read as "the overflowY property was set by the overflow 2843 * shorthand". That is, the values are the property that each was derived from. 2844 */ 2845 2846 2847function expandShorthandMap(styles) { 2848 var expanded = {}; 2849 2850 for (var key in styles) { 2851 var longhands = shorthandToLonghand[key] || [key]; 2852 2853 for (var i = 0; i < longhands.length; i++) { 2854 expanded[longhands[i]] = key; 2855 } 2856 } 2857 2858 return expanded; 2859} 2860/** 2861 * When mixing shorthand and longhand property names, we warn during updates if 2862 * we expect an incorrect result to occur. In particular, we warn for: 2863 * 2864 * Updating a shorthand property (longhand gets overwritten): 2865 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'} 2866 * becomes .style.font = 'baz' 2867 * Removing a shorthand property (longhand gets lost too): 2868 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'} 2869 * becomes .style.font = '' 2870 * Removing a longhand property (should revert to shorthand; doesn't): 2871 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'} 2872 * becomes .style.fontVariant = '' 2873 */ 2874 2875 2876function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) { 2877 { 2878 if (!nextStyles) { 2879 return; 2880 } 2881 2882 var expandedUpdates = expandShorthandMap(styleUpdates); 2883 var expandedStyles = expandShorthandMap(nextStyles); 2884 var warnedAbout = {}; 2885 2886 for (var key in expandedUpdates) { 2887 var originalKey = expandedUpdates[key]; 2888 var correctOriginalKey = expandedStyles[key]; 2889 2890 if (correctOriginalKey && originalKey !== correctOriginalKey) { 2891 var warningKey = originalKey + ',' + correctOriginalKey; 2892 2893 if (warnedAbout[warningKey]) { 2894 continue; 2895 } 2896 2897 warnedAbout[warningKey] = true; 2898 2899 error('%s a style property during rerender (%s) when a ' + 'conflicting property is set (%s) can lead to styling bugs. To ' + "avoid this, don't mix shorthand and non-shorthand properties " + 'for the same value; instead, replace the shorthand with ' + 'separate values.', isValueEmpty(styleUpdates[originalKey]) ? 'Removing' : 'Updating', originalKey, correctOriginalKey); 2900 } 2901 } 2902 } 2903} 2904 2905// For HTML, certain tags should omit their close tag. We keep a list for 2906// those special-case tags. 2907var omittedCloseTags = { 2908 area: true, 2909 base: true, 2910 br: true, 2911 col: true, 2912 embed: true, 2913 hr: true, 2914 img: true, 2915 input: true, 2916 keygen: true, 2917 link: true, 2918 meta: true, 2919 param: true, 2920 source: true, 2921 track: true, 2922 wbr: true // NOTE: menuitem's close tag should be omitted, but that causes problems. 2923 2924}; 2925 2926// `omittedCloseTags` except that `menuitem` should still have its closing tag. 2927 2928var voidElementTags = assign({ 2929 menuitem: true 2930}, omittedCloseTags); 2931 2932var HTML = '__html'; 2933 2934function assertValidProps(tag, props) { 2935 if (!props) { 2936 return; 2937 } // Note the use of `==` which checks for null or undefined. 2938 2939 2940 if (voidElementTags[tag]) { 2941 if (props.children != null || props.dangerouslySetInnerHTML != null) { 2942 throw new Error(tag + " is a void element tag and must neither have `children` nor " + 'use `dangerouslySetInnerHTML`.'); 2943 } 2944 } 2945 2946 if (props.dangerouslySetInnerHTML != null) { 2947 if (props.children != null) { 2948 throw new Error('Can only set one of `children` or `props.dangerouslySetInnerHTML`.'); 2949 } 2950 2951 if (typeof props.dangerouslySetInnerHTML !== 'object' || !(HTML in props.dangerouslySetInnerHTML)) { 2952 throw new Error('`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://reactjs.org/link/dangerously-set-inner-html ' + 'for more information.'); 2953 } 2954 } 2955 2956 { 2957 if (!props.suppressContentEditableWarning && props.contentEditable && props.children != null) { 2958 error('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.'); 2959 } 2960 } 2961 2962 if (props.style != null && typeof props.style !== 'object') { 2963 throw new Error('The `style` prop expects a mapping from style properties to values, ' + "not a string. For example, style={{marginRight: spacing + 'em'}} when " + 'using JSX.'); 2964 } 2965} 2966 2967function isCustomComponent(tagName, props) { 2968 if (tagName.indexOf('-') === -1) { 2969 return typeof props.is === 'string'; 2970 } 2971 2972 switch (tagName) { 2973 // These are reserved SVG and MathML elements. 2974 // We don't mind this list too much because we expect it to never grow. 2975 // The alternative is to track the namespace in a few places which is convoluted. 2976 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts 2977 case 'annotation-xml': 2978 case 'color-profile': 2979 case 'font-face': 2980 case 'font-face-src': 2981 case 'font-face-uri': 2982 case 'font-face-format': 2983 case 'font-face-name': 2984 case 'missing-glyph': 2985 return false; 2986 2987 default: 2988 return true; 2989 } 2990} 2991 2992// When adding attributes to the HTML or SVG allowed attribute list, be sure to 2993// also add them to this module to ensure casing and incorrect name 2994// warnings. 2995var possibleStandardNames = { 2996 // HTML 2997 accept: 'accept', 2998 acceptcharset: 'acceptCharset', 2999 'accept-charset': 'acceptCharset', 3000 accesskey: 'accessKey', 3001 action: 'action', 3002 allowfullscreen: 'allowFullScreen', 3003 alt: 'alt', 3004 as: 'as', 3005 async: 'async', 3006 autocapitalize: 'autoCapitalize', 3007 autocomplete: 'autoComplete', 3008 autocorrect: 'autoCorrect', 3009 autofocus: 'autoFocus', 3010 autoplay: 'autoPlay', 3011 autosave: 'autoSave', 3012 capture: 'capture', 3013 cellpadding: 'cellPadding', 3014 cellspacing: 'cellSpacing', 3015 challenge: 'challenge', 3016 charset: 'charSet', 3017 checked: 'checked', 3018 children: 'children', 3019 cite: 'cite', 3020 class: 'className', 3021 classid: 'classID', 3022 classname: 'className', 3023 cols: 'cols', 3024 colspan: 'colSpan', 3025 content: 'content', 3026 contenteditable: 'contentEditable', 3027 contextmenu: 'contextMenu', 3028 controls: 'controls', 3029 controlslist: 'controlsList', 3030 coords: 'coords', 3031 crossorigin: 'crossOrigin', 3032 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML', 3033 data: 'data', 3034 datetime: 'dateTime', 3035 default: 'default', 3036 defaultchecked: 'defaultChecked', 3037 defaultvalue: 'defaultValue', 3038 defer: 'defer', 3039 dir: 'dir', 3040 disabled: 'disabled', 3041 disablepictureinpicture: 'disablePictureInPicture', 3042 disableremoteplayback: 'disableRemotePlayback', 3043 download: 'download', 3044 draggable: 'draggable', 3045 enctype: 'encType', 3046 enterkeyhint: 'enterKeyHint', 3047 for: 'htmlFor', 3048 form: 'form', 3049 formmethod: 'formMethod', 3050 formaction: 'formAction', 3051 formenctype: 'formEncType', 3052 formnovalidate: 'formNoValidate', 3053 formtarget: 'formTarget', 3054 frameborder: 'frameBorder', 3055 headers: 'headers', 3056 height: 'height', 3057 hidden: 'hidden', 3058 high: 'high', 3059 href: 'href', 3060 hreflang: 'hrefLang', 3061 htmlfor: 'htmlFor', 3062 httpequiv: 'httpEquiv', 3063 'http-equiv': 'httpEquiv', 3064 icon: 'icon', 3065 id: 'id', 3066 imagesizes: 'imageSizes', 3067 imagesrcset: 'imageSrcSet', 3068 innerhtml: 'innerHTML', 3069 inputmode: 'inputMode', 3070 integrity: 'integrity', 3071 is: 'is', 3072 itemid: 'itemID', 3073 itemprop: 'itemProp', 3074 itemref: 'itemRef', 3075 itemscope: 'itemScope', 3076 itemtype: 'itemType', 3077 keyparams: 'keyParams', 3078 keytype: 'keyType', 3079 kind: 'kind', 3080 label: 'label', 3081 lang: 'lang', 3082 list: 'list', 3083 loop: 'loop', 3084 low: 'low', 3085 manifest: 'manifest', 3086 marginwidth: 'marginWidth', 3087 marginheight: 'marginHeight', 3088 max: 'max', 3089 maxlength: 'maxLength', 3090 media: 'media', 3091 mediagroup: 'mediaGroup', 3092 method: 'method', 3093 min: 'min', 3094 minlength: 'minLength', 3095 multiple: 'multiple', 3096 muted: 'muted', 3097 name: 'name', 3098 nomodule: 'noModule', 3099 nonce: 'nonce', 3100 novalidate: 'noValidate', 3101 open: 'open', 3102 optimum: 'optimum', 3103 pattern: 'pattern', 3104 placeholder: 'placeholder', 3105 playsinline: 'playsInline', 3106 poster: 'poster', 3107 preload: 'preload', 3108 profile: 'profile', 3109 radiogroup: 'radioGroup', 3110 readonly: 'readOnly', 3111 referrerpolicy: 'referrerPolicy', 3112 rel: 'rel', 3113 required: 'required', 3114 reversed: 'reversed', 3115 role: 'role', 3116 rows: 'rows', 3117 rowspan: 'rowSpan', 3118 sandbox: 'sandbox', 3119 scope: 'scope', 3120 scoped: 'scoped', 3121 scrolling: 'scrolling', 3122 seamless: 'seamless', 3123 selected: 'selected', 3124 shape: 'shape', 3125 size: 'size', 3126 sizes: 'sizes', 3127 span: 'span', 3128 spellcheck: 'spellCheck', 3129 src: 'src', 3130 srcdoc: 'srcDoc', 3131 srclang: 'srcLang', 3132 srcset: 'srcSet', 3133 start: 'start', 3134 step: 'step', 3135 style: 'style', 3136 summary: 'summary', 3137 tabindex: 'tabIndex', 3138 target: 'target', 3139 title: 'title', 3140 type: 'type', 3141 usemap: 'useMap', 3142 value: 'value', 3143 width: 'width', 3144 wmode: 'wmode', 3145 wrap: 'wrap', 3146 // SVG 3147 about: 'about', 3148 accentheight: 'accentHeight', 3149 'accent-height': 'accentHeight', 3150 accumulate: 'accumulate', 3151 additive: 'additive', 3152 alignmentbaseline: 'alignmentBaseline', 3153 'alignment-baseline': 'alignmentBaseline', 3154 allowreorder: 'allowReorder', 3155 alphabetic: 'alphabetic', 3156 amplitude: 'amplitude', 3157 arabicform: 'arabicForm', 3158 'arabic-form': 'arabicForm', 3159 ascent: 'ascent', 3160 attributename: 'attributeName', 3161 attributetype: 'attributeType', 3162 autoreverse: 'autoReverse', 3163 azimuth: 'azimuth', 3164 basefrequency: 'baseFrequency', 3165 baselineshift: 'baselineShift', 3166 'baseline-shift': 'baselineShift', 3167 baseprofile: 'baseProfile', 3168 bbox: 'bbox', 3169 begin: 'begin', 3170 bias: 'bias', 3171 by: 'by', 3172 calcmode: 'calcMode', 3173 capheight: 'capHeight', 3174 'cap-height': 'capHeight', 3175 clip: 'clip', 3176 clippath: 'clipPath', 3177 'clip-path': 'clipPath', 3178 clippathunits: 'clipPathUnits', 3179 cliprule: 'clipRule', 3180 'clip-rule': 'clipRule', 3181 color: 'color', 3182 colorinterpolation: 'colorInterpolation', 3183 'color-interpolation': 'colorInterpolation', 3184 colorinterpolationfilters: 'colorInterpolationFilters', 3185 'color-interpolation-filters': 'colorInterpolationFilters', 3186 colorprofile: 'colorProfile', 3187 'color-profile': 'colorProfile', 3188 colorrendering: 'colorRendering', 3189 'color-rendering': 'colorRendering', 3190 contentscripttype: 'contentScriptType', 3191 contentstyletype: 'contentStyleType', 3192 cursor: 'cursor', 3193 cx: 'cx', 3194 cy: 'cy', 3195 d: 'd', 3196 datatype: 'datatype', 3197 decelerate: 'decelerate', 3198 descent: 'descent', 3199 diffuseconstant: 'diffuseConstant', 3200 direction: 'direction', 3201 display: 'display', 3202 divisor: 'divisor', 3203 dominantbaseline: 'dominantBaseline', 3204 'dominant-baseline': 'dominantBaseline', 3205 dur: 'dur', 3206 dx: 'dx', 3207 dy: 'dy', 3208 edgemode: 'edgeMode', 3209 elevation: 'elevation', 3210 enablebackground: 'enableBackground', 3211 'enable-background': 'enableBackground', 3212 end: 'end', 3213 exponent: 'exponent', 3214 externalresourcesrequired: 'externalResourcesRequired', 3215 fill: 'fill', 3216 fillopacity: 'fillOpacity', 3217 'fill-opacity': 'fillOpacity', 3218 fillrule: 'fillRule', 3219 'fill-rule': 'fillRule', 3220 filter: 'filter', 3221 filterres: 'filterRes', 3222 filterunits: 'filterUnits', 3223 floodopacity: 'floodOpacity', 3224 'flood-opacity': 'floodOpacity', 3225 floodcolor: 'floodColor', 3226 'flood-color': 'floodColor', 3227 focusable: 'focusable', 3228 fontfamily: 'fontFamily', 3229 'font-family': 'fontFamily', 3230 fontsize: 'fontSize', 3231 'font-size': 'fontSize', 3232 fontsizeadjust: 'fontSizeAdjust', 3233 'font-size-adjust': 'fontSizeAdjust', 3234 fontstretch: 'fontStretch', 3235 'font-stretch': 'fontStretch', 3236 fontstyle: 'fontStyle', 3237 'font-style': 'fontStyle', 3238 fontvariant: 'fontVariant', 3239 'font-variant': 'fontVariant', 3240 fontweight: 'fontWeight', 3241 'font-weight': 'fontWeight', 3242 format: 'format', 3243 from: 'from', 3244 fx: 'fx', 3245 fy: 'fy', 3246 g1: 'g1', 3247 g2: 'g2', 3248 glyphname: 'glyphName', 3249 'glyph-name': 'glyphName', 3250 glyphorientationhorizontal: 'glyphOrientationHorizontal', 3251 'glyph-orientation-horizontal': 'glyphOrientationHorizontal', 3252 glyphorientationvertical: 'glyphOrientationVertical', 3253 'glyph-orientation-vertical': 'glyphOrientationVertical', 3254 glyphref: 'glyphRef', 3255 gradienttransform: 'gradientTransform', 3256 gradientunits: 'gradientUnits', 3257 hanging: 'hanging', 3258 horizadvx: 'horizAdvX', 3259 'horiz-adv-x': 'horizAdvX', 3260 horizoriginx: 'horizOriginX', 3261 'horiz-origin-x': 'horizOriginX', 3262 ideographic: 'ideographic', 3263 imagerendering: 'imageRendering', 3264 'image-rendering': 'imageRendering', 3265 in2: 'in2', 3266 in: 'in', 3267 inlist: 'inlist', 3268 intercept: 'intercept', 3269 k1: 'k1', 3270 k2: 'k2', 3271 k3: 'k3', 3272 k4: 'k4', 3273 k: 'k', 3274 kernelmatrix: 'kernelMatrix', 3275 kernelunitlength: 'kernelUnitLength', 3276 kerning: 'kerning', 3277 keypoints: 'keyPoints', 3278 keysplines: 'keySplines', 3279 keytimes: 'keyTimes', 3280 lengthadjust: 'lengthAdjust', 3281 letterspacing: 'letterSpacing', 3282 'letter-spacing': 'letterSpacing', 3283 lightingcolor: 'lightingColor', 3284 'lighting-color': 'lightingColor', 3285 limitingconeangle: 'limitingConeAngle', 3286 local: 'local', 3287 markerend: 'markerEnd', 3288 'marker-end': 'markerEnd', 3289 markerheight: 'markerHeight', 3290 markermid: 'markerMid', 3291 'marker-mid': 'markerMid', 3292 markerstart: 'markerStart', 3293 'marker-start': 'markerStart', 3294 markerunits: 'markerUnits', 3295 markerwidth: 'markerWidth', 3296 mask: 'mask', 3297 maskcontentunits: 'maskContentUnits', 3298 maskunits: 'maskUnits', 3299 mathematical: 'mathematical', 3300 mode: 'mode', 3301 numoctaves: 'numOctaves', 3302 offset: 'offset', 3303 opacity: 'opacity', 3304 operator: 'operator', 3305 order: 'order', 3306 orient: 'orient', 3307 orientation: 'orientation', 3308 origin: 'origin', 3309 overflow: 'overflow', 3310 overlineposition: 'overlinePosition', 3311 'overline-position': 'overlinePosition', 3312 overlinethickness: 'overlineThickness', 3313 'overline-thickness': 'overlineThickness', 3314 paintorder: 'paintOrder', 3315 'paint-order': 'paintOrder', 3316 panose1: 'panose1', 3317 'panose-1': 'panose1', 3318 pathlength: 'pathLength', 3319 patterncontentunits: 'patternContentUnits', 3320 patterntransform: 'patternTransform', 3321 patternunits: 'patternUnits', 3322 pointerevents: 'pointerEvents', 3323 'pointer-events': 'pointerEvents', 3324 points: 'points', 3325 pointsatx: 'pointsAtX', 3326 pointsaty: 'pointsAtY', 3327 pointsatz: 'pointsAtZ', 3328 prefix: 'prefix', 3329 preservealpha: 'preserveAlpha', 3330 preserveaspectratio: 'preserveAspectRatio', 3331 primitiveunits: 'primitiveUnits', 3332 property: 'property', 3333 r: 'r', 3334 radius: 'radius', 3335 refx: 'refX', 3336 refy: 'refY', 3337 renderingintent: 'renderingIntent', 3338 'rendering-intent': 'renderingIntent', 3339 repeatcount: 'repeatCount', 3340 repeatdur: 'repeatDur', 3341 requiredextensions: 'requiredExtensions', 3342 requiredfeatures: 'requiredFeatures', 3343 resource: 'resource', 3344 restart: 'restart', 3345 result: 'result', 3346 results: 'results', 3347 rotate: 'rotate', 3348 rx: 'rx', 3349 ry: 'ry', 3350 scale: 'scale', 3351 security: 'security', 3352 seed: 'seed', 3353 shaperendering: 'shapeRendering', 3354 'shape-rendering': 'shapeRendering', 3355 slope: 'slope', 3356 spacing: 'spacing', 3357 specularconstant: 'specularConstant', 3358 specularexponent: 'specularExponent', 3359 speed: 'speed', 3360 spreadmethod: 'spreadMethod', 3361 startoffset: 'startOffset', 3362 stddeviation: 'stdDeviation', 3363 stemh: 'stemh', 3364 stemv: 'stemv', 3365 stitchtiles: 'stitchTiles', 3366 stopcolor: 'stopColor', 3367 'stop-color': 'stopColor', 3368 stopopacity: 'stopOpacity', 3369 'stop-opacity': 'stopOpacity', 3370 strikethroughposition: 'strikethroughPosition', 3371 'strikethrough-position': 'strikethroughPosition', 3372 strikethroughthickness: 'strikethroughThickness', 3373 'strikethrough-thickness': 'strikethroughThickness', 3374 string: 'string', 3375 stroke: 'stroke', 3376 strokedasharray: 'strokeDasharray', 3377 'stroke-dasharray': 'strokeDasharray', 3378 strokedashoffset: 'strokeDashoffset', 3379 'stroke-dashoffset': 'strokeDashoffset', 3380 strokelinecap: 'strokeLinecap', 3381 'stroke-linecap': 'strokeLinecap', 3382 strokelinejoin: 'strokeLinejoin', 3383 'stroke-linejoin': 'strokeLinejoin', 3384 strokemiterlimit: 'strokeMiterlimit', 3385 'stroke-miterlimit': 'strokeMiterlimit', 3386 strokewidth: 'strokeWidth', 3387 'stroke-width': 'strokeWidth', 3388 strokeopacity: 'strokeOpacity', 3389 'stroke-opacity': 'strokeOpacity', 3390 suppresscontenteditablewarning: 'suppressContentEditableWarning', 3391 suppresshydrationwarning: 'suppressHydrationWarning', 3392 surfacescale: 'surfaceScale', 3393 systemlanguage: 'systemLanguage', 3394 tablevalues: 'tableValues', 3395 targetx: 'targetX', 3396 targety: 'targetY', 3397 textanchor: 'textAnchor', 3398 'text-anchor': 'textAnchor', 3399 textdecoration: 'textDecoration', 3400 'text-decoration': 'textDecoration', 3401 textlength: 'textLength', 3402 textrendering: 'textRendering', 3403 'text-rendering': 'textRendering', 3404 to: 'to', 3405 transform: 'transform', 3406 typeof: 'typeof', 3407 u1: 'u1', 3408 u2: 'u2', 3409 underlineposition: 'underlinePosition', 3410 'underline-position': 'underlinePosition', 3411 underlinethickness: 'underlineThickness', 3412 'underline-thickness': 'underlineThickness', 3413 unicode: 'unicode', 3414 unicodebidi: 'unicodeBidi', 3415 'unicode-bidi': 'unicodeBidi', 3416 unicoderange: 'unicodeRange', 3417 'unicode-range': 'unicodeRange', 3418 unitsperem: 'unitsPerEm', 3419 'units-per-em': 'unitsPerEm', 3420 unselectable: 'unselectable', 3421 valphabetic: 'vAlphabetic', 3422 'v-alphabetic': 'vAlphabetic', 3423 values: 'values', 3424 vectoreffect: 'vectorEffect', 3425 'vector-effect': 'vectorEffect', 3426 version: 'version', 3427 vertadvy: 'vertAdvY', 3428 'vert-adv-y': 'vertAdvY', 3429 vertoriginx: 'vertOriginX', 3430 'vert-origin-x': 'vertOriginX', 3431 vertoriginy: 'vertOriginY', 3432 'vert-origin-y': 'vertOriginY', 3433 vhanging: 'vHanging', 3434 'v-hanging': 'vHanging', 3435 videographic: 'vIdeographic', 3436 'v-ideographic': 'vIdeographic', 3437 viewbox: 'viewBox', 3438 viewtarget: 'viewTarget', 3439 visibility: 'visibility', 3440 vmathematical: 'vMathematical', 3441 'v-mathematical': 'vMathematical', 3442 vocab: 'vocab', 3443 widths: 'widths', 3444 wordspacing: 'wordSpacing', 3445 'word-spacing': 'wordSpacing', 3446 writingmode: 'writingMode', 3447 'writing-mode': 'writingMode', 3448 x1: 'x1', 3449 x2: 'x2', 3450 x: 'x', 3451 xchannelselector: 'xChannelSelector', 3452 xheight: 'xHeight', 3453 'x-height': 'xHeight', 3454 xlinkactuate: 'xlinkActuate', 3455 'xlink:actuate': 'xlinkActuate', 3456 xlinkarcrole: 'xlinkArcrole', 3457 'xlink:arcrole': 'xlinkArcrole', 3458 xlinkhref: 'xlinkHref', 3459 'xlink:href': 'xlinkHref', 3460 xlinkrole: 'xlinkRole', 3461 'xlink:role': 'xlinkRole', 3462 xlinkshow: 'xlinkShow', 3463 'xlink:show': 'xlinkShow', 3464 xlinktitle: 'xlinkTitle', 3465 'xlink:title': 'xlinkTitle', 3466 xlinktype: 'xlinkType', 3467 'xlink:type': 'xlinkType', 3468 xmlbase: 'xmlBase', 3469 'xml:base': 'xmlBase', 3470 xmllang: 'xmlLang', 3471 'xml:lang': 'xmlLang', 3472 xmlns: 'xmlns', 3473 'xml:space': 'xmlSpace', 3474 xmlnsxlink: 'xmlnsXlink', 3475 'xmlns:xlink': 'xmlnsXlink', 3476 xmlspace: 'xmlSpace', 3477 y1: 'y1', 3478 y2: 'y2', 3479 y: 'y', 3480 ychannelselector: 'yChannelSelector', 3481 z: 'z', 3482 zoomandpan: 'zoomAndPan' 3483}; 3484 3485var ariaProperties = { 3486 'aria-current': 0, 3487 // state 3488 'aria-description': 0, 3489 'aria-details': 0, 3490 'aria-disabled': 0, 3491 // state 3492 'aria-hidden': 0, 3493 // state 3494 'aria-invalid': 0, 3495 // state 3496 'aria-keyshortcuts': 0, 3497 'aria-label': 0, 3498 'aria-roledescription': 0, 3499 // Widget Attributes 3500 'aria-autocomplete': 0, 3501 'aria-checked': 0, 3502 'aria-expanded': 0, 3503 'aria-haspopup': 0, 3504 'aria-level': 0, 3505 'aria-modal': 0, 3506 'aria-multiline': 0, 3507 'aria-multiselectable': 0, 3508 'aria-orientation': 0, 3509 'aria-placeholder': 0, 3510 'aria-pressed': 0, 3511 'aria-readonly': 0, 3512 'aria-required': 0, 3513 'aria-selected': 0, 3514 'aria-sort': 0, 3515 'aria-valuemax': 0, 3516 'aria-valuemin': 0, 3517 'aria-valuenow': 0, 3518 'aria-valuetext': 0, 3519 // Live Region Attributes 3520 'aria-atomic': 0, 3521 'aria-busy': 0, 3522 'aria-live': 0, 3523 'aria-relevant': 0, 3524 // Drag-and-Drop Attributes 3525 'aria-dropeffect': 0, 3526 'aria-grabbed': 0, 3527 // Relationship Attributes 3528 'aria-activedescendant': 0, 3529 'aria-colcount': 0, 3530 'aria-colindex': 0, 3531 'aria-colspan': 0, 3532 'aria-controls': 0, 3533 'aria-describedby': 0, 3534 'aria-errormessage': 0, 3535 'aria-flowto': 0, 3536 'aria-labelledby': 0, 3537 'aria-owns': 0, 3538 'aria-posinset': 0, 3539 'aria-rowcount': 0, 3540 'aria-rowindex': 0, 3541 'aria-rowspan': 0, 3542 'aria-setsize': 0 3543}; 3544 3545var warnedProperties = {}; 3546var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$'); 3547var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$'); 3548 3549function validateProperty(tagName, name) { 3550 { 3551 if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) { 3552 return true; 3553 } 3554 3555 if (rARIACamel.test(name)) { 3556 var ariaName = 'aria-' + name.slice(4).toLowerCase(); 3557 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; // If this is an aria-* attribute, but is not listed in the known DOM 3558 // DOM properties, then it is an invalid aria-* attribute. 3559 3560 if (correctName == null) { 3561 error('Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name); 3562 3563 warnedProperties[name] = true; 3564 return true; 3565 } // aria-* attributes should be lowercase; suggest the lowercase version. 3566 3567 3568 if (name !== correctName) { 3569 error('Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName); 3570 3571 warnedProperties[name] = true; 3572 return true; 3573 } 3574 } 3575 3576 if (rARIA.test(name)) { 3577 var lowerCasedName = name.toLowerCase(); 3578 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; // If this is an aria-* attribute, but is not listed in the known DOM 3579 // DOM properties, then it is an invalid aria-* attribute. 3580 3581 if (standardName == null) { 3582 warnedProperties[name] = true; 3583 return false; 3584 } // aria-* attributes should be lowercase; suggest the lowercase version. 3585 3586 3587 if (name !== standardName) { 3588 error('Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName); 3589 3590 warnedProperties[name] = true; 3591 return true; 3592 } 3593 } 3594 } 3595 3596 return true; 3597} 3598 3599function warnInvalidARIAProps(type, props) { 3600 { 3601 var invalidProps = []; 3602 3603 for (var key in props) { 3604 var isValid = validateProperty(type, key); 3605 3606 if (!isValid) { 3607 invalidProps.push(key); 3608 } 3609 } 3610 3611 var unknownPropString = invalidProps.map(function (prop) { 3612 return '`' + prop + '`'; 3613 }).join(', '); 3614 3615 if (invalidProps.length === 1) { 3616 error('Invalid aria prop %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type); 3617 } else if (invalidProps.length > 1) { 3618 error('Invalid aria props %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type); 3619 } 3620 } 3621} 3622 3623function validateProperties(type, props) { 3624 if (isCustomComponent(type, props)) { 3625 return; 3626 } 3627 3628 warnInvalidARIAProps(type, props); 3629} 3630 3631var didWarnValueNull = false; 3632function validateProperties$1(type, props) { 3633 { 3634 if (type !== 'input' && type !== 'textarea' && type !== 'select') { 3635 return; 3636 } 3637 3638 if (props != null && props.value === null && !didWarnValueNull) { 3639 didWarnValueNull = true; 3640 3641 if (type === 'select' && props.multiple) { 3642 error('`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); 3643 } else { 3644 error('`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type); 3645 } 3646 } 3647 } 3648} 3649 3650var validateProperty$1 = function () {}; 3651 3652{ 3653 var warnedProperties$1 = {}; 3654 var EVENT_NAME_REGEX = /^on./; 3655 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/; 3656 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$'); 3657 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$'); 3658 3659 validateProperty$1 = function (tagName, name, value, eventRegistry) { 3660 if (hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) { 3661 return true; 3662 } 3663 3664 var lowerCasedName = name.toLowerCase(); 3665 3666 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') { 3667 error('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.'); 3668 3669 warnedProperties$1[name] = true; 3670 return true; 3671 } // We can't rely on the event system being injected on the server. 3672 3673 3674 if (eventRegistry != null) { 3675 var registrationNameDependencies = eventRegistry.registrationNameDependencies, 3676 possibleRegistrationNames = eventRegistry.possibleRegistrationNames; 3677 3678 if (registrationNameDependencies.hasOwnProperty(name)) { 3679 return true; 3680 } 3681 3682 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null; 3683 3684 if (registrationName != null) { 3685 error('Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName); 3686 3687 warnedProperties$1[name] = true; 3688 return true; 3689 } 3690 3691 if (EVENT_NAME_REGEX.test(name)) { 3692 error('Unknown event handler property `%s`. It will be ignored.', name); 3693 3694 warnedProperties$1[name] = true; 3695 return true; 3696 } 3697 } else if (EVENT_NAME_REGEX.test(name)) { 3698 // If no event plugins have been injected, we are in a server environment. 3699 // So we can't tell if the event name is correct for sure, but we can filter 3700 // out known bad ones like `onclick`. We can't suggest a specific replacement though. 3701 if (INVALID_EVENT_NAME_REGEX.test(name)) { 3702 error('Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name); 3703 } 3704 3705 warnedProperties$1[name] = true; 3706 return true; 3707 } // Let the ARIA attribute hook validate ARIA attributes 3708 3709 3710 if (rARIA$1.test(name) || rARIACamel$1.test(name)) { 3711 return true; 3712 } 3713 3714 if (lowerCasedName === 'innerhtml') { 3715 error('Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.'); 3716 3717 warnedProperties$1[name] = true; 3718 return true; 3719 } 3720 3721 if (lowerCasedName === 'aria') { 3722 error('The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.'); 3723 3724 warnedProperties$1[name] = true; 3725 return true; 3726 } 3727 3728 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') { 3729 error('Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value); 3730 3731 warnedProperties$1[name] = true; 3732 return true; 3733 } 3734 3735 if (typeof value === 'number' && isNaN(value)) { 3736 error('Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name); 3737 3738 warnedProperties$1[name] = true; 3739 return true; 3740 } 3741 3742 var propertyInfo = getPropertyInfo(name); 3743 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED; // Known attributes should match the casing specified in the property config. 3744 3745 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) { 3746 var standardName = possibleStandardNames[lowerCasedName]; 3747 3748 if (standardName !== name) { 3749 error('Invalid DOM property `%s`. Did you mean `%s`?', name, standardName); 3750 3751 warnedProperties$1[name] = true; 3752 return true; 3753 } 3754 } else if (!isReserved && name !== lowerCasedName) { 3755 // Unknown attributes should have lowercase casing since that's how they 3756 // will be cased anyway with server rendering. 3757 error('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); 3758 3759 warnedProperties$1[name] = true; 3760 return true; 3761 } 3762 3763 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) { 3764 if (value) { 3765 error('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); 3766 } else { 3767 error('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); 3768 } 3769 3770 warnedProperties$1[name] = true; 3771 return true; 3772 } // Now that we've validated casing, do not validate 3773 // data types for reserved props 3774 3775 3776 if (isReserved) { 3777 return true; 3778 } // Warn when a known attribute is a bad type 3779 3780 3781 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) { 3782 warnedProperties$1[name] = true; 3783 return false; 3784 } // Warn when passing the strings 'false' or 'true' into a boolean prop 3785 3786 3787 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) { 3788 error('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); 3789 3790 warnedProperties$1[name] = true; 3791 return true; 3792 } 3793 3794 return true; 3795 }; 3796} 3797 3798var warnUnknownProperties = function (type, props, eventRegistry) { 3799 { 3800 var unknownProps = []; 3801 3802 for (var key in props) { 3803 var isValid = validateProperty$1(type, key, props[key], eventRegistry); 3804 3805 if (!isValid) { 3806 unknownProps.push(key); 3807 } 3808 } 3809 3810 var unknownPropString = unknownProps.map(function (prop) { 3811 return '`' + prop + '`'; 3812 }).join(', '); 3813 3814 if (unknownProps.length === 1) { 3815 error('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://reactjs.org/link/attribute-behavior ', unknownPropString, type); 3816 } else if (unknownProps.length > 1) { 3817 error('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://reactjs.org/link/attribute-behavior ', unknownPropString, type); 3818 } 3819 } 3820}; 3821 3822function validateProperties$2(type, props, eventRegistry) { 3823 if (isCustomComponent(type, props)) { 3824 return; 3825 } 3826 3827 warnUnknownProperties(type, props, eventRegistry); 3828} 3829 3830var IS_EVENT_HANDLE_NON_MANAGED_NODE = 1; 3831var IS_NON_DELEGATED = 1 << 1; 3832var IS_CAPTURE_PHASE = 1 << 2; 3833// set to LEGACY_FB_SUPPORT. LEGACY_FB_SUPPORT only gets set when 3834// we call willDeferLaterForLegacyFBSupport, thus not bailing out 3835// will result in endless cycles like an infinite loop. 3836// We also don't want to defer during event replaying. 3837 3838var SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS = IS_EVENT_HANDLE_NON_MANAGED_NODE | IS_NON_DELEGATED | IS_CAPTURE_PHASE; 3839 3840// This exists to avoid circular dependency between ReactDOMEventReplaying 3841// and DOMPluginEventSystem. 3842var currentReplayingEvent = null; 3843function setReplayingEvent(event) { 3844 { 3845 if (currentReplayingEvent !== null) { 3846 error('Expected currently replaying event to be null. This error ' + 'is likely caused by a bug in React. Please file an issue.'); 3847 } 3848 } 3849 3850 currentReplayingEvent = event; 3851} 3852function resetReplayingEvent() { 3853 { 3854 if (currentReplayingEvent === null) { 3855 error('Expected currently replaying event to not be null. This error ' + 'is likely caused by a bug in React. Please file an issue.'); 3856 } 3857 } 3858 3859 currentReplayingEvent = null; 3860} 3861function isReplayingEvent(event) { 3862 return event === currentReplayingEvent; 3863} 3864 3865/** 3866 * Gets the target node from a native browser event by accounting for 3867 * inconsistencies in browser DOM APIs. 3868 * 3869 * @param {object} nativeEvent Native browser event. 3870 * @return {DOMEventTarget} Target node. 3871 */ 3872 3873function getEventTarget(nativeEvent) { 3874 // Fallback to nativeEvent.srcElement for IE9 3875 // https://github.com/facebook/react/issues/12506 3876 var target = nativeEvent.target || nativeEvent.srcElement || window; // Normalize SVG <use> element events #4963 3877 3878 if (target.correspondingUseElement) { 3879 target = target.correspondingUseElement; 3880 } // Safari may fire events on text nodes (Node.TEXT_NODE is 3). 3881 // @see http://www.quirksmode.org/js/events_properties.html 3882 3883 3884 return target.nodeType === TEXT_NODE ? target.parentNode : target; 3885} 3886 3887var restoreImpl = null; 3888var restoreTarget = null; 3889var restoreQueue = null; 3890 3891function restoreStateOfTarget(target) { 3892 // We perform this translation at the end of the event loop so that we 3893 // always receive the correct fiber here 3894 var internalInstance = getInstanceFromNode(target); 3895 3896 if (!internalInstance) { 3897 // Unmounted 3898 return; 3899 } 3900 3901 if (typeof restoreImpl !== 'function') { 3902 throw new Error('setRestoreImplementation() needs to be called to handle a target for controlled ' + 'events. This error is likely caused by a bug in React. Please file an issue.'); 3903 } 3904 3905 var stateNode = internalInstance.stateNode; // Guard against Fiber being unmounted. 3906 3907 if (stateNode) { 3908 var _props = getFiberCurrentPropsFromNode(stateNode); 3909 3910 restoreImpl(internalInstance.stateNode, internalInstance.type, _props); 3911 } 3912} 3913 3914function setRestoreImplementation(impl) { 3915 restoreImpl = impl; 3916} 3917function enqueueStateRestore(target) { 3918 if (restoreTarget) { 3919 if (restoreQueue) { 3920 restoreQueue.push(target); 3921 } else { 3922 restoreQueue = [target]; 3923 } 3924 } else { 3925 restoreTarget = target; 3926 } 3927} 3928function needsStateRestore() { 3929 return restoreTarget !== null || restoreQueue !== null; 3930} 3931function restoreStateIfNeeded() { 3932 if (!restoreTarget) { 3933 return; 3934 } 3935 3936 var target = restoreTarget; 3937 var queuedTargets = restoreQueue; 3938 restoreTarget = null; 3939 restoreQueue = null; 3940 restoreStateOfTarget(target); 3941 3942 if (queuedTargets) { 3943 for (var i = 0; i < queuedTargets.length; i++) { 3944 restoreStateOfTarget(queuedTargets[i]); 3945 } 3946 } 3947} 3948 3949// the renderer. Such as when we're dispatching events or if third party 3950// libraries need to call batchedUpdates. Eventually, this API will go away when 3951// everything is batched by default. We'll then have a similar API to opt-out of 3952// scheduled work and instead do synchronous work. 3953// Defaults 3954 3955var batchedUpdatesImpl = function (fn, bookkeeping) { 3956 return fn(bookkeeping); 3957}; 3958 3959var flushSyncImpl = function () {}; 3960 3961var isInsideEventHandler = false; 3962 3963function finishEventHandler() { 3964 // Here we wait until all updates have propagated, which is important 3965 // when using controlled components within layers: 3966 // https://github.com/facebook/react/issues/1698 3967 // Then we restore state of any controlled component. 3968 var controlledComponentsHavePendingUpdates = needsStateRestore(); 3969 3970 if (controlledComponentsHavePendingUpdates) { 3971 // If a controlled event was fired, we may need to restore the state of 3972 // the DOM node back to the controlled value. This is necessary when React 3973 // bails out of the update without touching the DOM. 3974 // TODO: Restore state in the microtask, after the discrete updates flush, 3975 // instead of early flushing them here. 3976 flushSyncImpl(); 3977 restoreStateIfNeeded(); 3978 } 3979} 3980 3981function batchedUpdates(fn, a, b) { 3982 if (isInsideEventHandler) { 3983 // If we are currently inside another batch, we need to wait until it 3984 // fully completes before restoring state. 3985 return fn(a, b); 3986 } 3987 3988 isInsideEventHandler = true; 3989 3990 try { 3991 return batchedUpdatesImpl(fn, a, b); 3992 } finally { 3993 isInsideEventHandler = false; 3994 finishEventHandler(); 3995 } 3996} // TODO: Replace with flushSync 3997function setBatchingImplementation(_batchedUpdatesImpl, _discreteUpdatesImpl, _flushSyncImpl) { 3998 batchedUpdatesImpl = _batchedUpdatesImpl; 3999 flushSyncImpl = _flushSyncImpl; 4000} 4001 4002function isInteractive(tag) { 4003 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea'; 4004} 4005 4006function shouldPreventMouseEvent(name, type, props) { 4007 switch (name) { 4008 case 'onClick': 4009 case 'onClickCapture': 4010 case 'onDoubleClick': 4011 case 'onDoubleClickCapture': 4012 case 'onMouseDown': 4013 case 'onMouseDownCapture': 4014 case 'onMouseMove': 4015 case 'onMouseMoveCapture': 4016 case 'onMouseUp': 4017 case 'onMouseUpCapture': 4018 case 'onMouseEnter': 4019 return !!(props.disabled && isInteractive(type)); 4020 4021 default: 4022 return false; 4023 } 4024} 4025/** 4026 * @param {object} inst The instance, which is the source of events. 4027 * @param {string} registrationName Name of listener (e.g. `onClick`). 4028 * @return {?function} The stored callback. 4029 */ 4030 4031 4032function getListener(inst, registrationName) { 4033 var stateNode = inst.stateNode; 4034 4035 if (stateNode === null) { 4036 // Work in progress (ex: onload events in incremental mode). 4037 return null; 4038 } 4039 4040 var props = getFiberCurrentPropsFromNode(stateNode); 4041 4042 if (props === null) { 4043 // Work in progress. 4044 return null; 4045 } 4046 4047 var listener = props[registrationName]; 4048 4049 if (shouldPreventMouseEvent(registrationName, inst.type, props)) { 4050 return null; 4051 } 4052 4053 if (listener && typeof listener !== 'function') { 4054 throw new Error("Expected `" + registrationName + "` listener to be a function, instead got a value of `" + typeof listener + "` type."); 4055 } 4056 4057 return listener; 4058} 4059 4060var passiveBrowserEventsSupported = false; // Check if browser support events with passive listeners 4061// https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support 4062 4063if (canUseDOM) { 4064 try { 4065 var options = {}; // $FlowFixMe: Ignore Flow complaining about needing a value 4066 4067 Object.defineProperty(options, 'passive', { 4068 get: function () { 4069 passiveBrowserEventsSupported = true; 4070 } 4071 }); 4072 window.addEventListener('test', options, options); 4073 window.removeEventListener('test', options, options); 4074 } catch (e) { 4075 passiveBrowserEventsSupported = false; 4076 } 4077} 4078 4079function invokeGuardedCallbackProd(name, func, context, a, b, c, d, e, f) { 4080 var funcArgs = Array.prototype.slice.call(arguments, 3); 4081 4082 try { 4083 func.apply(context, funcArgs); 4084 } catch (error) { 4085 this.onError(error); 4086 } 4087} 4088 4089var invokeGuardedCallbackImpl = invokeGuardedCallbackProd; 4090 4091{ 4092 // In DEV mode, we swap out invokeGuardedCallback for a special version 4093 // that plays more nicely with the browser's DevTools. The idea is to preserve 4094 // "Pause on exceptions" behavior. Because React wraps all user-provided 4095 // functions in invokeGuardedCallback, and the production version of 4096 // invokeGuardedCallback uses a try-catch, all user exceptions are treated 4097 // like caught exceptions, and the DevTools won't pause unless the developer 4098 // takes the extra step of enabling pause on caught exceptions. This is 4099 // unintuitive, though, because even though React has caught the error, from 4100 // the developer's perspective, the error is uncaught. 4101 // 4102 // To preserve the expected "Pause on exceptions" behavior, we don't use a 4103 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake 4104 // DOM node, and call the user-provided callback from inside an event handler 4105 // for that fake event. If the callback throws, the error is "captured" using 4106 // a global event handler. But because the error happens in a different 4107 // event loop context, it does not interrupt the normal program flow. 4108 // Effectively, this gives us try-catch behavior without actually using 4109 // try-catch. Neat! 4110 // Check that the browser supports the APIs we need to implement our special 4111 // DEV version of invokeGuardedCallback 4112 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') { 4113 var fakeNode = document.createElement('react'); 4114 4115 invokeGuardedCallbackImpl = function invokeGuardedCallbackDev(name, func, context, a, b, c, d, e, f) { 4116 // If document doesn't exist we know for sure we will crash in this method 4117 // when we call document.createEvent(). However this can cause confusing 4118 // errors: https://github.com/facebook/create-react-app/issues/3482 4119 // So we preemptively throw with a better message instead. 4120 if (typeof document === 'undefined' || document === null) { 4121 throw new Error('The `document` global was defined when React was initialized, but is not ' + 'defined anymore. This can happen in a test environment if a component ' + 'schedules an update from an asynchronous callback, but the test has already ' + 'finished running. To solve this, you can either unmount the component at ' + 'the end of your test (and ensure that any asynchronous operations get ' + 'canceled in `componentWillUnmount`), or you can change the test itself ' + 'to be asynchronous.'); 4122 } 4123 4124 var evt = document.createEvent('Event'); 4125 var didCall = false; // Keeps track of whether the user-provided callback threw an error. We 4126 // set this to true at the beginning, then set it to false right after 4127 // calling the function. If the function errors, `didError` will never be 4128 // set to false. This strategy works even if the browser is flaky and 4129 // fails to call our global error handler, because it doesn't rely on 4130 // the error event at all. 4131 4132 var didError = true; // Keeps track of the value of window.event so that we can reset it 4133 // during the callback to let user code access window.event in the 4134 // browsers that support it. 4135 4136 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event 4137 // dispatching: https://github.com/facebook/react/issues/13688 4138 4139 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event'); 4140 4141 function restoreAfterDispatch() { 4142 // We immediately remove the callback from event listeners so that 4143 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a 4144 // nested call would trigger the fake event handlers of any call higher 4145 // in the stack. 4146 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the 4147 // window.event assignment in both IE <= 10 as they throw an error 4148 // "Member not found" in strict mode, and in Firefox which does not 4149 // support window.event. 4150 4151 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) { 4152 window.event = windowEvent; 4153 } 4154 } // Create an event handler for our fake event. We will synchronously 4155 // dispatch our fake event using `dispatchEvent`. Inside the handler, we 4156 // call the user-provided callback. 4157 4158 4159 var funcArgs = Array.prototype.slice.call(arguments, 3); 4160 4161 function callCallback() { 4162 didCall = true; 4163 restoreAfterDispatch(); 4164 func.apply(context, funcArgs); 4165 didError = false; 4166 } // Create a global error event handler. We use this to capture the value 4167 // that was thrown. It's possible that this error handler will fire more 4168 // than once; for example, if non-React code also calls `dispatchEvent` 4169 // and a handler for that event throws. We should be resilient to most of 4170 // those cases. Even if our error event handler fires more than once, the 4171 // last error event is always used. If the callback actually does error, 4172 // we know that the last error event is the correct one, because it's not 4173 // possible for anything else to have happened in between our callback 4174 // erroring and the code that follows the `dispatchEvent` call below. If 4175 // the callback doesn't error, but the error event was fired, we know to 4176 // ignore it because `didError` will be false, as described above. 4177 4178 4179 var error; // Use this to track whether the error event is ever called. 4180 4181 var didSetError = false; 4182 var isCrossOriginError = false; 4183 4184 function handleWindowError(event) { 4185 error = event.error; 4186 didSetError = true; 4187 4188 if (error === null && event.colno === 0 && event.lineno === 0) { 4189 isCrossOriginError = true; 4190 } 4191 4192 if (event.defaultPrevented) { 4193 // Some other error handler has prevented default. 4194 // Browsers silence the error report if this happens. 4195 // We'll remember this to later decide whether to log it or not. 4196 if (error != null && typeof error === 'object') { 4197 try { 4198 error._suppressLogging = true; 4199 } catch (inner) {// Ignore. 4200 } 4201 } 4202 } 4203 } // Create a fake event type. 4204 4205 4206 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers 4207 4208 window.addEventListener('error', handleWindowError); 4209 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function 4210 // errors, it will trigger our global error handler. 4211 4212 evt.initEvent(evtType, false, false); 4213 fakeNode.dispatchEvent(evt); 4214 4215 if (windowEventDescriptor) { 4216 Object.defineProperty(window, 'event', windowEventDescriptor); 4217 } 4218 4219 if (didCall && didError) { 4220 if (!didSetError) { 4221 // The callback errored, but the error event never fired. 4222 // eslint-disable-next-line react-internal/prod-error-codes 4223 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.'); 4224 } else if (isCrossOriginError) { 4225 // eslint-disable-next-line react-internal/prod-error-codes 4226 error = new Error("A cross-origin error was thrown. React doesn't have access to " + 'the actual error object in development. ' + 'See https://reactjs.org/link/crossorigin-error for more information.'); 4227 } 4228 4229 this.onError(error); 4230 } // Remove our event listeners 4231 4232 4233 window.removeEventListener('error', handleWindowError); 4234 4235 if (!didCall) { 4236 // Something went really wrong, and our event was not dispatched. 4237 // https://github.com/facebook/react/issues/16734 4238 // https://github.com/facebook/react/issues/16585 4239 // Fall back to the production implementation. 4240 restoreAfterDispatch(); 4241 return invokeGuardedCallbackProd.apply(this, arguments); 4242 } 4243 }; 4244 } 4245} 4246 4247var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl; 4248 4249var hasError = false; 4250var caughtError = null; // Used by event system to capture/rethrow the first error. 4251 4252var hasRethrowError = false; 4253var rethrowError = null; 4254var reporter = { 4255 onError: function (error) { 4256 hasError = true; 4257 caughtError = error; 4258 } 4259}; 4260/** 4261 * Call a function while guarding against errors that happens within it. 4262 * Returns an error if it throws, otherwise null. 4263 * 4264 * In production, this is implemented using a try-catch. The reason we don't 4265 * use a try-catch directly is so that we can swap out a different 4266 * implementation in DEV mode. 4267 * 4268 * @param {String} name of the guard to use for logging or debugging 4269 * @param {Function} func The function to invoke 4270 * @param {*} context The context to use when calling the function 4271 * @param {...*} args Arguments for function 4272 */ 4273 4274function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) { 4275 hasError = false; 4276 caughtError = null; 4277 invokeGuardedCallbackImpl$1.apply(reporter, arguments); 4278} 4279/** 4280 * Same as invokeGuardedCallback, but instead of returning an error, it stores 4281 * it in a global so it can be rethrown by `rethrowCaughtError` later. 4282 * TODO: See if caughtError and rethrowError can be unified. 4283 * 4284 * @param {String} name of the guard to use for logging or debugging 4285 * @param {Function} func The function to invoke 4286 * @param {*} context The context to use when calling the function 4287 * @param {...*} args Arguments for function 4288 */ 4289 4290function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) { 4291 invokeGuardedCallback.apply(this, arguments); 4292 4293 if (hasError) { 4294 var error = clearCaughtError(); 4295 4296 if (!hasRethrowError) { 4297 hasRethrowError = true; 4298 rethrowError = error; 4299 } 4300 } 4301} 4302/** 4303 * During execution of guarded functions we will capture the first error which 4304 * we will rethrow to be handled by the top level error handler. 4305 */ 4306 4307function rethrowCaughtError() { 4308 if (hasRethrowError) { 4309 var error = rethrowError; 4310 hasRethrowError = false; 4311 rethrowError = null; 4312 throw error; 4313 } 4314} 4315function hasCaughtError() { 4316 return hasError; 4317} 4318function clearCaughtError() { 4319 if (hasError) { 4320 var error = caughtError; 4321 hasError = false; 4322 caughtError = null; 4323 return error; 4324 } else { 4325 throw new Error('clearCaughtError was called but no error was captured. This error ' + 'is likely caused by a bug in React. Please file an issue.'); 4326 } 4327} 4328 4329/** 4330 * `ReactInstanceMap` maintains a mapping from a public facing stateful 4331 * instance (key) and the internal representation (value). This allows public 4332 * methods to accept the user facing instance as an argument and map them back 4333 * to internal methods. 4334 * 4335 * Note that this module is currently shared and assumed to be stateless. 4336 * If this becomes an actual Map, that will break. 4337 */ 4338function get(key) { 4339 return key._reactInternals; 4340} 4341function has(key) { 4342 return key._reactInternals !== undefined; 4343} 4344function set(key, value) { 4345 key._reactInternals = value; 4346} 4347 4348// Don't change these two values. They're used by React Dev Tools. 4349var NoFlags = 4350/* */ 43510; 4352var PerformedWork = 4353/* */ 43541; // You can change the rest (and add more). 4355 4356var Placement = 4357/* */ 43582; 4359var Update = 4360/* */ 43614; 4362var ChildDeletion = 4363/* */ 436416; 4365var ContentReset = 4366/* */ 436732; 4368var Callback = 4369/* */ 437064; 4371var DidCapture = 4372/* */ 4373128; 4374var ForceClientRender = 4375/* */ 4376256; 4377var Ref = 4378/* */ 4379512; 4380var Snapshot = 4381/* */ 43821024; 4383var Passive = 4384/* */ 43852048; 4386var Hydrating = 4387/* */ 43884096; 4389var Visibility = 4390/* */ 43918192; 4392var StoreConsistency = 4393/* */ 439416384; 4395var LifecycleEffectMask = Passive | Update | Callback | Ref | Snapshot | StoreConsistency; // Union of all commit flags (flags with the lifetime of a particular commit) 4396 4397var HostEffectMask = 4398/* */ 439932767; // These are not really side effects, but we still reuse this field. 4400 4401var Incomplete = 4402/* */ 440332768; 4404var ShouldCapture = 4405/* */ 440665536; 4407var ForceUpdateForLegacySuspense = 4408/* */ 4409131072; 4410var Forked = 4411/* */ 44121048576; // Static tags describe aspects of a fiber that are not specific to a render, 4413// e.g. a fiber uses a passive effect (even if there are no updates on this particular render). 4414// This enables us to defer more work in the unmount case, 4415// since we can defer traversing the tree during layout to look for Passive effects, 4416// and instead rely on the static flag as a signal that there may be cleanup work. 4417 4418var RefStatic = 4419/* */ 44202097152; 4421var LayoutStatic = 4422/* */ 44234194304; 4424var PassiveStatic = 4425/* */ 44268388608; // These flags allow us to traverse to fibers that have effects on mount 4427// without traversing the entire tree after every commit for 4428// double invoking 4429 4430var MountLayoutDev = 4431/* */ 443216777216; 4433var MountPassiveDev = 4434/* */ 443533554432; // Groups of flags that are used in the commit phase to skip over trees that 4436// don't contain effects, by checking subtreeFlags. 4437 4438var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visibility 4439// flag logic (see #20043) 4440Update | Snapshot | ( 0); 4441var MutationMask = Placement | Update | ChildDeletion | ContentReset | Ref | Hydrating | Visibility; 4442var LayoutMask = Update | Callback | Ref | Visibility; // TODO: Split into PassiveMountMask and PassiveUnmountMask 4443 4444var PassiveMask = Passive | ChildDeletion; // Union of tags that don't get reset on clones. 4445// This allows certain concepts to persist without recalculating them, 4446// e.g. whether a subtree contains passive effects or portals. 4447 4448var StaticMask = LayoutStatic | PassiveStatic | RefStatic; 4449 4450var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; 4451function getNearestMountedFiber(fiber) { 4452 var node = fiber; 4453 var nearestMounted = fiber; 4454 4455 if (!fiber.alternate) { 4456 // If there is no alternate, this might be a new tree that isn't inserted 4457 // yet. If it is, then it will have a pending insertion effect on it. 4458 var nextNode = node; 4459 4460 do { 4461 node = nextNode; 4462 4463 if ((node.flags & (Placement | Hydrating)) !== NoFlags) { 4464 // This is an insertion or in-progress hydration. The nearest possible 4465 // mounted fiber is the parent but we need to continue to figure out 4466 // if that one is still mounted. 4467 nearestMounted = node.return; 4468 } 4469 4470 nextNode = node.return; 4471 } while (nextNode); 4472 } else { 4473 while (node.return) { 4474 node = node.return; 4475 } 4476 } 4477 4478 if (node.tag === HostRoot) { 4479 // TODO: Check if this was a nested HostRoot when used with 4480 // renderContainerIntoSubtree. 4481 return nearestMounted; 4482 } // If we didn't hit the root, that means that we're in an disconnected tree 4483 // that has been unmounted. 4484 4485 4486 return null; 4487} 4488function getSuspenseInstanceFromFiber(fiber) { 4489 if (fiber.tag === SuspenseComponent) { 4490 var suspenseState = fiber.memoizedState; 4491 4492 if (suspenseState === null) { 4493 var current = fiber.alternate; 4494 4495 if (current !== null) { 4496 suspenseState = current.memoizedState; 4497 } 4498 } 4499 4500 if (suspenseState !== null) { 4501 return suspenseState.dehydrated; 4502 } 4503 } 4504 4505 return null; 4506} 4507function getContainerFromFiber(fiber) { 4508 return fiber.tag === HostRoot ? fiber.stateNode.containerInfo : null; 4509} 4510function isFiberMounted(fiber) { 4511 return getNearestMountedFiber(fiber) === fiber; 4512} 4513function isMounted(component) { 4514 { 4515 var owner = ReactCurrentOwner.current; 4516 4517 if (owner !== null && owner.tag === ClassComponent) { 4518 var ownerFiber = owner; 4519 var instance = ownerFiber.stateNode; 4520 4521 if (!instance._warnedAboutRefsInRender) { 4522 error('%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.', getComponentNameFromFiber(ownerFiber) || 'A component'); 4523 } 4524 4525 instance._warnedAboutRefsInRender = true; 4526 } 4527 } 4528 4529 var fiber = get(component); 4530 4531 if (!fiber) { 4532 return false; 4533 } 4534 4535 return getNearestMountedFiber(fiber) === fiber; 4536} 4537 4538function assertIsMounted(fiber) { 4539 if (getNearestMountedFiber(fiber) !== fiber) { 4540 throw new Error('Unable to find node on an unmounted component.'); 4541 } 4542} 4543 4544function findCurrentFiberUsingSlowPath(fiber) { 4545 var alternate = fiber.alternate; 4546 4547 if (!alternate) { 4548 // If there is no alternate, then we only need to check if it is mounted. 4549 var nearestMounted = getNearestMountedFiber(fiber); 4550 4551 if (nearestMounted === null) { 4552 throw new Error('Unable to find node on an unmounted component.'); 4553 } 4554 4555 if (nearestMounted !== fiber) { 4556 return null; 4557 } 4558 4559 return fiber; 4560 } // If we have two possible branches, we'll walk backwards up to the root 4561 // to see what path the root points to. On the way we may hit one of the 4562 // special cases and we'll deal with them. 4563 4564 4565 var a = fiber; 4566 var b = alternate; 4567 4568 while (true) { 4569 var parentA = a.return; 4570 4571 if (parentA === null) { 4572 // We're at the root. 4573 break; 4574 } 4575 4576 var parentB = parentA.alternate; 4577 4578 if (parentB === null) { 4579 // There is no alternate. This is an unusual case. Currently, it only 4580 // happens when a Suspense component is hidden. An extra fragment fiber 4581 // is inserted in between the Suspense fiber and its children. Skip 4582 // over this extra fragment fiber and proceed to the next parent. 4583 var nextParent = parentA.return; 4584 4585 if (nextParent !== null) { 4586 a = b = nextParent; 4587 continue; 4588 } // If there's no parent, we're at the root. 4589 4590 4591 break; 4592 } // If both copies of the parent fiber point to the same child, we can 4593 // assume that the child is current. This happens when we bailout on low 4594 // priority: the bailed out fiber's child reuses the current child. 4595 4596 4597 if (parentA.child === parentB.child) { 4598 var child = parentA.child; 4599 4600 while (child) { 4601 if (child === a) { 4602 // We've determined that A is the current branch. 4603 assertIsMounted(parentA); 4604 return fiber; 4605 } 4606 4607 if (child === b) { 4608 // We've determined that B is the current branch. 4609 assertIsMounted(parentA); 4610 return alternate; 4611 } 4612 4613 child = child.sibling; 4614 } // We should never have an alternate for any mounting node. So the only 4615 // way this could possibly happen is if this was unmounted, if at all. 4616 4617 4618 throw new Error('Unable to find node on an unmounted component.'); 4619 } 4620 4621 if (a.return !== b.return) { 4622 // The return pointer of A and the return pointer of B point to different 4623 // fibers. We assume that return pointers never criss-cross, so A must 4624 // belong to the child set of A.return, and B must belong to the child 4625 // set of B.return. 4626 a = parentA; 4627 b = parentB; 4628 } else { 4629 // The return pointers point to the same fiber. We'll have to use the 4630 // default, slow path: scan the child sets of each parent alternate to see 4631 // which child belongs to which set. 4632 // 4633 // Search parent A's child set 4634 var didFindChild = false; 4635 var _child = parentA.child; 4636 4637 while (_child) { 4638 if (_child === a) { 4639 didFindChild = true; 4640 a = parentA; 4641 b = parentB; 4642 break; 4643 } 4644 4645 if (_child === b) { 4646 didFindChild = true; 4647 b = parentA; 4648 a = parentB; 4649 break; 4650 } 4651 4652 _child = _child.sibling; 4653 } 4654 4655 if (!didFindChild) { 4656 // Search parent B's child set 4657 _child = parentB.child; 4658 4659 while (_child) { 4660 if (_child === a) { 4661 didFindChild = true; 4662 a = parentB; 4663 b = parentA; 4664 break; 4665 } 4666 4667 if (_child === b) { 4668 didFindChild = true; 4669 b = parentB; 4670 a = parentA; 4671 break; 4672 } 4673 4674 _child = _child.sibling; 4675 } 4676 4677 if (!didFindChild) { 4678 throw new Error('Child was not found in either parent set. This indicates a bug ' + 'in React related to the return pointer. Please file an issue.'); 4679 } 4680 } 4681 } 4682 4683 if (a.alternate !== b) { 4684 throw new Error("Return fibers should always be each others' alternates. " + 'This error is likely caused by a bug in React. Please file an issue.'); 4685 } 4686 } // If the root is not a host container, we're in a disconnected tree. I.e. 4687 // unmounted. 4688 4689 4690 if (a.tag !== HostRoot) { 4691 throw new Error('Unable to find node on an unmounted component.'); 4692 } 4693 4694 if (a.stateNode.current === a) { 4695 // We've determined that A is the current branch. 4696 return fiber; 4697 } // Otherwise B has to be current branch. 4698 4699 4700 return alternate; 4701} 4702function findCurrentHostFiber(parent) { 4703 var currentParent = findCurrentFiberUsingSlowPath(parent); 4704 return currentParent !== null ? findCurrentHostFiberImpl(currentParent) : null; 4705} 4706 4707function findCurrentHostFiberImpl(node) { 4708 // Next we'll drill down this component to find the first HostComponent/Text. 4709 if (node.tag === HostComponent || node.tag === HostText) { 4710 return node; 4711 } 4712 4713 var child = node.child; 4714 4715 while (child !== null) { 4716 var match = findCurrentHostFiberImpl(child); 4717 4718 if (match !== null) { 4719 return match; 4720 } 4721 4722 child = child.sibling; 4723 } 4724 4725 return null; 4726} 4727 4728function findCurrentHostFiberWithNoPortals(parent) { 4729 var currentParent = findCurrentFiberUsingSlowPath(parent); 4730 return currentParent !== null ? findCurrentHostFiberWithNoPortalsImpl(currentParent) : null; 4731} 4732 4733function findCurrentHostFiberWithNoPortalsImpl(node) { 4734 // Next we'll drill down this component to find the first HostComponent/Text. 4735 if (node.tag === HostComponent || node.tag === HostText) { 4736 return node; 4737 } 4738 4739 var child = node.child; 4740 4741 while (child !== null) { 4742 if (child.tag !== HostPortal) { 4743 var match = findCurrentHostFiberWithNoPortalsImpl(child); 4744 4745 if (match !== null) { 4746 return match; 4747 } 4748 } 4749 4750 child = child.sibling; 4751 } 4752 4753 return null; 4754} 4755 4756// This module only exists as an ESM wrapper around the external CommonJS 4757var scheduleCallback = Scheduler.unstable_scheduleCallback; 4758var cancelCallback = Scheduler.unstable_cancelCallback; 4759var shouldYield = Scheduler.unstable_shouldYield; 4760var requestPaint = Scheduler.unstable_requestPaint; 4761var now = Scheduler.unstable_now; 4762var getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel; 4763var ImmediatePriority = Scheduler.unstable_ImmediatePriority; 4764var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; 4765var NormalPriority = Scheduler.unstable_NormalPriority; 4766var LowPriority = Scheduler.unstable_LowPriority; 4767var IdlePriority = Scheduler.unstable_IdlePriority; 4768// this doesn't actually exist on the scheduler, but it *does* 4769// on scheduler/unstable_mock, which we'll need for internal testing 4770var unstable_yieldValue = Scheduler.unstable_yieldValue; 4771var unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue; 4772 4773var rendererID = null; 4774var injectedHook = null; 4775var injectedProfilingHooks = null; 4776var hasLoggedError = false; 4777var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined'; 4778function injectInternals(internals) { 4779 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') { 4780 // No DevTools 4781 return false; 4782 } 4783 4784 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; 4785 4786 if (hook.isDisabled) { 4787 // This isn't a real property on the hook, but it can be set to opt out 4788 // of DevTools integration and associated warnings and logs. 4789 // https://github.com/facebook/react/issues/3877 4790 return true; 4791 } 4792 4793 if (!hook.supportsFiber) { 4794 { 4795 error('The installed version of React DevTools is too old and will not work ' + 'with the current version of React. Please update React DevTools. ' + 'https://reactjs.org/link/react-devtools'); 4796 } // DevTools exists, even though it doesn't support Fiber. 4797 4798 4799 return true; 4800 } 4801 4802 try { 4803 if (enableSchedulingProfiler) { 4804 // Conditionally inject these hooks only if Timeline profiler is supported by this build. 4805 // This gives DevTools a way to feature detect that isn't tied to version number 4806 // (since profiling and timeline are controlled by different feature flags). 4807 internals = assign({}, internals, { 4808 getLaneLabelMap: getLaneLabelMap, 4809 injectProfilingHooks: injectProfilingHooks 4810 }); 4811 } 4812 4813 rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. 4814 4815 injectedHook = hook; 4816 } catch (err) { 4817 // Catch all errors because it is unsafe to throw during initialization. 4818 { 4819 error('React instrumentation encountered an error: %s.', err); 4820 } 4821 } 4822 4823 if (hook.checkDCE) { 4824 // This is the real DevTools. 4825 return true; 4826 } else { 4827 // This is likely a hook installed by Fast Refresh runtime. 4828 return false; 4829 } 4830} 4831function onScheduleRoot(root, children) { 4832 { 4833 if (injectedHook && typeof injectedHook.onScheduleFiberRoot === 'function') { 4834 try { 4835 injectedHook.onScheduleFiberRoot(rendererID, root, children); 4836 } catch (err) { 4837 if ( !hasLoggedError) { 4838 hasLoggedError = true; 4839 4840 error('React instrumentation encountered an error: %s', err); 4841 } 4842 } 4843 } 4844 } 4845} 4846function onCommitRoot(root, eventPriority) { 4847 if (injectedHook && typeof injectedHook.onCommitFiberRoot === 'function') { 4848 try { 4849 var didError = (root.current.flags & DidCapture) === DidCapture; 4850 4851 if (enableProfilerTimer) { 4852 var schedulerPriority; 4853 4854 switch (eventPriority) { 4855 case DiscreteEventPriority: 4856 schedulerPriority = ImmediatePriority; 4857 break; 4858 4859 case ContinuousEventPriority: 4860 schedulerPriority = UserBlockingPriority; 4861 break; 4862 4863 case DefaultEventPriority: 4864 schedulerPriority = NormalPriority; 4865 break; 4866 4867 case IdleEventPriority: 4868 schedulerPriority = IdlePriority; 4869 break; 4870 4871 default: 4872 schedulerPriority = NormalPriority; 4873 break; 4874 } 4875 4876 injectedHook.onCommitFiberRoot(rendererID, root, schedulerPriority, didError); 4877 } else { 4878 injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); 4879 } 4880 } catch (err) { 4881 { 4882 if (!hasLoggedError) { 4883 hasLoggedError = true; 4884 4885 error('React instrumentation encountered an error: %s', err); 4886 } 4887 } 4888 } 4889 } 4890} 4891function onPostCommitRoot(root) { 4892 if (injectedHook && typeof injectedHook.onPostCommitFiberRoot === 'function') { 4893 try { 4894 injectedHook.onPostCommitFiberRoot(rendererID, root); 4895 } catch (err) { 4896 { 4897 if (!hasLoggedError) { 4898 hasLoggedError = true; 4899 4900 error('React instrumentation encountered an error: %s', err); 4901 } 4902 } 4903 } 4904 } 4905} 4906function onCommitUnmount(fiber) { 4907 if (injectedHook && typeof injectedHook.onCommitFiberUnmount === 'function') { 4908 try { 4909 injectedHook.onCommitFiberUnmount(rendererID, fiber); 4910 } catch (err) { 4911 { 4912 if (!hasLoggedError) { 4913 hasLoggedError = true; 4914 4915 error('React instrumentation encountered an error: %s', err); 4916 } 4917 } 4918 } 4919 } 4920} 4921function setIsStrictModeForDevtools(newIsStrictMode) { 4922 { 4923 if (typeof unstable_yieldValue === 'function') { 4924 // We're in a test because Scheduler.unstable_yieldValue only exists 4925 // in SchedulerMock. To reduce the noise in strict mode tests, 4926 // suppress warnings and disable scheduler yielding during the double render 4927 unstable_setDisableYieldValue(newIsStrictMode); 4928 setSuppressWarning(newIsStrictMode); 4929 } 4930 4931 if (injectedHook && typeof injectedHook.setStrictMode === 'function') { 4932 try { 4933 injectedHook.setStrictMode(rendererID, newIsStrictMode); 4934 } catch (err) { 4935 { 4936 if (!hasLoggedError) { 4937 hasLoggedError = true; 4938 4939 error('React instrumentation encountered an error: %s', err); 4940 } 4941 } 4942 } 4943 } 4944 } 4945} // Profiler API hooks 4946 4947function injectProfilingHooks(profilingHooks) { 4948 injectedProfilingHooks = profilingHooks; 4949} 4950 4951function getLaneLabelMap() { 4952 { 4953 var map = new Map(); 4954 var lane = 1; 4955 4956 for (var index = 0; index < TotalLanes; index++) { 4957 var label = getLabelForLane(lane); 4958 map.set(lane, label); 4959 lane *= 2; 4960 } 4961 4962 return map; 4963 } 4964} 4965 4966function markCommitStarted(lanes) { 4967 { 4968 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markCommitStarted === 'function') { 4969 injectedProfilingHooks.markCommitStarted(lanes); 4970 } 4971 } 4972} 4973function markCommitStopped() { 4974 { 4975 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markCommitStopped === 'function') { 4976 injectedProfilingHooks.markCommitStopped(); 4977 } 4978 } 4979} 4980function markComponentRenderStarted(fiber) { 4981 { 4982 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentRenderStarted === 'function') { 4983 injectedProfilingHooks.markComponentRenderStarted(fiber); 4984 } 4985 } 4986} 4987function markComponentRenderStopped() { 4988 { 4989 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentRenderStopped === 'function') { 4990 injectedProfilingHooks.markComponentRenderStopped(); 4991 } 4992 } 4993} 4994function markComponentPassiveEffectMountStarted(fiber) { 4995 { 4996 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectMountStarted === 'function') { 4997 injectedProfilingHooks.markComponentPassiveEffectMountStarted(fiber); 4998 } 4999 } 5000} 5001function markComponentPassiveEffectMountStopped() { 5002 { 5003 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectMountStopped === 'function') { 5004 injectedProfilingHooks.markComponentPassiveEffectMountStopped(); 5005 } 5006 } 5007} 5008function markComponentPassiveEffectUnmountStarted(fiber) { 5009 { 5010 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStarted === 'function') { 5011 injectedProfilingHooks.markComponentPassiveEffectUnmountStarted(fiber); 5012 } 5013 } 5014} 5015function markComponentPassiveEffectUnmountStopped() { 5016 { 5017 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStopped === 'function') { 5018 injectedProfilingHooks.markComponentPassiveEffectUnmountStopped(); 5019 } 5020 } 5021} 5022function markComponentLayoutEffectMountStarted(fiber) { 5023 { 5024 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectMountStarted === 'function') { 5025 injectedProfilingHooks.markComponentLayoutEffectMountStarted(fiber); 5026 } 5027 } 5028} 5029function markComponentLayoutEffectMountStopped() { 5030 { 5031 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectMountStopped === 'function') { 5032 injectedProfilingHooks.markComponentLayoutEffectMountStopped(); 5033 } 5034 } 5035} 5036function markComponentLayoutEffectUnmountStarted(fiber) { 5037 { 5038 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStarted === 'function') { 5039 injectedProfilingHooks.markComponentLayoutEffectUnmountStarted(fiber); 5040 } 5041 } 5042} 5043function markComponentLayoutEffectUnmountStopped() { 5044 { 5045 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStopped === 'function') { 5046 injectedProfilingHooks.markComponentLayoutEffectUnmountStopped(); 5047 } 5048 } 5049} 5050function markComponentErrored(fiber, thrownValue, lanes) { 5051 { 5052 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentErrored === 'function') { 5053 injectedProfilingHooks.markComponentErrored(fiber, thrownValue, lanes); 5054 } 5055 } 5056} 5057function markComponentSuspended(fiber, wakeable, lanes) { 5058 { 5059 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentSuspended === 'function') { 5060 injectedProfilingHooks.markComponentSuspended(fiber, wakeable, lanes); 5061 } 5062 } 5063} 5064function markLayoutEffectsStarted(lanes) { 5065 { 5066 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markLayoutEffectsStarted === 'function') { 5067 injectedProfilingHooks.markLayoutEffectsStarted(lanes); 5068 } 5069 } 5070} 5071function markLayoutEffectsStopped() { 5072 { 5073 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markLayoutEffectsStopped === 'function') { 5074 injectedProfilingHooks.markLayoutEffectsStopped(); 5075 } 5076 } 5077} 5078function markPassiveEffectsStarted(lanes) { 5079 { 5080 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markPassiveEffectsStarted === 'function') { 5081 injectedProfilingHooks.markPassiveEffectsStarted(lanes); 5082 } 5083 } 5084} 5085function markPassiveEffectsStopped() { 5086 { 5087 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markPassiveEffectsStopped === 'function') { 5088 injectedProfilingHooks.markPassiveEffectsStopped(); 5089 } 5090 } 5091} 5092function markRenderStarted(lanes) { 5093 { 5094 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderStarted === 'function') { 5095 injectedProfilingHooks.markRenderStarted(lanes); 5096 } 5097 } 5098} 5099function markRenderYielded() { 5100 { 5101 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderYielded === 'function') { 5102 injectedProfilingHooks.markRenderYielded(); 5103 } 5104 } 5105} 5106function markRenderStopped() { 5107 { 5108 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderStopped === 'function') { 5109 injectedProfilingHooks.markRenderStopped(); 5110 } 5111 } 5112} 5113function markRenderScheduled(lane) { 5114 { 5115 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderScheduled === 'function') { 5116 injectedProfilingHooks.markRenderScheduled(lane); 5117 } 5118 } 5119} 5120function markForceUpdateScheduled(fiber, lane) { 5121 { 5122 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markForceUpdateScheduled === 'function') { 5123 injectedProfilingHooks.markForceUpdateScheduled(fiber, lane); 5124 } 5125 } 5126} 5127function markStateUpdateScheduled(fiber, lane) { 5128 { 5129 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markStateUpdateScheduled === 'function') { 5130 injectedProfilingHooks.markStateUpdateScheduled(fiber, lane); 5131 } 5132 } 5133} 5134 5135var NoMode = 5136/* */ 51370; // TODO: Remove ConcurrentMode by reading from the root tag instead 5138 5139var ConcurrentMode = 5140/* */ 51411; 5142var ProfileMode = 5143/* */ 51442; 5145var StrictLegacyMode = 5146/* */ 51478; 5148var StrictEffectsMode = 5149/* */ 515016; 5151 5152// TODO: This is pretty well supported by browsers. Maybe we can drop it. 5153var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. 5154// Based on: 5155// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 5156 5157var log = Math.log; 5158var LN2 = Math.LN2; 5159 5160function clz32Fallback(x) { 5161 var asUint = x >>> 0; 5162 5163 if (asUint === 0) { 5164 return 32; 5165 } 5166 5167 return 31 - (log(asUint) / LN2 | 0) | 0; 5168} 5169 5170// If those values are changed that package should be rebuilt and redeployed. 5171 5172var TotalLanes = 31; 5173var NoLanes = 5174/* */ 51750; 5176var NoLane = 5177/* */ 51780; 5179var SyncLane = 5180/* */ 51811; 5182var InputContinuousHydrationLane = 5183/* */ 51842; 5185var InputContinuousLane = 5186/* */ 51874; 5188var DefaultHydrationLane = 5189/* */ 51908; 5191var DefaultLane = 5192/* */ 519316; 5194var TransitionHydrationLane = 5195/* */ 519632; 5197var TransitionLanes = 5198/* */ 51994194240; 5200var TransitionLane1 = 5201/* */ 520264; 5203var TransitionLane2 = 5204/* */ 5205128; 5206var TransitionLane3 = 5207/* */ 5208256; 5209var TransitionLane4 = 5210/* */ 5211512; 5212var TransitionLane5 = 5213/* */ 52141024; 5215var TransitionLane6 = 5216/* */ 52172048; 5218var TransitionLane7 = 5219/* */ 52204096; 5221var TransitionLane8 = 5222/* */ 52238192; 5224var TransitionLane9 = 5225/* */ 522616384; 5227var TransitionLane10 = 5228/* */ 522932768; 5230var TransitionLane11 = 5231/* */ 523265536; 5233var TransitionLane12 = 5234/* */ 5235131072; 5236var TransitionLane13 = 5237/* */ 5238262144; 5239var TransitionLane14 = 5240/* */ 5241524288; 5242var TransitionLane15 = 5243/* */ 52441048576; 5245var TransitionLane16 = 5246/* */ 52472097152; 5248var RetryLanes = 5249/* */ 5250130023424; 5251var RetryLane1 = 5252/* */ 52534194304; 5254var RetryLane2 = 5255/* */ 52568388608; 5257var RetryLane3 = 5258/* */ 525916777216; 5260var RetryLane4 = 5261/* */ 526233554432; 5263var RetryLane5 = 5264/* */ 526567108864; 5266var SomeRetryLane = RetryLane1; 5267var SelectiveHydrationLane = 5268/* */ 5269134217728; 5270var NonIdleLanes = 5271/* */ 5272268435455; 5273var IdleHydrationLane = 5274/* */ 5275268435456; 5276var IdleLane = 5277/* */ 5278536870912; 5279var OffscreenLane = 5280/* */ 52811073741824; // This function is used for the experimental timeline (react-devtools-timeline) 5282// It should be kept in sync with the Lanes values above. 5283 5284function getLabelForLane(lane) { 5285 { 5286 if (lane & SyncLane) { 5287 return 'Sync'; 5288 } 5289 5290 if (lane & InputContinuousHydrationLane) { 5291 return 'InputContinuousHydration'; 5292 } 5293 5294 if (lane & InputContinuousLane) { 5295 return 'InputContinuous'; 5296 } 5297 5298 if (lane & DefaultHydrationLane) { 5299 return 'DefaultHydration'; 5300 } 5301 5302 if (lane & DefaultLane) { 5303 return 'Default'; 5304 } 5305 5306 if (lane & TransitionHydrationLane) { 5307 return 'TransitionHydration'; 5308 } 5309 5310 if (lane & TransitionLanes) { 5311 return 'Transition'; 5312 } 5313 5314 if (lane & RetryLanes) { 5315 return 'Retry'; 5316 } 5317 5318 if (lane & SelectiveHydrationLane) { 5319 return 'SelectiveHydration'; 5320 } 5321 5322 if (lane & IdleHydrationLane) { 5323 return 'IdleHydration'; 5324 } 5325 5326 if (lane & IdleLane) { 5327 return 'Idle'; 5328 } 5329 5330 if (lane & OffscreenLane) { 5331 return 'Offscreen'; 5332 } 5333 } 5334} 5335var NoTimestamp = -1; 5336var nextTransitionLane = TransitionLane1; 5337var nextRetryLane = RetryLane1; 5338 5339function getHighestPriorityLanes(lanes) { 5340 switch (getHighestPriorityLane(lanes)) { 5341 case SyncLane: 5342 return SyncLane; 5343 5344 case InputContinuousHydrationLane: 5345 return InputContinuousHydrationLane; 5346 5347 case InputContinuousLane: 5348 return InputContinuousLane; 5349 5350 case DefaultHydrationLane: 5351 return DefaultHydrationLane; 5352 5353 case DefaultLane: 5354 return DefaultLane; 5355 5356 case TransitionHydrationLane: 5357 return TransitionHydrationLane; 5358 5359 case TransitionLane1: 5360 case TransitionLane2: 5361 case TransitionLane3: 5362 case TransitionLane4: 5363 case TransitionLane5: 5364 case TransitionLane6: 5365 case TransitionLane7: 5366 case TransitionLane8: 5367 case TransitionLane9: 5368 case TransitionLane10: 5369 case TransitionLane11: 5370 case TransitionLane12: 5371 case TransitionLane13: 5372 case TransitionLane14: 5373 case TransitionLane15: 5374 case TransitionLane16: 5375 return lanes & TransitionLanes; 5376 5377 case RetryLane1: 5378 case RetryLane2: 5379 case RetryLane3: 5380 case RetryLane4: 5381 case RetryLane5: 5382 return lanes & RetryLanes; 5383 5384 case SelectiveHydrationLane: 5385 return SelectiveHydrationLane; 5386 5387 case IdleHydrationLane: 5388 return IdleHydrationLane; 5389 5390 case IdleLane: 5391 return IdleLane; 5392 5393 case OffscreenLane: 5394 return OffscreenLane; 5395 5396 default: 5397 { 5398 error('Should have found matching lanes. This is a bug in React.'); 5399 } // This shouldn't be reachable, but as a fallback, return the entire bitmask. 5400 5401 5402 return lanes; 5403 } 5404} 5405 5406function getNextLanes(root, wipLanes) { 5407 // Early bailout if there's no pending work left. 5408 var pendingLanes = root.pendingLanes; 5409 5410 if (pendingLanes === NoLanes) { 5411 return NoLanes; 5412 } 5413 5414 var nextLanes = NoLanes; 5415 var suspendedLanes = root.suspendedLanes; 5416 var pingedLanes = root.pingedLanes; // Do not work on any idle work until all the non-idle work has finished, 5417 // even if the work is suspended. 5418 5419 var nonIdlePendingLanes = pendingLanes & NonIdleLanes; 5420 5421 if (nonIdlePendingLanes !== NoLanes) { 5422 var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; 5423 5424 if (nonIdleUnblockedLanes !== NoLanes) { 5425 nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); 5426 } else { 5427 var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; 5428 5429 if (nonIdlePingedLanes !== NoLanes) { 5430 nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); 5431 } 5432 } 5433 } else { 5434 // The only remaining work is Idle. 5435 var unblockedLanes = pendingLanes & ~suspendedLanes; 5436 5437 if (unblockedLanes !== NoLanes) { 5438 nextLanes = getHighestPriorityLanes(unblockedLanes); 5439 } else { 5440 if (pingedLanes !== NoLanes) { 5441 nextLanes = getHighestPriorityLanes(pingedLanes); 5442 } 5443 } 5444 } 5445 5446 if (nextLanes === NoLanes) { 5447 // This should only be reachable if we're suspended 5448 // TODO: Consider warning in this path if a fallback timer is not scheduled. 5449 return NoLanes; 5450 } // If we're already in the middle of a render, switching lanes will interrupt 5451 // it and we'll lose our progress. We should only do this if the new lanes are 5452 // higher priority. 5453 5454 5455 if (wipLanes !== NoLanes && wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't 5456 // bother waiting until the root is complete. 5457 (wipLanes & suspendedLanes) === NoLanes) { 5458 var nextLane = getHighestPriorityLane(nextLanes); 5459 var wipLane = getHighestPriorityLane(wipLanes); 5460 5461 if ( // Tests whether the next lane is equal or lower priority than the wip 5462 // one. This works because the bits decrease in priority as you go left. 5463 nextLane >= wipLane || // Default priority updates should not interrupt transition updates. The 5464 // only difference between default updates and transition updates is that 5465 // default updates do not support refresh transitions. 5466 nextLane === DefaultLane && (wipLane & TransitionLanes) !== NoLanes) { 5467 // Keep working on the existing in-progress tree. Do not interrupt. 5468 return wipLanes; 5469 } 5470 } 5471 5472 if ((nextLanes & InputContinuousLane) !== NoLanes) { 5473 // When updates are sync by default, we entangle continuous priority updates 5474 // and default updates, so they render in the same batch. The only reason 5475 // they use separate lanes is because continuous updates should interrupt 5476 // transitions, but default updates should not. 5477 nextLanes |= pendingLanes & DefaultLane; 5478 } // Check for entangled lanes and add them to the batch. 5479 // 5480 // A lane is said to be entangled with another when it's not allowed to render 5481 // in a batch that does not also include the other lane. Typically we do this 5482 // when multiple updates have the same source, and we only want to respond to 5483 // the most recent event from that source. 5484 // 5485 // Note that we apply entanglements *after* checking for partial work above. 5486 // This means that if a lane is entangled during an interleaved event while 5487 // it's already rendering, we won't interrupt it. This is intentional, since 5488 // entanglement is usually "best effort": we'll try our best to render the 5489 // lanes in the same batch, but it's not worth throwing out partially 5490 // completed work in order to do it. 5491 // TODO: Reconsider this. The counter-argument is that the partial work 5492 // represents an intermediate state, which we don't want to show to the user. 5493 // And by spending extra time finishing it, we're increasing the amount of 5494 // time it takes to show the final state, which is what they are actually 5495 // waiting for. 5496 // 5497 // For those exceptions where entanglement is semantically important, like 5498 // useMutableSource, we should ensure that there is no partial work at the 5499 // time we apply the entanglement. 5500 5501 5502 var entangledLanes = root.entangledLanes; 5503 5504 if (entangledLanes !== NoLanes) { 5505 var entanglements = root.entanglements; 5506 var lanes = nextLanes & entangledLanes; 5507 5508 while (lanes > 0) { 5509 var index = pickArbitraryLaneIndex(lanes); 5510 var lane = 1 << index; 5511 nextLanes |= entanglements[index]; 5512 lanes &= ~lane; 5513 } 5514 } 5515 5516 return nextLanes; 5517} 5518function getMostRecentEventTime(root, lanes) { 5519 var eventTimes = root.eventTimes; 5520 var mostRecentEventTime = NoTimestamp; 5521 5522 while (lanes > 0) { 5523 var index = pickArbitraryLaneIndex(lanes); 5524 var lane = 1 << index; 5525 var eventTime = eventTimes[index]; 5526 5527 if (eventTime > mostRecentEventTime) { 5528 mostRecentEventTime = eventTime; 5529 } 5530 5531 lanes &= ~lane; 5532 } 5533 5534 return mostRecentEventTime; 5535} 5536 5537function computeExpirationTime(lane, currentTime) { 5538 switch (lane) { 5539 case SyncLane: 5540 case InputContinuousHydrationLane: 5541 case InputContinuousLane: 5542 // User interactions should expire slightly more quickly. 5543 // 5544 // NOTE: This is set to the corresponding constant as in Scheduler.js. 5545 // When we made it larger, a product metric in www regressed, suggesting 5546 // there's a user interaction that's being starved by a series of 5547 // synchronous updates. If that theory is correct, the proper solution is 5548 // to fix the starvation. However, this scenario supports the idea that 5549 // expiration times are an important safeguard when starvation 5550 // does happen. 5551 return currentTime + 250; 5552 5553 case DefaultHydrationLane: 5554 case DefaultLane: 5555 case TransitionHydrationLane: 5556 case TransitionLane1: 5557 case TransitionLane2: 5558 case TransitionLane3: 5559 case TransitionLane4: 5560 case TransitionLane5: 5561 case TransitionLane6: 5562 case TransitionLane7: 5563 case TransitionLane8: 5564 case TransitionLane9: 5565 case TransitionLane10: 5566 case TransitionLane11: 5567 case TransitionLane12: 5568 case TransitionLane13: 5569 case TransitionLane14: 5570 case TransitionLane15: 5571 case TransitionLane16: 5572 return currentTime + 5000; 5573 5574 case RetryLane1: 5575 case RetryLane2: 5576 case RetryLane3: 5577 case RetryLane4: 5578 case RetryLane5: 5579 // TODO: Retries should be allowed to expire if they are CPU bound for 5580 // too long, but when I made this change it caused a spike in browser 5581 // crashes. There must be some other underlying bug; not super urgent but 5582 // ideally should figure out why and fix it. Unfortunately we don't have 5583 // a repro for the crashes, only detected via production metrics. 5584 return NoTimestamp; 5585 5586 case SelectiveHydrationLane: 5587 case IdleHydrationLane: 5588 case IdleLane: 5589 case OffscreenLane: 5590 // Anything idle priority or lower should never expire. 5591 return NoTimestamp; 5592 5593 default: 5594 { 5595 error('Should have found matching lanes. This is a bug in React.'); 5596 } 5597 5598 return NoTimestamp; 5599 } 5600} 5601 5602function markStarvedLanesAsExpired(root, currentTime) { 5603 // TODO: This gets called every time we yield. We can optimize by storing 5604 // the earliest expiration time on the root. Then use that to quickly bail out 5605 // of this function. 5606 var pendingLanes = root.pendingLanes; 5607 var suspendedLanes = root.suspendedLanes; 5608 var pingedLanes = root.pingedLanes; 5609 var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their 5610 // expiration time. If so, we'll assume the update is being starved and mark 5611 // it as expired to force it to finish. 5612 5613 var lanes = pendingLanes; 5614 5615 while (lanes > 0) { 5616 var index = pickArbitraryLaneIndex(lanes); 5617 var lane = 1 << index; 5618 var expirationTime = expirationTimes[index]; 5619 5620 if (expirationTime === NoTimestamp) { 5621 // Found a pending lane with no expiration time. If it's not suspended, or 5622 // if it's pinged, assume it's CPU-bound. Compute a new expiration time 5623 // using the current time. 5624 if ((lane & suspendedLanes) === NoLanes || (lane & pingedLanes) !== NoLanes) { 5625 // Assumes timestamps are monotonically increasing. 5626 expirationTimes[index] = computeExpirationTime(lane, currentTime); 5627 } 5628 } else if (expirationTime <= currentTime) { 5629 // This lane expired 5630 root.expiredLanes |= lane; 5631 } 5632 5633 lanes &= ~lane; 5634 } 5635} // This returns the highest priority pending lanes regardless of whether they 5636// are suspended. 5637 5638function getHighestPriorityPendingLanes(root) { 5639 return getHighestPriorityLanes(root.pendingLanes); 5640} 5641function getLanesToRetrySynchronouslyOnError(root) { 5642 var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; 5643 5644 if (everythingButOffscreen !== NoLanes) { 5645 return everythingButOffscreen; 5646 } 5647 5648 if (everythingButOffscreen & OffscreenLane) { 5649 return OffscreenLane; 5650 } 5651 5652 return NoLanes; 5653} 5654function includesSyncLane(lanes) { 5655 return (lanes & SyncLane) !== NoLanes; 5656} 5657function includesNonIdleWork(lanes) { 5658 return (lanes & NonIdleLanes) !== NoLanes; 5659} 5660function includesOnlyRetries(lanes) { 5661 return (lanes & RetryLanes) === lanes; 5662} 5663function includesOnlyNonUrgentLanes(lanes) { 5664 var UrgentLanes = SyncLane | InputContinuousLane | DefaultLane; 5665 return (lanes & UrgentLanes) === NoLanes; 5666} 5667function includesOnlyTransitions(lanes) { 5668 return (lanes & TransitionLanes) === lanes; 5669} 5670function includesBlockingLane(root, lanes) { 5671 5672 var SyncDefaultLanes = InputContinuousHydrationLane | InputContinuousLane | DefaultHydrationLane | DefaultLane; 5673 return (lanes & SyncDefaultLanes) !== NoLanes; 5674} 5675function includesExpiredLane(root, lanes) { 5676 // This is a separate check from includesBlockingLane because a lane can 5677 // expire after a render has already started. 5678 return (lanes & root.expiredLanes) !== NoLanes; 5679} 5680function isTransitionLane(lane) { 5681 return (lane & TransitionLanes) !== NoLanes; 5682} 5683function claimNextTransitionLane() { 5684 // Cycle through the lanes, assigning each new transition to the next lane. 5685 // In most cases, this means every transition gets its own lane, until we 5686 // run out of lanes and cycle back to the beginning. 5687 var lane = nextTransitionLane; 5688 nextTransitionLane <<= 1; 5689 5690 if ((nextTransitionLane & TransitionLanes) === NoLanes) { 5691 nextTransitionLane = TransitionLane1; 5692 } 5693 5694 return lane; 5695} 5696function claimNextRetryLane() { 5697 var lane = nextRetryLane; 5698 nextRetryLane <<= 1; 5699 5700 if ((nextRetryLane & RetryLanes) === NoLanes) { 5701 nextRetryLane = RetryLane1; 5702 } 5703 5704 return lane; 5705} 5706function getHighestPriorityLane(lanes) { 5707 return lanes & -lanes; 5708} 5709function pickArbitraryLane(lanes) { 5710 // This wrapper function gets inlined. Only exists so to communicate that it 5711 // doesn't matter which bit is selected; you can pick any bit without 5712 // affecting the algorithms where its used. Here I'm using 5713 // getHighestPriorityLane because it requires the fewest operations. 5714 return getHighestPriorityLane(lanes); 5715} 5716 5717function pickArbitraryLaneIndex(lanes) { 5718 return 31 - clz32(lanes); 5719} 5720 5721function laneToIndex(lane) { 5722 return pickArbitraryLaneIndex(lane); 5723} 5724 5725function includesSomeLane(a, b) { 5726 return (a & b) !== NoLanes; 5727} 5728function isSubsetOfLanes(set, subset) { 5729 return (set & subset) === subset; 5730} 5731function mergeLanes(a, b) { 5732 return a | b; 5733} 5734function removeLanes(set, subset) { 5735 return set & ~subset; 5736} 5737function intersectLanes(a, b) { 5738 return a & b; 5739} // Seems redundant, but it changes the type from a single lane (used for 5740// updates) to a group of lanes (used for flushing work). 5741 5742function laneToLanes(lane) { 5743 return lane; 5744} 5745function higherPriorityLane(a, b) { 5746 // This works because the bit ranges decrease in priority as you go left. 5747 return a !== NoLane && a < b ? a : b; 5748} 5749function createLaneMap(initial) { 5750 // Intentionally pushing one by one. 5751 // https://v8.dev/blog/elements-kinds#avoid-creating-holes 5752 var laneMap = []; 5753 5754 for (var i = 0; i < TotalLanes; i++) { 5755 laneMap.push(initial); 5756 } 5757 5758 return laneMap; 5759} 5760function markRootUpdated(root, updateLane, eventTime) { 5761 root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update 5762 // could unblock them. Clear the suspended lanes so that we can try rendering 5763 // them again. 5764 // 5765 // TODO: We really only need to unsuspend only lanes that are in the 5766 // `subtreeLanes` of the updated fiber, or the update lanes of the return 5767 // path. This would exclude suspended updates in an unrelated sibling tree, 5768 // since there's no way for this update to unblock it. 5769 // 5770 // We don't do this if the incoming update is idle, because we never process 5771 // idle updates until after all the regular updates have finished; there's no 5772 // way it could unblock a transition. 5773 5774 if (updateLane !== IdleLane) { 5775 root.suspendedLanes = NoLanes; 5776 root.pingedLanes = NoLanes; 5777 } 5778 5779 var eventTimes = root.eventTimes; 5780 var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most 5781 // recent event, and we assume time is monotonically increasing. 5782 5783 eventTimes[index] = eventTime; 5784} 5785function markRootSuspended(root, suspendedLanes) { 5786 root.suspendedLanes |= suspendedLanes; 5787 root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. 5788 5789 var expirationTimes = root.expirationTimes; 5790 var lanes = suspendedLanes; 5791 5792 while (lanes > 0) { 5793 var index = pickArbitraryLaneIndex(lanes); 5794 var lane = 1 << index; 5795 expirationTimes[index] = NoTimestamp; 5796 lanes &= ~lane; 5797 } 5798} 5799function markRootPinged(root, pingedLanes, eventTime) { 5800 root.pingedLanes |= root.suspendedLanes & pingedLanes; 5801} 5802function markRootFinished(root, remainingLanes) { 5803 var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; 5804 root.pendingLanes = remainingLanes; // Let's try everything again 5805 5806 root.suspendedLanes = NoLanes; 5807 root.pingedLanes = NoLanes; 5808 root.expiredLanes &= remainingLanes; 5809 root.mutableReadLanes &= remainingLanes; 5810 root.entangledLanes &= remainingLanes; 5811 var entanglements = root.entanglements; 5812 var eventTimes = root.eventTimes; 5813 var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work 5814 5815 var lanes = noLongerPendingLanes; 5816 5817 while (lanes > 0) { 5818 var index = pickArbitraryLaneIndex(lanes); 5819 var lane = 1 << index; 5820 entanglements[index] = NoLanes; 5821 eventTimes[index] = NoTimestamp; 5822 expirationTimes[index] = NoTimestamp; 5823 lanes &= ~lane; 5824 } 5825} 5826function markRootEntangled(root, entangledLanes) { 5827 // In addition to entangling each of the given lanes with each other, we also 5828 // have to consider _transitive_ entanglements. For each lane that is already 5829 // entangled with *any* of the given lanes, that lane is now transitively 5830 // entangled with *all* the given lanes. 5831 // 5832 // Translated: If C is entangled with A, then entangling A with B also 5833 // entangles C with B. 5834 // 5835 // If this is hard to grasp, it might help to intentionally break this 5836 // function and look at the tests that fail in ReactTransition-test.js. Try 5837 // commenting out one of the conditions below. 5838 var rootEntangledLanes = root.entangledLanes |= entangledLanes; 5839 var entanglements = root.entanglements; 5840 var lanes = rootEntangledLanes; 5841 5842 while (lanes) { 5843 var index = pickArbitraryLaneIndex(lanes); 5844 var lane = 1 << index; 5845 5846 if ( // Is this one of the newly entangled lanes? 5847 lane & entangledLanes | // Is this lane transitively entangled with the newly entangled lanes? 5848 entanglements[index] & entangledLanes) { 5849 entanglements[index] |= entangledLanes; 5850 } 5851 5852 lanes &= ~lane; 5853 } 5854} 5855function getBumpedLaneForHydration(root, renderLanes) { 5856 var renderLane = getHighestPriorityLane(renderLanes); 5857 var lane; 5858 5859 switch (renderLane) { 5860 case InputContinuousLane: 5861 lane = InputContinuousHydrationLane; 5862 break; 5863 5864 case DefaultLane: 5865 lane = DefaultHydrationLane; 5866 break; 5867 5868 case TransitionLane1: 5869 case TransitionLane2: 5870 case TransitionLane3: 5871 case TransitionLane4: 5872 case TransitionLane5: 5873 case TransitionLane6: 5874 case TransitionLane7: 5875 case TransitionLane8: 5876 case TransitionLane9: 5877 case TransitionLane10: 5878 case TransitionLane11: 5879 case TransitionLane12: 5880 case TransitionLane13: 5881 case TransitionLane14: 5882 case TransitionLane15: 5883 case TransitionLane16: 5884 case RetryLane1: 5885 case RetryLane2: 5886 case RetryLane3: 5887 case RetryLane4: 5888 case RetryLane5: 5889 lane = TransitionHydrationLane; 5890 break; 5891 5892 case IdleLane: 5893 lane = IdleHydrationLane; 5894 break; 5895 5896 default: 5897 // Everything else is already either a hydration lane, or shouldn't 5898 // be retried at a hydration lane. 5899 lane = NoLane; 5900 break; 5901 } // Check if the lane we chose is suspended. If so, that indicates that we 5902 // already attempted and failed to hydrate at that level. Also check if we're 5903 // already rendering that lane, which is rare but could happen. 5904 5905 5906 if ((lane & (root.suspendedLanes | renderLanes)) !== NoLane) { 5907 // Give up trying to hydrate and fall back to client render. 5908 return NoLane; 5909 } 5910 5911 return lane; 5912} 5913function addFiberToLanesMap(root, fiber, lanes) { 5914 5915 if (!isDevToolsPresent) { 5916 return; 5917 } 5918 5919 var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap; 5920 5921 while (lanes > 0) { 5922 var index = laneToIndex(lanes); 5923 var lane = 1 << index; 5924 var updaters = pendingUpdatersLaneMap[index]; 5925 updaters.add(fiber); 5926 lanes &= ~lane; 5927 } 5928} 5929function movePendingFibersToMemoized(root, lanes) { 5930 5931 if (!isDevToolsPresent) { 5932 return; 5933 } 5934 5935 var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap; 5936 var memoizedUpdaters = root.memoizedUpdaters; 5937 5938 while (lanes > 0) { 5939 var index = laneToIndex(lanes); 5940 var lane = 1 << index; 5941 var updaters = pendingUpdatersLaneMap[index]; 5942 5943 if (updaters.size > 0) { 5944 updaters.forEach(function (fiber) { 5945 var alternate = fiber.alternate; 5946 5947 if (alternate === null || !memoizedUpdaters.has(alternate)) { 5948 memoizedUpdaters.add(fiber); 5949 } 5950 }); 5951 updaters.clear(); 5952 } 5953 5954 lanes &= ~lane; 5955 } 5956} 5957function getTransitionsForLanes(root, lanes) { 5958 { 5959 return null; 5960 } 5961} 5962 5963var DiscreteEventPriority = SyncLane; 5964var ContinuousEventPriority = InputContinuousLane; 5965var DefaultEventPriority = DefaultLane; 5966var IdleEventPriority = IdleLane; 5967var currentUpdatePriority = NoLane; 5968function getCurrentUpdatePriority() { 5969 return currentUpdatePriority; 5970} 5971function setCurrentUpdatePriority(newPriority) { 5972 currentUpdatePriority = newPriority; 5973} 5974function runWithPriority(priority, fn) { 5975 var previousPriority = currentUpdatePriority; 5976 5977 try { 5978 currentUpdatePriority = priority; 5979 return fn(); 5980 } finally { 5981 currentUpdatePriority = previousPriority; 5982 } 5983} 5984function higherEventPriority(a, b) { 5985 return a !== 0 && a < b ? a : b; 5986} 5987function lowerEventPriority(a, b) { 5988 return a === 0 || a > b ? a : b; 5989} 5990function isHigherEventPriority(a, b) { 5991 return a !== 0 && a < b; 5992} 5993function lanesToEventPriority(lanes) { 5994 var lane = getHighestPriorityLane(lanes); 5995 5996 if (!isHigherEventPriority(DiscreteEventPriority, lane)) { 5997 return DiscreteEventPriority; 5998 } 5999 6000 if (!isHigherEventPriority(ContinuousEventPriority, lane)) { 6001 return ContinuousEventPriority; 6002 } 6003 6004 if (includesNonIdleWork(lane)) { 6005 return DefaultEventPriority; 6006 } 6007 6008 return IdleEventPriority; 6009} 6010 6011// This is imported by the event replaying implementation in React DOM. It's 6012// in a separate file to break a circular dependency between the renderer and 6013// the reconciler. 6014function isRootDehydrated(root) { 6015 var currentState = root.current.memoizedState; 6016 return currentState.isDehydrated; 6017} 6018 6019var _attemptSynchronousHydration; 6020 6021function setAttemptSynchronousHydration(fn) { 6022 _attemptSynchronousHydration = fn; 6023} 6024function attemptSynchronousHydration(fiber) { 6025 _attemptSynchronousHydration(fiber); 6026} 6027var attemptContinuousHydration; 6028function setAttemptContinuousHydration(fn) { 6029 attemptContinuousHydration = fn; 6030} 6031var attemptHydrationAtCurrentPriority; 6032function setAttemptHydrationAtCurrentPriority(fn) { 6033 attemptHydrationAtCurrentPriority = fn; 6034} 6035var getCurrentUpdatePriority$1; 6036function setGetCurrentUpdatePriority(fn) { 6037 getCurrentUpdatePriority$1 = fn; 6038} 6039var attemptHydrationAtPriority; 6040function setAttemptHydrationAtPriority(fn) { 6041 attemptHydrationAtPriority = fn; 6042} // TODO: Upgrade this definition once we're on a newer version of Flow that 6043// has this definition built-in. 6044 6045var hasScheduledReplayAttempt = false; // The queue of discrete events to be replayed. 6046 6047var queuedDiscreteEvents = []; // Indicates if any continuous event targets are non-null for early bailout. 6048// if the last target was dehydrated. 6049 6050var queuedFocus = null; 6051var queuedDrag = null; 6052var queuedMouse = null; // For pointer events there can be one latest event per pointerId. 6053 6054var queuedPointers = new Map(); 6055var queuedPointerCaptures = new Map(); // We could consider replaying selectionchange and touchmoves too. 6056 6057var queuedExplicitHydrationTargets = []; 6058var discreteReplayableEvents = ['mousedown', 'mouseup', 'touchcancel', 'touchend', 'touchstart', 'auxclick', 'dblclick', 'pointercancel', 'pointerdown', 'pointerup', 'dragend', 'dragstart', 'drop', 'compositionend', 'compositionstart', 'keydown', 'keypress', 'keyup', 'input', 'textInput', // Intentionally camelCase 6059'copy', 'cut', 'paste', 'click', 'change', 'contextmenu', 'reset', 'submit']; 6060function isDiscreteEventThatRequiresHydration(eventType) { 6061 return discreteReplayableEvents.indexOf(eventType) > -1; 6062} 6063 6064function createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) { 6065 return { 6066 blockedOn: blockedOn, 6067 domEventName: domEventName, 6068 eventSystemFlags: eventSystemFlags, 6069 nativeEvent: nativeEvent, 6070 targetContainers: [targetContainer] 6071 }; 6072} 6073 6074function clearIfContinuousEvent(domEventName, nativeEvent) { 6075 switch (domEventName) { 6076 case 'focusin': 6077 case 'focusout': 6078 queuedFocus = null; 6079 break; 6080 6081 case 'dragenter': 6082 case 'dragleave': 6083 queuedDrag = null; 6084 break; 6085 6086 case 'mouseover': 6087 case 'mouseout': 6088 queuedMouse = null; 6089 break; 6090 6091 case 'pointerover': 6092 case 'pointerout': 6093 { 6094 var pointerId = nativeEvent.pointerId; 6095 queuedPointers.delete(pointerId); 6096 break; 6097 } 6098 6099 case 'gotpointercapture': 6100 case 'lostpointercapture': 6101 { 6102 var _pointerId = nativeEvent.pointerId; 6103 queuedPointerCaptures.delete(_pointerId); 6104 break; 6105 } 6106 } 6107} 6108 6109function accumulateOrCreateContinuousQueuedReplayableEvent(existingQueuedEvent, blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) { 6110 if (existingQueuedEvent === null || existingQueuedEvent.nativeEvent !== nativeEvent) { 6111 var queuedEvent = createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent); 6112 6113 if (blockedOn !== null) { 6114 var _fiber2 = getInstanceFromNode(blockedOn); 6115 6116 if (_fiber2 !== null) { 6117 // Attempt to increase the priority of this target. 6118 attemptContinuousHydration(_fiber2); 6119 } 6120 } 6121 6122 return queuedEvent; 6123 } // If we have already queued this exact event, then it's because 6124 // the different event systems have different DOM event listeners. 6125 // We can accumulate the flags, and the targetContainers, and 6126 // store a single event to be replayed. 6127 6128 6129 existingQueuedEvent.eventSystemFlags |= eventSystemFlags; 6130 var targetContainers = existingQueuedEvent.targetContainers; 6131 6132 if (targetContainer !== null && targetContainers.indexOf(targetContainer) === -1) { 6133 targetContainers.push(targetContainer); 6134 } 6135 6136 return existingQueuedEvent; 6137} 6138 6139function queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) { 6140 // These set relatedTarget to null because the replayed event will be treated as if we 6141 // moved from outside the window (no target) onto the target once it hydrates. 6142 // Instead of mutating we could clone the event. 6143 switch (domEventName) { 6144 case 'focusin': 6145 { 6146 var focusEvent = nativeEvent; 6147 queuedFocus = accumulateOrCreateContinuousQueuedReplayableEvent(queuedFocus, blockedOn, domEventName, eventSystemFlags, targetContainer, focusEvent); 6148 return true; 6149 } 6150 6151 case 'dragenter': 6152 { 6153 var dragEvent = nativeEvent; 6154 queuedDrag = accumulateOrCreateContinuousQueuedReplayableEvent(queuedDrag, blockedOn, domEventName, eventSystemFlags, targetContainer, dragEvent); 6155 return true; 6156 } 6157 6158 case 'mouseover': 6159 { 6160 var mouseEvent = nativeEvent; 6161 queuedMouse = accumulateOrCreateContinuousQueuedReplayableEvent(queuedMouse, blockedOn, domEventName, eventSystemFlags, targetContainer, mouseEvent); 6162 return true; 6163 } 6164 6165 case 'pointerover': 6166 { 6167 var pointerEvent = nativeEvent; 6168 var pointerId = pointerEvent.pointerId; 6169 queuedPointers.set(pointerId, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointers.get(pointerId) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, pointerEvent)); 6170 return true; 6171 } 6172 6173 case 'gotpointercapture': 6174 { 6175 var _pointerEvent = nativeEvent; 6176 var _pointerId2 = _pointerEvent.pointerId; 6177 queuedPointerCaptures.set(_pointerId2, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointerCaptures.get(_pointerId2) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, _pointerEvent)); 6178 return true; 6179 } 6180 } 6181 6182 return false; 6183} // Check if this target is unblocked. Returns true if it's unblocked. 6184 6185function attemptExplicitHydrationTarget(queuedTarget) { 6186 // TODO: This function shares a lot of logic with findInstanceBlockingEvent. 6187 // Try to unify them. It's a bit tricky since it would require two return 6188 // values. 6189 var targetInst = getClosestInstanceFromNode(queuedTarget.target); 6190 6191 if (targetInst !== null) { 6192 var nearestMounted = getNearestMountedFiber(targetInst); 6193 6194 if (nearestMounted !== null) { 6195 var tag = nearestMounted.tag; 6196 6197 if (tag === SuspenseComponent) { 6198 var instance = getSuspenseInstanceFromFiber(nearestMounted); 6199 6200 if (instance !== null) { 6201 // We're blocked on hydrating this boundary. 6202 // Increase its priority. 6203 queuedTarget.blockedOn = instance; 6204 attemptHydrationAtPriority(queuedTarget.priority, function () { 6205 attemptHydrationAtCurrentPriority(nearestMounted); 6206 }); 6207 return; 6208 } 6209 } else if (tag === HostRoot) { 6210 var root = nearestMounted.stateNode; 6211 6212 if (isRootDehydrated(root)) { 6213 queuedTarget.blockedOn = getContainerFromFiber(nearestMounted); // We don't currently have a way to increase the priority of 6214 // a root other than sync. 6215 6216 return; 6217 } 6218 } 6219 } 6220 } 6221 6222 queuedTarget.blockedOn = null; 6223} 6224 6225function queueExplicitHydrationTarget(target) { 6226 // TODO: This will read the priority if it's dispatched by the React 6227 // event system but not native events. Should read window.event.type, like 6228 // we do for updates (getCurrentEventPriority). 6229 var updatePriority = getCurrentUpdatePriority$1(); 6230 var queuedTarget = { 6231 blockedOn: null, 6232 target: target, 6233 priority: updatePriority 6234 }; 6235 var i = 0; 6236 6237 for (; i < queuedExplicitHydrationTargets.length; i++) { 6238 // Stop once we hit the first target with lower priority than 6239 if (!isHigherEventPriority(updatePriority, queuedExplicitHydrationTargets[i].priority)) { 6240 break; 6241 } 6242 } 6243 6244 queuedExplicitHydrationTargets.splice(i, 0, queuedTarget); 6245 6246 if (i === 0) { 6247 attemptExplicitHydrationTarget(queuedTarget); 6248 } 6249} 6250 6251function attemptReplayContinuousQueuedEvent(queuedEvent) { 6252 if (queuedEvent.blockedOn !== null) { 6253 return false; 6254 } 6255 6256 var targetContainers = queuedEvent.targetContainers; 6257 6258 while (targetContainers.length > 0) { 6259 var targetContainer = targetContainers[0]; 6260 var nextBlockedOn = findInstanceBlockingEvent(queuedEvent.domEventName, queuedEvent.eventSystemFlags, targetContainer, queuedEvent.nativeEvent); 6261 6262 if (nextBlockedOn === null) { 6263 { 6264 var nativeEvent = queuedEvent.nativeEvent; 6265 var nativeEventClone = new nativeEvent.constructor(nativeEvent.type, nativeEvent); 6266 setReplayingEvent(nativeEventClone); 6267 nativeEvent.target.dispatchEvent(nativeEventClone); 6268 resetReplayingEvent(); 6269 } 6270 } else { 6271 // We're still blocked. Try again later. 6272 var _fiber3 = getInstanceFromNode(nextBlockedOn); 6273 6274 if (_fiber3 !== null) { 6275 attemptContinuousHydration(_fiber3); 6276 } 6277 6278 queuedEvent.blockedOn = nextBlockedOn; 6279 return false; 6280 } // This target container was successfully dispatched. Try the next. 6281 6282 6283 targetContainers.shift(); 6284 } 6285 6286 return true; 6287} 6288 6289function attemptReplayContinuousQueuedEventInMap(queuedEvent, key, map) { 6290 if (attemptReplayContinuousQueuedEvent(queuedEvent)) { 6291 map.delete(key); 6292 } 6293} 6294 6295function replayUnblockedEvents() { 6296 hasScheduledReplayAttempt = false; 6297 6298 6299 if (queuedFocus !== null && attemptReplayContinuousQueuedEvent(queuedFocus)) { 6300 queuedFocus = null; 6301 } 6302 6303 if (queuedDrag !== null && attemptReplayContinuousQueuedEvent(queuedDrag)) { 6304 queuedDrag = null; 6305 } 6306 6307 if (queuedMouse !== null && attemptReplayContinuousQueuedEvent(queuedMouse)) { 6308 queuedMouse = null; 6309 } 6310 6311 queuedPointers.forEach(attemptReplayContinuousQueuedEventInMap); 6312 queuedPointerCaptures.forEach(attemptReplayContinuousQueuedEventInMap); 6313} 6314 6315function scheduleCallbackIfUnblocked(queuedEvent, unblocked) { 6316 if (queuedEvent.blockedOn === unblocked) { 6317 queuedEvent.blockedOn = null; 6318 6319 if (!hasScheduledReplayAttempt) { 6320 hasScheduledReplayAttempt = true; // Schedule a callback to attempt replaying as many events as are 6321 // now unblocked. This first might not actually be unblocked yet. 6322 // We could check it early to avoid scheduling an unnecessary callback. 6323 6324 Scheduler.unstable_scheduleCallback(Scheduler.unstable_NormalPriority, replayUnblockedEvents); 6325 } 6326 } 6327} 6328 6329function retryIfBlockedOn(unblocked) { 6330 // Mark anything that was blocked on this as no longer blocked 6331 // and eligible for a replay. 6332 if (queuedDiscreteEvents.length > 0) { 6333 scheduleCallbackIfUnblocked(queuedDiscreteEvents[0], unblocked); // This is a exponential search for each boundary that commits. I think it's 6334 // worth it because we expect very few discrete events to queue up and once 6335 // we are actually fully unblocked it will be fast to replay them. 6336 6337 for (var i = 1; i < queuedDiscreteEvents.length; i++) { 6338 var queuedEvent = queuedDiscreteEvents[i]; 6339 6340 if (queuedEvent.blockedOn === unblocked) { 6341 queuedEvent.blockedOn = null; 6342 } 6343 } 6344 } 6345 6346 if (queuedFocus !== null) { 6347 scheduleCallbackIfUnblocked(queuedFocus, unblocked); 6348 } 6349 6350 if (queuedDrag !== null) { 6351 scheduleCallbackIfUnblocked(queuedDrag, unblocked); 6352 } 6353 6354 if (queuedMouse !== null) { 6355 scheduleCallbackIfUnblocked(queuedMouse, unblocked); 6356 } 6357 6358 var unblock = function (queuedEvent) { 6359 return scheduleCallbackIfUnblocked(queuedEvent, unblocked); 6360 }; 6361 6362 queuedPointers.forEach(unblock); 6363 queuedPointerCaptures.forEach(unblock); 6364 6365 for (var _i = 0; _i < queuedExplicitHydrationTargets.length; _i++) { 6366 var queuedTarget = queuedExplicitHydrationTargets[_i]; 6367 6368 if (queuedTarget.blockedOn === unblocked) { 6369 queuedTarget.blockedOn = null; 6370 } 6371 } 6372 6373 while (queuedExplicitHydrationTargets.length > 0) { 6374 var nextExplicitTarget = queuedExplicitHydrationTargets[0]; 6375 6376 if (nextExplicitTarget.blockedOn !== null) { 6377 // We're still blocked. 6378 break; 6379 } else { 6380 attemptExplicitHydrationTarget(nextExplicitTarget); 6381 6382 if (nextExplicitTarget.blockedOn === null) { 6383 // We're unblocked. 6384 queuedExplicitHydrationTargets.shift(); 6385 } 6386 } 6387 } 6388} 6389 6390var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; // TODO: can we stop exporting these? 6391 6392var _enabled = true; // This is exported in FB builds for use by legacy FB layer infra. 6393// We'd like to remove this but it's not clear if this is safe. 6394 6395function setEnabled(enabled) { 6396 _enabled = !!enabled; 6397} 6398function isEnabled() { 6399 return _enabled; 6400} 6401function createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags) { 6402 var eventPriority = getEventPriority(domEventName); 6403 var listenerWrapper; 6404 6405 switch (eventPriority) { 6406 case DiscreteEventPriority: 6407 listenerWrapper = dispatchDiscreteEvent; 6408 break; 6409 6410 case ContinuousEventPriority: 6411 listenerWrapper = dispatchContinuousEvent; 6412 break; 6413 6414 case DefaultEventPriority: 6415 default: 6416 listenerWrapper = dispatchEvent; 6417 break; 6418 } 6419 6420 return listenerWrapper.bind(null, domEventName, eventSystemFlags, targetContainer); 6421} 6422 6423function dispatchDiscreteEvent(domEventName, eventSystemFlags, container, nativeEvent) { 6424 var previousPriority = getCurrentUpdatePriority(); 6425 var prevTransition = ReactCurrentBatchConfig.transition; 6426 ReactCurrentBatchConfig.transition = null; 6427 6428 try { 6429 setCurrentUpdatePriority(DiscreteEventPriority); 6430 dispatchEvent(domEventName, eventSystemFlags, container, nativeEvent); 6431 } finally { 6432 setCurrentUpdatePriority(previousPriority); 6433 ReactCurrentBatchConfig.transition = prevTransition; 6434 } 6435} 6436 6437function dispatchContinuousEvent(domEventName, eventSystemFlags, container, nativeEvent) { 6438 var previousPriority = getCurrentUpdatePriority(); 6439 var prevTransition = ReactCurrentBatchConfig.transition; 6440 ReactCurrentBatchConfig.transition = null; 6441 6442 try { 6443 setCurrentUpdatePriority(ContinuousEventPriority); 6444 dispatchEvent(domEventName, eventSystemFlags, container, nativeEvent); 6445 } finally { 6446 setCurrentUpdatePriority(previousPriority); 6447 ReactCurrentBatchConfig.transition = prevTransition; 6448 } 6449} 6450 6451function dispatchEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) { 6452 if (!_enabled) { 6453 return; 6454 } 6455 6456 { 6457 dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay(domEventName, eventSystemFlags, targetContainer, nativeEvent); 6458 } 6459} 6460 6461function dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay(domEventName, eventSystemFlags, targetContainer, nativeEvent) { 6462 var blockedOn = findInstanceBlockingEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent); 6463 6464 if (blockedOn === null) { 6465 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, return_targetInst, targetContainer); 6466 clearIfContinuousEvent(domEventName, nativeEvent); 6467 return; 6468 } 6469 6470 if (queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent)) { 6471 nativeEvent.stopPropagation(); 6472 return; 6473 } // We need to clear only if we didn't queue because 6474 // queueing is accumulative. 6475 6476 6477 clearIfContinuousEvent(domEventName, nativeEvent); 6478 6479 if (eventSystemFlags & IS_CAPTURE_PHASE && isDiscreteEventThatRequiresHydration(domEventName)) { 6480 while (blockedOn !== null) { 6481 var fiber = getInstanceFromNode(blockedOn); 6482 6483 if (fiber !== null) { 6484 attemptSynchronousHydration(fiber); 6485 } 6486 6487 var nextBlockedOn = findInstanceBlockingEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent); 6488 6489 if (nextBlockedOn === null) { 6490 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, return_targetInst, targetContainer); 6491 } 6492 6493 if (nextBlockedOn === blockedOn) { 6494 break; 6495 } 6496 6497 blockedOn = nextBlockedOn; 6498 } 6499 6500 if (blockedOn !== null) { 6501 nativeEvent.stopPropagation(); 6502 } 6503 6504 return; 6505 } // This is not replayable so we'll invoke it but without a target, 6506 // in case the event system needs to trace it. 6507 6508 6509 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, null, targetContainer); 6510} 6511 6512var return_targetInst = null; // Returns a SuspenseInstance or Container if it's blocked. 6513// The return_targetInst field above is conceptually part of the return value. 6514 6515function findInstanceBlockingEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) { 6516 // TODO: Warn if _enabled is false. 6517 return_targetInst = null; 6518 var nativeEventTarget = getEventTarget(nativeEvent); 6519 var targetInst = getClosestInstanceFromNode(nativeEventTarget); 6520 6521 if (targetInst !== null) { 6522 var nearestMounted = getNearestMountedFiber(targetInst); 6523 6524 if (nearestMounted === null) { 6525 // This tree has been unmounted already. Dispatch without a target. 6526 targetInst = null; 6527 } else { 6528 var tag = nearestMounted.tag; 6529 6530 if (tag === SuspenseComponent) { 6531 var instance = getSuspenseInstanceFromFiber(nearestMounted); 6532 6533 if (instance !== null) { 6534 // Queue the event to be replayed later. Abort dispatching since we 6535 // don't want this event dispatched twice through the event system. 6536 // TODO: If this is the first discrete event in the queue. Schedule an increased 6537 // priority for this boundary. 6538 return instance; 6539 } // This shouldn't happen, something went wrong but to avoid blocking 6540 // the whole system, dispatch the event without a target. 6541 // TODO: Warn. 6542 6543 6544 targetInst = null; 6545 } else if (tag === HostRoot) { 6546 var root = nearestMounted.stateNode; 6547 6548 if (isRootDehydrated(root)) { 6549 // If this happens during a replay something went wrong and it might block 6550 // the whole system. 6551 return getContainerFromFiber(nearestMounted); 6552 } 6553 6554 targetInst = null; 6555 } else if (nearestMounted !== targetInst) { 6556 // If we get an event (ex: img onload) before committing that 6557 // component's mount, ignore it for now (that is, treat it as if it was an 6558 // event on a non-React tree). We might also consider queueing events and 6559 // dispatching them after the mount. 6560 targetInst = null; 6561 } 6562 } 6563 } 6564 6565 return_targetInst = targetInst; // We're not blocked on anything. 6566 6567 return null; 6568} 6569function getEventPriority(domEventName) { 6570 switch (domEventName) { 6571 // Used by SimpleEventPlugin: 6572 case 'cancel': 6573 case 'click': 6574 case 'close': 6575 case 'contextmenu': 6576 case 'copy': 6577 case 'cut': 6578 case 'auxclick': 6579 case 'dblclick': 6580 case 'dragend': 6581 case 'dragstart': 6582 case 'drop': 6583 case 'focusin': 6584 case 'focusout': 6585 case 'input': 6586 case 'invalid': 6587 case 'keydown': 6588 case 'keypress': 6589 case 'keyup': 6590 case 'mousedown': 6591 case 'mouseup': 6592 case 'paste': 6593 case 'pause': 6594 case 'play': 6595 case 'pointercancel': 6596 case 'pointerdown': 6597 case 'pointerup': 6598 case 'ratechange': 6599 case 'reset': 6600 case 'resize': 6601 case 'seeked': 6602 case 'submit': 6603 case 'touchcancel': 6604 case 'touchend': 6605 case 'touchstart': 6606 case 'volumechange': // Used by polyfills: 6607 // eslint-disable-next-line no-fallthrough 6608 6609 case 'change': 6610 case 'selectionchange': 6611 case 'textInput': 6612 case 'compositionstart': 6613 case 'compositionend': 6614 case 'compositionupdate': // Only enableCreateEventHandleAPI: 6615 // eslint-disable-next-line no-fallthrough 6616 6617 case 'beforeblur': 6618 case 'afterblur': // Not used by React but could be by user code: 6619 // eslint-disable-next-line no-fallthrough 6620 6621 case 'beforeinput': 6622 case 'blur': 6623 case 'fullscreenchange': 6624 case 'focus': 6625 case 'hashchange': 6626 case 'popstate': 6627 case 'select': 6628 case 'selectstart': 6629 return DiscreteEventPriority; 6630 6631 case 'drag': 6632 case 'dragenter': 6633 case 'dragexit': 6634 case 'dragleave': 6635 case 'dragover': 6636 case 'mousemove': 6637 case 'mouseout': 6638 case 'mouseover': 6639 case 'pointermove': 6640 case 'pointerout': 6641 case 'pointerover': 6642 case 'scroll': 6643 case 'toggle': 6644 case 'touchmove': 6645 case 'wheel': // Not used by React but could be by user code: 6646 // eslint-disable-next-line no-fallthrough 6647 6648 case 'mouseenter': 6649 case 'mouseleave': 6650 case 'pointerenter': 6651 case 'pointerleave': 6652 return ContinuousEventPriority; 6653 6654 case 'message': 6655 { 6656 // We might be in the Scheduler callback. 6657 // Eventually this mechanism will be replaced by a check 6658 // of the current priority on the native scheduler. 6659 var schedulerPriority = getCurrentPriorityLevel(); 6660 6661 switch (schedulerPriority) { 6662 case ImmediatePriority: 6663 return DiscreteEventPriority; 6664 6665 case UserBlockingPriority: 6666 return ContinuousEventPriority; 6667 6668 case NormalPriority: 6669 case LowPriority: 6670 // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration. 6671 return DefaultEventPriority; 6672 6673 case IdlePriority: 6674 return IdleEventPriority; 6675 6676 default: 6677 return DefaultEventPriority; 6678 } 6679 } 6680 6681 default: 6682 return DefaultEventPriority; 6683 } 6684} 6685 6686function addEventBubbleListener(target, eventType, listener) { 6687 target.addEventListener(eventType, listener, false); 6688 return listener; 6689} 6690function addEventCaptureListener(target, eventType, listener) { 6691 target.addEventListener(eventType, listener, true); 6692 return listener; 6693} 6694function addEventCaptureListenerWithPassiveFlag(target, eventType, listener, passive) { 6695 target.addEventListener(eventType, listener, { 6696 capture: true, 6697 passive: passive 6698 }); 6699 return listener; 6700} 6701function addEventBubbleListenerWithPassiveFlag(target, eventType, listener, passive) { 6702 target.addEventListener(eventType, listener, { 6703 passive: passive 6704 }); 6705 return listener; 6706} 6707 6708/** 6709 * These variables store information about text content of a target node, 6710 * allowing comparison of content before and after a given event. 6711 * 6712 * Identify the node where selection currently begins, then observe 6713 * both its text content and its current position in the DOM. Since the 6714 * browser may natively replace the target node during composition, we can 6715 * use its position to find its replacement. 6716 * 6717 * 6718 */ 6719var root = null; 6720var startText = null; 6721var fallbackText = null; 6722function initialize(nativeEventTarget) { 6723 root = nativeEventTarget; 6724 startText = getText(); 6725 return true; 6726} 6727function reset() { 6728 root = null; 6729 startText = null; 6730 fallbackText = null; 6731} 6732function getData() { 6733 if (fallbackText) { 6734 return fallbackText; 6735 } 6736 6737 var start; 6738 var startValue = startText; 6739 var startLength = startValue.length; 6740 var end; 6741 var endValue = getText(); 6742 var endLength = endValue.length; 6743 6744 for (start = 0; start < startLength; start++) { 6745 if (startValue[start] !== endValue[start]) { 6746 break; 6747 } 6748 } 6749 6750 var minEnd = startLength - start; 6751 6752 for (end = 1; end <= minEnd; end++) { 6753 if (startValue[startLength - end] !== endValue[endLength - end]) { 6754 break; 6755 } 6756 } 6757 6758 var sliceTail = end > 1 ? 1 - end : undefined; 6759 fallbackText = endValue.slice(start, sliceTail); 6760 return fallbackText; 6761} 6762function getText() { 6763 if ('value' in root) { 6764 return root.value; 6765 } 6766 6767 return root.textContent; 6768} 6769 6770/** 6771 * `charCode` represents the actual "character code" and is safe to use with 6772 * `String.fromCharCode`. As such, only keys that correspond to printable 6773 * characters produce a valid `charCode`, the only exception to this is Enter. 6774 * The Tab-key is considered non-printable and does not have a `charCode`, 6775 * presumably because it does not produce a tab-character in browsers. 6776 * 6777 * @param {object} nativeEvent Native browser event. 6778 * @return {number} Normalized `charCode` property. 6779 */ 6780function getEventCharCode(nativeEvent) { 6781 var charCode; 6782 var keyCode = nativeEvent.keyCode; 6783 6784 if ('charCode' in nativeEvent) { 6785 charCode = nativeEvent.charCode; // FF does not set `charCode` for the Enter-key, check against `keyCode`. 6786 6787 if (charCode === 0 && keyCode === 13) { 6788 charCode = 13; 6789 } 6790 } else { 6791 // IE8 does not implement `charCode`, but `keyCode` has the correct value. 6792 charCode = keyCode; 6793 } // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux) 6794 // report Enter as charCode 10 when ctrl is pressed. 6795 6796 6797 if (charCode === 10) { 6798 charCode = 13; 6799 } // Some non-printable keys are reported in `charCode`/`keyCode`, discard them. 6800 // Must not discard the (non-)printable Enter-key. 6801 6802 6803 if (charCode >= 32 || charCode === 13) { 6804 return charCode; 6805 } 6806 6807 return 0; 6808} 6809 6810function functionThatReturnsTrue() { 6811 return true; 6812} 6813 6814function functionThatReturnsFalse() { 6815 return false; 6816} // This is intentionally a factory so that we have different returned constructors. 6817// If we had a single constructor, it would be megamorphic and engines would deopt. 6818 6819 6820function createSyntheticEvent(Interface) { 6821 /** 6822 * Synthetic events are dispatched by event plugins, typically in response to a 6823 * top-level event delegation handler. 6824 * 6825 * These systems should generally use pooling to reduce the frequency of garbage 6826 * collection. The system should check `isPersistent` to determine whether the 6827 * event should be released into the pool after being dispatched. Users that 6828 * need a persisted event should invoke `persist`. 6829 * 6830 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by 6831 * normalizing browser quirks. Subclasses do not necessarily have to implement a 6832 * DOM interface; custom application-specific events can also subclass this. 6833 */ 6834 function SyntheticBaseEvent(reactName, reactEventType, targetInst, nativeEvent, nativeEventTarget) { 6835 this._reactName = reactName; 6836 this._targetInst = targetInst; 6837 this.type = reactEventType; 6838 this.nativeEvent = nativeEvent; 6839 this.target = nativeEventTarget; 6840 this.currentTarget = null; 6841 6842 for (var _propName in Interface) { 6843 if (!Interface.hasOwnProperty(_propName)) { 6844 continue; 6845 } 6846 6847 var normalize = Interface[_propName]; 6848 6849 if (normalize) { 6850 this[_propName] = normalize(nativeEvent); 6851 } else { 6852 this[_propName] = nativeEvent[_propName]; 6853 } 6854 } 6855 6856 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false; 6857 6858 if (defaultPrevented) { 6859 this.isDefaultPrevented = functionThatReturnsTrue; 6860 } else { 6861 this.isDefaultPrevented = functionThatReturnsFalse; 6862 } 6863 6864 this.isPropagationStopped = functionThatReturnsFalse; 6865 return this; 6866 } 6867 6868 assign(SyntheticBaseEvent.prototype, { 6869 preventDefault: function () { 6870 this.defaultPrevented = true; 6871 var event = this.nativeEvent; 6872 6873 if (!event) { 6874 return; 6875 } 6876 6877 if (event.preventDefault) { 6878 event.preventDefault(); // $FlowFixMe - flow is not aware of `unknown` in IE 6879 } else if (typeof event.returnValue !== 'unknown') { 6880 event.returnValue = false; 6881 } 6882 6883 this.isDefaultPrevented = functionThatReturnsTrue; 6884 }, 6885 stopPropagation: function () { 6886 var event = this.nativeEvent; 6887 6888 if (!event) { 6889 return; 6890 } 6891 6892 if (event.stopPropagation) { 6893 event.stopPropagation(); // $FlowFixMe - flow is not aware of `unknown` in IE 6894 } else if (typeof event.cancelBubble !== 'unknown') { 6895 // The ChangeEventPlugin registers a "propertychange" event for 6896 // IE. This event does not support bubbling or cancelling, and 6897 // any references to cancelBubble throw "Member not found". A 6898 // typeof check of "unknown" circumvents this issue (and is also 6899 // IE specific). 6900 event.cancelBubble = true; 6901 } 6902 6903 this.isPropagationStopped = functionThatReturnsTrue; 6904 }, 6905 6906 /** 6907 * We release all dispatched `SyntheticEvent`s after each event loop, adding 6908 * them back into the pool. This allows a way to hold onto a reference that 6909 * won't be added back into the pool. 6910 */ 6911 persist: function () {// Modern event system doesn't use pooling. 6912 }, 6913 6914 /** 6915 * Checks if this event should be released back into the pool. 6916 * 6917 * @return {boolean} True if this should not be released, false otherwise. 6918 */ 6919 isPersistent: functionThatReturnsTrue 6920 }); 6921 return SyntheticBaseEvent; 6922} 6923/** 6924 * @interface Event 6925 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 6926 */ 6927 6928 6929var EventInterface = { 6930 eventPhase: 0, 6931 bubbles: 0, 6932 cancelable: 0, 6933 timeStamp: function (event) { 6934 return event.timeStamp || Date.now(); 6935 }, 6936 defaultPrevented: 0, 6937 isTrusted: 0 6938}; 6939var SyntheticEvent = createSyntheticEvent(EventInterface); 6940 6941var UIEventInterface = assign({}, EventInterface, { 6942 view: 0, 6943 detail: 0 6944}); 6945 6946var SyntheticUIEvent = createSyntheticEvent(UIEventInterface); 6947var lastMovementX; 6948var lastMovementY; 6949var lastMouseEvent; 6950 6951function updateMouseMovementPolyfillState(event) { 6952 if (event !== lastMouseEvent) { 6953 if (lastMouseEvent && event.type === 'mousemove') { 6954 lastMovementX = event.screenX - lastMouseEvent.screenX; 6955 lastMovementY = event.screenY - lastMouseEvent.screenY; 6956 } else { 6957 lastMovementX = 0; 6958 lastMovementY = 0; 6959 } 6960 6961 lastMouseEvent = event; 6962 } 6963} 6964/** 6965 * @interface MouseEvent 6966 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 6967 */ 6968 6969 6970var MouseEventInterface = assign({}, UIEventInterface, { 6971 screenX: 0, 6972 screenY: 0, 6973 clientX: 0, 6974 clientY: 0, 6975 pageX: 0, 6976 pageY: 0, 6977 ctrlKey: 0, 6978 shiftKey: 0, 6979 altKey: 0, 6980 metaKey: 0, 6981 getModifierState: getEventModifierState, 6982 button: 0, 6983 buttons: 0, 6984 relatedTarget: function (event) { 6985 if (event.relatedTarget === undefined) return event.fromElement === event.srcElement ? event.toElement : event.fromElement; 6986 return event.relatedTarget; 6987 }, 6988 movementX: function (event) { 6989 if ('movementX' in event) { 6990 return event.movementX; 6991 } 6992 6993 updateMouseMovementPolyfillState(event); 6994 return lastMovementX; 6995 }, 6996 movementY: function (event) { 6997 if ('movementY' in event) { 6998 return event.movementY; 6999 } // Don't need to call updateMouseMovementPolyfillState() here 7000 // because it's guaranteed to have already run when movementX 7001 // was copied. 7002 7003 7004 return lastMovementY; 7005 } 7006}); 7007 7008var SyntheticMouseEvent = createSyntheticEvent(MouseEventInterface); 7009/** 7010 * @interface DragEvent 7011 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 7012 */ 7013 7014var DragEventInterface = assign({}, MouseEventInterface, { 7015 dataTransfer: 0 7016}); 7017 7018var SyntheticDragEvent = createSyntheticEvent(DragEventInterface); 7019/** 7020 * @interface FocusEvent 7021 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 7022 */ 7023 7024var FocusEventInterface = assign({}, UIEventInterface, { 7025 relatedTarget: 0 7026}); 7027 7028var SyntheticFocusEvent = createSyntheticEvent(FocusEventInterface); 7029/** 7030 * @interface Event 7031 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface 7032 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent 7033 */ 7034 7035var AnimationEventInterface = assign({}, EventInterface, { 7036 animationName: 0, 7037 elapsedTime: 0, 7038 pseudoElement: 0 7039}); 7040 7041var SyntheticAnimationEvent = createSyntheticEvent(AnimationEventInterface); 7042/** 7043 * @interface Event 7044 * @see http://www.w3.org/TR/clipboard-apis/ 7045 */ 7046 7047var ClipboardEventInterface = assign({}, EventInterface, { 7048 clipboardData: function (event) { 7049 return 'clipboardData' in event ? event.clipboardData : window.clipboardData; 7050 } 7051}); 7052 7053var SyntheticClipboardEvent = createSyntheticEvent(ClipboardEventInterface); 7054/** 7055 * @interface Event 7056 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents 7057 */ 7058 7059var CompositionEventInterface = assign({}, EventInterface, { 7060 data: 0 7061}); 7062 7063var SyntheticCompositionEvent = createSyntheticEvent(CompositionEventInterface); 7064/** 7065 * @interface Event 7066 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105 7067 * /#events-inputevents 7068 */ 7069// Happens to share the same list for now. 7070 7071var SyntheticInputEvent = SyntheticCompositionEvent; 7072/** 7073 * Normalization of deprecated HTML5 `key` values 7074 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names 7075 */ 7076 7077var normalizeKey = { 7078 Esc: 'Escape', 7079 Spacebar: ' ', 7080 Left: 'ArrowLeft', 7081 Up: 'ArrowUp', 7082 Right: 'ArrowRight', 7083 Down: 'ArrowDown', 7084 Del: 'Delete', 7085 Win: 'OS', 7086 Menu: 'ContextMenu', 7087 Apps: 'ContextMenu', 7088 Scroll: 'ScrollLock', 7089 MozPrintableKey: 'Unidentified' 7090}; 7091/** 7092 * Translation from legacy `keyCode` to HTML5 `key` 7093 * Only special keys supported, all others depend on keyboard layout or browser 7094 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names 7095 */ 7096 7097var translateToKey = { 7098 '8': 'Backspace', 7099 '9': 'Tab', 7100 '12': 'Clear', 7101 '13': 'Enter', 7102 '16': 'Shift', 7103 '17': 'Control', 7104 '18': 'Alt', 7105 '19': 'Pause', 7106 '20': 'CapsLock', 7107 '27': 'Escape', 7108 '32': ' ', 7109 '33': 'PageUp', 7110 '34': 'PageDown', 7111 '35': 'End', 7112 '36': 'Home', 7113 '37': 'ArrowLeft', 7114 '38': 'ArrowUp', 7115 '39': 'ArrowRight', 7116 '40': 'ArrowDown', 7117 '45': 'Insert', 7118 '46': 'Delete', 7119 '112': 'F1', 7120 '113': 'F2', 7121 '114': 'F3', 7122 '115': 'F4', 7123 '116': 'F5', 7124 '117': 'F6', 7125 '118': 'F7', 7126 '119': 'F8', 7127 '120': 'F9', 7128 '121': 'F10', 7129 '122': 'F11', 7130 '123': 'F12', 7131 '144': 'NumLock', 7132 '145': 'ScrollLock', 7133 '224': 'Meta' 7134}; 7135/** 7136 * @param {object} nativeEvent Native browser event. 7137 * @return {string} Normalized `key` property. 7138 */ 7139 7140function getEventKey(nativeEvent) { 7141 if (nativeEvent.key) { 7142 // Normalize inconsistent values reported by browsers due to 7143 // implementations of a working draft specification. 7144 // FireFox implements `key` but returns `MozPrintableKey` for all 7145 // printable characters (normalized to `Unidentified`), ignore it. 7146 var key = normalizeKey[nativeEvent.key] || nativeEvent.key; 7147 7148 if (key !== 'Unidentified') { 7149 return key; 7150 } 7151 } // Browser does not implement `key`, polyfill as much of it as we can. 7152 7153 7154 if (nativeEvent.type === 'keypress') { 7155 var charCode = getEventCharCode(nativeEvent); // The enter-key is technically both printable and non-printable and can 7156 // thus be captured by `keypress`, no other non-printable key should. 7157 7158 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode); 7159 } 7160 7161 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') { 7162 // While user keyboard layout determines the actual meaning of each 7163 // `keyCode` value, almost all function keys have a universal value. 7164 return translateToKey[nativeEvent.keyCode] || 'Unidentified'; 7165 } 7166 7167 return ''; 7168} 7169/** 7170 * Translation from modifier key to the associated property in the event. 7171 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers 7172 */ 7173 7174 7175var modifierKeyToProp = { 7176 Alt: 'altKey', 7177 Control: 'ctrlKey', 7178 Meta: 'metaKey', 7179 Shift: 'shiftKey' 7180}; // Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support 7181// getModifierState. If getModifierState is not supported, we map it to a set of 7182// modifier keys exposed by the event. In this case, Lock-keys are not supported. 7183 7184function modifierStateGetter(keyArg) { 7185 var syntheticEvent = this; 7186 var nativeEvent = syntheticEvent.nativeEvent; 7187 7188 if (nativeEvent.getModifierState) { 7189 return nativeEvent.getModifierState(keyArg); 7190 } 7191 7192 var keyProp = modifierKeyToProp[keyArg]; 7193 return keyProp ? !!nativeEvent[keyProp] : false; 7194} 7195 7196function getEventModifierState(nativeEvent) { 7197 return modifierStateGetter; 7198} 7199/** 7200 * @interface KeyboardEvent 7201 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 7202 */ 7203 7204 7205var KeyboardEventInterface = assign({}, UIEventInterface, { 7206 key: getEventKey, 7207 code: 0, 7208 location: 0, 7209 ctrlKey: 0, 7210 shiftKey: 0, 7211 altKey: 0, 7212 metaKey: 0, 7213 repeat: 0, 7214 locale: 0, 7215 getModifierState: getEventModifierState, 7216 // Legacy Interface 7217 charCode: function (event) { 7218 // `charCode` is the result of a KeyPress event and represents the value of 7219 // the actual printable character. 7220 // KeyPress is deprecated, but its replacement is not yet final and not 7221 // implemented in any major browser. Only KeyPress has charCode. 7222 if (event.type === 'keypress') { 7223 return getEventCharCode(event); 7224 } 7225 7226 return 0; 7227 }, 7228 keyCode: function (event) { 7229 // `keyCode` is the result of a KeyDown/Up event and represents the value of 7230 // physical keyboard key. 7231 // The actual meaning of the value depends on the users' keyboard layout 7232 // which cannot be detected. Assuming that it is a US keyboard layout 7233 // provides a surprisingly accurate mapping for US and European users. 7234 // Due to this, it is left to the user to implement at this time. 7235 if (event.type === 'keydown' || event.type === 'keyup') { 7236 return event.keyCode; 7237 } 7238 7239 return 0; 7240 }, 7241 which: function (event) { 7242 // `which` is an alias for either `keyCode` or `charCode` depending on the 7243 // type of the event. 7244 if (event.type === 'keypress') { 7245 return getEventCharCode(event); 7246 } 7247 7248 if (event.type === 'keydown' || event.type === 'keyup') { 7249 return event.keyCode; 7250 } 7251 7252 return 0; 7253 } 7254}); 7255 7256var SyntheticKeyboardEvent = createSyntheticEvent(KeyboardEventInterface); 7257/** 7258 * @interface PointerEvent 7259 * @see http://www.w3.org/TR/pointerevents/ 7260 */ 7261 7262var PointerEventInterface = assign({}, MouseEventInterface, { 7263 pointerId: 0, 7264 width: 0, 7265 height: 0, 7266 pressure: 0, 7267 tangentialPressure: 0, 7268 tiltX: 0, 7269 tiltY: 0, 7270 twist: 0, 7271 pointerType: 0, 7272 isPrimary: 0 7273}); 7274 7275var SyntheticPointerEvent = createSyntheticEvent(PointerEventInterface); 7276/** 7277 * @interface TouchEvent 7278 * @see http://www.w3.org/TR/touch-events/ 7279 */ 7280 7281var TouchEventInterface = assign({}, UIEventInterface, { 7282 touches: 0, 7283 targetTouches: 0, 7284 changedTouches: 0, 7285 altKey: 0, 7286 metaKey: 0, 7287 ctrlKey: 0, 7288 shiftKey: 0, 7289 getModifierState: getEventModifierState 7290}); 7291 7292var SyntheticTouchEvent = createSyntheticEvent(TouchEventInterface); 7293/** 7294 * @interface Event 7295 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events- 7296 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent 7297 */ 7298 7299var TransitionEventInterface = assign({}, EventInterface, { 7300 propertyName: 0, 7301 elapsedTime: 0, 7302 pseudoElement: 0 7303}); 7304 7305var SyntheticTransitionEvent = createSyntheticEvent(TransitionEventInterface); 7306/** 7307 * @interface WheelEvent 7308 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 7309 */ 7310 7311var WheelEventInterface = assign({}, MouseEventInterface, { 7312 deltaX: function (event) { 7313 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive). 7314 'wheelDeltaX' in event ? -event.wheelDeltaX : 0; 7315 }, 7316 deltaY: function (event) { 7317 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive). 7318 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive). 7319 'wheelDelta' in event ? -event.wheelDelta : 0; 7320 }, 7321 deltaZ: 0, 7322 // Browsers without "deltaMode" is reporting in raw wheel delta where one 7323 // notch on the scroll is always +/- 120, roughly equivalent to pixels. 7324 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or 7325 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size. 7326 deltaMode: 0 7327}); 7328 7329var SyntheticWheelEvent = createSyntheticEvent(WheelEventInterface); 7330 7331var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space 7332 7333var START_KEYCODE = 229; 7334var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window; 7335var documentMode = null; 7336 7337if (canUseDOM && 'documentMode' in document) { 7338 documentMode = document.documentMode; 7339} // Webkit offers a very useful `textInput` event that can be used to 7340// directly represent `beforeInput`. The IE `textinput` event is not as 7341// useful, so we don't use it. 7342 7343 7344var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode; // In IE9+, we have access to composition events, but the data supplied 7345// by the native compositionend event may be incorrect. Japanese ideographic 7346// spaces, for instance (\u3000) are not recorded correctly. 7347 7348var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11); 7349var SPACEBAR_CODE = 32; 7350var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); 7351 7352function registerEvents() { 7353 registerTwoPhaseEvent('onBeforeInput', ['compositionend', 'keypress', 'textInput', 'paste']); 7354 registerTwoPhaseEvent('onCompositionEnd', ['compositionend', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']); 7355 registerTwoPhaseEvent('onCompositionStart', ['compositionstart', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']); 7356 registerTwoPhaseEvent('onCompositionUpdate', ['compositionupdate', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']); 7357} // Track whether we've ever handled a keypress on the space key. 7358 7359 7360var hasSpaceKeypress = false; 7361/** 7362 * Return whether a native keypress event is assumed to be a command. 7363 * This is required because Firefox fires `keypress` events for key commands 7364 * (cut, copy, select-all, etc.) even though no character is inserted. 7365 */ 7366 7367function isKeypressCommand(nativeEvent) { 7368 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && // ctrlKey && altKey is equivalent to AltGr, and is not a command. 7369 !(nativeEvent.ctrlKey && nativeEvent.altKey); 7370} 7371/** 7372 * Translate native top level events into event types. 7373 */ 7374 7375 7376function getCompositionEventType(domEventName) { 7377 switch (domEventName) { 7378 case 'compositionstart': 7379 return 'onCompositionStart'; 7380 7381 case 'compositionend': 7382 return 'onCompositionEnd'; 7383 7384 case 'compositionupdate': 7385 return 'onCompositionUpdate'; 7386 } 7387} 7388/** 7389 * Does our fallback best-guess model think this event signifies that 7390 * composition has begun? 7391 */ 7392 7393 7394function isFallbackCompositionStart(domEventName, nativeEvent) { 7395 return domEventName === 'keydown' && nativeEvent.keyCode === START_KEYCODE; 7396} 7397/** 7398 * Does our fallback mode think that this event is the end of composition? 7399 */ 7400 7401 7402function isFallbackCompositionEnd(domEventName, nativeEvent) { 7403 switch (domEventName) { 7404 case 'keyup': 7405 // Command keys insert or clear IME input. 7406 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1; 7407 7408 case 'keydown': 7409 // Expect IME keyCode on each keydown. If we get any other 7410 // code we must have exited earlier. 7411 return nativeEvent.keyCode !== START_KEYCODE; 7412 7413 case 'keypress': 7414 case 'mousedown': 7415 case 'focusout': 7416 // Events are not possible without cancelling IME. 7417 return true; 7418 7419 default: 7420 return false; 7421 } 7422} 7423/** 7424 * Google Input Tools provides composition data via a CustomEvent, 7425 * with the `data` property populated in the `detail` object. If this 7426 * is available on the event object, use it. If not, this is a plain 7427 * composition event and we have nothing special to extract. 7428 * 7429 * @param {object} nativeEvent 7430 * @return {?string} 7431 */ 7432 7433 7434function getDataFromCustomEvent(nativeEvent) { 7435 var detail = nativeEvent.detail; 7436 7437 if (typeof detail === 'object' && 'data' in detail) { 7438 return detail.data; 7439 } 7440 7441 return null; 7442} 7443/** 7444 * Check if a composition event was triggered by Korean IME. 7445 * Our fallback mode does not work well with IE's Korean IME, 7446 * so just use native composition events when Korean IME is used. 7447 * Although CompositionEvent.locale property is deprecated, 7448 * it is available in IE, where our fallback mode is enabled. 7449 * 7450 * @param {object} nativeEvent 7451 * @return {boolean} 7452 */ 7453 7454 7455function isUsingKoreanIME(nativeEvent) { 7456 return nativeEvent.locale === 'ko'; 7457} // Track the current IME composition status, if any. 7458 7459 7460var isComposing = false; 7461/** 7462 * @return {?object} A SyntheticCompositionEvent. 7463 */ 7464 7465function extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) { 7466 var eventType; 7467 var fallbackData; 7468 7469 if (canUseCompositionEvent) { 7470 eventType = getCompositionEventType(domEventName); 7471 } else if (!isComposing) { 7472 if (isFallbackCompositionStart(domEventName, nativeEvent)) { 7473 eventType = 'onCompositionStart'; 7474 } 7475 } else if (isFallbackCompositionEnd(domEventName, nativeEvent)) { 7476 eventType = 'onCompositionEnd'; 7477 } 7478 7479 if (!eventType) { 7480 return null; 7481 } 7482 7483 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) { 7484 // The current composition is stored statically and must not be 7485 // overwritten while composition continues. 7486 if (!isComposing && eventType === 'onCompositionStart') { 7487 isComposing = initialize(nativeEventTarget); 7488 } else if (eventType === 'onCompositionEnd') { 7489 if (isComposing) { 7490 fallbackData = getData(); 7491 } 7492 } 7493 } 7494 7495 var listeners = accumulateTwoPhaseListeners(targetInst, eventType); 7496 7497 if (listeners.length > 0) { 7498 var event = new SyntheticCompositionEvent(eventType, domEventName, null, nativeEvent, nativeEventTarget); 7499 dispatchQueue.push({ 7500 event: event, 7501 listeners: listeners 7502 }); 7503 7504 if (fallbackData) { 7505 // Inject data generated from fallback path into the synthetic event. 7506 // This matches the property of native CompositionEventInterface. 7507 event.data = fallbackData; 7508 } else { 7509 var customData = getDataFromCustomEvent(nativeEvent); 7510 7511 if (customData !== null) { 7512 event.data = customData; 7513 } 7514 } 7515 } 7516} 7517 7518function getNativeBeforeInputChars(domEventName, nativeEvent) { 7519 switch (domEventName) { 7520 case 'compositionend': 7521 return getDataFromCustomEvent(nativeEvent); 7522 7523 case 'keypress': 7524 /** 7525 * If native `textInput` events are available, our goal is to make 7526 * use of them. However, there is a special case: the spacebar key. 7527 * In Webkit, preventing default on a spacebar `textInput` event 7528 * cancels character insertion, but it *also* causes the browser 7529 * to fall back to its default spacebar behavior of scrolling the 7530 * page. 7531 * 7532 * Tracking at: 7533 * https://code.google.com/p/chromium/issues/detail?id=355103 7534 * 7535 * To avoid this issue, use the keypress event as if no `textInput` 7536 * event is available. 7537 */ 7538 var which = nativeEvent.which; 7539 7540 if (which !== SPACEBAR_CODE) { 7541 return null; 7542 } 7543 7544 hasSpaceKeypress = true; 7545 return SPACEBAR_CHAR; 7546 7547 case 'textInput': 7548 // Record the characters to be added to the DOM. 7549 var chars = nativeEvent.data; // If it's a spacebar character, assume that we have already handled 7550 // it at the keypress level and bail immediately. Android Chrome 7551 // doesn't give us keycodes, so we need to ignore it. 7552 7553 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) { 7554 return null; 7555 } 7556 7557 return chars; 7558 7559 default: 7560 // For other native event types, do nothing. 7561 return null; 7562 } 7563} 7564/** 7565 * For browsers that do not provide the `textInput` event, extract the 7566 * appropriate string to use for SyntheticInputEvent. 7567 */ 7568 7569 7570function getFallbackBeforeInputChars(domEventName, nativeEvent) { 7571 // If we are currently composing (IME) and using a fallback to do so, 7572 // try to extract the composed characters from the fallback object. 7573 // If composition event is available, we extract a string only at 7574 // compositionevent, otherwise extract it at fallback events. 7575 if (isComposing) { 7576 if (domEventName === 'compositionend' || !canUseCompositionEvent && isFallbackCompositionEnd(domEventName, nativeEvent)) { 7577 var chars = getData(); 7578 reset(); 7579 isComposing = false; 7580 return chars; 7581 } 7582 7583 return null; 7584 } 7585 7586 switch (domEventName) { 7587 case 'paste': 7588 // If a paste event occurs after a keypress, throw out the input 7589 // chars. Paste events should not lead to BeforeInput events. 7590 return null; 7591 7592 case 'keypress': 7593 /** 7594 * As of v27, Firefox may fire keypress events even when no character 7595 * will be inserted. A few possibilities: 7596 * 7597 * - `which` is `0`. Arrow keys, Esc key, etc. 7598 * 7599 * - `which` is the pressed key code, but no char is available. 7600 * Ex: 'AltGr + d` in Polish. There is no modified character for 7601 * this key combination and no character is inserted into the 7602 * document, but FF fires the keypress for char code `100` anyway. 7603 * No `input` event will occur. 7604 * 7605 * - `which` is the pressed key code, but a command combination is 7606 * being used. Ex: `Cmd+C`. No character is inserted, and no 7607 * `input` event will occur. 7608 */ 7609 if (!isKeypressCommand(nativeEvent)) { 7610 // IE fires the `keypress` event when a user types an emoji via 7611 // Touch keyboard of Windows. In such a case, the `char` property 7612 // holds an emoji character like `\uD83D\uDE0A`. Because its length 7613 // is 2, the property `which` does not represent an emoji correctly. 7614 // In such a case, we directly return the `char` property instead of 7615 // using `which`. 7616 if (nativeEvent.char && nativeEvent.char.length > 1) { 7617 return nativeEvent.char; 7618 } else if (nativeEvent.which) { 7619 return String.fromCharCode(nativeEvent.which); 7620 } 7621 } 7622 7623 return null; 7624 7625 case 'compositionend': 7626 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data; 7627 7628 default: 7629 return null; 7630 } 7631} 7632/** 7633 * Extract a SyntheticInputEvent for `beforeInput`, based on either native 7634 * `textInput` or fallback behavior. 7635 * 7636 * @return {?object} A SyntheticInputEvent. 7637 */ 7638 7639 7640function extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) { 7641 var chars; 7642 7643 if (canUseTextInputEvent) { 7644 chars = getNativeBeforeInputChars(domEventName, nativeEvent); 7645 } else { 7646 chars = getFallbackBeforeInputChars(domEventName, nativeEvent); 7647 } // If no characters are being inserted, no BeforeInput event should 7648 // be fired. 7649 7650 7651 if (!chars) { 7652 return null; 7653 } 7654 7655 var listeners = accumulateTwoPhaseListeners(targetInst, 'onBeforeInput'); 7656 7657 if (listeners.length > 0) { 7658 var event = new SyntheticInputEvent('onBeforeInput', 'beforeinput', null, nativeEvent, nativeEventTarget); 7659 dispatchQueue.push({ 7660 event: event, 7661 listeners: listeners 7662 }); 7663 event.data = chars; 7664 } 7665} 7666/** 7667 * Create an `onBeforeInput` event to match 7668 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents. 7669 * 7670 * This event plugin is based on the native `textInput` event 7671 * available in Chrome, Safari, Opera, and IE. This event fires after 7672 * `onKeyPress` and `onCompositionEnd`, but before `onInput`. 7673 * 7674 * `beforeInput` is spec'd but not implemented in any browsers, and 7675 * the `input` event does not provide any useful information about what has 7676 * actually been added, contrary to the spec. Thus, `textInput` is the best 7677 * available event to identify the characters that have actually been inserted 7678 * into the target node. 7679 * 7680 * This plugin is also responsible for emitting `composition` events, thus 7681 * allowing us to share composition fallback code for both `beforeInput` and 7682 * `composition` event types. 7683 */ 7684 7685 7686function extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) { 7687 extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget); 7688 extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget); 7689} 7690 7691/** 7692 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary 7693 */ 7694var supportedInputTypes = { 7695 color: true, 7696 date: true, 7697 datetime: true, 7698 'datetime-local': true, 7699 email: true, 7700 month: true, 7701 number: true, 7702 password: true, 7703 range: true, 7704 search: true, 7705 tel: true, 7706 text: true, 7707 time: true, 7708 url: true, 7709 week: true 7710}; 7711 7712function isTextInputElement(elem) { 7713 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); 7714 7715 if (nodeName === 'input') { 7716 return !!supportedInputTypes[elem.type]; 7717 } 7718 7719 if (nodeName === 'textarea') { 7720 return true; 7721 } 7722 7723 return false; 7724} 7725 7726/** 7727 * Checks if an event is supported in the current execution environment. 7728 * 7729 * NOTE: This will not work correctly for non-generic events such as `change`, 7730 * `reset`, `load`, `error`, and `select`. 7731 * 7732 * Borrows from Modernizr. 7733 * 7734 * @param {string} eventNameSuffix Event name, e.g. "click". 7735 * @return {boolean} True if the event is supported. 7736 * @internal 7737 * @license Modernizr 3.0.0pre (Custom Build) | MIT 7738 */ 7739 7740function isEventSupported(eventNameSuffix) { 7741 if (!canUseDOM) { 7742 return false; 7743 } 7744 7745 var eventName = 'on' + eventNameSuffix; 7746 var isSupported = (eventName in document); 7747 7748 if (!isSupported) { 7749 var element = document.createElement('div'); 7750 element.setAttribute(eventName, 'return;'); 7751 isSupported = typeof element[eventName] === 'function'; 7752 } 7753 7754 return isSupported; 7755} 7756 7757function registerEvents$1() { 7758 registerTwoPhaseEvent('onChange', ['change', 'click', 'focusin', 'focusout', 'input', 'keydown', 'keyup', 'selectionchange']); 7759} 7760 7761function createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, target) { 7762 // Flag this event loop as needing state restore. 7763 enqueueStateRestore(target); 7764 var listeners = accumulateTwoPhaseListeners(inst, 'onChange'); 7765 7766 if (listeners.length > 0) { 7767 var event = new SyntheticEvent('onChange', 'change', null, nativeEvent, target); 7768 dispatchQueue.push({ 7769 event: event, 7770 listeners: listeners 7771 }); 7772 } 7773} 7774/** 7775 * For IE shims 7776 */ 7777 7778 7779var activeElement = null; 7780var activeElementInst = null; 7781/** 7782 * SECTION: handle `change` event 7783 */ 7784 7785function shouldUseChangeEvent(elem) { 7786 var nodeName = elem.nodeName && elem.nodeName.toLowerCase(); 7787 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file'; 7788} 7789 7790function manualDispatchChangeEvent(nativeEvent) { 7791 var dispatchQueue = []; 7792 createAndAccumulateChangeEvent(dispatchQueue, activeElementInst, nativeEvent, getEventTarget(nativeEvent)); // If change and propertychange bubbled, we'd just bind to it like all the 7793 // other events and have it go through ReactBrowserEventEmitter. Since it 7794 // doesn't, we manually listen for the events and so we have to enqueue and 7795 // process the abstract event manually. 7796 // 7797 // Batching is necessary here in order to ensure that all event handlers run 7798 // before the next rerender (including event handlers attached to ancestor 7799 // elements instead of directly on the input). Without this, controlled 7800 // components don't work properly in conjunction with event bubbling because 7801 // the component is rerendered and the value reverted before all the event 7802 // handlers can run. See https://github.com/facebook/react/issues/708. 7803 7804 batchedUpdates(runEventInBatch, dispatchQueue); 7805} 7806 7807function runEventInBatch(dispatchQueue) { 7808 processDispatchQueue(dispatchQueue, 0); 7809} 7810 7811function getInstIfValueChanged(targetInst) { 7812 var targetNode = getNodeFromInstance(targetInst); 7813 7814 if (updateValueIfChanged(targetNode)) { 7815 return targetInst; 7816 } 7817} 7818 7819function getTargetInstForChangeEvent(domEventName, targetInst) { 7820 if (domEventName === 'change') { 7821 return targetInst; 7822 } 7823} 7824/** 7825 * SECTION: handle `input` event 7826 */ 7827 7828 7829var isInputEventSupported = false; 7830 7831if (canUseDOM) { 7832 // IE9 claims to support the input event but fails to trigger it when 7833 // deleting text, so we ignore its input events. 7834 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9); 7835} 7836/** 7837 * (For IE <=9) Starts tracking propertychange events on the passed-in element 7838 * and override the value property so that we can distinguish user events from 7839 * value changes in JS. 7840 */ 7841 7842 7843function startWatchingForValueChange(target, targetInst) { 7844 activeElement = target; 7845 activeElementInst = targetInst; 7846 activeElement.attachEvent('onpropertychange', handlePropertyChange); 7847} 7848/** 7849 * (For IE <=9) Removes the event listeners from the currently-tracked element, 7850 * if any exists. 7851 */ 7852 7853 7854function stopWatchingForValueChange() { 7855 if (!activeElement) { 7856 return; 7857 } 7858 7859 activeElement.detachEvent('onpropertychange', handlePropertyChange); 7860 activeElement = null; 7861 activeElementInst = null; 7862} 7863/** 7864 * (For IE <=9) Handles a propertychange event, sending a `change` event if 7865 * the value of the active element has changed. 7866 */ 7867 7868 7869function handlePropertyChange(nativeEvent) { 7870 if (nativeEvent.propertyName !== 'value') { 7871 return; 7872 } 7873 7874 if (getInstIfValueChanged(activeElementInst)) { 7875 manualDispatchChangeEvent(nativeEvent); 7876 } 7877} 7878 7879function handleEventsForInputEventPolyfill(domEventName, target, targetInst) { 7880 if (domEventName === 'focusin') { 7881 // In IE9, propertychange fires for most input events but is buggy and 7882 // doesn't fire when text is deleted, but conveniently, selectionchange 7883 // appears to fire in all of the remaining cases so we catch those and 7884 // forward the event if the value has changed 7885 // In either case, we don't want to call the event handler if the value 7886 // is changed from JS so we redefine a setter for `.value` that updates 7887 // our activeElementValue variable, allowing us to ignore those changes 7888 // 7889 // stopWatching() should be a noop here but we call it just in case we 7890 // missed a blur event somehow. 7891 stopWatchingForValueChange(); 7892 startWatchingForValueChange(target, targetInst); 7893 } else if (domEventName === 'focusout') { 7894 stopWatchingForValueChange(); 7895 } 7896} // For IE8 and IE9. 7897 7898 7899function getTargetInstForInputEventPolyfill(domEventName, targetInst) { 7900 if (domEventName === 'selectionchange' || domEventName === 'keyup' || domEventName === 'keydown') { 7901 // On the selectionchange event, the target is just document which isn't 7902 // helpful for us so just check activeElement instead. 7903 // 7904 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire 7905 // propertychange on the first input event after setting `value` from a 7906 // script and fires only keydown, keypress, keyup. Catching keyup usually 7907 // gets it and catching keydown lets us fire an event for the first 7908 // keystroke if user does a key repeat (it'll be a little delayed: right 7909 // before the second keystroke). Other input methods (e.g., paste) seem to 7910 // fire selectionchange normally. 7911 return getInstIfValueChanged(activeElementInst); 7912 } 7913} 7914/** 7915 * SECTION: handle `click` event 7916 */ 7917 7918 7919function shouldUseClickEvent(elem) { 7920 // Use the `click` event to detect changes to checkbox and radio inputs. 7921 // This approach works across all browsers, whereas `change` does not fire 7922 // until `blur` in IE8. 7923 var nodeName = elem.nodeName; 7924 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio'); 7925} 7926 7927function getTargetInstForClickEvent(domEventName, targetInst) { 7928 if (domEventName === 'click') { 7929 return getInstIfValueChanged(targetInst); 7930 } 7931} 7932 7933function getTargetInstForInputOrChangeEvent(domEventName, targetInst) { 7934 if (domEventName === 'input' || domEventName === 'change') { 7935 return getInstIfValueChanged(targetInst); 7936 } 7937} 7938 7939function handleControlledInputBlur(node) { 7940 var state = node._wrapperState; 7941 7942 if (!state || !state.controlled || node.type !== 'number') { 7943 return; 7944 } 7945 7946 { 7947 // If controlled, assign the value attribute to the current value on blur 7948 setDefaultValue(node, 'number', node.value); 7949 } 7950} 7951/** 7952 * This plugin creates an `onChange` event that normalizes change events 7953 * across form elements. This event fires at a time when it's possible to 7954 * change the element's value without seeing a flicker. 7955 * 7956 * Supported elements are: 7957 * - input (see `isTextInputElement`) 7958 * - textarea 7959 * - select 7960 */ 7961 7962 7963function extractEvents$1(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) { 7964 var targetNode = targetInst ? getNodeFromInstance(targetInst) : window; 7965 var getTargetInstFunc, handleEventFunc; 7966 7967 if (shouldUseChangeEvent(targetNode)) { 7968 getTargetInstFunc = getTargetInstForChangeEvent; 7969 } else if (isTextInputElement(targetNode)) { 7970 if (isInputEventSupported) { 7971 getTargetInstFunc = getTargetInstForInputOrChangeEvent; 7972 } else { 7973 getTargetInstFunc = getTargetInstForInputEventPolyfill; 7974 handleEventFunc = handleEventsForInputEventPolyfill; 7975 } 7976 } else if (shouldUseClickEvent(targetNode)) { 7977 getTargetInstFunc = getTargetInstForClickEvent; 7978 } 7979 7980 if (getTargetInstFunc) { 7981 var inst = getTargetInstFunc(domEventName, targetInst); 7982 7983 if (inst) { 7984 createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, nativeEventTarget); 7985 return; 7986 } 7987 } 7988 7989 if (handleEventFunc) { 7990 handleEventFunc(domEventName, targetNode, targetInst); 7991 } // When blurring, set the value attribute for number inputs 7992 7993 7994 if (domEventName === 'focusout') { 7995 handleControlledInputBlur(targetNode); 7996 } 7997} 7998 7999function registerEvents$2() { 8000 registerDirectEvent('onMouseEnter', ['mouseout', 'mouseover']); 8001 registerDirectEvent('onMouseLeave', ['mouseout', 'mouseover']); 8002 registerDirectEvent('onPointerEnter', ['pointerout', 'pointerover']); 8003 registerDirectEvent('onPointerLeave', ['pointerout', 'pointerover']); 8004} 8005/** 8006 * For almost every interaction we care about, there will be both a top-level 8007 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that 8008 * we do not extract duplicate events. However, moving the mouse into the 8009 * browser from outside will not fire a `mouseout` event. In this case, we use 8010 * the `mouseover` top-level event. 8011 */ 8012 8013 8014function extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) { 8015 var isOverEvent = domEventName === 'mouseover' || domEventName === 'pointerover'; 8016 var isOutEvent = domEventName === 'mouseout' || domEventName === 'pointerout'; 8017 8018 if (isOverEvent && !isReplayingEvent(nativeEvent)) { 8019 // If this is an over event with a target, we might have already dispatched 8020 // the event in the out event of the other target. If this is replayed, 8021 // then it's because we couldn't dispatch against this target previously 8022 // so we have to do it now instead. 8023 var related = nativeEvent.relatedTarget || nativeEvent.fromElement; 8024 8025 if (related) { 8026 // If the related node is managed by React, we can assume that we have 8027 // already dispatched the corresponding events during its mouseout. 8028 if (getClosestInstanceFromNode(related) || isContainerMarkedAsRoot(related)) { 8029 return; 8030 } 8031 } 8032 } 8033 8034 if (!isOutEvent && !isOverEvent) { 8035 // Must not be a mouse or pointer in or out - ignoring. 8036 return; 8037 } 8038 8039 var win; // TODO: why is this nullable in the types but we read from it? 8040 8041 if (nativeEventTarget.window === nativeEventTarget) { 8042 // `nativeEventTarget` is probably a window object. 8043 win = nativeEventTarget; 8044 } else { 8045 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. 8046 var doc = nativeEventTarget.ownerDocument; 8047 8048 if (doc) { 8049 win = doc.defaultView || doc.parentWindow; 8050 } else { 8051 win = window; 8052 } 8053 } 8054 8055 var from; 8056 var to; 8057 8058 if (isOutEvent) { 8059 var _related = nativeEvent.relatedTarget || nativeEvent.toElement; 8060 8061 from = targetInst; 8062 to = _related ? getClosestInstanceFromNode(_related) : null; 8063 8064 if (to !== null) { 8065 var nearestMounted = getNearestMountedFiber(to); 8066 8067 if (to !== nearestMounted || to.tag !== HostComponent && to.tag !== HostText) { 8068 to = null; 8069 } 8070 } 8071 } else { 8072 // Moving to a node from outside the window. 8073 from = null; 8074 to = targetInst; 8075 } 8076 8077 if (from === to) { 8078 // Nothing pertains to our managed components. 8079 return; 8080 } 8081 8082 var SyntheticEventCtor = SyntheticMouseEvent; 8083 var leaveEventType = 'onMouseLeave'; 8084 var enterEventType = 'onMouseEnter'; 8085 var eventTypePrefix = 'mouse'; 8086 8087 if (domEventName === 'pointerout' || domEventName === 'pointerover') { 8088 SyntheticEventCtor = SyntheticPointerEvent; 8089 leaveEventType = 'onPointerLeave'; 8090 enterEventType = 'onPointerEnter'; 8091 eventTypePrefix = 'pointer'; 8092 } 8093 8094 var fromNode = from == null ? win : getNodeFromInstance(from); 8095 var toNode = to == null ? win : getNodeFromInstance(to); 8096 var leave = new SyntheticEventCtor(leaveEventType, eventTypePrefix + 'leave', from, nativeEvent, nativeEventTarget); 8097 leave.target = fromNode; 8098 leave.relatedTarget = toNode; 8099 var enter = null; // We should only process this nativeEvent if we are processing 8100 // the first ancestor. Next time, we will ignore the event. 8101 8102 var nativeTargetInst = getClosestInstanceFromNode(nativeEventTarget); 8103 8104 if (nativeTargetInst === targetInst) { 8105 var enterEvent = new SyntheticEventCtor(enterEventType, eventTypePrefix + 'enter', to, nativeEvent, nativeEventTarget); 8106 enterEvent.target = toNode; 8107 enterEvent.relatedTarget = fromNode; 8108 enter = enterEvent; 8109 } 8110 8111 accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leave, enter, from, to); 8112} 8113 8114/** 8115 * inlined Object.is polyfill to avoid requiring consumers ship their own 8116 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is 8117 */ 8118function is(x, y) { 8119 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare 8120 ; 8121} 8122 8123var objectIs = typeof Object.is === 'function' ? Object.is : is; 8124 8125/** 8126 * Performs equality by iterating through keys on an object and returning false 8127 * when any key has values which are not strictly equal between the arguments. 8128 * Returns true when the values of all keys are strictly equal. 8129 */ 8130 8131function shallowEqual(objA, objB) { 8132 if (objectIs(objA, objB)) { 8133 return true; 8134 } 8135 8136 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { 8137 return false; 8138 } 8139 8140 var keysA = Object.keys(objA); 8141 var keysB = Object.keys(objB); 8142 8143 if (keysA.length !== keysB.length) { 8144 return false; 8145 } // Test for A's keys different from B. 8146 8147 8148 for (var i = 0; i < keysA.length; i++) { 8149 var currentKey = keysA[i]; 8150 8151 if (!hasOwnProperty.call(objB, currentKey) || !objectIs(objA[currentKey], objB[currentKey])) { 8152 return false; 8153 } 8154 } 8155 8156 return true; 8157} 8158 8159/** 8160 * Given any node return the first leaf node without children. 8161 * 8162 * @param {DOMElement|DOMTextNode} node 8163 * @return {DOMElement|DOMTextNode} 8164 */ 8165 8166function getLeafNode(node) { 8167 while (node && node.firstChild) { 8168 node = node.firstChild; 8169 } 8170 8171 return node; 8172} 8173/** 8174 * Get the next sibling within a container. This will walk up the 8175 * DOM if a node's siblings have been exhausted. 8176 * 8177 * @param {DOMElement|DOMTextNode} node 8178 * @return {?DOMElement|DOMTextNode} 8179 */ 8180 8181 8182function getSiblingNode(node) { 8183 while (node) { 8184 if (node.nextSibling) { 8185 return node.nextSibling; 8186 } 8187 8188 node = node.parentNode; 8189 } 8190} 8191/** 8192 * Get object describing the nodes which contain characters at offset. 8193 * 8194 * @param {DOMElement|DOMTextNode} root 8195 * @param {number} offset 8196 * @return {?object} 8197 */ 8198 8199 8200function getNodeForCharacterOffset(root, offset) { 8201 var node = getLeafNode(root); 8202 var nodeStart = 0; 8203 var nodeEnd = 0; 8204 8205 while (node) { 8206 if (node.nodeType === TEXT_NODE) { 8207 nodeEnd = nodeStart + node.textContent.length; 8208 8209 if (nodeStart <= offset && nodeEnd >= offset) { 8210 return { 8211 node: node, 8212 offset: offset - nodeStart 8213 }; 8214 } 8215 8216 nodeStart = nodeEnd; 8217 } 8218 8219 node = getLeafNode(getSiblingNode(node)); 8220 } 8221} 8222 8223/** 8224 * @param {DOMElement} outerNode 8225 * @return {?object} 8226 */ 8227 8228function getOffsets(outerNode) { 8229 var ownerDocument = outerNode.ownerDocument; 8230 var win = ownerDocument && ownerDocument.defaultView || window; 8231 var selection = win.getSelection && win.getSelection(); 8232 8233 if (!selection || selection.rangeCount === 0) { 8234 return null; 8235 } 8236 8237 var anchorNode = selection.anchorNode, 8238 anchorOffset = selection.anchorOffset, 8239 focusNode = selection.focusNode, 8240 focusOffset = selection.focusOffset; // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the 8241 // up/down buttons on an <input type="number">. Anonymous divs do not seem to 8242 // expose properties, triggering a "Permission denied error" if any of its 8243 // properties are accessed. The only seemingly possible way to avoid erroring 8244 // is to access a property that typically works for non-anonymous divs and 8245 // catch any error that may otherwise arise. See 8246 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427 8247 8248 try { 8249 /* eslint-disable no-unused-expressions */ 8250 anchorNode.nodeType; 8251 focusNode.nodeType; 8252 /* eslint-enable no-unused-expressions */ 8253 } catch (e) { 8254 return null; 8255 } 8256 8257 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset); 8258} 8259/** 8260 * Returns {start, end} where `start` is the character/codepoint index of 8261 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and 8262 * `end` is the index of (focusNode, focusOffset). 8263 * 8264 * Returns null if you pass in garbage input but we should probably just crash. 8265 * 8266 * Exported only for testing. 8267 */ 8268 8269function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) { 8270 var length = 0; 8271 var start = -1; 8272 var end = -1; 8273 var indexWithinAnchor = 0; 8274 var indexWithinFocus = 0; 8275 var node = outerNode; 8276 var parentNode = null; 8277 8278 outer: while (true) { 8279 var next = null; 8280 8281 while (true) { 8282 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) { 8283 start = length + anchorOffset; 8284 } 8285 8286 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) { 8287 end = length + focusOffset; 8288 } 8289 8290 if (node.nodeType === TEXT_NODE) { 8291 length += node.nodeValue.length; 8292 } 8293 8294 if ((next = node.firstChild) === null) { 8295 break; 8296 } // Moving from `node` to its first child `next`. 8297 8298 8299 parentNode = node; 8300 node = next; 8301 } 8302 8303 while (true) { 8304 if (node === outerNode) { 8305 // If `outerNode` has children, this is always the second time visiting 8306 // it. If it has no children, this is still the first loop, and the only 8307 // valid selection is anchorNode and focusNode both equal to this node 8308 // and both offsets 0, in which case we will have handled above. 8309 break outer; 8310 } 8311 8312 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) { 8313 start = length; 8314 } 8315 8316 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) { 8317 end = length; 8318 } 8319 8320 if ((next = node.nextSibling) !== null) { 8321 break; 8322 } 8323 8324 node = parentNode; 8325 parentNode = node.parentNode; 8326 } // Moving from `node` to its next sibling `next`. 8327 8328 8329 node = next; 8330 } 8331 8332 if (start === -1 || end === -1) { 8333 // This should never happen. (Would happen if the anchor/focus nodes aren't 8334 // actually inside the passed-in node.) 8335 return null; 8336 } 8337 8338 return { 8339 start: start, 8340 end: end 8341 }; 8342} 8343/** 8344 * In modern non-IE browsers, we can support both forward and backward 8345 * selections. 8346 * 8347 * Note: IE10+ supports the Selection object, but it does not support 8348 * the `extend` method, which means that even in modern IE, it's not possible 8349 * to programmatically create a backward selection. Thus, for all IE 8350 * versions, we use the old IE API to create our selections. 8351 * 8352 * @param {DOMElement|DOMTextNode} node 8353 * @param {object} offsets 8354 */ 8355 8356function setOffsets(node, offsets) { 8357 var doc = node.ownerDocument || document; 8358 var win = doc && doc.defaultView || window; // Edge fails with "Object expected" in some scenarios. 8359 // (For instance: TinyMCE editor used in a list component that supports pasting to add more, 8360 // fails when pasting 100+ items) 8361 8362 if (!win.getSelection) { 8363 return; 8364 } 8365 8366 var selection = win.getSelection(); 8367 var length = node.textContent.length; 8368 var start = Math.min(offsets.start, length); 8369 var end = offsets.end === undefined ? start : Math.min(offsets.end, length); // IE 11 uses modern selection, but doesn't support the extend method. 8370 // Flip backward selections, so we can set with a single range. 8371 8372 if (!selection.extend && start > end) { 8373 var temp = end; 8374 end = start; 8375 start = temp; 8376 } 8377 8378 var startMarker = getNodeForCharacterOffset(node, start); 8379 var endMarker = getNodeForCharacterOffset(node, end); 8380 8381 if (startMarker && endMarker) { 8382 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) { 8383 return; 8384 } 8385 8386 var range = doc.createRange(); 8387 range.setStart(startMarker.node, startMarker.offset); 8388 selection.removeAllRanges(); 8389 8390 if (start > end) { 8391 selection.addRange(range); 8392 selection.extend(endMarker.node, endMarker.offset); 8393 } else { 8394 range.setEnd(endMarker.node, endMarker.offset); 8395 selection.addRange(range); 8396 } 8397 } 8398} 8399 8400function isTextNode(node) { 8401 return node && node.nodeType === TEXT_NODE; 8402} 8403 8404function containsNode(outerNode, innerNode) { 8405 if (!outerNode || !innerNode) { 8406 return false; 8407 } else if (outerNode === innerNode) { 8408 return true; 8409 } else if (isTextNode(outerNode)) { 8410 return false; 8411 } else if (isTextNode(innerNode)) { 8412 return containsNode(outerNode, innerNode.parentNode); 8413 } else if ('contains' in outerNode) { 8414 return outerNode.contains(innerNode); 8415 } else if (outerNode.compareDocumentPosition) { 8416 return !!(outerNode.compareDocumentPosition(innerNode) & 16); 8417 } else { 8418 return false; 8419 } 8420} 8421 8422function isInDocument(node) { 8423 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node); 8424} 8425 8426function isSameOriginFrame(iframe) { 8427 try { 8428 // Accessing the contentDocument of a HTMLIframeElement can cause the browser 8429 // to throw, e.g. if it has a cross-origin src attribute. 8430 // Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g: 8431 // iframe.contentDocument.defaultView; 8432 // A safety way is to access one of the cross origin properties: Window or Location 8433 // Which might result in "SecurityError" DOM Exception and it is compatible to Safari. 8434 // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl 8435 return typeof iframe.contentWindow.location.href === 'string'; 8436 } catch (err) { 8437 return false; 8438 } 8439} 8440 8441function getActiveElementDeep() { 8442 var win = window; 8443 var element = getActiveElement(); 8444 8445 while (element instanceof win.HTMLIFrameElement) { 8446 if (isSameOriginFrame(element)) { 8447 win = element.contentWindow; 8448 } else { 8449 return element; 8450 } 8451 8452 element = getActiveElement(win.document); 8453 } 8454 8455 return element; 8456} 8457/** 8458 * @ReactInputSelection: React input selection module. Based on Selection.js, 8459 * but modified to be suitable for react and has a couple of bug fixes (doesn't 8460 * assume buttons have range selections allowed). 8461 * Input selection module for React. 8462 */ 8463 8464/** 8465 * @hasSelectionCapabilities: we get the element types that support selection 8466 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart` 8467 * and `selectionEnd` rows. 8468 */ 8469 8470 8471function hasSelectionCapabilities(elem) { 8472 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); 8473 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true'); 8474} 8475function getSelectionInformation() { 8476 var focusedElem = getActiveElementDeep(); 8477 return { 8478 focusedElem: focusedElem, 8479 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection(focusedElem) : null 8480 }; 8481} 8482/** 8483 * @restoreSelection: If any selection information was potentially lost, 8484 * restore it. This is useful when performing operations that could remove dom 8485 * nodes and place them back in, resulting in focus being lost. 8486 */ 8487 8488function restoreSelection(priorSelectionInformation) { 8489 var curFocusedElem = getActiveElementDeep(); 8490 var priorFocusedElem = priorSelectionInformation.focusedElem; 8491 var priorSelectionRange = priorSelectionInformation.selectionRange; 8492 8493 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) { 8494 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) { 8495 setSelection(priorFocusedElem, priorSelectionRange); 8496 } // Focusing a node can change the scroll position, which is undesirable 8497 8498 8499 var ancestors = []; 8500 var ancestor = priorFocusedElem; 8501 8502 while (ancestor = ancestor.parentNode) { 8503 if (ancestor.nodeType === ELEMENT_NODE) { 8504 ancestors.push({ 8505 element: ancestor, 8506 left: ancestor.scrollLeft, 8507 top: ancestor.scrollTop 8508 }); 8509 } 8510 } 8511 8512 if (typeof priorFocusedElem.focus === 'function') { 8513 priorFocusedElem.focus(); 8514 } 8515 8516 for (var i = 0; i < ancestors.length; i++) { 8517 var info = ancestors[i]; 8518 info.element.scrollLeft = info.left; 8519 info.element.scrollTop = info.top; 8520 } 8521 } 8522} 8523/** 8524 * @getSelection: Gets the selection bounds of a focused textarea, input or 8525 * contentEditable node. 8526 * -@input: Look up selection bounds of this input 8527 * -@return {start: selectionStart, end: selectionEnd} 8528 */ 8529 8530function getSelection(input) { 8531 var selection; 8532 8533 if ('selectionStart' in input) { 8534 // Modern browser with input or textarea. 8535 selection = { 8536 start: input.selectionStart, 8537 end: input.selectionEnd 8538 }; 8539 } else { 8540 // Content editable or old IE textarea. 8541 selection = getOffsets(input); 8542 } 8543 8544 return selection || { 8545 start: 0, 8546 end: 0 8547 }; 8548} 8549/** 8550 * @setSelection: Sets the selection bounds of a textarea or input and focuses 8551 * the input. 8552 * -@input Set selection bounds of this input or textarea 8553 * -@offsets Object of same form that is returned from get* 8554 */ 8555 8556function setSelection(input, offsets) { 8557 var start = offsets.start; 8558 var end = offsets.end; 8559 8560 if (end === undefined) { 8561 end = start; 8562 } 8563 8564 if ('selectionStart' in input) { 8565 input.selectionStart = start; 8566 input.selectionEnd = Math.min(end, input.value.length); 8567 } else { 8568 setOffsets(input, offsets); 8569 } 8570} 8571 8572var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11; 8573 8574function registerEvents$3() { 8575 registerTwoPhaseEvent('onSelect', ['focusout', 'contextmenu', 'dragend', 'focusin', 'keydown', 'keyup', 'mousedown', 'mouseup', 'selectionchange']); 8576} 8577 8578var activeElement$1 = null; 8579var activeElementInst$1 = null; 8580var lastSelection = null; 8581var mouseDown = false; 8582/** 8583 * Get an object which is a unique representation of the current selection. 8584 * 8585 * The return value will not be consistent across nodes or browsers, but 8586 * two identical selections on the same node will return identical objects. 8587 */ 8588 8589function getSelection$1(node) { 8590 if ('selectionStart' in node && hasSelectionCapabilities(node)) { 8591 return { 8592 start: node.selectionStart, 8593 end: node.selectionEnd 8594 }; 8595 } else { 8596 var win = node.ownerDocument && node.ownerDocument.defaultView || window; 8597 var selection = win.getSelection(); 8598 return { 8599 anchorNode: selection.anchorNode, 8600 anchorOffset: selection.anchorOffset, 8601 focusNode: selection.focusNode, 8602 focusOffset: selection.focusOffset 8603 }; 8604 } 8605} 8606/** 8607 * Get document associated with the event target. 8608 */ 8609 8610 8611function getEventTargetDocument(eventTarget) { 8612 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument; 8613} 8614/** 8615 * Poll selection to see whether it's changed. 8616 * 8617 * @param {object} nativeEvent 8618 * @param {object} nativeEventTarget 8619 * @return {?SyntheticEvent} 8620 */ 8621 8622 8623function constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget) { 8624 // Ensure we have the right element, and that the user is not dragging a 8625 // selection (this matches native `select` event behavior). In HTML5, select 8626 // fires only on input and textarea thus if there's no focused element we 8627 // won't dispatch. 8628 var doc = getEventTargetDocument(nativeEventTarget); 8629 8630 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) { 8631 return; 8632 } // Only fire when selection has actually changed. 8633 8634 8635 var currentSelection = getSelection$1(activeElement$1); 8636 8637 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) { 8638 lastSelection = currentSelection; 8639 var listeners = accumulateTwoPhaseListeners(activeElementInst$1, 'onSelect'); 8640 8641 if (listeners.length > 0) { 8642 var event = new SyntheticEvent('onSelect', 'select', null, nativeEvent, nativeEventTarget); 8643 dispatchQueue.push({ 8644 event: event, 8645 listeners: listeners 8646 }); 8647 event.target = activeElement$1; 8648 } 8649 } 8650} 8651/** 8652 * This plugin creates an `onSelect` event that normalizes select events 8653 * across form elements. 8654 * 8655 * Supported elements are: 8656 * - input (see `isTextInputElement`) 8657 * - textarea 8658 * - contentEditable 8659 * 8660 * This differs from native browser implementations in the following ways: 8661 * - Fires on contentEditable fields as well as inputs. 8662 * - Fires for collapsed selection. 8663 * - Fires after user input. 8664 */ 8665 8666 8667function extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) { 8668 var targetNode = targetInst ? getNodeFromInstance(targetInst) : window; 8669 8670 switch (domEventName) { 8671 // Track the input node that has focus. 8672 case 'focusin': 8673 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') { 8674 activeElement$1 = targetNode; 8675 activeElementInst$1 = targetInst; 8676 lastSelection = null; 8677 } 8678 8679 break; 8680 8681 case 'focusout': 8682 activeElement$1 = null; 8683 activeElementInst$1 = null; 8684 lastSelection = null; 8685 break; 8686 // Don't fire the event while the user is dragging. This matches the 8687 // semantics of the native select event. 8688 8689 case 'mousedown': 8690 mouseDown = true; 8691 break; 8692 8693 case 'contextmenu': 8694 case 'mouseup': 8695 case 'dragend': 8696 mouseDown = false; 8697 constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget); 8698 break; 8699 // Chrome and IE fire non-standard event when selection is changed (and 8700 // sometimes when it hasn't). IE's event fires out of order with respect 8701 // to key and input events on deletion, so we discard it. 8702 // 8703 // Firefox doesn't support selectionchange, so check selection status 8704 // after each key entry. The selection changes after keydown and before 8705 // keyup, but we check on keydown as well in the case of holding down a 8706 // key, when multiple keydown events are fired but only one keyup is. 8707 // This is also our approach for IE handling, for the reason above. 8708 8709 case 'selectionchange': 8710 if (skipSelectionChangeEvent) { 8711 break; 8712 } 8713 8714 // falls through 8715 8716 case 'keydown': 8717 case 'keyup': 8718 constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget); 8719 } 8720} 8721 8722/** 8723 * Generate a mapping of standard vendor prefixes using the defined style property and event name. 8724 * 8725 * @param {string} styleProp 8726 * @param {string} eventName 8727 * @returns {object} 8728 */ 8729 8730function makePrefixMap(styleProp, eventName) { 8731 var prefixes = {}; 8732 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase(); 8733 prefixes['Webkit' + styleProp] = 'webkit' + eventName; 8734 prefixes['Moz' + styleProp] = 'moz' + eventName; 8735 return prefixes; 8736} 8737/** 8738 * A list of event names to a configurable list of vendor prefixes. 8739 */ 8740 8741 8742var vendorPrefixes = { 8743 animationend: makePrefixMap('Animation', 'AnimationEnd'), 8744 animationiteration: makePrefixMap('Animation', 'AnimationIteration'), 8745 animationstart: makePrefixMap('Animation', 'AnimationStart'), 8746 transitionend: makePrefixMap('Transition', 'TransitionEnd') 8747}; 8748/** 8749 * Event names that have already been detected and prefixed (if applicable). 8750 */ 8751 8752var prefixedEventNames = {}; 8753/** 8754 * Element to check for prefixes on. 8755 */ 8756 8757var style = {}; 8758/** 8759 * Bootstrap if a DOM exists. 8760 */ 8761 8762if (canUseDOM) { 8763 style = document.createElement('div').style; // On some platforms, in particular some releases of Android 4.x, 8764 // the un-prefixed "animation" and "transition" properties are defined on the 8765 // style object but the events that fire will still be prefixed, so we need 8766 // to check if the un-prefixed events are usable, and if not remove them from the map. 8767 8768 if (!('AnimationEvent' in window)) { 8769 delete vendorPrefixes.animationend.animation; 8770 delete vendorPrefixes.animationiteration.animation; 8771 delete vendorPrefixes.animationstart.animation; 8772 } // Same as above 8773 8774 8775 if (!('TransitionEvent' in window)) { 8776 delete vendorPrefixes.transitionend.transition; 8777 } 8778} 8779/** 8780 * Attempts to determine the correct vendor prefixed event name. 8781 * 8782 * @param {string} eventName 8783 * @returns {string} 8784 */ 8785 8786 8787function getVendorPrefixedEventName(eventName) { 8788 if (prefixedEventNames[eventName]) { 8789 return prefixedEventNames[eventName]; 8790 } else if (!vendorPrefixes[eventName]) { 8791 return eventName; 8792 } 8793 8794 var prefixMap = vendorPrefixes[eventName]; 8795 8796 for (var styleProp in prefixMap) { 8797 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) { 8798 return prefixedEventNames[eventName] = prefixMap[styleProp]; 8799 } 8800 } 8801 8802 return eventName; 8803} 8804 8805var ANIMATION_END = getVendorPrefixedEventName('animationend'); 8806var ANIMATION_ITERATION = getVendorPrefixedEventName('animationiteration'); 8807var ANIMATION_START = getVendorPrefixedEventName('animationstart'); 8808var TRANSITION_END = getVendorPrefixedEventName('transitionend'); 8809 8810var topLevelEventsToReactNames = new Map(); // NOTE: Capitalization is important in this list! 8811// 8812// E.g. it needs "pointerDown", not "pointerdown". 8813// This is because we derive both React name ("onPointerDown") 8814// and DOM name ("pointerdown") from the same list. 8815// 8816// Exceptions that don't match this convention are listed separately. 8817// 8818// prettier-ignore 8819 8820var simpleEventPluginEvents = ['abort', 'auxClick', 'cancel', 'canPlay', 'canPlayThrough', 'click', 'close', 'contextMenu', 'copy', 'cut', 'drag', 'dragEnd', 'dragEnter', 'dragExit', 'dragLeave', 'dragOver', 'dragStart', 'drop', 'durationChange', 'emptied', 'encrypted', 'ended', 'error', 'gotPointerCapture', 'input', 'invalid', 'keyDown', 'keyPress', 'keyUp', 'load', 'loadedData', 'loadedMetadata', 'loadStart', 'lostPointerCapture', 'mouseDown', 'mouseMove', 'mouseOut', 'mouseOver', 'mouseUp', 'paste', 'pause', 'play', 'playing', 'pointerCancel', 'pointerDown', 'pointerMove', 'pointerOut', 'pointerOver', 'pointerUp', 'progress', 'rateChange', 'reset', 'resize', 'seeked', 'seeking', 'stalled', 'submit', 'suspend', 'timeUpdate', 'touchCancel', 'touchEnd', 'touchStart', 'volumeChange', 'scroll', 'toggle', 'touchMove', 'waiting', 'wheel']; 8821 8822function registerSimpleEvent(domEventName, reactName) { 8823 topLevelEventsToReactNames.set(domEventName, reactName); 8824 registerTwoPhaseEvent(reactName, [domEventName]); 8825} 8826 8827function registerSimpleEvents() { 8828 for (var i = 0; i < simpleEventPluginEvents.length; i++) { 8829 var eventName = simpleEventPluginEvents[i]; 8830 var domEventName = eventName.toLowerCase(); 8831 var capitalizedEvent = eventName[0].toUpperCase() + eventName.slice(1); 8832 registerSimpleEvent(domEventName, 'on' + capitalizedEvent); 8833 } // Special cases where event names don't match. 8834 8835 8836 registerSimpleEvent(ANIMATION_END, 'onAnimationEnd'); 8837 registerSimpleEvent(ANIMATION_ITERATION, 'onAnimationIteration'); 8838 registerSimpleEvent(ANIMATION_START, 'onAnimationStart'); 8839 registerSimpleEvent('dblclick', 'onDoubleClick'); 8840 registerSimpleEvent('focusin', 'onFocus'); 8841 registerSimpleEvent('focusout', 'onBlur'); 8842 registerSimpleEvent(TRANSITION_END, 'onTransitionEnd'); 8843} 8844 8845function extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) { 8846 var reactName = topLevelEventsToReactNames.get(domEventName); 8847 8848 if (reactName === undefined) { 8849 return; 8850 } 8851 8852 var SyntheticEventCtor = SyntheticEvent; 8853 var reactEventType = domEventName; 8854 8855 switch (domEventName) { 8856 case 'keypress': 8857 // Firefox creates a keypress event for function keys too. This removes 8858 // the unwanted keypress events. Enter is however both printable and 8859 // non-printable. One would expect Tab to be as well (but it isn't). 8860 if (getEventCharCode(nativeEvent) === 0) { 8861 return; 8862 } 8863 8864 /* falls through */ 8865 8866 case 'keydown': 8867 case 'keyup': 8868 SyntheticEventCtor = SyntheticKeyboardEvent; 8869 break; 8870 8871 case 'focusin': 8872 reactEventType = 'focus'; 8873 SyntheticEventCtor = SyntheticFocusEvent; 8874 break; 8875 8876 case 'focusout': 8877 reactEventType = 'blur'; 8878 SyntheticEventCtor = SyntheticFocusEvent; 8879 break; 8880 8881 case 'beforeblur': 8882 case 'afterblur': 8883 SyntheticEventCtor = SyntheticFocusEvent; 8884 break; 8885 8886 case 'click': 8887 // Firefox creates a click event on right mouse clicks. This removes the 8888 // unwanted click events. 8889 if (nativeEvent.button === 2) { 8890 return; 8891 } 8892 8893 /* falls through */ 8894 8895 case 'auxclick': 8896 case 'dblclick': 8897 case 'mousedown': 8898 case 'mousemove': 8899 case 'mouseup': // TODO: Disabled elements should not respond to mouse events 8900 8901 /* falls through */ 8902 8903 case 'mouseout': 8904 case 'mouseover': 8905 case 'contextmenu': 8906 SyntheticEventCtor = SyntheticMouseEvent; 8907 break; 8908 8909 case 'drag': 8910 case 'dragend': 8911 case 'dragenter': 8912 case 'dragexit': 8913 case 'dragleave': 8914 case 'dragover': 8915 case 'dragstart': 8916 case 'drop': 8917 SyntheticEventCtor = SyntheticDragEvent; 8918 break; 8919 8920 case 'touchcancel': 8921 case 'touchend': 8922 case 'touchmove': 8923 case 'touchstart': 8924 SyntheticEventCtor = SyntheticTouchEvent; 8925 break; 8926 8927 case ANIMATION_END: 8928 case ANIMATION_ITERATION: 8929 case ANIMATION_START: 8930 SyntheticEventCtor = SyntheticAnimationEvent; 8931 break; 8932 8933 case TRANSITION_END: 8934 SyntheticEventCtor = SyntheticTransitionEvent; 8935 break; 8936 8937 case 'scroll': 8938 SyntheticEventCtor = SyntheticUIEvent; 8939 break; 8940 8941 case 'wheel': 8942 SyntheticEventCtor = SyntheticWheelEvent; 8943 break; 8944 8945 case 'copy': 8946 case 'cut': 8947 case 'paste': 8948 SyntheticEventCtor = SyntheticClipboardEvent; 8949 break; 8950 8951 case 'gotpointercapture': 8952 case 'lostpointercapture': 8953 case 'pointercancel': 8954 case 'pointerdown': 8955 case 'pointermove': 8956 case 'pointerout': 8957 case 'pointerover': 8958 case 'pointerup': 8959 SyntheticEventCtor = SyntheticPointerEvent; 8960 break; 8961 } 8962 8963 var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0; 8964 8965 { 8966 // Some events don't bubble in the browser. 8967 // In the past, React has always bubbled them, but this can be surprising. 8968 // We're going to try aligning closer to the browser behavior by not bubbling 8969 // them in React either. We'll start by not bubbling onScroll, and then expand. 8970 var accumulateTargetOnly = !inCapturePhase && // TODO: ideally, we'd eventually add all events from 8971 // nonDelegatedEvents list in DOMPluginEventSystem. 8972 // Then we can remove this special list. 8973 // This is a breaking change that can wait until React 18. 8974 domEventName === 'scroll'; 8975 8976 var _listeners = accumulateSinglePhaseListeners(targetInst, reactName, nativeEvent.type, inCapturePhase, accumulateTargetOnly); 8977 8978 if (_listeners.length > 0) { 8979 // Intentionally create event lazily. 8980 var _event = new SyntheticEventCtor(reactName, reactEventType, null, nativeEvent, nativeEventTarget); 8981 8982 dispatchQueue.push({ 8983 event: _event, 8984 listeners: _listeners 8985 }); 8986 } 8987 } 8988} 8989 8990// TODO: remove top-level side effect. 8991registerSimpleEvents(); 8992registerEvents$2(); 8993registerEvents$1(); 8994registerEvents$3(); 8995registerEvents(); 8996 8997function extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) { 8998 // TODO: we should remove the concept of a "SimpleEventPlugin". 8999 // This is the basic functionality of the event system. All 9000 // the other plugins are essentially polyfills. So the plugin 9001 // should probably be inlined somewhere and have its logic 9002 // be core the to event system. This would potentially allow 9003 // us to ship builds of React without the polyfilled plugins below. 9004 extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags); 9005 var shouldProcessPolyfillPlugins = (eventSystemFlags & SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS) === 0; // We don't process these events unless we are in the 9006 // event's native "bubble" phase, which means that we're 9007 // not in the capture phase. That's because we emulate 9008 // the capture phase here still. This is a trade-off, 9009 // because in an ideal world we would not emulate and use 9010 // the phases properly, like we do with the SimpleEvent 9011 // plugin. However, the plugins below either expect 9012 // emulation (EnterLeave) or use state localized to that 9013 // plugin (BeforeInput, Change, Select). The state in 9014 // these modules complicates things, as you'll essentially 9015 // get the case where the capture phase event might change 9016 // state, only for the following bubble event to come in 9017 // later and not trigger anything as the state now 9018 // invalidates the heuristics of the event plugin. We 9019 // could alter all these plugins to work in such ways, but 9020 // that might cause other unknown side-effects that we 9021 // can't foresee right now. 9022 9023 if (shouldProcessPolyfillPlugins) { 9024 extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget); 9025 extractEvents$1(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget); 9026 extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget); 9027 extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget); 9028 } 9029} // List of events that need to be individually attached to media elements. 9030 9031 9032var mediaEventTypes = ['abort', 'canplay', 'canplaythrough', 'durationchange', 'emptied', 'encrypted', 'ended', 'error', 'loadeddata', 'loadedmetadata', 'loadstart', 'pause', 'play', 'playing', 'progress', 'ratechange', 'resize', 'seeked', 'seeking', 'stalled', 'suspend', 'timeupdate', 'volumechange', 'waiting']; // We should not delegate these events to the container, but rather 9033// set them on the actual target element itself. This is primarily 9034// because these events do not consistently bubble in the DOM. 9035 9036var nonDelegatedEvents = new Set(['cancel', 'close', 'invalid', 'load', 'scroll', 'toggle'].concat(mediaEventTypes)); 9037 9038function executeDispatch(event, listener, currentTarget) { 9039 var type = event.type || 'unknown-event'; 9040 event.currentTarget = currentTarget; 9041 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event); 9042 event.currentTarget = null; 9043} 9044 9045function processDispatchQueueItemsInOrder(event, dispatchListeners, inCapturePhase) { 9046 var previousInstance; 9047 9048 if (inCapturePhase) { 9049 for (var i = dispatchListeners.length - 1; i >= 0; i--) { 9050 var _dispatchListeners$i = dispatchListeners[i], 9051 instance = _dispatchListeners$i.instance, 9052 currentTarget = _dispatchListeners$i.currentTarget, 9053 listener = _dispatchListeners$i.listener; 9054 9055 if (instance !== previousInstance && event.isPropagationStopped()) { 9056 return; 9057 } 9058 9059 executeDispatch(event, listener, currentTarget); 9060 previousInstance = instance; 9061 } 9062 } else { 9063 for (var _i = 0; _i < dispatchListeners.length; _i++) { 9064 var _dispatchListeners$_i = dispatchListeners[_i], 9065 _instance = _dispatchListeners$_i.instance, 9066 _currentTarget = _dispatchListeners$_i.currentTarget, 9067 _listener = _dispatchListeners$_i.listener; 9068 9069 if (_instance !== previousInstance && event.isPropagationStopped()) { 9070 return; 9071 } 9072 9073 executeDispatch(event, _listener, _currentTarget); 9074 previousInstance = _instance; 9075 } 9076 } 9077} 9078 9079function processDispatchQueue(dispatchQueue, eventSystemFlags) { 9080 var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0; 9081 9082 for (var i = 0; i < dispatchQueue.length; i++) { 9083 var _dispatchQueue$i = dispatchQueue[i], 9084 event = _dispatchQueue$i.event, 9085 listeners = _dispatchQueue$i.listeners; 9086 processDispatchQueueItemsInOrder(event, listeners, inCapturePhase); // event system doesn't use pooling. 9087 } // This would be a good time to rethrow if any of the event handlers threw. 9088 9089 9090 rethrowCaughtError(); 9091} 9092 9093function dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) { 9094 var nativeEventTarget = getEventTarget(nativeEvent); 9095 var dispatchQueue = []; 9096 extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags); 9097 processDispatchQueue(dispatchQueue, eventSystemFlags); 9098} 9099 9100function listenToNonDelegatedEvent(domEventName, targetElement) { 9101 { 9102 if (!nonDelegatedEvents.has(domEventName)) { 9103 error('Did not expect a listenToNonDelegatedEvent() call for "%s". ' + 'This is a bug in React. Please file an issue.', domEventName); 9104 } 9105 } 9106 9107 var isCapturePhaseListener = false; 9108 var listenerSet = getEventListenerSet(targetElement); 9109 var listenerSetKey = getListenerSetKey(domEventName, isCapturePhaseListener); 9110 9111 if (!listenerSet.has(listenerSetKey)) { 9112 addTrappedEventListener(targetElement, domEventName, IS_NON_DELEGATED, isCapturePhaseListener); 9113 listenerSet.add(listenerSetKey); 9114 } 9115} 9116function listenToNativeEvent(domEventName, isCapturePhaseListener, target) { 9117 { 9118 if (nonDelegatedEvents.has(domEventName) && !isCapturePhaseListener) { 9119 error('Did not expect a listenToNativeEvent() call for "%s" in the bubble phase. ' + 'This is a bug in React. Please file an issue.', domEventName); 9120 } 9121 } 9122 9123 var eventSystemFlags = 0; 9124 9125 if (isCapturePhaseListener) { 9126 eventSystemFlags |= IS_CAPTURE_PHASE; 9127 } 9128 9129 addTrappedEventListener(target, domEventName, eventSystemFlags, isCapturePhaseListener); 9130} // This is only used by createEventHandle when the 9131var listeningMarker = '_reactListening' + Math.random().toString(36).slice(2); 9132function listenToAllSupportedEvents(rootContainerElement) { 9133 if (!rootContainerElement[listeningMarker]) { 9134 rootContainerElement[listeningMarker] = true; 9135 allNativeEvents.forEach(function (domEventName) { 9136 // We handle selectionchange separately because it 9137 // doesn't bubble and needs to be on the document. 9138 if (domEventName !== 'selectionchange') { 9139 if (!nonDelegatedEvents.has(domEventName)) { 9140 listenToNativeEvent(domEventName, false, rootContainerElement); 9141 } 9142 9143 listenToNativeEvent(domEventName, true, rootContainerElement); 9144 } 9145 }); 9146 var ownerDocument = rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument; 9147 9148 if (ownerDocument !== null) { 9149 // The selectionchange event also needs deduplication 9150 // but it is attached to the document. 9151 if (!ownerDocument[listeningMarker]) { 9152 ownerDocument[listeningMarker] = true; 9153 listenToNativeEvent('selectionchange', false, ownerDocument); 9154 } 9155 } 9156 } 9157} 9158 9159function addTrappedEventListener(targetContainer, domEventName, eventSystemFlags, isCapturePhaseListener, isDeferredListenerForLegacyFBSupport) { 9160 var listener = createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags); // If passive option is not supported, then the event will be 9161 // active and not passive. 9162 9163 var isPassiveListener = undefined; 9164 9165 if (passiveBrowserEventsSupported) { 9166 // Browsers introduced an intervention, making these events 9167 // passive by default on document. React doesn't bind them 9168 // to document anymore, but changing this now would undo 9169 // the performance wins from the change. So we emulate 9170 // the existing behavior manually on the roots now. 9171 // https://github.com/facebook/react/issues/19651 9172 if (domEventName === 'touchstart' || domEventName === 'touchmove' || domEventName === 'wheel') { 9173 isPassiveListener = true; 9174 } 9175 } 9176 9177 targetContainer = targetContainer; 9178 var unsubscribeListener; // When legacyFBSupport is enabled, it's for when we 9179 9180 9181 if (isCapturePhaseListener) { 9182 if (isPassiveListener !== undefined) { 9183 unsubscribeListener = addEventCaptureListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener); 9184 } else { 9185 unsubscribeListener = addEventCaptureListener(targetContainer, domEventName, listener); 9186 } 9187 } else { 9188 if (isPassiveListener !== undefined) { 9189 unsubscribeListener = addEventBubbleListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener); 9190 } else { 9191 unsubscribeListener = addEventBubbleListener(targetContainer, domEventName, listener); 9192 } 9193 } 9194} 9195 9196function isMatchingRootContainer(grandContainer, targetContainer) { 9197 return grandContainer === targetContainer || grandContainer.nodeType === COMMENT_NODE && grandContainer.parentNode === targetContainer; 9198} 9199 9200function dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) { 9201 var ancestorInst = targetInst; 9202 9203 if ((eventSystemFlags & IS_EVENT_HANDLE_NON_MANAGED_NODE) === 0 && (eventSystemFlags & IS_NON_DELEGATED) === 0) { 9204 var targetContainerNode = targetContainer; // If we are using the legacy FB support flag, we 9205 9206 if (targetInst !== null) { 9207 // The below logic attempts to work out if we need to change 9208 // the target fiber to a different ancestor. We had similar logic 9209 // in the legacy event system, except the big difference between 9210 // systems is that the modern event system now has an event listener 9211 // attached to each React Root and React Portal Root. Together, 9212 // the DOM nodes representing these roots are the "rootContainer". 9213 // To figure out which ancestor instance we should use, we traverse 9214 // up the fiber tree from the target instance and attempt to find 9215 // root boundaries that match that of our current "rootContainer". 9216 // If we find that "rootContainer", we find the parent fiber 9217 // sub-tree for that root and make that our ancestor instance. 9218 var node = targetInst; 9219 9220 mainLoop: while (true) { 9221 if (node === null) { 9222 return; 9223 } 9224 9225 var nodeTag = node.tag; 9226 9227 if (nodeTag === HostRoot || nodeTag === HostPortal) { 9228 var container = node.stateNode.containerInfo; 9229 9230 if (isMatchingRootContainer(container, targetContainerNode)) { 9231 break; 9232 } 9233 9234 if (nodeTag === HostPortal) { 9235 // The target is a portal, but it's not the rootContainer we're looking for. 9236 // Normally portals handle their own events all the way down to the root. 9237 // So we should be able to stop now. However, we don't know if this portal 9238 // was part of *our* root. 9239 var grandNode = node.return; 9240 9241 while (grandNode !== null) { 9242 var grandTag = grandNode.tag; 9243 9244 if (grandTag === HostRoot || grandTag === HostPortal) { 9245 var grandContainer = grandNode.stateNode.containerInfo; 9246 9247 if (isMatchingRootContainer(grandContainer, targetContainerNode)) { 9248 // This is the rootContainer we're looking for and we found it as 9249 // a parent of the Portal. That means we can ignore it because the 9250 // Portal will bubble through to us. 9251 return; 9252 } 9253 } 9254 9255 grandNode = grandNode.return; 9256 } 9257 } // Now we need to find it's corresponding host fiber in the other 9258 // tree. To do this we can use getClosestInstanceFromNode, but we 9259 // need to validate that the fiber is a host instance, otherwise 9260 // we need to traverse up through the DOM till we find the correct 9261 // node that is from the other tree. 9262 9263 9264 while (container !== null) { 9265 var parentNode = getClosestInstanceFromNode(container); 9266 9267 if (parentNode === null) { 9268 return; 9269 } 9270 9271 var parentTag = parentNode.tag; 9272 9273 if (parentTag === HostComponent || parentTag === HostText) { 9274 node = ancestorInst = parentNode; 9275 continue mainLoop; 9276 } 9277 9278 container = container.parentNode; 9279 } 9280 } 9281 9282 node = node.return; 9283 } 9284 } 9285 } 9286 9287 batchedUpdates(function () { 9288 return dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, ancestorInst); 9289 }); 9290} 9291 9292function createDispatchListener(instance, listener, currentTarget) { 9293 return { 9294 instance: instance, 9295 listener: listener, 9296 currentTarget: currentTarget 9297 }; 9298} 9299 9300function accumulateSinglePhaseListeners(targetFiber, reactName, nativeEventType, inCapturePhase, accumulateTargetOnly, nativeEvent) { 9301 var captureName = reactName !== null ? reactName + 'Capture' : null; 9302 var reactEventName = inCapturePhase ? captureName : reactName; 9303 var listeners = []; 9304 var instance = targetFiber; 9305 var lastHostComponent = null; // Accumulate all instances and listeners via the target -> root path. 9306 9307 while (instance !== null) { 9308 var _instance2 = instance, 9309 stateNode = _instance2.stateNode, 9310 tag = _instance2.tag; // Handle listeners that are on HostComponents (i.e. <div>) 9311 9312 if (tag === HostComponent && stateNode !== null) { 9313 lastHostComponent = stateNode; // createEventHandle listeners 9314 9315 9316 if (reactEventName !== null) { 9317 var listener = getListener(instance, reactEventName); 9318 9319 if (listener != null) { 9320 listeners.push(createDispatchListener(instance, listener, lastHostComponent)); 9321 } 9322 } 9323 } // If we are only accumulating events for the target, then we don't 9324 // continue to propagate through the React fiber tree to find other 9325 // listeners. 9326 9327 9328 if (accumulateTargetOnly) { 9329 break; 9330 } // If we are processing the onBeforeBlur event, then we need to take 9331 9332 instance = instance.return; 9333 } 9334 9335 return listeners; 9336} // We should only use this function for: 9337// - BeforeInputEventPlugin 9338// - ChangeEventPlugin 9339// - SelectEventPlugin 9340// This is because we only process these plugins 9341// in the bubble phase, so we need to accumulate two 9342// phase event listeners (via emulation). 9343 9344function accumulateTwoPhaseListeners(targetFiber, reactName) { 9345 var captureName = reactName + 'Capture'; 9346 var listeners = []; 9347 var instance = targetFiber; // Accumulate all instances and listeners via the target -> root path. 9348 9349 while (instance !== null) { 9350 var _instance3 = instance, 9351 stateNode = _instance3.stateNode, 9352 tag = _instance3.tag; // Handle listeners that are on HostComponents (i.e. <div>) 9353 9354 if (tag === HostComponent && stateNode !== null) { 9355 var currentTarget = stateNode; 9356 var captureListener = getListener(instance, captureName); 9357 9358 if (captureListener != null) { 9359 listeners.unshift(createDispatchListener(instance, captureListener, currentTarget)); 9360 } 9361 9362 var bubbleListener = getListener(instance, reactName); 9363 9364 if (bubbleListener != null) { 9365 listeners.push(createDispatchListener(instance, bubbleListener, currentTarget)); 9366 } 9367 } 9368 9369 instance = instance.return; 9370 } 9371 9372 return listeners; 9373} 9374 9375function getParent(inst) { 9376 if (inst === null) { 9377 return null; 9378 } 9379 9380 do { 9381 inst = inst.return; // TODO: If this is a HostRoot we might want to bail out. 9382 // That is depending on if we want nested subtrees (layers) to bubble 9383 // events to their parent. We could also go through parentNode on the 9384 // host node but that wouldn't work for React Native and doesn't let us 9385 // do the portal feature. 9386 } while (inst && inst.tag !== HostComponent); 9387 9388 if (inst) { 9389 return inst; 9390 } 9391 9392 return null; 9393} 9394/** 9395 * Return the lowest common ancestor of A and B, or null if they are in 9396 * different trees. 9397 */ 9398 9399 9400function getLowestCommonAncestor(instA, instB) { 9401 var nodeA = instA; 9402 var nodeB = instB; 9403 var depthA = 0; 9404 9405 for (var tempA = nodeA; tempA; tempA = getParent(tempA)) { 9406 depthA++; 9407 } 9408 9409 var depthB = 0; 9410 9411 for (var tempB = nodeB; tempB; tempB = getParent(tempB)) { 9412 depthB++; 9413 } // If A is deeper, crawl up. 9414 9415 9416 while (depthA - depthB > 0) { 9417 nodeA = getParent(nodeA); 9418 depthA--; 9419 } // If B is deeper, crawl up. 9420 9421 9422 while (depthB - depthA > 0) { 9423 nodeB = getParent(nodeB); 9424 depthB--; 9425 } // Walk in lockstep until we find a match. 9426 9427 9428 var depth = depthA; 9429 9430 while (depth--) { 9431 if (nodeA === nodeB || nodeB !== null && nodeA === nodeB.alternate) { 9432 return nodeA; 9433 } 9434 9435 nodeA = getParent(nodeA); 9436 nodeB = getParent(nodeB); 9437 } 9438 9439 return null; 9440} 9441 9442function accumulateEnterLeaveListenersForEvent(dispatchQueue, event, target, common, inCapturePhase) { 9443 var registrationName = event._reactName; 9444 var listeners = []; 9445 var instance = target; 9446 9447 while (instance !== null) { 9448 if (instance === common) { 9449 break; 9450 } 9451 9452 var _instance4 = instance, 9453 alternate = _instance4.alternate, 9454 stateNode = _instance4.stateNode, 9455 tag = _instance4.tag; 9456 9457 if (alternate !== null && alternate === common) { 9458 break; 9459 } 9460 9461 if (tag === HostComponent && stateNode !== null) { 9462 var currentTarget = stateNode; 9463 9464 if (inCapturePhase) { 9465 var captureListener = getListener(instance, registrationName); 9466 9467 if (captureListener != null) { 9468 listeners.unshift(createDispatchListener(instance, captureListener, currentTarget)); 9469 } 9470 } else if (!inCapturePhase) { 9471 var bubbleListener = getListener(instance, registrationName); 9472 9473 if (bubbleListener != null) { 9474 listeners.push(createDispatchListener(instance, bubbleListener, currentTarget)); 9475 } 9476 } 9477 } 9478 9479 instance = instance.return; 9480 } 9481 9482 if (listeners.length !== 0) { 9483 dispatchQueue.push({ 9484 event: event, 9485 listeners: listeners 9486 }); 9487 } 9488} // We should only use this function for: 9489// - EnterLeaveEventPlugin 9490// This is because we only process this plugin 9491// in the bubble phase, so we need to accumulate two 9492// phase event listeners. 9493 9494 9495function accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leaveEvent, enterEvent, from, to) { 9496 var common = from && to ? getLowestCommonAncestor(from, to) : null; 9497 9498 if (from !== null) { 9499 accumulateEnterLeaveListenersForEvent(dispatchQueue, leaveEvent, from, common, false); 9500 } 9501 9502 if (to !== null && enterEvent !== null) { 9503 accumulateEnterLeaveListenersForEvent(dispatchQueue, enterEvent, to, common, true); 9504 } 9505} 9506function getListenerSetKey(domEventName, capture) { 9507 return domEventName + "__" + (capture ? 'capture' : 'bubble'); 9508} 9509 9510var didWarnInvalidHydration = false; 9511var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML'; 9512var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning'; 9513var SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning'; 9514var AUTOFOCUS = 'autoFocus'; 9515var CHILDREN = 'children'; 9516var STYLE = 'style'; 9517var HTML$1 = '__html'; 9518var warnedUnknownTags; 9519var validatePropertiesInDevelopment; 9520var warnForPropDifference; 9521var warnForExtraAttributes; 9522var warnForInvalidEventListener; 9523var canDiffStyleForHydrationWarning; 9524var normalizeHTML; 9525 9526{ 9527 warnedUnknownTags = { 9528 // There are working polyfills for <dialog>. Let people use it. 9529 dialog: true, 9530 // Electron ships a custom <webview> tag to display external web content in 9531 // an isolated frame and process. 9532 // This tag is not present in non Electron environments such as JSDom which 9533 // is often used for testing purposes. 9534 // @see https://electronjs.org/docs/api/webview-tag 9535 webview: true 9536 }; 9537 9538 validatePropertiesInDevelopment = function (type, props) { 9539 validateProperties(type, props); 9540 validateProperties$1(type, props); 9541 validateProperties$2(type, props, { 9542 registrationNameDependencies: registrationNameDependencies, 9543 possibleRegistrationNames: possibleRegistrationNames 9544 }); 9545 }; // IE 11 parses & normalizes the style attribute as opposed to other 9546 // browsers. It adds spaces and sorts the properties in some 9547 // non-alphabetical order. Handling that would require sorting CSS 9548 // properties in the client & server versions or applying 9549 // `expectedStyle` to a temporary DOM node to read its `style` attribute 9550 // normalized. Since it only affects IE, we're skipping style warnings 9551 // in that browser completely in favor of doing all that work. 9552 // See https://github.com/facebook/react/issues/11807 9553 9554 9555 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode; 9556 9557 warnForPropDifference = function (propName, serverValue, clientValue) { 9558 if (didWarnInvalidHydration) { 9559 return; 9560 } 9561 9562 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue); 9563 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue); 9564 9565 if (normalizedServerValue === normalizedClientValue) { 9566 return; 9567 } 9568 9569 didWarnInvalidHydration = true; 9570 9571 error('Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue)); 9572 }; 9573 9574 warnForExtraAttributes = function (attributeNames) { 9575 if (didWarnInvalidHydration) { 9576 return; 9577 } 9578 9579 didWarnInvalidHydration = true; 9580 var names = []; 9581 attributeNames.forEach(function (name) { 9582 names.push(name); 9583 }); 9584 9585 error('Extra attributes from the server: %s', names); 9586 }; 9587 9588 warnForInvalidEventListener = function (registrationName, listener) { 9589 if (listener === false) { 9590 error('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); 9591 } else { 9592 error('Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener); 9593 } 9594 }; // Parse the HTML and read it back to normalize the HTML string so that it 9595 // can be used for comparison. 9596 9597 9598 normalizeHTML = function (parent, html) { 9599 // We could have created a separate document here to avoid 9600 // re-initializing custom elements if they exist. But this breaks 9601 // how <noscript> is being handled. So we use the same document. 9602 // See the discussion in https://github.com/facebook/react/pull/11157. 9603 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName); 9604 testElement.innerHTML = html; 9605 return testElement.innerHTML; 9606 }; 9607} // HTML parsing normalizes CR and CRLF to LF. 9608// It also can turn \u0000 into \uFFFD inside attributes. 9609// https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream 9610// If we have a mismatch, it might be caused by that. 9611// We will still patch up in this case but not fire the warning. 9612 9613 9614var NORMALIZE_NEWLINES_REGEX = /\r\n?/g; 9615var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g; 9616 9617function normalizeMarkupForTextOrAttribute(markup) { 9618 { 9619 checkHtmlStringCoercion(markup); 9620 } 9621 9622 var markupString = typeof markup === 'string' ? markup : '' + markup; 9623 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, ''); 9624} 9625 9626function checkForUnmatchedText(serverText, clientText, isConcurrentMode, shouldWarnDev) { 9627 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText); 9628 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText); 9629 9630 if (normalizedServerText === normalizedClientText) { 9631 return; 9632 } 9633 9634 if (shouldWarnDev) { 9635 { 9636 if (!didWarnInvalidHydration) { 9637 didWarnInvalidHydration = true; 9638 9639 error('Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText); 9640 } 9641 } 9642 } 9643 9644 if (isConcurrentMode && enableClientRenderFallbackOnTextMismatch) { 9645 // In concurrent roots, we throw when there's a text mismatch and revert to 9646 // client rendering, up to the nearest Suspense boundary. 9647 throw new Error('Text content does not match server-rendered HTML.'); 9648 } 9649} 9650 9651function getOwnerDocumentFromRootContainer(rootContainerElement) { 9652 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument; 9653} 9654 9655function noop() {} 9656 9657function trapClickOnNonInteractiveElement(node) { 9658 // Mobile Safari does not fire properly bubble click events on 9659 // non-interactive elements, which means delegated click listeners do not 9660 // fire. The workaround for this bug involves attaching an empty click 9661 // listener on the target node. 9662 // https://www.quirksmode.org/blog/archives/2010/09/click_event_del.html 9663 // Just set it using the onclick property so that we don't have to manage any 9664 // bookkeeping for it. Not sure if we need to clear it when the listener is 9665 // removed. 9666 // TODO: Only do this for the relevant Safaris maybe? 9667 node.onclick = noop; 9668} 9669 9670function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) { 9671 for (var propKey in nextProps) { 9672 if (!nextProps.hasOwnProperty(propKey)) { 9673 continue; 9674 } 9675 9676 var nextProp = nextProps[propKey]; 9677 9678 if (propKey === STYLE) { 9679 { 9680 if (nextProp) { 9681 // Freeze the next style object so that we can assume it won't be 9682 // mutated. We have already warned for this in the past. 9683 Object.freeze(nextProp); 9684 } 9685 } // Relies on `updateStylesByID` not mutating `styleUpdates`. 9686 9687 9688 setValueForStyles(domElement, nextProp); 9689 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { 9690 var nextHtml = nextProp ? nextProp[HTML$1] : undefined; 9691 9692 if (nextHtml != null) { 9693 setInnerHTML(domElement, nextHtml); 9694 } 9695 } else if (propKey === CHILDREN) { 9696 if (typeof nextProp === 'string') { 9697 // Avoid setting initial textContent when the text is empty. In IE11 setting 9698 // textContent on a <textarea> will cause the placeholder to not 9699 // show within the <textarea> until it has been focused and blurred again. 9700 // https://github.com/facebook/react/issues/6731#issuecomment-254874553 9701 var canSetTextContent = tag !== 'textarea' || nextProp !== ''; 9702 9703 if (canSetTextContent) { 9704 setTextContent(domElement, nextProp); 9705 } 9706 } else if (typeof nextProp === 'number') { 9707 setTextContent(domElement, '' + nextProp); 9708 } 9709 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) { 9710 if (nextProp != null) { 9711 if ( typeof nextProp !== 'function') { 9712 warnForInvalidEventListener(propKey, nextProp); 9713 } 9714 9715 if (propKey === 'onScroll') { 9716 listenToNonDelegatedEvent('scroll', domElement); 9717 } 9718 } 9719 } else if (nextProp != null) { 9720 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag); 9721 } 9722 } 9723} 9724 9725function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) { 9726 // TODO: Handle wasCustomComponentTag 9727 for (var i = 0; i < updatePayload.length; i += 2) { 9728 var propKey = updatePayload[i]; 9729 var propValue = updatePayload[i + 1]; 9730 9731 if (propKey === STYLE) { 9732 setValueForStyles(domElement, propValue); 9733 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { 9734 setInnerHTML(domElement, propValue); 9735 } else if (propKey === CHILDREN) { 9736 setTextContent(domElement, propValue); 9737 } else { 9738 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag); 9739 } 9740 } 9741} 9742 9743function createElement(type, props, rootContainerElement, parentNamespace) { 9744 var isCustomComponentTag; // We create tags in the namespace of their parent container, except HTML 9745 // tags get no namespace. 9746 9747 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement); 9748 var domElement; 9749 var namespaceURI = parentNamespace; 9750 9751 if (namespaceURI === HTML_NAMESPACE) { 9752 namespaceURI = getIntrinsicNamespace(type); 9753 } 9754 9755 if (namespaceURI === HTML_NAMESPACE) { 9756 { 9757 isCustomComponentTag = isCustomComponent(type, props); // Should this check be gated by parent namespace? Not sure we want to 9758 // allow <SVG> or <mATH>. 9759 9760 if (!isCustomComponentTag && type !== type.toLowerCase()) { 9761 error('<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type); 9762 } 9763 } 9764 9765 if (type === 'script') { 9766 // Create the script via .innerHTML so its "parser-inserted" flag is 9767 // set to true and it does not execute 9768 var div = ownerDocument.createElement('div'); 9769 9770 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line 9771 // This is guaranteed to yield a script element. 9772 9773 var firstChild = div.firstChild; 9774 domElement = div.removeChild(firstChild); 9775 } else if (typeof props.is === 'string') { 9776 // $FlowIssue `createElement` should be updated for Web Components 9777 domElement = ownerDocument.createElement(type, { 9778 is: props.is 9779 }); 9780 } else { 9781 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug. 9782 // See discussion in https://github.com/facebook/react/pull/6896 9783 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240 9784 domElement = ownerDocument.createElement(type); // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size` 9785 // attributes on `select`s needs to be added before `option`s are inserted. 9786 // This prevents: 9787 // - a bug where the `select` does not scroll to the correct option because singular 9788 // `select` elements automatically pick the first item #13222 9789 // - a bug where the `select` set the first item as selected despite the `size` attribute #14239 9790 // See https://github.com/facebook/react/issues/13222 9791 // and https://github.com/facebook/react/issues/14239 9792 9793 if (type === 'select') { 9794 var node = domElement; 9795 9796 if (props.multiple) { 9797 node.multiple = true; 9798 } else if (props.size) { 9799 // Setting a size greater than 1 causes a select to behave like `multiple=true`, where 9800 // it is possible that no option is selected. 9801 // 9802 // This is only necessary when a select in "single selection mode". 9803 node.size = props.size; 9804 } 9805 } 9806 } 9807 } else { 9808 domElement = ownerDocument.createElementNS(namespaceURI, type); 9809 } 9810 9811 { 9812 if (namespaceURI === HTML_NAMESPACE) { 9813 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !hasOwnProperty.call(warnedUnknownTags, type)) { 9814 warnedUnknownTags[type] = true; 9815 9816 error('The tag <%s> is unrecognized in this browser. ' + 'If you meant to render a React component, start its name with ' + 'an uppercase letter.', type); 9817 } 9818 } 9819 } 9820 9821 return domElement; 9822} 9823function createTextNode(text, rootContainerElement) { 9824 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text); 9825} 9826function setInitialProperties(domElement, tag, rawProps, rootContainerElement) { 9827 var isCustomComponentTag = isCustomComponent(tag, rawProps); 9828 9829 { 9830 validatePropertiesInDevelopment(tag, rawProps); 9831 } // TODO: Make sure that we check isMounted before firing any of these events. 9832 9833 9834 var props; 9835 9836 switch (tag) { 9837 case 'dialog': 9838 listenToNonDelegatedEvent('cancel', domElement); 9839 listenToNonDelegatedEvent('close', domElement); 9840 props = rawProps; 9841 break; 9842 9843 case 'iframe': 9844 case 'object': 9845 case 'embed': 9846 // We listen to this event in case to ensure emulated bubble 9847 // listeners still fire for the load event. 9848 listenToNonDelegatedEvent('load', domElement); 9849 props = rawProps; 9850 break; 9851 9852 case 'video': 9853 case 'audio': 9854 // We listen to these events in case to ensure emulated bubble 9855 // listeners still fire for all the media events. 9856 for (var i = 0; i < mediaEventTypes.length; i++) { 9857 listenToNonDelegatedEvent(mediaEventTypes[i], domElement); 9858 } 9859 9860 props = rawProps; 9861 break; 9862 9863 case 'source': 9864 // We listen to this event in case to ensure emulated bubble 9865 // listeners still fire for the error event. 9866 listenToNonDelegatedEvent('error', domElement); 9867 props = rawProps; 9868 break; 9869 9870 case 'img': 9871 case 'image': 9872 case 'link': 9873 // We listen to these events in case to ensure emulated bubble 9874 // listeners still fire for error and load events. 9875 listenToNonDelegatedEvent('error', domElement); 9876 listenToNonDelegatedEvent('load', domElement); 9877 props = rawProps; 9878 break; 9879 9880 case 'details': 9881 // We listen to this event in case to ensure emulated bubble 9882 // listeners still fire for the toggle event. 9883 listenToNonDelegatedEvent('toggle', domElement); 9884 props = rawProps; 9885 break; 9886 9887 case 'input': 9888 initWrapperState(domElement, rawProps); 9889 props = getHostProps(domElement, rawProps); // We listen to this event in case to ensure emulated bubble 9890 // listeners still fire for the invalid event. 9891 9892 listenToNonDelegatedEvent('invalid', domElement); 9893 break; 9894 9895 case 'option': 9896 validateProps(domElement, rawProps); 9897 props = rawProps; 9898 break; 9899 9900 case 'select': 9901 initWrapperState$1(domElement, rawProps); 9902 props = getHostProps$1(domElement, rawProps); // We listen to this event in case to ensure emulated bubble 9903 // listeners still fire for the invalid event. 9904 9905 listenToNonDelegatedEvent('invalid', domElement); 9906 break; 9907 9908 case 'textarea': 9909 initWrapperState$2(domElement, rawProps); 9910 props = getHostProps$2(domElement, rawProps); // We listen to this event in case to ensure emulated bubble 9911 // listeners still fire for the invalid event. 9912 9913 listenToNonDelegatedEvent('invalid', domElement); 9914 break; 9915 9916 default: 9917 props = rawProps; 9918 } 9919 9920 assertValidProps(tag, props); 9921 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag); 9922 9923 switch (tag) { 9924 case 'input': 9925 // TODO: Make sure we check if this is still unmounted or do any clean 9926 // up necessary since we never stop tracking anymore. 9927 track(domElement); 9928 postMountWrapper(domElement, rawProps, false); 9929 break; 9930 9931 case 'textarea': 9932 // TODO: Make sure we check if this is still unmounted or do any clean 9933 // up necessary since we never stop tracking anymore. 9934 track(domElement); 9935 postMountWrapper$3(domElement); 9936 break; 9937 9938 case 'option': 9939 postMountWrapper$1(domElement, rawProps); 9940 break; 9941 9942 case 'select': 9943 postMountWrapper$2(domElement, rawProps); 9944 break; 9945 9946 default: 9947 if (typeof props.onClick === 'function') { 9948 // TODO: This cast may not be sound for SVG, MathML or custom elements. 9949 trapClickOnNonInteractiveElement(domElement); 9950 } 9951 9952 break; 9953 } 9954} // Calculate the diff between the two objects. 9955 9956function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) { 9957 { 9958 validatePropertiesInDevelopment(tag, nextRawProps); 9959 } 9960 9961 var updatePayload = null; 9962 var lastProps; 9963 var nextProps; 9964 9965 switch (tag) { 9966 case 'input': 9967 lastProps = getHostProps(domElement, lastRawProps); 9968 nextProps = getHostProps(domElement, nextRawProps); 9969 updatePayload = []; 9970 break; 9971 9972 case 'select': 9973 lastProps = getHostProps$1(domElement, lastRawProps); 9974 nextProps = getHostProps$1(domElement, nextRawProps); 9975 updatePayload = []; 9976 break; 9977 9978 case 'textarea': 9979 lastProps = getHostProps$2(domElement, lastRawProps); 9980 nextProps = getHostProps$2(domElement, nextRawProps); 9981 updatePayload = []; 9982 break; 9983 9984 default: 9985 lastProps = lastRawProps; 9986 nextProps = nextRawProps; 9987 9988 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') { 9989 // TODO: This cast may not be sound for SVG, MathML or custom elements. 9990 trapClickOnNonInteractiveElement(domElement); 9991 } 9992 9993 break; 9994 } 9995 9996 assertValidProps(tag, nextProps); 9997 var propKey; 9998 var styleName; 9999 var styleUpdates = null; 10000 10001 for (propKey in lastProps) { 10002 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) { 10003 continue; 10004 } 10005 10006 if (propKey === STYLE) { 10007 var lastStyle = lastProps[propKey]; 10008 10009 for (styleName in lastStyle) { 10010 if (lastStyle.hasOwnProperty(styleName)) { 10011 if (!styleUpdates) { 10012 styleUpdates = {}; 10013 } 10014 10015 styleUpdates[styleName] = ''; 10016 } 10017 } 10018 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) ; else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) { 10019 // This is a special case. If any listener updates we need to ensure 10020 // that the "current" fiber pointer gets updated so we need a commit 10021 // to update this element. 10022 if (!updatePayload) { 10023 updatePayload = []; 10024 } 10025 } else { 10026 // For all other deleted properties we add it to the queue. We use 10027 // the allowed property list in the commit phase instead. 10028 (updatePayload = updatePayload || []).push(propKey, null); 10029 } 10030 } 10031 10032 for (propKey in nextProps) { 10033 var nextProp = nextProps[propKey]; 10034 var lastProp = lastProps != null ? lastProps[propKey] : undefined; 10035 10036 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) { 10037 continue; 10038 } 10039 10040 if (propKey === STYLE) { 10041 { 10042 if (nextProp) { 10043 // Freeze the next style object so that we can assume it won't be 10044 // mutated. We have already warned for this in the past. 10045 Object.freeze(nextProp); 10046 } 10047 } 10048 10049 if (lastProp) { 10050 // Unset styles on `lastProp` but not on `nextProp`. 10051 for (styleName in lastProp) { 10052 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) { 10053 if (!styleUpdates) { 10054 styleUpdates = {}; 10055 } 10056 10057 styleUpdates[styleName] = ''; 10058 } 10059 } // Update styles that changed since `lastProp`. 10060 10061 10062 for (styleName in nextProp) { 10063 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) { 10064 if (!styleUpdates) { 10065 styleUpdates = {}; 10066 } 10067 10068 styleUpdates[styleName] = nextProp[styleName]; 10069 } 10070 } 10071 } else { 10072 // Relies on `updateStylesByID` not mutating `styleUpdates`. 10073 if (!styleUpdates) { 10074 if (!updatePayload) { 10075 updatePayload = []; 10076 } 10077 10078 updatePayload.push(propKey, styleUpdates); 10079 } 10080 10081 styleUpdates = nextProp; 10082 } 10083 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { 10084 var nextHtml = nextProp ? nextProp[HTML$1] : undefined; 10085 var lastHtml = lastProp ? lastProp[HTML$1] : undefined; 10086 10087 if (nextHtml != null) { 10088 if (lastHtml !== nextHtml) { 10089 (updatePayload = updatePayload || []).push(propKey, nextHtml); 10090 } 10091 } 10092 } else if (propKey === CHILDREN) { 10093 if (typeof nextProp === 'string' || typeof nextProp === 'number') { 10094 (updatePayload = updatePayload || []).push(propKey, '' + nextProp); 10095 } 10096 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) { 10097 if (nextProp != null) { 10098 // We eagerly listen to this even though we haven't committed yet. 10099 if ( typeof nextProp !== 'function') { 10100 warnForInvalidEventListener(propKey, nextProp); 10101 } 10102 10103 if (propKey === 'onScroll') { 10104 listenToNonDelegatedEvent('scroll', domElement); 10105 } 10106 } 10107 10108 if (!updatePayload && lastProp !== nextProp) { 10109 // This is a special case. If any listener updates we need to ensure 10110 // that the "current" props pointer gets updated so we need a commit 10111 // to update this element. 10112 updatePayload = []; 10113 } 10114 } else { 10115 // For any other property we always add it to the queue and then we 10116 // filter it out using the allowed property list during the commit. 10117 (updatePayload = updatePayload || []).push(propKey, nextProp); 10118 } 10119 } 10120 10121 if (styleUpdates) { 10122 { 10123 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE]); 10124 } 10125 10126 (updatePayload = updatePayload || []).push(STYLE, styleUpdates); 10127 } 10128 10129 return updatePayload; 10130} // Apply the diff. 10131 10132function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) { 10133 // Update checked *before* name. 10134 // In the middle of an update, it is possible to have multiple checked. 10135 // When a checked radio tries to change name, browser makes another radio's checked false. 10136 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) { 10137 updateChecked(domElement, nextRawProps); 10138 } 10139 10140 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps); 10141 var isCustomComponentTag = isCustomComponent(tag, nextRawProps); // Apply the diff. 10142 10143 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag); // TODO: Ensure that an update gets scheduled if any of the special props 10144 // changed. 10145 10146 switch (tag) { 10147 case 'input': 10148 // Update the wrapper around inputs *after* updating props. This has to 10149 // happen after `updateDOMProperties`. Otherwise HTML5 input validations 10150 // raise warnings and prevent the new value from being assigned. 10151 updateWrapper(domElement, nextRawProps); 10152 break; 10153 10154 case 'textarea': 10155 updateWrapper$1(domElement, nextRawProps); 10156 break; 10157 10158 case 'select': 10159 // <select> value update needs to occur after <option> children 10160 // reconciliation 10161 postUpdateWrapper(domElement, nextRawProps); 10162 break; 10163 } 10164} 10165 10166function getPossibleStandardName(propName) { 10167 { 10168 var lowerCasedName = propName.toLowerCase(); 10169 10170 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) { 10171 return null; 10172 } 10173 10174 return possibleStandardNames[lowerCasedName] || null; 10175 } 10176} 10177 10178function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement, isConcurrentMode, shouldWarnDev) { 10179 var isCustomComponentTag; 10180 var extraAttributeNames; 10181 10182 { 10183 isCustomComponentTag = isCustomComponent(tag, rawProps); 10184 validatePropertiesInDevelopment(tag, rawProps); 10185 } // TODO: Make sure that we check isMounted before firing any of these events. 10186 10187 10188 switch (tag) { 10189 case 'dialog': 10190 listenToNonDelegatedEvent('cancel', domElement); 10191 listenToNonDelegatedEvent('close', domElement); 10192 break; 10193 10194 case 'iframe': 10195 case 'object': 10196 case 'embed': 10197 // We listen to this event in case to ensure emulated bubble 10198 // listeners still fire for the load event. 10199 listenToNonDelegatedEvent('load', domElement); 10200 break; 10201 10202 case 'video': 10203 case 'audio': 10204 // We listen to these events in case to ensure emulated bubble 10205 // listeners still fire for all the media events. 10206 for (var i = 0; i < mediaEventTypes.length; i++) { 10207 listenToNonDelegatedEvent(mediaEventTypes[i], domElement); 10208 } 10209 10210 break; 10211 10212 case 'source': 10213 // We listen to this event in case to ensure emulated bubble 10214 // listeners still fire for the error event. 10215 listenToNonDelegatedEvent('error', domElement); 10216 break; 10217 10218 case 'img': 10219 case 'image': 10220 case 'link': 10221 // We listen to these events in case to ensure emulated bubble 10222 // listeners still fire for error and load events. 10223 listenToNonDelegatedEvent('error', domElement); 10224 listenToNonDelegatedEvent('load', domElement); 10225 break; 10226 10227 case 'details': 10228 // We listen to this event in case to ensure emulated bubble 10229 // listeners still fire for the toggle event. 10230 listenToNonDelegatedEvent('toggle', domElement); 10231 break; 10232 10233 case 'input': 10234 initWrapperState(domElement, rawProps); // We listen to this event in case to ensure emulated bubble 10235 // listeners still fire for the invalid event. 10236 10237 listenToNonDelegatedEvent('invalid', domElement); 10238 break; 10239 10240 case 'option': 10241 validateProps(domElement, rawProps); 10242 break; 10243 10244 case 'select': 10245 initWrapperState$1(domElement, rawProps); // We listen to this event in case to ensure emulated bubble 10246 // listeners still fire for the invalid event. 10247 10248 listenToNonDelegatedEvent('invalid', domElement); 10249 break; 10250 10251 case 'textarea': 10252 initWrapperState$2(domElement, rawProps); // We listen to this event in case to ensure emulated bubble 10253 // listeners still fire for the invalid event. 10254 10255 listenToNonDelegatedEvent('invalid', domElement); 10256 break; 10257 } 10258 10259 assertValidProps(tag, rawProps); 10260 10261 { 10262 extraAttributeNames = new Set(); 10263 var attributes = domElement.attributes; 10264 10265 for (var _i = 0; _i < attributes.length; _i++) { 10266 var name = attributes[_i].name.toLowerCase(); 10267 10268 switch (name) { 10269 // Controlled attributes are not validated 10270 // TODO: Only ignore them on controlled tags. 10271 case 'value': 10272 break; 10273 10274 case 'checked': 10275 break; 10276 10277 case 'selected': 10278 break; 10279 10280 default: 10281 // Intentionally use the original name. 10282 // See discussion in https://github.com/facebook/react/pull/10676. 10283 extraAttributeNames.add(attributes[_i].name); 10284 } 10285 } 10286 } 10287 10288 var updatePayload = null; 10289 10290 for (var propKey in rawProps) { 10291 if (!rawProps.hasOwnProperty(propKey)) { 10292 continue; 10293 } 10294 10295 var nextProp = rawProps[propKey]; 10296 10297 if (propKey === CHILDREN) { 10298 // For text content children we compare against textContent. This 10299 // might match additional HTML that is hidden when we read it using 10300 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still 10301 // satisfies our requirement. Our requirement is not to produce perfect 10302 // HTML and attributes. Ideally we should preserve structure but it's 10303 // ok not to if the visible content is still enough to indicate what 10304 // even listeners these nodes might be wired up to. 10305 // TODO: Warn if there is more than a single textNode as a child. 10306 // TODO: Should we use domElement.firstChild.nodeValue to compare? 10307 if (typeof nextProp === 'string') { 10308 if (domElement.textContent !== nextProp) { 10309 if (rawProps[SUPPRESS_HYDRATION_WARNING] !== true) { 10310 checkForUnmatchedText(domElement.textContent, nextProp, isConcurrentMode, shouldWarnDev); 10311 } 10312 10313 updatePayload = [CHILDREN, nextProp]; 10314 } 10315 } else if (typeof nextProp === 'number') { 10316 if (domElement.textContent !== '' + nextProp) { 10317 if (rawProps[SUPPRESS_HYDRATION_WARNING] !== true) { 10318 checkForUnmatchedText(domElement.textContent, nextProp, isConcurrentMode, shouldWarnDev); 10319 } 10320 10321 updatePayload = [CHILDREN, '' + nextProp]; 10322 } 10323 } 10324 } else if (registrationNameDependencies.hasOwnProperty(propKey)) { 10325 if (nextProp != null) { 10326 if ( typeof nextProp !== 'function') { 10327 warnForInvalidEventListener(propKey, nextProp); 10328 } 10329 10330 if (propKey === 'onScroll') { 10331 listenToNonDelegatedEvent('scroll', domElement); 10332 } 10333 } 10334 } else if (shouldWarnDev && true && // Convince Flow we've calculated it (it's DEV-only in this method.) 10335 typeof isCustomComponentTag === 'boolean') { 10336 // Validate that the properties correspond to their expected values. 10337 var serverValue = void 0; 10338 var propertyInfo = isCustomComponentTag && enableCustomElementPropertySupport ? null : getPropertyInfo(propKey); 10339 10340 if (rawProps[SUPPRESS_HYDRATION_WARNING] === true) ; else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING || // Controlled attributes are not validated 10341 // TODO: Only ignore them on controlled tags. 10342 propKey === 'value' || propKey === 'checked' || propKey === 'selected') ; else if (propKey === DANGEROUSLY_SET_INNER_HTML) { 10343 var serverHTML = domElement.innerHTML; 10344 var nextHtml = nextProp ? nextProp[HTML$1] : undefined; 10345 10346 if (nextHtml != null) { 10347 var expectedHTML = normalizeHTML(domElement, nextHtml); 10348 10349 if (expectedHTML !== serverHTML) { 10350 warnForPropDifference(propKey, serverHTML, expectedHTML); 10351 } 10352 } 10353 } else if (propKey === STYLE) { 10354 // $FlowFixMe - Should be inferred as not undefined. 10355 extraAttributeNames.delete(propKey); 10356 10357 if (canDiffStyleForHydrationWarning) { 10358 var expectedStyle = createDangerousStringForStyles(nextProp); 10359 serverValue = domElement.getAttribute('style'); 10360 10361 if (expectedStyle !== serverValue) { 10362 warnForPropDifference(propKey, serverValue, expectedStyle); 10363 } 10364 } 10365 } else if (isCustomComponentTag && !enableCustomElementPropertySupport) { 10366 // $FlowFixMe - Should be inferred as not undefined. 10367 extraAttributeNames.delete(propKey.toLowerCase()); 10368 serverValue = getValueForAttribute(domElement, propKey, nextProp); 10369 10370 if (nextProp !== serverValue) { 10371 warnForPropDifference(propKey, serverValue, nextProp); 10372 } 10373 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) { 10374 var isMismatchDueToBadCasing = false; 10375 10376 if (propertyInfo !== null) { 10377 // $FlowFixMe - Should be inferred as not undefined. 10378 extraAttributeNames.delete(propertyInfo.attributeName); 10379 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo); 10380 } else { 10381 var ownNamespace = parentNamespace; 10382 10383 if (ownNamespace === HTML_NAMESPACE) { 10384 ownNamespace = getIntrinsicNamespace(tag); 10385 } 10386 10387 if (ownNamespace === HTML_NAMESPACE) { 10388 // $FlowFixMe - Should be inferred as not undefined. 10389 extraAttributeNames.delete(propKey.toLowerCase()); 10390 } else { 10391 var standardName = getPossibleStandardName(propKey); 10392 10393 if (standardName !== null && standardName !== propKey) { 10394 // If an SVG prop is supplied with bad casing, it will 10395 // be successfully parsed from HTML, but will produce a mismatch 10396 // (and would be incorrectly rendered on the client). 10397 // However, we already warn about bad casing elsewhere. 10398 // So we'll skip the misleading extra mismatch warning in this case. 10399 isMismatchDueToBadCasing = true; // $FlowFixMe - Should be inferred as not undefined. 10400 10401 extraAttributeNames.delete(standardName); 10402 } // $FlowFixMe - Should be inferred as not undefined. 10403 10404 10405 extraAttributeNames.delete(propKey); 10406 } 10407 10408 serverValue = getValueForAttribute(domElement, propKey, nextProp); 10409 } 10410 10411 var dontWarnCustomElement = enableCustomElementPropertySupport ; 10412 10413 if (!dontWarnCustomElement && nextProp !== serverValue && !isMismatchDueToBadCasing) { 10414 warnForPropDifference(propKey, serverValue, nextProp); 10415 } 10416 } 10417 } 10418 } 10419 10420 { 10421 if (shouldWarnDev) { 10422 if ( // $FlowFixMe - Should be inferred as not undefined. 10423 extraAttributeNames.size > 0 && rawProps[SUPPRESS_HYDRATION_WARNING] !== true) { 10424 // $FlowFixMe - Should be inferred as not undefined. 10425 warnForExtraAttributes(extraAttributeNames); 10426 } 10427 } 10428 } 10429 10430 switch (tag) { 10431 case 'input': 10432 // TODO: Make sure we check if this is still unmounted or do any clean 10433 // up necessary since we never stop tracking anymore. 10434 track(domElement); 10435 postMountWrapper(domElement, rawProps, true); 10436 break; 10437 10438 case 'textarea': 10439 // TODO: Make sure we check if this is still unmounted or do any clean 10440 // up necessary since we never stop tracking anymore. 10441 track(domElement); 10442 postMountWrapper$3(domElement); 10443 break; 10444 10445 case 'select': 10446 case 'option': 10447 // For input and textarea we current always set the value property at 10448 // post mount to force it to diverge from attributes. However, for 10449 // option and select we don't quite do the same thing and select 10450 // is not resilient to the DOM state changing so we don't do that here. 10451 // TODO: Consider not doing this for input and textarea. 10452 break; 10453 10454 default: 10455 if (typeof rawProps.onClick === 'function') { 10456 // TODO: This cast may not be sound for SVG, MathML or custom elements. 10457 trapClickOnNonInteractiveElement(domElement); 10458 } 10459 10460 break; 10461 } 10462 10463 return updatePayload; 10464} 10465function diffHydratedText(textNode, text, isConcurrentMode) { 10466 var isDifferent = textNode.nodeValue !== text; 10467 return isDifferent; 10468} 10469function warnForDeletedHydratableElement(parentNode, child) { 10470 { 10471 if (didWarnInvalidHydration) { 10472 return; 10473 } 10474 10475 didWarnInvalidHydration = true; 10476 10477 error('Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase()); 10478 } 10479} 10480function warnForDeletedHydratableText(parentNode, child) { 10481 { 10482 if (didWarnInvalidHydration) { 10483 return; 10484 } 10485 10486 didWarnInvalidHydration = true; 10487 10488 error('Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase()); 10489 } 10490} 10491function warnForInsertedHydratedElement(parentNode, tag, props) { 10492 { 10493 if (didWarnInvalidHydration) { 10494 return; 10495 } 10496 10497 didWarnInvalidHydration = true; 10498 10499 error('Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase()); 10500 } 10501} 10502function warnForInsertedHydratedText(parentNode, text) { 10503 { 10504 if (text === '') { 10505 // We expect to insert empty text nodes since they're not represented in 10506 // the HTML. 10507 // TODO: Remove this special case if we can just avoid inserting empty 10508 // text nodes. 10509 return; 10510 } 10511 10512 if (didWarnInvalidHydration) { 10513 return; 10514 } 10515 10516 didWarnInvalidHydration = true; 10517 10518 error('Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase()); 10519 } 10520} 10521function restoreControlledState$3(domElement, tag, props) { 10522 switch (tag) { 10523 case 'input': 10524 restoreControlledState(domElement, props); 10525 return; 10526 10527 case 'textarea': 10528 restoreControlledState$2(domElement, props); 10529 return; 10530 10531 case 'select': 10532 restoreControlledState$1(domElement, props); 10533 return; 10534 } 10535} 10536 10537var validateDOMNesting = function () {}; 10538 10539var updatedAncestorInfo = function () {}; 10540 10541{ 10542 // This validation code was written based on the HTML5 parsing spec: 10543 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope 10544 // 10545 // Note: this does not catch all invalid nesting, nor does it try to (as it's 10546 // not clear what practical benefit doing so provides); instead, we warn only 10547 // for cases where the parser will give a parse tree differing from what React 10548 // intended. For example, <b><div></div></b> is invalid but we don't warn 10549 // because it still parses correctly; we do warn for other cases like nested 10550 // <p> tags where the beginning of the second element implicitly closes the 10551 // first, causing a confusing mess. 10552 // https://html.spec.whatwg.org/multipage/syntax.html#special 10553 var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope 10554 10555 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point 10556 // TODO: Distinguish by namespace here -- for <title>, including it here 10557 // errs on the side of fewer warnings 10558 'foreignObject', 'desc', 'title']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope 10559 10560 var buttonScopeTags = inScopeTags.concat(['button']); // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags 10561 10562 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt']; 10563 var emptyAncestorInfo = { 10564 current: null, 10565 formTag: null, 10566 aTagInScope: null, 10567 buttonTagInScope: null, 10568 nobrTagInScope: null, 10569 pTagInButtonScope: null, 10570 listItemTagAutoclosing: null, 10571 dlItemTagAutoclosing: null 10572 }; 10573 10574 updatedAncestorInfo = function (oldInfo, tag) { 10575 var ancestorInfo = assign({}, oldInfo || emptyAncestorInfo); 10576 10577 var info = { 10578 tag: tag 10579 }; 10580 10581 if (inScopeTags.indexOf(tag) !== -1) { 10582 ancestorInfo.aTagInScope = null; 10583 ancestorInfo.buttonTagInScope = null; 10584 ancestorInfo.nobrTagInScope = null; 10585 } 10586 10587 if (buttonScopeTags.indexOf(tag) !== -1) { 10588 ancestorInfo.pTagInButtonScope = null; 10589 } // See rules for 'li', 'dd', 'dt' start tags in 10590 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody 10591 10592 10593 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') { 10594 ancestorInfo.listItemTagAutoclosing = null; 10595 ancestorInfo.dlItemTagAutoclosing = null; 10596 } 10597 10598 ancestorInfo.current = info; 10599 10600 if (tag === 'form') { 10601 ancestorInfo.formTag = info; 10602 } 10603 10604 if (tag === 'a') { 10605 ancestorInfo.aTagInScope = info; 10606 } 10607 10608 if (tag === 'button') { 10609 ancestorInfo.buttonTagInScope = info; 10610 } 10611 10612 if (tag === 'nobr') { 10613 ancestorInfo.nobrTagInScope = info; 10614 } 10615 10616 if (tag === 'p') { 10617 ancestorInfo.pTagInButtonScope = info; 10618 } 10619 10620 if (tag === 'li') { 10621 ancestorInfo.listItemTagAutoclosing = info; 10622 } 10623 10624 if (tag === 'dd' || tag === 'dt') { 10625 ancestorInfo.dlItemTagAutoclosing = info; 10626 } 10627 10628 return ancestorInfo; 10629 }; 10630 /** 10631 * Returns whether 10632 */ 10633 10634 10635 var isTagValidWithParent = function (tag, parentTag) { 10636 // First, let's check if we're in an unusual parsing mode... 10637 switch (parentTag) { 10638 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect 10639 case 'select': 10640 return tag === 'option' || tag === 'optgroup' || tag === '#text'; 10641 10642 case 'optgroup': 10643 return tag === 'option' || tag === '#text'; 10644 // Strictly speaking, seeing an <option> doesn't mean we're in a <select> 10645 // but 10646 10647 case 'option': 10648 return tag === '#text'; 10649 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd 10650 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption 10651 // No special behavior since these rules fall back to "in body" mode for 10652 // all except special table nodes which cause bad parsing behavior anyway. 10653 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr 10654 10655 case 'tr': 10656 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template'; 10657 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody 10658 10659 case 'tbody': 10660 case 'thead': 10661 case 'tfoot': 10662 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template'; 10663 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup 10664 10665 case 'colgroup': 10666 return tag === 'col' || tag === 'template'; 10667 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable 10668 10669 case 'table': 10670 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template'; 10671 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead 10672 10673 case 'head': 10674 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template'; 10675 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element 10676 10677 case 'html': 10678 return tag === 'head' || tag === 'body' || tag === 'frameset'; 10679 10680 case 'frameset': 10681 return tag === 'frame'; 10682 10683 case '#document': 10684 return tag === 'html'; 10685 } // Probably in the "in body" parsing mode, so we outlaw only tag combos 10686 // where the parsing rules cause implicit opens or closes to be added. 10687 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody 10688 10689 10690 switch (tag) { 10691 case 'h1': 10692 case 'h2': 10693 case 'h3': 10694 case 'h4': 10695 case 'h5': 10696 case 'h6': 10697 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6'; 10698 10699 case 'rp': 10700 case 'rt': 10701 return impliedEndTags.indexOf(parentTag) === -1; 10702 10703 case 'body': 10704 case 'caption': 10705 case 'col': 10706 case 'colgroup': 10707 case 'frameset': 10708 case 'frame': 10709 case 'head': 10710 case 'html': 10711 case 'tbody': 10712 case 'td': 10713 case 'tfoot': 10714 case 'th': 10715 case 'thead': 10716 case 'tr': 10717 // These tags are only valid with a few parents that have special child 10718 // parsing rules -- if we're down here, then none of those matched and 10719 // so we allow it only if we don't know what the parent is, as all other 10720 // cases are invalid. 10721 return parentTag == null; 10722 } 10723 10724 return true; 10725 }; 10726 /** 10727 * Returns whether 10728 */ 10729 10730 10731 var findInvalidAncestorForTag = function (tag, ancestorInfo) { 10732 switch (tag) { 10733 case 'address': 10734 case 'article': 10735 case 'aside': 10736 case 'blockquote': 10737 case 'center': 10738 case 'details': 10739 case 'dialog': 10740 case 'dir': 10741 case 'div': 10742 case 'dl': 10743 case 'fieldset': 10744 case 'figcaption': 10745 case 'figure': 10746 case 'footer': 10747 case 'header': 10748 case 'hgroup': 10749 case 'main': 10750 case 'menu': 10751 case 'nav': 10752 case 'ol': 10753 case 'p': 10754 case 'section': 10755 case 'summary': 10756 case 'ul': 10757 case 'pre': 10758 case 'listing': 10759 case 'table': 10760 case 'hr': 10761 case 'xmp': 10762 case 'h1': 10763 case 'h2': 10764 case 'h3': 10765 case 'h4': 10766 case 'h5': 10767 case 'h6': 10768 return ancestorInfo.pTagInButtonScope; 10769 10770 case 'form': 10771 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope; 10772 10773 case 'li': 10774 return ancestorInfo.listItemTagAutoclosing; 10775 10776 case 'dd': 10777 case 'dt': 10778 return ancestorInfo.dlItemTagAutoclosing; 10779 10780 case 'button': 10781 return ancestorInfo.buttonTagInScope; 10782 10783 case 'a': 10784 // Spec says something about storing a list of markers, but it sounds 10785 // equivalent to this check. 10786 return ancestorInfo.aTagInScope; 10787 10788 case 'nobr': 10789 return ancestorInfo.nobrTagInScope; 10790 } 10791 10792 return null; 10793 }; 10794 10795 var didWarn$1 = {}; 10796 10797 validateDOMNesting = function (childTag, childText, ancestorInfo) { 10798 ancestorInfo = ancestorInfo || emptyAncestorInfo; 10799 var parentInfo = ancestorInfo.current; 10800 var parentTag = parentInfo && parentInfo.tag; 10801 10802 if (childText != null) { 10803 if (childTag != null) { 10804 error('validateDOMNesting: when childText is passed, childTag should be null'); 10805 } 10806 10807 childTag = '#text'; 10808 } 10809 10810 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo; 10811 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo); 10812 var invalidParentOrAncestor = invalidParent || invalidAncestor; 10813 10814 if (!invalidParentOrAncestor) { 10815 return; 10816 } 10817 10818 var ancestorTag = invalidParentOrAncestor.tag; 10819 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag; 10820 10821 if (didWarn$1[warnKey]) { 10822 return; 10823 } 10824 10825 didWarn$1[warnKey] = true; 10826 var tagDisplayName = childTag; 10827 var whitespaceInfo = ''; 10828 10829 if (childTag === '#text') { 10830 if (/\S/.test(childText)) { 10831 tagDisplayName = 'Text nodes'; 10832 } else { 10833 tagDisplayName = 'Whitespace text nodes'; 10834 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.'; 10835 } 10836 } else { 10837 tagDisplayName = '<' + childTag + '>'; 10838 } 10839 10840 if (invalidParent) { 10841 var info = ''; 10842 10843 if (ancestorTag === 'table' && childTag === 'tr') { 10844 info += ' Add a <tbody>, <thead> or <tfoot> to your code to match the DOM tree generated by ' + 'the browser.'; 10845 } 10846 10847 error('validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info); 10848 } else { 10849 error('validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.', tagDisplayName, ancestorTag); 10850 } 10851 }; 10852} 10853 10854var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning'; 10855var SUSPENSE_START_DATA = '$'; 10856var SUSPENSE_END_DATA = '/$'; 10857var SUSPENSE_PENDING_START_DATA = '$?'; 10858var SUSPENSE_FALLBACK_START_DATA = '$!'; 10859var STYLE$1 = 'style'; 10860var eventsEnabled = null; 10861var selectionInformation = null; 10862function getRootHostContext(rootContainerInstance) { 10863 var type; 10864 var namespace; 10865 var nodeType = rootContainerInstance.nodeType; 10866 10867 switch (nodeType) { 10868 case DOCUMENT_NODE: 10869 case DOCUMENT_FRAGMENT_NODE: 10870 { 10871 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment'; 10872 var root = rootContainerInstance.documentElement; 10873 namespace = root ? root.namespaceURI : getChildNamespace(null, ''); 10874 break; 10875 } 10876 10877 default: 10878 { 10879 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance; 10880 var ownNamespace = container.namespaceURI || null; 10881 type = container.tagName; 10882 namespace = getChildNamespace(ownNamespace, type); 10883 break; 10884 } 10885 } 10886 10887 { 10888 var validatedTag = type.toLowerCase(); 10889 var ancestorInfo = updatedAncestorInfo(null, validatedTag); 10890 return { 10891 namespace: namespace, 10892 ancestorInfo: ancestorInfo 10893 }; 10894 } 10895} 10896function getChildHostContext(parentHostContext, type, rootContainerInstance) { 10897 { 10898 var parentHostContextDev = parentHostContext; 10899 var namespace = getChildNamespace(parentHostContextDev.namespace, type); 10900 var ancestorInfo = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type); 10901 return { 10902 namespace: namespace, 10903 ancestorInfo: ancestorInfo 10904 }; 10905 } 10906} 10907function getPublicInstance(instance) { 10908 return instance; 10909} 10910function prepareForCommit(containerInfo) { 10911 eventsEnabled = isEnabled(); 10912 selectionInformation = getSelectionInformation(); 10913 var activeInstance = null; 10914 10915 setEnabled(false); 10916 return activeInstance; 10917} 10918function resetAfterCommit(containerInfo) { 10919 restoreSelection(selectionInformation); 10920 setEnabled(eventsEnabled); 10921 eventsEnabled = null; 10922 selectionInformation = null; 10923} 10924function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) { 10925 var parentNamespace; 10926 10927 { 10928 // TODO: take namespace into account when validating. 10929 var hostContextDev = hostContext; 10930 validateDOMNesting(type, null, hostContextDev.ancestorInfo); 10931 10932 if (typeof props.children === 'string' || typeof props.children === 'number') { 10933 var string = '' + props.children; 10934 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type); 10935 validateDOMNesting(null, string, ownAncestorInfo); 10936 } 10937 10938 parentNamespace = hostContextDev.namespace; 10939 } 10940 10941 var domElement = createElement(type, props, rootContainerInstance, parentNamespace); 10942 precacheFiberNode(internalInstanceHandle, domElement); 10943 updateFiberProps(domElement, props); 10944 return domElement; 10945} 10946function appendInitialChild(parentInstance, child) { 10947 parentInstance.appendChild(child); 10948} 10949function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) { 10950 setInitialProperties(domElement, type, props, rootContainerInstance); 10951 10952 switch (type) { 10953 case 'button': 10954 case 'input': 10955 case 'select': 10956 case 'textarea': 10957 return !!props.autoFocus; 10958 10959 case 'img': 10960 return true; 10961 10962 default: 10963 return false; 10964 } 10965} 10966function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) { 10967 { 10968 var hostContextDev = hostContext; 10969 10970 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) { 10971 var string = '' + newProps.children; 10972 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type); 10973 validateDOMNesting(null, string, ownAncestorInfo); 10974 } 10975 } 10976 10977 return diffProperties(domElement, type, oldProps, newProps); 10978} 10979function shouldSetTextContent(type, props) { 10980 return type === 'textarea' || type === 'noscript' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && props.dangerouslySetInnerHTML.__html != null; 10981} 10982function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) { 10983 { 10984 var hostContextDev = hostContext; 10985 validateDOMNesting(null, text, hostContextDev.ancestorInfo); 10986 } 10987 10988 var textNode = createTextNode(text, rootContainerInstance); 10989 precacheFiberNode(internalInstanceHandle, textNode); 10990 return textNode; 10991} 10992function getCurrentEventPriority() { 10993 var currentEvent = window.event; 10994 10995 if (currentEvent === undefined) { 10996 return DefaultEventPriority; 10997 } 10998 10999 return getEventPriority(currentEvent.type); 11000} 11001// if a component just imports ReactDOM (e.g. for findDOMNode). 11002// Some environments might not have setTimeout or clearTimeout. 11003 11004var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined; 11005var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined; 11006var noTimeout = -1; 11007var localPromise = typeof Promise === 'function' ? Promise : undefined; // ------------------- 11008var scheduleMicrotask = typeof queueMicrotask === 'function' ? queueMicrotask : typeof localPromise !== 'undefined' ? function (callback) { 11009 return localPromise.resolve(null).then(callback).catch(handleErrorInNextTick); 11010} : scheduleTimeout; // TODO: Determine the best fallback here. 11011 11012function handleErrorInNextTick(error) { 11013 setTimeout(function () { 11014 throw error; 11015 }); 11016} // ------------------- 11017function commitMount(domElement, type, newProps, internalInstanceHandle) { 11018 // Despite the naming that might imply otherwise, this method only 11019 // fires if there is an `Update` effect scheduled during mounting. 11020 // This happens if `finalizeInitialChildren` returns `true` (which it 11021 // does to implement the `autoFocus` attribute on the client). But 11022 // there are also other cases when this might happen (such as patching 11023 // up text content during hydration mismatch). So we'll check this again. 11024 switch (type) { 11025 case 'button': 11026 case 'input': 11027 case 'select': 11028 case 'textarea': 11029 if (newProps.autoFocus) { 11030 domElement.focus(); 11031 } 11032 11033 return; 11034 11035 case 'img': 11036 { 11037 if (newProps.src) { 11038 domElement.src = newProps.src; 11039 } 11040 11041 return; 11042 } 11043 } 11044} 11045function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) { 11046 // Apply the diff to the DOM node. 11047 updateProperties(domElement, updatePayload, type, oldProps, newProps); // Update the props handle so that we know which props are the ones with 11048 // with current event handlers. 11049 11050 updateFiberProps(domElement, newProps); 11051} 11052function resetTextContent(domElement) { 11053 setTextContent(domElement, ''); 11054} 11055function commitTextUpdate(textInstance, oldText, newText) { 11056 textInstance.nodeValue = newText; 11057} 11058function appendChild(parentInstance, child) { 11059 parentInstance.appendChild(child); 11060} 11061function appendChildToContainer(container, child) { 11062 var parentNode; 11063 11064 if (container.nodeType === COMMENT_NODE) { 11065 parentNode = container.parentNode; 11066 parentNode.insertBefore(child, container); 11067 } else { 11068 parentNode = container; 11069 parentNode.appendChild(child); 11070 } // This container might be used for a portal. 11071 // If something inside a portal is clicked, that click should bubble 11072 // through the React tree. However, on Mobile Safari the click would 11073 // never bubble through the *DOM* tree unless an ancestor with onclick 11074 // event exists. So we wouldn't see it and dispatch it. 11075 // This is why we ensure that non React root containers have inline onclick 11076 // defined. 11077 // https://github.com/facebook/react/issues/11918 11078 11079 11080 var reactRootContainer = container._reactRootContainer; 11081 11082 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) { 11083 // TODO: This cast may not be sound for SVG, MathML or custom elements. 11084 trapClickOnNonInteractiveElement(parentNode); 11085 } 11086} 11087function insertBefore(parentInstance, child, beforeChild) { 11088 parentInstance.insertBefore(child, beforeChild); 11089} 11090function insertInContainerBefore(container, child, beforeChild) { 11091 if (container.nodeType === COMMENT_NODE) { 11092 container.parentNode.insertBefore(child, beforeChild); 11093 } else { 11094 container.insertBefore(child, beforeChild); 11095 } 11096} 11097 11098function removeChild(parentInstance, child) { 11099 parentInstance.removeChild(child); 11100} 11101function removeChildFromContainer(container, child) { 11102 if (container.nodeType === COMMENT_NODE) { 11103 container.parentNode.removeChild(child); 11104 } else { 11105 container.removeChild(child); 11106 } 11107} 11108function clearSuspenseBoundary(parentInstance, suspenseInstance) { 11109 var node = suspenseInstance; // Delete all nodes within this suspense boundary. 11110 // There might be nested nodes so we need to keep track of how 11111 // deep we are and only break out when we're back on top. 11112 11113 var depth = 0; 11114 11115 do { 11116 var nextNode = node.nextSibling; 11117 parentInstance.removeChild(node); 11118 11119 if (nextNode && nextNode.nodeType === COMMENT_NODE) { 11120 var data = nextNode.data; 11121 11122 if (data === SUSPENSE_END_DATA) { 11123 if (depth === 0) { 11124 parentInstance.removeChild(nextNode); // Retry if any event replaying was blocked on this. 11125 11126 retryIfBlockedOn(suspenseInstance); 11127 return; 11128 } else { 11129 depth--; 11130 } 11131 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_PENDING_START_DATA || data === SUSPENSE_FALLBACK_START_DATA) { 11132 depth++; 11133 } 11134 } 11135 11136 node = nextNode; 11137 } while (node); // TODO: Warn, we didn't find the end comment boundary. 11138 // Retry if any event replaying was blocked on this. 11139 11140 11141 retryIfBlockedOn(suspenseInstance); 11142} 11143function clearSuspenseBoundaryFromContainer(container, suspenseInstance) { 11144 if (container.nodeType === COMMENT_NODE) { 11145 clearSuspenseBoundary(container.parentNode, suspenseInstance); 11146 } else if (container.nodeType === ELEMENT_NODE) { 11147 clearSuspenseBoundary(container, suspenseInstance); 11148 } // Retry if any event replaying was blocked on this. 11149 11150 11151 retryIfBlockedOn(container); 11152} 11153function hideInstance(instance) { 11154 // TODO: Does this work for all element types? What about MathML? Should we 11155 // pass host context to this method? 11156 instance = instance; 11157 var style = instance.style; 11158 11159 if (typeof style.setProperty === 'function') { 11160 style.setProperty('display', 'none', 'important'); 11161 } else { 11162 style.display = 'none'; 11163 } 11164} 11165function hideTextInstance(textInstance) { 11166 textInstance.nodeValue = ''; 11167} 11168function unhideInstance(instance, props) { 11169 instance = instance; 11170 var styleProp = props[STYLE$1]; 11171 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null; 11172 instance.style.display = dangerousStyleValue('display', display); 11173} 11174function unhideTextInstance(textInstance, text) { 11175 textInstance.nodeValue = text; 11176} 11177function clearContainer(container) { 11178 if (container.nodeType === ELEMENT_NODE) { 11179 container.textContent = ''; 11180 } else if (container.nodeType === DOCUMENT_NODE) { 11181 if (container.documentElement) { 11182 container.removeChild(container.documentElement); 11183 } 11184 } 11185} // ------------------- 11186function canHydrateInstance(instance, type, props) { 11187 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) { 11188 return null; 11189 } // This has now been refined to an element node. 11190 11191 11192 return instance; 11193} 11194function canHydrateTextInstance(instance, text) { 11195 if (text === '' || instance.nodeType !== TEXT_NODE) { 11196 // Empty strings are not parsed by HTML so there won't be a correct match here. 11197 return null; 11198 } // This has now been refined to a text node. 11199 11200 11201 return instance; 11202} 11203function canHydrateSuspenseInstance(instance) { 11204 if (instance.nodeType !== COMMENT_NODE) { 11205 // Empty strings are not parsed by HTML so there won't be a correct match here. 11206 return null; 11207 } // This has now been refined to a suspense node. 11208 11209 11210 return instance; 11211} 11212function isSuspenseInstancePending(instance) { 11213 return instance.data === SUSPENSE_PENDING_START_DATA; 11214} 11215function isSuspenseInstanceFallback(instance) { 11216 return instance.data === SUSPENSE_FALLBACK_START_DATA; 11217} 11218function getSuspenseInstanceFallbackErrorDetails(instance) { 11219 var dataset = instance.nextSibling && instance.nextSibling.dataset; 11220 var digest, message, stack; 11221 11222 if (dataset) { 11223 digest = dataset.dgst; 11224 11225 { 11226 message = dataset.msg; 11227 stack = dataset.stck; 11228 } 11229 } 11230 11231 { 11232 return { 11233 message: message, 11234 digest: digest, 11235 stack: stack 11236 }; 11237 } // let value = {message: undefined, hash: undefined}; 11238 // const nextSibling = instance.nextSibling; 11239 // if (nextSibling) { 11240 // const dataset = ((nextSibling: any): HTMLTemplateElement).dataset; 11241 // value.message = dataset.msg; 11242 // value.hash = dataset.hash; 11243 // if (true) { 11244 // value.stack = dataset.stack; 11245 // } 11246 // } 11247 // return value; 11248 11249} 11250function registerSuspenseInstanceRetry(instance, callback) { 11251 instance._reactRetry = callback; 11252} 11253 11254function getNextHydratable(node) { 11255 // Skip non-hydratable nodes. 11256 for (; node != null; node = node.nextSibling) { 11257 var nodeType = node.nodeType; 11258 11259 if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) { 11260 break; 11261 } 11262 11263 if (nodeType === COMMENT_NODE) { 11264 var nodeData = node.data; 11265 11266 if (nodeData === SUSPENSE_START_DATA || nodeData === SUSPENSE_FALLBACK_START_DATA || nodeData === SUSPENSE_PENDING_START_DATA) { 11267 break; 11268 } 11269 11270 if (nodeData === SUSPENSE_END_DATA) { 11271 return null; 11272 } 11273 } 11274 } 11275 11276 return node; 11277} 11278 11279function getNextHydratableSibling(instance) { 11280 return getNextHydratable(instance.nextSibling); 11281} 11282function getFirstHydratableChild(parentInstance) { 11283 return getNextHydratable(parentInstance.firstChild); 11284} 11285function getFirstHydratableChildWithinContainer(parentContainer) { 11286 return getNextHydratable(parentContainer.firstChild); 11287} 11288function getFirstHydratableChildWithinSuspenseInstance(parentInstance) { 11289 return getNextHydratable(parentInstance.nextSibling); 11290} 11291function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle, shouldWarnDev) { 11292 precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events 11293 // get attached. 11294 11295 updateFiberProps(instance, props); 11296 var parentNamespace; 11297 11298 { 11299 var hostContextDev = hostContext; 11300 parentNamespace = hostContextDev.namespace; 11301 } // TODO: Temporary hack to check if we're in a concurrent root. We can delete 11302 // when the legacy root API is removed. 11303 11304 11305 var isConcurrentMode = (internalInstanceHandle.mode & ConcurrentMode) !== NoMode; 11306 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance, isConcurrentMode, shouldWarnDev); 11307} 11308function hydrateTextInstance(textInstance, text, internalInstanceHandle, shouldWarnDev) { 11309 precacheFiberNode(internalInstanceHandle, textInstance); // TODO: Temporary hack to check if we're in a concurrent root. We can delete 11310 // when the legacy root API is removed. 11311 11312 var isConcurrentMode = (internalInstanceHandle.mode & ConcurrentMode) !== NoMode; 11313 return diffHydratedText(textInstance, text); 11314} 11315function hydrateSuspenseInstance(suspenseInstance, internalInstanceHandle) { 11316 precacheFiberNode(internalInstanceHandle, suspenseInstance); 11317} 11318function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) { 11319 var node = suspenseInstance.nextSibling; // Skip past all nodes within this suspense boundary. 11320 // There might be nested nodes so we need to keep track of how 11321 // deep we are and only break out when we're back on top. 11322 11323 var depth = 0; 11324 11325 while (node) { 11326 if (node.nodeType === COMMENT_NODE) { 11327 var data = node.data; 11328 11329 if (data === SUSPENSE_END_DATA) { 11330 if (depth === 0) { 11331 return getNextHydratableSibling(node); 11332 } else { 11333 depth--; 11334 } 11335 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) { 11336 depth++; 11337 } 11338 } 11339 11340 node = node.nextSibling; 11341 } // TODO: Warn, we didn't find the end comment boundary. 11342 11343 11344 return null; 11345} // Returns the SuspenseInstance if this node is a direct child of a 11346// SuspenseInstance. I.e. if its previous sibling is a Comment with 11347// SUSPENSE_x_START_DATA. Otherwise, null. 11348 11349function getParentSuspenseInstance(targetInstance) { 11350 var node = targetInstance.previousSibling; // Skip past all nodes within this suspense boundary. 11351 // There might be nested nodes so we need to keep track of how 11352 // deep we are and only break out when we're back on top. 11353 11354 var depth = 0; 11355 11356 while (node) { 11357 if (node.nodeType === COMMENT_NODE) { 11358 var data = node.data; 11359 11360 if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) { 11361 if (depth === 0) { 11362 return node; 11363 } else { 11364 depth--; 11365 } 11366 } else if (data === SUSPENSE_END_DATA) { 11367 depth++; 11368 } 11369 } 11370 11371 node = node.previousSibling; 11372 } 11373 11374 return null; 11375} 11376function commitHydratedContainer(container) { 11377 // Retry if any event replaying was blocked on this. 11378 retryIfBlockedOn(container); 11379} 11380function commitHydratedSuspenseInstance(suspenseInstance) { 11381 // Retry if any event replaying was blocked on this. 11382 retryIfBlockedOn(suspenseInstance); 11383} 11384function shouldDeleteUnhydratedTailInstances(parentType) { 11385 return parentType !== 'head' && parentType !== 'body'; 11386} 11387function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text, isConcurrentMode) { 11388 var shouldWarnDev = true; 11389 checkForUnmatchedText(textInstance.nodeValue, text, isConcurrentMode, shouldWarnDev); 11390} 11391function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text, isConcurrentMode) { 11392 if (parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) { 11393 var shouldWarnDev = true; 11394 checkForUnmatchedText(textInstance.nodeValue, text, isConcurrentMode, shouldWarnDev); 11395 } 11396} 11397function didNotHydrateInstanceWithinContainer(parentContainer, instance) { 11398 { 11399 if (instance.nodeType === ELEMENT_NODE) { 11400 warnForDeletedHydratableElement(parentContainer, instance); 11401 } else if (instance.nodeType === COMMENT_NODE) ; else { 11402 warnForDeletedHydratableText(parentContainer, instance); 11403 } 11404 } 11405} 11406function didNotHydrateInstanceWithinSuspenseInstance(parentInstance, instance) { 11407 { 11408 // $FlowFixMe: Only Element or Document can be parent nodes. 11409 var parentNode = parentInstance.parentNode; 11410 11411 if (parentNode !== null) { 11412 if (instance.nodeType === ELEMENT_NODE) { 11413 warnForDeletedHydratableElement(parentNode, instance); 11414 } else if (instance.nodeType === COMMENT_NODE) ; else { 11415 warnForDeletedHydratableText(parentNode, instance); 11416 } 11417 } 11418 } 11419} 11420function didNotHydrateInstance(parentType, parentProps, parentInstance, instance, isConcurrentMode) { 11421 { 11422 if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) { 11423 if (instance.nodeType === ELEMENT_NODE) { 11424 warnForDeletedHydratableElement(parentInstance, instance); 11425 } else if (instance.nodeType === COMMENT_NODE) ; else { 11426 warnForDeletedHydratableText(parentInstance, instance); 11427 } 11428 } 11429 } 11430} 11431function didNotFindHydratableInstanceWithinContainer(parentContainer, type, props) { 11432 { 11433 warnForInsertedHydratedElement(parentContainer, type); 11434 } 11435} 11436function didNotFindHydratableTextInstanceWithinContainer(parentContainer, text) { 11437 { 11438 warnForInsertedHydratedText(parentContainer, text); 11439 } 11440} 11441function didNotFindHydratableInstanceWithinSuspenseInstance(parentInstance, type, props) { 11442 { 11443 // $FlowFixMe: Only Element or Document can be parent nodes. 11444 var parentNode = parentInstance.parentNode; 11445 if (parentNode !== null) warnForInsertedHydratedElement(parentNode, type); 11446 } 11447} 11448function didNotFindHydratableTextInstanceWithinSuspenseInstance(parentInstance, text) { 11449 { 11450 // $FlowFixMe: Only Element or Document can be parent nodes. 11451 var parentNode = parentInstance.parentNode; 11452 if (parentNode !== null) warnForInsertedHydratedText(parentNode, text); 11453 } 11454} 11455function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props, isConcurrentMode) { 11456 { 11457 if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) { 11458 warnForInsertedHydratedElement(parentInstance, type); 11459 } 11460 } 11461} 11462function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text, isConcurrentMode) { 11463 { 11464 if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) { 11465 warnForInsertedHydratedText(parentInstance, text); 11466 } 11467 } 11468} 11469function errorHydratingContainer(parentContainer) { 11470 { 11471 // TODO: This gets logged by onRecoverableError, too, so we should be 11472 // able to remove it. 11473 error('An error occurred during hydration. The server HTML was replaced with client content in <%s>.', parentContainer.nodeName.toLowerCase()); 11474 } 11475} 11476function preparePortalMount(portalInstance) { 11477 listenToAllSupportedEvents(portalInstance); 11478} 11479 11480var randomKey = Math.random().toString(36).slice(2); 11481var internalInstanceKey = '__reactFiber$' + randomKey; 11482var internalPropsKey = '__reactProps$' + randomKey; 11483var internalContainerInstanceKey = '__reactContainer$' + randomKey; 11484var internalEventHandlersKey = '__reactEvents$' + randomKey; 11485var internalEventHandlerListenersKey = '__reactListeners$' + randomKey; 11486var internalEventHandlesSetKey = '__reactHandles$' + randomKey; 11487function detachDeletedInstance(node) { 11488 // TODO: This function is only called on host components. I don't think all of 11489 // these fields are relevant. 11490 delete node[internalInstanceKey]; 11491 delete node[internalPropsKey]; 11492 delete node[internalEventHandlersKey]; 11493 delete node[internalEventHandlerListenersKey]; 11494 delete node[internalEventHandlesSetKey]; 11495} 11496function precacheFiberNode(hostInst, node) { 11497 node[internalInstanceKey] = hostInst; 11498} 11499function markContainerAsRoot(hostRoot, node) { 11500 node[internalContainerInstanceKey] = hostRoot; 11501} 11502function unmarkContainerAsRoot(node) { 11503 node[internalContainerInstanceKey] = null; 11504} 11505function isContainerMarkedAsRoot(node) { 11506 return !!node[internalContainerInstanceKey]; 11507} // Given a DOM node, return the closest HostComponent or HostText fiber ancestor. 11508// If the target node is part of a hydrated or not yet rendered subtree, then 11509// this may also return a SuspenseComponent or HostRoot to indicate that. 11510// Conceptually the HostRoot fiber is a child of the Container node. So if you 11511// pass the Container node as the targetNode, you will not actually get the 11512// HostRoot back. To get to the HostRoot, you need to pass a child of it. 11513// The same thing applies to Suspense boundaries. 11514 11515function getClosestInstanceFromNode(targetNode) { 11516 var targetInst = targetNode[internalInstanceKey]; 11517 11518 if (targetInst) { 11519 // Don't return HostRoot or SuspenseComponent here. 11520 return targetInst; 11521 } // If the direct event target isn't a React owned DOM node, we need to look 11522 // to see if one of its parents is a React owned DOM node. 11523 11524 11525 var parentNode = targetNode.parentNode; 11526 11527 while (parentNode) { 11528 // We'll check if this is a container root that could include 11529 // React nodes in the future. We need to check this first because 11530 // if we're a child of a dehydrated container, we need to first 11531 // find that inner container before moving on to finding the parent 11532 // instance. Note that we don't check this field on the targetNode 11533 // itself because the fibers are conceptually between the container 11534 // node and the first child. It isn't surrounding the container node. 11535 // If it's not a container, we check if it's an instance. 11536 targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey]; 11537 11538 if (targetInst) { 11539 // Since this wasn't the direct target of the event, we might have 11540 // stepped past dehydrated DOM nodes to get here. However they could 11541 // also have been non-React nodes. We need to answer which one. 11542 // If we the instance doesn't have any children, then there can't be 11543 // a nested suspense boundary within it. So we can use this as a fast 11544 // bailout. Most of the time, when people add non-React children to 11545 // the tree, it is using a ref to a child-less DOM node. 11546 // Normally we'd only need to check one of the fibers because if it 11547 // has ever gone from having children to deleting them or vice versa 11548 // it would have deleted the dehydrated boundary nested inside already. 11549 // However, since the HostRoot starts out with an alternate it might 11550 // have one on the alternate so we need to check in case this was a 11551 // root. 11552 var alternate = targetInst.alternate; 11553 11554 if (targetInst.child !== null || alternate !== null && alternate.child !== null) { 11555 // Next we need to figure out if the node that skipped past is 11556 // nested within a dehydrated boundary and if so, which one. 11557 var suspenseInstance = getParentSuspenseInstance(targetNode); 11558 11559 while (suspenseInstance !== null) { 11560 // We found a suspense instance. That means that we haven't 11561 // hydrated it yet. Even though we leave the comments in the 11562 // DOM after hydrating, and there are boundaries in the DOM 11563 // that could already be hydrated, we wouldn't have found them 11564 // through this pass since if the target is hydrated it would 11565 // have had an internalInstanceKey on it. 11566 // Let's get the fiber associated with the SuspenseComponent 11567 // as the deepest instance. 11568 var targetSuspenseInst = suspenseInstance[internalInstanceKey]; 11569 11570 if (targetSuspenseInst) { 11571 return targetSuspenseInst; 11572 } // If we don't find a Fiber on the comment, it might be because 11573 // we haven't gotten to hydrate it yet. There might still be a 11574 // parent boundary that hasn't above this one so we need to find 11575 // the outer most that is known. 11576 11577 11578 suspenseInstance = getParentSuspenseInstance(suspenseInstance); // If we don't find one, then that should mean that the parent 11579 // host component also hasn't hydrated yet. We can return it 11580 // below since it will bail out on the isMounted check later. 11581 } 11582 } 11583 11584 return targetInst; 11585 } 11586 11587 targetNode = parentNode; 11588 parentNode = targetNode.parentNode; 11589 } 11590 11591 return null; 11592} 11593/** 11594 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent 11595 * instance, or null if the node was not rendered by this React. 11596 */ 11597 11598function getInstanceFromNode(node) { 11599 var inst = node[internalInstanceKey] || node[internalContainerInstanceKey]; 11600 11601 if (inst) { 11602 if (inst.tag === HostComponent || inst.tag === HostText || inst.tag === SuspenseComponent || inst.tag === HostRoot) { 11603 return inst; 11604 } else { 11605 return null; 11606 } 11607 } 11608 11609 return null; 11610} 11611/** 11612 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding 11613 * DOM node. 11614 */ 11615 11616function getNodeFromInstance(inst) { 11617 if (inst.tag === HostComponent || inst.tag === HostText) { 11618 // In Fiber this, is just the state node right now. We assume it will be 11619 // a host component or host text. 11620 return inst.stateNode; 11621 } // Without this first invariant, passing a non-DOM-component triggers the next 11622 // invariant for a missing parent, which is super confusing. 11623 11624 11625 throw new Error('getNodeFromInstance: Invalid argument.'); 11626} 11627function getFiberCurrentPropsFromNode(node) { 11628 return node[internalPropsKey] || null; 11629} 11630function updateFiberProps(node, props) { 11631 node[internalPropsKey] = props; 11632} 11633function getEventListenerSet(node) { 11634 var elementListenerSet = node[internalEventHandlersKey]; 11635 11636 if (elementListenerSet === undefined) { 11637 elementListenerSet = node[internalEventHandlersKey] = new Set(); 11638 } 11639 11640 return elementListenerSet; 11641} 11642 11643var loggedTypeFailures = {}; 11644var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame; 11645 11646function setCurrentlyValidatingElement(element) { 11647 { 11648 if (element) { 11649 var owner = element._owner; 11650 var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null); 11651 ReactDebugCurrentFrame$1.setExtraStackFrame(stack); 11652 } else { 11653 ReactDebugCurrentFrame$1.setExtraStackFrame(null); 11654 } 11655 } 11656} 11657 11658function checkPropTypes(typeSpecs, values, location, componentName, element) { 11659 { 11660 // $FlowFixMe This is okay but Flow doesn't know it. 11661 var has = Function.call.bind(hasOwnProperty); 11662 11663 for (var typeSpecName in typeSpecs) { 11664 if (has(typeSpecs, typeSpecName)) { 11665 var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to 11666 // fail the render phase where it didn't fail before. So we log it. 11667 // After these have been cleaned up, we'll let them throw. 11668 11669 try { 11670 // This is intentionally an invariant that gets caught. It's the same 11671 // behavior as without this statement except with a better message. 11672 if (typeof typeSpecs[typeSpecName] !== 'function') { 11673 // eslint-disable-next-line react-internal/prod-error-codes 11674 var err = Error((componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' + 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.'); 11675 err.name = 'Invariant Violation'; 11676 throw err; 11677 } 11678 11679 error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'); 11680 } catch (ex) { 11681 error$1 = ex; 11682 } 11683 11684 if (error$1 && !(error$1 instanceof Error)) { 11685 setCurrentlyValidatingElement(element); 11686 11687 error('%s: type specification of %s' + ' `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error$1); 11688 11689 setCurrentlyValidatingElement(null); 11690 } 11691 11692 if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) { 11693 // Only monitor this failure once because there tends to be a lot of the 11694 // same error. 11695 loggedTypeFailures[error$1.message] = true; 11696 setCurrentlyValidatingElement(element); 11697 11698 error('Failed %s type: %s', location, error$1.message); 11699 11700 setCurrentlyValidatingElement(null); 11701 } 11702 } 11703 } 11704 } 11705} 11706 11707var valueStack = []; 11708var fiberStack; 11709 11710{ 11711 fiberStack = []; 11712} 11713 11714var index = -1; 11715 11716function createCursor(defaultValue) { 11717 return { 11718 current: defaultValue 11719 }; 11720} 11721 11722function pop(cursor, fiber) { 11723 if (index < 0) { 11724 { 11725 error('Unexpected pop.'); 11726 } 11727 11728 return; 11729 } 11730 11731 { 11732 if (fiber !== fiberStack[index]) { 11733 error('Unexpected Fiber popped.'); 11734 } 11735 } 11736 11737 cursor.current = valueStack[index]; 11738 valueStack[index] = null; 11739 11740 { 11741 fiberStack[index] = null; 11742 } 11743 11744 index--; 11745} 11746 11747function push(cursor, value, fiber) { 11748 index++; 11749 valueStack[index] = cursor.current; 11750 11751 { 11752 fiberStack[index] = fiber; 11753 } 11754 11755 cursor.current = value; 11756} 11757 11758var warnedAboutMissingGetChildContext; 11759 11760{ 11761 warnedAboutMissingGetChildContext = {}; 11762} 11763 11764var emptyContextObject = {}; 11765 11766{ 11767 Object.freeze(emptyContextObject); 11768} // A cursor to the current merged context object on the stack. 11769 11770 11771var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. 11772 11773var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. 11774// We use this to get access to the parent context after we have already 11775// pushed the next context provider, and now need to merge their contexts. 11776 11777var previousContext = emptyContextObject; 11778 11779function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) { 11780 { 11781 if (didPushOwnContextIfProvider && isContextProvider(Component)) { 11782 // If the fiber is a context provider itself, when we read its context 11783 // we may have already pushed its own child context on the stack. A context 11784 // provider should not "see" its own child context. Therefore we read the 11785 // previous (parent) context instead for a context provider. 11786 return previousContext; 11787 } 11788 11789 return contextStackCursor.current; 11790 } 11791} 11792 11793function cacheContext(workInProgress, unmaskedContext, maskedContext) { 11794 { 11795 var instance = workInProgress.stateNode; 11796 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; 11797 instance.__reactInternalMemoizedMaskedChildContext = maskedContext; 11798 } 11799} 11800 11801function getMaskedContext(workInProgress, unmaskedContext) { 11802 { 11803 var type = workInProgress.type; 11804 var contextTypes = type.contextTypes; 11805 11806 if (!contextTypes) { 11807 return emptyContextObject; 11808 } // Avoid recreating masked context unless unmasked context has changed. 11809 // Failing to do this will result in unnecessary calls to componentWillReceiveProps. 11810 // This may trigger infinite loops if componentWillReceiveProps calls setState. 11811 11812 11813 var instance = workInProgress.stateNode; 11814 11815 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) { 11816 return instance.__reactInternalMemoizedMaskedChildContext; 11817 } 11818 11819 var context = {}; 11820 11821 for (var key in contextTypes) { 11822 context[key] = unmaskedContext[key]; 11823 } 11824 11825 { 11826 var name = getComponentNameFromFiber(workInProgress) || 'Unknown'; 11827 checkPropTypes(contextTypes, context, 'context', name); 11828 } // Cache unmasked context so we can avoid recreating masked context unless necessary. 11829 // Context is created before the class component is instantiated so check for instance. 11830 11831 11832 if (instance) { 11833 cacheContext(workInProgress, unmaskedContext, context); 11834 } 11835 11836 return context; 11837 } 11838} 11839 11840function hasContextChanged() { 11841 { 11842 return didPerformWorkStackCursor.current; 11843 } 11844} 11845 11846function isContextProvider(type) { 11847 { 11848 var childContextTypes = type.childContextTypes; 11849 return childContextTypes !== null && childContextTypes !== undefined; 11850 } 11851} 11852 11853function popContext(fiber) { 11854 { 11855 pop(didPerformWorkStackCursor, fiber); 11856 pop(contextStackCursor, fiber); 11857 } 11858} 11859 11860function popTopLevelContextObject(fiber) { 11861 { 11862 pop(didPerformWorkStackCursor, fiber); 11863 pop(contextStackCursor, fiber); 11864 } 11865} 11866 11867function pushTopLevelContextObject(fiber, context, didChange) { 11868 { 11869 if (contextStackCursor.current !== emptyContextObject) { 11870 throw new Error('Unexpected context found on stack. ' + 'This error is likely caused by a bug in React. Please file an issue.'); 11871 } 11872 11873 push(contextStackCursor, context, fiber); 11874 push(didPerformWorkStackCursor, didChange, fiber); 11875 } 11876} 11877 11878function processChildContext(fiber, type, parentContext) { 11879 { 11880 var instance = fiber.stateNode; 11881 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. 11882 // It has only been added in Fiber to match the (unintentional) behavior in Stack. 11883 11884 if (typeof instance.getChildContext !== 'function') { 11885 { 11886 var componentName = getComponentNameFromFiber(fiber) || 'Unknown'; 11887 11888 if (!warnedAboutMissingGetChildContext[componentName]) { 11889 warnedAboutMissingGetChildContext[componentName] = true; 11890 11891 error('%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); 11892 } 11893 } 11894 11895 return parentContext; 11896 } 11897 11898 var childContext = instance.getChildContext(); 11899 11900 for (var contextKey in childContext) { 11901 if (!(contextKey in childContextTypes)) { 11902 throw new Error((getComponentNameFromFiber(fiber) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes."); 11903 } 11904 } 11905 11906 { 11907 var name = getComponentNameFromFiber(fiber) || 'Unknown'; 11908 checkPropTypes(childContextTypes, childContext, 'child context', name); 11909 } 11910 11911 return assign({}, parentContext, childContext); 11912 } 11913} 11914 11915function pushContextProvider(workInProgress) { 11916 { 11917 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. 11918 // If the instance does not exist yet, we will push null at first, 11919 // and replace it on the stack later when invalidating the context. 11920 11921 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later. 11922 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. 11923 11924 previousContext = contextStackCursor.current; 11925 push(contextStackCursor, memoizedMergedChildContext, workInProgress); 11926 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress); 11927 return true; 11928 } 11929} 11930 11931function invalidateContextProvider(workInProgress, type, didChange) { 11932 { 11933 var instance = workInProgress.stateNode; 11934 11935 if (!instance) { 11936 throw new Error('Expected to have an instance by this point. ' + 'This error is likely caused by a bug in React. Please file an issue.'); 11937 } 11938 11939 if (didChange) { 11940 // Merge parent and own context. 11941 // Skip this if we're not updating due to sCU. 11942 // This avoids unnecessarily recomputing memoized values. 11943 var mergedContext = processChildContext(workInProgress, type, previousContext); 11944 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. 11945 // It is important to unwind the context in the reverse order. 11946 11947 pop(didPerformWorkStackCursor, workInProgress); 11948 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. 11949 11950 push(contextStackCursor, mergedContext, workInProgress); 11951 push(didPerformWorkStackCursor, didChange, workInProgress); 11952 } else { 11953 pop(didPerformWorkStackCursor, workInProgress); 11954 push(didPerformWorkStackCursor, didChange, workInProgress); 11955 } 11956 } 11957} 11958 11959function findCurrentUnmaskedContext(fiber) { 11960 { 11961 // Currently this is only used with renderSubtreeIntoContainer; not sure if it 11962 // makes sense elsewhere 11963 if (!isFiberMounted(fiber) || fiber.tag !== ClassComponent) { 11964 throw new Error('Expected subtree parent to be a mounted class component. ' + 'This error is likely caused by a bug in React. Please file an issue.'); 11965 } 11966 11967 var node = fiber; 11968 11969 do { 11970 switch (node.tag) { 11971 case HostRoot: 11972 return node.stateNode.context; 11973 11974 case ClassComponent: 11975 { 11976 var Component = node.type; 11977 11978 if (isContextProvider(Component)) { 11979 return node.stateNode.__reactInternalMemoizedMergedChildContext; 11980 } 11981 11982 break; 11983 } 11984 } 11985 11986 node = node.return; 11987 } while (node !== null); 11988 11989 throw new Error('Found unexpected detached subtree parent. ' + 'This error is likely caused by a bug in React. Please file an issue.'); 11990 } 11991} 11992 11993var LegacyRoot = 0; 11994var ConcurrentRoot = 1; 11995 11996var syncQueue = null; 11997var includesLegacySyncCallbacks = false; 11998var isFlushingSyncQueue = false; 11999function scheduleSyncCallback(callback) { 12000 // Push this callback into an internal queue. We'll flush these either in 12001 // the next tick, or earlier if something calls `flushSyncCallbackQueue`. 12002 if (syncQueue === null) { 12003 syncQueue = [callback]; 12004 } else { 12005 // Push onto existing queue. Don't need to schedule a callback because 12006 // we already scheduled one when we created the queue. 12007 syncQueue.push(callback); 12008 } 12009} 12010function scheduleLegacySyncCallback(callback) { 12011 includesLegacySyncCallbacks = true; 12012 scheduleSyncCallback(callback); 12013} 12014function flushSyncCallbacksOnlyInLegacyMode() { 12015 // Only flushes the queue if there's a legacy sync callback scheduled. 12016 // TODO: There's only a single type of callback: performSyncOnWorkOnRoot. So 12017 // it might make more sense for the queue to be a list of roots instead of a 12018 // list of generic callbacks. Then we can have two: one for legacy roots, one 12019 // for concurrent roots. And this method would only flush the legacy ones. 12020 if (includesLegacySyncCallbacks) { 12021 flushSyncCallbacks(); 12022 } 12023} 12024function flushSyncCallbacks() { 12025 if (!isFlushingSyncQueue && syncQueue !== null) { 12026 // Prevent re-entrance. 12027 isFlushingSyncQueue = true; 12028 var i = 0; 12029 var previousUpdatePriority = getCurrentUpdatePriority(); 12030 12031 try { 12032 var isSync = true; 12033 var queue = syncQueue; // TODO: Is this necessary anymore? The only user code that runs in this 12034 // queue is in the render or commit phases. 12035 12036 setCurrentUpdatePriority(DiscreteEventPriority); 12037 12038 for (; i < queue.length; i++) { 12039 var callback = queue[i]; 12040 12041 do { 12042 callback = callback(isSync); 12043 } while (callback !== null); 12044 } 12045 12046 syncQueue = null; 12047 includesLegacySyncCallbacks = false; 12048 } catch (error) { 12049 // If something throws, leave the remaining callbacks on the queue. 12050 if (syncQueue !== null) { 12051 syncQueue = syncQueue.slice(i + 1); 12052 } // Resume flushing in the next tick 12053 12054 12055 scheduleCallback(ImmediatePriority, flushSyncCallbacks); 12056 throw error; 12057 } finally { 12058 setCurrentUpdatePriority(previousUpdatePriority); 12059 isFlushingSyncQueue = false; 12060 } 12061 } 12062 12063 return null; 12064} 12065 12066// TODO: Use the unified fiber stack module instead of this local one? 12067// Intentionally not using it yet to derisk the initial implementation, because 12068// the way we push/pop these values is a bit unusual. If there's a mistake, I'd 12069// rather the ids be wrong than crash the whole reconciler. 12070var forkStack = []; 12071var forkStackIndex = 0; 12072var treeForkProvider = null; 12073var treeForkCount = 0; 12074var idStack = []; 12075var idStackIndex = 0; 12076var treeContextProvider = null; 12077var treeContextId = 1; 12078var treeContextOverflow = ''; 12079function isForkedChild(workInProgress) { 12080 warnIfNotHydrating(); 12081 return (workInProgress.flags & Forked) !== NoFlags; 12082} 12083function getForksAtLevel(workInProgress) { 12084 warnIfNotHydrating(); 12085 return treeForkCount; 12086} 12087function getTreeId() { 12088 var overflow = treeContextOverflow; 12089 var idWithLeadingBit = treeContextId; 12090 var id = idWithLeadingBit & ~getLeadingBit(idWithLeadingBit); 12091 return id.toString(32) + overflow; 12092} 12093function pushTreeFork(workInProgress, totalChildren) { 12094 // This is called right after we reconcile an array (or iterator) of child 12095 // fibers, because that's the only place where we know how many children in 12096 // the whole set without doing extra work later, or storing addtional 12097 // information on the fiber. 12098 // 12099 // That's why this function is separate from pushTreeId — it's called during 12100 // the render phase of the fork parent, not the child, which is where we push 12101 // the other context values. 12102 // 12103 // In the Fizz implementation this is much simpler because the child is 12104 // rendered in the same callstack as the parent. 12105 // 12106 // It might be better to just add a `forks` field to the Fiber type. It would 12107 // make this module simpler. 12108 warnIfNotHydrating(); 12109 forkStack[forkStackIndex++] = treeForkCount; 12110 forkStack[forkStackIndex++] = treeForkProvider; 12111 treeForkProvider = workInProgress; 12112 treeForkCount = totalChildren; 12113} 12114function pushTreeId(workInProgress, totalChildren, index) { 12115 warnIfNotHydrating(); 12116 idStack[idStackIndex++] = treeContextId; 12117 idStack[idStackIndex++] = treeContextOverflow; 12118 idStack[idStackIndex++] = treeContextProvider; 12119 treeContextProvider = workInProgress; 12120 var baseIdWithLeadingBit = treeContextId; 12121 var baseOverflow = treeContextOverflow; // The leftmost 1 marks the end of the sequence, non-inclusive. It's not part 12122 // of the id; we use it to account for leading 0s. 12123 12124 var baseLength = getBitLength(baseIdWithLeadingBit) - 1; 12125 var baseId = baseIdWithLeadingBit & ~(1 << baseLength); 12126 var slot = index + 1; 12127 var length = getBitLength(totalChildren) + baseLength; // 30 is the max length we can store without overflowing, taking into 12128 // consideration the leading 1 we use to mark the end of the sequence. 12129 12130 if (length > 30) { 12131 // We overflowed the bitwise-safe range. Fall back to slower algorithm. 12132 // This branch assumes the length of the base id is greater than 5; it won't 12133 // work for smaller ids, because you need 5 bits per character. 12134 // 12135 // We encode the id in multiple steps: first the base id, then the 12136 // remaining digits. 12137 // 12138 // Each 5 bit sequence corresponds to a single base 32 character. So for 12139 // example, if the current id is 23 bits long, we can convert 20 of those 12140 // bits into a string of 4 characters, with 3 bits left over. 12141 // 12142 // First calculate how many bits in the base id represent a complete 12143 // sequence of characters. 12144 var numberOfOverflowBits = baseLength - baseLength % 5; // Then create a bitmask that selects only those bits. 12145 12146 var newOverflowBits = (1 << numberOfOverflowBits) - 1; // Select the bits, and convert them to a base 32 string. 12147 12148 var newOverflow = (baseId & newOverflowBits).toString(32); // Now we can remove those bits from the base id. 12149 12150 var restOfBaseId = baseId >> numberOfOverflowBits; 12151 var restOfBaseLength = baseLength - numberOfOverflowBits; // Finally, encode the rest of the bits using the normal algorithm. Because 12152 // we made more room, this time it won't overflow. 12153 12154 var restOfLength = getBitLength(totalChildren) + restOfBaseLength; 12155 var restOfNewBits = slot << restOfBaseLength; 12156 var id = restOfNewBits | restOfBaseId; 12157 var overflow = newOverflow + baseOverflow; 12158 treeContextId = 1 << restOfLength | id; 12159 treeContextOverflow = overflow; 12160 } else { 12161 // Normal path 12162 var newBits = slot << baseLength; 12163 12164 var _id = newBits | baseId; 12165 12166 var _overflow = baseOverflow; 12167 treeContextId = 1 << length | _id; 12168 treeContextOverflow = _overflow; 12169 } 12170} 12171function pushMaterializedTreeId(workInProgress) { 12172 warnIfNotHydrating(); // This component materialized an id. This will affect any ids that appear 12173 // in its children. 12174 12175 var returnFiber = workInProgress.return; 12176 12177 if (returnFiber !== null) { 12178 var numberOfForks = 1; 12179 var slotIndex = 0; 12180 pushTreeFork(workInProgress, numberOfForks); 12181 pushTreeId(workInProgress, numberOfForks, slotIndex); 12182 } 12183} 12184 12185function getBitLength(number) { 12186 return 32 - clz32(number); 12187} 12188 12189function getLeadingBit(id) { 12190 return 1 << getBitLength(id) - 1; 12191} 12192 12193function popTreeContext(workInProgress) { 12194 // Restore the previous values. 12195 // This is a bit more complicated than other context-like modules in Fiber 12196 // because the same Fiber may appear on the stack multiple times and for 12197 // different reasons. We have to keep popping until the work-in-progress is 12198 // no longer at the top of the stack. 12199 while (workInProgress === treeForkProvider) { 12200 treeForkProvider = forkStack[--forkStackIndex]; 12201 forkStack[forkStackIndex] = null; 12202 treeForkCount = forkStack[--forkStackIndex]; 12203 forkStack[forkStackIndex] = null; 12204 } 12205 12206 while (workInProgress === treeContextProvider) { 12207 treeContextProvider = idStack[--idStackIndex]; 12208 idStack[idStackIndex] = null; 12209 treeContextOverflow = idStack[--idStackIndex]; 12210 idStack[idStackIndex] = null; 12211 treeContextId = idStack[--idStackIndex]; 12212 idStack[idStackIndex] = null; 12213 } 12214} 12215function getSuspendedTreeContext() { 12216 warnIfNotHydrating(); 12217 12218 if (treeContextProvider !== null) { 12219 return { 12220 id: treeContextId, 12221 overflow: treeContextOverflow 12222 }; 12223 } else { 12224 return null; 12225 } 12226} 12227function restoreSuspendedTreeContext(workInProgress, suspendedContext) { 12228 warnIfNotHydrating(); 12229 idStack[idStackIndex++] = treeContextId; 12230 idStack[idStackIndex++] = treeContextOverflow; 12231 idStack[idStackIndex++] = treeContextProvider; 12232 treeContextId = suspendedContext.id; 12233 treeContextOverflow = suspendedContext.overflow; 12234 treeContextProvider = workInProgress; 12235} 12236 12237function warnIfNotHydrating() { 12238 { 12239 if (!getIsHydrating()) { 12240 error('Expected to be hydrating. This is a bug in React. Please file ' + 'an issue.'); 12241 } 12242 } 12243} 12244 12245// This may have been an insertion or a hydration. 12246 12247var hydrationParentFiber = null; 12248var nextHydratableInstance = null; 12249var isHydrating = false; // This flag allows for warning supression when we expect there to be mismatches 12250// due to earlier mismatches or a suspended fiber. 12251 12252var didSuspendOrErrorDEV = false; // Hydration errors that were thrown inside this boundary 12253 12254var hydrationErrors = null; 12255 12256function warnIfHydrating() { 12257 { 12258 if (isHydrating) { 12259 error('We should not be hydrating here. This is a bug in React. Please file a bug.'); 12260 } 12261 } 12262} 12263 12264function markDidThrowWhileHydratingDEV() { 12265 { 12266 didSuspendOrErrorDEV = true; 12267 } 12268} 12269function didSuspendOrErrorWhileHydratingDEV() { 12270 { 12271 return didSuspendOrErrorDEV; 12272 } 12273} 12274 12275function enterHydrationState(fiber) { 12276 12277 var parentInstance = fiber.stateNode.containerInfo; 12278 nextHydratableInstance = getFirstHydratableChildWithinContainer(parentInstance); 12279 hydrationParentFiber = fiber; 12280 isHydrating = true; 12281 hydrationErrors = null; 12282 didSuspendOrErrorDEV = false; 12283 return true; 12284} 12285 12286function reenterHydrationStateFromDehydratedSuspenseInstance(fiber, suspenseInstance, treeContext) { 12287 12288 nextHydratableInstance = getFirstHydratableChildWithinSuspenseInstance(suspenseInstance); 12289 hydrationParentFiber = fiber; 12290 isHydrating = true; 12291 hydrationErrors = null; 12292 didSuspendOrErrorDEV = false; 12293 12294 if (treeContext !== null) { 12295 restoreSuspendedTreeContext(fiber, treeContext); 12296 } 12297 12298 return true; 12299} 12300 12301function warnUnhydratedInstance(returnFiber, instance) { 12302 { 12303 switch (returnFiber.tag) { 12304 case HostRoot: 12305 { 12306 didNotHydrateInstanceWithinContainer(returnFiber.stateNode.containerInfo, instance); 12307 break; 12308 } 12309 12310 case HostComponent: 12311 { 12312 var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode; 12313 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance, // TODO: Delete this argument when we remove the legacy root API. 12314 isConcurrentMode); 12315 break; 12316 } 12317 12318 case SuspenseComponent: 12319 { 12320 var suspenseState = returnFiber.memoizedState; 12321 if (suspenseState.dehydrated !== null) didNotHydrateInstanceWithinSuspenseInstance(suspenseState.dehydrated, instance); 12322 break; 12323 } 12324 } 12325 } 12326} 12327 12328function deleteHydratableInstance(returnFiber, instance) { 12329 warnUnhydratedInstance(returnFiber, instance); 12330 var childToDelete = createFiberFromHostInstanceForDeletion(); 12331 childToDelete.stateNode = instance; 12332 childToDelete.return = returnFiber; 12333 var deletions = returnFiber.deletions; 12334 12335 if (deletions === null) { 12336 returnFiber.deletions = [childToDelete]; 12337 returnFiber.flags |= ChildDeletion; 12338 } else { 12339 deletions.push(childToDelete); 12340 } 12341} 12342 12343function warnNonhydratedInstance(returnFiber, fiber) { 12344 { 12345 if (didSuspendOrErrorDEV) { 12346 // Inside a boundary that already suspended. We're currently rendering the 12347 // siblings of a suspended node. The mismatch may be due to the missing 12348 // data, so it's probably a false positive. 12349 return; 12350 } 12351 12352 switch (returnFiber.tag) { 12353 case HostRoot: 12354 { 12355 var parentContainer = returnFiber.stateNode.containerInfo; 12356 12357 switch (fiber.tag) { 12358 case HostComponent: 12359 var type = fiber.type; 12360 var props = fiber.pendingProps; 12361 didNotFindHydratableInstanceWithinContainer(parentContainer, type); 12362 break; 12363 12364 case HostText: 12365 var text = fiber.pendingProps; 12366 didNotFindHydratableTextInstanceWithinContainer(parentContainer, text); 12367 break; 12368 } 12369 12370 break; 12371 } 12372 12373 case HostComponent: 12374 { 12375 var parentType = returnFiber.type; 12376 var parentProps = returnFiber.memoizedProps; 12377 var parentInstance = returnFiber.stateNode; 12378 12379 switch (fiber.tag) { 12380 case HostComponent: 12381 { 12382 var _type = fiber.type; 12383 var _props = fiber.pendingProps; 12384 var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode; 12385 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props, // TODO: Delete this argument when we remove the legacy root API. 12386 isConcurrentMode); 12387 break; 12388 } 12389 12390 case HostText: 12391 { 12392 var _text = fiber.pendingProps; 12393 12394 var _isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode; 12395 12396 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text, // TODO: Delete this argument when we remove the legacy root API. 12397 _isConcurrentMode); 12398 break; 12399 } 12400 } 12401 12402 break; 12403 } 12404 12405 case SuspenseComponent: 12406 { 12407 var suspenseState = returnFiber.memoizedState; 12408 var _parentInstance = suspenseState.dehydrated; 12409 if (_parentInstance !== null) switch (fiber.tag) { 12410 case HostComponent: 12411 var _type2 = fiber.type; 12412 var _props2 = fiber.pendingProps; 12413 didNotFindHydratableInstanceWithinSuspenseInstance(_parentInstance, _type2); 12414 break; 12415 12416 case HostText: 12417 var _text2 = fiber.pendingProps; 12418 didNotFindHydratableTextInstanceWithinSuspenseInstance(_parentInstance, _text2); 12419 break; 12420 } 12421 break; 12422 } 12423 12424 default: 12425 return; 12426 } 12427 } 12428} 12429 12430function insertNonHydratedInstance(returnFiber, fiber) { 12431 fiber.flags = fiber.flags & ~Hydrating | Placement; 12432 warnNonhydratedInstance(returnFiber, fiber); 12433} 12434 12435function tryHydrate(fiber, nextInstance) { 12436 switch (fiber.tag) { 12437 case HostComponent: 12438 { 12439 var type = fiber.type; 12440 var props = fiber.pendingProps; 12441 var instance = canHydrateInstance(nextInstance, type); 12442 12443 if (instance !== null) { 12444 fiber.stateNode = instance; 12445 hydrationParentFiber = fiber; 12446 nextHydratableInstance = getFirstHydratableChild(instance); 12447 return true; 12448 } 12449 12450 return false; 12451 } 12452 12453 case HostText: 12454 { 12455 var text = fiber.pendingProps; 12456 var textInstance = canHydrateTextInstance(nextInstance, text); 12457 12458 if (textInstance !== null) { 12459 fiber.stateNode = textInstance; 12460 hydrationParentFiber = fiber; // Text Instances don't have children so there's nothing to hydrate. 12461 12462 nextHydratableInstance = null; 12463 return true; 12464 } 12465 12466 return false; 12467 } 12468 12469 case SuspenseComponent: 12470 { 12471 var suspenseInstance = canHydrateSuspenseInstance(nextInstance); 12472 12473 if (suspenseInstance !== null) { 12474 var suspenseState = { 12475 dehydrated: suspenseInstance, 12476 treeContext: getSuspendedTreeContext(), 12477 retryLane: OffscreenLane 12478 }; 12479 fiber.memoizedState = suspenseState; // Store the dehydrated fragment as a child fiber. 12480 // This simplifies the code for getHostSibling and deleting nodes, 12481 // since it doesn't have to consider all Suspense boundaries and 12482 // check if they're dehydrated ones or not. 12483 12484 var dehydratedFragment = createFiberFromDehydratedFragment(suspenseInstance); 12485 dehydratedFragment.return = fiber; 12486 fiber.child = dehydratedFragment; 12487 hydrationParentFiber = fiber; // While a Suspense Instance does have children, we won't step into 12488 // it during the first pass. Instead, we'll reenter it later. 12489 12490 nextHydratableInstance = null; 12491 return true; 12492 } 12493 12494 return false; 12495 } 12496 12497 default: 12498 return false; 12499 } 12500} 12501 12502function shouldClientRenderOnMismatch(fiber) { 12503 return (fiber.mode & ConcurrentMode) !== NoMode && (fiber.flags & DidCapture) === NoFlags; 12504} 12505 12506function throwOnHydrationMismatch(fiber) { 12507 throw new Error('Hydration failed because the initial UI does not match what was ' + 'rendered on the server.'); 12508} 12509 12510function tryToClaimNextHydratableInstance(fiber) { 12511 if (!isHydrating) { 12512 return; 12513 } 12514 12515 var nextInstance = nextHydratableInstance; 12516 12517 if (!nextInstance) { 12518 if (shouldClientRenderOnMismatch(fiber)) { 12519 warnNonhydratedInstance(hydrationParentFiber, fiber); 12520 throwOnHydrationMismatch(); 12521 } // Nothing to hydrate. Make it an insertion. 12522 12523 12524 insertNonHydratedInstance(hydrationParentFiber, fiber); 12525 isHydrating = false; 12526 hydrationParentFiber = fiber; 12527 return; 12528 } 12529 12530 var firstAttemptedInstance = nextInstance; 12531 12532 if (!tryHydrate(fiber, nextInstance)) { 12533 if (shouldClientRenderOnMismatch(fiber)) { 12534 warnNonhydratedInstance(hydrationParentFiber, fiber); 12535 throwOnHydrationMismatch(); 12536 } // If we can't hydrate this instance let's try the next one. 12537 // We use this as a heuristic. It's based on intuition and not data so it 12538 // might be flawed or unnecessary. 12539 12540 12541 nextInstance = getNextHydratableSibling(firstAttemptedInstance); 12542 var prevHydrationParentFiber = hydrationParentFiber; 12543 12544 if (!nextInstance || !tryHydrate(fiber, nextInstance)) { 12545 // Nothing to hydrate. Make it an insertion. 12546 insertNonHydratedInstance(hydrationParentFiber, fiber); 12547 isHydrating = false; 12548 hydrationParentFiber = fiber; 12549 return; 12550 } // We matched the next one, we'll now assume that the first one was 12551 // superfluous and we'll delete it. Since we can't eagerly delete it 12552 // we'll have to schedule a deletion. To do that, this node needs a dummy 12553 // fiber associated with it. 12554 12555 12556 deleteHydratableInstance(prevHydrationParentFiber, firstAttemptedInstance); 12557 } 12558} 12559 12560function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) { 12561 12562 var instance = fiber.stateNode; 12563 var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV; 12564 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber, shouldWarnIfMismatchDev); // TODO: Type this specific to this type of component. 12565 12566 fiber.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there 12567 // is a new ref we mark this as an update. 12568 12569 if (updatePayload !== null) { 12570 return true; 12571 } 12572 12573 return false; 12574} 12575 12576function prepareToHydrateHostTextInstance(fiber) { 12577 12578 var textInstance = fiber.stateNode; 12579 var textContent = fiber.memoizedProps; 12580 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber); 12581 12582 if (shouldUpdate) { 12583 // We assume that prepareToHydrateHostTextInstance is called in a context where the 12584 // hydration parent is the parent host component of this host text. 12585 var returnFiber = hydrationParentFiber; 12586 12587 if (returnFiber !== null) { 12588 switch (returnFiber.tag) { 12589 case HostRoot: 12590 { 12591 var parentContainer = returnFiber.stateNode.containerInfo; 12592 var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode; 12593 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent, // TODO: Delete this argument when we remove the legacy root API. 12594 isConcurrentMode); 12595 break; 12596 } 12597 12598 case HostComponent: 12599 { 12600 var parentType = returnFiber.type; 12601 var parentProps = returnFiber.memoizedProps; 12602 var parentInstance = returnFiber.stateNode; 12603 12604 var _isConcurrentMode2 = (returnFiber.mode & ConcurrentMode) !== NoMode; 12605 12606 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent, // TODO: Delete this argument when we remove the legacy root API. 12607 _isConcurrentMode2); 12608 break; 12609 } 12610 } 12611 } 12612 } 12613 12614 return shouldUpdate; 12615} 12616 12617function prepareToHydrateHostSuspenseInstance(fiber) { 12618 12619 var suspenseState = fiber.memoizedState; 12620 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null; 12621 12622 if (!suspenseInstance) { 12623 throw new Error('Expected to have a hydrated suspense instance. ' + 'This error is likely caused by a bug in React. Please file an issue.'); 12624 } 12625 12626 hydrateSuspenseInstance(suspenseInstance, fiber); 12627} 12628 12629function skipPastDehydratedSuspenseInstance(fiber) { 12630 12631 var suspenseState = fiber.memoizedState; 12632 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null; 12633 12634 if (!suspenseInstance) { 12635 throw new Error('Expected to have a hydrated suspense instance. ' + 'This error is likely caused by a bug in React. Please file an issue.'); 12636 } 12637 12638 return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance); 12639} 12640 12641function popToNextHostParent(fiber) { 12642 var parent = fiber.return; 12643 12644 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== SuspenseComponent) { 12645 parent = parent.return; 12646 } 12647 12648 hydrationParentFiber = parent; 12649} 12650 12651function popHydrationState(fiber) { 12652 12653 if (fiber !== hydrationParentFiber) { 12654 // We're deeper than the current hydration context, inside an inserted 12655 // tree. 12656 return false; 12657 } 12658 12659 if (!isHydrating) { 12660 // If we're not currently hydrating but we're in a hydration context, then 12661 // we were an insertion and now need to pop up reenter hydration of our 12662 // siblings. 12663 popToNextHostParent(fiber); 12664 isHydrating = true; 12665 return false; 12666 } // If we have any remaining hydratable nodes, we need to delete them now. 12667 // We only do this deeper than head and body since they tend to have random 12668 // other nodes in them. We also ignore components with pure text content in 12669 // side of them. We also don't delete anything inside the root container. 12670 12671 12672 if (fiber.tag !== HostRoot && (fiber.tag !== HostComponent || shouldDeleteUnhydratedTailInstances(fiber.type) && !shouldSetTextContent(fiber.type, fiber.memoizedProps))) { 12673 var nextInstance = nextHydratableInstance; 12674 12675 if (nextInstance) { 12676 if (shouldClientRenderOnMismatch(fiber)) { 12677 warnIfUnhydratedTailNodes(fiber); 12678 throwOnHydrationMismatch(); 12679 } else { 12680 while (nextInstance) { 12681 deleteHydratableInstance(fiber, nextInstance); 12682 nextInstance = getNextHydratableSibling(nextInstance); 12683 } 12684 } 12685 } 12686 } 12687 12688 popToNextHostParent(fiber); 12689 12690 if (fiber.tag === SuspenseComponent) { 12691 nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber); 12692 } else { 12693 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null; 12694 } 12695 12696 return true; 12697} 12698 12699function hasUnhydratedTailNodes() { 12700 return isHydrating && nextHydratableInstance !== null; 12701} 12702 12703function warnIfUnhydratedTailNodes(fiber) { 12704 var nextInstance = nextHydratableInstance; 12705 12706 while (nextInstance) { 12707 warnUnhydratedInstance(fiber, nextInstance); 12708 nextInstance = getNextHydratableSibling(nextInstance); 12709 } 12710} 12711 12712function resetHydrationState() { 12713 12714 hydrationParentFiber = null; 12715 nextHydratableInstance = null; 12716 isHydrating = false; 12717 didSuspendOrErrorDEV = false; 12718} 12719 12720function upgradeHydrationErrorsToRecoverable() { 12721 if (hydrationErrors !== null) { 12722 // Successfully completed a forced client render. The errors that occurred 12723 // during the hydration attempt are now recovered. We will log them in 12724 // commit phase, once the entire tree has finished. 12725 queueRecoverableErrors(hydrationErrors); 12726 hydrationErrors = null; 12727 } 12728} 12729 12730function getIsHydrating() { 12731 return isHydrating; 12732} 12733 12734function queueHydrationError(error) { 12735 if (hydrationErrors === null) { 12736 hydrationErrors = [error]; 12737 } else { 12738 hydrationErrors.push(error); 12739 } 12740} 12741 12742var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; 12743var NoTransition = null; 12744function requestCurrentTransition() { 12745 return ReactCurrentBatchConfig$1.transition; 12746} 12747 12748var ReactStrictModeWarnings = { 12749 recordUnsafeLifecycleWarnings: function (fiber, instance) {}, 12750 flushPendingUnsafeLifecycleWarnings: function () {}, 12751 recordLegacyContextWarning: function (fiber, instance) {}, 12752 flushLegacyContextWarning: function () {}, 12753 discardPendingWarnings: function () {} 12754}; 12755 12756{ 12757 var findStrictRoot = function (fiber) { 12758 var maybeStrictRoot = null; 12759 var node = fiber; 12760 12761 while (node !== null) { 12762 if (node.mode & StrictLegacyMode) { 12763 maybeStrictRoot = node; 12764 } 12765 12766 node = node.return; 12767 } 12768 12769 return maybeStrictRoot; 12770 }; 12771 12772 var setToSortedString = function (set) { 12773 var array = []; 12774 set.forEach(function (value) { 12775 array.push(value); 12776 }); 12777 return array.sort().join(', '); 12778 }; 12779 12780 var pendingComponentWillMountWarnings = []; 12781 var pendingUNSAFE_ComponentWillMountWarnings = []; 12782 var pendingComponentWillReceivePropsWarnings = []; 12783 var pendingUNSAFE_ComponentWillReceivePropsWarnings = []; 12784 var pendingComponentWillUpdateWarnings = []; 12785 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about. 12786 12787 var didWarnAboutUnsafeLifecycles = new Set(); 12788 12789 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) { 12790 // Dedupe strategy: Warn once per component. 12791 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { 12792 return; 12793 } 12794 12795 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components. 12796 instance.componentWillMount.__suppressDeprecationWarning !== true) { 12797 pendingComponentWillMountWarnings.push(fiber); 12798 } 12799 12800 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillMount === 'function') { 12801 pendingUNSAFE_ComponentWillMountWarnings.push(fiber); 12802 } 12803 12804 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) { 12805 pendingComponentWillReceivePropsWarnings.push(fiber); 12806 } 12807 12808 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') { 12809 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); 12810 } 12811 12812 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) { 12813 pendingComponentWillUpdateWarnings.push(fiber); 12814 } 12815 12816 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillUpdate === 'function') { 12817 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); 12818 } 12819 }; 12820 12821 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () { 12822 // We do an initial pass to gather component names 12823 var componentWillMountUniqueNames = new Set(); 12824 12825 if (pendingComponentWillMountWarnings.length > 0) { 12826 pendingComponentWillMountWarnings.forEach(function (fiber) { 12827 componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component'); 12828 didWarnAboutUnsafeLifecycles.add(fiber.type); 12829 }); 12830 pendingComponentWillMountWarnings = []; 12831 } 12832 12833 var UNSAFE_componentWillMountUniqueNames = new Set(); 12834 12835 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) { 12836 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) { 12837 UNSAFE_componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component'); 12838 didWarnAboutUnsafeLifecycles.add(fiber.type); 12839 }); 12840 pendingUNSAFE_ComponentWillMountWarnings = []; 12841 } 12842 12843 var componentWillReceivePropsUniqueNames = new Set(); 12844 12845 if (pendingComponentWillReceivePropsWarnings.length > 0) { 12846 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) { 12847 componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component'); 12848 didWarnAboutUnsafeLifecycles.add(fiber.type); 12849 }); 12850 pendingComponentWillReceivePropsWarnings = []; 12851 } 12852 12853 var UNSAFE_componentWillReceivePropsUniqueNames = new Set(); 12854 12855 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) { 12856 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) { 12857 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component'); 12858 didWarnAboutUnsafeLifecycles.add(fiber.type); 12859 }); 12860 pendingUNSAFE_ComponentWillReceivePropsWarnings = []; 12861 } 12862 12863 var componentWillUpdateUniqueNames = new Set(); 12864 12865 if (pendingComponentWillUpdateWarnings.length > 0) { 12866 pendingComponentWillUpdateWarnings.forEach(function (fiber) { 12867 componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component'); 12868 didWarnAboutUnsafeLifecycles.add(fiber.type); 12869 }); 12870 pendingComponentWillUpdateWarnings = []; 12871 } 12872 12873 var UNSAFE_componentWillUpdateUniqueNames = new Set(); 12874 12875 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) { 12876 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) { 12877 UNSAFE_componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component'); 12878 didWarnAboutUnsafeLifecycles.add(fiber.type); 12879 }); 12880 pendingUNSAFE_ComponentWillUpdateWarnings = []; 12881 } // Finally, we flush all the warnings 12882 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder' 12883 12884 12885 if (UNSAFE_componentWillMountUniqueNames.size > 0) { 12886 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); 12887 12888 error('Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '\nPlease update the following components: %s', sortedNames); 12889 } 12890 12891 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) { 12892 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames); 12893 12894 error('Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, " + 'refactor your code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n' + '\nPlease update the following components: %s', _sortedNames); 12895 } 12896 12897 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) { 12898 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames); 12899 12900 error('Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2); 12901 } 12902 12903 if (componentWillMountUniqueNames.size > 0) { 12904 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); 12905 12906 warn('componentWillMount has been renamed, and is not recommended for use. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames3); 12907 } 12908 12909 if (componentWillReceivePropsUniqueNames.size > 0) { 12910 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames); 12911 12912 warn('componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, refactor your " + 'code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n' + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames4); 12913 } 12914 12915 if (componentWillUpdateUniqueNames.size > 0) { 12916 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); 12917 12918 warn('componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames5); 12919 } 12920 }; 12921 12922 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about. 12923 12924 var didWarnAboutLegacyContext = new Set(); 12925 12926 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) { 12927 var strictRoot = findStrictRoot(fiber); 12928 12929 if (strictRoot === null) { 12930 error('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.'); 12931 12932 return; 12933 } // Dedup strategy: Warn once per component. 12934 12935 12936 if (didWarnAboutLegacyContext.has(fiber.type)) { 12937 return; 12938 } 12939 12940 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot); 12941 12942 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') { 12943 if (warningsForRoot === undefined) { 12944 warningsForRoot = []; 12945 pendingLegacyContextWarning.set(strictRoot, warningsForRoot); 12946 } 12947 12948 warningsForRoot.push(fiber); 12949 } 12950 }; 12951 12952 ReactStrictModeWarnings.flushLegacyContextWarning = function () { 12953 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) { 12954 if (fiberArray.length === 0) { 12955 return; 12956 } 12957 12958 var firstFiber = fiberArray[0]; 12959 var uniqueNames = new Set(); 12960 fiberArray.forEach(function (fiber) { 12961 uniqueNames.add(getComponentNameFromFiber(fiber) || 'Component'); 12962 didWarnAboutLegacyContext.add(fiber.type); 12963 }); 12964 var sortedNames = setToSortedString(uniqueNames); 12965 12966 try { 12967 setCurrentFiber(firstFiber); 12968 12969 error('Legacy context API has been detected within a strict-mode tree.' + '\n\nThe old API will be supported in all 16.x releases, but applications ' + 'using it should migrate to the new version.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here: https://reactjs.org/link/legacy-context', sortedNames); 12970 } finally { 12971 resetCurrentFiber(); 12972 } 12973 }); 12974 }; 12975 12976 ReactStrictModeWarnings.discardPendingWarnings = function () { 12977 pendingComponentWillMountWarnings = []; 12978 pendingUNSAFE_ComponentWillMountWarnings = []; 12979 pendingComponentWillReceivePropsWarnings = []; 12980 pendingUNSAFE_ComponentWillReceivePropsWarnings = []; 12981 pendingComponentWillUpdateWarnings = []; 12982 pendingUNSAFE_ComponentWillUpdateWarnings = []; 12983 pendingLegacyContextWarning = new Map(); 12984 }; 12985} 12986 12987function resolveDefaultProps(Component, baseProps) { 12988 if (Component && Component.defaultProps) { 12989 // Resolve default props. Taken from ReactElement 12990 var props = assign({}, baseProps); 12991 var defaultProps = Component.defaultProps; 12992 12993 for (var propName in defaultProps) { 12994 if (props[propName] === undefined) { 12995 props[propName] = defaultProps[propName]; 12996 } 12997 } 12998 12999 return props; 13000 } 13001 13002 return baseProps; 13003} 13004 13005var valueCursor = createCursor(null); 13006var rendererSigil; 13007 13008{ 13009 // Use this to detect multiple renderers using the same context 13010 rendererSigil = {}; 13011} 13012 13013var currentlyRenderingFiber = null; 13014var lastContextDependency = null; 13015var lastFullyObservedContext = null; 13016var isDisallowedContextReadInDEV = false; 13017function resetContextDependencies() { 13018 // This is called right before React yields execution, to ensure `readContext` 13019 // cannot be called outside the render phase. 13020 currentlyRenderingFiber = null; 13021 lastContextDependency = null; 13022 lastFullyObservedContext = null; 13023 13024 { 13025 isDisallowedContextReadInDEV = false; 13026 } 13027} 13028function enterDisallowedContextReadInDEV() { 13029 { 13030 isDisallowedContextReadInDEV = true; 13031 } 13032} 13033function exitDisallowedContextReadInDEV() { 13034 { 13035 isDisallowedContextReadInDEV = false; 13036 } 13037} 13038function pushProvider(providerFiber, context, nextValue) { 13039 { 13040 push(valueCursor, context._currentValue, providerFiber); 13041 context._currentValue = nextValue; 13042 13043 { 13044 if (context._currentRenderer !== undefined && context._currentRenderer !== null && context._currentRenderer !== rendererSigil) { 13045 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.'); 13046 } 13047 13048 context._currentRenderer = rendererSigil; 13049 } 13050 } 13051} 13052function popProvider(context, providerFiber) { 13053 var currentValue = valueCursor.current; 13054 pop(valueCursor, providerFiber); 13055 13056 { 13057 { 13058 context._currentValue = currentValue; 13059 } 13060 } 13061} 13062function scheduleContextWorkOnParentPath(parent, renderLanes, propagationRoot) { 13063 // Update the child lanes of all the ancestors, including the alternates. 13064 var node = parent; 13065 13066 while (node !== null) { 13067 var alternate = node.alternate; 13068 13069 if (!isSubsetOfLanes(node.childLanes, renderLanes)) { 13070 node.childLanes = mergeLanes(node.childLanes, renderLanes); 13071 13072 if (alternate !== null) { 13073 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes); 13074 } 13075 } else if (alternate !== null && !isSubsetOfLanes(alternate.childLanes, renderLanes)) { 13076 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes); 13077 } 13078 13079 if (node === propagationRoot) { 13080 break; 13081 } 13082 13083 node = node.return; 13084 } 13085 13086 { 13087 if (node !== propagationRoot) { 13088 error('Expected to find the propagation root when scheduling context work. ' + 'This error is likely caused by a bug in React. Please file an issue.'); 13089 } 13090 } 13091} 13092function propagateContextChange(workInProgress, context, renderLanes) { 13093 { 13094 propagateContextChange_eager(workInProgress, context, renderLanes); 13095 } 13096} 13097 13098function propagateContextChange_eager(workInProgress, context, renderLanes) { 13099 13100 var fiber = workInProgress.child; 13101 13102 if (fiber !== null) { 13103 // Set the return pointer of the child to the work-in-progress fiber. 13104 fiber.return = workInProgress; 13105 } 13106 13107 while (fiber !== null) { 13108 var nextFiber = void 0; // Visit this fiber. 13109 13110 var list = fiber.dependencies; 13111 13112 if (list !== null) { 13113 nextFiber = fiber.child; 13114 var dependency = list.firstContext; 13115 13116 while (dependency !== null) { 13117 // Check if the context matches. 13118 if (dependency.context === context) { 13119 // Match! Schedule an update on this fiber. 13120 if (fiber.tag === ClassComponent) { 13121 // Schedule a force update on the work-in-progress. 13122 var lane = pickArbitraryLane(renderLanes); 13123 var update = createUpdate(NoTimestamp, lane); 13124 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the 13125 // update to the current fiber, too, which means it will persist even if 13126 // this render is thrown away. Since it's a race condition, not sure it's 13127 // worth fixing. 13128 // Inlined `enqueueUpdate` to remove interleaved update check 13129 13130 var updateQueue = fiber.updateQueue; 13131 13132 if (updateQueue === null) ; else { 13133 var sharedQueue = updateQueue.shared; 13134 var pending = sharedQueue.pending; 13135 13136 if (pending === null) { 13137 // This is the first update. Create a circular list. 13138 update.next = update; 13139 } else { 13140 update.next = pending.next; 13141 pending.next = update; 13142 } 13143 13144 sharedQueue.pending = update; 13145 } 13146 } 13147 13148 fiber.lanes = mergeLanes(fiber.lanes, renderLanes); 13149 var alternate = fiber.alternate; 13150 13151 if (alternate !== null) { 13152 alternate.lanes = mergeLanes(alternate.lanes, renderLanes); 13153 } 13154 13155 scheduleContextWorkOnParentPath(fiber.return, renderLanes, workInProgress); // Mark the updated lanes on the list, too. 13156 13157 list.lanes = mergeLanes(list.lanes, renderLanes); // Since we already found a match, we can stop traversing the 13158 // dependency list. 13159 13160 break; 13161 } 13162 13163 dependency = dependency.next; 13164 } 13165 } else if (fiber.tag === ContextProvider) { 13166 // Don't scan deeper if this is a matching provider 13167 nextFiber = fiber.type === workInProgress.type ? null : fiber.child; 13168 } else if (fiber.tag === DehydratedFragment) { 13169 // If a dehydrated suspense boundary is in this subtree, we don't know 13170 // if it will have any context consumers in it. The best we can do is 13171 // mark it as having updates. 13172 var parentSuspense = fiber.return; 13173 13174 if (parentSuspense === null) { 13175 throw new Error('We just came from a parent so we must have had a parent. This is a bug in React.'); 13176 } 13177 13178 parentSuspense.lanes = mergeLanes(parentSuspense.lanes, renderLanes); 13179 var _alternate = parentSuspense.alternate; 13180 13181 if (_alternate !== null) { 13182 _alternate.lanes = mergeLanes(_alternate.lanes, renderLanes); 13183 } // This is intentionally passing this fiber as the parent 13184 // because we want to schedule this fiber as having work 13185 // on its children. We'll use the childLanes on 13186 // this fiber to indicate that a context has changed. 13187 13188 13189 scheduleContextWorkOnParentPath(parentSuspense, renderLanes, workInProgress); 13190 nextFiber = fiber.sibling; 13191 } else { 13192 // Traverse down. 13193 nextFiber = fiber.child; 13194 } 13195 13196 if (nextFiber !== null) { 13197 // Set the return pointer of the child to the work-in-progress fiber. 13198 nextFiber.return = fiber; 13199 } else { 13200 // No child. Traverse to next sibling. 13201 nextFiber = fiber; 13202 13203 while (nextFiber !== null) { 13204 if (nextFiber === workInProgress) { 13205 // We're back to the root of this subtree. Exit. 13206 nextFiber = null; 13207 break; 13208 } 13209 13210 var sibling = nextFiber.sibling; 13211 13212 if (sibling !== null) { 13213 // Set the return pointer of the sibling to the work-in-progress fiber. 13214 sibling.return = nextFiber.return; 13215 nextFiber = sibling; 13216 break; 13217 } // No more siblings. Traverse up. 13218 13219 13220 nextFiber = nextFiber.return; 13221 } 13222 } 13223 13224 fiber = nextFiber; 13225 } 13226} 13227function prepareToReadContext(workInProgress, renderLanes) { 13228 currentlyRenderingFiber = workInProgress; 13229 lastContextDependency = null; 13230 lastFullyObservedContext = null; 13231 var dependencies = workInProgress.dependencies; 13232 13233 if (dependencies !== null) { 13234 { 13235 var firstContext = dependencies.firstContext; 13236 13237 if (firstContext !== null) { 13238 if (includesSomeLane(dependencies.lanes, renderLanes)) { 13239 // Context list has a pending update. Mark that this fiber performed work. 13240 markWorkInProgressReceivedUpdate(); 13241 } // Reset the work-in-progress list 13242 13243 13244 dependencies.firstContext = null; 13245 } 13246 } 13247 } 13248} 13249function readContext(context) { 13250 { 13251 // This warning would fire if you read context inside a Hook like useMemo. 13252 // Unlike the class check below, it's not enforced in production for perf. 13253 if (isDisallowedContextReadInDEV) { 13254 error('Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().'); 13255 } 13256 } 13257 13258 var value = context._currentValue ; 13259 13260 if (lastFullyObservedContext === context) ; else { 13261 var contextItem = { 13262 context: context, 13263 memoizedValue: value, 13264 next: null 13265 }; 13266 13267 if (lastContextDependency === null) { 13268 if (currentlyRenderingFiber === null) { 13269 throw new Error('Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().'); 13270 } // This is the first dependency for this component. Create a new list. 13271 13272 13273 lastContextDependency = contextItem; 13274 currentlyRenderingFiber.dependencies = { 13275 lanes: NoLanes, 13276 firstContext: contextItem 13277 }; 13278 } else { 13279 // Append a new context item. 13280 lastContextDependency = lastContextDependency.next = contextItem; 13281 } 13282 } 13283 13284 return value; 13285} 13286 13287// render. When this render exits, either because it finishes or because it is 13288// interrupted, the interleaved updates will be transferred onto the main part 13289// of the queue. 13290 13291var concurrentQueues = null; 13292function pushConcurrentUpdateQueue(queue) { 13293 if (concurrentQueues === null) { 13294 concurrentQueues = [queue]; 13295 } else { 13296 concurrentQueues.push(queue); 13297 } 13298} 13299function finishQueueingConcurrentUpdates() { 13300 // Transfer the interleaved updates onto the main queue. Each queue has a 13301 // `pending` field and an `interleaved` field. When they are not null, they 13302 // point to the last node in a circular linked list. We need to append the 13303 // interleaved list to the end of the pending list by joining them into a 13304 // single, circular list. 13305 if (concurrentQueues !== null) { 13306 for (var i = 0; i < concurrentQueues.length; i++) { 13307 var queue = concurrentQueues[i]; 13308 var lastInterleavedUpdate = queue.interleaved; 13309 13310 if (lastInterleavedUpdate !== null) { 13311 queue.interleaved = null; 13312 var firstInterleavedUpdate = lastInterleavedUpdate.next; 13313 var lastPendingUpdate = queue.pending; 13314 13315 if (lastPendingUpdate !== null) { 13316 var firstPendingUpdate = lastPendingUpdate.next; 13317 lastPendingUpdate.next = firstInterleavedUpdate; 13318 lastInterleavedUpdate.next = firstPendingUpdate; 13319 } 13320 13321 queue.pending = lastInterleavedUpdate; 13322 } 13323 } 13324 13325 concurrentQueues = null; 13326 } 13327} 13328function enqueueConcurrentHookUpdate(fiber, queue, update, lane) { 13329 var interleaved = queue.interleaved; 13330 13331 if (interleaved === null) { 13332 // This is the first update. Create a circular list. 13333 update.next = update; // At the end of the current render, this queue's interleaved updates will 13334 // be transferred to the pending queue. 13335 13336 pushConcurrentUpdateQueue(queue); 13337 } else { 13338 update.next = interleaved.next; 13339 interleaved.next = update; 13340 } 13341 13342 queue.interleaved = update; 13343 return markUpdateLaneFromFiberToRoot(fiber, lane); 13344} 13345function enqueueConcurrentHookUpdateAndEagerlyBailout(fiber, queue, update, lane) { 13346 var interleaved = queue.interleaved; 13347 13348 if (interleaved === null) { 13349 // This is the first update. Create a circular list. 13350 update.next = update; // At the end of the current render, this queue's interleaved updates will 13351 // be transferred to the pending queue. 13352 13353 pushConcurrentUpdateQueue(queue); 13354 } else { 13355 update.next = interleaved.next; 13356 interleaved.next = update; 13357 } 13358 13359 queue.interleaved = update; 13360} 13361function enqueueConcurrentClassUpdate(fiber, queue, update, lane) { 13362 var interleaved = queue.interleaved; 13363 13364 if (interleaved === null) { 13365 // This is the first update. Create a circular list. 13366 update.next = update; // At the end of the current render, this queue's interleaved updates will 13367 // be transferred to the pending queue. 13368 13369 pushConcurrentUpdateQueue(queue); 13370 } else { 13371 update.next = interleaved.next; 13372 interleaved.next = update; 13373 } 13374 13375 queue.interleaved = update; 13376 return markUpdateLaneFromFiberToRoot(fiber, lane); 13377} 13378function enqueueConcurrentRenderForLane(fiber, lane) { 13379 return markUpdateLaneFromFiberToRoot(fiber, lane); 13380} // Calling this function outside this module should only be done for backwards 13381// compatibility and should always be accompanied by a warning. 13382 13383var unsafe_markUpdateLaneFromFiberToRoot = markUpdateLaneFromFiberToRoot; 13384 13385function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { 13386 // Update the source fiber's lanes 13387 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane); 13388 var alternate = sourceFiber.alternate; 13389 13390 if (alternate !== null) { 13391 alternate.lanes = mergeLanes(alternate.lanes, lane); 13392 } 13393 13394 { 13395 if (alternate === null && (sourceFiber.flags & (Placement | Hydrating)) !== NoFlags) { 13396 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); 13397 } 13398 } // Walk the parent path to the root and update the child lanes. 13399 13400 13401 var node = sourceFiber; 13402 var parent = sourceFiber.return; 13403 13404 while (parent !== null) { 13405 parent.childLanes = mergeLanes(parent.childLanes, lane); 13406 alternate = parent.alternate; 13407 13408 if (alternate !== null) { 13409 alternate.childLanes = mergeLanes(alternate.childLanes, lane); 13410 } else { 13411 { 13412 if ((parent.flags & (Placement | Hydrating)) !== NoFlags) { 13413 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); 13414 } 13415 } 13416 } 13417 13418 node = parent; 13419 parent = parent.return; 13420 } 13421 13422 if (node.tag === HostRoot) { 13423 var root = node.stateNode; 13424 return root; 13425 } else { 13426 return null; 13427 } 13428} 13429 13430var UpdateState = 0; 13431var ReplaceState = 1; 13432var ForceUpdate = 2; 13433var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`. 13434// It should only be read right after calling `processUpdateQueue`, via 13435// `checkHasForceUpdateAfterProcessing`. 13436 13437var hasForceUpdate = false; 13438var didWarnUpdateInsideUpdate; 13439var currentlyProcessingQueue; 13440 13441{ 13442 didWarnUpdateInsideUpdate = false; 13443 currentlyProcessingQueue = null; 13444} 13445 13446function initializeUpdateQueue(fiber) { 13447 var queue = { 13448 baseState: fiber.memoizedState, 13449 firstBaseUpdate: null, 13450 lastBaseUpdate: null, 13451 shared: { 13452 pending: null, 13453 interleaved: null, 13454 lanes: NoLanes 13455 }, 13456 effects: null 13457 }; 13458 fiber.updateQueue = queue; 13459} 13460function cloneUpdateQueue(current, workInProgress) { 13461 // Clone the update queue from current. Unless it's already a clone. 13462 var queue = workInProgress.updateQueue; 13463 var currentQueue = current.updateQueue; 13464 13465 if (queue === currentQueue) { 13466 var clone = { 13467 baseState: currentQueue.baseState, 13468 firstBaseUpdate: currentQueue.firstBaseUpdate, 13469 lastBaseUpdate: currentQueue.lastBaseUpdate, 13470 shared: currentQueue.shared, 13471 effects: currentQueue.effects 13472 }; 13473 workInProgress.updateQueue = clone; 13474 } 13475} 13476function createUpdate(eventTime, lane) { 13477 var update = { 13478 eventTime: eventTime, 13479 lane: lane, 13480 tag: UpdateState, 13481 payload: null, 13482 callback: null, 13483 next: null 13484 }; 13485 return update; 13486} 13487function enqueueUpdate(fiber, update, lane) { 13488 var updateQueue = fiber.updateQueue; 13489 13490 if (updateQueue === null) { 13491 // Only occurs if the fiber has been unmounted. 13492 return null; 13493 } 13494 13495 var sharedQueue = updateQueue.shared; 13496 13497 { 13498 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) { 13499 error('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.'); 13500 13501 didWarnUpdateInsideUpdate = true; 13502 } 13503 } 13504 13505 if (isUnsafeClassRenderPhaseUpdate()) { 13506 // This is an unsafe render phase update. Add directly to the update 13507 // queue so we can process it immediately during the current render. 13508 var pending = sharedQueue.pending; 13509 13510 if (pending === null) { 13511 // This is the first update. Create a circular list. 13512 update.next = update; 13513 } else { 13514 update.next = pending.next; 13515 pending.next = update; 13516 } 13517 13518 sharedQueue.pending = update; // Update the childLanes even though we're most likely already rendering 13519 // this fiber. This is for backwards compatibility in the case where you 13520 // update a different component during render phase than the one that is 13521 // currently renderings (a pattern that is accompanied by a warning). 13522 13523 return unsafe_markUpdateLaneFromFiberToRoot(fiber, lane); 13524 } else { 13525 return enqueueConcurrentClassUpdate(fiber, sharedQueue, update, lane); 13526 } 13527} 13528function entangleTransitions(root, fiber, lane) { 13529 var updateQueue = fiber.updateQueue; 13530 13531 if (updateQueue === null) { 13532 // Only occurs if the fiber has been unmounted. 13533 return; 13534 } 13535 13536 var sharedQueue = updateQueue.shared; 13537 13538 if (isTransitionLane(lane)) { 13539 var queueLanes = sharedQueue.lanes; // If any entangled lanes are no longer pending on the root, then they must 13540 // have finished. We can remove them from the shared queue, which represents 13541 // a superset of the actually pending lanes. In some cases we may entangle 13542 // more than we need to, but that's OK. In fact it's worse if we *don't* 13543 // entangle when we should. 13544 13545 queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. 13546 13547 var newQueueLanes = mergeLanes(queueLanes, lane); 13548 sharedQueue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if 13549 // the lane finished since the last time we entangled it. So we need to 13550 // entangle it again, just to be sure. 13551 13552 markRootEntangled(root, newQueueLanes); 13553 } 13554} 13555function enqueueCapturedUpdate(workInProgress, capturedUpdate) { 13556 // Captured updates are updates that are thrown by a child during the render 13557 // phase. They should be discarded if the render is aborted. Therefore, 13558 // we should only put them on the work-in-progress queue, not the current one. 13559 var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone. 13560 13561 var current = workInProgress.alternate; 13562 13563 if (current !== null) { 13564 var currentQueue = current.updateQueue; 13565 13566 if (queue === currentQueue) { 13567 // The work-in-progress queue is the same as current. This happens when 13568 // we bail out on a parent fiber that then captures an error thrown by 13569 // a child. Since we want to append the update only to the work-in 13570 // -progress queue, we need to clone the updates. We usually clone during 13571 // processUpdateQueue, but that didn't happen in this case because we 13572 // skipped over the parent when we bailed out. 13573 var newFirst = null; 13574 var newLast = null; 13575 var firstBaseUpdate = queue.firstBaseUpdate; 13576 13577 if (firstBaseUpdate !== null) { 13578 // Loop through the updates and clone them. 13579 var update = firstBaseUpdate; 13580 13581 do { 13582 var clone = { 13583 eventTime: update.eventTime, 13584 lane: update.lane, 13585 tag: update.tag, 13586 payload: update.payload, 13587 callback: update.callback, 13588 next: null 13589 }; 13590 13591 if (newLast === null) { 13592 newFirst = newLast = clone; 13593 } else { 13594 newLast.next = clone; 13595 newLast = clone; 13596 } 13597 13598 update = update.next; 13599 } while (update !== null); // Append the captured update the end of the cloned list. 13600 13601 13602 if (newLast === null) { 13603 newFirst = newLast = capturedUpdate; 13604 } else { 13605 newLast.next = capturedUpdate; 13606 newLast = capturedUpdate; 13607 } 13608 } else { 13609 // There are no base updates. 13610 newFirst = newLast = capturedUpdate; 13611 } 13612 13613 queue = { 13614 baseState: currentQueue.baseState, 13615 firstBaseUpdate: newFirst, 13616 lastBaseUpdate: newLast, 13617 shared: currentQueue.shared, 13618 effects: currentQueue.effects 13619 }; 13620 workInProgress.updateQueue = queue; 13621 return; 13622 } 13623 } // Append the update to the end of the list. 13624 13625 13626 var lastBaseUpdate = queue.lastBaseUpdate; 13627 13628 if (lastBaseUpdate === null) { 13629 queue.firstBaseUpdate = capturedUpdate; 13630 } else { 13631 lastBaseUpdate.next = capturedUpdate; 13632 } 13633 13634 queue.lastBaseUpdate = capturedUpdate; 13635} 13636 13637function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) { 13638 switch (update.tag) { 13639 case ReplaceState: 13640 { 13641 var payload = update.payload; 13642 13643 if (typeof payload === 'function') { 13644 // Updater function 13645 { 13646 enterDisallowedContextReadInDEV(); 13647 } 13648 13649 var nextState = payload.call(instance, prevState, nextProps); 13650 13651 { 13652 if ( workInProgress.mode & StrictLegacyMode) { 13653 setIsStrictModeForDevtools(true); 13654 13655 try { 13656 payload.call(instance, prevState, nextProps); 13657 } finally { 13658 setIsStrictModeForDevtools(false); 13659 } 13660 } 13661 13662 exitDisallowedContextReadInDEV(); 13663 } 13664 13665 return nextState; 13666 } // State object 13667 13668 13669 return payload; 13670 } 13671 13672 case CaptureUpdate: 13673 { 13674 workInProgress.flags = workInProgress.flags & ~ShouldCapture | DidCapture; 13675 } 13676 // Intentional fallthrough 13677 13678 case UpdateState: 13679 { 13680 var _payload = update.payload; 13681 var partialState; 13682 13683 if (typeof _payload === 'function') { 13684 // Updater function 13685 { 13686 enterDisallowedContextReadInDEV(); 13687 } 13688 13689 partialState = _payload.call(instance, prevState, nextProps); 13690 13691 { 13692 if ( workInProgress.mode & StrictLegacyMode) { 13693 setIsStrictModeForDevtools(true); 13694 13695 try { 13696 _payload.call(instance, prevState, nextProps); 13697 } finally { 13698 setIsStrictModeForDevtools(false); 13699 } 13700 } 13701 13702 exitDisallowedContextReadInDEV(); 13703 } 13704 } else { 13705 // Partial state object 13706 partialState = _payload; 13707 } 13708 13709 if (partialState === null || partialState === undefined) { 13710 // Null and undefined are treated as no-ops. 13711 return prevState; 13712 } // Merge the partial state and the previous state. 13713 13714 13715 return assign({}, prevState, partialState); 13716 } 13717 13718 case ForceUpdate: 13719 { 13720 hasForceUpdate = true; 13721 return prevState; 13722 } 13723 } 13724 13725 return prevState; 13726} 13727 13728function processUpdateQueue(workInProgress, props, instance, renderLanes) { 13729 // This is always non-null on a ClassComponent or HostRoot 13730 var queue = workInProgress.updateQueue; 13731 hasForceUpdate = false; 13732 13733 { 13734 currentlyProcessingQueue = queue.shared; 13735 } 13736 13737 var firstBaseUpdate = queue.firstBaseUpdate; 13738 var lastBaseUpdate = queue.lastBaseUpdate; // Check if there are pending updates. If so, transfer them to the base queue. 13739 13740 var pendingQueue = queue.shared.pending; 13741 13742 if (pendingQueue !== null) { 13743 queue.shared.pending = null; // The pending queue is circular. Disconnect the pointer between first 13744 // and last so that it's non-circular. 13745 13746 var lastPendingUpdate = pendingQueue; 13747 var firstPendingUpdate = lastPendingUpdate.next; 13748 lastPendingUpdate.next = null; // Append pending updates to base queue 13749 13750 if (lastBaseUpdate === null) { 13751 firstBaseUpdate = firstPendingUpdate; 13752 } else { 13753 lastBaseUpdate.next = firstPendingUpdate; 13754 } 13755 13756 lastBaseUpdate = lastPendingUpdate; // If there's a current queue, and it's different from the base queue, then 13757 // we need to transfer the updates to that queue, too. Because the base 13758 // queue is a singly-linked list with no cycles, we can append to both 13759 // lists and take advantage of structural sharing. 13760 // TODO: Pass `current` as argument 13761 13762 var current = workInProgress.alternate; 13763 13764 if (current !== null) { 13765 // This is always non-null on a ClassComponent or HostRoot 13766 var currentQueue = current.updateQueue; 13767 var currentLastBaseUpdate = currentQueue.lastBaseUpdate; 13768 13769 if (currentLastBaseUpdate !== lastBaseUpdate) { 13770 if (currentLastBaseUpdate === null) { 13771 currentQueue.firstBaseUpdate = firstPendingUpdate; 13772 } else { 13773 currentLastBaseUpdate.next = firstPendingUpdate; 13774 } 13775 13776 currentQueue.lastBaseUpdate = lastPendingUpdate; 13777 } 13778 } 13779 } // These values may change as we process the queue. 13780 13781 13782 if (firstBaseUpdate !== null) { 13783 // Iterate through the list of updates to compute the result. 13784 var newState = queue.baseState; // TODO: Don't need to accumulate this. Instead, we can remove renderLanes 13785 // from the original lanes. 13786 13787 var newLanes = NoLanes; 13788 var newBaseState = null; 13789 var newFirstBaseUpdate = null; 13790 var newLastBaseUpdate = null; 13791 var update = firstBaseUpdate; 13792 13793 do { 13794 var updateLane = update.lane; 13795 var updateEventTime = update.eventTime; 13796 13797 if (!isSubsetOfLanes(renderLanes, updateLane)) { 13798 // Priority is insufficient. Skip this update. If this is the first 13799 // skipped update, the previous update/state is the new base 13800 // update/state. 13801 var clone = { 13802 eventTime: updateEventTime, 13803 lane: updateLane, 13804 tag: update.tag, 13805 payload: update.payload, 13806 callback: update.callback, 13807 next: null 13808 }; 13809 13810 if (newLastBaseUpdate === null) { 13811 newFirstBaseUpdate = newLastBaseUpdate = clone; 13812 newBaseState = newState; 13813 } else { 13814 newLastBaseUpdate = newLastBaseUpdate.next = clone; 13815 } // Update the remaining priority in the queue. 13816 13817 13818 newLanes = mergeLanes(newLanes, updateLane); 13819 } else { 13820 // This update does have sufficient priority. 13821 if (newLastBaseUpdate !== null) { 13822 var _clone = { 13823 eventTime: updateEventTime, 13824 // This update is going to be committed so we never want uncommit 13825 // it. Using NoLane works because 0 is a subset of all bitmasks, so 13826 // this will never be skipped by the check above. 13827 lane: NoLane, 13828 tag: update.tag, 13829 payload: update.payload, 13830 callback: update.callback, 13831 next: null 13832 }; 13833 newLastBaseUpdate = newLastBaseUpdate.next = _clone; 13834 } // Process this update. 13835 13836 13837 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance); 13838 var callback = update.callback; 13839 13840 if (callback !== null && // If the update was already committed, we should not queue its 13841 // callback again. 13842 update.lane !== NoLane) { 13843 workInProgress.flags |= Callback; 13844 var effects = queue.effects; 13845 13846 if (effects === null) { 13847 queue.effects = [update]; 13848 } else { 13849 effects.push(update); 13850 } 13851 } 13852 } 13853 13854 update = update.next; 13855 13856 if (update === null) { 13857 pendingQueue = queue.shared.pending; 13858 13859 if (pendingQueue === null) { 13860 break; 13861 } else { 13862 // An update was scheduled from inside a reducer. Add the new 13863 // pending updates to the end of the list and keep processing. 13864 var _lastPendingUpdate = pendingQueue; // Intentionally unsound. Pending updates form a circular list, but we 13865 // unravel them when transferring them to the base queue. 13866 13867 var _firstPendingUpdate = _lastPendingUpdate.next; 13868 _lastPendingUpdate.next = null; 13869 update = _firstPendingUpdate; 13870 queue.lastBaseUpdate = _lastPendingUpdate; 13871 queue.shared.pending = null; 13872 } 13873 } 13874 } while (true); 13875 13876 if (newLastBaseUpdate === null) { 13877 newBaseState = newState; 13878 } 13879 13880 queue.baseState = newBaseState; 13881 queue.firstBaseUpdate = newFirstBaseUpdate; 13882 queue.lastBaseUpdate = newLastBaseUpdate; // Interleaved updates are stored on a separate queue. We aren't going to 13883 // process them during this render, but we do need to track which lanes 13884 // are remaining. 13885 13886 var lastInterleaved = queue.shared.interleaved; 13887 13888 if (lastInterleaved !== null) { 13889 var interleaved = lastInterleaved; 13890 13891 do { 13892 newLanes = mergeLanes(newLanes, interleaved.lane); 13893 interleaved = interleaved.next; 13894 } while (interleaved !== lastInterleaved); 13895 } else if (firstBaseUpdate === null) { 13896 // `queue.lanes` is used for entangling transitions. We can set it back to 13897 // zero once the queue is empty. 13898 queue.shared.lanes = NoLanes; 13899 } // Set the remaining expiration time to be whatever is remaining in the queue. 13900 // This should be fine because the only two other things that contribute to 13901 // expiration time are props and context. We're already in the middle of the 13902 // begin phase by the time we start processing the queue, so we've already 13903 // dealt with the props. Context in components that specify 13904 // shouldComponentUpdate is tricky; but we'll have to account for 13905 // that regardless. 13906 13907 13908 markSkippedUpdateLanes(newLanes); 13909 workInProgress.lanes = newLanes; 13910 workInProgress.memoizedState = newState; 13911 } 13912 13913 { 13914 currentlyProcessingQueue = null; 13915 } 13916} 13917 13918function callCallback(callback, context) { 13919 if (typeof callback !== 'function') { 13920 throw new Error('Invalid argument passed as callback. Expected a function. Instead ' + ("received: " + callback)); 13921 } 13922 13923 callback.call(context); 13924} 13925 13926function resetHasForceUpdateBeforeProcessing() { 13927 hasForceUpdate = false; 13928} 13929function checkHasForceUpdateAfterProcessing() { 13930 return hasForceUpdate; 13931} 13932function commitUpdateQueue(finishedWork, finishedQueue, instance) { 13933 // Commit the effects 13934 var effects = finishedQueue.effects; 13935 finishedQueue.effects = null; 13936 13937 if (effects !== null) { 13938 for (var i = 0; i < effects.length; i++) { 13939 var effect = effects[i]; 13940 var callback = effect.callback; 13941 13942 if (callback !== null) { 13943 effect.callback = null; 13944 callCallback(callback, instance); 13945 } 13946 } 13947 } 13948} 13949 13950var fakeInternalInstance = {}; // React.Component uses a shared frozen object by default. 13951// We'll use it to determine whether we need to initialize legacy refs. 13952 13953var emptyRefsObject = new React.Component().refs; 13954var didWarnAboutStateAssignmentForComponent; 13955var didWarnAboutUninitializedState; 13956var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate; 13957var didWarnAboutLegacyLifecyclesAndDerivedState; 13958var didWarnAboutUndefinedDerivedState; 13959var warnOnUndefinedDerivedState; 13960var warnOnInvalidCallback; 13961var didWarnAboutDirectlyAssigningPropsToState; 13962var didWarnAboutContextTypeAndContextTypes; 13963var didWarnAboutInvalidateContextType; 13964 13965{ 13966 didWarnAboutStateAssignmentForComponent = new Set(); 13967 didWarnAboutUninitializedState = new Set(); 13968 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set(); 13969 didWarnAboutLegacyLifecyclesAndDerivedState = new Set(); 13970 didWarnAboutDirectlyAssigningPropsToState = new Set(); 13971 didWarnAboutUndefinedDerivedState = new Set(); 13972 didWarnAboutContextTypeAndContextTypes = new Set(); 13973 didWarnAboutInvalidateContextType = new Set(); 13974 var didWarnOnInvalidCallback = new Set(); 13975 13976 warnOnInvalidCallback = function (callback, callerName) { 13977 if (callback === null || typeof callback === 'function') { 13978 return; 13979 } 13980 13981 var key = callerName + '_' + callback; 13982 13983 if (!didWarnOnInvalidCallback.has(key)) { 13984 didWarnOnInvalidCallback.add(key); 13985 13986 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback); 13987 } 13988 }; 13989 13990 warnOnUndefinedDerivedState = function (type, partialState) { 13991 if (partialState === undefined) { 13992 var componentName = getComponentNameFromType(type) || 'Component'; 13993 13994 if (!didWarnAboutUndefinedDerivedState.has(componentName)) { 13995 didWarnAboutUndefinedDerivedState.add(componentName); 13996 13997 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName); 13998 } 13999 } 14000 }; // This is so gross but it's at least non-critical and can be removed if 14001 // it causes problems. This is meant to give a nicer error message for 14002 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component, 14003 // ...)) which otherwise throws a "_processChildContext is not a function" 14004 // exception. 14005 14006 14007 Object.defineProperty(fakeInternalInstance, '_processChildContext', { 14008 enumerable: false, 14009 value: function () { 14010 throw new Error('_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).'); 14011 } 14012 }); 14013 Object.freeze(fakeInternalInstance); 14014} 14015 14016function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) { 14017 var prevState = workInProgress.memoizedState; 14018 var partialState = getDerivedStateFromProps(nextProps, prevState); 14019 14020 { 14021 if ( workInProgress.mode & StrictLegacyMode) { 14022 setIsStrictModeForDevtools(true); 14023 14024 try { 14025 // Invoke the function an extra time to help detect side-effects. 14026 partialState = getDerivedStateFromProps(nextProps, prevState); 14027 } finally { 14028 setIsStrictModeForDevtools(false); 14029 } 14030 } 14031 14032 warnOnUndefinedDerivedState(ctor, partialState); 14033 } // Merge the partial state and the previous state. 14034 14035 14036 var memoizedState = partialState === null || partialState === undefined ? prevState : assign({}, prevState, partialState); 14037 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the 14038 // base state. 14039 14040 if (workInProgress.lanes === NoLanes) { 14041 // Queue is always non-null for classes 14042 var updateQueue = workInProgress.updateQueue; 14043 updateQueue.baseState = memoizedState; 14044 } 14045} 14046 14047var classComponentUpdater = { 14048 isMounted: isMounted, 14049 enqueueSetState: function (inst, payload, callback) { 14050 var fiber = get(inst); 14051 var eventTime = requestEventTime(); 14052 var lane = requestUpdateLane(fiber); 14053 var update = createUpdate(eventTime, lane); 14054 update.payload = payload; 14055 14056 if (callback !== undefined && callback !== null) { 14057 { 14058 warnOnInvalidCallback(callback, 'setState'); 14059 } 14060 14061 update.callback = callback; 14062 } 14063 14064 var root = enqueueUpdate(fiber, update, lane); 14065 14066 if (root !== null) { 14067 scheduleUpdateOnFiber(root, fiber, lane, eventTime); 14068 entangleTransitions(root, fiber, lane); 14069 } 14070 14071 { 14072 markStateUpdateScheduled(fiber, lane); 14073 } 14074 }, 14075 enqueueReplaceState: function (inst, payload, callback) { 14076 var fiber = get(inst); 14077 var eventTime = requestEventTime(); 14078 var lane = requestUpdateLane(fiber); 14079 var update = createUpdate(eventTime, lane); 14080 update.tag = ReplaceState; 14081 update.payload = payload; 14082 14083 if (callback !== undefined && callback !== null) { 14084 { 14085 warnOnInvalidCallback(callback, 'replaceState'); 14086 } 14087 14088 update.callback = callback; 14089 } 14090 14091 var root = enqueueUpdate(fiber, update, lane); 14092 14093 if (root !== null) { 14094 scheduleUpdateOnFiber(root, fiber, lane, eventTime); 14095 entangleTransitions(root, fiber, lane); 14096 } 14097 14098 { 14099 markStateUpdateScheduled(fiber, lane); 14100 } 14101 }, 14102 enqueueForceUpdate: function (inst, callback) { 14103 var fiber = get(inst); 14104 var eventTime = requestEventTime(); 14105 var lane = requestUpdateLane(fiber); 14106 var update = createUpdate(eventTime, lane); 14107 update.tag = ForceUpdate; 14108 14109 if (callback !== undefined && callback !== null) { 14110 { 14111 warnOnInvalidCallback(callback, 'forceUpdate'); 14112 } 14113 14114 update.callback = callback; 14115 } 14116 14117 var root = enqueueUpdate(fiber, update, lane); 14118 14119 if (root !== null) { 14120 scheduleUpdateOnFiber(root, fiber, lane, eventTime); 14121 entangleTransitions(root, fiber, lane); 14122 } 14123 14124 { 14125 markForceUpdateScheduled(fiber, lane); 14126 } 14127 } 14128}; 14129 14130function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) { 14131 var instance = workInProgress.stateNode; 14132 14133 if (typeof instance.shouldComponentUpdate === 'function') { 14134 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext); 14135 14136 { 14137 if ( workInProgress.mode & StrictLegacyMode) { 14138 setIsStrictModeForDevtools(true); 14139 14140 try { 14141 // Invoke the function an extra time to help detect side-effects. 14142 shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext); 14143 } finally { 14144 setIsStrictModeForDevtools(false); 14145 } 14146 } 14147 14148 if (shouldUpdate === undefined) { 14149 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentNameFromType(ctor) || 'Component'); 14150 } 14151 } 14152 14153 return shouldUpdate; 14154 } 14155 14156 if (ctor.prototype && ctor.prototype.isPureReactComponent) { 14157 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState); 14158 } 14159 14160 return true; 14161} 14162 14163function checkClassInstance(workInProgress, ctor, newProps) { 14164 var instance = workInProgress.stateNode; 14165 14166 { 14167 var name = getComponentNameFromType(ctor) || 'Component'; 14168 var renderPresent = instance.render; 14169 14170 if (!renderPresent) { 14171 if (ctor.prototype && typeof ctor.prototype.render === 'function') { 14172 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name); 14173 } else { 14174 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name); 14175 } 14176 } 14177 14178 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) { 14179 error('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); 14180 } 14181 14182 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) { 14183 error('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); 14184 } 14185 14186 if (instance.propTypes) { 14187 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name); 14188 } 14189 14190 if (instance.contextType) { 14191 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name); 14192 } 14193 14194 { 14195 if (instance.contextTypes) { 14196 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name); 14197 } 14198 14199 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) { 14200 didWarnAboutContextTypeAndContextTypes.add(ctor); 14201 14202 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name); 14203 } 14204 } 14205 14206 if (typeof instance.componentShouldUpdate === 'function') { 14207 error('%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); 14208 } 14209 14210 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') { 14211 error('%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentNameFromType(ctor) || 'A pure component'); 14212 } 14213 14214 if (typeof instance.componentDidUnmount === 'function') { 14215 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name); 14216 } 14217 14218 if (typeof instance.componentDidReceiveProps === 'function') { 14219 error('%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); 14220 } 14221 14222 if (typeof instance.componentWillRecieveProps === 'function') { 14223 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name); 14224 } 14225 14226 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') { 14227 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name); 14228 } 14229 14230 var hasMutatedProps = instance.props !== newProps; 14231 14232 if (instance.props !== undefined && hasMutatedProps) { 14233 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name); 14234 } 14235 14236 if (instance.defaultProps) { 14237 error('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); 14238 } 14239 14240 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) { 14241 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); 14242 14243 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentNameFromType(ctor)); 14244 } 14245 14246 if (typeof instance.getDerivedStateFromProps === 'function') { 14247 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name); 14248 } 14249 14250 if (typeof instance.getDerivedStateFromError === 'function') { 14251 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name); 14252 } 14253 14254 if (typeof ctor.getSnapshotBeforeUpdate === 'function') { 14255 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name); 14256 } 14257 14258 var _state = instance.state; 14259 14260 if (_state && (typeof _state !== 'object' || isArray(_state))) { 14261 error('%s.state: must be set to an object or null', name); 14262 } 14263 14264 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') { 14265 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name); 14266 } 14267 } 14268} 14269 14270function adoptClassInstance(workInProgress, instance) { 14271 instance.updater = classComponentUpdater; 14272 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates 14273 14274 set(instance, workInProgress); 14275 14276 { 14277 instance._reactInternalInstance = fakeInternalInstance; 14278 } 14279} 14280 14281function constructClassInstance(workInProgress, ctor, props) { 14282 var isLegacyContextConsumer = false; 14283 var unmaskedContext = emptyContextObject; 14284 var context = emptyContextObject; 14285 var contextType = ctor.contextType; 14286 14287 { 14288 if ('contextType' in ctor) { 14289 var isValid = // Allow null for conditional declaration 14290 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer> 14291 14292 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) { 14293 didWarnAboutInvalidateContextType.add(ctor); 14294 var addendum = ''; 14295 14296 if (contextType === undefined) { 14297 addendum = ' However, it is set to undefined. ' + 'This can be caused by a typo or by mixing up named and default imports. ' + 'This can also happen due to a circular dependency, so ' + 'try moving the createContext() call to a separate file.'; 14298 } else if (typeof contextType !== 'object') { 14299 addendum = ' However, it is set to a ' + typeof contextType + '.'; 14300 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) { 14301 addendum = ' Did you accidentally pass the Context.Provider instead?'; 14302 } else if (contextType._context !== undefined) { 14303 // <Context.Consumer> 14304 addendum = ' Did you accidentally pass the Context.Consumer instead?'; 14305 } else { 14306 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.'; 14307 } 14308 14309 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentNameFromType(ctor) || 'Component', addendum); 14310 } 14311 } 14312 } 14313 14314 if (typeof contextType === 'object' && contextType !== null) { 14315 context = readContext(contextType); 14316 } else { 14317 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); 14318 var contextTypes = ctor.contextTypes; 14319 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined; 14320 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject; 14321 } 14322 14323 var instance = new ctor(props, context); // Instantiate twice to help detect side-effects. 14324 14325 { 14326 if ( workInProgress.mode & StrictLegacyMode) { 14327 setIsStrictModeForDevtools(true); 14328 14329 try { 14330 instance = new ctor(props, context); // eslint-disable-line no-new 14331 } finally { 14332 setIsStrictModeForDevtools(false); 14333 } 14334 } 14335 } 14336 14337 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null; 14338 adoptClassInstance(workInProgress, instance); 14339 14340 { 14341 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) { 14342 var componentName = getComponentNameFromType(ctor) || 'Component'; 14343 14344 if (!didWarnAboutUninitializedState.has(componentName)) { 14345 didWarnAboutUninitializedState.add(componentName); 14346 14347 error('`%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); 14348 } 14349 } // If new component APIs are defined, "unsafe" lifecycles won't be called. 14350 // Warn about these lifecycles if they are present. 14351 // Don't warn about react-lifecycles-compat polyfilled methods though. 14352 14353 14354 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') { 14355 var foundWillMountName = null; 14356 var foundWillReceivePropsName = null; 14357 var foundWillUpdateName = null; 14358 14359 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) { 14360 foundWillMountName = 'componentWillMount'; 14361 } else if (typeof instance.UNSAFE_componentWillMount === 'function') { 14362 foundWillMountName = 'UNSAFE_componentWillMount'; 14363 } 14364 14365 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) { 14366 foundWillReceivePropsName = 'componentWillReceiveProps'; 14367 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') { 14368 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps'; 14369 } 14370 14371 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) { 14372 foundWillUpdateName = 'componentWillUpdate'; 14373 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') { 14374 foundWillUpdateName = 'UNSAFE_componentWillUpdate'; 14375 } 14376 14377 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) { 14378 var _componentName = getComponentNameFromType(ctor) || 'Component'; 14379 14380 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()'; 14381 14382 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) { 14383 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); 14384 14385 error('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://reactjs.org/link/unsafe-component-lifecycles', _componentName, newApiName, foundWillMountName !== null ? "\n " + foundWillMountName : '', foundWillReceivePropsName !== null ? "\n " + foundWillReceivePropsName : '', foundWillUpdateName !== null ? "\n " + foundWillUpdateName : ''); 14386 } 14387 } 14388 } 14389 } // Cache unmasked context so we can avoid recreating masked context unless necessary. 14390 // ReactFiberContext usually updates this cache but can't for newly-created instances. 14391 14392 14393 if (isLegacyContextConsumer) { 14394 cacheContext(workInProgress, unmaskedContext, context); 14395 } 14396 14397 return instance; 14398} 14399 14400function callComponentWillMount(workInProgress, instance) { 14401 var oldState = instance.state; 14402 14403 if (typeof instance.componentWillMount === 'function') { 14404 instance.componentWillMount(); 14405 } 14406 14407 if (typeof instance.UNSAFE_componentWillMount === 'function') { 14408 instance.UNSAFE_componentWillMount(); 14409 } 14410 14411 if (oldState !== instance.state) { 14412 { 14413 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentNameFromFiber(workInProgress) || 'Component'); 14414 } 14415 14416 classComponentUpdater.enqueueReplaceState(instance, instance.state, null); 14417 } 14418} 14419 14420function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) { 14421 var oldState = instance.state; 14422 14423 if (typeof instance.componentWillReceiveProps === 'function') { 14424 instance.componentWillReceiveProps(newProps, nextContext); 14425 } 14426 14427 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') { 14428 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext); 14429 } 14430 14431 if (instance.state !== oldState) { 14432 { 14433 var componentName = getComponentNameFromFiber(workInProgress) || 'Component'; 14434 14435 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { 14436 didWarnAboutStateAssignmentForComponent.add(componentName); 14437 14438 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName); 14439 } 14440 } 14441 14442 classComponentUpdater.enqueueReplaceState(instance, instance.state, null); 14443 } 14444} // Invokes the mount life-cycles on a previously never rendered instance. 14445 14446 14447function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { 14448 { 14449 checkClassInstance(workInProgress, ctor, newProps); 14450 } 14451 14452 var instance = workInProgress.stateNode; 14453 instance.props = newProps; 14454 instance.state = workInProgress.memoizedState; 14455 instance.refs = emptyRefsObject; 14456 initializeUpdateQueue(workInProgress); 14457 var contextType = ctor.contextType; 14458 14459 if (typeof contextType === 'object' && contextType !== null) { 14460 instance.context = readContext(contextType); 14461 } else { 14462 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); 14463 instance.context = getMaskedContext(workInProgress, unmaskedContext); 14464 } 14465 14466 { 14467 if (instance.state === newProps) { 14468 var componentName = getComponentNameFromType(ctor) || 'Component'; 14469 14470 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { 14471 didWarnAboutDirectlyAssigningPropsToState.add(componentName); 14472 14473 error('%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); 14474 } 14475 } 14476 14477 if (workInProgress.mode & StrictLegacyMode) { 14478 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance); 14479 } 14480 14481 { 14482 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance); 14483 } 14484 } 14485 14486 instance.state = workInProgress.memoizedState; 14487 var getDerivedStateFromProps = ctor.getDerivedStateFromProps; 14488 14489 if (typeof getDerivedStateFromProps === 'function') { 14490 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps); 14491 instance.state = workInProgress.memoizedState; 14492 } // In order to support react-lifecycles-compat polyfilled components, 14493 // Unsafe lifecycles should not be invoked for components using the new APIs. 14494 14495 14496 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) { 14497 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's 14498 // process them now. 14499 14500 processUpdateQueue(workInProgress, newProps, instance, renderLanes); 14501 instance.state = workInProgress.memoizedState; 14502 } 14503 14504 if (typeof instance.componentDidMount === 'function') { 14505 var fiberFlags = Update; 14506 14507 { 14508 fiberFlags |= LayoutStatic; 14509 } 14510 14511 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) { 14512 fiberFlags |= MountLayoutDev; 14513 } 14514 14515 workInProgress.flags |= fiberFlags; 14516 } 14517} 14518 14519function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { 14520 var instance = workInProgress.stateNode; 14521 var oldProps = workInProgress.memoizedProps; 14522 instance.props = oldProps; 14523 var oldContext = instance.context; 14524 var contextType = ctor.contextType; 14525 var nextContext = emptyContextObject; 14526 14527 if (typeof contextType === 'object' && contextType !== null) { 14528 nextContext = readContext(contextType); 14529 } else { 14530 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); 14531 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext); 14532 } 14533 14534 var getDerivedStateFromProps = ctor.getDerivedStateFromProps; 14535 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what 14536 // ever the previously attempted to render - not the "current". However, 14537 // during componentDidUpdate we pass the "current" props. 14538 // In order to support react-lifecycles-compat polyfilled components, 14539 // Unsafe lifecycles should not be invoked for components using the new APIs. 14540 14541 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) { 14542 if (oldProps !== newProps || oldContext !== nextContext) { 14543 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext); 14544 } 14545 } 14546 14547 resetHasForceUpdateBeforeProcessing(); 14548 var oldState = workInProgress.memoizedState; 14549 var newState = instance.state = oldState; 14550 processUpdateQueue(workInProgress, newProps, instance, renderLanes); 14551 newState = workInProgress.memoizedState; 14552 14553 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) { 14554 // If an update was already in progress, we should schedule an Update 14555 // effect even though we're bailing out, so that cWU/cDU are called. 14556 if (typeof instance.componentDidMount === 'function') { 14557 var fiberFlags = Update; 14558 14559 { 14560 fiberFlags |= LayoutStatic; 14561 } 14562 14563 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) { 14564 fiberFlags |= MountLayoutDev; 14565 } 14566 14567 workInProgress.flags |= fiberFlags; 14568 } 14569 14570 return false; 14571 } 14572 14573 if (typeof getDerivedStateFromProps === 'function') { 14574 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps); 14575 newState = workInProgress.memoizedState; 14576 } 14577 14578 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext); 14579 14580 if (shouldUpdate) { 14581 // In order to support react-lifecycles-compat polyfilled components, 14582 // Unsafe lifecycles should not be invoked for components using the new APIs. 14583 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) { 14584 if (typeof instance.componentWillMount === 'function') { 14585 instance.componentWillMount(); 14586 } 14587 14588 if (typeof instance.UNSAFE_componentWillMount === 'function') { 14589 instance.UNSAFE_componentWillMount(); 14590 } 14591 } 14592 14593 if (typeof instance.componentDidMount === 'function') { 14594 var _fiberFlags = Update; 14595 14596 { 14597 _fiberFlags |= LayoutStatic; 14598 } 14599 14600 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) { 14601 _fiberFlags |= MountLayoutDev; 14602 } 14603 14604 workInProgress.flags |= _fiberFlags; 14605 } 14606 } else { 14607 // If an update was already in progress, we should schedule an Update 14608 // effect even though we're bailing out, so that cWU/cDU are called. 14609 if (typeof instance.componentDidMount === 'function') { 14610 var _fiberFlags2 = Update; 14611 14612 { 14613 _fiberFlags2 |= LayoutStatic; 14614 } 14615 14616 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) { 14617 _fiberFlags2 |= MountLayoutDev; 14618 } 14619 14620 workInProgress.flags |= _fiberFlags2; 14621 } // If shouldComponentUpdate returned false, we should still update the 14622 // memoized state to indicate that this work can be reused. 14623 14624 14625 workInProgress.memoizedProps = newProps; 14626 workInProgress.memoizedState = newState; 14627 } // Update the existing instance's state, props, and context pointers even 14628 // if shouldComponentUpdate returns false. 14629 14630 14631 instance.props = newProps; 14632 instance.state = newState; 14633 instance.context = nextContext; 14634 return shouldUpdate; 14635} // Invokes the update life-cycles and returns false if it shouldn't rerender. 14636 14637 14638function updateClassInstance(current, workInProgress, ctor, newProps, renderLanes) { 14639 var instance = workInProgress.stateNode; 14640 cloneUpdateQueue(current, workInProgress); 14641 var unresolvedOldProps = workInProgress.memoizedProps; 14642 var oldProps = workInProgress.type === workInProgress.elementType ? unresolvedOldProps : resolveDefaultProps(workInProgress.type, unresolvedOldProps); 14643 instance.props = oldProps; 14644 var unresolvedNewProps = workInProgress.pendingProps; 14645 var oldContext = instance.context; 14646 var contextType = ctor.contextType; 14647 var nextContext = emptyContextObject; 14648 14649 if (typeof contextType === 'object' && contextType !== null) { 14650 nextContext = readContext(contextType); 14651 } else { 14652 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); 14653 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext); 14654 } 14655 14656 var getDerivedStateFromProps = ctor.getDerivedStateFromProps; 14657 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what 14658 // ever the previously attempted to render - not the "current". However, 14659 // during componentDidUpdate we pass the "current" props. 14660 // In order to support react-lifecycles-compat polyfilled components, 14661 // Unsafe lifecycles should not be invoked for components using the new APIs. 14662 14663 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) { 14664 if (unresolvedOldProps !== unresolvedNewProps || oldContext !== nextContext) { 14665 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext); 14666 } 14667 } 14668 14669 resetHasForceUpdateBeforeProcessing(); 14670 var oldState = workInProgress.memoizedState; 14671 var newState = instance.state = oldState; 14672 processUpdateQueue(workInProgress, newProps, instance, renderLanes); 14673 newState = workInProgress.memoizedState; 14674 14675 if (unresolvedOldProps === unresolvedNewProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing() && !(enableLazyContextPropagation )) { 14676 // If an update was already in progress, we should schedule an Update 14677 // effect even though we're bailing out, so that cWU/cDU are called. 14678 if (typeof instance.componentDidUpdate === 'function') { 14679 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) { 14680 workInProgress.flags |= Update; 14681 } 14682 } 14683 14684 if (typeof instance.getSnapshotBeforeUpdate === 'function') { 14685 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) { 14686 workInProgress.flags |= Snapshot; 14687 } 14688 } 14689 14690 return false; 14691 } 14692 14693 if (typeof getDerivedStateFromProps === 'function') { 14694 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps); 14695 newState = workInProgress.memoizedState; 14696 } 14697 14698 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) || // TODO: In some cases, we'll end up checking if context has changed twice, 14699 // both before and after `shouldComponentUpdate` has been called. Not ideal, 14700 // but I'm loath to refactor this function. This only happens for memoized 14701 // components so it's not that common. 14702 enableLazyContextPropagation ; 14703 14704 if (shouldUpdate) { 14705 // In order to support react-lifecycles-compat polyfilled components, 14706 // Unsafe lifecycles should not be invoked for components using the new APIs. 14707 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) { 14708 if (typeof instance.componentWillUpdate === 'function') { 14709 instance.componentWillUpdate(newProps, newState, nextContext); 14710 } 14711 14712 if (typeof instance.UNSAFE_componentWillUpdate === 'function') { 14713 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext); 14714 } 14715 } 14716 14717 if (typeof instance.componentDidUpdate === 'function') { 14718 workInProgress.flags |= Update; 14719 } 14720 14721 if (typeof instance.getSnapshotBeforeUpdate === 'function') { 14722 workInProgress.flags |= Snapshot; 14723 } 14724 } else { 14725 // If an update was already in progress, we should schedule an Update 14726 // effect even though we're bailing out, so that cWU/cDU are called. 14727 if (typeof instance.componentDidUpdate === 'function') { 14728 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) { 14729 workInProgress.flags |= Update; 14730 } 14731 } 14732 14733 if (typeof instance.getSnapshotBeforeUpdate === 'function') { 14734 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) { 14735 workInProgress.flags |= Snapshot; 14736 } 14737 } // If shouldComponentUpdate returned false, we should still update the 14738 // memoized props/state to indicate that this work can be reused. 14739 14740 14741 workInProgress.memoizedProps = newProps; 14742 workInProgress.memoizedState = newState; 14743 } // Update the existing instance's state, props, and context pointers even 14744 // if shouldComponentUpdate returns false. 14745 14746 14747 instance.props = newProps; 14748 instance.state = newState; 14749 instance.context = nextContext; 14750 return shouldUpdate; 14751} 14752 14753var didWarnAboutMaps; 14754var didWarnAboutGenerators; 14755var didWarnAboutStringRefs; 14756var ownerHasKeyUseWarning; 14757var ownerHasFunctionTypeWarning; 14758 14759var warnForMissingKey = function (child, returnFiber) {}; 14760 14761{ 14762 didWarnAboutMaps = false; 14763 didWarnAboutGenerators = false; 14764 didWarnAboutStringRefs = {}; 14765 /** 14766 * Warn if there's no key explicitly set on dynamic arrays of children or 14767 * object keys are not valid. This allows us to keep track of children between 14768 * updates. 14769 */ 14770 14771 ownerHasKeyUseWarning = {}; 14772 ownerHasFunctionTypeWarning = {}; 14773 14774 warnForMissingKey = function (child, returnFiber) { 14775 if (child === null || typeof child !== 'object') { 14776 return; 14777 } 14778 14779 if (!child._store || child._store.validated || child.key != null) { 14780 return; 14781 } 14782 14783 if (typeof child._store !== 'object') { 14784 throw new Error('React Component in warnForMissingKey should have a _store. ' + 'This error is likely caused by a bug in React. Please file an issue.'); 14785 } 14786 14787 child._store.validated = true; 14788 var componentName = getComponentNameFromFiber(returnFiber) || 'Component'; 14789 14790 if (ownerHasKeyUseWarning[componentName]) { 14791 return; 14792 } 14793 14794 ownerHasKeyUseWarning[componentName] = true; 14795 14796 error('Each child in a list should have a unique ' + '"key" prop. See https://reactjs.org/link/warning-keys for ' + 'more information.'); 14797 }; 14798} 14799 14800function coerceRef(returnFiber, current, element) { 14801 var mixedRef = element.ref; 14802 14803 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') { 14804 { 14805 // TODO: Clean this up once we turn on the string ref warning for 14806 // everyone, because the strict mode case will no longer be relevant 14807 if ((returnFiber.mode & StrictLegacyMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs 14808 // because these cannot be automatically converted to an arrow function 14809 // using a codemod. Therefore, we don't have to warn about string refs again. 14810 !(element._owner && element._self && element._owner.stateNode !== element._self)) { 14811 var componentName = getComponentNameFromFiber(returnFiber) || 'Component'; 14812 14813 if (!didWarnAboutStringRefs[componentName]) { 14814 { 14815 error('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 useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-string-ref', mixedRef); 14816 } 14817 14818 didWarnAboutStringRefs[componentName] = true; 14819 } 14820 } 14821 } 14822 14823 if (element._owner) { 14824 var owner = element._owner; 14825 var inst; 14826 14827 if (owner) { 14828 var ownerFiber = owner; 14829 14830 if (ownerFiber.tag !== ClassComponent) { 14831 throw new Error('Function components cannot have string refs. ' + 'We recommend using useRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-string-ref'); 14832 } 14833 14834 inst = ownerFiber.stateNode; 14835 } 14836 14837 if (!inst) { 14838 throw new Error("Missing owner for string ref " + mixedRef + ". This error is likely caused by a " + 'bug in React. Please file an issue.'); 14839 } // Assigning this to a const so Flow knows it won't change in the closure 14840 14841 14842 var resolvedInst = inst; 14843 14844 { 14845 checkPropStringCoercion(mixedRef, 'ref'); 14846 } 14847 14848 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref 14849 14850 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) { 14851 return current.ref; 14852 } 14853 14854 var ref = function (value) { 14855 var refs = resolvedInst.refs; 14856 14857 if (refs === emptyRefsObject) { 14858 // This is a lazy pooled frozen object, so we need to initialize. 14859 refs = resolvedInst.refs = {}; 14860 } 14861 14862 if (value === null) { 14863 delete refs[stringRef]; 14864 } else { 14865 refs[stringRef] = value; 14866 } 14867 }; 14868 14869 ref._stringRef = stringRef; 14870 return ref; 14871 } else { 14872 if (typeof mixedRef !== 'string') { 14873 throw new Error('Expected ref to be a function, a string, an object returned by React.createRef(), or null.'); 14874 } 14875 14876 if (!element._owner) { 14877 throw new Error("Element ref was specified as a string (" + mixedRef + ") but no owner was set. This could happen for one of" + ' the following reasons:\n' + '1. You may be adding a ref to a function component\n' + "2. You may be adding a ref to a component that was not created inside a component's render method\n" + '3. You have multiple copies of React loaded\n' + 'See https://reactjs.org/link/refs-must-have-owner for more information.'); 14878 } 14879 } 14880 } 14881 14882 return mixedRef; 14883} 14884 14885function throwOnInvalidObjectType(returnFiber, newChild) { 14886 var childString = Object.prototype.toString.call(newChild); 14887 throw new Error("Objects are not valid as a React child (found: " + (childString === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : childString) + "). " + 'If you meant to render a collection of children, use an array ' + 'instead.'); 14888} 14889 14890function warnOnFunctionType(returnFiber) { 14891 { 14892 var componentName = getComponentNameFromFiber(returnFiber) || 'Component'; 14893 14894 if (ownerHasFunctionTypeWarning[componentName]) { 14895 return; 14896 } 14897 14898 ownerHasFunctionTypeWarning[componentName] = true; 14899 14900 error('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.'); 14901 } 14902} 14903 14904function resolveLazy(lazyType) { 14905 var payload = lazyType._payload; 14906 var init = lazyType._init; 14907 return init(payload); 14908} // This wrapper function exists because I expect to clone the code in each path 14909// to be able to optimize each path individually by branching early. This needs 14910// a compiler or we can do it manually. Helpers that don't need this branching 14911// live outside of this function. 14912 14913 14914function ChildReconciler(shouldTrackSideEffects) { 14915 function deleteChild(returnFiber, childToDelete) { 14916 if (!shouldTrackSideEffects) { 14917 // Noop. 14918 return; 14919 } 14920 14921 var deletions = returnFiber.deletions; 14922 14923 if (deletions === null) { 14924 returnFiber.deletions = [childToDelete]; 14925 returnFiber.flags |= ChildDeletion; 14926 } else { 14927 deletions.push(childToDelete); 14928 } 14929 } 14930 14931 function deleteRemainingChildren(returnFiber, currentFirstChild) { 14932 if (!shouldTrackSideEffects) { 14933 // Noop. 14934 return null; 14935 } // TODO: For the shouldClone case, this could be micro-optimized a bit by 14936 // assuming that after the first child we've already added everything. 14937 14938 14939 var childToDelete = currentFirstChild; 14940 14941 while (childToDelete !== null) { 14942 deleteChild(returnFiber, childToDelete); 14943 childToDelete = childToDelete.sibling; 14944 } 14945 14946 return null; 14947 } 14948 14949 function mapRemainingChildren(returnFiber, currentFirstChild) { 14950 // Add the remaining children to a temporary map so that we can find them by 14951 // keys quickly. Implicit (null) keys get added to this set with their index 14952 // instead. 14953 var existingChildren = new Map(); 14954 var existingChild = currentFirstChild; 14955 14956 while (existingChild !== null) { 14957 if (existingChild.key !== null) { 14958 existingChildren.set(existingChild.key, existingChild); 14959 } else { 14960 existingChildren.set(existingChild.index, existingChild); 14961 } 14962 14963 existingChild = existingChild.sibling; 14964 } 14965 14966 return existingChildren; 14967 } 14968 14969 function useFiber(fiber, pendingProps) { 14970 // We currently set sibling to null and index to 0 here because it is easy 14971 // to forget to do before returning it. E.g. for the single child case. 14972 var clone = createWorkInProgress(fiber, pendingProps); 14973 clone.index = 0; 14974 clone.sibling = null; 14975 return clone; 14976 } 14977 14978 function placeChild(newFiber, lastPlacedIndex, newIndex) { 14979 newFiber.index = newIndex; 14980 14981 if (!shouldTrackSideEffects) { 14982 // During hydration, the useId algorithm needs to know which fibers are 14983 // part of a list of children (arrays, iterators). 14984 newFiber.flags |= Forked; 14985 return lastPlacedIndex; 14986 } 14987 14988 var current = newFiber.alternate; 14989 14990 if (current !== null) { 14991 var oldIndex = current.index; 14992 14993 if (oldIndex < lastPlacedIndex) { 14994 // This is a move. 14995 newFiber.flags |= Placement; 14996 return lastPlacedIndex; 14997 } else { 14998 // This item can stay in place. 14999 return oldIndex; 15000 } 15001 } else { 15002 // This is an insertion. 15003 newFiber.flags |= Placement; 15004 return lastPlacedIndex; 15005 } 15006 } 15007 15008 function placeSingleChild(newFiber) { 15009 // This is simpler for the single child case. We only need to do a 15010 // placement for inserting new children. 15011 if (shouldTrackSideEffects && newFiber.alternate === null) { 15012 newFiber.flags |= Placement; 15013 } 15014 15015 return newFiber; 15016 } 15017 15018 function updateTextNode(returnFiber, current, textContent, lanes) { 15019 if (current === null || current.tag !== HostText) { 15020 // Insert 15021 var created = createFiberFromText(textContent, returnFiber.mode, lanes); 15022 created.return = returnFiber; 15023 return created; 15024 } else { 15025 // Update 15026 var existing = useFiber(current, textContent); 15027 existing.return = returnFiber; 15028 return existing; 15029 } 15030 } 15031 15032 function updateElement(returnFiber, current, element, lanes) { 15033 var elementType = element.type; 15034 15035 if (elementType === REACT_FRAGMENT_TYPE) { 15036 return updateFragment(returnFiber, current, element.props.children, lanes, element.key); 15037 } 15038 15039 if (current !== null) { 15040 if (current.elementType === elementType || ( // Keep this check inline so it only runs on the false path: 15041 isCompatibleFamilyForHotReloading(current, element) ) || // Lazy types should reconcile their resolved type. 15042 // We need to do this after the Hot Reloading check above, 15043 // because hot reloading has different semantics than prod because 15044 // it doesn't resuspend. So we can't let the call below suspend. 15045 typeof elementType === 'object' && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === current.type) { 15046 // Move based on index 15047 var existing = useFiber(current, element.props); 15048 existing.ref = coerceRef(returnFiber, current, element); 15049 existing.return = returnFiber; 15050 15051 { 15052 existing._debugSource = element._source; 15053 existing._debugOwner = element._owner; 15054 } 15055 15056 return existing; 15057 } 15058 } // Insert 15059 15060 15061 var created = createFiberFromElement(element, returnFiber.mode, lanes); 15062 created.ref = coerceRef(returnFiber, current, element); 15063 created.return = returnFiber; 15064 return created; 15065 } 15066 15067 function updatePortal(returnFiber, current, portal, lanes) { 15068 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) { 15069 // Insert 15070 var created = createFiberFromPortal(portal, returnFiber.mode, lanes); 15071 created.return = returnFiber; 15072 return created; 15073 } else { 15074 // Update 15075 var existing = useFiber(current, portal.children || []); 15076 existing.return = returnFiber; 15077 return existing; 15078 } 15079 } 15080 15081 function updateFragment(returnFiber, current, fragment, lanes, key) { 15082 if (current === null || current.tag !== Fragment) { 15083 // Insert 15084 var created = createFiberFromFragment(fragment, returnFiber.mode, lanes, key); 15085 created.return = returnFiber; 15086 return created; 15087 } else { 15088 // Update 15089 var existing = useFiber(current, fragment); 15090 existing.return = returnFiber; 15091 return existing; 15092 } 15093 } 15094 15095 function createChild(returnFiber, newChild, lanes) { 15096 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') { 15097 // Text nodes don't have keys. If the previous node is implicitly keyed 15098 // we can continue to replace it without aborting even if it is not a text 15099 // node. 15100 var created = createFiberFromText('' + newChild, returnFiber.mode, lanes); 15101 created.return = returnFiber; 15102 return created; 15103 } 15104 15105 if (typeof newChild === 'object' && newChild !== null) { 15106 switch (newChild.$$typeof) { 15107 case REACT_ELEMENT_TYPE: 15108 { 15109 var _created = createFiberFromElement(newChild, returnFiber.mode, lanes); 15110 15111 _created.ref = coerceRef(returnFiber, null, newChild); 15112 _created.return = returnFiber; 15113 return _created; 15114 } 15115 15116 case REACT_PORTAL_TYPE: 15117 { 15118 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, lanes); 15119 15120 _created2.return = returnFiber; 15121 return _created2; 15122 } 15123 15124 case REACT_LAZY_TYPE: 15125 { 15126 var payload = newChild._payload; 15127 var init = newChild._init; 15128 return createChild(returnFiber, init(payload), lanes); 15129 } 15130 } 15131 15132 if (isArray(newChild) || getIteratorFn(newChild)) { 15133 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, lanes, null); 15134 15135 _created3.return = returnFiber; 15136 return _created3; 15137 } 15138 15139 throwOnInvalidObjectType(returnFiber, newChild); 15140 } 15141 15142 { 15143 if (typeof newChild === 'function') { 15144 warnOnFunctionType(returnFiber); 15145 } 15146 } 15147 15148 return null; 15149 } 15150 15151 function updateSlot(returnFiber, oldFiber, newChild, lanes) { 15152 // Update the fiber if the keys match, otherwise return null. 15153 var key = oldFiber !== null ? oldFiber.key : null; 15154 15155 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') { 15156 // Text nodes don't have keys. If the previous node is implicitly keyed 15157 // we can continue to replace it without aborting even if it is not a text 15158 // node. 15159 if (key !== null) { 15160 return null; 15161 } 15162 15163 return updateTextNode(returnFiber, oldFiber, '' + newChild, lanes); 15164 } 15165 15166 if (typeof newChild === 'object' && newChild !== null) { 15167 switch (newChild.$$typeof) { 15168 case REACT_ELEMENT_TYPE: 15169 { 15170 if (newChild.key === key) { 15171 return updateElement(returnFiber, oldFiber, newChild, lanes); 15172 } else { 15173 return null; 15174 } 15175 } 15176 15177 case REACT_PORTAL_TYPE: 15178 { 15179 if (newChild.key === key) { 15180 return updatePortal(returnFiber, oldFiber, newChild, lanes); 15181 } else { 15182 return null; 15183 } 15184 } 15185 15186 case REACT_LAZY_TYPE: 15187 { 15188 var payload = newChild._payload; 15189 var init = newChild._init; 15190 return updateSlot(returnFiber, oldFiber, init(payload), lanes); 15191 } 15192 } 15193 15194 if (isArray(newChild) || getIteratorFn(newChild)) { 15195 if (key !== null) { 15196 return null; 15197 } 15198 15199 return updateFragment(returnFiber, oldFiber, newChild, lanes, null); 15200 } 15201 15202 throwOnInvalidObjectType(returnFiber, newChild); 15203 } 15204 15205 { 15206 if (typeof newChild === 'function') { 15207 warnOnFunctionType(returnFiber); 15208 } 15209 } 15210 15211 return null; 15212 } 15213 15214 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, lanes) { 15215 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') { 15216 // Text nodes don't have keys, so we neither have to check the old nor 15217 // new node for the key. If both are text nodes, they match. 15218 var matchedFiber = existingChildren.get(newIdx) || null; 15219 return updateTextNode(returnFiber, matchedFiber, '' + newChild, lanes); 15220 } 15221 15222 if (typeof newChild === 'object' && newChild !== null) { 15223 switch (newChild.$$typeof) { 15224 case REACT_ELEMENT_TYPE: 15225 { 15226 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null; 15227 15228 return updateElement(returnFiber, _matchedFiber, newChild, lanes); 15229 } 15230 15231 case REACT_PORTAL_TYPE: 15232 { 15233 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null; 15234 15235 return updatePortal(returnFiber, _matchedFiber2, newChild, lanes); 15236 } 15237 15238 case REACT_LAZY_TYPE: 15239 var payload = newChild._payload; 15240 var init = newChild._init; 15241 return updateFromMap(existingChildren, returnFiber, newIdx, init(payload), lanes); 15242 } 15243 15244 if (isArray(newChild) || getIteratorFn(newChild)) { 15245 var _matchedFiber3 = existingChildren.get(newIdx) || null; 15246 15247 return updateFragment(returnFiber, _matchedFiber3, newChild, lanes, null); 15248 } 15249 15250 throwOnInvalidObjectType(returnFiber, newChild); 15251 } 15252 15253 { 15254 if (typeof newChild === 'function') { 15255 warnOnFunctionType(returnFiber); 15256 } 15257 } 15258 15259 return null; 15260 } 15261 /** 15262 * Warns if there is a duplicate or missing key 15263 */ 15264 15265 15266 function warnOnInvalidKey(child, knownKeys, returnFiber) { 15267 { 15268 if (typeof child !== 'object' || child === null) { 15269 return knownKeys; 15270 } 15271 15272 switch (child.$$typeof) { 15273 case REACT_ELEMENT_TYPE: 15274 case REACT_PORTAL_TYPE: 15275 warnForMissingKey(child, returnFiber); 15276 var key = child.key; 15277 15278 if (typeof key !== 'string') { 15279 break; 15280 } 15281 15282 if (knownKeys === null) { 15283 knownKeys = new Set(); 15284 knownKeys.add(key); 15285 break; 15286 } 15287 15288 if (!knownKeys.has(key)) { 15289 knownKeys.add(key); 15290 break; 15291 } 15292 15293 error('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); 15294 15295 break; 15296 15297 case REACT_LAZY_TYPE: 15298 var payload = child._payload; 15299 var init = child._init; 15300 warnOnInvalidKey(init(payload), knownKeys, returnFiber); 15301 break; 15302 } 15303 } 15304 15305 return knownKeys; 15306 } 15307 15308 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, lanes) { 15309 // This algorithm can't optimize by searching from both ends since we 15310 // don't have backpointers on fibers. I'm trying to see how far we can get 15311 // with that model. If it ends up not being worth the tradeoffs, we can 15312 // add it later. 15313 // Even with a two ended optimization, we'd want to optimize for the case 15314 // where there are few changes and brute force the comparison instead of 15315 // going for the Map. It'd like to explore hitting that path first in 15316 // forward-only mode and only go for the Map once we notice that we need 15317 // lots of look ahead. This doesn't handle reversal as well as two ended 15318 // search but that's unusual. Besides, for the two ended optimization to 15319 // work on Iterables, we'd need to copy the whole set. 15320 // In this first iteration, we'll just live with hitting the bad case 15321 // (adding everything to a Map) in for every insert/move. 15322 // If you change this code, also update reconcileChildrenIterator() which 15323 // uses the same algorithm. 15324 { 15325 // First, validate keys. 15326 var knownKeys = null; 15327 15328 for (var i = 0; i < newChildren.length; i++) { 15329 var child = newChildren[i]; 15330 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber); 15331 } 15332 } 15333 15334 var resultingFirstChild = null; 15335 var previousNewFiber = null; 15336 var oldFiber = currentFirstChild; 15337 var lastPlacedIndex = 0; 15338 var newIdx = 0; 15339 var nextOldFiber = null; 15340 15341 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) { 15342 if (oldFiber.index > newIdx) { 15343 nextOldFiber = oldFiber; 15344 oldFiber = null; 15345 } else { 15346 nextOldFiber = oldFiber.sibling; 15347 } 15348 15349 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], lanes); 15350 15351 if (newFiber === null) { 15352 // TODO: This breaks on empty slots like null children. That's 15353 // unfortunate because it triggers the slow path all the time. We need 15354 // a better way to communicate whether this was a miss or null, 15355 // boolean, undefined, etc. 15356 if (oldFiber === null) { 15357 oldFiber = nextOldFiber; 15358 } 15359 15360 break; 15361 } 15362 15363 if (shouldTrackSideEffects) { 15364 if (oldFiber && newFiber.alternate === null) { 15365 // We matched the slot, but we didn't reuse the existing fiber, so we 15366 // need to delete the existing child. 15367 deleteChild(returnFiber, oldFiber); 15368 } 15369 } 15370 15371 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx); 15372 15373 if (previousNewFiber === null) { 15374 // TODO: Move out of the loop. This only happens for the first run. 15375 resultingFirstChild = newFiber; 15376 } else { 15377 // TODO: Defer siblings if we're not at the right index for this slot. 15378 // I.e. if we had null values before, then we want to defer this 15379 // for each null value. However, we also don't want to call updateSlot 15380 // with the previous one. 15381 previousNewFiber.sibling = newFiber; 15382 } 15383 15384 previousNewFiber = newFiber; 15385 oldFiber = nextOldFiber; 15386 } 15387 15388 if (newIdx === newChildren.length) { 15389 // We've reached the end of the new children. We can delete the rest. 15390 deleteRemainingChildren(returnFiber, oldFiber); 15391 15392 if (getIsHydrating()) { 15393 var numberOfForks = newIdx; 15394 pushTreeFork(returnFiber, numberOfForks); 15395 } 15396 15397 return resultingFirstChild; 15398 } 15399 15400 if (oldFiber === null) { 15401 // If we don't have any more existing children we can choose a fast path 15402 // since the rest will all be insertions. 15403 for (; newIdx < newChildren.length; newIdx++) { 15404 var _newFiber = createChild(returnFiber, newChildren[newIdx], lanes); 15405 15406 if (_newFiber === null) { 15407 continue; 15408 } 15409 15410 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx); 15411 15412 if (previousNewFiber === null) { 15413 // TODO: Move out of the loop. This only happens for the first run. 15414 resultingFirstChild = _newFiber; 15415 } else { 15416 previousNewFiber.sibling = _newFiber; 15417 } 15418 15419 previousNewFiber = _newFiber; 15420 } 15421 15422 if (getIsHydrating()) { 15423 var _numberOfForks = newIdx; 15424 pushTreeFork(returnFiber, _numberOfForks); 15425 } 15426 15427 return resultingFirstChild; 15428 } // Add all children to a key map for quick lookups. 15429 15430 15431 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves. 15432 15433 for (; newIdx < newChildren.length; newIdx++) { 15434 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes); 15435 15436 if (_newFiber2 !== null) { 15437 if (shouldTrackSideEffects) { 15438 if (_newFiber2.alternate !== null) { 15439 // The new fiber is a work in progress, but if there exists a 15440 // current, that means that we reused the fiber. We need to delete 15441 // it from the child list so that we don't add it to the deletion 15442 // list. 15443 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key); 15444 } 15445 } 15446 15447 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx); 15448 15449 if (previousNewFiber === null) { 15450 resultingFirstChild = _newFiber2; 15451 } else { 15452 previousNewFiber.sibling = _newFiber2; 15453 } 15454 15455 previousNewFiber = _newFiber2; 15456 } 15457 } 15458 15459 if (shouldTrackSideEffects) { 15460 // Any existing children that weren't consumed above were deleted. We need 15461 // to add them to the deletion list. 15462 existingChildren.forEach(function (child) { 15463 return deleteChild(returnFiber, child); 15464 }); 15465 } 15466 15467 if (getIsHydrating()) { 15468 var _numberOfForks2 = newIdx; 15469 pushTreeFork(returnFiber, _numberOfForks2); 15470 } 15471 15472 return resultingFirstChild; 15473 } 15474 15475 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, lanes) { 15476 // This is the same implementation as reconcileChildrenArray(), 15477 // but using the iterator instead. 15478 var iteratorFn = getIteratorFn(newChildrenIterable); 15479 15480 if (typeof iteratorFn !== 'function') { 15481 throw new Error('An object is not an iterable. This error is likely caused by a bug in ' + 'React. Please file an issue.'); 15482 } 15483 15484 { 15485 // We don't support rendering Generators because it's a mutation. 15486 // See https://github.com/facebook/react/issues/12995 15487 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag 15488 newChildrenIterable[Symbol.toStringTag] === 'Generator') { 15489 if (!didWarnAboutGenerators) { 15490 error('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.'); 15491 } 15492 15493 didWarnAboutGenerators = true; 15494 } // Warn about using Maps as children 15495 15496 15497 if (newChildrenIterable.entries === iteratorFn) { 15498 if (!didWarnAboutMaps) { 15499 error('Using Maps as children is not supported. ' + 'Use an array of keyed ReactElements instead.'); 15500 } 15501 15502 didWarnAboutMaps = true; 15503 } // First, validate keys. 15504 // We'll get a different iterator later for the main pass. 15505 15506 15507 var _newChildren = iteratorFn.call(newChildrenIterable); 15508 15509 if (_newChildren) { 15510 var knownKeys = null; 15511 15512 var _step = _newChildren.next(); 15513 15514 for (; !_step.done; _step = _newChildren.next()) { 15515 var child = _step.value; 15516 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber); 15517 } 15518 } 15519 } 15520 15521 var newChildren = iteratorFn.call(newChildrenIterable); 15522 15523 if (newChildren == null) { 15524 throw new Error('An iterable object provided no iterator.'); 15525 } 15526 15527 var resultingFirstChild = null; 15528 var previousNewFiber = null; 15529 var oldFiber = currentFirstChild; 15530 var lastPlacedIndex = 0; 15531 var newIdx = 0; 15532 var nextOldFiber = null; 15533 var step = newChildren.next(); 15534 15535 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) { 15536 if (oldFiber.index > newIdx) { 15537 nextOldFiber = oldFiber; 15538 oldFiber = null; 15539 } else { 15540 nextOldFiber = oldFiber.sibling; 15541 } 15542 15543 var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes); 15544 15545 if (newFiber === null) { 15546 // TODO: This breaks on empty slots like null children. That's 15547 // unfortunate because it triggers the slow path all the time. We need 15548 // a better way to communicate whether this was a miss or null, 15549 // boolean, undefined, etc. 15550 if (oldFiber === null) { 15551 oldFiber = nextOldFiber; 15552 } 15553 15554 break; 15555 } 15556 15557 if (shouldTrackSideEffects) { 15558 if (oldFiber && newFiber.alternate === null) { 15559 // We matched the slot, but we didn't reuse the existing fiber, so we 15560 // need to delete the existing child. 15561 deleteChild(returnFiber, oldFiber); 15562 } 15563 } 15564 15565 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx); 15566 15567 if (previousNewFiber === null) { 15568 // TODO: Move out of the loop. This only happens for the first run. 15569 resultingFirstChild = newFiber; 15570 } else { 15571 // TODO: Defer siblings if we're not at the right index for this slot. 15572 // I.e. if we had null values before, then we want to defer this 15573 // for each null value. However, we also don't want to call updateSlot 15574 // with the previous one. 15575 previousNewFiber.sibling = newFiber; 15576 } 15577 15578 previousNewFiber = newFiber; 15579 oldFiber = nextOldFiber; 15580 } 15581 15582 if (step.done) { 15583 // We've reached the end of the new children. We can delete the rest. 15584 deleteRemainingChildren(returnFiber, oldFiber); 15585 15586 if (getIsHydrating()) { 15587 var numberOfForks = newIdx; 15588 pushTreeFork(returnFiber, numberOfForks); 15589 } 15590 15591 return resultingFirstChild; 15592 } 15593 15594 if (oldFiber === null) { 15595 // If we don't have any more existing children we can choose a fast path 15596 // since the rest will all be insertions. 15597 for (; !step.done; newIdx++, step = newChildren.next()) { 15598 var _newFiber3 = createChild(returnFiber, step.value, lanes); 15599 15600 if (_newFiber3 === null) { 15601 continue; 15602 } 15603 15604 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx); 15605 15606 if (previousNewFiber === null) { 15607 // TODO: Move out of the loop. This only happens for the first run. 15608 resultingFirstChild = _newFiber3; 15609 } else { 15610 previousNewFiber.sibling = _newFiber3; 15611 } 15612 15613 previousNewFiber = _newFiber3; 15614 } 15615 15616 if (getIsHydrating()) { 15617 var _numberOfForks3 = newIdx; 15618 pushTreeFork(returnFiber, _numberOfForks3); 15619 } 15620 15621 return resultingFirstChild; 15622 } // Add all children to a key map for quick lookups. 15623 15624 15625 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves. 15626 15627 for (; !step.done; newIdx++, step = newChildren.next()) { 15628 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes); 15629 15630 if (_newFiber4 !== null) { 15631 if (shouldTrackSideEffects) { 15632 if (_newFiber4.alternate !== null) { 15633 // The new fiber is a work in progress, but if there exists a 15634 // current, that means that we reused the fiber. We need to delete 15635 // it from the child list so that we don't add it to the deletion 15636 // list. 15637 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key); 15638 } 15639 } 15640 15641 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx); 15642 15643 if (previousNewFiber === null) { 15644 resultingFirstChild = _newFiber4; 15645 } else { 15646 previousNewFiber.sibling = _newFiber4; 15647 } 15648 15649 previousNewFiber = _newFiber4; 15650 } 15651 } 15652 15653 if (shouldTrackSideEffects) { 15654 // Any existing children that weren't consumed above were deleted. We need 15655 // to add them to the deletion list. 15656 existingChildren.forEach(function (child) { 15657 return deleteChild(returnFiber, child); 15658 }); 15659 } 15660 15661 if (getIsHydrating()) { 15662 var _numberOfForks4 = newIdx; 15663 pushTreeFork(returnFiber, _numberOfForks4); 15664 } 15665 15666 return resultingFirstChild; 15667 } 15668 15669 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, lanes) { 15670 // There's no need to check for keys on text nodes since we don't have a 15671 // way to define them. 15672 if (currentFirstChild !== null && currentFirstChild.tag === HostText) { 15673 // We already have an existing node so let's just update it and delete 15674 // the rest. 15675 deleteRemainingChildren(returnFiber, currentFirstChild.sibling); 15676 var existing = useFiber(currentFirstChild, textContent); 15677 existing.return = returnFiber; 15678 return existing; 15679 } // The existing first child is not a text node so we need to create one 15680 // and delete the existing ones. 15681 15682 15683 deleteRemainingChildren(returnFiber, currentFirstChild); 15684 var created = createFiberFromText(textContent, returnFiber.mode, lanes); 15685 created.return = returnFiber; 15686 return created; 15687 } 15688 15689 function reconcileSingleElement(returnFiber, currentFirstChild, element, lanes) { 15690 var key = element.key; 15691 var child = currentFirstChild; 15692 15693 while (child !== null) { 15694 // TODO: If key === null and child.key === null, then this only applies to 15695 // the first item in the list. 15696 if (child.key === key) { 15697 var elementType = element.type; 15698 15699 if (elementType === REACT_FRAGMENT_TYPE) { 15700 if (child.tag === Fragment) { 15701 deleteRemainingChildren(returnFiber, child.sibling); 15702 var existing = useFiber(child, element.props.children); 15703 existing.return = returnFiber; 15704 15705 { 15706 existing._debugSource = element._source; 15707 existing._debugOwner = element._owner; 15708 } 15709 15710 return existing; 15711 } 15712 } else { 15713 if (child.elementType === elementType || ( // Keep this check inline so it only runs on the false path: 15714 isCompatibleFamilyForHotReloading(child, element) ) || // Lazy types should reconcile their resolved type. 15715 // We need to do this after the Hot Reloading check above, 15716 // because hot reloading has different semantics than prod because 15717 // it doesn't resuspend. So we can't let the call below suspend. 15718 typeof elementType === 'object' && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === child.type) { 15719 deleteRemainingChildren(returnFiber, child.sibling); 15720 15721 var _existing = useFiber(child, element.props); 15722 15723 _existing.ref = coerceRef(returnFiber, child, element); 15724 _existing.return = returnFiber; 15725 15726 { 15727 _existing._debugSource = element._source; 15728 _existing._debugOwner = element._owner; 15729 } 15730 15731 return _existing; 15732 } 15733 } // Didn't match. 15734 15735 15736 deleteRemainingChildren(returnFiber, child); 15737 break; 15738 } else { 15739 deleteChild(returnFiber, child); 15740 } 15741 15742 child = child.sibling; 15743 } 15744 15745 if (element.type === REACT_FRAGMENT_TYPE) { 15746 var created = createFiberFromFragment(element.props.children, returnFiber.mode, lanes, element.key); 15747 created.return = returnFiber; 15748 return created; 15749 } else { 15750 var _created4 = createFiberFromElement(element, returnFiber.mode, lanes); 15751 15752 _created4.ref = coerceRef(returnFiber, currentFirstChild, element); 15753 _created4.return = returnFiber; 15754 return _created4; 15755 } 15756 } 15757 15758 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, lanes) { 15759 var key = portal.key; 15760 var child = currentFirstChild; 15761 15762 while (child !== null) { 15763 // TODO: If key === null and child.key === null, then this only applies to 15764 // the first item in the list. 15765 if (child.key === key) { 15766 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) { 15767 deleteRemainingChildren(returnFiber, child.sibling); 15768 var existing = useFiber(child, portal.children || []); 15769 existing.return = returnFiber; 15770 return existing; 15771 } else { 15772 deleteRemainingChildren(returnFiber, child); 15773 break; 15774 } 15775 } else { 15776 deleteChild(returnFiber, child); 15777 } 15778 15779 child = child.sibling; 15780 } 15781 15782 var created = createFiberFromPortal(portal, returnFiber.mode, lanes); 15783 created.return = returnFiber; 15784 return created; 15785 } // This API will tag the children with the side-effect of the reconciliation 15786 // itself. They will be added to the side-effect list as we pass through the 15787 // children and the parent. 15788 15789 15790 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, lanes) { 15791 // This function is not recursive. 15792 // If the top level item is an array, we treat it as a set of children, 15793 // not as a fragment. Nested arrays on the other hand will be treated as 15794 // fragment nodes. Recursion happens at the normal flow. 15795 // Handle top level unkeyed fragments as if they were arrays. 15796 // This leads to an ambiguity between <>{[...]}</> and <>...</>. 15797 // We treat the ambiguous cases above the same. 15798 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null; 15799 15800 if (isUnkeyedTopLevelFragment) { 15801 newChild = newChild.props.children; 15802 } // Handle object types 15803 15804 15805 if (typeof newChild === 'object' && newChild !== null) { 15806 switch (newChild.$$typeof) { 15807 case REACT_ELEMENT_TYPE: 15808 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, lanes)); 15809 15810 case REACT_PORTAL_TYPE: 15811 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, lanes)); 15812 15813 case REACT_LAZY_TYPE: 15814 var payload = newChild._payload; 15815 var init = newChild._init; // TODO: This function is supposed to be non-recursive. 15816 15817 return reconcileChildFibers(returnFiber, currentFirstChild, init(payload), lanes); 15818 } 15819 15820 if (isArray(newChild)) { 15821 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, lanes); 15822 } 15823 15824 if (getIteratorFn(newChild)) { 15825 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, lanes); 15826 } 15827 15828 throwOnInvalidObjectType(returnFiber, newChild); 15829 } 15830 15831 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') { 15832 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, lanes)); 15833 } 15834 15835 { 15836 if (typeof newChild === 'function') { 15837 warnOnFunctionType(returnFiber); 15838 } 15839 } // Remaining cases are all treated as empty. 15840 15841 15842 return deleteRemainingChildren(returnFiber, currentFirstChild); 15843 } 15844 15845 return reconcileChildFibers; 15846} 15847 15848var reconcileChildFibers = ChildReconciler(true); 15849var mountChildFibers = ChildReconciler(false); 15850function cloneChildFibers(current, workInProgress) { 15851 if (current !== null && workInProgress.child !== current.child) { 15852 throw new Error('Resuming work not yet implemented.'); 15853 } 15854 15855 if (workInProgress.child === null) { 15856 return; 15857 } 15858 15859 var currentChild = workInProgress.child; 15860 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps); 15861 workInProgress.child = newChild; 15862 newChild.return = workInProgress; 15863 15864 while (currentChild.sibling !== null) { 15865 currentChild = currentChild.sibling; 15866 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps); 15867 newChild.return = workInProgress; 15868 } 15869 15870 newChild.sibling = null; 15871} // Reset a workInProgress child set to prepare it for a second pass. 15872 15873function resetChildFibers(workInProgress, lanes) { 15874 var child = workInProgress.child; 15875 15876 while (child !== null) { 15877 resetWorkInProgress(child, lanes); 15878 child = child.sibling; 15879 } 15880} 15881 15882var NO_CONTEXT = {}; 15883var contextStackCursor$1 = createCursor(NO_CONTEXT); 15884var contextFiberStackCursor = createCursor(NO_CONTEXT); 15885var rootInstanceStackCursor = createCursor(NO_CONTEXT); 15886 15887function requiredContext(c) { 15888 if (c === NO_CONTEXT) { 15889 throw new Error('Expected host context to exist. This error is likely caused by a bug ' + 'in React. Please file an issue.'); 15890 } 15891 15892 return c; 15893} 15894 15895function getRootHostContainer() { 15896 var rootInstance = requiredContext(rootInstanceStackCursor.current); 15897 return rootInstance; 15898} 15899 15900function pushHostContainer(fiber, nextRootInstance) { 15901 // Push current root instance onto the stack; 15902 // This allows us to reset root when portals are popped. 15903 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it. 15904 // This enables us to pop only Fibers that provide unique contexts. 15905 15906 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack. 15907 // However, we can't just call getRootHostContext() and push it because 15908 // we'd have a different number of entries on the stack depending on 15909 // whether getRootHostContext() throws somewhere in renderer code or not. 15910 // So we push an empty value first. This lets us safely unwind on errors. 15911 15912 push(contextStackCursor$1, NO_CONTEXT, fiber); 15913 var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it. 15914 15915 pop(contextStackCursor$1, fiber); 15916 push(contextStackCursor$1, nextRootContext, fiber); 15917} 15918 15919function popHostContainer(fiber) { 15920 pop(contextStackCursor$1, fiber); 15921 pop(contextFiberStackCursor, fiber); 15922 pop(rootInstanceStackCursor, fiber); 15923} 15924 15925function getHostContext() { 15926 var context = requiredContext(contextStackCursor$1.current); 15927 return context; 15928} 15929 15930function pushHostContext(fiber) { 15931 var rootInstance = requiredContext(rootInstanceStackCursor.current); 15932 var context = requiredContext(contextStackCursor$1.current); 15933 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique. 15934 15935 if (context === nextContext) { 15936 return; 15937 } // Track the context and the Fiber that provided it. 15938 // This enables us to pop only Fibers that provide unique contexts. 15939 15940 15941 push(contextFiberStackCursor, fiber, fiber); 15942 push(contextStackCursor$1, nextContext, fiber); 15943} 15944 15945function popHostContext(fiber) { 15946 // Do not pop unless this Fiber provided the current context. 15947 // pushHostContext() only pushes Fibers that provide unique contexts. 15948 if (contextFiberStackCursor.current !== fiber) { 15949 return; 15950 } 15951 15952 pop(contextStackCursor$1, fiber); 15953 pop(contextFiberStackCursor, fiber); 15954} 15955 15956var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is 15957// inherited deeply down the subtree. The upper bits only affect 15958// this immediate suspense boundary and gets reset each new 15959// boundary or suspense list. 15960 15961var SubtreeSuspenseContextMask = 1; // Subtree Flags: 15962// InvisibleParentSuspenseContext indicates that one of our parent Suspense 15963// boundaries is not currently showing visible main content. 15964// Either because it is already showing a fallback or is not mounted at all. 15965// We can use this to determine if it is desirable to trigger a fallback at 15966// the parent. If not, then we might need to trigger undesirable boundaries 15967// and/or suspend the commit to avoid hiding the parent content. 15968 15969var InvisibleParentSuspenseContext = 1; // Shallow Flags: 15970// ForceSuspenseFallback can be used by SuspenseList to force newly added 15971// items into their fallback state during one of the render passes. 15972 15973var ForceSuspenseFallback = 2; 15974var suspenseStackCursor = createCursor(DefaultSuspenseContext); 15975function hasSuspenseContext(parentContext, flag) { 15976 return (parentContext & flag) !== 0; 15977} 15978function setDefaultShallowSuspenseContext(parentContext) { 15979 return parentContext & SubtreeSuspenseContextMask; 15980} 15981function setShallowSuspenseContext(parentContext, shallowContext) { 15982 return parentContext & SubtreeSuspenseContextMask | shallowContext; 15983} 15984function addSubtreeSuspenseContext(parentContext, subtreeContext) { 15985 return parentContext | subtreeContext; 15986} 15987function pushSuspenseContext(fiber, newContext) { 15988 push(suspenseStackCursor, newContext, fiber); 15989} 15990function popSuspenseContext(fiber) { 15991 pop(suspenseStackCursor, fiber); 15992} 15993 15994function shouldCaptureSuspense(workInProgress, hasInvisibleParent) { 15995 // If it was the primary children that just suspended, capture and render the 15996 // fallback. Otherwise, don't capture and bubble to the next boundary. 15997 var nextState = workInProgress.memoizedState; 15998 15999 if (nextState !== null) { 16000 if (nextState.dehydrated !== null) { 16001 // A dehydrated boundary always captures. 16002 return true; 16003 } 16004 16005 return false; 16006 } 16007 16008 var props = workInProgress.memoizedProps; // Regular boundaries always capture. 16009 16010 { 16011 return true; 16012 } // If it's a boundary we should avoid, then we prefer to bubble up to the 16013} 16014function findFirstSuspended(row) { 16015 var node = row; 16016 16017 while (node !== null) { 16018 if (node.tag === SuspenseComponent) { 16019 var state = node.memoizedState; 16020 16021 if (state !== null) { 16022 var dehydrated = state.dehydrated; 16023 16024 if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) { 16025 return node; 16026 } 16027 } 16028 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't 16029 // keep track of whether it suspended or not. 16030 node.memoizedProps.revealOrder !== undefined) { 16031 var didSuspend = (node.flags & DidCapture) !== NoFlags; 16032 16033 if (didSuspend) { 16034 return node; 16035 } 16036 } else if (node.child !== null) { 16037 node.child.return = node; 16038 node = node.child; 16039 continue; 16040 } 16041 16042 if (node === row) { 16043 return null; 16044 } 16045 16046 while (node.sibling === null) { 16047 if (node.return === null || node.return === row) { 16048 return null; 16049 } 16050 16051 node = node.return; 16052 } 16053 16054 node.sibling.return = node.return; 16055 node = node.sibling; 16056 } 16057 16058 return null; 16059} 16060 16061var NoFlags$1 = 16062/* */ 160630; // Represents whether effect should fire. 16064 16065var HasEffect = 16066/* */ 160671; // Represents the phase in which the effect (not the clean-up) fires. 16068 16069var Insertion = 16070/* */ 160712; 16072var Layout = 16073/* */ 160744; 16075var Passive$1 = 16076/* */ 160778; 16078 16079// and should be reset before starting a new render. 16080// This tracks which mutable sources need to be reset after a render. 16081 16082var workInProgressSources = []; 16083function resetWorkInProgressVersions() { 16084 for (var i = 0; i < workInProgressSources.length; i++) { 16085 var mutableSource = workInProgressSources[i]; 16086 16087 { 16088 mutableSource._workInProgressVersionPrimary = null; 16089 } 16090 } 16091 16092 workInProgressSources.length = 0; 16093} 16094// This ensures that the version used for server rendering matches the one 16095// that is eventually read during hydration. 16096// If they don't match there's a potential tear and a full deopt render is required. 16097 16098function registerMutableSourceForHydration(root, mutableSource) { 16099 var getVersion = mutableSource._getVersion; 16100 var version = getVersion(mutableSource._source); // TODO Clear this data once all pending hydration work is finished. 16101 // Retaining it forever may interfere with GC. 16102 16103 if (root.mutableSourceEagerHydrationData == null) { 16104 root.mutableSourceEagerHydrationData = [mutableSource, version]; 16105 } else { 16106 root.mutableSourceEagerHydrationData.push(mutableSource, version); 16107 } 16108} 16109 16110var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, 16111 ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig; 16112var didWarnAboutMismatchedHooksForComponent; 16113var didWarnUncachedGetSnapshot; 16114 16115{ 16116 didWarnAboutMismatchedHooksForComponent = new Set(); 16117} 16118 16119// These are set right before calling the component. 16120var renderLanes = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from 16121// the work-in-progress hook. 16122 16123var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The 16124// current hook list is the list that belongs to the current fiber. The 16125// work-in-progress hook list is a new list that will be added to the 16126// work-in-progress fiber. 16127 16128var currentHook = null; 16129var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This 16130// does not get reset if we do another render pass; only when we're completely 16131// finished evaluating this component. This is an optimization so we know 16132// whether we need to clear render phase updates after a throw. 16133 16134var didScheduleRenderPhaseUpdate = false; // Where an update was scheduled only during the current render pass. This 16135// gets reset after each attempt. 16136// TODO: Maybe there's some way to consolidate this with 16137// `didScheduleRenderPhaseUpdate`. Or with `numberOfReRenders`. 16138 16139var didScheduleRenderPhaseUpdateDuringThisPass = false; // Counts the number of useId hooks in this component. 16140 16141var localIdCounter = 0; // Used for ids that are generated completely client-side (i.e. not during 16142// hydration). This counter is global, so client ids are not stable across 16143// render attempts. 16144 16145var globalClientIdCounter = 0; 16146var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook 16147 16148var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders. 16149// The list stores the order of hooks used during the initial render (mount). 16150// Subsequent renders (updates) reference this list. 16151 16152var hookTypesDev = null; 16153var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore 16154// the dependencies for Hooks that need them (e.g. useEffect or useMemo). 16155// When true, such Hooks will always be "remounted". Only used during hot reload. 16156 16157var ignorePreviousDependencies = false; 16158 16159function mountHookTypesDev() { 16160 { 16161 var hookName = currentHookNameInDev; 16162 16163 if (hookTypesDev === null) { 16164 hookTypesDev = [hookName]; 16165 } else { 16166 hookTypesDev.push(hookName); 16167 } 16168 } 16169} 16170 16171function updateHookTypesDev() { 16172 { 16173 var hookName = currentHookNameInDev; 16174 16175 if (hookTypesDev !== null) { 16176 hookTypesUpdateIndexDev++; 16177 16178 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) { 16179 warnOnHookMismatchInDev(hookName); 16180 } 16181 } 16182 } 16183} 16184 16185function checkDepsAreArrayDev(deps) { 16186 { 16187 if (deps !== undefined && deps !== null && !isArray(deps)) { 16188 // Verify deps, but only on mount to avoid extra checks. 16189 // It's unlikely their type would change as usually you define them inline. 16190 error('%s received a final argument that is not an array (instead, received `%s`). When ' + 'specified, the final argument must be an array.', currentHookNameInDev, typeof deps); 16191 } 16192 } 16193} 16194 16195function warnOnHookMismatchInDev(currentHookName) { 16196 { 16197 var componentName = getComponentNameFromFiber(currentlyRenderingFiber$1); 16198 16199 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) { 16200 didWarnAboutMismatchedHooksForComponent.add(componentName); 16201 16202 if (hookTypesDev !== null) { 16203 var table = ''; 16204 var secondColumnStart = 30; 16205 16206 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) { 16207 var oldHookName = hookTypesDev[i]; 16208 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName; 16209 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up 16210 // lol @ IE not supporting String#repeat 16211 16212 while (row.length < secondColumnStart) { 16213 row += ' '; 16214 } 16215 16216 row += newHookName + '\n'; 16217 table += row; 16218 } 16219 16220 error('React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table); 16221 } 16222 } 16223 } 16224} 16225 16226function throwInvalidHookError() { 16227 throw new Error('Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + ' one of the following reasons:\n' + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + '2. You might be breaking the Rules of Hooks\n' + '3. You might have more than one copy of React in the same app\n' + 'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.'); 16228} 16229 16230function areHookInputsEqual(nextDeps, prevDeps) { 16231 { 16232 if (ignorePreviousDependencies) { 16233 // Only true when this component is being hot reloaded. 16234 return false; 16235 } 16236 } 16237 16238 if (prevDeps === null) { 16239 { 16240 error('%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev); 16241 } 16242 16243 return false; 16244 } 16245 16246 { 16247 // Don't bother comparing lengths in prod because these arrays should be 16248 // passed inline. 16249 if (nextDeps.length !== prevDeps.length) { 16250 error('The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, "[" + prevDeps.join(', ') + "]", "[" + nextDeps.join(', ') + "]"); 16251 } 16252 } 16253 16254 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { 16255 if (objectIs(nextDeps[i], prevDeps[i])) { 16256 continue; 16257 } 16258 16259 return false; 16260 } 16261 16262 return true; 16263} 16264 16265function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderLanes) { 16266 renderLanes = nextRenderLanes; 16267 currentlyRenderingFiber$1 = workInProgress; 16268 16269 { 16270 hookTypesDev = current !== null ? current._debugHookTypes : null; 16271 hookTypesUpdateIndexDev = -1; // Used for hot reloading: 16272 16273 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type; 16274 } 16275 16276 workInProgress.memoizedState = null; 16277 workInProgress.updateQueue = null; 16278 workInProgress.lanes = NoLanes; // The following should have already been reset 16279 // currentHook = null; 16280 // workInProgressHook = null; 16281 // didScheduleRenderPhaseUpdate = false; 16282 // localIdCounter = 0; 16283 // TODO Warn if no hooks are used at all during mount, then some are used during update. 16284 // Currently we will identify the update render as a mount because memoizedState === null. 16285 // This is tricky because it's valid for certain types of components (e.g. React.lazy) 16286 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used. 16287 // Non-stateful hooks (e.g. context) don't get added to memoizedState, 16288 // so memoizedState would be null during updates and mounts. 16289 16290 { 16291 if (current !== null && current.memoizedState !== null) { 16292 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; 16293 } else if (hookTypesDev !== null) { 16294 // This dispatcher handles an edge case where a component is updating, 16295 // but no stateful hooks have been used. 16296 // We want to match the production code behavior (which will use HooksDispatcherOnMount), 16297 // but with the extra DEV validation to ensure hooks ordering hasn't changed. 16298 // This dispatcher does that. 16299 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV; 16300 } else { 16301 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV; 16302 } 16303 } 16304 16305 var children = Component(props, secondArg); // Check if there was a render phase update 16306 16307 if (didScheduleRenderPhaseUpdateDuringThisPass) { 16308 // Keep rendering in a loop for as long as render phase updates continue to 16309 // be scheduled. Use a counter to prevent infinite loops. 16310 var numberOfReRenders = 0; 16311 16312 do { 16313 didScheduleRenderPhaseUpdateDuringThisPass = false; 16314 localIdCounter = 0; 16315 16316 if (numberOfReRenders >= RE_RENDER_LIMIT) { 16317 throw new Error('Too many re-renders. React limits the number of renders to prevent ' + 'an infinite loop.'); 16318 } 16319 16320 numberOfReRenders += 1; 16321 16322 { 16323 // Even when hot reloading, allow dependencies to stabilize 16324 // after first render to prevent infinite render phase updates. 16325 ignorePreviousDependencies = false; 16326 } // Start over from the beginning of the list 16327 16328 16329 currentHook = null; 16330 workInProgressHook = null; 16331 workInProgress.updateQueue = null; 16332 16333 { 16334 // Also validate hook order for cascading updates. 16335 hookTypesUpdateIndexDev = -1; 16336 } 16337 16338 ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV ; 16339 children = Component(props, secondArg); 16340 } while (didScheduleRenderPhaseUpdateDuringThisPass); 16341 } // We can assume the previous dispatcher is always this one, since we set it 16342 // at the beginning of the render phase and there's no re-entrance. 16343 16344 16345 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; 16346 16347 { 16348 workInProgress._debugHookTypes = hookTypesDev; 16349 } // This check uses currentHook so that it works the same in DEV and prod bundles. 16350 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles. 16351 16352 16353 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null; 16354 renderLanes = NoLanes; 16355 currentlyRenderingFiber$1 = null; 16356 currentHook = null; 16357 workInProgressHook = null; 16358 16359 { 16360 currentHookNameInDev = null; 16361 hookTypesDev = null; 16362 hookTypesUpdateIndexDev = -1; // Confirm that a static flag was not added or removed since the last 16363 // render. If this fires, it suggests that we incorrectly reset the static 16364 // flags in some other part of the codebase. This has happened before, for 16365 // example, in the SuspenseList implementation. 16366 16367 if (current !== null && (current.flags & StaticMask) !== (workInProgress.flags & StaticMask) && // Disable this warning in legacy mode, because legacy Suspense is weird 16368 // and creates false positives. To make this work in legacy mode, we'd 16369 // need to mark fibers that commit in an incomplete state, somehow. For 16370 // now I'll disable the warning that most of the bugs that would trigger 16371 // it are either exclusive to concurrent mode or exist in both. 16372 (current.mode & ConcurrentMode) !== NoMode) { 16373 error('Internal React error: Expected static flag was missing. Please ' + 'notify the React team.'); 16374 } 16375 } 16376 16377 didScheduleRenderPhaseUpdate = false; // This is reset by checkDidRenderIdHook 16378 // localIdCounter = 0; 16379 16380 if (didRenderTooFewHooks) { 16381 throw new Error('Rendered fewer hooks than expected. This may be caused by an accidental ' + 'early return statement.'); 16382 } 16383 16384 return children; 16385} 16386function checkDidRenderIdHook() { 16387 // This should be called immediately after every renderWithHooks call. 16388 // Conceptually, it's part of the return value of renderWithHooks; it's only a 16389 // separate function to avoid using an array tuple. 16390 var didRenderIdHook = localIdCounter !== 0; 16391 localIdCounter = 0; 16392 return didRenderIdHook; 16393} 16394function bailoutHooks(current, workInProgress, lanes) { 16395 workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the 16396 // complete phase (bubbleProperties). 16397 16398 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) { 16399 workInProgress.flags &= ~(MountPassiveDev | MountLayoutDev | Passive | Update); 16400 } else { 16401 workInProgress.flags &= ~(Passive | Update); 16402 } 16403 16404 current.lanes = removeLanes(current.lanes, lanes); 16405} 16406function resetHooksAfterThrow() { 16407 // We can assume the previous dispatcher is always this one, since we set it 16408 // at the beginning of the render phase and there's no re-entrance. 16409 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; 16410 16411 if (didScheduleRenderPhaseUpdate) { 16412 // There were render phase updates. These are only valid for this render 16413 // phase, which we are now aborting. Remove the updates from the queues so 16414 // they do not persist to the next render. Do not remove updates from hooks 16415 // that weren't processed. 16416 // 16417 // Only reset the updates from the queue if it has a clone. If it does 16418 // not have a clone, that means it wasn't processed, and the updates were 16419 // scheduled before we entered the render phase. 16420 var hook = currentlyRenderingFiber$1.memoizedState; 16421 16422 while (hook !== null) { 16423 var queue = hook.queue; 16424 16425 if (queue !== null) { 16426 queue.pending = null; 16427 } 16428 16429 hook = hook.next; 16430 } 16431 16432 didScheduleRenderPhaseUpdate = false; 16433 } 16434 16435 renderLanes = NoLanes; 16436 currentlyRenderingFiber$1 = null; 16437 currentHook = null; 16438 workInProgressHook = null; 16439 16440 { 16441 hookTypesDev = null; 16442 hookTypesUpdateIndexDev = -1; 16443 currentHookNameInDev = null; 16444 isUpdatingOpaqueValueInRenderPhase = false; 16445 } 16446 16447 didScheduleRenderPhaseUpdateDuringThisPass = false; 16448 localIdCounter = 0; 16449} 16450 16451function mountWorkInProgressHook() { 16452 var hook = { 16453 memoizedState: null, 16454 baseState: null, 16455 baseQueue: null, 16456 queue: null, 16457 next: null 16458 }; 16459 16460 if (workInProgressHook === null) { 16461 // This is the first hook in the list 16462 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook; 16463 } else { 16464 // Append to the end of the list 16465 workInProgressHook = workInProgressHook.next = hook; 16466 } 16467 16468 return workInProgressHook; 16469} 16470 16471function updateWorkInProgressHook() { 16472 // This function is used both for updates and for re-renders triggered by a 16473 // render phase update. It assumes there is either a current hook we can 16474 // clone, or a work-in-progress hook from a previous render pass that we can 16475 // use as a base. When we reach the end of the base list, we must switch to 16476 // the dispatcher used for mounts. 16477 var nextCurrentHook; 16478 16479 if (currentHook === null) { 16480 var current = currentlyRenderingFiber$1.alternate; 16481 16482 if (current !== null) { 16483 nextCurrentHook = current.memoizedState; 16484 } else { 16485 nextCurrentHook = null; 16486 } 16487 } else { 16488 nextCurrentHook = currentHook.next; 16489 } 16490 16491 var nextWorkInProgressHook; 16492 16493 if (workInProgressHook === null) { 16494 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState; 16495 } else { 16496 nextWorkInProgressHook = workInProgressHook.next; 16497 } 16498 16499 if (nextWorkInProgressHook !== null) { 16500 // There's already a work-in-progress. Reuse it. 16501 workInProgressHook = nextWorkInProgressHook; 16502 nextWorkInProgressHook = workInProgressHook.next; 16503 currentHook = nextCurrentHook; 16504 } else { 16505 // Clone from the current hook. 16506 if (nextCurrentHook === null) { 16507 throw new Error('Rendered more hooks than during the previous render.'); 16508 } 16509 16510 currentHook = nextCurrentHook; 16511 var newHook = { 16512 memoizedState: currentHook.memoizedState, 16513 baseState: currentHook.baseState, 16514 baseQueue: currentHook.baseQueue, 16515 queue: currentHook.queue, 16516 next: null 16517 }; 16518 16519 if (workInProgressHook === null) { 16520 // This is the first hook in the list. 16521 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook; 16522 } else { 16523 // Append to the end of the list. 16524 workInProgressHook = workInProgressHook.next = newHook; 16525 } 16526 } 16527 16528 return workInProgressHook; 16529} 16530 16531function createFunctionComponentUpdateQueue() { 16532 return { 16533 lastEffect: null, 16534 stores: null 16535 }; 16536} 16537 16538function basicStateReducer(state, action) { 16539 // $FlowFixMe: Flow doesn't like mixed types 16540 return typeof action === 'function' ? action(state) : action; 16541} 16542 16543function mountReducer(reducer, initialArg, init) { 16544 var hook = mountWorkInProgressHook(); 16545 var initialState; 16546 16547 if (init !== undefined) { 16548 initialState = init(initialArg); 16549 } else { 16550 initialState = initialArg; 16551 } 16552 16553 hook.memoizedState = hook.baseState = initialState; 16554 var queue = { 16555 pending: null, 16556 interleaved: null, 16557 lanes: NoLanes, 16558 dispatch: null, 16559 lastRenderedReducer: reducer, 16560 lastRenderedState: initialState 16561 }; 16562 hook.queue = queue; 16563 var dispatch = queue.dispatch = dispatchReducerAction.bind(null, currentlyRenderingFiber$1, queue); 16564 return [hook.memoizedState, dispatch]; 16565} 16566 16567function updateReducer(reducer, initialArg, init) { 16568 var hook = updateWorkInProgressHook(); 16569 var queue = hook.queue; 16570 16571 if (queue === null) { 16572 throw new Error('Should have a queue. This is likely a bug in React. Please file an issue.'); 16573 } 16574 16575 queue.lastRenderedReducer = reducer; 16576 var current = currentHook; // The last rebase update that is NOT part of the base state. 16577 16578 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. 16579 16580 var pendingQueue = queue.pending; 16581 16582 if (pendingQueue !== null) { 16583 // We have new updates that haven't been processed yet. 16584 // We'll add them to the base queue. 16585 if (baseQueue !== null) { 16586 // Merge the pending queue and the base queue. 16587 var baseFirst = baseQueue.next; 16588 var pendingFirst = pendingQueue.next; 16589 baseQueue.next = pendingFirst; 16590 pendingQueue.next = baseFirst; 16591 } 16592 16593 { 16594 if (current.baseQueue !== baseQueue) { 16595 // Internal invariant that should never happen, but feasibly could in 16596 // the future if we implement resuming, or some form of that. 16597 error('Internal error: Expected work-in-progress queue to be a clone. ' + 'This is a bug in React.'); 16598 } 16599 } 16600 16601 current.baseQueue = baseQueue = pendingQueue; 16602 queue.pending = null; 16603 } 16604 16605 if (baseQueue !== null) { 16606 // We have a queue to process. 16607 var first = baseQueue.next; 16608 var newState = current.baseState; 16609 var newBaseState = null; 16610 var newBaseQueueFirst = null; 16611 var newBaseQueueLast = null; 16612 var update = first; 16613 16614 do { 16615 var updateLane = update.lane; 16616 16617 if (!isSubsetOfLanes(renderLanes, updateLane)) { 16618 // Priority is insufficient. Skip this update. If this is the first 16619 // skipped update, the previous update/state is the new base 16620 // update/state. 16621 var clone = { 16622 lane: updateLane, 16623 action: update.action, 16624 hasEagerState: update.hasEagerState, 16625 eagerState: update.eagerState, 16626 next: null 16627 }; 16628 16629 if (newBaseQueueLast === null) { 16630 newBaseQueueFirst = newBaseQueueLast = clone; 16631 newBaseState = newState; 16632 } else { 16633 newBaseQueueLast = newBaseQueueLast.next = clone; 16634 } // Update the remaining priority in the queue. 16635 // TODO: Don't need to accumulate this. Instead, we can remove 16636 // renderLanes from the original lanes. 16637 16638 16639 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, updateLane); 16640 markSkippedUpdateLanes(updateLane); 16641 } else { 16642 // This update does have sufficient priority. 16643 if (newBaseQueueLast !== null) { 16644 var _clone = { 16645 // This update is going to be committed so we never want uncommit 16646 // it. Using NoLane works because 0 is a subset of all bitmasks, so 16647 // this will never be skipped by the check above. 16648 lane: NoLane, 16649 action: update.action, 16650 hasEagerState: update.hasEagerState, 16651 eagerState: update.eagerState, 16652 next: null 16653 }; 16654 newBaseQueueLast = newBaseQueueLast.next = _clone; 16655 } // Process this update. 16656 16657 16658 if (update.hasEagerState) { 16659 // If this update is a state update (not a reducer) and was processed eagerly, 16660 // we can use the eagerly computed state 16661 newState = update.eagerState; 16662 } else { 16663 var action = update.action; 16664 newState = reducer(newState, action); 16665 } 16666 } 16667 16668 update = update.next; 16669 } while (update !== null && update !== first); 16670 16671 if (newBaseQueueLast === null) { 16672 newBaseState = newState; 16673 } else { 16674 newBaseQueueLast.next = newBaseQueueFirst; 16675 } // Mark that the fiber performed work, but only if the new state is 16676 // different from the current state. 16677 16678 16679 if (!objectIs(newState, hook.memoizedState)) { 16680 markWorkInProgressReceivedUpdate(); 16681 } 16682 16683 hook.memoizedState = newState; 16684 hook.baseState = newBaseState; 16685 hook.baseQueue = newBaseQueueLast; 16686 queue.lastRenderedState = newState; 16687 } // Interleaved updates are stored on a separate queue. We aren't going to 16688 // process them during this render, but we do need to track which lanes 16689 // are remaining. 16690 16691 16692 var lastInterleaved = queue.interleaved; 16693 16694 if (lastInterleaved !== null) { 16695 var interleaved = lastInterleaved; 16696 16697 do { 16698 var interleavedLane = interleaved.lane; 16699 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, interleavedLane); 16700 markSkippedUpdateLanes(interleavedLane); 16701 interleaved = interleaved.next; 16702 } while (interleaved !== lastInterleaved); 16703 } else if (baseQueue === null) { 16704 // `queue.lanes` is used for entangling transitions. We can set it back to 16705 // zero once the queue is empty. 16706 queue.lanes = NoLanes; 16707 } 16708 16709 var dispatch = queue.dispatch; 16710 return [hook.memoizedState, dispatch]; 16711} 16712 16713function rerenderReducer(reducer, initialArg, init) { 16714 var hook = updateWorkInProgressHook(); 16715 var queue = hook.queue; 16716 16717 if (queue === null) { 16718 throw new Error('Should have a queue. This is likely a bug in React. Please file an issue.'); 16719 } 16720 16721 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous 16722 // work-in-progress hook. 16723 16724 var dispatch = queue.dispatch; 16725 var lastRenderPhaseUpdate = queue.pending; 16726 var newState = hook.memoizedState; 16727 16728 if (lastRenderPhaseUpdate !== null) { 16729 // The queue doesn't persist past this render pass. 16730 queue.pending = null; 16731 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next; 16732 var update = firstRenderPhaseUpdate; 16733 16734 do { 16735 // Process this render phase update. We don't have to check the 16736 // priority because it will always be the same as the current 16737 // render's. 16738 var action = update.action; 16739 newState = reducer(newState, action); 16740 update = update.next; 16741 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is 16742 // different from the current state. 16743 16744 16745 if (!objectIs(newState, hook.memoizedState)) { 16746 markWorkInProgressReceivedUpdate(); 16747 } 16748 16749 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to 16750 // the base state unless the queue is empty. 16751 // TODO: Not sure if this is the desired semantics, but it's what we 16752 // do for gDSFP. I can't remember why. 16753 16754 if (hook.baseQueue === null) { 16755 hook.baseState = newState; 16756 } 16757 16758 queue.lastRenderedState = newState; 16759 } 16760 16761 return [newState, dispatch]; 16762} 16763 16764function mountMutableSource(source, getSnapshot, subscribe) { 16765 { 16766 return undefined; 16767 } 16768} 16769 16770function updateMutableSource(source, getSnapshot, subscribe) { 16771 { 16772 return undefined; 16773 } 16774} 16775 16776function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { 16777 var fiber = currentlyRenderingFiber$1; 16778 var hook = mountWorkInProgressHook(); 16779 var nextSnapshot; 16780 var isHydrating = getIsHydrating(); 16781 16782 if (isHydrating) { 16783 if (getServerSnapshot === undefined) { 16784 throw new Error('Missing getServerSnapshot, which is required for ' + 'server-rendered content. Will revert to client rendering.'); 16785 } 16786 16787 nextSnapshot = getServerSnapshot(); 16788 16789 { 16790 if (!didWarnUncachedGetSnapshot) { 16791 if (nextSnapshot !== getServerSnapshot()) { 16792 error('The result of getServerSnapshot should be cached to avoid an infinite loop'); 16793 16794 didWarnUncachedGetSnapshot = true; 16795 } 16796 } 16797 } 16798 } else { 16799 nextSnapshot = getSnapshot(); 16800 16801 { 16802 if (!didWarnUncachedGetSnapshot) { 16803 var cachedSnapshot = getSnapshot(); 16804 16805 if (!objectIs(nextSnapshot, cachedSnapshot)) { 16806 error('The result of getSnapshot should be cached to avoid an infinite loop'); 16807 16808 didWarnUncachedGetSnapshot = true; 16809 } 16810 } 16811 } // Unless we're rendering a blocking lane, schedule a consistency check. 16812 // Right before committing, we will walk the tree and check if any of the 16813 // stores were mutated. 16814 // 16815 // We won't do this if we're hydrating server-rendered content, because if 16816 // the content is stale, it's already visible anyway. Instead we'll patch 16817 // it up in a passive effect. 16818 16819 16820 var root = getWorkInProgressRoot(); 16821 16822 if (root === null) { 16823 throw new Error('Expected a work-in-progress root. This is a bug in React. Please file an issue.'); 16824 } 16825 16826 if (!includesBlockingLane(root, renderLanes)) { 16827 pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); 16828 } 16829 } // Read the current snapshot from the store on every render. This breaks the 16830 // normal rules of React, and only works because store updates are 16831 // always synchronous. 16832 16833 16834 hook.memoizedState = nextSnapshot; 16835 var inst = { 16836 value: nextSnapshot, 16837 getSnapshot: getSnapshot 16838 }; 16839 hook.queue = inst; // Schedule an effect to subscribe to the store. 16840 16841 mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]); // Schedule an effect to update the mutable instance fields. We will update 16842 // this whenever subscribe, getSnapshot, or value changes. Because there's no 16843 // clean-up function, and we track the deps correctly, we can call pushEffect 16844 // directly, without storing any additional state. For the same reason, we 16845 // don't need to set a static flag, either. 16846 // TODO: We can move this to the passive phase once we add a pre-commit 16847 // consistency check. See the next comment. 16848 16849 fiber.flags |= Passive; 16850 pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), undefined, null); 16851 return nextSnapshot; 16852} 16853 16854function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { 16855 var fiber = currentlyRenderingFiber$1; 16856 var hook = updateWorkInProgressHook(); // Read the current snapshot from the store on every render. This breaks the 16857 // normal rules of React, and only works because store updates are 16858 // always synchronous. 16859 16860 var nextSnapshot = getSnapshot(); 16861 16862 { 16863 if (!didWarnUncachedGetSnapshot) { 16864 var cachedSnapshot = getSnapshot(); 16865 16866 if (!objectIs(nextSnapshot, cachedSnapshot)) { 16867 error('The result of getSnapshot should be cached to avoid an infinite loop'); 16868 16869 didWarnUncachedGetSnapshot = true; 16870 } 16871 } 16872 } 16873 16874 var prevSnapshot = hook.memoizedState; 16875 var snapshotChanged = !objectIs(prevSnapshot, nextSnapshot); 16876 16877 if (snapshotChanged) { 16878 hook.memoizedState = nextSnapshot; 16879 markWorkInProgressReceivedUpdate(); 16880 } 16881 16882 var inst = hook.queue; 16883 updateEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]); // Whenever getSnapshot or subscribe changes, we need to check in the 16884 // commit phase if there was an interleaved mutation. In concurrent mode 16885 // this can happen all the time, but even in synchronous mode, an earlier 16886 // effect may have mutated the store. 16887 16888 if (inst.getSnapshot !== getSnapshot || snapshotChanged || // Check if the susbcribe function changed. We can save some memory by 16889 // checking whether we scheduled a subscription effect above. 16890 workInProgressHook !== null && workInProgressHook.memoizedState.tag & HasEffect) { 16891 fiber.flags |= Passive; 16892 pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), undefined, null); // Unless we're rendering a blocking lane, schedule a consistency check. 16893 // Right before committing, we will walk the tree and check if any of the 16894 // stores were mutated. 16895 16896 var root = getWorkInProgressRoot(); 16897 16898 if (root === null) { 16899 throw new Error('Expected a work-in-progress root. This is a bug in React. Please file an issue.'); 16900 } 16901 16902 if (!includesBlockingLane(root, renderLanes)) { 16903 pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); 16904 } 16905 } 16906 16907 return nextSnapshot; 16908} 16909 16910function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) { 16911 fiber.flags |= StoreConsistency; 16912 var check = { 16913 getSnapshot: getSnapshot, 16914 value: renderedSnapshot 16915 }; 16916 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue; 16917 16918 if (componentUpdateQueue === null) { 16919 componentUpdateQueue = createFunctionComponentUpdateQueue(); 16920 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue; 16921 componentUpdateQueue.stores = [check]; 16922 } else { 16923 var stores = componentUpdateQueue.stores; 16924 16925 if (stores === null) { 16926 componentUpdateQueue.stores = [check]; 16927 } else { 16928 stores.push(check); 16929 } 16930 } 16931} 16932 16933function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) { 16934 // These are updated in the passive phase 16935 inst.value = nextSnapshot; 16936 inst.getSnapshot = getSnapshot; // Something may have been mutated in between render and commit. This could 16937 // have been in an event that fired before the passive effects, or it could 16938 // have been in a layout effect. In that case, we would have used the old 16939 // snapsho and getSnapshot values to bail out. We need to check one more time. 16940 16941 if (checkIfSnapshotChanged(inst)) { 16942 // Force a re-render. 16943 forceStoreRerender(fiber); 16944 } 16945} 16946 16947function subscribeToStore(fiber, inst, subscribe) { 16948 var handleStoreChange = function () { 16949 // The store changed. Check if the snapshot changed since the last time we 16950 // read from the store. 16951 if (checkIfSnapshotChanged(inst)) { 16952 // Force a re-render. 16953 forceStoreRerender(fiber); 16954 } 16955 }; // Subscribe to the store and return a clean-up function. 16956 16957 16958 return subscribe(handleStoreChange); 16959} 16960 16961function checkIfSnapshotChanged(inst) { 16962 var latestGetSnapshot = inst.getSnapshot; 16963 var prevValue = inst.value; 16964 16965 try { 16966 var nextValue = latestGetSnapshot(); 16967 return !objectIs(prevValue, nextValue); 16968 } catch (error) { 16969 return true; 16970 } 16971} 16972 16973function forceStoreRerender(fiber) { 16974 var root = enqueueConcurrentRenderForLane(fiber, SyncLane); 16975 16976 if (root !== null) { 16977 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp); 16978 } 16979} 16980 16981function mountState(initialState) { 16982 var hook = mountWorkInProgressHook(); 16983 16984 if (typeof initialState === 'function') { 16985 // $FlowFixMe: Flow doesn't like mixed types 16986 initialState = initialState(); 16987 } 16988 16989 hook.memoizedState = hook.baseState = initialState; 16990 var queue = { 16991 pending: null, 16992 interleaved: null, 16993 lanes: NoLanes, 16994 dispatch: null, 16995 lastRenderedReducer: basicStateReducer, 16996 lastRenderedState: initialState 16997 }; 16998 hook.queue = queue; 16999 var dispatch = queue.dispatch = dispatchSetState.bind(null, currentlyRenderingFiber$1, queue); 17000 return [hook.memoizedState, dispatch]; 17001} 17002 17003function updateState(initialState) { 17004 return updateReducer(basicStateReducer); 17005} 17006 17007function rerenderState(initialState) { 17008 return rerenderReducer(basicStateReducer); 17009} 17010 17011function pushEffect(tag, create, destroy, deps) { 17012 var effect = { 17013 tag: tag, 17014 create: create, 17015 destroy: destroy, 17016 deps: deps, 17017 // Circular 17018 next: null 17019 }; 17020 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue; 17021 17022 if (componentUpdateQueue === null) { 17023 componentUpdateQueue = createFunctionComponentUpdateQueue(); 17024 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue; 17025 componentUpdateQueue.lastEffect = effect.next = effect; 17026 } else { 17027 var lastEffect = componentUpdateQueue.lastEffect; 17028 17029 if (lastEffect === null) { 17030 componentUpdateQueue.lastEffect = effect.next = effect; 17031 } else { 17032 var firstEffect = lastEffect.next; 17033 lastEffect.next = effect; 17034 effect.next = firstEffect; 17035 componentUpdateQueue.lastEffect = effect; 17036 } 17037 } 17038 17039 return effect; 17040} 17041 17042function mountRef(initialValue) { 17043 var hook = mountWorkInProgressHook(); 17044 17045 { 17046 var _ref2 = { 17047 current: initialValue 17048 }; 17049 hook.memoizedState = _ref2; 17050 return _ref2; 17051 } 17052} 17053 17054function updateRef(initialValue) { 17055 var hook = updateWorkInProgressHook(); 17056 return hook.memoizedState; 17057} 17058 17059function mountEffectImpl(fiberFlags, hookFlags, create, deps) { 17060 var hook = mountWorkInProgressHook(); 17061 var nextDeps = deps === undefined ? null : deps; 17062 currentlyRenderingFiber$1.flags |= fiberFlags; 17063 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, undefined, nextDeps); 17064} 17065 17066function updateEffectImpl(fiberFlags, hookFlags, create, deps) { 17067 var hook = updateWorkInProgressHook(); 17068 var nextDeps = deps === undefined ? null : deps; 17069 var destroy = undefined; 17070 17071 if (currentHook !== null) { 17072 var prevEffect = currentHook.memoizedState; 17073 destroy = prevEffect.destroy; 17074 17075 if (nextDeps !== null) { 17076 var prevDeps = prevEffect.deps; 17077 17078 if (areHookInputsEqual(nextDeps, prevDeps)) { 17079 hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); 17080 return; 17081 } 17082 } 17083 } 17084 17085 currentlyRenderingFiber$1.flags |= fiberFlags; 17086 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, destroy, nextDeps); 17087} 17088 17089function mountEffect(create, deps) { 17090 if ( (currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) { 17091 return mountEffectImpl(MountPassiveDev | Passive | PassiveStatic, Passive$1, create, deps); 17092 } else { 17093 return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps); 17094 } 17095} 17096 17097function updateEffect(create, deps) { 17098 return updateEffectImpl(Passive, Passive$1, create, deps); 17099} 17100 17101function mountInsertionEffect(create, deps) { 17102 return mountEffectImpl(Update, Insertion, create, deps); 17103} 17104 17105function updateInsertionEffect(create, deps) { 17106 return updateEffectImpl(Update, Insertion, create, deps); 17107} 17108 17109function mountLayoutEffect(create, deps) { 17110 var fiberFlags = Update; 17111 17112 { 17113 fiberFlags |= LayoutStatic; 17114 } 17115 17116 if ( (currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) { 17117 fiberFlags |= MountLayoutDev; 17118 } 17119 17120 return mountEffectImpl(fiberFlags, Layout, create, deps); 17121} 17122 17123function updateLayoutEffect(create, deps) { 17124 return updateEffectImpl(Update, Layout, create, deps); 17125} 17126 17127function imperativeHandleEffect(create, ref) { 17128 if (typeof ref === 'function') { 17129 var refCallback = ref; 17130 17131 var _inst = create(); 17132 17133 refCallback(_inst); 17134 return function () { 17135 refCallback(null); 17136 }; 17137 } else if (ref !== null && ref !== undefined) { 17138 var refObject = ref; 17139 17140 { 17141 if (!refObject.hasOwnProperty('current')) { 17142 error('Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}'); 17143 } 17144 } 17145 17146 var _inst2 = create(); 17147 17148 refObject.current = _inst2; 17149 return function () { 17150 refObject.current = null; 17151 }; 17152 } 17153} 17154 17155function mountImperativeHandle(ref, create, deps) { 17156 { 17157 if (typeof create !== 'function') { 17158 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null'); 17159 } 17160 } // TODO: If deps are provided, should we skip comparing the ref itself? 17161 17162 17163 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; 17164 var fiberFlags = Update; 17165 17166 { 17167 fiberFlags |= LayoutStatic; 17168 } 17169 17170 if ( (currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) { 17171 fiberFlags |= MountLayoutDev; 17172 } 17173 17174 return mountEffectImpl(fiberFlags, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps); 17175} 17176 17177function updateImperativeHandle(ref, create, deps) { 17178 { 17179 if (typeof create !== 'function') { 17180 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null'); 17181 } 17182 } // TODO: If deps are provided, should we skip comparing the ref itself? 17183 17184 17185 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; 17186 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps); 17187} 17188 17189function mountDebugValue(value, formatterFn) {// This hook is normally a no-op. 17190 // The react-debug-hooks package injects its own implementation 17191 // so that e.g. DevTools can display custom hook values. 17192} 17193 17194var updateDebugValue = mountDebugValue; 17195 17196function mountCallback(callback, deps) { 17197 var hook = mountWorkInProgressHook(); 17198 var nextDeps = deps === undefined ? null : deps; 17199 hook.memoizedState = [callback, nextDeps]; 17200 return callback; 17201} 17202 17203function updateCallback(callback, deps) { 17204 var hook = updateWorkInProgressHook(); 17205 var nextDeps = deps === undefined ? null : deps; 17206 var prevState = hook.memoizedState; 17207 17208 if (prevState !== null) { 17209 if (nextDeps !== null) { 17210 var prevDeps = prevState[1]; 17211 17212 if (areHookInputsEqual(nextDeps, prevDeps)) { 17213 return prevState[0]; 17214 } 17215 } 17216 } 17217 17218 hook.memoizedState = [callback, nextDeps]; 17219 return callback; 17220} 17221 17222function mountMemo(nextCreate, deps) { 17223 var hook = mountWorkInProgressHook(); 17224 var nextDeps = deps === undefined ? null : deps; 17225 var nextValue = nextCreate(); 17226 hook.memoizedState = [nextValue, nextDeps]; 17227 return nextValue; 17228} 17229 17230function updateMemo(nextCreate, deps) { 17231 var hook = updateWorkInProgressHook(); 17232 var nextDeps = deps === undefined ? null : deps; 17233 var prevState = hook.memoizedState; 17234 17235 if (prevState !== null) { 17236 // Assume these are defined. If they're not, areHookInputsEqual will warn. 17237 if (nextDeps !== null) { 17238 var prevDeps = prevState[1]; 17239 17240 if (areHookInputsEqual(nextDeps, prevDeps)) { 17241 return prevState[0]; 17242 } 17243 } 17244 } 17245 17246 var nextValue = nextCreate(); 17247 hook.memoizedState = [nextValue, nextDeps]; 17248 return nextValue; 17249} 17250 17251function mountDeferredValue(value) { 17252 var hook = mountWorkInProgressHook(); 17253 hook.memoizedState = value; 17254 return value; 17255} 17256 17257function updateDeferredValue(value) { 17258 var hook = updateWorkInProgressHook(); 17259 var resolvedCurrentHook = currentHook; 17260 var prevValue = resolvedCurrentHook.memoizedState; 17261 return updateDeferredValueImpl(hook, prevValue, value); 17262} 17263 17264function rerenderDeferredValue(value) { 17265 var hook = updateWorkInProgressHook(); 17266 17267 if (currentHook === null) { 17268 // This is a rerender during a mount. 17269 hook.memoizedState = value; 17270 return value; 17271 } else { 17272 // This is a rerender during an update. 17273 var prevValue = currentHook.memoizedState; 17274 return updateDeferredValueImpl(hook, prevValue, value); 17275 } 17276} 17277 17278function updateDeferredValueImpl(hook, prevValue, value) { 17279 var shouldDeferValue = !includesOnlyNonUrgentLanes(renderLanes); 17280 17281 if (shouldDeferValue) { 17282 // This is an urgent update. If the value has changed, keep using the 17283 // previous value and spawn a deferred render to update it later. 17284 if (!objectIs(value, prevValue)) { 17285 // Schedule a deferred render 17286 var deferredLane = claimNextTransitionLane(); 17287 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, deferredLane); 17288 markSkippedUpdateLanes(deferredLane); // Set this to true to indicate that the rendered value is inconsistent 17289 // from the latest value. The name "baseState" doesn't really match how we 17290 // use it because we're reusing a state hook field instead of creating a 17291 // new one. 17292 17293 hook.baseState = true; 17294 } // Reuse the previous value 17295 17296 17297 return prevValue; 17298 } else { 17299 // This is not an urgent update, so we can use the latest value regardless 17300 // of what it is. No need to defer it. 17301 // However, if we're currently inside a spawned render, then we need to mark 17302 // this as an update to prevent the fiber from bailing out. 17303 // 17304 // `baseState` is true when the current value is different from the rendered 17305 // value. The name doesn't really match how we use it because we're reusing 17306 // a state hook field instead of creating a new one. 17307 if (hook.baseState) { 17308 // Flip this back to false. 17309 hook.baseState = false; 17310 markWorkInProgressReceivedUpdate(); 17311 } 17312 17313 hook.memoizedState = value; 17314 return value; 17315 } 17316} 17317 17318function startTransition(setPending, callback, options) { 17319 var previousPriority = getCurrentUpdatePriority(); 17320 setCurrentUpdatePriority(higherEventPriority(previousPriority, ContinuousEventPriority)); 17321 setPending(true); 17322 var prevTransition = ReactCurrentBatchConfig$2.transition; 17323 ReactCurrentBatchConfig$2.transition = {}; 17324 var currentTransition = ReactCurrentBatchConfig$2.transition; 17325 17326 { 17327 ReactCurrentBatchConfig$2.transition._updatedFibers = new Set(); 17328 } 17329 17330 try { 17331 setPending(false); 17332 callback(); 17333 } finally { 17334 setCurrentUpdatePriority(previousPriority); 17335 ReactCurrentBatchConfig$2.transition = prevTransition; 17336 17337 { 17338 if (prevTransition === null && currentTransition._updatedFibers) { 17339 var updatedFibersCount = currentTransition._updatedFibers.size; 17340 17341 if (updatedFibersCount > 10) { 17342 warn('Detected a large number of updates inside startTransition. ' + 'If this is due to a subscription please re-write it to use React provided hooks. ' + 'Otherwise concurrent mode guarantees are off the table.'); 17343 } 17344 17345 currentTransition._updatedFibers.clear(); 17346 } 17347 } 17348 } 17349} 17350 17351function mountTransition() { 17352 var _mountState = mountState(false), 17353 isPending = _mountState[0], 17354 setPending = _mountState[1]; // The `start` method never changes. 17355 17356 17357 var start = startTransition.bind(null, setPending); 17358 var hook = mountWorkInProgressHook(); 17359 hook.memoizedState = start; 17360 return [isPending, start]; 17361} 17362 17363function updateTransition() { 17364 var _updateState = updateState(), 17365 isPending = _updateState[0]; 17366 17367 var hook = updateWorkInProgressHook(); 17368 var start = hook.memoizedState; 17369 return [isPending, start]; 17370} 17371 17372function rerenderTransition() { 17373 var _rerenderState = rerenderState(), 17374 isPending = _rerenderState[0]; 17375 17376 var hook = updateWorkInProgressHook(); 17377 var start = hook.memoizedState; 17378 return [isPending, start]; 17379} 17380 17381var isUpdatingOpaqueValueInRenderPhase = false; 17382function getIsUpdatingOpaqueValueInRenderPhaseInDEV() { 17383 { 17384 return isUpdatingOpaqueValueInRenderPhase; 17385 } 17386} 17387 17388function mountId() { 17389 var hook = mountWorkInProgressHook(); 17390 var root = getWorkInProgressRoot(); // TODO: In Fizz, id generation is specific to each server config. Maybe we 17391 // should do this in Fiber, too? Deferring this decision for now because 17392 // there's no other place to store the prefix except for an internal field on 17393 // the public createRoot object, which the fiber tree does not currently have 17394 // a reference to. 17395 17396 var identifierPrefix = root.identifierPrefix; 17397 var id; 17398 17399 if (getIsHydrating()) { 17400 var treeId = getTreeId(); // Use a captial R prefix for server-generated ids. 17401 17402 id = ':' + identifierPrefix + 'R' + treeId; // Unless this is the first id at this level, append a number at the end 17403 // that represents the position of this useId hook among all the useId 17404 // hooks for this fiber. 17405 17406 var localId = localIdCounter++; 17407 17408 if (localId > 0) { 17409 id += 'H' + localId.toString(32); 17410 } 17411 17412 id += ':'; 17413 } else { 17414 // Use a lowercase r prefix for client-generated ids. 17415 var globalClientId = globalClientIdCounter++; 17416 id = ':' + identifierPrefix + 'r' + globalClientId.toString(32) + ':'; 17417 } 17418 17419 hook.memoizedState = id; 17420 return id; 17421} 17422 17423function updateId() { 17424 var hook = updateWorkInProgressHook(); 17425 var id = hook.memoizedState; 17426 return id; 17427} 17428 17429function dispatchReducerAction(fiber, queue, action) { 17430 { 17431 if (typeof arguments[3] === 'function') { 17432 error("State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().'); 17433 } 17434 } 17435 17436 var lane = requestUpdateLane(fiber); 17437 var update = { 17438 lane: lane, 17439 action: action, 17440 hasEagerState: false, 17441 eagerState: null, 17442 next: null 17443 }; 17444 17445 if (isRenderPhaseUpdate(fiber)) { 17446 enqueueRenderPhaseUpdate(queue, update); 17447 } else { 17448 var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane); 17449 17450 if (root !== null) { 17451 var eventTime = requestEventTime(); 17452 scheduleUpdateOnFiber(root, fiber, lane, eventTime); 17453 entangleTransitionUpdate(root, queue, lane); 17454 } 17455 } 17456 17457 markUpdateInDevTools(fiber, lane); 17458} 17459 17460function dispatchSetState(fiber, queue, action) { 17461 { 17462 if (typeof arguments[3] === 'function') { 17463 error("State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().'); 17464 } 17465 } 17466 17467 var lane = requestUpdateLane(fiber); 17468 var update = { 17469 lane: lane, 17470 action: action, 17471 hasEagerState: false, 17472 eagerState: null, 17473 next: null 17474 }; 17475 17476 if (isRenderPhaseUpdate(fiber)) { 17477 enqueueRenderPhaseUpdate(queue, update); 17478 } else { 17479 var alternate = fiber.alternate; 17480 17481 if (fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes)) { 17482 // The queue is currently empty, which means we can eagerly compute the 17483 // next state before entering the render phase. If the new state is the 17484 // same as the current state, we may be able to bail out entirely. 17485 var lastRenderedReducer = queue.lastRenderedReducer; 17486 17487 if (lastRenderedReducer !== null) { 17488 var prevDispatcher; 17489 17490 { 17491 prevDispatcher = ReactCurrentDispatcher$1.current; 17492 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 17493 } 17494 17495 try { 17496 var currentState = queue.lastRenderedState; 17497 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute 17498 // it, on the update object. If the reducer hasn't changed by the 17499 // time we enter the render phase, then the eager state can be used 17500 // without calling the reducer again. 17501 17502 update.hasEagerState = true; 17503 update.eagerState = eagerState; 17504 17505 if (objectIs(eagerState, currentState)) { 17506 // Fast path. We can bail out without scheduling React to re-render. 17507 // It's still possible that we'll need to rebase this update later, 17508 // if the component re-renders for a different reason and by that 17509 // time the reducer has changed. 17510 // TODO: Do we still need to entangle transitions in this case? 17511 enqueueConcurrentHookUpdateAndEagerlyBailout(fiber, queue, update, lane); 17512 return; 17513 } 17514 } catch (error) {// Suppress the error. It will throw again in the render phase. 17515 } finally { 17516 { 17517 ReactCurrentDispatcher$1.current = prevDispatcher; 17518 } 17519 } 17520 } 17521 } 17522 17523 var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane); 17524 17525 if (root !== null) { 17526 var eventTime = requestEventTime(); 17527 scheduleUpdateOnFiber(root, fiber, lane, eventTime); 17528 entangleTransitionUpdate(root, queue, lane); 17529 } 17530 } 17531 17532 markUpdateInDevTools(fiber, lane); 17533} 17534 17535function isRenderPhaseUpdate(fiber) { 17536 var alternate = fiber.alternate; 17537 return fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1; 17538} 17539 17540function enqueueRenderPhaseUpdate(queue, update) { 17541 // This is a render phase update. Stash it in a lazily-created map of 17542 // queue -> linked list of updates. After this render pass, we'll restart 17543 // and apply the stashed updates on top of the work-in-progress hook. 17544 didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true; 17545 var pending = queue.pending; 17546 17547 if (pending === null) { 17548 // This is the first update. Create a circular list. 17549 update.next = update; 17550 } else { 17551 update.next = pending.next; 17552 pending.next = update; 17553 } 17554 17555 queue.pending = update; 17556} // TODO: Move to ReactFiberConcurrentUpdates? 17557 17558 17559function entangleTransitionUpdate(root, queue, lane) { 17560 if (isTransitionLane(lane)) { 17561 var queueLanes = queue.lanes; // If any entangled lanes are no longer pending on the root, then they 17562 // must have finished. We can remove them from the shared queue, which 17563 // represents a superset of the actually pending lanes. In some cases we 17564 // may entangle more than we need to, but that's OK. In fact it's worse if 17565 // we *don't* entangle when we should. 17566 17567 queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. 17568 17569 var newQueueLanes = mergeLanes(queueLanes, lane); 17570 queue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if 17571 // the lane finished since the last time we entangled it. So we need to 17572 // entangle it again, just to be sure. 17573 17574 markRootEntangled(root, newQueueLanes); 17575 } 17576} 17577 17578function markUpdateInDevTools(fiber, lane, action) { 17579 17580 { 17581 markStateUpdateScheduled(fiber, lane); 17582 } 17583} 17584 17585var ContextOnlyDispatcher = { 17586 readContext: readContext, 17587 useCallback: throwInvalidHookError, 17588 useContext: throwInvalidHookError, 17589 useEffect: throwInvalidHookError, 17590 useImperativeHandle: throwInvalidHookError, 17591 useInsertionEffect: throwInvalidHookError, 17592 useLayoutEffect: throwInvalidHookError, 17593 useMemo: throwInvalidHookError, 17594 useReducer: throwInvalidHookError, 17595 useRef: throwInvalidHookError, 17596 useState: throwInvalidHookError, 17597 useDebugValue: throwInvalidHookError, 17598 useDeferredValue: throwInvalidHookError, 17599 useTransition: throwInvalidHookError, 17600 useMutableSource: throwInvalidHookError, 17601 useSyncExternalStore: throwInvalidHookError, 17602 useId: throwInvalidHookError, 17603 unstable_isNewReconciler: enableNewReconciler 17604}; 17605 17606var HooksDispatcherOnMountInDEV = null; 17607var HooksDispatcherOnMountWithHookTypesInDEV = null; 17608var HooksDispatcherOnUpdateInDEV = null; 17609var HooksDispatcherOnRerenderInDEV = null; 17610var InvalidNestedHooksDispatcherOnMountInDEV = null; 17611var InvalidNestedHooksDispatcherOnUpdateInDEV = null; 17612var InvalidNestedHooksDispatcherOnRerenderInDEV = null; 17613 17614{ 17615 var warnInvalidContextAccess = function () { 17616 error('Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().'); 17617 }; 17618 17619 var warnInvalidHookAccess = function () { 17620 error('Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + 'https://reactjs.org/link/rules-of-hooks'); 17621 }; 17622 17623 HooksDispatcherOnMountInDEV = { 17624 readContext: function (context) { 17625 return readContext(context); 17626 }, 17627 useCallback: function (callback, deps) { 17628 currentHookNameInDev = 'useCallback'; 17629 mountHookTypesDev(); 17630 checkDepsAreArrayDev(deps); 17631 return mountCallback(callback, deps); 17632 }, 17633 useContext: function (context) { 17634 currentHookNameInDev = 'useContext'; 17635 mountHookTypesDev(); 17636 return readContext(context); 17637 }, 17638 useEffect: function (create, deps) { 17639 currentHookNameInDev = 'useEffect'; 17640 mountHookTypesDev(); 17641 checkDepsAreArrayDev(deps); 17642 return mountEffect(create, deps); 17643 }, 17644 useImperativeHandle: function (ref, create, deps) { 17645 currentHookNameInDev = 'useImperativeHandle'; 17646 mountHookTypesDev(); 17647 checkDepsAreArrayDev(deps); 17648 return mountImperativeHandle(ref, create, deps); 17649 }, 17650 useInsertionEffect: function (create, deps) { 17651 currentHookNameInDev = 'useInsertionEffect'; 17652 mountHookTypesDev(); 17653 checkDepsAreArrayDev(deps); 17654 return mountInsertionEffect(create, deps); 17655 }, 17656 useLayoutEffect: function (create, deps) { 17657 currentHookNameInDev = 'useLayoutEffect'; 17658 mountHookTypesDev(); 17659 checkDepsAreArrayDev(deps); 17660 return mountLayoutEffect(create, deps); 17661 }, 17662 useMemo: function (create, deps) { 17663 currentHookNameInDev = 'useMemo'; 17664 mountHookTypesDev(); 17665 checkDepsAreArrayDev(deps); 17666 var prevDispatcher = ReactCurrentDispatcher$1.current; 17667 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 17668 17669 try { 17670 return mountMemo(create, deps); 17671 } finally { 17672 ReactCurrentDispatcher$1.current = prevDispatcher; 17673 } 17674 }, 17675 useReducer: function (reducer, initialArg, init) { 17676 currentHookNameInDev = 'useReducer'; 17677 mountHookTypesDev(); 17678 var prevDispatcher = ReactCurrentDispatcher$1.current; 17679 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 17680 17681 try { 17682 return mountReducer(reducer, initialArg, init); 17683 } finally { 17684 ReactCurrentDispatcher$1.current = prevDispatcher; 17685 } 17686 }, 17687 useRef: function (initialValue) { 17688 currentHookNameInDev = 'useRef'; 17689 mountHookTypesDev(); 17690 return mountRef(initialValue); 17691 }, 17692 useState: function (initialState) { 17693 currentHookNameInDev = 'useState'; 17694 mountHookTypesDev(); 17695 var prevDispatcher = ReactCurrentDispatcher$1.current; 17696 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 17697 17698 try { 17699 return mountState(initialState); 17700 } finally { 17701 ReactCurrentDispatcher$1.current = prevDispatcher; 17702 } 17703 }, 17704 useDebugValue: function (value, formatterFn) { 17705 currentHookNameInDev = 'useDebugValue'; 17706 mountHookTypesDev(); 17707 return mountDebugValue(); 17708 }, 17709 useDeferredValue: function (value) { 17710 currentHookNameInDev = 'useDeferredValue'; 17711 mountHookTypesDev(); 17712 return mountDeferredValue(value); 17713 }, 17714 useTransition: function () { 17715 currentHookNameInDev = 'useTransition'; 17716 mountHookTypesDev(); 17717 return mountTransition(); 17718 }, 17719 useMutableSource: function (source, getSnapshot, subscribe) { 17720 currentHookNameInDev = 'useMutableSource'; 17721 mountHookTypesDev(); 17722 return mountMutableSource(); 17723 }, 17724 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) { 17725 currentHookNameInDev = 'useSyncExternalStore'; 17726 mountHookTypesDev(); 17727 return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); 17728 }, 17729 useId: function () { 17730 currentHookNameInDev = 'useId'; 17731 mountHookTypesDev(); 17732 return mountId(); 17733 }, 17734 unstable_isNewReconciler: enableNewReconciler 17735 }; 17736 17737 HooksDispatcherOnMountWithHookTypesInDEV = { 17738 readContext: function (context) { 17739 return readContext(context); 17740 }, 17741 useCallback: function (callback, deps) { 17742 currentHookNameInDev = 'useCallback'; 17743 updateHookTypesDev(); 17744 return mountCallback(callback, deps); 17745 }, 17746 useContext: function (context) { 17747 currentHookNameInDev = 'useContext'; 17748 updateHookTypesDev(); 17749 return readContext(context); 17750 }, 17751 useEffect: function (create, deps) { 17752 currentHookNameInDev = 'useEffect'; 17753 updateHookTypesDev(); 17754 return mountEffect(create, deps); 17755 }, 17756 useImperativeHandle: function (ref, create, deps) { 17757 currentHookNameInDev = 'useImperativeHandle'; 17758 updateHookTypesDev(); 17759 return mountImperativeHandle(ref, create, deps); 17760 }, 17761 useInsertionEffect: function (create, deps) { 17762 currentHookNameInDev = 'useInsertionEffect'; 17763 updateHookTypesDev(); 17764 return mountInsertionEffect(create, deps); 17765 }, 17766 useLayoutEffect: function (create, deps) { 17767 currentHookNameInDev = 'useLayoutEffect'; 17768 updateHookTypesDev(); 17769 return mountLayoutEffect(create, deps); 17770 }, 17771 useMemo: function (create, deps) { 17772 currentHookNameInDev = 'useMemo'; 17773 updateHookTypesDev(); 17774 var prevDispatcher = ReactCurrentDispatcher$1.current; 17775 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 17776 17777 try { 17778 return mountMemo(create, deps); 17779 } finally { 17780 ReactCurrentDispatcher$1.current = prevDispatcher; 17781 } 17782 }, 17783 useReducer: function (reducer, initialArg, init) { 17784 currentHookNameInDev = 'useReducer'; 17785 updateHookTypesDev(); 17786 var prevDispatcher = ReactCurrentDispatcher$1.current; 17787 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 17788 17789 try { 17790 return mountReducer(reducer, initialArg, init); 17791 } finally { 17792 ReactCurrentDispatcher$1.current = prevDispatcher; 17793 } 17794 }, 17795 useRef: function (initialValue) { 17796 currentHookNameInDev = 'useRef'; 17797 updateHookTypesDev(); 17798 return mountRef(initialValue); 17799 }, 17800 useState: function (initialState) { 17801 currentHookNameInDev = 'useState'; 17802 updateHookTypesDev(); 17803 var prevDispatcher = ReactCurrentDispatcher$1.current; 17804 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 17805 17806 try { 17807 return mountState(initialState); 17808 } finally { 17809 ReactCurrentDispatcher$1.current = prevDispatcher; 17810 } 17811 }, 17812 useDebugValue: function (value, formatterFn) { 17813 currentHookNameInDev = 'useDebugValue'; 17814 updateHookTypesDev(); 17815 return mountDebugValue(); 17816 }, 17817 useDeferredValue: function (value) { 17818 currentHookNameInDev = 'useDeferredValue'; 17819 updateHookTypesDev(); 17820 return mountDeferredValue(value); 17821 }, 17822 useTransition: function () { 17823 currentHookNameInDev = 'useTransition'; 17824 updateHookTypesDev(); 17825 return mountTransition(); 17826 }, 17827 useMutableSource: function (source, getSnapshot, subscribe) { 17828 currentHookNameInDev = 'useMutableSource'; 17829 updateHookTypesDev(); 17830 return mountMutableSource(); 17831 }, 17832 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) { 17833 currentHookNameInDev = 'useSyncExternalStore'; 17834 updateHookTypesDev(); 17835 return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); 17836 }, 17837 useId: function () { 17838 currentHookNameInDev = 'useId'; 17839 updateHookTypesDev(); 17840 return mountId(); 17841 }, 17842 unstable_isNewReconciler: enableNewReconciler 17843 }; 17844 17845 HooksDispatcherOnUpdateInDEV = { 17846 readContext: function (context) { 17847 return readContext(context); 17848 }, 17849 useCallback: function (callback, deps) { 17850 currentHookNameInDev = 'useCallback'; 17851 updateHookTypesDev(); 17852 return updateCallback(callback, deps); 17853 }, 17854 useContext: function (context) { 17855 currentHookNameInDev = 'useContext'; 17856 updateHookTypesDev(); 17857 return readContext(context); 17858 }, 17859 useEffect: function (create, deps) { 17860 currentHookNameInDev = 'useEffect'; 17861 updateHookTypesDev(); 17862 return updateEffect(create, deps); 17863 }, 17864 useImperativeHandle: function (ref, create, deps) { 17865 currentHookNameInDev = 'useImperativeHandle'; 17866 updateHookTypesDev(); 17867 return updateImperativeHandle(ref, create, deps); 17868 }, 17869 useInsertionEffect: function (create, deps) { 17870 currentHookNameInDev = 'useInsertionEffect'; 17871 updateHookTypesDev(); 17872 return updateInsertionEffect(create, deps); 17873 }, 17874 useLayoutEffect: function (create, deps) { 17875 currentHookNameInDev = 'useLayoutEffect'; 17876 updateHookTypesDev(); 17877 return updateLayoutEffect(create, deps); 17878 }, 17879 useMemo: function (create, deps) { 17880 currentHookNameInDev = 'useMemo'; 17881 updateHookTypesDev(); 17882 var prevDispatcher = ReactCurrentDispatcher$1.current; 17883 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 17884 17885 try { 17886 return updateMemo(create, deps); 17887 } finally { 17888 ReactCurrentDispatcher$1.current = prevDispatcher; 17889 } 17890 }, 17891 useReducer: function (reducer, initialArg, init) { 17892 currentHookNameInDev = 'useReducer'; 17893 updateHookTypesDev(); 17894 var prevDispatcher = ReactCurrentDispatcher$1.current; 17895 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 17896 17897 try { 17898 return updateReducer(reducer, initialArg, init); 17899 } finally { 17900 ReactCurrentDispatcher$1.current = prevDispatcher; 17901 } 17902 }, 17903 useRef: function (initialValue) { 17904 currentHookNameInDev = 'useRef'; 17905 updateHookTypesDev(); 17906 return updateRef(); 17907 }, 17908 useState: function (initialState) { 17909 currentHookNameInDev = 'useState'; 17910 updateHookTypesDev(); 17911 var prevDispatcher = ReactCurrentDispatcher$1.current; 17912 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 17913 17914 try { 17915 return updateState(initialState); 17916 } finally { 17917 ReactCurrentDispatcher$1.current = prevDispatcher; 17918 } 17919 }, 17920 useDebugValue: function (value, formatterFn) { 17921 currentHookNameInDev = 'useDebugValue'; 17922 updateHookTypesDev(); 17923 return updateDebugValue(); 17924 }, 17925 useDeferredValue: function (value) { 17926 currentHookNameInDev = 'useDeferredValue'; 17927 updateHookTypesDev(); 17928 return updateDeferredValue(value); 17929 }, 17930 useTransition: function () { 17931 currentHookNameInDev = 'useTransition'; 17932 updateHookTypesDev(); 17933 return updateTransition(); 17934 }, 17935 useMutableSource: function (source, getSnapshot, subscribe) { 17936 currentHookNameInDev = 'useMutableSource'; 17937 updateHookTypesDev(); 17938 return updateMutableSource(); 17939 }, 17940 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) { 17941 currentHookNameInDev = 'useSyncExternalStore'; 17942 updateHookTypesDev(); 17943 return updateSyncExternalStore(subscribe, getSnapshot); 17944 }, 17945 useId: function () { 17946 currentHookNameInDev = 'useId'; 17947 updateHookTypesDev(); 17948 return updateId(); 17949 }, 17950 unstable_isNewReconciler: enableNewReconciler 17951 }; 17952 17953 HooksDispatcherOnRerenderInDEV = { 17954 readContext: function (context) { 17955 return readContext(context); 17956 }, 17957 useCallback: function (callback, deps) { 17958 currentHookNameInDev = 'useCallback'; 17959 updateHookTypesDev(); 17960 return updateCallback(callback, deps); 17961 }, 17962 useContext: function (context) { 17963 currentHookNameInDev = 'useContext'; 17964 updateHookTypesDev(); 17965 return readContext(context); 17966 }, 17967 useEffect: function (create, deps) { 17968 currentHookNameInDev = 'useEffect'; 17969 updateHookTypesDev(); 17970 return updateEffect(create, deps); 17971 }, 17972 useImperativeHandle: function (ref, create, deps) { 17973 currentHookNameInDev = 'useImperativeHandle'; 17974 updateHookTypesDev(); 17975 return updateImperativeHandle(ref, create, deps); 17976 }, 17977 useInsertionEffect: function (create, deps) { 17978 currentHookNameInDev = 'useInsertionEffect'; 17979 updateHookTypesDev(); 17980 return updateInsertionEffect(create, deps); 17981 }, 17982 useLayoutEffect: function (create, deps) { 17983 currentHookNameInDev = 'useLayoutEffect'; 17984 updateHookTypesDev(); 17985 return updateLayoutEffect(create, deps); 17986 }, 17987 useMemo: function (create, deps) { 17988 currentHookNameInDev = 'useMemo'; 17989 updateHookTypesDev(); 17990 var prevDispatcher = ReactCurrentDispatcher$1.current; 17991 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; 17992 17993 try { 17994 return updateMemo(create, deps); 17995 } finally { 17996 ReactCurrentDispatcher$1.current = prevDispatcher; 17997 } 17998 }, 17999 useReducer: function (reducer, initialArg, init) { 18000 currentHookNameInDev = 'useReducer'; 18001 updateHookTypesDev(); 18002 var prevDispatcher = ReactCurrentDispatcher$1.current; 18003 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; 18004 18005 try { 18006 return rerenderReducer(reducer, initialArg, init); 18007 } finally { 18008 ReactCurrentDispatcher$1.current = prevDispatcher; 18009 } 18010 }, 18011 useRef: function (initialValue) { 18012 currentHookNameInDev = 'useRef'; 18013 updateHookTypesDev(); 18014 return updateRef(); 18015 }, 18016 useState: function (initialState) { 18017 currentHookNameInDev = 'useState'; 18018 updateHookTypesDev(); 18019 var prevDispatcher = ReactCurrentDispatcher$1.current; 18020 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; 18021 18022 try { 18023 return rerenderState(initialState); 18024 } finally { 18025 ReactCurrentDispatcher$1.current = prevDispatcher; 18026 } 18027 }, 18028 useDebugValue: function (value, formatterFn) { 18029 currentHookNameInDev = 'useDebugValue'; 18030 updateHookTypesDev(); 18031 return updateDebugValue(); 18032 }, 18033 useDeferredValue: function (value) { 18034 currentHookNameInDev = 'useDeferredValue'; 18035 updateHookTypesDev(); 18036 return rerenderDeferredValue(value); 18037 }, 18038 useTransition: function () { 18039 currentHookNameInDev = 'useTransition'; 18040 updateHookTypesDev(); 18041 return rerenderTransition(); 18042 }, 18043 useMutableSource: function (source, getSnapshot, subscribe) { 18044 currentHookNameInDev = 'useMutableSource'; 18045 updateHookTypesDev(); 18046 return updateMutableSource(); 18047 }, 18048 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) { 18049 currentHookNameInDev = 'useSyncExternalStore'; 18050 updateHookTypesDev(); 18051 return updateSyncExternalStore(subscribe, getSnapshot); 18052 }, 18053 useId: function () { 18054 currentHookNameInDev = 'useId'; 18055 updateHookTypesDev(); 18056 return updateId(); 18057 }, 18058 unstable_isNewReconciler: enableNewReconciler 18059 }; 18060 18061 InvalidNestedHooksDispatcherOnMountInDEV = { 18062 readContext: function (context) { 18063 warnInvalidContextAccess(); 18064 return readContext(context); 18065 }, 18066 useCallback: function (callback, deps) { 18067 currentHookNameInDev = 'useCallback'; 18068 warnInvalidHookAccess(); 18069 mountHookTypesDev(); 18070 return mountCallback(callback, deps); 18071 }, 18072 useContext: function (context) { 18073 currentHookNameInDev = 'useContext'; 18074 warnInvalidHookAccess(); 18075 mountHookTypesDev(); 18076 return readContext(context); 18077 }, 18078 useEffect: function (create, deps) { 18079 currentHookNameInDev = 'useEffect'; 18080 warnInvalidHookAccess(); 18081 mountHookTypesDev(); 18082 return mountEffect(create, deps); 18083 }, 18084 useImperativeHandle: function (ref, create, deps) { 18085 currentHookNameInDev = 'useImperativeHandle'; 18086 warnInvalidHookAccess(); 18087 mountHookTypesDev(); 18088 return mountImperativeHandle(ref, create, deps); 18089 }, 18090 useInsertionEffect: function (create, deps) { 18091 currentHookNameInDev = 'useInsertionEffect'; 18092 warnInvalidHookAccess(); 18093 mountHookTypesDev(); 18094 return mountInsertionEffect(create, deps); 18095 }, 18096 useLayoutEffect: function (create, deps) { 18097 currentHookNameInDev = 'useLayoutEffect'; 18098 warnInvalidHookAccess(); 18099 mountHookTypesDev(); 18100 return mountLayoutEffect(create, deps); 18101 }, 18102 useMemo: function (create, deps) { 18103 currentHookNameInDev = 'useMemo'; 18104 warnInvalidHookAccess(); 18105 mountHookTypesDev(); 18106 var prevDispatcher = ReactCurrentDispatcher$1.current; 18107 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 18108 18109 try { 18110 return mountMemo(create, deps); 18111 } finally { 18112 ReactCurrentDispatcher$1.current = prevDispatcher; 18113 } 18114 }, 18115 useReducer: function (reducer, initialArg, init) { 18116 currentHookNameInDev = 'useReducer'; 18117 warnInvalidHookAccess(); 18118 mountHookTypesDev(); 18119 var prevDispatcher = ReactCurrentDispatcher$1.current; 18120 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 18121 18122 try { 18123 return mountReducer(reducer, initialArg, init); 18124 } finally { 18125 ReactCurrentDispatcher$1.current = prevDispatcher; 18126 } 18127 }, 18128 useRef: function (initialValue) { 18129 currentHookNameInDev = 'useRef'; 18130 warnInvalidHookAccess(); 18131 mountHookTypesDev(); 18132 return mountRef(initialValue); 18133 }, 18134 useState: function (initialState) { 18135 currentHookNameInDev = 'useState'; 18136 warnInvalidHookAccess(); 18137 mountHookTypesDev(); 18138 var prevDispatcher = ReactCurrentDispatcher$1.current; 18139 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; 18140 18141 try { 18142 return mountState(initialState); 18143 } finally { 18144 ReactCurrentDispatcher$1.current = prevDispatcher; 18145 } 18146 }, 18147 useDebugValue: function (value, formatterFn) { 18148 currentHookNameInDev = 'useDebugValue'; 18149 warnInvalidHookAccess(); 18150 mountHookTypesDev(); 18151 return mountDebugValue(); 18152 }, 18153 useDeferredValue: function (value) { 18154 currentHookNameInDev = 'useDeferredValue'; 18155 warnInvalidHookAccess(); 18156 mountHookTypesDev(); 18157 return mountDeferredValue(value); 18158 }, 18159 useTransition: function () { 18160 currentHookNameInDev = 'useTransition'; 18161 warnInvalidHookAccess(); 18162 mountHookTypesDev(); 18163 return mountTransition(); 18164 }, 18165 useMutableSource: function (source, getSnapshot, subscribe) { 18166 currentHookNameInDev = 'useMutableSource'; 18167 warnInvalidHookAccess(); 18168 mountHookTypesDev(); 18169 return mountMutableSource(); 18170 }, 18171 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) { 18172 currentHookNameInDev = 'useSyncExternalStore'; 18173 warnInvalidHookAccess(); 18174 mountHookTypesDev(); 18175 return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); 18176 }, 18177 useId: function () { 18178 currentHookNameInDev = 'useId'; 18179 warnInvalidHookAccess(); 18180 mountHookTypesDev(); 18181 return mountId(); 18182 }, 18183 unstable_isNewReconciler: enableNewReconciler 18184 }; 18185 18186 InvalidNestedHooksDispatcherOnUpdateInDEV = { 18187 readContext: function (context) { 18188 warnInvalidContextAccess(); 18189 return readContext(context); 18190 }, 18191 useCallback: function (callback, deps) { 18192 currentHookNameInDev = 'useCallback'; 18193 warnInvalidHookAccess(); 18194 updateHookTypesDev(); 18195 return updateCallback(callback, deps); 18196 }, 18197 useContext: function (context) { 18198 currentHookNameInDev = 'useContext'; 18199 warnInvalidHookAccess(); 18200 updateHookTypesDev(); 18201 return readContext(context); 18202 }, 18203 useEffect: function (create, deps) { 18204 currentHookNameInDev = 'useEffect'; 18205 warnInvalidHookAccess(); 18206 updateHookTypesDev(); 18207 return updateEffect(create, deps); 18208 }, 18209 useImperativeHandle: function (ref, create, deps) { 18210 currentHookNameInDev = 'useImperativeHandle'; 18211 warnInvalidHookAccess(); 18212 updateHookTypesDev(); 18213 return updateImperativeHandle(ref, create, deps); 18214 }, 18215 useInsertionEffect: function (create, deps) { 18216 currentHookNameInDev = 'useInsertionEffect'; 18217 warnInvalidHookAccess(); 18218 updateHookTypesDev(); 18219 return updateInsertionEffect(create, deps); 18220 }, 18221 useLayoutEffect: function (create, deps) { 18222 currentHookNameInDev = 'useLayoutEffect'; 18223 warnInvalidHookAccess(); 18224 updateHookTypesDev(); 18225 return updateLayoutEffect(create, deps); 18226 }, 18227 useMemo: function (create, deps) { 18228 currentHookNameInDev = 'useMemo'; 18229 warnInvalidHookAccess(); 18230 updateHookTypesDev(); 18231 var prevDispatcher = ReactCurrentDispatcher$1.current; 18232 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 18233 18234 try { 18235 return updateMemo(create, deps); 18236 } finally { 18237 ReactCurrentDispatcher$1.current = prevDispatcher; 18238 } 18239 }, 18240 useReducer: function (reducer, initialArg, init) { 18241 currentHookNameInDev = 'useReducer'; 18242 warnInvalidHookAccess(); 18243 updateHookTypesDev(); 18244 var prevDispatcher = ReactCurrentDispatcher$1.current; 18245 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 18246 18247 try { 18248 return updateReducer(reducer, initialArg, init); 18249 } finally { 18250 ReactCurrentDispatcher$1.current = prevDispatcher; 18251 } 18252 }, 18253 useRef: function (initialValue) { 18254 currentHookNameInDev = 'useRef'; 18255 warnInvalidHookAccess(); 18256 updateHookTypesDev(); 18257 return updateRef(); 18258 }, 18259 useState: function (initialState) { 18260 currentHookNameInDev = 'useState'; 18261 warnInvalidHookAccess(); 18262 updateHookTypesDev(); 18263 var prevDispatcher = ReactCurrentDispatcher$1.current; 18264 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 18265 18266 try { 18267 return updateState(initialState); 18268 } finally { 18269 ReactCurrentDispatcher$1.current = prevDispatcher; 18270 } 18271 }, 18272 useDebugValue: function (value, formatterFn) { 18273 currentHookNameInDev = 'useDebugValue'; 18274 warnInvalidHookAccess(); 18275 updateHookTypesDev(); 18276 return updateDebugValue(); 18277 }, 18278 useDeferredValue: function (value) { 18279 currentHookNameInDev = 'useDeferredValue'; 18280 warnInvalidHookAccess(); 18281 updateHookTypesDev(); 18282 return updateDeferredValue(value); 18283 }, 18284 useTransition: function () { 18285 currentHookNameInDev = 'useTransition'; 18286 warnInvalidHookAccess(); 18287 updateHookTypesDev(); 18288 return updateTransition(); 18289 }, 18290 useMutableSource: function (source, getSnapshot, subscribe) { 18291 currentHookNameInDev = 'useMutableSource'; 18292 warnInvalidHookAccess(); 18293 updateHookTypesDev(); 18294 return updateMutableSource(); 18295 }, 18296 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) { 18297 currentHookNameInDev = 'useSyncExternalStore'; 18298 warnInvalidHookAccess(); 18299 updateHookTypesDev(); 18300 return updateSyncExternalStore(subscribe, getSnapshot); 18301 }, 18302 useId: function () { 18303 currentHookNameInDev = 'useId'; 18304 warnInvalidHookAccess(); 18305 updateHookTypesDev(); 18306 return updateId(); 18307 }, 18308 unstable_isNewReconciler: enableNewReconciler 18309 }; 18310 18311 InvalidNestedHooksDispatcherOnRerenderInDEV = { 18312 readContext: function (context) { 18313 warnInvalidContextAccess(); 18314 return readContext(context); 18315 }, 18316 useCallback: function (callback, deps) { 18317 currentHookNameInDev = 'useCallback'; 18318 warnInvalidHookAccess(); 18319 updateHookTypesDev(); 18320 return updateCallback(callback, deps); 18321 }, 18322 useContext: function (context) { 18323 currentHookNameInDev = 'useContext'; 18324 warnInvalidHookAccess(); 18325 updateHookTypesDev(); 18326 return readContext(context); 18327 }, 18328 useEffect: function (create, deps) { 18329 currentHookNameInDev = 'useEffect'; 18330 warnInvalidHookAccess(); 18331 updateHookTypesDev(); 18332 return updateEffect(create, deps); 18333 }, 18334 useImperativeHandle: function (ref, create, deps) { 18335 currentHookNameInDev = 'useImperativeHandle'; 18336 warnInvalidHookAccess(); 18337 updateHookTypesDev(); 18338 return updateImperativeHandle(ref, create, deps); 18339 }, 18340 useInsertionEffect: function (create, deps) { 18341 currentHookNameInDev = 'useInsertionEffect'; 18342 warnInvalidHookAccess(); 18343 updateHookTypesDev(); 18344 return updateInsertionEffect(create, deps); 18345 }, 18346 useLayoutEffect: function (create, deps) { 18347 currentHookNameInDev = 'useLayoutEffect'; 18348 warnInvalidHookAccess(); 18349 updateHookTypesDev(); 18350 return updateLayoutEffect(create, deps); 18351 }, 18352 useMemo: function (create, deps) { 18353 currentHookNameInDev = 'useMemo'; 18354 warnInvalidHookAccess(); 18355 updateHookTypesDev(); 18356 var prevDispatcher = ReactCurrentDispatcher$1.current; 18357 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 18358 18359 try { 18360 return updateMemo(create, deps); 18361 } finally { 18362 ReactCurrentDispatcher$1.current = prevDispatcher; 18363 } 18364 }, 18365 useReducer: function (reducer, initialArg, init) { 18366 currentHookNameInDev = 'useReducer'; 18367 warnInvalidHookAccess(); 18368 updateHookTypesDev(); 18369 var prevDispatcher = ReactCurrentDispatcher$1.current; 18370 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 18371 18372 try { 18373 return rerenderReducer(reducer, initialArg, init); 18374 } finally { 18375 ReactCurrentDispatcher$1.current = prevDispatcher; 18376 } 18377 }, 18378 useRef: function (initialValue) { 18379 currentHookNameInDev = 'useRef'; 18380 warnInvalidHookAccess(); 18381 updateHookTypesDev(); 18382 return updateRef(); 18383 }, 18384 useState: function (initialState) { 18385 currentHookNameInDev = 'useState'; 18386 warnInvalidHookAccess(); 18387 updateHookTypesDev(); 18388 var prevDispatcher = ReactCurrentDispatcher$1.current; 18389 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; 18390 18391 try { 18392 return rerenderState(initialState); 18393 } finally { 18394 ReactCurrentDispatcher$1.current = prevDispatcher; 18395 } 18396 }, 18397 useDebugValue: function (value, formatterFn) { 18398 currentHookNameInDev = 'useDebugValue'; 18399 warnInvalidHookAccess(); 18400 updateHookTypesDev(); 18401 return updateDebugValue(); 18402 }, 18403 useDeferredValue: function (value) { 18404 currentHookNameInDev = 'useDeferredValue'; 18405 warnInvalidHookAccess(); 18406 updateHookTypesDev(); 18407 return rerenderDeferredValue(value); 18408 }, 18409 useTransition: function () { 18410 currentHookNameInDev = 'useTransition'; 18411 warnInvalidHookAccess(); 18412 updateHookTypesDev(); 18413 return rerenderTransition(); 18414 }, 18415 useMutableSource: function (source, getSnapshot, subscribe) { 18416 currentHookNameInDev = 'useMutableSource'; 18417 warnInvalidHookAccess(); 18418 updateHookTypesDev(); 18419 return updateMutableSource(); 18420 }, 18421 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) { 18422 currentHookNameInDev = 'useSyncExternalStore'; 18423 warnInvalidHookAccess(); 18424 updateHookTypesDev(); 18425 return updateSyncExternalStore(subscribe, getSnapshot); 18426 }, 18427 useId: function () { 18428 currentHookNameInDev = 'useId'; 18429 warnInvalidHookAccess(); 18430 updateHookTypesDev(); 18431 return updateId(); 18432 }, 18433 unstable_isNewReconciler: enableNewReconciler 18434 }; 18435} 18436 18437var now$1 = Scheduler.unstable_now; 18438var commitTime = 0; 18439var layoutEffectStartTime = -1; 18440var profilerStartTime = -1; 18441var passiveEffectStartTime = -1; 18442/** 18443 * Tracks whether the current update was a nested/cascading update (scheduled from a layout effect). 18444 * 18445 * The overall sequence is: 18446 * 1. render 18447 * 2. commit (and call `onRender`, `onCommit`) 18448 * 3. check for nested updates 18449 * 4. flush passive effects (and call `onPostCommit`) 18450 * 18451 * Nested updates are identified in step 3 above, 18452 * but step 4 still applies to the work that was just committed. 18453 * We use two flags to track nested updates then: 18454 * one tracks whether the upcoming update is a nested update, 18455 * and the other tracks whether the current update was a nested update. 18456 * The first value gets synced to the second at the start of the render phase. 18457 */ 18458 18459var currentUpdateIsNested = false; 18460var nestedUpdateScheduled = false; 18461 18462function isCurrentUpdateNested() { 18463 return currentUpdateIsNested; 18464} 18465 18466function markNestedUpdateScheduled() { 18467 { 18468 nestedUpdateScheduled = true; 18469 } 18470} 18471 18472function resetNestedUpdateFlag() { 18473 { 18474 currentUpdateIsNested = false; 18475 nestedUpdateScheduled = false; 18476 } 18477} 18478 18479function syncNestedUpdateFlag() { 18480 { 18481 currentUpdateIsNested = nestedUpdateScheduled; 18482 nestedUpdateScheduled = false; 18483 } 18484} 18485 18486function getCommitTime() { 18487 return commitTime; 18488} 18489 18490function recordCommitTime() { 18491 18492 commitTime = now$1(); 18493} 18494 18495function startProfilerTimer(fiber) { 18496 18497 profilerStartTime = now$1(); 18498 18499 if (fiber.actualStartTime < 0) { 18500 fiber.actualStartTime = now$1(); 18501 } 18502} 18503 18504function stopProfilerTimerIfRunning(fiber) { 18505 18506 profilerStartTime = -1; 18507} 18508 18509function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { 18510 18511 if (profilerStartTime >= 0) { 18512 var elapsedTime = now$1() - profilerStartTime; 18513 fiber.actualDuration += elapsedTime; 18514 18515 if (overrideBaseTime) { 18516 fiber.selfBaseDuration = elapsedTime; 18517 } 18518 18519 profilerStartTime = -1; 18520 } 18521} 18522 18523function recordLayoutEffectDuration(fiber) { 18524 18525 if (layoutEffectStartTime >= 0) { 18526 var elapsedTime = now$1() - layoutEffectStartTime; 18527 layoutEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor 18528 // Or the root (for the DevTools Profiler to read) 18529 18530 var parentFiber = fiber.return; 18531 18532 while (parentFiber !== null) { 18533 switch (parentFiber.tag) { 18534 case HostRoot: 18535 var root = parentFiber.stateNode; 18536 root.effectDuration += elapsedTime; 18537 return; 18538 18539 case Profiler: 18540 var parentStateNode = parentFiber.stateNode; 18541 parentStateNode.effectDuration += elapsedTime; 18542 return; 18543 } 18544 18545 parentFiber = parentFiber.return; 18546 } 18547 } 18548} 18549 18550function recordPassiveEffectDuration(fiber) { 18551 18552 if (passiveEffectStartTime >= 0) { 18553 var elapsedTime = now$1() - passiveEffectStartTime; 18554 passiveEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor 18555 // Or the root (for the DevTools Profiler to read) 18556 18557 var parentFiber = fiber.return; 18558 18559 while (parentFiber !== null) { 18560 switch (parentFiber.tag) { 18561 case HostRoot: 18562 var root = parentFiber.stateNode; 18563 18564 if (root !== null) { 18565 root.passiveEffectDuration += elapsedTime; 18566 } 18567 18568 return; 18569 18570 case Profiler: 18571 var parentStateNode = parentFiber.stateNode; 18572 18573 if (parentStateNode !== null) { 18574 // Detached fibers have their state node cleared out. 18575 // In this case, the return pointer is also cleared out, 18576 // so we won't be able to report the time spent in this Profiler's subtree. 18577 parentStateNode.passiveEffectDuration += elapsedTime; 18578 } 18579 18580 return; 18581 } 18582 18583 parentFiber = parentFiber.return; 18584 } 18585 } 18586} 18587 18588function startLayoutEffectTimer() { 18589 18590 layoutEffectStartTime = now$1(); 18591} 18592 18593function startPassiveEffectTimer() { 18594 18595 passiveEffectStartTime = now$1(); 18596} 18597 18598function transferActualDuration(fiber) { 18599 // Transfer time spent rendering these children so we don't lose it 18600 // after we rerender. This is used as a helper in special cases 18601 // where we should count the work of multiple passes. 18602 var child = fiber.child; 18603 18604 while (child) { 18605 fiber.actualDuration += child.actualDuration; 18606 child = child.sibling; 18607 } 18608} 18609 18610function createCapturedValueAtFiber(value, source) { 18611 // If the value is an error, call this function immediately after it is thrown 18612 // so the stack is accurate. 18613 return { 18614 value: value, 18615 source: source, 18616 stack: getStackByFiberInDevAndProd(source), 18617 digest: null 18618 }; 18619} 18620function createCapturedValue(value, digest, stack) { 18621 return { 18622 value: value, 18623 source: null, 18624 stack: stack != null ? stack : null, 18625 digest: digest != null ? digest : null 18626 }; 18627} 18628 18629// This module is forked in different environments. 18630// By default, return `true` to log errors to the console. 18631// Forks can return `false` if this isn't desirable. 18632function showErrorDialog(boundary, errorInfo) { 18633 return true; 18634} 18635 18636function logCapturedError(boundary, errorInfo) { 18637 try { 18638 var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging. 18639 // This enables renderers like ReactNative to better manage redbox behavior. 18640 18641 if (logError === false) { 18642 return; 18643 } 18644 18645 var error = errorInfo.value; 18646 18647 if (true) { 18648 var source = errorInfo.source; 18649 var stack = errorInfo.stack; 18650 var componentStack = stack !== null ? stack : ''; // Browsers support silencing uncaught errors by calling 18651 // `preventDefault()` in window `error` handler. 18652 // We record this information as an expando on the error. 18653 18654 if (error != null && error._suppressLogging) { 18655 if (boundary.tag === ClassComponent) { 18656 // The error is recoverable and was silenced. 18657 // Ignore it and don't print the stack addendum. 18658 // This is handy for testing error boundaries without noise. 18659 return; 18660 } // The error is fatal. Since the silencing might have 18661 // been accidental, we'll surface it anyway. 18662 // However, the browser would have silenced the original error 18663 // so we'll print it first, and then print the stack addendum. 18664 18665 18666 console['error'](error); // Don't transform to our wrapper 18667 // For a more detailed description of this block, see: 18668 // https://github.com/facebook/react/pull/13384 18669 } 18670 18671 var componentName = source ? getComponentNameFromFiber(source) : null; 18672 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:'; 18673 var errorBoundaryMessage; 18674 18675 if (boundary.tag === HostRoot) { 18676 errorBoundaryMessage = 'Consider adding an error boundary to your tree to customize error handling behavior.\n' + 'Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.'; 18677 } else { 18678 var errorBoundaryName = getComponentNameFromFiber(boundary) || 'Anonymous'; 18679 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + "."); 18680 } 18681 18682 var combinedMessage = componentNameMessage + "\n" + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack. 18683 // We don't include the original error message and JS stack because the browser 18684 // has already printed it. Even if the application swallows the error, it is still 18685 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. 18686 18687 console['error'](combinedMessage); // Don't transform to our wrapper 18688 } else { 18689 // In production, we print the error directly. 18690 // This will include the message, the JS stack, and anything the browser wants to show. 18691 // We pass the error object instead of custom message so that the browser displays the error natively. 18692 console['error'](error); // Don't transform to our wrapper 18693 } 18694 } catch (e) { 18695 // This method must not throw, or React internal state will get messed up. 18696 // If console.error is overridden, or logCapturedError() shows a dialog that throws, 18697 // we want to report this error outside of the normal stack as a last resort. 18698 // https://github.com/facebook/react/issues/13188 18699 setTimeout(function () { 18700 throw e; 18701 }); 18702 } 18703} 18704 18705var PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map; 18706 18707function createRootErrorUpdate(fiber, errorInfo, lane) { 18708 var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null. 18709 18710 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property 18711 // being called "element". 18712 18713 update.payload = { 18714 element: null 18715 }; 18716 var error = errorInfo.value; 18717 18718 update.callback = function () { 18719 onUncaughtError(error); 18720 logCapturedError(fiber, errorInfo); 18721 }; 18722 18723 return update; 18724} 18725 18726function createClassErrorUpdate(fiber, errorInfo, lane) { 18727 var update = createUpdate(NoTimestamp, lane); 18728 update.tag = CaptureUpdate; 18729 var getDerivedStateFromError = fiber.type.getDerivedStateFromError; 18730 18731 if (typeof getDerivedStateFromError === 'function') { 18732 var error$1 = errorInfo.value; 18733 18734 update.payload = function () { 18735 return getDerivedStateFromError(error$1); 18736 }; 18737 18738 update.callback = function () { 18739 { 18740 markFailedErrorBoundaryForHotReloading(fiber); 18741 } 18742 18743 logCapturedError(fiber, errorInfo); 18744 }; 18745 } 18746 18747 var inst = fiber.stateNode; 18748 18749 if (inst !== null && typeof inst.componentDidCatch === 'function') { 18750 update.callback = function callback() { 18751 { 18752 markFailedErrorBoundaryForHotReloading(fiber); 18753 } 18754 18755 logCapturedError(fiber, errorInfo); 18756 18757 if (typeof getDerivedStateFromError !== 'function') { 18758 // To preserve the preexisting retry behavior of error boundaries, 18759 // we keep track of which ones already failed during this batch. 18760 // This gets reset before we yield back to the browser. 18761 // TODO: Warn in strict mode if getDerivedStateFromError is 18762 // not defined. 18763 markLegacyErrorBoundaryAsFailed(this); 18764 } 18765 18766 var error$1 = errorInfo.value; 18767 var stack = errorInfo.stack; 18768 this.componentDidCatch(error$1, { 18769 componentStack: stack !== null ? stack : '' 18770 }); 18771 18772 { 18773 if (typeof getDerivedStateFromError !== 'function') { 18774 // If componentDidCatch is the only error boundary method defined, 18775 // then it needs to call setState to recover from errors. 18776 // If no state update is scheduled then the boundary will swallow the error. 18777 if (!includesSomeLane(fiber.lanes, SyncLane)) { 18778 error('%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentNameFromFiber(fiber) || 'Unknown'); 18779 } 18780 } 18781 } 18782 }; 18783 } 18784 18785 return update; 18786} 18787 18788function attachPingListener(root, wakeable, lanes) { 18789 // Attach a ping listener 18790 // 18791 // The data might resolve before we have a chance to commit the fallback. Or, 18792 // in the case of a refresh, we'll never commit a fallback. So we need to 18793 // attach a listener now. When it resolves ("pings"), we can decide whether to 18794 // try rendering the tree again. 18795 // 18796 // Only attach a listener if one does not already exist for the lanes 18797 // we're currently rendering (which acts like a "thread ID" here). 18798 // 18799 // We only need to do this in concurrent mode. Legacy Suspense always 18800 // commits fallbacks synchronously, so there are no pings. 18801 var pingCache = root.pingCache; 18802 var threadIDs; 18803 18804 if (pingCache === null) { 18805 pingCache = root.pingCache = new PossiblyWeakMap$1(); 18806 threadIDs = new Set(); 18807 pingCache.set(wakeable, threadIDs); 18808 } else { 18809 threadIDs = pingCache.get(wakeable); 18810 18811 if (threadIDs === undefined) { 18812 threadIDs = new Set(); 18813 pingCache.set(wakeable, threadIDs); 18814 } 18815 } 18816 18817 if (!threadIDs.has(lanes)) { 18818 // Memoize using the thread ID to prevent redundant listeners. 18819 threadIDs.add(lanes); 18820 var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); 18821 18822 { 18823 if (isDevToolsPresent) { 18824 // If we have pending work still, restore the original updaters 18825 restorePendingUpdaters(root, lanes); 18826 } 18827 } 18828 18829 wakeable.then(ping, ping); 18830 } 18831} 18832 18833function attachRetryListener(suspenseBoundary, root, wakeable, lanes) { 18834 // Retry listener 18835 // 18836 // If the fallback does commit, we need to attach a different type of 18837 // listener. This one schedules an update on the Suspense boundary to turn 18838 // the fallback state off. 18839 // 18840 // Stash the wakeable on the boundary fiber so we can access it in the 18841 // commit phase. 18842 // 18843 // When the wakeable resolves, we'll attempt to render the boundary 18844 // again ("retry"). 18845 var wakeables = suspenseBoundary.updateQueue; 18846 18847 if (wakeables === null) { 18848 var updateQueue = new Set(); 18849 updateQueue.add(wakeable); 18850 suspenseBoundary.updateQueue = updateQueue; 18851 } else { 18852 wakeables.add(wakeable); 18853 } 18854} 18855 18856function resetSuspendedComponent(sourceFiber, rootRenderLanes) { 18857 // A legacy mode Suspense quirk, only relevant to hook components. 18858 18859 18860 var tag = sourceFiber.tag; 18861 18862 if ((sourceFiber.mode & ConcurrentMode) === NoMode && (tag === FunctionComponent || tag === ForwardRef || tag === SimpleMemoComponent)) { 18863 var currentSource = sourceFiber.alternate; 18864 18865 if (currentSource) { 18866 sourceFiber.updateQueue = currentSource.updateQueue; 18867 sourceFiber.memoizedState = currentSource.memoizedState; 18868 sourceFiber.lanes = currentSource.lanes; 18869 } else { 18870 sourceFiber.updateQueue = null; 18871 sourceFiber.memoizedState = null; 18872 } 18873 } 18874} 18875 18876function getNearestSuspenseBoundaryToCapture(returnFiber) { 18877 var node = returnFiber; 18878 18879 do { 18880 if (node.tag === SuspenseComponent && shouldCaptureSuspense(node)) { 18881 return node; 18882 } // This boundary already captured during this render. Continue to the next 18883 // boundary. 18884 18885 18886 node = node.return; 18887 } while (node !== null); 18888 18889 return null; 18890} 18891 18892function markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes) { 18893 // This marks a Suspense boundary so that when we're unwinding the stack, 18894 // it captures the suspended "exception" and does a second (fallback) pass. 18895 if ((suspenseBoundary.mode & ConcurrentMode) === NoMode) { 18896 // Legacy Mode Suspense 18897 // 18898 // If the boundary is in legacy mode, we should *not* 18899 // suspend the commit. Pretend as if the suspended component rendered 18900 // null and keep rendering. When the Suspense boundary completes, 18901 // we'll do a second pass to render the fallback. 18902 if (suspenseBoundary === returnFiber) { 18903 // Special case where we suspended while reconciling the children of 18904 // a Suspense boundary's inner Offscreen wrapper fiber. This happens 18905 // when a React.lazy component is a direct child of a 18906 // Suspense boundary. 18907 // 18908 // Suspense boundaries are implemented as multiple fibers, but they 18909 // are a single conceptual unit. The legacy mode behavior where we 18910 // pretend the suspended fiber committed as `null` won't work, 18911 // because in this case the "suspended" fiber is the inner 18912 // Offscreen wrapper. 18913 // 18914 // Because the contents of the boundary haven't started rendering 18915 // yet (i.e. nothing in the tree has partially rendered) we can 18916 // switch to the regular, concurrent mode behavior: mark the 18917 // boundary with ShouldCapture and enter the unwind phase. 18918 suspenseBoundary.flags |= ShouldCapture; 18919 } else { 18920 suspenseBoundary.flags |= DidCapture; 18921 sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. 18922 // But we shouldn't call any lifecycle methods or callbacks. Remove 18923 // all lifecycle effect tags. 18924 18925 sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); 18926 18927 if (sourceFiber.tag === ClassComponent) { 18928 var currentSourceFiber = sourceFiber.alternate; 18929 18930 if (currentSourceFiber === null) { 18931 // This is a new mount. Change the tag so it's not mistaken for a 18932 // completed class component. For example, we should not call 18933 // componentWillUnmount if it is deleted. 18934 sourceFiber.tag = IncompleteClassComponent; 18935 } else { 18936 // When we try rendering again, we should not reuse the current fiber, 18937 // since it's known to be in an inconsistent state. Use a force update to 18938 // prevent a bail out. 18939 var update = createUpdate(NoTimestamp, SyncLane); 18940 update.tag = ForceUpdate; 18941 enqueueUpdate(sourceFiber, update, SyncLane); 18942 } 18943 } // The source fiber did not complete. Mark it with Sync priority to 18944 // indicate that it still has pending work. 18945 18946 18947 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); 18948 } 18949 18950 return suspenseBoundary; 18951 } // Confirmed that the boundary is in a concurrent mode tree. Continue 18952 // with the normal suspend path. 18953 // 18954 // After this we'll use a set of heuristics to determine whether this 18955 // render pass will run to completion or restart or "suspend" the commit. 18956 // The actual logic for this is spread out in different places. 18957 // 18958 // This first principle is that if we're going to suspend when we complete 18959 // a root, then we should also restart if we get an update or ping that 18960 // might unsuspend it, and vice versa. The only reason to suspend is 18961 // because you think you might want to restart before committing. However, 18962 // it doesn't make sense to restart only while in the period we're suspended. 18963 // 18964 // Restarting too aggressively is also not good because it starves out any 18965 // intermediate loading state. So we use heuristics to determine when. 18966 // Suspense Heuristics 18967 // 18968 // If nothing threw a Promise or all the same fallbacks are already showing, 18969 // then don't suspend/restart. 18970 // 18971 // If this is an initial render of a new tree of Suspense boundaries and 18972 // those trigger a fallback, then don't suspend/restart. We want to ensure 18973 // that we can show the initial loading state as quickly as possible. 18974 // 18975 // If we hit a "Delayed" case, such as when we'd switch from content back into 18976 // a fallback, then we should always suspend/restart. Transitions apply 18977 // to this case. If none is defined, JND is used instead. 18978 // 18979 // If we're already showing a fallback and it gets "retried", allowing us to show 18980 // another level, but there's still an inner boundary that would show a fallback, 18981 // then we suspend/restart for 500ms since the last time we showed a fallback 18982 // anywhere in the tree. This effectively throttles progressive loading into a 18983 // consistent train of commits. This also gives us an opportunity to restart to 18984 // get to the completed state slightly earlier. 18985 // 18986 // If there's ambiguity due to batching it's resolved in preference of: 18987 // 1) "delayed", 2) "initial render", 3) "retry". 18988 // 18989 // We want to ensure that a "busy" state doesn't get force committed. We want to 18990 // ensure that new initial loading states can commit as soon as possible. 18991 18992 18993 suspenseBoundary.flags |= ShouldCapture; // TODO: I think we can remove this, since we now use `DidCapture` in 18994 // the begin phase to prevent an early bailout. 18995 18996 suspenseBoundary.lanes = rootRenderLanes; 18997 return suspenseBoundary; 18998} 18999 19000function throwException(root, returnFiber, sourceFiber, value, rootRenderLanes) { 19001 // The source fiber did not complete. 19002 sourceFiber.flags |= Incomplete; 19003 19004 { 19005 if (isDevToolsPresent) { 19006 // If we have pending work still, restore the original updaters 19007 restorePendingUpdaters(root, rootRenderLanes); 19008 } 19009 } 19010 19011 if (value !== null && typeof value === 'object' && typeof value.then === 'function') { 19012 // This is a wakeable. The component suspended. 19013 var wakeable = value; 19014 resetSuspendedComponent(sourceFiber); 19015 19016 { 19017 if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) { 19018 markDidThrowWhileHydratingDEV(); 19019 } 19020 } 19021 19022 19023 var suspenseBoundary = getNearestSuspenseBoundaryToCapture(returnFiber); 19024 19025 if (suspenseBoundary !== null) { 19026 suspenseBoundary.flags &= ~ForceClientRender; 19027 markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes); // We only attach ping listeners in concurrent mode. Legacy Suspense always 19028 // commits fallbacks synchronously, so there are no pings. 19029 19030 if (suspenseBoundary.mode & ConcurrentMode) { 19031 attachPingListener(root, wakeable, rootRenderLanes); 19032 } 19033 19034 attachRetryListener(suspenseBoundary, root, wakeable); 19035 return; 19036 } else { 19037 // No boundary was found. Unless this is a sync update, this is OK. 19038 // We can suspend and wait for more data to arrive. 19039 if (!includesSyncLane(rootRenderLanes)) { 19040 // This is not a sync update. Suspend. Since we're not activating a 19041 // Suspense boundary, this will unwind all the way to the root without 19042 // performing a second pass to render a fallback. (This is arguably how 19043 // refresh transitions should work, too, since we're not going to commit 19044 // the fallbacks anyway.) 19045 // 19046 // This case also applies to initial hydration. 19047 attachPingListener(root, wakeable, rootRenderLanes); 19048 renderDidSuspendDelayIfPossible(); 19049 return; 19050 } // This is a sync/discrete update. We treat this case like an error 19051 // because discrete renders are expected to produce a complete tree 19052 // synchronously to maintain consistency with external state. 19053 19054 19055 var uncaughtSuspenseError = new Error('A component suspended while responding to synchronous input. This ' + 'will cause the UI to be replaced with a loading indicator. To ' + 'fix, updates that suspend should be wrapped ' + 'with startTransition.'); // If we're outside a transition, fall through to the regular error path. 19056 // The error will be caught by the nearest suspense boundary. 19057 19058 value = uncaughtSuspenseError; 19059 } 19060 } else { 19061 // This is a regular error, not a Suspense wakeable. 19062 if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) { 19063 markDidThrowWhileHydratingDEV(); 19064 19065 var _suspenseBoundary = getNearestSuspenseBoundaryToCapture(returnFiber); // If the error was thrown during hydration, we may be able to recover by 19066 // discarding the dehydrated content and switching to a client render. 19067 // Instead of surfacing the error, find the nearest Suspense boundary 19068 // and render it again without hydration. 19069 19070 19071 if (_suspenseBoundary !== null) { 19072 if ((_suspenseBoundary.flags & ShouldCapture) === NoFlags) { 19073 // Set a flag to indicate that we should try rendering the normal 19074 // children again, not the fallback. 19075 _suspenseBoundary.flags |= ForceClientRender; 19076 } 19077 19078 markSuspenseBoundaryShouldCapture(_suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes); // Even though the user may not be affected by this error, we should 19079 // still log it so it can be fixed. 19080 19081 queueHydrationError(createCapturedValueAtFiber(value, sourceFiber)); 19082 return; 19083 } 19084 } 19085 } 19086 19087 value = createCapturedValueAtFiber(value, sourceFiber); 19088 renderDidError(value); // We didn't find a boundary that could handle this type of exception. Start 19089 // over and traverse parent path again, this time treating the exception 19090 // as an error. 19091 19092 var workInProgress = returnFiber; 19093 19094 do { 19095 switch (workInProgress.tag) { 19096 case HostRoot: 19097 { 19098 var _errorInfo = value; 19099 workInProgress.flags |= ShouldCapture; 19100 var lane = pickArbitraryLane(rootRenderLanes); 19101 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); 19102 var update = createRootErrorUpdate(workInProgress, _errorInfo, lane); 19103 enqueueCapturedUpdate(workInProgress, update); 19104 return; 19105 } 19106 19107 case ClassComponent: 19108 // Capture and retry 19109 var errorInfo = value; 19110 var ctor = workInProgress.type; 19111 var instance = workInProgress.stateNode; 19112 19113 if ((workInProgress.flags & DidCapture) === NoFlags && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) { 19114 workInProgress.flags |= ShouldCapture; 19115 19116 var _lane = pickArbitraryLane(rootRenderLanes); 19117 19118 workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state 19119 19120 var _update = createClassErrorUpdate(workInProgress, errorInfo, _lane); 19121 19122 enqueueCapturedUpdate(workInProgress, _update); 19123 return; 19124 } 19125 19126 break; 19127 } 19128 19129 workInProgress = workInProgress.return; 19130 } while (workInProgress !== null); 19131} 19132 19133function getSuspendedCache() { 19134 { 19135 return null; 19136 } // This function is called when a Suspense boundary suspends. It returns the 19137} 19138 19139var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; 19140var didReceiveUpdate = false; 19141var didWarnAboutBadClass; 19142var didWarnAboutModulePatternComponent; 19143var didWarnAboutContextTypeOnFunctionComponent; 19144var didWarnAboutGetDerivedStateOnFunctionComponent; 19145var didWarnAboutFunctionRefs; 19146var didWarnAboutReassigningProps; 19147var didWarnAboutRevealOrder; 19148var didWarnAboutTailOptions; 19149 19150{ 19151 didWarnAboutBadClass = {}; 19152 didWarnAboutModulePatternComponent = {}; 19153 didWarnAboutContextTypeOnFunctionComponent = {}; 19154 didWarnAboutGetDerivedStateOnFunctionComponent = {}; 19155 didWarnAboutFunctionRefs = {}; 19156 didWarnAboutReassigningProps = false; 19157 didWarnAboutRevealOrder = {}; 19158 didWarnAboutTailOptions = {}; 19159} 19160 19161function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { 19162 if (current === null) { 19163 // If this is a fresh new component that hasn't been rendered yet, we 19164 // won't update its child set by applying minimal side-effects. Instead, 19165 // we will add them all to the child before it gets rendered. That means 19166 // we can optimize this reconciliation pass by not tracking side-effects. 19167 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderLanes); 19168 } else { 19169 // If the current child is the same as the work in progress, it means that 19170 // we haven't yet started any work on these children. Therefore, we use 19171 // the clone algorithm to create a copy of all the current children. 19172 // If we had any progressed work already, that is invalid at this point so 19173 // let's throw it out. 19174 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderLanes); 19175 } 19176} 19177 19178function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes) { 19179 // This function is fork of reconcileChildren. It's used in cases where we 19180 // want to reconcile without matching against the existing set. This has the 19181 // effect of all current children being unmounted; even if the type and key 19182 // are the same, the old child is unmounted and a new child is created. 19183 // 19184 // To do this, we're going to go through the reconcile algorithm twice. In 19185 // the first pass, we schedule a deletion for all the current children by 19186 // passing null. 19187 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderLanes); // In the second pass, we mount the new children. The trick here is that we 19188 // pass null in place of where we usually pass the current child set. This has 19189 // the effect of remounting all children regardless of whether their 19190 // identities match. 19191 19192 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes); 19193} 19194 19195function updateForwardRef(current, workInProgress, Component, nextProps, renderLanes) { 19196 // TODO: current can be non-null here even if the component 19197 // hasn't yet mounted. This happens after the first render suspends. 19198 // We'll need to figure out if this is fine or can cause issues. 19199 { 19200 if (workInProgress.type !== workInProgress.elementType) { 19201 // Lazy component props can't be validated in createElement 19202 // because they're only guaranteed to be resolved here. 19203 var innerPropTypes = Component.propTypes; 19204 19205 if (innerPropTypes) { 19206 checkPropTypes(innerPropTypes, nextProps, // Resolved props 19207 'prop', getComponentNameFromType(Component)); 19208 } 19209 } 19210 } 19211 19212 var render = Component.render; 19213 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent 19214 19215 var nextChildren; 19216 var hasId; 19217 prepareToReadContext(workInProgress, renderLanes); 19218 19219 { 19220 markComponentRenderStarted(workInProgress); 19221 } 19222 19223 { 19224 ReactCurrentOwner$1.current = workInProgress; 19225 setIsRendering(true); 19226 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes); 19227 hasId = checkDidRenderIdHook(); 19228 19229 if ( workInProgress.mode & StrictLegacyMode) { 19230 setIsStrictModeForDevtools(true); 19231 19232 try { 19233 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes); 19234 hasId = checkDidRenderIdHook(); 19235 } finally { 19236 setIsStrictModeForDevtools(false); 19237 } 19238 } 19239 19240 setIsRendering(false); 19241 } 19242 19243 { 19244 markComponentRenderStopped(); 19245 } 19246 19247 if (current !== null && !didReceiveUpdate) { 19248 bailoutHooks(current, workInProgress, renderLanes); 19249 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 19250 } 19251 19252 if (getIsHydrating() && hasId) { 19253 pushMaterializedTreeId(workInProgress); 19254 } // React DevTools reads this flag. 19255 19256 19257 workInProgress.flags |= PerformedWork; 19258 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 19259 return workInProgress.child; 19260} 19261 19262function updateMemoComponent(current, workInProgress, Component, nextProps, renderLanes) { 19263 if (current === null) { 19264 var type = Component.type; 19265 19266 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either. 19267 Component.defaultProps === undefined) { 19268 var resolvedType = type; 19269 19270 { 19271 resolvedType = resolveFunctionForHotReloading(type); 19272 } // If this is a plain function component without default props, 19273 // and with only the default shallow comparison, we upgrade it 19274 // to a SimpleMemoComponent to allow fast path updates. 19275 19276 19277 workInProgress.tag = SimpleMemoComponent; 19278 workInProgress.type = resolvedType; 19279 19280 { 19281 validateFunctionComponentInDev(workInProgress, type); 19282 } 19283 19284 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, renderLanes); 19285 } 19286 19287 { 19288 var innerPropTypes = type.propTypes; 19289 19290 if (innerPropTypes) { 19291 // Inner memo component props aren't currently validated in createElement. 19292 // We could move it there, but we'd still need this for lazy code path. 19293 checkPropTypes(innerPropTypes, nextProps, // Resolved props 19294 'prop', getComponentNameFromType(type)); 19295 } 19296 } 19297 19298 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, workInProgress, workInProgress.mode, renderLanes); 19299 child.ref = workInProgress.ref; 19300 child.return = workInProgress; 19301 workInProgress.child = child; 19302 return child; 19303 } 19304 19305 { 19306 var _type = Component.type; 19307 var _innerPropTypes = _type.propTypes; 19308 19309 if (_innerPropTypes) { 19310 // Inner memo component props aren't currently validated in createElement. 19311 // We could move it there, but we'd still need this for lazy code path. 19312 checkPropTypes(_innerPropTypes, nextProps, // Resolved props 19313 'prop', getComponentNameFromType(_type)); 19314 } 19315 } 19316 19317 var currentChild = current.child; // This is always exactly one child 19318 19319 var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes); 19320 19321 if (!hasScheduledUpdateOrContext) { 19322 // This will be the props with resolved defaultProps, 19323 // unlike current.memoizedProps which will be the unresolved ones. 19324 var prevProps = currentChild.memoizedProps; // Default to shallow comparison 19325 19326 var compare = Component.compare; 19327 compare = compare !== null ? compare : shallowEqual; 19328 19329 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { 19330 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 19331 } 19332 } // React DevTools reads this flag. 19333 19334 19335 workInProgress.flags |= PerformedWork; 19336 var newChild = createWorkInProgress(currentChild, nextProps); 19337 newChild.ref = workInProgress.ref; 19338 newChild.return = workInProgress; 19339 workInProgress.child = newChild; 19340 return newChild; 19341} 19342 19343function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, renderLanes) { 19344 // TODO: current can be non-null here even if the component 19345 // hasn't yet mounted. This happens when the inner render suspends. 19346 // We'll need to figure out if this is fine or can cause issues. 19347 { 19348 if (workInProgress.type !== workInProgress.elementType) { 19349 // Lazy component props can't be validated in createElement 19350 // because they're only guaranteed to be resolved here. 19351 var outerMemoType = workInProgress.elementType; 19352 19353 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) { 19354 // We warn when you define propTypes on lazy() 19355 // so let's just skip over it to find memo() outer wrapper. 19356 // Inner props for memo are validated later. 19357 var lazyComponent = outerMemoType; 19358 var payload = lazyComponent._payload; 19359 var init = lazyComponent._init; 19360 19361 try { 19362 outerMemoType = init(payload); 19363 } catch (x) { 19364 outerMemoType = null; 19365 } // Inner propTypes will be validated in the function component path. 19366 19367 19368 var outerPropTypes = outerMemoType && outerMemoType.propTypes; 19369 19370 if (outerPropTypes) { 19371 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps) 19372 'prop', getComponentNameFromType(outerMemoType)); 19373 } 19374 } 19375 } 19376 } 19377 19378 if (current !== null) { 19379 var prevProps = current.memoizedProps; 19380 19381 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload. 19382 workInProgress.type === current.type )) { 19383 didReceiveUpdate = false; // The props are shallowly equal. Reuse the previous props object, like we 19384 // would during a normal fiber bailout. 19385 // 19386 // We don't have strong guarantees that the props object is referentially 19387 // equal during updates where we can't bail out anyway — like if the props 19388 // are shallowly equal, but there's a local state or context update in the 19389 // same batch. 19390 // 19391 // However, as a principle, we should aim to make the behavior consistent 19392 // across different ways of memoizing a component. For example, React.memo 19393 // has a different internal Fiber layout if you pass a normal function 19394 // component (SimpleMemoComponent) versus if you pass a different type 19395 // like forwardRef (MemoComponent). But this is an implementation detail. 19396 // Wrapping a component in forwardRef (or React.lazy, etc) shouldn't 19397 // affect whether the props object is reused during a bailout. 19398 19399 workInProgress.pendingProps = nextProps = prevProps; 19400 19401 if (!checkScheduledUpdateOrContext(current, renderLanes)) { 19402 // The pending lanes were cleared at the beginning of beginWork. We're 19403 // about to bail out, but there might be other lanes that weren't 19404 // included in the current render. Usually, the priority level of the 19405 // remaining updates is accumulated during the evaluation of the 19406 // component (i.e. when processing the update queue). But since since 19407 // we're bailing out early *without* evaluating the component, we need 19408 // to account for it here, too. Reset to the value of the current fiber. 19409 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent, 19410 // because a MemoComponent fiber does not have hooks or an update queue; 19411 // rather, it wraps around an inner component, which may or may not 19412 // contains hooks. 19413 // TODO: Move the reset at in beginWork out of the common path so that 19414 // this is no longer necessary. 19415 workInProgress.lanes = current.lanes; 19416 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 19417 } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { 19418 // This is a special case that only exists for legacy mode. 19419 // See https://github.com/facebook/react/pull/19216. 19420 didReceiveUpdate = true; 19421 } 19422 } 19423 } 19424 19425 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes); 19426} 19427 19428function updateOffscreenComponent(current, workInProgress, renderLanes) { 19429 var nextProps = workInProgress.pendingProps; 19430 var nextChildren = nextProps.children; 19431 var prevState = current !== null ? current.memoizedState : null; 19432 19433 if (nextProps.mode === 'hidden' || enableLegacyHidden ) { 19434 // Rendering a hidden tree. 19435 if ((workInProgress.mode & ConcurrentMode) === NoMode) { 19436 // In legacy sync mode, don't defer the subtree. Render it now. 19437 // TODO: Consider how Offscreen should work with transitions in the future 19438 var nextState = { 19439 baseLanes: NoLanes, 19440 cachePool: null, 19441 transitions: null 19442 }; 19443 workInProgress.memoizedState = nextState; 19444 19445 pushRenderLanes(workInProgress, renderLanes); 19446 } else if (!includesSomeLane(renderLanes, OffscreenLane)) { 19447 var spawnedCachePool = null; // We're hidden, and we're not rendering at Offscreen. We will bail out 19448 // and resume this tree later. 19449 19450 var nextBaseLanes; 19451 19452 if (prevState !== null) { 19453 var prevBaseLanes = prevState.baseLanes; 19454 nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes); 19455 } else { 19456 nextBaseLanes = renderLanes; 19457 } // Schedule this fiber to re-render at offscreen priority. Then bailout. 19458 19459 19460 workInProgress.lanes = workInProgress.childLanes = laneToLanes(OffscreenLane); 19461 var _nextState = { 19462 baseLanes: nextBaseLanes, 19463 cachePool: spawnedCachePool, 19464 transitions: null 19465 }; 19466 workInProgress.memoizedState = _nextState; 19467 workInProgress.updateQueue = null; 19468 // to avoid a push/pop misalignment. 19469 19470 19471 pushRenderLanes(workInProgress, nextBaseLanes); 19472 19473 return null; 19474 } else { 19475 // This is the second render. The surrounding visible content has already 19476 // committed. Now we resume rendering the hidden tree. 19477 // Rendering at offscreen, so we can clear the base lanes. 19478 var _nextState2 = { 19479 baseLanes: NoLanes, 19480 cachePool: null, 19481 transitions: null 19482 }; 19483 workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. 19484 19485 var subtreeRenderLanes = prevState !== null ? prevState.baseLanes : renderLanes; 19486 19487 pushRenderLanes(workInProgress, subtreeRenderLanes); 19488 } 19489 } else { 19490 // Rendering a visible tree. 19491 var _subtreeRenderLanes; 19492 19493 if (prevState !== null) { 19494 // We're going from hidden -> visible. 19495 _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); 19496 19497 workInProgress.memoizedState = null; 19498 } else { 19499 // We weren't previously hidden, and we still aren't, so there's nothing 19500 // special to do. Need to push to the stack regardless, though, to avoid 19501 // a push/pop misalignment. 19502 _subtreeRenderLanes = renderLanes; 19503 } 19504 19505 pushRenderLanes(workInProgress, _subtreeRenderLanes); 19506 } 19507 19508 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 19509 return workInProgress.child; 19510} // Note: These happen to have identical begin phases, for now. We shouldn't hold 19511 19512function updateFragment(current, workInProgress, renderLanes) { 19513 var nextChildren = workInProgress.pendingProps; 19514 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 19515 return workInProgress.child; 19516} 19517 19518function updateMode(current, workInProgress, renderLanes) { 19519 var nextChildren = workInProgress.pendingProps.children; 19520 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 19521 return workInProgress.child; 19522} 19523 19524function updateProfiler(current, workInProgress, renderLanes) { 19525 { 19526 workInProgress.flags |= Update; 19527 19528 { 19529 // Reset effect durations for the next eventual effect phase. 19530 // These are reset during render to allow the DevTools commit hook a chance to read them, 19531 var stateNode = workInProgress.stateNode; 19532 stateNode.effectDuration = 0; 19533 stateNode.passiveEffectDuration = 0; 19534 } 19535 } 19536 19537 var nextProps = workInProgress.pendingProps; 19538 var nextChildren = nextProps.children; 19539 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 19540 return workInProgress.child; 19541} 19542 19543function markRef(current, workInProgress) { 19544 var ref = workInProgress.ref; 19545 19546 if (current === null && ref !== null || current !== null && current.ref !== ref) { 19547 // Schedule a Ref effect 19548 workInProgress.flags |= Ref; 19549 19550 { 19551 workInProgress.flags |= RefStatic; 19552 } 19553 } 19554} 19555 19556function updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes) { 19557 { 19558 if (workInProgress.type !== workInProgress.elementType) { 19559 // Lazy component props can't be validated in createElement 19560 // because they're only guaranteed to be resolved here. 19561 var innerPropTypes = Component.propTypes; 19562 19563 if (innerPropTypes) { 19564 checkPropTypes(innerPropTypes, nextProps, // Resolved props 19565 'prop', getComponentNameFromType(Component)); 19566 } 19567 } 19568 } 19569 19570 var context; 19571 19572 { 19573 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); 19574 context = getMaskedContext(workInProgress, unmaskedContext); 19575 } 19576 19577 var nextChildren; 19578 var hasId; 19579 prepareToReadContext(workInProgress, renderLanes); 19580 19581 { 19582 markComponentRenderStarted(workInProgress); 19583 } 19584 19585 { 19586 ReactCurrentOwner$1.current = workInProgress; 19587 setIsRendering(true); 19588 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes); 19589 hasId = checkDidRenderIdHook(); 19590 19591 if ( workInProgress.mode & StrictLegacyMode) { 19592 setIsStrictModeForDevtools(true); 19593 19594 try { 19595 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes); 19596 hasId = checkDidRenderIdHook(); 19597 } finally { 19598 setIsStrictModeForDevtools(false); 19599 } 19600 } 19601 19602 setIsRendering(false); 19603 } 19604 19605 { 19606 markComponentRenderStopped(); 19607 } 19608 19609 if (current !== null && !didReceiveUpdate) { 19610 bailoutHooks(current, workInProgress, renderLanes); 19611 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 19612 } 19613 19614 if (getIsHydrating() && hasId) { 19615 pushMaterializedTreeId(workInProgress); 19616 } // React DevTools reads this flag. 19617 19618 19619 workInProgress.flags |= PerformedWork; 19620 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 19621 return workInProgress.child; 19622} 19623 19624function updateClassComponent(current, workInProgress, Component, nextProps, renderLanes) { 19625 { 19626 // This is used by DevTools to force a boundary to error. 19627 switch (shouldError(workInProgress)) { 19628 case false: 19629 { 19630 var _instance = workInProgress.stateNode; 19631 var ctor = workInProgress.type; // TODO This way of resetting the error boundary state is a hack. 19632 // Is there a better way to do this? 19633 19634 var tempInstance = new ctor(workInProgress.memoizedProps, _instance.context); 19635 var state = tempInstance.state; 19636 19637 _instance.updater.enqueueSetState(_instance, state, null); 19638 19639 break; 19640 } 19641 19642 case true: 19643 { 19644 workInProgress.flags |= DidCapture; 19645 workInProgress.flags |= ShouldCapture; // eslint-disable-next-line react-internal/prod-error-codes 19646 19647 var error$1 = new Error('Simulated error coming from DevTools'); 19648 var lane = pickArbitraryLane(renderLanes); 19649 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); // Schedule the error boundary to re-render using updated state 19650 19651 var update = createClassErrorUpdate(workInProgress, createCapturedValueAtFiber(error$1, workInProgress), lane); 19652 enqueueCapturedUpdate(workInProgress, update); 19653 break; 19654 } 19655 } 19656 19657 if (workInProgress.type !== workInProgress.elementType) { 19658 // Lazy component props can't be validated in createElement 19659 // because they're only guaranteed to be resolved here. 19660 var innerPropTypes = Component.propTypes; 19661 19662 if (innerPropTypes) { 19663 checkPropTypes(innerPropTypes, nextProps, // Resolved props 19664 'prop', getComponentNameFromType(Component)); 19665 } 19666 } 19667 } // Push context providers early to prevent context stack mismatches. 19668 // During mounting we don't know the child context yet as the instance doesn't exist. 19669 // We will invalidate the child context in finishClassComponent() right after rendering. 19670 19671 19672 var hasContext; 19673 19674 if (isContextProvider(Component)) { 19675 hasContext = true; 19676 pushContextProvider(workInProgress); 19677 } else { 19678 hasContext = false; 19679 } 19680 19681 prepareToReadContext(workInProgress, renderLanes); 19682 var instance = workInProgress.stateNode; 19683 var shouldUpdate; 19684 19685 if (instance === null) { 19686 resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); // In the initial pass we might need to construct the instance. 19687 19688 constructClassInstance(workInProgress, Component, nextProps); 19689 mountClassInstance(workInProgress, Component, nextProps, renderLanes); 19690 shouldUpdate = true; 19691 } else if (current === null) { 19692 // In a resume, we'll already have an instance we can reuse. 19693 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderLanes); 19694 } else { 19695 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderLanes); 19696 } 19697 19698 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes); 19699 19700 { 19701 var inst = workInProgress.stateNode; 19702 19703 if (shouldUpdate && inst.props !== nextProps) { 19704 if (!didWarnAboutReassigningProps) { 19705 error('It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentNameFromFiber(workInProgress) || 'a component'); 19706 } 19707 19708 didWarnAboutReassigningProps = true; 19709 } 19710 } 19711 19712 return nextUnitOfWork; 19713} 19714 19715function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes) { 19716 // Refs should update even if shouldComponentUpdate returns false 19717 markRef(current, workInProgress); 19718 var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags; 19719 19720 if (!shouldUpdate && !didCaptureError) { 19721 // Context providers should defer to sCU for rendering 19722 if (hasContext) { 19723 invalidateContextProvider(workInProgress, Component, false); 19724 } 19725 19726 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 19727 } 19728 19729 var instance = workInProgress.stateNode; // Rerender 19730 19731 ReactCurrentOwner$1.current = workInProgress; 19732 var nextChildren; 19733 19734 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') { 19735 // If we captured an error, but getDerivedStateFromError is not defined, 19736 // unmount all the children. componentDidCatch will schedule an update to 19737 // re-render a fallback. This is temporary until we migrate everyone to 19738 // the new API. 19739 // TODO: Warn in a future release. 19740 nextChildren = null; 19741 19742 { 19743 stopProfilerTimerIfRunning(); 19744 } 19745 } else { 19746 { 19747 markComponentRenderStarted(workInProgress); 19748 } 19749 19750 { 19751 setIsRendering(true); 19752 nextChildren = instance.render(); 19753 19754 if ( workInProgress.mode & StrictLegacyMode) { 19755 setIsStrictModeForDevtools(true); 19756 19757 try { 19758 instance.render(); 19759 } finally { 19760 setIsStrictModeForDevtools(false); 19761 } 19762 } 19763 19764 setIsRendering(false); 19765 } 19766 19767 { 19768 markComponentRenderStopped(); 19769 } 19770 } // React DevTools reads this flag. 19771 19772 19773 workInProgress.flags |= PerformedWork; 19774 19775 if (current !== null && didCaptureError) { 19776 // If we're recovering from an error, reconcile without reusing any of 19777 // the existing children. Conceptually, the normal children and the children 19778 // that are shown on error are two different sets, so we shouldn't reuse 19779 // normal children even if their identities match. 19780 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes); 19781 } else { 19782 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 19783 } // Memoize state using the values we just used to render. 19784 // TODO: Restructure so we never read values from the instance. 19785 19786 19787 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. 19788 19789 if (hasContext) { 19790 invalidateContextProvider(workInProgress, Component, true); 19791 } 19792 19793 return workInProgress.child; 19794} 19795 19796function pushHostRootContext(workInProgress) { 19797 var root = workInProgress.stateNode; 19798 19799 if (root.pendingContext) { 19800 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context); 19801 } else if (root.context) { 19802 // Should always be set 19803 pushTopLevelContextObject(workInProgress, root.context, false); 19804 } 19805 19806 pushHostContainer(workInProgress, root.containerInfo); 19807} 19808 19809function updateHostRoot(current, workInProgress, renderLanes) { 19810 pushHostRootContext(workInProgress); 19811 19812 if (current === null) { 19813 throw new Error('Should have a current fiber. This is a bug in React.'); 19814 } 19815 19816 var nextProps = workInProgress.pendingProps; 19817 var prevState = workInProgress.memoizedState; 19818 var prevChildren = prevState.element; 19819 cloneUpdateQueue(current, workInProgress); 19820 processUpdateQueue(workInProgress, nextProps, null, renderLanes); 19821 var nextState = workInProgress.memoizedState; 19822 var root = workInProgress.stateNode; 19823 // being called "element". 19824 19825 19826 var nextChildren = nextState.element; 19827 19828 if ( prevState.isDehydrated) { 19829 // This is a hydration root whose shell has not yet hydrated. We should 19830 // attempt to hydrate. 19831 // Flip isDehydrated to false to indicate that when this render 19832 // finishes, the root will no longer be dehydrated. 19833 var overrideState = { 19834 element: nextChildren, 19835 isDehydrated: false, 19836 cache: nextState.cache, 19837 pendingSuspenseBoundaries: nextState.pendingSuspenseBoundaries, 19838 transitions: nextState.transitions 19839 }; 19840 var updateQueue = workInProgress.updateQueue; // `baseState` can always be the last state because the root doesn't 19841 // have reducer functions so it doesn't need rebasing. 19842 19843 updateQueue.baseState = overrideState; 19844 workInProgress.memoizedState = overrideState; 19845 19846 if (workInProgress.flags & ForceClientRender) { 19847 // Something errored during a previous attempt to hydrate the shell, so we 19848 // forced a client render. 19849 var recoverableError = createCapturedValueAtFiber(new Error('There was an error while hydrating. Because the error happened outside ' + 'of a Suspense boundary, the entire root will switch to ' + 'client rendering.'), workInProgress); 19850 return mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, recoverableError); 19851 } else if (nextChildren !== prevChildren) { 19852 var _recoverableError = createCapturedValueAtFiber(new Error('This root received an early update, before anything was able ' + 'hydrate. Switched the entire root to client rendering.'), workInProgress); 19853 19854 return mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, _recoverableError); 19855 } else { 19856 // The outermost shell has not hydrated yet. Start hydrating. 19857 enterHydrationState(workInProgress); 19858 19859 var child = mountChildFibers(workInProgress, null, nextChildren, renderLanes); 19860 workInProgress.child = child; 19861 var node = child; 19862 19863 while (node) { 19864 // Mark each child as hydrating. This is a fast path to know whether this 19865 // tree is part of a hydrating tree. This is used to determine if a child 19866 // node has fully mounted yet, and for scheduling event replaying. 19867 // Conceptually this is similar to Placement in that a new subtree is 19868 // inserted into the React tree here. It just happens to not need DOM 19869 // mutations because it already exists. 19870 node.flags = node.flags & ~Placement | Hydrating; 19871 node = node.sibling; 19872 } 19873 } 19874 } else { 19875 // Root is not dehydrated. Either this is a client-only root, or it 19876 // already hydrated. 19877 resetHydrationState(); 19878 19879 if (nextChildren === prevChildren) { 19880 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 19881 } 19882 19883 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 19884 } 19885 19886 return workInProgress.child; 19887} 19888 19889function mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, recoverableError) { 19890 // Revert to client rendering. 19891 resetHydrationState(); 19892 queueHydrationError(recoverableError); 19893 workInProgress.flags |= ForceClientRender; 19894 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 19895 return workInProgress.child; 19896} 19897 19898function updateHostComponent(current, workInProgress, renderLanes) { 19899 pushHostContext(workInProgress); 19900 19901 if (current === null) { 19902 tryToClaimNextHydratableInstance(workInProgress); 19903 } 19904 19905 var type = workInProgress.type; 19906 var nextProps = workInProgress.pendingProps; 19907 var prevProps = current !== null ? current.memoizedProps : null; 19908 var nextChildren = nextProps.children; 19909 var isDirectTextChild = shouldSetTextContent(type, nextProps); 19910 19911 if (isDirectTextChild) { 19912 // We special case a direct text child of a host node. This is a common 19913 // case. We won't handle it as a reified child. We will instead handle 19914 // this in the host environment that also has access to this prop. That 19915 // avoids allocating another HostText fiber and traversing it. 19916 nextChildren = null; 19917 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) { 19918 // If we're switching from a direct text child to a normal child, or to 19919 // empty, we need to schedule the text content to be reset. 19920 workInProgress.flags |= ContentReset; 19921 } 19922 19923 markRef(current, workInProgress); 19924 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 19925 return workInProgress.child; 19926} 19927 19928function updateHostText(current, workInProgress) { 19929 if (current === null) { 19930 tryToClaimNextHydratableInstance(workInProgress); 19931 } // Nothing to do here. This is terminal. We'll do the completion step 19932 // immediately after. 19933 19934 19935 return null; 19936} 19937 19938function mountLazyComponent(_current, workInProgress, elementType, renderLanes) { 19939 resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); 19940 var props = workInProgress.pendingProps; 19941 var lazyComponent = elementType; 19942 var payload = lazyComponent._payload; 19943 var init = lazyComponent._init; 19944 var Component = init(payload); // Store the unwrapped component in the type. 19945 19946 workInProgress.type = Component; 19947 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component); 19948 var resolvedProps = resolveDefaultProps(Component, props); 19949 var child; 19950 19951 switch (resolvedTag) { 19952 case FunctionComponent: 19953 { 19954 { 19955 validateFunctionComponentInDev(workInProgress, Component); 19956 workInProgress.type = Component = resolveFunctionForHotReloading(Component); 19957 } 19958 19959 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderLanes); 19960 return child; 19961 } 19962 19963 case ClassComponent: 19964 { 19965 { 19966 workInProgress.type = Component = resolveClassForHotReloading(Component); 19967 } 19968 19969 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderLanes); 19970 return child; 19971 } 19972 19973 case ForwardRef: 19974 { 19975 { 19976 workInProgress.type = Component = resolveForwardRefForHotReloading(Component); 19977 } 19978 19979 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderLanes); 19980 return child; 19981 } 19982 19983 case MemoComponent: 19984 { 19985 { 19986 if (workInProgress.type !== workInProgress.elementType) { 19987 var outerPropTypes = Component.propTypes; 19988 19989 if (outerPropTypes) { 19990 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only 19991 'prop', getComponentNameFromType(Component)); 19992 } 19993 } 19994 } 19995 19996 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too 19997 renderLanes); 19998 return child; 19999 } 20000 } 20001 20002 var hint = ''; 20003 20004 { 20005 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) { 20006 hint = ' Did you wrap a component in React.lazy() more than once?'; 20007 } 20008 } // This message intentionally doesn't mention ForwardRef or MemoComponent 20009 // because the fact that it's a separate type of work is an 20010 // implementation detail. 20011 20012 20013 throw new Error("Element type is invalid. Received a promise that resolves to: " + Component + ". " + ("Lazy element type must resolve to a class or function." + hint)); 20014} 20015 20016function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderLanes) { 20017 resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); // Promote the fiber to a class and try rendering again. 20018 20019 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent` 20020 // Push context providers early to prevent context stack mismatches. 20021 // During mounting we don't know the child context yet as the instance doesn't exist. 20022 // We will invalidate the child context in finishClassComponent() right after rendering. 20023 20024 var hasContext; 20025 20026 if (isContextProvider(Component)) { 20027 hasContext = true; 20028 pushContextProvider(workInProgress); 20029 } else { 20030 hasContext = false; 20031 } 20032 20033 prepareToReadContext(workInProgress, renderLanes); 20034 constructClassInstance(workInProgress, Component, nextProps); 20035 mountClassInstance(workInProgress, Component, nextProps, renderLanes); 20036 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes); 20037} 20038 20039function mountIndeterminateComponent(_current, workInProgress, Component, renderLanes) { 20040 resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); 20041 var props = workInProgress.pendingProps; 20042 var context; 20043 20044 { 20045 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); 20046 context = getMaskedContext(workInProgress, unmaskedContext); 20047 } 20048 20049 prepareToReadContext(workInProgress, renderLanes); 20050 var value; 20051 var hasId; 20052 20053 { 20054 markComponentRenderStarted(workInProgress); 20055 } 20056 20057 { 20058 if (Component.prototype && typeof Component.prototype.render === 'function') { 20059 var componentName = getComponentNameFromType(Component) || 'Unknown'; 20060 20061 if (!didWarnAboutBadClass[componentName]) { 20062 error("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); 20063 20064 didWarnAboutBadClass[componentName] = true; 20065 } 20066 } 20067 20068 if (workInProgress.mode & StrictLegacyMode) { 20069 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); 20070 } 20071 20072 setIsRendering(true); 20073 ReactCurrentOwner$1.current = workInProgress; 20074 value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes); 20075 hasId = checkDidRenderIdHook(); 20076 setIsRendering(false); 20077 } 20078 20079 { 20080 markComponentRenderStopped(); 20081 } // React DevTools reads this flag. 20082 20083 20084 workInProgress.flags |= PerformedWork; 20085 20086 { 20087 // Support for module components is deprecated and is removed behind a flag. 20088 // Whether or not it would crash later, we want to show a good message in DEV first. 20089 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) { 20090 var _componentName = getComponentNameFromType(Component) || 'Unknown'; 20091 20092 if (!didWarnAboutModulePatternComponent[_componentName]) { 20093 error('The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + "If you can't use a class try assigning the prototype on the function as a workaround. " + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + 'cannot be called with `new` by React.', _componentName, _componentName, _componentName); 20094 20095 didWarnAboutModulePatternComponent[_componentName] = true; 20096 } 20097 } 20098 } 20099 20100 if ( // Run these checks in production only if the flag is off. 20101 // Eventually we'll delete this branch altogether. 20102 typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) { 20103 { 20104 var _componentName2 = getComponentNameFromType(Component) || 'Unknown'; 20105 20106 if (!didWarnAboutModulePatternComponent[_componentName2]) { 20107 error('The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + "If you can't use a class try assigning the prototype on the function as a workaround. " + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + 'cannot be called with `new` by React.', _componentName2, _componentName2, _componentName2); 20108 20109 didWarnAboutModulePatternComponent[_componentName2] = true; 20110 } 20111 } // Proceed under the assumption that this is a class instance 20112 20113 20114 workInProgress.tag = ClassComponent; // Throw out any hooks that were used. 20115 20116 workInProgress.memoizedState = null; 20117 workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. 20118 // During mounting we don't know the child context yet as the instance doesn't exist. 20119 // We will invalidate the child context in finishClassComponent() right after rendering. 20120 20121 var hasContext = false; 20122 20123 if (isContextProvider(Component)) { 20124 hasContext = true; 20125 pushContextProvider(workInProgress); 20126 } else { 20127 hasContext = false; 20128 } 20129 20130 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; 20131 initializeUpdateQueue(workInProgress); 20132 adoptClassInstance(workInProgress, value); 20133 mountClassInstance(workInProgress, Component, props, renderLanes); 20134 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes); 20135 } else { 20136 // Proceed under the assumption that this is a function component 20137 workInProgress.tag = FunctionComponent; 20138 20139 { 20140 20141 if ( workInProgress.mode & StrictLegacyMode) { 20142 setIsStrictModeForDevtools(true); 20143 20144 try { 20145 value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes); 20146 hasId = checkDidRenderIdHook(); 20147 } finally { 20148 setIsStrictModeForDevtools(false); 20149 } 20150 } 20151 } 20152 20153 if (getIsHydrating() && hasId) { 20154 pushMaterializedTreeId(workInProgress); 20155 } 20156 20157 reconcileChildren(null, workInProgress, value, renderLanes); 20158 20159 { 20160 validateFunctionComponentInDev(workInProgress, Component); 20161 } 20162 20163 return workInProgress.child; 20164 } 20165} 20166 20167function validateFunctionComponentInDev(workInProgress, Component) { 20168 { 20169 if (Component) { 20170 if (Component.childContextTypes) { 20171 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component'); 20172 } 20173 } 20174 20175 if (workInProgress.ref !== null) { 20176 var info = ''; 20177 var ownerName = getCurrentFiberOwnerNameInDevOrNull(); 20178 20179 if (ownerName) { 20180 info += '\n\nCheck the render method of `' + ownerName + '`.'; 20181 } 20182 20183 var warningKey = ownerName || ''; 20184 var debugSource = workInProgress._debugSource; 20185 20186 if (debugSource) { 20187 warningKey = debugSource.fileName + ':' + debugSource.lineNumber; 20188 } 20189 20190 if (!didWarnAboutFunctionRefs[warningKey]) { 20191 didWarnAboutFunctionRefs[warningKey] = true; 20192 20193 error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info); 20194 } 20195 } 20196 20197 if (typeof Component.getDerivedStateFromProps === 'function') { 20198 var _componentName3 = getComponentNameFromType(Component) || 'Unknown'; 20199 20200 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { 20201 error('%s: Function components do not support getDerivedStateFromProps.', _componentName3); 20202 20203 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; 20204 } 20205 } 20206 20207 if (typeof Component.contextType === 'object' && Component.contextType !== null) { 20208 var _componentName4 = getComponentNameFromType(Component) || 'Unknown'; 20209 20210 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { 20211 error('%s: Function components do not support contextType.', _componentName4); 20212 20213 didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; 20214 } 20215 } 20216 } 20217} 20218 20219var SUSPENDED_MARKER = { 20220 dehydrated: null, 20221 treeContext: null, 20222 retryLane: NoLane 20223}; 20224 20225function mountSuspenseOffscreenState(renderLanes) { 20226 return { 20227 baseLanes: renderLanes, 20228 cachePool: getSuspendedCache(), 20229 transitions: null 20230 }; 20231} 20232 20233function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { 20234 var cachePool = null; 20235 20236 return { 20237 baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes), 20238 cachePool: cachePool, 20239 transitions: prevOffscreenState.transitions 20240 }; 20241} // TODO: Probably should inline this back 20242 20243 20244function shouldRemainOnFallback(suspenseContext, current, workInProgress, renderLanes) { 20245 // If we're already showing a fallback, there are cases where we need to 20246 // remain on that fallback regardless of whether the content has resolved. 20247 // For example, SuspenseList coordinates when nested content appears. 20248 if (current !== null) { 20249 var suspenseState = current.memoizedState; 20250 20251 if (suspenseState === null) { 20252 // Currently showing content. Don't hide it, even if ForceSuspenseFallback 20253 // is true. More precise name might be "ForceRemainSuspenseFallback". 20254 // Note: This is a factoring smell. Can't remain on a fallback if there's 20255 // no fallback to remain on. 20256 return false; 20257 } 20258 } // Not currently showing content. Consult the Suspense context. 20259 20260 20261 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); 20262} 20263 20264function getRemainingWorkInPrimaryTree(current, renderLanes) { 20265 // TODO: Should not remove render lanes that were pinged during this render 20266 return removeLanes(current.childLanes, renderLanes); 20267} 20268 20269function updateSuspenseComponent(current, workInProgress, renderLanes) { 20270 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. 20271 20272 { 20273 if (shouldSuspend(workInProgress)) { 20274 workInProgress.flags |= DidCapture; 20275 } 20276 } 20277 20278 var suspenseContext = suspenseStackCursor.current; 20279 var showFallback = false; 20280 var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; 20281 20282 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) { 20283 // Something in this boundary's subtree already suspended. Switch to 20284 // rendering the fallback children. 20285 showFallback = true; 20286 workInProgress.flags &= ~DidCapture; 20287 } else { 20288 // Attempting the main content 20289 if (current === null || current.memoizedState !== null) { 20290 // This is a new mount or this boundary is already showing a fallback state. 20291 // Mark this subtree context as having at least one invisible parent that could 20292 // handle the fallback state. 20293 // Avoided boundaries are not considered since they cannot handle preferred fallback states. 20294 { 20295 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext); 20296 } 20297 } 20298 } 20299 20300 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); 20301 pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense 20302 // boundary's children. This involves some custom reconciliation logic. Two 20303 // main reasons this is so complicated. 20304 // 20305 // First, Legacy Mode has different semantics for backwards compatibility. The 20306 // primary tree will commit in an inconsistent state, so when we do the 20307 // second pass to render the fallback, we do some exceedingly, uh, clever 20308 // hacks to make that not totally break. Like transferring effects and 20309 // deletions from hidden tree. In Concurrent Mode, it's much simpler, 20310 // because we bailout on the primary tree completely and leave it in its old 20311 // state, no effects. Same as what we do for Offscreen (except that 20312 // Offscreen doesn't have the first render pass). 20313 // 20314 // Second is hydration. During hydration, the Suspense fiber has a slightly 20315 // different layout, where the child points to a dehydrated fragment, which 20316 // contains the DOM rendered by the server. 20317 // 20318 // Third, even if you set all that aside, Suspense is like error boundaries in 20319 // that we first we try to render one tree, and if that fails, we render again 20320 // and switch to a different tree. Like a try/catch block. So we have to track 20321 // which branch we're currently rendering. Ideally we would model this using 20322 // a stack. 20323 20324 if (current === null) { 20325 // Initial mount 20326 // Special path for hydration 20327 // If we're currently hydrating, try to hydrate this boundary. 20328 tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component. 20329 20330 var suspenseState = workInProgress.memoizedState; 20331 20332 if (suspenseState !== null) { 20333 var dehydrated = suspenseState.dehydrated; 20334 20335 if (dehydrated !== null) { 20336 return mountDehydratedSuspenseComponent(workInProgress, dehydrated); 20337 } 20338 } 20339 20340 var nextPrimaryChildren = nextProps.children; 20341 var nextFallbackChildren = nextProps.fallback; 20342 20343 if (showFallback) { 20344 var fallbackFragment = mountSuspenseFallbackChildren(workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes); 20345 var primaryChildFragment = workInProgress.child; 20346 primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes); 20347 workInProgress.memoizedState = SUSPENDED_MARKER; 20348 20349 return fallbackFragment; 20350 } else { 20351 return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren); 20352 } 20353 } else { 20354 // This is an update. 20355 // Special path for hydration 20356 var prevState = current.memoizedState; 20357 20358 if (prevState !== null) { 20359 var _dehydrated = prevState.dehydrated; 20360 20361 if (_dehydrated !== null) { 20362 return updateDehydratedSuspenseComponent(current, workInProgress, didSuspend, nextProps, _dehydrated, prevState, renderLanes); 20363 } 20364 } 20365 20366 if (showFallback) { 20367 var _nextFallbackChildren = nextProps.fallback; 20368 var _nextPrimaryChildren = nextProps.children; 20369 var fallbackChildFragment = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren, _nextFallbackChildren, renderLanes); 20370 var _primaryChildFragment2 = workInProgress.child; 20371 var prevOffscreenState = current.child.memoizedState; 20372 _primaryChildFragment2.memoizedState = prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(prevOffscreenState, renderLanes); 20373 20374 _primaryChildFragment2.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes); 20375 workInProgress.memoizedState = SUSPENDED_MARKER; 20376 return fallbackChildFragment; 20377 } else { 20378 var _nextPrimaryChildren2 = nextProps.children; 20379 20380 var _primaryChildFragment3 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren2, renderLanes); 20381 20382 workInProgress.memoizedState = null; 20383 return _primaryChildFragment3; 20384 } 20385 } 20386} 20387 20388function mountSuspensePrimaryChildren(workInProgress, primaryChildren, renderLanes) { 20389 var mode = workInProgress.mode; 20390 var primaryChildProps = { 20391 mode: 'visible', 20392 children: primaryChildren 20393 }; 20394 var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode); 20395 primaryChildFragment.return = workInProgress; 20396 workInProgress.child = primaryChildFragment; 20397 return primaryChildFragment; 20398} 20399 20400function mountSuspenseFallbackChildren(workInProgress, primaryChildren, fallbackChildren, renderLanes) { 20401 var mode = workInProgress.mode; 20402 var progressedPrimaryFragment = workInProgress.child; 20403 var primaryChildProps = { 20404 mode: 'hidden', 20405 children: primaryChildren 20406 }; 20407 var primaryChildFragment; 20408 var fallbackChildFragment; 20409 20410 if ((mode & ConcurrentMode) === NoMode && progressedPrimaryFragment !== null) { 20411 // In legacy mode, we commit the primary tree as if it successfully 20412 // completed, even though it's in an inconsistent state. 20413 primaryChildFragment = progressedPrimaryFragment; 20414 primaryChildFragment.childLanes = NoLanes; 20415 primaryChildFragment.pendingProps = primaryChildProps; 20416 20417 if ( workInProgress.mode & ProfileMode) { 20418 // Reset the durations from the first pass so they aren't included in the 20419 // final amounts. This seems counterintuitive, since we're intentionally 20420 // not measuring part of the render phase, but this makes it match what we 20421 // do in Concurrent Mode. 20422 primaryChildFragment.actualDuration = 0; 20423 primaryChildFragment.actualStartTime = -1; 20424 primaryChildFragment.selfBaseDuration = 0; 20425 primaryChildFragment.treeBaseDuration = 0; 20426 } 20427 20428 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); 20429 } else { 20430 primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode); 20431 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); 20432 } 20433 20434 primaryChildFragment.return = workInProgress; 20435 fallbackChildFragment.return = workInProgress; 20436 primaryChildFragment.sibling = fallbackChildFragment; 20437 workInProgress.child = primaryChildFragment; 20438 return fallbackChildFragment; 20439} 20440 20441function mountWorkInProgressOffscreenFiber(offscreenProps, mode, renderLanes) { 20442 // The props argument to `createFiberFromOffscreen` is `any` typed, so we use 20443 // this wrapper function to constrain it. 20444 return createFiberFromOffscreen(offscreenProps, mode, NoLanes, null); 20445} 20446 20447function updateWorkInProgressOffscreenFiber(current, offscreenProps) { 20448 // The props argument to `createWorkInProgress` is `any` typed, so we use this 20449 // wrapper function to constrain it. 20450 return createWorkInProgress(current, offscreenProps); 20451} 20452 20453function updateSuspensePrimaryChildren(current, workInProgress, primaryChildren, renderLanes) { 20454 var currentPrimaryChildFragment = current.child; 20455 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; 20456 var primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, { 20457 mode: 'visible', 20458 children: primaryChildren 20459 }); 20460 20461 if ((workInProgress.mode & ConcurrentMode) === NoMode) { 20462 primaryChildFragment.lanes = renderLanes; 20463 } 20464 20465 primaryChildFragment.return = workInProgress; 20466 primaryChildFragment.sibling = null; 20467 20468 if (currentFallbackChildFragment !== null) { 20469 // Delete the fallback child fragment 20470 var deletions = workInProgress.deletions; 20471 20472 if (deletions === null) { 20473 workInProgress.deletions = [currentFallbackChildFragment]; 20474 workInProgress.flags |= ChildDeletion; 20475 } else { 20476 deletions.push(currentFallbackChildFragment); 20477 } 20478 } 20479 20480 workInProgress.child = primaryChildFragment; 20481 return primaryChildFragment; 20482} 20483 20484function updateSuspenseFallbackChildren(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) { 20485 var mode = workInProgress.mode; 20486 var currentPrimaryChildFragment = current.child; 20487 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; 20488 var primaryChildProps = { 20489 mode: 'hidden', 20490 children: primaryChildren 20491 }; 20492 var primaryChildFragment; 20493 20494 if ( // In legacy mode, we commit the primary tree as if it successfully 20495 // completed, even though it's in an inconsistent state. 20496 (mode & ConcurrentMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was 20497 // already cloned. In legacy mode, the only case where this isn't true is 20498 // when DevTools forces us to display a fallback; we skip the first render 20499 // pass entirely and go straight to rendering the fallback. (In Concurrent 20500 // Mode, SuspenseList can also trigger this scenario, but this is a legacy- 20501 // only codepath.) 20502 workInProgress.child !== currentPrimaryChildFragment) { 20503 var progressedPrimaryFragment = workInProgress.child; 20504 primaryChildFragment = progressedPrimaryFragment; 20505 primaryChildFragment.childLanes = NoLanes; 20506 primaryChildFragment.pendingProps = primaryChildProps; 20507 20508 if ( workInProgress.mode & ProfileMode) { 20509 // Reset the durations from the first pass so they aren't included in the 20510 // final amounts. This seems counterintuitive, since we're intentionally 20511 // not measuring part of the render phase, but this makes it match what we 20512 // do in Concurrent Mode. 20513 primaryChildFragment.actualDuration = 0; 20514 primaryChildFragment.actualStartTime = -1; 20515 primaryChildFragment.selfBaseDuration = currentPrimaryChildFragment.selfBaseDuration; 20516 primaryChildFragment.treeBaseDuration = currentPrimaryChildFragment.treeBaseDuration; 20517 } // The fallback fiber was added as a deletion during the first pass. 20518 // However, since we're going to remain on the fallback, we no longer want 20519 // to delete it. 20520 20521 20522 workInProgress.deletions = null; 20523 } else { 20524 primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, primaryChildProps); // Since we're reusing a current tree, we need to reuse the flags, too. 20525 // (We don't do this in legacy mode, because in legacy mode we don't re-use 20526 // the current tree; see previous branch.) 20527 20528 primaryChildFragment.subtreeFlags = currentPrimaryChildFragment.subtreeFlags & StaticMask; 20529 } 20530 20531 var fallbackChildFragment; 20532 20533 if (currentFallbackChildFragment !== null) { 20534 fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, fallbackChildren); 20535 } else { 20536 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); // Needs a placement effect because the parent (the Suspense boundary) already 20537 // mounted but this is a new fiber. 20538 20539 fallbackChildFragment.flags |= Placement; 20540 } 20541 20542 fallbackChildFragment.return = workInProgress; 20543 primaryChildFragment.return = workInProgress; 20544 primaryChildFragment.sibling = fallbackChildFragment; 20545 workInProgress.child = primaryChildFragment; 20546 return fallbackChildFragment; 20547} 20548 20549function retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, recoverableError) { 20550 // Falling back to client rendering. Because this has performance 20551 // implications, it's considered a recoverable error, even though the user 20552 // likely won't observe anything wrong with the UI. 20553 // 20554 // The error is passed in as an argument to enforce that every caller provide 20555 // a custom message, or explicitly opt out (currently the only path that opts 20556 // out is legacy mode; every concurrent path provides an error). 20557 if (recoverableError !== null) { 20558 queueHydrationError(recoverableError); 20559 } // This will add the old fiber to the deletion list 20560 20561 20562 reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated. 20563 20564 var nextProps = workInProgress.pendingProps; 20565 var primaryChildren = nextProps.children; 20566 var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress, primaryChildren); // Needs a placement effect because the parent (the Suspense boundary) already 20567 // mounted but this is a new fiber. 20568 20569 primaryChildFragment.flags |= Placement; 20570 workInProgress.memoizedState = null; 20571 return primaryChildFragment; 20572} 20573 20574function mountSuspenseFallbackAfterRetryWithoutHydrating(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) { 20575 var fiberMode = workInProgress.mode; 20576 var primaryChildProps = { 20577 mode: 'visible', 20578 children: primaryChildren 20579 }; 20580 var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, fiberMode); 20581 var fallbackChildFragment = createFiberFromFragment(fallbackChildren, fiberMode, renderLanes, null); // Needs a placement effect because the parent (the Suspense 20582 // boundary) already mounted but this is a new fiber. 20583 20584 fallbackChildFragment.flags |= Placement; 20585 primaryChildFragment.return = workInProgress; 20586 fallbackChildFragment.return = workInProgress; 20587 primaryChildFragment.sibling = fallbackChildFragment; 20588 workInProgress.child = primaryChildFragment; 20589 20590 if ((workInProgress.mode & ConcurrentMode) !== NoMode) { 20591 // We will have dropped the effect list which contains the 20592 // deletion. We need to reconcile to delete the current child. 20593 reconcileChildFibers(workInProgress, current.child, null, renderLanes); 20594 } 20595 20596 return fallbackChildFragment; 20597} 20598 20599function mountDehydratedSuspenseComponent(workInProgress, suspenseInstance, renderLanes) { 20600 // During the first pass, we'll bail out and not drill into the children. 20601 // Instead, we'll leave the content in place and try to hydrate it later. 20602 if ((workInProgress.mode & ConcurrentMode) === NoMode) { 20603 { 20604 error('Cannot hydrate Suspense in legacy mode. Switch from ' + 'ReactDOM.hydrate(element, container) to ' + 'ReactDOMClient.hydrateRoot(container, <App />)' + '.render(element) or remove the Suspense components from ' + 'the server rendered components.'); 20605 } 20606 20607 workInProgress.lanes = laneToLanes(SyncLane); 20608 } else if (isSuspenseInstanceFallback(suspenseInstance)) { 20609 // This is a client-only boundary. Since we won't get any content from the server 20610 // for this, we need to schedule that at a higher priority based on when it would 20611 // have timed out. In theory we could render it in this pass but it would have the 20612 // wrong priority associated with it and will prevent hydration of parent path. 20613 // Instead, we'll leave work left on it to render it in a separate commit. 20614 // TODO This time should be the time at which the server rendered response that is 20615 // a parent to this boundary was displayed. However, since we currently don't have 20616 // a protocol to transfer that time, we'll just estimate it by using the current 20617 // time. This will mean that Suspense timeouts are slightly shifted to later than 20618 // they should be. 20619 // Schedule a normal pri update to render this content. 20620 workInProgress.lanes = laneToLanes(DefaultHydrationLane); 20621 } else { 20622 // We'll continue hydrating the rest at offscreen priority since we'll already 20623 // be showing the right content coming from the server, it is no rush. 20624 workInProgress.lanes = laneToLanes(OffscreenLane); 20625 } 20626 20627 return null; 20628} 20629 20630function updateDehydratedSuspenseComponent(current, workInProgress, didSuspend, nextProps, suspenseInstance, suspenseState, renderLanes) { 20631 if (!didSuspend) { 20632 // This is the first render pass. Attempt to hydrate. 20633 // We should never be hydrating at this point because it is the first pass, 20634 // but after we've already committed once. 20635 warnIfHydrating(); 20636 20637 if ((workInProgress.mode & ConcurrentMode) === NoMode) { 20638 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, // TODO: When we delete legacy mode, we should make this error argument 20639 // required — every concurrent mode path that causes hydration to 20640 // de-opt to client rendering should have an error message. 20641 null); 20642 } 20643 20644 if (isSuspenseInstanceFallback(suspenseInstance)) { 20645 // This boundary is in a permanent fallback state. In this case, we'll never 20646 // get an update and we'll never be able to hydrate the final content. Let's just try the 20647 // client side render instead. 20648 var digest, message, stack; 20649 20650 { 20651 var _getSuspenseInstanceF = getSuspenseInstanceFallbackErrorDetails(suspenseInstance); 20652 20653 digest = _getSuspenseInstanceF.digest; 20654 message = _getSuspenseInstanceF.message; 20655 stack = _getSuspenseInstanceF.stack; 20656 } 20657 20658 var error; 20659 20660 if (message) { 20661 // eslint-disable-next-line react-internal/prod-error-codes 20662 error = new Error(message); 20663 } else { 20664 error = new Error('The server could not finish this Suspense boundary, likely ' + 'due to an error during server rendering. Switched to ' + 'client rendering.'); 20665 } 20666 20667 var capturedValue = createCapturedValue(error, digest, stack); 20668 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, capturedValue); 20669 } 20670 // any context has changed, we need to treat is as if the input might have changed. 20671 20672 20673 var hasContextChanged = includesSomeLane(renderLanes, current.childLanes); 20674 20675 if (didReceiveUpdate || hasContextChanged) { 20676 // This boundary has changed since the first render. This means that we are now unable to 20677 // hydrate it. We might still be able to hydrate it using a higher priority lane. 20678 var root = getWorkInProgressRoot(); 20679 20680 if (root !== null) { 20681 var attemptHydrationAtLane = getBumpedLaneForHydration(root, renderLanes); 20682 20683 if (attemptHydrationAtLane !== NoLane && attemptHydrationAtLane !== suspenseState.retryLane) { 20684 // Intentionally mutating since this render will get interrupted. This 20685 // is one of the very rare times where we mutate the current tree 20686 // during the render phase. 20687 suspenseState.retryLane = attemptHydrationAtLane; // TODO: Ideally this would inherit the event time of the current render 20688 20689 var eventTime = NoTimestamp; 20690 enqueueConcurrentRenderForLane(current, attemptHydrationAtLane); 20691 scheduleUpdateOnFiber(root, current, attemptHydrationAtLane, eventTime); 20692 } 20693 } // If we have scheduled higher pri work above, this will probably just abort the render 20694 // since we now have higher priority work, but in case it doesn't, we need to prepare to 20695 // render something, if we time out. Even if that requires us to delete everything and 20696 // skip hydration. 20697 // Delay having to do this as long as the suspense timeout allows us. 20698 20699 20700 renderDidSuspendDelayIfPossible(); 20701 20702 var _capturedValue = createCapturedValue(new Error('This Suspense boundary received an update before it finished ' + 'hydrating. This caused the boundary to switch to client rendering. ' + 'The usual way to fix this is to wrap the original update ' + 'in startTransition.')); 20703 20704 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, _capturedValue); 20705 } else if (isSuspenseInstancePending(suspenseInstance)) { 20706 // This component is still pending more data from the server, so we can't hydrate its 20707 // content. We treat it as if this component suspended itself. It might seem as if 20708 // we could just try to render it client-side instead. However, this will perform a 20709 // lot of unnecessary work and is unlikely to complete since it often will suspend 20710 // on missing data anyway. Additionally, the server might be able to render more 20711 // than we can on the client yet. In that case we'd end up with more fallback states 20712 // on the client than if we just leave it alone. If the server times out or errors 20713 // these should update this boundary to the permanent Fallback state instead. 20714 // Mark it as having captured (i.e. suspended). 20715 workInProgress.flags |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment. 20716 20717 workInProgress.child = current.child; // Register a callback to retry this boundary once the server has sent the result. 20718 20719 var retry = retryDehydratedSuspenseBoundary.bind(null, current); 20720 registerSuspenseInstanceRetry(suspenseInstance, retry); 20721 return null; 20722 } else { 20723 // This is the first attempt. 20724 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress, suspenseInstance, suspenseState.treeContext); 20725 var primaryChildren = nextProps.children; 20726 var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress, primaryChildren); // Mark the children as hydrating. This is a fast path to know whether this 20727 // tree is part of a hydrating tree. This is used to determine if a child 20728 // node has fully mounted yet, and for scheduling event replaying. 20729 // Conceptually this is similar to Placement in that a new subtree is 20730 // inserted into the React tree here. It just happens to not need DOM 20731 // mutations because it already exists. 20732 20733 primaryChildFragment.flags |= Hydrating; 20734 return primaryChildFragment; 20735 } 20736 } else { 20737 // This is the second render pass. We already attempted to hydrated, but 20738 // something either suspended or errored. 20739 if (workInProgress.flags & ForceClientRender) { 20740 // Something errored during hydration. Try again without hydrating. 20741 workInProgress.flags &= ~ForceClientRender; 20742 20743 var _capturedValue2 = createCapturedValue(new Error('There was an error while hydrating this Suspense boundary. ' + 'Switched to client rendering.')); 20744 20745 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, _capturedValue2); 20746 } else if (workInProgress.memoizedState !== null) { 20747 // Something suspended and we should still be in dehydrated mode. 20748 // Leave the existing child in place. 20749 workInProgress.child = current.child; // The dehydrated completion pass expects this flag to be there 20750 // but the normal suspense pass doesn't. 20751 20752 workInProgress.flags |= DidCapture; 20753 return null; 20754 } else { 20755 // Suspended but we should no longer be in dehydrated mode. 20756 // Therefore we now have to render the fallback. 20757 var nextPrimaryChildren = nextProps.children; 20758 var nextFallbackChildren = nextProps.fallback; 20759 var fallbackChildFragment = mountSuspenseFallbackAfterRetryWithoutHydrating(current, workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes); 20760 var _primaryChildFragment4 = workInProgress.child; 20761 _primaryChildFragment4.memoizedState = mountSuspenseOffscreenState(renderLanes); 20762 workInProgress.memoizedState = SUSPENDED_MARKER; 20763 return fallbackChildFragment; 20764 } 20765 } 20766} 20767 20768function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) { 20769 fiber.lanes = mergeLanes(fiber.lanes, renderLanes); 20770 var alternate = fiber.alternate; 20771 20772 if (alternate !== null) { 20773 alternate.lanes = mergeLanes(alternate.lanes, renderLanes); 20774 } 20775 20776 scheduleContextWorkOnParentPath(fiber.return, renderLanes, propagationRoot); 20777} 20778 20779function propagateSuspenseContextChange(workInProgress, firstChild, renderLanes) { 20780 // Mark any Suspense boundaries with fallbacks as having work to do. 20781 // If they were previously forced into fallbacks, they may now be able 20782 // to unblock. 20783 var node = firstChild; 20784 20785 while (node !== null) { 20786 if (node.tag === SuspenseComponent) { 20787 var state = node.memoizedState; 20788 20789 if (state !== null) { 20790 scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress); 20791 } 20792 } else if (node.tag === SuspenseListComponent) { 20793 // If the tail is hidden there might not be an Suspense boundaries 20794 // to schedule work on. In this case we have to schedule it on the 20795 // list itself. 20796 // We don't have to traverse to the children of the list since 20797 // the list will propagate the change when it rerenders. 20798 scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress); 20799 } else if (node.child !== null) { 20800 node.child.return = node; 20801 node = node.child; 20802 continue; 20803 } 20804 20805 if (node === workInProgress) { 20806 return; 20807 } 20808 20809 while (node.sibling === null) { 20810 if (node.return === null || node.return === workInProgress) { 20811 return; 20812 } 20813 20814 node = node.return; 20815 } 20816 20817 node.sibling.return = node.return; 20818 node = node.sibling; 20819 } 20820} 20821 20822function findLastContentRow(firstChild) { 20823 // This is going to find the last row among these children that is already 20824 // showing content on the screen, as opposed to being in fallback state or 20825 // new. If a row has multiple Suspense boundaries, any of them being in the 20826 // fallback state, counts as the whole row being in a fallback state. 20827 // Note that the "rows" will be workInProgress, but any nested children 20828 // will still be current since we haven't rendered them yet. The mounted 20829 // order may not be the same as the new order. We use the new order. 20830 var row = firstChild; 20831 var lastContentRow = null; 20832 20833 while (row !== null) { 20834 var currentRow = row.alternate; // New rows can't be content rows. 20835 20836 if (currentRow !== null && findFirstSuspended(currentRow) === null) { 20837 lastContentRow = row; 20838 } 20839 20840 row = row.sibling; 20841 } 20842 20843 return lastContentRow; 20844} 20845 20846function validateRevealOrder(revealOrder) { 20847 { 20848 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) { 20849 didWarnAboutRevealOrder[revealOrder] = true; 20850 20851 if (typeof revealOrder === 'string') { 20852 switch (revealOrder.toLowerCase()) { 20853 case 'together': 20854 case 'forwards': 20855 case 'backwards': 20856 { 20857 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase()); 20858 20859 break; 20860 } 20861 20862 case 'forward': 20863 case 'backward': 20864 { 20865 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase()); 20866 20867 break; 20868 } 20869 20870 default: 20871 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder); 20872 20873 break; 20874 } 20875 } else { 20876 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder); 20877 } 20878 } 20879 } 20880} 20881 20882function validateTailOptions(tailMode, revealOrder) { 20883 { 20884 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { 20885 if (tailMode !== 'collapsed' && tailMode !== 'hidden') { 20886 didWarnAboutTailOptions[tailMode] = true; 20887 20888 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode); 20889 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') { 20890 didWarnAboutTailOptions[tailMode] = true; 20891 20892 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode); 20893 } 20894 } 20895 } 20896} 20897 20898function validateSuspenseListNestedChild(childSlot, index) { 20899 { 20900 var isAnArray = isArray(childSlot); 20901 var isIterable = !isAnArray && typeof getIteratorFn(childSlot) === 'function'; 20902 20903 if (isAnArray || isIterable) { 20904 var type = isAnArray ? 'array' : 'iterable'; 20905 20906 error('A nested %s was passed to row #%s in <SuspenseList />. Wrap it in ' + 'an additional SuspenseList to configure its revealOrder: ' + '<SuspenseList revealOrder=...> ... ' + '<SuspenseList revealOrder=...>{%s}</SuspenseList> ... ' + '</SuspenseList>', type, index, type); 20907 20908 return false; 20909 } 20910 } 20911 20912 return true; 20913} 20914 20915function validateSuspenseListChildren(children, revealOrder) { 20916 { 20917 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) { 20918 if (isArray(children)) { 20919 for (var i = 0; i < children.length; i++) { 20920 if (!validateSuspenseListNestedChild(children[i], i)) { 20921 return; 20922 } 20923 } 20924 } else { 20925 var iteratorFn = getIteratorFn(children); 20926 20927 if (typeof iteratorFn === 'function') { 20928 var childrenIterator = iteratorFn.call(children); 20929 20930 if (childrenIterator) { 20931 var step = childrenIterator.next(); 20932 var _i = 0; 20933 20934 for (; !step.done; step = childrenIterator.next()) { 20935 if (!validateSuspenseListNestedChild(step.value, _i)) { 20936 return; 20937 } 20938 20939 _i++; 20940 } 20941 } 20942 } else { 20943 error('A single row was passed to a <SuspenseList revealOrder="%s" />. ' + 'This is not useful since it needs multiple rows. ' + 'Did you mean to pass multiple children or an array?', revealOrder); 20944 } 20945 } 20946 } 20947 } 20948} 20949 20950function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode) { 20951 var renderState = workInProgress.memoizedState; 20952 20953 if (renderState === null) { 20954 workInProgress.memoizedState = { 20955 isBackwards: isBackwards, 20956 rendering: null, 20957 renderingStartTime: 0, 20958 last: lastContentRow, 20959 tail: tail, 20960 tailMode: tailMode 20961 }; 20962 } else { 20963 // We can reuse the existing object from previous renders. 20964 renderState.isBackwards = isBackwards; 20965 renderState.rendering = null; 20966 renderState.renderingStartTime = 0; 20967 renderState.last = lastContentRow; 20968 renderState.tail = tail; 20969 renderState.tailMode = tailMode; 20970 } 20971} // This can end up rendering this component multiple passes. 20972// The first pass splits the children fibers into two sets. A head and tail. 20973// We first render the head. If anything is in fallback state, we do another 20974// pass through beginWork to rerender all children (including the tail) with 20975// the force suspend context. If the first render didn't have anything in 20976// in fallback state. Then we render each row in the tail one-by-one. 20977// That happens in the completeWork phase without going back to beginWork. 20978 20979 20980function updateSuspenseListComponent(current, workInProgress, renderLanes) { 20981 var nextProps = workInProgress.pendingProps; 20982 var revealOrder = nextProps.revealOrder; 20983 var tailMode = nextProps.tail; 20984 var newChildren = nextProps.children; 20985 validateRevealOrder(revealOrder); 20986 validateTailOptions(tailMode, revealOrder); 20987 validateSuspenseListChildren(newChildren, revealOrder); 20988 reconcileChildren(current, workInProgress, newChildren, renderLanes); 20989 var suspenseContext = suspenseStackCursor.current; 20990 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback); 20991 20992 if (shouldForceFallback) { 20993 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback); 20994 workInProgress.flags |= DidCapture; 20995 } else { 20996 var didSuspendBefore = current !== null && (current.flags & DidCapture) !== NoFlags; 20997 20998 if (didSuspendBefore) { 20999 // If we previously forced a fallback, we need to schedule work 21000 // on any nested boundaries to let them know to try to render 21001 // again. This is the same as context updating. 21002 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderLanes); 21003 } 21004 21005 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); 21006 } 21007 21008 pushSuspenseContext(workInProgress, suspenseContext); 21009 21010 if ((workInProgress.mode & ConcurrentMode) === NoMode) { 21011 // In legacy mode, SuspenseList doesn't work so we just 21012 // use make it a noop by treating it as the default revealOrder. 21013 workInProgress.memoizedState = null; 21014 } else { 21015 switch (revealOrder) { 21016 case 'forwards': 21017 { 21018 var lastContentRow = findLastContentRow(workInProgress.child); 21019 var tail; 21020 21021 if (lastContentRow === null) { 21022 // The whole list is part of the tail. 21023 // TODO: We could fast path by just rendering the tail now. 21024 tail = workInProgress.child; 21025 workInProgress.child = null; 21026 } else { 21027 // Disconnect the tail rows after the content row. 21028 // We're going to render them separately later. 21029 tail = lastContentRow.sibling; 21030 lastContentRow.sibling = null; 21031 } 21032 21033 initSuspenseListRenderState(workInProgress, false, // isBackwards 21034 tail, lastContentRow, tailMode); 21035 break; 21036 } 21037 21038 case 'backwards': 21039 { 21040 // We're going to find the first row that has existing content. 21041 // At the same time we're going to reverse the list of everything 21042 // we pass in the meantime. That's going to be our tail in reverse 21043 // order. 21044 var _tail = null; 21045 var row = workInProgress.child; 21046 workInProgress.child = null; 21047 21048 while (row !== null) { 21049 var currentRow = row.alternate; // New rows can't be content rows. 21050 21051 if (currentRow !== null && findFirstSuspended(currentRow) === null) { 21052 // This is the beginning of the main content. 21053 workInProgress.child = row; 21054 break; 21055 } 21056 21057 var nextRow = row.sibling; 21058 row.sibling = _tail; 21059 _tail = row; 21060 row = nextRow; 21061 } // TODO: If workInProgress.child is null, we can continue on the tail immediately. 21062 21063 21064 initSuspenseListRenderState(workInProgress, true, // isBackwards 21065 _tail, null, // last 21066 tailMode); 21067 break; 21068 } 21069 21070 case 'together': 21071 { 21072 initSuspenseListRenderState(workInProgress, false, // isBackwards 21073 null, // tail 21074 null, // last 21075 undefined); 21076 break; 21077 } 21078 21079 default: 21080 { 21081 // The default reveal order is the same as not having 21082 // a boundary. 21083 workInProgress.memoizedState = null; 21084 } 21085 } 21086 } 21087 21088 return workInProgress.child; 21089} 21090 21091function updatePortalComponent(current, workInProgress, renderLanes) { 21092 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); 21093 var nextChildren = workInProgress.pendingProps; 21094 21095 if (current === null) { 21096 // Portals are special because we don't append the children during mount 21097 // but at commit. Therefore we need to track insertions which the normal 21098 // flow doesn't do during mount. This doesn't happen at the root because 21099 // the root always starts with a "current" with a null child. 21100 // TODO: Consider unifying this with how the root works. 21101 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes); 21102 } else { 21103 reconcileChildren(current, workInProgress, nextChildren, renderLanes); 21104 } 21105 21106 return workInProgress.child; 21107} 21108 21109var hasWarnedAboutUsingNoValuePropOnContextProvider = false; 21110 21111function updateContextProvider(current, workInProgress, renderLanes) { 21112 var providerType = workInProgress.type; 21113 var context = providerType._context; 21114 var newProps = workInProgress.pendingProps; 21115 var oldProps = workInProgress.memoizedProps; 21116 var newValue = newProps.value; 21117 21118 { 21119 if (!('value' in newProps)) { 21120 if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { 21121 hasWarnedAboutUsingNoValuePropOnContextProvider = true; 21122 21123 error('The `value` prop is required for the `<Context.Provider>`. Did you misspell it or forget to pass it?'); 21124 } 21125 } 21126 21127 var providerPropTypes = workInProgress.type.propTypes; 21128 21129 if (providerPropTypes) { 21130 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider'); 21131 } 21132 } 21133 21134 pushProvider(workInProgress, context, newValue); 21135 21136 { 21137 if (oldProps !== null) { 21138 var oldValue = oldProps.value; 21139 21140 if (objectIs(oldValue, newValue)) { 21141 // No change. Bailout early if children are the same. 21142 if (oldProps.children === newProps.children && !hasContextChanged()) { 21143 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 21144 } 21145 } else { 21146 // The context value changed. Search for matching consumers and schedule 21147 // them to update. 21148 propagateContextChange(workInProgress, context, renderLanes); 21149 } 21150 } 21151 } 21152 21153 var newChildren = newProps.children; 21154 reconcileChildren(current, workInProgress, newChildren, renderLanes); 21155 return workInProgress.child; 21156} 21157 21158var hasWarnedAboutUsingContextAsConsumer = false; 21159 21160function updateContextConsumer(current, workInProgress, renderLanes) { 21161 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In 21162 // DEV mode, we create a separate object for Context.Consumer that acts 21163 // like a proxy to Context. This proxy object adds unnecessary code in PROD 21164 // so we use the old behaviour (Context.Consumer references Context) to 21165 // reduce size and overhead. The separate object references context via 21166 // a property called "_context", which also gives us the ability to check 21167 // in DEV mode if this property exists or not and warn if it does not. 21168 21169 { 21170 if (context._context === undefined) { 21171 // This may be because it's a Context (rather than a Consumer). 21172 // Or it may be because it's older React where they're the same thing. 21173 // We only want to warn if we're sure it's a new React. 21174 if (context !== context.Consumer) { 21175 if (!hasWarnedAboutUsingContextAsConsumer) { 21176 hasWarnedAboutUsingContextAsConsumer = true; 21177 21178 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?'); 21179 } 21180 } 21181 } else { 21182 context = context._context; 21183 } 21184 } 21185 21186 var newProps = workInProgress.pendingProps; 21187 var render = newProps.children; 21188 21189 { 21190 if (typeof render !== 'function') { 21191 error('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.'); 21192 } 21193 } 21194 21195 prepareToReadContext(workInProgress, renderLanes); 21196 var newValue = readContext(context); 21197 21198 { 21199 markComponentRenderStarted(workInProgress); 21200 } 21201 21202 var newChildren; 21203 21204 { 21205 ReactCurrentOwner$1.current = workInProgress; 21206 setIsRendering(true); 21207 newChildren = render(newValue); 21208 setIsRendering(false); 21209 } 21210 21211 { 21212 markComponentRenderStopped(); 21213 } // React DevTools reads this flag. 21214 21215 21216 workInProgress.flags |= PerformedWork; 21217 reconcileChildren(current, workInProgress, newChildren, renderLanes); 21218 return workInProgress.child; 21219} 21220 21221function markWorkInProgressReceivedUpdate() { 21222 didReceiveUpdate = true; 21223} 21224 21225function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) { 21226 if ((workInProgress.mode & ConcurrentMode) === NoMode) { 21227 if (current !== null) { 21228 // A lazy component only mounts if it suspended inside a non- 21229 // concurrent tree, in an inconsistent state. We want to treat it like 21230 // a new mount, even though an empty version of it already committed. 21231 // Disconnect the alternate pointers. 21232 current.alternate = null; 21233 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect 21234 21235 workInProgress.flags |= Placement; 21236 } 21237 } 21238} 21239 21240function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { 21241 if (current !== null) { 21242 // Reuse previous dependencies 21243 workInProgress.dependencies = current.dependencies; 21244 } 21245 21246 { 21247 // Don't update "base" render times for bailouts. 21248 stopProfilerTimerIfRunning(); 21249 } 21250 21251 markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. 21252 21253 if (!includesSomeLane(renderLanes, workInProgress.childLanes)) { 21254 // The children don't have any work either. We can skip them. 21255 // TODO: Once we add back resuming, we should check if the children are 21256 // a work-in-progress set. If so, we need to transfer their effects. 21257 { 21258 return null; 21259 } 21260 } // This fiber doesn't have work, but its subtree does. Clone the child 21261 // fibers and continue. 21262 21263 21264 cloneChildFibers(current, workInProgress); 21265 return workInProgress.child; 21266} 21267 21268function remountFiber(current, oldWorkInProgress, newWorkInProgress) { 21269 { 21270 var returnFiber = oldWorkInProgress.return; 21271 21272 if (returnFiber === null) { 21273 // eslint-disable-next-line react-internal/prod-error-codes 21274 throw new Error('Cannot swap the root fiber.'); 21275 } // Disconnect from the old current. 21276 // It will get deleted. 21277 21278 21279 current.alternate = null; 21280 oldWorkInProgress.alternate = null; // Connect to the new tree. 21281 21282 newWorkInProgress.index = oldWorkInProgress.index; 21283 newWorkInProgress.sibling = oldWorkInProgress.sibling; 21284 newWorkInProgress.return = oldWorkInProgress.return; 21285 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. 21286 21287 if (oldWorkInProgress === returnFiber.child) { 21288 returnFiber.child = newWorkInProgress; 21289 } else { 21290 var prevSibling = returnFiber.child; 21291 21292 if (prevSibling === null) { 21293 // eslint-disable-next-line react-internal/prod-error-codes 21294 throw new Error('Expected parent to have a child.'); 21295 } 21296 21297 while (prevSibling.sibling !== oldWorkInProgress) { 21298 prevSibling = prevSibling.sibling; 21299 21300 if (prevSibling === null) { 21301 // eslint-disable-next-line react-internal/prod-error-codes 21302 throw new Error('Expected to find the previous sibling.'); 21303 } 21304 } 21305 21306 prevSibling.sibling = newWorkInProgress; 21307 } // Delete the old fiber and place the new one. 21308 // Since the old fiber is disconnected, we have to schedule it manually. 21309 21310 21311 var deletions = returnFiber.deletions; 21312 21313 if (deletions === null) { 21314 returnFiber.deletions = [current]; 21315 returnFiber.flags |= ChildDeletion; 21316 } else { 21317 deletions.push(current); 21318 } 21319 21320 newWorkInProgress.flags |= Placement; // Restart work from the new fiber. 21321 21322 return newWorkInProgress; 21323 } 21324} 21325 21326function checkScheduledUpdateOrContext(current, renderLanes) { 21327 // Before performing an early bailout, we must check if there are pending 21328 // updates or context. 21329 var updateLanes = current.lanes; 21330 21331 if (includesSomeLane(updateLanes, renderLanes)) { 21332 return true; 21333 } // No pending update, but because context is propagated lazily, we need 21334 21335 return false; 21336} 21337 21338function attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes) { 21339 // This fiber does not have any pending work. Bailout without entering 21340 // the begin phase. There's still some bookkeeping we that needs to be done 21341 // in this optimized path, mostly pushing stuff onto the stack. 21342 switch (workInProgress.tag) { 21343 case HostRoot: 21344 pushHostRootContext(workInProgress); 21345 var root = workInProgress.stateNode; 21346 21347 resetHydrationState(); 21348 break; 21349 21350 case HostComponent: 21351 pushHostContext(workInProgress); 21352 break; 21353 21354 case ClassComponent: 21355 { 21356 var Component = workInProgress.type; 21357 21358 if (isContextProvider(Component)) { 21359 pushContextProvider(workInProgress); 21360 } 21361 21362 break; 21363 } 21364 21365 case HostPortal: 21366 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); 21367 break; 21368 21369 case ContextProvider: 21370 { 21371 var newValue = workInProgress.memoizedProps.value; 21372 var context = workInProgress.type._context; 21373 pushProvider(workInProgress, context, newValue); 21374 break; 21375 } 21376 21377 case Profiler: 21378 { 21379 // Profiler should only call onRender when one of its descendants actually rendered. 21380 var hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes); 21381 21382 if (hasChildWork) { 21383 workInProgress.flags |= Update; 21384 } 21385 21386 { 21387 // Reset effect durations for the next eventual effect phase. 21388 // These are reset during render to allow the DevTools commit hook a chance to read them, 21389 var stateNode = workInProgress.stateNode; 21390 stateNode.effectDuration = 0; 21391 stateNode.passiveEffectDuration = 0; 21392 } 21393 } 21394 21395 break; 21396 21397 case SuspenseComponent: 21398 { 21399 var state = workInProgress.memoizedState; 21400 21401 if (state !== null) { 21402 if (state.dehydrated !== null) { 21403 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // We know that this component will suspend again because if it has 21404 // been unsuspended it has committed as a resolved Suspense component. 21405 // If it needs to be retried, it should have work scheduled on it. 21406 21407 workInProgress.flags |= DidCapture; // We should never render the children of a dehydrated boundary until we 21408 // upgrade it. We return null instead of bailoutOnAlreadyFinishedWork. 21409 21410 return null; 21411 } // If this boundary is currently timed out, we need to decide 21412 // whether to retry the primary children, or to skip over it and 21413 // go straight to the fallback. Check the priority of the primary 21414 // child fragment. 21415 21416 21417 var primaryChildFragment = workInProgress.child; 21418 var primaryChildLanes = primaryChildFragment.childLanes; 21419 21420 if (includesSomeLane(renderLanes, primaryChildLanes)) { 21421 // The primary children have pending work. Use the normal path 21422 // to attempt to render the primary children again. 21423 return updateSuspenseComponent(current, workInProgress, renderLanes); 21424 } else { 21425 // The primary child fragment does not have pending work marked 21426 // on it 21427 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient 21428 // priority. Bailout. 21429 21430 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 21431 21432 if (child !== null) { 21433 // The fallback children have pending work. Skip over the 21434 // primary children and work on the fallback. 21435 return child.sibling; 21436 } else { 21437 // Note: We can return `null` here because we already checked 21438 // whether there were nested context consumers, via the call to 21439 // `bailoutOnAlreadyFinishedWork` above. 21440 return null; 21441 } 21442 } 21443 } else { 21444 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); 21445 } 21446 21447 break; 21448 } 21449 21450 case SuspenseListComponent: 21451 { 21452 var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; 21453 21454 var _hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes); 21455 21456 if (didSuspendBefore) { 21457 if (_hasChildWork) { 21458 // If something was in fallback state last time, and we have all the 21459 // same children then we're still in progressive loading state. 21460 // Something might get unblocked by state updates or retries in the 21461 // tree which will affect the tail. So we need to use the normal 21462 // path to compute the correct tail. 21463 return updateSuspenseListComponent(current, workInProgress, renderLanes); 21464 } // If none of the children had any work, that means that none of 21465 // them got retried so they'll still be blocked in the same way 21466 // as before. We can fast bail out. 21467 21468 21469 workInProgress.flags |= DidCapture; 21470 } // If nothing suspended before and we're rendering the same children, 21471 // then the tail doesn't matter. Anything new that suspends will work 21472 // in the "together" mode, so we can continue from the state we had. 21473 21474 21475 var renderState = workInProgress.memoizedState; 21476 21477 if (renderState !== null) { 21478 // Reset to the "together" mode in case we've started a different 21479 // update in the past but didn't complete it. 21480 renderState.rendering = null; 21481 renderState.tail = null; 21482 renderState.lastEffect = null; 21483 } 21484 21485 pushSuspenseContext(workInProgress, suspenseStackCursor.current); 21486 21487 if (_hasChildWork) { 21488 break; 21489 } else { 21490 // If none of the children had any work, that means that none of 21491 // them got retried so they'll still be blocked in the same way 21492 // as before. We can fast bail out. 21493 return null; 21494 } 21495 } 21496 21497 case OffscreenComponent: 21498 case LegacyHiddenComponent: 21499 { 21500 // Need to check if the tree still needs to be deferred. This is 21501 // almost identical to the logic used in the normal update path, 21502 // so we'll just enter that. The only difference is we'll bail out 21503 // at the next level instead of this one, because the child props 21504 // have not changed. Which is fine. 21505 // TODO: Probably should refactor `beginWork` to split the bailout 21506 // path from the normal path. I'm tempted to do a labeled break here 21507 // but I won't :) 21508 workInProgress.lanes = NoLanes; 21509 return updateOffscreenComponent(current, workInProgress, renderLanes); 21510 } 21511 } 21512 21513 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); 21514} 21515 21516function beginWork(current, workInProgress, renderLanes) { 21517 { 21518 if (workInProgress._debugNeedsRemount && current !== null) { 21519 // This will restart the begin phase with a new fiber. 21520 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.lanes)); 21521 } 21522 } 21523 21524 if (current !== null) { 21525 var oldProps = current.memoizedProps; 21526 var newProps = workInProgress.pendingProps; 21527 21528 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload: 21529 workInProgress.type !== current.type )) { 21530 // If props or context changed, mark the fiber as having performed work. 21531 // This may be unset if the props are determined to be equal later (memo). 21532 didReceiveUpdate = true; 21533 } else { 21534 // Neither props nor legacy context changes. Check if there's a pending 21535 // update or context change. 21536 var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes); 21537 21538 if (!hasScheduledUpdateOrContext && // If this is the second pass of an error or suspense boundary, there 21539 // may not be work scheduled on `current`, so we check for this flag. 21540 (workInProgress.flags & DidCapture) === NoFlags) { 21541 // No pending updates or context. Bail out now. 21542 didReceiveUpdate = false; 21543 return attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes); 21544 } 21545 21546 if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { 21547 // This is a special case that only exists for legacy mode. 21548 // See https://github.com/facebook/react/pull/19216. 21549 didReceiveUpdate = true; 21550 } else { 21551 // An update was scheduled on this fiber, but there are no new props 21552 // nor legacy context. Set this to false. If an update queue or context 21553 // consumer produces a changed value, it will set this to true. Otherwise, 21554 // the component will assume the children have not changed and bail out. 21555 didReceiveUpdate = false; 21556 } 21557 } 21558 } else { 21559 didReceiveUpdate = false; 21560 21561 if (getIsHydrating() && isForkedChild(workInProgress)) { 21562 // Check if this child belongs to a list of muliple children in 21563 // its parent. 21564 // 21565 // In a true multi-threaded implementation, we would render children on 21566 // parallel threads. This would represent the beginning of a new render 21567 // thread for this subtree. 21568 // 21569 // We only use this for id generation during hydration, which is why the 21570 // logic is located in this special branch. 21571 var slotIndex = workInProgress.index; 21572 var numberOfForks = getForksAtLevel(); 21573 pushTreeId(workInProgress, numberOfForks, slotIndex); 21574 } 21575 } // Before entering the begin phase, clear pending update priority. 21576 // TODO: This assumes that we're about to evaluate the component and process 21577 // the update queue. However, there's an exception: SimpleMemoComponent 21578 // sometimes bails out later in the begin phase. This indicates that we should 21579 // move this assignment out of the common path and into each branch. 21580 21581 21582 workInProgress.lanes = NoLanes; 21583 21584 switch (workInProgress.tag) { 21585 case IndeterminateComponent: 21586 { 21587 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderLanes); 21588 } 21589 21590 case LazyComponent: 21591 { 21592 var elementType = workInProgress.elementType; 21593 return mountLazyComponent(current, workInProgress, elementType, renderLanes); 21594 } 21595 21596 case FunctionComponent: 21597 { 21598 var Component = workInProgress.type; 21599 var unresolvedProps = workInProgress.pendingProps; 21600 var resolvedProps = workInProgress.elementType === Component ? unresolvedProps : resolveDefaultProps(Component, unresolvedProps); 21601 return updateFunctionComponent(current, workInProgress, Component, resolvedProps, renderLanes); 21602 } 21603 21604 case ClassComponent: 21605 { 21606 var _Component = workInProgress.type; 21607 var _unresolvedProps = workInProgress.pendingProps; 21608 21609 var _resolvedProps = workInProgress.elementType === _Component ? _unresolvedProps : resolveDefaultProps(_Component, _unresolvedProps); 21610 21611 return updateClassComponent(current, workInProgress, _Component, _resolvedProps, renderLanes); 21612 } 21613 21614 case HostRoot: 21615 return updateHostRoot(current, workInProgress, renderLanes); 21616 21617 case HostComponent: 21618 return updateHostComponent(current, workInProgress, renderLanes); 21619 21620 case HostText: 21621 return updateHostText(current, workInProgress); 21622 21623 case SuspenseComponent: 21624 return updateSuspenseComponent(current, workInProgress, renderLanes); 21625 21626 case HostPortal: 21627 return updatePortalComponent(current, workInProgress, renderLanes); 21628 21629 case ForwardRef: 21630 { 21631 var type = workInProgress.type; 21632 var _unresolvedProps2 = workInProgress.pendingProps; 21633 21634 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2); 21635 21636 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderLanes); 21637 } 21638 21639 case Fragment: 21640 return updateFragment(current, workInProgress, renderLanes); 21641 21642 case Mode: 21643 return updateMode(current, workInProgress, renderLanes); 21644 21645 case Profiler: 21646 return updateProfiler(current, workInProgress, renderLanes); 21647 21648 case ContextProvider: 21649 return updateContextProvider(current, workInProgress, renderLanes); 21650 21651 case ContextConsumer: 21652 return updateContextConsumer(current, workInProgress, renderLanes); 21653 21654 case MemoComponent: 21655 { 21656 var _type2 = workInProgress.type; 21657 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. 21658 21659 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); 21660 21661 { 21662 if (workInProgress.type !== workInProgress.elementType) { 21663 var outerPropTypes = _type2.propTypes; 21664 21665 if (outerPropTypes) { 21666 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only 21667 'prop', getComponentNameFromType(_type2)); 21668 } 21669 } 21670 } 21671 21672 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); 21673 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, renderLanes); 21674 } 21675 21676 case SimpleMemoComponent: 21677 { 21678 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, renderLanes); 21679 } 21680 21681 case IncompleteClassComponent: 21682 { 21683 var _Component2 = workInProgress.type; 21684 var _unresolvedProps4 = workInProgress.pendingProps; 21685 21686 var _resolvedProps4 = workInProgress.elementType === _Component2 ? _unresolvedProps4 : resolveDefaultProps(_Component2, _unresolvedProps4); 21687 21688 return mountIncompleteClassComponent(current, workInProgress, _Component2, _resolvedProps4, renderLanes); 21689 } 21690 21691 case SuspenseListComponent: 21692 { 21693 return updateSuspenseListComponent(current, workInProgress, renderLanes); 21694 } 21695 21696 case ScopeComponent: 21697 { 21698 21699 break; 21700 } 21701 21702 case OffscreenComponent: 21703 { 21704 return updateOffscreenComponent(current, workInProgress, renderLanes); 21705 } 21706 } 21707 21708 throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + 'React. Please file an issue.'); 21709} 21710 21711function markUpdate(workInProgress) { 21712 // Tag the fiber with an update effect. This turns a Placement into 21713 // a PlacementAndUpdate. 21714 workInProgress.flags |= Update; 21715} 21716 21717function markRef$1(workInProgress) { 21718 workInProgress.flags |= Ref; 21719 21720 { 21721 workInProgress.flags |= RefStatic; 21722 } 21723} 21724 21725var appendAllChildren; 21726var updateHostContainer; 21727var updateHostComponent$1; 21728var updateHostText$1; 21729 21730{ 21731 // Mutation mode 21732 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) { 21733 // We only have the top Fiber that was created but we need recurse down its 21734 // children to find all the terminal nodes. 21735 var node = workInProgress.child; 21736 21737 while (node !== null) { 21738 if (node.tag === HostComponent || node.tag === HostText) { 21739 appendInitialChild(parent, node.stateNode); 21740 } else if (node.tag === HostPortal) ; else if (node.child !== null) { 21741 node.child.return = node; 21742 node = node.child; 21743 continue; 21744 } 21745 21746 if (node === workInProgress) { 21747 return; 21748 } 21749 21750 while (node.sibling === null) { 21751 if (node.return === null || node.return === workInProgress) { 21752 return; 21753 } 21754 21755 node = node.return; 21756 } 21757 21758 node.sibling.return = node.return; 21759 node = node.sibling; 21760 } 21761 }; 21762 21763 updateHostContainer = function (current, workInProgress) {// Noop 21764 }; 21765 21766 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) { 21767 // If we have an alternate, that means this is an update and we need to 21768 // schedule a side-effect to do the updates. 21769 var oldProps = current.memoizedProps; 21770 21771 if (oldProps === newProps) { 21772 // In mutation mode, this is sufficient for a bailout because 21773 // we won't touch this node even if children changed. 21774 return; 21775 } // If we get updated because one of our children updated, we don't 21776 // have newProps so we'll have to reuse them. 21777 // TODO: Split the update API as separate for the props vs. children. 21778 // Even better would be if children weren't special cased at all tho. 21779 21780 21781 var instance = workInProgress.stateNode; 21782 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host 21783 // component is hitting the resume path. Figure out why. Possibly 21784 // related to `hidden`. 21785 21786 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); // TODO: Type this specific to this type of component. 21787 21788 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there 21789 // is a new ref we mark this as an update. All the work is done in commitWork. 21790 21791 if (updatePayload) { 21792 markUpdate(workInProgress); 21793 } 21794 }; 21795 21796 updateHostText$1 = function (current, workInProgress, oldText, newText) { 21797 // If the text differs, mark it as an update. All the work in done in commitWork. 21798 if (oldText !== newText) { 21799 markUpdate(workInProgress); 21800 } 21801 }; 21802} 21803 21804function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { 21805 if (getIsHydrating()) { 21806 // If we're hydrating, we should consume as many items as we can 21807 // so we don't leave any behind. 21808 return; 21809 } 21810 21811 switch (renderState.tailMode) { 21812 case 'hidden': 21813 { 21814 // Any insertions at the end of the tail list after this point 21815 // should be invisible. If there are already mounted boundaries 21816 // anything before them are not considered for collapsing. 21817 // Therefore we need to go through the whole tail to find if 21818 // there are any. 21819 var tailNode = renderState.tail; 21820 var lastTailNode = null; 21821 21822 while (tailNode !== null) { 21823 if (tailNode.alternate !== null) { 21824 lastTailNode = tailNode; 21825 } 21826 21827 tailNode = tailNode.sibling; 21828 } // Next we're simply going to delete all insertions after the 21829 // last rendered item. 21830 21831 21832 if (lastTailNode === null) { 21833 // All remaining items in the tail are insertions. 21834 renderState.tail = null; 21835 } else { 21836 // Detach the insertion after the last node that was already 21837 // inserted. 21838 lastTailNode.sibling = null; 21839 } 21840 21841 break; 21842 } 21843 21844 case 'collapsed': 21845 { 21846 // Any insertions at the end of the tail list after this point 21847 // should be invisible. If there are already mounted boundaries 21848 // anything before them are not considered for collapsing. 21849 // Therefore we need to go through the whole tail to find if 21850 // there are any. 21851 var _tailNode = renderState.tail; 21852 var _lastTailNode = null; 21853 21854 while (_tailNode !== null) { 21855 if (_tailNode.alternate !== null) { 21856 _lastTailNode = _tailNode; 21857 } 21858 21859 _tailNode = _tailNode.sibling; 21860 } // Next we're simply going to delete all insertions after the 21861 // last rendered item. 21862 21863 21864 if (_lastTailNode === null) { 21865 // All remaining items in the tail are insertions. 21866 if (!hasRenderedATailFallback && renderState.tail !== null) { 21867 // We suspended during the head. We want to show at least one 21868 // row at the tail. So we'll keep on and cut off the rest. 21869 renderState.tail.sibling = null; 21870 } else { 21871 renderState.tail = null; 21872 } 21873 } else { 21874 // Detach the insertion after the last node that was already 21875 // inserted. 21876 _lastTailNode.sibling = null; 21877 } 21878 21879 break; 21880 } 21881 } 21882} 21883 21884function bubbleProperties(completedWork) { 21885 var didBailout = completedWork.alternate !== null && completedWork.alternate.child === completedWork.child; 21886 var newChildLanes = NoLanes; 21887 var subtreeFlags = NoFlags; 21888 21889 if (!didBailout) { 21890 // Bubble up the earliest expiration time. 21891 if ( (completedWork.mode & ProfileMode) !== NoMode) { 21892 // In profiling mode, resetChildExpirationTime is also used to reset 21893 // profiler durations. 21894 var actualDuration = completedWork.actualDuration; 21895 var treeBaseDuration = completedWork.selfBaseDuration; 21896 var child = completedWork.child; 21897 21898 while (child !== null) { 21899 newChildLanes = mergeLanes(newChildLanes, mergeLanes(child.lanes, child.childLanes)); 21900 subtreeFlags |= child.subtreeFlags; 21901 subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will 21902 // only be updated if work is done on the fiber (i.e. it doesn't bailout). 21903 // When work is done, it should bubble to the parent's actualDuration. If 21904 // the fiber has not been cloned though, (meaning no work was done), then 21905 // this value will reflect the amount of time spent working on a previous 21906 // render. In that case it should not bubble. We determine whether it was 21907 // cloned by comparing the child pointer. 21908 21909 actualDuration += child.actualDuration; 21910 treeBaseDuration += child.treeBaseDuration; 21911 child = child.sibling; 21912 } 21913 21914 completedWork.actualDuration = actualDuration; 21915 completedWork.treeBaseDuration = treeBaseDuration; 21916 } else { 21917 var _child = completedWork.child; 21918 21919 while (_child !== null) { 21920 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child.lanes, _child.childLanes)); 21921 subtreeFlags |= _child.subtreeFlags; 21922 subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code 21923 // smell because it assumes the commit phase is never concurrent with 21924 // the render phase. Will address during refactor to alternate model. 21925 21926 _child.return = completedWork; 21927 _child = _child.sibling; 21928 } 21929 } 21930 21931 completedWork.subtreeFlags |= subtreeFlags; 21932 } else { 21933 // Bubble up the earliest expiration time. 21934 if ( (completedWork.mode & ProfileMode) !== NoMode) { 21935 // In profiling mode, resetChildExpirationTime is also used to reset 21936 // profiler durations. 21937 var _treeBaseDuration = completedWork.selfBaseDuration; 21938 var _child2 = completedWork.child; 21939 21940 while (_child2 !== null) { 21941 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child2.lanes, _child2.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to, 21942 // so we should bubble those up even during a bailout. All the other 21943 // flags have a lifetime only of a single render + commit, so we should 21944 // ignore them. 21945 21946 subtreeFlags |= _child2.subtreeFlags & StaticMask; 21947 subtreeFlags |= _child2.flags & StaticMask; 21948 _treeBaseDuration += _child2.treeBaseDuration; 21949 _child2 = _child2.sibling; 21950 } 21951 21952 completedWork.treeBaseDuration = _treeBaseDuration; 21953 } else { 21954 var _child3 = completedWork.child; 21955 21956 while (_child3 !== null) { 21957 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child3.lanes, _child3.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to, 21958 // so we should bubble those up even during a bailout. All the other 21959 // flags have a lifetime only of a single render + commit, so we should 21960 // ignore them. 21961 21962 subtreeFlags |= _child3.subtreeFlags & StaticMask; 21963 subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code 21964 // smell because it assumes the commit phase is never concurrent with 21965 // the render phase. Will address during refactor to alternate model. 21966 21967 _child3.return = completedWork; 21968 _child3 = _child3.sibling; 21969 } 21970 } 21971 21972 completedWork.subtreeFlags |= subtreeFlags; 21973 } 21974 21975 completedWork.childLanes = newChildLanes; 21976 return didBailout; 21977} 21978 21979function completeDehydratedSuspenseBoundary(current, workInProgress, nextState) { 21980 if (hasUnhydratedTailNodes() && (workInProgress.mode & ConcurrentMode) !== NoMode && (workInProgress.flags & DidCapture) === NoFlags) { 21981 warnIfUnhydratedTailNodes(workInProgress); 21982 resetHydrationState(); 21983 workInProgress.flags |= ForceClientRender | Incomplete | ShouldCapture; 21984 return false; 21985 } 21986 21987 var wasHydrated = popHydrationState(workInProgress); 21988 21989 if (nextState !== null && nextState.dehydrated !== null) { 21990 // We might be inside a hydration state the first time we're picking up this 21991 // Suspense boundary, and also after we've reentered it for further hydration. 21992 if (current === null) { 21993 if (!wasHydrated) { 21994 throw new Error('A dehydrated suspense component was completed without a hydrated node. ' + 'This is probably a bug in React.'); 21995 } 21996 21997 prepareToHydrateHostSuspenseInstance(workInProgress); 21998 bubbleProperties(workInProgress); 21999 22000 { 22001 if ((workInProgress.mode & ProfileMode) !== NoMode) { 22002 var isTimedOutSuspense = nextState !== null; 22003 22004 if (isTimedOutSuspense) { 22005 // Don't count time spent in a timed out Suspense subtree as part of the base duration. 22006 var primaryChildFragment = workInProgress.child; 22007 22008 if (primaryChildFragment !== null) { 22009 // $FlowFixMe Flow doesn't support type casting in combination with the -= operator 22010 workInProgress.treeBaseDuration -= primaryChildFragment.treeBaseDuration; 22011 } 22012 } 22013 } 22014 } 22015 22016 return false; 22017 } else { 22018 // We might have reentered this boundary to hydrate it. If so, we need to reset the hydration 22019 // state since we're now exiting out of it. popHydrationState doesn't do that for us. 22020 resetHydrationState(); 22021 22022 if ((workInProgress.flags & DidCapture) === NoFlags) { 22023 // This boundary did not suspend so it's now hydrated and unsuspended. 22024 workInProgress.memoizedState = null; 22025 } // If nothing suspended, we need to schedule an effect to mark this boundary 22026 // as having hydrated so events know that they're free to be invoked. 22027 // It's also a signal to replay events and the suspense callback. 22028 // If something suspended, schedule an effect to attach retry listeners. 22029 // So we might as well always mark this. 22030 22031 22032 workInProgress.flags |= Update; 22033 bubbleProperties(workInProgress); 22034 22035 { 22036 if ((workInProgress.mode & ProfileMode) !== NoMode) { 22037 var _isTimedOutSuspense = nextState !== null; 22038 22039 if (_isTimedOutSuspense) { 22040 // Don't count time spent in a timed out Suspense subtree as part of the base duration. 22041 var _primaryChildFragment = workInProgress.child; 22042 22043 if (_primaryChildFragment !== null) { 22044 // $FlowFixMe Flow doesn't support type casting in combination with the -= operator 22045 workInProgress.treeBaseDuration -= _primaryChildFragment.treeBaseDuration; 22046 } 22047 } 22048 } 22049 } 22050 22051 return false; 22052 } 22053 } else { 22054 // Successfully completed this tree. If this was a forced client render, 22055 // there may have been recoverable errors during first hydration 22056 // attempt. If so, add them to a queue so we can log them in the 22057 // commit phase. 22058 upgradeHydrationErrorsToRecoverable(); // Fall through to normal Suspense path 22059 22060 return true; 22061 } 22062} 22063 22064function completeWork(current, workInProgress, renderLanes) { 22065 var newProps = workInProgress.pendingProps; // Note: This intentionally doesn't check if we're hydrating because comparing 22066 // to the current tree provider fiber is just as fast and less error-prone. 22067 // Ideally we would have a special version of the work loop only 22068 // for hydration. 22069 22070 popTreeContext(workInProgress); 22071 22072 switch (workInProgress.tag) { 22073 case IndeterminateComponent: 22074 case LazyComponent: 22075 case SimpleMemoComponent: 22076 case FunctionComponent: 22077 case ForwardRef: 22078 case Fragment: 22079 case Mode: 22080 case Profiler: 22081 case ContextConsumer: 22082 case MemoComponent: 22083 bubbleProperties(workInProgress); 22084 return null; 22085 22086 case ClassComponent: 22087 { 22088 var Component = workInProgress.type; 22089 22090 if (isContextProvider(Component)) { 22091 popContext(workInProgress); 22092 } 22093 22094 bubbleProperties(workInProgress); 22095 return null; 22096 } 22097 22098 case HostRoot: 22099 { 22100 var fiberRoot = workInProgress.stateNode; 22101 popHostContainer(workInProgress); 22102 popTopLevelContextObject(workInProgress); 22103 resetWorkInProgressVersions(); 22104 22105 if (fiberRoot.pendingContext) { 22106 fiberRoot.context = fiberRoot.pendingContext; 22107 fiberRoot.pendingContext = null; 22108 } 22109 22110 if (current === null || current.child === null) { 22111 // If we hydrated, pop so that we can delete any remaining children 22112 // that weren't hydrated. 22113 var wasHydrated = popHydrationState(workInProgress); 22114 22115 if (wasHydrated) { 22116 // If we hydrated, then we'll need to schedule an update for 22117 // the commit side-effects on the root. 22118 markUpdate(workInProgress); 22119 } else { 22120 if (current !== null) { 22121 var prevState = current.memoizedState; 22122 22123 if ( // Check if this is a client root 22124 !prevState.isDehydrated || // Check if we reverted to client rendering (e.g. due to an error) 22125 (workInProgress.flags & ForceClientRender) !== NoFlags) { 22126 // Schedule an effect to clear this container at the start of the 22127 // next commit. This handles the case of React rendering into a 22128 // container with previous children. It's also safe to do for 22129 // updates too, because current.child would only be null if the 22130 // previous render was null (so the container would already 22131 // be empty). 22132 workInProgress.flags |= Snapshot; // If this was a forced client render, there may have been 22133 // recoverable errors during first hydration attempt. If so, add 22134 // them to a queue so we can log them in the commit phase. 22135 22136 upgradeHydrationErrorsToRecoverable(); 22137 } 22138 } 22139 } 22140 } 22141 22142 updateHostContainer(current, workInProgress); 22143 bubbleProperties(workInProgress); 22144 22145 return null; 22146 } 22147 22148 case HostComponent: 22149 { 22150 popHostContext(workInProgress); 22151 var rootContainerInstance = getRootHostContainer(); 22152 var type = workInProgress.type; 22153 22154 if (current !== null && workInProgress.stateNode != null) { 22155 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance); 22156 22157 if (current.ref !== workInProgress.ref) { 22158 markRef$1(workInProgress); 22159 } 22160 } else { 22161 if (!newProps) { 22162 if (workInProgress.stateNode === null) { 22163 throw new Error('We must have new props for new mounts. This error is likely ' + 'caused by a bug in React. Please file an issue.'); 22164 } // This can happen when we abort work. 22165 22166 22167 bubbleProperties(workInProgress); 22168 return null; 22169 } 22170 22171 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context 22172 // "stack" as the parent. Then append children as we go in beginWork 22173 // or completeWork depending on whether we want to add them top->down or 22174 // bottom->up. Top->down is faster in IE11. 22175 22176 var _wasHydrated = popHydrationState(workInProgress); 22177 22178 if (_wasHydrated) { 22179 // TODO: Move this and createInstance step into the beginPhase 22180 // to consolidate. 22181 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) { 22182 // If changes to the hydrated node need to be applied at the 22183 // commit-phase we mark this as such. 22184 markUpdate(workInProgress); 22185 } 22186 } else { 22187 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress); 22188 appendAllChildren(instance, workInProgress, false, false); 22189 workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount. 22190 // (eg DOM renderer supports auto-focus for certain elements). 22191 // Make sure such renderers get scheduled for later work. 22192 22193 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance)) { 22194 markUpdate(workInProgress); 22195 } 22196 } 22197 22198 if (workInProgress.ref !== null) { 22199 // If there is a ref on a host node we need to schedule a callback 22200 markRef$1(workInProgress); 22201 } 22202 } 22203 22204 bubbleProperties(workInProgress); 22205 return null; 22206 } 22207 22208 case HostText: 22209 { 22210 var newText = newProps; 22211 22212 if (current && workInProgress.stateNode != null) { 22213 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need 22214 // to schedule a side-effect to do the updates. 22215 22216 updateHostText$1(current, workInProgress, oldText, newText); 22217 } else { 22218 if (typeof newText !== 'string') { 22219 if (workInProgress.stateNode === null) { 22220 throw new Error('We must have new props for new mounts. This error is likely ' + 'caused by a bug in React. Please file an issue.'); 22221 } // This can happen when we abort work. 22222 22223 } 22224 22225 var _rootContainerInstance = getRootHostContainer(); 22226 22227 var _currentHostContext = getHostContext(); 22228 22229 var _wasHydrated2 = popHydrationState(workInProgress); 22230 22231 if (_wasHydrated2) { 22232 if (prepareToHydrateHostTextInstance(workInProgress)) { 22233 markUpdate(workInProgress); 22234 } 22235 } else { 22236 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress); 22237 } 22238 } 22239 22240 bubbleProperties(workInProgress); 22241 return null; 22242 } 22243 22244 case SuspenseComponent: 22245 { 22246 popSuspenseContext(workInProgress); 22247 var nextState = workInProgress.memoizedState; // Special path for dehydrated boundaries. We may eventually move this 22248 // to its own fiber type so that we can add other kinds of hydration 22249 // boundaries that aren't associated with a Suspense tree. In anticipation 22250 // of such a refactor, all the hydration logic is contained in 22251 // this branch. 22252 22253 if (current === null || current.memoizedState !== null && current.memoizedState.dehydrated !== null) { 22254 var fallthroughToNormalSuspensePath = completeDehydratedSuspenseBoundary(current, workInProgress, nextState); 22255 22256 if (!fallthroughToNormalSuspensePath) { 22257 if (workInProgress.flags & ShouldCapture) { 22258 // Special case. There were remaining unhydrated nodes. We treat 22259 // this as a mismatch. Revert to client rendering. 22260 return workInProgress; 22261 } else { 22262 // Did not finish hydrating, either because this is the initial 22263 // render or because something suspended. 22264 return null; 22265 } 22266 } // Continue with the normal Suspense path. 22267 22268 } 22269 22270 if ((workInProgress.flags & DidCapture) !== NoFlags) { 22271 // Something suspended. Re-render with the fallback children. 22272 workInProgress.lanes = renderLanes; // Do not reset the effect list. 22273 22274 if ( (workInProgress.mode & ProfileMode) !== NoMode) { 22275 transferActualDuration(workInProgress); 22276 } // Don't bubble properties in this case. 22277 22278 22279 return workInProgress; 22280 } 22281 22282 var nextDidTimeout = nextState !== null; 22283 var prevDidTimeout = current !== null && current.memoizedState !== null; 22284 // a passive effect, which is when we process the transitions 22285 22286 22287 if (nextDidTimeout !== prevDidTimeout) { 22288 // an effect to toggle the subtree's visibility. When we switch from 22289 // fallback -> primary, the inner Offscreen fiber schedules this effect 22290 // as part of its normal complete phase. But when we switch from 22291 // primary -> fallback, the inner Offscreen fiber does not have a complete 22292 // phase. So we need to schedule its effect here. 22293 // 22294 // We also use this flag to connect/disconnect the effects, but the same 22295 // logic applies: when re-connecting, the Offscreen fiber's complete 22296 // phase will handle scheduling the effect. It's only when the fallback 22297 // is active that we have to do anything special. 22298 22299 22300 if (nextDidTimeout) { 22301 var _offscreenFiber2 = workInProgress.child; 22302 _offscreenFiber2.flags |= Visibility; // TODO: This will still suspend a synchronous tree if anything 22303 // in the concurrent tree already suspended during this render. 22304 // This is a known bug. 22305 22306 if ((workInProgress.mode & ConcurrentMode) !== NoMode) { 22307 // TODO: Move this back to throwException because this is too late 22308 // if this is a large tree which is common for initial loads. We 22309 // don't know if we should restart a render or not until we get 22310 // this marker, and this is too late. 22311 // If this render already had a ping or lower pri updates, 22312 // and this is the first time we know we're going to suspend we 22313 // should be able to immediately restart from within throwException. 22314 var hasInvisibleChildContext = current === null && (workInProgress.memoizedProps.unstable_avoidThisFallback !== true || !enableSuspenseAvoidThisFallback); 22315 22316 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) { 22317 // If this was in an invisible tree or a new render, then showing 22318 // this boundary is ok. 22319 renderDidSuspend(); 22320 } else { 22321 // Otherwise, we're going to have to hide content so we should 22322 // suspend for longer if possible. 22323 renderDidSuspendDelayIfPossible(); 22324 } 22325 } 22326 } 22327 } 22328 22329 var wakeables = workInProgress.updateQueue; 22330 22331 if (wakeables !== null) { 22332 // Schedule an effect to attach a retry listener to the promise. 22333 // TODO: Move to passive phase 22334 workInProgress.flags |= Update; 22335 } 22336 22337 bubbleProperties(workInProgress); 22338 22339 { 22340 if ((workInProgress.mode & ProfileMode) !== NoMode) { 22341 if (nextDidTimeout) { 22342 // Don't count time spent in a timed out Suspense subtree as part of the base duration. 22343 var primaryChildFragment = workInProgress.child; 22344 22345 if (primaryChildFragment !== null) { 22346 // $FlowFixMe Flow doesn't support type casting in combination with the -= operator 22347 workInProgress.treeBaseDuration -= primaryChildFragment.treeBaseDuration; 22348 } 22349 } 22350 } 22351 } 22352 22353 return null; 22354 } 22355 22356 case HostPortal: 22357 popHostContainer(workInProgress); 22358 updateHostContainer(current, workInProgress); 22359 22360 if (current === null) { 22361 preparePortalMount(workInProgress.stateNode.containerInfo); 22362 } 22363 22364 bubbleProperties(workInProgress); 22365 return null; 22366 22367 case ContextProvider: 22368 // Pop provider fiber 22369 var context = workInProgress.type._context; 22370 popProvider(context, workInProgress); 22371 bubbleProperties(workInProgress); 22372 return null; 22373 22374 case IncompleteClassComponent: 22375 { 22376 // Same as class component case. I put it down here so that the tags are 22377 // sequential to ensure this switch is compiled to a jump table. 22378 var _Component = workInProgress.type; 22379 22380 if (isContextProvider(_Component)) { 22381 popContext(workInProgress); 22382 } 22383 22384 bubbleProperties(workInProgress); 22385 return null; 22386 } 22387 22388 case SuspenseListComponent: 22389 { 22390 popSuspenseContext(workInProgress); 22391 var renderState = workInProgress.memoizedState; 22392 22393 if (renderState === null) { 22394 // We're running in the default, "independent" mode. 22395 // We don't do anything in this mode. 22396 bubbleProperties(workInProgress); 22397 return null; 22398 } 22399 22400 var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; 22401 var renderedTail = renderState.rendering; 22402 22403 if (renderedTail === null) { 22404 // We just rendered the head. 22405 if (!didSuspendAlready) { 22406 // This is the first pass. We need to figure out if anything is still 22407 // suspended in the rendered set. 22408 // If new content unsuspended, but there's still some content that 22409 // didn't. Then we need to do a second pass that forces everything 22410 // to keep showing their fallbacks. 22411 // We might be suspended if something in this render pass suspended, or 22412 // something in the previous committed pass suspended. Otherwise, 22413 // there's no chance so we can skip the expensive call to 22414 // findFirstSuspended. 22415 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.flags & DidCapture) === NoFlags); 22416 22417 if (!cannotBeSuspended) { 22418 var row = workInProgress.child; 22419 22420 while (row !== null) { 22421 var suspended = findFirstSuspended(row); 22422 22423 if (suspended !== null) { 22424 didSuspendAlready = true; 22425 workInProgress.flags |= DidCapture; 22426 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as 22427 // part of the second pass. In that case nothing will subscribe to 22428 // its thenables. Instead, we'll transfer its thenables to the 22429 // SuspenseList so that it can retry if they resolve. 22430 // There might be multiple of these in the list but since we're 22431 // going to wait for all of them anyway, it doesn't really matter 22432 // which ones gets to ping. In theory we could get clever and keep 22433 // track of how many dependencies remain but it gets tricky because 22434 // in the meantime, we can add/remove/change items and dependencies. 22435 // We might bail out of the loop before finding any but that 22436 // doesn't matter since that means that the other boundaries that 22437 // we did find already has their listeners attached. 22438 22439 var newThenables = suspended.updateQueue; 22440 22441 if (newThenables !== null) { 22442 workInProgress.updateQueue = newThenables; 22443 workInProgress.flags |= Update; 22444 } // Rerender the whole list, but this time, we'll force fallbacks 22445 // to stay in place. 22446 // Reset the effect flags before doing the second pass since that's now invalid. 22447 // Reset the child fibers to their original state. 22448 22449 22450 workInProgress.subtreeFlags = NoFlags; 22451 resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately 22452 // rerender the children. 22453 22454 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback)); // Don't bubble properties in this case. 22455 22456 return workInProgress.child; 22457 } 22458 22459 row = row.sibling; 22460 } 22461 } 22462 22463 if (renderState.tail !== null && now() > getRenderTargetTime()) { 22464 // We have already passed our CPU deadline but we still have rows 22465 // left in the tail. We'll just give up further attempts to render 22466 // the main content and only render fallbacks. 22467 workInProgress.flags |= DidCapture; 22468 didSuspendAlready = true; 22469 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this 22470 // to get it started back up to attempt the next item. While in terms 22471 // of priority this work has the same priority as this current render, 22472 // it's not part of the same transition once the transition has 22473 // committed. If it's sync, we still want to yield so that it can be 22474 // painted. Conceptually, this is really the same as pinging. 22475 // We can use any RetryLane even if it's the one currently rendering 22476 // since we're leaving it behind on this node. 22477 22478 workInProgress.lanes = SomeRetryLane; 22479 } 22480 } else { 22481 cutOffTailIfNeeded(renderState, false); 22482 } // Next we're going to render the tail. 22483 22484 } else { 22485 // Append the rendered row to the child list. 22486 if (!didSuspendAlready) { 22487 var _suspended = findFirstSuspended(renderedTail); 22488 22489 if (_suspended !== null) { 22490 workInProgress.flags |= DidCapture; 22491 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't 22492 // get lost if this row ends up dropped during a second pass. 22493 22494 var _newThenables = _suspended.updateQueue; 22495 22496 if (_newThenables !== null) { 22497 workInProgress.updateQueue = _newThenables; 22498 workInProgress.flags |= Update; 22499 } 22500 22501 cutOffTailIfNeeded(renderState, true); // This might have been modified. 22502 22503 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate && !getIsHydrating() // We don't cut it if we're hydrating. 22504 ) { 22505 // We're done. 22506 bubbleProperties(workInProgress); 22507 return null; 22508 } 22509 } else if ( // The time it took to render last row is greater than the remaining 22510 // time we have to render. So rendering one more row would likely 22511 // exceed it. 22512 now() * 2 - renderState.renderingStartTime > getRenderTargetTime() && renderLanes !== OffscreenLane) { 22513 // We have now passed our CPU deadline and we'll just give up further 22514 // attempts to render the main content and only render fallbacks. 22515 // The assumption is that this is usually faster. 22516 workInProgress.flags |= DidCapture; 22517 didSuspendAlready = true; 22518 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this 22519 // to get it started back up to attempt the next item. While in terms 22520 // of priority this work has the same priority as this current render, 22521 // it's not part of the same transition once the transition has 22522 // committed. If it's sync, we still want to yield so that it can be 22523 // painted. Conceptually, this is really the same as pinging. 22524 // We can use any RetryLane even if it's the one currently rendering 22525 // since we're leaving it behind on this node. 22526 22527 workInProgress.lanes = SomeRetryLane; 22528 } 22529 } 22530 22531 if (renderState.isBackwards) { 22532 // The effect list of the backwards tail will have been added 22533 // to the end. This breaks the guarantee that life-cycles fire in 22534 // sibling order but that isn't a strong guarantee promised by React. 22535 // Especially since these might also just pop in during future commits. 22536 // Append to the beginning of the list. 22537 renderedTail.sibling = workInProgress.child; 22538 workInProgress.child = renderedTail; 22539 } else { 22540 var previousSibling = renderState.last; 22541 22542 if (previousSibling !== null) { 22543 previousSibling.sibling = renderedTail; 22544 } else { 22545 workInProgress.child = renderedTail; 22546 } 22547 22548 renderState.last = renderedTail; 22549 } 22550 } 22551 22552 if (renderState.tail !== null) { 22553 // We still have tail rows to render. 22554 // Pop a row. 22555 var next = renderState.tail; 22556 renderState.rendering = next; 22557 renderState.tail = next.sibling; 22558 renderState.renderingStartTime = now(); 22559 next.sibling = null; // Restore the context. 22560 // TODO: We can probably just avoid popping it instead and only 22561 // setting it the first time we go from not suspended to suspended. 22562 22563 var suspenseContext = suspenseStackCursor.current; 22564 22565 if (didSuspendAlready) { 22566 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback); 22567 } else { 22568 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); 22569 } 22570 22571 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. 22572 // Don't bubble properties in this case. 22573 22574 return next; 22575 } 22576 22577 bubbleProperties(workInProgress); 22578 return null; 22579 } 22580 22581 case ScopeComponent: 22582 { 22583 22584 break; 22585 } 22586 22587 case OffscreenComponent: 22588 case LegacyHiddenComponent: 22589 { 22590 popRenderLanes(workInProgress); 22591 var _nextState = workInProgress.memoizedState; 22592 var nextIsHidden = _nextState !== null; 22593 22594 if (current !== null) { 22595 var _prevState = current.memoizedState; 22596 var prevIsHidden = _prevState !== null; 22597 22598 if (prevIsHidden !== nextIsHidden && ( // LegacyHidden doesn't do any hiding — it only pre-renders. 22599 !enableLegacyHidden )) { 22600 workInProgress.flags |= Visibility; 22601 } 22602 } 22603 22604 if (!nextIsHidden || (workInProgress.mode & ConcurrentMode) === NoMode) { 22605 bubbleProperties(workInProgress); 22606 } else { 22607 // Don't bubble properties for hidden children unless we're rendering 22608 // at offscreen priority. 22609 if (includesSomeLane(subtreeRenderLanes, OffscreenLane)) { 22610 bubbleProperties(workInProgress); 22611 22612 { 22613 // Check if there was an insertion or update in the hidden subtree. 22614 // If so, we need to hide those nodes in the commit phase, so 22615 // schedule a visibility effect. 22616 if ( workInProgress.subtreeFlags & (Placement | Update)) { 22617 workInProgress.flags |= Visibility; 22618 } 22619 } 22620 } 22621 } 22622 return null; 22623 } 22624 22625 case CacheComponent: 22626 { 22627 22628 return null; 22629 } 22630 22631 case TracingMarkerComponent: 22632 { 22633 22634 return null; 22635 } 22636 } 22637 22638 throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + 'React. Please file an issue.'); 22639} 22640 22641function unwindWork(current, workInProgress, renderLanes) { 22642 // Note: This intentionally doesn't check if we're hydrating because comparing 22643 // to the current tree provider fiber is just as fast and less error-prone. 22644 // Ideally we would have a special version of the work loop only 22645 // for hydration. 22646 popTreeContext(workInProgress); 22647 22648 switch (workInProgress.tag) { 22649 case ClassComponent: 22650 { 22651 var Component = workInProgress.type; 22652 22653 if (isContextProvider(Component)) { 22654 popContext(workInProgress); 22655 } 22656 22657 var flags = workInProgress.flags; 22658 22659 if (flags & ShouldCapture) { 22660 workInProgress.flags = flags & ~ShouldCapture | DidCapture; 22661 22662 if ( (workInProgress.mode & ProfileMode) !== NoMode) { 22663 transferActualDuration(workInProgress); 22664 } 22665 22666 return workInProgress; 22667 } 22668 22669 return null; 22670 } 22671 22672 case HostRoot: 22673 { 22674 var root = workInProgress.stateNode; 22675 popHostContainer(workInProgress); 22676 popTopLevelContextObject(workInProgress); 22677 resetWorkInProgressVersions(); 22678 var _flags = workInProgress.flags; 22679 22680 if ((_flags & ShouldCapture) !== NoFlags && (_flags & DidCapture) === NoFlags) { 22681 // There was an error during render that wasn't captured by a suspense 22682 // boundary. Do a second pass on the root to unmount the children. 22683 workInProgress.flags = _flags & ~ShouldCapture | DidCapture; 22684 return workInProgress; 22685 } // We unwound to the root without completing it. Exit. 22686 22687 22688 return null; 22689 } 22690 22691 case HostComponent: 22692 { 22693 // TODO: popHydrationState 22694 popHostContext(workInProgress); 22695 return null; 22696 } 22697 22698 case SuspenseComponent: 22699 { 22700 popSuspenseContext(workInProgress); 22701 var suspenseState = workInProgress.memoizedState; 22702 22703 if (suspenseState !== null && suspenseState.dehydrated !== null) { 22704 if (workInProgress.alternate === null) { 22705 throw new Error('Threw in newly mounted dehydrated component. This is likely a bug in ' + 'React. Please file an issue.'); 22706 } 22707 22708 resetHydrationState(); 22709 } 22710 22711 var _flags2 = workInProgress.flags; 22712 22713 if (_flags2 & ShouldCapture) { 22714 workInProgress.flags = _flags2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary. 22715 22716 if ( (workInProgress.mode & ProfileMode) !== NoMode) { 22717 transferActualDuration(workInProgress); 22718 } 22719 22720 return workInProgress; 22721 } 22722 22723 return null; 22724 } 22725 22726 case SuspenseListComponent: 22727 { 22728 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been 22729 // caught by a nested boundary. If not, it should bubble through. 22730 22731 return null; 22732 } 22733 22734 case HostPortal: 22735 popHostContainer(workInProgress); 22736 return null; 22737 22738 case ContextProvider: 22739 var context = workInProgress.type._context; 22740 popProvider(context, workInProgress); 22741 return null; 22742 22743 case OffscreenComponent: 22744 case LegacyHiddenComponent: 22745 popRenderLanes(workInProgress); 22746 return null; 22747 22748 case CacheComponent: 22749 22750 return null; 22751 22752 default: 22753 return null; 22754 } 22755} 22756 22757function unwindInterruptedWork(current, interruptedWork, renderLanes) { 22758 // Note: This intentionally doesn't check if we're hydrating because comparing 22759 // to the current tree provider fiber is just as fast and less error-prone. 22760 // Ideally we would have a special version of the work loop only 22761 // for hydration. 22762 popTreeContext(interruptedWork); 22763 22764 switch (interruptedWork.tag) { 22765 case ClassComponent: 22766 { 22767 var childContextTypes = interruptedWork.type.childContextTypes; 22768 22769 if (childContextTypes !== null && childContextTypes !== undefined) { 22770 popContext(interruptedWork); 22771 } 22772 22773 break; 22774 } 22775 22776 case HostRoot: 22777 { 22778 var root = interruptedWork.stateNode; 22779 popHostContainer(interruptedWork); 22780 popTopLevelContextObject(interruptedWork); 22781 resetWorkInProgressVersions(); 22782 break; 22783 } 22784 22785 case HostComponent: 22786 { 22787 popHostContext(interruptedWork); 22788 break; 22789 } 22790 22791 case HostPortal: 22792 popHostContainer(interruptedWork); 22793 break; 22794 22795 case SuspenseComponent: 22796 popSuspenseContext(interruptedWork); 22797 break; 22798 22799 case SuspenseListComponent: 22800 popSuspenseContext(interruptedWork); 22801 break; 22802 22803 case ContextProvider: 22804 var context = interruptedWork.type._context; 22805 popProvider(context, interruptedWork); 22806 break; 22807 22808 case OffscreenComponent: 22809 case LegacyHiddenComponent: 22810 popRenderLanes(interruptedWork); 22811 break; 22812 } 22813} 22814 22815var didWarnAboutUndefinedSnapshotBeforeUpdate = null; 22816 22817{ 22818 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); 22819} // Used during the commit phase to track the state of the Offscreen component stack. 22820// Allows us to avoid traversing the return path to find the nearest Offscreen ancestor. 22821// Only used when enableSuspenseLayoutEffectSemantics is enabled. 22822 22823 22824var offscreenSubtreeIsHidden = false; 22825var offscreenSubtreeWasHidden = false; 22826var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set; 22827var nextEffect = null; // Used for Profiling builds to track updaters. 22828 22829var inProgressLanes = null; 22830var inProgressRoot = null; 22831function reportUncaughtErrorInDEV(error) { 22832 // Wrapping each small part of the commit phase into a guarded 22833 // callback is a bit too slow (https://github.com/facebook/react/pull/21666). 22834 // But we rely on it to surface errors to DEV tools like overlays 22835 // (https://github.com/facebook/react/issues/21712). 22836 // As a compromise, rethrow only caught errors in a guard. 22837 { 22838 invokeGuardedCallback(null, function () { 22839 throw error; 22840 }); 22841 clearCaughtError(); 22842 } 22843} 22844 22845var callComponentWillUnmountWithTimer = function (current, instance) { 22846 instance.props = current.memoizedProps; 22847 instance.state = current.memoizedState; 22848 22849 if ( current.mode & ProfileMode) { 22850 try { 22851 startLayoutEffectTimer(); 22852 instance.componentWillUnmount(); 22853 } finally { 22854 recordLayoutEffectDuration(current); 22855 } 22856 } else { 22857 instance.componentWillUnmount(); 22858 } 22859}; // Capture errors so they don't interrupt mounting. 22860 22861 22862function safelyCallCommitHookLayoutEffectListMount(current, nearestMountedAncestor) { 22863 try { 22864 commitHookEffectListMount(Layout, current); 22865 } catch (error) { 22866 captureCommitPhaseError(current, nearestMountedAncestor, error); 22867 } 22868} // Capture errors so they don't interrupt unmounting. 22869 22870 22871function safelyCallComponentWillUnmount(current, nearestMountedAncestor, instance) { 22872 try { 22873 callComponentWillUnmountWithTimer(current, instance); 22874 } catch (error) { 22875 captureCommitPhaseError(current, nearestMountedAncestor, error); 22876 } 22877} // Capture errors so they don't interrupt mounting. 22878 22879 22880function safelyCallComponentDidMount(current, nearestMountedAncestor, instance) { 22881 try { 22882 instance.componentDidMount(); 22883 } catch (error) { 22884 captureCommitPhaseError(current, nearestMountedAncestor, error); 22885 } 22886} // Capture errors so they don't interrupt mounting. 22887 22888 22889function safelyAttachRef(current, nearestMountedAncestor) { 22890 try { 22891 commitAttachRef(current); 22892 } catch (error) { 22893 captureCommitPhaseError(current, nearestMountedAncestor, error); 22894 } 22895} 22896 22897function safelyDetachRef(current, nearestMountedAncestor) { 22898 var ref = current.ref; 22899 22900 if (ref !== null) { 22901 if (typeof ref === 'function') { 22902 var retVal; 22903 22904 try { 22905 if (enableProfilerTimer && enableProfilerCommitHooks && current.mode & ProfileMode) { 22906 try { 22907 startLayoutEffectTimer(); 22908 retVal = ref(null); 22909 } finally { 22910 recordLayoutEffectDuration(current); 22911 } 22912 } else { 22913 retVal = ref(null); 22914 } 22915 } catch (error) { 22916 captureCommitPhaseError(current, nearestMountedAncestor, error); 22917 } 22918 22919 { 22920 if (typeof retVal === 'function') { 22921 error('Unexpected return value from a callback ref in %s. ' + 'A callback ref should not return a function.', getComponentNameFromFiber(current)); 22922 } 22923 } 22924 } else { 22925 ref.current = null; 22926 } 22927 } 22928} 22929 22930function safelyCallDestroy(current, nearestMountedAncestor, destroy) { 22931 try { 22932 destroy(); 22933 } catch (error) { 22934 captureCommitPhaseError(current, nearestMountedAncestor, error); 22935 } 22936} 22937 22938var focusedInstanceHandle = null; 22939var shouldFireAfterActiveInstanceBlur = false; 22940function commitBeforeMutationEffects(root, firstChild) { 22941 focusedInstanceHandle = prepareForCommit(root.containerInfo); 22942 nextEffect = firstChild; 22943 commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber 22944 22945 var shouldFire = shouldFireAfterActiveInstanceBlur; 22946 shouldFireAfterActiveInstanceBlur = false; 22947 focusedInstanceHandle = null; 22948 return shouldFire; 22949} 22950 22951function commitBeforeMutationEffects_begin() { 22952 while (nextEffect !== null) { 22953 var fiber = nextEffect; // This phase is only used for beforeActiveInstanceBlur. 22954 22955 var child = fiber.child; 22956 22957 if ((fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && child !== null) { 22958 child.return = fiber; 22959 nextEffect = child; 22960 } else { 22961 commitBeforeMutationEffects_complete(); 22962 } 22963 } 22964} 22965 22966function commitBeforeMutationEffects_complete() { 22967 while (nextEffect !== null) { 22968 var fiber = nextEffect; 22969 setCurrentFiber(fiber); 22970 22971 try { 22972 commitBeforeMutationEffectsOnFiber(fiber); 22973 } catch (error) { 22974 captureCommitPhaseError(fiber, fiber.return, error); 22975 } 22976 22977 resetCurrentFiber(); 22978 var sibling = fiber.sibling; 22979 22980 if (sibling !== null) { 22981 sibling.return = fiber.return; 22982 nextEffect = sibling; 22983 return; 22984 } 22985 22986 nextEffect = fiber.return; 22987 } 22988} 22989 22990function commitBeforeMutationEffectsOnFiber(finishedWork) { 22991 var current = finishedWork.alternate; 22992 var flags = finishedWork.flags; 22993 22994 if ((flags & Snapshot) !== NoFlags) { 22995 setCurrentFiber(finishedWork); 22996 22997 switch (finishedWork.tag) { 22998 case FunctionComponent: 22999 case ForwardRef: 23000 case SimpleMemoComponent: 23001 { 23002 break; 23003 } 23004 23005 case ClassComponent: 23006 { 23007 if (current !== null) { 23008 var prevProps = current.memoizedProps; 23009 var prevState = current.memoizedState; 23010 var instance = finishedWork.stateNode; // We could update instance props and state here, 23011 // but instead we rely on them being set during last render. 23012 // TODO: revisit this when we implement resuming. 23013 23014 { 23015 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) { 23016 if (instance.props !== finishedWork.memoizedProps) { 23017 error('Expected %s props to match memoized props before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance'); 23018 } 23019 23020 if (instance.state !== finishedWork.memoizedState) { 23021 error('Expected %s state to match memoized state before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance'); 23022 } 23023 } 23024 } 23025 23026 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState); 23027 23028 { 23029 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; 23030 23031 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { 23032 didWarnSet.add(finishedWork.type); 23033 23034 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentNameFromFiber(finishedWork)); 23035 } 23036 } 23037 23038 instance.__reactInternalSnapshotBeforeUpdate = snapshot; 23039 } 23040 23041 break; 23042 } 23043 23044 case HostRoot: 23045 { 23046 { 23047 var root = finishedWork.stateNode; 23048 clearContainer(root.containerInfo); 23049 } 23050 23051 break; 23052 } 23053 23054 case HostComponent: 23055 case HostText: 23056 case HostPortal: 23057 case IncompleteClassComponent: 23058 // Nothing to do for these component types 23059 break; 23060 23061 default: 23062 { 23063 throw new Error('This unit of work tag should not have side-effects. This error is ' + 'likely caused by a bug in React. Please file an issue.'); 23064 } 23065 } 23066 23067 resetCurrentFiber(); 23068 } 23069} 23070 23071function commitHookEffectListUnmount(flags, finishedWork, nearestMountedAncestor) { 23072 var updateQueue = finishedWork.updateQueue; 23073 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; 23074 23075 if (lastEffect !== null) { 23076 var firstEffect = lastEffect.next; 23077 var effect = firstEffect; 23078 23079 do { 23080 if ((effect.tag & flags) === flags) { 23081 // Unmount 23082 var destroy = effect.destroy; 23083 effect.destroy = undefined; 23084 23085 if (destroy !== undefined) { 23086 { 23087 if ((flags & Passive$1) !== NoFlags$1) { 23088 markComponentPassiveEffectUnmountStarted(finishedWork); 23089 } else if ((flags & Layout) !== NoFlags$1) { 23090 markComponentLayoutEffectUnmountStarted(finishedWork); 23091 } 23092 } 23093 23094 { 23095 if ((flags & Insertion) !== NoFlags$1) { 23096 setIsRunningInsertionEffect(true); 23097 } 23098 } 23099 23100 safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); 23101 23102 { 23103 if ((flags & Insertion) !== NoFlags$1) { 23104 setIsRunningInsertionEffect(false); 23105 } 23106 } 23107 23108 { 23109 if ((flags & Passive$1) !== NoFlags$1) { 23110 markComponentPassiveEffectUnmountStopped(); 23111 } else if ((flags & Layout) !== NoFlags$1) { 23112 markComponentLayoutEffectUnmountStopped(); 23113 } 23114 } 23115 } 23116 } 23117 23118 effect = effect.next; 23119 } while (effect !== firstEffect); 23120 } 23121} 23122 23123function commitHookEffectListMount(flags, finishedWork) { 23124 var updateQueue = finishedWork.updateQueue; 23125 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; 23126 23127 if (lastEffect !== null) { 23128 var firstEffect = lastEffect.next; 23129 var effect = firstEffect; 23130 23131 do { 23132 if ((effect.tag & flags) === flags) { 23133 { 23134 if ((flags & Passive$1) !== NoFlags$1) { 23135 markComponentPassiveEffectMountStarted(finishedWork); 23136 } else if ((flags & Layout) !== NoFlags$1) { 23137 markComponentLayoutEffectMountStarted(finishedWork); 23138 } 23139 } // Mount 23140 23141 23142 var create = effect.create; 23143 23144 { 23145 if ((flags & Insertion) !== NoFlags$1) { 23146 setIsRunningInsertionEffect(true); 23147 } 23148 } 23149 23150 effect.destroy = create(); 23151 23152 { 23153 if ((flags & Insertion) !== NoFlags$1) { 23154 setIsRunningInsertionEffect(false); 23155 } 23156 } 23157 23158 { 23159 if ((flags & Passive$1) !== NoFlags$1) { 23160 markComponentPassiveEffectMountStopped(); 23161 } else if ((flags & Layout) !== NoFlags$1) { 23162 markComponentLayoutEffectMountStopped(); 23163 } 23164 } 23165 23166 { 23167 var destroy = effect.destroy; 23168 23169 if (destroy !== undefined && typeof destroy !== 'function') { 23170 var hookName = void 0; 23171 23172 if ((effect.tag & Layout) !== NoFlags) { 23173 hookName = 'useLayoutEffect'; 23174 } else if ((effect.tag & Insertion) !== NoFlags) { 23175 hookName = 'useInsertionEffect'; 23176 } else { 23177 hookName = 'useEffect'; 23178 } 23179 23180 var addendum = void 0; 23181 23182 if (destroy === null) { 23183 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).'; 23184 } else if (typeof destroy.then === 'function') { 23185 addendum = '\n\nIt looks like you wrote ' + hookName + '(async () => ...) or returned a Promise. ' + 'Instead, write the async function inside your effect ' + 'and call it immediately:\n\n' + hookName + '(() => {\n' + ' async function fetchData() {\n' + ' // You can await here\n' + ' const response = await MyAPI.getData(someId);\n' + ' // ...\n' + ' }\n' + ' fetchData();\n' + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + 'Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching'; 23186 } else { 23187 addendum = ' You returned: ' + destroy; 23188 } 23189 23190 error('%s must not return anything besides a function, ' + 'which is used for clean-up.%s', hookName, addendum); 23191 } 23192 } 23193 } 23194 23195 effect = effect.next; 23196 } while (effect !== firstEffect); 23197 } 23198} 23199 23200function commitPassiveEffectDurations(finishedRoot, finishedWork) { 23201 { 23202 // Only Profilers with work in their subtree will have an Update effect scheduled. 23203 if ((finishedWork.flags & Update) !== NoFlags) { 23204 switch (finishedWork.tag) { 23205 case Profiler: 23206 { 23207 var passiveEffectDuration = finishedWork.stateNode.passiveEffectDuration; 23208 var _finishedWork$memoize = finishedWork.memoizedProps, 23209 id = _finishedWork$memoize.id, 23210 onPostCommit = _finishedWork$memoize.onPostCommit; // This value will still reflect the previous commit phase. 23211 // It does not get reset until the start of the next commit phase. 23212 23213 var commitTime = getCommitTime(); 23214 var phase = finishedWork.alternate === null ? 'mount' : 'update'; 23215 23216 { 23217 if (isCurrentUpdateNested()) { 23218 phase = 'nested-update'; 23219 } 23220 } 23221 23222 if (typeof onPostCommit === 'function') { 23223 onPostCommit(id, phase, passiveEffectDuration, commitTime); 23224 } // Bubble times to the next nearest ancestor Profiler. 23225 // After we process that Profiler, we'll bubble further up. 23226 23227 23228 var parentFiber = finishedWork.return; 23229 23230 outer: while (parentFiber !== null) { 23231 switch (parentFiber.tag) { 23232 case HostRoot: 23233 var root = parentFiber.stateNode; 23234 root.passiveEffectDuration += passiveEffectDuration; 23235 break outer; 23236 23237 case Profiler: 23238 var parentStateNode = parentFiber.stateNode; 23239 parentStateNode.passiveEffectDuration += passiveEffectDuration; 23240 break outer; 23241 } 23242 23243 parentFiber = parentFiber.return; 23244 } 23245 23246 break; 23247 } 23248 } 23249 } 23250 } 23251} 23252 23253function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork, committedLanes) { 23254 if ((finishedWork.flags & LayoutMask) !== NoFlags) { 23255 switch (finishedWork.tag) { 23256 case FunctionComponent: 23257 case ForwardRef: 23258 case SimpleMemoComponent: 23259 { 23260 if ( !offscreenSubtreeWasHidden) { 23261 // At this point layout effects have already been destroyed (during mutation phase). 23262 // This is done to prevent sibling component effects from interfering with each other, 23263 // e.g. a destroy function in one component should never override a ref set 23264 // by a create function in another component during the same commit. 23265 if ( finishedWork.mode & ProfileMode) { 23266 try { 23267 startLayoutEffectTimer(); 23268 commitHookEffectListMount(Layout | HasEffect, finishedWork); 23269 } finally { 23270 recordLayoutEffectDuration(finishedWork); 23271 } 23272 } else { 23273 commitHookEffectListMount(Layout | HasEffect, finishedWork); 23274 } 23275 } 23276 23277 break; 23278 } 23279 23280 case ClassComponent: 23281 { 23282 var instance = finishedWork.stateNode; 23283 23284 if (finishedWork.flags & Update) { 23285 if (!offscreenSubtreeWasHidden) { 23286 if (current === null) { 23287 // We could update instance props and state here, 23288 // but instead we rely on them being set during last render. 23289 // TODO: revisit this when we implement resuming. 23290 { 23291 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) { 23292 if (instance.props !== finishedWork.memoizedProps) { 23293 error('Expected %s props to match memoized props before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance'); 23294 } 23295 23296 if (instance.state !== finishedWork.memoizedState) { 23297 error('Expected %s state to match memoized state before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance'); 23298 } 23299 } 23300 } 23301 23302 if ( finishedWork.mode & ProfileMode) { 23303 try { 23304 startLayoutEffectTimer(); 23305 instance.componentDidMount(); 23306 } finally { 23307 recordLayoutEffectDuration(finishedWork); 23308 } 23309 } else { 23310 instance.componentDidMount(); 23311 } 23312 } else { 23313 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps); 23314 var prevState = current.memoizedState; // We could update instance props and state here, 23315 // but instead we rely on them being set during last render. 23316 // TODO: revisit this when we implement resuming. 23317 23318 { 23319 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) { 23320 if (instance.props !== finishedWork.memoizedProps) { 23321 error('Expected %s props to match memoized props before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance'); 23322 } 23323 23324 if (instance.state !== finishedWork.memoizedState) { 23325 error('Expected %s state to match memoized state before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance'); 23326 } 23327 } 23328 } 23329 23330 if ( finishedWork.mode & ProfileMode) { 23331 try { 23332 startLayoutEffectTimer(); 23333 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate); 23334 } finally { 23335 recordLayoutEffectDuration(finishedWork); 23336 } 23337 } else { 23338 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate); 23339 } 23340 } 23341 } 23342 } // TODO: I think this is now always non-null by the time it reaches the 23343 // commit phase. Consider removing the type check. 23344 23345 23346 var updateQueue = finishedWork.updateQueue; 23347 23348 if (updateQueue !== null) { 23349 { 23350 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) { 23351 if (instance.props !== finishedWork.memoizedProps) { 23352 error('Expected %s props to match memoized props before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance'); 23353 } 23354 23355 if (instance.state !== finishedWork.memoizedState) { 23356 error('Expected %s state to match memoized state before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance'); 23357 } 23358 } 23359 } // We could update instance props and state here, 23360 // but instead we rely on them being set during last render. 23361 // TODO: revisit this when we implement resuming. 23362 23363 23364 commitUpdateQueue(finishedWork, updateQueue, instance); 23365 } 23366 23367 break; 23368 } 23369 23370 case HostRoot: 23371 { 23372 // TODO: I think this is now always non-null by the time it reaches the 23373 // commit phase. Consider removing the type check. 23374 var _updateQueue = finishedWork.updateQueue; 23375 23376 if (_updateQueue !== null) { 23377 var _instance = null; 23378 23379 if (finishedWork.child !== null) { 23380 switch (finishedWork.child.tag) { 23381 case HostComponent: 23382 _instance = getPublicInstance(finishedWork.child.stateNode); 23383 break; 23384 23385 case ClassComponent: 23386 _instance = finishedWork.child.stateNode; 23387 break; 23388 } 23389 } 23390 23391 commitUpdateQueue(finishedWork, _updateQueue, _instance); 23392 } 23393 23394 break; 23395 } 23396 23397 case HostComponent: 23398 { 23399 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted 23400 // (eg DOM renderer may schedule auto-focus for inputs and form controls). 23401 // These effects should only be committed when components are first mounted, 23402 // aka when there is no current/alternate. 23403 23404 if (current === null && finishedWork.flags & Update) { 23405 var type = finishedWork.type; 23406 var props = finishedWork.memoizedProps; 23407 commitMount(_instance2, type, props); 23408 } 23409 23410 break; 23411 } 23412 23413 case HostText: 23414 { 23415 // We have no life-cycles associated with text. 23416 break; 23417 } 23418 23419 case HostPortal: 23420 { 23421 // We have no life-cycles associated with portals. 23422 break; 23423 } 23424 23425 case Profiler: 23426 { 23427 { 23428 var _finishedWork$memoize2 = finishedWork.memoizedProps, 23429 onCommit = _finishedWork$memoize2.onCommit, 23430 onRender = _finishedWork$memoize2.onRender; 23431 var effectDuration = finishedWork.stateNode.effectDuration; 23432 var commitTime = getCommitTime(); 23433 var phase = current === null ? 'mount' : 'update'; 23434 23435 { 23436 if (isCurrentUpdateNested()) { 23437 phase = 'nested-update'; 23438 } 23439 } 23440 23441 if (typeof onRender === 'function') { 23442 onRender(finishedWork.memoizedProps.id, phase, finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, commitTime); 23443 } 23444 23445 { 23446 if (typeof onCommit === 'function') { 23447 onCommit(finishedWork.memoizedProps.id, phase, effectDuration, commitTime); 23448 } // Schedule a passive effect for this Profiler to call onPostCommit hooks. 23449 // This effect should be scheduled even if there is no onPostCommit callback for this Profiler, 23450 // because the effect is also where times bubble to parent Profilers. 23451 23452 23453 enqueuePendingPassiveProfilerEffect(finishedWork); // Propagate layout effect durations to the next nearest Profiler ancestor. 23454 // Do not reset these values until the next render so DevTools has a chance to read them first. 23455 23456 var parentFiber = finishedWork.return; 23457 23458 outer: while (parentFiber !== null) { 23459 switch (parentFiber.tag) { 23460 case HostRoot: 23461 var root = parentFiber.stateNode; 23462 root.effectDuration += effectDuration; 23463 break outer; 23464 23465 case Profiler: 23466 var parentStateNode = parentFiber.stateNode; 23467 parentStateNode.effectDuration += effectDuration; 23468 break outer; 23469 } 23470 23471 parentFiber = parentFiber.return; 23472 } 23473 } 23474 } 23475 23476 break; 23477 } 23478 23479 case SuspenseComponent: 23480 { 23481 commitSuspenseHydrationCallbacks(finishedRoot, finishedWork); 23482 break; 23483 } 23484 23485 case SuspenseListComponent: 23486 case IncompleteClassComponent: 23487 case ScopeComponent: 23488 case OffscreenComponent: 23489 case LegacyHiddenComponent: 23490 case TracingMarkerComponent: 23491 { 23492 break; 23493 } 23494 23495 default: 23496 throw new Error('This unit of work tag should not have side-effects. This error is ' + 'likely caused by a bug in React. Please file an issue.'); 23497 } 23498 } 23499 23500 if ( !offscreenSubtreeWasHidden) { 23501 { 23502 if (finishedWork.flags & Ref) { 23503 commitAttachRef(finishedWork); 23504 } 23505 } 23506 } 23507} 23508 23509function reappearLayoutEffectsOnFiber(node) { 23510 // Turn on layout effects in a tree that previously disappeared. 23511 // TODO (Offscreen) Check: flags & LayoutStatic 23512 switch (node.tag) { 23513 case FunctionComponent: 23514 case ForwardRef: 23515 case SimpleMemoComponent: 23516 { 23517 if ( node.mode & ProfileMode) { 23518 try { 23519 startLayoutEffectTimer(); 23520 safelyCallCommitHookLayoutEffectListMount(node, node.return); 23521 } finally { 23522 recordLayoutEffectDuration(node); 23523 } 23524 } else { 23525 safelyCallCommitHookLayoutEffectListMount(node, node.return); 23526 } 23527 23528 break; 23529 } 23530 23531 case ClassComponent: 23532 { 23533 var instance = node.stateNode; 23534 23535 if (typeof instance.componentDidMount === 'function') { 23536 safelyCallComponentDidMount(node, node.return, instance); 23537 } 23538 23539 safelyAttachRef(node, node.return); 23540 break; 23541 } 23542 23543 case HostComponent: 23544 { 23545 safelyAttachRef(node, node.return); 23546 break; 23547 } 23548 } 23549} 23550 23551function hideOrUnhideAllChildren(finishedWork, isHidden) { 23552 // Only hide or unhide the top-most host nodes. 23553 var hostSubtreeRoot = null; 23554 23555 { 23556 // We only have the top Fiber that was inserted but we need to recurse down its 23557 // children to find all the terminal nodes. 23558 var node = finishedWork; 23559 23560 while (true) { 23561 if (node.tag === HostComponent) { 23562 if (hostSubtreeRoot === null) { 23563 hostSubtreeRoot = node; 23564 23565 try { 23566 var instance = node.stateNode; 23567 23568 if (isHidden) { 23569 hideInstance(instance); 23570 } else { 23571 unhideInstance(node.stateNode, node.memoizedProps); 23572 } 23573 } catch (error) { 23574 captureCommitPhaseError(finishedWork, finishedWork.return, error); 23575 } 23576 } 23577 } else if (node.tag === HostText) { 23578 if (hostSubtreeRoot === null) { 23579 try { 23580 var _instance3 = node.stateNode; 23581 23582 if (isHidden) { 23583 hideTextInstance(_instance3); 23584 } else { 23585 unhideTextInstance(_instance3, node.memoizedProps); 23586 } 23587 } catch (error) { 23588 captureCommitPhaseError(finishedWork, finishedWork.return, error); 23589 } 23590 } 23591 } else if ((node.tag === OffscreenComponent || node.tag === LegacyHiddenComponent) && node.memoizedState !== null && node !== finishedWork) ; else if (node.child !== null) { 23592 node.child.return = node; 23593 node = node.child; 23594 continue; 23595 } 23596 23597 if (node === finishedWork) { 23598 return; 23599 } 23600 23601 while (node.sibling === null) { 23602 if (node.return === null || node.return === finishedWork) { 23603 return; 23604 } 23605 23606 if (hostSubtreeRoot === node) { 23607 hostSubtreeRoot = null; 23608 } 23609 23610 node = node.return; 23611 } 23612 23613 if (hostSubtreeRoot === node) { 23614 hostSubtreeRoot = null; 23615 } 23616 23617 node.sibling.return = node.return; 23618 node = node.sibling; 23619 } 23620 } 23621} 23622 23623function commitAttachRef(finishedWork) { 23624 var ref = finishedWork.ref; 23625 23626 if (ref !== null) { 23627 var instance = finishedWork.stateNode; 23628 var instanceToUse; 23629 23630 switch (finishedWork.tag) { 23631 case HostComponent: 23632 instanceToUse = getPublicInstance(instance); 23633 break; 23634 23635 default: 23636 instanceToUse = instance; 23637 } // Moved outside to ensure DCE works with this flag 23638 23639 if (typeof ref === 'function') { 23640 var retVal; 23641 23642 if ( finishedWork.mode & ProfileMode) { 23643 try { 23644 startLayoutEffectTimer(); 23645 retVal = ref(instanceToUse); 23646 } finally { 23647 recordLayoutEffectDuration(finishedWork); 23648 } 23649 } else { 23650 retVal = ref(instanceToUse); 23651 } 23652 23653 { 23654 if (typeof retVal === 'function') { 23655 error('Unexpected return value from a callback ref in %s. ' + 'A callback ref should not return a function.', getComponentNameFromFiber(finishedWork)); 23656 } 23657 } 23658 } else { 23659 { 23660 if (!ref.hasOwnProperty('current')) { 23661 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().', getComponentNameFromFiber(finishedWork)); 23662 } 23663 } 23664 23665 ref.current = instanceToUse; 23666 } 23667 } 23668} 23669 23670function detachFiberMutation(fiber) { 23671 // Cut off the return pointer to disconnect it from the tree. 23672 // This enables us to detect and warn against state updates on an unmounted component. 23673 // It also prevents events from bubbling from within disconnected components. 23674 // 23675 // Ideally, we should also clear the child pointer of the parent alternate to let this 23676 // get GC:ed but we don't know which for sure which parent is the current 23677 // one so we'll settle for GC:ing the subtree of this child. 23678 // This child itself will be GC:ed when the parent updates the next time. 23679 // 23680 // Note that we can't clear child or sibling pointers yet. 23681 // They're needed for passive effects and for findDOMNode. 23682 // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects). 23683 // 23684 // Don't reset the alternate yet, either. We need that so we can detach the 23685 // alternate's fields in the passive phase. Clearing the return pointer is 23686 // sufficient for findDOMNode semantics. 23687 var alternate = fiber.alternate; 23688 23689 if (alternate !== null) { 23690 alternate.return = null; 23691 } 23692 23693 fiber.return = null; 23694} 23695 23696function detachFiberAfterEffects(fiber) { 23697 var alternate = fiber.alternate; 23698 23699 if (alternate !== null) { 23700 fiber.alternate = null; 23701 detachFiberAfterEffects(alternate); 23702 } // Note: Defensively using negation instead of < in case 23703 // `deletedTreeCleanUpLevel` is undefined. 23704 23705 23706 { 23707 // Clear cyclical Fiber fields. This level alone is designed to roughly 23708 // approximate the planned Fiber refactor. In that world, `setState` will be 23709 // bound to a special "instance" object instead of a Fiber. The Instance 23710 // object will not have any of these fields. It will only be connected to 23711 // the fiber tree via a single link at the root. So if this level alone is 23712 // sufficient to fix memory issues, that bodes well for our plans. 23713 fiber.child = null; 23714 fiber.deletions = null; 23715 fiber.sibling = null; // The `stateNode` is cyclical because on host nodes it points to the host 23716 // tree, which has its own pointers to children, parents, and siblings. 23717 // The other host nodes also point back to fibers, so we should detach that 23718 // one, too. 23719 23720 if (fiber.tag === HostComponent) { 23721 var hostInstance = fiber.stateNode; 23722 23723 if (hostInstance !== null) { 23724 detachDeletedInstance(hostInstance); 23725 } 23726 } 23727 23728 fiber.stateNode = null; // I'm intentionally not clearing the `return` field in this level. We 23729 // already disconnect the `return` pointer at the root of the deleted 23730 // subtree (in `detachFiberMutation`). Besides, `return` by itself is not 23731 // cyclical — it's only cyclical when combined with `child`, `sibling`, and 23732 // `alternate`. But we'll clear it in the next level anyway, just in case. 23733 23734 { 23735 fiber._debugOwner = null; 23736 } 23737 23738 { 23739 // Theoretically, nothing in here should be necessary, because we already 23740 // disconnected the fiber from the tree. So even if something leaks this 23741 // particular fiber, it won't leak anything else 23742 // 23743 // The purpose of this branch is to be super aggressive so we can measure 23744 // if there's any difference in memory impact. If there is, that could 23745 // indicate a React leak we don't know about. 23746 fiber.return = null; 23747 fiber.dependencies = null; 23748 fiber.memoizedProps = null; 23749 fiber.memoizedState = null; 23750 fiber.pendingProps = null; 23751 fiber.stateNode = null; // TODO: Move to `commitPassiveUnmountInsideDeletedTreeOnFiber` instead. 23752 23753 fiber.updateQueue = null; 23754 } 23755 } 23756} 23757 23758function getHostParentFiber(fiber) { 23759 var parent = fiber.return; 23760 23761 while (parent !== null) { 23762 if (isHostParent(parent)) { 23763 return parent; 23764 } 23765 23766 parent = parent.return; 23767 } 23768 23769 throw new Error('Expected to find a host parent. This error is likely caused by a bug ' + 'in React. Please file an issue.'); 23770} 23771 23772function isHostParent(fiber) { 23773 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal; 23774} 23775 23776function getHostSibling(fiber) { 23777 // We're going to search forward into the tree until we find a sibling host 23778 // node. Unfortunately, if multiple insertions are done in a row we have to 23779 // search past them. This leads to exponential search for the next sibling. 23780 // TODO: Find a more efficient way to do this. 23781 var node = fiber; 23782 23783 siblings: while (true) { 23784 // If we didn't find anything, let's try the next sibling. 23785 while (node.sibling === null) { 23786 if (node.return === null || isHostParent(node.return)) { 23787 // If we pop out of the root or hit the parent the fiber we are the 23788 // last sibling. 23789 return null; 23790 } 23791 23792 node = node.return; 23793 } 23794 23795 node.sibling.return = node.return; 23796 node = node.sibling; 23797 23798 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) { 23799 // If it is not host node and, we might have a host node inside it. 23800 // Try to search down until we find one. 23801 if (node.flags & Placement) { 23802 // If we don't have a child, try the siblings instead. 23803 continue siblings; 23804 } // If we don't have a child, try the siblings instead. 23805 // We also skip portals because they are not part of this host tree. 23806 23807 23808 if (node.child === null || node.tag === HostPortal) { 23809 continue siblings; 23810 } else { 23811 node.child.return = node; 23812 node = node.child; 23813 } 23814 } // Check if this host node is stable or about to be placed. 23815 23816 23817 if (!(node.flags & Placement)) { 23818 // Found it! 23819 return node.stateNode; 23820 } 23821 } 23822} 23823 23824function commitPlacement(finishedWork) { 23825 23826 23827 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together. 23828 23829 switch (parentFiber.tag) { 23830 case HostComponent: 23831 { 23832 var parent = parentFiber.stateNode; 23833 23834 if (parentFiber.flags & ContentReset) { 23835 // Reset the text content of the parent before doing any insertions 23836 resetTextContent(parent); // Clear ContentReset from the effect tag 23837 23838 parentFiber.flags &= ~ContentReset; 23839 } 23840 23841 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its 23842 // children to find all the terminal nodes. 23843 23844 insertOrAppendPlacementNode(finishedWork, before, parent); 23845 break; 23846 } 23847 23848 case HostRoot: 23849 case HostPortal: 23850 { 23851 var _parent = parentFiber.stateNode.containerInfo; 23852 23853 var _before = getHostSibling(finishedWork); 23854 23855 insertOrAppendPlacementNodeIntoContainer(finishedWork, _before, _parent); 23856 break; 23857 } 23858 // eslint-disable-next-line-no-fallthrough 23859 23860 default: 23861 throw new Error('Invalid host parent fiber. This error is likely caused by a bug ' + 'in React. Please file an issue.'); 23862 } 23863} 23864 23865function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { 23866 var tag = node.tag; 23867 var isHost = tag === HostComponent || tag === HostText; 23868 23869 if (isHost) { 23870 var stateNode = node.stateNode; 23871 23872 if (before) { 23873 insertInContainerBefore(parent, stateNode, before); 23874 } else { 23875 appendChildToContainer(parent, stateNode); 23876 } 23877 } else if (tag === HostPortal) ; else { 23878 var child = node.child; 23879 23880 if (child !== null) { 23881 insertOrAppendPlacementNodeIntoContainer(child, before, parent); 23882 var sibling = child.sibling; 23883 23884 while (sibling !== null) { 23885 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent); 23886 sibling = sibling.sibling; 23887 } 23888 } 23889 } 23890} 23891 23892function insertOrAppendPlacementNode(node, before, parent) { 23893 var tag = node.tag; 23894 var isHost = tag === HostComponent || tag === HostText; 23895 23896 if (isHost) { 23897 var stateNode = node.stateNode; 23898 23899 if (before) { 23900 insertBefore(parent, stateNode, before); 23901 } else { 23902 appendChild(parent, stateNode); 23903 } 23904 } else if (tag === HostPortal) ; else { 23905 var child = node.child; 23906 23907 if (child !== null) { 23908 insertOrAppendPlacementNode(child, before, parent); 23909 var sibling = child.sibling; 23910 23911 while (sibling !== null) { 23912 insertOrAppendPlacementNode(sibling, before, parent); 23913 sibling = sibling.sibling; 23914 } 23915 } 23916 } 23917} // These are tracked on the stack as we recursively traverse a 23918// deleted subtree. 23919// TODO: Update these during the whole mutation phase, not just during 23920// a deletion. 23921 23922 23923var hostParent = null; 23924var hostParentIsContainer = false; 23925 23926function commitDeletionEffects(root, returnFiber, deletedFiber) { 23927 { 23928 // We only have the top Fiber that was deleted but we need to recurse down its 23929 // children to find all the terminal nodes. 23930 // Recursively delete all host nodes from the parent, detach refs, clean 23931 // up mounted layout effects, and call componentWillUnmount. 23932 // We only need to remove the topmost host child in each branch. But then we 23933 // still need to keep traversing to unmount effects, refs, and cWU. TODO: We 23934 // could split this into two separate traversals functions, where the second 23935 // one doesn't include any removeChild logic. This is maybe the same 23936 // function as "disappearLayoutEffects" (or whatever that turns into after 23937 // the layout phase is refactored to use recursion). 23938 // Before starting, find the nearest host parent on the stack so we know 23939 // which instance/container to remove the children from. 23940 // TODO: Instead of searching up the fiber return path on every deletion, we 23941 // can track the nearest host component on the JS stack as we traverse the 23942 // tree during the commit phase. This would make insertions faster, too. 23943 var parent = returnFiber; 23944 23945 findParent: while (parent !== null) { 23946 switch (parent.tag) { 23947 case HostComponent: 23948 { 23949 hostParent = parent.stateNode; 23950 hostParentIsContainer = false; 23951 break findParent; 23952 } 23953 23954 case HostRoot: 23955 { 23956 hostParent = parent.stateNode.containerInfo; 23957 hostParentIsContainer = true; 23958 break findParent; 23959 } 23960 23961 case HostPortal: 23962 { 23963 hostParent = parent.stateNode.containerInfo; 23964 hostParentIsContainer = true; 23965 break findParent; 23966 } 23967 } 23968 23969 parent = parent.return; 23970 } 23971 23972 if (hostParent === null) { 23973 throw new Error('Expected to find a host parent. This error is likely caused by ' + 'a bug in React. Please file an issue.'); 23974 } 23975 23976 commitDeletionEffectsOnFiber(root, returnFiber, deletedFiber); 23977 hostParent = null; 23978 hostParentIsContainer = false; 23979 } 23980 23981 detachFiberMutation(deletedFiber); 23982} 23983 23984function recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, parent) { 23985 // TODO: Use a static flag to skip trees that don't have unmount effects 23986 var child = parent.child; 23987 23988 while (child !== null) { 23989 commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, child); 23990 child = child.sibling; 23991 } 23992} 23993 23994function commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, deletedFiber) { 23995 onCommitUnmount(deletedFiber); // The cases in this outer switch modify the stack before they traverse 23996 // into their subtree. There are simpler cases in the inner switch 23997 // that don't modify the stack. 23998 23999 switch (deletedFiber.tag) { 24000 case HostComponent: 24001 { 24002 if (!offscreenSubtreeWasHidden) { 24003 safelyDetachRef(deletedFiber, nearestMountedAncestor); 24004 } // Intentional fallthrough to next branch 24005 24006 } 24007 // eslint-disable-next-line-no-fallthrough 24008 24009 case HostText: 24010 { 24011 // We only need to remove the nearest host child. Set the host parent 24012 // to `null` on the stack to indicate that nested children don't 24013 // need to be removed. 24014 { 24015 var prevHostParent = hostParent; 24016 var prevHostParentIsContainer = hostParentIsContainer; 24017 hostParent = null; 24018 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber); 24019 hostParent = prevHostParent; 24020 hostParentIsContainer = prevHostParentIsContainer; 24021 24022 if (hostParent !== null) { 24023 // Now that all the child effects have unmounted, we can remove the 24024 // node from the tree. 24025 if (hostParentIsContainer) { 24026 removeChildFromContainer(hostParent, deletedFiber.stateNode); 24027 } else { 24028 removeChild(hostParent, deletedFiber.stateNode); 24029 } 24030 } 24031 } 24032 24033 return; 24034 } 24035 24036 case DehydratedFragment: 24037 { 24038 // Delete the dehydrated suspense boundary and all of its content. 24039 24040 24041 { 24042 if (hostParent !== null) { 24043 if (hostParentIsContainer) { 24044 clearSuspenseBoundaryFromContainer(hostParent, deletedFiber.stateNode); 24045 } else { 24046 clearSuspenseBoundary(hostParent, deletedFiber.stateNode); 24047 } 24048 } 24049 } 24050 24051 return; 24052 } 24053 24054 case HostPortal: 24055 { 24056 { 24057 // When we go into a portal, it becomes the parent to remove from. 24058 var _prevHostParent = hostParent; 24059 var _prevHostParentIsContainer = hostParentIsContainer; 24060 hostParent = deletedFiber.stateNode.containerInfo; 24061 hostParentIsContainer = true; 24062 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber); 24063 hostParent = _prevHostParent; 24064 hostParentIsContainer = _prevHostParentIsContainer; 24065 } 24066 24067 return; 24068 } 24069 24070 case FunctionComponent: 24071 case ForwardRef: 24072 case MemoComponent: 24073 case SimpleMemoComponent: 24074 { 24075 if (!offscreenSubtreeWasHidden) { 24076 var updateQueue = deletedFiber.updateQueue; 24077 24078 if (updateQueue !== null) { 24079 var lastEffect = updateQueue.lastEffect; 24080 24081 if (lastEffect !== null) { 24082 var firstEffect = lastEffect.next; 24083 var effect = firstEffect; 24084 24085 do { 24086 var _effect = effect, 24087 destroy = _effect.destroy, 24088 tag = _effect.tag; 24089 24090 if (destroy !== undefined) { 24091 if ((tag & Insertion) !== NoFlags$1) { 24092 safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy); 24093 } else if ((tag & Layout) !== NoFlags$1) { 24094 { 24095 markComponentLayoutEffectUnmountStarted(deletedFiber); 24096 } 24097 24098 if ( deletedFiber.mode & ProfileMode) { 24099 startLayoutEffectTimer(); 24100 safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy); 24101 recordLayoutEffectDuration(deletedFiber); 24102 } else { 24103 safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy); 24104 } 24105 24106 { 24107 markComponentLayoutEffectUnmountStopped(); 24108 } 24109 } 24110 } 24111 24112 effect = effect.next; 24113 } while (effect !== firstEffect); 24114 } 24115 } 24116 } 24117 24118 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber); 24119 return; 24120 } 24121 24122 case ClassComponent: 24123 { 24124 if (!offscreenSubtreeWasHidden) { 24125 safelyDetachRef(deletedFiber, nearestMountedAncestor); 24126 var instance = deletedFiber.stateNode; 24127 24128 if (typeof instance.componentWillUnmount === 'function') { 24129 safelyCallComponentWillUnmount(deletedFiber, nearestMountedAncestor, instance); 24130 } 24131 } 24132 24133 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber); 24134 return; 24135 } 24136 24137 case ScopeComponent: 24138 { 24139 24140 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber); 24141 return; 24142 } 24143 24144 case OffscreenComponent: 24145 { 24146 if ( // TODO: Remove this dead flag 24147 deletedFiber.mode & ConcurrentMode) { 24148 // If this offscreen component is hidden, we already unmounted it. Before 24149 // deleting the children, track that it's already unmounted so that we 24150 // don't attempt to unmount the effects again. 24151 // TODO: If the tree is hidden, in most cases we should be able to skip 24152 // over the nested children entirely. An exception is we haven't yet found 24153 // the topmost host node to delete, which we already track on the stack. 24154 // But the other case is portals, which need to be detached no matter how 24155 // deeply they are nested. We should use a subtree flag to track whether a 24156 // subtree includes a nested portal. 24157 var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; 24158 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden || deletedFiber.memoizedState !== null; 24159 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber); 24160 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; 24161 } else { 24162 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber); 24163 } 24164 24165 break; 24166 } 24167 24168 default: 24169 { 24170 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber); 24171 return; 24172 } 24173 } 24174} 24175 24176function commitSuspenseCallback(finishedWork) { 24177 // TODO: Move this to passive phase 24178 var newState = finishedWork.memoizedState; 24179} 24180 24181function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) { 24182 24183 var newState = finishedWork.memoizedState; 24184 24185 if (newState === null) { 24186 var current = finishedWork.alternate; 24187 24188 if (current !== null) { 24189 var prevState = current.memoizedState; 24190 24191 if (prevState !== null) { 24192 var suspenseInstance = prevState.dehydrated; 24193 24194 if (suspenseInstance !== null) { 24195 commitHydratedSuspenseInstance(suspenseInstance); 24196 } 24197 } 24198 } 24199 } 24200} 24201 24202function attachSuspenseRetryListeners(finishedWork) { 24203 // If this boundary just timed out, then it will have a set of wakeables. 24204 // For each wakeable, attach a listener so that when it resolves, React 24205 // attempts to re-render the boundary in the primary (pre-timeout) state. 24206 var wakeables = finishedWork.updateQueue; 24207 24208 if (wakeables !== null) { 24209 finishedWork.updateQueue = null; 24210 var retryCache = finishedWork.stateNode; 24211 24212 if (retryCache === null) { 24213 retryCache = finishedWork.stateNode = new PossiblyWeakSet(); 24214 } 24215 24216 wakeables.forEach(function (wakeable) { 24217 // Memoize using the boundary fiber to prevent redundant listeners. 24218 var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); 24219 24220 if (!retryCache.has(wakeable)) { 24221 retryCache.add(wakeable); 24222 24223 { 24224 if (isDevToolsPresent) { 24225 if (inProgressLanes !== null && inProgressRoot !== null) { 24226 // If we have pending work still, associate the original updaters with it. 24227 restorePendingUpdaters(inProgressRoot, inProgressLanes); 24228 } else { 24229 throw Error('Expected finished root and lanes to be set. This is a bug in React.'); 24230 } 24231 } 24232 } 24233 24234 wakeable.then(retry, retry); 24235 } 24236 }); 24237 } 24238} // This function detects when a Suspense boundary goes from visible to hidden. 24239function commitMutationEffects(root, finishedWork, committedLanes) { 24240 inProgressLanes = committedLanes; 24241 inProgressRoot = root; 24242 setCurrentFiber(finishedWork); 24243 commitMutationEffectsOnFiber(finishedWork, root); 24244 setCurrentFiber(finishedWork); 24245 inProgressLanes = null; 24246 inProgressRoot = null; 24247} 24248 24249function recursivelyTraverseMutationEffects(root, parentFiber, lanes) { 24250 // Deletions effects can be scheduled on any fiber type. They need to happen 24251 // before the children effects hae fired. 24252 var deletions = parentFiber.deletions; 24253 24254 if (deletions !== null) { 24255 for (var i = 0; i < deletions.length; i++) { 24256 var childToDelete = deletions[i]; 24257 24258 try { 24259 commitDeletionEffects(root, parentFiber, childToDelete); 24260 } catch (error) { 24261 captureCommitPhaseError(childToDelete, parentFiber, error); 24262 } 24263 } 24264 } 24265 24266 var prevDebugFiber = getCurrentFiber(); 24267 24268 if (parentFiber.subtreeFlags & MutationMask) { 24269 var child = parentFiber.child; 24270 24271 while (child !== null) { 24272 setCurrentFiber(child); 24273 commitMutationEffectsOnFiber(child, root); 24274 child = child.sibling; 24275 } 24276 } 24277 24278 setCurrentFiber(prevDebugFiber); 24279} 24280 24281function commitMutationEffectsOnFiber(finishedWork, root, lanes) { 24282 var current = finishedWork.alternate; 24283 var flags = finishedWork.flags; // The effect flag should be checked *after* we refine the type of fiber, 24284 // because the fiber tag is more specific. An exception is any flag related 24285 // to reconcilation, because those can be set on all fiber types. 24286 24287 switch (finishedWork.tag) { 24288 case FunctionComponent: 24289 case ForwardRef: 24290 case MemoComponent: 24291 case SimpleMemoComponent: 24292 { 24293 recursivelyTraverseMutationEffects(root, finishedWork); 24294 commitReconciliationEffects(finishedWork); 24295 24296 if (flags & Update) { 24297 try { 24298 commitHookEffectListUnmount(Insertion | HasEffect, finishedWork, finishedWork.return); 24299 commitHookEffectListMount(Insertion | HasEffect, finishedWork); 24300 } catch (error) { 24301 captureCommitPhaseError(finishedWork, finishedWork.return, error); 24302 } // Layout effects are destroyed during the mutation phase so that all 24303 // destroy functions for all fibers are called before any create functions. 24304 // This prevents sibling component effects from interfering with each other, 24305 // e.g. a destroy function in one component should never override a ref set 24306 // by a create function in another component during the same commit. 24307 24308 24309 if ( finishedWork.mode & ProfileMode) { 24310 try { 24311 startLayoutEffectTimer(); 24312 commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return); 24313 } catch (error) { 24314 captureCommitPhaseError(finishedWork, finishedWork.return, error); 24315 } 24316 24317 recordLayoutEffectDuration(finishedWork); 24318 } else { 24319 try { 24320 commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return); 24321 } catch (error) { 24322 captureCommitPhaseError(finishedWork, finishedWork.return, error); 24323 } 24324 } 24325 } 24326 24327 return; 24328 } 24329 24330 case ClassComponent: 24331 { 24332 recursivelyTraverseMutationEffects(root, finishedWork); 24333 commitReconciliationEffects(finishedWork); 24334 24335 if (flags & Ref) { 24336 if (current !== null) { 24337 safelyDetachRef(current, current.return); 24338 } 24339 } 24340 24341 return; 24342 } 24343 24344 case HostComponent: 24345 { 24346 recursivelyTraverseMutationEffects(root, finishedWork); 24347 commitReconciliationEffects(finishedWork); 24348 24349 if (flags & Ref) { 24350 if (current !== null) { 24351 safelyDetachRef(current, current.return); 24352 } 24353 } 24354 24355 { 24356 // TODO: ContentReset gets cleared by the children during the commit 24357 // phase. This is a refactor hazard because it means we must read 24358 // flags the flags after `commitReconciliationEffects` has already run; 24359 // the order matters. We should refactor so that ContentReset does not 24360 // rely on mutating the flag during commit. Like by setting a flag 24361 // during the render phase instead. 24362 if (finishedWork.flags & ContentReset) { 24363 var instance = finishedWork.stateNode; 24364 24365 try { 24366 resetTextContent(instance); 24367 } catch (error) { 24368 captureCommitPhaseError(finishedWork, finishedWork.return, error); 24369 } 24370 } 24371 24372 if (flags & Update) { 24373 var _instance4 = finishedWork.stateNode; 24374 24375 if (_instance4 != null) { 24376 // Commit the work prepared earlier. 24377 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps 24378 // as the newProps. The updatePayload will contain the real change in 24379 // this case. 24380 24381 var oldProps = current !== null ? current.memoizedProps : newProps; 24382 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. 24383 24384 var updatePayload = finishedWork.updateQueue; 24385 finishedWork.updateQueue = null; 24386 24387 if (updatePayload !== null) { 24388 try { 24389 commitUpdate(_instance4, updatePayload, type, oldProps, newProps, finishedWork); 24390 } catch (error) { 24391 captureCommitPhaseError(finishedWork, finishedWork.return, error); 24392 } 24393 } 24394 } 24395 } 24396 } 24397 24398 return; 24399 } 24400 24401 case HostText: 24402 { 24403 recursivelyTraverseMutationEffects(root, finishedWork); 24404 commitReconciliationEffects(finishedWork); 24405 24406 if (flags & Update) { 24407 { 24408 if (finishedWork.stateNode === null) { 24409 throw new Error('This should have a text node initialized. This error is likely ' + 'caused by a bug in React. Please file an issue.'); 24410 } 24411 24412 var textInstance = finishedWork.stateNode; 24413 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps 24414 // as the newProps. The updatePayload will contain the real change in 24415 // this case. 24416 24417 var oldText = current !== null ? current.memoizedProps : newText; 24418 24419 try { 24420 commitTextUpdate(textInstance, oldText, newText); 24421 } catch (error) { 24422 captureCommitPhaseError(finishedWork, finishedWork.return, error); 24423 } 24424 } 24425 } 24426 24427 return; 24428 } 24429 24430 case HostRoot: 24431 { 24432 recursivelyTraverseMutationEffects(root, finishedWork); 24433 commitReconciliationEffects(finishedWork); 24434 24435 if (flags & Update) { 24436 { 24437 if (current !== null) { 24438 var prevRootState = current.memoizedState; 24439 24440 if (prevRootState.isDehydrated) { 24441 try { 24442 commitHydratedContainer(root.containerInfo); 24443 } catch (error) { 24444 captureCommitPhaseError(finishedWork, finishedWork.return, error); 24445 } 24446 } 24447 } 24448 } 24449 } 24450 24451 return; 24452 } 24453 24454 case HostPortal: 24455 { 24456 recursivelyTraverseMutationEffects(root, finishedWork); 24457 commitReconciliationEffects(finishedWork); 24458 24459 return; 24460 } 24461 24462 case SuspenseComponent: 24463 { 24464 recursivelyTraverseMutationEffects(root, finishedWork); 24465 commitReconciliationEffects(finishedWork); 24466 var offscreenFiber = finishedWork.child; 24467 24468 if (offscreenFiber.flags & Visibility) { 24469 var offscreenInstance = offscreenFiber.stateNode; 24470 var newState = offscreenFiber.memoizedState; 24471 var isHidden = newState !== null; // Track the current state on the Offscreen instance so we can 24472 // read it during an event 24473 24474 offscreenInstance.isHidden = isHidden; 24475 24476 if (isHidden) { 24477 var wasHidden = offscreenFiber.alternate !== null && offscreenFiber.alternate.memoizedState !== null; 24478 24479 if (!wasHidden) { 24480 // TODO: Move to passive phase 24481 markCommitTimeOfFallback(); 24482 } 24483 } 24484 } 24485 24486 if (flags & Update) { 24487 try { 24488 commitSuspenseCallback(finishedWork); 24489 } catch (error) { 24490 captureCommitPhaseError(finishedWork, finishedWork.return, error); 24491 } 24492 24493 attachSuspenseRetryListeners(finishedWork); 24494 } 24495 24496 return; 24497 } 24498 24499 case OffscreenComponent: 24500 { 24501 var _wasHidden = current !== null && current.memoizedState !== null; 24502 24503 if ( // TODO: Remove this dead flag 24504 finishedWork.mode & ConcurrentMode) { 24505 // Before committing the children, track on the stack whether this 24506 // offscreen subtree was already hidden, so that we don't unmount the 24507 // effects again. 24508 var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; 24509 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden || _wasHidden; 24510 recursivelyTraverseMutationEffects(root, finishedWork); 24511 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; 24512 } else { 24513 recursivelyTraverseMutationEffects(root, finishedWork); 24514 } 24515 24516 commitReconciliationEffects(finishedWork); 24517 24518 if (flags & Visibility) { 24519 var _offscreenInstance = finishedWork.stateNode; 24520 var _newState = finishedWork.memoizedState; 24521 24522 var _isHidden = _newState !== null; 24523 24524 var offscreenBoundary = finishedWork; // Track the current state on the Offscreen instance so we can 24525 // read it during an event 24526 24527 _offscreenInstance.isHidden = _isHidden; 24528 24529 { 24530 if (_isHidden) { 24531 if (!_wasHidden) { 24532 if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) { 24533 nextEffect = offscreenBoundary; 24534 var offscreenChild = offscreenBoundary.child; 24535 24536 while (offscreenChild !== null) { 24537 nextEffect = offscreenChild; 24538 disappearLayoutEffects_begin(offscreenChild); 24539 offscreenChild = offscreenChild.sibling; 24540 } 24541 } 24542 } 24543 } 24544 } 24545 24546 { 24547 // TODO: This needs to run whenever there's an insertion or update 24548 // inside a hidden Offscreen tree. 24549 hideOrUnhideAllChildren(offscreenBoundary, _isHidden); 24550 } 24551 } 24552 24553 return; 24554 } 24555 24556 case SuspenseListComponent: 24557 { 24558 recursivelyTraverseMutationEffects(root, finishedWork); 24559 commitReconciliationEffects(finishedWork); 24560 24561 if (flags & Update) { 24562 attachSuspenseRetryListeners(finishedWork); 24563 } 24564 24565 return; 24566 } 24567 24568 case ScopeComponent: 24569 { 24570 24571 return; 24572 } 24573 24574 default: 24575 { 24576 recursivelyTraverseMutationEffects(root, finishedWork); 24577 commitReconciliationEffects(finishedWork); 24578 return; 24579 } 24580 } 24581} 24582 24583function commitReconciliationEffects(finishedWork) { 24584 // Placement effects (insertions, reorders) can be scheduled on any fiber 24585 // type. They needs to happen after the children effects have fired, but 24586 // before the effects on this fiber have fired. 24587 var flags = finishedWork.flags; 24588 24589 if (flags & Placement) { 24590 try { 24591 commitPlacement(finishedWork); 24592 } catch (error) { 24593 captureCommitPhaseError(finishedWork, finishedWork.return, error); 24594 } // Clear the "placement" from effect tag so that we know that this is 24595 // inserted, before any life-cycles like componentDidMount gets called. 24596 // TODO: findDOMNode doesn't rely on this any more but isMounted does 24597 // and isMounted is deprecated anyway so we should be able to kill this. 24598 24599 24600 finishedWork.flags &= ~Placement; 24601 } 24602 24603 if (flags & Hydrating) { 24604 finishedWork.flags &= ~Hydrating; 24605 } 24606} 24607 24608function commitLayoutEffects(finishedWork, root, committedLanes) { 24609 inProgressLanes = committedLanes; 24610 inProgressRoot = root; 24611 nextEffect = finishedWork; 24612 commitLayoutEffects_begin(finishedWork, root, committedLanes); 24613 inProgressLanes = null; 24614 inProgressRoot = null; 24615} 24616 24617function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) { 24618 // Suspense layout effects semantics don't change for legacy roots. 24619 var isModernRoot = (subtreeRoot.mode & ConcurrentMode) !== NoMode; 24620 24621 while (nextEffect !== null) { 24622 var fiber = nextEffect; 24623 var firstChild = fiber.child; 24624 24625 if ( fiber.tag === OffscreenComponent && isModernRoot) { 24626 // Keep track of the current Offscreen stack's state. 24627 var isHidden = fiber.memoizedState !== null; 24628 var newOffscreenSubtreeIsHidden = isHidden || offscreenSubtreeIsHidden; 24629 24630 if (newOffscreenSubtreeIsHidden) { 24631 // The Offscreen tree is hidden. Skip over its layout effects. 24632 commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes); 24633 continue; 24634 } else { 24635 // TODO (Offscreen) Also check: subtreeFlags & LayoutMask 24636 var current = fiber.alternate; 24637 var wasHidden = current !== null && current.memoizedState !== null; 24638 var newOffscreenSubtreeWasHidden = wasHidden || offscreenSubtreeWasHidden; 24639 var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden; 24640 var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; // Traverse the Offscreen subtree with the current Offscreen as the root. 24641 24642 offscreenSubtreeIsHidden = newOffscreenSubtreeIsHidden; 24643 offscreenSubtreeWasHidden = newOffscreenSubtreeWasHidden; 24644 24645 if (offscreenSubtreeWasHidden && !prevOffscreenSubtreeWasHidden) { 24646 // This is the root of a reappearing boundary. Turn its layout effects 24647 // back on. 24648 nextEffect = fiber; 24649 reappearLayoutEffects_begin(fiber); 24650 } 24651 24652 var child = firstChild; 24653 24654 while (child !== null) { 24655 nextEffect = child; 24656 commitLayoutEffects_begin(child, // New root; bubble back up to here and stop. 24657 root, committedLanes); 24658 child = child.sibling; 24659 } // Restore Offscreen state and resume in our-progress traversal. 24660 24661 24662 nextEffect = fiber; 24663 offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden; 24664 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; 24665 commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes); 24666 continue; 24667 } 24668 } 24669 24670 if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) { 24671 firstChild.return = fiber; 24672 nextEffect = firstChild; 24673 } else { 24674 commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes); 24675 } 24676 } 24677} 24678 24679function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { 24680 while (nextEffect !== null) { 24681 var fiber = nextEffect; 24682 24683 if ((fiber.flags & LayoutMask) !== NoFlags) { 24684 var current = fiber.alternate; 24685 setCurrentFiber(fiber); 24686 24687 try { 24688 commitLayoutEffectOnFiber(root, current, fiber, committedLanes); 24689 } catch (error) { 24690 captureCommitPhaseError(fiber, fiber.return, error); 24691 } 24692 24693 resetCurrentFiber(); 24694 } 24695 24696 if (fiber === subtreeRoot) { 24697 nextEffect = null; 24698 return; 24699 } 24700 24701 var sibling = fiber.sibling; 24702 24703 if (sibling !== null) { 24704 sibling.return = fiber.return; 24705 nextEffect = sibling; 24706 return; 24707 } 24708 24709 nextEffect = fiber.return; 24710 } 24711} 24712 24713function disappearLayoutEffects_begin(subtreeRoot) { 24714 while (nextEffect !== null) { 24715 var fiber = nextEffect; 24716 var firstChild = fiber.child; // TODO (Offscreen) Check: flags & (RefStatic | LayoutStatic) 24717 24718 switch (fiber.tag) { 24719 case FunctionComponent: 24720 case ForwardRef: 24721 case MemoComponent: 24722 case SimpleMemoComponent: 24723 { 24724 if ( fiber.mode & ProfileMode) { 24725 try { 24726 startLayoutEffectTimer(); 24727 commitHookEffectListUnmount(Layout, fiber, fiber.return); 24728 } finally { 24729 recordLayoutEffectDuration(fiber); 24730 } 24731 } else { 24732 commitHookEffectListUnmount(Layout, fiber, fiber.return); 24733 } 24734 24735 break; 24736 } 24737 24738 case ClassComponent: 24739 { 24740 // TODO (Offscreen) Check: flags & RefStatic 24741 safelyDetachRef(fiber, fiber.return); 24742 var instance = fiber.stateNode; 24743 24744 if (typeof instance.componentWillUnmount === 'function') { 24745 safelyCallComponentWillUnmount(fiber, fiber.return, instance); 24746 } 24747 24748 break; 24749 } 24750 24751 case HostComponent: 24752 { 24753 safelyDetachRef(fiber, fiber.return); 24754 break; 24755 } 24756 24757 case OffscreenComponent: 24758 { 24759 // Check if this is a 24760 var isHidden = fiber.memoizedState !== null; 24761 24762 if (isHidden) { 24763 // Nested Offscreen tree is already hidden. Don't disappear 24764 // its effects. 24765 disappearLayoutEffects_complete(subtreeRoot); 24766 continue; 24767 } 24768 24769 break; 24770 } 24771 } // TODO (Offscreen) Check: subtreeFlags & LayoutStatic 24772 24773 24774 if (firstChild !== null) { 24775 firstChild.return = fiber; 24776 nextEffect = firstChild; 24777 } else { 24778 disappearLayoutEffects_complete(subtreeRoot); 24779 } 24780 } 24781} 24782 24783function disappearLayoutEffects_complete(subtreeRoot) { 24784 while (nextEffect !== null) { 24785 var fiber = nextEffect; 24786 24787 if (fiber === subtreeRoot) { 24788 nextEffect = null; 24789 return; 24790 } 24791 24792 var sibling = fiber.sibling; 24793 24794 if (sibling !== null) { 24795 sibling.return = fiber.return; 24796 nextEffect = sibling; 24797 return; 24798 } 24799 24800 nextEffect = fiber.return; 24801 } 24802} 24803 24804function reappearLayoutEffects_begin(subtreeRoot) { 24805 while (nextEffect !== null) { 24806 var fiber = nextEffect; 24807 var firstChild = fiber.child; 24808 24809 if (fiber.tag === OffscreenComponent) { 24810 var isHidden = fiber.memoizedState !== null; 24811 24812 if (isHidden) { 24813 // Nested Offscreen tree is still hidden. Don't re-appear its effects. 24814 reappearLayoutEffects_complete(subtreeRoot); 24815 continue; 24816 } 24817 } // TODO (Offscreen) Check: subtreeFlags & LayoutStatic 24818 24819 24820 if (firstChild !== null) { 24821 // This node may have been reused from a previous render, so we can't 24822 // assume its return pointer is correct. 24823 firstChild.return = fiber; 24824 nextEffect = firstChild; 24825 } else { 24826 reappearLayoutEffects_complete(subtreeRoot); 24827 } 24828 } 24829} 24830 24831function reappearLayoutEffects_complete(subtreeRoot) { 24832 while (nextEffect !== null) { 24833 var fiber = nextEffect; // TODO (Offscreen) Check: flags & LayoutStatic 24834 24835 setCurrentFiber(fiber); 24836 24837 try { 24838 reappearLayoutEffectsOnFiber(fiber); 24839 } catch (error) { 24840 captureCommitPhaseError(fiber, fiber.return, error); 24841 } 24842 24843 resetCurrentFiber(); 24844 24845 if (fiber === subtreeRoot) { 24846 nextEffect = null; 24847 return; 24848 } 24849 24850 var sibling = fiber.sibling; 24851 24852 if (sibling !== null) { 24853 // This node may have been reused from a previous render, so we can't 24854 // assume its return pointer is correct. 24855 sibling.return = fiber.return; 24856 nextEffect = sibling; 24857 return; 24858 } 24859 24860 nextEffect = fiber.return; 24861 } 24862} 24863 24864function commitPassiveMountEffects(root, finishedWork, committedLanes, committedTransitions) { 24865 nextEffect = finishedWork; 24866 commitPassiveMountEffects_begin(finishedWork, root, committedLanes, committedTransitions); 24867} 24868 24869function commitPassiveMountEffects_begin(subtreeRoot, root, committedLanes, committedTransitions) { 24870 while (nextEffect !== null) { 24871 var fiber = nextEffect; 24872 var firstChild = fiber.child; 24873 24874 if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) { 24875 firstChild.return = fiber; 24876 nextEffect = firstChild; 24877 } else { 24878 commitPassiveMountEffects_complete(subtreeRoot, root, committedLanes, committedTransitions); 24879 } 24880 } 24881} 24882 24883function commitPassiveMountEffects_complete(subtreeRoot, root, committedLanes, committedTransitions) { 24884 while (nextEffect !== null) { 24885 var fiber = nextEffect; 24886 24887 if ((fiber.flags & Passive) !== NoFlags) { 24888 setCurrentFiber(fiber); 24889 24890 try { 24891 commitPassiveMountOnFiber(root, fiber, committedLanes, committedTransitions); 24892 } catch (error) { 24893 captureCommitPhaseError(fiber, fiber.return, error); 24894 } 24895 24896 resetCurrentFiber(); 24897 } 24898 24899 if (fiber === subtreeRoot) { 24900 nextEffect = null; 24901 return; 24902 } 24903 24904 var sibling = fiber.sibling; 24905 24906 if (sibling !== null) { 24907 sibling.return = fiber.return; 24908 nextEffect = sibling; 24909 return; 24910 } 24911 24912 nextEffect = fiber.return; 24913 } 24914} 24915 24916function commitPassiveMountOnFiber(finishedRoot, finishedWork, committedLanes, committedTransitions) { 24917 switch (finishedWork.tag) { 24918 case FunctionComponent: 24919 case ForwardRef: 24920 case SimpleMemoComponent: 24921 { 24922 if ( finishedWork.mode & ProfileMode) { 24923 startPassiveEffectTimer(); 24924 24925 try { 24926 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork); 24927 } finally { 24928 recordPassiveEffectDuration(finishedWork); 24929 } 24930 } else { 24931 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork); 24932 } 24933 24934 break; 24935 } 24936 } 24937} 24938 24939function commitPassiveUnmountEffects(firstChild) { 24940 nextEffect = firstChild; 24941 commitPassiveUnmountEffects_begin(); 24942} 24943 24944function commitPassiveUnmountEffects_begin() { 24945 while (nextEffect !== null) { 24946 var fiber = nextEffect; 24947 var child = fiber.child; 24948 24949 if ((nextEffect.flags & ChildDeletion) !== NoFlags) { 24950 var deletions = fiber.deletions; 24951 24952 if (deletions !== null) { 24953 for (var i = 0; i < deletions.length; i++) { 24954 var fiberToDelete = deletions[i]; 24955 nextEffect = fiberToDelete; 24956 commitPassiveUnmountEffectsInsideOfDeletedTree_begin(fiberToDelete, fiber); 24957 } 24958 24959 { 24960 // A fiber was deleted from this parent fiber, but it's still part of 24961 // the previous (alternate) parent fiber's list of children. Because 24962 // children are a linked list, an earlier sibling that's still alive 24963 // will be connected to the deleted fiber via its `alternate`: 24964 // 24965 // live fiber 24966 // --alternate--> previous live fiber 24967 // --sibling--> deleted fiber 24968 // 24969 // We can't disconnect `alternate` on nodes that haven't been deleted 24970 // yet, but we can disconnect the `sibling` and `child` pointers. 24971 var previousFiber = fiber.alternate; 24972 24973 if (previousFiber !== null) { 24974 var detachedChild = previousFiber.child; 24975 24976 if (detachedChild !== null) { 24977 previousFiber.child = null; 24978 24979 do { 24980 var detachedSibling = detachedChild.sibling; 24981 detachedChild.sibling = null; 24982 detachedChild = detachedSibling; 24983 } while (detachedChild !== null); 24984 } 24985 } 24986 } 24987 24988 nextEffect = fiber; 24989 } 24990 } 24991 24992 if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) { 24993 child.return = fiber; 24994 nextEffect = child; 24995 } else { 24996 commitPassiveUnmountEffects_complete(); 24997 } 24998 } 24999} 25000 25001function commitPassiveUnmountEffects_complete() { 25002 while (nextEffect !== null) { 25003 var fiber = nextEffect; 25004 25005 if ((fiber.flags & Passive) !== NoFlags) { 25006 setCurrentFiber(fiber); 25007 commitPassiveUnmountOnFiber(fiber); 25008 resetCurrentFiber(); 25009 } 25010 25011 var sibling = fiber.sibling; 25012 25013 if (sibling !== null) { 25014 sibling.return = fiber.return; 25015 nextEffect = sibling; 25016 return; 25017 } 25018 25019 nextEffect = fiber.return; 25020 } 25021} 25022 25023function commitPassiveUnmountOnFiber(finishedWork) { 25024 switch (finishedWork.tag) { 25025 case FunctionComponent: 25026 case ForwardRef: 25027 case SimpleMemoComponent: 25028 { 25029 if ( finishedWork.mode & ProfileMode) { 25030 startPassiveEffectTimer(); 25031 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return); 25032 recordPassiveEffectDuration(finishedWork); 25033 } else { 25034 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return); 25035 } 25036 25037 break; 25038 } 25039 } 25040} 25041 25042function commitPassiveUnmountEffectsInsideOfDeletedTree_begin(deletedSubtreeRoot, nearestMountedAncestor) { 25043 while (nextEffect !== null) { 25044 var fiber = nextEffect; // Deletion effects fire in parent -> child order 25045 // TODO: Check if fiber has a PassiveStatic flag 25046 25047 setCurrentFiber(fiber); 25048 commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor); 25049 resetCurrentFiber(); 25050 var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag. (But, if we 25051 // do this, still need to handle `deletedTreeCleanUpLevel` correctly.) 25052 25053 if (child !== null) { 25054 child.return = fiber; 25055 nextEffect = child; 25056 } else { 25057 commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot); 25058 } 25059 } 25060} 25061 25062function commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot) { 25063 while (nextEffect !== null) { 25064 var fiber = nextEffect; 25065 var sibling = fiber.sibling; 25066 var returnFiber = fiber.return; 25067 25068 { 25069 // Recursively traverse the entire deleted tree and clean up fiber fields. 25070 // This is more aggressive than ideal, and the long term goal is to only 25071 // have to detach the deleted tree at the root. 25072 detachFiberAfterEffects(fiber); 25073 25074 if (fiber === deletedSubtreeRoot) { 25075 nextEffect = null; 25076 return; 25077 } 25078 } 25079 25080 if (sibling !== null) { 25081 sibling.return = returnFiber; 25082 nextEffect = sibling; 25083 return; 25084 } 25085 25086 nextEffect = returnFiber; 25087 } 25088} 25089 25090function commitPassiveUnmountInsideDeletedTreeOnFiber(current, nearestMountedAncestor) { 25091 switch (current.tag) { 25092 case FunctionComponent: 25093 case ForwardRef: 25094 case SimpleMemoComponent: 25095 { 25096 if ( current.mode & ProfileMode) { 25097 startPassiveEffectTimer(); 25098 commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor); 25099 recordPassiveEffectDuration(current); 25100 } else { 25101 commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor); 25102 } 25103 25104 break; 25105 } 25106 } 25107} // TODO: Reuse reappearLayoutEffects traversal here? 25108 25109 25110function invokeLayoutEffectMountInDEV(fiber) { 25111 { 25112 // We don't need to re-check StrictEffectsMode here. 25113 // This function is only called if that check has already passed. 25114 switch (fiber.tag) { 25115 case FunctionComponent: 25116 case ForwardRef: 25117 case SimpleMemoComponent: 25118 { 25119 try { 25120 commitHookEffectListMount(Layout | HasEffect, fiber); 25121 } catch (error) { 25122 captureCommitPhaseError(fiber, fiber.return, error); 25123 } 25124 25125 break; 25126 } 25127 25128 case ClassComponent: 25129 { 25130 var instance = fiber.stateNode; 25131 25132 try { 25133 instance.componentDidMount(); 25134 } catch (error) { 25135 captureCommitPhaseError(fiber, fiber.return, error); 25136 } 25137 25138 break; 25139 } 25140 } 25141 } 25142} 25143 25144function invokePassiveEffectMountInDEV(fiber) { 25145 { 25146 // We don't need to re-check StrictEffectsMode here. 25147 // This function is only called if that check has already passed. 25148 switch (fiber.tag) { 25149 case FunctionComponent: 25150 case ForwardRef: 25151 case SimpleMemoComponent: 25152 { 25153 try { 25154 commitHookEffectListMount(Passive$1 | HasEffect, fiber); 25155 } catch (error) { 25156 captureCommitPhaseError(fiber, fiber.return, error); 25157 } 25158 25159 break; 25160 } 25161 } 25162 } 25163} 25164 25165function invokeLayoutEffectUnmountInDEV(fiber) { 25166 { 25167 // We don't need to re-check StrictEffectsMode here. 25168 // This function is only called if that check has already passed. 25169 switch (fiber.tag) { 25170 case FunctionComponent: 25171 case ForwardRef: 25172 case SimpleMemoComponent: 25173 { 25174 try { 25175 commitHookEffectListUnmount(Layout | HasEffect, fiber, fiber.return); 25176 } catch (error) { 25177 captureCommitPhaseError(fiber, fiber.return, error); 25178 } 25179 25180 break; 25181 } 25182 25183 case ClassComponent: 25184 { 25185 var instance = fiber.stateNode; 25186 25187 if (typeof instance.componentWillUnmount === 'function') { 25188 safelyCallComponentWillUnmount(fiber, fiber.return, instance); 25189 } 25190 25191 break; 25192 } 25193 } 25194 } 25195} 25196 25197function invokePassiveEffectUnmountInDEV(fiber) { 25198 { 25199 // We don't need to re-check StrictEffectsMode here. 25200 // This function is only called if that check has already passed. 25201 switch (fiber.tag) { 25202 case FunctionComponent: 25203 case ForwardRef: 25204 case SimpleMemoComponent: 25205 { 25206 try { 25207 commitHookEffectListUnmount(Passive$1 | HasEffect, fiber, fiber.return); 25208 } catch (error) { 25209 captureCommitPhaseError(fiber, fiber.return, error); 25210 } 25211 } 25212 } 25213 } 25214} 25215 25216var COMPONENT_TYPE = 0; 25217var HAS_PSEUDO_CLASS_TYPE = 1; 25218var ROLE_TYPE = 2; 25219var TEST_NAME_TYPE = 3; 25220var TEXT_TYPE = 4; 25221 25222if (typeof Symbol === 'function' && Symbol.for) { 25223 var symbolFor = Symbol.for; 25224 COMPONENT_TYPE = symbolFor('selector.component'); 25225 HAS_PSEUDO_CLASS_TYPE = symbolFor('selector.has_pseudo_class'); 25226 ROLE_TYPE = symbolFor('selector.role'); 25227 TEST_NAME_TYPE = symbolFor('selector.test_id'); 25228 TEXT_TYPE = symbolFor('selector.text'); 25229} 25230var commitHooks = []; 25231function onCommitRoot$1() { 25232 { 25233 commitHooks.forEach(function (commitHook) { 25234 return commitHook(); 25235 }); 25236 } 25237} 25238 25239var ReactCurrentActQueue = ReactSharedInternals.ReactCurrentActQueue; 25240function isLegacyActEnvironment(fiber) { 25241 { 25242 // Legacy mode. We preserve the behavior of React 17's act. It assumes an 25243 // act environment whenever `jest` is defined, but you can still turn off 25244 // spurious warnings by setting IS_REACT_ACT_ENVIRONMENT explicitly 25245 // to false. 25246 var isReactActEnvironmentGlobal = // $FlowExpectedError – Flow doesn't know about IS_REACT_ACT_ENVIRONMENT global 25247 typeof IS_REACT_ACT_ENVIRONMENT !== 'undefined' ? IS_REACT_ACT_ENVIRONMENT : undefined; // $FlowExpectedError - Flow doesn't know about jest 25248 25249 var jestIsDefined = typeof jest !== 'undefined'; 25250 return jestIsDefined && isReactActEnvironmentGlobal !== false; 25251 } 25252} 25253function isConcurrentActEnvironment() { 25254 { 25255 var isReactActEnvironmentGlobal = // $FlowExpectedError – Flow doesn't know about IS_REACT_ACT_ENVIRONMENT global 25256 typeof IS_REACT_ACT_ENVIRONMENT !== 'undefined' ? IS_REACT_ACT_ENVIRONMENT : undefined; 25257 25258 if (!isReactActEnvironmentGlobal && ReactCurrentActQueue.current !== null) { 25259 // TODO: Include link to relevant documentation page. 25260 error('The current testing environment is not configured to support ' + 'act(...)'); 25261 } 25262 25263 return isReactActEnvironmentGlobal; 25264 } 25265} 25266 25267var ceil = Math.ceil; 25268var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, 25269 ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, 25270 ReactCurrentBatchConfig$3 = ReactSharedInternals.ReactCurrentBatchConfig, 25271 ReactCurrentActQueue$1 = ReactSharedInternals.ReactCurrentActQueue; 25272var NoContext = 25273/* */ 252740; 25275var BatchedContext = 25276/* */ 252771; 25278var RenderContext = 25279/* */ 252802; 25281var CommitContext = 25282/* */ 252834; 25284var RootInProgress = 0; 25285var RootFatalErrored = 1; 25286var RootErrored = 2; 25287var RootSuspended = 3; 25288var RootSuspendedWithDelay = 4; 25289var RootCompleted = 5; 25290var RootDidNotComplete = 6; // Describes where we are in the React execution stack 25291 25292var executionContext = NoContext; // The root we're working on 25293 25294var workInProgressRoot = null; // The fiber we're working on 25295 25296var workInProgress = null; // The lanes we're rendering 25297 25298var workInProgressRootRenderLanes = NoLanes; // Stack that allows components to change the render lanes for its subtree 25299// This is a superset of the lanes we started working on at the root. The only 25300// case where it's different from `workInProgressRootRenderLanes` is when we 25301// enter a subtree that is hidden and needs to be unhidden: Suspense and 25302// Offscreen component. 25303// 25304// Most things in the work loop should deal with workInProgressRootRenderLanes. 25305// Most things in begin/complete phases should deal with subtreeRenderLanes. 25306 25307var subtreeRenderLanes = NoLanes; 25308var subtreeRenderLanesCursor = createCursor(NoLanes); // Whether to root completed, errored, suspended, etc. 25309 25310var workInProgressRootExitStatus = RootInProgress; // A fatal error, if one is thrown 25311 25312var workInProgressRootFatalError = null; // "Included" lanes refer to lanes that were worked on during this render. It's 25313// slightly different than `renderLanes` because `renderLanes` can change as you 25314// enter and exit an Offscreen tree. This value is the combination of all render 25315// lanes for the entire render phase. 25316 25317var workInProgressRootIncludedLanes = NoLanes; // The work left over by components that were visited during this render. Only 25318// includes unprocessed updates, not work in bailed out children. 25319 25320var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an interleaved event) during this render. 25321 25322var workInProgressRootInterleavedUpdatedLanes = NoLanes; // Lanes that were updated during the render phase (*not* an interleaved event). 25323 25324var workInProgressRootPingedLanes = NoLanes; // Errors that are thrown during the render phase. 25325 25326var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI. 25327// We will log them once the tree commits. 25328 25329var workInProgressRootRecoverableErrors = null; // The most recent time we committed a fallback. This lets us ensure a train 25330// model where we don't commit new loading states in too quick succession. 25331 25332var globalMostRecentFallbackTime = 0; 25333var FALLBACK_THROTTLE_MS = 500; // The absolute time for when we should start giving up on rendering 25334// more and prefer CPU suspense heuristics instead. 25335 25336var workInProgressRootRenderTargetTime = Infinity; // How long a render is supposed to take before we start following CPU 25337// suspense heuristics and opt out of rendering more content. 25338 25339var RENDER_TIMEOUT_MS = 500; 25340var workInProgressTransitions = null; 25341 25342function resetRenderTimer() { 25343 workInProgressRootRenderTargetTime = now() + RENDER_TIMEOUT_MS; 25344} 25345 25346function getRenderTargetTime() { 25347 return workInProgressRootRenderTargetTime; 25348} 25349var hasUncaughtError = false; 25350var firstUncaughtError = null; 25351var legacyErrorBoundariesThatAlreadyFailed = null; // Only used when enableProfilerNestedUpdateScheduledHook is true; 25352var rootDoesHavePassiveEffects = false; 25353var rootWithPendingPassiveEffects = null; 25354var pendingPassiveEffectsLanes = NoLanes; 25355var pendingPassiveProfilerEffects = []; 25356var pendingPassiveTransitions = null; // Use these to prevent an infinite loop of nested updates 25357 25358var NESTED_UPDATE_LIMIT = 50; 25359var nestedUpdateCount = 0; 25360var rootWithNestedUpdates = null; 25361var isFlushingPassiveEffects = false; 25362var didScheduleUpdateDuringPassiveEffects = false; 25363var NESTED_PASSIVE_UPDATE_LIMIT = 50; 25364var nestedPassiveUpdateCount = 0; 25365var rootWithPassiveNestedUpdates = null; // If two updates are scheduled within the same event, we should treat their 25366// event times as simultaneous, even if the actual clock time has advanced 25367// between the first and second call. 25368 25369var currentEventTime = NoTimestamp; 25370var currentEventTransitionLane = NoLanes; 25371var isRunningInsertionEffect = false; 25372function getWorkInProgressRoot() { 25373 return workInProgressRoot; 25374} 25375function requestEventTime() { 25376 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { 25377 // We're inside React, so it's fine to read the actual time. 25378 return now(); 25379 } // We're not inside React, so we may be in the middle of a browser event. 25380 25381 25382 if (currentEventTime !== NoTimestamp) { 25383 // Use the same start time for all updates until we enter React again. 25384 return currentEventTime; 25385 } // This is the first update since React yielded. Compute a new start time. 25386 25387 25388 currentEventTime = now(); 25389 return currentEventTime; 25390} 25391function requestUpdateLane(fiber) { 25392 // Special cases 25393 var mode = fiber.mode; 25394 25395 if ((mode & ConcurrentMode) === NoMode) { 25396 return SyncLane; 25397 } else if ( (executionContext & RenderContext) !== NoContext && workInProgressRootRenderLanes !== NoLanes) { 25398 // This is a render phase update. These are not officially supported. The 25399 // old behavior is to give this the same "thread" (lanes) as 25400 // whatever is currently rendering. So if you call `setState` on a component 25401 // that happens later in the same render, it will flush. Ideally, we want to 25402 // remove the special case and treat them as if they came from an 25403 // interleaved event. Regardless, this pattern is not officially supported. 25404 // This behavior is only a fallback. The flag only exists until we can roll 25405 // out the setState warning, since existing code might accidentally rely on 25406 // the current behavior. 25407 return pickArbitraryLane(workInProgressRootRenderLanes); 25408 } 25409 25410 var isTransition = requestCurrentTransition() !== NoTransition; 25411 25412 if (isTransition) { 25413 if ( ReactCurrentBatchConfig$3.transition !== null) { 25414 var transition = ReactCurrentBatchConfig$3.transition; 25415 25416 if (!transition._updatedFibers) { 25417 transition._updatedFibers = new Set(); 25418 } 25419 25420 transition._updatedFibers.add(fiber); 25421 } // The algorithm for assigning an update to a lane should be stable for all 25422 // updates at the same priority within the same event. To do this, the 25423 // inputs to the algorithm must be the same. 25424 // 25425 // The trick we use is to cache the first of each of these inputs within an 25426 // event. Then reset the cached values once we can be sure the event is 25427 // over. Our heuristic for that is whenever we enter a concurrent work loop. 25428 25429 25430 if (currentEventTransitionLane === NoLane) { 25431 // All transitions within the same event are assigned the same lane. 25432 currentEventTransitionLane = claimNextTransitionLane(); 25433 } 25434 25435 return currentEventTransitionLane; 25436 } // Updates originating inside certain React methods, like flushSync, have 25437 // their priority set by tracking it with a context variable. 25438 // 25439 // The opaque type returned by the host config is internally a lane, so we can 25440 // use that directly. 25441 // TODO: Move this type conversion to the event priority module. 25442 25443 25444 var updateLane = getCurrentUpdatePriority(); 25445 25446 if (updateLane !== NoLane) { 25447 return updateLane; 25448 } // This update originated outside React. Ask the host environment for an 25449 // appropriate priority, based on the type of event. 25450 // 25451 // The opaque type returned by the host config is internally a lane, so we can 25452 // use that directly. 25453 // TODO: Move this type conversion to the event priority module. 25454 25455 25456 var eventLane = getCurrentEventPriority(); 25457 return eventLane; 25458} 25459 25460function requestRetryLane(fiber) { 25461 // This is a fork of `requestUpdateLane` designed specifically for Suspense 25462 // "retries" — a special update that attempts to flip a Suspense boundary 25463 // from its placeholder state to its primary/resolved state. 25464 // Special cases 25465 var mode = fiber.mode; 25466 25467 if ((mode & ConcurrentMode) === NoMode) { 25468 return SyncLane; 25469 } 25470 25471 return claimNextRetryLane(); 25472} 25473 25474function scheduleUpdateOnFiber(root, fiber, lane, eventTime) { 25475 checkForNestedUpdates(); 25476 25477 { 25478 if (isRunningInsertionEffect) { 25479 error('useInsertionEffect must not schedule updates.'); 25480 } 25481 } 25482 25483 { 25484 if (isFlushingPassiveEffects) { 25485 didScheduleUpdateDuringPassiveEffects = true; 25486 } 25487 } // Mark that the root has a pending update. 25488 25489 25490 markRootUpdated(root, lane, eventTime); 25491 25492 if ((executionContext & RenderContext) !== NoLanes && root === workInProgressRoot) { 25493 // This update was dispatched during the render phase. This is a mistake 25494 // if the update originates from user space (with the exception of local 25495 // hook updates, which are handled differently and don't reach this 25496 // function), but there are some internal React features that use this as 25497 // an implementation detail, like selective hydration. 25498 warnAboutRenderPhaseUpdatesInDEV(fiber); // Track lanes that were updated during the render phase 25499 } else { 25500 // This is a normal update, scheduled from outside the render phase. For 25501 // example, during an input event. 25502 { 25503 if (isDevToolsPresent) { 25504 addFiberToLanesMap(root, fiber, lane); 25505 } 25506 } 25507 25508 warnIfUpdatesNotWrappedWithActDEV(fiber); 25509 25510 if (root === workInProgressRoot) { 25511 // Received an update to a tree that's in the middle of rendering. Mark 25512 // that there was an interleaved update work on this root. Unless the 25513 // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render 25514 // phase update. In that case, we don't treat render phase updates as if 25515 // they were interleaved, for backwards compat reasons. 25516 if ( (executionContext & RenderContext) === NoContext) { 25517 workInProgressRootInterleavedUpdatedLanes = mergeLanes(workInProgressRootInterleavedUpdatedLanes, lane); 25518 } 25519 25520 if (workInProgressRootExitStatus === RootSuspendedWithDelay) { 25521 // The root already suspended with a delay, which means this render 25522 // definitely won't finish. Since we have a new update, let's mark it as 25523 // suspended now, right before marking the incoming update. This has the 25524 // effect of interrupting the current render and switching to the update. 25525 // TODO: Make sure this doesn't override pings that happen while we've 25526 // already started rendering. 25527 markRootSuspended$1(root, workInProgressRootRenderLanes); 25528 } 25529 } 25530 25531 ensureRootIsScheduled(root, eventTime); 25532 25533 if (lane === SyncLane && executionContext === NoContext && (fiber.mode & ConcurrentMode) === NoMode && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode. 25534 !( ReactCurrentActQueue$1.isBatchingLegacy)) { 25535 // Flush the synchronous work now, unless we're already working or inside 25536 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of 25537 // scheduleCallbackForFiber to preserve the ability to schedule a callback 25538 // without immediately flushing it. We only do this for user-initiated 25539 // updates, to preserve historical behavior of legacy mode. 25540 resetRenderTimer(); 25541 flushSyncCallbacksOnlyInLegacyMode(); 25542 } 25543 } 25544} 25545function scheduleInitialHydrationOnRoot(root, lane, eventTime) { 25546 // This is a special fork of scheduleUpdateOnFiber that is only used to 25547 // schedule the initial hydration of a root that has just been created. Most 25548 // of the stuff in scheduleUpdateOnFiber can be skipped. 25549 // 25550 // The main reason for this separate path, though, is to distinguish the 25551 // initial children from subsequent updates. In fully client-rendered roots 25552 // (createRoot instead of hydrateRoot), all top-level renders are modeled as 25553 // updates, but hydration roots are special because the initial render must 25554 // match what was rendered on the server. 25555 var current = root.current; 25556 current.lanes = lane; 25557 markRootUpdated(root, lane, eventTime); 25558 ensureRootIsScheduled(root, eventTime); 25559} 25560function isUnsafeClassRenderPhaseUpdate(fiber) { 25561 // Check if this is a render phase update. Only called by class components, 25562 // which special (deprecated) behavior for UNSAFE_componentWillReceive props. 25563 return (// TODO: Remove outdated deferRenderPhaseUpdateToNextBatch experiment. We 25564 // decided not to enable it. 25565 (executionContext & RenderContext) !== NoContext 25566 ); 25567} // Use this function to schedule a task for a root. There's only one task per 25568// root; if a task was already scheduled, we'll check to make sure the priority 25569// of the existing task is the same as the priority of the next level that the 25570// root has work on. This function is called on every update, and right before 25571// exiting a task. 25572 25573function ensureRootIsScheduled(root, currentTime) { 25574 var existingCallbackNode = root.callbackNode; // Check if any lanes are being starved by other work. If so, mark them as 25575 // expired so we know to work on those next. 25576 25577 markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority. 25578 25579 var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes); 25580 25581 if (nextLanes === NoLanes) { 25582 // Special case: There's nothing to work on. 25583 if (existingCallbackNode !== null) { 25584 cancelCallback$1(existingCallbackNode); 25585 } 25586 25587 root.callbackNode = null; 25588 root.callbackPriority = NoLane; 25589 return; 25590 } // We use the highest priority lane to represent the priority of the callback. 25591 25592 25593 var newCallbackPriority = getHighestPriorityLane(nextLanes); // Check if there's an existing task. We may be able to reuse it. 25594 25595 var existingCallbackPriority = root.callbackPriority; 25596 25597 if (existingCallbackPriority === newCallbackPriority && // Special case related to `act`. If the currently scheduled task is a 25598 // Scheduler task, rather than an `act` task, cancel it and re-scheduled 25599 // on the `act` queue. 25600 !( ReactCurrentActQueue$1.current !== null && existingCallbackNode !== fakeActCallbackNode)) { 25601 { 25602 // If we're going to re-use an existing task, it needs to exist. 25603 // Assume that discrete update microtasks are non-cancellable and null. 25604 // TODO: Temporary until we confirm this warning is not fired. 25605 if (existingCallbackNode == null && existingCallbackPriority !== SyncLane) { 25606 error('Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.'); 25607 } 25608 } // The priority hasn't changed. We can reuse the existing task. Exit. 25609 25610 25611 return; 25612 } 25613 25614 if (existingCallbackNode != null) { 25615 // Cancel the existing callback. We'll schedule a new one below. 25616 cancelCallback$1(existingCallbackNode); 25617 } // Schedule a new callback. 25618 25619 25620 var newCallbackNode; 25621 25622 if (newCallbackPriority === SyncLane) { 25623 // Special case: Sync React callbacks are scheduled on a special 25624 // internal queue 25625 if (root.tag === LegacyRoot) { 25626 if ( ReactCurrentActQueue$1.isBatchingLegacy !== null) { 25627 ReactCurrentActQueue$1.didScheduleLegacyUpdate = true; 25628 } 25629 25630 scheduleLegacySyncCallback(performSyncWorkOnRoot.bind(null, root)); 25631 } else { 25632 scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); 25633 } 25634 25635 { 25636 // Flush the queue in a microtask. 25637 if ( ReactCurrentActQueue$1.current !== null) { 25638 // Inside `act`, use our internal `act` queue so that these get flushed 25639 // at the end of the current scope even when using the sync version 25640 // of `act`. 25641 ReactCurrentActQueue$1.current.push(flushSyncCallbacks); 25642 } else { 25643 scheduleMicrotask(function () { 25644 // In Safari, appending an iframe forces microtasks to run. 25645 // https://github.com/facebook/react/issues/22459 25646 // We don't support running callbacks in the middle of render 25647 // or commit so we need to check against that. 25648 if ((executionContext & (RenderContext | CommitContext)) === NoContext) { 25649 // Note that this would still prematurely flush the callbacks 25650 // if this happens outside render or commit phase (e.g. in an event). 25651 flushSyncCallbacks(); 25652 } 25653 }); 25654 } 25655 } 25656 25657 newCallbackNode = null; 25658 } else { 25659 var schedulerPriorityLevel; 25660 25661 switch (lanesToEventPriority(nextLanes)) { 25662 case DiscreteEventPriority: 25663 schedulerPriorityLevel = ImmediatePriority; 25664 break; 25665 25666 case ContinuousEventPriority: 25667 schedulerPriorityLevel = UserBlockingPriority; 25668 break; 25669 25670 case DefaultEventPriority: 25671 schedulerPriorityLevel = NormalPriority; 25672 break; 25673 25674 case IdleEventPriority: 25675 schedulerPriorityLevel = IdlePriority; 25676 break; 25677 25678 default: 25679 schedulerPriorityLevel = NormalPriority; 25680 break; 25681 } 25682 25683 newCallbackNode = scheduleCallback$1(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root)); 25684 } 25685 25686 root.callbackPriority = newCallbackPriority; 25687 root.callbackNode = newCallbackNode; 25688} // This is the entry point for every concurrent task, i.e. anything that 25689// goes through Scheduler. 25690 25691 25692function performConcurrentWorkOnRoot(root, didTimeout) { 25693 { 25694 resetNestedUpdateFlag(); 25695 } // Since we know we're in a React event, we can clear the current 25696 // event time. The next update will compute a new event time. 25697 25698 25699 currentEventTime = NoTimestamp; 25700 currentEventTransitionLane = NoLanes; 25701 25702 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { 25703 throw new Error('Should not already be working.'); 25704 } // Flush any pending passive effects before deciding which lanes to work on, 25705 // in case they schedule additional work. 25706 25707 25708 var originalCallbackNode = root.callbackNode; 25709 var didFlushPassiveEffects = flushPassiveEffects(); 25710 25711 if (didFlushPassiveEffects) { 25712 // Something in the passive effect phase may have canceled the current task. 25713 // Check if the task node for this root was changed. 25714 if (root.callbackNode !== originalCallbackNode) { 25715 // The current task was canceled. Exit. We don't need to call 25716 // `ensureRootIsScheduled` because the check above implies either that 25717 // there's a new task, or that there's no remaining work on this root. 25718 return null; 25719 } 25720 } // Determine the next lanes to work on, using the fields stored 25721 // on the root. 25722 25723 25724 var lanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes); 25725 25726 if (lanes === NoLanes) { 25727 // Defensive coding. This is never expected to happen. 25728 return null; 25729 } // We disable time-slicing in some cases: if the work has been CPU-bound 25730 // for too long ("expired" work, to prevent starvation), or we're in 25731 // sync-updates-by-default mode. 25732 // TODO: We only check `didTimeout` defensively, to account for a Scheduler 25733 // bug we're still investigating. Once the bug in Scheduler is fixed, 25734 // we can remove this, since we track expiration ourselves. 25735 25736 25737 var shouldTimeSlice = !includesBlockingLane(root, lanes) && !includesExpiredLane(root, lanes) && ( !didTimeout); 25738 var exitStatus = shouldTimeSlice ? renderRootConcurrent(root, lanes) : renderRootSync(root, lanes); 25739 25740 if (exitStatus !== RootInProgress) { 25741 if (exitStatus === RootErrored) { 25742 // If something threw an error, try rendering one more time. We'll 25743 // render synchronously to block concurrent data mutations, and we'll 25744 // includes all pending updates are included. If it still fails after 25745 // the second attempt, we'll give up and commit the resulting tree. 25746 var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); 25747 25748 if (errorRetryLanes !== NoLanes) { 25749 lanes = errorRetryLanes; 25750 exitStatus = recoverFromConcurrentError(root, errorRetryLanes); 25751 } 25752 } 25753 25754 if (exitStatus === RootFatalErrored) { 25755 var fatalError = workInProgressRootFatalError; 25756 prepareFreshStack(root, NoLanes); 25757 markRootSuspended$1(root, lanes); 25758 ensureRootIsScheduled(root, now()); 25759 throw fatalError; 25760 } 25761 25762 if (exitStatus === RootDidNotComplete) { 25763 // The render unwound without completing the tree. This happens in special 25764 // cases where need to exit the current render without producing a 25765 // consistent tree or committing. 25766 // 25767 // This should only happen during a concurrent render, not a discrete or 25768 // synchronous update. We should have already checked for this when we 25769 // unwound the stack. 25770 markRootSuspended$1(root, lanes); 25771 } else { 25772 // The render completed. 25773 // Check if this render may have yielded to a concurrent event, and if so, 25774 // confirm that any newly rendered stores are consistent. 25775 // TODO: It's possible that even a concurrent render may never have yielded 25776 // to the main thread, if it was fast enough, or if it expired. We could 25777 // skip the consistency check in that case, too. 25778 var renderWasConcurrent = !includesBlockingLane(root, lanes); 25779 var finishedWork = root.current.alternate; 25780 25781 if (renderWasConcurrent && !isRenderConsistentWithExternalStores(finishedWork)) { 25782 // A store was mutated in an interleaved event. Render again, 25783 // synchronously, to block further mutations. 25784 exitStatus = renderRootSync(root, lanes); // We need to check again if something threw 25785 25786 if (exitStatus === RootErrored) { 25787 var _errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); 25788 25789 if (_errorRetryLanes !== NoLanes) { 25790 lanes = _errorRetryLanes; 25791 exitStatus = recoverFromConcurrentError(root, _errorRetryLanes); // We assume the tree is now consistent because we didn't yield to any 25792 // concurrent events. 25793 } 25794 } 25795 25796 if (exitStatus === RootFatalErrored) { 25797 var _fatalError = workInProgressRootFatalError; 25798 prepareFreshStack(root, NoLanes); 25799 markRootSuspended$1(root, lanes); 25800 ensureRootIsScheduled(root, now()); 25801 throw _fatalError; 25802 } 25803 } // We now have a consistent tree. The next step is either to commit it, 25804 // or, if something suspended, wait to commit it after a timeout. 25805 25806 25807 root.finishedWork = finishedWork; 25808 root.finishedLanes = lanes; 25809 finishConcurrentRender(root, exitStatus, lanes); 25810 } 25811 } 25812 25813 ensureRootIsScheduled(root, now()); 25814 25815 if (root.callbackNode === originalCallbackNode) { 25816 // The task node scheduled for this root is the same one that's 25817 // currently executed. Need to return a continuation. 25818 return performConcurrentWorkOnRoot.bind(null, root); 25819 } 25820 25821 return null; 25822} 25823 25824function recoverFromConcurrentError(root, errorRetryLanes) { 25825 // If an error occurred during hydration, discard server response and fall 25826 // back to client side render. 25827 // Before rendering again, save the errors from the previous attempt. 25828 var errorsFromFirstAttempt = workInProgressRootConcurrentErrors; 25829 25830 if (isRootDehydrated(root)) { 25831 // The shell failed to hydrate. Set a flag to force a client rendering 25832 // during the next attempt. To do this, we call prepareFreshStack now 25833 // to create the root work-in-progress fiber. This is a bit weird in terms 25834 // of factoring, because it relies on renderRootSync not calling 25835 // prepareFreshStack again in the call below, which happens because the 25836 // root and lanes haven't changed. 25837 // 25838 // TODO: I think what we should do is set ForceClientRender inside 25839 // throwException, like we do for nested Suspense boundaries. The reason 25840 // it's here instead is so we can switch to the synchronous work loop, too. 25841 // Something to consider for a future refactor. 25842 var rootWorkInProgress = prepareFreshStack(root, errorRetryLanes); 25843 rootWorkInProgress.flags |= ForceClientRender; 25844 25845 { 25846 errorHydratingContainer(root.containerInfo); 25847 } 25848 } 25849 25850 var exitStatus = renderRootSync(root, errorRetryLanes); 25851 25852 if (exitStatus !== RootErrored) { 25853 // Successfully finished rendering on retry 25854 // The errors from the failed first attempt have been recovered. Add 25855 // them to the collection of recoverable errors. We'll log them in the 25856 // commit phase. 25857 var errorsFromSecondAttempt = workInProgressRootRecoverableErrors; 25858 workInProgressRootRecoverableErrors = errorsFromFirstAttempt; // The errors from the second attempt should be queued after the errors 25859 // from the first attempt, to preserve the causal sequence. 25860 25861 if (errorsFromSecondAttempt !== null) { 25862 queueRecoverableErrors(errorsFromSecondAttempt); 25863 } 25864 } 25865 25866 return exitStatus; 25867} 25868 25869function queueRecoverableErrors(errors) { 25870 if (workInProgressRootRecoverableErrors === null) { 25871 workInProgressRootRecoverableErrors = errors; 25872 } else { 25873 workInProgressRootRecoverableErrors.push.apply(workInProgressRootRecoverableErrors, errors); 25874 } 25875} 25876 25877function finishConcurrentRender(root, exitStatus, lanes) { 25878 switch (exitStatus) { 25879 case RootInProgress: 25880 case RootFatalErrored: 25881 { 25882 throw new Error('Root did not complete. This is a bug in React.'); 25883 } 25884 // Flow knows about invariant, so it complains if I add a break 25885 // statement, but eslint doesn't know about invariant, so it complains 25886 // if I do. eslint-disable-next-line no-fallthrough 25887 25888 case RootErrored: 25889 { 25890 // We should have already attempted to retry this tree. If we reached 25891 // this point, it errored again. Commit it. 25892 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions); 25893 break; 25894 } 25895 25896 case RootSuspended: 25897 { 25898 markRootSuspended$1(root, lanes); // We have an acceptable loading state. We need to figure out if we 25899 // should immediately commit it or wait a bit. 25900 25901 if (includesOnlyRetries(lanes) && // do not delay if we're inside an act() scope 25902 !shouldForceFlushFallbacksInDEV()) { 25903 // This render only included retries, no updates. Throttle committing 25904 // retries so that we don't show too many loading states too quickly. 25905 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time. 25906 25907 if (msUntilTimeout > 10) { 25908 var nextLanes = getNextLanes(root, NoLanes); 25909 25910 if (nextLanes !== NoLanes) { 25911 // There's additional work on this root. 25912 break; 25913 } 25914 25915 var suspendedLanes = root.suspendedLanes; 25916 25917 if (!isSubsetOfLanes(suspendedLanes, lanes)) { 25918 // We should prefer to render the fallback of at the last 25919 // suspended level. Ping the last suspended level to try 25920 // rendering it again. 25921 // FIXME: What if the suspended lanes are Idle? Should not restart. 25922 var eventTime = requestEventTime(); 25923 markRootPinged(root, suspendedLanes); 25924 break; 25925 } // The render is suspended, it hasn't timed out, and there's no 25926 // lower priority work to do. Instead of committing the fallback 25927 // immediately, wait for more data to arrive. 25928 25929 25930 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root, workInProgressRootRecoverableErrors, workInProgressTransitions), msUntilTimeout); 25931 break; 25932 } 25933 } // The work expired. Commit immediately. 25934 25935 25936 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions); 25937 break; 25938 } 25939 25940 case RootSuspendedWithDelay: 25941 { 25942 markRootSuspended$1(root, lanes); 25943 25944 if (includesOnlyTransitions(lanes)) { 25945 // This is a transition, so we should exit without committing a 25946 // placeholder and without scheduling a timeout. Delay indefinitely 25947 // until we receive more data. 25948 break; 25949 } 25950 25951 if (!shouldForceFlushFallbacksInDEV()) { 25952 // This is not a transition, but we did trigger an avoided state. 25953 // Schedule a placeholder to display after a short delay, using the Just 25954 // Noticeable Difference. 25955 // TODO: Is the JND optimization worth the added complexity? If this is 25956 // the only reason we track the event time, then probably not. 25957 // Consider removing. 25958 var mostRecentEventTime = getMostRecentEventTime(root, lanes); 25959 var eventTimeMs = mostRecentEventTime; 25960 var timeElapsedMs = now() - eventTimeMs; 25961 25962 var _msUntilTimeout = jnd(timeElapsedMs) - timeElapsedMs; // Don't bother with a very short suspense time. 25963 25964 25965 if (_msUntilTimeout > 10) { 25966 // Instead of committing the fallback immediately, wait for more data 25967 // to arrive. 25968 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root, workInProgressRootRecoverableErrors, workInProgressTransitions), _msUntilTimeout); 25969 break; 25970 } 25971 } // Commit the placeholder. 25972 25973 25974 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions); 25975 break; 25976 } 25977 25978 case RootCompleted: 25979 { 25980 // The work completed. Ready to commit. 25981 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions); 25982 break; 25983 } 25984 25985 default: 25986 { 25987 throw new Error('Unknown root exit status.'); 25988 } 25989 } 25990} 25991 25992function isRenderConsistentWithExternalStores(finishedWork) { 25993 // Search the rendered tree for external store reads, and check whether the 25994 // stores were mutated in a concurrent event. Intentionally using an iterative 25995 // loop instead of recursion so we can exit early. 25996 var node = finishedWork; 25997 25998 while (true) { 25999 if (node.flags & StoreConsistency) { 26000 var updateQueue = node.updateQueue; 26001 26002 if (updateQueue !== null) { 26003 var checks = updateQueue.stores; 26004 26005 if (checks !== null) { 26006 for (var i = 0; i < checks.length; i++) { 26007 var check = checks[i]; 26008 var getSnapshot = check.getSnapshot; 26009 var renderedValue = check.value; 26010 26011 try { 26012 if (!objectIs(getSnapshot(), renderedValue)) { 26013 // Found an inconsistent store. 26014 return false; 26015 } 26016 } catch (error) { 26017 // If `getSnapshot` throws, return `false`. This will schedule 26018 // a re-render, and the error will be rethrown during render. 26019 return false; 26020 } 26021 } 26022 } 26023 } 26024 } 26025 26026 var child = node.child; 26027 26028 if (node.subtreeFlags & StoreConsistency && child !== null) { 26029 child.return = node; 26030 node = child; 26031 continue; 26032 } 26033 26034 if (node === finishedWork) { 26035 return true; 26036 } 26037 26038 while (node.sibling === null) { 26039 if (node.return === null || node.return === finishedWork) { 26040 return true; 26041 } 26042 26043 node = node.return; 26044 } 26045 26046 node.sibling.return = node.return; 26047 node = node.sibling; 26048 } // Flow doesn't know this is unreachable, but eslint does 26049 // eslint-disable-next-line no-unreachable 26050 26051 26052 return true; 26053} 26054 26055function markRootSuspended$1(root, suspendedLanes) { 26056 // When suspending, we should always exclude lanes that were pinged or (more 26057 // rarely, since we try to avoid it) updated during the render phase. 26058 // TODO: Lol maybe there's a better way to factor this besides this 26059 // obnoxiously named function :) 26060 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootPingedLanes); 26061 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootInterleavedUpdatedLanes); 26062 markRootSuspended(root, suspendedLanes); 26063} // This is the entry point for synchronous tasks that don't go 26064// through Scheduler 26065 26066 26067function performSyncWorkOnRoot(root) { 26068 { 26069 syncNestedUpdateFlag(); 26070 } 26071 26072 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { 26073 throw new Error('Should not already be working.'); 26074 } 26075 26076 flushPassiveEffects(); 26077 var lanes = getNextLanes(root, NoLanes); 26078 26079 if (!includesSomeLane(lanes, SyncLane)) { 26080 // There's no remaining sync work left. 26081 ensureRootIsScheduled(root, now()); 26082 return null; 26083 } 26084 26085 var exitStatus = renderRootSync(root, lanes); 26086 26087 if (root.tag !== LegacyRoot && exitStatus === RootErrored) { 26088 // If something threw an error, try rendering one more time. We'll render 26089 // synchronously to block concurrent data mutations, and we'll includes 26090 // all pending updates are included. If it still fails after the second 26091 // attempt, we'll give up and commit the resulting tree. 26092 var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); 26093 26094 if (errorRetryLanes !== NoLanes) { 26095 lanes = errorRetryLanes; 26096 exitStatus = recoverFromConcurrentError(root, errorRetryLanes); 26097 } 26098 } 26099 26100 if (exitStatus === RootFatalErrored) { 26101 var fatalError = workInProgressRootFatalError; 26102 prepareFreshStack(root, NoLanes); 26103 markRootSuspended$1(root, lanes); 26104 ensureRootIsScheduled(root, now()); 26105 throw fatalError; 26106 } 26107 26108 if (exitStatus === RootDidNotComplete) { 26109 throw new Error('Root did not complete. This is a bug in React.'); 26110 } // We now have a consistent tree. Because this is a sync render, we 26111 // will commit it even if something suspended. 26112 26113 26114 var finishedWork = root.current.alternate; 26115 root.finishedWork = finishedWork; 26116 root.finishedLanes = lanes; 26117 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions); // Before exiting, make sure there's a callback scheduled for the next 26118 // pending level. 26119 26120 ensureRootIsScheduled(root, now()); 26121 return null; 26122} 26123 26124function flushRoot(root, lanes) { 26125 if (lanes !== NoLanes) { 26126 markRootEntangled(root, mergeLanes(lanes, SyncLane)); 26127 ensureRootIsScheduled(root, now()); 26128 26129 if ((executionContext & (RenderContext | CommitContext)) === NoContext) { 26130 resetRenderTimer(); 26131 flushSyncCallbacks(); 26132 } 26133 } 26134} 26135function batchedUpdates$1(fn, a) { 26136 var prevExecutionContext = executionContext; 26137 executionContext |= BatchedContext; 26138 26139 try { 26140 return fn(a); 26141 } finally { 26142 executionContext = prevExecutionContext; // If there were legacy sync updates, flush them at the end of the outer 26143 // most batchedUpdates-like method. 26144 26145 if (executionContext === NoContext && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode. 26146 !( ReactCurrentActQueue$1.isBatchingLegacy)) { 26147 resetRenderTimer(); 26148 flushSyncCallbacksOnlyInLegacyMode(); 26149 } 26150 } 26151} 26152function discreteUpdates(fn, a, b, c, d) { 26153 var previousPriority = getCurrentUpdatePriority(); 26154 var prevTransition = ReactCurrentBatchConfig$3.transition; 26155 26156 try { 26157 ReactCurrentBatchConfig$3.transition = null; 26158 setCurrentUpdatePriority(DiscreteEventPriority); 26159 return fn(a, b, c, d); 26160 } finally { 26161 setCurrentUpdatePriority(previousPriority); 26162 ReactCurrentBatchConfig$3.transition = prevTransition; 26163 26164 if (executionContext === NoContext) { 26165 resetRenderTimer(); 26166 } 26167 } 26168} // Overload the definition to the two valid signatures. 26169// Warning, this opts-out of checking the function body. 26170 26171// eslint-disable-next-line no-redeclare 26172function flushSync(fn) { 26173 // In legacy mode, we flush pending passive effects at the beginning of the 26174 // next event, not at the end of the previous one. 26175 if (rootWithPendingPassiveEffects !== null && rootWithPendingPassiveEffects.tag === LegacyRoot && (executionContext & (RenderContext | CommitContext)) === NoContext) { 26176 flushPassiveEffects(); 26177 } 26178 26179 var prevExecutionContext = executionContext; 26180 executionContext |= BatchedContext; 26181 var prevTransition = ReactCurrentBatchConfig$3.transition; 26182 var previousPriority = getCurrentUpdatePriority(); 26183 26184 try { 26185 ReactCurrentBatchConfig$3.transition = null; 26186 setCurrentUpdatePriority(DiscreteEventPriority); 26187 26188 if (fn) { 26189 return fn(); 26190 } else { 26191 return undefined; 26192 } 26193 } finally { 26194 setCurrentUpdatePriority(previousPriority); 26195 ReactCurrentBatchConfig$3.transition = prevTransition; 26196 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch. 26197 // Note that this will happen even if batchedUpdates is higher up 26198 // the stack. 26199 26200 if ((executionContext & (RenderContext | CommitContext)) === NoContext) { 26201 flushSyncCallbacks(); 26202 } 26203 } 26204} 26205function isAlreadyRendering() { 26206 // Used by the renderer to print a warning if certain APIs are called from 26207 // the wrong context. 26208 return (executionContext & (RenderContext | CommitContext)) !== NoContext; 26209} 26210function pushRenderLanes(fiber, lanes) { 26211 push(subtreeRenderLanesCursor, subtreeRenderLanes, fiber); 26212 subtreeRenderLanes = mergeLanes(subtreeRenderLanes, lanes); 26213 workInProgressRootIncludedLanes = mergeLanes(workInProgressRootIncludedLanes, lanes); 26214} 26215function popRenderLanes(fiber) { 26216 subtreeRenderLanes = subtreeRenderLanesCursor.current; 26217 pop(subtreeRenderLanesCursor, fiber); 26218} 26219 26220function prepareFreshStack(root, lanes) { 26221 root.finishedWork = null; 26222 root.finishedLanes = NoLanes; 26223 var timeoutHandle = root.timeoutHandle; 26224 26225 if (timeoutHandle !== noTimeout) { 26226 // The root previous suspended and scheduled a timeout to commit a fallback 26227 // state. Now that we have additional work, cancel the timeout. 26228 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above 26229 26230 cancelTimeout(timeoutHandle); 26231 } 26232 26233 if (workInProgress !== null) { 26234 var interruptedWork = workInProgress.return; 26235 26236 while (interruptedWork !== null) { 26237 var current = interruptedWork.alternate; 26238 unwindInterruptedWork(current, interruptedWork); 26239 interruptedWork = interruptedWork.return; 26240 } 26241 } 26242 26243 workInProgressRoot = root; 26244 var rootWorkInProgress = createWorkInProgress(root.current, null); 26245 workInProgress = rootWorkInProgress; 26246 workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; 26247 workInProgressRootExitStatus = RootInProgress; 26248 workInProgressRootFatalError = null; 26249 workInProgressRootSkippedLanes = NoLanes; 26250 workInProgressRootInterleavedUpdatedLanes = NoLanes; 26251 workInProgressRootPingedLanes = NoLanes; 26252 workInProgressRootConcurrentErrors = null; 26253 workInProgressRootRecoverableErrors = null; 26254 finishQueueingConcurrentUpdates(); 26255 26256 { 26257 ReactStrictModeWarnings.discardPendingWarnings(); 26258 } 26259 26260 return rootWorkInProgress; 26261} 26262 26263function handleError(root, thrownValue) { 26264 do { 26265 var erroredWork = workInProgress; 26266 26267 try { 26268 // Reset module-level state that was set during the render phase. 26269 resetContextDependencies(); 26270 resetHooksAfterThrow(); 26271 resetCurrentFiber(); // TODO: I found and added this missing line while investigating a 26272 // separate issue. Write a regression test using string refs. 26273 26274 ReactCurrentOwner$2.current = null; 26275 26276 if (erroredWork === null || erroredWork.return === null) { 26277 // Expected to be working on a non-root fiber. This is a fatal error 26278 // because there's no ancestor that can handle it; the root is 26279 // supposed to capture all errors that weren't caught by an error 26280 // boundary. 26281 workInProgressRootExitStatus = RootFatalErrored; 26282 workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next 26283 // sibling, or the parent if there are no siblings. But since the root 26284 // has no siblings nor a parent, we set it to null. Usually this is 26285 // handled by `completeUnitOfWork` or `unwindWork`, but since we're 26286 // intentionally not calling those, we need set it here. 26287 // TODO: Consider calling `unwindWork` to pop the contexts. 26288 26289 workInProgress = null; 26290 return; 26291 } 26292 26293 if (enableProfilerTimer && erroredWork.mode & ProfileMode) { 26294 // Record the time spent rendering before an error was thrown. This 26295 // avoids inaccurate Profiler durations in the case of a 26296 // suspended render. 26297 stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true); 26298 } 26299 26300 if (enableSchedulingProfiler) { 26301 markComponentRenderStopped(); 26302 26303 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') { 26304 var wakeable = thrownValue; 26305 markComponentSuspended(erroredWork, wakeable, workInProgressRootRenderLanes); 26306 } else { 26307 markComponentErrored(erroredWork, thrownValue, workInProgressRootRenderLanes); 26308 } 26309 } 26310 26311 throwException(root, erroredWork.return, erroredWork, thrownValue, workInProgressRootRenderLanes); 26312 completeUnitOfWork(erroredWork); 26313 } catch (yetAnotherThrownValue) { 26314 // Something in the return path also threw. 26315 thrownValue = yetAnotherThrownValue; 26316 26317 if (workInProgress === erroredWork && erroredWork !== null) { 26318 // If this boundary has already errored, then we had trouble processing 26319 // the error. Bubble it to the next boundary. 26320 erroredWork = erroredWork.return; 26321 workInProgress = erroredWork; 26322 } else { 26323 erroredWork = workInProgress; 26324 } 26325 26326 continue; 26327 } // Return to the normal work loop. 26328 26329 26330 return; 26331 } while (true); 26332} 26333 26334function pushDispatcher() { 26335 var prevDispatcher = ReactCurrentDispatcher$2.current; 26336 ReactCurrentDispatcher$2.current = ContextOnlyDispatcher; 26337 26338 if (prevDispatcher === null) { 26339 // The React isomorphic package does not include a default dispatcher. 26340 // Instead the first renderer will lazily attach one, in order to give 26341 // nicer error messages. 26342 return ContextOnlyDispatcher; 26343 } else { 26344 return prevDispatcher; 26345 } 26346} 26347 26348function popDispatcher(prevDispatcher) { 26349 ReactCurrentDispatcher$2.current = prevDispatcher; 26350} 26351 26352function markCommitTimeOfFallback() { 26353 globalMostRecentFallbackTime = now(); 26354} 26355function markSkippedUpdateLanes(lane) { 26356 workInProgressRootSkippedLanes = mergeLanes(lane, workInProgressRootSkippedLanes); 26357} 26358function renderDidSuspend() { 26359 if (workInProgressRootExitStatus === RootInProgress) { 26360 workInProgressRootExitStatus = RootSuspended; 26361 } 26362} 26363function renderDidSuspendDelayIfPossible() { 26364 if (workInProgressRootExitStatus === RootInProgress || workInProgressRootExitStatus === RootSuspended || workInProgressRootExitStatus === RootErrored) { 26365 workInProgressRootExitStatus = RootSuspendedWithDelay; 26366 } // Check if there are updates that we skipped tree that might have unblocked 26367 // this render. 26368 26369 26370 if (workInProgressRoot !== null && (includesNonIdleWork(workInProgressRootSkippedLanes) || includesNonIdleWork(workInProgressRootInterleavedUpdatedLanes))) { 26371 // Mark the current render as suspended so that we switch to working on 26372 // the updates that were skipped. Usually we only suspend at the end of 26373 // the render phase. 26374 // TODO: We should probably always mark the root as suspended immediately 26375 // (inside this function), since by suspending at the end of the render 26376 // phase introduces a potential mistake where we suspend lanes that were 26377 // pinged or updated while we were rendering. 26378 markRootSuspended$1(workInProgressRoot, workInProgressRootRenderLanes); 26379 } 26380} 26381function renderDidError(error) { 26382 if (workInProgressRootExitStatus !== RootSuspendedWithDelay) { 26383 workInProgressRootExitStatus = RootErrored; 26384 } 26385 26386 if (workInProgressRootConcurrentErrors === null) { 26387 workInProgressRootConcurrentErrors = [error]; 26388 } else { 26389 workInProgressRootConcurrentErrors.push(error); 26390 } 26391} // Called during render to determine if anything has suspended. 26392// Returns false if we're not sure. 26393 26394function renderHasNotSuspendedYet() { 26395 // If something errored or completed, we can't really be sure, 26396 // so those are false. 26397 return workInProgressRootExitStatus === RootInProgress; 26398} 26399 26400function renderRootSync(root, lanes) { 26401 var prevExecutionContext = executionContext; 26402 executionContext |= RenderContext; 26403 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack 26404 // and prepare a fresh one. Otherwise we'll continue where we left off. 26405 26406 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { 26407 { 26408 if (isDevToolsPresent) { 26409 var memoizedUpdaters = root.memoizedUpdaters; 26410 26411 if (memoizedUpdaters.size > 0) { 26412 restorePendingUpdaters(root, workInProgressRootRenderLanes); 26413 memoizedUpdaters.clear(); 26414 } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set. 26415 // If we bailout on this work, we'll move them back (like above). 26416 // It's important to move them now in case the work spawns more work at the same priority with different updaters. 26417 // That way we can keep the current update and future updates separate. 26418 26419 26420 movePendingFibersToMemoized(root, lanes); 26421 } 26422 } 26423 26424 workInProgressTransitions = getTransitionsForLanes(); 26425 prepareFreshStack(root, lanes); 26426 } 26427 26428 { 26429 markRenderStarted(lanes); 26430 } 26431 26432 do { 26433 try { 26434 workLoopSync(); 26435 break; 26436 } catch (thrownValue) { 26437 handleError(root, thrownValue); 26438 } 26439 } while (true); 26440 26441 resetContextDependencies(); 26442 executionContext = prevExecutionContext; 26443 popDispatcher(prevDispatcher); 26444 26445 if (workInProgress !== null) { 26446 // This is a sync render, so we should have finished the whole tree. 26447 throw new Error('Cannot commit an incomplete root. This error is likely caused by a ' + 'bug in React. Please file an issue.'); 26448 } 26449 26450 { 26451 markRenderStopped(); 26452 } // Set this to null to indicate there's no in-progress render. 26453 26454 26455 workInProgressRoot = null; 26456 workInProgressRootRenderLanes = NoLanes; 26457 return workInProgressRootExitStatus; 26458} // The work loop is an extremely hot path. Tell Closure not to inline it. 26459 26460/** @noinline */ 26461 26462 26463function workLoopSync() { 26464 // Already timed out, so perform work without checking if we need to yield. 26465 while (workInProgress !== null) { 26466 performUnitOfWork(workInProgress); 26467 } 26468} 26469 26470function renderRootConcurrent(root, lanes) { 26471 var prevExecutionContext = executionContext; 26472 executionContext |= RenderContext; 26473 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack 26474 // and prepare a fresh one. Otherwise we'll continue where we left off. 26475 26476 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { 26477 { 26478 if (isDevToolsPresent) { 26479 var memoizedUpdaters = root.memoizedUpdaters; 26480 26481 if (memoizedUpdaters.size > 0) { 26482 restorePendingUpdaters(root, workInProgressRootRenderLanes); 26483 memoizedUpdaters.clear(); 26484 } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set. 26485 // If we bailout on this work, we'll move them back (like above). 26486 // It's important to move them now in case the work spawns more work at the same priority with different updaters. 26487 // That way we can keep the current update and future updates separate. 26488 26489 26490 movePendingFibersToMemoized(root, lanes); 26491 } 26492 } 26493 26494 workInProgressTransitions = getTransitionsForLanes(); 26495 resetRenderTimer(); 26496 prepareFreshStack(root, lanes); 26497 } 26498 26499 { 26500 markRenderStarted(lanes); 26501 } 26502 26503 do { 26504 try { 26505 workLoopConcurrent(); 26506 break; 26507 } catch (thrownValue) { 26508 handleError(root, thrownValue); 26509 } 26510 } while (true); 26511 26512 resetContextDependencies(); 26513 popDispatcher(prevDispatcher); 26514 executionContext = prevExecutionContext; 26515 26516 26517 if (workInProgress !== null) { 26518 // Still work remaining. 26519 { 26520 markRenderYielded(); 26521 } 26522 26523 return RootInProgress; 26524 } else { 26525 // Completed the tree. 26526 { 26527 markRenderStopped(); 26528 } // Set this to null to indicate there's no in-progress render. 26529 26530 26531 workInProgressRoot = null; 26532 workInProgressRootRenderLanes = NoLanes; // Return the final exit status. 26533 26534 return workInProgressRootExitStatus; 26535 } 26536} 26537/** @noinline */ 26538 26539 26540function workLoopConcurrent() { 26541 // Perform work until Scheduler asks us to yield 26542 while (workInProgress !== null && !shouldYield()) { 26543 performUnitOfWork(workInProgress); 26544 } 26545} 26546 26547function performUnitOfWork(unitOfWork) { 26548 // The current, flushed, state of this fiber is the alternate. Ideally 26549 // nothing should rely on this, but relying on it here means that we don't 26550 // need an additional field on the work in progress. 26551 var current = unitOfWork.alternate; 26552 setCurrentFiber(unitOfWork); 26553 var next; 26554 26555 if ( (unitOfWork.mode & ProfileMode) !== NoMode) { 26556 startProfilerTimer(unitOfWork); 26557 next = beginWork$1(current, unitOfWork, subtreeRenderLanes); 26558 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); 26559 } else { 26560 next = beginWork$1(current, unitOfWork, subtreeRenderLanes); 26561 } 26562 26563 resetCurrentFiber(); 26564 unitOfWork.memoizedProps = unitOfWork.pendingProps; 26565 26566 if (next === null) { 26567 // If this doesn't spawn new work, complete the current work. 26568 completeUnitOfWork(unitOfWork); 26569 } else { 26570 workInProgress = next; 26571 } 26572 26573 ReactCurrentOwner$2.current = null; 26574} 26575 26576function completeUnitOfWork(unitOfWork) { 26577 // Attempt to complete the current unit of work, then move to the next 26578 // sibling. If there are no more siblings, return to the parent fiber. 26579 var completedWork = unitOfWork; 26580 26581 do { 26582 // The current, flushed, state of this fiber is the alternate. Ideally 26583 // nothing should rely on this, but relying on it here means that we don't 26584 // need an additional field on the work in progress. 26585 var current = completedWork.alternate; 26586 var returnFiber = completedWork.return; // Check if the work completed or if something threw. 26587 26588 if ((completedWork.flags & Incomplete) === NoFlags) { 26589 setCurrentFiber(completedWork); 26590 var next = void 0; 26591 26592 if ( (completedWork.mode & ProfileMode) === NoMode) { 26593 next = completeWork(current, completedWork, subtreeRenderLanes); 26594 } else { 26595 startProfilerTimer(completedWork); 26596 next = completeWork(current, completedWork, subtreeRenderLanes); // Update render duration assuming we didn't error. 26597 26598 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); 26599 } 26600 26601 resetCurrentFiber(); 26602 26603 if (next !== null) { 26604 // Completing this fiber spawned new work. Work on that next. 26605 workInProgress = next; 26606 return; 26607 } 26608 } else { 26609 // This fiber did not complete because something threw. Pop values off 26610 // the stack without entering the complete phase. If this is a boundary, 26611 // capture values if possible. 26612 var _next = unwindWork(current, completedWork); // Because this fiber did not complete, don't reset its lanes. 26613 26614 26615 if (_next !== null) { 26616 // If completing this work spawned new work, do that next. We'll come 26617 // back here again. 26618 // Since we're restarting, remove anything that is not a host effect 26619 // from the effect tag. 26620 _next.flags &= HostEffectMask; 26621 workInProgress = _next; 26622 return; 26623 } 26624 26625 if ( (completedWork.mode & ProfileMode) !== NoMode) { 26626 // Record the render duration for the fiber that errored. 26627 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); // Include the time spent working on failed children before continuing. 26628 26629 var actualDuration = completedWork.actualDuration; 26630 var child = completedWork.child; 26631 26632 while (child !== null) { 26633 actualDuration += child.actualDuration; 26634 child = child.sibling; 26635 } 26636 26637 completedWork.actualDuration = actualDuration; 26638 } 26639 26640 if (returnFiber !== null) { 26641 // Mark the parent fiber as incomplete and clear its subtree flags. 26642 returnFiber.flags |= Incomplete; 26643 returnFiber.subtreeFlags = NoFlags; 26644 returnFiber.deletions = null; 26645 } else { 26646 // We've unwound all the way to the root. 26647 workInProgressRootExitStatus = RootDidNotComplete; 26648 workInProgress = null; 26649 return; 26650 } 26651 } 26652 26653 var siblingFiber = completedWork.sibling; 26654 26655 if (siblingFiber !== null) { 26656 // If there is more work to do in this returnFiber, do that next. 26657 workInProgress = siblingFiber; 26658 return; 26659 } // Otherwise, return to the parent 26660 26661 26662 completedWork = returnFiber; // Update the next thing we're working on in case something throws. 26663 26664 workInProgress = completedWork; 26665 } while (completedWork !== null); // We've reached the root. 26666 26667 26668 if (workInProgressRootExitStatus === RootInProgress) { 26669 workInProgressRootExitStatus = RootCompleted; 26670 } 26671} 26672 26673function commitRoot(root, recoverableErrors, transitions) { 26674 // TODO: This no longer makes any sense. We already wrap the mutation and 26675 // layout phases. Should be able to remove. 26676 var previousUpdateLanePriority = getCurrentUpdatePriority(); 26677 var prevTransition = ReactCurrentBatchConfig$3.transition; 26678 26679 try { 26680 ReactCurrentBatchConfig$3.transition = null; 26681 setCurrentUpdatePriority(DiscreteEventPriority); 26682 commitRootImpl(root, recoverableErrors, transitions, previousUpdateLanePriority); 26683 } finally { 26684 ReactCurrentBatchConfig$3.transition = prevTransition; 26685 setCurrentUpdatePriority(previousUpdateLanePriority); 26686 } 26687 26688 return null; 26689} 26690 26691function commitRootImpl(root, recoverableErrors, transitions, renderPriorityLevel) { 26692 do { 26693 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which 26694 // means `flushPassiveEffects` will sometimes result in additional 26695 // passive effects. So we need to keep flushing in a loop until there are 26696 // no more pending effects. 26697 // TODO: Might be better if `flushPassiveEffects` did not automatically 26698 // flush synchronous work at the end, to avoid factoring hazards like this. 26699 flushPassiveEffects(); 26700 } while (rootWithPendingPassiveEffects !== null); 26701 26702 flushRenderPhaseStrictModeWarningsInDEV(); 26703 26704 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { 26705 throw new Error('Should not already be working.'); 26706 } 26707 26708 var finishedWork = root.finishedWork; 26709 var lanes = root.finishedLanes; 26710 26711 { 26712 markCommitStarted(lanes); 26713 } 26714 26715 if (finishedWork === null) { 26716 26717 { 26718 markCommitStopped(); 26719 } 26720 26721 return null; 26722 } else { 26723 { 26724 if (lanes === NoLanes) { 26725 error('root.finishedLanes should not be empty during a commit. This is a ' + 'bug in React.'); 26726 } 26727 } 26728 } 26729 26730 root.finishedWork = null; 26731 root.finishedLanes = NoLanes; 26732 26733 if (finishedWork === root.current) { 26734 throw new Error('Cannot commit the same tree as before. This error is likely caused by ' + 'a bug in React. Please file an issue.'); 26735 } // commitRoot never returns a continuation; it always finishes synchronously. 26736 // So we can clear these now to allow a new callback to be scheduled. 26737 26738 26739 root.callbackNode = null; 26740 root.callbackPriority = NoLane; // Update the first and last pending times on this root. The new first 26741 // pending time is whatever is left on the root fiber. 26742 26743 var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes); 26744 markRootFinished(root, remainingLanes); 26745 26746 if (root === workInProgressRoot) { 26747 // We can reset these now that they are finished. 26748 workInProgressRoot = null; 26749 workInProgress = null; 26750 workInProgressRootRenderLanes = NoLanes; 26751 } // If there are pending passive effects, schedule a callback to process them. 26752 // Do this as early as possible, so it is queued before anything else that 26753 // might get scheduled in the commit phase. (See #16714.) 26754 // TODO: Delete all other places that schedule the passive effect callback 26755 // They're redundant. 26756 26757 26758 if ((finishedWork.subtreeFlags & PassiveMask) !== NoFlags || (finishedWork.flags & PassiveMask) !== NoFlags) { 26759 if (!rootDoesHavePassiveEffects) { 26760 rootDoesHavePassiveEffects = true; 26761 // to store it in pendingPassiveTransitions until they get processed 26762 // We need to pass this through as an argument to commitRoot 26763 // because workInProgressTransitions might have changed between 26764 // the previous render and commit if we throttle the commit 26765 // with setTimeout 26766 26767 pendingPassiveTransitions = transitions; 26768 scheduleCallback$1(NormalPriority, function () { 26769 flushPassiveEffects(); // This render triggered passive effects: release the root cache pool 26770 // *after* passive effects fire to avoid freeing a cache pool that may 26771 // be referenced by a node in the tree (HostRoot, Cache boundary etc) 26772 26773 return null; 26774 }); 26775 } 26776 } // Check if there are any effects in the whole tree. 26777 // TODO: This is left over from the effect list implementation, where we had 26778 // to check for the existence of `firstEffect` to satisfy Flow. I think the 26779 // only other reason this optimization exists is because it affects profiling. 26780 // Reconsider whether this is necessary. 26781 26782 26783 var subtreeHasEffects = (finishedWork.subtreeFlags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags; 26784 var rootHasEffect = (finishedWork.flags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags; 26785 26786 if (subtreeHasEffects || rootHasEffect) { 26787 var prevTransition = ReactCurrentBatchConfig$3.transition; 26788 ReactCurrentBatchConfig$3.transition = null; 26789 var previousPriority = getCurrentUpdatePriority(); 26790 setCurrentUpdatePriority(DiscreteEventPriority); 26791 var prevExecutionContext = executionContext; 26792 executionContext |= CommitContext; // Reset this to null before calling lifecycles 26793 26794 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass 26795 // of the effect list for each phase: all mutation effects come before all 26796 // layout effects, and so on. 26797 // The first phase a "before mutation" phase. We use this phase to read the 26798 // state of the host tree right before we mutate it. This is where 26799 // getSnapshotBeforeUpdate is called. 26800 26801 var shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects(root, finishedWork); 26802 26803 { 26804 // Mark the current commit time to be shared by all Profilers in this 26805 // batch. This enables them to be grouped later. 26806 recordCommitTime(); 26807 } 26808 26809 26810 commitMutationEffects(root, finishedWork, lanes); 26811 26812 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after 26813 // the mutation phase, so that the previous tree is still current during 26814 // componentWillUnmount, but before the layout phase, so that the finished 26815 // work is current during componentDidMount/Update. 26816 26817 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read 26818 26819 { 26820 markLayoutEffectsStarted(lanes); 26821 } 26822 26823 commitLayoutEffects(finishedWork, root, lanes); 26824 26825 { 26826 markLayoutEffectsStopped(); 26827 } 26828 // opportunity to paint. 26829 26830 26831 requestPaint(); 26832 executionContext = prevExecutionContext; // Reset the priority to the previous non-sync value. 26833 26834 setCurrentUpdatePriority(previousPriority); 26835 ReactCurrentBatchConfig$3.transition = prevTransition; 26836 } else { 26837 // No effects. 26838 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were 26839 // no effects. 26840 // TODO: Maybe there's a better way to report this. 26841 26842 { 26843 recordCommitTime(); 26844 } 26845 } 26846 26847 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects; 26848 26849 if (rootDoesHavePassiveEffects) { 26850 // This commit has passive effects. Stash a reference to them. But don't 26851 // schedule a callback until after flushing layout work. 26852 rootDoesHavePassiveEffects = false; 26853 rootWithPendingPassiveEffects = root; 26854 pendingPassiveEffectsLanes = lanes; 26855 } else { 26856 26857 { 26858 nestedPassiveUpdateCount = 0; 26859 rootWithPassiveNestedUpdates = null; 26860 } 26861 } // Read this again, since an effect might have updated it 26862 26863 26864 remainingLanes = root.pendingLanes; // Check if there's remaining work on this root 26865 // TODO: This is part of the `componentDidCatch` implementation. Its purpose 26866 // is to detect whether something might have called setState inside 26867 // `componentDidCatch`. The mechanism is known to be flawed because `setState` 26868 // inside `componentDidCatch` is itself flawed — that's why we recommend 26869 // `getDerivedStateFromError` instead. However, it could be improved by 26870 // checking if remainingLanes includes Sync work, instead of whether there's 26871 // any work remaining at all (which would also include stuff like Suspense 26872 // retries or transitions). It's been like this for a while, though, so fixing 26873 // it probably isn't that urgent. 26874 26875 if (remainingLanes === NoLanes) { 26876 // If there's no remaining work, we can clear the set of already failed 26877 // error boundaries. 26878 legacyErrorBoundariesThatAlreadyFailed = null; 26879 } 26880 26881 { 26882 if (!rootDidHavePassiveEffects) { 26883 commitDoubleInvokeEffectsInDEV(root.current, false); 26884 } 26885 } 26886 26887 onCommitRoot(finishedWork.stateNode, renderPriorityLevel); 26888 26889 { 26890 if (isDevToolsPresent) { 26891 root.memoizedUpdaters.clear(); 26892 } 26893 } 26894 26895 { 26896 onCommitRoot$1(); 26897 } // Always call this before exiting `commitRoot`, to ensure that any 26898 // additional work on this root is scheduled. 26899 26900 26901 ensureRootIsScheduled(root, now()); 26902 26903 if (recoverableErrors !== null) { 26904 // There were errors during this render, but recovered from them without 26905 // needing to surface it to the UI. We log them here. 26906 var onRecoverableError = root.onRecoverableError; 26907 26908 for (var i = 0; i < recoverableErrors.length; i++) { 26909 var recoverableError = recoverableErrors[i]; 26910 var componentStack = recoverableError.stack; 26911 var digest = recoverableError.digest; 26912 onRecoverableError(recoverableError.value, { 26913 componentStack: componentStack, 26914 digest: digest 26915 }); 26916 } 26917 } 26918 26919 if (hasUncaughtError) { 26920 hasUncaughtError = false; 26921 var error$1 = firstUncaughtError; 26922 firstUncaughtError = null; 26923 throw error$1; 26924 } // If the passive effects are the result of a discrete render, flush them 26925 // synchronously at the end of the current task so that the result is 26926 // immediately observable. Otherwise, we assume that they are not 26927 // order-dependent and do not need to be observed by external systems, so we 26928 // can wait until after paint. 26929 // TODO: We can optimize this by not scheduling the callback earlier. Since we 26930 // currently schedule the callback in multiple places, will wait until those 26931 // are consolidated. 26932 26933 26934 if (includesSomeLane(pendingPassiveEffectsLanes, SyncLane) && root.tag !== LegacyRoot) { 26935 flushPassiveEffects(); 26936 } // Read this again, since a passive effect might have updated it 26937 26938 26939 remainingLanes = root.pendingLanes; 26940 26941 if (includesSomeLane(remainingLanes, SyncLane)) { 26942 { 26943 markNestedUpdateScheduled(); 26944 } // Count the number of times the root synchronously re-renders without 26945 // finishing. If there are too many, it indicates an infinite update loop. 26946 26947 26948 if (root === rootWithNestedUpdates) { 26949 nestedUpdateCount++; 26950 } else { 26951 nestedUpdateCount = 0; 26952 rootWithNestedUpdates = root; 26953 } 26954 } else { 26955 nestedUpdateCount = 0; 26956 } // If layout work was scheduled, flush it now. 26957 26958 26959 flushSyncCallbacks(); 26960 26961 { 26962 markCommitStopped(); 26963 } 26964 26965 return null; 26966} 26967 26968function flushPassiveEffects() { 26969 // Returns whether passive effects were flushed. 26970 // TODO: Combine this check with the one in flushPassiveEFfectsImpl. We should 26971 // probably just combine the two functions. I believe they were only separate 26972 // in the first place because we used to wrap it with 26973 // `Scheduler.runWithPriority`, which accepts a function. But now we track the 26974 // priority within React itself, so we can mutate the variable directly. 26975 if (rootWithPendingPassiveEffects !== null) { 26976 var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes); 26977 var priority = lowerEventPriority(DefaultEventPriority, renderPriority); 26978 var prevTransition = ReactCurrentBatchConfig$3.transition; 26979 var previousPriority = getCurrentUpdatePriority(); 26980 26981 try { 26982 ReactCurrentBatchConfig$3.transition = null; 26983 setCurrentUpdatePriority(priority); 26984 return flushPassiveEffectsImpl(); 26985 } finally { 26986 setCurrentUpdatePriority(previousPriority); 26987 ReactCurrentBatchConfig$3.transition = prevTransition; // Once passive effects have run for the tree - giving components a 26988 } 26989 } 26990 26991 return false; 26992} 26993function enqueuePendingPassiveProfilerEffect(fiber) { 26994 { 26995 pendingPassiveProfilerEffects.push(fiber); 26996 26997 if (!rootDoesHavePassiveEffects) { 26998 rootDoesHavePassiveEffects = true; 26999 scheduleCallback$1(NormalPriority, function () { 27000 flushPassiveEffects(); 27001 return null; 27002 }); 27003 } 27004 } 27005} 27006 27007function flushPassiveEffectsImpl() { 27008 if (rootWithPendingPassiveEffects === null) { 27009 return false; 27010 } // Cache and clear the transitions flag 27011 27012 27013 var transitions = pendingPassiveTransitions; 27014 pendingPassiveTransitions = null; 27015 var root = rootWithPendingPassiveEffects; 27016 var lanes = pendingPassiveEffectsLanes; 27017 rootWithPendingPassiveEffects = null; // TODO: This is sometimes out of sync with rootWithPendingPassiveEffects. 27018 // Figure out why and fix it. It's not causing any known issues (probably 27019 // because it's only used for profiling), but it's a refactor hazard. 27020 27021 pendingPassiveEffectsLanes = NoLanes; 27022 27023 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { 27024 throw new Error('Cannot flush passive effects while already rendering.'); 27025 } 27026 27027 { 27028 isFlushingPassiveEffects = true; 27029 didScheduleUpdateDuringPassiveEffects = false; 27030 } 27031 27032 { 27033 markPassiveEffectsStarted(lanes); 27034 } 27035 27036 var prevExecutionContext = executionContext; 27037 executionContext |= CommitContext; 27038 commitPassiveUnmountEffects(root.current); 27039 commitPassiveMountEffects(root, root.current, lanes, transitions); // TODO: Move to commitPassiveMountEffects 27040 27041 { 27042 var profilerEffects = pendingPassiveProfilerEffects; 27043 pendingPassiveProfilerEffects = []; 27044 27045 for (var i = 0; i < profilerEffects.length; i++) { 27046 var _fiber = profilerEffects[i]; 27047 commitPassiveEffectDurations(root, _fiber); 27048 } 27049 } 27050 27051 { 27052 markPassiveEffectsStopped(); 27053 } 27054 27055 { 27056 commitDoubleInvokeEffectsInDEV(root.current, true); 27057 } 27058 27059 executionContext = prevExecutionContext; 27060 flushSyncCallbacks(); 27061 27062 { 27063 // If additional passive effects were scheduled, increment a counter. If this 27064 // exceeds the limit, we'll fire a warning. 27065 if (didScheduleUpdateDuringPassiveEffects) { 27066 if (root === rootWithPassiveNestedUpdates) { 27067 nestedPassiveUpdateCount++; 27068 } else { 27069 nestedPassiveUpdateCount = 0; 27070 rootWithPassiveNestedUpdates = root; 27071 } 27072 } else { 27073 nestedPassiveUpdateCount = 0; 27074 } 27075 27076 isFlushingPassiveEffects = false; 27077 didScheduleUpdateDuringPassiveEffects = false; 27078 } // TODO: Move to commitPassiveMountEffects 27079 27080 27081 onPostCommitRoot(root); 27082 27083 { 27084 var stateNode = root.current.stateNode; 27085 stateNode.effectDuration = 0; 27086 stateNode.passiveEffectDuration = 0; 27087 } 27088 27089 return true; 27090} 27091 27092function isAlreadyFailedLegacyErrorBoundary(instance) { 27093 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance); 27094} 27095function markLegacyErrorBoundaryAsFailed(instance) { 27096 if (legacyErrorBoundariesThatAlreadyFailed === null) { 27097 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]); 27098 } else { 27099 legacyErrorBoundariesThatAlreadyFailed.add(instance); 27100 } 27101} 27102 27103function prepareToThrowUncaughtError(error) { 27104 if (!hasUncaughtError) { 27105 hasUncaughtError = true; 27106 firstUncaughtError = error; 27107 } 27108} 27109 27110var onUncaughtError = prepareToThrowUncaughtError; 27111 27112function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { 27113 var errorInfo = createCapturedValueAtFiber(error, sourceFiber); 27114 var update = createRootErrorUpdate(rootFiber, errorInfo, SyncLane); 27115 var root = enqueueUpdate(rootFiber, update, SyncLane); 27116 var eventTime = requestEventTime(); 27117 27118 if (root !== null) { 27119 markRootUpdated(root, SyncLane, eventTime); 27120 ensureRootIsScheduled(root, eventTime); 27121 } 27122} 27123 27124function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { 27125 { 27126 reportUncaughtErrorInDEV(error$1); 27127 setIsRunningInsertionEffect(false); 27128 } 27129 27130 if (sourceFiber.tag === HostRoot) { 27131 // Error was thrown at the root. There is no parent, so the root 27132 // itself should capture it. 27133 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1); 27134 return; 27135 } 27136 27137 var fiber = null; 27138 27139 { 27140 fiber = nearestMountedAncestor; 27141 } 27142 27143 while (fiber !== null) { 27144 if (fiber.tag === HostRoot) { 27145 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1); 27146 return; 27147 } else if (fiber.tag === ClassComponent) { 27148 var ctor = fiber.type; 27149 var instance = fiber.stateNode; 27150 27151 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) { 27152 var errorInfo = createCapturedValueAtFiber(error$1, sourceFiber); 27153 var update = createClassErrorUpdate(fiber, errorInfo, SyncLane); 27154 var root = enqueueUpdate(fiber, update, SyncLane); 27155 var eventTime = requestEventTime(); 27156 27157 if (root !== null) { 27158 markRootUpdated(root, SyncLane, eventTime); 27159 ensureRootIsScheduled(root, eventTime); 27160 } 27161 27162 return; 27163 } 27164 } 27165 27166 fiber = fiber.return; 27167 } 27168 27169 { 27170 // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning 27171 // will fire for errors that are thrown by destroy functions inside deleted 27172 // trees. What it should instead do is propagate the error to the parent of 27173 // the deleted tree. In the meantime, do not add this warning to the 27174 // allowlist; this is only for our internal use. 27175 error('Internal React error: Attempted to capture a commit phase error ' + 'inside a detached tree. This indicates a bug in React. Likely ' + 'causes include deleting the same fiber more than once, committing an ' + 'already-finished tree, or an inconsistent return pointer.\n\n' + 'Error message:\n\n%s', error$1); 27176 } 27177} 27178function pingSuspendedRoot(root, wakeable, pingedLanes) { 27179 var pingCache = root.pingCache; 27180 27181 if (pingCache !== null) { 27182 // The wakeable resolved, so we no longer need to memoize, because it will 27183 // never be thrown again. 27184 pingCache.delete(wakeable); 27185 } 27186 27187 var eventTime = requestEventTime(); 27188 markRootPinged(root, pingedLanes); 27189 warnIfSuspenseResolutionNotWrappedWithActDEV(root); 27190 27191 if (workInProgressRoot === root && isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes)) { 27192 // Received a ping at the same priority level at which we're currently 27193 // rendering. We might want to restart this render. This should mirror 27194 // the logic of whether or not a root suspends once it completes. 27195 // TODO: If we're rendering sync either due to Sync, Batched or expired, 27196 // we should probably never restart. 27197 // If we're suspended with delay, or if it's a retry, we'll always suspend 27198 // so we can always restart. 27199 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && includesOnlyRetries(workInProgressRootRenderLanes) && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) { 27200 // Restart from the root. 27201 prepareFreshStack(root, NoLanes); 27202 } else { 27203 // Even though we can't restart right now, we might get an 27204 // opportunity later. So we mark this render as having a ping. 27205 workInProgressRootPingedLanes = mergeLanes(workInProgressRootPingedLanes, pingedLanes); 27206 } 27207 } 27208 27209 ensureRootIsScheduled(root, eventTime); 27210} 27211 27212function retryTimedOutBoundary(boundaryFiber, retryLane) { 27213 // The boundary fiber (a Suspense component or SuspenseList component) 27214 // previously was rendered in its fallback state. One of the promises that 27215 // suspended it has resolved, which means at least part of the tree was 27216 // likely unblocked. Try rendering again, at a new lanes. 27217 if (retryLane === NoLane) { 27218 // TODO: Assign this to `suspenseState.retryLane`? to avoid 27219 // unnecessary entanglement? 27220 retryLane = requestRetryLane(boundaryFiber); 27221 } // TODO: Special case idle priority? 27222 27223 27224 var eventTime = requestEventTime(); 27225 var root = enqueueConcurrentRenderForLane(boundaryFiber, retryLane); 27226 27227 if (root !== null) { 27228 markRootUpdated(root, retryLane, eventTime); 27229 ensureRootIsScheduled(root, eventTime); 27230 } 27231} 27232 27233function retryDehydratedSuspenseBoundary(boundaryFiber) { 27234 var suspenseState = boundaryFiber.memoizedState; 27235 var retryLane = NoLane; 27236 27237 if (suspenseState !== null) { 27238 retryLane = suspenseState.retryLane; 27239 } 27240 27241 retryTimedOutBoundary(boundaryFiber, retryLane); 27242} 27243function resolveRetryWakeable(boundaryFiber, wakeable) { 27244 var retryLane = NoLane; // Default 27245 27246 var retryCache; 27247 27248 switch (boundaryFiber.tag) { 27249 case SuspenseComponent: 27250 retryCache = boundaryFiber.stateNode; 27251 var suspenseState = boundaryFiber.memoizedState; 27252 27253 if (suspenseState !== null) { 27254 retryLane = suspenseState.retryLane; 27255 } 27256 27257 break; 27258 27259 case SuspenseListComponent: 27260 retryCache = boundaryFiber.stateNode; 27261 break; 27262 27263 default: 27264 throw new Error('Pinged unknown suspense boundary type. ' + 'This is probably a bug in React.'); 27265 } 27266 27267 if (retryCache !== null) { 27268 // The wakeable resolved, so we no longer need to memoize, because it will 27269 // never be thrown again. 27270 retryCache.delete(wakeable); 27271 } 27272 27273 retryTimedOutBoundary(boundaryFiber, retryLane); 27274} // Computes the next Just Noticeable Difference (JND) boundary. 27275// The theory is that a person can't tell the difference between small differences in time. 27276// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable 27277// difference in the experience. However, waiting for longer might mean that we can avoid 27278// showing an intermediate loading state. The longer we have already waited, the harder it 27279// is to tell small differences in time. Therefore, the longer we've already waited, 27280// the longer we can wait additionally. At some point we have to give up though. 27281// We pick a train model where the next boundary commits at a consistent schedule. 27282// These particular numbers are vague estimates. We expect to adjust them based on research. 27283 27284function jnd(timeElapsed) { 27285 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960; 27286} 27287 27288function checkForNestedUpdates() { 27289 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) { 27290 nestedUpdateCount = 0; 27291 rootWithNestedUpdates = null; 27292 throw new Error('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.'); 27293 } 27294 27295 { 27296 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { 27297 nestedPassiveUpdateCount = 0; 27298 rootWithPassiveNestedUpdates = null; 27299 27300 error('Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + 'have a dependency array, or one of the dependencies changes on ' + 'every render.'); 27301 } 27302 } 27303} 27304 27305function flushRenderPhaseStrictModeWarningsInDEV() { 27306 { 27307 ReactStrictModeWarnings.flushLegacyContextWarning(); 27308 27309 { 27310 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); 27311 } 27312 } 27313} 27314 27315function commitDoubleInvokeEffectsInDEV(fiber, hasPassiveEffects) { 27316 { 27317 // TODO (StrictEffects) Should we set a marker on the root if it contains strict effects 27318 // so we don't traverse unnecessarily? similar to subtreeFlags but just at the root level. 27319 // Maybe not a big deal since this is DEV only behavior. 27320 setCurrentFiber(fiber); 27321 invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectUnmountInDEV); 27322 27323 if (hasPassiveEffects) { 27324 invokeEffectsInDev(fiber, MountPassiveDev, invokePassiveEffectUnmountInDEV); 27325 } 27326 27327 invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectMountInDEV); 27328 27329 if (hasPassiveEffects) { 27330 invokeEffectsInDev(fiber, MountPassiveDev, invokePassiveEffectMountInDEV); 27331 } 27332 27333 resetCurrentFiber(); 27334 } 27335} 27336 27337function invokeEffectsInDev(firstChild, fiberFlags, invokeEffectFn) { 27338 { 27339 // We don't need to re-check StrictEffectsMode here. 27340 // This function is only called if that check has already passed. 27341 var current = firstChild; 27342 var subtreeRoot = null; 27343 27344 while (current !== null) { 27345 var primarySubtreeFlag = current.subtreeFlags & fiberFlags; 27346 27347 if (current !== subtreeRoot && current.child !== null && primarySubtreeFlag !== NoFlags) { 27348 current = current.child; 27349 } else { 27350 if ((current.flags & fiberFlags) !== NoFlags) { 27351 invokeEffectFn(current); 27352 } 27353 27354 if (current.sibling !== null) { 27355 current = current.sibling; 27356 } else { 27357 current = subtreeRoot = current.return; 27358 } 27359 } 27360 } 27361 } 27362} 27363 27364var didWarnStateUpdateForNotYetMountedComponent = null; 27365function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) { 27366 { 27367 if ((executionContext & RenderContext) !== NoContext) { 27368 // We let the other warning about render phase updates deal with this one. 27369 return; 27370 } 27371 27372 if (!(fiber.mode & ConcurrentMode)) { 27373 return; 27374 } 27375 27376 var tag = fiber.tag; 27377 27378 if (tag !== IndeterminateComponent && tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) { 27379 // Only warn for user-defined components, not internal ones like Suspense. 27380 return; 27381 } // We show the whole stack but dedupe on the top component's name because 27382 // the problematic code almost always lies inside that component. 27383 27384 27385 var componentName = getComponentNameFromFiber(fiber) || 'ReactComponent'; 27386 27387 if (didWarnStateUpdateForNotYetMountedComponent !== null) { 27388 if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) { 27389 return; 27390 } 27391 27392 didWarnStateUpdateForNotYetMountedComponent.add(componentName); 27393 } else { 27394 didWarnStateUpdateForNotYetMountedComponent = new Set([componentName]); 27395 } 27396 27397 var previousFiber = current; 27398 27399 try { 27400 setCurrentFiber(fiber); 27401 27402 error("Can't perform a React state update on a component that hasn't mounted yet. " + 'This indicates that you have a side-effect in your render function that ' + 'asynchronously later calls tries to update the component. Move this work to ' + 'useEffect instead.'); 27403 } finally { 27404 if (previousFiber) { 27405 setCurrentFiber(fiber); 27406 } else { 27407 resetCurrentFiber(); 27408 } 27409 } 27410 } 27411} 27412var beginWork$1; 27413 27414{ 27415 var dummyFiber = null; 27416 27417 beginWork$1 = function (current, unitOfWork, lanes) { 27418 // If a component throws an error, we replay it again in a synchronously 27419 // dispatched event, so that the debugger will treat it as an uncaught 27420 // error See ReactErrorUtils for more information. 27421 // Before entering the begin phase, copy the work-in-progress onto a dummy 27422 // fiber. If beginWork throws, we'll use this to reset the state. 27423 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork); 27424 27425 try { 27426 return beginWork(current, unitOfWork, lanes); 27427 } catch (originalError) { 27428 if (didSuspendOrErrorWhileHydratingDEV() || originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') { 27429 // Don't replay promises. 27430 // Don't replay errors if we are hydrating and have already suspended or handled an error 27431 throw originalError; 27432 } // Keep this code in sync with handleError; any changes here must have 27433 // corresponding changes there. 27434 27435 27436 resetContextDependencies(); 27437 resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the 27438 // same fiber again. 27439 // Unwind the failed stack frame 27440 27441 unwindInterruptedWork(current, unitOfWork); // Restore the original properties of the fiber. 27442 27443 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy); 27444 27445 if ( unitOfWork.mode & ProfileMode) { 27446 // Reset the profiler timer. 27447 startProfilerTimer(unitOfWork); 27448 } // Run beginWork again. 27449 27450 27451 invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes); 27452 27453 if (hasCaughtError()) { 27454 var replayError = clearCaughtError(); 27455 27456 if (typeof replayError === 'object' && replayError !== null && replayError._suppressLogging && typeof originalError === 'object' && originalError !== null && !originalError._suppressLogging) { 27457 // If suppressed, let the flag carry over to the original error which is the one we'll rethrow. 27458 originalError._suppressLogging = true; 27459 } 27460 } // We always throw the original error in case the second render pass is not idempotent. 27461 // This can happen if a memoized function or CommonJS module doesn't throw after first invocation. 27462 27463 27464 throw originalError; 27465 } 27466 }; 27467} 27468 27469var didWarnAboutUpdateInRender = false; 27470var didWarnAboutUpdateInRenderForAnotherComponent; 27471 27472{ 27473 didWarnAboutUpdateInRenderForAnotherComponent = new Set(); 27474} 27475 27476function warnAboutRenderPhaseUpdatesInDEV(fiber) { 27477 { 27478 if (isRendering && !getIsUpdatingOpaqueValueInRenderPhaseInDEV()) { 27479 switch (fiber.tag) { 27480 case FunctionComponent: 27481 case ForwardRef: 27482 case SimpleMemoComponent: 27483 { 27484 var renderingComponentName = workInProgress && getComponentNameFromFiber(workInProgress) || 'Unknown'; // Dedupe by the rendering component because it's the one that needs to be fixed. 27485 27486 var dedupeKey = renderingComponentName; 27487 27488 if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) { 27489 didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey); 27490 var setStateComponentName = getComponentNameFromFiber(fiber) || 'Unknown'; 27491 27492 error('Cannot update a component (`%s`) while rendering a ' + 'different component (`%s`). To locate the bad setState() call inside `%s`, ' + 'follow the stack trace as described in https://reactjs.org/link/setstate-in-render', setStateComponentName, renderingComponentName, renderingComponentName); 27493 } 27494 27495 break; 27496 } 27497 27498 case ClassComponent: 27499 { 27500 if (!didWarnAboutUpdateInRender) { 27501 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.'); 27502 27503 didWarnAboutUpdateInRender = true; 27504 } 27505 27506 break; 27507 } 27508 } 27509 } 27510 } 27511} 27512 27513function restorePendingUpdaters(root, lanes) { 27514 { 27515 if (isDevToolsPresent) { 27516 var memoizedUpdaters = root.memoizedUpdaters; 27517 memoizedUpdaters.forEach(function (schedulingFiber) { 27518 addFiberToLanesMap(root, schedulingFiber, lanes); 27519 }); // This function intentionally does not clear memoized updaters. 27520 // Those may still be relevant to the current commit 27521 // and a future one (e.g. Suspense). 27522 } 27523 } 27524} 27525var fakeActCallbackNode = {}; 27526 27527function scheduleCallback$1(priorityLevel, callback) { 27528 { 27529 // If we're currently inside an `act` scope, bypass Scheduler and push to 27530 // the `act` queue instead. 27531 var actQueue = ReactCurrentActQueue$1.current; 27532 27533 if (actQueue !== null) { 27534 actQueue.push(callback); 27535 return fakeActCallbackNode; 27536 } else { 27537 return scheduleCallback(priorityLevel, callback); 27538 } 27539 } 27540} 27541 27542function cancelCallback$1(callbackNode) { 27543 if ( callbackNode === fakeActCallbackNode) { 27544 return; 27545 } // In production, always call Scheduler. This function will be stripped out. 27546 27547 27548 return cancelCallback(callbackNode); 27549} 27550 27551function shouldForceFlushFallbacksInDEV() { 27552 // Never force flush in production. This function should get stripped out. 27553 return ReactCurrentActQueue$1.current !== null; 27554} 27555 27556function warnIfUpdatesNotWrappedWithActDEV(fiber) { 27557 { 27558 if (fiber.mode & ConcurrentMode) { 27559 if (!isConcurrentActEnvironment()) { 27560 // Not in an act environment. No need to warn. 27561 return; 27562 } 27563 } else { 27564 // Legacy mode has additional cases where we suppress a warning. 27565 if (!isLegacyActEnvironment()) { 27566 // Not in an act environment. No need to warn. 27567 return; 27568 } 27569 27570 if (executionContext !== NoContext) { 27571 // Legacy mode doesn't warn if the update is batched, i.e. 27572 // batchedUpdates or flushSync. 27573 return; 27574 } 27575 27576 if (fiber.tag !== FunctionComponent && fiber.tag !== ForwardRef && fiber.tag !== SimpleMemoComponent) { 27577 // For backwards compatibility with pre-hooks code, legacy mode only 27578 // warns for updates that originate from a hook. 27579 return; 27580 } 27581 } 27582 27583 if (ReactCurrentActQueue$1.current === null) { 27584 var previousFiber = current; 27585 27586 try { 27587 setCurrentFiber(fiber); 27588 27589 error('An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://reactjs.org/link/wrap-tests-with-act', getComponentNameFromFiber(fiber)); 27590 } finally { 27591 if (previousFiber) { 27592 setCurrentFiber(fiber); 27593 } else { 27594 resetCurrentFiber(); 27595 } 27596 } 27597 } 27598 } 27599} 27600 27601function warnIfSuspenseResolutionNotWrappedWithActDEV(root) { 27602 { 27603 if (root.tag !== LegacyRoot && isConcurrentActEnvironment() && ReactCurrentActQueue$1.current === null) { 27604 error('A suspended resource finished loading inside a test, but the event ' + 'was not wrapped in act(...).\n\n' + 'When testing, code that resolves suspended data should be wrapped ' + 'into act(...):\n\n' + 'act(() => {\n' + ' /* finish loading suspended data */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://reactjs.org/link/wrap-tests-with-act'); 27605 } 27606 } 27607} 27608 27609function setIsRunningInsertionEffect(isRunning) { 27610 { 27611 isRunningInsertionEffect = isRunning; 27612 } 27613} 27614 27615/* eslint-disable react-internal/prod-error-codes */ 27616var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below. 27617 27618var failedBoundaries = null; 27619var setRefreshHandler = function (handler) { 27620 { 27621 resolveFamily = handler; 27622 } 27623}; 27624function resolveFunctionForHotReloading(type) { 27625 { 27626 if (resolveFamily === null) { 27627 // Hot reloading is disabled. 27628 return type; 27629 } 27630 27631 var family = resolveFamily(type); 27632 27633 if (family === undefined) { 27634 return type; 27635 } // Use the latest known implementation. 27636 27637 27638 return family.current; 27639 } 27640} 27641function resolveClassForHotReloading(type) { 27642 // No implementation differences. 27643 return resolveFunctionForHotReloading(type); 27644} 27645function resolveForwardRefForHotReloading(type) { 27646 { 27647 if (resolveFamily === null) { 27648 // Hot reloading is disabled. 27649 return type; 27650 } 27651 27652 var family = resolveFamily(type); 27653 27654 if (family === undefined) { 27655 // Check if we're dealing with a real forwardRef. Don't want to crash early. 27656 if (type !== null && type !== undefined && typeof type.render === 'function') { 27657 // ForwardRef is special because its resolved .type is an object, 27658 // but it's possible that we only have its inner render function in the map. 27659 // If that inner render function is different, we'll build a new forwardRef type. 27660 var currentRender = resolveFunctionForHotReloading(type.render); 27661 27662 if (type.render !== currentRender) { 27663 var syntheticType = { 27664 $$typeof: REACT_FORWARD_REF_TYPE, 27665 render: currentRender 27666 }; 27667 27668 if (type.displayName !== undefined) { 27669 syntheticType.displayName = type.displayName; 27670 } 27671 27672 return syntheticType; 27673 } 27674 } 27675 27676 return type; 27677 } // Use the latest known implementation. 27678 27679 27680 return family.current; 27681 } 27682} 27683function isCompatibleFamilyForHotReloading(fiber, element) { 27684 { 27685 if (resolveFamily === null) { 27686 // Hot reloading is disabled. 27687 return false; 27688 } 27689 27690 var prevType = fiber.elementType; 27691 var nextType = element.type; // If we got here, we know types aren't === equal. 27692 27693 var needsCompareFamilies = false; 27694 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null; 27695 27696 switch (fiber.tag) { 27697 case ClassComponent: 27698 { 27699 if (typeof nextType === 'function') { 27700 needsCompareFamilies = true; 27701 } 27702 27703 break; 27704 } 27705 27706 case FunctionComponent: 27707 { 27708 if (typeof nextType === 'function') { 27709 needsCompareFamilies = true; 27710 } else if ($$typeofNextType === REACT_LAZY_TYPE) { 27711 // We don't know the inner type yet. 27712 // We're going to assume that the lazy inner type is stable, 27713 // and so it is sufficient to avoid reconciling it away. 27714 // We're not going to unwrap or actually use the new lazy type. 27715 needsCompareFamilies = true; 27716 } 27717 27718 break; 27719 } 27720 27721 case ForwardRef: 27722 { 27723 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) { 27724 needsCompareFamilies = true; 27725 } else if ($$typeofNextType === REACT_LAZY_TYPE) { 27726 needsCompareFamilies = true; 27727 } 27728 27729 break; 27730 } 27731 27732 case MemoComponent: 27733 case SimpleMemoComponent: 27734 { 27735 if ($$typeofNextType === REACT_MEMO_TYPE) { 27736 // TODO: if it was but can no longer be simple, 27737 // we shouldn't set this. 27738 needsCompareFamilies = true; 27739 } else if ($$typeofNextType === REACT_LAZY_TYPE) { 27740 needsCompareFamilies = true; 27741 } 27742 27743 break; 27744 } 27745 27746 default: 27747 return false; 27748 } // Check if both types have a family and it's the same one. 27749 27750 27751 if (needsCompareFamilies) { 27752 // Note: memo() and forwardRef() we'll compare outer rather than inner type. 27753 // This means both of them need to be registered to preserve state. 27754 // If we unwrapped and compared the inner types for wrappers instead, 27755 // then we would risk falsely saying two separate memo(Foo) 27756 // calls are equivalent because they wrap the same Foo function. 27757 var prevFamily = resolveFamily(prevType); 27758 27759 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) { 27760 return true; 27761 } 27762 } 27763 27764 return false; 27765 } 27766} 27767function markFailedErrorBoundaryForHotReloading(fiber) { 27768 { 27769 if (resolveFamily === null) { 27770 // Hot reloading is disabled. 27771 return; 27772 } 27773 27774 if (typeof WeakSet !== 'function') { 27775 return; 27776 } 27777 27778 if (failedBoundaries === null) { 27779 failedBoundaries = new WeakSet(); 27780 } 27781 27782 failedBoundaries.add(fiber); 27783 } 27784} 27785var scheduleRefresh = function (root, update) { 27786 { 27787 if (resolveFamily === null) { 27788 // Hot reloading is disabled. 27789 return; 27790 } 27791 27792 var staleFamilies = update.staleFamilies, 27793 updatedFamilies = update.updatedFamilies; 27794 flushPassiveEffects(); 27795 flushSync(function () { 27796 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies); 27797 }); 27798 } 27799}; 27800var scheduleRoot = function (root, element) { 27801 { 27802 if (root.context !== emptyContextObject) { 27803 // Super edge case: root has a legacy _renderSubtree context 27804 // but we don't know the parentComponent so we can't pass it. 27805 // Just ignore. We'll delete this with _renderSubtree code path later. 27806 return; 27807 } 27808 27809 flushPassiveEffects(); 27810 flushSync(function () { 27811 updateContainer(element, root, null, null); 27812 }); 27813 } 27814}; 27815 27816function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) { 27817 { 27818 var alternate = fiber.alternate, 27819 child = fiber.child, 27820 sibling = fiber.sibling, 27821 tag = fiber.tag, 27822 type = fiber.type; 27823 var candidateType = null; 27824 27825 switch (tag) { 27826 case FunctionComponent: 27827 case SimpleMemoComponent: 27828 case ClassComponent: 27829 candidateType = type; 27830 break; 27831 27832 case ForwardRef: 27833 candidateType = type.render; 27834 break; 27835 } 27836 27837 if (resolveFamily === null) { 27838 throw new Error('Expected resolveFamily to be set during hot reload.'); 27839 } 27840 27841 var needsRender = false; 27842 var needsRemount = false; 27843 27844 if (candidateType !== null) { 27845 var family = resolveFamily(candidateType); 27846 27847 if (family !== undefined) { 27848 if (staleFamilies.has(family)) { 27849 needsRemount = true; 27850 } else if (updatedFamilies.has(family)) { 27851 if (tag === ClassComponent) { 27852 needsRemount = true; 27853 } else { 27854 needsRender = true; 27855 } 27856 } 27857 } 27858 } 27859 27860 if (failedBoundaries !== null) { 27861 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) { 27862 needsRemount = true; 27863 } 27864 } 27865 27866 if (needsRemount) { 27867 fiber._debugNeedsRemount = true; 27868 } 27869 27870 if (needsRemount || needsRender) { 27871 var _root = enqueueConcurrentRenderForLane(fiber, SyncLane); 27872 27873 if (_root !== null) { 27874 scheduleUpdateOnFiber(_root, fiber, SyncLane, NoTimestamp); 27875 } 27876 } 27877 27878 if (child !== null && !needsRemount) { 27879 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies); 27880 } 27881 27882 if (sibling !== null) { 27883 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies); 27884 } 27885 } 27886} 27887 27888var findHostInstancesForRefresh = function (root, families) { 27889 { 27890 var hostInstances = new Set(); 27891 var types = new Set(families.map(function (family) { 27892 return family.current; 27893 })); 27894 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances); 27895 return hostInstances; 27896 } 27897}; 27898 27899function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) { 27900 { 27901 var child = fiber.child, 27902 sibling = fiber.sibling, 27903 tag = fiber.tag, 27904 type = fiber.type; 27905 var candidateType = null; 27906 27907 switch (tag) { 27908 case FunctionComponent: 27909 case SimpleMemoComponent: 27910 case ClassComponent: 27911 candidateType = type; 27912 break; 27913 27914 case ForwardRef: 27915 candidateType = type.render; 27916 break; 27917 } 27918 27919 var didMatch = false; 27920 27921 if (candidateType !== null) { 27922 if (types.has(candidateType)) { 27923 didMatch = true; 27924 } 27925 } 27926 27927 if (didMatch) { 27928 // We have a match. This only drills down to the closest host components. 27929 // There's no need to search deeper because for the purpose of giving 27930 // visual feedback, "flashing" outermost parent rectangles is sufficient. 27931 findHostInstancesForFiberShallowly(fiber, hostInstances); 27932 } else { 27933 // If there's no match, maybe there will be one further down in the child tree. 27934 if (child !== null) { 27935 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances); 27936 } 27937 } 27938 27939 if (sibling !== null) { 27940 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances); 27941 } 27942 } 27943} 27944 27945function findHostInstancesForFiberShallowly(fiber, hostInstances) { 27946 { 27947 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances); 27948 27949 if (foundHostInstances) { 27950 return; 27951 } // If we didn't find any host children, fallback to closest host parent. 27952 27953 27954 var node = fiber; 27955 27956 while (true) { 27957 switch (node.tag) { 27958 case HostComponent: 27959 hostInstances.add(node.stateNode); 27960 return; 27961 27962 case HostPortal: 27963 hostInstances.add(node.stateNode.containerInfo); 27964 return; 27965 27966 case HostRoot: 27967 hostInstances.add(node.stateNode.containerInfo); 27968 return; 27969 } 27970 27971 if (node.return === null) { 27972 throw new Error('Expected to reach root first.'); 27973 } 27974 27975 node = node.return; 27976 } 27977 } 27978} 27979 27980function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { 27981 { 27982 var node = fiber; 27983 var foundHostInstances = false; 27984 27985 while (true) { 27986 if (node.tag === HostComponent) { 27987 // We got a match. 27988 foundHostInstances = true; 27989 hostInstances.add(node.stateNode); // There may still be more, so keep searching. 27990 } else if (node.child !== null) { 27991 node.child.return = node; 27992 node = node.child; 27993 continue; 27994 } 27995 27996 if (node === fiber) { 27997 return foundHostInstances; 27998 } 27999 28000 while (node.sibling === null) { 28001 if (node.return === null || node.return === fiber) { 28002 return foundHostInstances; 28003 } 28004 28005 node = node.return; 28006 } 28007 28008 node.sibling.return = node.return; 28009 node = node.sibling; 28010 } 28011 } 28012 28013 return false; 28014} 28015 28016var hasBadMapPolyfill; 28017 28018{ 28019 hasBadMapPolyfill = false; 28020 28021 try { 28022 var nonExtensibleObject = Object.preventExtensions({}); 28023 /* eslint-disable no-new */ 28024 28025 new Map([[nonExtensibleObject, null]]); 28026 new Set([nonExtensibleObject]); 28027 /* eslint-enable no-new */ 28028 } catch (e) { 28029 // TODO: Consider warning about bad polyfills 28030 hasBadMapPolyfill = true; 28031 } 28032} 28033 28034function FiberNode(tag, pendingProps, key, mode) { 28035 // Instance 28036 this.tag = tag; 28037 this.key = key; 28038 this.elementType = null; 28039 this.type = null; 28040 this.stateNode = null; // Fiber 28041 28042 this.return = null; 28043 this.child = null; 28044 this.sibling = null; 28045 this.index = 0; 28046 this.ref = null; 28047 this.pendingProps = pendingProps; 28048 this.memoizedProps = null; 28049 this.updateQueue = null; 28050 this.memoizedState = null; 28051 this.dependencies = null; 28052 this.mode = mode; // Effects 28053 28054 this.flags = NoFlags; 28055 this.subtreeFlags = NoFlags; 28056 this.deletions = null; 28057 this.lanes = NoLanes; 28058 this.childLanes = NoLanes; 28059 this.alternate = null; 28060 28061 { 28062 // Note: The following is done to avoid a v8 performance cliff. 28063 // 28064 // Initializing the fields below to smis and later updating them with 28065 // double values will cause Fibers to end up having separate shapes. 28066 // This behavior/bug has something to do with Object.preventExtension(). 28067 // Fortunately this only impacts DEV builds. 28068 // Unfortunately it makes React unusably slow for some applications. 28069 // To work around this, initialize the fields below with doubles. 28070 // 28071 // Learn more about this here: 28072 // https://github.com/facebook/react/issues/14365 28073 // https://bugs.chromium.org/p/v8/issues/detail?id=8538 28074 this.actualDuration = Number.NaN; 28075 this.actualStartTime = Number.NaN; 28076 this.selfBaseDuration = Number.NaN; 28077 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization. 28078 // This won't trigger the performance cliff mentioned above, 28079 // and it simplifies other profiler code (including DevTools). 28080 28081 this.actualDuration = 0; 28082 this.actualStartTime = -1; 28083 this.selfBaseDuration = 0; 28084 this.treeBaseDuration = 0; 28085 } 28086 28087 { 28088 // This isn't directly used but is handy for debugging internals: 28089 this._debugSource = null; 28090 this._debugOwner = null; 28091 this._debugNeedsRemount = false; 28092 this._debugHookTypes = null; 28093 28094 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') { 28095 Object.preventExtensions(this); 28096 } 28097 } 28098} // This is a constructor function, rather than a POJO constructor, still 28099// please ensure we do the following: 28100// 1) Nobody should add any instance methods on this. Instance methods can be 28101// more difficult to predict when they get optimized and they are almost 28102// never inlined properly in static compilers. 28103// 2) Nobody should rely on `instanceof Fiber` for type testing. We should 28104// always know when it is a fiber. 28105// 3) We might want to experiment with using numeric keys since they are easier 28106// to optimize in a non-JIT environment. 28107// 4) We can easily go from a constructor to a createFiber object literal if that 28108// is faster. 28109// 5) It should be easy to port this to a C struct and keep a C implementation 28110// compatible. 28111 28112 28113var createFiber = function (tag, pendingProps, key, mode) { 28114 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors 28115 return new FiberNode(tag, pendingProps, key, mode); 28116}; 28117 28118function shouldConstruct$1(Component) { 28119 var prototype = Component.prototype; 28120 return !!(prototype && prototype.isReactComponent); 28121} 28122 28123function isSimpleFunctionComponent(type) { 28124 return typeof type === 'function' && !shouldConstruct$1(type) && type.defaultProps === undefined; 28125} 28126function resolveLazyComponentTag(Component) { 28127 if (typeof Component === 'function') { 28128 return shouldConstruct$1(Component) ? ClassComponent : FunctionComponent; 28129 } else if (Component !== undefined && Component !== null) { 28130 var $$typeof = Component.$$typeof; 28131 28132 if ($$typeof === REACT_FORWARD_REF_TYPE) { 28133 return ForwardRef; 28134 } 28135 28136 if ($$typeof === REACT_MEMO_TYPE) { 28137 return MemoComponent; 28138 } 28139 } 28140 28141 return IndeterminateComponent; 28142} // This is used to create an alternate fiber to do work on. 28143 28144function createWorkInProgress(current, pendingProps) { 28145 var workInProgress = current.alternate; 28146 28147 if (workInProgress === null) { 28148 // We use a double buffering pooling technique because we know that we'll 28149 // only ever need at most two versions of a tree. We pool the "other" unused 28150 // node that we're free to reuse. This is lazily created to avoid allocating 28151 // extra objects for things that are never updated. It also allow us to 28152 // reclaim the extra memory if needed. 28153 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode); 28154 workInProgress.elementType = current.elementType; 28155 workInProgress.type = current.type; 28156 workInProgress.stateNode = current.stateNode; 28157 28158 { 28159 // DEV-only fields 28160 workInProgress._debugSource = current._debugSource; 28161 workInProgress._debugOwner = current._debugOwner; 28162 workInProgress._debugHookTypes = current._debugHookTypes; 28163 } 28164 28165 workInProgress.alternate = current; 28166 current.alternate = workInProgress; 28167 } else { 28168 workInProgress.pendingProps = pendingProps; // Needed because Blocks store data on type. 28169 28170 workInProgress.type = current.type; // We already have an alternate. 28171 // Reset the effect tag. 28172 28173 workInProgress.flags = NoFlags; // The effects are no longer valid. 28174 28175 workInProgress.subtreeFlags = NoFlags; 28176 workInProgress.deletions = null; 28177 28178 { 28179 // We intentionally reset, rather than copy, actualDuration & actualStartTime. 28180 // This prevents time from endlessly accumulating in new commits. 28181 // This has the downside of resetting values for different priority renders, 28182 // But works for yielding (the common case) and should support resuming. 28183 workInProgress.actualDuration = 0; 28184 workInProgress.actualStartTime = -1; 28185 } 28186 } // Reset all effects except static ones. 28187 // Static effects are not specific to a render. 28188 28189 28190 workInProgress.flags = current.flags & StaticMask; 28191 workInProgress.childLanes = current.childLanes; 28192 workInProgress.lanes = current.lanes; 28193 workInProgress.child = current.child; 28194 workInProgress.memoizedProps = current.memoizedProps; 28195 workInProgress.memoizedState = current.memoizedState; 28196 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so 28197 // it cannot be shared with the current fiber. 28198 28199 var currentDependencies = current.dependencies; 28200 workInProgress.dependencies = currentDependencies === null ? null : { 28201 lanes: currentDependencies.lanes, 28202 firstContext: currentDependencies.firstContext 28203 }; // These will be overridden during the parent's reconciliation 28204 28205 workInProgress.sibling = current.sibling; 28206 workInProgress.index = current.index; 28207 workInProgress.ref = current.ref; 28208 28209 { 28210 workInProgress.selfBaseDuration = current.selfBaseDuration; 28211 workInProgress.treeBaseDuration = current.treeBaseDuration; 28212 } 28213 28214 { 28215 workInProgress._debugNeedsRemount = current._debugNeedsRemount; 28216 28217 switch (workInProgress.tag) { 28218 case IndeterminateComponent: 28219 case FunctionComponent: 28220 case SimpleMemoComponent: 28221 workInProgress.type = resolveFunctionForHotReloading(current.type); 28222 break; 28223 28224 case ClassComponent: 28225 workInProgress.type = resolveClassForHotReloading(current.type); 28226 break; 28227 28228 case ForwardRef: 28229 workInProgress.type = resolveForwardRefForHotReloading(current.type); 28230 break; 28231 } 28232 } 28233 28234 return workInProgress; 28235} // Used to reuse a Fiber for a second pass. 28236 28237function resetWorkInProgress(workInProgress, renderLanes) { 28238 // This resets the Fiber to what createFiber or createWorkInProgress would 28239 // have set the values to before during the first pass. Ideally this wouldn't 28240 // be necessary but unfortunately many code paths reads from the workInProgress 28241 // when they should be reading from current and writing to workInProgress. 28242 // We assume pendingProps, index, key, ref, return are still untouched to 28243 // avoid doing another reconciliation. 28244 // Reset the effect flags but keep any Placement tags, since that's something 28245 // that child fiber is setting, not the reconciliation. 28246 workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid. 28247 28248 var current = workInProgress.alternate; 28249 28250 if (current === null) { 28251 // Reset to createFiber's initial values. 28252 workInProgress.childLanes = NoLanes; 28253 workInProgress.lanes = renderLanes; 28254 workInProgress.child = null; 28255 workInProgress.subtreeFlags = NoFlags; 28256 workInProgress.memoizedProps = null; 28257 workInProgress.memoizedState = null; 28258 workInProgress.updateQueue = null; 28259 workInProgress.dependencies = null; 28260 workInProgress.stateNode = null; 28261 28262 { 28263 // Note: We don't reset the actualTime counts. It's useful to accumulate 28264 // actual time across multiple render passes. 28265 workInProgress.selfBaseDuration = 0; 28266 workInProgress.treeBaseDuration = 0; 28267 } 28268 } else { 28269 // Reset to the cloned values that createWorkInProgress would've. 28270 workInProgress.childLanes = current.childLanes; 28271 workInProgress.lanes = current.lanes; 28272 workInProgress.child = current.child; 28273 workInProgress.subtreeFlags = NoFlags; 28274 workInProgress.deletions = null; 28275 workInProgress.memoizedProps = current.memoizedProps; 28276 workInProgress.memoizedState = current.memoizedState; 28277 workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type. 28278 28279 workInProgress.type = current.type; // Clone the dependencies object. This is mutated during the render phase, so 28280 // it cannot be shared with the current fiber. 28281 28282 var currentDependencies = current.dependencies; 28283 workInProgress.dependencies = currentDependencies === null ? null : { 28284 lanes: currentDependencies.lanes, 28285 firstContext: currentDependencies.firstContext 28286 }; 28287 28288 { 28289 // Note: We don't reset the actualTime counts. It's useful to accumulate 28290 // actual time across multiple render passes. 28291 workInProgress.selfBaseDuration = current.selfBaseDuration; 28292 workInProgress.treeBaseDuration = current.treeBaseDuration; 28293 } 28294 } 28295 28296 return workInProgress; 28297} 28298function createHostRootFiber(tag, isStrictMode, concurrentUpdatesByDefaultOverride) { 28299 var mode; 28300 28301 if (tag === ConcurrentRoot) { 28302 mode = ConcurrentMode; 28303 28304 if (isStrictMode === true) { 28305 mode |= StrictLegacyMode; 28306 28307 { 28308 mode |= StrictEffectsMode; 28309 } 28310 } 28311 } else { 28312 mode = NoMode; 28313 } 28314 28315 if ( isDevToolsPresent) { 28316 // Always collect profile timings when DevTools are present. 28317 // This enables DevTools to start capturing timing at any point– 28318 // Without some nodes in the tree having empty base times. 28319 mode |= ProfileMode; 28320 } 28321 28322 return createFiber(HostRoot, null, null, mode); 28323} 28324function createFiberFromTypeAndProps(type, // React$ElementType 28325key, pendingProps, owner, mode, lanes) { 28326 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy. 28327 28328 var resolvedType = type; 28329 28330 if (typeof type === 'function') { 28331 if (shouldConstruct$1(type)) { 28332 fiberTag = ClassComponent; 28333 28334 { 28335 resolvedType = resolveClassForHotReloading(resolvedType); 28336 } 28337 } else { 28338 { 28339 resolvedType = resolveFunctionForHotReloading(resolvedType); 28340 } 28341 } 28342 } else if (typeof type === 'string') { 28343 fiberTag = HostComponent; 28344 } else { 28345 getTag: switch (type) { 28346 case REACT_FRAGMENT_TYPE: 28347 return createFiberFromFragment(pendingProps.children, mode, lanes, key); 28348 28349 case REACT_STRICT_MODE_TYPE: 28350 fiberTag = Mode; 28351 mode |= StrictLegacyMode; 28352 28353 if ( (mode & ConcurrentMode) !== NoMode) { 28354 // Strict effects should never run on legacy roots 28355 mode |= StrictEffectsMode; 28356 } 28357 28358 break; 28359 28360 case REACT_PROFILER_TYPE: 28361 return createFiberFromProfiler(pendingProps, mode, lanes, key); 28362 28363 case REACT_SUSPENSE_TYPE: 28364 return createFiberFromSuspense(pendingProps, mode, lanes, key); 28365 28366 case REACT_SUSPENSE_LIST_TYPE: 28367 return createFiberFromSuspenseList(pendingProps, mode, lanes, key); 28368 28369 case REACT_OFFSCREEN_TYPE: 28370 return createFiberFromOffscreen(pendingProps, mode, lanes, key); 28371 28372 case REACT_LEGACY_HIDDEN_TYPE: 28373 28374 // eslint-disable-next-line no-fallthrough 28375 28376 case REACT_SCOPE_TYPE: 28377 28378 // eslint-disable-next-line no-fallthrough 28379 28380 case REACT_CACHE_TYPE: 28381 28382 // eslint-disable-next-line no-fallthrough 28383 28384 case REACT_TRACING_MARKER_TYPE: 28385 28386 // eslint-disable-next-line no-fallthrough 28387 28388 case REACT_DEBUG_TRACING_MODE_TYPE: 28389 28390 // eslint-disable-next-line no-fallthrough 28391 28392 default: 28393 { 28394 if (typeof type === 'object' && type !== null) { 28395 switch (type.$$typeof) { 28396 case REACT_PROVIDER_TYPE: 28397 fiberTag = ContextProvider; 28398 break getTag; 28399 28400 case REACT_CONTEXT_TYPE: 28401 // This is a consumer 28402 fiberTag = ContextConsumer; 28403 break getTag; 28404 28405 case REACT_FORWARD_REF_TYPE: 28406 fiberTag = ForwardRef; 28407 28408 { 28409 resolvedType = resolveForwardRefForHotReloading(resolvedType); 28410 } 28411 28412 break getTag; 28413 28414 case REACT_MEMO_TYPE: 28415 fiberTag = MemoComponent; 28416 break getTag; 28417 28418 case REACT_LAZY_TYPE: 28419 fiberTag = LazyComponent; 28420 resolvedType = null; 28421 break getTag; 28422 } 28423 } 28424 28425 var info = ''; 28426 28427 { 28428 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) { 28429 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.'; 28430 } 28431 28432 var ownerName = owner ? getComponentNameFromFiber(owner) : null; 28433 28434 if (ownerName) { 28435 info += '\n\nCheck the render method of `' + ownerName + '`.'; 28436 } 28437 } 28438 28439 throw new Error('Element type is invalid: expected a string (for built-in ' + 'components) or a class/function (for composite components) ' + ("but got: " + (type == null ? type : typeof type) + "." + info)); 28440 } 28441 } 28442 } 28443 28444 var fiber = createFiber(fiberTag, pendingProps, key, mode); 28445 fiber.elementType = type; 28446 fiber.type = resolvedType; 28447 fiber.lanes = lanes; 28448 28449 { 28450 fiber._debugOwner = owner; 28451 } 28452 28453 return fiber; 28454} 28455function createFiberFromElement(element, mode, lanes) { 28456 var owner = null; 28457 28458 { 28459 owner = element._owner; 28460 } 28461 28462 var type = element.type; 28463 var key = element.key; 28464 var pendingProps = element.props; 28465 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, lanes); 28466 28467 { 28468 fiber._debugSource = element._source; 28469 fiber._debugOwner = element._owner; 28470 } 28471 28472 return fiber; 28473} 28474function createFiberFromFragment(elements, mode, lanes, key) { 28475 var fiber = createFiber(Fragment, elements, key, mode); 28476 fiber.lanes = lanes; 28477 return fiber; 28478} 28479 28480function createFiberFromProfiler(pendingProps, mode, lanes, key) { 28481 { 28482 if (typeof pendingProps.id !== 'string') { 28483 error('Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', typeof pendingProps.id); 28484 } 28485 } 28486 28487 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); 28488 fiber.elementType = REACT_PROFILER_TYPE; 28489 fiber.lanes = lanes; 28490 28491 { 28492 fiber.stateNode = { 28493 effectDuration: 0, 28494 passiveEffectDuration: 0 28495 }; 28496 } 28497 28498 return fiber; 28499} 28500 28501function createFiberFromSuspense(pendingProps, mode, lanes, key) { 28502 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); 28503 fiber.elementType = REACT_SUSPENSE_TYPE; 28504 fiber.lanes = lanes; 28505 return fiber; 28506} 28507function createFiberFromSuspenseList(pendingProps, mode, lanes, key) { 28508 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode); 28509 fiber.elementType = REACT_SUSPENSE_LIST_TYPE; 28510 fiber.lanes = lanes; 28511 return fiber; 28512} 28513function createFiberFromOffscreen(pendingProps, mode, lanes, key) { 28514 var fiber = createFiber(OffscreenComponent, pendingProps, key, mode); 28515 fiber.elementType = REACT_OFFSCREEN_TYPE; 28516 fiber.lanes = lanes; 28517 var primaryChildInstance = { 28518 isHidden: false 28519 }; 28520 fiber.stateNode = primaryChildInstance; 28521 return fiber; 28522} 28523function createFiberFromText(content, mode, lanes) { 28524 var fiber = createFiber(HostText, content, null, mode); 28525 fiber.lanes = lanes; 28526 return fiber; 28527} 28528function createFiberFromHostInstanceForDeletion() { 28529 var fiber = createFiber(HostComponent, null, null, NoMode); 28530 fiber.elementType = 'DELETED'; 28531 return fiber; 28532} 28533function createFiberFromDehydratedFragment(dehydratedNode) { 28534 var fiber = createFiber(DehydratedFragment, null, null, NoMode); 28535 fiber.stateNode = dehydratedNode; 28536 return fiber; 28537} 28538function createFiberFromPortal(portal, mode, lanes) { 28539 var pendingProps = portal.children !== null ? portal.children : []; 28540 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode); 28541 fiber.lanes = lanes; 28542 fiber.stateNode = { 28543 containerInfo: portal.containerInfo, 28544 pendingChildren: null, 28545 // Used by persistent updates 28546 implementation: portal.implementation 28547 }; 28548 return fiber; 28549} // Used for stashing WIP properties to replay failed work in DEV. 28550 28551function assignFiberPropertiesInDEV(target, source) { 28552 if (target === null) { 28553 // This Fiber's initial properties will always be overwritten. 28554 // We only use a Fiber to ensure the same hidden class so DEV isn't slow. 28555 target = createFiber(IndeterminateComponent, null, null, NoMode); 28556 } // This is intentionally written as a list of all properties. 28557 // We tried to use Object.assign() instead but this is called in 28558 // the hottest path, and Object.assign() was too slow: 28559 // https://github.com/facebook/react/issues/12502 28560 // This code is DEV-only so size is not a concern. 28561 28562 28563 target.tag = source.tag; 28564 target.key = source.key; 28565 target.elementType = source.elementType; 28566 target.type = source.type; 28567 target.stateNode = source.stateNode; 28568 target.return = source.return; 28569 target.child = source.child; 28570 target.sibling = source.sibling; 28571 target.index = source.index; 28572 target.ref = source.ref; 28573 target.pendingProps = source.pendingProps; 28574 target.memoizedProps = source.memoizedProps; 28575 target.updateQueue = source.updateQueue; 28576 target.memoizedState = source.memoizedState; 28577 target.dependencies = source.dependencies; 28578 target.mode = source.mode; 28579 target.flags = source.flags; 28580 target.subtreeFlags = source.subtreeFlags; 28581 target.deletions = source.deletions; 28582 target.lanes = source.lanes; 28583 target.childLanes = source.childLanes; 28584 target.alternate = source.alternate; 28585 28586 { 28587 target.actualDuration = source.actualDuration; 28588 target.actualStartTime = source.actualStartTime; 28589 target.selfBaseDuration = source.selfBaseDuration; 28590 target.treeBaseDuration = source.treeBaseDuration; 28591 } 28592 28593 target._debugSource = source._debugSource; 28594 target._debugOwner = source._debugOwner; 28595 target._debugNeedsRemount = source._debugNeedsRemount; 28596 target._debugHookTypes = source._debugHookTypes; 28597 return target; 28598} 28599 28600function FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onRecoverableError) { 28601 this.tag = tag; 28602 this.containerInfo = containerInfo; 28603 this.pendingChildren = null; 28604 this.current = null; 28605 this.pingCache = null; 28606 this.finishedWork = null; 28607 this.timeoutHandle = noTimeout; 28608 this.context = null; 28609 this.pendingContext = null; 28610 this.callbackNode = null; 28611 this.callbackPriority = NoLane; 28612 this.eventTimes = createLaneMap(NoLanes); 28613 this.expirationTimes = createLaneMap(NoTimestamp); 28614 this.pendingLanes = NoLanes; 28615 this.suspendedLanes = NoLanes; 28616 this.pingedLanes = NoLanes; 28617 this.expiredLanes = NoLanes; 28618 this.mutableReadLanes = NoLanes; 28619 this.finishedLanes = NoLanes; 28620 this.entangledLanes = NoLanes; 28621 this.entanglements = createLaneMap(NoLanes); 28622 this.identifierPrefix = identifierPrefix; 28623 this.onRecoverableError = onRecoverableError; 28624 28625 { 28626 this.mutableSourceEagerHydrationData = null; 28627 } 28628 28629 { 28630 this.effectDuration = 0; 28631 this.passiveEffectDuration = 0; 28632 } 28633 28634 { 28635 this.memoizedUpdaters = new Set(); 28636 var pendingUpdatersLaneMap = this.pendingUpdatersLaneMap = []; 28637 28638 for (var _i = 0; _i < TotalLanes; _i++) { 28639 pendingUpdatersLaneMap.push(new Set()); 28640 } 28641 } 28642 28643 { 28644 switch (tag) { 28645 case ConcurrentRoot: 28646 this._debugRootType = hydrate ? 'hydrateRoot()' : 'createRoot()'; 28647 break; 28648 28649 case LegacyRoot: 28650 this._debugRootType = hydrate ? 'hydrate()' : 'render()'; 28651 break; 28652 } 28653 } 28654} 28655 28656function createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, // TODO: We have several of these arguments that are conceptually part of the 28657// host config, but because they are passed in at runtime, we have to thread 28658// them through the root constructor. Perhaps we should put them all into a 28659// single type, like a DynamicHostConfig that is defined by the renderer. 28660identifierPrefix, onRecoverableError, transitionCallbacks) { 28661 var root = new FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onRecoverableError); 28662 // stateNode is any. 28663 28664 28665 var uninitializedFiber = createHostRootFiber(tag, isStrictMode); 28666 root.current = uninitializedFiber; 28667 uninitializedFiber.stateNode = root; 28668 28669 { 28670 var _initialState = { 28671 element: initialChildren, 28672 isDehydrated: hydrate, 28673 cache: null, 28674 // not enabled yet 28675 transitions: null, 28676 pendingSuspenseBoundaries: null 28677 }; 28678 uninitializedFiber.memoizedState = _initialState; 28679 } 28680 28681 initializeUpdateQueue(uninitializedFiber); 28682 return root; 28683} 28684 28685var ReactVersion = '18.2.0'; 28686 28687function createPortal(children, containerInfo, // TODO: figure out the API for cross-renderer implementation. 28688implementation) { 28689 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; 28690 28691 { 28692 checkKeyStringCoercion(key); 28693 } 28694 28695 return { 28696 // This tag allow us to uniquely identify this as a React Portal 28697 $$typeof: REACT_PORTAL_TYPE, 28698 key: key == null ? null : '' + key, 28699 children: children, 28700 containerInfo: containerInfo, 28701 implementation: implementation 28702 }; 28703} 28704 28705var didWarnAboutNestedUpdates; 28706var didWarnAboutFindNodeInStrictMode; 28707 28708{ 28709 didWarnAboutNestedUpdates = false; 28710 didWarnAboutFindNodeInStrictMode = {}; 28711} 28712 28713function getContextForSubtree(parentComponent) { 28714 if (!parentComponent) { 28715 return emptyContextObject; 28716 } 28717 28718 var fiber = get(parentComponent); 28719 var parentContext = findCurrentUnmaskedContext(fiber); 28720 28721 if (fiber.tag === ClassComponent) { 28722 var Component = fiber.type; 28723 28724 if (isContextProvider(Component)) { 28725 return processChildContext(fiber, Component, parentContext); 28726 } 28727 } 28728 28729 return parentContext; 28730} 28731 28732function findHostInstanceWithWarning(component, methodName) { 28733 { 28734 var fiber = get(component); 28735 28736 if (fiber === undefined) { 28737 if (typeof component.render === 'function') { 28738 throw new Error('Unable to find node on an unmounted component.'); 28739 } else { 28740 var keys = Object.keys(component).join(','); 28741 throw new Error("Argument appears to not be a ReactComponent. Keys: " + keys); 28742 } 28743 } 28744 28745 var hostFiber = findCurrentHostFiber(fiber); 28746 28747 if (hostFiber === null) { 28748 return null; 28749 } 28750 28751 if (hostFiber.mode & StrictLegacyMode) { 28752 var componentName = getComponentNameFromFiber(fiber) || 'Component'; 28753 28754 if (!didWarnAboutFindNodeInStrictMode[componentName]) { 28755 didWarnAboutFindNodeInStrictMode[componentName] = true; 28756 var previousFiber = current; 28757 28758 try { 28759 setCurrentFiber(hostFiber); 28760 28761 if (fiber.mode & StrictLegacyMode) { 28762 error('%s is deprecated in StrictMode. ' + '%s was passed an instance of %s which is inside StrictMode. ' + 'Instead, add a ref directly to the element you want to reference. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-find-node', methodName, methodName, componentName); 28763 } else { 28764 error('%s is deprecated in StrictMode. ' + '%s was passed an instance of %s which renders StrictMode children. ' + 'Instead, add a ref directly to the element you want to reference. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-find-node', methodName, methodName, componentName); 28765 } 28766 } finally { 28767 // Ideally this should reset to previous but this shouldn't be called in 28768 // render and there's another warning for that anyway. 28769 if (previousFiber) { 28770 setCurrentFiber(previousFiber); 28771 } else { 28772 resetCurrentFiber(); 28773 } 28774 } 28775 } 28776 } 28777 28778 return hostFiber.stateNode; 28779 } 28780} 28781 28782function createContainer(containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks) { 28783 var hydrate = false; 28784 var initialChildren = null; 28785 return createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError); 28786} 28787function createHydrationContainer(initialChildren, // TODO: Remove `callback` when we delete legacy mode. 28788callback, containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks) { 28789 var hydrate = true; 28790 var root = createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError); // TODO: Move this to FiberRoot constructor 28791 28792 root.context = getContextForSubtree(null); // Schedule the initial render. In a hydration root, this is different from 28793 // a regular update because the initial render must match was was rendered 28794 // on the server. 28795 // NOTE: This update intentionally doesn't have a payload. We're only using 28796 // the update to schedule work on the root fiber (and, for legacy roots, to 28797 // enqueue the callback if one is provided). 28798 28799 var current = root.current; 28800 var eventTime = requestEventTime(); 28801 var lane = requestUpdateLane(current); 28802 var update = createUpdate(eventTime, lane); 28803 update.callback = callback !== undefined && callback !== null ? callback : null; 28804 enqueueUpdate(current, update, lane); 28805 scheduleInitialHydrationOnRoot(root, lane, eventTime); 28806 return root; 28807} 28808function updateContainer(element, container, parentComponent, callback) { 28809 { 28810 onScheduleRoot(container, element); 28811 } 28812 28813 var current$1 = container.current; 28814 var eventTime = requestEventTime(); 28815 var lane = requestUpdateLane(current$1); 28816 28817 { 28818 markRenderScheduled(lane); 28819 } 28820 28821 var context = getContextForSubtree(parentComponent); 28822 28823 if (container.context === null) { 28824 container.context = context; 28825 } else { 28826 container.pendingContext = context; 28827 } 28828 28829 { 28830 if (isRendering && current !== null && !didWarnAboutNestedUpdates) { 28831 didWarnAboutNestedUpdates = true; 28832 28833 error('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.', getComponentNameFromFiber(current) || 'Unknown'); 28834 } 28835 } 28836 28837 var update = createUpdate(eventTime, lane); // Caution: React DevTools currently depends on this property 28838 // being called "element". 28839 28840 update.payload = { 28841 element: element 28842 }; 28843 callback = callback === undefined ? null : callback; 28844 28845 if (callback !== null) { 28846 { 28847 if (typeof callback !== 'function') { 28848 error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback); 28849 } 28850 } 28851 28852 update.callback = callback; 28853 } 28854 28855 var root = enqueueUpdate(current$1, update, lane); 28856 28857 if (root !== null) { 28858 scheduleUpdateOnFiber(root, current$1, lane, eventTime); 28859 entangleTransitions(root, current$1, lane); 28860 } 28861 28862 return lane; 28863} 28864function getPublicRootInstance(container) { 28865 var containerFiber = container.current; 28866 28867 if (!containerFiber.child) { 28868 return null; 28869 } 28870 28871 switch (containerFiber.child.tag) { 28872 case HostComponent: 28873 return getPublicInstance(containerFiber.child.stateNode); 28874 28875 default: 28876 return containerFiber.child.stateNode; 28877 } 28878} 28879function attemptSynchronousHydration$1(fiber) { 28880 switch (fiber.tag) { 28881 case HostRoot: 28882 { 28883 var root = fiber.stateNode; 28884 28885 if (isRootDehydrated(root)) { 28886 // Flush the first scheduled "update". 28887 var lanes = getHighestPriorityPendingLanes(root); 28888 flushRoot(root, lanes); 28889 } 28890 28891 break; 28892 } 28893 28894 case SuspenseComponent: 28895 { 28896 flushSync(function () { 28897 var root = enqueueConcurrentRenderForLane(fiber, SyncLane); 28898 28899 if (root !== null) { 28900 var eventTime = requestEventTime(); 28901 scheduleUpdateOnFiber(root, fiber, SyncLane, eventTime); 28902 } 28903 }); // If we're still blocked after this, we need to increase 28904 // the priority of any promises resolving within this 28905 // boundary so that they next attempt also has higher pri. 28906 28907 var retryLane = SyncLane; 28908 markRetryLaneIfNotHydrated(fiber, retryLane); 28909 break; 28910 } 28911 } 28912} 28913 28914function markRetryLaneImpl(fiber, retryLane) { 28915 var suspenseState = fiber.memoizedState; 28916 28917 if (suspenseState !== null && suspenseState.dehydrated !== null) { 28918 suspenseState.retryLane = higherPriorityLane(suspenseState.retryLane, retryLane); 28919 } 28920} // Increases the priority of thenables when they resolve within this boundary. 28921 28922 28923function markRetryLaneIfNotHydrated(fiber, retryLane) { 28924 markRetryLaneImpl(fiber, retryLane); 28925 var alternate = fiber.alternate; 28926 28927 if (alternate) { 28928 markRetryLaneImpl(alternate, retryLane); 28929 } 28930} 28931function attemptContinuousHydration$1(fiber) { 28932 if (fiber.tag !== SuspenseComponent) { 28933 // We ignore HostRoots here because we can't increase 28934 // their priority and they should not suspend on I/O, 28935 // since you have to wrap anything that might suspend in 28936 // Suspense. 28937 return; 28938 } 28939 28940 var lane = SelectiveHydrationLane; 28941 var root = enqueueConcurrentRenderForLane(fiber, lane); 28942 28943 if (root !== null) { 28944 var eventTime = requestEventTime(); 28945 scheduleUpdateOnFiber(root, fiber, lane, eventTime); 28946 } 28947 28948 markRetryLaneIfNotHydrated(fiber, lane); 28949} 28950function attemptHydrationAtCurrentPriority$1(fiber) { 28951 if (fiber.tag !== SuspenseComponent) { 28952 // We ignore HostRoots here because we can't increase 28953 // their priority other than synchronously flush it. 28954 return; 28955 } 28956 28957 var lane = requestUpdateLane(fiber); 28958 var root = enqueueConcurrentRenderForLane(fiber, lane); 28959 28960 if (root !== null) { 28961 var eventTime = requestEventTime(); 28962 scheduleUpdateOnFiber(root, fiber, lane, eventTime); 28963 } 28964 28965 markRetryLaneIfNotHydrated(fiber, lane); 28966} 28967function findHostInstanceWithNoPortals(fiber) { 28968 var hostFiber = findCurrentHostFiberWithNoPortals(fiber); 28969 28970 if (hostFiber === null) { 28971 return null; 28972 } 28973 28974 return hostFiber.stateNode; 28975} 28976 28977var shouldErrorImpl = function (fiber) { 28978 return null; 28979}; 28980 28981function shouldError(fiber) { 28982 return shouldErrorImpl(fiber); 28983} 28984 28985var shouldSuspendImpl = function (fiber) { 28986 return false; 28987}; 28988 28989function shouldSuspend(fiber) { 28990 return shouldSuspendImpl(fiber); 28991} 28992var overrideHookState = null; 28993var overrideHookStateDeletePath = null; 28994var overrideHookStateRenamePath = null; 28995var overrideProps = null; 28996var overridePropsDeletePath = null; 28997var overridePropsRenamePath = null; 28998var scheduleUpdate = null; 28999var setErrorHandler = null; 29000var setSuspenseHandler = null; 29001 29002{ 29003 var copyWithDeleteImpl = function (obj, path, index) { 29004 var key = path[index]; 29005 var updated = isArray(obj) ? obj.slice() : assign({}, obj); 29006 29007 if (index + 1 === path.length) { 29008 if (isArray(updated)) { 29009 updated.splice(key, 1); 29010 } else { 29011 delete updated[key]; 29012 } 29013 29014 return updated; 29015 } // $FlowFixMe number or string is fine here 29016 29017 29018 updated[key] = copyWithDeleteImpl(obj[key], path, index + 1); 29019 return updated; 29020 }; 29021 29022 var copyWithDelete = function (obj, path) { 29023 return copyWithDeleteImpl(obj, path, 0); 29024 }; 29025 29026 var copyWithRenameImpl = function (obj, oldPath, newPath, index) { 29027 var oldKey = oldPath[index]; 29028 var updated = isArray(obj) ? obj.slice() : assign({}, obj); 29029 29030 if (index + 1 === oldPath.length) { 29031 var newKey = newPath[index]; // $FlowFixMe number or string is fine here 29032 29033 updated[newKey] = updated[oldKey]; 29034 29035 if (isArray(updated)) { 29036 updated.splice(oldKey, 1); 29037 } else { 29038 delete updated[oldKey]; 29039 } 29040 } else { 29041 // $FlowFixMe number or string is fine here 29042 updated[oldKey] = copyWithRenameImpl( // $FlowFixMe number or string is fine here 29043 obj[oldKey], oldPath, newPath, index + 1); 29044 } 29045 29046 return updated; 29047 }; 29048 29049 var copyWithRename = function (obj, oldPath, newPath) { 29050 if (oldPath.length !== newPath.length) { 29051 warn('copyWithRename() expects paths of the same length'); 29052 29053 return; 29054 } else { 29055 for (var i = 0; i < newPath.length - 1; i++) { 29056 if (oldPath[i] !== newPath[i]) { 29057 warn('copyWithRename() expects paths to be the same except for the deepest key'); 29058 29059 return; 29060 } 29061 } 29062 } 29063 29064 return copyWithRenameImpl(obj, oldPath, newPath, 0); 29065 }; 29066 29067 var copyWithSetImpl = function (obj, path, index, value) { 29068 if (index >= path.length) { 29069 return value; 29070 } 29071 29072 var key = path[index]; 29073 var updated = isArray(obj) ? obj.slice() : assign({}, obj); // $FlowFixMe number or string is fine here 29074 29075 updated[key] = copyWithSetImpl(obj[key], path, index + 1, value); 29076 return updated; 29077 }; 29078 29079 var copyWithSet = function (obj, path, value) { 29080 return copyWithSetImpl(obj, path, 0, value); 29081 }; 29082 29083 var findHook = function (fiber, id) { 29084 // For now, the "id" of stateful hooks is just the stateful hook index. 29085 // This may change in the future with e.g. nested hooks. 29086 var currentHook = fiber.memoizedState; 29087 29088 while (currentHook !== null && id > 0) { 29089 currentHook = currentHook.next; 29090 id--; 29091 } 29092 29093 return currentHook; 29094 }; // Support DevTools editable values for useState and useReducer. 29095 29096 29097 overrideHookState = function (fiber, id, path, value) { 29098 var hook = findHook(fiber, id); 29099 29100 if (hook !== null) { 29101 var newState = copyWithSet(hook.memoizedState, path, value); 29102 hook.memoizedState = newState; 29103 hook.baseState = newState; // We aren't actually adding an update to the queue, 29104 // because there is no update we can add for useReducer hooks that won't trigger an error. 29105 // (There's no appropriate action type for DevTools overrides.) 29106 // As a result though, React will see the scheduled update as a noop and bailout. 29107 // Shallow cloning props works as a workaround for now to bypass the bailout check. 29108 29109 fiber.memoizedProps = assign({}, fiber.memoizedProps); 29110 var root = enqueueConcurrentRenderForLane(fiber, SyncLane); 29111 29112 if (root !== null) { 29113 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp); 29114 } 29115 } 29116 }; 29117 29118 overrideHookStateDeletePath = function (fiber, id, path) { 29119 var hook = findHook(fiber, id); 29120 29121 if (hook !== null) { 29122 var newState = copyWithDelete(hook.memoizedState, path); 29123 hook.memoizedState = newState; 29124 hook.baseState = newState; // We aren't actually adding an update to the queue, 29125 // because there is no update we can add for useReducer hooks that won't trigger an error. 29126 // (There's no appropriate action type for DevTools overrides.) 29127 // As a result though, React will see the scheduled update as a noop and bailout. 29128 // Shallow cloning props works as a workaround for now to bypass the bailout check. 29129 29130 fiber.memoizedProps = assign({}, fiber.memoizedProps); 29131 var root = enqueueConcurrentRenderForLane(fiber, SyncLane); 29132 29133 if (root !== null) { 29134 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp); 29135 } 29136 } 29137 }; 29138 29139 overrideHookStateRenamePath = function (fiber, id, oldPath, newPath) { 29140 var hook = findHook(fiber, id); 29141 29142 if (hook !== null) { 29143 var newState = copyWithRename(hook.memoizedState, oldPath, newPath); 29144 hook.memoizedState = newState; 29145 hook.baseState = newState; // We aren't actually adding an update to the queue, 29146 // because there is no update we can add for useReducer hooks that won't trigger an error. 29147 // (There's no appropriate action type for DevTools overrides.) 29148 // As a result though, React will see the scheduled update as a noop and bailout. 29149 // Shallow cloning props works as a workaround for now to bypass the bailout check. 29150 29151 fiber.memoizedProps = assign({}, fiber.memoizedProps); 29152 var root = enqueueConcurrentRenderForLane(fiber, SyncLane); 29153 29154 if (root !== null) { 29155 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp); 29156 } 29157 } 29158 }; // Support DevTools props for function components, forwardRef, memo, host components, etc. 29159 29160 29161 overrideProps = function (fiber, path, value) { 29162 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); 29163 29164 if (fiber.alternate) { 29165 fiber.alternate.pendingProps = fiber.pendingProps; 29166 } 29167 29168 var root = enqueueConcurrentRenderForLane(fiber, SyncLane); 29169 29170 if (root !== null) { 29171 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp); 29172 } 29173 }; 29174 29175 overridePropsDeletePath = function (fiber, path) { 29176 fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path); 29177 29178 if (fiber.alternate) { 29179 fiber.alternate.pendingProps = fiber.pendingProps; 29180 } 29181 29182 var root = enqueueConcurrentRenderForLane(fiber, SyncLane); 29183 29184 if (root !== null) { 29185 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp); 29186 } 29187 }; 29188 29189 overridePropsRenamePath = function (fiber, oldPath, newPath) { 29190 fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath); 29191 29192 if (fiber.alternate) { 29193 fiber.alternate.pendingProps = fiber.pendingProps; 29194 } 29195 29196 var root = enqueueConcurrentRenderForLane(fiber, SyncLane); 29197 29198 if (root !== null) { 29199 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp); 29200 } 29201 }; 29202 29203 scheduleUpdate = function (fiber) { 29204 var root = enqueueConcurrentRenderForLane(fiber, SyncLane); 29205 29206 if (root !== null) { 29207 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp); 29208 } 29209 }; 29210 29211 setErrorHandler = function (newShouldErrorImpl) { 29212 shouldErrorImpl = newShouldErrorImpl; 29213 }; 29214 29215 setSuspenseHandler = function (newShouldSuspendImpl) { 29216 shouldSuspendImpl = newShouldSuspendImpl; 29217 }; 29218} 29219 29220function findHostInstanceByFiber(fiber) { 29221 var hostFiber = findCurrentHostFiber(fiber); 29222 29223 if (hostFiber === null) { 29224 return null; 29225 } 29226 29227 return hostFiber.stateNode; 29228} 29229 29230function emptyFindFiberByHostInstance(instance) { 29231 return null; 29232} 29233 29234function getCurrentFiberForDevTools() { 29235 return current; 29236} 29237 29238function injectIntoDevTools(devToolsConfig) { 29239 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; 29240 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; 29241 return injectInternals({ 29242 bundleType: devToolsConfig.bundleType, 29243 version: devToolsConfig.version, 29244 rendererPackageName: devToolsConfig.rendererPackageName, 29245 rendererConfig: devToolsConfig.rendererConfig, 29246 overrideHookState: overrideHookState, 29247 overrideHookStateDeletePath: overrideHookStateDeletePath, 29248 overrideHookStateRenamePath: overrideHookStateRenamePath, 29249 overrideProps: overrideProps, 29250 overridePropsDeletePath: overridePropsDeletePath, 29251 overridePropsRenamePath: overridePropsRenamePath, 29252 setErrorHandler: setErrorHandler, 29253 setSuspenseHandler: setSuspenseHandler, 29254 scheduleUpdate: scheduleUpdate, 29255 currentDispatcherRef: ReactCurrentDispatcher, 29256 findHostInstanceByFiber: findHostInstanceByFiber, 29257 findFiberByHostInstance: findFiberByHostInstance || emptyFindFiberByHostInstance, 29258 // React Refresh 29259 findHostInstancesForRefresh: findHostInstancesForRefresh , 29260 scheduleRefresh: scheduleRefresh , 29261 scheduleRoot: scheduleRoot , 29262 setRefreshHandler: setRefreshHandler , 29263 // Enables DevTools to append owner stacks to error messages in DEV mode. 29264 getCurrentFiber: getCurrentFiberForDevTools , 29265 // Enables DevTools to detect reconciler version rather than renderer version 29266 // which may not match for third party renderers. 29267 reconcilerVersion: ReactVersion 29268 }); 29269} 29270 29271/* global reportError */ 29272 29273var defaultOnRecoverableError = typeof reportError === 'function' ? // In modern browsers, reportError will dispatch an error event, 29274// emulating an uncaught JavaScript error. 29275reportError : function (error) { 29276 // In older browsers and test environments, fallback to console.error. 29277 // eslint-disable-next-line react-internal/no-production-logging 29278 console['error'](error); 29279}; 29280 29281function ReactDOMRoot(internalRoot) { 29282 this._internalRoot = internalRoot; 29283} 29284 29285ReactDOMHydrationRoot.prototype.render = ReactDOMRoot.prototype.render = function (children) { 29286 var root = this._internalRoot; 29287 29288 if (root === null) { 29289 throw new Error('Cannot update an unmounted root.'); 29290 } 29291 29292 { 29293 if (typeof arguments[1] === 'function') { 29294 error('render(...): does not support the second callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().'); 29295 } else if (isValidContainer(arguments[1])) { 29296 error('You passed a container to the second argument of root.render(...). ' + "You don't need to pass it again since you already passed it to create the root."); 29297 } else if (typeof arguments[1] !== 'undefined') { 29298 error('You passed a second argument to root.render(...) but it only accepts ' + 'one argument.'); 29299 } 29300 29301 var container = root.containerInfo; 29302 29303 if (container.nodeType !== COMMENT_NODE) { 29304 var hostInstance = findHostInstanceWithNoPortals(root.current); 29305 29306 if (hostInstance) { 29307 if (hostInstance.parentNode !== container) { 29308 error('render(...): It looks like the React-rendered content of the ' + 'root container was removed without using React. This is not ' + 'supported and will cause errors. Instead, call ' + "root.unmount() to empty a root's container."); 29309 } 29310 } 29311 } 29312 } 29313 29314 updateContainer(children, root, null, null); 29315}; 29316 29317ReactDOMHydrationRoot.prototype.unmount = ReactDOMRoot.prototype.unmount = function () { 29318 { 29319 if (typeof arguments[0] === 'function') { 29320 error('unmount(...): does not support a callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().'); 29321 } 29322 } 29323 29324 var root = this._internalRoot; 29325 29326 if (root !== null) { 29327 this._internalRoot = null; 29328 var container = root.containerInfo; 29329 29330 { 29331 if (isAlreadyRendering()) { 29332 error('Attempted to synchronously unmount a root while React was already ' + 'rendering. React cannot finish unmounting the root until the ' + 'current render has completed, which may lead to a race condition.'); 29333 } 29334 } 29335 29336 flushSync(function () { 29337 updateContainer(null, root, null, null); 29338 }); 29339 unmarkContainerAsRoot(container); 29340 } 29341}; 29342 29343function createRoot(container, options) { 29344 if (!isValidContainer(container)) { 29345 throw new Error('createRoot(...): Target container is not a DOM element.'); 29346 } 29347 29348 warnIfReactDOMContainerInDEV(container); 29349 var isStrictMode = false; 29350 var concurrentUpdatesByDefaultOverride = false; 29351 var identifierPrefix = ''; 29352 var onRecoverableError = defaultOnRecoverableError; 29353 var transitionCallbacks = null; 29354 29355 if (options !== null && options !== undefined) { 29356 { 29357 if (options.hydrate) { 29358 warn('hydrate through createRoot is deprecated. Use ReactDOMClient.hydrateRoot(container, <App />) instead.'); 29359 } else { 29360 if (typeof options === 'object' && options !== null && options.$$typeof === REACT_ELEMENT_TYPE) { 29361 error('You passed a JSX element to createRoot. You probably meant to ' + 'call root.render instead. ' + 'Example usage:\n\n' + ' let root = createRoot(domContainer);\n' + ' root.render(<App />);'); 29362 } 29363 } 29364 } 29365 29366 if (options.unstable_strictMode === true) { 29367 isStrictMode = true; 29368 } 29369 29370 if (options.identifierPrefix !== undefined) { 29371 identifierPrefix = options.identifierPrefix; 29372 } 29373 29374 if (options.onRecoverableError !== undefined) { 29375 onRecoverableError = options.onRecoverableError; 29376 } 29377 29378 if (options.transitionCallbacks !== undefined) { 29379 transitionCallbacks = options.transitionCallbacks; 29380 } 29381 } 29382 29383 var root = createContainer(container, ConcurrentRoot, null, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError); 29384 markContainerAsRoot(root.current, container); 29385 var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container; 29386 listenToAllSupportedEvents(rootContainerElement); 29387 return new ReactDOMRoot(root); 29388} 29389 29390function ReactDOMHydrationRoot(internalRoot) { 29391 this._internalRoot = internalRoot; 29392} 29393 29394function scheduleHydration(target) { 29395 if (target) { 29396 queueExplicitHydrationTarget(target); 29397 } 29398} 29399 29400ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = scheduleHydration; 29401function hydrateRoot(container, initialChildren, options) { 29402 if (!isValidContainer(container)) { 29403 throw new Error('hydrateRoot(...): Target container is not a DOM element.'); 29404 } 29405 29406 warnIfReactDOMContainerInDEV(container); 29407 29408 { 29409 if (initialChildren === undefined) { 29410 error('Must provide initial children as second argument to hydrateRoot. ' + 'Example usage: hydrateRoot(domContainer, <App />)'); 29411 } 29412 } // For now we reuse the whole bag of options since they contain 29413 // the hydration callbacks. 29414 29415 29416 var hydrationCallbacks = options != null ? options : null; // TODO: Delete this option 29417 29418 var mutableSources = options != null && options.hydratedSources || null; 29419 var isStrictMode = false; 29420 var concurrentUpdatesByDefaultOverride = false; 29421 var identifierPrefix = ''; 29422 var onRecoverableError = defaultOnRecoverableError; 29423 29424 if (options !== null && options !== undefined) { 29425 if (options.unstable_strictMode === true) { 29426 isStrictMode = true; 29427 } 29428 29429 if (options.identifierPrefix !== undefined) { 29430 identifierPrefix = options.identifierPrefix; 29431 } 29432 29433 if (options.onRecoverableError !== undefined) { 29434 onRecoverableError = options.onRecoverableError; 29435 } 29436 } 29437 29438 var root = createHydrationContainer(initialChildren, null, container, ConcurrentRoot, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError); 29439 markContainerAsRoot(root.current, container); // This can't be a comment node since hydration doesn't work on comment nodes anyway. 29440 29441 listenToAllSupportedEvents(container); 29442 29443 if (mutableSources) { 29444 for (var i = 0; i < mutableSources.length; i++) { 29445 var mutableSource = mutableSources[i]; 29446 registerMutableSourceForHydration(root, mutableSource); 29447 } 29448 } 29449 29450 return new ReactDOMHydrationRoot(root); 29451} 29452function isValidContainer(node) { 29453 return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || !disableCommentsAsDOMContainers )); 29454} // TODO: Remove this function which also includes comment nodes. 29455// We only use it in places that are currently more relaxed. 29456 29457function isValidContainerLegacy(node) { 29458 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 ')); 29459} 29460 29461function warnIfReactDOMContainerInDEV(container) { 29462 { 29463 if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === 'BODY') { 29464 error('createRoot(): Creating roots directly with 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 using a container element created ' + 'for your app.'); 29465 } 29466 29467 if (isContainerMarkedAsRoot(container)) { 29468 if (container._reactRootContainer) { 29469 error('You are calling ReactDOMClient.createRoot() on a container that was previously ' + 'passed to ReactDOM.render(). This is not supported.'); 29470 } else { 29471 error('You are calling ReactDOMClient.createRoot() on a container that ' + 'has already been passed to createRoot() before. Instead, call ' + 'root.render() on the existing root instead if you want to update it.'); 29472 } 29473 } 29474 } 29475} 29476 29477var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; 29478var topLevelUpdateWarnings; 29479 29480{ 29481 topLevelUpdateWarnings = function (container) { 29482 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) { 29483 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer.current); 29484 29485 if (hostInstance) { 29486 if (hostInstance.parentNode !== container) { 29487 error('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.'); 29488 } 29489 } 29490 } 29491 29492 var isRootRenderedBySomeReact = !!container._reactRootContainer; 29493 var rootEl = getReactRootElementInContainer(container); 29494 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode(rootEl)); 29495 29496 if (hasNonRootReactChild && !isRootRenderedBySomeReact) { 29497 error('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.'); 29498 } 29499 29500 if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === 'BODY') { 29501 error('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.'); 29502 } 29503 }; 29504} 29505 29506function getReactRootElementInContainer(container) { 29507 if (!container) { 29508 return null; 29509 } 29510 29511 if (container.nodeType === DOCUMENT_NODE) { 29512 return container.documentElement; 29513 } else { 29514 return container.firstChild; 29515 } 29516} 29517 29518function noopOnRecoverableError() {// This isn't reachable because onRecoverableError isn't called in the 29519 // legacy API. 29520} 29521 29522function legacyCreateRootFromDOMContainer(container, initialChildren, parentComponent, callback, isHydrationContainer) { 29523 if (isHydrationContainer) { 29524 if (typeof callback === 'function') { 29525 var originalCallback = callback; 29526 29527 callback = function () { 29528 var instance = getPublicRootInstance(root); 29529 originalCallback.call(instance); 29530 }; 29531 } 29532 29533 var root = createHydrationContainer(initialChildren, callback, container, LegacyRoot, null, // hydrationCallbacks 29534 false, // isStrictMode 29535 false, // concurrentUpdatesByDefaultOverride, 29536 '', // identifierPrefix 29537 noopOnRecoverableError); 29538 container._reactRootContainer = root; 29539 markContainerAsRoot(root.current, container); 29540 var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container; 29541 listenToAllSupportedEvents(rootContainerElement); 29542 flushSync(); 29543 return root; 29544 } else { 29545 // First clear any existing content. 29546 var rootSibling; 29547 29548 while (rootSibling = container.lastChild) { 29549 container.removeChild(rootSibling); 29550 } 29551 29552 if (typeof callback === 'function') { 29553 var _originalCallback = callback; 29554 29555 callback = function () { 29556 var instance = getPublicRootInstance(_root); 29557 29558 _originalCallback.call(instance); 29559 }; 29560 } 29561 29562 var _root = createContainer(container, LegacyRoot, null, // hydrationCallbacks 29563 false, // isStrictMode 29564 false, // concurrentUpdatesByDefaultOverride, 29565 '', // identifierPrefix 29566 noopOnRecoverableError); 29567 29568 container._reactRootContainer = _root; 29569 markContainerAsRoot(_root.current, container); 29570 29571 var _rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container; 29572 29573 listenToAllSupportedEvents(_rootContainerElement); // Initial mount should not be batched. 29574 29575 flushSync(function () { 29576 updateContainer(initialChildren, _root, parentComponent, callback); 29577 }); 29578 return _root; 29579 } 29580} 29581 29582function warnOnInvalidCallback$1(callback, callerName) { 29583 { 29584 if (callback !== null && typeof callback !== 'function') { 29585 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback); 29586 } 29587 } 29588} 29589 29590function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) { 29591 { 29592 topLevelUpdateWarnings(container); 29593 warnOnInvalidCallback$1(callback === undefined ? null : callback, 'render'); 29594 } 29595 29596 var maybeRoot = container._reactRootContainer; 29597 var root; 29598 29599 if (!maybeRoot) { 29600 // Initial mount 29601 root = legacyCreateRootFromDOMContainer(container, children, parentComponent, callback, forceHydrate); 29602 } else { 29603 root = maybeRoot; 29604 29605 if (typeof callback === 'function') { 29606 var originalCallback = callback; 29607 29608 callback = function () { 29609 var instance = getPublicRootInstance(root); 29610 originalCallback.call(instance); 29611 }; 29612 } // Update 29613 29614 29615 updateContainer(children, root, parentComponent, callback); 29616 } 29617 29618 return getPublicRootInstance(root); 29619} 29620 29621function findDOMNode(componentOrElement) { 29622 { 29623 var owner = ReactCurrentOwner$3.current; 29624 29625 if (owner !== null && owner.stateNode !== null) { 29626 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender; 29627 29628 if (!warnedAboutRefsInRender) { 29629 error('%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.', getComponentNameFromType(owner.type) || 'A component'); 29630 } 29631 29632 owner.stateNode._warnedAboutRefsInRender = true; 29633 } 29634 } 29635 29636 if (componentOrElement == null) { 29637 return null; 29638 } 29639 29640 if (componentOrElement.nodeType === ELEMENT_NODE) { 29641 return componentOrElement; 29642 } 29643 29644 { 29645 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode'); 29646 } 29647} 29648function hydrate(element, container, callback) { 29649 { 29650 error('ReactDOM.hydrate is no longer supported in React 18. Use hydrateRoot ' + 'instead. Until you switch to the new API, your app will behave as ' + "if it's running React 17. Learn " + 'more: https://reactjs.org/link/switch-to-createroot'); 29651 } 29652 29653 if (!isValidContainerLegacy(container)) { 29654 throw new Error('Target container is not a DOM element.'); 29655 } 29656 29657 { 29658 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined; 29659 29660 if (isModernRoot) { 29661 error('You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOMClient.createRoot(). This is not supported. ' + 'Did you mean to call hydrateRoot(container, element)?'); 29662 } 29663 } // TODO: throw or warn if we couldn't hydrate? 29664 29665 29666 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback); 29667} 29668function render(element, container, callback) { 29669 { 29670 error('ReactDOM.render is no longer supported in React 18. Use createRoot ' + 'instead. Until you switch to the new API, your app will behave as ' + "if it's running React 17. Learn " + 'more: https://reactjs.org/link/switch-to-createroot'); 29671 } 29672 29673 if (!isValidContainerLegacy(container)) { 29674 throw new Error('Target container is not a DOM element.'); 29675 } 29676 29677 { 29678 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined; 29679 29680 if (isModernRoot) { 29681 error('You are calling ReactDOM.render() on a container that was previously ' + 'passed to ReactDOMClient.createRoot(). This is not supported. ' + 'Did you mean to call root.render(element)?'); 29682 } 29683 } 29684 29685 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback); 29686} 29687function unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) { 29688 { 29689 error('ReactDOM.unstable_renderSubtreeIntoContainer() is no longer supported ' + 'in React 18. Consider using a portal instead. Until you switch to ' + "the createRoot API, your app will behave as if it's running React " + '17. Learn more: https://reactjs.org/link/switch-to-createroot'); 29690 } 29691 29692 if (!isValidContainerLegacy(containerNode)) { 29693 throw new Error('Target container is not a DOM element.'); 29694 } 29695 29696 if (parentComponent == null || !has(parentComponent)) { 29697 throw new Error('parentComponent must be a valid React Component'); 29698 } 29699 29700 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback); 29701} 29702function unmountComponentAtNode(container) { 29703 if (!isValidContainerLegacy(container)) { 29704 throw new Error('unmountComponentAtNode(...): Target container is not a DOM element.'); 29705 } 29706 29707 { 29708 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined; 29709 29710 if (isModernRoot) { 29711 error('You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' + 'passed to ReactDOMClient.createRoot(). This is not supported. Did you mean to call root.unmount()?'); 29712 } 29713 } 29714 29715 if (container._reactRootContainer) { 29716 { 29717 var rootEl = getReactRootElementInContainer(container); 29718 var renderedByDifferentReact = rootEl && !getInstanceFromNode(rootEl); 29719 29720 if (renderedByDifferentReact) { 29721 error("unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.'); 29722 } 29723 } // Unmount should not be batched. 29724 29725 29726 flushSync(function () { 29727 legacyRenderSubtreeIntoContainer(null, null, container, false, function () { 29728 // $FlowFixMe This should probably use `delete container._reactRootContainer` 29729 container._reactRootContainer = null; 29730 unmarkContainerAsRoot(container); 29731 }); 29732 }); // If you call unmountComponentAtNode twice in quick succession, you'll 29733 // get `true` twice. That's probably fine? 29734 29735 return true; 29736 } else { 29737 { 29738 var _rootEl = getReactRootElementInContainer(container); 29739 29740 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode(_rootEl)); // Check if the container itself is a React root node. 29741 29742 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainerLegacy(container.parentNode) && !!container.parentNode._reactRootContainer; 29743 29744 if (hasNonRootReactChild) { 29745 error("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.'); 29746 } 29747 } 29748 29749 return false; 29750 } 29751} 29752 29753setAttemptSynchronousHydration(attemptSynchronousHydration$1); 29754setAttemptContinuousHydration(attemptContinuousHydration$1); 29755setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority$1); 29756setGetCurrentUpdatePriority(getCurrentUpdatePriority); 29757setAttemptHydrationAtPriority(runWithPriority); 29758 29759{ 29760 if (typeof Map !== 'function' || // $FlowIssue Flow incorrectly thinks Map has no prototype 29761 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || // $FlowIssue Flow incorrectly thinks Set has no prototype 29762 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') { 29763 error('React depends on Map and Set built-in types. Make sure that you load a ' + 'polyfill in older browsers. https://reactjs.org/link/react-polyfills'); 29764 } 29765} 29766 29767setRestoreImplementation(restoreControlledState$3); 29768setBatchingImplementation(batchedUpdates$1, discreteUpdates, flushSync); 29769 29770function createPortal$1(children, container) { 29771 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; 29772 29773 if (!isValidContainer(container)) { 29774 throw new Error('Target container is not a DOM element.'); 29775 } // TODO: pass ReactDOM portal implementation as third argument 29776 // $FlowFixMe The Flow type is opaque but there's no way to actually create it. 29777 29778 29779 return createPortal(children, container, null, key); 29780} 29781 29782function renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) { 29783 return unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback); 29784} 29785 29786var Internals = { 29787 usingClientEntryPoint: false, 29788 // Keep in sync with ReactTestUtils.js. 29789 // This is an array for better minification. 29790 Events: [getInstanceFromNode, getNodeFromInstance, getFiberCurrentPropsFromNode, enqueueStateRestore, restoreStateIfNeeded, batchedUpdates$1] 29791}; 29792 29793function createRoot$1(container, options) { 29794 { 29795 if (!Internals.usingClientEntryPoint && !false) { 29796 error('You are importing createRoot from "react-dom" which is not supported. ' + 'You should instead import it from "react-dom/client".'); 29797 } 29798 } 29799 29800 return createRoot(container, options); 29801} 29802 29803function hydrateRoot$1(container, initialChildren, options) { 29804 { 29805 if (!Internals.usingClientEntryPoint && !false) { 29806 error('You are importing hydrateRoot from "react-dom" which is not supported. ' + 'You should instead import it from "react-dom/client".'); 29807 } 29808 } 29809 29810 return hydrateRoot(container, initialChildren, options); 29811} // Overload the definition to the two valid signatures. 29812// Warning, this opts-out of checking the function body. 29813 29814 29815// eslint-disable-next-line no-redeclare 29816function flushSync$1(fn) { 29817 { 29818 if (isAlreadyRendering()) { 29819 error('flushSync was called from inside a lifecycle method. React cannot ' + 'flush when React is already rendering. Consider moving this call to ' + 'a scheduler task or micro task.'); 29820 } 29821 } 29822 29823 return flushSync(fn); 29824} 29825var foundDevTools = injectIntoDevTools({ 29826 findFiberByHostInstance: getClosestInstanceFromNode, 29827 bundleType: 1 , 29828 version: ReactVersion, 29829 rendererPackageName: 'react-dom' 29830}); 29831 29832{ 29833 if (!foundDevTools && canUseDOM && window.top === window.self) { 29834 // If we're in Chrome or Firefox, provide a download link if not installed. 29835 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) { 29836 var protocol = window.location.protocol; // Don't warn in exotic cases like chrome-extension://. 29837 29838 if (/^(https?|file):$/.test(protocol)) { 29839 // eslint-disable-next-line react-internal/no-production-logging 29840 console.info('%cDownload the React DevTools ' + 'for a better development experience: ' + 'https://reactjs.org/link/react-devtools' + (protocol === 'file:' ? '\nYou might need to use a local HTTP server (instead of file://): ' + 'https://reactjs.org/link/react-devtools-faq' : ''), 'font-weight:bold'); 29841 } 29842 } 29843 } 29844} 29845 29846exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals; 29847exports.createPortal = createPortal$1; 29848exports.createRoot = createRoot$1; 29849exports.findDOMNode = findDOMNode; 29850exports.flushSync = flushSync$1; 29851exports.hydrate = hydrate; 29852exports.hydrateRoot = hydrateRoot$1; 29853exports.render = render; 29854exports.unmountComponentAtNode = unmountComponentAtNode; 29855exports.unstable_batchedUpdates = batchedUpdates$1; 29856exports.unstable_renderSubtreeIntoContainer = renderSubtreeIntoContainer; 29857exports.version = ReactVersion; 29858 /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ 29859if ( 29860 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && 29861 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === 29862 'function' 29863) { 29864 __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error()); 29865} 29866 29867 })(); 29868}